@nifrajs/coding-agent 3.3.0 → 4.0.0

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 (88) hide show
  1. package/README.md +11 -4
  2. package/SECURITY.md +2 -1
  3. package/dist/approvals.d.ts +14 -2
  4. package/dist/approvals.d.ts.map +1 -1
  5. package/dist/approvals.js +51 -43
  6. package/dist/approvals.js.map +1 -1
  7. package/dist/cli.d.ts +1 -0
  8. package/dist/cli.d.ts.map +1 -1
  9. package/dist/cli.js +11 -2
  10. package/dist/cli.js.map +1 -1
  11. package/dist/context.js +29 -1
  12. package/dist/context.js.map +1 -1
  13. package/dist/diff.js +38 -2
  14. package/dist/diff.js.map +1 -1
  15. package/dist/handoffs.d.ts.map +1 -1
  16. package/dist/handoffs.js +12 -4
  17. package/dist/handoffs.js.map +1 -1
  18. package/dist/host.d.ts.map +1 -1
  19. package/dist/host.js +146 -23
  20. package/dist/host.js.map +1 -1
  21. package/dist/index.d.ts +2 -2
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +1 -1
  24. package/dist/index.js.map +1 -1
  25. package/dist/isolated.js +37 -2
  26. package/dist/isolated.js.map +1 -1
  27. package/dist/native.d.ts +12 -0
  28. package/dist/native.d.ts.map +1 -1
  29. package/dist/native.js +165 -40
  30. package/dist/native.js.map +1 -1
  31. package/dist/orchestration/compile.d.ts +7 -0
  32. package/dist/orchestration/compile.d.ts.map +1 -1
  33. package/dist/orchestration/compile.js +16 -2
  34. package/dist/orchestration/compile.js.map +1 -1
  35. package/dist/orchestration/evidence-store.d.ts.map +1 -1
  36. package/dist/orchestration/evidence-store.js +9 -4
  37. package/dist/orchestration/evidence-store.js.map +1 -1
  38. package/dist/orchestration/host.d.ts +10 -0
  39. package/dist/orchestration/host.d.ts.map +1 -1
  40. package/dist/orchestration/host.js +9 -0
  41. package/dist/orchestration/host.js.map +1 -1
  42. package/dist/replay.d.ts +4 -0
  43. package/dist/replay.d.ts.map +1 -1
  44. package/dist/replay.js +189 -24
  45. package/dist/replay.js.map +1 -1
  46. package/dist/rpc.d.ts +10 -0
  47. package/dist/rpc.d.ts.map +1 -1
  48. package/dist/rpc.js +209 -29
  49. package/dist/rpc.js.map +1 -1
  50. package/dist/session-migration.d.ts.map +1 -1
  51. package/dist/session-migration.js +3 -2
  52. package/dist/session-migration.js.map +1 -1
  53. package/dist/sessions.d.ts +20 -2
  54. package/dist/sessions.d.ts.map +1 -1
  55. package/dist/sessions.js +269 -60
  56. package/dist/sessions.js.map +1 -1
  57. package/dist/subagents.d.ts +30 -0
  58. package/dist/subagents.d.ts.map +1 -1
  59. package/dist/subagents.js +118 -15
  60. package/dist/subagents.js.map +1 -1
  61. package/dist/verification.d.ts +28 -1
  62. package/dist/verification.d.ts.map +1 -1
  63. package/dist/verification.js +119 -3
  64. package/dist/verification.js.map +1 -1
  65. package/dist/workflows.d.ts +1 -0
  66. package/dist/workflows.d.ts.map +1 -1
  67. package/dist/workflows.js +55 -23
  68. package/dist/workflows.js.map +1 -1
  69. package/package.json +9 -5
  70. package/src/approvals.ts +62 -45
  71. package/src/cli.ts +11 -2
  72. package/src/context.ts +32 -1
  73. package/src/diff.ts +40 -2
  74. package/src/handoffs.ts +20 -8
  75. package/src/host.ts +146 -23
  76. package/src/index.ts +7 -0
  77. package/src/isolated.ts +39 -2
  78. package/src/native.ts +213 -39
  79. package/src/orchestration/compile.ts +28 -2
  80. package/src/orchestration/evidence-store.ts +9 -3
  81. package/src/orchestration/host.ts +17 -0
  82. package/src/replay.ts +206 -25
  83. package/src/rpc.ts +262 -33
  84. package/src/session-migration.ts +3 -2
  85. package/src/sessions.ts +288 -57
  86. package/src/subagents.ts +147 -17
  87. package/src/verification.ts +146 -3
  88. package/src/workflows.ts +47 -27
