@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.
- package/README.md +2 -2
- package/dist/builtin-skills/skills/crouter-development/marketplaces/SKILL.md +1 -1
- package/dist/builtin-skills/skills/crouter-development/plugins/SKILL.md +3 -3
- package/dist/cli.js +16 -26
- package/dist/commands/__tests__/skill.test.js +24 -28
- package/dist/commands/agent.d.ts +6 -0
- package/dist/commands/agent.js +585 -0
- package/dist/commands/debug.d.ts +1 -1
- package/dist/commands/debug.js +20 -7
- package/dist/commands/human.js +51 -19
- package/dist/commands/job.d.ts +9 -0
- package/dist/commands/job.js +100 -385
- package/dist/commands/{flow.d.ts → mode.d.ts} +1 -1
- package/dist/commands/mode.js +231 -0
- package/dist/commands/pkg.js +5 -0
- package/dist/commands/plan.d.ts +1 -1
- package/dist/commands/plan.js +24 -11
- package/dist/commands/skill.js +130 -107
- package/dist/commands/spec.d.ts +1 -1
- package/dist/commands/spec.js +24 -11
- package/dist/commands/sys.js +5 -0
- package/dist/core/__tests__/job.test.js +38 -74
- package/dist/core/__tests__/jobs.test.d.ts +1 -0
- package/dist/core/__tests__/jobs.test.js +98 -0
- package/dist/core/__tests__/resolver.test.d.ts +1 -0
- package/dist/core/__tests__/resolver.test.js +181 -0
- package/dist/core/__tests__/spawn.test.d.ts +1 -0
- package/dist/core/__tests__/spawn.test.js +138 -0
- package/dist/core/__tests__/subagents.test.d.ts +1 -0
- package/dist/core/__tests__/subagents.test.js +75 -0
- package/dist/core/__tests__/unknown-path.test.d.ts +1 -0
- package/dist/core/__tests__/unknown-path.test.js +52 -0
- package/dist/core/bootstrap.d.ts +2 -0
- package/dist/core/bootstrap.js +66 -0
- package/dist/core/command.d.ts +58 -2
- package/dist/core/command.js +62 -14
- package/dist/core/config.js +20 -2
- package/dist/core/frontmatter.d.ts +10 -0
- package/dist/core/frontmatter.js +24 -9
- package/dist/core/help.d.ts +39 -8
- package/dist/core/help.js +64 -32
- package/dist/core/jobs.d.ts +33 -13
- package/dist/core/jobs.js +259 -47
- package/dist/core/resolver.d.ts +1 -2
- package/dist/core/resolver.js +111 -47
- package/dist/core/spawn.d.ts +150 -10
- package/dist/core/spawn.js +493 -41
- package/dist/core/subagents.d.ts +18 -0
- package/dist/core/subagents.js +163 -0
- package/dist/prompts/agent.d.ts +12 -3
- package/dist/prompts/agent.js +51 -18
- package/dist/prompts/debug.js +14 -7
- package/dist/prompts/skill.js +16 -16
- package/dist/types.d.ts +22 -1
- package/dist/types.js +5 -2
- package/package.json +2 -2
- 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
|
|
23
|
-
crtr
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 {
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
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
|
|
142
|
+
// skill read
|
|
143
143
|
// ---------------------------------------------------------------------------
|
|
144
|
-
describe('skill read
|
|
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
|
|
243
|
-
assert.equal(r['qualifier'], 'myplugin
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
291
|
-
const r = await parseArgv(params, ['myplugin
|
|
292
|
-
assert.equal(r['name'], 'myplugin
|
|
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;
|