@caupulican/pi-adaptative 0.84.1 → 0.85.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 (145) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts.map +1 -1
  3. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js +14 -8
  4. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js.map +1 -1
  5. package/dist/bundled-resources/extensions/tmux-agent-manager/index.ts +14 -8
  6. package/dist/bundled-resources/skills/deduplicate-by-evidence/SKILL.md +7 -5
  7. package/dist/bundled-resources/skills/worker-profile-writer/SKILL.md +63 -0
  8. package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
  9. package/dist/core/autonomy/lane-tool-surface.js +4 -2
  10. package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
  11. package/dist/core/background-lane-controller.d.ts +3 -0
  12. package/dist/core/background-lane-controller.d.ts.map +1 -1
  13. package/dist/core/background-lane-controller.js +6 -0
  14. package/dist/core/background-lane-controller.js.map +1 -1
  15. package/dist/core/default-tool-surface.d.ts.map +1 -1
  16. package/dist/core/default-tool-surface.js +1 -0
  17. package/dist/core/default-tool-surface.js.map +1 -1
  18. package/dist/core/delegation/worker-delegation-controller.d.ts +7 -0
  19. package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
  20. package/dist/core/delegation/worker-delegation-controller.js +28 -0
  21. package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
  22. package/dist/core/delegation/worker-profile-resolver.d.ts +2 -0
  23. package/dist/core/delegation/worker-profile-resolver.d.ts.map +1 -1
  24. package/dist/core/delegation/worker-profile-resolver.js +46 -11
  25. package/dist/core/delegation/worker-profile-resolver.js.map +1 -1
  26. package/dist/core/doctor.d.ts +1 -1
  27. package/dist/core/doctor.d.ts.map +1 -1
  28. package/dist/core/doctor.js +5 -4
  29. package/dist/core/doctor.js.map +1 -1
  30. package/dist/core/model-capability.d.ts.map +1 -1
  31. package/dist/core/model-capability.js +1 -0
  32. package/dist/core/model-capability.js.map +1 -1
  33. package/dist/core/orchestration/lane-tool-manifests.d.ts +1 -1
  34. package/dist/core/orchestration/lane-tool-manifests.d.ts.map +1 -1
  35. package/dist/core/orchestration/lane-tool-manifests.js +6 -1
  36. package/dist/core/orchestration/lane-tool-manifests.js.map +1 -1
  37. package/dist/core/orchestration/session-task-profile-store.d.ts +31 -0
  38. package/dist/core/orchestration/session-task-profile-store.d.ts.map +1 -0
  39. package/dist/core/orchestration/session-task-profile-store.js +138 -0
  40. package/dist/core/orchestration/session-task-profile-store.js.map +1 -0
  41. package/dist/core/orchestration/task-profile-writer.d.ts +58 -0
  42. package/dist/core/orchestration/task-profile-writer.d.ts.map +1 -0
  43. package/dist/core/orchestration/task-profile-writer.js +165 -0
  44. package/dist/core/orchestration/task-profile-writer.js.map +1 -0
  45. package/dist/core/runtime-builder.d.ts +3 -1
  46. package/dist/core/runtime-builder.d.ts.map +1 -1
  47. package/dist/core/runtime-builder.js +14 -0
  48. package/dist/core/runtime-builder.js.map +1 -1
  49. package/dist/core/security/untrusted-boundary.d.ts.map +1 -1
  50. package/dist/core/security/untrusted-boundary.js +4 -6
  51. package/dist/core/security/untrusted-boundary.js.map +1 -1
  52. package/dist/core/session-role.d.ts.map +1 -1
  53. package/dist/core/session-role.js +1 -0
  54. package/dist/core/session-role.js.map +1 -1
  55. package/dist/core/system-prompt.d.ts.map +1 -1
  56. package/dist/core/system-prompt.js +21 -23
  57. package/dist/core/system-prompt.js.map +1 -1
  58. package/dist/core/tool-capability-policy.js +1 -1
  59. package/dist/core/tool-capability-policy.js.map +1 -1
  60. package/dist/core/tools/bash.d.ts +1 -6
  61. package/dist/core/tools/bash.d.ts.map +1 -1
  62. package/dist/core/tools/bash.js +2 -26
  63. package/dist/core/tools/bash.js.map +1 -1
  64. package/dist/core/tools/delegate.js +4 -4
  65. package/dist/core/tools/delegate.js.map +1 -1
  66. package/dist/core/tools/edit-diff.d.ts +32 -5
  67. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  68. package/dist/core/tools/edit-diff.js +137 -69
  69. package/dist/core/tools/edit-diff.js.map +1 -1
  70. package/dist/core/tools/edit.d.ts +22 -7
  71. package/dist/core/tools/edit.d.ts.map +1 -1
  72. package/dist/core/tools/edit.js +128 -55
  73. package/dist/core/tools/edit.js.map +1 -1
  74. package/dist/core/tools/file-mutation-intent.d.ts +70 -0
  75. package/dist/core/tools/file-mutation-intent.d.ts.map +1 -0
  76. package/dist/core/tools/file-mutation-intent.js +325 -0
  77. package/dist/core/tools/file-mutation-intent.js.map +1 -0
  78. package/dist/core/tools/goal.d.ts.map +1 -1
  79. package/dist/core/tools/goal.js +41 -18
  80. package/dist/core/tools/goal.js.map +1 -1
  81. package/dist/core/tools/index.d.ts +3 -1
  82. package/dist/core/tools/index.d.ts.map +1 -1
  83. package/dist/core/tools/index.js +31 -8
  84. package/dist/core/tools/index.js.map +1 -1
  85. package/dist/core/tools/profile-writer.d.ts +33 -0
  86. package/dist/core/tools/profile-writer.d.ts.map +1 -0
  87. package/dist/core/tools/profile-writer.js +67 -0
  88. package/dist/core/tools/profile-writer.js.map +1 -0
  89. package/dist/core/tools/task-steps.d.ts.map +1 -1
  90. package/dist/core/tools/task-steps.js +6 -11
  91. package/dist/core/tools/task-steps.js.map +1 -1
  92. package/dist/core/tools/tmux-dispatch.d.ts +2 -0
  93. package/dist/core/tools/tmux-dispatch.d.ts.map +1 -1
  94. package/dist/core/tools/tmux-dispatch.js +16 -2
  95. package/dist/core/tools/tmux-dispatch.js.map +1 -1
  96. package/dist/core/tools/write.d.ts +24 -7
  97. package/dist/core/tools/write.d.ts.map +1 -1
  98. package/dist/core/tools/write.js +182 -107
  99. package/dist/core/tools/write.js.map +1 -1
  100. package/dist/index.d.ts +1 -1
  101. package/dist/index.d.ts.map +1 -1
  102. package/dist/index.js +1 -1
  103. package/dist/index.js.map +1 -1
  104. package/dist/jscpd-cli.d.ts +3 -0
  105. package/dist/jscpd-cli.d.ts.map +1 -0
  106. package/dist/jscpd-cli.js +22 -0
  107. package/dist/jscpd-cli.js.map +1 -0
  108. package/dist/modes/interactive/components/profile-resource-editor.js +2 -2
  109. package/dist/modes/interactive/components/profile-resource-editor.js.map +1 -1
  110. package/dist/modes/interactive/components/tool-execution.d.ts +1 -0
  111. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  112. package/dist/modes/interactive/components/tool-execution.js +85 -3
  113. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  114. package/dist/modes/interactive/interactive-mode.js +1 -1
  115. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  116. package/dist/utils/bundled-jscpd.d.ts +20 -0
  117. package/dist/utils/bundled-jscpd.d.ts.map +1 -0
  118. package/dist/utils/bundled-jscpd.js +154 -0
  119. package/dist/utils/bundled-jscpd.js.map +1 -0
  120. package/dist/utils/shell.d.ts.map +1 -1
  121. package/dist/utils/shell.js +11 -0
  122. package/dist/utils/shell.js.map +1 -1
  123. package/dist/utils/tools-manager.d.ts +1 -1
  124. package/dist/utils/tools-manager.d.ts.map +1 -1
  125. package/dist/utils/tools-manager.js +22 -0
  126. package/dist/utils/tools-manager.js.map +1 -1
  127. package/docs/index.md +3 -0
  128. package/docs/managed-data-tools.md +15 -0
  129. package/docs/quickstart.md +2 -2
  130. package/docs/tool-boundary-performance-roadmap-2026-08-02.md +166 -0
  131. package/docs/tool-repair.md +1 -1
  132. package/docs/worker-profiles.md +16 -0
  133. package/examples/extensions/built-in-tool-renderer.ts +12 -5
  134. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  135. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  136. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  137. package/examples/extensions/minimal-mode.ts +8 -7
  138. package/examples/extensions/prompt-customizer.ts +4 -2
  139. package/examples/extensions/sandbox/package-lock.json +2 -2
  140. package/examples/extensions/sandbox/package.json +1 -1
  141. package/examples/extensions/ssh.ts +113 -24
  142. package/examples/extensions/with-deps/package-lock.json +2 -2
  143. package/examples/extensions/with-deps/package.json +1 -1
  144. package/npm-shrinkwrap.json +112 -12
  145. package/package.json +7 -5
