@ze-norm/cli 0.14.1 → 0.14.2
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/dist/commands/interactive-agent.d.ts +1 -1
- package/dist/commands/pull.d.ts.map +1 -1
- package/dist/commands/pull.js +5 -3
- package/dist/commands/task.d.ts.map +1 -1
- package/dist/commands/task.js +3 -1
- package/dist/commands/work.d.ts +5 -4
- package/dist/commands/work.d.ts.map +1 -1
- package/dist/commands/work.js +24 -10
- package/dist/zenorm-skills/skills/zenorm/SKILL.md +8 -5
- package/package.json +1 -1
|
@@ -6,7 +6,7 @@ import type { ChildProcess, SpawnOptions } from "node:child_process";
|
|
|
6
6
|
* the daemon does NOT run the agent headlessly. Instead it launches the active
|
|
7
7
|
* coding agent — Claude Code by default, or Codex when the user runs with
|
|
8
8
|
* `--agent codex` — as a *live interactive session*, seeded with the
|
|
9
|
-
*
|
|
9
|
+
* harness-native ZeNorm skill handoff. The agent owns the terminal directly (inherited
|
|
10
10
|
* stdio), so the operator works with it interactively until they close it; when
|
|
11
11
|
* the agent exits, the daemon releases the worker and moves on to the next task.
|
|
12
12
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"AAcA,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"AAcA,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA8F/D"}
|
package/dist/commands/pull.js
CHANGED
|
@@ -39,9 +39,11 @@ export async function pullCommand(argv) {
|
|
|
39
39
|
log.debug("Listing specs to resolve by key", { specRef });
|
|
40
40
|
const { specs } = await client.get("/v1/specs");
|
|
41
41
|
spec = specs.find((s) => s.key === specRef);
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
if (!spec) {
|
|
43
|
+
const available = specs.map((s) => s.key).join(", ");
|
|
44
|
+
throw new CliError(`Spec "${specRef}" not found by key or id.` +
|
|
45
|
+
(available ? ` Available spec keys: ${available}` : " The workspace has no specs."));
|
|
46
|
+
}
|
|
45
47
|
}
|
|
46
48
|
// Fetch grilled blocks (goals, constraints, acceptance criteria, tasks).
|
|
47
49
|
let blocksMd = "";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../../src/commands/task.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../../src/commands/task.ts"],"names":[],"mappings":"AA2OA,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAqB/D"}
|
package/dist/commands/task.js
CHANGED
|
@@ -33,7 +33,9 @@ async function resolveSpecId(client, specRef) {
|
|
|
33
33
|
const { specs } = await client.get("/v1/specs");
|
|
34
34
|
const spec = specs.find((s) => s.key === specRef);
|
|
35
35
|
if (!spec) {
|
|
36
|
-
|
|
36
|
+
const available = specs.map((s) => s.key).join(", ");
|
|
37
|
+
throw new CliError(`Spec "${specRef}" not found by key or id.` +
|
|
38
|
+
(available ? ` Available spec keys: ${available}` : " The workspace has no specs."));
|
|
37
39
|
}
|
|
38
40
|
return spec.id;
|
|
39
41
|
}
|
package/dist/commands/work.d.ts
CHANGED
|
@@ -23,8 +23,9 @@ export interface TaskRunner {
|
|
|
23
23
|
* Build the handoff prompt that hands the agent the WHOLE SPEC the claimed task
|
|
24
24
|
* belongs to, so a single agent session implements every available task for that
|
|
25
25
|
* spec with shared context — instead of one fresh session per task. The
|
|
26
|
-
*
|
|
27
|
-
*
|
|
26
|
+
* harness-native ZeNorm invocation (`/zenorm` for Claude Code, `$zenorm`
|
|
27
|
+
* for Codex) triggers the dispatcher in spec mode, where `execute-task` walks
|
|
28
|
+
* every `planned`/`todo` task in order.
|
|
28
29
|
*
|
|
29
30
|
* The claim only flips THIS one task to `active` server-side (the lease that
|
|
30
31
|
* proves there is work for this repo and guards against a second daemon). The
|
|
@@ -35,14 +36,14 @@ export interface TaskRunner {
|
|
|
35
36
|
*
|
|
36
37
|
* Exported for unit testing.
|
|
37
38
|
*/
|
|
38
|
-
export declare function buildHandoffPrompt(task: SpecTaskRecord): string;
|
|
39
|
+
export declare function buildHandoffPrompt(task: SpecTaskRecord, agent: SupportedAgent): string;
|
|
39
40
|
/**
|
|
40
41
|
* The interactive (coding-agent mode) handoff prompt. Same spec-mode handoff as
|
|
41
42
|
* the headless prompt, MINUS the "work non-interactively" instruction: in this
|
|
42
43
|
* mode the agent runs as a live session the operator drives, so it SHOULD pause
|
|
43
44
|
* for input. Exported for unit testing.
|
|
44
45
|
*/
|
|
45
|
-
export declare function buildInteractiveHandoffPrompt(task: SpecTaskRecord): string;
|
|
46
|
+
export declare function buildInteractiveHandoffPrompt(task: SpecTaskRecord, agent: SupportedAgent): string;
|
|
46
47
|
/**
|
|
47
48
|
* The headless subprocess invocation for a given agent + task. Pure (no
|
|
48
49
|
* side effects) so it can be unit-tested directly without spawning anything.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"work.d.ts","sourceRoot":"","sources":["../../src/commands/work.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,EAGV,cAAc,EAEf,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EAIL,KAAK,QAAQ,EACd,MAAM,wBAAwB,CAAC;AAehC;;;;GAIG;AACH,QAAA,MAAM,gBAAgB,8BAA+B,CAAC;AACtD,KAAK,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAuCxD;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,GAAG,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAeD
|
|
1
|
+
{"version":3,"file":"work.d.ts","sourceRoot":"","sources":["../../src/commands/work.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/work.js
CHANGED
|
@@ -61,8 +61,9 @@ const AGENT_INSTALL_HINT = {
|
|
|
61
61
|
* Build the handoff prompt that hands the agent the WHOLE SPEC the claimed task
|
|
62
62
|
* belongs to, so a single agent session implements every available task for that
|
|
63
63
|
* spec with shared context — instead of one fresh session per task. The
|
|
64
|
-
*
|
|
65
|
-
*
|
|
64
|
+
* harness-native ZeNorm invocation (`/zenorm` for Claude Code, `$zenorm`
|
|
65
|
+
* for Codex) triggers the dispatcher in spec mode, where `execute-task` walks
|
|
66
|
+
* every `planned`/`todo` task in order.
|
|
66
67
|
*
|
|
67
68
|
* The claim only flips THIS one task to `active` server-side (the lease that
|
|
68
69
|
* proves there is work for this repo and guards against a second daemon). The
|
|
@@ -73,10 +74,10 @@ const AGENT_INSTALL_HINT = {
|
|
|
73
74
|
*
|
|
74
75
|
* Exported for unit testing.
|
|
75
76
|
*/
|
|
76
|
-
export function buildHandoffPrompt(task) {
|
|
77
|
+
export function buildHandoffPrompt(task, agent) {
|
|
77
78
|
const zenormCli = process.env["ZENORM_CLI"]?.trim() || "zenorm";
|
|
78
79
|
return [
|
|
79
|
-
...handoffPromptBody(task, zenormCli),
|
|
80
|
+
...handoffPromptBody(task, zenormCli, agent),
|
|
80
81
|
// Headless runs have no operator to wait on — tell the agent to drive
|
|
81
82
|
// straight through without pausing for input. The interactive variant
|
|
82
83
|
// (buildInteractiveHandoffPrompt) deliberately omits this line.
|
|
@@ -89,14 +90,14 @@ export function buildHandoffPrompt(task) {
|
|
|
89
90
|
* mode the agent runs as a live session the operator drives, so it SHOULD pause
|
|
90
91
|
* for input. Exported for unit testing.
|
|
91
92
|
*/
|
|
92
|
-
export function buildInteractiveHandoffPrompt(task) {
|
|
93
|
+
export function buildInteractiveHandoffPrompt(task, agent) {
|
|
93
94
|
const zenormCli = process.env["ZENORM_CLI"]?.trim() || "zenorm";
|
|
94
|
-
return handoffPromptBody(task, zenormCli).join("\n");
|
|
95
|
+
return handoffPromptBody(task, zenormCli, agent).join("\n");
|
|
95
96
|
}
|
|
96
97
|
/** Shared spec-mode handoff lines for both the headless and interactive prompts. */
|
|
97
|
-
function handoffPromptBody(task, zenormCli) {
|
|
98
|
+
function handoffPromptBody(task, zenormCli, agent) {
|
|
98
99
|
return [
|
|
99
|
-
|
|
100
|
+
buildSkillInvocation(agent, task.specId),
|
|
100
101
|
"",
|
|
101
102
|
`Execute ALL available tasks for ZeNorm spec ${task.specId} in THIS one`,
|
|
102
103
|
"session (spec mode — walk every `planned`/`todo` task in list order). Do not",
|
|
@@ -112,6 +113,19 @@ function handoffPromptBody(task, zenormCli) {
|
|
|
112
113
|
`\`${zenormCli} task complete <task-id>\` flow as you finish it.`,
|
|
113
114
|
];
|
|
114
115
|
}
|
|
116
|
+
/** Build the explicit skill invocation understood by the selected harness. */
|
|
117
|
+
function buildSkillInvocation(agent, specId) {
|
|
118
|
+
switch (agent) {
|
|
119
|
+
case "claude":
|
|
120
|
+
return `/zenorm ${specId}`;
|
|
121
|
+
case "codex":
|
|
122
|
+
return `$zenorm ${specId}`;
|
|
123
|
+
default: {
|
|
124
|
+
const never = agent;
|
|
125
|
+
throw new CliError(`No ZeNorm skill invocation defined for agent "${String(never)}".`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
115
129
|
/**
|
|
116
130
|
* The headless subprocess invocation for a given agent + task. Pure (no
|
|
117
131
|
* side effects) so it can be unit-tested directly without spawning anything.
|
|
@@ -125,7 +139,7 @@ function handoffPromptBody(task, zenormCli) {
|
|
|
125
139
|
* Exported for unit testing.
|
|
126
140
|
*/
|
|
127
141
|
export function buildAgentCommand(agent, task, model) {
|
|
128
|
-
const prompt = buildHandoffPrompt(task);
|
|
142
|
+
const prompt = buildHandoffPrompt(task, agent);
|
|
129
143
|
switch (agent) {
|
|
130
144
|
case "claude":
|
|
131
145
|
// stream-json requires --verbose; it does NOT make the transcript verbose
|
|
@@ -208,7 +222,7 @@ export function buildAgentCommand(agent, task, model) {
|
|
|
208
222
|
* Exported for unit testing.
|
|
209
223
|
*/
|
|
210
224
|
export function buildInteractiveAgentCommand(agent, task, model) {
|
|
211
|
-
const prompt = buildInteractiveHandoffPrompt(task);
|
|
225
|
+
const prompt = buildInteractiveHandoffPrompt(task, agent);
|
|
212
226
|
switch (agent) {
|
|
213
227
|
case "claude":
|
|
214
228
|
return {
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
name: zenorm
|
|
3
3
|
description: >-
|
|
4
4
|
Dispatcher for explicit ZeNorm spec-driven work. Use when the user invokes
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
the harness-native ZeNorm skill command (`/zenorm ...` in Claude Code,
|
|
6
|
+
`$zenorm ...` in Codex, or `@zenorm ...` in Cursor), or explicitly asks to
|
|
7
|
+
execute, implement, run, continue, or sync a ZeNorm spec or task — e.g.
|
|
8
|
+
"implement spec AUTH-123", "run this ZeNorm spec", "continue spec Z-9",
|
|
9
|
+
"do ZeNorm task UUID", "sync zenorm",
|
|
8
10
|
"wrap up the ZeNorm session". It routes to the right focused skill:
|
|
9
11
|
full-spec execution, single-task execution, or session sync-back, and owns
|
|
10
12
|
the session id and the final outcome flush. Do NOT trigger merely because a
|
|
@@ -20,7 +22,8 @@ child skills rely on: the **session id** and the **single final sync**.
|
|
|
20
22
|
|
|
21
23
|
## Routing
|
|
22
24
|
|
|
23
|
-
`$ARGUMENTS` is everything after
|
|
25
|
+
`$ARGUMENTS` is everything after the harness-native skill invocation
|
|
26
|
+
(`/zenorm`, `$zenorm`, or `@zenorm`). Run the resolver — it strips
|
|
24
27
|
verbs, classifies the target, and resolves spec keys of ANY shape (code,
|
|
25
28
|
slug, or UUID) against the CLI so you do not guess:
|
|
26
29
|
|
|
@@ -42,7 +45,7 @@ for looking unfamiliar. The resolver already checked it against the CLI.
|
|
|
42
45
|
|
|
43
46
|
The `--dispatched` flag tells `execute-task` that *you* (the dispatcher) own
|
|
44
47
|
the final `zenorm-sync`, so it will not run its own. This keeps sync
|
|
45
|
-
single-owner: exactly one sync per
|
|
48
|
+
single-owner: exactly one sync per ZeNorm skill invocation, no double posts. (If
|
|
46
49
|
a user runs `execute-task` directly without going through you, it has no
|
|
47
50
|
`--dispatched` flag and syncs itself — that path stays correct too.)
|
|
48
51
|
|