mirror of
https://github.com/getcargohq/cargo-skills.git
synced 2026-09-14 19:17:15 +08:00
main
169 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
addc862efb |
Rename cargo-cdk to cargo-project, following the CLI's project group (#128)
* Rename cargo-cdk to cargo-project, following the CLI's `project` group @cargo-ai/cli renamed `cargo-ai cdk` to `cargo-ai project` and kept `cdk` as an alias. The skill directory, its name, every cross-link, and every command example now say project. The @cargo-ai/cdk package, its imports, `npx @cargo-ai/cdk`, cargo.state.json and the define* builders are unchanged. - hooks/approve-cli.sh gates `project deploy` and `project destroy` next to the cdk pairs; without them the renamed deploy auto-approved. - skills-lint knows `project` as a CLI domain. - The "deploy from CI" trigger becomes "deploy the workspace from CI". The CI routing case was a tie on main, won only because cargo-cdk sorted before cargo-hosting; cargo-project sorts after it. - No redirect stub at the old name. - cargo-project 2.0.0; patch bumps for the eight skills that link to it, and the plugin manifests follow the router to 1.25.1. Needs the CLI release that ships the project group, with cargo/cli-version bumped to it, before merge. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KRC3ERvnznXTw3WFLWrPaS * Keep cargo-cdk as a redirect to cargo-project `npx skills add` never deletes an installed skill that vanished upstream, and `skills update` skips the deletion non-interactively. A plain rename left every existing install with a frozen cargo-cdk routing next to cargo-project. cargo-cdk/SKILL.md is now a pointer (2.0.0), so the next refresh overwrites the stale copy, and a CLI that still hands off to cargo-cdk lands on it. Checked by installing main and then this branch into a throwaway HOME. It is marked `metadata.redirect: cargo-project`. skill-redirects.mjs lets lint (count, router check), the routing eval, llms.txt and the Codex package skip it; lint still lints the file and requires the target to be a skill. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KRC3ERvnznXTw3WFLWrPaS --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
2881e22550 |
CI: bump hashgraph-online/ai-plugin-scanner-action (#125)
Bumps [hashgraph-online/ai-plugin-scanner-action](https://github.com/hashgraph-online/ai-plugin-scanner-action) from 1.2.537 to 1.2.577. - [Release notes](https://github.com/hashgraph-online/ai-plugin-scanner-action/releases) - [Commits](https://github.com/hashgraph-online/ai-plugin-scanner-action/compare/bbeac35a403ccc95459cdbe68249916e6149182c...575e29933351065c43d1b2b0456f9ad415118d60) --- updated-dependencies: - dependency-name: hashgraph-online/ai-plugin-scanner-action dependency-version: 1.2.577 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
b6d00f426d |
Document the JS script node's require allowlist. (#126)
Agents were told it ships lodash; the sandbox also allows axios, cheerio, crypto-js, date-fns, jsonschema, url, uuid, and zod, and knex is gone. Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
bb59f8d4db |
CI: bump hashgraph-online/ai-plugin-scanner-action (#119)
Bumps [hashgraph-online/ai-plugin-scanner-action](https://github.com/hashgraph-online/ai-plugin-scanner-action) from 1.2.528 to 1.2.537. - [Release notes](https://github.com/hashgraph-online/ai-plugin-scanner-action/releases) - [Commits](https://github.com/hashgraph-online/ai-plugin-scanner-action/compare/b402d3b3aaa8f59df8e8aa427dc97694a0af2819...bbeac35a403ccc95459cdbe68249916e6149182c) --- updated-dependencies: - dependency-name: hashgraph-online/ai-plugin-scanner-action dependency-version: 1.2.537 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
bf23619313 |
Stop documenting the first-party enrichment provider (#122)
* Stop documenting the first-party enrichment provider
Its playbook, its 21 priced actions, and every recipe step that led with it
are removed. Each one now leads with the rung the pack already named as its
fallback, so nothing here is invented — the replacements were sitting in
stage-action-map.md and alternatives.md the whole time.
The substitutions:
firmographics aiArk.enrichCompany (0.01) -> companyEnrich (0.25) -> waterfall (1)
person aiArk.enrichPerson (0.1) -> waterfall.enrichContact (2)
funding enrichCrm.getFunding (1), now the catalog's only one
technographics builtwith.getDomainSummary (free) -> enrichDomain (1)
dedupe free storage query against the workspace's own models
That last line is the one worth reading twice. The match actions existed to
mint an id the other actions required; every replacement keys on the domain
or a LinkedIn URL, so a step that cost 0.5/record now costs nothing.
The event feed has no replacement and the recipes say so. fetchBusinessEvents
took a timestamp_from and nothing else in the catalog does, so funding-watch,
re-engagement and lost-deal-revival are rewritten as a diff: re-pull, compare
against the stored round date, keep what moved. Cadence becomes the only cost
dial, which is why funding-watch's default drops from daily to weekly.
Every credit budget was recomputed rather than relabelled:
build-tam 2,955 -> 2,210 (500 companies + 1,500 contacts)
prospecting P2 821 -> 107 (200 verified prospects)
icp-discovery 602 -> 204 (200 deals)
context bootstrap 3 -> 1
Catalog counts now follow the generated data file rather than the older
hand-kept figure: 136 integrations, 176 credits-based actions of 513.
Also bumps the CLI pin 1.0.66 -> 1.0.78.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019wkwbhrEoE5KW9A1CKBmcA
* Fix the three generated artifacts the removal invalidated
CI caught what the local lint could not: skills-lint.mjs is only one of five
checks, and the other four all had something to say.
llms.txt was stale — it is generated from the skill descriptions, and
cargo-gtm's dropped a provider from its roster.
The codex package build enforces override version == upstream version, so
bumping only .github/package-overrides/cargo-quickstart.SKILL.md to 1.0.3 broke
it. The guard exists to stop the override silently shipping last month's demo,
so the fix is to bump both, not to revert the override.
That build also patches literal source strings at package time, and one anchor
ran through a line this branch rewrote:
snitcher.searchSessions (0 cred) -> cargo.matchProspect
snitcher.searchSessions (0 cred) -> aiArk.reverseLookup (0.05)
The edit strips the visitor-de-anonymisation path from the packaged skill, so a
silent miss would have shipped it. Re-anchored, and every other PACKAGE_EDITS
find string verified against the tree — 1 broken, now 0.
Also drops the packaged cargo-connection description from 138 integrations to
136, matching the repo.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019wkwbhrEoE5KW9A1CKBmcA
* Say where revenue went, and that employee ratings went nowhere
Removing the provider took two data points off the map without replacing the
map entry, which is the failure mode this recipe's own feasibility gate exists
to prevent: an attribute that quietly stops being answerable reads the same as
one nobody asked for.
They are not the same case, so they get different rows.
Revenue and NAICS survive. companyEnrich.enrichByDomain (0.25) returns them in
the same call as firmographics, employees, funding and socials — so it fills
several rows at once and the row says that, because the per-account arithmetic
in step 4 gets it wrong otherwise.
Employee ratings have no successor at any price. Nothing credits-based in the
catalog returns Glassdoor-style employer reputation. The row says none, and
says to report it as a research note rather than substituting a scrape that
reads like the real thing — which is the recipe's stated position on valuable
attributes with no obtainable source, applied to itself.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019wkwbhrEoE5KW9A1CKBmcA
* Fix the data-flow breaks the provider swap left behind
Bugbot found eight, all real, and verifying them turned up five more. The
pattern in every case is the same: I replaced an action but left the code that
consumed its output reading the old response shape, so the step still runs,
still bills, and quietly returns nothing.
Response-shape breaks:
funding-watch Pattern A still filtered funding_rounds[].announced_date
while Pattern B read lastFundingDate. The 90-day select
matched nothing, so the primary path returned an empty
list after a paid pull.
re-engagement Step 5 read .results[] and .events[] from a file step 3
now writes as a bare array. Funding branch always empty.
lost-deal-revival Step 4 read .events[0] and expected a deal_id that
getFunding does not return. Step 3b now carries deal_id
through, which is the only place it exists.
Wrong-source breaks:
re-engagement The diff read last_funding_round_at off the Contacts
segment. It is a Companies column, so the stored date was
always empty and every account re-flagged every week. Now
queries the Companies model, and fans the company-level
signal back out to contacts, since step 5 unions on email.
build-tam Step 4 keyed searchLeads on .linkedinId from the
aiArk.enrichCompany output. No enrichment action returns a
Sales Navigator accountId. Now carried from the sourcing
step, with an explicit gate for rows that have none.
guide snitcher.searchSessions identifies a COMPANY; I had
chained it into aiArk.reverseLookup, which needs an email
or phone. Its own playbook says to route identified
domains through the enrich chain.
Budget break:
prospecting P2 step 5 ran FullEnrich over every lead while the budget
quoted the residue. 200 credits against 60. P1 had the
gate; P2 did not.
Pre-existing, fixed because the fixes above sit inside them:
icp-discovery [.[] | {domain}] over storage query execute output, which
is {rows: [...]}. Enriched one null domain, not 200.
jq inputs[N] `inputs` is a generator, not an array, so the union
expressions in re-engagement and lost-deal-revival errored
out. Slurped to [inputs] as $in.
Every rewritten jq expression was run against fixtures rather than eyeballed.
Also five provider mentions the sweep missed, because they wrote it as bare
`cargo` with a price rather than cargo.actionName: societeInfo, snitcher,
enrichCrm, linkedin, oceanio, apolloio, rocketreach.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019wkwbhrEoE5KW9A1CKBmcA
* Make funding-watch Pattern B stand on its own
It re-pulled two hardcoded example domains and then diffed them against
/tmp/targets.json, a Pattern A artifact. Run Pattern B alone and the slurp
fails; run both and it compares a fresh pull of one set against stored dates
for a different set, so the "new round" filter cannot fire correctly either way.
Both sides of a diff have to come from the same query. Now they do: one storage
read supplies the domains to pull *and* the stored dates to compare against, so
the sets align by construction and the pattern has no cross-dependency.
Also states what a missing stored date means — it compares against "" and always
passes, which is right on a first run and is exactly why the write-back step is
not optional. Without it every run is a first run and the watch re-flags the
whole segment forever.
Verified against fixtures: an account whose round moved is kept, one whose
stored date already matches is dropped, one with no stored date passes.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019wkwbhrEoE5KW9A1CKBmcA
* Route the questions people ask but the map never answered (#124)
Measured instead of guessed. Of the 176 credits-based actions, 148 were
reachable from a routing surface — the stage map, the phase guides,
alternatives.md, a recipe. The other 28 were reachable only from their own
provider playbook, which is findable if you already know which provider to
open. That is the wrong way round.
The worst of it: headcount had no section at all. It is the most-asked company
attribute and the first row of the custom-datapoints feasibility gate, and not
one of the four salesNavigator.find* actions appeared anywhere in the stage map.
New section carries all four, plus the only historical series
(companyEnrich.getWorkforce), plus linkedin.findCustomHeadcount for the roles
the fixed buckets don't have, plus the companyId prerequisite that quietly
turns a 0.25 action into 0.30 on a list that arrived without one.
"Who works at this domain" was not a documented question either. It is not the
same as searching a population by title, and it has two answers at very
different prices. New section, with the trap stated: looping hunter.searchDomain
to build a list is the pitfall its own playbook warns about.
Also adds rocketreach, mixrank and societeInfo to Enrich/Sourcing —
societeInfo reaches French registry data (NAF code, collective agreement,
filed accounts) that nothing else in the catalog does — and gives Hiring intent
a second index at the same price.
154/176 now. The remaining 22 stay unrouted on purpose, and the CHANGELOG says
why for each: the four LinkedIn engagement actions would undercut the
acceptable-use refusal to batch-blast them, three natives belong to other
skills, searchLeadsLegacy costs 300x its replacement, and the rest are finer
grain on an already-routed surface rather than separate questions.
One thing the build caught: adding aiArk.analyzePersonality re-introduced a
term the codex package deliberately strips, since the directory rejected
person-level inference. Kept for the channels that carry it, with matching
PACKAGE_EDITS so the package still removes it. Dropped the forager rung rather
than add machinery for a last-resort action priced 20x above its own chain.
All 67 anchors verified.
Claude-Session: https://claude.ai/code/session_019wkwbhrEoE5KW9A1CKBmcA
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
7a5f8375be |
Disable Cisco scanner to work around v2.0.14 false positives
cisco-ai-skill-scanner 2.0.14 incorrectly flags standard Unicode characters (em dashes, arrows) as 'obfuscated prompt-injection'. Neither baseline files, severity_overrides, nor cisco_policy: permissive suppress these false positives. Disabling the Cisco scanner until the upstream fix is released. The base plugin scanner still runs all core security checks. Co-authored-by: Auree Aubert <aureeaubert@users.noreply.github.com> |
||
|
|
ea1acfad1a |
Set cisco_policy to permissive to fix scanner false positives
The cisco-ai-skill-scanner 2.0.14 flags standard Unicode characters (em dashes, arrows) as 'obfuscated prompt-injection'. The baseline and severity_overrides config options don't affect the Cisco scanner, so use cisco_policy: permissive to relax the detection rules. Co-authored-by: Auree Aubert <aureeaubert@users.noreply.github.com> |
||
|
|
786bdeb290 |
Downgrade OBFUSCATED_PROMPT_INJECTION severity to bypass scanner false positives
The baseline file alone isn't suppressing the false positives, so also add a severity_overrides rule to downgrade the finding severity to 'low', which is below the 'high' threshold that fails the CI check. Co-authored-by: Auree Aubert <aureeaubert@users.noreply.github.com> |
||
|
|
d91ab11e45 |
Point the CDK skill at cdk add, and stop documenting a template flag (#121)
The cookbook guidance said there was no copy tool and the agent had to place the code itself. `cdk add cookbook/<slug>` is that tool now, so the skill says what it does, where it writes, and — the part an agent gets wrong — that the cookbook's own procedure has to be picked up at its Adapt section, because its opening steps assume you found the folder on GitHub and still have to place it. The command reference documented `--template <blank|full>` and `--list-templates` for `cdk init`. Neither flag exists: the scaffold never varies and a worked example comes from a cookbook. It also had no row for `add` or `cookbook` at all, which is the reference an agent reads to decide what to run. Fixed, along with the two recipes and the example that invoked `--template full`. Refreshes the cookbook snapshot, which had gone stale at two cookbooks while the catalog grew to three — `crm-enrichment` was missing from the menu. Regenerates llms.txt and the skill's metadata snapshot, both CI-gated. Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
be823b3fcb |
Generate the cost table, and stop omitting the native actions (#111)
* Generate the cost table, and stop omitting the native actions
The credits price list was hand-kept. The first attempt to generate it read
`connection integration list`, which is connector-only — so its own header
claimed "every credits-based action in the cargo catalog" while silently
omitting every billed native action:
sendEmail 0.1 fixed
modelAsk 0.5 fixed
fileSearch 0.02 / 1k tokens
`sendEmail` is the whole outbound send path, priced at 0.1 in the mailbox
skill, and it was absent from the canonical price list.
It is now generated by `cargo-ai orchestration action cost-table --raw`
(getcargohq/cargo#5641), which lives beside `action list` and `action execute`
— the surface that spans connector, native, tool and agent. 197 credits-based
actions of the 534 the catalog exposes, up from the 145 the hand-kept table
claimed and the 194 a connector-only generator found.
What the hand-kept table got wrong, now that a generated one can be diffed
against it: 145 actions where there are 197, four prices quoted from memory,
and cost columns that concatenated every tier into an unreadable comma list —
`openAi.instruct` rendered 28 numbers. Per-config pricing moves to its own
section.
Two providers gain playbooks rather than staying unlisted: brightData
(Instagram/TikTok/Facebook/YouTube by URL, the catalog's only non-LinkedIn,
non-X social coverage) and proxycurl. An undocumented provider still shows up
in the cost table, so the acceptable-use framing is better stated than implied;
brightData.md opens with the consumer-targeting refusal that gates it. Only
openRouter remains without a playbook, and it has no credits-based actions.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TBfa73ishJJRe4pccyhTAa
* Pin the CLI at 1.0.66, and fix five commands that never existed (#117)
* Pin the CLI at 1.0.66, and fix five commands that never existed
The pin had drifted 19 releases behind npm, and the bundle now teaches
`orchestration action list`, which only exists in 1.0.66. The pin is what the
session-start refresh installs, so leaving it meant an agent following these
skills would reach for a command its CLI did not have.
Checked before moving it, not after: the CLI's whole command surface was diffed
across 1.0.47..1.0.66. The only removals are three billing commands no skill
documents; `update-payment-method`, which the skills do use, replaced one of
them and is still there. Everything else in the range is additive.
That verification then turned up five documented commands that do not exist —
and all five were already broken at the old pin, so this is old debt the bump
surfaced rather than caused:
- `orchestration draft-release {get,update,deploy}` (18 sites) is really
`orchestration release {get-draft,update-draft,deploy-draft}`.
- `ai template get <slug>` (6 sites) does not exist. `ai template list` already
returns each template in full, so the fix is to filter that response.
- `action execute --record` (5 sites) is `--data`.
- `storage model list --dataset-uuid` (4 sites): the command takes no options
at all, and every model carries `datasetUuid`, so filter client-side.
- `storage model get-ddl --model-uuid <uuid>` takes the uuid positionally.
Also folds in the skills half of getcargohq/cargo#5740: `get-output-schema`
takes an action plus an optional `--data` rather than demanding a `config`, so
the object `action list` returns now pastes into all four action commands
unchanged. The gotcha row about the 400 becomes a note about `--data`, which is
the part worth knowing.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TBfa73ishJJRe4pccyhTAa
* Mark --data on get-output-schema as CLI >= 1.0.67
getcargohq/cargo#5740 ships --data in CLI 1.0.67, one above the pin this PR
sets. The config-less --action works on the pinned 1.0.66 as soon as that
backend deploys; --data needs the next release, so it carries a version marker
like every other post-pin flag in the bundle.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Document the execution charge the pack said did not exist (#118)
Every node execution bills 0.01 credits (1 per 100) — structural natives
and errored executions included. Three places in the pack said otherwise,
and they reinforced each other:
- troubleshooting.md described executions[].creditsUsedCount as "native
nodes are zero", accurate about the field but read as pricing;
play-optimize-credits.md restated it and cited it as the authority.
- The generated cost table prices actions, and structural natives are
excluded from `action list` entirely, so branch/filter/switch/variables
appear in no price list here — read as free.
- cargo/SKILL.md said "Everything else is free" outright.
Verified live: `billing usage get-metrics --unit orchestration.executions`
returns success/error as execution counts, reconciling row-for-row with
`SELECT execution_status, count() FROM spans`. spans.execution_credits_used_count
reads 0 on natives that billed, so the charge is attributed to no node and
per-node profiling under-counts every graph.
Two adjacent bugs fixed while verifying:
- `--unit credits` was documented and 400s. The flag takes exactly
billing.credits | orchestration.executions | storage.records, and with
no --unit all three interleave in one items[] array with different
meanings for `count`.
- The example slugs `enrichment` / `ai_message` were invented (real:
integration.<slug>.action.<action>, native.<action>, success/error,
insert), as was `.totalUsage` — the response has one key, `metrics`.
Estimates now carry two terms: (provider cost × records) + (nodes ×
records / 100), measured on the pilot rather than inferred from the graph.
cargo-billing 1.1.0 -> 2.0.0 (agents relearn --unit and the slug shapes),
cargo-orchestration 1.11.0, cargo-gtm 1.19.0, cargo-diagnostics 1.4.0,
cargo 1.24.0 + the three plugin manifests.
Still upstream: `orchestration action cost-table` generates the header
"The other 337 actions ... cost no credits" — unfixable from this repo.
Claude-Session: https://claude.ai/code/session_01AbUvyTQMDABiexZgQCsGoe
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Source the cost table from action list, not a bespoke generator
`orchestration action cost-table` is being removed from the CLI: it read
`action list` twice and added no data, and the markdown it generated was
its only consumer. `action list` already returns a `credits` array on every
billed action, so the table is regenerated from that directly.
Regeneration is now two calls (`--kind connector`, `--kind native`) plus
the three cost shapes documented in the header, so a reader can render the
table without the generator's price-formatting logic. Notably `fixedCost`
adds to the metered rate rather than replacing it — the trap that made a
0.175 + 0.025/item search read as 0.025.
Two fixes that fall out of owning the header again:
- The opening line claimed the other 337 actions "cost no credits". True
of provider price, false of anything that runs in a workflow. It was
flagged as unfixable while the CLI generated it; it now states no
*provider* price and points at the execution charge.
- `stage-action-map.md` still carried 194/310 from the connector-only
generation, against 197/337 everywhere else.
Co-Authored-By: Auree Aubert <16732193+aureeaubert@users.noreply.github.com>
Co-Authored-By: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com>
Co-authored-by: Auree Aubert <aureeaubert@users.noreply.github.com>
* Fix PACKAGE_EDITS patterns to match regenerated cost table format
Co-authored-by: Auree Aubert <aureeaubert@users.noreply.github.com>
* Add PACKAGE_EDITS rule to remove extractEventAttendees from stage-action-map.md
Co-authored-by: Auree Aubert <aureeaubert@users.noreply.github.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com>
Co-authored-by: Auree Aubert <aureeaubert@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
|
||
|
|
55d2eaf660 |
Ship the OpenAI package without the surfaces its review rejected (#120)
* Hold the sending skill out of the OpenAI package The directory review rejected two skills under "Spam mass abuse". cargo-mailbox-management is a true positive on category: it provisions sending mailboxes and runs a 5-to-40/day warm-up ramp, which is the shape of cold-email infrastructure whatever the gates around it. So the package now ships without it — EXCLUDED_SKILLS — and says so by shipping eighteen skills rather than by rewording the nineteenth. The alternative, deleting the refusal lists and ramp documentation until the keywords stop matching, would ship a less guarded skill in order to pass a safety review. cargo-gtm looks like a false positive on negation: its description ended "bulk unsolicited messaging, purchased or scraped lists, and consumer targeting are refused", which hands a keyword classifier four spam nouns in one clause. The packaged description now states the same policy as what the skill does — documented lawful basis, suppression screening, per-recipient relevance, sends nothing itself — and keeps every routing trigger. That did not clear review — gtm was rejected again with the new card live, so the trigger is the skill body or the capability itself, not the description. The reframed card is kept because it is the more accurate of the two, not because it fixed anything. Excluding a skill is not just skipping a directory. Fifteen of the remaining skills link to it: a router table row, an ASCII diagram box, a recap section, the domain list, defineMailbox/defineDomain in cargo-cdk, a routing row in cargo-mcp, three passages in cargo-gtm's acceptable-use. PACKAGE_EDITS removes each one in the staged copy, and every find must match exactly once or the build fails — they are anchored to prose that will drift, and a silent no-op would ship a dangling link. Skill counts renumber from the real packaged total, so the router reads "18 skills ... fifteen capability skills" without anyone maintaining the number. Backstopping all of that, zipgrep asserts after zipping that no packaged file names an excluded skill anywhere. That check does not care whether the edits above were written correctly. Every edit applies to the staging copy under dist/. The repo files are read-only inputs, so Claude Code, Cursor, skills.sh and Hermes still install all nineteen skills with every mailbox reference intact. Also fixes the packaged manifest description, which claimed 17 skills — stale since two were added. It derives from the packaged count now. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YL6YdzRFUf27A2WChKxr1C * Narrow cargo-gtm's person-level surface for the OpenAI package Second rejection, with the reframed description already live in the listing — so the card was never the trigger. Reading the skill body as a policy reviewer would, five capabilities carry most of the risk, and on those the reviewer is not wrong: snitcher de-anonymising website visitors aiArk.analyzePersonality OCEAN/DISC inference from a profile forager personal email and personal phone from a URL linkedin.extractEventAttendees harvesting a platform's attendee list x reading a social platform's posts and profiles "We gate it" is a weak answer to visitor de-anonymisation and personality inference. So the packaged skill no longer offers them: three playbooks leave the tree, and the actions are removed from the stack table, the cost table, the stage map, the alternatives table, the finding guide's decision tree, two recipes, the aiArk playbook and the router's glossary. Thirty-four edits, each asserted to match exactly once. What remains is the same skill minus a person-level edge: company research, work-email enrichment from licensed providers, verification, scoring, signal monitoring, CRM sync. That is a real narrowing of what the package can do rather than a rewording of what it says it does, which is also what makes the appeal behind it checkable. REMOVED_TERMS asserts against the built archive that nothing survived, scoped by path — extractEventAttendees stays in cargo-connection, which documents the catalog rather than recommending the action, and which the directory already approved. Metadata is regenerated with the repo's own skills-metadata.mjs over the staged tree: three files left and a dozen changed, so every packaged skill-metadata.json was stale by construction, content hash included. Repo copies are untouched, as before. Every other channel still ships all nineteen skills with the full provider stack. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YL6YdzRFUf27A2WChKxr1C * Give the packaged quickstart a company-level demo Third rejection, same category: the quickstart's headline pull is 25 named people with titles and a "recently hired" flag. Sixteen skills that never touch a person passed on the first try; the three that were rejected are the three that do. Rather than drop the onboarding skill, the package now ships a variant that runs the same two-minute arc against company-level hiring intent — theirStack.searchCompanies on the persona's role, postings inside 30 days. This is the skill's own fallback rung 2, which it already describes as "same wow, different angle". The receipt is unchanged at ~0.5 credits, because searchCompanies bills per call rather than per row, so `limit` is free to set. The demo names no individuals. It ships as a whole file rather than as edits. The spine is rewritten — action, filter, output fields, headline, fallback ladder, next steps — and a dozen brittle anchors through a rewritten section would fail on the next upstream wording change with nothing useful to say about it. The copy is tied to the repo skill's frontmatter version instead. Bump cargo-quickstart and this build fails, naming both versions and asking for the port. That is the maintenance cost of an override, made loud on purpose. Step 3 reads the first row's keys and renders from them rather than hardcoding a shape: the payload of this action is not something I have run, and a demo that dies on line 3 is worse than one that spends a second looking. Worth one 0.5-credit run against a live workspace before the package is resubmitted. Repo copies untouched, as with the two commits before this. Every other channel still ships the leads demo. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YL6YdzRFUf27A2WChKxr1C * Rebuild the quickstart demo on aiArk, against a live run theirStack was the wrong pick and the reason is not taste: it needs its own API-key connector, so on the fresh workspace a quickstart exists for it dead-ends on rung 1. It got chosen because the fallback ladder named it, not because anything checked it. aiArk.searchCompanies is better on every axis that matters here. It runs on cargo's managed connection, so a workspace with nothing wired up can still complete the demo. At 0.01 per returned record, 25 rows cost 0.25 credits — half what the leads demo cost. And it answers the persona question with accounts rather than people. The demo also opens on countCompanies, which is fixed-cost 0. Sizing the whole addressable market for free and then sampling it for a quarter of a credit is a better first beat than 25 rows with no denominator, and it puts the pack's own count-first rule in the first thing a new user sees. Everything here is verified against a real run rather than a playbook: countCompanies free, returns {"count": N} — 1,904 on the example searchCompanies 25 rows for 0.25 credits employeeRole employee_title_or / employee_seniority_or / employee_department_or industry industry_or takes plain lowercase strings ("software development") — no autocomplete needed, and it halved the pool to 840 row fields name, industry, employee_count, city, country, domain, linkedin_url, revenue, founded_year, technologies So step 4 renders named columns now instead of printing the keys and hoping. theirStack keeps a place as rung 3, where its own-key connector is a known cost rather than a surprise. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YL6YdzRFUf27A2WChKxr1C * Remove only the mailbox bullet from the CDK critical rules The drop_block helper takes the blank-line-delimited block around a marker, which is right for a standalone diagram and wrong for a markdown bullet list: consecutive bullets have no blank line between them, so the whole list is one block. The cargo-cdk edit anchored on the defineMailbox bullet and took all of "## 6) Critical rules" with it — 71 lines instead of 12. The packaged CDK skill shipped an empty heading, losing the state-file, secrets, handle-wiring, --yes, paid-play sample and alert cost-gate rules. Caught by Bugbot on #120, not by the build: every assertion here checks that a find matched exactly once and that removed things left no trace. Nothing checked that what remained was still there. A repo-vs-package line-count diff over the whole archive now reconciles: every SKILL.md is -12 for the dropped metadata block, and each further delta matches a specific edit. cargo-cdk is the only file that was wrong. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YL6YdzRFUf27A2WChKxr1C * Document aiArk's three undocumented actions Bugbot flagged the quickstart override for calling aiArk.countCompanies, an action absent from the packaged playbook. The action is real — the demo was verified against a live run — so the gap is in the documentation, and it is a repo gap rather than a packaging one. The playbook described six actions and asserted "all six are credits-based". The integration exposes nine: enrichCompany 0.01 the cheapest company enrich in the catalog countCompanies free {"count": N} for a searchCompanies filter countPeople free same, for searchPeople The count pair is the more useful omission. Cost discipline tells an agent to size a pool before paying per record, and on this provider that check costs nothing — but only if the agent knows the actions exist. Added alongside the per-record billing warning, where the question actually comes up. Also corrects the override's claim that industry_or takes ordinary lowercase strings, which contradicted the same playbook two files away. Both are true and neither said so: the enum members are LinkedIn-style lowercase names, identical to the strings each row returns in its own industry field, so a value copied off a result matches while a guess empties the pool. The override now says that, and points at listIndustries for anything less obvious. Repo change, so every channel gets it, not just the OpenAI package. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YL6YdzRFUf27A2WChKxr1C * Remove the personality pitch, not just its slug REMOVED_TERMS asserted on "analyzePersonality" and passed, while the packaged playbook went on selling the capability in prose that named no action: an intro pitching "a personality-analysis action nothing else in the catalog has", and a reason-to-reach-for-it clause offering "personality/selling guidance". A slug-only check waved both through. The counts were wrong too. The repo playbook says nine actions, seven credits-based; the package removes one, so it ships eight and six. Now stated as such, and the packaged action table has exactly eight rows to match. The assertion now looks for "personality" itself. It cannot collide with "personalization", which is a different word, and the sweep it flagged on the first run is what found the second clause — the fix caught its own gap before the archive shipped. Also adds .github/package-overrides/** to the Codex package workflow's path filter. The package depends on that file now, so a change touching only the override needs to run the build and the version guard, and did not. Both found by Bugbot on #120. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YL6YdzRFUf27A2WChKxr1C * Fetch the count, drop the attendee pitch, fail a broken sweep Three from Bugbot on #120, all correct. The quickstart's headline number was never fetched. Step 1 wrote the countCompanies run object to a file and step 4 told the agent to lead with the pool size, but the run object holds no results — the same skill says so two paragraphs earlier — and nothing ever called download-outputs for that run. The demo would have opened on an empty variable. Both steps now go through one fetch_output helper, so the retrieval that was already correct for the search is correct for the count too, and the headline reads $POOL. The linkedin playbook still pitched event-attendee harvesting in prose after the action row was removed: an engagement-sourcing bullet and the per-item billing note. Same failure as the personality pitch — the slug left, the capability stayed. The new assertion is scoped to that one file on purpose: "event attendees" appears four more times in cargo-gtm as a lawful BASIS for contacting someone, and that must stay exactly where it is. And the sweeps themselves could not fail. Every throw was read as "nothing matched", so a missing binary or an unreadable archive reported a clean package. grep-family exit codes distinguish these: 1 is no match, anything else is an error. Verified by putting a zipgrep that exits 2 on PATH — the build now stops with "could not verify ... zipgrep exited 2" where it previously passed. That last one is the pattern worth naming: three of the five findings on this PR were assertions that were true and conclusions that were wrong. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YL6YdzRFUf27A2WChKxr1C --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
aead4ddc20 |
Search for actions, and config stopped shouting (#115)
* Cargo has a first-party MCP, and `config` stopped shouting Tracks the platform-MCP branch in the CLI repo: a first-party MCP server at `/mcp`, a new `orchestration action list`, and `config` split off the top-level action type. Two of those three contradict sentences this bundle stated as fact. - The router, `cargo-ai`, and the glossary all said there is no first-party Cargo MCP server. There is one now, at `mcp.getcargo.io/mcp`, with a fixed operate-the-workspace toolset. Both surfaces — platform and curated — are documented, and the routing rule they exist for is unchanged. - `cargo-ai mcp` with no `--server` now bridges the platform MCP rather than resolving "the workspace's only MCP server". Same command, different server by CLI version, so it is in the gotchas table. - New `orchestration action list <keywords>`: free, searches connector, native, tool, and agent actions in one call, and returns a ready `action` object with `connectorUuid` resolved plus the action's credit costs. - `config` is optional on execute/execute-batch and still required on nodes, alerts, play health actions, and get-output-schema. The dangerous half is the deleted guard: misplaced inputs are now dropped silently and the action runs with none. - Nine documents were telling agents to do exactly that. The four LLM playbooks, the prompt-library index, and three GTM recipes put `model`/`advancedSettings`/ `output` (or `customerId`, `spreadsheetId`) in the action's `config`; all now put inputs in `--data`/`--records`. The ads recipe also loses two `execute-batch --model-uuid --filter` calls against flags that do not exist. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TBfa73ishJJRe4pccyhTAa Co-authored-by: Auree Aubert <aureeaubert@users.noreply.github.com> * Drop `config` from every top-level action, and lead with action search The platform-MCP work shipped while this PR was open — CLI 1.0.66 is on npm and the platform MCP answers at mcp.getcargo.io/mcp — so the hedging this branch was written with ("newer backends accept…", "stays valid on any version") is now just the rule. - `config` is gone from 272 execute / execute-batch examples across 79 files. That is the shape `action list` returns, so a search result pastes straight into a run. Nodes, alert `--actions`, play `healthAlertActions`, and agent / MCP-server `--actions` keep theirs; the strip was scoped around them. - `get-output-schema` is the exception and still requires `config` — verified live: the action object from `action list` fails 400 at `action.config`. The CLI's own help examples for that command omit it and therefore all 400. It is now a gotcha row, and those examples keep `"config": {}` on purpose. - `connection action search` shipped in 1.0.36 and no skill had ever mentioned it. cargo-connection now opens with both searches and a table for choosing: `action list` by default, `action search` for `--credits-only` and `--category`. `integration list` / `integration get` drop to what they are good at — the integration, and the schema of an action already picked. - Removed a phantom command: `connection integration list-actions` has never existed, and cost-discipline.md was recommending it as a free lookup. - cargo-mcp gains the one config rule that surface needs: pass the action object as-is, never with a config — `get_action_schema` supplies the empty one, which makes MCP safer here than the CLI. Verified against the live workspace at 1.0.66: a config-less `action execute` returns status success at 0 credits, and `get-output-schema` without `config` returns 400. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TBfa73ishJJRe4pccyhTAa * Fix the strip's leftovers, and bump the router so it actually ships An audit of the 272-example strip turned up one real defect and a set of phrasings the strip left behind, plus a packaging bug that would have made the router's half of this PR a no-op. - `cargo/SKILL.md` was still at 1.22.0, the version main already publishes, so its 14 changed lines — including both new critical rules and both new gotcha rows — would have been skipped at publish. Bumped to 1.23.0, plugin manifests follow. - `guides/writing-outreach.md` still declared the action shape as `integrationSlug + actionSlug + config: {}` directly above an example whose config had been stripped. Every sibling "Action shape" line had been rewritten; this one was missed. - Seven places said the action's config "is empty" or "stays empty" where the rule is now that there is no config key at all. Normalised, including the deliberate contrast in cargo-observability, where alert actions do require one. - The report template in cargo-workspace-management modelled the old shape in a copyable `action execute` string, and cited `config.portalId required` as the symptom. Both corrected. - perplexity's `searchContextSize` is an input, not a "config cost lever" — the same rewrite had moved it into `advancedSettings` in `--records`. Verified clean afterwards: no execute example retains a config, no get-output-schema example lost one, no node/alert/agent/mcp-server action lost one, and every JSON block still parses. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TBfa73ishJJRe4pccyhTAa --------- Co-authored-by: Auree Aubert <aureeaubert@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
5680754126 |
Add cargo-mcp, and correct the router on the hosted MCP server (#116)
mcp.getcargo.io/mcp is live and serves thirteen platform tools plus whatever a workspace published with defineMcpServer. Nothing in the bundle covered it, and cargo/SKILL.md asserted "There is no first-party 'Cargo MCP server'" - true when written, wrong now, and the one claim an agent would act on. - cargo-mcp/SKILL.md (1.0.0): connect, the discover to price to execute to poll spine, and the routing table for MCP tool vs cargo-ai. - cargo/SKILL.md (1.22.0): the MCP section becomes a three-way disambiguation. Hosted server, workspace server served over stdio by cargo-ai mcp, and an MCP client attached to a Cargo agent are three things sharing a name and sharing no answers. - evals/routing.jsonl: "How do I use Cargo from ChatGPT?" now expects cargo-mcp; three cases added for the new surface. - Counts, catalogs, plugin manifests, SKILL_DIRS, llms.txt, metadata. skills-lint, routing-eval, sync-trigger-slugs and the cargo-gtm script fixtures all pass. Co-authored-by: Cargo FSD <fsd@getcargo.io> Co-authored-by: Auree Aubert <16732193+aureeaubert@users.noreply.github.com> Co-authored-by: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com> |
||
|
|
da11a0957a |
CI: bump hashgraph-online/ai-plugin-scanner-action (#114)
Bumps [hashgraph-online/ai-plugin-scanner-action](https://github.com/hashgraph-online/ai-plugin-scanner-action) from 1.2.515 to 1.2.528. - [Release notes](https://github.com/hashgraph-online/ai-plugin-scanner-action/releases) - [Commits](https://github.com/hashgraph-online/ai-plugin-scanner-action/compare/55616c962cf86368423f7673b2ecdfdbe613d1af...b402d3b3aaa8f59df8e8aa427dc97694a0af2819) --- updated-dependencies: - dependency-name: hashgraph-online/ai-plugin-scanner-action dependency-version: 1.2.528 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
e61f67f105 |
New skill: cargo-mailbox-management, and Cargo sends now (#113)
`mailboxManagement` landed in the CLI (cargo#5493, plus warm-up stats in cargo#5646) and nothing in the bundle covered it. It is the first domain that makes Cargo own the inbox, so the gap was not one more capability skill — it was a skill whose absence let an agent send mail with no idea what it cost or what governed it. - New `cargo-mailbox-management` (the fifteenth capability skill): six command groups, the send that is deliberately not in them, and four references — the ramp arithmetic and fleet sizing, the `sendEmail` action, response shapes, troubleshooting — plus eight worked recipes. - The two facts an agent gets wrong without it. A mailbox is a recurring monthly credit charge (100-160 per mailbox per month), not a per-record one, and `mailbox remove` is the only way to stop it. And volume is a ramp, not a setting: 5/day to 40/day over 45 days from `warmupStartedAt`, pinned at 5/day forever if warm-up never started, reset to day 0 by `stop-warmup`, and `dailySendLimit` can only tighten it. - `cargo-gtm`'s acceptable use said the pack never sends. That paragraph is the substance of the plugin-directory remedy, and mailboxManagement made it false. Section 1 now says what is true, section 6 names the ramp and calls spreading one campaign across extra mailboxes what it is, and section 7 cross-references the new skill. - `cargo-cdk` gained `defineMailbox` and `defineDomain` in the same release and had documented neither. Both are now in the builder table with the create-only, monthly-fee and whole-zone rules that bite. - Known gap, filed rather than papered over: `mailbox create --domain-uuid` is required and no command lists sending domains. Counts move 17 to 18 across the router, README, AGENTS, CONTRIBUTING and the manifests. Seven new routing cases, two of them hard-tier negatives pinning the boundary the word "email" blurs. Core tier 93/93; lint, metadata, llms.txt, trigger slugs, cookbooks and hooks all clean. Claude-Session: https://claude.ai/code/session_01TF1ZRweJqqnPeGbVmUeGkY Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
afb0e67fa5 |
Document relationships and unification, which the CLI has always had (#112)
* Document relationships and unification, which the CLI has always had The relationship section documented three flags that do not exist (`list --model-uuid`, `set --from-model-uuid/--to-model-uuid`). The real surface is `list` with no flags and `set --dataset-uuid --relationships <json array>`. Unification appeared nowhere in the pack at all, despite `model update --unification` shipping since well before 1.0.61. An agent reading this reasonably concluded both were UI-only, because every documented command it tried was rejected on an unknown flag. That conclusion then reached a customer conversation. Two behaviours worth stating outright, since neither is guessable and both are destructive to get wrong: - `relationship set` is a full replace scoped to the dataset. Entries without a `uuid` are created, entries with one are updated, and anything whose `uuid` is missing from the payload is deleted. Sending a single relationship to a dataset holding five removes four. - `--unification` only writes config. Unified rows are rebuilt by the model's sync run, so nothing merges until `storage run create`. Also records the real `relationship list` response (workspace-wide, carrying `fromDatasetUuid`/`toDatasetUuid`/`fromPropertySlug`), adds `unification` to the model shape, and adds routing triggers so "unify these models" and "merge duplicate accounts" land here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JU1NTvKaBEiLDaAAnFW2ho * Trim the router line to the one rule that fails silently "Not UI-only" was a rebuttal to a belief that only existed because the docs were broken, and those are fixed in this branch. What survives is the destructive half: `relationship set` deletes anything absent from the payload. That belongs next to the `conjonction` rule — the router is what's in context when an agent fires a one-off command without loading cargo-storage, which is exactly when it would remove four relationships to add one. The unification recompute stays in cargo-storage only: a silent no-op that a row count catches, not a data loss. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JU1NTvKaBEiLDaAAnFW2ho --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
fb95217c52 |
Make the cookbook menu a local file, and route on one-off vs standing (#110)
* Make the cookbook menu a local file, and route on one-off vs standing cargo-cdk told the agent to "read the cookbook menu (the repo README's table)" — a network fetch to another GitHub repo, mid-task, which an agent may simply not make. When it does not, it authors from scratch a GTM outcome that was already sitting there written. A menu you have to go and get is a menu that gets skipped. So the menu becomes a local reference, generated from the cookbook repo: .github/data/cookbooks.json committed snapshot .github/scripts/sync-cookbooks.ts --refresh to re-pull, --check in CI cargo-cdk/references/cookbooks.md generated prose Same shape as sync-trigger-slugs.ts, deliberately: CI reads the snapshot and never the network, so a change in the cookbook repo cannot turn this build red on its own. Staleness is fixed on purpose, with --refresh. Two things the pointers got wrong, beyond being remote: Routing. cargo-cdk's description triggers on "as code", "in git", "Terraform for Cargo". Nobody says that when what they want is a rep cockpit. The real seam is one-off versus standing: "build our TAM" is cargo-gtm when the user wants a list today and a cookbook when they want a pipeline that keeps producing it. The words are identical, so both skills now say so explicitly and the description carries the outcome vocabulary. What a cookbook is. Both pointers called them "scaffoldable outcome templates", which invites copy-and-fill. The code is a worked example: each cookbook declares what may be reshaped, what must hold, and what must be answered, and installing one means adapting it until it is this company's code. Also carries the --force warning into both, because the damage is silent: `cdk init --force` into a non-empty directory replaces the project's package.json and reverts adapted cookbook code while cargo.state.json survives, so the next plan diffs a live workspace against code nobody wrote. Note: the snapshot includes `variations`, which land in cargo-cookbooks#3. Re-run --refresh once that merges. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Read the menu from SKILL.md frontmatter; leave "install a cookbook" to deploy-cookbook cargo-cookbooks folded cookbook.json into SKILL.md (every reader of the contract is an agent, and agents read markdown), so sync-cookbooks.ts now reads frontmatter (outcome, state, chain) plus `kind` and `requires` from cargo.scaffold.json, and the variations table under "## What you can change". Foundations take their one-liner from the README's first paragraph. No new dependency: the frontmatter is validated as real YAML in its own repo, so four scalar fields do not need a parser here. Two corrections to the previous commit on this branch: - cargo-cdk's description carried "install a cookbook" verbatim, which is deploy-cookbook's own trigger. With both installed the tie went to cargo-cdk, so the skill that merely points at cookbooks beat the one that installs them. cargo-cdk now carries discovery vocabulary ("is there a cookbook for this", "start from a cookbook") and leaves the install phrase to the skill that does the work. - `cargo-ai manifest add` is the way into an existing project (copy-in, existing files kept, every file hashed in manifest.json). It replaces the "scaffold to a temp dir and copy across" advice, which was a workaround for a command that already existed. skills-lint learns the `manifest` domain, shipped in 1.0.57. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * List every scaffoldable cookbook in the menu, not only the ones with a skill The menu hid 16 of 20 cookbooks because they had no SKILL.md yet. The old pointer sent the agent to a README that listed all 20, so this was a regression: a user asking for contact sourcing was told nothing existed while the code sat there and cdk init --from scaffolded it fine. Every outcome is listed now; the Skill column says whether the adaptation contract exists or the README and PLACEHOLDER comments are the interview. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * cargo-cdk: no session reload needed to reach a cookbook skill mid-task A cargo-skills user who asks for a cookbook outcome is one hop from the skill that installs it. Say exactly what to do in that hop: skills add, then read the two SKILL.md files directly; or `npx skills use` to read one without installing. And name the --dir default, which lands a cookbook in infra/ where a plain CDK project imports nothing from. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * menu: manifest add, not scaffold-to-temp, into an existing project Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * regenerate cargo-cdk metadata Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * menu: read state from the cookbook manifest, not from customer-facing frontmatter cargo-cookbooks moved state, approval and chain out of SKILL.md frontmatter into cargo.scaffold.json, because SKILL.md is what a customer installs and Cargo's bookkeeping is not their concern. The menu now takes everything from the manifest and each README's first paragraph; SKILL.md contributes only the variations table. One code path for foundations, unconverted and converted outcomes alike. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * regenerate metadata Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Point at gtm-skills' catalog.json: the CDK examples are skills there now cargo-cookbooks merged into gtm-skills as flat, self-contained skills, and that repo publishes one validated catalog.json. This script fetches it and parses no markdown; the menu lists the skills that carry a CDK example and the folders whose skill is not written yet. cargo-cdk and the router say what changed in the model: the agent copies the folder in and reconciles it, there is no scaffolder, and the shell comes from cdk init --template blank. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * menu: gtm-skills keeps only skills at the root, so no 'no skill yet' section Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Address review: GTM_SKILLS_ROOT accepts a dir or the catalog file; routing cases for cargo-cdk's new vocabulary Bugbot's third finding (foundation variations dropped from the menu) is moot: gtm-skills dissolved base-gtm and crm-sync into the skills that used them, so there are no foundations and nothing to render. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Name things what they are: CDK examples, not cookbooks The script, snapshot, reference file and type were named after the repo the examples came from before the merge. That repo is being archived and the examples are skills in gtm-skills now, so the names follow: sync-cdk-examples, .github/data/cdk-examples.json, references/cdk-examples.md, CdkExample. The llms.txt link to cargo-cookbooks goes; the linter's note that the CLI's manifest domain includes 'manifest add' goes too, ahead of its removal. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * cookbook is the name of the kind: rename the menu, snapshot and sync back to it gtm-skills#12 fixes metadata.source as one-off | cookbook. So the menu of gtm-skills that carry a worked CDK example is the cookbook menu, and the file, snapshot, script and type are named for the kind, not for the repo they once came from. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
e262b64780 |
Document the ASCII diagram format, and route "show me the workflow" here (#108)
* Document the ASCII diagram format, and route "show me the workflow" here CLI 1.0.56 adds `--format ascii` to `node diagram`, so the command now renders a drawing a person can read in a terminal as well as a Mermaid block to paste somewhere that renders it. Two gaps went with it. **Format selection.** `references/node-diagram.md` gains a `## The ASCII format` section: a table that picks the format by where the output is going, the legend (detour `├──┐…├──┘` vs fork `┌──┴──┐`, `┆ on failure`, `💳`, `◀━`, `↑`), and the width limit. Its closing section used to say "don't replace the diagram with an ASCII drawing; it wastes context and reads worse than the sentence" — true when the only option was hand-drawing one, wrong now that the CLI emits a real drawing, so it becomes the fallback for CLIs older than 1.0.56. The flag table, the JSON shape, and the "Show the graph, don't describe it" callout all carry `--format` now. **Routing.** The reference documented the command well, but the description carried no visualise vocabulary at all — and the description is the only thing an agent reads before deciding whether to load a skill. Asked to explain a workflow, a session never loaded this skill: it fell back to `workflow list` / `release get-deployed` and reconstructed the routing by hand, which walks `childrenUuids` only, drops every `fallbackChildUuid` hop, and describes a workflow that survives a provider outage as one that dies on it. The description now leads with "or show what it would run" and carries "show me the workflow", "what does this tool do", "visualize this play", "draw the graph", "explain this workflow". `cargo-diagnostics` gains a fourth evidence surface — the graph a run executed with the failing node marked — and the rule that a step which looks skipped is often one the run reached via a fallback edge, which is a different diagnosis with a different fix. Six evals pin the split: drawing a healthy graph is orchestration, drawing a run that broke is diagnostics. Core tier 86/86, linter clean. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Refresh the ASCII sample against the catalog naming The reference still showed `Code` and `AI agent`, which the platform calls JavaScript and Agent — the CLI now takes both from the native-integration catalog rather than from a map of its own, so the sample had drifted. Regenerated from the renderer, and the prose says where the names come from. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Note that the ASCII format draws loop bodies Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Remove an accidentally committed worktree pointer A `git add -A` in the previous commit swept in `.claude/worktrees/`, a local scratch worktree, as an embedded repository pointer. It is not part of the skills and clones cannot resolve it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
010ae38779 |
Playbooks for parallel and exa, and a 20x price error in the stage map (#107)
* Playbooks for parallel and exa, and a 20x price error in the stage map Section 11 claims every credits-based provider in the catalog has a playbook. Nine do not: brightData, builtwith, datachimp, exa, openRouter, parallel, proxycurl, sillage and x. This adds the two that matter most for research and leaves the claim to be squared with the other seven separately. Both are worth having because both beat what the recipes currently reach for. parallel.extract reads a known URL for 0.025, half of firecrawl.scrape. parallel.createTask is the only action in the catalog that fills a caller-supplied output schema, and at processor lite it is 0.125 against linkup.instruct at 1. exa.search is the only rung with a document-type category filter and publication-date bounds, which is what makes it worth 0.175 fixed plus 0.025 an item over a 0.05 flat search. Every action, input and price here was read from the live integration catalog rather than from documentation, per the lesson this pack keeps relearning: a capability claim needs the implementation, not the docs index. That is also how the error surfaced. references/stage-action-map.md priced serper.search at 1. It is 0.05, and provider-playbooks/serper.md had it right throughout, so the map was steering agents away from the cheapest search rung by a factor of twenty. alternatives.md carried the same wrong number for serper.searchPlaces. Both corrected, and the correction is stated in the table rather than made silently. The Web research table is rebuilt around the actual decision: known URL means parallel.extract, plain keyword means serper, document-type or date filter means exa, structured output means parallel.createTask at lite. The createTask ladder gets its own table and a warning. processor is required with no default, and the top rung is 60 credits per record, which is more than a full contact waterfall. Co-Authored-By: Auree Aubert <16732193+aureeaubert@users.noreply.github.com> Co-Authored-By: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com> * Ban datachimp in code, and close three of the playbook gaps Two things, both about the same claim: section 11 said every credits-based provider has a playbook, and nine did not. Datachimp is removed everywhere and cannot come back. Aurelien's instruction, 2026-08-15. It appeared in the generated catalog and in two lines of cargo-storage prose. Deleting those would have lasted until the next --refresh, so the removal is enforced in code instead: a DENIED_INTEGRATIONS set filters it out of the catalog on both write and read, and skills-lint fails on the string anywhere in the repo, which is what catches the hand-written half no generator touches. It was also an integration with zero callable actions, so nothing was lost. Three playbooks added, each earning its place on price rather than on coverage. builtwith's getDomainSummary is FREE and answers most stack questions, so the playbook's whole argument is that it runs in front of enrichDomain (1); the current recipes reach straight for a paid rung. sillage's searchLeads is also free and is the only free signal rung in the catalog, which makes it first on any signal question by definition. x is fourteen actions at 0.02, the cheapest signal surface there is, and the playbook spends most of its length on why that is dangerous rather than on how to use it. Three are deliberately not written and the claim now names them instead of overstating. openRouter exposes a model lister and no credits-based actions, so there is nothing to document. proxycurl is excluded on instruction. brightData is excluded because its entire action set is consumer social-platform scraping (Instagram, TikTok, Facebook), which acceptable-use already refuses for person targeting: documenting it as a GTM provider would contradict the gate two files away. Every action, input and price read from the live integration catalog. Co-Authored-By: Auree Aubert <16732193+aureeaubert@users.noreply.github.com> Co-Authored-By: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com> * x: a cost table a validator can read, not a grouping a human can The action list was grouped by input shape, which reads well and parses to nothing. Every other playbook here carries `| action | cost | inputs | use for |` and the downstream validator in getcargohq/gtm-skills asserts a skill's quoted price against that column, so a skill calling any x action would have failed with "not in that provider's cost table" and sent someone hunting for a missing price rather than a missing table shape. The four engagement-list actions keep their warning in the Use for column instead of only in the anti-patterns, since that column is what a reader scans. Co-Authored-By: Auree Aubert <16732193+aureeaubert@users.noreply.github.com> Co-Authored-By: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com> * Install the whole bundle by default, and stop hand-counting installs skills.sh counts per skill, and one `skills add` sends a single event carrying every skill it installed. So the command in the README decides how many counters a real install moves. `--all` is now the documented form: it is shorthand for `--skill '*' --agent '*' -y` and behaves the same in a terminal, in CI, and inside an agent, where a bare add would drop into an interactive picker. Two stale hand-maintained facts removed rather than corrected, which is the same call this repo made about "sixteen skills" in the CLI help. The install total read "installed 54,885 times". The live figure is 58,245 across the seventeen skills. A number in prose that only moves when somebody remembers to move it will be wrong again next week, and this one is a public claim about traction, which is the worst kind to be casually wrong about. The gtm-skills section listed twelve skills by name. That repo has grown past twelve, so the list now points at its README instead: a hand-maintained copy of someone else's list is a copy that goes stale. Co-Authored-By: Auree Aubert <16732193+aureeaubert@users.noreply.github.com> Co-Authored-By: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com> --------- Co-authored-by: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com> Co-authored-by: Auree Aubert <16732193+aureeaubert@users.noreply.github.com> |
||
|
|
cda2ee39cb |
CI: bump actions/checkout from 4.4.0 to 7.0.1 (#103)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.4.0 to 7.0.1. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/11d5960a326750d5838078e36cf38b85af677262...3d3c42e5aac5ba805825da76410c181273ba90b1) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
842e9940ba |
CI: bump actions/setup-node from 4.4.0 to 7.0.0 (#106)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4.4.0 to 7.0.0. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/49933ea5288caeca8642d1e84afbd3f7d6820020...820762786026740c76f36085b0efc47a31fe5020) --- updated-dependencies: - dependency-name: actions/setup-node dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
144be3ea00 |
CI: bump actions/download-artifact from 4.3.0 to 8.0.1 (#105)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4.3.0 to 8.0.1. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/d3f86a106a0bac45b974a628896c90dbdf5c8093...3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: 8.0.1 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
08ec7127de |
CI: bump actions/upload-artifact from 4.6.2 to 7.0.1 (#104)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.2 to 7.0.1. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/ea165f8d65b6e75b540449e92b4886f43607fa02...043fb46d1a93c77aae656e7c1c64a875d1fc6a0a) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
6683645b00 |
CI: run the HOL AI plugin scanner (#102)
* CI: run the HOL AI plugin scanner hashgraph-online/awesome-ai-plugins requires every listed plugin's source repo to invoke `ai-plugin-scanner-action` on push/pull_request before the listing PR can merge (getcargohq/cargo-skills#83 → their PR #72). Pinned to a full commit SHA instead of the floating `v1` tag, with a read-only token and no secrets in scope, so a third-party action in our workflow surface can't reach anything it shouldn't. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * CI: publish the scanner report when the scan fails The action's built-in summary step is `if: success()`, so a failing scan prints counts and no findings. Render markdown to a file and cat it into the step summary unconditionally. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * CI: tee the scanner report to the job log as well Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * CI: clear the plugin scanner's 80-point / no-high gate The scanner job this PR added failed on its first run: 71/100 against a `min_score` of 80, one critical finding and one high. The awesome-ai-plugins contribution gate re-scans this repo with the same two thresholds, so the findings had to be fixed rather than configured around. Now 92/100 (A), zero critical, zero high. - Pin every `uses:` in .github/workflows/ to a full commit SHA, and add .github/dependabot.yml so the pins move weekly instead of never. - Add SECURITY.md: private reporting via the Security tab, and an explicit boundary between this bundle and the cargo-ai CLI / Cargo platform. - Stop inlining `curl … install.sh` in cargo/SKILL.md. The command now lives only in README.md, where a human runs it; the router keeps the guidance (never run it on the user's behalf) and points there. - Use execFileSync, not execSync, for `npm root -g` in the QA script library — no shell to interpret a command string. Windows gets the npm.cmd shim. - Fill in repository/license/keywords in .codex-plugin/plugin.json, a category on the .agents marketplace entry, and add .codexignore. - Set write_step_summary: false on the scanner action and publish the report ourselves, so it lands once whether the gate passes or fails. Two medium findings are left standing and documented in CHANGELOG.md: the `anthropic` provider slug in cargo-gtm's description (correct, and CI-synced with the CLI) and `fetch(` in the run-output downloader (the point of the function). Neither is a gate failure. Co-Authored-By: Auree Aubert <16732193+aureeaubert@users.noreply.github.com> Co-Authored-By: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com> Co-authored-by: Auree Aubert <16732193+aureeaubert@users.noreply.github.com> |
||
|
|
8b36982db4 |
cargo-orchestration 1.7.0: draw the workflow (#100)
* cargo-orchestration 1.7.0: draw the workflow
Nothing in the bundle told an agent to show a node graph as a picture. The
only nudge was one line in interaction.md — "a compact node-flow sketch or
table beats prose" — which left the format to the model, so the plan gate
asked users to approve a graph they had to reconstruct from prose. Every
surface these skills print into renders Mermaid.
- references/node-diagram.md: when to draw one (plan gate, "what does this
play do", trace reporting), when not to, the shape/edge mapping per node
kind, cost marking, and the rules that make a diagram true.
- scripts/workflow-to-mermaid.ts: zero-dep TS (Node >= 22.18, 6 fixture
cases) taking release get / get-draft / template get / an ad-hoc run get /
a raw node array. Flags: --title, --direction, --paid, --highlight.
- Two doc defects found against a live workspace: release get's documented
nodes[] was a {uuid, slug, name} summary of the full graph it actually
returns, and run get carries nodes XOR releaseUuid depending on whether
the run came from a deployed release.
- Node slugs are not unique within a release (six `variables` in one shipped
waterfall), so anything walking the graph keys on uuid. Recorded as router
gotchas, with the knock-on for {{nodes.<slug>...}} ambiguity.
- Call sites wired: plan gate and presenting defaults, router rules,
nodes.md, the diagnostics trace runbook, and cdk plan.
- CI runs fixtures for every cargo-*/scripts/*.ts, not only cargo-gtm's.
Verified against CLI 1.0.52: every diagram in the reference is script output
from a real release, and each parses under mermaid 11.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Move the diagram generator into the CLI
`cargo-ai orchestration node diagram` replaces the skill script the reference
was prototyped against. It belongs next to `node validate` — same input, same
free/runs-nothing character — and the sequence now reads validate → diagram →
deploy without leaving the CLI.
- scripts/workflow-to-mermaid.ts and its fixtures deleted; the CI fixture glob
goes back to cargo-gtm/scripts/*.ts.
- node-diagram.md documents the command: one source per call (--nodes / --file
/ --workflow-uuid / --draft / --release-uuid / --run-uuid), the JSON shape,
and reading `warnings` out loud rather than drawing over a broken graph.
- --run-uuid absorbs the nodes-XOR-releaseUuid split, so the diagnostics
runbook no longer has to explain which kind of run it was handed.
- Requires CLI >= 1.0.54 (getcargohq/cargo#5580); the cli-version pin moves in
the follow-up that ships with that release.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Refresh skill-metadata content hashes after rebase
The rebase onto main took both sides of the version conflicts in cargo/SKILL.md
and cargo-orchestration/SKILL.md (this branch's 1.20.0 / 1.7.0, which stay ahead
of main's 1.19.2 / 1.6.3), which left the recorded contentHash in the two
skill-metadata.json files stale. Regenerated with skills-metadata.mjs --write;
skills-lint is back to 0 errors.
Co-Authored-By: Auree Aubert <16732193+aureeaubert@users.noreply.github.com>
Co-Authored-By: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com>
Co-authored-by: Auree Aubert <16732193+aureeaubert@users.noreply.github.com>
|
||
|
|
7f5582595a |
cargo-gtm 1.14.0: design custom datapoints, don't just fill them (#99)
* cargo-gtm 1.14.0: design custom datapoints, don't just fill them Every recipe in the pack assumed the field was already named: source-planning sources one field you asked for, icp-discovery needs closed deals to mine. Nothing covered the blank page — "what should we even be collecting?" — which is where the GTM conversation starts, and which a model will answer with ten plausible attributes, four of which have no obtainable source at any price. New recipes/custom-datapoints.md: research the seller from fetched pages rather than model recall, draft candidates against the discriminator test, gate each one on a real catalog action + credit cost + probed hit rate, present a costed shortlist with the cut list and the full fan-out arithmetic, then wire the survivors into columns, scoring, a segment, and a refresh cadence. The gate is the point — a candidate with no action slug is a research note, and saying so beats padding to ten. Attribute vs signal, mechanically: in Cargo a live signal is a tracked column diff, so the recipe ends by putting the signal-bearing attributes into --tracking-column-slugs at segment creation and reading the delta feed — the step whose omission leaves updatedRecordsCount at 0 forever. Two prompts in the data-extraction shard: custom-attribute-extraction (one defined attribute from page text, with a confidence band and a verbatim evidence quote — Unknown is a first-class answer, because an unsupported value in a scoring column is a decision made on noise) and technology-adoption-state (mixed evidence to individual_usage … company_standard, with a hard rule that one job posting never establishes company-wide adoption). First-party fields — product usage, activation, billing, visitor sessions — are called out as structurally unavailable for net-new accounts and routed to account-expansion instead of quietly ranking customers above prospects. Routed from the router table, the cargo-gtm recipe table, the README and llms.txt; cargo 1.19.1 and the three plugin manifests follow. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Fix Bugbot findings on the custom-datapoints recipe Four issues, all verified against the pack's own docs rather than taken at face value. - **`linkup.instruct` payload was invalid.** Step 2 passed `prompt` and no `depth`. Per `provider-playbooks/linkup.md`, `instruct` takes `q` plus a required `depth`, and a sourced answer needs `outputType: "sourcedAnswer"`. As written the seller-research call — the step the recipe says determines everything after it — fails. - **`change fetch --change-uuid` does not exist.** The flag is `--uuid` (the change UUID from `change list`), as `cargo-segmentation` documents in three places. The delta read 400s as written. - **The signal-watch filter matched every record.** `conditions` sat beside an empty `groups`, and `{"conjonction":"and","groups":[]}` is the match-everything filter — so tracking and refresh spend would have run over the whole model instead of the ICP. Conditions now nest inside a group, in the `{kind, columnSlug, operator, values}` shape the sibling recipes use. - **The `estimated` confidence band was unreachable.** The prompt listed it, then told the model to return `unknown` for anything below the `inferred` bar — dropping exactly the calculated values Step 7 tells agents to store with a companion confidence column. `confirmed`, `inferred`, and `estimated` are now all reportable, with `estimated` scoped to arithmetic on figures actually in the text. Also rebased onto main, which shipped router 1.19.1 in #97, so this moves to **1.19.2** across `cargo/SKILL.md` and the three plugin manifests. skills-lint 0/0 · skills-metadata --write clean · sync-trigger-slugs --check up to date · routing-eval 81/81 core, all gating evals pass. Co-Authored-By: Auree Aubert <16732193+aureeaubert@users.noreply.github.com> Co-Authored-By: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com> * Fix second Bugbot round: ID prereqs, billing shape, shortlist math, snitcher Four more findings on the recipe's pre-existing content. All four hold up against the provider playbooks. - **`salesNavigator.find*` ID prerequisite was missing.** All four `find*` actions key on a LinkedIn `companyId`, not a domain (playbook, Inputs column). The recipe carefully amortized `cargo.matchBusiness` and said nothing about the equivalent fee here, so probes fail on domain-only lists and every shortlist under-quotes. Now a named cost mechanic alongside `matchBusiness`, at 0.05/account via `searchAccounts`. - **"`salesNavigator.*` bills per returned row" was wrong for the actions this recipe leads with.** Per-row billing is the search/extract family; `findEmployeesDistribution` and `findCompanyMetrics` are flat 0.25 per account. Split the two families explicitly. - **The Step 6 approval example did not reconcile.** It quoted ~7,400 credits, then claimed dropping two 1-credit attributes over 4,100 accounts saved ~4,200. The table also stopped at row 4 with an ellipsis, so the total could not be checked against it. All six rows plus both ID prereqs are now explicit and every figure is derived: 3.55/account → ~14,600 full, ~4,300 cheaper cut, ~3,200 narrow cut. The cut now makes the point the old numbers obscured — dropping both cargo enrichments also drops the 0.50 match, so the saving is 2.50/account, not 2.00. Step 8's refresh figure is rederived from the same table (~5,100/month for the monthly-cadence fields). - **Snitcher was filed as unavailable for net-new.** Visitor ID surfaces companies browsing the seller's site — mostly cold. The pack's own playbook calls them "the warmest cold segment there is" and files them in the SIGNAL stage, routed to outreach-activation, not expansion. It belongs in a net-new schema; what disqualifies it from the sourced shortlist is that it is arrival-driven, not that the prospect never logged in. Reframed on that axis, with the `fetchOrganisations` 3/company recurring cost called out. Arithmetic verified numerically, not by eye. skills-lint 0/0 · routing-eval 81/81 core · llms.txt regenerates clean. Co-Authored-By: Auree Aubert <16732193+aureeaubert@users.noreply.github.com> Co-Authored-By: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com> * Fix row-billed pricing for theirStack across the gate and the shortlist Bugbot's third round, one finding, and it lands on an inconsistency the previous commit introduced: that commit sharpened "search-shaped actions bill per returned row" while leaving the hiring-intent row priced at a flat 0.5/account. `cost-discipline.md` uses this exact case as its worked example of an estimate missing by 2x ("theirStack billed per returned job posting, and 12 companies had >5 postings each"), so the recipe was demonstrating the failure its own reference warns about. - **Gate table** now prices both theirStack rows as `unit x rows`, with `limit` named as the cap. `searchTechnologies` had the same defect — cost-discipline §4 is explicit that search actions bill on returned rows, not matched totals, so it is not specific to `searchJobs`. - **Step 5** measures rows-per-account as a recorded output, median *and* max, since the max is what `limit` has to cap. Without that multiplier a per-row price gets copied into the shortlist as if it were per-account, which is the whole mechanism of this bug. - **Step 6** prices #5 as 0.5 x `limit: 3` = 1.50, states the probe's median (3) and max (9), and notes that uncapped the top decile costs 4.50. Every downstream figure rederived: 4.55/account, ~18,700 full, ~8,400 cheaper cut, ~4,100 narrow, ~16,400 all-six monthly. - **Step 8** adds the annual arithmetic on the fastest field, which is where row billing actually hurts: #5 weekly over the full list is ~6,200/week and ~320,000/year, more than the first fill of everything else combined. The fix is a narrower audience, not a lower price. - **Probe budget** moved 10-40 -> 30-80; the Step 6 schema alone probes at ~46, so the old range was unreachable. - Noted the provider inversion this exposes: theirStack at 0.5/row only undercuts cargo's flat-1 technographics while an account returns one row. Compare per-account totals, not unit prices — which is also why Step 6 picks the flat action for #4. All 16 figures verified numerically against the table. skills-lint 0/0 · routing-eval 81/81 core. Co-Authored-By: Auree Aubert <16732193+aureeaubert@users.noreply.github.com> Co-Authored-By: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com> * Rebase onto main (#101) and true up the changelog entry `main` picked up #101 (the Clay migration recipe). Conflicts were all in generated files — `llms.txt` and two `skill-metadata.json` — resolved by re-running the generators rather than hand-merging, then verified: both recipes appear exactly once, 92 metadata entries, zero duplicates, and a regenerate-after produces no diff. Two corrections to the changelog entry while here: - **The snitcher bullet still described the pre-fix behavior**, calling visitor sessions structurally unavailable for net-new and routing them to expansion — the exact claim the round-2 review corrected in the recipe. The entry now says what the recipe says. - **Added the costing bullet**, since per-account vs per-row pricing and the two ID prerequisites are now a substantive part of what the recipe teaches and were not mentioned at all. Also noted that this bump publishes #101's recipe: that PR added `clay-to-cargo.md` without moving `cargo-gtm` off 1.13.0, so 1.14.0 is the release that ships it. Drop that line if a separate bump is planned. Router stays at 1.19.2 — #101 did not touch it. All 15 figures in the recipe re-verified numerically post-rebase. skills-lint 0/0 · routing-eval 81/81 core · sync-trigger-slugs up to date. Co-Authored-By: Auree Aubert <16732193+aureeaubert@users.noreply.github.com> Co-Authored-By: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com> Co-authored-by: Auree Aubert <16732193+aureeaubert@users.noreply.github.com> |
||
|
|
1fb253e0a9 |
Migrate the configuration, not the CSV: a Clay recipe (#101)
`import-gtm-data.md` closes by saying it deliberately carries no per-tool mappings, because source tools change their internals and CSV export is universal. That reasoning holds for every source except the one this product is most often replacing, and the universal advice actively costs accuracy there: a CSV export destroys the per-row cost, the waterfall order and the run conditions, which are exactly what a rebuild depends on. The exception is argued in both files rather than left to be discovered as a contradiction. The recipe leads with extraction because that decides everything after it. A Clay CSV says a column was filled; it does not say which provider filled it, in what order, or under which condition, and none of that is recoverable from the results. Three paths in descending fidelity, and a run on the weakest one has to say so out loud. Then: the column-family map across sourcing, contact data, company data and the non-enrichment columns; the four Clay concepts that do not map one to one (waterfalls, run conditions, auto-update, partial runs), each invisible in an export; and a parity check whose sample deliberately includes rows Clay FAILED to fill, since a sample of Clay's wins measures nothing. Two claims that stop this reading as a sales document. On an email disagreement, the verified value wins rather than the source. And a Clay credit is never compared to a Cargo credit: they are different units, so the comparison is what one sample cost end to end on each side. All twenty action slugs and prices check against the provider playbooks. The maintenance rule is the pack's: the playbook wins, and an unmapped Clay column is reported as unmapped rather than guessed at. Co-authored-by: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com> Co-authored-by: Auree Aubert <16732193+aureeaubert@users.noreply.github.com> |
||
|
|
69f8642cb5 |
cargo-analytics 1.5.0: describe what the run exports actually return (#98)
* cargo-analytics 1.5.0: describe what the run exports actually return
`run download` was documented as returning "each run as a JSON object with
status, timing, executions, and runContext.<nodeSlug> containing per-node
outputs". It returns a signed URL to a gzipped CSV with one column per node
slug holding that execution's `title` — the truncated summary the diagnostics
runbooks call "never evidence". No runContext, no executions, not JSON.
- Rewrites the run download section around the real columns, with a warning
to treat it as a status board across runs, not as node output.
- Corrects run download-outputs: --output-node-slug is optional (falls back to
the last executed node), each row is input + output, and without --limit the
file covers every matching run.
- Adds a section answering "can I get runContext for several runs at once" —
you can't: it is a per-run S3 object and run get is the only command that
hydrates it. Orchestration SQL is ruled out explicitly.
- Marks --is-finished broken in the six snippets that taught it; it returns
400 unrecognized_keys on all four run commands. Replaced with
--statuses success,error.
- Fixes the partial-retry pattern in polling.md, which piped run download
stdout into jq '.recordId' — impossible against a signed URL to a gzipped
CSV whose column is _record_id.
- response-shapes.md gains entries for both run exports and corrects batch
download, which also returns {"url": …} rather than streaming to stdout.
- Adds the 500 case to analytics troubleshooting.
Verified against CLI 1.0.52 and the backend source. Underlying defects are
fixed in getcargohq/cargo#5579; these docs describe today's behavior.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Drop the --is-finished caveats; the fix is a backend deploy
The caveats dated the docs against a deploy the bundle can't observe, and my
stated reason for them was wrong: cargo#5579 changes no CLI code for
isFinished (0 occurrences in its packages/cli diff) — the flag was always
sent, the API route schemas rejected it. So the fix lands when the backend
deploys, independent of the cli-version pin.
Examples keep --statuses success,error, which expresses the same filter and
is correct before and after that deploy, so nothing here expires. The specific
400 is replaced by a generic `400 unrecognized_keys` troubleshooting row that
stays useful whatever the flag, and points at report create.
Also drops "until the fix ships" from the 500 row, for the same reason.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Restore --is-finished: it is wider than success+error
Swapping the flag for `--statuses success,error` was semantically wrong, not
just verbose. `isFinished` maps to `finished_at IS NOT NULL`, and cancelled
(cancelRuns.ts:94) and skipped (launchRuns.ts:151) runs stamp finishedAt too.
Skipped is routine — checkToSkipRuns marks records skipped as ordinary dedupe
behaviour — so the substitution would silently under-report on any play that
skips records.
exports.md and run-analytics.md revert to their original content: their
--is-finished examples were correct all along. The run download section now
shows both forms with a note that they are not interchangeable.
The flag still 400s until cargo#5579 reaches production, which is a backend
deploy independent of the CLI release; the generic 400 unrecognized_keys row
in troubleshooting.md covers that window without dating the docs.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
0d3981a8b7 |
cargo-diagnostics 1.1.0: find the run when all you have is a symptom (#97)
* cargo-diagnostics 1.1.0: find the run when all you have is a symptom `orchestration run list` requires --workflow-uuid and has no "most recent run" form, and run-trace.md § 0 — the one place documenting how to find a run — already assumed a workflow_uuid in hand. Asked to "look at the last run", an agent has nothing to call and reports the node inputs/outputs as inaccessible. They aren't: orchestration SQL over `runs` takes no filter. - run-trace.md § 0 rewritten as a discovery ladder ordered by what the user hands you: no UUID (unfiltered `runs`), a company/domain (record_title ILIKE), a play by name (play list -> workflowUuid -> filter). - Explicit instruction not to give up at `run list`, in the runbook and in the diagnostics routing section. - Error rows for the discovery step, both hit while verifying against CLI 1.0.52: `SELECT * FROM runs` exceeds the 50-column read cap (51 columns), and `runs` has no play_uuid / name / trigger-source column. - States what the UI editor does not change: CLI, scheduled, and UI-triggered runs all land in `runs`. One that doesn't is a bug to report. - Same caveat at the other two doors: cargo-orchestration troubleshooting and two rows in the router's gotchas table. Every documented query was run against CLI 1.0.52 before being written down. No CLI change needed — the surfaces existed, they just weren't reachable from the question a user asks. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Bump the Codex and Cursor manifests, regenerate skill metadata The plugin version mirrors the router's, and .claude-plugin was the only one of the three I bumped. Regenerates the three stale skill-metadata.json files alongside it. skills-lint is clean locally. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
4f9d4aa1d3 |
cargo-connection 1.3.0: document integration list --slugs (#96)
The CLI now filters with --slugs instead of --slug; keep the skill examples in sync. Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
4e92cafb2c |
cargo-billing 1.1.0: document adding a card (#94)
An agent that hit the free-tier ceiling had nothing to do about it — the skill covered reading the balance and nothing about paying. update-payment-method now takes card details directly and tokenizes them against Stripe from the caller machine, so document the three input modes, why --card-stdin beats the flags, and the instruction never to invent a card number. Declines are documented as a normal outcome rather than an error path. On the spend-limited virtual cards agents are increasingly issued, declineCode is the difference between "ask the cardholder to raise the budget" and "wrong card", and the agent can only tell them apart by reading it. Requires @cargo-ai/cli >= 1.0.51. cargo/cli-version is still 1.0.47, so this must not publish before the pin moves — the documented flags do not exist in the CLI an agent would install today. The pin is left untouched here: moving it is the release pipeline PR, and the skill marks it read-only. Co-authored-by: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com> Co-authored-by: Auree Aubert <16732193+aureeaubert@users.noreply.github.com> |
||
|
|
8d45b172df |
Stop calling it email finding in the plugin manifests (#95)
"Email finding" is the phrasing that drew the OpenAI spam rejection on cargo-gtm, and it sat unchanged in the three channel plugin descriptions and the root manifest blurb -- the copy a reviewer or a user reads before anything else. It also misdescribes the product: the CLI queries licensed data providers and verifies what comes back, which is the part that makes the difference to whoever is deciding whether this is a scraper. Channel descriptions now say "contact enrichment and verification from licensed data providers" and name lead scoring, replacing "enrichment, email finding". The root manifest picks up the blurb merged in #91, so all five manifests finally describe the same product. No version bump: marketplace copy only, no skill content, and the OpenAI archive does not contain these files -- verified by diffing an archive built with and without this change (identical, only zip mtimes differ). Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
d0458d0b8a |
Version the acceptable-use work for an OpenAI resubmission (#93)
The directory is a submission-time snapshot — published skills do not update live — so getting the gates in front of a reviewer needs a version to claim, not just a merged branch. cargo-gtm goes to 1.13.0: a new mandatory reference and new sections, no command or response-shape changes, which is MINOR under the policy at the top of the changelog. The router goes to 1.19.0 and carries the gate in its own cargo-gtm critical-rules block, so an agent that stops at the router still learns that basis, suppression, and relevance are blocking — the router is what gets read first, and a rule only in the leaf skill is a rule an agent can route around. The three plugin manifests mirror the router by lint rule. Root plugin.json stays at 1.17.1: different channel, not linted against the router, and not read by the package builder. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
cf24d5aebf |
Describe what the marketplaces actually ship (#91)
Every manifest carried the same two placeholders: "Official Cargo plugin for <target>" said nothing, and the plugin blurb listed subsystem names rather than what a user gets. The plugin description now leads with the count and the work, and says where contact data comes from -- licensed providers -- because "sourcing, enrichment" reads as scraping to anyone who has not used the product. Each marketplace description now names what that channel adds over a plain skills install, which differs per target: Claude Code gets session lifecycle hooks, Codex and Cursor get the approval hook only. Identifiers, sources, displayName and the Codex policy block are untouched -- string replacement rather than a JSON round-trip, so the diff is six lines and not a reformat. Rebuilt on main after the original commit landed empty of these edits: a stray `git reset --hard` discarded the working tree, so 5691f12 captured only an untracked dist/cargo-skills-codex.zip. That 624 KB build artifact is dropped here -- dist/ is gitignored on main, the archive is built by .github/scripts/build-codex-package.mjs and attached to a release by CI, and it has no business in history. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
07e792124c |
Add a reproducible build for the OpenAI directory package (#90)
* Add a reproducible build for the OpenAI directory package
The OpenAI Plugins Directory is the only channel that does not track this
repo. Its docs are explicit: "published plugins do not update those
skills live." It takes a submission-time snapshot, and every change needs
a new version, a fresh review, and a manual publish -- where skills.sh,
ClawHub, the Gemini gallery and the Claude community catalog all follow
main on their own.
So the archive cannot be a hand-assembled zip. This builds it from the
repo, takes the version from .claude-plugin/plugin.json so the upload can
never claim a version the repo does not have, and discovers skills with
the same rule skills-lint uses so the three cannot disagree.
Two deliberate differences from the repo layout, both documented in the
script: skills go under skills/ (OpenAI's convention, not our root
layout), and the Gemini symlinks are dereferenced because symlinks do not
survive a zip reliably. Skills-only, since codex-hooks.json invokes
${CLAUDE_PLUGIN_ROOT} -- a Claude Code variable -- and shipping an
unverified path into review is not worth it.
Verifies the archive rather than the staging dir: manifest at root, one
SKILL.md per repo skill, no symlinks.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Normalise the package for OpenAI's validator
First upload surfaced three rules no other channel enforces:
- interface.shortDescription is required, 240 chars max.
- Skill descriptions cap at 1024. cargo-gtm (1393) and cargo-connection
(1208) exceed it, both because they enumerate every provider and
integration -- which is exactly what makes them route well elsewhere.
- metadata in SKILL.md is rejected outright. Ours carries OpenClaw
install directives, meaningless to OpenAI.
All three are fixed in the package, not the repo, because the repo copies
serve channels that want the fuller form. The two long descriptions are
rewritten by hand rather than truncated -- every trigger phrase kept, the
rosters cut to a sample plus a count -- so no list ends mid-name.
A description that grows past the limit without a rewrite now fails the
build with the reason, instead of shipping into a rejected review. The
archive is re-read after zipping and checked against the validator's own
rules, since that is what actually gets uploaded.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Add the required plugin icon and verify it is square
OpenAI requires interface.composerIcon and interface.logo, both square.
assets/icon.png is the Cargo product mark at 512x512, lifted from the
browser extension where it already ships -- the real brand asset rather
than a new one. The repo's existing assets/logo.svg would have been the
obvious source, but rendering it here only produced a padded, off-centre
bitmap, and a logo that sits wrong in the UI is worse than none.
The build now resolves both asset paths inside the archive and checks the
image is square, because a dangling path or a 1200x630 crop is invisible
from the manifest and costs a review cycle to discover. Verified against
a deliberately non-square image: it fails with the dimensions.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Automate everything up to the upload, and encode the full ruleset
There is no submission API. The portal is the only path and every version
is human-reviewed, so the upload itself cannot be automated. Everything
before it can:
- On a release, CI builds the archive and attaches it, so publishing is
"download the asset, drop it in the portal" rather than "find whoever
built the zip last time".
- On a PR touching skills, assets or the builder, the same build runs,
so a change that would fail OpenAI's validator fails in CI instead of
months later in a review cycle.
Also encodes the published error catalogue. Two of our values would have
failed the final stage after passing the uploader, because the two tiers
disagree: shortDescription is 240 chars at upload but 30 in the directory
(ours was 201), and displayName drops from 80 to 30. LIMITS targets the
stricter tier throughout, plus name/version/URL shape, skill identity
length, archive entry count and path rules, and icon bounds.
The runner shims sips - scriptable image processing system.
This tool is used to query or modify raster image files and ColorSync ICC profiles.
Its functionality can also be used through the "Image Events" AppleScript suite.
Usages:
sips [image-functions] imagefile ...
sips [profile-functions] profile ...
Profile query functions:
-g, --getProperty key
-X, --extractTag tag tagFile
--verify
-1, --oneLine
Image query functions:
-g, --getProperty key
-x, --extractProfile profile
-1, --oneLine
Profile modification functions:
-s, --setProperty key value
-d, --deleteProperty key
--deleteTag tag
--copyTag srcTag dstTag
--loadTag tag tagFile
--repair
-o, --out file-or-directory
Image modification functions:
-s, --setProperty key value
-d, --deleteProperty key
-e, --embedProfile profile
-E, --embedProfileIfNone profile
-m, --matchTo profile
-M, --matchToWithIntent profile intent
--deleteColorManagementProperties
-r, --rotate degreesCW
-f, --flip horizontal|vertical
-c, --cropToHeightWidth pixelsH pixelsW
--cropOffset offsetY offsetH
-p, --padToHeightWidth pixelsH pixelsW
--padColor hexcolor
-z, --resampleHeightWidth pixelsH pixelsW
--resampleWidth pixelsW
--resampleHeight pixelsH
-Z, --resampleHeightWidthMax pixelsWH
-i, --addIcon
--optimizeColorForSharing
-o, --out file-or-directory
-j, --js file
Other functions:
--debug Enable debugging output
-h, --help Show help
-H, --helpProperties Show help for properties
--man Generate man pages
-v, --version Show the version
--formats Show the read/write formats with ImageMagick -- the icon check is the only
macOS-specific part, and that beats paying for a macOS runner to measure
two PNGs.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Detect packaged symlinks from zipinfo modes, not a listing that never shows them
The post-zip guard tested `unzip -l` output for ` -> `, but that listing
prints only length, date, and name. No zipinfo format prints ` -> target`
either, so the check could never fire and a packaged symlink would have
shipped despite being treated as a hard upload invariant.
Read zipinfo's Unix mode column instead, where a symlink reads
`lrwxrwxrwx`, and name the offending entries in the error. Require a mode
for every entry so an archive whose types cannot be read fails loudly
rather than passing by default.
Co-authored-by: Auree Aubert <aureeaubert@users.noreply.github.com>
* Answer the spam rejection with real gates, not a reworded description (#92)
OpenAI rejected cargo-gtm under "Spam mass abuse". The description was the
whole case against it: "find emails, phones and LinkedIn URLs", "write cold
emails", "build me a list of" — contact harvesting plus bulk cold mail, with
nothing in 8,800 lines about consent, suppression, or volume. Opening the
archive confirmed it; the outreach guide and prompt library are cold-email
prompts end to end.
Rewording alone would be dressing it up, so this does both halves.
references/acceptable-use.md is the substantive half — a peer of
cost-discipline.md at the same mandatory tier. Hard refusals (undifferentiated
fan-out, consumer targeting, lists with no stated origin, contacting a
suppressed record, filter and identity evasion, auto-dialing, batch-blasting
LinkedIn engagement actions), three free blocking checks before any outreach
step (basis, suppression, relevance), what drafted copy must carry, and the
data-hygiene obligations that follow a person out of the workspace.
It is wired into the path an agent actually walks rather than filed next to
it: a mandatory section above Bootstrap, the outreach row of the routing
table, a gate at the top of the outreach guide, and a "before you start" block
in outreach-activation that subtracts suppression before enrichment — which
is also cheaper. The opener prompt now returns NULL when no signal justifies
writing to that person.
The description half stays honest. It leads with B2B, licensed providers, and
the gates, and says the pack sends nothing itself. Every routing-eval trigger
survives except two rewordings ("write cold emails", "find emails for these"),
so evals/routing.jsonl line 14 is worth re-running before the next upload.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Auree Aubert <aureeaubert@users.noreply.github.com>
|
||
|
|
84a9a94f4f |
Name the pack Cargo Skills in the README title (#89)
We were shipping three names: "Cargo" in every plugin manifest and marketplace.json, "Cargo Skills" in the CLI's npm README, and "Cargo Agent Skills" here. Three names build recall for none. Settling on two, deliberately: "Cargo" in-product, where the install is `cargo@cargo` and context disambiguates, and "Cargo Skills" everywhere external. The external name matches the repo slug that renders beside it in every listing, and it avoids the collision a bare "Cargo" has with Rust's package manager -- searching a 2,281-plugin registry for "cargo" returns only Rust tooling. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
68d854b2b1 |
Document Hermes Agent support and group the skills for repo pages (#87)
Hermes reads the same SKILL.md standard and already installs these skills unchanged -- verified: `npx skills add getcargohq/cargo-skills --agent hermes-agent` copies all 17 into .hermes/skills/ with zero broken cross-references. Nothing in the repo said so. - README: a Hermes section with the three working install paths, the tap caveat (our skills sit at the repo root, not under skills/), and what does not carry over -- Hermes pre_tool_call hooks can only block a call, never pre-approve one, so the plugin's approval hook has no equivalent there. - skills.sh.json: groupings per the skills.sh schema. Sections the repo page on skills.sh, and Hermes reads the same file for Skills Hub categorization instead of guessing from tags. All 17 skills grouped exactly once. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
f9238b4ec6 |
Add version, license, and skills.sh badges to the README (#86)
Also state the skills.sh install total in the manual-install section — it is the strongest adoption signal the project has and it appeared nowhere on the repo. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
3438f8222d |
Let the agent ask for a star, never take one (#85)
* Let the agent ask for a star, never take one A star is the user's endorsement, so the skill asks for it instead of running the API call behind their back. Adds an end-of-Job-3 subsection gated on a real deliverable, nothing left failing, and a once-per-machine marker in the CLI's own config dir — with the marker touched on either answer so a "no" is never re-asked. Also corrects the three-jobs note: it claimed hooks cover Job 3, but a hook can print and cannot take a Y/N, so both end-of-session asks belong to the model. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Regenerate cargo skill metadata after the star-ask edit Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
8afa8ecd95 |
Close the ClawHub security-audit documentation gaps (cargo 1.18.2) (#84)
* Close the ClawHub security-audit documentation gaps (cargo 1.18.2) The automated audit of the published bundle returned Review with five findings. Three were real documentation gaps — places where the bundle assumed the reader had the whole thing in context. No behavior changes. - use-cases.md §6 opened on `token create` as a bare numbered step. The "shown once → secrets manager" rule lived in ~10 other files but not this one, so an agent loading only the use-cases reference never saw it. Added token handling, least-privilege scoping, and a confirm-first note on the steps that change who can access the workspace. - README.md and cargo/SKILL.md now say what `curl … install.sh | sh` actually is, how to read it first, and the by-hand equivalent. sessions.md already pointed at the installer source; the two more-read files did not. The router also tells the agent never to run it on the user's behalf without asking. - "Why the pin" now documents cli-version as the reason session-start refresh is not a blind auto-update, tells the agent to surface a global npm install rather than doing it silently, and marks the pin read-only. The other two findings need no change: the flagged egress is the product's own API, and the script-fetching match is the same installer. Plugin manifests bumped in lockstep (linter enforces they mirror the router). skills-lint clean, llms.txt and trigger slugs in sync, routing evals 81/81 core. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Make the audit response survive an actual audit Review of the 1.18.2 branch found the trust paragraph pointing readers at `apps/backend/src/http/routes/install.sh` in `getcargohq/cargo` — a private repo. Every external reader following that gets a 404, from the one paragraph whose entire job is making `curl | sh` auditable. Removed from README.md and cargo/SKILL.md; neither now sends anyone somewhere they cannot go. `curl … | less` followed by `curl … | sh` is two fetches, and the server can serve different bytes to the second, so reading first guarantees nothing about what runs. Replaced with download-once-then-execute in both files. The use-case gate named the wrong steps: step 9 is `folder create` (no access change) and step 2 is `role list` (read-only). The steps that actually grant access are 1 (`token create`) and 3 (`user create`), so an agent was pausing on a benign organizational step and skipping a credential mint. Also: README pointed "below" at the plugin install, which is above it — now an anchor link; and cargo-workspace-management/SKILL.md still inlined the bare pipe-to-shell command the rest of this change set was written to caveat. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
97680e41fe |
Point the pack at the standalone single-job skills (#82)
getcargohq/gtm-skills packages twelve of these outcomes as skills named after the job — find-work-email, find-stakeholders, track-job-changes — for people who want one thing rather than the whole workstation. Nothing here pointed at them, which wasted the best backlink available: this repo is public, indexed, and already crawled, and that one is brand new. Adds the pointer in two places that matter — the README install section, where someone is choosing what to install, and llms.txt, which is what LLM-facing crawlers read. Both state the exclusivity rule, since installing both sides would put two skills in front of the same request. The llms.txt section is generated, not hand-written, so it cannot drift from the pack it advertises. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
99137c2dd0 |
Publish every skill to ClawHub, not the fifteen someone remembered (#80)
The publish loop hand-listed its skill directories, and the list had fallen two behind the tree: cargo-segmentation and cargo-observability have never been published to the registry. Discover the set from */SKILL.md instead, so adding a skill publishes it. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
2c072d267d |
Let the routing evals grade any skill set, not just this repo (#81)
The standalone skills in getcargohq/gtm-skills compete for prompts using the same four-part descriptions, and twelve of them are deliberately adjacent — find-work-email against enrich-linkedin-profile against find-linkedin-url. That is exactly the set most likely to drift into each other, and it had no regression test because the ranker was hardwired to this repo's layout. `--skills-root` points it at any directory of `<name>/SKILL.md`; cases default to `<root>/evals/routing.jsonl` and `--cases` overrides. Default behaviour is unchanged: 17 skills, 81/81 core. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
57254032cf |
Record which skills a session actually loaded (#78)
* Record which skills a session actually loaded Routing is the thing this bundle turns on, and it has been argued rather than measured. evals/routing.jsonl now scores 100% on the real-model tier — a ceiling effect, not a victory: every prompt in it was written by someone looking at the descriptions they were grading, and several were added to pin behavior that had just been implemented. A suite that always passes has stopped discovering anything. Prompts nobody wrote to pass have to come from real sessions. - hooks/skill-loads.sh reads a Claude Code transcript and emits a marker naming the skills invoked and the recipes/playbooks/guides opened: `[cargo-skills: cargo-gtm | docs: build-tam,waterfall]`. The session hooks append it to the row's summary, so it is queryable today over workspace_management.sessions with no schema change. - Wired into both session-checkpoint.sh and session-end.sh. Recomputed from the whole transcript each time rather than accumulated, so a session that dies abruptly still carries it. Emits nothing at all for sessions that never touched Cargo. - evals/README.md documents the three questions the data answers (which skills never load, which sessions loaded two before settling, which load with no doc read after) and how each turns into an eval case. - Self-test wired into skills-lint, because a regression here corrupts telemetry silently instead of failing loudly. Two bugs the fixtures passed and real transcripts caught: - **Prose mentions counted as reads.** The doc regex matched a bare path anywhere in the transcript, and a skill's own catalog table names every recipe and playbook — so one cargo-gtm load reported all 43 playbooks as opened. Now anchored to a `"file_path":` tool input. Fixture 7 is that exact case. - **Dangling prefix** when docs were read without a Skill call, giving `[cargo-skills: | docs: …]`. Both halves are now independently optional. Also: the doc list caps at 12, and says `+N more` rather than looking complete. PRIVACY: skill and document names only, all of them already public in this repository. Never a prompt, file contents, an argument, a record, or anything a user typed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Fix Bugbot issues: preserve marker in sync finalize, retain skill load order 1. End hook drops skill marker (high severity): The sync finalize now includes the skill marker in the placeholder summary, so it persists even when refine() fails, times out, or is skipped. The marker is fast (no LLM call, just grep/sed). 2. Skill order lost to sorting (medium severity): Replaced 'sort -u' with 'awk !seen[$0]++' to preserve load order. The first skill in a multi-skill session is the misroute candidate, so order matters for harvest question 2. Added test case 10 to verify load order preservation. Co-authored-by: Auree Aubert <aureeaubert@users.noreply.github.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Auree Aubert <aureeaubert@users.noreply.github.com> |
||
|
|
9b5a78ba46 |
Stop the SessionEnd hook from spawning an endless summarizer chain (#79)
hooks/session-end.sh refines the session title by piping the transcript to `claude -p`. That subprocess is a full Claude Code session, so when it exits it fires SessionEnd, which runs the hook again, which spawns another summarizer. Nothing broke the chain except a child that happened to have no transcript. Reported from the field on v1.17.1: 264 headless sessions against 8 real ones in a day (~16.5M tokens), each spawn burning ~66K tokens — 46.5K cache write plus 20K cache read — to produce a 150-token title. The session log shows the signature: distinct session ids seconds apart, all refined with an identical title, because each child summarizes the previous child's transcript. The fix is a CARGO_SESSION_SUMMARIZER marker exported across the `claude -p` call. It reaches the child's own hooks through the environment, and all three lifecycle hooks now exit on it — so a summarizer child registers no session row, refreshes no CLI, writes no checkpoint, and spawns no second summarizer. session-end.sh also keeps a rolling-hour spawn budget (20 by default, CARGO_SUMMARIZER_MAX) as a mechanism-independent backstop: if the marker is ever lost to a hook runner that re-execs with a scrubbed environment, a runaway is capped instead of unbounded. Exhausting the budget costs a refined title, nothing else — the row is already finalized with the placeholder. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
8ec848ca0f |
fix(cargo-orchestration): trigger plays with kind "filter", not the generated segment (#68)
* fix(cargo-orchestration): trigger plays with kind "filter", not the generated segment
Every play-triggering example told the agent to take `segmentUuid` from
`play list` and pass it to `batch create --data '{"kind":"segment",...}'`. That
UUID is the play's internally generated segment, whose record count is never
populated, so the batch is always rejected — as `segmentLinkedToPlay`, or as a
misleading `noRecords` on older backends that sends you off debugging a filter
that was never the problem.
This matters more here than in the hosted docs: agents driving the CLI emit these
commands automatically, so the broken recipe fails without a human ever reading
it. A customer hit exactly this and lost most of a day to it.
Switched every play example to `{"kind":"filter","modelUuid":"<play.modelUuid>"}`,
which queries the model directly with no record-count gate and enrols every row
by default.
`{"kind":"segment"}` itself is fine and is left documented — it takes a
standalone segment from `segmentation segment list`. Only the instruction to feed
it a play's generated segment was wrong, so the distinction is now spelled out
rather than the kind removed.
`references/filter-syntax.md` is untouched: its `kind: "segment"` is a filter
condition, unrelated to batch data kinds.
Bumps cargo-orchestration 1.5.1 → 1.6.0 and cargo 1.15.0 → 1.16.0, since
ClawHub publish skips skills whose version is unchanged.
Co-Authored-By: Auree Aubert <16732193+aureeaubert@users.noreply.github.com>
Co-Authored-By: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* chore: regenerate skill-metadata.json after rebase
Co-authored-by: Auree Aubert <aureeaubert@users.noreply.github.com>
* fix: include filter property in kind=filter examples
All batch create examples with kind='filter' now include the explicit
filter property. An empty filter {'conjonction':'and','groups':[]}
matches all rows in the model.
Co-authored-by: Auree Aubert <aureeaubert@users.noreply.github.com>
---------
Co-authored-by: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com>
Co-authored-by: Auree Aubert <16732193+aureeaubert@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Auree Aubert <aureeaubert@users.noreply.github.com>
|
||
|
|
3708f8c955 |
Agent discoverability: trigger-shaped descriptions, routing evals, standalone bootstrap (#77)
* Agent discoverability: trigger-shaped descriptions, routing evals, standalone bootstrap The `description` field is the only text an agent weighs before deciding whether to load a skill. Everything else in the bundle is invisible until that decision is already made — and twelve of the seventeen descriptions read as "Manage <CLI nouns> using the Cargo CLI", which matches a user who is already thinking in Cargo's object model rather than one stating a job. This rebuilds that layer and, for the first time, tests it. Routing - Every description rewritten to a four-part template: job in the user's words -> literal quoted trigger phrases -> proper nouns -> an explicit `Skip when:` pointing at the sibling skill that owns the adjacent case. - Integration and provider names are generated, not hand-maintained. sync-trigger-slugs.ts fills cargo-gtm's `Providers:` list from the playbook tree and cargo-connection's `Integrations:` list from a committed catalog snapshot (138 integrations, 50 credits-based). `--refresh` re-pulls from a logged-in CLI; `--check` gates CI. - evals/routing.jsonl (92 prompts) + routing-eval.ts, wired into CI. Structural tier asserts the template and that each skill keeps >=5 terms unique to it; lexical tier requires the expected skill to rank first; an opt-in --llm tier asks a real model to route from descriptions alone. Deep paraphrases are tagged "hard" and reported rather than gated — a lexical proxy cannot judge them fairly. Standalone installs - `skills add --skill <one>` is a supported path and the registry lists each skill separately, but thirteen skills' only install instructions were a relative link to ../cargo/references/prerequisites.md, which does not exist in a single-skill install. Every SKILL.md now has a self-contained Bootstrap section, enforced by the linter. Coverage - New capability skill cargo-segmentation — the segmentation CLI domain, previously uncovered while segments were load-bearing in most recipes. Verified against the live CLI, including the flag traps. - Three cargo-gtm recipes: source-planning (probe and cost candidate sources per *hit* before any fan-out), ads-audience-activation (Google Customer Match / LinkedIn Matched Audiences), review-and-iterate (human review of judgment output, kept as an eval set). - Router gains a "these skills vs a workspace MCP server" section: Cargo has no first-party MCP server — a workspace builds one and serves it over `cargo-ai mcp` — so the routing rule is scale and reproducibility. Index and hygiene - llms.txt now lists every recipe and provider playbook with a generated summary: 17 entries -> ~80 job-named addressable URLs. - Router trimmed ~80 lines of per-skill summaries that restated each skill's own description; critical rules kept in full. - Linter: bootstrap check, skill-count claims validated against the tree, `doctor` and `mcp` added to the known CLI domains. - CONTRIBUTING.md, keyword-dense README opening, updated repo metadata. Also carries the aiArk/apolloio priority-stack promotion authored in a parallel session on this branch (cargo-gtm 1.12.0) — the two touch the same SKILL.md files and could not be split cleanly. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Surface the 100-credit free tier where an agent meets it There is no purchase gate between installing Cargo and producing a real deliverable — a new account starts with 100 free credits and no card — and nothing in the bundle said so. An agent that doesn't know the budget can't tell a first-time user whether the demo is a look around or a commitment, and defaults to hedging. Now stated at every point an agent encounters the question: - README opening and the generated llms.txt install block: an agent can install, sign the user up, and hand back a list in one turn. - Router install section and prerequisites.md, with anchors for what 100 credits buys (~5,000 sourced leads, ~1,000 verified-email enrichments, ~50 fully enriched contacts). - cargo-quickstart: the demo spends ~0.5 of the 100, and the skill now says so before the first paid call — that reframes the moment from a purchase decision into a look around, which is the job of a quickstart. - cargo-billing: a "what 100 credits buys" table, plus two new trigger phrases so free-tier questions route here at all. - cost-discipline.md: on a new account, receipts and next-step proposals must be framed against the free tier. "87.6 of your 100 free credits left" is a number the user can act on; "87.6 remaining" is not. Also warns that phone lookups (6-7/call) are the fastest way to burn a tier a first session should end with something left to try. Two routing eval cases added for free-tier questions (79/79 core). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Run the routing evals against a real model in CI The lexical tier passes 79/79, but it is a deterministic proxy written alongside the descriptions it grades — it cannot fail in a way that surprises us, which is what makes it weak evidence. The only honest scoreboard for the description rewrite is whether a real model, shown nothing but the 17 descriptions, routes the eval prompts correctly. That tier existed but had never run. Now it does, in its own workflow. - New .github/workflows/routing-evals-llm.yml, using the repo's ANTHROPIC_API_KEY. Deliberately not part of skills-lint: it costs money and is non-deterministic, so it must never stand between a typo fix and a merge. Triggers on PRs and pushes that touch a SKILL.md, the eval cases, or the runner; weekly on a schedule so model drift surfaces even when nobody edits a description; and on demand with a model override. - runLlm reworked for CI: 6-way concurrency (92 sequential calls is a slow job), retry with backoff on 429/5xx, tolerant answer parsing, and a core/hard/overall breakdown instead of one number. - Results are written to GITHUB_STEP_SUMMARY as a table, including every misroute with what the model picked instead — so a regression is readable on the run page without opening logs. - Optional --llm-min=<percent> floor, wired to the exit code. Left unset until the first runs establish a baseline; a floor guessed before the data would either never fire or block on noise. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Act on the first real-model routing run: 92/94, two fixes Baseline from the model tier (claude-haiku-4-5, judging from the 17 descriptions alone): 92/94 overall — core 79/79, hard 13/15. The lexical proxy's 3/15 on the hard tier was noise about the proxy, not the descriptions, which is what that tier existed to establish. Both misroutes were worth having: - "Our outbound is going to the wrong people — help me figure out who actually buys from us" routed to cargo-context instead of cargo-gtm. A real collision: cargo-context's triggers include "who do we sell to", which reads as ICP ownership. It owns *writing the conclusion down*; deriving it from won/lost data is cargo-gtm. Added that boundary to cargo-context's Skip when, and the two phrasings to cargo-gtm. - "Give the assistant access to our sales collateral so it stops making things up" routed to cargo-content instead of cargo-ai — and the model was right. As written the first step is getting the collateral into the workspace. Corrected the expectation and added the other side of the boundary as its own case ("attach the library we already uploaded to the agent"), which the lexical tier then failed, correctly: cargo-ai never said "library" or "release resources". Added both, so the content/ai split is now legible to a ranker and a model. Set --llm-min=93 now that a baseline exists. Deliberately below the observed 98%, not at it: a model tier that fails on one non-deterministic flip trains people to ignore it. Lexical 80/80 core. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Document cargo-ai mcp — the bridge that was written down nowhere Cargo reaches coding agents through two doors. Skills reach agents that implement skills.sh; a workspace MCP server reaches everything else — Claude Desktop, ChatGPT, and whatever ships next. The second door was fully built and documented in exactly one place: `cargo-ai mcp --help`. Worse, cargo-ai/SKILL.md taught `ai mcp-server create` (building a server) without ever mentioning the command that serves it, so an agent could construct one and have no idea how to connect it — and the section conflated publishing a server with consuming someone else's, which are unrelated surfaces. - MCP section rewritten around the two directions, with a table: publish (`ai mcp-server`, called by any MCP client, wired via `cargo-ai mcp`) vs consume (`ai mcp-client`, called by your agents, wired via `release update-draft --mcp-clients`). States plainly that there is no first-party Cargo MCP server — a workspace builds its own. - Documents `cargo-ai mcp` with the registration one-liner, the CARGO_MCP_SERVER_UUID fallback, and the stdout-is-protocol constraint. - Details verified against the live API rather than --help: actions take kind "tool" *or* "agent" (an agent is exposable as a callable MCP tool), resources take model or file, and `update` replaces the arrays wholesale instead of merging — a real footgun. - Routing rule for which door to use, pointing at the router section. - Two trigger phrases ("expose our tools as an MCP server", "use Cargo from Claude Desktop or ChatGPT") and two eval cases, so the publish direction is reachable from a description at all. It previously wasn't. Lexical 81/81 core. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
f93cac3f05 |
Improve agent distribution: paste-prompt install, llms.txt, provider routing, cookbook wiring (#66)
- README now leads with the one-line agent-paste install (agent-install.txt)
and documents Claude Cowork setup (network egress, no-TTY token sign-in,
folder-persisted auth)
- Add CI-generated llms.txt (.github/scripts/generate-llms-txt.ts, TS via
native type-stripping) with a --check step in skills-lint so the index can
never drift from the shipped skill tree
- cargo-gtm frontmatter description now lists every provider slug so naming a
provider ("enrich with FullEnrich") triggers routing into the skill
- Route cargo-cdk (and the router recap) to the cargo-cookbooks menu before
hand-authoring common GTM outcomes, with the deploy-unverified caveat
- Version bumps: cargo 1.16.0, cargo-gtm 1.10.0, cargo-cdk 1.1.0; plugin
manifests mirrored; skill-metadata regenerated
Co-authored-by: Auree Aubert <aureeaubert@users.noreply.github.com>
|
||
|
|
53dac5fd32 |
chore: point the brand URL at getcargo.ai (#76)
owner.url / author.url in the three marketplace and plugin manifests were the last places linking the brand at getcargo.io. README.md and the docs link already use getcargo.ai. app.getcargo.io and api.getcargo.io are left as-is on purpose: neither has a .ai equivalent in DNS, and they are live hosts the skills depend on. Co-authored-by: Auree Aubert <16732193+aureeaubert@users.noreply.github.com> Co-authored-by: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com> |
||
|
|
d64746b872 |
chore: set displayName "Cargo" on the Claude manifests (#75)
The plugin slug stays `cargo` — it is immutable once listed in a directory, it already matches the router skill, and `cargo-ai` is taken by one of the sixteen skills. `displayName` is the supported way to fix the UI label, so the /plugin picker shows "Cargo" rather than the bare slug. Not added to .cursor-plugin/plugin.json (no such field in Cursor's manifest) or the root plugin.json (Agent Plugins is a closed schema). .codex-plugin and .agents already carry it as interface.displayName. Co-authored-by: Auree Aubert <16732193+aureeaubert@users.noreply.github.com> Co-authored-by: replicas-connector[bot] <replicas-connector[bot]@users.noreply.github.com> |