@@ -0,0 +1,325 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import { constants } from "node:fs";
3
+ import { access, copyFile, lstat, open, stat, unlink } from "node:fs/promises";
4
+ import { dirname, resolve } from "node:path";
5
+ const DEFAULT_INTENT_LIMIT = 64;
6
+ const DEFAULT_CONTENT_REFERENCE_LIMIT = 64;
7
+ const DEFAULT_INTENT_TTL_MS = 10 * 60 * 1000;
8
+ const DEFAULT_CONTENT_REFERENCE_TTL_MS = 60 * 60 * 1000;
9
+ const HASH_BUFFER_BYTES = 64 * 1024;
10
+ const CONTENT_REFERENCE_PREFIX = "file-content:";
11
+ function isMissingPathError(error) {
12
+ return (typeof error === "object" &&
13
+ error !== null &&
14
+ "code" in error &&
15
+ (error.code === "ENOENT" || error.code === "ENOTDIR"));
16
+ }
17
+ function errorCode(error) {
18
+ return typeof error === "object" && error !== null && "code" in error && typeof error.code === "string"
19
+ ? error.code
20
+ : undefined;
21
+ }
22
+ function normalizedPath(path) {
23
+ const absolutePath = resolve(path);
24
+ return process.platform === "win32" ? absolutePath.toLocaleLowerCase("en-US") : absolutePath;
25
+ }
26
+ function positiveBound(value, fallback, label) {
27
+ const resolvedValue = value ?? fallback;
28
+ if (!Number.isSafeInteger(resolvedValue) || resolvedValue < 1) {
29
+ throw new TypeError(`${label} must be a positive safe integer.`);
30
+ }
31
+ return resolvedValue;
32
+ }
33
+ function normalizedIdentity(value) {
34
+ return {
35
+ dev: String(value.dev),
36
+ ino: String(value.ino),
37
+ mode: String(value.mode),
38
+ size: String(value.size),
39
+ mtimeMs: String(value.mtimeMs),
40
+ ctimeMs: String(value.ctimeMs),
41
+ };
42
+ }
43
+ function identitiesMatch(left, right) {
44
+ return (left !== undefined &&
45
+ right !== undefined &&
46
+ left.dev === right.dev &&
47
+ left.ino === right.ino &&
48
+ left.mode === right.mode &&
49
+ left.size === right.size &&
50
+ left.mtimeMs === right.mtimeMs &&
51
+ left.ctimeMs === right.ctimeMs);
52
+ }
53
+ async function inspectLocalPath(path, followSymlinks) {
54
+ try {
55
+ const result = followSymlinks ? await stat(path, { bigint: true }) : await lstat(path, { bigint: true });
56
+ return {
57
+ kind: result.isFile() ? "file" : result.isDirectory() ? "directory" : "other",
58
+ identity: normalizedIdentity(result),
59
+ };
60
+ }
61
+ catch (error) {
62
+ if (isMissingPathError(error))
63
+ return undefined;
64
+ throw error;
65
+ }
66
+ }
67
+ async function hashLocalFile(path, signal) {
68
+ const handle = await open(path, "r");
69
+ const hash = createHash("sha256");
70
+ const buffer = Buffer.allocUnsafe(HASH_BUFFER_BYTES);
71
+ try {
72
+ let position = 0;
73
+ while (true) {
74
+ if (signal?.aborted)
75
+ throw new Error("Operation aborted");
76
+ const { bytesRead } = await handle.read(buffer, 0, buffer.length, position);
77
+ if (bytesRead === 0)
78
+ break;
79
+ hash.update(buffer.subarray(0, bytesRead));
80
+ position += bytesRead;
81
+ }
82
+ return hash.digest("hex");
83
+ }
84
+ finally {
85
+ await handle.close();
86
+ }
87
+ }
88
+ export const localFileMutationIntentOperations = {
89
+ inspect: inspectLocalPath,
90
+ access,
91
+ copyFileExclusive: (sourcePath, targetPath) => copyFile(sourcePath, targetPath, constants.COPYFILE_EXCL),
92
+ hashFile: hashLocalFile,
93
+ removeFile: unlink,
94
+ };
95
+ /**
96
+ * Session-owned authority for two-phase file mutation intents and bounded exact-content references.
97
+ * It retains only fixed-size metadata; file bytes remain owned by the filesystem.
98
+ */
99
+ export class FileMutationIntentController {
100
+ constructor(options = {}) {
101
+ this.intents = new Map();
102
+ this.intentByPath = new Map();
103
+ this.contentReferences = new Map();
104
+ this.operations = options.operations ?? localFileMutationIntentOperations;
105
+ this.intentLimit = positiveBound(options.intentLimit, DEFAULT_INTENT_LIMIT, "Intent limit");
106
+ this.contentReferenceLimit = positiveBound(options.contentReferenceLimit, DEFAULT_CONTENT_REFERENCE_LIMIT, "Content reference limit");
107
+ this.intentTtlMs = positiveBound(options.intentTtlMs, DEFAULT_INTENT_TTL_MS, "Intent TTL");
108
+ this.contentReferenceTtlMs = positiveBound(options.contentReferenceTtlMs, DEFAULT_CONTENT_REFERENCE_TTL_MS, "Content reference TTL");
109
+ this.now = options.now ?? Date.now;
110
+ }
111
+ async prepare(kind, path, signal, displayPath = path) {
112
+ this.pruneExpired();
113
+ if (signal?.aborted)
114
+ throw new Error("Operation aborted");
115
+ const absolutePath = resolve(path);
116
+ let identity;
117
+ if (kind === "write") {
118
+ const existing = await this.operations.inspect(absolutePath, false);
119
+ if (existing)
120
+ throw new Error(`Write collision: ${displayPath} already exists.`);
121
+ await this.assertCreatableParent(absolutePath);
122
+ }
123
+ else {
124
+ const existing = await this.operations.inspect(absolutePath, true);
125
+ if (!existing)
126
+ throw new Error(`Could not edit file: ${displayPath}. Error code: ENOENT.`);
127
+ if (existing.kind !== "file")
128
+ throw new Error(`Could not edit file: ${displayPath}. Target is not a regular file.`);
129
+ try {
130
+ await this.operations.access(absolutePath, constants.R_OK | constants.W_OK);
131
+ }
132
+ catch (error) {
133
+ const code = errorCode(error);
134
+ throw new Error(`Could not edit file: ${displayPath}. ${code ? `Error code: ${code}` : String(error)}.`);
135
+ }
136
+ identity = existing.identity;
137
+ }
138
+ if (signal?.aborted)
139
+ throw new Error("Operation aborted");
140
+ const key = `${kind}\0${normalizedPath(absolutePath)}`;
141
+ const priorIntentId = this.intentByPath.get(key);
142
+ if (priorIntentId)
143
+ this.deleteIntent(priorIntentId);
144
+ while (this.intents.size >= this.intentLimit) {
145
+ const oldestIntentId = this.intents.keys().next().value;
146
+ if (typeof oldestIntentId !== "string")
147
+ break;
148
+ this.deleteIntent(oldestIntentId);
149
+ }
150
+ const intentId = randomUUID();
151
+ const record = {
152
+ intentId,
153
+ kind,
154
+ path: absolutePath,
155
+ displayPath,
156
+ ...(identity ? { identity } : {}),
157
+ expiresAt: this.now() + this.intentTtlMs,
158
+ };
159
+ this.intents.set(intentId, record);
160
+ this.intentByPath.set(key, intentId);
161
+ return { intentId, kind, path: absolutePath, displayPath };
162
+ }
163
+ consume(intentId, kind, path) {
164
+ this.pruneExpired();
165
+ const record = this.intents.get(intentId);
166
+ if (!record)
167
+ throw new Error("File mutation intent is invalid, expired, or belongs to another session.");
168
+ this.deleteIntent(intentId);
169
+ if (record.kind !== kind)
170
+ throw new Error(`File mutation intent is for ${record.kind}, not ${kind}.`);
171
+ if (normalizedPath(record.path) !== normalizedPath(path)) {
172
+ throw new Error("File mutation intent path does not match the commit path.");
173
+ }
174
+ return {
175
+ intentId: record.intentId,
176
+ kind: record.kind,
177
+ path: record.path,
178
+ displayPath: record.displayPath,
179
+ ...(record.identity ? { identity: record.identity } : {}),
180
+ };
181
+ }
182
+ async assertCurrent(lease, signal) {
183
+ if (signal?.aborted)
184
+ throw new Error("Operation aborted");
185
+ if (lease.kind === "write") {
186
+ if (await this.operations.inspect(lease.path, false)) {
187
+ throw new Error(`Write collision: ${lease.displayPath} already exists; the prepared intent is stale.`);
188
+ }
189
+ return;
190
+ }
191
+ const current = await this.operations.inspect(lease.path, true);
192
+ if (!current || current.kind !== "file") {
193
+ throw new Error(`Could not edit file: ${lease.displayPath}. The prepared target no longer exists.`);
194
+ }
195
+ if (!identitiesMatch(lease.identity, current.identity)) {
196
+ throw new Error(`Could not edit file: ${lease.displayPath}. The file changed after preparation; prepare again.`);
197
+ }
198
+ try {
199
+ await this.operations.access(lease.path, constants.R_OK | constants.W_OK);
200
+ }
201
+ catch (error) {
202
+ const code = errorCode(error);
203
+ throw new Error(`Could not edit file: ${lease.displayPath}. ${code ? `Error code: ${code}` : String(error)}.`);
204
+ }
205
+ }
206
+ rememberContent(sourcePath, content) {
207
+ const digest = createHash("sha256").update(content, "utf8").digest("hex");
208
+ return this.rememberContentDigest(sourcePath, digest, Buffer.byteLength(content, "utf8"));
209
+ }
210
+ async copyReferencedContent(contentRef, targetPath, signal) {
211
+ this.pruneExpired();
212
+ const record = this.contentReferences.get(contentRef);
213
+ if (!record)
214
+ throw new Error("File content reference is invalid, expired, or belongs to another session.");
215
+ this.touchContentReference(record);
216
+ if (signal?.aborted)
217
+ throw new Error("Operation aborted");
218
+ let sourceDigest;
219
+ try {
220
+ sourceDigest = await this.operations.hashFile(record.sourcePath, signal);
221
+ }
222
+ catch (error) {
223
+ throw new Error(`File content reference source is unavailable: ${String(error)}.`);
224
+ }
225
+ if (sourceDigest !== record.digest) {
226
+ this.contentReferences.delete(contentRef);
227
+ throw new Error("File content reference source changed after it was cached.");
228
+ }
229
+ await this.operations.copyFileExclusive(record.sourcePath, targetPath);
230
+ let targetDigest;
231
+ try {
232
+ targetDigest = await this.operations.hashFile(targetPath, signal);
233
+ }
234
+ catch (error) {
235
+ await this.removeFailedCopy(targetPath, error);
236
+ throw error;
237
+ }
238
+ if (targetDigest !== record.digest) {
239
+ await this.removeFailedCopy(targetPath, new Error("copied bytes did not match the cached digest"));
240
+ throw new Error("File content copy changed while it was being created; the target was removed.");
241
+ }
242
+ return this.rememberContentDigest(targetPath, record.digest, record.byteLength);
243
+ }
244
+ async assertCreatableParent(path) {
245
+ let candidate = dirname(path);
246
+ while (true) {
247
+ const inspection = await this.operations.inspect(candidate, true);
248
+ if (inspection) {
249
+ if (inspection.kind !== "directory") {
250
+ throw new Error(`Write parent path is not a directory: ${candidate}.`);
251
+ }
252
+ try {
253
+ await this.operations.access(candidate, constants.W_OK);
254
+ }
255
+ catch (error) {
256
+ const code = errorCode(error);
257
+ throw new Error(`Write parent is not writable: ${candidate}${code ? ` (${code})` : ""}.`);
258
+ }
259
+ return;
260
+ }
261
+ const parent = dirname(candidate);
262
+ if (parent === candidate)
263
+ throw new Error(`No writable parent exists for ${path}.`);
264
+ candidate = parent;
265
+ }
266
+ }
267
+ rememberContentDigest(sourcePath, digest, byteLength) {
268
+ this.pruneExpired();
269
+ for (const existing of this.contentReferences.values()) {
270
+ if (existing.sourcePath === sourcePath && existing.digest === digest) {
271
+ this.touchContentReference(existing);
272
+ return { contentRef: existing.contentRef, byteLength: existing.byteLength };
273
+ }
274
+ }
275
+ while (this.contentReferences.size >= this.contentReferenceLimit) {
276
+ const oldestContentRef = this.contentReferences.keys().next().value;
277
+ if (typeof oldestContentRef !== "string")
278
+ break;
279
+ this.contentReferences.delete(oldestContentRef);
280
+ }
281
+ const contentRef = `${CONTENT_REFERENCE_PREFIX}${randomUUID()}`;
282
+ this.contentReferences.set(contentRef, {
283
+ contentRef,
284
+ sourcePath,
285
+ digest,
286
+ byteLength,
287
+ expiresAt: this.now() + this.contentReferenceTtlMs,
288
+ });
289
+ return { contentRef, byteLength };
290
+ }
291
+ touchContentReference(record) {
292
+ record.expiresAt = this.now() + this.contentReferenceTtlMs;
293
+ this.contentReferences.delete(record.contentRef);
294
+ this.contentReferences.set(record.contentRef, record);
295
+ }
296
+ async removeFailedCopy(path, cause) {
297
+ try {
298
+ await this.operations.removeFile(path);
299
+ }
300
+ catch (cleanupError) {
301
+ throw new Error(`Copied content verification failed (${String(cause)}), and the newly created target could not be removed: ${String(cleanupError)}.`);
302
+ }
303
+ }
304
+ deleteIntent(intentId) {
305
+ const record = this.intents.get(intentId);
306
+ if (!record)
307
+ return;
308
+ this.intents.delete(intentId);
309
+ const key = `${record.kind}\0${normalizedPath(record.path)}`;
310
+ if (this.intentByPath.get(key) === intentId)
311
+ this.intentByPath.delete(key);
312
+ }
313
+ pruneExpired() {
314
+ const now = this.now();
315
+ for (const [intentId, record] of this.intents) {
316
+ if (record.expiresAt <= now)
317
+ this.deleteIntent(intentId);
318
+ }
319
+ for (const [contentRef, record] of this.contentReferences) {
320
+ if (record.expiresAt <= now)
321
+ this.contentReferences.delete(contentRef);
322
+ }
323
+ }
324
+ }
325
+ //# sourceMappingURL=file-mutation-intent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-mutation-intent.js","sourceRoot":"","sources":["../../../src/core/tools/file-mutation-intent.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash, randomUUID } from \"node:crypto\";\nimport { constants } from \"node:fs\";\nimport { access, copyFile, lstat, open, stat, unlink } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\n\nconst DEFAULT_INTENT_LIMIT = 64;\nconst DEFAULT_CONTENT_REFERENCE_LIMIT = 64;\nconst DEFAULT_INTENT_TTL_MS = 10 * 60 * 1000;\nconst DEFAULT_CONTENT_REFERENCE_TTL_MS = 60 * 60 * 1000;\nconst HASH_BUFFER_BYTES = 64 * 1024;\nconst CONTENT_REFERENCE_PREFIX = \"file-content:\";\n\nexport type FileMutationKind = \"write\" | \"edit\";\n\nexport interface FilePathIdentity {\n\tdev: string;\n\tino: string;\n\tmode: string;\n\tsize: string;\n\tmtimeMs: string;\n\tctimeMs: string;\n}\n\nexport interface FilePathInspection {\n\tkind: \"file\" | \"directory\" | \"other\";\n\tidentity: FilePathIdentity;\n}\n\nexport interface FileMutationIntentOperations {\n\tinspect(path: string, followSymlinks: boolean): Promise<FilePathInspection | undefined>;\n\taccess(path: string, mode: number): Promise<void>;\n\tcopyFileExclusive(sourcePath: string, targetPath: string): Promise<void>;\n\thashFile(path: string, signal?: AbortSignal): Promise<string>;\n\tremoveFile(path: string): Promise<void>;\n}\n\nexport interface PreparedFileMutation {\n\tintentId: string;\n\tkind: FileMutationKind;\n\tpath: string;\n\tdisplayPath: string;\n}\n\nexport interface FileMutationLease extends PreparedFileMutation {\n\tidentity?: FilePathIdentity;\n}\n\nexport interface FileContentReference {\n\tcontentRef: string;\n\tbyteLength: number;\n}\n\ninterface MutationIntentRecord extends FileMutationLease {\n\texpiresAt: number;\n}\n\ninterface ContentReferenceRecord {\n\tcontentRef: string;\n\tsourcePath: string;\n\tdigest: string;\n\tbyteLength: number;\n\texpiresAt: number;\n}\n\nexport interface FileMutationIntentControllerOptions {\n\toperations?: FileMutationIntentOperations;\n\tintentLimit?: number;\n\tcontentReferenceLimit?: number;\n\tintentTtlMs?: number;\n\tcontentReferenceTtlMs?: number;\n\tnow?: () => number;\n}\n\nfunction isMissingPathError(error: unknown): boolean {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t\"code\" in error &&\n\t\t(error.code === \"ENOENT\" || error.code === \"ENOTDIR\")\n\t);\n}\n\nfunction errorCode(error: unknown): string | undefined {\n\treturn typeof error === \"object\" && error !== null && \"code\" in error && typeof error.code === \"string\"\n\t\t? error.code\n\t\t: undefined;\n}\n\nfunction normalizedPath(path: string): string {\n\tconst absolutePath = resolve(path);\n\treturn process.platform === \"win32\" ? absolutePath.toLocaleLowerCase(\"en-US\") : absolutePath;\n}\n\nfunction positiveBound(value: number | undefined, fallback: number, label: string): number {\n\tconst resolvedValue = value ?? fallback;\n\tif (!Number.isSafeInteger(resolvedValue) || resolvedValue < 1) {\n\t\tthrow new TypeError(`${label} must be a positive safe integer.`);\n\t}\n\treturn resolvedValue;\n}\n\nfunction normalizedIdentity(value: {\n\tdev: number | bigint;\n\tino: number | bigint;\n\tmode: number | bigint;\n\tsize: number | bigint;\n\tmtimeMs: number | bigint;\n\tctimeMs: number | bigint;\n}): FilePathIdentity {\n\treturn {\n\t\tdev: String(value.dev),\n\t\tino: String(value.ino),\n\t\tmode: String(value.mode),\n\t\tsize: String(value.size),\n\t\tmtimeMs: String(value.mtimeMs),\n\t\tctimeMs: String(value.ctimeMs),\n\t};\n}\n\nfunction identitiesMatch(left: FilePathIdentity | undefined, right: FilePathIdentity | undefined): boolean {\n\treturn (\n\t\tleft !== undefined &&\n\t\tright !== undefined &&\n\t\tleft.dev === right.dev &&\n\t\tleft.ino === right.ino &&\n\t\tleft.mode === right.mode &&\n\t\tleft.size === right.size &&\n\t\tleft.mtimeMs === right.mtimeMs &&\n\t\tleft.ctimeMs === right.ctimeMs\n\t);\n}\n\nasync function inspectLocalPath(path: string, followSymlinks: boolean): Promise<FilePathInspection | undefined> {\n\ttry {\n\t\tconst result = followSymlinks ? await stat(path, { bigint: true }) : await lstat(path, { bigint: true });\n\t\treturn {\n\t\t\tkind: result.isFile() ? \"file\" : result.isDirectory() ? \"directory\" : \"other\",\n\t\t\tidentity: normalizedIdentity(result),\n\t\t};\n\t} catch (error) {\n\t\tif (isMissingPathError(error)) return undefined;\n\t\tthrow error;\n\t}\n}\n\nasync function hashLocalFile(path: string, signal?: AbortSignal): Promise<string> {\n\tconst handle = await open(path, \"r\");\n\tconst hash = createHash(\"sha256\");\n\tconst buffer = Buffer.allocUnsafe(HASH_BUFFER_BYTES);\n\ttry {\n\t\tlet position = 0;\n\t\twhile (true) {\n\t\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\t\tconst { bytesRead } = await handle.read(buffer, 0, buffer.length, position);\n\t\t\tif (bytesRead === 0) break;\n\t\t\thash.update(buffer.subarray(0, bytesRead));\n\t\t\tposition += bytesRead;\n\t\t}\n\t\treturn hash.digest(\"hex\");\n\t} finally {\n\t\tawait handle.close();\n\t}\n}\n\nexport const localFileMutationIntentOperations: FileMutationIntentOperations = {\n\tinspect: inspectLocalPath,\n\taccess,\n\tcopyFileExclusive: (sourcePath, targetPath) => copyFile(sourcePath, targetPath, constants.COPYFILE_EXCL),\n\thashFile: hashLocalFile,\n\tremoveFile: unlink,\n};\n\n/**\n * Session-owned authority for two-phase file mutation intents and bounded exact-content references.\n * It retains only fixed-size metadata; file bytes remain owned by the filesystem.\n */\nexport class FileMutationIntentController {\n\tprivate readonly operations: FileMutationIntentOperations;\n\tprivate readonly intentLimit: number;\n\tprivate readonly contentReferenceLimit: number;\n\tprivate readonly intentTtlMs: number;\n\tprivate readonly contentReferenceTtlMs: number;\n\tprivate readonly now: () => number;\n\tprivate readonly intents = new Map<string, MutationIntentRecord>();\n\tprivate readonly intentByPath = new Map<string, string>();\n\tprivate readonly contentReferences = new Map<string, ContentReferenceRecord>();\n\n\tconstructor(options: FileMutationIntentControllerOptions = {}) {\n\t\tthis.operations = options.operations ?? localFileMutationIntentOperations;\n\t\tthis.intentLimit = positiveBound(options.intentLimit, DEFAULT_INTENT_LIMIT, \"Intent limit\");\n\t\tthis.contentReferenceLimit = positiveBound(\n\t\t\toptions.contentReferenceLimit,\n\t\t\tDEFAULT_CONTENT_REFERENCE_LIMIT,\n\t\t\t\"Content reference limit\",\n\t\t);\n\t\tthis.intentTtlMs = positiveBound(options.intentTtlMs, DEFAULT_INTENT_TTL_MS, \"Intent TTL\");\n\t\tthis.contentReferenceTtlMs = positiveBound(\n\t\t\toptions.contentReferenceTtlMs,\n\t\t\tDEFAULT_CONTENT_REFERENCE_TTL_MS,\n\t\t\t\"Content reference TTL\",\n\t\t);\n\t\tthis.now = options.now ?? Date.now;\n\t}\n\n\tasync prepare(\n\t\tkind: FileMutationKind,\n\t\tpath: string,\n\t\tsignal?: AbortSignal,\n\t\tdisplayPath: string = path,\n\t): Promise<PreparedFileMutation> {\n\t\tthis.pruneExpired();\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\tconst absolutePath = resolve(path);\n\t\tlet identity: FilePathIdentity | undefined;\n\t\tif (kind === \"write\") {\n\t\t\tconst existing = await this.operations.inspect(absolutePath, false);\n\t\t\tif (existing) throw new Error(`Write collision: ${displayPath} already exists.`);\n\t\t\tawait this.assertCreatableParent(absolutePath);\n\t\t} else {\n\t\t\tconst existing = await this.operations.inspect(absolutePath, true);\n\t\t\tif (!existing) throw new Error(`Could not edit file: ${displayPath}. Error code: ENOENT.`);\n\t\t\tif (existing.kind !== \"file\")\n\t\t\t\tthrow new Error(`Could not edit file: ${displayPath}. Target is not a regular file.`);\n\t\t\ttry {\n\t\t\t\tawait this.operations.access(absolutePath, constants.R_OK | constants.W_OK);\n\t\t\t} catch (error) {\n\t\t\t\tconst code = errorCode(error);\n\t\t\t\tthrow new Error(`Could not edit file: ${displayPath}. ${code ? `Error code: ${code}` : String(error)}.`);\n\t\t\t}\n\t\t\tidentity = existing.identity;\n\t\t}\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\n\t\tconst key = `${kind}\\0${normalizedPath(absolutePath)}`;\n\t\tconst priorIntentId = this.intentByPath.get(key);\n\t\tif (priorIntentId) this.deleteIntent(priorIntentId);\n\t\twhile (this.intents.size >= this.intentLimit) {\n\t\t\tconst oldestIntentId = this.intents.keys().next().value;\n\t\t\tif (typeof oldestIntentId !== \"string\") break;\n\t\t\tthis.deleteIntent(oldestIntentId);\n\t\t}\n\t\tconst intentId = randomUUID();\n\t\tconst record: MutationIntentRecord = {\n\t\t\tintentId,\n\t\t\tkind,\n\t\t\tpath: absolutePath,\n\t\t\tdisplayPath,\n\t\t\t...(identity ? { identity } : {}),\n\t\t\texpiresAt: this.now() + this.intentTtlMs,\n\t\t};\n\t\tthis.intents.set(intentId, record);\n\t\tthis.intentByPath.set(key, intentId);\n\t\treturn { intentId, kind, path: absolutePath, displayPath };\n\t}\n\n\tconsume(intentId: string, kind: FileMutationKind, path: string): FileMutationLease {\n\t\tthis.pruneExpired();\n\t\tconst record = this.intents.get(intentId);\n\t\tif (!record) throw new Error(\"File mutation intent is invalid, expired, or belongs to another session.\");\n\t\tthis.deleteIntent(intentId);\n\t\tif (record.kind !== kind) throw new Error(`File mutation intent is for ${record.kind}, not ${kind}.`);\n\t\tif (normalizedPath(record.path) !== normalizedPath(path)) {\n\t\t\tthrow new Error(\"File mutation intent path does not match the commit path.\");\n\t\t}\n\t\treturn {\n\t\t\tintentId: record.intentId,\n\t\t\tkind: record.kind,\n\t\t\tpath: record.path,\n\t\t\tdisplayPath: record.displayPath,\n\t\t\t...(record.identity ? { identity: record.identity } : {}),\n\t\t};\n\t}\n\n\tasync assertCurrent(lease: FileMutationLease, signal?: AbortSignal): Promise<void> {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\tif (lease.kind === \"write\") {\n\t\t\tif (await this.operations.inspect(lease.path, false)) {\n\t\t\t\tthrow new Error(`Write collision: ${lease.displayPath} already exists; the prepared intent is stale.`);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst current = await this.operations.inspect(lease.path, true);\n\t\tif (!current || current.kind !== \"file\") {\n\t\t\tthrow new Error(`Could not edit file: ${lease.displayPath}. The prepared target no longer exists.`);\n\t\t}\n\t\tif (!identitiesMatch(lease.identity, current.identity)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Could not edit file: ${lease.displayPath}. The file changed after preparation; prepare again.`,\n\t\t\t);\n\t\t}\n\t\ttry {\n\t\t\tawait this.operations.access(lease.path, constants.R_OK | constants.W_OK);\n\t\t} catch (error) {\n\t\t\tconst code = errorCode(error);\n\t\t\tthrow new Error(`Could not edit file: ${lease.displayPath}. ${code ? `Error code: ${code}` : String(error)}.`);\n\t\t}\n\t}\n\n\trememberContent(sourcePath: string, content: string): FileContentReference {\n\t\tconst digest = createHash(\"sha256\").update(content, \"utf8\").digest(\"hex\");\n\t\treturn this.rememberContentDigest(sourcePath, digest, Buffer.byteLength(content, \"utf8\"));\n\t}\n\n\tasync copyReferencedContent(\n\t\tcontentRef: string,\n\t\ttargetPath: string,\n\t\tsignal?: AbortSignal,\n\t): Promise<FileContentReference> {\n\t\tthis.pruneExpired();\n\t\tconst record = this.contentReferences.get(contentRef);\n\t\tif (!record) throw new Error(\"File content reference is invalid, expired, or belongs to another session.\");\n\t\tthis.touchContentReference(record);\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\tlet sourceDigest: string;\n\t\ttry {\n\t\t\tsourceDigest = await this.operations.hashFile(record.sourcePath, signal);\n\t\t} catch (error) {\n\t\t\tthrow new Error(`File content reference source is unavailable: ${String(error)}.`);\n\t\t}\n\t\tif (sourceDigest !== record.digest) {\n\t\t\tthis.contentReferences.delete(contentRef);\n\t\t\tthrow new Error(\"File content reference source changed after it was cached.\");\n\t\t}\n\n\t\tawait this.operations.copyFileExclusive(record.sourcePath, targetPath);\n\t\tlet targetDigest: string;\n\t\ttry {\n\t\t\ttargetDigest = await this.operations.hashFile(targetPath, signal);\n\t\t} catch (error) {\n\t\t\tawait this.removeFailedCopy(targetPath, error);\n\t\t\tthrow error;\n\t\t}\n\t\tif (targetDigest !== record.digest) {\n\t\t\tawait this.removeFailedCopy(targetPath, new Error(\"copied bytes did not match the cached digest\"));\n\t\t\tthrow new Error(\"File content copy changed while it was being created; the target was removed.\");\n\t\t}\n\t\treturn this.rememberContentDigest(targetPath, record.digest, record.byteLength);\n\t}\n\n\tprivate async assertCreatableParent(path: string): Promise<void> {\n\t\tlet candidate = dirname(path);\n\t\twhile (true) {\n\t\t\tconst inspection = await this.operations.inspect(candidate, true);\n\t\t\tif (inspection) {\n\t\t\t\tif (inspection.kind !== \"directory\") {\n\t\t\t\t\tthrow new Error(`Write parent path is not a directory: ${candidate}.`);\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tawait this.operations.access(candidate, constants.W_OK);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst code = errorCode(error);\n\t\t\t\t\tthrow new Error(`Write parent is not writable: ${candidate}${code ? ` (${code})` : \"\"}.`);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst parent = dirname(candidate);\n\t\t\tif (parent === candidate) throw new Error(`No writable parent exists for ${path}.`);\n\t\t\tcandidate = parent;\n\t\t}\n\t}\n\n\tprivate rememberContentDigest(sourcePath: string, digest: string, byteLength: number): FileContentReference {\n\t\tthis.pruneExpired();\n\t\tfor (const existing of this.contentReferences.values()) {\n\t\t\tif (existing.sourcePath === sourcePath && existing.digest === digest) {\n\t\t\t\tthis.touchContentReference(existing);\n\t\t\t\treturn { contentRef: existing.contentRef, byteLength: existing.byteLength };\n\t\t\t}\n\t\t}\n\t\twhile (this.contentReferences.size >= this.contentReferenceLimit) {\n\t\t\tconst oldestContentRef = this.contentReferences.keys().next().value;\n\t\t\tif (typeof oldestContentRef !== \"string\") break;\n\t\t\tthis.contentReferences.delete(oldestContentRef);\n\t\t}\n\t\tconst contentRef = `${CONTENT_REFERENCE_PREFIX}${randomUUID()}`;\n\t\tthis.contentReferences.set(contentRef, {\n\t\t\tcontentRef,\n\t\t\tsourcePath,\n\t\t\tdigest,\n\t\t\tbyteLength,\n\t\t\texpiresAt: this.now() + this.contentReferenceTtlMs,\n\t\t});\n\t\treturn { contentRef, byteLength };\n\t}\n\n\tprivate touchContentReference(record: ContentReferenceRecord): void {\n\t\trecord.expiresAt = this.now() + this.contentReferenceTtlMs;\n\t\tthis.contentReferences.delete(record.contentRef);\n\t\tthis.contentReferences.set(record.contentRef, record);\n\t}\n\n\tprivate async removeFailedCopy(path: string, cause: unknown): Promise<void> {\n\t\ttry {\n\t\t\tawait this.operations.removeFile(path);\n\t\t} catch (cleanupError) {\n\t\t\tthrow new Error(\n\t\t\t\t`Copied content verification failed (${String(cause)}), and the newly created target could not be removed: ${String(cleanupError)}.`,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate deleteIntent(intentId: string): void {\n\t\tconst record = this.intents.get(intentId);\n\t\tif (!record) return;\n\t\tthis.intents.delete(intentId);\n\t\tconst key = `${record.kind}\\0${normalizedPath(record.path)}`;\n\t\tif (this.intentByPath.get(key) === intentId) this.intentByPath.delete(key);\n\t}\n\n\tprivate pruneExpired(): void {\n\t\tconst now = this.now();\n\t\tfor (const [intentId, record] of this.intents) {\n\t\t\tif (record.expiresAt <= now) this.deleteIntent(intentId);\n\t\t}\n\t\tfor (const [contentRef, record] of this.contentReferences) {\n\t\t\tif (record.expiresAt <= now) this.contentReferences.delete(contentRef);\n\t\t}\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"goal.d.ts","sourceRoot":"","sources":["../../../src/core/tools/goal.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,KAAK,iBAAiB,EAAwB,MAAM,4BAA4B,CAAC;AAC1F,OAAO,KAAK,EAAoB,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EAGN,KAAK,cAAc,EACnB,KAAK,eAAe,EAEpB,MAAM,4BAA4B,CAAC;AAQpC,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;EAkEf,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAEtD,MAAM,WAAW,eAAe;IAC/B,MAAM,EAAE,cAAc,GAAG,KAAK,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;iHAE6G;IAC7G,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;uGAImG;IACnG,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACpC,mEAAmE;IACnE,YAAY,EAAE,MAAM,SAAS,GAAG,SAAS,CAAC;IAC1C,+DAA+D;IAC/D,aAAa,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACxE,+CAA+C;IAC/C,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;IAChD;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,SAAS,UAAU,EAAE,CAAC;IAC7C;;;;;;OAMG;IACH,uBAAuB,CAAC,EAAE,MAAM,SAAS,WAAW,EAAE,CAAC;IACvD;;;;;;;;;OASG;IACH,qBAAqB,CAAC,EAAE,CAAC,IAAI,EAAE;QAC9B,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;KACrB,KAAK;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IAC3D;;;;;;;;;;;;;;;;;OAiBG;IACH,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE;QAC3B,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;KACrB,KAAK,OAAO,CAAC;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,mGAAmG;IACnG,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB;;;OAGG;IACH,oCAAoC,CAAC,EAAE,MAAM,OAAO,CAAC;IACrD;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,SAAS,eAAe,EAAE,CAAC;CACpD;AA4JD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,oBAAoB,GAAG,cAAc,CAkKnF"}
1
+ {"version":3,"file":"goal.d.ts","sourceRoot":"","sources":["../../../src/core/tools/goal.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,KAAK,iBAAiB,EAAwB,MAAM,4BAA4B,CAAC;AAC1F,OAAO,KAAK,EAAoB,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EAGN,KAAK,cAAc,EACnB,KAAK,eAAe,EAEpB,MAAM,4BAA4B,CAAC;AAQpC,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;EAgEf,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAEtD,MAAM,WAAW,eAAe;IAC/B,MAAM,EAAE,cAAc,GAAG,KAAK,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;iHAE6G;IAC7G,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;uGAImG;IACnG,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACpC,mEAAmE;IACnE,YAAY,EAAE,MAAM,SAAS,GAAG,SAAS,CAAC;IAC1C,+DAA+D;IAC/D,aAAa,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACxE,+CAA+C;IAC/C,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;IAChD;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,SAAS,UAAU,EAAE,CAAC;IAC7C;;;;;;OAMG;IACH,uBAAuB,CAAC,EAAE,MAAM,SAAS,WAAW,EAAE,CAAC;IACvD;;;;;;;;;OASG;IACH,qBAAqB,CAAC,EAAE,CAAC,IAAI,EAAE;QAC9B,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;KACrB,KAAK;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IAC3D;;;;;;;;;;;;;;;;;OAiBG;IACH,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE;QAC3B,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;KACrB,KAAK,OAAO,CAAC;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,mGAAmG;IACnG,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB;;;OAGG;IACH,oCAAoC,CAAC,EAAE,MAAM,OAAO,CAAC;IACrD;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,SAAS,eAAe,EAAE,CAAC;CACpD;AAgKD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,oBAAoB,GAAG,cAAc,CAsLnF"}
@@ -23,13 +23,13 @@ const goalSchema = Type.Object({
23
23
  userGoal: Type.Optional(Type.String({ description: "The goal statement. Required for action 'start'." })),
24
24
  tokenBudget: Type.Optional(Type.Integer({ minimum: 1, description: "Optional positive token budget for action 'start'." })),
25
25
  requirementId: Type.Optional(Type.String({
26
- description: "Requirement id for add_requirement/satisfy_requirement/block_requirement/reopen_requirement/dispatch_worker.",
26
+ description: "Requirement id for requirement actions.",
27
27
  })),
28
28
  text: Type.Optional(Type.String({ description: "Requirement text. Required for add_requirement." })),
29
29
  instructions: Type.Optional(Type.String({ description: "Worker instructions. Required for dispatch_worker." })),
30
30
  evidenceId: Type.Optional(Type.String({ description: "Evidence id. Required for add_evidence." })),
31
31
  evidenceIds: Type.Optional(Type.Array(Type.String(), {
32
- description: "Evidence ids supporting a satisfy_requirement action. Each must already be recorded.",
32
+ description: "Existing evidence ids for satisfy_requirement.",
33
33
  })),
34
34
  kind: Type.Optional(Type.Union([
35
35
  Type.Literal("file"),
@@ -41,13 +41,16 @@ const goalSchema = Type.Object({
41
41
  ], { description: "Evidence kind. Required for add_evidence." })),
42
42
  summary: Type.Optional(Type.String({ description: "Evidence summary. Required for add_evidence." })),
43
43
  uri: Type.Optional(Type.String({
44
- description: "Optional evidence locator (path/URL for kind 'file', a toolCallId for kind 'tool', a laneId for kind 'worker').",
44
+ description: "Optional file/URL, toolCallId, or laneId evidence locator.",
45
45
  })),
46
46
  reason: Type.Optional(Type.String({ description: "Reason for block_requirement or block_goal." })),
47
47
  dispatchTarget: Type.Optional(Type.Union([Type.Literal("in_process"), Type.Literal("tmux")], {
48
- description: "Legacy worker target. Prefer the delegate tool for new work.",
48
+ description: "Legacy target. Native is default; use tmux only for an owner-requested persistent pane.",
49
49
  })),
50
50
  }, { additionalProperties: false });
51
+ function allowsNativeTmuxFallback(reason) {
52
+ return reason === "tmux_unavailable" || reason === "tmux_extension_not_loaded";
53
+ }
51
54
  /**
52
55
  * Validate an evidence ref's `uri` against session records ("tool") or the filesystem ("file").
53
56
  * Returns `undefined` for kinds/refs that carry nothing checkable (e.g. "user"/"finding"/"test",
@@ -204,12 +207,12 @@ export function createGoalToolDefinition(deps) {
204
207
  return {
205
208
  name: "goal",
206
209
  label: "goal",
207
- description: "Read or update the compact durable goal record for explicitly requested long-running work. Planning belongs to task_steps, workers to delegate, and evidence to current tools/artifacts. Pause, resume, edit, clear, and budget stops are owner/system controlled.",
208
- promptSnippet: "Read or update the compact durable goal record.",
210
+ description: "Read or update the durable goal for explicitly persistent work. Use task_steps for plans and delegate for workers; owner or system controls lifecycle and budget stops.",
211
+ promptSnippet: "Read or update the durable goal.",
209
212
  promptGuidelines: [
210
- "Call action 'start' only when the user or system explicitly requests a persistent goal; that request may be ordinary chat and does not require a slash command. The host may already have admitted high-confidence chat wording, so use 'get' before starting when uncertain. Do not infer a goal from an ordinary multi-step task or replace an unfinished goal implicitly. Set tokenBudget only when the user explicitly requested a token budget.",
211
- "Use 'get' when the current objective or status is uncertain. Use task_steps for decomposition and delegate for workers; detailed ledger actions exist only for goals that already use the legacy ledger.",
212
- "Mark 'complete' only after current authoritative evidence proves the full objective and no required work remains. Mark 'block_goal' only after the same genuine impasse persists for three goal turns.",
213
+ "Start only for an explicit persistent goal from chat or system; no slash command is needed. Use get when uncertain, never replace an unfinished goal, and set tokenBudget only when explicitly requested.",
214
+ "Use task_steps for plans and delegate for workers; use legacy actions only on legacy goals.",
215
+ "Complete only with current authoritative evidence and no remaining work; block_goal only after the same real impasse lasts three goal turns.",
213
216
  ],
214
217
  parameters: goalSchema,
215
218
  renderShell: "self",
@@ -291,26 +294,46 @@ export function createGoalToolDefinition(deps) {
291
294
  }
292
295
  }
293
296
  if (action.action === "dispatch_worker" && !dispatchGuardRefused) {
294
- const useTmux = input.dispatchTarget === "tmux" && deps.dispatchTmuxWorker !== undefined;
295
- const dispatched = useTmux
296
- ? await deps.dispatchTmuxWorker?.({
297
+ const tmuxRequested = input.dispatchTarget === "tmux";
298
+ let useTmux = tmuxRequested && deps.dispatchTmuxWorker !== undefined;
299
+ let tmuxFallbackReason;
300
+ let dispatched;
301
+ if (useTmux) {
302
+ dispatched = await deps.dispatchTmuxWorker?.({
297
303
  requirementId: action.requirementId,
298
304
  instructions: action.instructions,
299
- })
300
- : deps.startWorkerDelegation?.({
305
+ });
306
+ if (!dispatched?.laneId &&
307
+ allowsNativeTmuxFallback(dispatched?.skipReason) &&
308
+ deps.startWorkerDelegation) {
309
+ tmuxFallbackReason = dispatched?.skipReason;
310
+ useTmux = false;
311
+ dispatched = deps.startWorkerDelegation({
312
+ requirementId: action.requirementId,
313
+ instructions: action.instructions,
314
+ });
315
+ }
316
+ }
317
+ else {
318
+ if (tmuxRequested)
319
+ tmuxFallbackReason = "tmux_extension_not_loaded";
320
+ dispatched = deps.startWorkerDelegation?.({
301
321
  requirementId: action.requirementId,
302
322
  instructions: action.instructions,
303
323
  });
324
+ }
304
325
  action = { ...action, laneId: dispatched?.laneId };
305
326
  if (dispatched?.laneId) {
306
- dispatchNote = useTmux
307
- ? `Dispatched tmux worker lane '${dispatched.laneId}' for requirement '${action.requirementId}'.`
308
- : `Dispatched in-process worker lane '${dispatched.laneId}' for requirement '${action.requirementId}' (tmux dispatch is not available from this tool yet).`;
327
+ dispatchNote = tmuxFallbackReason
328
+ ? `Tmux route returned ${tmuxFallbackReason}; dispatched native fallback worker lane '${dispatched.laneId}' for requirement '${action.requirementId}'.`
329
+ : useTmux
330
+ ? `Dispatched tmux worker lane '${dispatched.laneId}' for requirement '${action.requirementId}'.`
331
+ : `Dispatched in-process worker lane '${dispatched.laneId}' for requirement '${action.requirementId}' (native default).`;
309
332
  }
310
333
  else {
311
334
  const wired = useTmux ? deps.dispatchTmuxWorker : deps.startWorkerDelegation;
312
335
  dispatchSkipReason = dispatched?.skipReason ?? (wired ? "declined" : "dependency_unwired");
313
- dispatchNote = `No worker was dispatched (${dispatchSkipReason}); requirement '${action.requirementId}' is recorded but not bound to a lane.`;
336
+ dispatchNote = `${tmuxFallbackReason ? `Tmux route returned ${tmuxFallbackReason}; ` : ""}No worker was dispatched (${dispatchSkipReason}); requirement '${action.requirementId}' is recorded but not bound to a lane.`;
314
337
  }
315
338
  }
316
339
  const current = deps.getGoalState();