@blxzer/cursor-trellis 0.3.4 → 0.3.6
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 +46 -0
- package/README.md +13 -13
- package/README.zh-CN.md +1 -1
- package/bin/cstl.js +1 -1
- package/bin/smart-search.js +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +17 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/campaign/canvas-render.d.ts +68 -0
- package/dist/commands/campaign/canvas-render.d.ts.map +1 -0
- package/dist/commands/campaign/canvas-render.js +414 -0
- package/dist/commands/campaign/canvas-render.js.map +1 -0
- package/dist/commands/campaign/compose.d.ts +15 -0
- package/dist/commands/campaign/compose.d.ts.map +1 -0
- package/dist/commands/campaign/compose.js +110 -0
- package/dist/commands/campaign/compose.js.map +1 -0
- package/dist/commands/campaign/index.d.ts +13 -0
- package/dist/commands/campaign/index.d.ts.map +1 -0
- package/dist/commands/campaign/index.js +134 -0
- package/dist/commands/campaign/index.js.map +1 -0
- package/dist/commands/campaign/kind-map.d.ts +6 -0
- package/dist/commands/campaign/kind-map.d.ts.map +1 -0
- package/dist/commands/campaign/kind-map.js +21 -0
- package/dist/commands/campaign/kind-map.js.map +1 -0
- package/dist/commands/campaign/mcp-server.d.ts +6 -0
- package/dist/commands/campaign/mcp-server.d.ts.map +1 -0
- package/dist/commands/campaign/mcp-server.js +167 -0
- package/dist/commands/campaign/mcp-server.js.map +1 -0
- package/dist/commands/campaign/render.d.ts +5 -0
- package/dist/commands/campaign/render.d.ts.map +1 -0
- package/dist/commands/campaign/render.js +103 -0
- package/dist/commands/campaign/render.js.map +1 -0
- package/dist/commands/campaign/trellis-load.d.ts +13 -0
- package/dist/commands/campaign/trellis-load.d.ts.map +1 -0
- package/dist/commands/campaign/trellis-load.js +122 -0
- package/dist/commands/campaign/trellis-load.js.map +1 -0
- package/dist/commands/campaign/types.d.ts +61 -0
- package/dist/commands/campaign/types.d.ts.map +1 -0
- package/dist/commands/campaign/types.js +3 -0
- package/dist/commands/campaign/types.js.map +1 -0
- package/dist/commands/goal/index.d.ts +3 -0
- package/dist/commands/goal/index.d.ts.map +1 -0
- package/dist/commands/goal/index.js +159 -0
- package/dist/commands/goal/index.js.map +1 -0
- package/dist/commands/goal/review.d.ts +6 -0
- package/dist/commands/goal/review.d.ts.map +1 -0
- package/dist/commands/goal/review.js +28 -0
- package/dist/commands/goal/review.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +11 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/rpc/client.d.ts +51 -0
- package/dist/commands/rpc/client.d.ts.map +1 -0
- package/dist/commands/rpc/client.js +147 -0
- package/dist/commands/rpc/client.js.map +1 -0
- package/dist/commands/rpc/index.d.ts +10 -0
- package/dist/commands/rpc/index.d.ts.map +1 -0
- package/dist/commands/rpc/index.js +157 -0
- package/dist/commands/rpc/index.js.map +1 -0
- package/dist/commands/rpc/serve.d.ts +23 -0
- package/dist/commands/rpc/serve.d.ts.map +1 -0
- package/dist/commands/rpc/serve.js +60 -0
- package/dist/commands/rpc/serve.js.map +1 -0
- package/dist/commands/rpc/smoke.d.ts +16 -0
- package/dist/commands/rpc/smoke.d.ts.map +1 -0
- package/dist/commands/rpc/smoke.js +92 -0
- package/dist/commands/rpc/smoke.js.map +1 -0
- package/dist/commands/sdk/index.d.ts +9 -0
- package/dist/commands/sdk/index.d.ts.map +1 -0
- package/dist/commands/sdk/index.js +58 -0
- package/dist/commands/sdk/index.js.map +1 -0
- package/dist/commands/sdk/run.d.ts +42 -0
- package/dist/commands/sdk/run.d.ts.map +1 -0
- package/dist/commands/sdk/run.js +220 -0
- package/dist/commands/sdk/run.js.map +1 -0
- package/dist/commands/sdk/status.d.ts +14 -0
- package/dist/commands/sdk/status.d.ts.map +1 -0
- package/dist/commands/sdk/status.js +69 -0
- package/dist/commands/sdk/status.js.map +1 -0
- package/dist/configurators/workflow.d.ts.map +1 -1
- package/dist/configurators/workflow.js +13 -1
- package/dist/configurators/workflow.js.map +1 -1
- package/dist/goal/action-packet.d.ts +89 -0
- package/dist/goal/action-packet.d.ts.map +1 -0
- package/dist/goal/action-packet.js +113 -0
- package/dist/goal/action-packet.js.map +1 -0
- package/dist/goal/audit.d.ts +14 -0
- package/dist/goal/audit.d.ts.map +1 -0
- package/dist/goal/audit.js +12 -0
- package/dist/goal/audit.js.map +1 -0
- package/dist/goal/constants.d.ts +26 -0
- package/dist/goal/constants.d.ts.map +1 -0
- package/dist/goal/constants.js +24 -0
- package/dist/goal/constants.js.map +1 -0
- package/dist/goal/paths.d.ts +8 -0
- package/dist/goal/paths.d.ts.map +1 -0
- package/dist/goal/paths.js +36 -0
- package/dist/goal/paths.js.map +1 -0
- package/dist/goal/preflight.d.ts +21 -0
- package/dist/goal/preflight.d.ts.map +1 -0
- package/dist/goal/preflight.js +97 -0
- package/dist/goal/preflight.js.map +1 -0
- package/dist/goal/review-seam.d.ts +44 -0
- package/dist/goal/review-seam.d.ts.map +1 -0
- package/dist/goal/review-seam.js +153 -0
- package/dist/goal/review-seam.js.map +1 -0
- package/dist/goal/reviewer-rules.d.ts +13 -0
- package/dist/goal/reviewer-rules.d.ts.map +1 -0
- package/dist/goal/reviewer-rules.js +153 -0
- package/dist/goal/reviewer-rules.js.map +1 -0
- package/dist/goal/reviewer.d.ts +9 -0
- package/dist/goal/reviewer.d.ts.map +1 -0
- package/dist/goal/reviewer.js +54 -0
- package/dist/goal/reviewer.js.map +1 -0
- package/dist/goal/runtime.d.ts +32 -0
- package/dist/goal/runtime.d.ts.map +1 -0
- package/dist/goal/runtime.js +242 -0
- package/dist/goal/runtime.js.map +1 -0
- package/dist/goal/sdk-client.d.ts +10 -0
- package/dist/goal/sdk-client.d.ts.map +1 -0
- package/dist/goal/sdk-client.js +34 -0
- package/dist/goal/sdk-client.js.map +1 -0
- package/dist/goal/state.d.ts +40 -0
- package/dist/goal/state.d.ts.map +1 -0
- package/dist/goal/state.js +37 -0
- package/dist/goal/state.js.map +1 -0
- package/dist/goal/task-triggers.d.ts +15 -0
- package/dist/goal/task-triggers.d.ts.map +1 -0
- package/dist/goal/task-triggers.js +23 -0
- package/dist/goal/task-triggers.js.map +1 -0
- package/dist/goal/walls.d.ts +12 -0
- package/dist/goal/walls.d.ts.map +1 -0
- package/dist/goal/walls.js +65 -0
- package/dist/goal/walls.js.map +1 -0
- package/dist/goal/worker-prompt.d.ts +13 -0
- package/dist/goal/worker-prompt.d.ts.map +1 -0
- package/dist/goal/worker-prompt.js +41 -0
- package/dist/goal/worker-prompt.js.map +1 -0
- package/dist/goal/worker.d.ts +42 -0
- package/dist/goal/worker.d.ts.map +1 -0
- package/dist/goal/worker.js +180 -0
- package/dist/goal/worker.js.map +1 -0
- package/dist/migrations/manifests/0.3.5.json +9 -0
- package/dist/migrations/manifests/0.3.6.json +9 -0
- package/dist/templates/common/bundled-skills/smart-search-cli/SKILL.md +35 -29
- package/dist/templates/common/bundled-skills/smart-search-cli/references/cli-contract.md +11 -25
- package/dist/templates/common/commands/continue.md +15 -3
- package/dist/templates/common/skills/check.md +7 -4
- package/dist/templates/cursor/agents/cstl-check.md +1 -0
- package/dist/templates/cursor/fixtures/expected-rules.d.ts.map +1 -1
- package/dist/templates/cursor/fixtures/expected-rules.js +6 -1
- package/dist/templates/cursor/fixtures/expected-rules.js.map +1 -1
- package/dist/templates/cursor/rules/cstl-cursor-modes.mdc +32 -0
- package/dist/templates/cursor/rules/cstl-triage.mdc +2 -4
- package/dist/templates/cursor/rules/retrieval-routing.mdc +26 -7
- package/dist/templates/markdown/agents.md +2 -0
- package/dist/templates/markdown/index.d.ts +3 -0
- package/dist/templates/markdown/index.d.ts.map +1 -1
- package/dist/templates/markdown/index.js +3 -0
- package/dist/templates/markdown/index.js.map +1 -1
- package/dist/templates/markdown/spec/guides/cursor-context-injection-guide.md.txt +38 -21
- package/dist/templates/markdown/spec/guides/cursor-native-modes-guide.md.txt +125 -0
- package/dist/templates/markdown/spec/guides/index.md.txt +107 -104
- package/dist/templates/markdown/spec/guides/injection-budget-guide.md.txt +111 -0
- package/dist/templates/markdown/spec/guides/retrieval-daily-guide.md.txt +38 -6
- package/dist/templates/markdown/spec/guides/verification-strength-guide.md.txt +184 -0
- package/dist/templates/shared-hooks/session-start.py +10 -0
- package/dist/templates/trellis/config.yaml +18 -0
- package/dist/templates/trellis/index.d.ts +5 -0
- package/dist/templates/trellis/index.d.ts.map +1 -1
- package/dist/templates/trellis/index.js +14 -0
- package/dist/templates/trellis/index.js.map +1 -1
- package/dist/templates/trellis/scripts/common/artifact_locale.py +278 -0
- package/dist/templates/trellis/scripts/common/codebase_retrieval_router.py +51 -2
- package/dist/templates/trellis/scripts/common/config.py +39 -0
- package/dist/templates/trellis/scripts/common/injection_budget.py +317 -0
- package/dist/templates/trellis/scripts/common/parent_orchestration.py +500 -5
- package/dist/templates/trellis/scripts/common/retrieval_agent_instructions.py +9 -3
- package/dist/templates/trellis/scripts/common/session_context.py +32 -4
- package/dist/templates/trellis/scripts/common/session_memory.py +26 -0
- package/dist/templates/trellis/scripts/common/subagent_dispatch.py +74 -9
- package/dist/templates/trellis/scripts/common/task_context.py +18 -0
- package/dist/templates/trellis/scripts/common/task_dashboard.py +16 -1
- package/dist/templates/trellis/scripts/common/task_map.py +670 -614
- package/dist/templates/trellis/scripts/common/task_store.py +191 -40
- package/dist/templates/trellis/scripts/common/test_observable_defaults.py +135 -0
- package/dist/templates/trellis/scripts/cursor_retrieval_probe_prompt.md +14 -12
- package/dist/templates/trellis/scripts/generate_dispatch_prompt.py +182 -0
- package/dist/templates/trellis/scripts/injection_budget_probe.py +69 -0
- package/dist/templates/trellis/scripts/retrieval_probe_matrix_template.json +3 -3
- package/dist/templates/trellis/scripts/spec_health_outcomes.py +160 -0
- package/dist/templates/trellis/scripts/task.py +51 -0
- package/dist/templates/trellis/tasks/locale/en/default-prd.md +19 -0
- package/dist/templates/trellis/tasks/locale/zh/default-prd.md +19 -0
- package/dist/templates/trellis/workflow.md +23 -3
- package/dist/utils/codebase-retrieval-router.d.ts.map +1 -1
- package/dist/utils/codebase-retrieval-router.js +14 -0
- package/dist/utils/codebase-retrieval-router.js.map +1 -1
- package/dist/utils/cursor-sdk-gate.d.ts +10 -0
- package/dist/utils/cursor-sdk-gate.d.ts.map +1 -0
- package/dist/utils/cursor-sdk-gate.js +32 -0
- package/dist/utils/cursor-sdk-gate.js.map +1 -0
- package/dist/utils/project-capabilities.d.ts +30 -3
- package/dist/utils/project-capabilities.d.ts.map +1 -1
- package/dist/utils/project-capabilities.js +182 -11
- package/dist/utils/project-capabilities.js.map +1 -1
- package/dist/utils/readiness.d.ts.map +1 -1
- package/dist/utils/readiness.js +26 -0
- package/dist/utils/readiness.js.map +1 -1
- package/package.json +4 -3
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
import { execFileSync, spawn } from "node:child_process";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { findHarnessRoot } from "./trellis-load.js";
|
|
6
|
+
/**
|
|
7
|
+
* Cursor project slug for `~/.cursor/projects/<slug>/`.
|
|
8
|
+
* Example: `D:\\MyHarness` → `d-MyHarness`.
|
|
9
|
+
*/
|
|
10
|
+
export function cursorProjectSlug(absPath) {
|
|
11
|
+
const normalized = path.resolve(absPath).replace(/\\/g, "/");
|
|
12
|
+
const win = normalized.match(/^([A-Za-z]):\/(.*)$/);
|
|
13
|
+
if (win) {
|
|
14
|
+
const drive = win[1].toLowerCase();
|
|
15
|
+
const rest = win[2].replace(/\/+/g, "-").replace(/^-|-$/g, "");
|
|
16
|
+
return rest ? `${drive}-${rest}` : drive;
|
|
17
|
+
}
|
|
18
|
+
return normalized.replace(/^\//, "").replace(/\/+/g, "-");
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Resolve the Cursor canvases directory for a harness root.
|
|
22
|
+
* When harness is known, always returns `~/.cursor/projects/<slug>/canvases`
|
|
23
|
+
* (directory need not exist yet — callers mkdir on write).
|
|
24
|
+
* Returns null only when neither env override nor harness root is available.
|
|
25
|
+
*/
|
|
26
|
+
export function resolveCanvasesDir(harnessRoot) {
|
|
27
|
+
const fromEnv = process.env.TRELLIS_CAMPAIGN_CANVAS_DIR?.trim() ||
|
|
28
|
+
process.env.CURSOR_CANVAS_DIR?.trim();
|
|
29
|
+
if (fromEnv)
|
|
30
|
+
return path.resolve(fromEnv);
|
|
31
|
+
if (!harnessRoot)
|
|
32
|
+
return null;
|
|
33
|
+
const slug = process.env.TRELLIS_CURSOR_PROJECT_SLUG?.trim() ||
|
|
34
|
+
cursorProjectSlug(harnessRoot);
|
|
35
|
+
const candidate = path.join(os.homedir(), ".cursor", "projects", slug, "canvases");
|
|
36
|
+
if (fs.existsSync(candidate))
|
|
37
|
+
return candidate;
|
|
38
|
+
// Soft match unusual project folder names; if projects root is missing, still
|
|
39
|
+
// return the candidate so write can mkdir.
|
|
40
|
+
const projectsRoot = path.join(os.homedir(), ".cursor", "projects");
|
|
41
|
+
if (fs.existsSync(projectsRoot)) {
|
|
42
|
+
const soft = softMatchCanvasesDir(projectsRoot, slug, harnessRoot);
|
|
43
|
+
if (soft)
|
|
44
|
+
return soft;
|
|
45
|
+
}
|
|
46
|
+
return candidate;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Soft-match `~/.cursor/projects/<name>/canvases` when the exact slug folder
|
|
50
|
+
* is missing or differently cased / hyphenated.
|
|
51
|
+
* Does **not** pick longer nested names (e.g. `d-MyHarness-Trellis` for harness
|
|
52
|
+
* `D:\\MyHarness`) — those would steal writes from the canonical slug mkdir path.
|
|
53
|
+
* Skips pure-numeric agent project ids.
|
|
54
|
+
*/
|
|
55
|
+
export function softMatchCanvasesDir(projectsRoot, slug, _harnessRoot) {
|
|
56
|
+
let entries;
|
|
57
|
+
try {
|
|
58
|
+
entries = fs.readdirSync(projectsRoot, { withFileTypes: true });
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
const dirs = entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
64
|
+
const slugLower = slug.toLowerCase();
|
|
65
|
+
const slugNorm = slugLower.replace(/_/g, "-");
|
|
66
|
+
const exact = dirs.find((n) => n.toLowerCase() === slugLower);
|
|
67
|
+
if (exact) {
|
|
68
|
+
return path.join(projectsRoot, exact, "canvases");
|
|
69
|
+
}
|
|
70
|
+
// Same path slug with `_` vs `-` (or mixed), not a longer nested project name.
|
|
71
|
+
const normalized = dirs.find((n) => {
|
|
72
|
+
const lower = n.toLowerCase();
|
|
73
|
+
if (/^\d+$/.test(lower))
|
|
74
|
+
return false;
|
|
75
|
+
return lower.replace(/_/g, "-") === slugNorm;
|
|
76
|
+
});
|
|
77
|
+
if (normalized) {
|
|
78
|
+
return path.join(projectsRoot, normalized, "canvases");
|
|
79
|
+
}
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
/** True when `absPath` is under `canvasDir` (Windows case-insensitive). */
|
|
83
|
+
export function isUnderCanvasDir(absPath, canvasDir) {
|
|
84
|
+
if (!canvasDir)
|
|
85
|
+
return false;
|
|
86
|
+
const file = path.resolve(absPath);
|
|
87
|
+
const root = path.resolve(canvasDir);
|
|
88
|
+
if (process.platform === "win32") {
|
|
89
|
+
const f = file.toLowerCase();
|
|
90
|
+
const r = root.toLowerCase().replace(/[/\\]+$/, "");
|
|
91
|
+
return f.startsWith(`${r}\\`) || f.startsWith(`${r}/`);
|
|
92
|
+
}
|
|
93
|
+
const rel = path.relative(root, file);
|
|
94
|
+
return rel !== "" && !rel.startsWith("..") && !path.isAbsolute(rel);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Heuristic: path sits under `~/.cursor/projects/<any>/canvases/` even when
|
|
98
|
+
* `resolveCanvasesDir` returned null (no harness / no env).
|
|
99
|
+
*/
|
|
100
|
+
export function looksLikeCursorCanvasesPath(absPath) {
|
|
101
|
+
const normalized = path.resolve(absPath).replace(/\\/g, "/").toLowerCase();
|
|
102
|
+
return /\/\.cursor\/projects\/[^/]+\/canvases\//.test(`${normalized}/`);
|
|
103
|
+
}
|
|
104
|
+
const OPEN_HINT = "Open this file in Cursor Canvas view (not a normal text editor). " +
|
|
105
|
+
"Cursor only renders .canvas.tsx under ~/.cursor/projects/<slug>/canvases/ " +
|
|
106
|
+
"(or TRELLIS_CAMPAIGN_CANVAS_DIR / CURSOR_CANVAS_DIR). " +
|
|
107
|
+
"Opening outside that folder in a normal editor shows source only — no graphics. " +
|
|
108
|
+
"By default the CLI also opens this file via the Cursor shell command. " +
|
|
109
|
+
"Use --no-open to skip, --quiet for scripts (no hints, no open).";
|
|
110
|
+
/**
|
|
111
|
+
* Evaluate write destination for warnings/hints after `campaign canvas` succeeds.
|
|
112
|
+
* Does not change exit code; callers print warnings on stderr.
|
|
113
|
+
*/
|
|
114
|
+
export function evaluateCanvasWritePath(absOut, canvasDir, opts) {
|
|
115
|
+
const underCanvasDir = isUnderCanvasDir(absOut, canvasDir) || looksLikeCursorCanvasesPath(absOut);
|
|
116
|
+
const usedWorkspaceFallback = opts?.usedWorkspaceFallback === true;
|
|
117
|
+
const warnings = [];
|
|
118
|
+
if (!underCanvasDir) {
|
|
119
|
+
warnings.push("⚠ Warning: output is outside the Cursor canvases directory" +
|
|
120
|
+
(canvasDir ? ` (${canvasDir})` : "") +
|
|
121
|
+
". Opening this path in a normal editor shows TypeScript source only — no Canvas UI.");
|
|
122
|
+
}
|
|
123
|
+
if (usedWorkspaceFallback) {
|
|
124
|
+
warnings.push("⚠ Warning: fell back to .cstl/workspace/campaign-status/ because no harness root " +
|
|
125
|
+
"and no TRELLIS_CAMPAIGN_CANVAS_DIR / CURSOR_CANVAS_DIR were available. " +
|
|
126
|
+
"Prefer the default path under ~/.cursor/projects/<slug>/canvases/.");
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
underCanvasDir,
|
|
130
|
+
usedWorkspaceFallback,
|
|
131
|
+
warnings,
|
|
132
|
+
hints: [OPEN_HINT],
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Best-effort open of a `.canvas.tsx` via the Cursor CLI (`cursor` / `CURSOR_BIN`).
|
|
137
|
+
* Does not guarantee Canvas view (IDE may open as text); callers still print hints.
|
|
138
|
+
*/
|
|
139
|
+
export function resolveCursorCliBin() {
|
|
140
|
+
const fromEnv = process.env.CURSOR_BIN?.trim();
|
|
141
|
+
if (fromEnv)
|
|
142
|
+
return fromEnv;
|
|
143
|
+
try {
|
|
144
|
+
const finder = process.platform === "win32" ? "where.exe" : "which";
|
|
145
|
+
const out = execFileSync(finder, ["cursor"], {
|
|
146
|
+
encoding: "utf8",
|
|
147
|
+
windowsHide: true,
|
|
148
|
+
});
|
|
149
|
+
const first = out
|
|
150
|
+
.split(/\r?\n/)
|
|
151
|
+
.map((s) => s.trim())
|
|
152
|
+
.find(Boolean);
|
|
153
|
+
return first ?? null;
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
export function tryOpenCanvasFile(absPath) {
|
|
160
|
+
const abs = path.resolve(absPath);
|
|
161
|
+
const bin = resolveCursorCliBin();
|
|
162
|
+
if (!bin) {
|
|
163
|
+
return {
|
|
164
|
+
attempted: true,
|
|
165
|
+
ok: false,
|
|
166
|
+
detail: "Cursor CLI not found on PATH (set CURSOR_BIN or install the `cursor` shell command)",
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
try {
|
|
170
|
+
// Prefer argv form without shell when bin is an absolute .exe/.cmd path.
|
|
171
|
+
const useShell = process.platform === "win32" &&
|
|
172
|
+
!path.isAbsolute(bin) &&
|
|
173
|
+
!/\.(exe|cmd|bat)$/i.test(bin);
|
|
174
|
+
const child = spawn(bin, [abs], {
|
|
175
|
+
detached: true,
|
|
176
|
+
stdio: "ignore",
|
|
177
|
+
windowsHide: true,
|
|
178
|
+
shell: useShell,
|
|
179
|
+
});
|
|
180
|
+
child.unref();
|
|
181
|
+
return {
|
|
182
|
+
attempted: true,
|
|
183
|
+
ok: true,
|
|
184
|
+
detail: `spawned ${bin} ${abs}`,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
189
|
+
return {
|
|
190
|
+
attempted: true,
|
|
191
|
+
ok: false,
|
|
192
|
+
detail: `failed to spawn Cursor CLI (${bin}): ${msg}`,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
export function shouldAutoOpenCanvas(opts) {
|
|
197
|
+
// Scripts: --quiet means path-only, do not pop the IDE.
|
|
198
|
+
if (opts?.quiet === true)
|
|
199
|
+
return false;
|
|
200
|
+
if (opts?.noOpen === true)
|
|
201
|
+
return false;
|
|
202
|
+
if (opts?.open === true)
|
|
203
|
+
return true;
|
|
204
|
+
const env = process.env.TRELLIS_CAMPAIGN_CANVAS_OPEN?.trim().toLowerCase();
|
|
205
|
+
if (env === "0" || env === "false" || env === "no")
|
|
206
|
+
return false;
|
|
207
|
+
if (env === "1" || env === "true" || env === "yes")
|
|
208
|
+
return true;
|
|
209
|
+
// Default ON: writing a canvas is useless if the user never sees it.
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
export function resolveHarnessForCanvas(parentDir) {
|
|
213
|
+
return findHarnessRoot(parentDir) ?? findHarnessRoot(process.cwd());
|
|
214
|
+
}
|
|
215
|
+
export function defaultCanvasPath(snapshot, parentDir) {
|
|
216
|
+
const harness = resolveHarnessForCanvas(parentDir);
|
|
217
|
+
const canvases = resolveCanvasesDir(harness);
|
|
218
|
+
const fileName = `campaign-${snapshot.parent.id}.canvas.tsx`;
|
|
219
|
+
if (canvases) {
|
|
220
|
+
return path.join(canvases, fileName);
|
|
221
|
+
}
|
|
222
|
+
// Last resort: no harness and no env canvas dir.
|
|
223
|
+
const base = path.join(process.cwd(), ".cstl", "workspace", "campaign-status");
|
|
224
|
+
return path.join(base, fileName);
|
|
225
|
+
}
|
|
226
|
+
/** Whether `defaultCanvasPath` would use the workspace fallback for this parent. */
|
|
227
|
+
export function defaultCanvasUsesWorkspaceFallback(parentDir) {
|
|
228
|
+
const harness = resolveHarnessForCanvas(parentDir);
|
|
229
|
+
return resolveCanvasesDir(harness) === null;
|
|
230
|
+
}
|
|
231
|
+
/** Escape a JSON text so it is safe as a JS/TS expression. */
|
|
232
|
+
function jsonAsTsLiteral(value) {
|
|
233
|
+
return JSON.stringify(value, null, 2);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Render a single-file Cursor Canvas (`.canvas.tsx`) with embedded snapshot.
|
|
237
|
+
* Imports only `cursor/canvas`; no fetch / network.
|
|
238
|
+
*/
|
|
239
|
+
export function renderCampaignCanvasTsx(snapshot) {
|
|
240
|
+
const dataLiteral = jsonAsTsLiteral(snapshot);
|
|
241
|
+
return `import {
|
|
242
|
+
Callout,
|
|
243
|
+
Card,
|
|
244
|
+
CardBody,
|
|
245
|
+
CardHeader,
|
|
246
|
+
Grid,
|
|
247
|
+
H1,
|
|
248
|
+
H2,
|
|
249
|
+
Pill,
|
|
250
|
+
Row,
|
|
251
|
+
Stack,
|
|
252
|
+
Stat,
|
|
253
|
+
Table,
|
|
254
|
+
Text,
|
|
255
|
+
useHostTheme,
|
|
256
|
+
} from "cursor/canvas";
|
|
257
|
+
|
|
258
|
+
/** Embedded campaign MIX snapshot — refresh via \\\`cstl campaign canvas\\\`. */
|
|
259
|
+
const DATA = ${dataLiteral};
|
|
260
|
+
|
|
261
|
+
type Snapshot = typeof DATA;
|
|
262
|
+
type Child = Snapshot["parent"]["children"][number];
|
|
263
|
+
type Stage = Snapshot["parent"]["stages"][number];
|
|
264
|
+
type RpcClient = Snapshot["rpc"]["clients"][number];
|
|
265
|
+
|
|
266
|
+
function stateTone(
|
|
267
|
+
state: string,
|
|
268
|
+
): "neutral" | "success" | "warning" | "info" | "deleted" {
|
|
269
|
+
const s = state.toLowerCase();
|
|
270
|
+
if (s === "integrated" || s === "done" || s === "completed") return "success";
|
|
271
|
+
if (s === "working" || s === "in_progress" || s === "integrating") return "info";
|
|
272
|
+
if (s === "blocked" || s === "failed") return "deleted";
|
|
273
|
+
if (s === "review" || s === "changes") return "warning";
|
|
274
|
+
return "neutral";
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export default function CampaignStatusCanvas() {
|
|
278
|
+
const theme = useHostTheme();
|
|
279
|
+
const parent = DATA.parent;
|
|
280
|
+
const rpc = DATA.rpc;
|
|
281
|
+
|
|
282
|
+
const stageRows = parent.stages.flatMap((stage: Stage) =>
|
|
283
|
+
stage.units.map((unit) => [
|
|
284
|
+
stage.id,
|
|
285
|
+
stage.title || "—",
|
|
286
|
+
unit.id,
|
|
287
|
+
<Pill key={\`\${stage.id}-\${unit.id}-st\`} tone={stateTone(unit.state)} size="sm">
|
|
288
|
+
{unit.state}
|
|
289
|
+
</Pill>,
|
|
290
|
+
unit.readiness,
|
|
291
|
+
]),
|
|
292
|
+
);
|
|
293
|
+
|
|
294
|
+
const childRows = parent.children.map((child: Child) => [
|
|
295
|
+
child.id,
|
|
296
|
+
<Pill key={\`\${child.id}-st\`} tone={stateTone(child.state)} size="sm">
|
|
297
|
+
{child.state}
|
|
298
|
+
</Pill>,
|
|
299
|
+
child.dependsOn.length ? child.dependsOn.join(", ") : "—",
|
|
300
|
+
child.ref ?? "—",
|
|
301
|
+
]);
|
|
302
|
+
|
|
303
|
+
const clientRows = rpc.clients.map((c: RpcClient) => [
|
|
304
|
+
c.kind,
|
|
305
|
+
c.id,
|
|
306
|
+
<Pill key={\`\${c.kind}-\${c.id}\`} tone="info" size="sm">
|
|
307
|
+
{c.capLabel}
|
|
308
|
+
</Pill>,
|
|
309
|
+
c.campaignId ?? "—",
|
|
310
|
+
c.lastSeenAt ?? "—",
|
|
311
|
+
]);
|
|
312
|
+
|
|
313
|
+
return (
|
|
314
|
+
<Stack gap={20} style={{ padding: 20, maxWidth: 1100 }}>
|
|
315
|
+
<Stack gap={8}>
|
|
316
|
+
<H1>Campaign — {parent.id}</H1>
|
|
317
|
+
<Text style={{ color: theme.text.secondary, fontSize: 12 }}>
|
|
318
|
+
Generated {DATA.generatedAt} · path {parent.path}
|
|
319
|
+
</Text>
|
|
320
|
+
<Text style={{ color: theme.text.tertiary, fontSize: 12 }}>
|
|
321
|
+
Source: Trellis parent-status + optional RPC /status · read-only MIX
|
|
322
|
+
</Text>
|
|
323
|
+
</Stack>
|
|
324
|
+
|
|
325
|
+
<Grid columns={4} gap={12}>
|
|
326
|
+
<Stat value={String(parent.contractEpoch ?? "?")} label="contract_epoch" />
|
|
327
|
+
<Stat
|
|
328
|
+
value={String(parent.executionTopology ?? "?")}
|
|
329
|
+
label="execution_topology"
|
|
330
|
+
/>
|
|
331
|
+
<Stat value={String(parent.mergeLimit ?? "?")} label="merge_limit" />
|
|
332
|
+
<Stat
|
|
333
|
+
value={rpc.reachable ? "up" : "down"}
|
|
334
|
+
label="RPC broker"
|
|
335
|
+
tone={rpc.reachable ? "success" : "danger"}
|
|
336
|
+
/>
|
|
337
|
+
</Grid>
|
|
338
|
+
|
|
339
|
+
{stageRows.length > 0 ? (
|
|
340
|
+
<Stack gap={8}>
|
|
341
|
+
<H2>Stages</H2>
|
|
342
|
+
<Table
|
|
343
|
+
headers={["Stage", "Title", "Unit", "State", "Readiness"]}
|
|
344
|
+
rows={stageRows}
|
|
345
|
+
/>
|
|
346
|
+
</Stack>
|
|
347
|
+
) : null}
|
|
348
|
+
|
|
349
|
+
{childRows.length > 0 ? (
|
|
350
|
+
<Stack gap={8}>
|
|
351
|
+
<H2>Children</H2>
|
|
352
|
+
<Table
|
|
353
|
+
headers={["Child", "State", "depends_on", "ref"]}
|
|
354
|
+
rows={childRows}
|
|
355
|
+
/>
|
|
356
|
+
</Stack>
|
|
357
|
+
) : null}
|
|
358
|
+
|
|
359
|
+
<Card>
|
|
360
|
+
<CardHeader>RPC broker</CardHeader>
|
|
361
|
+
<CardBody>
|
|
362
|
+
<Stack gap={12}>
|
|
363
|
+
<Row gap={8} align="center">
|
|
364
|
+
<Text style={{ fontSize: 12 }}>URL</Text>
|
|
365
|
+
<Text style={{ color: theme.text.secondary, fontSize: 12 }}>
|
|
366
|
+
{rpc.url}
|
|
367
|
+
</Text>
|
|
368
|
+
</Row>
|
|
369
|
+
{!rpc.reachable ? (
|
|
370
|
+
<Callout tone="warning" title="Broker unreachable">
|
|
371
|
+
{rpc.error ?? "reachable: false — Trellis stages/children still shown."}
|
|
372
|
+
</Callout>
|
|
373
|
+
) : null}
|
|
374
|
+
{clientRows.length > 0 ? (
|
|
375
|
+
<Table
|
|
376
|
+
headers={["kind", "id", "capLabel", "campaignId", "lastSeenAt"]}
|
|
377
|
+
rows={clientRows}
|
|
378
|
+
/>
|
|
379
|
+
) : null}
|
|
380
|
+
{rpc.topics.length > 0 ? (
|
|
381
|
+
<Text style={{ color: theme.text.secondary, fontSize: 12 }}>
|
|
382
|
+
Topics: {rpc.topics.join(", ")}
|
|
383
|
+
</Text>
|
|
384
|
+
) : null}
|
|
385
|
+
</Stack>
|
|
386
|
+
</CardBody>
|
|
387
|
+
</Card>
|
|
388
|
+
|
|
389
|
+
{DATA.notes.length > 0 ? (
|
|
390
|
+
<Stack gap={6}>
|
|
391
|
+
<H2>Notes</H2>
|
|
392
|
+
{DATA.notes.map((note: string) => (
|
|
393
|
+
<Text key={note} style={{ color: theme.text.secondary, fontSize: 12 }}>
|
|
394
|
+
{note}
|
|
395
|
+
</Text>
|
|
396
|
+
))}
|
|
397
|
+
</Stack>
|
|
398
|
+
) : null}
|
|
399
|
+
|
|
400
|
+
<Text style={{ color: theme.text.tertiary, fontSize: 12 }}>
|
|
401
|
+
Refresh: cstl campaign canvas --parent {parent.path}
|
|
402
|
+
</Text>
|
|
403
|
+
</Stack>
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
`;
|
|
407
|
+
}
|
|
408
|
+
export function writeCampaignCanvas(snapshot, outPath) {
|
|
409
|
+
const abs = path.resolve(outPath);
|
|
410
|
+
fs.mkdirSync(path.dirname(abs), { recursive: true });
|
|
411
|
+
fs.writeFileSync(abs, renderCampaignCanvasTsx(snapshot), "utf8");
|
|
412
|
+
return abs;
|
|
413
|
+
}
|
|
414
|
+
//# sourceMappingURL=canvas-render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas-render.js","sourceRoot":"","sources":["../../../src/commands/campaign/canvas-render.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { getJson } from "../rpc/client.js";
|
|
2
|
+
import type { CampaignParentSnapshot, CampaignStatusSnapshot } from "./types.js";
|
|
3
|
+
export type TrellisLoader = (parentDir: string) => Promise<CampaignParentSnapshot>;
|
|
4
|
+
export type RpcStatusFetcher = (url: string) => Promise<unknown>;
|
|
5
|
+
export interface ComposeCampaignStatusOptions {
|
|
6
|
+
parentDir: string;
|
|
7
|
+
rpcUrl?: string;
|
|
8
|
+
rpcTimeoutMs?: number;
|
|
9
|
+
loadTrellis?: TrellisLoader;
|
|
10
|
+
fetchRpcStatus?: RpcStatusFetcher;
|
|
11
|
+
}
|
|
12
|
+
export declare function composeCampaignStatus(options: ComposeCampaignStatusOptions): Promise<CampaignStatusSnapshot>;
|
|
13
|
+
/** Re-export for tests that want getJson-shaped helpers. */
|
|
14
|
+
export { getJson };
|
|
15
|
+
//# sourceMappingURL=compose.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../../../src/commands/campaign/compose.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAiB,MAAM,kBAAkB,CAAC;AAG1D,OAAO,KAAK,EACV,sBAAsB,EAGtB,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAQpB,MAAM,MAAM,aAAa,GAAG,CAC1B,SAAS,EAAE,MAAM,KACd,OAAO,CAAC,sBAAsB,CAAC,CAAC;AAErC,MAAM,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEjE,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,aAAa,CAAC;IAC5B,cAAc,CAAC,EAAE,gBAAgB,CAAC;CACnC;AA4ED,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,sBAAsB,CAAC,CAuCjC;AAED,4DAA4D;AAC5D,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { getJson, resolveRpcUrl } from "../rpc/client.js";
|
|
2
|
+
import { capLabelForKind } from "./kind-map.js";
|
|
3
|
+
import { loadTrellisParentSnapshot } from "./trellis-load.js";
|
|
4
|
+
const DEFAULT_NOTES = [
|
|
5
|
+
"Read-only observation. HITL gates remain task.py / human.",
|
|
6
|
+
"capLabel is advisory; Task ≠ Agent window (CAP MATRIX).",
|
|
7
|
+
"Refresh Canvas: cstl campaign canvas --parent <parent-task-dir>.",
|
|
8
|
+
];
|
|
9
|
+
function nowIso() {
|
|
10
|
+
return new Date().toISOString();
|
|
11
|
+
}
|
|
12
|
+
function mapRpcClients(raw) {
|
|
13
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
14
|
+
return { clients: [], topics: [] };
|
|
15
|
+
}
|
|
16
|
+
const o = raw;
|
|
17
|
+
const clientsRaw = Array.isArray(o.clients) ? o.clients : [];
|
|
18
|
+
const clients = [];
|
|
19
|
+
for (const item of clientsRaw) {
|
|
20
|
+
if (!item || typeof item !== "object")
|
|
21
|
+
continue;
|
|
22
|
+
const c = item;
|
|
23
|
+
const address = c.address && typeof c.address === "object"
|
|
24
|
+
? c.address
|
|
25
|
+
: null;
|
|
26
|
+
const kind = typeof address?.kind === "string"
|
|
27
|
+
? address.kind
|
|
28
|
+
: typeof c.kind === "string"
|
|
29
|
+
? c.kind
|
|
30
|
+
: "unknown";
|
|
31
|
+
const id = typeof address?.id === "string"
|
|
32
|
+
? address.id
|
|
33
|
+
: typeof c.id === "string"
|
|
34
|
+
? c.id
|
|
35
|
+
: "?";
|
|
36
|
+
clients.push({
|
|
37
|
+
kind,
|
|
38
|
+
id,
|
|
39
|
+
capLabel: capLabelForKind(kind),
|
|
40
|
+
...(typeof c.campaignId === "string" ? { campaignId: c.campaignId } : {}),
|
|
41
|
+
...(typeof c.lastSeenAt === "string" ? { lastSeenAt: c.lastSeenAt } : {}),
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
const topics = Array.isArray(o.topics)
|
|
45
|
+
? o.topics.filter((t) => typeof t === "string")
|
|
46
|
+
: [];
|
|
47
|
+
return {
|
|
48
|
+
protocolVersion: typeof o.protocolVersion === "number" ? o.protocolVersion : undefined,
|
|
49
|
+
clients,
|
|
50
|
+
topics,
|
|
51
|
+
auditCount: typeof o.auditCount === "number" ? o.auditCount : undefined,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
async function defaultFetchRpcStatus(url, timeoutMs) {
|
|
55
|
+
const controller = new AbortController();
|
|
56
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
57
|
+
try {
|
|
58
|
+
const res = await fetch(`${url.replace(/\/$/, "")}/status`, {
|
|
59
|
+
signal: controller.signal,
|
|
60
|
+
});
|
|
61
|
+
if (!res.ok) {
|
|
62
|
+
throw new Error(`HTTP ${res.status} for /status`);
|
|
63
|
+
}
|
|
64
|
+
return res.json();
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
clearTimeout(timer);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
export async function composeCampaignStatus(options) {
|
|
71
|
+
const loadTrellis = options.loadTrellis ?? loadTrellisParentSnapshot;
|
|
72
|
+
const parent = await loadTrellis(options.parentDir);
|
|
73
|
+
const url = resolveRpcUrl(options.rpcUrl);
|
|
74
|
+
const timeoutMs = options.rpcTimeoutMs ?? 1500;
|
|
75
|
+
let rpc;
|
|
76
|
+
try {
|
|
77
|
+
const fetchRpc = options.fetchRpcStatus ??
|
|
78
|
+
((u) => defaultFetchRpcStatus(u, timeoutMs));
|
|
79
|
+
const raw = await fetchRpc(url);
|
|
80
|
+
const mapped = mapRpcClients(raw);
|
|
81
|
+
rpc = {
|
|
82
|
+
url,
|
|
83
|
+
reachable: true,
|
|
84
|
+
protocolVersion: mapped.protocolVersion,
|
|
85
|
+
clients: mapped.clients,
|
|
86
|
+
topics: mapped.topics,
|
|
87
|
+
auditCount: mapped.auditCount,
|
|
88
|
+
error: null,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
rpc = {
|
|
93
|
+
url,
|
|
94
|
+
reachable: false,
|
|
95
|
+
clients: [],
|
|
96
|
+
topics: [],
|
|
97
|
+
error: error instanceof Error ? error.message : String(error),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
v: 1,
|
|
102
|
+
generatedAt: nowIso(),
|
|
103
|
+
parent,
|
|
104
|
+
rpc,
|
|
105
|
+
notes: [...DEFAULT_NOTES],
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/** Re-export for tests that want getJson-shaped helpers. */
|
|
109
|
+
export { getJson };
|
|
110
|
+
//# sourceMappingURL=compose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compose.js","sourceRoot":"","sources":["../../../src/commands/campaign/compose.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAQ9D,MAAM,aAAa,GAAG;IACpB,2DAA2D;IAC3D,yDAAyD;IACzD,kEAAkE;CACnE,CAAC;AAgBF,SAAS,MAAM;IACb,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAClC,CAAC;AAED,SAAS,aAAa,CAAC,GAAY;IAMjC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1D,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACrC,CAAC;IACD,MAAM,CAAC,GAAG,GAA8B,CAAC;IACzC,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7D,MAAM,OAAO,GAA4B,EAAE,CAAC;IAC5C,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,SAAS;QAChD,MAAM,CAAC,GAAG,IAA+B,CAAC;QAC1C,MAAM,OAAO,GACX,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ;YACxC,CAAC,CAAE,CAAC,CAAC,OAAmC;YACxC,CAAC,CAAC,IAAI,CAAC;QACX,MAAM,IAAI,GACR,OAAO,OAAO,EAAE,IAAI,KAAK,QAAQ;YAC/B,CAAC,CAAC,OAAO,CAAC,IAAI;YACd,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ;gBAC1B,CAAC,CAAC,CAAC,CAAC,IAAI;gBACR,CAAC,CAAC,SAAS,CAAC;QAClB,MAAM,EAAE,GACN,OAAO,OAAO,EAAE,EAAE,KAAK,QAAQ;YAC7B,CAAC,CAAC,OAAO,CAAC,EAAE;YACZ,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,QAAQ;gBACxB,CAAC,CAAC,CAAC,CAAC,EAAE;gBACN,CAAC,CAAC,GAAG,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC;YACX,IAAI;YACJ,EAAE;YACF,QAAQ,EAAE,eAAe,CAAC,IAAI,CAAC;YAC/B,GAAG,CAAC,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzE,GAAG,CAAC,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1E,CAAC,CAAC;IACL,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;QACpC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;QAC5D,CAAC,CAAC,EAAE,CAAC;IACP,OAAO;QACL,eAAe,EACb,OAAO,CAAC,CAAC,eAAe,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS;QACvE,OAAO;QACP,MAAM;QACN,UAAU,EAAE,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;KACxE,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,qBAAqB,CAClC,GAAW,EACX,SAAiB;IAEjB,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;IAC9D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,EAAE;YAC1D,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,MAAM,cAAc,CAAC,CAAC;QACpD,CAAC;QACD,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;IACpB,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAAqC;IAErC,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,yBAAyB,CAAC;IACrE,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,OAAO,CAAC,YAAY,IAAI,IAAI,CAAC;IAE/C,IAAI,GAAwB,CAAC;IAC7B,IAAI,CAAC;QACH,MAAM,QAAQ,GACZ,OAAO,CAAC,cAAc;YACtB,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,qBAAqB,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;QACvD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;QAClC,GAAG,GAAG;YACJ,GAAG;YACH,SAAS,EAAE,IAAI;YACf,eAAe,EAAE,MAAM,CAAC,eAAe;YACvC,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,KAAK,EAAE,IAAI;SACZ,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,GAAG;YACJ,GAAG;YACH,SAAS,EAAE,KAAK;YAChB,OAAO,EAAE,EAAE;YACX,MAAM,EAAE,EAAE;YACV,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC9D,CAAC;IACJ,CAAC;IAED,OAAO;QACL,CAAC,EAAE,CAAC;QACJ,WAAW,EAAE,MAAM,EAAE;QACrB,MAAM;QACN,GAAG;QACH,KAAK,EAAE,CAAC,GAAG,aAAa,CAAC;KAC1B,CAAC;AACJ,CAAC;AAED,4DAA4D;AAC5D,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Command } from "commander";
|
|
2
|
+
export { composeCampaignStatus } from "./compose.js";
|
|
3
|
+
export { capLabelForKind } from "./kind-map.js";
|
|
4
|
+
export { defaultCanvasPath, evaluateCanvasWritePath, isUnderCanvasDir, looksLikeCursorCanvasesPath, renderCampaignCanvasTsx, resolveCanvasesDir, softMatchCanvasesDir, tryOpenCanvasFile, writeCampaignCanvas, } from "./canvas-render.js";
|
|
5
|
+
export { renderCampaignStatusMarkdown, writeCampaignPanel, } from "./render.js";
|
|
6
|
+
export { loadTrellisParentSnapshot } from "./trellis-load.js";
|
|
7
|
+
export type { CampaignStatusSnapshot } from "./types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Register `cstl campaign` — Cursor MIX observation (CMD + MCP).
|
|
10
|
+
* Read-only; never auto-approves Trellis HITL gates.
|
|
11
|
+
*/
|
|
12
|
+
export declare function registerCampaignCommand(program: Command): void;
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/campaign/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,gBAAgB,EAChB,2BAA2B,EAC3B,uBAAuB,EACvB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,4BAA4B,EAC5B,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,YAAY,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAYzD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+J9D"}
|