@catalyst-cloud/cli 0.9.2 → 0.9.3
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 +6 -0
- package/dist/cli.js +20 -4
- package/dist/config.js +16 -0
- package/dist/execution.js +14 -2
- package/dist/skills.js +13 -1
- package/package.json +1 -1
- package/skills/catalyst-github/SKILL.md +1 -1
- package/skills/catalyst-linear/SKILL.md +1 -1
- package/skills/catalyst-onboard/SKILL.md +1 -1
- package/skills/catalyst-onboard/references/replacing-a-credential.md +5 -1
- package/skills/catalyst-onboard/scripts/where-am-i.mjs +10 -3
- package/skills/catalyst-setup/SKILL.md +1 -1
- package/skills/connect-me/SKILL.md +1 -1
- package/skills/how-catalyst-works/SKILL.md +1 -1
- package/skills/run-this-project/SKILL.md +1 -1
- package/skills/unstick/SKILL.md +1 -1
- package/skills/what-needs-me/SKILL.md +1 -1
- package/skills/whats-happening/SKILL.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.9.3
|
|
4
|
+
|
|
5
|
+
A machine the Catalyst installer moved from `@catalyst-cloud/catalyst-skills` to `@catalyst-cloud/cli` works without logging in again. The recorded launcher pointed into the removed package, so `ready` failed its CLI-path check and skill scripts could not start the CLI; any command now repoints it at the launcher that is running. The CLI also leaves the installer's skills alone: it never writes through a symlinked skill folder, and when the installer owns skill placement it does not refresh skills at all. When a refresh does fail, it tells you to re-run the install command.
|
|
6
|
+
|
|
7
|
+
Onboarding no longer tells you to re-credential an ended or cancelled coding account: it says to retire it on the AI accounts page, and such an account no longer leaves setup unfinished. Before you mint a replacement token, it has you check that your terminal is logged into the account the slot belongs to. `catalyst accounts` names each account by its label, else its email, with the slot id second, adds `displayName` to `--json`, and marks a cancelled subscription "subscription canceled — retire on the AI accounts page".
|
|
8
|
+
|
|
3
9
|
## 0.9.2
|
|
4
10
|
|
|
5
11
|
The CLI works against a tenant serving contract 2.x. Catalyst Cloud's tenant contract moved to 2.0.0 when it removed `merge.cloudRemediateRequiredChecks`, and every earlier bundle accepted only 1.x, so `ready`, onboarding and most commands stopped with "the tenant serves contract version 2.2.0 but this bundle accepts 1.x". This bundle accepts `1.x || 2.x`. The one place that read the removed field already treated it as absent.
|
package/dist/cli.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// their own modules; this file keeps every export the 0.1 tests and the bin import.
|
|
3
3
|
import { existsSync } from "node:fs";
|
|
4
4
|
import { parseArgs, positionals, verbHelp } from "./args.js";
|
|
5
|
-
import { CONFIG_MODE, DEFAULT_BASE_URL, LEGACY_PACKAGE_NAME, PACKAGE_NAME, cliPath, configPathFor, contractPathFor, defaultCtx, defaultReplicaDbFor, defaultSkillsDirFor, formatMode, loadConfig, modernCliPath, normalizeBaseUrl, readManifest, requireConfig, saveConfig, writeConfig, } from "./config.js";
|
|
5
|
+
import { CONFIG_MODE, DEFAULT_BASE_URL, LEGACY_PACKAGE_NAME, PACKAGE_NAME, cliPath, configPathFor, contractPathFor, defaultCtx, defaultReplicaDbFor, defaultSkillsDirFor, formatMode, installerOwnsSkills, INSTALL_COMMAND, loadConfig, modernCliPath, normalizeBaseUrl, readManifest, requireConfig, saveConfig, writeConfig, } from "./config.js";
|
|
6
6
|
import { loadContract, pickPath } from "./contract.js";
|
|
7
7
|
import { CliError, MeError, UsageError } from "./errors.js";
|
|
8
8
|
import { fetchMe } from "./transport.js";
|
|
@@ -100,8 +100,14 @@ function migrateLegacyCliPath(ctx) {
|
|
|
100
100
|
}
|
|
101
101
|
if (!cfg)
|
|
102
102
|
return;
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
let next = modernCliPath(cfg.cliPath);
|
|
104
|
+
// An upgrade from @catalyst-cloud/catalyst-skills to @catalyst-cloud/cli removes the old package
|
|
105
|
+
// folder, so the recorded launcher no longer exists and has no sibling. Point it at the launcher
|
|
106
|
+
// that is running now, so `ready` and every skill script work without another login.
|
|
107
|
+
if (next === null && typeof cfg.cliPath === "string" && cfg.cliPath !== "" && !existsSync(cfg.cliPath)) {
|
|
108
|
+
next = cliPath();
|
|
109
|
+
}
|
|
110
|
+
if (next === null || next === cfg.cliPath)
|
|
105
111
|
return;
|
|
106
112
|
cfg.cliPath = next;
|
|
107
113
|
try {
|
|
@@ -134,13 +140,23 @@ function maybePrintUpdateNotice(args, ctx) {
|
|
|
134
140
|
const entry = parseChangelogEntry(readChangelog(), manifest.version);
|
|
135
141
|
say(updateNoticeLine(previous, manifest.version, entry));
|
|
136
142
|
}
|
|
143
|
+
if (installerOwnsSkills(ctx.home, ctx.env)) {
|
|
144
|
+
cfg.lastSkillBundleVersion = manifest.version;
|
|
145
|
+
try {
|
|
146
|
+
saveConfig(ctx.home, cfg);
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
// Best effort: the notice prints again next time, and nothing else depends on it.
|
|
150
|
+
}
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
137
153
|
const skillsDir = resolveSkillsDir(args, ctx, cfg);
|
|
138
154
|
let refreshed;
|
|
139
155
|
try {
|
|
140
156
|
refreshed = installSkills(skillsDir, { force: false, onlyExisting: true });
|
|
141
157
|
}
|
|
142
158
|
catch (err) {
|
|
143
|
-
ctx.stderr(`[catalyst-skills] could not refresh the skills at ${skillsDir} (${err instanceof Error ? err.message : String(err)}) — the ${manifest.version} skills are not installed yet; run
|
|
159
|
+
ctx.stderr(`[catalyst-skills] could not refresh the skills at ${skillsDir} (${err instanceof Error ? err.message : String(err)}) — the ${manifest.version} skills are not installed yet; re-run the install command: ${INSTALL_COMMAND}`);
|
|
144
160
|
return;
|
|
145
161
|
}
|
|
146
162
|
if (refreshed.installed.length > 0)
|
package/dist/config.js
CHANGED
|
@@ -91,6 +91,8 @@ export function updatePackageName(root = packageRoot()) {
|
|
|
91
91
|
return LEGACY_PACKAGE_NAME;
|
|
92
92
|
return PACKAGE_NAME;
|
|
93
93
|
}
|
|
94
|
+
/** The Catalyst installer, which owns skill placement and switches a machine between packages. */
|
|
95
|
+
export const INSTALL_COMMAND = "curl -fsSL https://staging.catalystcloud.dev/install.sh | sh";
|
|
94
96
|
/** The one upgrade command every hint prints: update the installed package, then log in again so
|
|
95
97
|
* customer.json records the new launcher path. */
|
|
96
98
|
export function upgradeCommand(root) {
|
|
@@ -115,6 +117,20 @@ export function normalizeBaseUrl(url) {
|
|
|
115
117
|
export function apiBase(cfg) {
|
|
116
118
|
return `${normalizeBaseUrl(cfg.baseUrl)}/api/v1`;
|
|
117
119
|
}
|
|
120
|
+
/** True when the Catalyst installer owns skill placement on this machine: it exports
|
|
121
|
+
* CATALYST_SKILLS_DIR, or it wrote the machine paths file (every v1 record carries a skills role).
|
|
122
|
+
* The CLI then never refreshes skill folders itself; the installer's own refresh does. */
|
|
123
|
+
export function installerOwnsSkills(home, env = {}) {
|
|
124
|
+
if (env.CATALYST_SKILLS_DIR !== undefined && env.CATALYST_SKILLS_DIR !== "")
|
|
125
|
+
return true;
|
|
126
|
+
try {
|
|
127
|
+
const file = machinePathsFile({ env: { ...env, HOME: home } });
|
|
128
|
+
return Boolean(file && machineFilePresent(file));
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
118
134
|
function machineFilePresent(file) {
|
|
119
135
|
try {
|
|
120
136
|
lstatSync(file);
|
package/dist/execution.js
CHANGED
|
@@ -318,12 +318,23 @@ export const ACCOUNT_STATUS = {
|
|
|
318
318
|
attested: "attested — healthy at last check, no work observed since",
|
|
319
319
|
unobserved: "unobserved — enrolled, but nothing has been seen from it yet",
|
|
320
320
|
};
|
|
321
|
+
/** The name a person or agent calls an account by: its label, else its email, else its slot id. */
|
|
322
|
+
export function accountDisplayName(a) {
|
|
323
|
+
for (const v of [a.label, a.email])
|
|
324
|
+
if (typeof v === "string" && v.trim() !== "")
|
|
325
|
+
return v.trim();
|
|
326
|
+
return a.accountSlot ?? "?";
|
|
327
|
+
}
|
|
321
328
|
/** One slot as a line a human reads: who it is, what state it is in, and what it is spending on. */
|
|
322
329
|
export function renderAccount(a) {
|
|
323
|
-
const
|
|
330
|
+
const display = accountDisplayName(a);
|
|
331
|
+
const name = display === (a.accountSlot ?? "?") ? display : `${display} (${a.accountSlot ?? "?"})`;
|
|
324
332
|
const harness = a.harness ? `/${a.harness}` : "";
|
|
325
333
|
const status = a.status ? (ACCOUNT_STATUS[a.status] ?? a.status) : "status unknown";
|
|
326
334
|
const bits = [`${name} ${a.provider ?? "?"}${harness} ${status}`];
|
|
335
|
+
// CTC-4199: a cancelled subscription is retired, never re-credentialed; say so in the text view too.
|
|
336
|
+
if (a.renewalStatus === "canceled")
|
|
337
|
+
bits.push("subscription canceled — retire on the AI accounts page");
|
|
327
338
|
if (typeof a.bindingUsedPercent === "number") {
|
|
328
339
|
const resets = typeof a.bindingResetsAtMs === "number" ? `, resets ${new Date(a.bindingResetsAtMs).toISOString()}` : "";
|
|
329
340
|
bits.push(`usage ${a.bindingUsedPercent}% of the ${a.bindingWindow ?? "binding"} window${resets}`);
|
|
@@ -356,7 +367,8 @@ export async function cmdAccounts(args, ctx) {
|
|
|
356
367
|
throw needsNewerCloud("coding-account status", cfg);
|
|
357
368
|
const accounts = Array.isArray(res.body) ? res.body : (res.body?.accounts ?? []);
|
|
358
369
|
if (args.json) {
|
|
359
|
-
|
|
370
|
+
const named = accounts.map((a) => ({ ...a, displayName: accountDisplayName(a) }));
|
|
371
|
+
ctx.stdout(JSON.stringify(Array.isArray(res.body) ? named : { ...res.body, accounts: named }));
|
|
360
372
|
return 0;
|
|
361
373
|
}
|
|
362
374
|
if (accounts.length === 0) {
|
package/dist/skills.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// skills.ts — copying the bundled skills into the user's skills directory, and the one-line update
|
|
2
2
|
// notice a new version prints on its next session.
|
|
3
|
-
import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
3
|
+
import { cpSync, existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
import { defaultSkillsDirFor, upgradeCommand } from "./config.js";
|
|
@@ -31,6 +31,10 @@ export function installSkills(targetDir, opts, sourceDir = skillsSourceDir()) {
|
|
|
31
31
|
if (!existsSync(join(src, "SKILL.md")))
|
|
32
32
|
continue;
|
|
33
33
|
const dst = join(targetDir, name);
|
|
34
|
+
// A symlinked entry belongs to whoever linked it (the Catalyst installer links its skills in);
|
|
35
|
+
// this package never writes through one, and says nothing about it.
|
|
36
|
+
if (isSymlink(dst))
|
|
37
|
+
continue;
|
|
34
38
|
const existingMd = join(dst, "SKILL.md");
|
|
35
39
|
if (opts.onlyExisting && !existsSync(existingMd))
|
|
36
40
|
continue;
|
|
@@ -47,6 +51,14 @@ export function installSkills(targetDir, opts, sourceDir = skillsSourceDir()) {
|
|
|
47
51
|
}
|
|
48
52
|
return result;
|
|
49
53
|
}
|
|
54
|
+
function isSymlink(path) {
|
|
55
|
+
try {
|
|
56
|
+
return lstatSync(path).isSymbolicLink();
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
50
62
|
export function resolveSkillsDir(args, ctx, cfg) {
|
|
51
63
|
return args.skillsDir ?? ctx.env.CATALYST_SKILLS_CLAUDE_DIR ?? cfg?.skillsDir ?? defaultSkillsDirFor(ctx.home);
|
|
52
64
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@catalyst-cloud/cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.3",
|
|
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.
|
|
7
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.3 — 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.
|
|
8
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.3 — written in this repository for customer tenants -->
|
|
9
9
|
|
|
10
10
|
# Catalyst Linear
|
|
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.
|
|
8
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.3 — written in this repository for customer tenants -->
|
|
9
9
|
|
|
10
10
|
# Onboard me
|
|
11
11
|
|
|
@@ -34,7 +34,11 @@ Say these two things plainly:
|
|
|
34
34
|
|
|
35
35
|
## Claude
|
|
36
36
|
|
|
37
|
-
The same page takes a Claude account's new credential. Its field is "Replacement setup token".
|
|
37
|
+
The same page takes a Claude account's new credential. Its field is "Replacement setup token". `claude setup-token` mints a token for whichever Claude account the terminal is logged into, not for the slot. So first match them: read the slot's account on the AI accounts page (its label or email), then have the person run `claude` and `/status` to see the email the terminal is logged into. If they differ, stop, and log in to the slot's account first. Only then run `claude setup-token`, paste the token into that field, and press Replace credential. Then re-run the script.
|
|
38
|
+
|
|
39
|
+
## An ended or cancelled account
|
|
40
|
+
|
|
41
|
+
An account whose subscription is cancelled, or which has ended, is not a credential problem, and no token revives it. Retire it on the AI accounts page. Never replace its credential with a token from another account: that puts a working account's login onto a dead slot.
|
|
38
42
|
|
|
39
43
|
## Any other provider
|
|
40
44
|
|
|
@@ -288,7 +288,11 @@ let accountsNext = "enrol a coding account a phase can run on";
|
|
|
288
288
|
// credential itself. The poll fields are read only when the cloud sends them.
|
|
289
289
|
const CREDENTIAL_ERROR_CODES = new Set(["no_access_token", "no_credential", "http_401", "http_403", "usage_unauthorized", "usage_forbidden"]);
|
|
290
290
|
const CREDENTIAL_FAILURE_STREAK = 3;
|
|
291
|
+
// A cancelled subscription or an ended account is not a credential problem: no token brings it
|
|
292
|
+
// back. It is retired, never re-credentialed, and it does not make setup unfinished.
|
|
293
|
+
const isRetirable = (a) => a?.renewalStatus === "canceled" || a?.status === "ended" || a?.declaredState === "ended";
|
|
291
294
|
const credentialProblem = (a) => {
|
|
295
|
+
if (isRetirable(a)) return null;
|
|
292
296
|
if (a?.quarantined === true) return `quarantined${typeof a.quarantineReason === "string" && a.quarantineReason !== "" ? `: ${a.quarantineReason}` : ""}`;
|
|
293
297
|
if (a?.status === "expired-or-revoked") return "expired or revoked";
|
|
294
298
|
if (CREDENTIAL_ERROR_CODES.has(a?.lastPollErrorCode) && typeof a?.pollFailureCount === "number" && a.pollFailureCount >= CREDENTIAL_FAILURE_STREAK) {
|
|
@@ -318,18 +322,21 @@ if (!connected) {
|
|
|
318
322
|
const head = [line, `${ca.activeCount ?? "?"} active`];
|
|
319
323
|
const { rows, error } = readAccountRows();
|
|
320
324
|
const dead = rows === null ? [] : rows.filter((a) => credentialProblem(a) !== null);
|
|
325
|
+
const retirable = rows === null ? [] : rows.filter(isRetirable);
|
|
326
|
+
const who = (a) => [a.label, a.email].find((v) => typeof v === "string" && v !== "");
|
|
327
|
+
const retireLine = retirable.length === 0 ? [] : [`${retirable.length} account(s) ended or cancelled (${retirable.map((a) => `${a.provider ?? "unknown provider"} ${a.accountSlot ?? "?"}`).join(", ")}): retire them on the AI accounts page. Do not replace their credential; no token revives a cancelled subscription.`];
|
|
321
328
|
if (rows === null) {
|
|
322
329
|
accountsNext = "read the coding accounts again; each account's credential could not be checked";
|
|
323
330
|
add("coding accounts", DETAIL, "unreadable", [...head, `coding accounts could not be checked in detail (${error}). Whether each one still has a working credential is unknown. Do not enroll one on this reading.`], null, null);
|
|
324
331
|
} else if (dead.length > 0) {
|
|
325
|
-
const name = (a) => `${a.provider ?? "unknown provider"} account ${a.accountSlot ?? "?"}`;
|
|
332
|
+
const name = (a) => `${a.provider ?? "unknown provider"} account ${a.accountSlot ?? "?"}${who(a) ? ` (${who(a)})` : ""}`;
|
|
326
333
|
const more = dead.length > 1 ? ` (and ${dead.length - 1} more)` : "";
|
|
327
334
|
accountsNext = `${name(dead[0])} needs a new credential${more}. Replace it on the AI accounts page (Settings → AI accounts → the account → Replace credential). Do not enroll another account.`;
|
|
328
335
|
add(
|
|
329
336
|
"coding accounts",
|
|
330
337
|
DETAIL,
|
|
331
338
|
"unfinished",
|
|
332
|
-
[...head, ...dead.map((a) => `${name(a)} needs a new credential: ${credentialProblem(a)}`), "Replace its credential on its own page. Do not enroll another account. The steps are in references/replacing-a-credential.md."],
|
|
339
|
+
[...head, ...dead.map((a) => `${name(a)} needs a new credential: ${credentialProblem(a)}`), "Replace its credential on its own page, with a credential minted from THAT account: check the login you mint from matches the account named here first. Do not enroll another account. The steps are in references/replacing-a-credential.md.", ...retireLine],
|
|
333
340
|
owner,
|
|
334
341
|
where,
|
|
335
342
|
);
|
|
@@ -337,7 +344,7 @@ if (!connected) {
|
|
|
337
344
|
accountsNext = "replace the credential of the coding account the page marks; do not enroll another account";
|
|
338
345
|
add("coding accounts", DETAIL, "unfinished", [...head, "The contract says an account needs a new credential, and the account list does not say which. Open the page and look for it."], owner, where);
|
|
339
346
|
} else {
|
|
340
|
-
add("coding accounts", DETAIL, "ok", [...head, `${rows.length} checked, none needs a new credential
|
|
347
|
+
add("coding accounts", DETAIL, "ok", [...head, `${rows.length} checked, none needs a new credential`, ...retireLine]);
|
|
341
348
|
}
|
|
342
349
|
} else if (ca.state === "inactive") {
|
|
343
350
|
accountsNext = "reactivate a coding account that is out of rotation; do not enroll another one";
|
|
@@ -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.
|
|
7
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.3 — written in this repository for customer tenants -->
|
|
8
8
|
|
|
9
9
|
# Am I set up?
|
|
10
10
|
|
|
@@ -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.
|
|
8
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.3 — 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.
|
|
7
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.3 — written in this repository for customer tenants -->
|
|
8
8
|
|
|
9
9
|
# How Catalyst works
|
|
10
10
|
|
|
@@ -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.
|
|
8
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.3 — written in this repository for customer tenants -->
|
|
9
9
|
|
|
10
10
|
# Run this project
|
|
11
11
|
|
package/skills/unstick/SKILL.md
CHANGED
|
@@ -5,7 +5,7 @@ description: >-
|
|
|
5
5
|
disable-model-invocation: true
|
|
6
6
|
allowed-tools: Bash(catalyst-skills:*) Bash(npx @catalyst-cloud/catalyst-skills:*)
|
|
7
7
|
---
|
|
8
|
-
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.
|
|
8
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.3 — 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.
|
|
8
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.3 — 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.
|
|
7
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.9.3 — written in this repository for customer tenants -->
|
|
8
8
|
|
|
9
9
|
# What's happening
|
|
10
10
|
|