@crouton-kit/crouter 0.3.3 → 0.3.11

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 (57) hide show
  1. package/README.md +2 -2
  2. package/dist/builtin-skills/skills/crouter-development/marketplaces/SKILL.md +1 -1
  3. package/dist/builtin-skills/skills/crouter-development/plugins/SKILL.md +3 -3
  4. package/dist/cli.js +16 -26
  5. package/dist/commands/__tests__/skill.test.js +24 -28
  6. package/dist/commands/agent.d.ts +6 -0
  7. package/dist/commands/agent.js +585 -0
  8. package/dist/commands/debug.d.ts +1 -1
  9. package/dist/commands/debug.js +20 -7
  10. package/dist/commands/human.js +51 -19
  11. package/dist/commands/job.d.ts +9 -0
  12. package/dist/commands/job.js +100 -385
  13. package/dist/commands/{flow.d.ts → mode.d.ts} +1 -1
  14. package/dist/commands/mode.js +231 -0
  15. package/dist/commands/pkg.js +5 -0
  16. package/dist/commands/plan.d.ts +1 -1
  17. package/dist/commands/plan.js +24 -11
  18. package/dist/commands/skill.js +130 -107
  19. package/dist/commands/spec.d.ts +1 -1
  20. package/dist/commands/spec.js +24 -11
  21. package/dist/commands/sys.js +5 -0
  22. package/dist/core/__tests__/job.test.js +38 -74
  23. package/dist/core/__tests__/jobs.test.d.ts +1 -0
  24. package/dist/core/__tests__/jobs.test.js +98 -0
  25. package/dist/core/__tests__/resolver.test.d.ts +1 -0
  26. package/dist/core/__tests__/resolver.test.js +181 -0
  27. package/dist/core/__tests__/spawn.test.d.ts +1 -0
  28. package/dist/core/__tests__/spawn.test.js +138 -0
  29. package/dist/core/__tests__/subagents.test.d.ts +1 -0
  30. package/dist/core/__tests__/subagents.test.js +75 -0
  31. package/dist/core/__tests__/unknown-path.test.d.ts +1 -0
  32. package/dist/core/__tests__/unknown-path.test.js +52 -0
  33. package/dist/core/bootstrap.d.ts +2 -0
  34. package/dist/core/bootstrap.js +66 -0
  35. package/dist/core/command.d.ts +58 -2
  36. package/dist/core/command.js +62 -14
  37. package/dist/core/config.js +20 -2
  38. package/dist/core/frontmatter.d.ts +10 -0
  39. package/dist/core/frontmatter.js +24 -9
  40. package/dist/core/help.d.ts +39 -8
  41. package/dist/core/help.js +64 -32
  42. package/dist/core/jobs.d.ts +33 -13
  43. package/dist/core/jobs.js +259 -47
  44. package/dist/core/resolver.d.ts +1 -2
  45. package/dist/core/resolver.js +111 -47
  46. package/dist/core/spawn.d.ts +150 -10
  47. package/dist/core/spawn.js +493 -41
  48. package/dist/core/subagents.d.ts +18 -0
  49. package/dist/core/subagents.js +163 -0
  50. package/dist/prompts/agent.d.ts +12 -3
  51. package/dist/prompts/agent.js +51 -18
  52. package/dist/prompts/debug.js +14 -7
  53. package/dist/prompts/skill.js +16 -16
  54. package/dist/types.d.ts +22 -1
  55. package/dist/types.js +5 -2
  56. package/package.json +2 -2
  57. package/dist/commands/flow.js +0 -24
package/README.md CHANGED
@@ -19,8 +19,8 @@ crtr --help
19
19
  Browse and install plugins from it:
20
20
 
21
21
  ```bash
22
- crtr marketplace browse crouter-official-marketplace
23
- crtr marketplace install crouter-official-marketplace:<plugin>
22
+ crtr pkg market inspect browse --marketplace crouter-official-marketplace
23
+ crtr pkg market manage install --marketplace crouter-official-marketplace --plugin <plugin>
24
24
  ```
25
25
 
26
26
  To opt out of the bootstrap (e.g. in CI), set `CRTR_NO_BOOTSTRAP=1`.
