@crouton-kit/crouter 0.3.11 → 0.3.12

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.
Files changed (182) hide show
  1. package/bin/crtrd +2 -0
  2. package/dist/builtin-personas/design/base.md +9 -0
  3. package/dist/builtin-personas/design/orchestrator.md +10 -0
  4. package/dist/builtin-personas/developer/base.md +9 -0
  5. package/dist/builtin-personas/developer/orchestrator.md +12 -0
  6. package/dist/builtin-personas/explore/base.md +9 -0
  7. package/dist/builtin-personas/explore/orchestrator.md +9 -0
  8. package/dist/builtin-personas/general/base.md +5 -0
  9. package/dist/builtin-personas/general/orchestrator.md +7 -0
  10. package/dist/builtin-personas/orchestration-kernel.md +71 -0
  11. package/dist/builtin-personas/plan/base.md +7 -0
  12. package/dist/builtin-personas/plan/orchestrator.md +12 -0
  13. package/dist/builtin-personas/review/base.md +7 -0
  14. package/dist/builtin-personas/review/orchestrator.md +9 -0
  15. package/dist/builtin-personas/runtime-base.md +39 -0
  16. package/dist/builtin-personas/spec/base.md +7 -0
  17. package/dist/builtin-personas/spec/orchestrator.md +10 -0
  18. package/dist/builtin-skills/skills/design/SKILL.md +51 -0
  19. package/dist/builtin-skills/skills/development/SKILL.md +109 -0
  20. package/dist/builtin-skills/skills/planning/SKILL.md +59 -0
  21. package/dist/builtin-skills/skills/spec/SKILL.md +83 -0
  22. package/dist/cli.js +14 -6
  23. package/dist/commands/{mode.d.ts → attention.d.ts} +1 -1
  24. package/dist/commands/attention.js +152 -0
  25. package/dist/commands/canvas.d.ts +2 -0
  26. package/dist/commands/canvas.js +35 -0
  27. package/dist/commands/daemon.d.ts +2 -0
  28. package/dist/commands/daemon.js +111 -0
  29. package/dist/commands/dashboard.d.ts +2 -0
  30. package/dist/commands/dashboard.js +65 -0
  31. package/dist/commands/human/prompts.d.ts +5 -0
  32. package/dist/commands/human/prompts.js +269 -0
  33. package/dist/commands/human/queue.d.ts +3 -0
  34. package/dist/commands/human/queue.js +133 -0
  35. package/dist/commands/human/shared.d.ts +43 -0
  36. package/dist/commands/human/shared.js +107 -0
  37. package/dist/commands/human.js +10 -454
  38. package/dist/commands/node.d.ts +2 -0
  39. package/dist/commands/node.js +354 -0
  40. package/dist/commands/pkg/market-inspect.d.ts +1 -0
  41. package/dist/commands/pkg/market-inspect.js +157 -0
  42. package/dist/commands/pkg/market-manage.d.ts +1 -0
  43. package/dist/commands/pkg/market-manage.js +316 -0
  44. package/dist/commands/pkg/market.d.ts +1 -0
  45. package/dist/commands/pkg/market.js +16 -0
  46. package/dist/commands/pkg/plugin-inspect.d.ts +1 -0
  47. package/dist/commands/pkg/plugin-inspect.js +142 -0
  48. package/dist/commands/pkg/plugin-manage.d.ts +1 -0
  49. package/dist/commands/pkg/plugin-manage.js +294 -0
  50. package/dist/commands/pkg/plugin.d.ts +1 -0
  51. package/dist/commands/pkg/plugin.js +16 -0
  52. package/dist/commands/pkg/shared.d.ts +5 -0
  53. package/dist/commands/pkg/shared.js +61 -0
  54. package/dist/commands/pkg.js +3 -1004
  55. package/dist/commands/push.d.ts +3 -0
  56. package/dist/commands/push.js +159 -0
  57. package/dist/commands/revive.d.ts +2 -0
  58. package/dist/commands/revive.js +64 -0
  59. package/dist/commands/skill/author.d.ts +3 -0
  60. package/dist/commands/skill/author.js +147 -0
  61. package/dist/commands/skill/find.d.ts +4 -0
  62. package/dist/commands/skill/find.js +254 -0
  63. package/dist/commands/skill/read.d.ts +1 -0
  64. package/dist/commands/skill/read.js +89 -0
  65. package/dist/commands/skill/shared.d.ts +19 -0
  66. package/dist/commands/skill/shared.js +207 -0
  67. package/dist/commands/skill/state.d.ts +3 -0
  68. package/dist/commands/skill/state.js +69 -0
  69. package/dist/commands/skill.js +6 -691
  70. package/dist/commands/sys/config.d.ts +1 -0
  71. package/dist/commands/sys/config.js +186 -0
  72. package/dist/commands/sys/doctor.d.ts +1 -0
  73. package/dist/commands/sys/doctor.js +369 -0
  74. package/dist/commands/sys/shared.d.ts +3 -0
  75. package/dist/commands/sys/shared.js +24 -0
  76. package/dist/commands/sys/update.d.ts +2 -0
  77. package/dist/commands/sys/update.js +114 -0
  78. package/dist/commands/sys.js +4 -694
  79. package/dist/core/__tests__/argv-parser.test.js +19 -1
  80. package/dist/core/__tests__/canvas-inbox-watcher.test.js +100 -0
  81. package/dist/core/__tests__/canvas.test.js +154 -0
  82. package/dist/core/__tests__/reset.test.js +105 -0
  83. package/dist/core/canvas/attention.d.ts +24 -0
  84. package/dist/core/canvas/attention.js +94 -0
  85. package/dist/core/canvas/canvas.d.ts +40 -0
  86. package/dist/core/canvas/canvas.js +210 -0
  87. package/dist/core/canvas/db.d.ts +7 -0
  88. package/dist/core/canvas/db.js +61 -0
  89. package/dist/core/canvas/index.d.ts +4 -0
  90. package/dist/core/canvas/index.js +6 -0
  91. package/dist/core/canvas/paths.d.ts +16 -0
  92. package/dist/core/canvas/paths.js +62 -0
  93. package/dist/core/canvas/render.d.ts +30 -0
  94. package/dist/core/canvas/render.js +186 -0
  95. package/dist/core/canvas/types.d.ts +87 -0
  96. package/dist/core/canvas/types.js +8 -0
  97. package/dist/core/command.d.ts +5 -0
  98. package/dist/core/command.js +35 -10
  99. package/dist/core/feed/feed.d.ts +43 -0
  100. package/dist/core/feed/feed.js +116 -0
  101. package/dist/core/feed/inbox.d.ts +50 -0
  102. package/dist/core/feed/inbox.js +124 -0
  103. package/dist/core/help.js +5 -3
  104. package/dist/core/io.d.ts +15 -1
  105. package/dist/core/io.js +56 -6
  106. package/dist/core/personas/index.d.ts +12 -0
  107. package/dist/core/personas/index.js +10 -0
  108. package/dist/core/personas/loader.d.ts +44 -0
  109. package/dist/core/personas/loader.js +157 -0
  110. package/dist/core/personas/resolve.d.ts +36 -0
  111. package/dist/core/personas/resolve.js +110 -0
  112. package/dist/core/render.d.ts +11 -0
  113. package/dist/core/render.js +126 -0
  114. package/dist/core/resolver.d.ts +10 -0
  115. package/dist/core/resolver.js +109 -1
  116. package/dist/core/runtime/front-door.d.ts +10 -0
  117. package/dist/core/runtime/front-door.js +97 -0
  118. package/dist/core/runtime/kickoff.d.ts +23 -0
  119. package/dist/core/runtime/kickoff.js +134 -0
  120. package/dist/core/runtime/launch.d.ts +34 -0
  121. package/dist/core/runtime/launch.js +85 -0
  122. package/dist/core/runtime/nodes.d.ts +38 -0
  123. package/dist/core/runtime/nodes.js +95 -0
  124. package/dist/core/runtime/presence.d.ts +38 -0
  125. package/dist/core/runtime/presence.js +152 -0
  126. package/dist/core/runtime/promote.d.ts +30 -0
  127. package/dist/core/runtime/promote.js +105 -0
  128. package/dist/core/runtime/reset.d.ts +13 -0
  129. package/dist/core/runtime/reset.js +97 -0
  130. package/dist/core/runtime/revive.d.ts +26 -0
  131. package/dist/core/runtime/revive.js +89 -0
  132. package/dist/core/runtime/roadmap.d.ts +12 -0
  133. package/dist/core/runtime/roadmap.js +52 -0
  134. package/dist/core/runtime/spawn.d.ts +33 -0
  135. package/dist/core/runtime/spawn.js +118 -0
  136. package/dist/core/runtime/stop-guard.d.ts +18 -0
  137. package/dist/core/runtime/stop-guard.js +33 -0
  138. package/dist/core/runtime/tmux.d.ts +88 -0
  139. package/dist/core/runtime/tmux.js +198 -0
  140. package/dist/core/spawn.d.ts +17 -197
  141. package/dist/core/spawn.js +16 -539
  142. package/dist/daemon/crtrd-cli.js +4 -0
  143. package/dist/daemon/crtrd.d.ts +20 -0
  144. package/dist/daemon/crtrd.js +200 -0
  145. package/dist/daemon/manage.d.ts +17 -0
  146. package/dist/daemon/manage.js +57 -0
  147. package/dist/pi-extensions/canvas-inbox-watcher.d.ts +16 -0
  148. package/dist/pi-extensions/canvas-inbox-watcher.js +229 -0
  149. package/dist/pi-extensions/canvas-nav.d.ts +32 -0
  150. package/dist/pi-extensions/canvas-nav.js +536 -0
  151. package/dist/pi-extensions/canvas-stophook.d.ts +17 -0
  152. package/dist/pi-extensions/canvas-stophook.js +373 -0
  153. package/package.json +6 -5
  154. package/dist/commands/agent.d.ts +0 -6
  155. package/dist/commands/agent.js +0 -585
  156. package/dist/commands/debug.d.ts +0 -3
  157. package/dist/commands/debug.js +0 -192
  158. package/dist/commands/job.d.ts +0 -11
  159. package/dist/commands/job.js +0 -384
  160. package/dist/commands/mode.js +0 -231
  161. package/dist/commands/plan.d.ts +0 -4
  162. package/dist/commands/plan.js +0 -322
  163. package/dist/commands/spec.d.ts +0 -3
  164. package/dist/commands/spec.js +0 -299
  165. package/dist/core/__tests__/flow-leaves.test.js +0 -248
  166. package/dist/core/__tests__/job.test.js +0 -310
  167. package/dist/core/__tests__/jobs.test.js +0 -98
  168. package/dist/core/__tests__/spawn.test.js +0 -138
  169. package/dist/core/__tests__/subagents.test.d.ts +0 -1
  170. package/dist/core/__tests__/subagents.test.js +0 -75
  171. package/dist/core/jobs.d.ts +0 -107
  172. package/dist/core/jobs.js +0 -565
  173. package/dist/core/subagents.d.ts +0 -18
  174. package/dist/core/subagents.js +0 -163
  175. package/dist/prompts/agent.d.ts +0 -27
  176. package/dist/prompts/agent.js +0 -184
  177. package/dist/prompts/debug.d.ts +0 -8
  178. package/dist/prompts/debug.js +0 -44
  179. /package/dist/core/__tests__/{flow-leaves.test.d.ts → canvas-inbox-watcher.test.d.ts} +0 -0
  180. /package/dist/core/__tests__/{job.test.d.ts → canvas.test.d.ts} +0 -0
  181. /package/dist/core/__tests__/{jobs.test.d.ts → reset.test.d.ts} +0 -0
  182. /package/dist/{core/__tests__/spawn.test.d.ts → daemon/crtrd-cli.d.ts} +0 -0
