@akagilnc/pi-workflow-roles 0.1.2471 → 0.1.2477

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.
@@ -1,5 +1,5 @@
1
1
  import { Type } from "typebox";
2
- import { ENGINE_DETOUR_ALREADY_USED_DIAGNOSTIC, ENGINE_DETOUR_TOOL_NAME, engineDetourFailureDiagnostic, engineNameFromEnv, isEngineDetourFailure, runEngineDetourOnce, } from "./engine-detour.js";
2
+ import { ENGINE_DETOUR_TOOL_NAME, engineDetourFailureDiagnostic, engineNameFromEnv, isEngineDetourFailure, runEngineDetourOnce, } from "./engine-detour.js";
3
3
  const engineDetourArgsSchema = Type.Object({
4
4
  argv: Type.Array(Type.String({ minLength: 1 }), {
5
5
  minItems: 1,
@@ -18,26 +18,20 @@ function isCallerCancellation(error, signal) {
18
18
  return false;
19
19
  }
20
20
  /**
21
- * Build one once-latch detour tool definition for a configured engine name.
22
- * `latch` is shared so parent registration can reset between activations.
21
+ * Build one detour tool definition for a configured engine name.
23
22
  * `fail` owns host abort (parent) vs throw (evidence child) for tool misuse only.
24
23
  * Engine process failures (nonzero/empty/spawn) stop via `fail` with their cause.
25
24
  * Caller AbortSignal cancellation propagates unchanged.
26
25
  */
27
26
  export function createEngineDetourToolDefinition(input) {
28
- const latch = input.latch ?? { used: false };
29
27
  const engineName = input.engineName;
30
28
  return {
31
29
  name: ENGINE_DETOUR_TOOL_NAME,
32
30
  label: "劳务引擎",
33
- description: `运行一次劳务引擎子进程(engine=${engineName}),stdout 返回本 session;每次激活至多一次。`,
31
+ description: `运行一次劳务引擎子进程(engine=${engineName}),stdout 返回本 session。`,
34
32
  promptSnippet: "运行配置的劳务引擎一次并返回 stdout",
35
33
  parameters: engineDetourArgsSchema,
36
34
  async execute(toolCallId, params, signal, _onUpdate, ctx) {
37
- if (latch.used) {
38
- input.fail(new Error(ENGINE_DETOUR_ALREADY_USED_DIAGNOSTIC), toolCallId, ctx);
39
- }
40
- latch.used = true;
41
35
  const args = params;
42
36
  const argv = Array.isArray(args.argv) ? args.argv : [];
43
37
  if (argv.length === 0 || argv.some((part) => typeof part !== "string" || part.length === 0)) {
@@ -67,6 +61,7 @@ export function createEngineDetourToolDefinition(input) {
67
61
  details: {
68
62
  tool: ENGINE_DETOUR_TOOL_NAME,
69
63
  code: result.code,
64
+ stderr: result.stderr,
70
65
  },
71
66
  };
72
67
  },
@@ -75,31 +70,18 @@ export function createEngineDetourToolDefinition(input) {
75
70
  /**
76
71
  * Register the engine-generic detour tool once for this process when any role has
77
72
  * an engine activation signal. Returns whether registration occurred.
78
- * Once-latch is activation-scoped via the returned reset handle.
79
73
  */
80
74
  export function registerEngineDetourTool(pi, hostActions) {
81
75
  const engineName = engineNameFromEnv();
82
76
  if (engineName === undefined) {
83
- return {
84
- registered: false,
85
- resetLatch() {
86
- /* no-op when unregistered */
87
- },
88
- };
77
+ return false;
89
78
  }
90
- const latch = { used: false };
91
79
  const definition = createEngineDetourToolDefinition({
92
80
  engineName,
93
- latch,
94
81
  fail(error, toolCallId, ctx) {
95
82
  hostActions.failInfrastructure(error, ctx, toolCallId);
96
83
  },
97
84
  });
98
85
  pi.registerTool(definition);
99
- return {
100
- registered: true,
101
- resetLatch() {
102
- latch.used = false;
103
- },
104
- };
86
+ return true;
105
87
  }
@@ -22,7 +22,6 @@ export function applyEngineChildEnv(childEnv, engine) {
22
22
  }
23
23
  }
24
24
  export const ENGINE_DETOUR_EMPTY_STDOUT_DIAGNOSTIC = "劳务引擎 stdout 为空";
25
- export const ENGINE_DETOUR_ALREADY_USED_DIAGNOSTIC = "本激活内劳务引擎已使用";
26
25
  function abortReasonError(signal) {
27
26
  const reason = signal.reason;
28
27
  if (reason instanceof Error)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akagilnc/pi-workflow-roles",
3
- "version": "0.1.2471",
3
+ "version": "0.1.2477",
4
4
  "description": "Soul-bound workflow roles for Pi",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -0,0 +1,46 @@
1
+ # zcode engine method material
2
+
3
+ This file is packaged technical material for the optional `zcode` labor engine
4
+ (Z.AI ZCode agent runtime on the host, GLM Coding Plan models).
5
+
6
+ Before invoking the engine, read `../engine-dispatch.md`, resolving that path
7
+ relative to this note. This note only covers this engine's CLI technical
8
+ parameters.
9
+
10
+ ## Invocation (host-verified 2026-08-29)
11
+
12
+ The machine entrypoint is `zcode` (npm `zcode-app-cli`, wraps the official
13
+ ZCode runtime; host has 3.10.1-17 / runtime 0.16.5). Non-interactive labor:
14
+
15
+ ```bash
16
+ zcode --prompt 'YOUR_LABOR_PROMPT' --cwd /path/to/worktree
17
+ ```
18
+
19
+ `--prompt` defaults to permission mode `yolo` (no TTY permission stalls).
20
+ Useful extras measured from `zcode --help`: `--attach <path>` (repeatable),
21
+ `--mode build|edit|plan|yolo`, `--resume <sess_...>`, `--json` where
22
+ supported. Prefer `zcode --help` on the host over any remembered flag set.
23
+
24
+ ## Realm and model traps (host-verified 2026-08-29, all three hit in sequence)
25
+
26
+ - Missing `~/.zcode/cli/config.json` → hard error `Model config is missing`.
27
+ The desktop app's login is NOT shared with the CLI.
28
+ - `zcode login` signs into the **overseas Z.AI realm only**. An account on the
29
+ mainland BigModel realm then fails with
30
+ `[1113][Insufficient balance or no resource package]`.
31
+ - The scaffolded config defaults `model.main` to `zai/glm-5.2`, which is not
32
+ in the coding plan — same 1113 failure even with a valid plan.
33
+
34
+ Working mainland configuration (per official docs
35
+ `docs.bigmodel.cn/cn/coding-plan/quick-start`): in
36
+ `~/.zcode/cli/config.json`, provider kind `anthropic` with
37
+ `baseURL: https://open.bigmodel.cn/api/anthropic`, `options.apiKey` = the
38
+ coding-plan key (host keychain: service `glm-key`, account `akagilnc`), and
39
+ `model.main: zai/glm-5.3`, `model.lite: zai/glm-5.3-flash`. With that config
40
+ the smoke prompt returns normally.
41
+
42
+ ## Quota facts (owner-provided, 2026-08-28)
43
+
44
+ Plan quotas are daily and per-model (GLM-5.3 3M/day, Flash 5M/day on the
45
+ current plan; a weekend event granted a larger temporary pool). Whether cached
46
+ tokens count toward quota is unverified.
@@ -14,7 +14,6 @@ import type {
14
14
  import { Type, type Static } from "typebox";
15
15
 
16
16
  import {
17
- ENGINE_DETOUR_ALREADY_USED_DIAGNOSTIC,
18
17
  ENGINE_DETOUR_TOOL_NAME,
19
18
  engineDetourFailureDiagnostic,
20
19
  engineNameFromEnv,
@@ -42,13 +41,6 @@ export type EngineDetourHostActions = {
42
41
  ): never;
43
42
  };
44
43
 
45
- export type EngineDetourToolRegistration = {
46
- /** True when the tool definition was installed on this ExtensionAPI. */
47
- readonly registered: boolean;
48
- };
49
-
50
- type EngineDetourLatch = { used: boolean };
51
-
52
44
  /** Caller/upper-layer cancellation must propagate unchanged. */
53
45
  function isCallerCancellation(
54
46
  error: unknown,
@@ -66,24 +58,21 @@ function isCallerCancellation(
66
58
  }
67
59
 
68
60
  /**
69
- * Build one once-latch detour tool definition for a configured engine name.
70
- * `latch` is shared so parent registration can reset between activations.
61
+ * Build one detour tool definition for a configured engine name.
71
62
  * `fail` owns host abort (parent) vs throw (evidence child) for tool misuse only.
72
63
  * Engine process failures (nonzero/empty/spawn) stop via `fail` with their cause.
73
64
  * Caller AbortSignal cancellation propagates unchanged.
74
65
  */
75
66
  export function createEngineDetourToolDefinition(input: {
76
67
  engineName: string;
77
- latch?: EngineDetourLatch;
78
68
  fail: (error: Error, toolCallId: string, ctx: ExtensionContext) => never;
79
69
  }): ToolDefinition {
80
- const latch = input.latch ?? { used: false };
81
70
  const engineName = input.engineName;
82
71
  return {
83
72
  name: ENGINE_DETOUR_TOOL_NAME,
84
73
  label: "劳务引擎",
85
74
  description:
86
- `运行一次劳务引擎子进程(engine=${engineName}),stdout 返回本 session;每次激活至多一次。`,
75
+ `运行一次劳务引擎子进程(engine=${engineName}),stdout 返回本 session。`,
87
76
  promptSnippet: "运行配置的劳务引擎一次并返回 stdout",
88
77
  parameters: engineDetourArgsSchema,
89
78
  async execute(
@@ -93,15 +82,6 @@ export function createEngineDetourToolDefinition(input: {
93
82
  _onUpdate,
94
83
  ctx,
95
84
  ): Promise<AgentToolResult<unknown>> {
96
- if (latch.used) {
97
- input.fail(
98
- new Error(ENGINE_DETOUR_ALREADY_USED_DIAGNOSTIC),
99
- toolCallId,
100
- ctx,
101
- );
102
- }
103
- latch.used = true;
104
-
105
85
  const args = params as EngineDetourArgs;
106
86
  const argv = Array.isArray(args.argv) ? args.argv : [];
107
87
  if (argv.length === 0 || argv.some((part) => typeof part !== "string" || part.length === 0)) {
@@ -140,6 +120,7 @@ export function createEngineDetourToolDefinition(input: {
140
120
  details: {
141
121
  tool: ENGINE_DETOUR_TOOL_NAME,
142
122
  code: result.code,
123
+ stderr: result.stderr,
143
124
  },
144
125
  };
145
126
  },
@@ -149,36 +130,23 @@ export function createEngineDetourToolDefinition(input: {
149
130
  /**
150
131
  * Register the engine-generic detour tool once for this process when any role has
151
132
  * an engine activation signal. Returns whether registration occurred.
152
- * Once-latch is activation-scoped via the returned reset handle.
153
133
  */
154
134
  export function registerEngineDetourTool(
155
135
  pi: ExtensionAPI,
156
136
  hostActions: EngineDetourHostActions,
157
- ): EngineDetourToolRegistration & { resetLatch(): void } {
137
+ ): boolean {
158
138
  const engineName = engineNameFromEnv();
159
139
  if (engineName === undefined) {
160
- return {
161
- registered: false,
162
- resetLatch() {
163
- /* no-op when unregistered */
164
- },
165
- };
140
+ return false;
166
141
  }
167
142
 
168
- const latch: EngineDetourLatch = { used: false };
169
143
  const definition = createEngineDetourToolDefinition({
170
144
  engineName,
171
- latch,
172
145
  fail(error, toolCallId, ctx) {
173
146
  hostActions.failInfrastructure(error, ctx, toolCallId);
174
147
  },
175
148
  });
176
149
  pi.registerTool(definition);
177
150
 
178
- return {
179
- registered: true,
180
- resetLatch() {
181
- latch.used = false;
182
- },
183
- };
151
+ return true;
184
152
  }
@@ -30,9 +30,6 @@ export function applyEngineChildEnv(
30
30
  export const ENGINE_DETOUR_EMPTY_STDOUT_DIAGNOSTIC =
31
31
  "劳务引擎 stdout 为空" as const;
32
32
 
33
- export const ENGINE_DETOUR_ALREADY_USED_DIAGNOSTIC =
34
- "本激活内劳务引擎已使用" as const;
35
-
36
33
  export type EngineDetourResult = Readonly<{
37
34
  code: number;
38
35
  stdout: string;
@@ -629,7 +629,7 @@ export function createRoleRuntimeExtension(
629
629
  const pendingInfrastructureFailures = new Map<string, PendingInfrastructureFailure>();
630
630
  // Envelope-owned execute→tool_result bridge for Gatekeeper non-pass (ADR 0018).
631
631
  const pendingGatekeeperNonPassByToolCallId = new Map<string, GatekeeperNonPassResult>();
632
- let engineDetourRegistration: ReturnType<typeof registerEngineDetourTool> | undefined;
632
+ let engineDetourRegistered = false;
633
633
  // #288 primary-session thin adapter. The policy is the sole budget owner;
634
634
  // terminating-tool rejections and mechanical delivery requests share two turns.
635
635
  let receiptDelivery = createReceiptDeliveryPolicy();
@@ -1109,7 +1109,6 @@ export function createRoleRuntimeExtension(
1109
1109
  pendingNavigatorSettlement = undefined;
1110
1110
  pendingInfrastructureFailures.clear();
1111
1111
  pendingGatekeeperNonPassByToolCallId.clear();
1112
- engineDetourRegistration?.resetLatch();
1113
1112
  navigatorWorkContext = undefined;
1114
1113
  // #351: OAuth keepalive is orthogonal to --ak-role; start before role early-return
1115
1114
  // so role-less sessions (and reload after shutdown stop) still keep tokens alive.
@@ -1224,11 +1223,8 @@ export function createRoleRuntimeExtension(
1224
1223
  await executeActivationStage(entry.role, activationStage(entry.role, runtime), { clock, writeTrace });
1225
1224
  // #357 T2 / #378 / #380 / #391: any role+engine activation registers the package detour tool once.
1226
1225
  // Gate is env presence only — no per-engine execute branch; no role-module spawn.
1227
- if (engineDetourRegistration === undefined) {
1228
- engineDetourRegistration = registerEngineDetourTool(pi, hostActions);
1229
- if (!engineDetourRegistration.registered) {
1230
- engineDetourRegistration = undefined;
1231
- }
1226
+ if (!engineDetourRegistered) {
1227
+ engineDetourRegistered = registerEngineDetourTool(pi, hostActions);
1232
1228
  }
1233
1229
  // Worker gates ①②: arm records baseline and runs private one-shot hook uninstall (ADR 0070).
1234
1230
  // Parent session feeds #216 createRecordSession so baseline/bounce survive resume.