@catalyst-cloud/cli 0.9.5 → 0.13.1
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 +28 -0
- package/README.md +28 -29
- package/dist/args.js +19 -1
- package/dist/ask.js +30 -18
- package/dist/capabilities.js +5 -0
- package/dist/cli.js +24 -6
- package/dist/env/declaration-rules.js +163 -0
- package/dist/env/group.js +51 -0
- package/dist/env/inventory.js +102 -0
- package/dist/env/render.js +39 -0
- package/dist/env/scan-env-example.js +62 -0
- package/dist/env/scan-source.js +43 -0
- package/dist/env/scan-workflow.js +123 -0
- package/dist/env/scan-wrangler.js +120 -0
- package/dist/env/types.js +1 -0
- package/dist/env/walk.js +87 -0
- package/dist/env.js +76 -0
- package/dist/environment.js +1 -1
- package/dist/legacy.js +224 -0
- package/dist/project.js +129 -0
- package/dist/release.js +1 -1
- package/dist/repo.js +297 -0
- package/dist/runtime-verb.js +1 -1
- package/dist/secret.js +1 -1
- package/dist/skill-shape.js +21 -13
- package/dist/skills.js +44 -4
- package/dist/transport.js +26 -1
- package/package.json +7 -6
- package/skills/catalyst-github/SKILL.md +7 -7
- package/skills/catalyst-github/references/is-it-mergeable.md +8 -2
- package/skills/catalyst-github/references/what-a-pr-accumulates.md +3 -3
- package/skills/catalyst-github/scripts/is-it-mergeable.mjs +3 -3
- package/skills/catalyst-github/scripts/lib/cli.mjs +9 -7
- package/skills/catalyst-github/scripts/lib/credential.mjs +2 -2
- package/skills/catalyst-github/scripts/read-pr.mjs +2 -2
- package/skills/catalyst-linear/SKILL.md +17 -19
- package/skills/catalyst-linear/agents/openai.yaml +1 -1
- package/skills/catalyst-linear/agents/portability.yaml +1 -1
- package/skills/catalyst-linear/references/reading-a-ticket.md +9 -26
- package/skills/catalyst-linear/references/what-a-ticket-accumulates.md +2 -2
- package/skills/catalyst-linear/references/writing-to-linear.md +7 -9
- package/skills/catalyst-linear/scripts/comment.mjs +1 -1
- package/skills/catalyst-linear/scripts/create-ticket.mjs +1 -1
- package/skills/catalyst-linear/scripts/label.mjs +1 -1
- package/skills/catalyst-linear/scripts/lib/cli.mjs +9 -7
- package/skills/catalyst-linear/scripts/lib/credential.mjs +2 -2
- package/skills/catalyst-linear/scripts/move.mjs +1 -1
- package/skills/catalyst-linear/scripts/read-ticket.mjs +1 -1
- package/skills/catalyst-linear/scripts/search.mjs +1 -1
- package/skills/catalyst-onboard/SKILL.md +37 -57
- package/skills/catalyst-onboard/agents/openai.yaml +2 -2
- package/skills/catalyst-onboard/agents/portability.yaml +1 -1
- package/skills/catalyst-onboard/references/connecting-this-machine.md +35 -0
- package/skills/catalyst-onboard/references/declaring-a-repository.md +7 -17
- package/skills/catalyst-onboard/references/local-sync.md +19 -7
- package/skills/catalyst-onboard/references/reading-ready.md +79 -0
- package/skills/catalyst-onboard/references/replacing-a-credential.md +8 -33
- package/skills/catalyst-onboard/references/repository-agent-setup.md +23 -0
- package/skills/catalyst-onboard/references/skill-sources.md +13 -19
- package/skills/catalyst-onboard/references/the-one-path.md +18 -74
- package/skills/catalyst-onboard/references/what-a-phase-needs.md +21 -28
- package/skills/catalyst-onboard/references/what-the-browser-owns.md +20 -37
- package/skills/{catalyst-setup → catalyst-onboard}/scripts/check.mjs +10 -9
- package/skills/catalyst-onboard/scripts/lib/cli.mjs +6 -4
- package/skills/catalyst-onboard/scripts/lib/credential.mjs +2 -2
- package/skills/catalyst-onboard/scripts/where-am-i.mjs +60 -4
- package/skills/run-this-project/SKILL.md +23 -25
- package/skills/run-this-project/agents/openai.yaml +1 -1
- package/skills/run-this-project/agents/portability.yaml +1 -1
- package/skills/run-this-project/references/making-work-ready.md +20 -37
- package/skills/run-this-project/references/reacting-to-events.md +25 -48
- package/skills/run-this-project/references/stalls-and-escalation.md +20 -42
- package/skills/run-this-project/scripts/lib/cli.mjs +7 -5
- package/skills/run-this-project/scripts/lib/credential.mjs +2 -2
- package/skills/run-this-project/scripts/scope-status.mjs +0 -0
- package/skills/run-this-project/scripts/watch-scope.mjs +1 -1
- package/skills/unstick/SKILL.md +12 -12
- package/skills/unstick/agents/openai.yaml +1 -1
- package/skills/unstick/agents/portability.yaml +1 -1
- package/skills/unstick/references/playbook.md +13 -13
- package/skills/unstick/scripts/lib/cli.mjs +6 -4
- package/skills/unstick/scripts/lib/credential.mjs +2 -2
- package/skills/unstick/scripts/unstick.mjs +1 -1
- package/skills/what-needs-me/SKILL.md +12 -14
- package/skills/what-needs-me/agents/openai.yaml +2 -2
- package/skills/what-needs-me/agents/portability.yaml +1 -1
- package/skills/what-needs-me/references/raising-a-decision.md +8 -16
- package/skills/what-needs-me/references/reading-the-inbox.md +9 -12
- package/skills/what-needs-me/references/settling-an-answer.md +6 -12
- package/skills/what-needs-me/scripts/inbox.mjs +14 -13
- package/skills/what-needs-me/scripts/lib/cli.mjs +6 -4
- package/skills/what-needs-me/scripts/lib/credential.mjs +2 -2
- package/skills/what-needs-me/scripts/raise.mjs +1 -1
- package/skills/what-needs-me/scripts/settle.mjs +1 -1
- package/skills/what-this-repo-needs/SKILL.md +31 -0
- package/skills/what-this-repo-needs/agents/openai.yaml +6 -0
- package/skills/what-this-repo-needs/agents/portability.yaml +4 -0
- package/skills/what-this-repo-needs/references/what-each-group-means.md +38 -0
- package/skills/what-this-repo-needs/scripts/check.mjs +64 -0
- package/skills/what-this-repo-needs/scripts/inventory.mjs +61 -0
- package/skills/{catalyst-setup → what-this-repo-needs}/scripts/lib/cli.mjs +35 -22
- package/skills/{catalyst-setup → what-this-repo-needs}/scripts/lib/credential.mjs +2 -2
- package/skills/whats-happening/SKILL.md +27 -21
- package/skills/whats-happening/agents/openai.yaml +1 -1
- package/skills/whats-happening/references/coding-accounts.md +24 -0
- package/skills/whats-happening/references/routing-work.md +11 -29
- package/skills/whats-happening/references/settings-and-where-they-live.md +20 -0
- package/skills/whats-happening/references/stages-and-mapping.md +25 -0
- package/skills/whats-happening/references/status-reply.md +21 -21
- package/skills/whats-happening/references/the-ladder.md +30 -0
- package/skills/whats-happening/references/what-runs-next.md +32 -0
- package/skills/whats-happening/references/when-a-phase-fails.md +27 -0
- package/skills/whats-happening/references/why-is-it-stuck.md +33 -40
- package/skills/whats-happening/scripts/explain.mjs +1 -1
- package/skills/whats-happening/scripts/lib/cli.mjs +7 -5
- package/skills/whats-happening/scripts/lib/credential.mjs +2 -2
- package/skills/{how-catalyst-works → whats-happening}/scripts/show-my-map.mjs +18 -32
- package/skills/whats-happening/scripts/snapshot.mjs +10 -6
- package/skills/catalyst-onboard/references/choosing-a-coding-account.md +0 -52
- package/skills/catalyst-onboard/references/who-fixes-what.md +0 -64
- package/skills/catalyst-setup/SKILL.md +0 -36
- package/skills/catalyst-setup/agents/openai.yaml +0 -6
- package/skills/catalyst-setup/agents/portability.yaml +0 -4
- package/skills/catalyst-setup/references/what-each-check-means.md +0 -88
- package/skills/catalyst-setup/scripts/replica-status.mjs +0 -46
- package/skills/connect-me/SKILL.md +0 -63
- package/skills/connect-me/agents/openai.yaml +0 -6
- package/skills/connect-me/agents/portability.yaml +0 -5
- package/skills/connect-me/references/keeping-the-replica-running.md +0 -88
- package/skills/connect-me/scripts/lib/cli.mjs +0 -185
- package/skills/connect-me/scripts/lib/credential.mjs +0 -29
- package/skills/connect-me/scripts/verify-connection.mjs +0 -68
- package/skills/how-catalyst-works/SKILL.md +0 -43
- package/skills/how-catalyst-works/agents/openai.yaml +0 -6
- package/skills/how-catalyst-works/agents/portability.yaml +0 -4
- package/skills/how-catalyst-works/references/coding-accounts.md +0 -51
- package/skills/how-catalyst-works/references/stages-and-mapping.md +0 -56
- package/skills/how-catalyst-works/references/the-ladder.md +0 -41
- package/skills/how-catalyst-works/references/what-catalyst-is.md +0 -30
- package/skills/how-catalyst-works/references/what-runs-next.md +0 -88
- package/skills/how-catalyst-works/references/when-a-phase-fails.md +0 -57
- package/skills/how-catalyst-works/scripts/explain-ticket.mjs +0 -41
- package/skills/how-catalyst-works/scripts/lib/cli.mjs +0 -164
- package/skills/how-catalyst-works/scripts/lib/credential.mjs +0 -29
- package/skills/how-catalyst-works/scripts/whats-running.mjs +0 -65
- package/skills/whats-happening/references/reading-the-board.md +0 -43
- package/skills/whats-happening/references/reprioritising.md +0 -37
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# When a phase fails: retries, repair rounds, parks and holds
|
|
2
|
+
|
|
3
|
+
Numbers here are fleet defaults; quote the live `thresholds` that `node scripts/show-my-map.mjs` prints. A failed phase writes no board state: the ticket stays at its stage, and four layers decide what happens next.
|
|
4
|
+
|
|
5
|
+
1. **Retry in place.** A failure that is not the ticket's fault (one before any branch existed, or infrastructure: a vendor 5xx, a dropped stream, a timeout, an environment gap) re-offers the same phase with no repair round.
|
|
6
|
+
2. **Backoff.** Each retry in place, and a routing refusal at kickoff, waits out a rung first: 2, 5, then 15 minutes (`thresholds.retryBackoffMs`).
|
|
7
|
+
3. **Remediate.** Any other failure moves the card to the remediate stage and queues a repair round; a successful round returns the card to its exact pre-failure stage. A team with no remediate stage gets the hold label (`teams[].labels.hold`) instead. Rounds are capped per failure episode at `thresholds.remediateRoundCap` (default 3); a failed round queues no other, a repeated validate fingerprint spends one round per episode, and a ticket with no recorded branch gets none.
|
|
8
|
+
4. **Park.** After `thresholds.parkAfterConsecutiveFailures` consecutive failures (default 3) the phase parks. A repeated-failure park, and a park at the round cap, release through the person's own login once the cause is fixed (`catalyst release`, never a clock; at the cap it buys one more round). A missing-branch or rebase-conflict park is released by the cloud's own budgeted loop.
|
|
9
|
+
|
|
10
|
+
`catalyst release <ticket> --because <what changed>` releases every governor holding the ticket, or nothing, naming what a person must do; a cause it cannot see change needs `--retry-unchanged`. The `unstick` skill runs it.
|
|
11
|
+
|
|
12
|
+
## Holds, and what clears each
|
|
13
|
+
|
|
14
|
+
A hold stops the cloud retrying what would fail the same way. Each kind clears differently; keep them apart.
|
|
15
|
+
|
|
16
|
+
| hold | created by | cleared by | refused |
|
|
17
|
+
| -- | -- | -- | -- |
|
|
18
|
+
| **validate budget** (`validate_class_spent`) | the same validate failure returns after its one repair round | a push to the branch; a human comment (a `[bookkeeping]` one does not count); a validate pass; the person's own `catalyst release` after a push or comment since the hold, or with `--retry-unchanged` and a `--because`; an answer to the ask it raised; that ask's default (re-plan) after 48 hours unanswered | nothing a person can do is refused |
|
|
19
|
+
| **round threshold** (`round_threshold`) | the ticket's counted repair rounds reach its lifetime budget | each grants one more cycle: a push the fleet did not make, or an answer to its ask; the ask's default (re-plan) applies after 48 hours unanswered | a human comment does not clear it; `catalyst release` is refused |
|
|
20
|
+
| **review convergence** (`review_not_converging`) | validate and repair cycles that do not converge | a human comment, which resumes at validate; `catalyst: resume implement` in the comment resumes at implement | a push alone does not clear it; `catalyst release` is refused; it raises no ask and has no 48-hour default |
|
|
21
|
+
| **no change** (`no_change_hold`) | a repair round that changed nothing | a push, a human comment, or `catalyst release` | never a clock |
|
|
22
|
+
| **hand fix pending** | an ask answered "a human fixes it" | a commit landing on the branch | |
|
|
23
|
+
| **runner pin** | a runner change merged before the live runner image covers it | the image pin moving, which moves the ticket to Done | |
|
|
24
|
+
|
|
25
|
+
The 48-hour default applies only to the asks a validate-budget or round-threshold hold raises; every other ask waits for its answer (`what-needs-me`).
|
|
26
|
+
|
|
27
|
+
Two holds are fleet-wide, one alert for every ticket they hold: the **runner image breaker** (three distinct tickets failing the same startup class on the live image pauses their dispatch until the image pin moves) and a **paused repository** (an operator resumes it). `catalyst explain --history <ticket>` prints the attempts, rounds against the cap, holds with what releases each, and past releases.
|
|
@@ -1,63 +1,56 @@
|
|
|
1
|
-
# Why is it stuck
|
|
1
|
+
# Why is it stuck: every reason, and who acts
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## How to read a reason
|
|
6
|
-
|
|
7
|
-
`explain` prints one paragraph: the queue position (or none), the status, the reason, a detail or marker when the cloud gave one, the last failure, and any advisories. Match the reason to a row below. "Releases itself" means the cloud clears it with no human action; "needs" names who acts. When a reason is not in this table, `explain` prints it as the cloud spelled it; report it verbatim and say the bundle does not know it.
|
|
3
|
+
The pack's one reason table; other skills point here. Match the reason `node scripts/explain.mjs <ticket>` prints to a row. "No one acts" is an honest answer. A reason missing here is printed as the cloud spelled it: report it verbatim and say the bundle does not know it. The mechanism is in `references/when-a-phase-fails.md`.
|
|
8
4
|
|
|
9
5
|
## Reasons that release themselves
|
|
10
6
|
|
|
11
|
-
|
|
7
|
+
`retry_backoff` (a retry rung, `thresholds.retryBackoffMs`), `lease_held`, `intake_lease_held` and `later_phase_lease_held` (a live container holds this or a later phase), `environment_check_running`, `claim_storm` (claimed too often in the last hour), `repo_at_capacity` (every runner seat busy), `stale_failure_episode` (the round would repair a phase already passed, so it is dropped), and `no_branch_to_remediate` / `branch_missing` (the cloud's budgeted release): each clears on its own, and no one acts.
|
|
8
|
+
|
|
9
|
+
| reason | what it means, and what clears it | who acts |
|
|
12
10
|
| -- | -- | -- |
|
|
13
|
-
| `
|
|
14
|
-
| `
|
|
15
|
-
| `
|
|
16
|
-
| `
|
|
17
|
-
| `runner_image_breaker` | fleet-wide: the live runner image fails every phase at startup, so dispatch is held rather than parking tickets | the cloud moves the pin; one alert per tenant, no per-ticket action |
|
|
18
|
-
| `routing_unavailable` | claimed, then refused at kickoff: no route, no eligible coding-account slot, or the provider is unavailable | provider recovery or a slot freeing; if it persists, the tenant admin checks coding accounts in settings |
|
|
19
|
-
| `cooling_down` (with a named callback) | the phase is parked on a condition the cloud watches | the callback fires; the `detail` names it |
|
|
20
|
-
| `wip_limit` | the project (one Linear team, all its repositories) is at its WIP limit, default 12, so this ticket gets no first phase; tickets already in progress are unaffected | a ticket in progress finishes. If the fleet is idle at the limit, the in-progress tickets are the ones waiting (merge queue, holds, paused repositories, asks): unstick those, never the queue. Raising the limit is the project owner's call |
|
|
11
|
+
| `runner_image_breaker` | fleet-wide: the live runner image fails every phase at startup; the image pin moves; one alert per account | an operator |
|
|
12
|
+
| `routing_unavailable` | refused at kickoff: no route, no eligible slot, or the provider down (the detail says which); clears on recovery | usually no one acts; if it persists, a workspace owner or admin, in settings, checks coding accounts (`references/coding-accounts.md`) |
|
|
13
|
+
| `cooling_down` (with a named callback) | parked on a condition the cloud watches; the callback in `detail` fires | no one acts; if the callback stalls, the person, with their own login, releases it through `unstick` |
|
|
14
|
+
| `wip_limit` | the project is at its work-in-progress limit, so no first phase; a ticket in progress finishing clears it | no one acts on this ticket; the in-progress tickets it waits on each have their own row |
|
|
21
15
|
|
|
22
16
|
## Reasons that need a human
|
|
23
17
|
|
|
24
18
|
| reason | what it means | who acts and how |
|
|
25
19
|
| -- | -- | -- |
|
|
26
|
-
| `ask_ticket` | it carries an ask label; a question is never work | the
|
|
27
|
-
| `ask_shape_suspected` | its
|
|
28
|
-
| `blocked` | a live blocking relation holds it |
|
|
29
|
-
| `not_at_dispatch_stage` | the card is not in the
|
|
30
|
-
| `not_at_pr_stage` | merge is next but the card is
|
|
31
|
-
| `no_change_hold` | a repair round changed nothing |
|
|
32
|
-
| `waiting_on` | a merge-gate failure
|
|
33
|
-
| `externally_claimed` | a worker outside the cloud holds it | that worker, or the
|
|
34
|
-
| `environment_check_required` / `
|
|
35
|
-
| `repo_paused` | an operator paused the repository |
|
|
36
|
-
| `scope_overlap` | its declared file scope
|
|
20
|
+
| `ask_ticket` | it carries an ask label; a question is never work | the person, with their own login, answers the ask (`what-needs-me`) |
|
|
21
|
+
| `ask_shape_suspected` | its text reads as a decision request with no ask label | the person, with their own login, answers it as an ask or applies the contract's release label |
|
|
22
|
+
| `blocked` | a live blocking relation holds it | the blocker's owner closes it; for an ask, the person, with their own login |
|
|
23
|
+
| `not_at_dispatch_stage` | the card is not in the dispatch column | the person, with their own login, moves it to the dispatch slot |
|
|
24
|
+
| `not_at_pr_stage` | merge is next but the card is off the PR column | the person, with their own login, returns it to the pr slot and finds the automation that bounced it |
|
|
25
|
+
| `no_change_hold` | a repair round changed nothing | the person, with their own login, comments or pushes; `unstick` can also release it |
|
|
26
|
+
| `waiting_on` | a merge-gate failure the cloud cannot repair holds it at PR | the person, with their own login, reads the merge-wait comment: usually a hold label or an owed review (`catalyst-github`) |
|
|
27
|
+
| `externally_claimed` | a worker outside the cloud holds it | that worker, or the person, with their own login, removes the local-lane label |
|
|
28
|
+
| `environment_check_required` / `environment_check_failed` / `environment_check_expired` / `environment_check_hash_mismatch` | the repository's environment check has not run, failed, aged out, or predates a change | a workspace owner or admin, in settings, runs, fixes or reruns it |
|
|
29
|
+
| `repo_paused` | an operator paused the repository | an operator resumes it |
|
|
30
|
+
| `scope_overlap` | its declared file scope meets a ticket in flight | the person, with their own login, picks which goes first, or waits |
|
|
31
|
+
| `human_owned_pr` | a person's own pull request holds the ticket | the person, with their own login, closes, merges or hands over that pull request, which only they may close. The release command refuses it |
|
|
32
|
+
| `review_not_converging` | validate and repair cycles are not converging (review convergence hold) | the person, with their own login, reads the findings (`catalyst-github`) and comments. The release command refuses it; the hold table in `references/when-a-phase-fails.md` says what clears it |
|
|
33
|
+
| `round_threshold` | the lifetime repair budget is spent (round-threshold hold) | the person, with their own login, answers the ask the cloud raised or pushes a fix; point at that ask rather than raising another. The release command refuses it; see the hold table |
|
|
37
34
|
|
|
38
35
|
## Reasons a release clears once the cause is fixed
|
|
39
36
|
|
|
40
|
-
|
|
37
|
+
The desk does not release. Route these to the `unstick` skill, which reads the history, previews `catalyst release <ticket>`, and runs it or names what a person must do first.
|
|
41
38
|
|
|
42
|
-
| reason | what it means | note |
|
|
43
|
-
| -- | -- | -- |
|
|
44
|
-
| `phase_parked` / `cooling_down` (
|
|
45
|
-
| `remediate_parked` | the repair phase itself is parked
|
|
46
|
-
| `validate_class_spent` |
|
|
47
|
-
| `
|
|
48
|
-
| `review_not_converging` | review and repair kept finding new problems without converging | a person reads the findings and comments on the ticket to resume; raise an ask for that read |
|
|
49
|
-
| `round_threshold` | the ticket spent its lifetime repair budget | a person answers the ask the cloud raised, or pushes a fix |
|
|
50
|
-
| `no_branch_to_remediate` / `branch_missing` / `branch_gone` | a branch-dependent phase has no branch to clone | the cloud releases missing-branch parks on its own budget; a deleted branch needs a human to decide |
|
|
51
|
-
| `stale_failure_episode` | the ladder advanced after the recorded failure | informational; the round is dropped |
|
|
39
|
+
| reason | what it means | note | who acts |
|
|
40
|
+
| -- | -- | -- | -- |
|
|
41
|
+
| `phase_parked` / `cooling_down` (repeated failures, or the round cap spent) | the phase is parked | `explain --history` names the park | the person, with their own login |
|
|
42
|
+
| `remediate_parked` | the repair phase itself is parked | as above | the person, with their own login |
|
|
43
|
+
| `validate_class_spent` | the validate-budget hold | a push, comment or ask answer also clears it (the hold table) | the person, with their own login |
|
|
44
|
+
| `branch_gone` | a branch that existed was deleted | recreate it, or drop the ticket | the person, with their own login |
|
|
52
45
|
|
|
53
46
|
## Reasons that are not problems
|
|
54
47
|
|
|
55
|
-
`ticket_terminal
|
|
48
|
+
`ticket_terminal`, `pipeline_complete` and `pr_merged` describe finished work; no one acts. Report them as closed.
|
|
56
49
|
|
|
57
50
|
## When the cloud could not judge
|
|
58
51
|
|
|
59
|
-
A status of `unknown` with
|
|
52
|
+
A status of `unknown` with `ordering_never_published`, `ordering_stale`, `workflow_mapping_unknown`, `ticket_unknown`, `dependency_snapshot_unknown`, `blocker_unknown`, `label_snapshot_unknown`, `prior_artifact_unknown`, `scope_unknown`, `scope_occupancy_unknown` or `branch_snapshot_unknown` means "I could not look", never "it is not there": report it as inconclusive; most clear on the next pass. `workflow_mapping_unknown` (and `ordering_never_published` with it) does not clear by itself when the team has no saved mapping: a workspace owner or admin maps it (`catalyst team map <KEY>`). If another persists, read readiness (`catalyst-onboard`).
|
|
60
53
|
|
|
61
54
|
## The one advisory
|
|
62
55
|
|
|
63
|
-
`human_addressed_unlabeled_ask_suspect` gates nothing:
|
|
56
|
+
`human_addressed_unlabeled_ask_suspect` gates nothing: a human-assigned ticket may be an unlabelled ask. List it under waiting-on-human with a question mark.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// explain.mjs — "why is this ticket stuck?" in one paragraph. A thin wrapper over
|
|
3
|
-
// `catalyst
|
|
3
|
+
// `catalyst explain <ticket>`, which reads the cloud's eligibility explainer for the ticket's
|
|
4
4
|
// team and translates the exclusion reason, the failure block and any advisories into plain English.
|
|
5
5
|
import { mustRun, parseFlags, printHelp } from "./lib/cli.mjs";
|
|
6
6
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// lib/cli.mjs — the one way a skill script reaches Catalyst Cloud: spawn the catalyst
|
|
2
|
+
// lib/cli.mjs — the one way a skill script reaches Catalyst Cloud: spawn the catalyst CLI.
|
|
3
3
|
// The CLI holds the SDK and the key; this file holds neither. It reads customer.json only
|
|
4
4
|
// to learn where the CLI lives, and it exits 2 with one line when the machine is not connected.
|
|
5
5
|
// Run any script beside this one with --help; this file is a library and is never run directly.
|
|
@@ -8,7 +8,9 @@ import { existsSync, readFileSync } from "node:fs";
|
|
|
8
8
|
import { join } from "node:path";
|
|
9
9
|
import { CONNECT_COMMAND, hasCredential } from "./credential.mjs";
|
|
10
10
|
|
|
11
|
-
export const PACKAGE = "@catalyst-cloud/
|
|
11
|
+
export const PACKAGE = "@catalyst-cloud/cli";
|
|
12
|
+
/** The package ships two commands, so npx needs the one to run named: `npx -p <package> catalyst`. */
|
|
13
|
+
export const NPX_ARGS = ["-p", PACKAGE, "catalyst"];
|
|
12
14
|
export const NOT_CONFIGURED_EXIT = 2;
|
|
13
15
|
|
|
14
16
|
export function configPath() {
|
|
@@ -36,7 +38,7 @@ function notConfigured(why) {
|
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
/**
|
|
39
|
-
* Run one catalyst
|
|
41
|
+
* Run one catalyst verb and return {code, stdout, stderr}. Uses the CLI path the login
|
|
40
42
|
* recorded when it still exists, else `npx <package>`. A CLI exit of 2 with a "not joined" or
|
|
41
43
|
* "not connected" line is turned into this script's own exit 2, so every caller sees one contract.
|
|
42
44
|
*/
|
|
@@ -44,7 +46,7 @@ export function runCli(args, opts = {}) {
|
|
|
44
46
|
const cfg = loadConfig();
|
|
45
47
|
const useRecorded = typeof cfg.cliPath === "string" && existsSync(cfg.cliPath);
|
|
46
48
|
const cmd = useRecorded ? process.execPath : "npx";
|
|
47
|
-
const argv = useRecorded ? [cfg.cliPath, ...args] : [
|
|
49
|
+
const argv = useRecorded ? [cfg.cliPath, ...args] : [...NPX_ARGS, ...args];
|
|
48
50
|
const res = spawnSync(cmd, argv, {
|
|
49
51
|
input: opts.stdin,
|
|
50
52
|
encoding: "utf8",
|
|
@@ -130,6 +132,6 @@ export function printHelp(usage, spec, notes = []) {
|
|
|
130
132
|
for (const n of names) lines.push(` --${n}${spec[n].value ? " <value>" : ""} ${spec[n].help}`);
|
|
131
133
|
lines.push("");
|
|
132
134
|
}
|
|
133
|
-
lines.push(...notes, "", "Exit codes: 0 ok · 1 the check failed or the arguments were wrong · 2 this machine is not connected
|
|
135
|
+
lines.push(...notes, "", "Exit codes: 0 ok · 1 the check failed or the arguments were wrong · 2 this machine is not connected");
|
|
134
136
|
process.stdout.write(lines.join("\n") + "\n");
|
|
135
137
|
}
|
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
//
|
|
7
7
|
// customer.json carries exactly one credential: a personal key (`key`), or the keyless login's
|
|
8
8
|
// session (`auth`, the recommended rail). A script never reads either for its value: it spawns the
|
|
9
|
-
// catalyst
|
|
9
|
+
// catalyst CLI, which authenticates with whichever is present and refreshes a login's token
|
|
10
10
|
// itself. A new credential kind lands here, once.
|
|
11
11
|
|
|
12
12
|
/** The command that connects this machine, as every not-connected line names it. */
|
|
13
13
|
export const CONNECT_COMMAND =
|
|
14
|
-
"npx @catalyst-cloud/catalyst
|
|
14
|
+
"npx -p @catalyst-cloud/cli catalyst login (or, with a personal key: CATALYST_CLOUD_TOKEN=<your personal key> npx -p @catalyst-cloud/cli catalyst login)";
|
|
15
15
|
|
|
16
16
|
/** True when `cfg` (parsed customer.json) holds a usable credential of either kind. Never throws. */
|
|
17
17
|
export function hasCredential(cfg) {
|
|
@@ -1,45 +1,31 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// show-my-map.mjs — this
|
|
2
|
+
// show-my-map.mjs — this account's stage map, ladder and thresholds, straight from the contract:
|
|
3
3
|
// per team, every slot with the Linear stage it maps to, its type, whether that state still exists
|
|
4
4
|
// and how the mapping was chosen; then the ladder and the live failure thresholds.
|
|
5
|
-
import {
|
|
5
|
+
import { mustRun, parseFlags, parseJson, printHelp } from "./lib/cli.mjs";
|
|
6
6
|
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
--team <key> only this team
|
|
13
|
-
--json one JSON document: { slots, teams, ladder, thresholds }
|
|
14
|
-
--help this text
|
|
15
|
-
|
|
16
|
-
A slot marked * is load-bearing: dispatch, intake, pr, done and canceled must be mapped for the
|
|
17
|
-
ladder to move at all; the others are informational. "(unmapped)" means the team has no stage for
|
|
18
|
-
that slot; "(state gone)" means the mapped Linear state no longer exists and needs re-mapping in
|
|
19
|
-
settings.
|
|
20
|
-
|
|
21
|
-
Exit 0, 1 on a usage error or an unknown team, 2 when this machine is not connected to a tenant or
|
|
22
|
-
the contract could not be read (the line says which).`;
|
|
7
|
+
const SPEC = {
|
|
8
|
+
team: { value: true, help: "only this team" },
|
|
9
|
+
json: { value: false, help: "one JSON document: { slots, teams, ladder, thresholds }" },
|
|
10
|
+
};
|
|
23
11
|
|
|
24
12
|
const LOAD_BEARING = new Set(["dispatch", "intake", "pr", "done", "canceled"]);
|
|
25
13
|
|
|
26
|
-
const
|
|
27
|
-
if (
|
|
28
|
-
|
|
14
|
+
const { help, flags } = parseFlags(process.argv.slice(2), SPEC);
|
|
15
|
+
if (help) {
|
|
16
|
+
printHelp("node scripts/show-my-map.mjs [--team <key>] [--json] [--help]", SPEC, [
|
|
17
|
+
"Prints the contract's stage map, ladder and thresholds. Every value is read from the contract",
|
|
18
|
+
"Catalyst Cloud serves for your account. Wraps: catalyst contract --path.",
|
|
19
|
+
"A slot marked * is load-bearing: dispatch, intake, pr, done and canceled must be mapped for the",
|
|
20
|
+
'ladder to move at all. "(unmapped)" means the team has no stage for that slot; "(state gone)"',
|
|
21
|
+
"means the mapped Linear state no longer exists and the team needs re-mapping.",
|
|
22
|
+
]);
|
|
29
23
|
process.exit(0);
|
|
30
24
|
}
|
|
31
|
-
const { flags } = parseFlags(argv, { bool: ["json"], value: ["team"] });
|
|
32
25
|
|
|
33
26
|
function contractPath(path) {
|
|
34
|
-
const r =
|
|
35
|
-
|
|
36
|
-
const v = parseJson(r.stdout);
|
|
37
|
-
if (v === null || v === undefined) {
|
|
38
|
-
relayStderr(r);
|
|
39
|
-
console.error(`contract --path ${path} returned nothing readable`);
|
|
40
|
-
process.exit(1);
|
|
41
|
-
}
|
|
42
|
-
return { value: v, stderr: r.stderr };
|
|
27
|
+
const r = mustRun(["contract", "--path", path, "--json"]);
|
|
28
|
+
return { value: parseJson(r.stdout, `contract --path ${path}`), stderr: r.stderr };
|
|
43
29
|
}
|
|
44
30
|
|
|
45
31
|
const slotsRead = contractPath("slots");
|
|
@@ -53,7 +39,7 @@ if (flags.team) {
|
|
|
53
39
|
const want = flags.team.toUpperCase();
|
|
54
40
|
teams = teams.filter((t) => String(t.key ?? "").toUpperCase() === want);
|
|
55
41
|
if (teams.length === 0) {
|
|
56
|
-
console.error(`no team with key ${flags.team} on this
|
|
42
|
+
console.error(`no team with key ${flags.team} on this account's contract`);
|
|
57
43
|
process.exit(1);
|
|
58
44
|
}
|
|
59
45
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// snapshot.mjs — one call that answers "where are we?": the
|
|
2
|
+
// snapshot.mjs — one call that answers "where are we?": the account's contract (trimmed to what a
|
|
3
3
|
// status reply needs), what is running, what is queued, what is waiting on a human, and whether the
|
|
4
4
|
// local replica is fresh. Prints ONE JSON document on stdout and the source line on stderr.
|
|
5
5
|
import { mustRun, parseFlags, parseJson, printHelp, runCli } from "./lib/cli.mjs";
|
|
@@ -8,16 +8,18 @@ const SPEC = {
|
|
|
8
8
|
team: { value: true, help: "limit the queue and the board to this team key" },
|
|
9
9
|
board: { value: false, help: "also include open tickets grouped by stage, in the contract's slot order" },
|
|
10
10
|
limit: { value: true, help: "board: max tickets to read (default 200)" },
|
|
11
|
-
"full-contract": { value: false, help: "include the whole contract instead of the trimmed tenant block" },
|
|
11
|
+
"full-contract": { value: false, help: "include the whole contract instead of the trimmed `tenant` block" },
|
|
12
|
+
accounts: { value: false, help: "also include the coding accounts: provider, state, usage windows, walls, quarantine (never a credential)" },
|
|
12
13
|
};
|
|
13
14
|
|
|
14
15
|
const { help, flags } = parseFlags(process.argv.slice(2), SPEC);
|
|
15
16
|
if (help) {
|
|
16
|
-
printHelp("node scripts/snapshot.mjs [--team K] [--board] [--limit N] [--full-contract] [--help]", SPEC, [
|
|
17
|
-
"Runs, in order: catalyst
|
|
18
|
-
"
|
|
17
|
+
printHelp("node scripts/snapshot.mjs [--team K] [--board] [--accounts] [--limit N] [--full-contract] [--help]", SPEC, [
|
|
18
|
+
"Runs, in order: catalyst contract, running, queue, ask list, replica status (query issues with --board,",
|
|
19
|
+
"accounts with --accounts).",
|
|
20
|
+
"Output: one JSON document {takenAt, source, tenant, running, queue, waitingOnHuman, board?, accounts?, errors?}.",
|
|
19
21
|
"A section the cloud refused is reported under errors and the rest still prints; exit 1 in that case.",
|
|
20
|
-
"Every
|
|
22
|
+
"Every account fact (stage names, thresholds, teams) comes from the contract in this output, never from prose.",
|
|
21
23
|
]);
|
|
22
24
|
process.exit(0);
|
|
23
25
|
}
|
|
@@ -62,6 +64,8 @@ const out = {
|
|
|
62
64
|
waitingOnHuman: asks,
|
|
63
65
|
};
|
|
64
66
|
|
|
67
|
+
if (flags.accounts) out.accounts = section("accounts", ["accounts", "--json"]);
|
|
68
|
+
|
|
65
69
|
if (flags.board) {
|
|
66
70
|
const args = ["query", "issues", "--limit", String(flags.limit ?? 200), "--json"];
|
|
67
71
|
if (flags.team) args.push("--team", flags.team);
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
# Choosing a coding account
|
|
2
|
-
|
|
3
|
-
A coding account is the AI provider login the work runs on. It is the first thing to settle, because nothing else in setup produces any work without one, and because it needs nothing else in setup to be done. Read the part with `node scripts/where-am-i.mjs`; it says whether one is enrolled, whether each enrolled one can still take work, and who may enrol one.
|
|
4
|
-
|
|
5
|
-
## The first question
|
|
6
|
-
|
|
7
|
-
Ask it plainly: "Do you already have a coding account you want Catalyst to run on?" Then wait.
|
|
8
|
-
|
|
9
|
-
Say why in one line: Catalyst runs each stage of a ticket on an account you own, so you pay your own provider at your own rate and keep the usage under your own name.
|
|
10
|
-
|
|
11
|
-
## What we support today
|
|
12
|
-
|
|
13
|
-
Four kinds. Name the one they have in their words, then in the page's words.
|
|
14
|
-
|
|
15
|
-
| they say | kind | what enrolling asks for | how they get it |
|
|
16
|
-
| -- | -- | -- | -- |
|
|
17
|
-
| "a Claude subscription", "Claude Pro or Max", "I use Claude Code" | Claude, a setup token | the token `claude setup-token` prints | on their own machine: run `claude`, check `/status` shows the account they mean, then run `claude setup-token` and copy the token |
|
|
18
|
-
| "ChatGPT", "Codex", "a ChatGPT Plus or Pro plan" | Codex, an auth file | the contents of `~/.codex/auth.json` | run `codex login`, choose "Sign in with ChatGPT"; the login writes the file. `$CODEX_HOME/auth.json` if `CODEX_HOME` is set. On macOS `pbcopy < ~/.codex/auth.json` copies it |
|
|
19
|
-
| "a GLM key", "Z.ai", "a GLM coding plan" | GLM, an API key | the provider's API key | from the provider's console |
|
|
20
|
-
| "a Qwen key", "Alibaba Model Studio", "a Qwen coding plan" | Qwen, an API key | the provider's API key | from the provider's console |
|
|
21
|
-
|
|
22
|
-
A plain Anthropic or OpenAI API key is not something the page can enrol today. If that is what they have, say so in one sentence and ask whether they also have one of the four above. Do not improvise a way in.
|
|
23
|
-
|
|
24
|
-
Codex has one more thing to say, before they paste: Catalyst takes over that login. Its refresh token is single-use, so the copy on their machine stops working once Catalyst uses it. To keep using Codex locally, they sign in again afterwards, separately.
|
|
25
|
-
|
|
26
|
-
## Enrolling one
|
|
27
|
-
|
|
28
|
-
Enrolling is a browser step, by construction: the person pastes a credential into a write-only field, and nothing you run ever sees it.
|
|
29
|
-
|
|
30
|
-
1. Hand over the page the script printed for the part (Settings → AI accounts). Say: "Choose the provider, give the account a label you will recognise, and paste the credential the page asks for. Nothing on this side sees it."
|
|
31
|
-
2. Wait. Do not run anything while they are on the page.
|
|
32
|
-
3. When they say it is saved, run `node scripts/where-am-i.mjs` and read them the `coding accounts` part. An enrolled and active account, named by its label, is proof. If the part still says none is enrolled, refresh the contract once (`catalyst contract --refresh`) and read it again.
|
|
33
|
-
|
|
34
|
-
Only a workspace owner or admin can enrol one (the page still says "tenant" in places). If the person is neither, say who can, and stop this step there.
|
|
35
|
-
|
|
36
|
-
## Naming accounts
|
|
37
|
-
|
|
38
|
-
Call an account what the page calls it: its label, else its email, else its slot. `catalyst accounts --json` carries this as `displayName`. Never call one "the first account" or "account 2", and never read out a credential.
|
|
39
|
-
|
|
40
|
-
## An account that already exists
|
|
41
|
-
|
|
42
|
-
The script reads each enrolled account. Read it back in their words:
|
|
43
|
-
|
|
44
|
-
- **Active, or attested.** "Your Claude account, Work laptop, is enrolled and can take work." Move on.
|
|
45
|
-
- **Out of rotation.** Every account is deactivated. Reactivate one on its own page. Never enrol another.
|
|
46
|
-
- **Needs a new credential.** Quarantined, expired or revoked, or its last polls failed on the credential itself. Replace the credential on that account's own page, with a credential from that same login. The steps, and the login check that has to come first, are in `references/replacing-a-credential.md`. Never enrol a second account for this.
|
|
47
|
-
- **Cancelled or ended.** The subscription was cancelled, or the provider ended the account. Say so in one clause and move on: it stays for reporting, it is not used, and it is not counted against setup. Never paste a token from another login into it, which would put a live account's credential onto a dead slot, and never tell them to retire or delete it. If the subscription comes back, they reactivate it on its own page.
|
|
48
|
-
- **Could not be read.** Say the accounts could not be read this time and read again later. It is not "no accounts". Do not tell them to enrol one on this reading.
|
|
49
|
-
|
|
50
|
-
## When more than one is right
|
|
51
|
-
|
|
52
|
-
One account is enough to start. A second one, on a different provider or plan, gives the router somewhere to go when the first is at its limit. Offer it as a later improvement, not as a step now.
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# Who fixes what
|
|
2
|
-
|
|
3
|
-
Setup is eight parts. Each has one instrument, and each instrument answers about its own part and nothing else. Read this before you tell a person that something is not ready, and before you tell them to do anything about it. The product's words for what they own are Workspace, Project, Repository, Integration, Connected account and Member; the parts below are the instruments' names for the same things.
|
|
4
|
-
|
|
5
|
-
## The eight parts, and the instrument that owns each
|
|
6
|
-
|
|
7
|
-
| part | instrument | what a pass proves | what it does **not** prove | who fixes a failure, and where |
|
|
8
|
-
| -- | -- | -- | -- | -- |
|
|
9
|
-
| **machine** | `catalyst status`, and the non-team checks of `catalyst ready` | Node is new enough, this machine holds a credential, the CLI is where the config says, the contract is cached, the skills are on disk | anything at all about the tenant | the person at this keyboard, here |
|
|
10
|
-
| **person** | `catalyst me`, and `catalyst connections personal <linear|github> status` | the credential resolves to this person, shows their role and Linear identity match, and reports each personal grant's state | that their seat is active, or that they may change tenant settings | the member approves missing or expired personal grants in a browser; an owner or admin handles seat or identity conflicts in Settings → Members |
|
|
11
|
-
| **account** | `catalyst contract --path account` | a resolved Linear workspace means the tenant's Linear grant landed | that the GitHub App is installed — the contract does not carry it | a tenant owner or admin, `<their cloud>/settings/connections` |
|
|
12
|
-
| **project** | `catalyst team list`, then `team check <KEY>` and the `team:` checks of `ready` for the selected team | the live team list and the selected team's latest readiness verdict | that an unchecked team is ready | a tenant owner or admin, through `catalyst team` or `<their cloud>/settings/linear-teams` |
|
|
13
|
-
| **repository** | `catalyst contract --path merge.repositories` | the repository is registered to the account | that it is active, that a project can dispatch into it, or that its environment is declared | a tenant owner or admin, `<their cloud>/settings/repositories` |
|
|
14
|
-
| **coding accounts** | `codingAccounts` in `catalyst contract` (`catalyst accounts` on an older cloud) | an account is enrolled and active | that it has headroom left for the next phase | the enroller and page the contract names; see `references/what-a-phase-needs.md` |
|
|
15
|
-
| **repository declarations** | the `environment_declared` check in `catalyst contract --path teams`, and its per-repository notes | the project's default repository has a committed `.catalyst/catalyst.toml` in effect: ingested, valid, and its latest revision approved | that the values the names refer to exist; that any other repository is declared, unless its note says so | the person, with you, in the repository for the file; a tenant owner or admin for the approval, at the repository's Environment page under `<their cloud>/settings/repositories` |
|
|
16
|
-
| **host** | the `hosts_current` check in `catalyst contract --path teams` | no host is missing or behind, or the tenant runs none | anything before a project has been checked | the owner the contract names for `hosts_current`; see `references/what-a-phase-needs.md` |
|
|
17
|
-
|
|
18
|
-
`node scripts/where-am-i.mjs` runs all eight, in the order a person can act on them, and labels each finding with its part. Use it rather than composing this by hand.
|
|
19
|
-
|
|
20
|
-
## The two silences that are not absences
|
|
21
|
-
|
|
22
|
-
⛔ **An empty contract project list means nothing is mapped yet — it does not mean they have no projects.** The tenant contract carries a project only once someone has saved a stage mapping for it. Read the available team list with `catalyst team list`, choose one, then go to step 4. `team check --all` performs readiness checks and may create asks for every team.
|
|
23
|
-
|
|
24
|
-
⛔ **A registered repository is not a dispatchable one.** The contract's repository list carries no status and no project attachment, so a paused repository and an active one look identical there, and a repository registered without a project attached looks exactly like a correctly attached one. Registration is all it proves. If a card does not start, `catalyst explain <ticket>` names the real reason; do not conclude anything about the repository from its presence in a list.
|
|
25
|
-
|
|
26
|
-
⭐ And the general form of both: **an instrument that answers about a part it does not own will answer confidently and wrongly.** When you are unsure which part something belongs to, look it up in the table above rather than guessing from the wording of an error.
|
|
27
|
-
|
|
28
|
-
## Triaging NOT READY
|
|
29
|
-
|
|
30
|
-
`catalyst ready` prints one verdict over every check, machine and project together. That single verdict is correct for "can work run?" and useless for "what should I do now?", because it folds two parts into one word. Split it before you act:
|
|
31
|
-
|
|
32
|
-
1. Run `catalyst ready --json`. Every check has an `id`.
|
|
33
|
-
2. A check whose id begins with `team:` is a **project** finding. Everything else is a **machine** finding.
|
|
34
|
-
3. Report the two groups separately, in that order, each with its own owner.
|
|
35
|
-
|
|
36
|
-
- **A machine check failed.** This is the person's, here, now. Each failing check carries its own `fix` line; read it and do it. A missing or partial skill set is `catalyst install`; a stale contract is `catalyst contract --refresh`; a missing CLI path is one more `catalyst login`.
|
|
37
|
-
- **A project check failed.** Name the check, the project, and the owner; the `who` field carries the workspace's own owners and admins. An admin or owner can run the check, preview a stage mapping, or adopt the workflow through `catalyst team`; some failures still need provider consent or a browser action, and `<their cloud>/settings/linear-teams` is where those live. Use the check's reason to choose the next action. Re-running `ready` alone does not fix it.
|
|
38
|
-
- **A check is a note.** Notes never move the verdict. A stale or absent replica or event cache is optional; an unknown freshness probe means the cloud comparison could not be proved. A check that has never been run is waiting, not failing; a check the engine could not run is unknown, which is not a pass and not a failure. Say which it is. The API-backed skills still work; ask before starting the optional writer.
|
|
39
|
-
|
|
40
|
-
## When to stop rather than continue
|
|
41
|
-
|
|
42
|
-
- **They have no account yet.** There is no self-serve sign-up. Coalesce Labs provisions each account, and a person joins one by invitation from its admin. Say so and stop; the next step is theirs.
|
|
43
|
-
- **The account is suspended.** Setup cannot proceed and no retry changes that. Say so and name the conversation they need to have.
|
|
44
|
-
- **Their seat is not active, or they are not an owner or admin where one is required.** Say who is, and what to ask for. Do not offer a workaround.
|
|
45
|
-
- **A page said it worked and the instrument still disagrees.** Refresh the contract once (`catalyst contract --refresh`) and read it again. If it still disagrees, report both facts — what the page said and what the instrument says — and let the person decide. Do not pick one for them.
|
|
46
|
-
|
|
47
|
-
## What still happens in a browser, and why
|
|
48
|
-
|
|
49
|
-
Every step a key can do, the guide does. These are the ones it hands over, each with the reason; when a reason stops being true, the step moves to the CLI and this table changes in the same release.
|
|
50
|
-
|
|
51
|
-
| step | today | why it is still the person's |
|
|
52
|
-
| -- | -- | -- |
|
|
53
|
-
| install Node, or a coding agent | the person, on their machine | outside the CLI |
|
|
54
|
-
| approve the login | the code and URL `login` prints, in a browser | a grant only the person can give |
|
|
55
|
-
| connect the Linear integration | Settings → Connections | an OAuth grant, by construction |
|
|
56
|
-
| install the GitHub App | Settings → Connections | an OAuth grant, by construction |
|
|
57
|
-
| enrol a coding account, or replace its credential | Settings → AI accounts | the credential is theirs to paste; a CLI verb for the paste is being built |
|
|
58
|
-
| register a repository to a project | Settings → Repositories | the route exists; the CLI verb is being built |
|
|
59
|
-
| approve one repository's settings file | the repository's Environment page | the route for a key is being built |
|
|
60
|
-
| enter a secret's value | the repository's Environment page, or `secret set` | a value never passes through the agent |
|
|
61
|
-
| the person's own Linear and GitHub connected accounts | the link `connections personal … start` prints | a grant only the person can give |
|
|
62
|
-
| move the first ticket | Linear, or `write state` when they ask | their call which ticket runs first |
|
|
63
|
-
|
|
64
|
-
A project's readiness check, its stage mapping and adopting the workflow are CLI steps (`team check`, `team map`, `team adopt`) when `catalyst capabilities` says the installed CLI can run them for the person's role; the script names the command, and the page only for a person whose role cannot.
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: catalyst-setup
|
|
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 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
|
-
allowed-tools: Bash(catalyst-skills:*) Bash(npx @catalyst-cloud/catalyst-skills:*)
|
|
6
|
-
---
|
|
7
|
-
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.5 — written in this repository for customer tenants -->
|
|
8
|
-
|
|
9
|
-
# Am I set up?
|
|
10
|
-
|
|
11
|
-
You answer one question with one verdict and one list. The verdict is READY or NOT READY. The list is who can click what: the fixes only the person at the keyboard can make, the fixes only a tenant owner or admin can make in settings, and the checks that are simply waiting for the first event. The live check ids, severities, states and the people who can answer come from the contract; the scripts print them, you never restate them.
|
|
12
|
-
|
|
13
|
-
This readiness skill is part of `catalyst-cloud-skills` and checks tenant setup and operation. Coding workflow skills are a separate pack, `catalyst-dev-skills`. Do not direct a person to the deprecated local runtime or its `catalyst-dev@catalyst` plugin.
|
|
14
|
-
|
|
15
|
-
## Run first
|
|
16
|
-
|
|
17
|
-
- `node scripts/check.mjs --help` — every machine and tenant check, one line each, the fix and who for each failure, the verdict, then the who-can-click-what list. Exit 1 when NOT READY.
|
|
18
|
-
- `node scripts/replica-status.mjs --help` — the optional replica's verdict with no network (add `--probe` for how far behind it is). Exit 0 fresh, 1 stale, 2 not connected, 3 absent.
|
|
19
|
-
|
|
20
|
-
## Load on demand
|
|
21
|
-
|
|
22
|
-
| when | read |
|
|
23
|
-
| -- | -- |
|
|
24
|
-
| any check is red, unknown or waiting and the person asks what it proves, how to fix it, or who can | `references/what-each-check-means.md` |
|
|
25
|
-
| the person asks how to install, update, or migrate Catalyst skills | `../catalyst-onboard/references/skill-sources.md` |
|
|
26
|
-
|
|
27
|
-
## Rules
|
|
28
|
-
|
|
29
|
-
- Report, never repair. No tenant-reachable repair verb exists for a key yet; the settings page is where a tenant owner or admin fixes a mapping, a connection or a label, and you say which one.
|
|
30
|
-
- End every answer with the verdict and the who-can-click-what list, in that order.
|
|
31
|
-
- A stale or absent replica is a note, never a failure: every skill reads the API meanwhile and says so. Do not tell the person to start it unless they want local SQL or cheaper repeated reads.
|
|
32
|
-
- Not connected (exit 2) means the connect step, not a retry: `npx @catalyst-cloud/catalyst-skills login`, which logs the person in keyless in their browser; with a personal key from Settings → API keys instead, prefix it with `CATALYST_CLOUD_TOKEN=<your personal key>`. Never guess a tenant; the login (or the key) is the only selector.
|
|
33
|
-
- Waiting is not failing. "No write observed", "no delivery observed" and "no host connected" clear themselves the first time the thing happens; say that instead of raising them.
|
|
34
|
-
- Unknown is not a pass. A check the engine could not run is reported as such, never rounded up.
|
|
35
|
-
- **Give numbers and a time.** Say how many are `pass`, `fail` and `unknown`, and when the team verdicts were computed: `readiness.checkedAt` per team on the contract, null when no pass has run.
|
|
36
|
-
- Never run a check in a loop. If the person wants to know when a waiting check clears, that is the project-running skill's watch.
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
interface:
|
|
2
|
-
display_name: "Am I set up?"
|
|
3
|
-
short_description: "Machine and tenant readiness in one verdict: what passes, what is blocked, and who can click what"
|
|
4
|
-
default_prompt: "Use $catalyst-setup to tell me whether this machine and my tenant are ready, and what is missing."
|
|
5
|
-
policy:
|
|
6
|
-
allow_implicit_invocation: true
|