@catalyst-cloud/cli 0.9.0 → 0.9.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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.9.1
4
+
5
+ Onboarding now teaches `.catalyst/catalyst.toml`, the only file the cloud reads a repository's settings from. The skills still described `catalyst.env.json`, which the cloud has ignored since 2026-09-27, so a declaration written from them was silently dropped. The repository reference shows the file's shape (`[project]` with `linear_team`, then `[[environment.variables]]` and `[[environment.setup]]`) and the approval step: an owner or admin opens the repository's Environment page, goes to the Setup declaration tab, and clicks Approve this revision.
6
+
7
+ A ticket filed through the catalyst-linear skill now carries a description: `catalyst write create` takes `--description <text>` or `--stdin`, where before it could file only a title. The skill content never asks for a personal Linear token or a direct Linear API call.
8
+
3
9
  ## 0.9.0
4
10
 
5
11
  Onboarding now guides your own Linear and GitHub consent. `catalyst connections personal <linear|github> start` opens the provider's consent page in your browser and `status` confirms the grant landed; the tenant's own Linear connection and GitHub App install stay separate, and personal GitHub waits until the App is installed and a repository is registered.
package/README.md CHANGED
@@ -163,7 +163,7 @@ Some of these only read; the ones that write anything — or that drive you thro
163
163
 
164
164
  ## What a key cannot see yet
165
165
 
166
- Your personal key reads everything the skills need — tickets, pull requests, the eligibility explainer, the dispatch queue, fleet activity, per-ticket execution history (`catalyst-skills explain --history <ticket>`: phase attempts, remediation rounds, park state) and coding-account status (`catalyst-skills accounts`: provider, declared and observed state, window usage, walls, quarantine — never a credential; enrolling or pausing one is `<your cloud>/settings/coding-accounts`). It also releases a parked or held ticket once its cause is fixed: `catalyst-skills release <ticket> --because <what changed>` (the `unstick` skill runs it), recorded against your name and shown in the ticket's history. And it declares what your containers need: `catalyst-skills environment` reads the tenant-wide declaration, `environment propose --file <path> --approve` proposes and approves it in one compare-and-set, and the values behind the names stay in the cloud — reading needs any active seat, proposing and approving need an admin or owner one. An admin or owner can put a repository's values in from the terminal. `catalyst-skills secret import .env --repo owner/name` stores every name in the file and lists the declared names that still have no value. `catalyst-skills secret set NAME --repo owner/name --command 'op read op://Vault/item/field'` runs the command on your machine and stores its output; with no `--command` it reads the value from stdin, or asks for it without echoing. No value is ever printed, and the cloud's audit records the command, not its output. That is the account's own declaration — a repository's own `catalyst.env.json`, which `catalyst-setup` already reports on, is a separate thing. One thing it cannot do, and the skills say so by name rather than guess:
166
+ Your personal key reads everything the skills need — tickets, pull requests, the eligibility explainer, the dispatch queue, fleet activity, per-ticket execution history (`catalyst-skills explain --history <ticket>`: phase attempts, remediation rounds, park state) and coding-account status (`catalyst-skills accounts`: provider, declared and observed state, window usage, walls, quarantine — never a credential; enrolling or pausing one is `<your cloud>/settings/coding-accounts`). It also releases a parked or held ticket once its cause is fixed: `catalyst-skills release <ticket> --because <what changed>` (the `unstick` skill runs it), recorded against your name and shown in the ticket's history. And it declares what your containers need: `catalyst-skills environment` reads the tenant-wide declaration, `environment propose --file <path> --approve` proposes and approves it in one compare-and-set, and the values behind the names stay in the cloud — reading needs any active seat, proposing and approving need an admin or owner one. An admin or owner can put a repository's values in from the terminal. `catalyst-skills secret import .env --repo owner/name` stores every name in the file and lists the declared names that still have no value. `catalyst-skills secret set NAME --repo owner/name --command 'op read op://Vault/item/field'` runs the command on your machine and stores its output; with no `--command` it reads the value from stdin, or asks for it without echoing. No value is ever printed, and the cloud's audit records the command, not its output. That is the account's own declaration — a repository's own `.catalyst/catalyst.toml`, which `catalyst-setup` already reports on, is a separate thing. One thing it cannot do, and the skills say so by name rather than guess:
167
167
 
