@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
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// is-it-mergeable.mjs — the three legs of merge evidence for one PR (checks, reviewer signal,
|
|
3
3
|
// unresolved threads) judged under the policy the tenant contract resolves for its repository, plus
|
|
4
4
|
// the prerequisites a queue applies before any leg counts (open, not a draft, no conflict). Every
|
|
5
|
-
// input comes from `catalyst
|
|
5
|
+
// input comes from `catalyst query`, `contract` and, when fresh, `replica sql`.
|
|
6
6
|
// Exit 0 no leg is red, 1 a leg or prerequisite is red, 2 this machine is not connected.
|
|
7
7
|
import { parseJson, runCli, runCliOrExit } from "./lib/cli.mjs";
|
|
8
8
|
import { resolvePull, truthy } from "./lib/pull.mjs";
|
|
@@ -34,7 +34,7 @@ if (!target) {
|
|
|
34
34
|
const { ticket, detail } = resolvePull(target);
|
|
35
35
|
const merge = parseJson(runCliOrExit(["contract", "--path", "merge", "--json"]).stdout);
|
|
36
36
|
if (!merge || !Array.isArray(merge.policies)) {
|
|
37
|
-
console.error("the contract's merge block did not parse; run: catalyst
|
|
37
|
+
console.error("the contract's merge block did not parse; run: catalyst contract --refresh");
|
|
38
38
|
process.exit(1);
|
|
39
39
|
}
|
|
40
40
|
|
|
@@ -103,7 +103,7 @@ if (replica && replica.verdict === "fresh") {
|
|
|
103
103
|
else if (unknown > 0) add("threads", "inconclusive", `${unknown} thread(s) with no resolved flag mirrored`);
|
|
104
104
|
else add("threads", "pass", `${count(1)} thread(s), all resolved (ancestry against force-pushes is judged by the cloud, not here)`);
|
|
105
105
|
} else {
|
|
106
|
-
add("threads", "inconclusive", `the PR detail carries no thread count and the replica is ${replica?.verdict ?? "unavailable"}; start it (catalyst
|
|
106
|
+
add("threads", "inconclusive", `the PR detail carries no thread count and the replica is ${replica?.verdict ?? "unavailable"}; start it (catalyst replica start --detach) for a local read`);
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
const failed = legs.filter((l) => l.state === "fail");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// lib/cli.mjs — the one way a skill script reaches the Catalyst Cloud SDK and API: by spawning the
|
|
3
|
-
// catalyst
|
|
3
|
+
// catalyst CLI this bundle installed. It reads customer.json to find that CLI and nothing
|
|
4
4
|
// else; it never holds the key itself. This file is a library — run a sibling script with
|
|
5
5
|
// --help for usage. Identical in every skill of this bundle on purpose (skills install one directory
|
|
6
6
|
// at a time, so nothing shared outside the skill would ever be installed).
|
|
@@ -10,7 +10,9 @@ import { join } from "node:path";
|
|
|
10
10
|
import { fileURLToPath } from "node:url";
|
|
11
11
|
import { CONNECT_COMMAND, hasCredential } from "./credential.mjs";
|
|
12
12
|
|
|
13
|
-
export const PACKAGE = "@catalyst-cloud/
|
|
13
|
+
export const PACKAGE = "@catalyst-cloud/cli";
|
|
14
|
+
/** The package ships two commands, so npx needs the one to run named: `npx -p <package> catalyst`. */
|
|
15
|
+
export const NPX_ARGS = ["-p", PACKAGE, "catalyst"];
|
|
14
16
|
export const CONNECT_HINT = `this machine is not connected to a tenant yet — run: ${CONNECT_COMMAND}`;
|
|
15
17
|
|
|
16
18
|
/** ~/.config/catalyst-cloud/customer.json, honouring CATALYST_SKILLS_HOME before HOME. */
|
|
@@ -41,15 +43,15 @@ export function requireCustomerConfig() {
|
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
/**
|
|
44
|
-
* Run one catalyst
|
|
45
|
-
* connect step recorded in customer.json; falls back to `npx @catalyst-cloud/catalyst
|
|
46
|
+
* Run one catalyst verb and return {code, stdout, stderr}. Spawns the CLI whose path the
|
|
47
|
+
* connect step recorded in customer.json; falls back to `npx -p @catalyst-cloud/cli catalyst` when
|
|
46
48
|
* no path is recorded or it no longer exists. Exits 2 when the machine is not connected.
|
|
47
49
|
*/
|
|
48
50
|
export function runCli(args, opts = {}) {
|
|
49
51
|
const cfg = requireCustomerConfig();
|
|
50
52
|
const recorded = typeof cfg.cliPath === "string" && existsSync(cfg.cliPath);
|
|
51
53
|
const command = recorded ? process.execPath : process.platform === "win32" ? "npx.cmd" : "npx";
|
|
52
|
-
const argv = recorded ? [cfg.cliPath, ...args] : [
|
|
54
|
+
const argv = recorded ? [cfg.cliPath, ...args] : [...NPX_ARGS, ...args];
|
|
53
55
|
const res = spawnSync(command, argv, {
|
|
54
56
|
encoding: "utf8",
|
|
55
57
|
input: opts.stdin,
|
|
@@ -58,7 +60,7 @@ export function runCli(args, opts = {}) {
|
|
|
58
60
|
shell: !recorded && process.platform === "win32",
|
|
59
61
|
});
|
|
60
62
|
if (res.error) {
|
|
61
|
-
console.error(`could not run ${recorded ? cfg.cliPath : `npx ${PACKAGE}`}: ${res.error.message}`);
|
|
63
|
+
console.error(`could not run ${recorded ? cfg.cliPath : `npx -p ${PACKAGE} catalyst`}: ${res.error.message}`);
|
|
62
64
|
process.exit(2);
|
|
63
65
|
}
|
|
64
66
|
return { code: res.status ?? 1, stdout: res.stdout ?? "", stderr: res.stderr ?? "" };
|
|
@@ -72,7 +74,7 @@ export function runCli(args, opts = {}) {
|
|
|
72
74
|
export function runCliOrExit(args, opts = {}) {
|
|
73
75
|
const res = runCli(args, opts);
|
|
74
76
|
if (res.code === 0) return res;
|
|
75
|
-
const why = res.stderr.trim() || res.stdout.trim() || `catalyst
|
|
77
|
+
const why = res.stderr.trim() || res.stdout.trim() || `catalyst ${args.join(" ")} exited ${res.code}`;
|
|
76
78
|
console.error(why);
|
|
77
79
|
process.exit(res.code === 2 ? 2 : 1);
|
|
78
80
|
}
|
|
@@ -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,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// read-pr.mjs — one ticket's pull request (or one PR by node id) as the mirror holds it: state,
|
|
3
3
|
// branch, head, base, linked ticket and its stage, GitHub's own mergeable verdict, every check,
|
|
4
|
-
// review and commit status. Reads through `catalyst
|
|
4
|
+
// review and commit status. Reads through `catalyst query`; composes no URL.
|
|
5
5
|
import { linkedPulls, resolvePull, truthy } from "./lib/pull.mjs";
|
|
6
6
|
|
|
7
7
|
const HELP = `Usage: node scripts/read-pr.mjs <ticket | pr-node-id> [--all] [--json]
|
|
8
8
|
|
|
9
9
|
<ticket> a ticket identifier such as ABC-123: its open PR is shown (else the merged one, else the newest)
|
|
10
|
-
<pr-node-id> a GitHub pull-request node id, as printed by "catalyst
|
|
10
|
+
<pr-node-id> a GitHub pull-request node id, as printed by "catalyst query pulls"
|
|
11
11
|
--all for a ticket: list every PR that names it instead of one detail
|
|
12
12
|
--json print the raw detail document instead of the summary
|
|
13
13
|
|
|
@@ -1,26 +1,25 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: catalyst-linear
|
|
3
3
|
description: >-
|
|
4
|
-
Catalyst's view of Linear on the customer's own
|
|
5
|
-
allowed-tools: Bash(catalyst
|
|
6
|
-
disable-model-invocation: true
|
|
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 local replica when it is fresh and the origin-fresh API otherwise, 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
|
+
allowed-tools: Bash(catalyst:*) Bash(npx -p @catalyst-cloud/cli catalyst:*)
|
|
7
6
|
---
|
|
8
|
-
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.
|
|
7
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.13.1 — written in this repository for customer accounts -->
|
|
9
8
|
|
|
10
9
|
# Catalyst Linear
|
|
11
10
|
|
|
12
|
-
You read tickets and write to them
|
|
11
|
+
You read tickets and write to them in the person's cloud account, as Catalyst. Reads come from the replica when it is fresh, else the API, and name their source. Writes go out as the app actor, with routes, stage ids, label ids and the bookkeeping marker resolved from the contract by the `catalyst` CLI.
|
|
13
12
|
|
|
14
13
|
## Run first
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
Scripts are run, never read; each prints `--help`.
|
|
17
16
|
|
|
18
|
-
- `node scripts/read-ticket.mjs <ticket> [--comments]
|
|
19
|
-
- `node scripts/search.mjs <terms
|
|
20
|
-
- `node scripts/comment.mjs <ticket> --body <text> [--parent <id>] [--bookkeeping]
|
|
21
|
-
- `node scripts/move.mjs <ticket> --slot <slot
|
|
22
|
-
- `node scripts/label.mjs <ticket> --add <name> --remove <name
|
|
23
|
-
- `node scripts/create-ticket.mjs --team <key> --title <text> [--description <text> | --stdin]
|
|
17
|
+
- `node scripts/read-ticket.mjs <ticket> [--comments]`: one ticket, everything inline, source line on stderr.
|
|
18
|
+
- `node scripts/search.mjs <terms>`: tickets, PRs, projects, initiatives matching the terms.
|
|
19
|
+
- `node scripts/comment.mjs <ticket> --body <text> [--parent <id>] [--bookkeeping]`: a comment as the app actor.
|
|
20
|
+
- `node scripts/move.mjs <ticket> --slot <slot>`: a card move by slot (`--state-type backlog` parks).
|
|
21
|
+
- `node scripts/label.mjs <ticket> --add <name> --remove <name>`: labels, resolved through the contract.
|
|
22
|
+
- `node scripts/create-ticket.mjs --team <key> --title <text> [--description <text> | --stdin]`: a new ticket; cite its identifier only after it prints.
|
|
24
23
|
|
|
25
24
|
Exit codes: 0 done, 1 not found or a usage error, 2 this machine is not connected or the write was refused (budget spent, slot unmapped, label absent; the one line printed says which).
|
|
26
25
|
|
|
@@ -34,10 +33,9 @@ Exit codes: 0 done, 1 not found or a usage error, 2 this machine is not connecte
|
|
|
34
33
|
|
|
35
34
|
## Rules
|
|
36
35
|
|
|
37
|
-
- **Read before acting.**
|
|
38
|
-
- **
|
|
39
|
-
- **
|
|
40
|
-
- **
|
|
41
|
-
- **
|
|
42
|
-
- **
|
|
43
|
-
- **One write per need, no loops.** Writes spend a daily budget the contract names; batch, and report a refusal rather than retrying.
|
|
36
|
+
- **Read before acting.** Read the description and the thread, never just the title. Cite identifiers and comment ids only after a script printed them, and quote the source line when freshness matters.
|
|
37
|
+
- **Reply where it arrived, as Catalyst.** Thread under the comment you answer (`--parent`); the human speaks for themselves.
|
|
38
|
+
- **Records carry the marker.** A merge note, a state-move log, a chain summary: `--bookkeeping`. A real question is not bookkeeping.
|
|
39
|
+
- **Move by slot, label by contract.** Moving to `dispatch` dispatches; the backlog-type state parks.
|
|
40
|
+
- **A decision is an ask, not a ticket.** Raise it through `what-needs-me`; a question filed as a ticket is held out of dispatch by shape.
|
|
41
|
+
- **One write per need.** Every write is visible in the person's Linear and spends the contract's daily budget; batch, and report a refusal once. A move into dispatch starts paid work on a coding account.
|
|
@@ -3,4 +3,4 @@ interface:
|
|
|
3
3
|
short_description: "Read a ticket and what Catalyst wrote on it; comment, move, label and file tickets as the app actor"
|
|
4
4
|
default_prompt: "Use $catalyst-linear to show me the ticket, its history, and what Catalyst wrote on it."
|
|
5
5
|
policy:
|
|
6
|
-
allow_implicit_invocation:
|
|
6
|
+
allow_implicit_invocation: true
|
|
@@ -1,24 +1,20 @@
|
|
|
1
1
|
# Reading a ticket: freshness first, then the row
|
|
2
2
|
|
|
3
|
-
This reference restates invariants about how a read is made and reported. Nothing in it is a tenant value.
|
|
4
|
-
|
|
5
3
|
## Freshness first
|
|
6
4
|
|
|
7
5
|
Every `query` verb, and therefore `node scripts/read-ticket.mjs` and `node scripts/search.mjs`, prints one stderr line before the answer:
|
|
8
6
|
|
|
9
|
-
- `source: replica (cursor N)
|
|
10
|
-
- `source: api (replica stale
|
|
11
|
-
- `source: api (<verb> is api-only)
|
|
7
|
+
- `source: replica (cursor N)`: the local replica was fresh, so the answer is local and cheap.
|
|
8
|
+
- `source: api (replica stale|absent|not configured)`: the answer came from the origin-fresh cloud API; a stale replica always falls back.
|
|
9
|
+
- `source: api (<verb> is api-only)`: search, cycles, pull detail and change feeds never come from the replica.
|
|
12
10
|
|
|
13
|
-
|
|
11
|
+
Quote the source when a fact's freshness matters ("as of the replica at cursor N", "from the API just now").
|
|
14
12
|
|
|
15
13
|
`--source replica` or `--source api` forces one. Forcing the replica when it is absent or stale is refused.
|
|
16
14
|
|
|
17
15
|
## Then the row
|
|
18
16
|
|
|
19
|
-
One
|
|
20
|
-
|
|
21
|
-
The summary the script prints puts the counts first and the description last; `--comments` prints every comment with its id, author, time and whether the author is a bot. A comment with a `reply-to` marker is threaded under another; reply under the same parent when you answer it.
|
|
17
|
+
One read returns the whole record inline: fields, description, `labels[]`, `relations[]`, `linked_pulls[]`, `comments[]`, `activity[]` and `agent_sessions[]`, plus project, cycle, team, delegate and parent. `--comments` prints every comment with its id, author, time and bot flag; a comment with a `reply-to` marker is threaded, so reply under the same parent.
|
|
22
18
|
|
|
23
19
|
## Reading Catalyst's own writes
|
|
24
20
|
|
|
@@ -28,25 +24,12 @@ The comment shapes in `references/what-a-ticket-accumulates.md` tell you which c
|
|
|
28
24
|
2. Remediate-attempt comments give the failure class each round repaired.
|
|
29
25
|
3. The projection-link comments name the documents; open the document (it is attached to the ticket) to read what a phase actually concluded. A fallback comment carries the body inline instead.
|
|
30
26
|
4. `linked_pulls[]` names the PR; `catalyst-github` reads it.
|
|
31
|
-
5. For "what will it do next", leave this skill: `
|
|
32
|
-
|
|
33
|
-
## When to read a transcript
|
|
34
|
-
|
|
35
|
-
A phase's transcript (the full session log) exists in the cloud per ticket, but this bundle has no verb for it yet. Read the artifact document first; it is the phase's own account of what it did. Reach for the transcript only when the document leaves the question open, and say that the bundle cannot fetch it so the human opens it from the ticket's attachments.
|
|
27
|
+
5. For "what will it do next", leave this skill: `whats-happening` explains the eligibility row.
|
|
36
28
|
|
|
37
|
-
|
|
29
|
+
The attempt ledger, the round count against the cap, and park state come from `catalyst explain --history <ticket>`; read the count there rather than reconstructing it from comments. A phase's full transcript has no verb in this bundle: read the artifact document first, and if it leaves the question open, say the human can open the transcript from the ticket.
|
|
38
30
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
## How to cite
|
|
42
|
-
|
|
43
|
-
- Cite a ticket by its identifier (`KEY-123`), never by title alone, and only after you read it back from a script's output.
|
|
44
|
-
- Cite a comment by its id when you refer to it or reply under it.
|
|
45
|
-
- Cite a document by the title the projection comment gave it.
|
|
46
|
-
- Never summarise a ticket from its title. Read the description and the thread.
|
|
31
|
+
Cite a ticket by its identifier (`KEY-123`), a comment by its id, and a document by the title its projection comment gave it.
|
|
47
32
|
|
|
48
33
|
## Searching and listing
|
|
49
34
|
|
|
50
|
-
`node scripts/search.mjs <terms>` matches
|
|
51
|
-
|
|
52
|
-
A list verb now says when the cloud cut it short: without `--all`, `query issues`/`query pulls` print `truncated at N of M` on stderr the moment a scope holds more than one page. `query issues --all` and `query pulls --all` follow the cloud's page cursor to the end of the scope instead of stopping at the first page — use `--all` when the count, not just a sample, has to be right.
|
|
35
|
+
`node scripts/search.mjs <terms>` matches identifiers, titles, PR titles, and project and initiative names. It is the only search: a filtered list hands back its first page, which reads as a false "not found". Lists (`catalyst query issues --team <key>`, `query projects`, `query cycles`) are board views. A list cut short prints `truncated at N of M` on stderr; `query issues --all` and `query pulls --all` follow the page cursor to the end, for when the count has to be right.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# What a ticket accumulates as Catalyst works it
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The shapes of what the cloud writes onto a ticket are the same for every account. The live values (the bookkeeping marker and the label names) are on the contract under `vocabulary` and `teams[].labels`; print them with `catalyst contract --path vocabulary` and `catalyst contract --path teams`. Never quote a marker or a label id from memory.
|
|
4
4
|
|
|
5
5
|
## Comments the cloud posts
|
|
6
6
|
|
|
@@ -18,7 +18,7 @@ Every one of these is posted by the app actor and is skipped by the comment-wake
|
|
|
18
18
|
|
|
19
19
|
## One document per phase, attached
|
|
20
20
|
|
|
21
|
-
Each artifact-bearing phase (research, plan, implement, validate, pr, remediate) projects its artifact into Linear as a document at a deterministic id, titled `<TICKET> · <phase> · attempt <n> · <YYYY-MM-DD>`, attached to the ticket, and announced by the projection-link comment above. Research and plan documents on a ticket that belongs to a project are also linked from the project. The same body is committed into the
|
|
21
|
+
Each artifact-bearing phase (research, plan, implement, validate, pr, remediate) projects its artifact into Linear as a document at a deterministic id, titled `<TICKET> · <phase> · attempt <n> · <YYYY-MM-DD>`, attached to the ticket, and announced by the projection-link comment above. Research and plan documents on a ticket that belongs to a project are also linked from the project. The same body is committed into the account's thoughts repository when one is configured. Reading the document is how you read what a phase concluded; the phase-outcome comment only summarises it.
|
|
22
22
|
|
|
23
23
|
## The agent session
|
|
24
24
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Writing to Linear: identity, budget, slots, labels
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The CLI reads the route table, write budget, stage map and label ids from the contract on every write; nothing here is a literal to copy.
|
|
4
4
|
|
|
5
5
|
## Every write is one script
|
|
6
6
|
|
|
@@ -12,21 +12,19 @@ This reference restates the write mechanism. The live values it depends on — t
|
|
|
12
12
|
| a new ticket | `node scripts/create-ticket.mjs --team <key> --title <text> [--description <text> \| --stdin]` |
|
|
13
13
|
| a decision for a human | not here: the `what-needs-me` skill raises an ask with options, a default and what it blocks |
|
|
14
14
|
|
|
15
|
-
Each script wraps one `catalyst
|
|
15
|
+
Each script wraps one `catalyst write` verb, which posts to the contract's route as the app actor with this machine's personal key, so the write is attributed to the person.
|
|
16
16
|
|
|
17
17
|
## App actor versus personal identity
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Reply where the message arrived: a comment inside a thread is answered with `--parent <commentId>`, in that thread, and never as a new ticket. Never post as the human; you speak as Catalyst, or as yourself by role.
|
|
19
|
+
Writes go out as the app actor by default, which the comment-wake trigger recognises as not human, so an app-actor comment never wakes an agent and reads as Catalyst speaking. `--as-user` switches a comment or new ticket to the person's identity; use it only when they asked for that attribution, and then mark any machine record with `--bookkeeping`, because it is otherwise indistinguishable from them typing it. Answer a thread in that thread with `--parent <commentId>`.
|
|
22
20
|
|
|
23
21
|
## The daily write budget
|
|
24
22
|
|
|
25
|
-
Every write
|
|
23
|
+
Every write spends one unit of the per-host daily budget (`thresholds.hostDailyWriteBudget`), a label call one unit whatever its count; reads spend none. A spent budget exits 2 naming the retry time: report it, and batch into fewer writes.
|
|
26
24
|
|
|
27
25
|
## State moves are by slot, never by name
|
|
28
26
|
|
|
29
|
-
`--slot <slot>`
|
|
27
|
+
`--slot <slot>` resolves to the team's live state id from the contract, and refuses when the slot is unmapped or its state is gone (re-map first: `catalyst team map <KEY>`). Moving to `dispatch` dispatches work. `--state-type backlog` resolves the team's first backlog-type state and parks the card, stopping remediation rounds. Names are display fields that survive re-imports while ids do not, so there is no move by name.
|
|
30
28
|
|
|
31
29
|
## Labels are by contract id
|
|
32
30
|
|
|
@@ -36,8 +34,8 @@ Two labels are a human's, not yours: the release label (which frees a ticket the
|
|
|
36
34
|
|
|
37
35
|
## A new ticket takes the team key
|
|
38
36
|
|
|
39
|
-
`create-ticket.mjs --team <key>`
|
|
37
|
+
`create-ticket.mjs --team <key>` takes the identifier prefix; the CLI resolves the team from the contract. Give it a body (`--description`, or `--stdin` for several lines), since a bare title leaves nothing to act on. Cite the identifier only after the script prints it; a guessed number is usually a real, unrelated ticket. A question for a human filed this way is held out of dispatch by shape and never reaches their inbox; raise it through `what-needs-me`.
|
|
40
38
|
|
|
41
39
|
## What is never offered
|
|
42
40
|
|
|
43
|
-
|
|
41
|
+
Delegating a ticket to an agent is an operator action. The human answers their own asks (`what-needs-me` records the acceptance). Another actor's comment cannot be edited.
|
|
@@ -7,7 +7,7 @@ import { exitOnFailure, parseFlags, parseJson, relayStderr, runCli, usage, wants
|
|
|
7
7
|
|
|
8
8
|
const HELP = `Usage: node scripts/comment.mjs <ticket> (--body <text> | --stdin) [--parent <commentId>] [--bookkeeping] [--as-user] [--json]
|
|
9
9
|
|
|
10
|
-
Posts one comment on a ticket. Wraps: catalyst
|
|
10
|
+
Posts one comment on a ticket. Wraps: catalyst write comment. Spends one unit of the tenant's
|
|
11
11
|
daily write budget.
|
|
12
12
|
|
|
13
13
|
<ticket> the Linear identifier, e.g. KEY-123
|
|
@@ -7,7 +7,7 @@ import { exitOnFailure, parseFlags, parseJson, relayStderr, runCli, usage, wants
|
|
|
7
7
|
|
|
8
8
|
const HELP = `Usage: node scripts/create-ticket.mjs --team <key> --title <text> [--description <text> | --stdin] [--label <name|id>]... [--priority <0-4>] [--as-user] [--json]
|
|
9
9
|
|
|
10
|
-
Creates one ticket. Wraps: catalyst
|
|
10
|
+
Creates one ticket. Wraps: catalyst write create. Spends one unit of the daily write budget.
|
|
11
11
|
|
|
12
12
|
--team <key> the team key (the prefix of its ticket identifiers)
|
|
13
13
|
--title <text> the ticket title
|
|
@@ -5,7 +5,7 @@ import { exitOnFailure, parseFlags, parseJson, relayStderr, runCli, usage, wants
|
|
|
5
5
|
|
|
6
6
|
const HELP = `Usage: node scripts/label.mjs <ticket> [--add <name|id>]... [--remove <name|id>]... [--json]
|
|
7
7
|
|
|
8
|
-
Adds and/or removes labels. Wraps: catalyst
|
|
8
|
+
Adds and/or removes labels. Wraps: catalyst write label. One write-budget unit per call
|
|
9
9
|
direction (add, remove), whatever the label count.
|
|
10
10
|
|
|
11
11
|
<ticket> the Linear identifier, e.g. KEY-123
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// lib/cli.mjs — the one way a skill script reaches Catalyst Cloud: it spawns the catalyst
|
|
2
|
+
// lib/cli.mjs — the one way a skill script reaches Catalyst Cloud: it spawns the catalyst CLI
|
|
3
3
|
// this machine connected with (the path recorded in customer.json, else npx) and hands back its
|
|
4
4
|
// output. Scripts import it; a person runs it with --help to see what it does. No dependencies.
|
|
5
5
|
import { spawnSync } from "node:child_process";
|
|
@@ -8,7 +8,9 @@ import { join } from "node:path";
|
|
|
8
8
|
import { pathToFileURL } from "node:url";
|
|
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 CONNECT_HINT = CONNECT_COMMAND;
|
|
13
15
|
|
|
14
16
|
/** ~/.config/catalyst-cloud/customer.json, honouring CATALYST_SKILLS_HOME (used by tests) over HOME. */
|
|
@@ -39,8 +41,8 @@ export function notConfigured(reason) {
|
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
/**
|
|
42
|
-
* Run one catalyst
|
|
43
|
-
* the config recorded one that still exists, else `npx @catalyst-cloud/catalyst
|
|
44
|
+
* Run one catalyst verb. Returns { code, stdout, stderr }. The CLI is `node <cliPath>` when
|
|
45
|
+
* the config recorded one that still exists, else `npx -p @catalyst-cloud/cli catalyst`.
|
|
44
46
|
* Exits 2 (not configured) before spawning anything when the config is absent or unreadable.
|
|
45
47
|
*/
|
|
46
48
|
export function runCli(args, { stdin } = {}) {
|
|
@@ -55,7 +57,7 @@ export function runCli(args, { stdin } = {}) {
|
|
|
55
57
|
argv = [cfg.cliPath, ...args];
|
|
56
58
|
} else {
|
|
57
59
|
cmd = process.platform === "win32" ? "npx.cmd" : "npx";
|
|
58
|
-
argv = [
|
|
60
|
+
argv = [...NPX_ARGS, ...args];
|
|
59
61
|
shell = process.platform === "win32";
|
|
60
62
|
}
|
|
61
63
|
const r = spawnSync(cmd, argv, {
|
|
@@ -152,8 +154,8 @@ if (runDirectly) {
|
|
|
152
154
|
[
|
|
153
155
|
"lib/cli.mjs — shared helper for this skill's scripts (not a command of its own)",
|
|
154
156
|
"",
|
|
155
|
-
"Reads ~/.config/catalyst-cloud/customer.json and runs the catalyst
|
|
156
|
-
`(or npx ${PACKAGE} when no path is recorded). Exit 2 when the machine is not connected.`,
|
|
157
|
+
"Reads ~/.config/catalyst-cloud/customer.json and runs the catalyst CLI recorded there",
|
|
158
|
+
`(or npx -p ${PACKAGE} catalyst when no path is recorded). Exit 2 when the machine is not connected.`,
|
|
157
159
|
"",
|
|
158
160
|
`Connect first with: ${CONNECT_HINT}`,
|
|
159
161
|
`Config in use: ${configPath()}`,
|
|
@@ -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) {
|
|
@@ -5,7 +5,7 @@ import { exitOnFailure, parseFlags, parseJson, relayStderr, runCli, usage, wants
|
|
|
5
5
|
|
|
6
6
|
const HELP = `Usage: node scripts/move.mjs <ticket> (--slot <slot> | --state-type <type>) [--json]
|
|
7
7
|
|
|
8
|
-
Moves a ticket's card. Wraps: catalyst
|
|
8
|
+
Moves a ticket's card. Wraps: catalyst write state. Spends one unit of the daily write budget.
|
|
9
9
|
|
|
10
10
|
<ticket> the Linear identifier, e.g. KEY-123
|
|
11
11
|
--slot <slot> one of the eleven slots: dispatch, intake, research, plan, implement,
|
|
@@ -6,7 +6,7 @@ import { parseFlags, parseJson, relayStderr, runCli, usage, wantsHelp } from "./
|
|
|
6
6
|
|
|
7
7
|
const HELP = `Usage: node scripts/read-ticket.mjs <ticket> [--comments] [--source replica|api] [--json]
|
|
8
8
|
|
|
9
|
-
Reads one ticket record. Wraps: catalyst
|
|
9
|
+
Reads one ticket record. Wraps: catalyst query issue.
|
|
10
10
|
|
|
11
11
|
<ticket> the Linear identifier, e.g. KEY-123
|
|
12
12
|
--comments also print every comment (id, author, time, body)
|
|
@@ -6,7 +6,7 @@ import { exitOnFailure, parseFlags, parseJson, relayStderr, runCli, usage, wants
|
|
|
6
6
|
const HELP = `Usage: node scripts/search.mjs <terms...> [--limit <n>] [--json]
|
|
7
7
|
|
|
8
8
|
Searches your tenant for tickets, pull requests, projects and initiatives matching the terms.
|
|
9
|
-
Wraps: catalyst
|
|
9
|
+
Wraps: catalyst query search.
|
|
10
10
|
|
|
11
11
|
<terms> one or more words; matched against identifiers, titles and names
|
|
12
12
|
--limit <n> max rows (default 50)
|