package/dist/workflows.js CHANGED
@@ -2,6 +2,7 @@ import { publicErrorDetails } from "./errors.js";
2
2
  /** Bounded orchestration primitives. The kernel knows no provider, UI, or framework package. */
3
3
  export class WorkflowRunner {
4
4
  options;
5
+ signal;
5
6
  values = new Map();
6
7
  completed = [];
7
8
  steps = 0;
@@ -11,6 +12,7 @@ export class WorkflowRunner {
11
12
  maxSteps: options.maxSteps ?? 128,
12
13
  maxDepth: options.maxDepth ?? 8,
13
14
  };
15
+ this.signal = options.signal ?? new AbortController().signal;
14
16
  if (!Number.isSafeInteger(this.options.maxSteps) || this.options.maxSteps < 1)
15
17
  throw new RangeError("workflow: maxSteps must be positive");
16
18
  if (!Number.isSafeInteger(this.options.maxDepth) || this.options.maxDepth < 1)
@@ -36,12 +38,12 @@ export class WorkflowRunner {
36
38
  };
37
39
  }
38
40
  }
39
- context() {
41
+ context(depth) {
40
42
  return {
41
- signal: this.options.signal ?? new AbortController().signal,
43
+ signal: this.signal,
42
44
  values: this.values,
43
45
  set: (name, value) => this.values.set(name, value),
44
- run: (step) => this.execute(step, 1),
46
+ run: (step) => this.execute(step, depth + 1),
45
47
  };
46
48
  }
47
49
  async execute(step, depth) {
@@ -53,9 +55,9 @@ export class WorkflowRunner {
53
55
  throw new Error("workflow cancelled");
54
56
  switch (step.type) {
55
57
  case "task":
56
- return this.single(step.id, () => step.run(this.context()));
58
+ return this.single(step.id, () => step.run(this.context(depth)));
57
59
  case "verify": {
58
- const result = await this.single(step.id, () => step.run(this.context()));
60
+ const result = await this.single(step.id, () => step.run(this.context(depth)));
59
61
  const ok = typeof result === "boolean" ? result : isVerificationResult(result) && result.ok;
60
62
  if (!ok)
61
63
  throw new Error(`verification failed: ${step.id}`);
@@ -63,18 +65,18 @@ export class WorkflowRunner {
63
65
  }
64
66
  case "approve": {
65
67
  await this.emit({ type: "approval.required", id: step.id, reason: step.reason });
66
- const approved = await this.single(step.id, () => step.run(this.context()));
68
+ const approved = await this.single(step.id, () => step.run(this.context(depth)));
67
69
  if (approved !== true)
68
70
  throw new Error(`approval denied: ${step.id}`);
69
71
  return approved;
70
72
  }
71
73
  case "checkpoint": {
72
- const result = await this.single(step.id, () => step.run(this.context()));
74
+ const result = await this.single(step.id, () => step.run(this.context(depth)));
73
75
  await this.emit({ type: "checkpoint.created", id: step.id });
74
76
  return result;
75
77
  }
76
78
  case "handoff":
77
- return this.single(step.id, () => step.run(this.context()));
79
+ return this.single(step.id, () => step.run(this.context(depth)));
78
80
  case "sequence": {
79
81
  const results = [];
80
82
  for (const child of step.steps)
@@ -82,11 +84,16 @@ export class WorkflowRunner {
82
84
  return results;
83
85
  }
84
86
  case "parallel":
87
+ if (step.steps.length === 0)
88
+ return [];
85
89
  return this.parallel(step.steps, step.maxConcurrency ?? step.steps.length, depth);
86
90
  case "retry": {
87
91
  const attempts = step.attempts ?? 3;
88
92
  if (!Number.isSafeInteger(attempts) || attempts < 1 || attempts > 16)
89
93
  throw new RangeError("workflow: attempts must be between 1 and 16");
94
+ const backoffMs = step.backoffMs ?? 0;
95
+ if (!Number.isSafeInteger(backoffMs) || backoffMs < 0)
96
+ throw new RangeError("workflow: backoffMs must be a non-negative safe integer");
90
97
  let last;
91
98
  for (let attempt = 0; attempt < attempts; attempt++) {
92
99
  try {
@@ -94,14 +101,14 @@ export class WorkflowRunner {
94
101
  }
95
102
  catch (error) {
96
103
  last = error;
97
- if (attempt + 1 < attempts && (step.backoffMs ?? 0) > 0)
98
- await delay(Math.min(step.backoffMs * (attempt + 1), 10_000), this.options.signal);
104
+ if (attempt + 1 < attempts && backoffMs > 0)
105
+ await delay(Math.min(backoffMs * (attempt + 1), 10_000), this.options.signal);
99
106
  }
100
107
  }
101
108
  throw last instanceof Error ? last : new Error(String(last));
102
109
  }
103
110
  case "branch": {
104
- const selected = await this.single(step.id, () => step.when(this.context()));
111
+ const selected = await this.single(step.id, () => step.when(this.context(depth)));
105
112
  return selected === true
106
113
  ? this.execute(step.then, depth + 1)
107
114
  : step.otherwise === undefined
@@ -134,15 +141,25 @@ export class WorkflowRunner {
134
141
  throw new RangeError("workflow: maxConcurrency must be positive");
135
142
  const outputs = new Array(steps.length);
136
143
  let next = 0;
144
+ // The first failure starts no further step, and the group settles only once the steps already
145
+ // running have, so nothing runs on after the workflow reports its failure.
146
+ let failure;
137
147
  const worker = async () => {
138
- for (;;) {
148
+ while (failure === undefined) {
139
149
  const index = next++;
140
150
  if (index >= steps.length)
141
151
  return;
142
- outputs[index] = await this.execute(steps[index], depth + 1);
152
+ try {
153
+ outputs[index] = await this.execute(steps[index], depth + 1);
154
+ }
155
+ catch (error) {
156
+ failure ??= { error };
157
+ }
143
158
  }
144
159
  };
145
160
  await Promise.all(Array.from({ length: Math.min(maxConcurrency, steps.length) }, () => worker()));
161
+ if (failure !== undefined)
162
+ throw failure.error;
146
163
  return outputs;
147
164
  }
148
165
  async emit(event) {
@@ -151,18 +168,33 @@ export class WorkflowRunner {
151
168
  }
152
169
  async function delay(ms, signal) {
153
170
  await new Promise((resolve, reject) => {
154
- const timer = setTimeout(resolve, ms);
171
+ let settled = false;
172
+ let timer;
173
+ let onAbort;
174
+ const cleanup = () => {
175
+ if (timer !== undefined)
176
+ clearTimeout(timer);
177
+ if (signal !== undefined && onAbort !== undefined)
178
+ signal.removeEventListener("abort", onAbort);
179
+ };
180
+ const settle = (error) => {
181
+ if (settled)
182
+ return;
183
+ settled = true;
184
+ cleanup();
185
+ if (error === undefined)
186
+ resolve();
187
+ else
188
+ reject(error);
189
+ };
190
+ timer = setTimeout(() => settle(), ms);
155
191
  if (signal === undefined)
156
192
  return;
157
- if (signal.aborted) {
158
- clearTimeout(timer);
159
- reject(new Error("workflow cancelled"));
160
- return;
161
- }
162
- signal.addEventListener("abort", () => {
163
- clearTimeout(timer);
164
- reject(new Error("workflow cancelled"));
165
- }, { once: true });
193
+ onAbort = () => settle(new Error("workflow cancelled"));
194
+ signal.addEventListener("abort", onAbort, { once: true });
195
+ // Abort can race listener registration; check again after subscribing.
196
+ if (signal.aborted)
197
+ onAbort();
166
198
  });
167
199
  }
168
200
  function isVerificationResult(value) {
@@ -1 +1 @@
1
- {"version":3,"file":"workflows.js","sourceRoot":"","sources":["../src/workflows.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workflows.js","sourceRoot":"","sources":["../src/workflows.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nifrajs/coding-agent",
3
- "version": "3.3.0",
3
+ "version": "4.0.0",
4
4
  "description": "Standalone, extensible Nifra coding-agent host and CLI.",
5
5
  "keywords": [
6
6
  "bun",
@@ -12,6 +12,9 @@
12
12
  "workflows"
13
13
  ],
14
14
  "type": "module",
15
+ "nifra": {
16
+ "environment": "backend"
17
+ },
15
18
  "main": "./dist/index.js",
16
19
  "module": "./dist/index.js",
17
20
  "types": "./dist/index.d.ts",
@@ -67,10 +70,11 @@
67
70
  "access": "public"
68
71
  },
69
72
  "dependencies": {
70
- "@nifrajs/agent": "3.3.0",
71
- "@nifrajs/agent-protocol": "3.3.0",
72
- "@nifrajs/jobs": "3.3.0",
73
- "@nifrajs/pi": "3.3.0"
73
+ "@nifrajs/agent": "4.0.0",
74
+ "@nifrajs/agent-review": "4.0.0",
75
+ "@nifrajs/agent-protocol": "4.0.0",
76
+ "@nifrajs/jobs": "4.0.0",
77
+ "@nifrajs/pi": "4.0.0"
74
78
  },
75
79
  "repository": {
76
80
  "type": "git",
package/src/approvals.ts CHANGED
@@ -52,10 +52,16 @@ export interface ApprovalManagerOptions {
52
52
 
53
53
  interface PendingApproval {
54
54
  readonly request: ApprovalRequest
55
- readonly resolve: (approved: boolean) => void
55
+ /** Settles with the decision; it exists before `onRequired` runs, so no decision can miss it. */
56
+ readonly decided: Promise<boolean>
57
+ readonly settle: (approved: boolean) => void
56
58
  readonly timer: ReturnType<typeof setTimeout>
57
59
  }
58
60
 
61
+ /** The agent protocol's token alphabet, so every protocol-valid id is accepted here too. */
62
+ const ID_TOKEN = /^[A-Za-z0-9._:/-]{1,128}$/
63
+ const MAX_ACTION_LENGTH = 512
64
+
59
65
  /**
60
66
  * Small approval broker shared by RPC, Workbench, and workflow extensions.
61
67
  *
@@ -89,38 +95,37 @@ export class ApprovalManager {
89
95
 
90
96
  /** Convert a streamed backend approval event into a resolvable pending request. */
91
97
  async observe(event: AgentApprovalRequiredEvent): Promise<ApprovalRequest | undefined> {
92
- if (this.pendingApprovals.has(event.approvalId))
93
- return this.pendingApprovals.get(event.approvalId)?.request
94
- return this.create({
98
+ const existing = this.pendingApprovals.get(event.approvalId)
99
+ if (existing !== undefined) return existing.request
100
+ const pending = await this.create({
95
101
  id: event.approvalId,
96
102
  sessionId: event.sessionId,
97
103
  turnId: event.turnId,
98
- action: event.action,
104
+ // The protocol bounds text more loosely; a long label must not fail the backend's turn.
105
+ action: event.action.slice(0, MAX_ACTION_LENGTH),
99
106
  capability: event.capability,
100
107
  ...(event.reason === undefined ? {} : { reason: event.reason }),
101
108
  })
109
+ return pending?.request
102
110
  }
103
111
 
104
- /** Publish a pending approval without waiting for its decision (useful for transports). */
112
+ /**
113
+ * Publish a pending approval without waiting for its decision (useful for transports). Returns
114
+ * `undefined` when the broker is full or an approval with the same id is still pending.
115
+ */
105
116
  async offer(
106
117
  input: Omit<ApprovalRequest, "createdAt" | "expiresAt">,
107
118
  ): Promise<ApprovalRequest | undefined> {
108
- return this.create(input)
119
+ return (await this.create(input))?.request
109
120
  }
110
121
 
111
- /** Create a host-owned approval that can be awaited by a workflow or extension. */
122
+ /**
123
+ * Create a host-owned approval that can be awaited by a workflow or extension. Resolves `false`
124
+ * when the broker is full or an approval with the same id is still pending.
125
+ */
112
126
  async request(input: Omit<ApprovalRequest, "createdAt" | "expiresAt">): Promise<boolean> {
113
- const request = await this.offer(input)
114
- if (request === undefined) return false
115
- const pending = this.pendingApprovals.get(request.id)
116
- if (pending === undefined) return false
117
- return new Promise<boolean>((resolve) => {
118
- // Replace the resolver only for this host-owned request; observed backend requests are
119
- // intentionally notification-only and are resolved through `resolve`.
120
- const current = this.pendingApprovals.get(request.id)
121
- if (current === undefined) return resolve(false)
122
- this.pendingApprovals.set(request.id, { ...current, resolve })
123
- })
127
+ const pending = await this.create(input)
128
+ return pending === undefined ? false : pending.decided
124
129
  }
125
130
 
126
131
  /**
@@ -145,49 +150,68 @@ export class ApprovalManager {
145
150
  code: bound.vector !== coordinate.vector ? "stale_vector" : "identity_mismatch",
146
151
  }
147
152
  if (!coordinateIsFresh(bound, now)) {
148
- this.resolve(coordinate.requestId, false, "approval expired")
153
+ this.settle(coordinate.requestId, false, "approval expired")
149
154
  return { ok: false, code: "expired" }
150
155
  }
151
156
  if (nextApprovalState("pending", approved ? "approve" : "deny") === undefined)
152
157
  return { ok: false, code: "illegal_transition" }
153
- const decision = this.resolve(coordinate.requestId, approved)
158
+ const decision = this.settle(coordinate.requestId, approved)
154
159
  if (decision === undefined) return { ok: false, code: "unknown_boundary" }
155
160
  return { ok: true, decision }
156
161
  }
157
162
 
163
+ /**
164
+ * Settle a pending approval by id. An approval opened with a coordinate is approved only through
165
+ * {@link resolveMatched}; this untyped path can still deny it, and returns `undefined` for an
166
+ * approve.
167
+ */
158
168
  resolve(approvalId: string, approved: boolean, reason?: string): ApprovalDecision | undefined {
169
+ if (
170
+ approved === true &&
171
+ this.pendingApprovals.get(approvalId)?.request.coordinate !== undefined
172
+ )
173
+ return undefined
174
+ return this.settle(approvalId, approved, reason)
175
+ }
176
+
177
+ close(): void {
178
+ for (const approvalId of this.pendingApprovals.keys())
179
+ this.settle(approvalId, false, "approval manager closed")
180
+ }
181
+
182
+ private settle(
183
+ approvalId: string,
184
+ approved: boolean,
185
+ reason?: string,
186
+ ): ApprovalDecision | undefined {
159
187
  const pending = this.pendingApprovals.get(approvalId)
160
188
  if (pending === undefined) return undefined
161
189
  clearTimeout(pending.timer)
162
190
  this.pendingApprovals.delete(approvalId)
163
- pending.resolve(approved === true)
191
+ pending.settle(approved === true)
164
192
  const decision: ApprovalDecision = {
165
193
  approvalId,
166
194
  approved: approved === true,
167
195
  ...(reason === undefined ? {} : { reason: reason.slice(0, 512) }),
168
196
  at: Date.now(),
169
197
  }
170
- void this.options.onResolved?.(decision)
198
+ // A failing broadcast must not become an unhandled rejection in the host.
199
+ Promise.resolve(this.options.onResolved?.(decision)).catch(() => {})
171
200
  return decision
172
201
  }
173
202
 
174
- close(): void {
175
- for (const approvalId of this.pendingApprovals.keys())
176
- this.resolve(approvalId, false, "approval manager closed")
177
- }
178
-
179
203
  private async create(
180
204
  input: Omit<ApprovalRequest, "createdAt" | "expiresAt">,
181
- ): Promise<ApprovalRequest | undefined> {
205
+ ): Promise<PendingApproval | undefined> {
182
206
  if (this.pendingApprovals.size >= this.options.maxPending) return undefined
183
- if (!/^[A-Za-z0-9._:-]{1,128}$/.test(input.id))
184
- throw new TypeError("approvals: approval id is invalid")
185
- if (!/^[A-Za-z0-9._:-]{1,128}$/.test(input.sessionId))
186
- throw new TypeError("approvals: session id is invalid")
187
- if (!input.action || input.action.length > 512)
207
+ if (!ID_TOKEN.test(input.id)) throw new TypeError("approvals: approval id is invalid")
208
+ if (!ID_TOKEN.test(input.sessionId)) throw new TypeError("approvals: session id is invalid")
209
+ if (!input.action || input.action.length > MAX_ACTION_LENGTH)
188
210
  throw new TypeError("approvals: action is empty or too long")
189
211
  if (!input.capability || input.capability.length > 128)
190
212
  throw new TypeError("approvals: capability is empty or too long")
213
+ // Replacing a pending id would orphan the waiter of the request already holding it.
214
+ if (this.pendingApprovals.has(input.id)) return undefined
191
215
  const createdAt = Date.now()
192
216
  const request: ApprovalRequest = Object.freeze({
193
217
  ...input,
@@ -197,22 +221,15 @@ export class ApprovalManager {
197
221
  createdAt,
198
222
  expiresAt: createdAt + this.options.timeoutMs,
199
223
  })
200
- let resolveApproval = (_approved: boolean): void => {}
224
+ const { promise: decided, resolve: settle } = Promise.withResolvers<boolean>()
201
225
  const timer = setTimeout(() => {
202
- this.resolve(request.id, false, "approval timed out")
226
+ this.settle(request.id, false, "approval timed out")
203
227
  }, this.options.timeoutMs)
204
228
  ;(timer as unknown as { unref?: () => void }).unref?.()
205
- const pending: PendingApproval = {
206
- request,
207
- resolve: (approved) => resolveApproval(approved),
208
- timer,
209
- }
229
+ const pending: PendingApproval = { request, decided, settle, timer }
210
230
  this.pendingApprovals.set(request.id, pending)
211
231
  await this.options.onRequired?.(request)
212
- // A backend-observed request is resolved through `resolve`; a host request swaps this closure
213
- // from the promise below before returning to the workflow.
214
- resolveApproval = (_approved: boolean): void => {}
215
- return request
232
+ return pending
216
233
  }
217
234
  }
218
235
 
package/src/cli.ts CHANGED
@@ -25,10 +25,13 @@ Usage:
25
25
  nifra-agent [--backend pi|replay] [--cwd <dir>] [--once <prompt>]
26
26
  [--json] [--no-session] [--session-dir <dir>] [--session-id <id>]
27
27
  [--verify-after-turn check,assure] [--max-repair-attempts <n>]
28
- [--pi <command>] [--replay <file>]
28
+ [--pi <command>] [--replay <file>] [--extensions]
29
29
  nifra-agent --migrate-session <id> --migrate-from <dir> --migrate-to <dir> [--json]
30
30
  nifra-agent --rpc [--cwd <dir>] [--host 127.0.0.1] [--port 0] [--expose-error-stacks]
31
31
 
32
+ --extensions loads and runs .nifra/extensions/** from --cwd. That is the project's own code: pass it
33
+ only for a repository you trust. Without it no extension is loaded.
34
+
32
35
  Commands in interactive mode:
33
36
  /reload reload Pi or Nifra extensions
34
37
  /compact compact the bounded prompt window
@@ -64,6 +67,7 @@ export interface CliOptions {
64
67
  readonly migrationTarget?: string
65
68
  readonly verifyAfterTurn: readonly ("check" | "assure" | "test")[]
66
69
  readonly maxRepairAttempts: number
70
+ readonly extensions: boolean
67
71
  }
68
72
 
69
73
  export function parseArgs(args: readonly string[]): CliOptions {
@@ -72,6 +76,7 @@ export function parseArgs(args: readonly string[]): CliOptions {
72
76
  let once: string | undefined
73
77
  let json = false
74
78
  let noSession = false
79
+ let extensions = false
75
80
  let piCommand = "pi"
76
81
  let replayFile: string | undefined
77
82
  let sessionDir: string | undefined
@@ -93,6 +98,7 @@ export function parseArgs(args: readonly string[]): CliOptions {
93
98
  else if (arg === "--once" || arg === "--message") once = args[++index]
94
99
  else if (arg === "--json") json = true
95
100
  else if (arg === "--no-session") noSession = true
101
+ else if (arg === "--extensions") extensions = true
96
102
  else if (arg === "--session-dir") sessionDir = resolve(args[++index] ?? "")
97
103
  else if (arg === "--session-id") sessionId = args[++index]
98
104
  else if (arg === "--migrate-session") migrateSession = args[++index]
@@ -142,6 +148,7 @@ export function parseArgs(args: readonly string[]): CliOptions {
142
148
  ...(once === undefined ? {} : { once }),
143
149
  json,
144
150
  noSession,
151
+ extensions,
145
152
  piCommand,
146
153
  ...(replayFile === undefined ? {} : { replayFile }),
147
154
  ...(sessionDir === undefined ? {} : { sessionDir }),
@@ -215,7 +222,9 @@ async function main(): Promise<void> {
215
222
  enableNifraTools: true,
216
223
  ...(options.sessionDir === undefined ? {} : { sessionDir: options.sessionDir }),
217
224
  })
218
- const extensionRoots = await discoverExtensions(options.cwd)
225
+ // A module's top-level code runs as soon as it is imported, before any capability check can refuse
226
+ // it, so a cloned repository's extensions load only when the user asks.
227
+ const extensionRoots = options.extensions ? await discoverExtensions(options.cwd) : []
219
228
  const extensions = new ExtensionHost({
220
229
  cwd: options.cwd,
221
230
  roots: extensionRoots,
package/src/context.ts CHANGED
@@ -72,10 +72,41 @@ function safeEnv(
72
72
  "LC_ALL",
73
73
  "TERM",
74
74
  "CI",
75
+ ...(process.platform === "win32"
76
+ ? [
77
+ "SystemRoot",
78
+ "WINDIR",
79
+ "TEMP",
80
+ "TMP",
81
+ "USERPROFILE",
82
+ "LOCALAPPDATA",
83
+ "APPDATA",
84
+ "COMSPEC",
85
+ "PATHEXT",
86
+ "BUN_INSTALL",
87
+ "HOMEDRIVE",
88
+ "HOMEPATH",
89
+ "USERNAME",
90
+ "USERDOMAIN",
91
+ "ProgramData",
92
+ "ProgramFiles",
93
+ "ProgramFiles(x86)",
94
+ ]
95
+ : []),
75
96
  ...Object.keys(overrides ?? {}),
76
97
  ])) {
77
- const value = overrides?.[name] ?? process.env[name]
98
+ const value =
99
+ overrides !== undefined && Object.hasOwn(overrides, name) ? overrides[name] : readEnv(name)
78
100
  if (value !== undefined) result[name] = value
79
101
  }
80
102
  return result
81
103
  }
104
+
105
+ function readEnv(name: string): string | undefined {
106
+ const exact = process.env[name]
107
+ if (exact !== undefined || process.platform !== "win32") return exact
108
+ const key = Object.keys(process.env).find(
109
+ (candidate) => candidate.toLowerCase() === name.toLowerCase(),
110
+ )
111
+ return key === undefined ? undefined : process.env[key]
112
+ }
package/src/diff.ts CHANGED
@@ -72,9 +72,47 @@ export async function readProjectDiff(options: ProjectDiffOptions): Promise<Proj
72
72
 
73
73
  function safeEnv(): Record<string, string> {
74
74
  const result: Record<string, string> = {}
75
- for (const name of ["PATH", "HOME", "LANG", "LC_ALL", "TERM", "GIT_PAGER"]) {
76
- const value = name === "GIT_PAGER" ? "cat" : process.env[name]
75
+ const names = [
76
+ "PATH",
77
+ "HOME",
78
+ "LANG",
79
+ "LC_ALL",
80
+ "TERM",
81
+ "GIT_PAGER",
82
+ ...(process.platform === "win32"
83
+ ? [
84
+ "SystemRoot",
85
+ "WINDIR",
86
+ "TEMP",
87
+ "TMP",
88
+ "USERPROFILE",
89
+ "LOCALAPPDATA",
90
+ "APPDATA",
91
+ "COMSPEC",
92
+ "PATHEXT",
93
+ "BUN_INSTALL",
94
+ "HOMEDRIVE",
95
+ "HOMEPATH",
96
+ "USERNAME",
97
+ "USERDOMAIN",
98
+ "ProgramData",
99
+ "ProgramFiles",
100
+ "ProgramFiles(x86)",
101
+ ]
102
+ : []),
103
+ ]
104
+ for (const name of names) {
105
+ const value = name === "GIT_PAGER" ? "cat" : readEnv(name)
77
106
  if (value !== undefined) result[name] = value
78
107
  }
79
108
  return result
80
109
  }
110
+
111
+ function readEnv(name: string): string | undefined {
112
+ const exact = process.env[name]
113
+ if (exact !== undefined || process.platform !== "win32") return exact
114
+ const key = Object.keys(process.env).find(
115
+ (candidate) => candidate.toLowerCase() === name.toLowerCase(),
116
+ )
117
+ return key === undefined ? undefined : process.env[key]
118
+ }
package/src/handoffs.ts CHANGED
@@ -27,6 +27,8 @@ import type { ApprovalManager } from "./approvals.ts"
27
27
  import { ChildVectorTracker } from "./orchestration/policy.ts"
28
28
 
29
29
  const ID_TOKEN = /^[A-Za-z0-9._:-]{1,128}$/
30
+ /** The agent protocol's token alphabet, which the approval broker accepts for session ids. */
31
+ const SESSION_TOKEN = /^[A-Za-z0-9._:/-]{1,128}$/
30
32
 
31
33
  /** Stable, content-free reasons the coordinator refuses a handoff request or decision. */
32
34
  export type HandoffRejection =
@@ -136,7 +138,8 @@ export class HandoffCoordinator {
136
138
  !input.capability ||
137
139
  input.capability.length > 128 ||
138
140
  !input.from ||
139
- input.from.length > 128
141
+ input.from.length > 128 ||
142
+ (input.sessionId !== undefined && !SESSION_TOKEN.test(input.sessionId))
140
143
  )
141
144
  throw new HandoffError("invalid_handoff")
142
145
  if (this.records.has(input.requestId)) throw new HandoffError("duplicate")
@@ -162,13 +165,18 @@ export class HandoffCoordinator {
162
165
  }
163
166
  this.records.set(input.requestId, record)
164
167
 
168
+ // The mirror carries the boundary's coordinate, so only a matched decision approves it. It is a
169
+ // notification: a broker that is full or fails to broadcast leaves the handoff itself intact.
165
170
  if (record.requireApproval && this.approvals !== undefined)
166
- void this.approvals.offer({
167
- id: input.requestId,
168
- sessionId: input.sessionId ?? input.runId,
169
- action: "handoff",
170
- capability: input.capability,
171
- })
171
+ this.approvals
172
+ .offer({
173
+ id: input.requestId,
174
+ sessionId: input.sessionId ?? input.runId,
175
+ action: "handoff",
176
+ capability: input.capability,
177
+ coordinate,
178
+ })
179
+ .catch(() => {})
172
180
  return this.view(record)
173
181
  }
174
182
 
@@ -264,7 +272,11 @@ export class HandoffCoordinator {
264
272
 
265
273
  private settleApproval(record: HandoffRecord, op: string): void {
266
274
  if (!record.requireApproval || this.approvals === undefined) return
267
- this.approvals.resolve(record.coordinate.requestId, op === "accept" || op === "resolve")
275
+ this.approvals.resolveMatched(
276
+ record.coordinate,
277
+ op === "accept" || op === "resolve",
278
+ this.now(),
279
+ )
268
280
  }
269
281
 
270
282
  private isTerminal(state: HandoffLifecycleState): boolean {