168
168
  - Read pull-request labels or the reviewer's reaction. The mirror does not carry them; GitHub's own page does.
169
169
 
package/dist/args.js CHANGED
@@ -74,7 +74,7 @@ export const FLAG_TABLES = {
74
74
  },
75
75
  write: {
76
76
  body: { value: true, help: "comment: the body text" },
77
- stdin: { value: false, help: "comment: read the body from stdin" },
77
+ stdin: { value: false, help: "comment: read the body from stdin; create: read the description from stdin" },
78
78
  parent: { value: true, help: "comment: reply under this comment id" },
79
79
  bookkeeping: { value: false, help: "comment: prefix the contract's bookkeeping marker" },
80
80
  "as-user": { value: false, help: "post with the personal identity instead of the app actor" },
@@ -85,6 +85,7 @@ export const FLAG_TABLES = {
85
85
  remove: { value: true, repeat: true, help: "label: label name or id to remove (repeatable)" },
86
86
  team: { value: true, help: "create: team key" },
87
87
  title: { value: true, help: "create/attachment/session: title" },
88
+ description: { value: true, help: "create: the ticket description (markdown)" },
88
89
  label: { value: true, repeat: true, help: "create: label name or id (repeatable)" },
89
90
  priority: { value: true, help: "create: Linear priority 0-4" },
90
91
  comment: { value: true, help: "reaction: react to this comment id instead of the ticket" },
@@ -152,7 +153,7 @@ export const VERB_USAGE = {
152
153
  running: "running [--ticket T --phase P] [--json]",
153
154
  queue: "queue [--team K] [--json]",
154
155
  watch: "watch [--team K] [--ticket T]... [--project P] [--exec CMD] [--cursor-file <path>] [--from cursor|head]",
155
- write: "write <comment <ticket> --body|--stdin [--parent] [--bookkeeping] [--as-user] | state <ticket> --slot|--state-id|--state-type | label <ticket> --add... --remove... | create --team --title [--label] [--priority] | reaction <ticket>|--comment <id> --emoji <e> | attachment <ticket> --title --url | session <ticket> [--title] [--plan-file] [--activity]>",
156
+ write: "write <comment <ticket> --body|--stdin [--parent] [--bookkeeping] [--as-user] | state <ticket> --slot|--state-id|--state-type | label <ticket> --add... --remove... | create --team --title [--description|--stdin] [--label] [--priority] | reaction <ticket>|--comment <id> --emoji <e> | attachment <ticket> --title --url | session <ticket> [--title] [--plan-file] [--activity]>",
156
157
  ask: "ask <raise --team --title [--context] [--option]... [--default] --blocks <ticket>...|--nothing-to-block [--ask-key] | accept <askTicket> --answer <commentId> --role <role> | list [--anyone] [--json]>",
157
158
  ready: "ready [--json] [--offline]",
158
159
  accounts: "accounts [--json]",
@@ -27,6 +27,10 @@ export const FORBIDDEN_CONTENT = [
27
27
  { name: "an internal ticket id", re: /\bC[TL]C-\d+\b/ },
28
28
  { name: "a Linear CLI name (linearis)", re: /linearis/i },
29
29
  { name: "the internal replica tool name (catalyst-replica)", re: /catalyst-replica/ },
30
+ // A tenant workflow writes through the tenant's agent proxy as the app actor. A personal Linear
31
+ // token, or a call straight to Linear's API, is the path these skills exist to replace.
32
+ { name: "a personal Linear API token (LINEAR_API_TOKEN / LINEAR_API_KEY)", re: /LINEAR_API_(?:TOKEN|KEY)/ },
33
+ { name: "Linear's API host (api.linear.app)", re: /api\.linear\.app/ },
30
34
  ];
31
35
  function walk(dir) {
32
36
  const out = [];
package/dist/write.js CHANGED
@@ -149,12 +149,21 @@ export async function cmdWrite(args, ctx, deps = {}) {
149
149
  const title = flagString(args, "title");
150
150
  if (!teamKey || !title)
151
151
  throw new UsageError("write create needs --team <key> and --title <text>");
152
+ let description = flagString(args, "description");
153
+ if (flagBool(args, "stdin")) {
154
+ if (description !== undefined)
155
+ throw new UsageError("write create takes --description <text> or --stdin, not both");
156
+ description = (await (deps.readStdin ?? readStdin)()).trimEnd();
157
+ if (!description)
158
+ throw new UsageError("write create --stdin read an empty description");
159
+ }
152
160
  const team = teamByKey(doc, teamKey);
153
161
  const labels = flagList(args, "label").map((n) => labelId(team, n));
154
162
  const priority = flagString(args, "priority") !== undefined ? flagInt(args, "priority", 0) : undefined;
155
163
  result = await postAgent(api, doc, "issue-create", {
156
164
  teamId: team.id,
157
165
  title,
166
+ ...(description ? { description } : {}),
158
167
  ...(labels.length ? { labelIds: labels } : {}),
159
168
  ...(priority !== undefined ? { priority } : {}),
160
169
  ...(asUser ? { createAsUser: true } : {}),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@catalyst-cloud/cli",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "description": "Customer skill bundle for Catalyst Cloud, named from the executive's seat — get set up, see what is happening, see what needs you, run a project, unstick what is stuck — plus the catalyst CLI that reads through the Catalyst Cloud SDK, writes through the agent proxy, and connects your machine to your tenant with one command. The skills directory is the roster; this line never counts it.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -4,7 +4,7 @@ description: >-
4
4
  Catalyst's GitHub: show a ticket's pull request with its checks, reviews and review threads, say whether it is mergeable under this repository's policy, and explain what a PR accumulates as the ticket moves (the branch, the draft, the rewrite, the force-pushes, the labels, the queue). Use when someone asks "show me the PR", "what are the checks saying", "why hasn't it merged", "what does the queue need", "what does that label mean", or wants the branch and merge conventions Catalyst follows.
5
5
  allowed-tools: Bash(catalyst-skills:*) Bash(npx @catalyst-cloud/catalyst-skills:*)
6
6
  ---
7
- <!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.0 — written in this repository for customer tenants -->
7
+ <!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.1 — written in this repository for customer tenants -->
8
8
 
9
9
  # Catalyst's GitHub
10
10
 
@@ -5,7 +5,7 @@ description: >-
5
5
  allowed-tools: Bash(catalyst-skills:*) Bash(npx @catalyst-cloud/catalyst-skills:*)
6
6
  disable-model-invocation: true
7
7
  ---
8
- <!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.0 — written in this repository for customer tenants -->
8
+ <!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.1 — written in this repository for customer tenants -->
9
9
 
10
10
  # Catalyst Linear
11
11
 
@@ -20,7 +20,7 @@ Run each with `--help` first; scripts are executed, never read.
20
20
  - `node scripts/comment.mjs <ticket> --body <text> [--parent <id>] [--bookkeeping]` — a comment as the app actor; a machine record takes `--bookkeeping`.
21
21
  - `node scripts/move.mjs <ticket> --slot <slot>` — a card move by slot (`--state-type backlog` parks).
22
22
  - `node scripts/label.mjs <ticket> --add <name> --remove <name>` — labels, resolved through the contract.
23
- - `node scripts/create-ticket.mjs --team <key> --title <text>` — a new ticket; cite its identifier only after it prints.
23
+ - `node scripts/create-ticket.mjs --team <key> --title <text> [--description <text> | --stdin]` — a new ticket; cite its identifier only after it prints.
24
24
 
25
25
  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
26
 
@@ -9,7 +9,7 @@ This reference restates the write mechanism. The live values it depends on — t
9
9
  | a comment, threaded or top-level | `node scripts/comment.mjs <ticket> --body <text> [--parent <commentId>] [--bookkeeping]` |
10
10
  | a card move | `node scripts/move.mjs <ticket> --slot <slot>` or `--state-type backlog` |
11
11
  | a label on or off | `node scripts/label.mjs <ticket> --add <name> --remove <name>` |
12
- | a new ticket | `node scripts/create-ticket.mjs --team <key> --title <text>` |
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
15
  Each script wraps one `catalyst-skills write` verb, which posts to the route the contract names, as the tenant's app actor, with the personal key this machine connected with — so the write carries the person's identity for attribution, and an ask names them. No script composes a URL, and none needs a Linear credential of its own.
@@ -36,7 +36,7 @@ Two labels are a human's, not yours: the release label (which frees a ticket the
36
36
 
37
37
  ## A new ticket takes the team key
38
38
 
39
- `create-ticket.mjs --team <key>` names the team by the prefix its identifiers carry; the CLI resolves the team id from the contract and the cloud fences the write to your tenant on the team, not only on the credential. Cite the identifier only after the script prints it; a guessed number is usually a real, unrelated ticket. Do not file a question for a human this way: a ticket whose text reads as a decision request is held out of dispatch by shape until someone releases it, and it would never reach the human's inbox with what it blocks.
39
+ `create-ticket.mjs --team <key>` names the team by the prefix its identifiers carry; the CLI resolves the team id from the contract and the cloud fences the write to your tenant on the team, not only on the credential. A ticket's body goes in `--description`, or on stdin with `--stdin` when it runs to several lines; a title with no body gives whoever picks the ticket up nothing to act on. Cite the identifier only after the script prints it; a guessed number is usually a real, unrelated ticket. Do not file a question for a human this way: a ticket whose text reads as a decision request is held out of dispatch by shape until someone releases it, and it would never reach the human's inbox with what it blocks.
40
40
 
41
41
  ## What is never offered
42
42
 
@@ -2,14 +2,17 @@
2
2
  // create-ticket.mjs — file a new ticket on a team as the app actor. The team is named by its key;
3
3
  // the CLI resolves the team id from the contract. A decision for a human is NOT a ticket filed here:
4
4
  // that is an ask, raised through the what-needs-me skill so it carries options, a default and blocks.
5
+ import { readFileSync } from "node:fs";
5
6
  import { exitOnFailure, parseFlags, parseJson, relayStderr, runCli, usage, wantsHelp } from "./lib/cli.mjs";
6
7
 
7
- const HELP = `Usage: node scripts/create-ticket.mjs --team <key> --title <text> [--label <name|id>]... [--priority <0-4>] [--as-user] [--json]
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]
8
9
 
9
10
  Creates one ticket. Wraps: catalyst-skills write create. Spends one unit of the daily write budget.
10
11
 
11
12
  --team <key> the team key (the prefix of its ticket identifiers)
12
13
  --title <text> the ticket title
14
+ --description <text> the ticket description, in markdown
15
+ --stdin read the description from stdin instead (for a multi-line body)
13
16
  --label <name|id> a label to apply (repeatable); Catalyst label names resolve via the contract
14
17
  --priority <0-4> Linear priority: 0 none, 1 urgent, 2 high, 3 medium, 4 low
15
18
  --as-user create with the personal identity instead of the app actor (rare)
@@ -26,14 +29,22 @@ if (wantsHelp(argv)) {
26
29
  console.log(HELP);
27
30
  process.exit(0);
28
31
  }
29
- const { flags } = parseFlags(argv, { bool: ["as-user", "json"], value: ["team", "title", "priority"], repeat: ["label"] });
32
+ const { flags } = parseFlags(argv, { bool: ["stdin", "as-user", "json"], value: ["team", "title", "description", "priority"], repeat: ["label"] });
30
33
  if (!flags.team || !flags.title) usage("create-ticket needs --team <key> and --title <text> (see --help)");
34
+ if (flags.description && flags.stdin) usage("give --description or --stdin, not both");
31
35
 
32
36
  const args = ["write", "create", "--team", flags.team, "--title", flags.title, "--json"];
37
+ if (flags.description) args.push("--description", flags.description);
38
+ let stdin;
39
+ if (flags.stdin) {
40
+ stdin = readFileSync(0, "utf8");
41
+ if (!stdin.trim()) usage("stdin was empty");
42
+ args.push("--stdin");
43
+ }
33
44
  for (const l of flags.label ?? []) args.push("--label", l);
34
45
  if (flags.priority !== undefined) args.push("--priority", flags.priority);
35
46
  if (flags["as-user"]) args.push("--as-user");
36
- const r = runCli(args);
47
+ const r = runCli(args, { stdin });
37
48
  exitOnFailure(r);
38
49
  relayStderr(r);
39
50
  const result = parseJson(r.stdout);
@@ -5,7 +5,7 @@ description: >-
5
5
  disable-model-invocation: true
6
6
  allowed-tools: Bash(catalyst-skills:*) Bash(npx @catalyst-cloud/catalyst-skills:*)
7
7
  ---
8
- <!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.0 — written in this repository for customer tenants -->
8
+ <!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.1 — written in this repository for customer tenants -->
9
9
 
10
10
  # Onboard me
11
11
 
@@ -8,15 +8,36 @@ The cloud containers build and test the repository. They need the names of the v
8
8
  2. For each name, record the file it came from: a `.env.example` (never `.env`, which holds live values), a CI secret in a workflow's `env:` block, or a platform binding. A name you cannot tie to a file is a guess. Say so instead of listing it.
9
9
  3. Mark whether the container needs it to build and test, or only to deploy. Containers build and test. They do not deploy.
10
10
  4. Leave platform bindings and deploy-only CI secrets out by default. The platform supplies a binding at run time, and no build or test reads a deploy-only secret. Include one only when the person says the build needs it, and say why.
11
- 5. Write the names into `catalyst.env.json` at the repository root and open a pull request. Use that exact name and place; the cloud reads no other file. It reads the file once the pull request merges to the default branch. A tenant owner or admin then approves it at Settings → Repositories → the repository → Environment, and the person enters the values on that page.
11
+ 5. Write the names into `.catalyst/catalyst.toml` and open a pull request. Use that exact path. The cloud reads no other file, and an older `catalyst.env.json` is ignored. Once the pull request merges, each push to the default branch that touches the file makes the cloud read it and propose it as a new revision. A tenant owner or admin opens Settings → Repositories → the repository → Environment → Setup declaration and clicks Approve this revision. The person enters the values on the same page's Environment variables and Secrets tabs.
12
12
 
13
13
  ## The file's shape
14
14
 
15
- `"version": 1` plus eight arrays, each present even when empty: `toolchains`, `systemPackages`, `setup`, `verify`, `services`, `environment`, `agentAssets`, `provenance`. The repository's Environment page in the app shows a complete, valid example. Start from it rather than from memory.
15
+ `[project]` with `linear_team` is required. Every other section is optional. The names a build needs go under `[environment]`:
16
16
 
17
- - `setup` and `verify` carry this repository's own install and test commands. `command` is an argument list, not a shell string.
18
- - Each name under `environment` says whether it is `required`. Add `"secret": true` beside a secret.
19
- - Each `provenanceIds` entry points at a record under `provenance` that names the file the name came from.
17
+ ```toml
18
+ #:schema https://staging.catalystcloud.dev/schemas/catalyst.schema.json
19
+
20
+ [project]
21
+ linear_team = "ENG"
22
+
23
+ [[environment.variables]]
24
+ name = "DATABASE_URL"
25
+ required = true
26
+
27
+ [[environment.variables]]
28
+ name = "STRIPE_API_KEY"
29
+ required = true
30
+ secret = true
31
+
32
+ [[environment.setup]]
33
+ name = "install"
34
+ run = ["npm", "ci"]
35
+ ```
36
+
37
+ - `linear_team` is the key of the Linear team this repository's work belongs to.
38
+ - Each `[[environment.variables]]` entry names one variable and says whether it is `required`. Add `secret = true` for a secret. Names only: a value never goes in this file.
39
+ - `[[environment.setup]]` steps carry this repository's own install commands. `run` is an argument list, not a shell string, and `name` is kebab-case. `verify` steps have the same shape and carry the test commands. `toolchains`, `system_packages`, `services` and the other `[environment]` tables are optional; the schema lists their fields.
40
+ - The `#:schema` line lets an editor check the file as you type.
20
41
 
21
42
  ## After the merge
22
43
 
@@ -118,7 +118,7 @@ Add `--approve` to approve exactly the revision that propose just returned, whic
118
118
 
119
119
  **Owner:** you can read it from any active seat; proposing and approving need an admin or owner seat, and the cloud refuses with that sentence if the person does not have one — read the refusal to them rather than retrying.
120
120
 
121
- ⛔ **Values never pass through you.** The declaration carries the *names* a build needs. The values are entered by the person, once, in the app, and nothing you run ever sees them. Say that plainly; a person asked for a secret by an agent is right to be suspicious. The names one repository needs go in its own committed `catalyst.env.json`. See `references/declaring-a-repository.md`.
121
+ ⛔ **Values never pass through you.** The declaration carries the *names* a build needs. The values are entered by the person, once, in the app, and nothing you run ever sees them. Say that plainly; a person asked for a secret by an agent is right to be suspicious. The names one repository needs go in its own committed `.catalyst/catalyst.toml`. See `references/declaring-a-repository.md`.
122
122
 
123
123
  If they do not know what their build needs yet, skip this step. It blocks nothing until a phase needs a secret.
124
124
 
@@ -26,7 +26,7 @@ These are settings pages today because the routes behind them take a browser ses
26
26
  | checking a project's readiness, or re-checking it | the same page | "I can read the verdict your tenant last stored, from the contract. Asking for a fresh check is on that page." |
27
27
  | mapping stages, or adopting the workflow | the same page, per project | "Pick one project, then **Map my stages** — or **Adopt the Catalyst workflow** if you want Catalyst's stages created for you." |
28
28
  | registering a repository | `<their cloud>/settings/repositories` | "Add the repository here, and attach it to the project you just mapped, in the same form." |
29
- | approving the environment **for one repository**, and entering its values | that repository's environment section under `<their cloud>/settings/repositories` | "The names come from `catalyst.env.json` in the repository, which I can write with you. Approving it and entering the values happen here, once, by you. Nothing I run ever sees a value." (Account-wide names are **not** on this list: `catalyst-skills environment` does those.) |
29
+ | approving the environment **for one repository**, and entering its values | that repository's Environment page under `<their cloud>/settings/repositories`: the Setup declaration tab's Approve this revision button approves, and the Environment variables and Secrets tabs take the values | "The names come from `.catalyst/catalyst.toml` in the repository, which I can write with you. Approving it and entering the values happen here, once, by you. Nothing I run ever sees a value." (Account-wide names are **not** on this list: `catalyst-skills environment` does those.) |
30
30
 
31
31
  ⛔ **Do not compose a request for any of these.** A skill script never makes a request of its own; only the CLI does, and the CLI has no verb for them. If you find yourself constructing a URL, stop.
32
32
 
@@ -4,7 +4,7 @@ description: >-
4
4
  Am I set up? Machine readiness (Node, the tenant connection, the cached contract, the CLI path, the skills, the SDK, the optional replica) plus tenant readiness from the contract's per-team checks, in one verdict: what passes, what is blocked, what is merely waiting, and who can click what. Use when someone asks "am I set up", "what is missing", "why does nothing happen", "is the replica running", or right after connecting a new machine. Reports; never repairs.
5
5
  allowed-tools: Bash(catalyst-skills:*) Bash(npx @catalyst-cloud/catalyst-skills:*)
6
6
  ---
7
- <!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.0 — written in this repository for customer tenants -->
7
+ <!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.1 — written in this repository for customer tenants -->
8
8
 
9
9
  # Am I set up?
10
10
 
@@ -22,7 +22,7 @@ The contract's `readinessChecks[]` is the list of record. A check that appears t
22
22
  | `writes_land` | Catalyst has written to this team successfully | "no write observed" is waiting, not failing: it clears the first time Catalyst moves a ticket. "Write refused" means Linear rejected the last write: check the connection and the team's permissions | owner or admin when refused; otherwise nobody |
23
23
  | `webhook_covers_team` | events for this team are arriving | confirmed once a repository is registered and events flow; "no delivery observed" is waiting | owner or admin, by registering the repository |
24
24
  | `hosts_current` | no connected host runs an older mapping revision | a host that is behind re-loads the mapping on its next connect; a host that did not report its revision is flagged rather than assumed current; "no host connected" is waiting | whoever runs that host |
25
- | `environment_declared` | a committed environment declaration for the team's default repository is in effect (`catalyst.env.json` at the repository root was ingested, is valid, and its latest proposal is approved) | `no_team_repo_default`: register a repository and make it the team's default; `no_environment_declaration`: commit the declaration file to that repository; `declaration_invalid` / `declaration_read_failed`: fix the file (the ingest names the error); `declaration_awaiting_approval`: an owner or admin approves the proposal in Settings → Environment | owner or admin, except committing the file, which is whoever can push to the repository |
25
+ | `environment_declared` | a committed environment declaration for the team's default repository is in effect (`.catalyst/catalyst.toml` on the default branch was ingested, is valid, and its latest proposal is approved) | `no_team_repo_default`: register a repository and make it the team's default; `no_environment_declaration`: commit `.catalyst/catalyst.toml` with its `[environment]` names to that repository's default branch; `declaration_invalid` / `declaration_read_failed`: fix the file (the ingest names the error); `declaration_awaiting_approval`: an owner or admin opens Settings → Repositories → the repository → Environment → Setup declaration and clicks Approve this revision | owner or admin, except committing the file, which is whoever can push to the repository |
26
26
  | `tools_resolvable` | every MCP server and CLI the team's approved environment declaration names can be resolved for that team's repository | `tool_reference_unresolved`: the declaration names a vault secret that does not exist — add it at the right scope or correct the declaration; `toolchain_cli_missing`: a declared CLI is not in the runner image, which is not self-service; `tool_declarations_unread` reads as `unknown` and clears itself | owner or admin, in the declaration or Settings → Environment |
27
27
  | `reviewer_required` | this team's repository can merge under its own merge policy with the reviewers configured | it fails only under a strict merge policy with no reviewer — configure one at Settings → Repositories → Code reviews, or change the repository's merge policy; work still runs, only the merge waits | owner or admin, in settings |
28
28
  | `reviewer_configured` | a code reviewer is configured for this team's repository at all, whatever the current policy requires | a *failing* `reviewer_configured` never blocks or degrades a team — with no reviewer, pull requests merge on green checks and resolved threads alone; configure one at Settings → Repositories → Code reviews. An `unknown` one (`merge_reviewer_unread`: the reviewer registry could not be read) still degrades the team, like any unknown | owner or admin, in settings; nobody is required when it fails |
@@ -5,7 +5,7 @@ description: >-
5
5
  disable-model-invocation: true
6
6
  allowed-tools: Bash(catalyst-skills:*) Bash(npx @catalyst-cloud/catalyst-skills:*)
7
7
  ---
8
- <!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.0 — written in this repository for customer tenants -->
8
+ <!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.1 — written in this repository for customer tenants -->
9
9
 
10
10
  # Connect me
11
11
 
@@ -4,7 +4,7 @@ description: >-
4
4
  How Catalyst Cloud runs a ticket on the customer's own tenant, as facts an agent loads on demand: the eight-phase ladder and what each phase produces, the eleven board slots and this team's live stage map, what happens when a phase fails (retry, backoff, Remediate, park), how the queue is ordered and routed and every reason a ticket is excluded, and the coding-account model. Use when a person asks "how does this work?", "why did it do that?", "why is this stuck?", "what runs next?" or "how does it prioritise?". Read-only; its scripts explain one ticket's eligibility in plain English, show what is running and queued, and print the tenant's stage map and thresholds straight from the contract.
5
5
  allowed-tools: Bash(catalyst-skills:*) Bash(npx @catalyst-cloud/catalyst-skills:*)
6
6
  ---
7
- <!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.0 — written in this repository for customer tenants -->
7
+ <!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.1 — written in this repository for customer tenants -->
8
8
 
9
9
  # How Catalyst works
10
10
 
@@ -30,7 +30,7 @@ The contract's `teams[].workflowMode` reports which one a team is in:
30
30
 
31
31
  `teams[].gitAutomation` is a stored consent for a feature that is not built yet (Catalyst managing a team's Linear git automations); nothing reads it, so `off` never stops work and turning it on would start none. What decides whether a team's tickets start is the mapping above: until dispatch, pr, done and canceled each point at a live stage, Catalyst starts nothing in that team, and `explain` says so by name.
32
32
 
33
- Stage mappings live in the app, at Settings → Linear teams. The cloud does not read `.catalyst/catalyst.toml` yet, so a mapping written there changes nothing today. An older `.catalyst/config.json` is not imported.
33
+ Stage mappings live in the app, at Settings → Linear teams. The cloud reads each repository's `.catalyst/catalyst.toml`, but that file has no stage-mapping section, so a mapping written there changes nothing. An older `.catalyst/config.json` is not imported.
34
34
 
35
35
  ## The state id is the authority; names are display
36
36
 
@@ -5,7 +5,7 @@ description: >-
5
5
  disable-model-invocation: true
6
6
  allowed-tools: Bash(catalyst-skills:*) Bash(npx @catalyst-cloud/catalyst-skills:*)
7
7
  ---
8
- <!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.0 — written in this repository for customer tenants -->
8
+ <!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.1 — written in this repository for customer tenants -->
9
9
 
10
10
  # Run this project
11
11
 
@@ -5,7 +5,7 @@ description: >-
5
5
  disable-model-invocation: true
6
6
  allowed-tools: Bash(catalyst-skills:*) Bash(npx @catalyst-cloud/catalyst-skills:*)
7
7
  ---
8
- <!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.0 — written in this repository for customer tenants -->
8
+ <!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.1 — written in this repository for customer tenants -->
9
9
 
10
10
  # Unstick
11
11
 
@@ -5,7 +5,7 @@ description: >-
5
5
  disable-model-invocation: true
6
6
  allowed-tools: Bash(catalyst-skills:*) Bash(npx @catalyst-cloud/catalyst-skills:*)
7
7
  ---
8
- <!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.0 — written in this repository for customer tenants -->
8
+ <!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.1 — written in this repository for customer tenants -->
9
9
 
10
10
  # What needs me
11
11
 
@@ -4,7 +4,7 @@ description: >-
4
4
  The desk for a Catalyst Cloud tenant. Use when the person asks "what's happening?", "where are we?", "why is that stuck?", "what closed?", "what's next?", or asks for something to be done rather than known. Reads the tenant contract, what is running and queued, the eligibility explainer and the open asks through the catalyst-skills CLI, and answers in one reply with ticket ids. Routes work to a project owner and decisions to what-needs-me. Never composes a URL, never polls, never answers as the human.
5
5
  allowed-tools: Bash(catalyst-skills:*) Bash(npx @catalyst-cloud/catalyst-skills:*)
6
6
  ---
7
- <!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.0 — written in this repository for customer tenants -->
7
+ <!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.1 — written in this repository for customer tenants -->
8
8
 
9
9
  # What's happening
10
10