@catalyst-cloud/cli 0.14.7 → 0.14.9
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 +14 -0
- package/README.md +2 -2
- package/dist/args.js +17 -5
- package/dist/browser.js +37 -3
- package/dist/cli.js +6 -8
- package/dist/config.js +1 -2
- package/dist/consent-browser.js +58 -0
- package/dist/env/onboard-draft-store.js +10 -3
- package/dist/env/settings-authority.js +3 -1
- package/dist/events-cloud-tail.js +25 -13
- package/dist/events-cloud.js +124 -5
- package/dist/events.js +175 -29
- package/dist/oauth.js +4 -1
- package/dist/onboard-github.js +14 -3
- package/dist/onboard-next.js +139 -0
- package/dist/onboard-personal.js +14 -3
- package/dist/onboard-repositories.js +3 -4
- package/dist/onboard-runtime.js +4 -4
- package/dist/onboard-ui.js +14 -76
- package/dist/onboard-workflow.js +2 -8
- package/dist/onboard-workspace.js +14 -3
- package/dist/onboard.js +71 -12
- package/dist/pagination.js +13 -1
- package/dist/query.js +39 -16
- package/dist/repository-id.js +5 -0
- package/package.json +1 -1
- package/skills/catalyst-github/SKILL.md +3 -1
- package/skills/catalyst-github/references/local-replica.md +78 -0
- package/skills/catalyst-github/references/reading-from-the-cloud.md +24 -0
- package/skills/catalyst-linear/SKILL.md +3 -1
- package/skills/catalyst-linear/references/local-replica.md +91 -0
- package/skills/catalyst-linear/references/reading-from-the-cloud.md +38 -0
- package/skills/catalyst-onboard/SKILL.md +3 -2
- package/skills/catalyst-onboard/references/local-replica.md +40 -0
- package/skills/catalyst-onboard/references/local-sync.md +5 -3
- package/skills/catalyst-onboard/scripts/local-sync.mjs +2 -2
- package/skills/catalyst-onboard/scripts/where-am-i.mjs +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-this-repo-needs/SKILL.md +1 -1
- package/skills/whats-happening/SKILL.md +3 -1
- package/skills/whats-happening/references/local-replica.md +51 -0
- package/skills/whats-happening/references/reading-from-the-cloud.md +21 -0
|
@@ -4,7 +4,7 @@ description: >-
|
|
|
4
4
|
Catalyst's view of Linear on the customer's own cloud account. Reads a ticket with its comments, relations, labels, linked pull requests and agent sessions inline, from the cloud API by default, with local replica reads available as an explicit opt-in, always naming the source; searches tickets, PRs, projects and initiatives; writes comments, card moves, labels and new tickets through the account's agent proxy as the app actor, with every route, stage id, label id and marker read from the account's contract. Knows what a ticket accumulates as Catalyst works it (phase-outcome comments, the document per phase, the agent session, the labels, the single blocks relation, the bookkeeping marker, the eyes acknowledgement). Use when a person says "show me the ticket", "what did Catalyst write on it", "comment on it", "move it", "label it" or "file a ticket". Not for raising a decision for a human (what-needs-me) and not for pull requests (catalyst-github).
|
|
5
5
|
allowed-tools: Bash(catalyst:*) Bash(npx -p @catalyst-cloud/cli catalyst:*)
|
|
6
6
|
---
|
|
7
|
-
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.14.
|
|
7
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.14.9 — written in this repository for customer accounts -->
|
|
8
8
|
|
|
9
9
|
# Catalyst Linear
|
|
10
10
|
|
|
@@ -30,6 +30,8 @@ Exit codes: 0 done, 1 not found or a usage error, 2 this machine is not connecte
|
|
|
30
30
|
| "what did Catalyst write on this ticket?", a comment shape, a label, the marker, the 👀 | `references/what-a-ticket-accumulates.md` |
|
|
31
31
|
| before any read you will report on; "is this current?"; citing; searching | `references/reading-a-ticket.md` |
|
|
32
32
|
| before any comment, move, label or new ticket; identity, budget, slots, ids | `references/writing-to-linear.md` |
|
|
33
|
+
| which command answers a ticket question from the cloud: stage, last phase, PR, what changed | `references/reading-from-the-cloud.md` |
|
|
34
|
+
| local SQL, only when `catalyst replica status --json` reports `configured: true` | `references/local-replica.md` |
|
|
33
35
|
|
|
34
36
|
## Rules
|
|
35
37
|
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Reading a ticket from the local replica (opt-in)
|
|
2
|
+
|
|
3
|
+
Load this only when `catalyst replica status --json` reports `configured: true`. On any other machine, read from the cloud (`references/reading-from-the-cloud.md`) and do not mention the replica.
|
|
4
|
+
|
|
5
|
+
The replica is an on-machine SQLite copy of the account. It exists only when the person opted in to local sync. It is for ad hoc SQL and many repeated reads. It is never required, and the cloud read stays the default.
|
|
6
|
+
|
|
7
|
+
## Check it is caught up first
|
|
8
|
+
|
|
9
|
+
Run `catalyst replica status --probe --json` before every local read.
|
|
10
|
+
|
|
11
|
+
- Read locally only when `verdict` is `fresh` and `cursor` equals `head`. That proves the copy is caught up with the cloud at that moment.
|
|
12
|
+
- `fresh` without the probe proves a live writer, not a caught-up copy.
|
|
13
|
+
- `stale` (exit 1) or `absent` (exit 3) with `configured: true` means the person opted in and the writer is down. Answer from the cloud and say the local copy is behind. `catalyst replica start --detach` restarts it, but only start it when the person asks.
|
|
14
|
+
|
|
15
|
+
Quote the cursor with any local answer, for example "from the local replica at cursor 4810".
|
|
16
|
+
|
|
17
|
+
## Two ways to read it
|
|
18
|
+
|
|
19
|
+
- `catalyst query issue <KEY-123> --source replica` reads the ticket from the local copy. A replica built by an older SDK can lack fields the cloud read has, such as `linked_pulls`. `--source replica` on an absent replica is refused, never silently answered from the API.
|
|
20
|
+
- `catalyst replica sql "<one SELECT>" --json` runs one read-only `SELECT` and prints rows. Anything other than a single `SELECT` is refused.
|
|
21
|
+
|
|
22
|
+
`catalyst replica schema` prints every table with its columns, and `catalyst replica schema <table>` prints one. Read the columns before writing SQL against a table this page does not cover.
|
|
23
|
+
|
|
24
|
+
## What the tables hold
|
|
25
|
+
|
|
26
|
+
Timestamps are milliseconds since the epoch. A row with `removed_at` set was deleted upstream, so filter `removed_at is null` for current rows.
|
|
27
|
+
|
|
28
|
+
| table | one row is | join on |
|
|
29
|
+
| -- | -- | -- |
|
|
30
|
+
| `issues` | a ticket: `identifier`, `title`, `state`, `state_type`, `assignee`, `delegate_name`, `priority`, `team_key`, `project_id`, `cycle_id`, `parent_identifier`, `updated_at` | `id` |
|
|
31
|
+
| `comments` | a comment: `body`, `author_name`, `is_bot`, `parent_id`, `created_at` | `issue_id` = `issues.id` |
|
|
32
|
+
| `issue_history` | one change to a ticket: `from_state` / `to_state` and the other `from_*` / `to_*` pairs, `created_at` | `issue_id` = `issues.id` |
|
|
33
|
+
| `relations` | a link between tickets: `type`, `issue_identifier`, `related_identifier` | identifiers |
|
|
34
|
+
| `labels`, `issue_labels` | a label, and which ticket carries it | `issue_labels.label_id` = `labels.id` |
|
|
35
|
+
| `agent_sessions` | an agent session on a ticket: `status`, `created_at` | `issue_id` = `issues.id` |
|
|
36
|
+
| `pull_requests` | a pull request that names a ticket in `linear_issue_identifier` | `linear_issue_identifier` = `issues.identifier` |
|
|
37
|
+
|
|
38
|
+
## Recipes
|
|
39
|
+
|
|
40
|
+
Replace `ENG-123` and `ENG` with the real identifier and team key.
|
|
41
|
+
|
|
42
|
+
One ticket's current fields:
|
|
43
|
+
|
|
44
|
+
```sql
|
|
45
|
+
select identifier, title, state, assignee, delegate_name, priority, updated_at
|
|
46
|
+
from issues where identifier = 'ENG-123' and removed_at is null
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The newest comments on a ticket, Catalyst's own first:
|
|
50
|
+
|
|
51
|
+
```sql
|
|
52
|
+
select c.created_at, c.author_name, c.is_bot, substr(c.body, 1, 200) as body
|
|
53
|
+
from comments c join issues i on i.id = c.issue_id
|
|
54
|
+
where i.identifier = 'ENG-123' and c.removed_at is null
|
|
55
|
+
order by c.is_bot desc, c.created_at desc limit 20
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Every state change on a ticket, oldest first:
|
|
59
|
+
|
|
60
|
+
```sql
|
|
61
|
+
select h.created_at, h.from_state, h.to_state
|
|
62
|
+
from issue_history h join issues i on i.id = h.issue_id
|
|
63
|
+
where i.identifier = 'ENG-123' and h.to_state is not null
|
|
64
|
+
order by h.created_at
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
How many tickets sit in each state on one team:
|
|
68
|
+
|
|
69
|
+
```sql
|
|
70
|
+
select state, count(*) as n from issues
|
|
71
|
+
where team_key = 'ENG' and removed_at is null
|
|
72
|
+
group by state order by n desc
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
What a ticket blocks and what blocks it:
|
|
76
|
+
|
|
77
|
+
```sql
|
|
78
|
+
select type, issue_identifier, related_identifier from relations
|
|
79
|
+
where issue_identifier = 'ENG-123' or related_identifier = 'ENG-123'
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Pull requests that name a ticket:
|
|
83
|
+
|
|
84
|
+
```sql
|
|
85
|
+
select repo_id, number, state, draft, merged, head_sha
|
|
86
|
+
from pull_requests where linear_issue_identifier = 'ENG-123'
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## What the replica does not answer
|
|
90
|
+
|
|
91
|
+
Phase attempts, remediate rounds, park state and the live lease are not in the replica. `catalyst history <KEY-123>` reads them from the cloud. So do eligibility (`catalyst explain <KEY-123>`) and search (`node scripts/search.mjs`).
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Reading ticket facts from the cloud
|
|
2
|
+
|
|
3
|
+
Cloud reads are the default on every machine. They need no local writer and no local database. Every command below reads the cloud through the `catalyst` CLI.
|
|
4
|
+
|
|
5
|
+
| question | command |
|
|
6
|
+
| -- | -- |
|
|
7
|
+
| What stage is the ticket in, who has it, which PRs name it? | `catalyst query issue <KEY-123>`, or `node scripts/read-ticket.mjs <KEY-123>` |
|
|
8
|
+
| What did Catalyst and people write on it? | `node scripts/read-ticket.mjs <KEY-123> --comments`; comments and activity come inline with the ticket |
|
|
9
|
+
| What was the last phase, and how did it end? | `catalyst history <KEY-123>` |
|
|
10
|
+
| How many remediate rounds against the cap? Is it parked, and what releases it? | `catalyst history <KEY-123>` |
|
|
11
|
+
| Why is it not running, or what runs next? | `catalyst explain <KEY-123>` |
|
|
12
|
+
| What is the PR's state, checks and reviews? | `catalyst query pulls --ticket <KEY-123>`, then `catalyst query pull <node-id>` |
|
|
13
|
+
| What changed across the account since a point? | `catalyst query changes --since head`, then the cursor it prints |
|
|
14
|
+
| Find a ticket by words | `node scripts/search.mjs <terms>` |
|
|
15
|
+
| What happened to it, event by event? | `catalyst events query --ticket <KEY-123>` |
|
|
16
|
+
| Wait until its phase finishes | `catalyst events wait-for --ticket <KEY-123> --type relay.phase.completed --after <head> --timeout 300` |
|
|
17
|
+
|
|
18
|
+
## Reading the answer
|
|
19
|
+
|
|
20
|
+
The first stderr line names the source: `source: api (...)`. Quote it when freshness matters ("from the API just now").
|
|
21
|
+
|
|
22
|
+
The ticket read returns the whole record, so a question about one field still downloads comments and activity. That is fine for one ticket. For many tickets, use a list (`catalyst query issues --team <key>`) and read one record only where the list is not enough.
|
|
23
|
+
|
|
24
|
+
A smaller read is coming: the cloud will answer a ticket or its execution history with only the status fields. No CLI flag selects it yet, so read the full record and pick the fields you need.
|
|
25
|
+
|
|
26
|
+
## Events
|
|
27
|
+
|
|
28
|
+
`catalyst events` reads the cloud by default and needs no local file.
|
|
29
|
+
|
|
30
|
+
- `catalyst events query --ticket <KEY-123>` prints the ticket's events, newest first. Add `--type`, `--limit` (up to 200), `--order asc` and `--before` or `--after` to page. An empty page says which sequences the cloud has indexed, so "no match" is not "never happened".
|
|
31
|
+
- To wait for something to happen, first run `catalyst events status --json` and keep its `head`. Then run `catalyst events wait-for --ticket <KEY-123> --type relay.phase.completed --after <head> --timeout 300`. Exit 0 prints the event, exit 1 is a timeout, and exit 4 means the cloud was unreachable.
|
|
32
|
+
- `catalyst events tail --ticket <KEY-123>` stays in the foreground and prints one JSON line per new event.
|
|
33
|
+
|
|
34
|
+
The ticket filter reads the event's ticket entity, `payload.ticket`, and the lease that caused it. `--from-cache` reads this machine's local event cache instead. It exists only where local sync is on, and it pays off when several agents on one machine share it.
|
|
35
|
+
|
|
36
|
+
## The local replica
|
|
37
|
+
|
|
38
|
+
Only on a machine where `catalyst replica status --json` reports `configured: true`, `references/local-replica.md` adds local SQL. Everywhere else, these cloud reads are the whole answer.
|
|
@@ -4,7 +4,7 @@ description: >-
|
|
|
4
4
|
Set up Catalyst Cloud and say whether setup is working. Walks a person from nothing to their first ticket running, one step at a time: the coding account, the project, the integrations and connected accounts, each repository's settings file, then one real ticket moving. Also logs this machine in, reads the readiness verdict with who can fix each failure, and checks the optional local replica. Use when someone says "set me up", "onboard me", "I just signed up", "get me started", "what do I do first", "log me in", "which account is this machine on", "am I set up", "what is missing", "why does nothing happen" or "is the replica running", when a login expired, or when a skill script exits 2 saying this machine is not connected. Does every step a key can do through the catalyst CLI, hands over the exact page for the steps only a browser can do, and never claims a step it did not watch succeed.
|
|
5
5
|
allowed-tools: Bash(catalyst:*) Bash(npx -p @catalyst-cloud/cli catalyst:*)
|
|
6
6
|
---
|
|
7
|
-
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.14.
|
|
7
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.14.9 — written in this repository for customer accounts -->
|
|
8
8
|
|
|
9
9
|
# Onboard me
|
|
10
10
|
|
|
@@ -16,7 +16,7 @@ Guide setup through the same `catalyst onboard` flow that the installer runs. Th
|
|
|
16
16
|
2. For a requested setup, run `catalyst onboard`. To inspect first, run `catalyst onboard --dry-run --json`. Resume with `catalyst onboard`; the command rechecks saved results. Do not ask the person to confirm completed browser steps or add a separate approval before the command's plan question.
|
|
17
17
|
3. In a terminal, the command shows the verified person, workspace and plan before approval. Without terminal input, or with `--json`, use `--yes` only when the person has accepted the displayed defaults; otherwise setup waits with exit 11 and keeps the saved connection and receipt. JSON keeps progress, identity, the plan and quota disclosure on stderr and returns one result on stdout. A supplied key needs `catalyst login` before onboarding; browser sign-in does not replace it.
|
|
18
18
|
4. For the current onboarding checks, run `catalyst ready --onboarding --json`. A failed check needs attention. An unknown check needs evidence. Report observed project work separately from incomplete setup; an unknown setup check does not prove work stopped.
|
|
19
|
-
5. Exit 0 completes the requested scope. Exit 10 means a failed step, 11 means waiting, and 12 means a guard refused the action. A successful `--only` step does not mean onboarding is complete. Keep the command's safe fix and supported resume command in your reply.
|
|
19
|
+
5. Exit 0 completes the requested scope. For a full run, exit 0 means work can start. If the receipt's `complete` is false, repository settings, local values, the daily update or the first ticket are still open, and the command lists them under "Next, when you want". Exit 10 means a failed step, 11 means waiting, and 12 means a guard refused the action. A successful `--only` step does not mean onboarding is complete. Keep the command's safe fix and supported resume command in your reply.
|
|
20
20
|
|
|
21
21
|
Use cloud reads for ordinary workstation setup checks. Offer local sync for local SQL or sustained local reads inside the plan review. Local sync does not promise offline browsing. It is optional; do not make an absent replica a setup failure. Browser approval belongs to the person. Missing bearer capabilities stay unfinished; never call a session-only route from the CLI or invent a command.
|
|
22
22
|
|
|
@@ -58,6 +58,7 @@ Scripts are run, never read; each prints `--help`.
|
|
|
58
58
|
| a browser step, or confirming a page that said it worked | `references/what-the-browser-owns.md` |
|
|
59
59
|
| the repository's `.catalyst/catalyst.toml` and its approval; its AGENTS.md block and agent layout | `references/declaring-a-repository.md`; `references/repository-agent-setup.md` |
|
|
60
60
|
| the replica or event cache | `references/local-sync.md` |
|
|
61
|
+
| local SQL, only when `catalyst replica status --json` reports `configured: true` | `references/local-replica.md` |
|
|
61
62
|
| installing, updating, or migrating Catalyst skills | `references/skill-sources.md` |
|
|
62
63
|
| what Catalyst is, or why the first ticket did not start | the `whats-happening` skill, then `unstick` if something holds it |
|
|
63
64
|
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Local SQL on an opted-in machine
|
|
2
|
+
|
|
3
|
+
Load this only when `catalyst replica status --json` reports `configured: true`. On any other machine, setup is complete without a replica: every skill reads from the cloud, and `references/local-sync.md` explains how a person opts in if they ask for local SQL.
|
|
4
|
+
|
|
5
|
+
`configured: true` means this machine opted in: `CATALYST_REPLICA_DB` is set, or the machine paths file declares `replicaDb`. It does not mean the writer is running. `references/local-sync.md` reads liveness and starts the writer.
|
|
6
|
+
|
|
7
|
+
## Before any query
|
|
8
|
+
|
|
9
|
+
Run `catalyst replica status --probe --json`. Trust local rows only when `verdict` is `fresh` and `cursor` equals `head`. A first start seeds the whole snapshot, so a new replica reads stale until its cursor appears.
|
|
10
|
+
|
|
11
|
+
## Running SQL
|
|
12
|
+
|
|
13
|
+
- `catalyst replica sql "<one SELECT>" --json` runs one read-only `SELECT` and prints rows. Anything else is refused.
|
|
14
|
+
- `catalyst replica schema` prints every table with its columns; `catalyst replica schema <table>` prints one.
|
|
15
|
+
- `catalyst query issues --source replica`, `issue`, `pulls` and `projects` read the local copy through the same verbs as the cloud read. Without `--source replica`, they read the cloud.
|
|
16
|
+
|
|
17
|
+
Timestamps are milliseconds since the epoch. Rows with `removed_at` set were deleted upstream.
|
|
18
|
+
|
|
19
|
+
## First checks after a start
|
|
20
|
+
|
|
21
|
+
Is the copy populated?
|
|
22
|
+
|
|
23
|
+
```sql
|
|
24
|
+
select (select count(*) from issues where removed_at is null) as tickets,
|
|
25
|
+
(select count(*) from pull_requests) as pull_requests,
|
|
26
|
+
(select count(*) from projects) as projects
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Which teams does it hold?
|
|
30
|
+
|
|
31
|
+
```sql
|
|
32
|
+
select team_key, count(*) as tickets from issues
|
|
33
|
+
where removed_at is null group by team_key order by team_key
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Compare these counts with what the person sees in Linear. A team missing here is a scope question for the account, not a replica fault.
|
|
37
|
+
|
|
38
|
+
## Where the reading recipes live
|
|
39
|
+
|
|
40
|
+
Ticket recipes are in the `catalyst-linear` skill's local replica reference, and pull request recipes in the `catalyst-github` skill's. Both carry the same gate as this page.
|
|
@@ -12,13 +12,15 @@ Local sync is opt-in. `catalyst replica status --json` carries `configured`, whi
|
|
|
12
12
|
|
|
13
13
|
`node scripts/local-sync.mjs` shows the local state. Only after the person opts in, `--start` starts the replica and event cache writers and waits up to 90 seconds (`--wait <seconds>`, 0 to 300).
|
|
14
14
|
|
|
15
|
-
Say `Local sync current` only when both writers have live heartbeats and each cursor equals its cloud head. A detached process starting, one fresh heartbeat, or replica freshness alone does not prove event freshness. `catalyst replica status --probe --json` checks the replica cursor; `catalyst events status --probe --json` checks the separate event cursor. Unknown means the comparison could not be proved, which is not stale. The script exits 0 current, 1 stale, 3 absent, and 2 for "not connected" or "unknown", with a printed reason. After a restart, check again before relying on local data.
|
|
15
|
+
Say `Local sync current` only when both writers have live heartbeats and each cursor equals its cloud head. A detached process starting, one fresh heartbeat, or replica freshness alone does not prove event freshness. `catalyst replica status --probe --json` checks the replica cursor; `catalyst events status --from-cache --probe --json` checks the separate event cursor. Unknown means the comparison could not be proved, which is not stale. The script exits 0 current, 1 stale, 3 absent, and 2 for "not connected" or "unknown", with a printed reason. After a restart, check again before relying on local data.
|
|
16
16
|
|
|
17
17
|
## First ticket event
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
The default wait reads the cloud and needs no local sync. Before the person moves a card, run `catalyst events status --json` and record its `head` as `<cursor-before-move>`. Move the card only after this baseline is captured. Then run `catalyst events wait-for --ticket <ticket-identifier> --after <cursor-before-move> --timeout 300` with the identifier `explain` printed, and no guessed event type. The explicit cursor finds an event that happened before the command began.
|
|
20
20
|
|
|
21
|
-
Exit 0 prints a matching event after the baseline
|
|
21
|
+
Exit 0 prints a matching event after the baseline. Exit 1 means no matching event arrived within five minutes; check `catalyst explain <ticket-identifier>` before inferring a cloud or webhook failure. Exit 4 means the cloud event service was unreachable: an outage, not a timeout. Other errors are unknown. `explain` stays the API-backed answer to why a ticket can or cannot run.
|
|
22
|
+
|
|
23
|
+
On a machine that opted in to local sync, the same wait can also prove the event reached this machine's cache. Run `node scripts/local-sync.mjs --start` and wait until it reports current. Then run `catalyst events status --from-cache --probe --json` and record its `cursor` as `<cursor-before-move>`. Move the card only after this baseline is captured. Then run `catalyst events wait-for --from-cache --ticket <ticket-identifier> --after <cursor-before-move> --timeout 300`. Exit 1 means no matching cached event arrived within five minutes; recheck `node scripts/local-sync.mjs` and report stale or unknown evidence without inferring a cloud or webhook failure. Exit 3 means the event cache is absent; ask before starting it.
|
|
22
24
|
|
|
23
25
|
## The writer
|
|
24
26
|
|
|
@@ -6,7 +6,7 @@ import { fileURLToPath } from "node:url";
|
|
|
6
6
|
import { cliTarget } from "./lib/cli.mjs";
|
|
7
7
|
|
|
8
8
|
const STATUS_COMMAND = ["replica", "status", "--probe", "--json"];
|
|
9
|
-
const EVENTS_COMMAND = ["events", "status", "--probe", "--json"];
|
|
9
|
+
const EVENTS_COMMAND = ["events", "status", "--from-cache", "--probe", "--json"];
|
|
10
10
|
const START_COMMAND = ["replica", "start", "--detach"];
|
|
11
11
|
const RECOVERY_COMMAND = "catalyst replica start --detach";
|
|
12
12
|
|
|
@@ -120,7 +120,7 @@ function readStatus(run) {
|
|
|
120
120
|
current: false,
|
|
121
121
|
reason: `event freshness is unknown: ${eventsResult.error || eventsResult.stderr.trim() || "invalid JSON"}`,
|
|
122
122
|
},
|
|
123
|
-
recovery: "catalyst events status --probe --json",
|
|
123
|
+
recovery: "catalyst events status --from-cache --probe --json",
|
|
124
124
|
};
|
|
125
125
|
}
|
|
126
126
|
return { status, events, assessment: assessLocalSync(status, events) };
|
|
@@ -30,7 +30,7 @@ const SPEC = {
|
|
|
30
30
|
};
|
|
31
31
|
const NOTES = [
|
|
32
32
|
"Reads, in this order: `status` (machine), `ready --json` (machine checks and project checks, kept apart),",
|
|
33
|
-
"`replica status --probe --json` and `events status --probe --json` (optional local freshness),",
|
|
33
|
+
"`replica status --probe --json` and `events status --from-cache --probe --json` (optional local freshness),",
|
|
34
34
|
"`me --json` and personal connection statuses (person), `contract --path …` for the account, the projects and the repositories,",
|
|
35
35
|
"`contract --path codingAccounts` and `accounts --json` (coding accounts, and which one needs a new credential), and each",
|
|
36
36
|
"project's hosts_current check with its fixedWhere (host), and each project's environment_declared check with its per-repository notes (repository declarations). The teams read is refreshed, so a mapping just saved reads back mapped.",
|
|
@@ -4,7 +4,7 @@ description: >-
|
|
|
4
4
|
Own one Catalyst Cloud project end to end until it closes. Use when the person says "run this project for me", "own this until it ships", "keep this moving", or hands you a project id or a set of tickets to drive. Subscribes to the account's event stream for the scope through the catalyst CLI, reacts to each change in the same turn, makes tickets ready and moves them to dispatch, parks what should stop, chases stalls, escalates inward, and keeps one status summary current. Writes to Linear as the app actor; never polls.
|
|
5
5
|
allowed-tools: Bash(catalyst:*) Bash(npx -p @catalyst-cloud/cli catalyst:*)
|
|
6
6
|
---
|
|
7
|
-
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.14.
|
|
7
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.14.9 — written in this repository for customer accounts -->
|
|
8
8
|
|
|
9
9
|
# Run this project
|
|
10
10
|
|
package/skills/unstick/SKILL.md
CHANGED
|
@@ -4,7 +4,7 @@ description: >-
|
|
|
4
4
|
Get a stuck Catalyst Cloud ticket moving again. Use when the person asks "why is this parked and can you release it?", "unpark this", "get things flowing again", "the outage is over, retry what failed", or hands you a ticket that is not moving. Reads why nothing runs and what holds the ticket through the catalyst CLI, decides whether the recorded cause is fixed, previews the release, releases every governor holding the ticket the right way (or one failure class across a team), and raises an ask only for what a person has to do. Never releases a cause it cannot show changed without saying so.
|
|
5
5
|
allowed-tools: Bash(catalyst:*) Bash(npx -p @catalyst-cloud/cli catalyst:*)
|
|
6
6
|
---
|
|
7
|
-
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.14.
|
|
7
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.14.9 — written in this repository for customer accounts -->
|
|
8
8
|
|
|
9
9
|
# Unstick
|
|
10
10
|
|
|
@@ -4,7 +4,7 @@ description: >-
|
|
|
4
4
|
The human's decision inbox on Catalyst Cloud, and the one way an agent raises a decision on their behalf. Use when the person asks "what needs me?", "what am I blocking?", or when active work is gated on a choice only they can make. Lists open asks ranked by how much open work each one holds, files an ask through the cloud's ask route with the account's own template, and records the answer so the held work releases. Never answers as the human, never duplicates an open ask.
|
|
5
5
|
allowed-tools: Bash(catalyst:*) Bash(npx -p @catalyst-cloud/cli catalyst:*)
|
|
6
6
|
---
|
|
7
|
-
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.14.
|
|
7
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.14.9 — written in this repository for customer accounts -->
|
|
8
8
|
|
|
9
9
|
# What needs me
|
|
10
10
|
|
|
@@ -4,7 +4,7 @@ description: >-
|
|
|
4
4
|
What environment variable names does this repository need, and where does each one come from? Scans the repository offline (no login, no network) and lists the names in three groups (build/test, deploy-only, bindings), each with where it was found, what uses it, and where a local value would come from. Never reads a value or prints one. Also checks the environment variable table in `.catalyst/catalyst.toml` offline. Use when someone asks "what does catalyst.env.json mean", "what env vars does this repo need", "why does the container need this", or before reviewing or writing the declaration.
|
|
5
5
|
allowed-tools: Bash(catalyst:*) Bash(npx -p @catalyst-cloud/cli catalyst:*)
|
|
6
6
|
---
|
|
7
|
-
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.14.
|
|
7
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.14.9 — written in this repository for customer accounts -->
|
|
8
8
|
|
|
9
9
|
# What this repository needs
|
|
10
10
|
|
|
@@ -4,7 +4,7 @@ description: >-
|
|
|
4
4
|
Use for "what's happening?", "where are we?", "why is that stuck?", "what closed?", "what's next?", "how does this work?", "why did it do that?", "how does it prioritise?" and "what does this setting do, where is it set?" in Catalyst Cloud, or asks for something to be done rather than known. Reads the contract via catalyst CLI. Read-only: route work/decisions, never answer as the human.
|
|
5
5
|
allowed-tools: Bash(catalyst:*) Bash(npx -p @catalyst-cloud/cli catalyst:*)
|
|
6
6
|
---
|
|
7
|
-
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.14.
|
|
7
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.14.9 — written in this repository for customer accounts -->
|
|
8
8
|
|
|
9
9
|
# What's happening
|
|
10
10
|
|
|
@@ -29,5 +29,7 @@ Comments/relations: catalyst-linear. PRs: catalyst-github. Readiness: catalyst-o
|
|
|
29
29
|
| columns or slots? | references/stages-and-mapping.md |
|
|
30
30
|
| accounts, windows, quarantine or provider? | references/coding-accounts.md |
|
|
31
31
|
| setting, screen, route or role? | references/settings-and-where-they-live.md |
|
|
32
|
+
| which command answers it from the cloud? | references/reading-from-the-cloud.md |
|
|
33
|
+
| local SQL? only if `catalyst replica status --json` says `configured: true` | references/local-replica.md |
|
|
32
34
|
|
|
33
35
|
Read-only: give ids, source, release and actor. Route releases to `unstick`, decisions to what-needs-me before defaults, ownership to run-this-project. Subscribe, never poll. Report each system cause once.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Local replica (opt-in)
|
|
2
|
+
|
|
3
|
+
Load this only when `catalyst replica status --json` reports `configured: true`. Otherwise answer from the cloud (`references/reading-from-the-cloud.md`) and never mention the replica.
|
|
4
|
+
|
|
5
|
+
The replica is an on-machine SQLite copy of the account, present only after the person opted in to local sync. It adds ad hoc SQL over the board. It never holds running work, the queue, asks, eligibility or phase history; those stay cloud reads.
|
|
6
|
+
|
|
7
|
+
## Freshness
|
|
8
|
+
|
|
9
|
+
`catalyst replica status --probe --json` first. Use local rows only when `verdict` is `fresh` and `cursor` equals `head`, and quote the cursor. `stale` or `absent` with `configured: true` means the opted-in writer is down: answer from the cloud and say so in the source clause. Start it only when asked (`catalyst replica start --detach`).
|
|
10
|
+
|
|
11
|
+
The snapshot's replica verdict line belongs in the status reply's source clause only on an opted-in machine.
|
|
12
|
+
|
|
13
|
+
## SQL
|
|
14
|
+
|
|
15
|
+
`catalyst replica sql "<one SELECT>" --json` runs one read-only `SELECT`. `catalyst replica schema <table>` prints columns. Timestamps are milliseconds since the epoch; filter `removed_at is null` for current rows. Replace `<team key>` and `KEY-123` with real values from the contract.
|
|
16
|
+
|
|
17
|
+
Cards per stage on one team:
|
|
18
|
+
|
|
19
|
+
```sql
|
|
20
|
+
select state, count(*) as n from issues
|
|
21
|
+
where team_key = '<team key>' and removed_at is null
|
|
22
|
+
group by state order by n desc
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
What closed in the last day:
|
|
26
|
+
|
|
27
|
+
```sql
|
|
28
|
+
select identifier, title, completed_at from issues
|
|
29
|
+
where completed_at > (strftime('%s', 'now') - 86400) * 1000 and removed_at is null
|
|
30
|
+
order by completed_at desc
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Stage moves in the last day, newest first:
|
|
34
|
+
|
|
35
|
+
```sql
|
|
36
|
+
select i.identifier, h.from_state, h.to_state, h.created_at
|
|
37
|
+
from issue_history h join issues i on i.id = h.issue_id
|
|
38
|
+
where h.to_state is not null and h.created_at > (strftime('%s', 'now') - 86400) * 1000
|
|
39
|
+
order by h.created_at desc limit 50
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Cards unmoved for three days in a stage, oldest first:
|
|
43
|
+
|
|
44
|
+
```sql
|
|
45
|
+
select identifier, state, updated_at from issues
|
|
46
|
+
where team_key = '<team key>' and state = '<stage name>' and removed_at is null
|
|
47
|
+
and updated_at < (strftime('%s', 'now') - 3 * 86400) * 1000
|
|
48
|
+
order by updated_at
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
An unmoved card may still be running, retrying or remediating. Check `catalyst history KEY-123` before calling it stuck.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Reading from the cloud
|
|
2
|
+
|
|
3
|
+
Cloud reads are the default everywhere and need no local writer or database. Each command reads the cloud through the CLI.
|
|
4
|
+
|
|
5
|
+
| question | command |
|
|
6
|
+
| -- | -- |
|
|
7
|
+
| ticket stage, owner, linked PRs | `catalyst query issue KEY-123` |
|
|
8
|
+
| last phase, attempts, rounds, park, lease | `catalyst history KEY-123` |
|
|
9
|
+
| why not running, what runs next | `node scripts/explain.mjs KEY-123` |
|
|
10
|
+
| running now | `catalyst running` |
|
|
11
|
+
| queue order | `catalyst queue` |
|
|
12
|
+
| PR state and checks | `catalyst query pulls --ticket KEY-123`, then `catalyst query pull <node-id>` |
|
|
13
|
+
| what changed since a point | `catalyst query changes --since head` |
|
|
14
|
+
| a ticket's events, newest first | `catalyst events query --ticket KEY-123` |
|
|
15
|
+
| wait for a phase to finish | `catalyst events wait-for --ticket KEY-123 --type relay.phase.completed --after <head> --timeout 300` |
|
|
16
|
+
|
|
17
|
+
A status-only read of a ticket and of its execution history is coming. No CLI flag selects it yet; read the full record.
|
|
18
|
+
|
|
19
|
+
Events: `catalyst events` reads the cloud by default. `events status --json` gives the `head` to wait after. Exit 4 from `wait-for` is an outage, not a timeout. `--from-cache` reads the local event cache, which exists only where local sync is on.
|
|
20
|
+
|
|
21
|
+
Local SQL: `references/local-replica.md`, only when `configured: true`.
|