@@ -107,7 +107,7 @@ mkdir -p plugins/my-new-plugin/.crouter-plugin plugins/my-new-plugin/skills
107
107
  $EDITOR plugins/my-new-plugin/.crouter-plugin/plugin.json
108
108
 
109
109
  # Add at least one skill
110
- crtr skill author scaffold my-new-plugin:first-skill --type playbook --description "Use when …"
110
+ crtr skill author scaffold my-new-plugin/first-skill --type playbook --description "Use when …"
111
111
 
112
112
  # Add the plugin to the marketplace index
113
113
  $EDITOR .crouter-marketplace/marketplace.json
@@ -96,7 +96,7 @@ Three ways a plugin lands in a scope:
96
96
  mkdir -p my-plugin/.crouter-plugin my-plugin/skills
97
97
  $EDITOR my-plugin/.crouter-plugin/plugin.json # write the manifest
98
98
  cd my-plugin
99
- crtr skill author scaffold my-plugin:my-first-skill --type playbook --description "Use when …"
99
+ crtr skill author scaffold my-plugin/my-first-skill --type playbook --description "Use when …"
100
100
 
101
101
  # Symlink for fast iteration — no clone, edits land immediately
102
102
  ln -s $(pwd) ~/.crouter/plugins/my-plugin
@@ -124,9 +124,9 @@ Standard semver:
124
124
 
125
125
  ## Enable/disable
126
126
 
127
- `crtr pkg plugin manage disable <name>` flips the per-scope config without removing files. Disabled plugins are hidden from `crtr skill find list` and don't resolve via `crtr skill read show <name>`. Re-enable with `crtr pkg plugin manage enable <name>`.
127
+ `crtr pkg plugin manage disable <name>` flips the per-scope config without removing files. Disabled plugins are hidden from `crtr skill find list` and don't resolve via `crtr skill read <name>`. Re-enable with `crtr pkg plugin manage enable <name>`.
128
128
 
129
- Individual skills inside an enabled plugin can also be disabled: `crtr skill state disable <plugin>:<skill>`.
129
+ Individual skills inside an enabled plugin can also be disabled: `crtr skill state disable <plugin>/<skill>`.
130
130
 
131
131
  ## What goes in a plugin
132
132
 
package/dist/cli.js CHANGED
@@ -1,38 +1,27 @@
1
1
  #!/usr/bin/env node
2
2
  import { defineRoot, runCli } from './core/command.js';
3
- import { registerFlow } from './commands/flow.js';
3
+ import { registerAgent } from './commands/agent.js';
4
+ import { registerMode } from './commands/mode.js';
4
5
  import { registerSkill } from './commands/skill.js';
5
- import { registerPkg } from './commands/pkg.js';
6
6
  import { registerJob } from './commands/job.js';
7
+ import { registerPkg } from './commands/pkg.js';
7
8
  import { registerHuman } from './commands/human.js';
8
9
  import { registerSys } from './commands/sys.js';
9
10
  import { maybeAutoUpdate } from './core/auto-update.js';