@@ -1,163 +0,0 @@
1
- // Subagent discovery + resolution.
2
- //
3
- // Subagents are markdown files with YAML frontmatter, modeled on the pi
4
- // subagent extension but surfaced through the crtr `agent` CLI. Each file
5
- // declares a name/description (+ optional tools/model) in frontmatter; its
6
- // markdown body becomes the spawned agent's appended system prompt.
7
- //
8
- // Layout mirrors skills, one level shallower (flat files, not nested dirs):
9
- // <scope-root>/agents/<name>.md — scope-root agents (user/project)
10
- // <plugin-root>/agents/<name>.md — plugin-provided agents
11
- //
12
- // Resolution precedence matches skills: project before user before builtin;
13
- // scope-root agents before plugin agents within a scope.
14
- import { join, basename } from 'node:path';
15
- import { readdirSync } from 'node:fs';
16
- import { AGENTS_DIR, SCOPE_SKILL_PLUGIN } from '../types.js';
17
- import { listAllPlugins, listInstalledPlugins } from './resolver.js';
18
- import { parseFrontmatterGeneric } from './frontmatter.js';
19
- import { pathExists, readText } from './fs-utils.js';
20
- import { projectScopeRoot, scopeRoot } from './scope.js';
21
- import { ambiguous, notFound } from './errors.js';
22
- /** `<scope-root>/agents` for a given scope, or null when the scope has no root. */
23
- export function scopeAgentsDir(scope) {
24
- const root = scopeRoot(scope);
25
- return root ? join(root, AGENTS_DIR) : null;
26
- }
27
- function coerceTools(value) {
28
- if (Array.isArray(value)) {
29
- const arr = value.map((v) => String(v).trim()).filter(Boolean);
30
- return arr.length > 0 ? arr : undefined;
31
- }
32
- if (typeof value === 'string') {
33
- const arr = value
34
- .split(',')
35
- .map((t) => t.trim())
36
- .filter(Boolean);
37
- return arr.length > 0 ? arr : undefined;
38
- }
39
- return undefined;
40
- }
41
- function parseSubagentFile(filePath, scope, plugin) {
42
- let source;
43
- try {
44
- source = readText(filePath);
45
- }
46
- catch {
47
- return null;
48
- }
49
- const { data, body } = parseFrontmatterGeneric(source);
50
- if (data === null)
51
- return null;
52
- // Name defaults to the filename stem when frontmatter omits it. A description
53
- // is required for the agent to be useful in listings; skip files without one.
54
- const fileStem = basename(filePath).replace(/\.md$/i, '');
55
- const name = typeof data.name === 'string' && data.name.trim() !== ''
56
- ? data.name.trim()
57
- : fileStem;
58
- if (typeof data.description !== 'string' || data.description.trim() === '') {
59
- return null;
60
- }
61
- const fm = {
62
- name,
63
- description: data.description.trim(),
64
- tools: coerceTools(data.tools),
65
- model: typeof data.model === 'string' && data.model.trim() !== '' ? data.model.trim() : undefined,
66
- };
67
- return {
68
- name,
69
- plugin,
70
- scope,
71
- path: filePath,
72
- frontmatter: fm,
73
- systemPrompt: body,
74
- };
75
- }
76
- function listAgentsInDir(dir, scope, plugin) {
77
- if (!pathExists(dir))
78
- return [];
79
- let entries;
80
- try {
81
- entries = readdirSync(dir, { withFileTypes: true });
82
- }
83
- catch {
84
- return [];
85
- }
86
- const out = [];
87
- for (const e of entries) {
88
- if (!e.name.toLowerCase().endsWith('.md'))
89
- continue;
90
- if (!e.isFile() && !e.isSymbolicLink())
91
- continue;
92
- const parsed = parseSubagentFile(join(dir, e.name), scope, plugin);
93
- if (parsed !== null)
94
- out.push(parsed);
95
- }
96
- return out;
97
- }
98
- /** Scope-root agents under `<scope-root>/agents/*.md`. */
99
- export function listScopeRootSubagents(scope) {
100
- if (scope === 'builtin')
101
- return [];
102
- const dir = scopeAgentsDir(scope);
103
- if (!dir)
104
- return [];
105
- return listAgentsInDir(dir, scope, SCOPE_SKILL_PLUGIN);
106
- }
107
- /** All subagents: scope-root agents (project, user) plus enabled plugins. */
108
- export function listSubagents(scopeFilter) {
109
- const scopes = scopeFilter
110
- ? [scopeFilter]
111
- : [projectScopeRoot() ? 'project' : null, 'user'].filter(Boolean);
112
- const fromScopeRoots = scopes.flatMap((s) => listScopeRootSubagents(s));
113
- const plugins = scopeFilter ? listInstalledPlugins(scopeFilter) : listAllPlugins();
114
- const fromPlugins = plugins
115
- .filter((p) => p.enabled)
116
- .flatMap((p) => listAgentsInDir(join(p.root, AGENTS_DIR), p.scope, p.name));
117
- return [...fromScopeRoots, ...fromPlugins].sort((a, b) => a.name.localeCompare(b.name));
118
- }
119
- /** Canonical, unambiguous identifier: `<plugin>/<name>`, or bare `<name>` for
120
- * scope-root agents. */
121
- export function subagentId(a) {
122
- return a.plugin === SCOPE_SKILL_PLUGIN ? a.name : `${a.plugin}/${a.name}`;
123
- }
124
- /** Resolve a subagent by name. Accepts a bare `<name>` or a `<plugin>/<name>`
125
- * qualifier. Project precedes user precedes builtin; scope-root precedes
126
- * plugin. Throws notFound / ambiguous as the skill resolver does. */
127
- export function resolveSubagent(rawName, opts = {}) {
128
- const slash = rawName.indexOf('/');
129
- const pluginQualifier = opts.plugin ?? (slash !== -1 ? rawName.slice(0, slash) : undefined);
130
- const name = slash !== -1 && opts.plugin === undefined ? rawName.slice(slash + 1) : rawName;
131
- const all = listSubagents(opts.scope);
132
- let matches = all.filter((a) => a.name === name);
133
- if (pluginQualifier !== undefined) {
134
- matches = matches.filter((a) => a.plugin === pluginQualifier ||
135
- (pluginQualifier === SCOPE_SKILL_PLUGIN && a.plugin === SCOPE_SKILL_PLUGIN));
136
- }
137
- if (matches.length === 1)
138
- return matches[0];
139
- if (matches.length === 0) {
140
- const known = all.map(subagentId).slice(0, 8).join(', ');
141
- throw notFound(`subagent not found: ${rawName}`, {
142
- subagent: name,
143
- plugin: pluginQualifier,
144
- next: known !== ''
145
- ? `Known subagents: ${known}. Run \`crtr agent subagent list\` for the full set.`
146
- : 'No subagents defined. Run `crtr agent subagent author -h` to scaffold one.',
147
- });
148
- }
149
- // Multiple matches: prefer the highest-precedence scope/source deterministically.
150
- const score = (a) => {
151
- const scopeScore = a.scope === 'project' ? 0 : a.scope === 'user' ? 1 : 2;
152
- const sourceScore = a.plugin === SCOPE_SKILL_PLUGIN ? 0 : 1;
153
- return scopeScore * 2 + sourceScore;
154
- };
155
- const sorted = [...matches].sort((a, b) => score(a) - score(b));
156
- if (score(sorted[0]) !== score(sorted[1]))
157
- return sorted[0];
158
- throw ambiguous(`ambiguous subagent: ${rawName}`, {
159
- subagent: name,
160
- candidates: matches.map((m) => ({ id: subagentId(m), scope: m.scope, path: m.path })),
161
- next: 'Qualify with `<plugin>/<name>` or pass --scope to disambiguate.',
162
- });
163
- }
@@ -1,27 +0,0 @@
1
- /**
2
- * First user message for a spec → plan handoff.
3
- *
4
- * Thin prompt: the worker discovers the full planning workflow by running
5
- * `crtr mode plan new -h`, then saves the plan via `crtr mode plan new`. This
6
- * avoids embedding the planPrompt() blob here and keeps the prompt in sync
7
- * with the live CLI without any coupling.
8
- */
9
- export declare function planHandoffPrompt(specPath: string, jobId: string): string;
10
- /**
11
- * First user message for a plan → implementation handoff.
12
- */
13
- export declare function implementHandoffPrompt(planPath: string, jobId: string): string;
14
- /**
15
- * First user message for a reviewer agent.
16
- * The reviewer submits via `crtr job submit` rather than `crtr agent submit`.
17
- */
18
- export declare function reviewerHandoffPrompt(artifactPath: string, artifactKind: 'plan' | 'spec', specPath: string | null, jobId: string): string;
19
- /**
20
- * First user message for a general `agent new` worker.
21
- *
22
- * The worker runs as an interactive agent in a tmux pane (not print mode), so
23
- * its stdout is NOT captured as the result — it must deliver its answer via
24
- * `crtr job submit`, exactly like the mode-handoff workers. The original task
25
- * is sent verbatim; the submit contract is appended after a separator.
26
- */
27
- export declare function agentNewPrompt(task: string, jobId: string): string;
@@ -1,184 +0,0 @@
1
- import { planReviewPrompt, specReviewPrompt } from './review.js';
2
- /**
3
- * First user message for a spec → plan handoff.
4
- *
5
- * Thin prompt: the worker discovers the full planning workflow by running
6
- * `crtr mode plan new -h`, then saves the plan via `crtr mode plan new`. This
7
- * avoids embedding the planPrompt() blob here and keeps the prompt in sync
8
- * with the live CLI without any coupling.
9
- */
10
- export function planHandoffPrompt(specPath, jobId) {
11
- return `You were launched in a new tmux pane to turn an approved spec into a plan.
12
-
13
- **Spec:** ${specPath}
14
-
15
- 1. Run \`crtr mode plan new -h\` to load the planning workflow and output schema.
16
- 2. Read the spec end-to-end.
17
- 3. Follow the workflow from step 1 and save the plan by passing the plan markdown to \`crtr mode plan new\` on stdin.
18
- 4. When done, submit a short markdown report on stdin:
19
-
20
- \`\`\`bash
21
- crtr job submit ${jobId} <<'MD'
22
- Plan saved at <path>. <one-line summary of the plan's shape>.
23
- MD
24
- \`\`\`
25
-
26
- If you cannot complete the plan, submit a failure with a reason:
27
-
28
- \`\`\`bash
29
- crtr job submit ${jobId} --status failed --reason "<why>"
30
- \`\`\`
31
-
32
- Begin now.`;
33
- }
34
- /**
35
- * First user message for a plan → implementation handoff.
36
- */
37
- export function implementHandoffPrompt(planPath, jobId) {
38
- return `You are executing an approved plan. For small plans, implement directly.
39
- For plans with parallelizable scale, orchestrate parallel subagents and
40
- coordinate them — don't write all the code yourself when the plan is
41
- structured to fan out.
42
-
43
- **Plan to implement:** ${planPath}
44
-
45
- ## Phase 1: Read
46
-
47
- 1. Read the plan end-to-end. If it references a spec, read that too.
48
- 2. Read the files the plan names under "Files to modify / create" and
49
- "Existing utilities to reuse" to ground yourself in current code.
50
- 3. If the plan has task blocks with dependencies, extract the task list,
51
- dependency graph, and integration contracts.
52
-
53
- ## Phase 2: Scale
54
-
55
- Count the plan's **independent task groups** (tasks with no mutual
56
- dependencies that can run in parallel). Pick the strategy:
57
-
58
- | Independent groups | Files touched | Strategy |
59
- |-------------------|---------------|----------|
60
- | 1 | 1–3 | **Implement directly.** Skip Phases 3–5; just execute the plan and go to Phase 6. |
61
- | 1–2 | 3–5 | Implement directly, or single subagent if you want parallelism with verification |
62
- | 2–4 | 5–15 | **2 parallel subagents** |
63
- | 4–8 | 10–30 | **3 parallel subagents** |
64
- | 8+ | 25+ | **4 parallel subagents** (cap) |
65
-
66
- Use the higher column to pick the tier. Never spawn more subagents than
67
- there are independent groups. **Bump one tier** if: tight cross-group
68
- interface coordination, mixed languages/frameworks, or both infra +
69
- application layers change.
70
-
71
- ## Phase 3: Partition
72
-
73
- Group tasks into **disjoint sets** where:
74
-
75
- - Each group owns clear file boundaries — **no two groups edit the same files**.
76
- - Within a group, tasks are sequenced for one subagent to execute in order.
77
- - Across groups, dependencies become layers: dependent groups run *after*
78
- their predecessors complete.
79
-
80
- If two tasks must touch the same file, sequence them in the same group.
81
-
82
- ## Phase 4: Dispatch
83
-
84
- For each task group in the current dependency layer, dispatch a subagent
85
- in parallel via the Task tool. Use \`general-purpose\` by default; use
86
- \`devcore:programmer\` if the project has devcore installed.
87
-
88
- **Each subagent's prompt must include:**
89
- - The specific tasks from the plan it owns (paste verbatim)
90
- - The plan path: \`${planPath}\`
91
- - The spec path if one exists
92
- - The exact file ownership for this group
93
- - Integration contracts it produces or consumes (types, APIs, shapes)
94
- - **Constraint: do NOT run tests or typechecks** — other subagents may be
95
- mid-edit. The orchestrator runs verification at layer boundaries.
96
- - Instruction to return when its tasks are complete, surfacing blockers
97
-
98
- ## Phase 5: Coordinate
99
-
100
- Wait for all subagents in the current layer. Then:
101
-
102
- - If any reports a blocker, resolve it: fix yourself, adjust scope with
103
- the user, or re-dispatch a corrected task. Don't proceed past the blocker.
104
- - Run the plan's verification for the just-finished layer (tests, manual
105
- checks). Fix any failures before dispatching the next layer.
106
- - Dispatch the next layer.
107
-
108
- **Stay in the coordinator role.** Don't implement tasks yourself unless a
109
- subagent returns blocked work and the fix is small enough that re-dispatch
110
- would be slower.
111
-
112
- ## Phase 6: Report and submit
113
-
114
- When all tasks complete and verification passes, submit a markdown report on stdin:
115
-
116
- \`\`\`bash
117
- crtr job submit ${jobId} <<'MD'
118
- **Summary:** <one-line summary of files touched>
119
-
120
- <optional further notes — verification output, surprises, callouts>
121
- MD
122
- \`\`\`
123
-
124
- If implementation fails, submit a failure with a reason:
125
- \`\`\`bash
126
- crtr job submit ${jobId} --status failed --reason "<why>"
127
- \`\`\`
128
-
129
- ## Guardrails (apply to you AND your subagents)
130
-
131
- - **No redesign.** If the plan is wrong, surface the issue — do not
132
- silently substitute your own approach.
133
- - **No scope expansion.** No drive-by refactors, no "while I'm here"
134
- cleanup, no new abstractions the plan didn't request.
135
- - **Honor conventions.** Match each file's existing style, naming, and
136
- patterns. Use the utilities the plan named.
137
- - **Commit only if the user asks.**
138
-
139
- Begin by reading the plan.`;
140
- }
141
- /**
142
- * First user message for a reviewer agent.
143
- * The reviewer submits via `crtr job submit` rather than `crtr agent submit`.
144
- */
145
- export function reviewerHandoffPrompt(artifactPath, artifactKind, specPath, jobId) {
146
- const reviewBody = artifactKind === 'spec'
147
- ? specReviewPrompt(artifactPath)
148
- : planReviewPrompt(artifactPath, specPath);
149
- const patched = reviewBody.replace('__CRTR_SUBMIT_INSTRUCTION__', `the submit command injected below. Pipe your full review markdown on stdin. The \`--kill-pane\` flag closes this reviewer pane after submission — keep it, do not drop it.\n\n\`\`\`bash\ncrtr job submit ${jobId} --kill-pane <<'MD'\n<your full review markdown — the same Status/Issues/Recommendations block you composed above>\nMD\n\`\`\`\n\nIf the artifact is too malformed to review, submit a failure instead:\n\n\`\`\`bash\ncrtr job submit ${jobId} --status failed --reason "<why>" --kill-pane\n\`\`\``);
150
- return `${patched}
151
-
152
- After calling \`crtr job submit\`, your turn ends and the pane closes itself. Do NOT chat or summarize after submission.`;
153
- }
154
- /**
155
- * First user message for a general `agent new` worker.
156
- *
157
- * The worker runs as an interactive agent in a tmux pane (not print mode), so
158
- * its stdout is NOT captured as the result — it must deliver its answer via
159
- * `crtr job submit`, exactly like the mode-handoff workers. The original task
160
- * is sent verbatim; the submit contract is appended after a separator.
161
- */
162
- export function agentNewPrompt(task, jobId) {
163
- return `${task}
164
-
165
- ---
166
-
167
- When you have finished the task above, deliver your final answer by piping your
168
- full markdown result to \`crtr job submit\` — this is how the result is returned
169
- to whoever spawned you:
170
-
171
- \`\`\`bash
172
- crtr job submit ${jobId} <<'MD'
173
- <your complete answer / findings>
174
- MD
175
- \`\`\`
176
-
177
- If you cannot complete the task, submit a failure with a reason instead:
178
-
179
- \`\`\`bash
180
- crtr job submit ${jobId} --status failed --reason "<why>"
181
- \`\`\`
182
-
183
- Do your work first; submit exactly once when done. After submitting, your turn ends.`;
184
- }
@@ -1,8 +0,0 @@
1
- /**
2
- * First user message for a reproduction-only debug handoff.
3
- *
4
- * The agent's sole job is ONE failing integration test that reproduces the
5
- * reported bug. It never fixes the bug. Symmetric with the agent.ts handoff
6
- * builders: thin prompt, exact submit contract, turn ends after submit.
7
- */
8
- export declare function reproHandoffPrompt(issue: string, jobId: string): string;
@@ -1,44 +0,0 @@
1
- /**
2
- * First user message for a reproduction-only debug handoff.
3
- *
4
- * The agent's sole job is ONE failing integration test that reproduces the
5
- * reported bug. It never fixes the bug. Symmetric with the agent.ts handoff
6
- * builders: thin prompt, exact submit contract, turn ends after submit.
7
- */
8
- export function reproHandoffPrompt(issue, jobId) {
9
- return `You were spawned solely to write ONE integration test that fails *because of this bug*:
10
-
11
- ${issue}
12
-
13
- Rules — follow exactly:
14
-
15
- - Do NOT fix the bug. Do NOT modify product code to make a test pass. Your only output is a test.
16
- - The test must fail against the current code, and the failure must BE the reported bug — not an import error, a typo, or an unrelated assertion. Run it; paste the real failing output; confirm the failure mode matches the issue.
17
- - Prefer an integration test against real dependencies. Mocking away the broken component is theater and does NOT count as reproduction.
18
- - If you cannot produce a faithful failing test, GIVE UP. Never weaken assertions, hardcode expected values, or fabricate a clean-looking run — a tautological or over-mocked test is worse than none.
19
-
20
- Submit exactly one of the following via \`crtr job submit\`, then your turn ends — do not chat:
21
-
22
- Reproduced (markdown body on stdin):
23
- \`\`\`bash
24
- crtr job submit ${jobId} <<'MD'
25
- **Reproduces:** yes
26
-
27
- **Test path:** <path>
28
-
29
- **Test command:** \`<exact cmd>\`
30
-
31
- **Failure output:**
32
- \`\`\`
33
- <pasted failing output>
34
- \`\`\`
35
- MD
36
- \`\`\`
37
-
38
- Gave up (no faithful repro achievable):
39
- \`\`\`bash
40
- crtr job submit ${jobId} --status failed --reason "<why a faithful repro was not achievable>"
41
- \`\`\`
42
-
43
- Begin now.`;
44
- }