@catalyst-cloud/catalyst-skills 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/README.md +13 -9
- package/dist/args.js +16 -4
- package/dist/ask.js +6 -3
- package/dist/cli.js +9 -4
- package/dist/config.js +4 -0
- package/dist/contract.js +6 -0
- package/dist/environment.js +207 -0
- package/dist/execution.js +97 -15
- package/dist/pagination.js +76 -0
- package/dist/published.js +75 -0
- package/dist/query.js +41 -18
- package/dist/ready.js +110 -19
- package/dist/replica.js +295 -35
- package/dist/semver.js +18 -0
- package/dist/skill-shape.js +10 -0
- package/dist/skills.js +52 -1
- package/dist/ts-deps-loader.js +46 -1
- package/package.json +5 -3
- package/skills/catalyst-github/SKILL.md +1 -1
- package/skills/catalyst-linear/SKILL.md +1 -1
- package/skills/catalyst-linear/references/reading-a-ticket.md +2 -0
- package/skills/catalyst-onboard/SKILL.md +49 -0
- package/skills/catalyst-onboard/agents/openai.yaml +6 -0
- package/skills/catalyst-onboard/agents/portability.yaml +5 -0
- package/skills/catalyst-onboard/references/the-one-path.md +143 -0
- package/skills/catalyst-onboard/references/what-the-browser-owns.md +50 -0
- package/skills/catalyst-onboard/references/who-fixes-what.md +41 -0
- package/skills/catalyst-onboard/scripts/lib/cli.mjs +117 -0
- package/skills/catalyst-onboard/scripts/lib/credential.mjs +29 -0
- package/skills/catalyst-onboard/scripts/where-am-i.mjs +245 -0
- package/skills/catalyst-setup/SKILL.md +2 -2
- package/skills/catalyst-setup/references/what-each-check-means.md +17 -5
- package/skills/connect-me/SKILL.md +1 -1
- package/skills/how-catalyst-works/SKILL.md +1 -1
- package/skills/how-catalyst-works/references/stages-and-mapping.md +1 -1
- package/skills/run-this-project/SKILL.md +1 -1
- package/skills/unstick/SKILL.md +1 -1
- package/skills/what-needs-me/SKILL.md +1 -1
- package/skills/what-needs-me/references/reading-the-inbox.md +1 -1
- package/skills/whats-happening/SKILL.md +1 -1
- package/skills/whats-happening/scripts/snapshot.mjs +4 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: catalyst-setup
|
|
3
3
|
description: >-
|
|
4
|
-
Am I set up? Machine readiness (Node, the tenant connection, the cached contract, the CLI path, the skills, the SDK, the optional replica) plus tenant readiness from the contract's
|
|
4
|
+
Am I set up? Machine readiness (Node, the tenant connection, the cached contract, the CLI path, the skills, the SDK, the optional replica) plus tenant readiness from the contract's per-team checks, in one verdict: what passes, what is blocked, what is merely waiting, and who can click what. Use when someone asks "am I set up", "what is missing", "why does nothing happen", "is the replica running", or right after connecting a new machine. Reports; never repairs.
|
|
5
5
|
allowed-tools: Bash(catalyst-skills:*) Bash(npx @catalyst-cloud/catalyst-skills:*)
|
|
6
6
|
---
|
|
7
|
-
<!-- vendored-from: @catalyst-cloud/catalyst-skills — written in this repository for customer tenants -->
|
|
7
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.7.0 — written in this repository for customer tenants -->
|
|
8
8
|
|
|
9
9
|
# Am I set up?
|
|
10
10
|
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
# What each check means
|
|
2
2
|
|
|
3
|
-
This page restates invariants: the
|
|
3
|
+
This page restates invariants: the per-team readiness checks the cloud runs, what each proves, its fix and who can click it; the machine checks the CLI adds; and the four replica verdicts. The live values are never restated: each check's severity and whether it needs a human's answer come from the contract's `readinessChecks[]`, each team's current states from `teams[].readiness`, and the people who can answer from `humans[]`. `node scripts/check.mjs` prints all of it; this page is how to read what it printed.
|
|
4
4
|
|
|
5
5
|
## How a team's readiness is scored
|
|
6
6
|
|
|
7
|
-
A team's status is one of `ready`, `degraded`, `blocked` or `unchecked`. The engine always reports
|
|
7
|
+
A team's status is one of `ready`, `degraded`, `blocked` or `unchecked`. The engine always reports every check the contract lists; a check it could not run is `unknown`, never `pass`. Any failing check the contract marks as blocking makes the team blocked; any unknown, and any failing check marked degrading, makes it degraded. Unchecked means no readiness pass has run for that team yet, which is a note, not a failure. Readiness is stamped with the account-wide mapping revision it was computed against, so a stale verdict is visible as such.
|
|
8
8
|
|
|
9
|
-
## The
|
|
9
|
+
## The checks
|
|
10
|
+
|
|
11
|
+
The contract's `readinessChecks[]` is the list of record. A check that appears there and not here is newer than this page; `node scripts/check.mjs` still prints it with its own severity, fix and owner, so read the printed line and say you did.
|
|
10
12
|
|
|
11
13
|
| check id | proves | when it fails, the fix | who clicks |
|
|
12
14
|
| -- | -- | -- | -- |
|
|
@@ -20,9 +22,12 @@ A team's status is one of `ready`, `degraded`, `blocked` or `unchecked`. The eng
|
|
|
20
22
|
| `writes_land` | Catalyst has written to this team successfully | "no write observed" is waiting, not failing: it clears the first time Catalyst moves a ticket. "Write refused" means Linear rejected the last write: check the connection and the team's permissions | owner or admin when refused; otherwise nobody |
|
|
21
23
|
| `webhook_covers_team` | events for this team are arriving | confirmed once a repository is registered and events flow; "no delivery observed" is waiting | owner or admin, by registering the repository |
|
|
22
24
|
| `hosts_current` | no connected host runs an older mapping revision | a host that is behind re-loads the mapping on its next connect; a host that did not report its revision is flagged rather than assumed current; "no host connected" is waiting | whoever runs that host |
|
|
23
|
-
| `environment_declared` | a committed environment declaration for the team's default repository is in effect (
|
|
25
|
+
| `environment_declared` | a committed environment declaration for the team's default repository is in effect (`catalyst.env.json` at the repository root was ingested, is valid, and its latest proposal is approved) | `no_team_repo_default`: register a repository and make it the team's default; `no_environment_declaration`: commit the declaration file to that repository; `declaration_invalid` / `declaration_read_failed`: fix the file (the ingest names the error); `declaration_awaiting_approval`: an owner or admin approves the proposal in Settings → Environment | owner or admin, except committing the file, which is whoever can push to the repository |
|
|
26
|
+
| `tools_resolvable` | every MCP server and CLI the team's approved environment declaration names can be resolved for that team's repository | `tool_reference_unresolved`: the declaration names a vault secret that does not exist — add it at the right scope or correct the declaration; `toolchain_cli_missing`: a declared CLI is not in the runner image, which is not self-service; `tool_declarations_unread` reads as `unknown` and clears itself | owner or admin, in the declaration or Settings → Environment |
|
|
27
|
+
| `reviewer_required` | this team's repository can merge under its own merge policy with the reviewers configured | it fails only under a strict merge policy with no reviewer — configure one at Settings → Repositories → Code reviews, or change the repository's merge policy; work still runs, only the merge waits | owner or admin, in settings |
|
|
28
|
+
| `reviewer_configured` | a code reviewer is configured for this team's repository at all, whatever the current policy requires | a *failing* `reviewer_configured` never blocks or degrades a team — with no reviewer, pull requests merge on green checks and resolved threads alone; configure one at Settings → Repositories → Code reviews. An `unknown` one (`merge_reviewer_unread`: the reviewer registry could not be read) still degrades the team, like any unknown | owner or admin, in settings; nobody is required when it fails |
|
|
24
29
|
|
|
25
|
-
|
|
30
|
+
Some checks degrade a team without ever blocking it, and one is informational only — informational means a *fail* never moves the verdict, not that the check cannot: an unknown still degrades. Which check is which is served on `readinessChecks[].severity`; do not memorise the split.
|
|
26
31
|
|
|
27
32
|
## Reasons that look like failures and are not
|
|
28
33
|
|
|
@@ -39,8 +44,11 @@ Three checks are informational by design (labels, event delivery, host currency)
|
|
|
39
44
|
| `node` | Node 22 or newer, which the SDK's built-in SQLite engine needs | install Node 22+ |
|
|
40
45
|
| `config` | this machine is connected: `customer.json` exists and loads | `npx @catalyst-cloud/catalyst-skills login` (keyless: the person approves in their browser); or, with a personal key minted at Settings → API keys, the same command prefixed with `CATALYST_CLOUD_TOKEN=<your personal key>` |
|
|
41
46
|
| `contract` | the tenant contract is cached and its major version is one this bundle accepts | `catalyst-skills contract --refresh`; a version outside the range means update the bundle. A 403 naming an older cloud means the cloud has not yet deployed personal-key access |
|
|
47
|
+
| `bundle` | the installed CLI is at least the version this tenant requires | `npm install -g @catalyst-cloud/catalyst-skills@latest && catalyst-skills login`; a note, never a failure |
|
|
42
48
|
| `cliPath` | the CLI path recorded at login still exists, so skill scripts can spawn it | re-run login |
|
|
43
49
|
| `skills` | every skill of this bundle is present where the CLI installed them | `catalyst-skills install` |
|
|
50
|
+
| `cliRelease` | the installed CLI is not behind the newest published release | the same upgrade command as `bundle`; a note, never a failure |
|
|
51
|
+
| `skillsRelease` | the installed skill files are not behind the newest published bundle | `npx skills update -y`; a note, never a failure. A line saying the check could not run means the registry was unreachable, not that anything is wrong |
|
|
44
52
|
| `sdk` | the SDK loads, so the replica and the watch are available | run under Node 22.15 or newer; every read still works through the API meanwhile |
|
|
45
53
|
| `replica` | the optional replica is fresh | a note, never a failure; see below |
|
|
46
54
|
|
|
@@ -57,6 +65,10 @@ Three checks are informational by design (labels, event delivery, host currency)
|
|
|
57
65
|
|
|
58
66
|
`--probe` adds the one network call: it compares the local cursor with the cloud's head and prints how far behind the replica is, the only honest "how stale" number. A skill must never refuse to work because the replica is down, and must never silently read a stale one; both halves are one exit code away.
|
|
59
67
|
|
|
68
|
+
## The writer stops itself after repeated snapshot failures
|
|
69
|
+
|
|
70
|
+
`replica start` backs off with jitter after a failed or incomplete snapshot pull, and gives up after five consecutive snapshot failures rather than retrying forever — a writer that keeps failing never hammers the tenant. A snapshot that completes resets the count to zero. Both `catalyst-skills replica status` and `catalyst-skills ready` name the stopped state, the count, the last error, and the command that restarts it. The four exit codes above are unchanged: a stopped writer with a database already on disk still reads stale, since there truly is no live writer.
|
|
71
|
+
|
|
60
72
|
## Who can click what
|
|
61
73
|
|
|
62
74
|
The last block `check.mjs` prints groups every failure by the person it needs. Machine fixes name "you", the person at the keyboard. Tenant fixes name the owner or admin roles the contract lists (as Linear user ids, since that is how the cloud knows them), because the settings page that repairs a mapping, a connection or a label is theirs. A check the contract marks as not needing an answer names nobody: it is informational or self-clearing. This skill reports; it never repairs, because no key-reachable repair verb exists yet.
|
|
@@ -5,7 +5,7 @@ description: >-
|
|
|
5
5
|
disable-model-invocation: true
|
|
6
6
|
allowed-tools: Bash(catalyst-skills:*) Bash(npx @catalyst-cloud/catalyst-skills:*)
|
|
7
7
|
---
|
|
8
|
-
<!-- vendored-from: @catalyst-cloud/catalyst-skills — written in this repository for customer tenants -->
|
|
8
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.7.0 — written in this repository for customer tenants -->
|
|
9
9
|
|
|
10
10
|
# Connect me
|
|
11
11
|
|
|
@@ -4,7 +4,7 @@ description: >-
|
|
|
4
4
|
How Catalyst Cloud runs a ticket on the customer's own tenant, as facts an agent loads on demand: the eight-phase ladder and what each phase produces, the eleven board slots and this team's live stage map, what happens when a phase fails (retry, backoff, Remediate, park), how the queue is ordered and routed and every reason a ticket is excluded, and the coding-account model. Use when a person asks "how does this work?", "why did it do that?", "why is this stuck?", "what runs next?" or "how does it prioritise?". Read-only; its scripts explain one ticket's eligibility in plain English, show what is running and queued, and print the tenant's stage map and thresholds straight from the contract.
|
|
5
5
|
allowed-tools: Bash(catalyst-skills:*) Bash(npx @catalyst-cloud/catalyst-skills:*)
|
|
6
6
|
---
|
|
7
|
-
<!-- vendored-from: @catalyst-cloud/catalyst-skills — written in this repository for customer tenants -->
|
|
7
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.7.0 — written in this repository for customer tenants -->
|
|
8
8
|
|
|
9
9
|
# How Catalyst works
|
|
10
10
|
|
|
@@ -51,4 +51,4 @@ Reading it for a question:
|
|
|
51
51
|
|
|
52
52
|
## Readiness over the mapping
|
|
53
53
|
|
|
54
|
-
The contract carries a
|
|
54
|
+
The contract carries a readiness vector per team (`teams[].readiness`), including whether every mapped state exists, whether the mapping is total, whether the types are compatible, whether the labels are present, whether writes land and whether the webhook covers the team. A check the cloud could not run is `unknown`, never `pass`. `catalyst-setup` reads this vector; this skill only points at it.
|
|
@@ -5,7 +5,7 @@ description: >-
|
|
|
5
5
|
disable-model-invocation: true
|
|
6
6
|
allowed-tools: Bash(catalyst-skills:*) Bash(npx @catalyst-cloud/catalyst-skills:*)
|
|
7
7
|
---
|
|
8
|
-
<!-- vendored-from: @catalyst-cloud/catalyst-skills — written in this repository for customer tenants -->
|
|
8
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.7.0 — written in this repository for customer tenants -->
|
|
9
9
|
|
|
10
10
|
# Run this project
|
|
11
11
|
|
package/skills/unstick/SKILL.md
CHANGED
|
@@ -5,7 +5,7 @@ description: >-
|
|
|
5
5
|
disable-model-invocation: true
|
|
6
6
|
allowed-tools: Bash(catalyst-skills:*) Bash(npx @catalyst-cloud/catalyst-skills:*)
|
|
7
7
|
---
|
|
8
|
-
<!-- vendored-from: @catalyst-cloud/catalyst-skills — written in this repository for customer tenants -->
|
|
8
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.7.0 — written in this repository for customer tenants -->
|
|
9
9
|
|
|
10
10
|
# Unstick
|
|
11
11
|
|
|
@@ -5,7 +5,7 @@ description: >-
|
|
|
5
5
|
disable-model-invocation: true
|
|
6
6
|
allowed-tools: Bash(catalyst-skills:*) Bash(npx @catalyst-cloud/catalyst-skills:*)
|
|
7
7
|
---
|
|
8
|
-
<!-- vendored-from: @catalyst-cloud/catalyst-skills — written in this repository for customer tenants -->
|
|
8
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.7.0 — written in this repository for customer tenants -->
|
|
9
9
|
|
|
10
10
|
# What needs me
|
|
11
11
|
|
|
@@ -17,7 +17,7 @@ So an ask that holds nothing is real, but the person may never see it in their o
|
|
|
17
17
|
|
|
18
18
|
## What the script reads
|
|
19
19
|
|
|
20
|
-
`catalyst-skills ask list` reads the open tickets carrying the team's ask label (by the label ids and prefix the contract serves), follows each one's blocking relations to the tickets it holds, drops held tickets that are already terminal, and scores the rest by priority weight: urgent 4, high 3, medium 2, low 1, none 1. It filters to **the connected person** by default: `login` recorded who they are and their Linear user id, and the list keeps only asks assigned to that id. `--anyone` lists the whole tenant. The JSON answer carries a `scope` — `mine` (with the label and Linear id), `anyone`, `unmatched` (the person's Linear identity is not matched yet: an admin does that in Settings → Members, and until then the whole list is shown with a stderr line saying so), or `no-person` (the machine is connected with the tenant's account key, which names nobody: the whole list, with a line saying to log in with a personal key). Read the scope before presenting the list, and say which you got: "what needs me" is the `mine` list, "what needs anyone" is `--anyone`, and an empty `mine` list names the wider count so it never reads as "nothing needs anyone".
|
|
20
|
+
`catalyst-skills ask list` reads every page of the tenant's issues, not a windowed sample, so an empty list means nothing is assigned to you rather than that the read stopped early. It reads the open tickets carrying the team's ask label (by the label ids and prefix the contract serves), follows each one's blocking relations to the tickets it holds, drops held tickets that are already terminal, and scores the rest by priority weight: urgent 4, high 3, medium 2, low 1, none 1. It filters to **the connected person** by default: `login` recorded who they are and their Linear user id, and the list keeps only asks assigned to that id. `--anyone` lists the whole tenant. The JSON answer carries a `scope` — `mine` (with the label and Linear id), `anyone`, `unmatched` (the person's Linear identity is not matched yet: an admin does that in Settings → Members, and until then the whole list is shown with a stderr line saying so), or `no-person` (the machine is connected with the tenant's account key, which names nobody: the whole list, with a line saying to log in with a personal key). Read the scope before presenting the list, and say which you got: "what needs me" is the `mine` list, "what needs anyone" is `--anyone`, and an empty `mine` list names the wider count so it never reads as "nothing needs anyone".
|
|
21
21
|
|
|
22
22
|
## Presenting the queue
|
|
23
23
|
|
|
@@ -4,7 +4,7 @@ description: >-
|
|
|
4
4
|
The desk for a Catalyst Cloud tenant. Use when the person asks "what's happening?", "where are we?", "why is that stuck?", "what closed?", "what's next?", or asks for something to be done rather than known. Reads the tenant contract, what is running and queued, the eligibility explainer and the open asks through the catalyst-skills CLI, and answers in one reply with ticket ids. Routes work to a project owner and decisions to what-needs-me. Never composes a URL, never polls, never answers as the human.
|
|
5
5
|
allowed-tools: Bash(catalyst-skills:*) Bash(npx @catalyst-cloud/catalyst-skills:*)
|
|
6
6
|
---
|
|
7
|
-
<!-- vendored-from: @catalyst-cloud/catalyst-skills — written in this repository for customer tenants -->
|
|
7
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.7.0 — written in this repository for customer tenants -->
|
|
8
8
|
|
|
9
9
|
# What's happening
|
|
10
10
|
|
|
@@ -67,11 +67,15 @@ if (flags.board) {
|
|
|
67
67
|
if (flags.team) args.push("--team", flags.team);
|
|
68
68
|
const r = runCli(args);
|
|
69
69
|
const sourceLine = (r.stderr.match(/^source: .*$/m) ?? [null])[0];
|
|
70
|
+
// A board read is a window (`--limit` stays the default), and a window the cloud cut short must
|
|
71
|
+
// say so rather than reading as the whole team.
|
|
72
|
+
const truncatedLine = (r.stderr.match(/^truncated at .*$/m) ?? [null])[0];
|
|
70
73
|
if (r.code !== 0) errors.board = (r.stderr || `exit ${r.code}`).trim().split("\n").at(-1);
|
|
71
74
|
else {
|
|
72
75
|
const rows = parseJson(r.stdout, "issues");
|
|
73
76
|
out.board = groupByStage(rows, contract, flags.team);
|
|
74
77
|
if (sourceLine) out.source.board = sourceLine.replace(/^source: /, "");
|
|
78
|
+
if (truncatedLine) out.source.boardTruncated = truncatedLine;
|
|
75
79
|
}
|
|
76
80
|
}
|
|
77
81
|
|