10
- import { ensureBootSkill, ensureOfficialMarketplace, ensureProjectScope } from './core/bootstrap.js';
11
+ import { ensureBootSkill, ensureOfficialMarketplace, ensureProjectScope, ensureSlashCommands } from './core/bootstrap.js';
12
+ // Root owns only the tagline and globals. Every subtree's concept line,
13
+ // selection rubric, and any dynamic block it contributes to root -h are
14
+ // declared on the subtree itself (its rootEntry) and assembled here by
15
+ // defineRoot. Add a subtree to this list and it appears at root; nothing about
16
+ // it is restated here.
11
17
  const root = defineRoot({
12
- help: {
13
- tagline: 'crtr: agentic planning runtime.',
14
- concepts: [
15
- { name: 'flow', desc: 'spec → plan → debug: the development process' },
16
- { name: 'skill', desc: 'loadable SKILL.md document an agent reads to adopt a workflow' },
17
- { name: 'pkg', desc: 'plugins and marketplaces that supply skills' },
18
- { name: 'job', desc: 'a running agent worker and its logs and result' },
19
- { name: 'human', desc: 'human-in-the-loop decisions, document review, and live display' },
20
- { name: 'sys', desc: 'crtr configuration, diagnostics, and self-management' },
21
- ],
22
- subtrees: [
23
- { name: 'flow', desc: 'spec, plan, and debug workflows', useWhen: 'capturing requirements, planning work, or root-causing a bug' },
24
- { name: 'skill', desc: 'discover, read, author, and manage skills', useWhen: 'working with SKILL.md documents' },
25
- { name: 'pkg', desc: 'manage plugins and marketplaces', useWhen: 'installing or browsing skill collections' },
26
- { name: 'job', desc: 'spawn, monitor, and collect from agent workers', useWhen: 'running or watching agent jobs' },
27
- { name: 'human', desc: 'ask, approve, review, notify, show, inbox, list', useWhen: 'putting a decision or document in front of a person' },
28
- { name: 'sys', desc: 'config, doctor, update, version', useWhen: 'managing the crtr installation' },
29
- ],
30
- globals: [
31
- { name: '-h', desc: 'print help for any node — append to any subcommand path' },
32
- ],
33
- },
18
+ tagline: 'crtr: agentic planning runtime.',
19
+ globals: [
20
+ { name: '-h', desc: 'print help for any node — append to any subcommand path' },
21
+ ],
34
22
  subtrees: [
35
- registerFlow(),
23
+ registerAgent(),
24
+ registerMode(),
36
25
  registerSkill(),
37
26
  registerPkg(),
38
27
  registerJob(),
@@ -42,6 +31,7 @@ const root = defineRoot({
42
31
  });
43
32
  ensureOfficialMarketplace(process.argv);
44
33
  ensureBootSkill(process.argv);
34
+ ensureSlashCommands(root, process.argv);
45
35
  ensureProjectScope(process.argv);
46
36
  maybeAutoUpdate(process.argv);
47
37
  runCli(root, process.argv).catch((err) => {
@@ -139,14 +139,15 @@ describe('skill find grep params', () => {
139
139
  });
140
140
  });
141
141
  // ---------------------------------------------------------------------------
142
- // skill read show
142
+ // skill read
143
143
  // ---------------------------------------------------------------------------
144
- describe('skill read show params', () => {
144
+ describe('skill read params', () => {
145
145
  const params = [
146
146
  { kind: 'positional', name: 'name', required: true, constraint: '' },
147
147
  scopeWriteFlag,
148
148
  pluginFlag,
149
149
  { kind: 'flag', name: 'frontmatter', type: 'bool', required: false, constraint: '' },
150
+ { kind: 'flag', name: 'no-body', type: 'bool', required: false, constraint: '' },
150
151
  ];
151
152
  test('name positional required', async () => {
152
153
  await assert.rejects(() => parseArgv(params, []), (e) => { assert.match(e.message, /required parameter is missing/); return true; });
@@ -155,6 +156,10 @@ describe('skill read show params', () => {
155
156
  const r = await parseArgv(params, ['my-skill']);
156
157
  assert.equal(r['name'], 'my-skill');
157
158
  });
159
+ test('nested name parsed correctly', async () => {
160
+ const r = await parseArgv(params, ['some/nested/skill']);
161
+ assert.equal(r['name'], 'some/nested/skill');
162
+ });
158
163
  test('--frontmatter presence = true', async () => {
159
164
  const r = await parseArgv(params, ['my-skill', '--frontmatter']);
160
165
  assert.equal(r['frontmatter'], true);
@@ -163,6 +168,14 @@ describe('skill read show params', () => {
163
168
  const r = await parseArgv(params, ['my-skill']);
164
169
  assert.equal(r['frontmatter'], false);
165
170
  });
171
+ test('--no-body presence = true (kebab to camelCase key)', async () => {
172
+ const r = await parseArgv(params, ['my-skill', '--no-body']);
173
+ assert.equal(r['noBody'], true);
174
+ });
175
+ test('--no-body absent = false', async () => {
176
+ const r = await parseArgv(params, ['my-skill']);
177
+ assert.equal(r['noBody'], false);
178
+ });
166
179
  test('--scope rejects all', async () => {
167
180
  await assert.rejects(() => parseArgv(params, ['my-skill', '--scope', 'all']), (e) => { assert.match(e.message, /must be one of/); return true; });
168
181
  });
@@ -170,23 +183,6 @@ describe('skill read show params', () => {
170
183
  const r = await parseArgv(params, ['my-skill', '--scope', 'user']);
171
184
  assert.equal(r['scope'], 'user');
172
185
  });
173
- });
174
- // ---------------------------------------------------------------------------
175
- // skill read where
176
- // ---------------------------------------------------------------------------
177
- describe('skill read where params', () => {
178
- const params = [
179
- { kind: 'positional', name: 'name', required: true, constraint: '' },
180
- scopeWriteFlag,
181
- pluginFlag,
182
- ];
183
- test('name positional required', async () => {
184
- await assert.rejects(() => parseArgv(params, []), (e) => { assert.match(e.message, /required parameter is missing/); return true; });
185
- });
186
- test('name parsed correctly', async () => {
187
- const r = await parseArgv(params, ['some/nested/skill']);
188
- assert.equal(r['name'], 'some/nested/skill');
189
- });
190
186
  test('--scope project valid', async () => {
191
187
  const r = await parseArgv(params, ['skillname', '--scope', 'project']);
192
188
  assert.equal(r['scope'], 'project');
@@ -239,26 +235,26 @@ describe('skill author scaffold params', () => {
239
235
  await assert.rejects(() => parseArgv(params, []), (e) => { assert.match(e.message, /required parameter is missing/); return true; });
240
236
  });
241
237
  test('qualifier parsed correctly', async () => {
242
- const r = await parseArgv(params, ['myplugin:myskill']);
243
- assert.equal(r['qualifier'], 'myplugin:myskill');
238
+ const r = await parseArgv(params, ['myplugin/myskill']);
239
+ assert.equal(r['qualifier'], 'myplugin/myskill');
244
240
  });
245
241
  test('full invocation', async () => {
246
242
  const r = await parseArgv(params, [
247
- 'myplugin:myskill',
243
+ 'myplugin/myskill',
248
244
  '--type', 'playbook',
249
245
  '--scope', 'project',
250
246
  '--description', 'Use when debugging',
251
247
  ]);
252
- assert.equal(r['qualifier'], 'myplugin:myskill');
248
+ assert.equal(r['qualifier'], 'myplugin/myskill');
253
249
  assert.equal(r['type'], 'playbook');
254
250
  assert.equal(r['scope'], 'project');
255
251
  assert.equal(r['description'], 'Use when debugging');
256
252
  });
257
253
  test('--type invalid rejects', async () => {
258
- await assert.rejects(() => parseArgv(params, ['q:s', '--type', 'invalid']), (e) => { assert.match(e.message, /must be one of/); return true; });
254
+ await assert.rejects(() => parseArgv(params, ['q/s', '--type', 'invalid']), (e) => { assert.match(e.message, /must be one of/); return true; });
259
255
  });
260
256
  test('--scope all rejects', async () => {
261
- await assert.rejects(() => parseArgv(params, ['q:s', '--scope', 'all']), (e) => { assert.match(e.message, /must be one of/); return true; });
257
+ await assert.rejects(() => parseArgv(params, ['q/s', '--scope', 'all']), (e) => { assert.match(e.message, /must be one of/); return true; });
262
258
  });
263
259
  });
264
260
  // ---------------------------------------------------------------------------
@@ -287,8 +283,8 @@ describe('skill state enable/disable params', () => {
287
283
  test('--scope all rejects', async () => {
288
284
  await assert.rejects(() => parseArgv(params, ['my-skill', '--scope', 'all']), (e) => { assert.match(e.message, /must be one of/); return true; });
289
285
  });
290
- test('plugin:skill qualifier as name', async () => {
291
- const r = await parseArgv(params, ['myplugin:myskill']);
292
- assert.equal(r['name'], 'myplugin:myskill');
286
+ test('plugin/skill qualifier as name', async () => {
287
+ const r = await parseArgv(params, ['myplugin/myskill']);
288
+ assert.equal(r['name'], 'myplugin/myskill');
293
289
  });
294
290
  });
@@ -0,0 +1,6 @@
1
+ import type { BranchDef } from '../core/command.js';
2
+ export declare const DEFAULT_KILL_SECS = 2;
3
+ export declare function followUpResult(jobId: string): string;
4
+ export declare function resolveMaxPanes(): number;
5
+ export declare function assertTmux(): void;
6
+ export declare function registerAgent(): BranchDef;