@modelprofile.com/flexharness 10.24.0 → 10.24.1

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 (69) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/classes.flexharness.admission.d.ts +17 -0
  3. package/dist_ts/classes.flexharness.admission.js +263 -0
  4. package/dist_ts/classes.flexharness.callbacks.d.ts +38 -0
  5. package/dist_ts/classes.flexharness.callbacks.js +313 -0
  6. package/dist_ts/classes.flexharness.compaction.d.ts +25 -0
  7. package/dist_ts/classes.flexharness.compaction.js +87 -0
  8. package/dist_ts/classes.flexharness.configurations.d.ts +11 -0
  9. package/dist_ts/classes.flexharness.configurations.js +137 -0
  10. package/dist_ts/classes.flexharness.core.d.ts +143 -0
  11. package/dist_ts/classes.flexharness.core.js +1538 -0
  12. package/dist_ts/classes.flexharness.d.ts +2 -437
  13. package/dist_ts/classes.flexharness.deletion.d.ts +31 -0
  14. package/dist_ts/classes.flexharness.deletion.js +396 -0
  15. package/dist_ts/classes.flexharness.imports.d.ts +24 -0
  16. package/dist_ts/classes.flexharness.imports.js +345 -0
  17. package/dist_ts/classes.flexharness.js +119 -9776
  18. package/dist_ts/classes.flexharness.lifecycle.d.ts +47 -0
  19. package/dist_ts/classes.flexharness.lifecycle.js +625 -0
  20. package/dist_ts/classes.flexharness.permissions.d.ts +19 -0
  21. package/dist_ts/classes.flexharness.permissions.js +450 -0
  22. package/dist_ts/classes.flexharness.projects.d.ts +55 -0
  23. package/dist_ts/classes.flexharness.projects.js +575 -0
  24. package/dist_ts/classes.flexharness.prompts.d.ts +44 -0
  25. package/dist_ts/classes.flexharness.prompts.js +659 -0
  26. package/dist_ts/classes.flexharness.providers.d.ts +18 -0
  27. package/dist_ts/classes.flexharness.providers.js +267 -0
  28. package/dist_ts/classes.flexharness.results.d.ts +26 -0
  29. package/dist_ts/classes.flexharness.results.js +89 -0
  30. package/dist_ts/classes.flexharness.reversions.d.ts +52 -0
  31. package/dist_ts/classes.flexharness.reversions.js +1306 -0
  32. package/dist_ts/classes.flexharness.runs.d.ts +63 -0
  33. package/dist_ts/classes.flexharness.runs.js +1058 -0
  34. package/dist_ts/classes.flexharness.sessions.d.ts +20 -0
  35. package/dist_ts/classes.flexharness.sessions.js +381 -0
  36. package/dist_ts/classes.flexharness.slashcommands.d.ts +40 -0
  37. package/dist_ts/classes.flexharness.slashcommands.js +458 -0
  38. package/dist_ts/classes.flexharness.subagents.d.ts +31 -0
  39. package/dist_ts/classes.flexharness.subagents.js +690 -0
  40. package/dist_ts/classes.flexharness.tooldispatch.d.ts +53 -0
  41. package/dist_ts/classes.flexharness.tooldispatch.js +418 -0
  42. package/dist_ts/interfaces.flexharness.d.ts +455 -0
  43. package/dist_ts/interfaces.flexharness.js +2 -0
  44. package/dist_ts/utils.flexharness.d.ts +19 -0
  45. package/dist_ts/utils.flexharness.js +83 -0
  46. package/package.json +3 -3
  47. package/ts/00_commitinfo_data.ts +1 -1
  48. package/ts/classes.flexharness.admission.ts +331 -0
  49. package/ts/classes.flexharness.callbacks.ts +352 -0
  50. package/ts/classes.flexharness.compaction.ts +167 -0
  51. package/ts/classes.flexharness.configurations.ts +167 -0
  52. package/ts/classes.flexharness.core.ts +1830 -0
  53. package/ts/classes.flexharness.deletion.ts +616 -0
  54. package/ts/classes.flexharness.imports.ts +414 -0
  55. package/ts/classes.flexharness.lifecycle.ts +786 -0
  56. package/ts/classes.flexharness.permissions.ts +535 -0
  57. package/ts/classes.flexharness.projects.ts +1006 -0
  58. package/ts/classes.flexharness.prompts.ts +857 -0
  59. package/ts/classes.flexharness.providers.ts +322 -0
  60. package/ts/classes.flexharness.results.ts +98 -0
  61. package/ts/classes.flexharness.reversions.ts +1684 -0
  62. package/ts/classes.flexharness.runs.ts +1204 -0
  63. package/ts/classes.flexharness.sessions.ts +483 -0
  64. package/ts/classes.flexharness.slashcommands.ts +705 -0
  65. package/ts/classes.flexharness.subagents.ts +860 -0
  66. package/ts/classes.flexharness.tooldispatch.ts +475 -0
  67. package/ts/classes.flexharness.ts +147 -12567
  68. package/ts/interfaces.flexharness.ts +517 -0
  69. package/ts/utils.flexharness.ts +121 -0
@@ -0,0 +1,575 @@
1
+ import * as plugins from './plugins.js';
2
+ import { FlexHarnessNotFoundError, FlexHarnessStoreConflictError, FlexHarnessValidationError, } from './errors.js';
3
+ import { FLEX_PROJECT_MANAGEMENT_LIMITS, } from './interfaces.js';
4
+ import { cloneSerializable } from './utils.json.js';
5
+ import { assertFlexProjectManagementRecord, assertFlexProjectManagementSnapshot, createEmptyFlexProjectManagementSnapshot, } from './utils.projectmanagement.js';
6
+ import { maxTransferIdentifierBytes, publicSnapshot } from './utils.transfer.js';
7
+ import { validateCreateProjectTaskInput, validateProjectTaskId, validateUpdateProjectTaskInput, validateUtf8String, } from './utils.validation.js';
8
+ import { queueOperation, requireSessionGeneration, sha256Hex } from './utils.flexharness.js';
9
+ const maxProjectManagementTombstoneConflicts = 8;
10
+ /** The project tasks, goal and scratchpad that a session tree shares, and their agent tools. */
11
+ export class FlexHarnessProjectManagement {
12
+ core;
13
+ projectManagementQueues = new Map();
14
+ constructor(core) {
15
+ this.core = core;
16
+ }
17
+ async getProjectState(scopeId, sessionId) {
18
+ const { state, stored } = await this.resolveProjectManagementSession(scopeId, sessionId, 'read');
19
+ const snapshot = await this.readProjectManagementState(state, stored);
20
+ return this.projectStateResult(snapshot);
21
+ }
22
+ async listProjectTasks(scopeId, sessionId) {
23
+ const { state, stored } = await this.resolveProjectManagementSession(scopeId, sessionId, 'read');
24
+ const snapshot = await this.readProjectManagementState(state, stored);
25
+ return this.projectTasksResult(snapshot, snapshot.tasks);
26
+ }
27
+ async createProjectTask(scopeId, sessionId, input) {
28
+ validateCreateProjectTaskInput(input);
29
+ const { state, stored } = await this.resolveProjectManagementSession(scopeId, sessionId, 'write');
30
+ return this.createProjectTaskInState(state, stored, input, Object.freeze({ actor: 'application' }));
31
+ }
32
+ async updateProjectTask(scopeId, sessionId, input) {
33
+ validateUpdateProjectTaskInput(input);
34
+ const { state, stored } = await this.resolveProjectManagementSession(scopeId, sessionId, 'write');
35
+ return this.updateProjectTaskInState(state, stored, input, Object.freeze({ actor: 'application' }));
36
+ }
37
+ async deleteProjectTask(scopeId, sessionId, taskId) {
38
+ validateProjectTaskId(taskId);
39
+ const { state, stored } = await this.resolveProjectManagementSession(scopeId, sessionId, 'write');
40
+ return this.deleteProjectTaskInState(state, stored, taskId, Object.freeze({ actor: 'application' }));
41
+ }
42
+ async clearProjectTasks(scopeId, sessionId) {
43
+ const { state, stored } = await this.resolveProjectManagementSession(scopeId, sessionId, 'write');
44
+ return this.clearProjectTasksInState(state, stored, Object.freeze({ actor: 'application' }));
45
+ }
46
+ async getProjectGoal(scopeId, sessionId) {
47
+ const { state, stored } = await this.resolveProjectManagementSession(scopeId, sessionId, 'read');
48
+ const snapshot = await this.readProjectManagementState(state, stored);
49
+ return this.projectGoalResult(snapshot);
50
+ }
51
+ async setProjectGoal(scopeId, sessionId, goal) {
52
+ validateUtf8String(goal, 'project goal', FLEX_PROJECT_MANAGEMENT_LIMITS.maxGoalBytes, true);
53
+ const { state, stored } = await this.resolveProjectManagementSession(scopeId, sessionId, 'write');
54
+ return this.setProjectGoalInState(state, stored, goal, Object.freeze({ actor: 'application' }));
55
+ }
56
+ async clearProjectGoal(scopeId, sessionId) {
57
+ const { state, stored } = await this.resolveProjectManagementSession(scopeId, sessionId, 'write');
58
+ return this.clearProjectGoalInState(state, stored, Object.freeze({ actor: 'application' }));
59
+ }
60
+ async getProjectScratchpad(scopeId, sessionId) {
61
+ const { state, stored } = await this.resolveProjectManagementSession(scopeId, sessionId, 'read');
62
+ const snapshot = await this.readProjectManagementState(state, stored);
63
+ return this.projectScratchpadResult(snapshot);
64
+ }
65
+ async setProjectScratchpad(scopeId, sessionId, content) {
66
+ validateUtf8String(content, 'project scratchpad', FLEX_PROJECT_MANAGEMENT_LIMITS.maxScratchpadBytes);
67
+ const { state, stored } = await this.resolveProjectManagementSession(scopeId, sessionId, 'write');
68
+ return this.setProjectScratchpadInState(state, stored, content, Object.freeze({ actor: 'application' }));
69
+ }
70
+ async appendProjectScratchpad(scopeId, sessionId, content) {
71
+ validateUtf8String(content, 'project scratchpad append', FLEX_PROJECT_MANAGEMENT_LIMITS.maxScratchpadBytes);
72
+ const { state, stored } = await this.resolveProjectManagementSession(scopeId, sessionId, 'write');
73
+ return this.appendProjectScratchpadInState(state, stored, content, Object.freeze({ actor: 'application' }));
74
+ }
75
+ async clearProjectScratchpad(scopeId, sessionId) {
76
+ const { state, stored } = await this.resolveProjectManagementSession(scopeId, sessionId, 'write');
77
+ return this.clearProjectScratchpadInState(state, stored, Object.freeze({ actor: 'application' }));
78
+ }
79
+ requireProjectManagementTools() {
80
+ const projectManagement = this.core.builtInTools.projectManagement;
81
+ if (!projectManagement) {
82
+ throw new FlexHarnessValidationError('Project management is not configured for this FlexHarness.');
83
+ }
84
+ return projectManagement;
85
+ }
86
+ projectManagementKey(storageKey, sessionId) {
87
+ return JSON.stringify([storageKey, sessionId]);
88
+ }
89
+ queueProjectManagementOperation(storageKey, sessionId, operation) {
90
+ return queueOperation(this.projectManagementQueues, this.projectManagementKey(storageKey, sessionId), operation);
91
+ }
92
+ async awaitProjectManagementOperations(storageKey, sessionIds) {
93
+ const barriers = [...new Set(sessionIds)]
94
+ .map((sessionId) => this.projectManagementQueues.get(this.projectManagementKey(storageKey, sessionId)))
95
+ .filter((barrier) => barrier !== undefined);
96
+ await Promise.all(barriers);
97
+ }
98
+ async resolveProjectManagementSession(scopeId, sessionId, access) {
99
+ this.requireProjectManagementTools();
100
+ const { state } = await this.core.resolveState(scopeId);
101
+ await state.scopeQueue;
102
+ this.core.assertOpen();
103
+ this.core.assertStateAcceptingWork(state);
104
+ const stored = this.core.requireSession(state, sessionId);
105
+ if (access === 'write')
106
+ this.core.assertSessionWritable(stored);
107
+ return { state, stored };
108
+ }
109
+ assertProjectManagementSession(state, stored) {
110
+ this.core.assertOpen();
111
+ this.core.assertStateAcceptingWork(state);
112
+ if (state.sessions.get(stored.session.sessionId) !== stored
113
+ || state.tombstones.has(stored.session.sessionId)) {
114
+ throw new FlexHarnessNotFoundError('Session', stored.session.sessionId);
115
+ }
116
+ }
117
+ async loadProjectManagementState(state, stored) {
118
+ const store = this.core.stores.projectManagement;
119
+ const generation = requireSessionGeneration(stored.session);
120
+ const sessionContext = this.createProjectManagementSessionContext(state, stored.session);
121
+ const record = await store.load(state.storageKey, stored.session.sessionId, sessionContext);
122
+ if (record === undefined) {
123
+ return createEmptyFlexProjectManagementSnapshot(generation.sessionGenerationId, generation.sessionGenerationSequence);
124
+ }
125
+ assertFlexProjectManagementRecord(record);
126
+ if (record.sessionGenerationId === generation.sessionGenerationId) {
127
+ if (record.sessionGenerationSequence !== generation.sessionGenerationSequence) {
128
+ throw new FlexHarnessStoreConflictError(this.projectManagementKey(state.storageKey, stored.session.sessionId), 0, record.revision);
129
+ }
130
+ if (!('deletedAt' in record))
131
+ return cloneSerializable(record);
132
+ throw new FlexHarnessNotFoundError('Project management state', stored.session.sessionId);
133
+ }
134
+ if ('deletedAt' in record
135
+ && record.sessionGenerationSequence < generation.sessionGenerationSequence) {
136
+ return createEmptyFlexProjectManagementSnapshot(generation.sessionGenerationId, generation.sessionGenerationSequence);
137
+ }
138
+ throw new FlexHarnessStoreConflictError(this.projectManagementKey(state.storageKey, stored.session.sessionId), 0, record.revision);
139
+ }
140
+ readProjectManagementState(state, stored) {
141
+ return this.queueProjectManagementOperation(state.storageKey, stored.session.sessionId, async () => {
142
+ this.assertProjectManagementSession(state, stored);
143
+ const snapshot = await this.loadProjectManagementState(state, stored);
144
+ this.assertProjectManagementSession(state, stored);
145
+ return publicSnapshot(snapshot);
146
+ });
147
+ }
148
+ mutateProjectManagementState(state, stored, writeContext, mutation) {
149
+ return this.queueProjectManagementOperation(state.storageKey, stored.session.sessionId, async () => {
150
+ this.assertProjectManagementSession(state, stored);
151
+ const snapshot = await this.loadProjectManagementState(state, stored);
152
+ this.assertProjectManagementSession(state, stored);
153
+ const expectedRevision = snapshot.revision;
154
+ const result = mutation(snapshot);
155
+ if (result.changed) {
156
+ snapshot.revision = expectedRevision + 1;
157
+ assertFlexProjectManagementSnapshot(snapshot);
158
+ this.assertProjectManagementSession(state, stored);
159
+ await this.core.stores.projectManagement.save(state.storageKey, stored.session.sessionId, cloneSerializable(snapshot), expectedRevision, Object.freeze(cloneSerializable(writeContext)));
160
+ }
161
+ return {
162
+ snapshot: publicSnapshot(snapshot),
163
+ value: result.value === undefined ? result.value : publicSnapshot(result.value),
164
+ };
165
+ });
166
+ }
167
+ projectStateResult(snapshot) {
168
+ return publicSnapshot({ revision: snapshot.revision, state: snapshot });
169
+ }
170
+ createProjectManagementSessionContext(state, session) {
171
+ const source = 'deletedAt' in session
172
+ ? session.subagent
173
+ : this.core.subagentTasks.createSubagentProvenance(state, session);
174
+ const subagent = source === undefined
175
+ ? undefined
176
+ : Object.freeze({ ...cloneSerializable(source) });
177
+ return Object.freeze({
178
+ ...requireSessionGeneration(session),
179
+ ...(subagent === undefined ? {} : { subagent }),
180
+ });
181
+ }
182
+ projectTaskResult(snapshot, task) {
183
+ return publicSnapshot({ revision: snapshot.revision, task, state: snapshot });
184
+ }
185
+ projectTasksResult(snapshot, tasks) {
186
+ return publicSnapshot({ revision: snapshot.revision, tasks, state: snapshot });
187
+ }
188
+ projectGoalResult(snapshot) {
189
+ return publicSnapshot({
190
+ revision: snapshot.revision,
191
+ goal: snapshot.goal ?? null,
192
+ state: snapshot,
193
+ });
194
+ }
195
+ projectScratchpadResult(snapshot) {
196
+ return publicSnapshot({
197
+ revision: snapshot.revision,
198
+ scratchpad: snapshot.scratchpad,
199
+ state: snapshot,
200
+ });
201
+ }
202
+ async createProjectTaskInState(state, stored, input, writeContext) {
203
+ const status = input.status ?? 'pending';
204
+ const priority = input.priority ?? 'medium';
205
+ const result = await this.mutateProjectManagementState(state, stored, writeContext, (snapshot) => {
206
+ const existing = snapshot.tasks.find((task) => task.id === input.id);
207
+ if (existing) {
208
+ if (existing.content === input.content
209
+ && existing.status === status
210
+ && existing.priority === priority)
211
+ return { changed: false, value: existing };
212
+ throw new FlexHarnessValidationError(`Project task "${input.id}" already exists with different creation data.`);
213
+ }
214
+ if (snapshot.tasks.length >= FLEX_PROJECT_MANAGEMENT_LIMITS.maxTasks) {
215
+ throw new FlexHarnessValidationError('Project task count has reached its limit.');
216
+ }
217
+ const timestamp = new Date().toISOString();
218
+ const task = {
219
+ id: input.id,
220
+ content: input.content,
221
+ status,
222
+ priority,
223
+ createdAt: timestamp,
224
+ updatedAt: timestamp,
225
+ };
226
+ snapshot.tasks.push(task);
227
+ return { changed: true, value: task };
228
+ });
229
+ return this.projectTaskResult(result.snapshot, result.value);
230
+ }
231
+ async updateProjectTaskInState(state, stored, input, writeContext) {
232
+ const result = await this.mutateProjectManagementState(state, stored, writeContext, (snapshot) => {
233
+ const task = snapshot.tasks.find((entry) => entry.id === input.id);
234
+ if (!task)
235
+ throw new FlexHarnessNotFoundError('Project task', input.id);
236
+ const changed = (input.content !== undefined && input.content !== task.content)
237
+ || (input.status !== undefined && input.status !== task.status)
238
+ || (input.priority !== undefined && input.priority !== task.priority);
239
+ if (!changed)
240
+ return { changed: false, value: task };
241
+ if (input.content !== undefined)
242
+ task.content = input.content;
243
+ if (input.status !== undefined)
244
+ task.status = input.status;
245
+ if (input.priority !== undefined)
246
+ task.priority = input.priority;
247
+ task.updatedAt = new Date().toISOString();
248
+ return { changed: true, value: task };
249
+ });
250
+ return this.projectTaskResult(result.snapshot, result.value);
251
+ }
252
+ async deleteProjectTaskInState(state, stored, taskId, writeContext) {
253
+ const result = await this.mutateProjectManagementState(state, stored, writeContext, (snapshot) => {
254
+ const index = snapshot.tasks.findIndex((task) => task.id === taskId);
255
+ if (index < 0)
256
+ throw new FlexHarnessNotFoundError('Project task', taskId);
257
+ const [task] = snapshot.tasks.splice(index, 1);
258
+ return { changed: true, value: task };
259
+ });
260
+ return this.projectTaskResult(result.snapshot, result.value);
261
+ }
262
+ async clearProjectTasksInState(state, stored, writeContext) {
263
+ const result = await this.mutateProjectManagementState(state, stored, writeContext, (snapshot) => {
264
+ const tasks = snapshot.tasks;
265
+ if (tasks.length === 0)
266
+ return { changed: false, value: [] };
267
+ snapshot.tasks = [];
268
+ return { changed: true, value: tasks };
269
+ });
270
+ return this.projectTasksResult(result.snapshot, result.value);
271
+ }
272
+ async setProjectGoalInState(state, stored, goal, writeContext) {
273
+ const result = await this.mutateProjectManagementState(state, stored, writeContext, (snapshot) => {
274
+ if (snapshot.goal === goal)
275
+ return { changed: false, value: undefined };
276
+ snapshot.goal = goal;
277
+ return { changed: true, value: undefined };
278
+ });
279
+ return this.projectGoalResult(result.snapshot);
280
+ }
281
+ async clearProjectGoalInState(state, stored, writeContext) {
282
+ const result = await this.mutateProjectManagementState(state, stored, writeContext, (snapshot) => {
283
+ if (snapshot.goal === undefined)
284
+ return { changed: false, value: undefined };
285
+ delete snapshot.goal;
286
+ return { changed: true, value: undefined };
287
+ });
288
+ return this.projectGoalResult(result.snapshot);
289
+ }
290
+ async setProjectScratchpadInState(state, stored, content, writeContext) {
291
+ const result = await this.mutateProjectManagementState(state, stored, writeContext, (snapshot) => {
292
+ if (snapshot.scratchpad === content)
293
+ return { changed: false, value: undefined };
294
+ snapshot.scratchpad = content;
295
+ return { changed: true, value: undefined };
296
+ });
297
+ return this.projectScratchpadResult(result.snapshot);
298
+ }
299
+ async appendProjectScratchpadInState(state, stored, content, writeContext) {
300
+ const result = await this.mutateProjectManagementState(state, stored, writeContext, (snapshot) => {
301
+ if (content.length === 0)
302
+ return { changed: false, value: undefined };
303
+ const appended = `${snapshot.scratchpad}${content}`;
304
+ validateUtf8String(appended, 'project scratchpad', FLEX_PROJECT_MANAGEMENT_LIMITS.maxScratchpadBytes);
305
+ snapshot.scratchpad = appended;
306
+ return { changed: true, value: undefined };
307
+ });
308
+ return this.projectScratchpadResult(result.snapshot);
309
+ }
310
+ async clearProjectScratchpadInState(state, stored, writeContext) {
311
+ const result = await this.mutateProjectManagementState(state, stored, writeContext, (snapshot) => {
312
+ if (snapshot.scratchpad.length === 0)
313
+ return { changed: false, value: undefined };
314
+ snapshot.scratchpad = '';
315
+ return { changed: true, value: undefined };
316
+ });
317
+ return this.projectScratchpadResult(result.snapshot);
318
+ }
319
+ createProjectTaskTool(run) {
320
+ const status = plugins.z.enum(['pending', 'in_progress', 'completed', 'cancelled']);
321
+ const priority = plugins.z.enum(['high', 'medium', 'low']);
322
+ const id = plugins.z.string().min(1).max(FLEX_PROJECT_MANAGEMENT_LIMITS.maxTaskIdBytes);
323
+ const content = plugins.z.string().min(1).max(FLEX_PROJECT_MANAGEMENT_LIMITS.maxTaskContentBytes);
324
+ return plugins.tool({
325
+ description: 'List, create, update, delete, or clear session-local project tasks.',
326
+ strict: false,
327
+ inputSchema: plugins.z.object({
328
+ action: plugins.z.enum(['list', 'create', 'update', 'delete', 'clear']),
329
+ id: id.optional(),
330
+ content: content.optional(),
331
+ status: status.optional(),
332
+ priority: priority.optional(),
333
+ }).strict().superRefine((input, context) => {
334
+ const rejectFields = (...fields) => {
335
+ for (const field of fields) {
336
+ if (input[field] === undefined)
337
+ continue;
338
+ context.addIssue({
339
+ code: 'custom',
340
+ path: [field],
341
+ message: `Task action "${input.action}" does not accept ${field}.`,
342
+ });
343
+ }
344
+ };
345
+ if (input.action === 'list' || input.action === 'clear') {
346
+ rejectFields('id', 'content', 'status', 'priority');
347
+ }
348
+ else if (input.action === 'create') {
349
+ if (input.content === undefined) {
350
+ context.addIssue({
351
+ code: 'custom',
352
+ path: ['content'],
353
+ message: 'Task creation requires content.',
354
+ });
355
+ }
356
+ }
357
+ else if (input.action === 'update') {
358
+ if (input.id === undefined) {
359
+ context.addIssue({
360
+ code: 'custom',
361
+ path: ['id'],
362
+ message: 'Task update requires an id.',
363
+ });
364
+ }
365
+ if (input.content === undefined
366
+ && input.status === undefined
367
+ && input.priority === undefined) {
368
+ context.addIssue({
369
+ code: 'custom',
370
+ message: 'Task update requires content, status, or priority.',
371
+ });
372
+ }
373
+ }
374
+ else {
375
+ if (input.id === undefined) {
376
+ context.addIssue({
377
+ code: 'custom',
378
+ path: ['id'],
379
+ message: 'Task deletion requires an id.',
380
+ });
381
+ }
382
+ rejectFields('content', 'status', 'priority');
383
+ }
384
+ }),
385
+ execute: (input, options) => this.executeProjectTaskTool(run, input, options?.toolCallId),
386
+ });
387
+ }
388
+ createProjectGoalTool(run) {
389
+ return plugins.tool({
390
+ description: 'Get, set, or clear the session-local project goal.',
391
+ strict: false,
392
+ inputSchema: plugins.z.object({
393
+ action: plugins.z.enum(['get', 'set', 'clear']),
394
+ goal: plugins.z.string()
395
+ .min(1)
396
+ .max(FLEX_PROJECT_MANAGEMENT_LIMITS.maxGoalBytes)
397
+ .optional(),
398
+ }).strict().superRefine((input, context) => {
399
+ if (input.action === 'set' && input.goal === undefined) {
400
+ context.addIssue({
401
+ code: 'custom',
402
+ path: ['goal'],
403
+ message: 'Goal set requires a goal.',
404
+ });
405
+ }
406
+ else if (input.action !== 'set' && input.goal !== undefined) {
407
+ context.addIssue({
408
+ code: 'custom',
409
+ path: ['goal'],
410
+ message: `Goal action "${input.action}" does not accept goal.`,
411
+ });
412
+ }
413
+ }),
414
+ execute: (input, options) => this.executeProjectGoalTool(run, input, options?.toolCallId),
415
+ });
416
+ }
417
+ createProjectScratchpadTool(run) {
418
+ const content = plugins.z.string().max(FLEX_PROJECT_MANAGEMENT_LIMITS.maxScratchpadBytes);
419
+ return plugins.tool({
420
+ description: 'Get, set, append to, or clear the session-local project scratchpad.',
421
+ strict: false,
422
+ inputSchema: plugins.z.object({
423
+ action: plugins.z.enum(['get', 'set', 'append', 'clear']),
424
+ content: content.optional(),
425
+ }).strict().superRefine((input, context) => {
426
+ if ((input.action === 'set' || input.action === 'append')
427
+ && input.content === undefined) {
428
+ context.addIssue({
429
+ code: 'custom',
430
+ path: ['content'],
431
+ message: `Scratchpad ${input.action} requires content.`,
432
+ });
433
+ }
434
+ else if ((input.action === 'get' || input.action === 'clear')
435
+ && input.content !== undefined) {
436
+ context.addIssue({
437
+ code: 'custom',
438
+ path: ['content'],
439
+ message: `Scratchpad action "${input.action}" does not accept content.`,
440
+ });
441
+ }
442
+ }),
443
+ execute: (input, options) => this.executeProjectScratchpadTool(run, input, options?.toolCallId),
444
+ });
445
+ }
446
+ projectManagementAgentWriteContext(run, toolCallId) {
447
+ return Object.freeze({
448
+ actor: 'agent',
449
+ runId: run.runId,
450
+ ...(run.stored.session.agent === undefined ? {} : { agent: run.stored.session.agent }),
451
+ ...(toolCallId === undefined ? {} : { toolCallId }),
452
+ });
453
+ }
454
+ async executeProjectTaskTool(run, input, toolCallId) {
455
+ this.assertProjectManagementSession(run.state, run.stored);
456
+ if (input.action === 'list') {
457
+ const snapshot = await this.readProjectManagementState(run.state, run.stored);
458
+ return this.projectTasksResult(snapshot, snapshot.tasks);
459
+ }
460
+ const writeContext = this.projectManagementAgentWriteContext(run, toolCallId);
461
+ if (input.action === 'create') {
462
+ const id = input.id ?? (() => {
463
+ validateUtf8String(toolCallId, 'task toolCallId', maxTransferIdentifierBytes, true);
464
+ return this.createProjectTaskId(run.state.storageKey, run.sessionId, run.runId, toolCallId);
465
+ })();
466
+ const createInput = {
467
+ id,
468
+ content: input.content,
469
+ ...(input.status === undefined ? {} : { status: input.status }),
470
+ ...(input.priority === undefined ? {} : { priority: input.priority }),
471
+ };
472
+ validateCreateProjectTaskInput(createInput);
473
+ return this.createProjectTaskInState(run.state, run.stored, createInput, writeContext);
474
+ }
475
+ if (input.action === 'update') {
476
+ const updateInput = {
477
+ id: input.id,
478
+ ...(input.content === undefined ? {} : { content: input.content }),
479
+ ...(input.status === undefined ? {} : { status: input.status }),
480
+ ...(input.priority === undefined ? {} : { priority: input.priority }),
481
+ };
482
+ validateUpdateProjectTaskInput(updateInput);
483
+ return this.updateProjectTaskInState(run.state, run.stored, updateInput, writeContext);
484
+ }
485
+ if (input.action === 'delete') {
486
+ validateProjectTaskId(input.id);
487
+ return this.deleteProjectTaskInState(run.state, run.stored, input.id, writeContext);
488
+ }
489
+ return this.clearProjectTasksInState(run.state, run.stored, writeContext);
490
+ }
491
+ async executeProjectGoalTool(run, input, toolCallId) {
492
+ this.assertProjectManagementSession(run.state, run.stored);
493
+ if (input.action === 'get') {
494
+ return this.projectGoalResult(await this.readProjectManagementState(run.state, run.stored));
495
+ }
496
+ const writeContext = this.projectManagementAgentWriteContext(run, toolCallId);
497
+ if (input.action === 'set') {
498
+ validateUtf8String(input.goal, 'project goal', FLEX_PROJECT_MANAGEMENT_LIMITS.maxGoalBytes, true);
499
+ return this.setProjectGoalInState(run.state, run.stored, input.goal, writeContext);
500
+ }
501
+ return this.clearProjectGoalInState(run.state, run.stored, writeContext);
502
+ }
503
+ async executeProjectScratchpadTool(run, input, toolCallId) {
504
+ this.assertProjectManagementSession(run.state, run.stored);
505
+ if (input.action === 'get') {
506
+ return this.projectScratchpadResult(await this.readProjectManagementState(run.state, run.stored));
507
+ }
508
+ const writeContext = this.projectManagementAgentWriteContext(run, toolCallId);
509
+ if (input.action === 'set') {
510
+ validateUtf8String(input.content, 'project scratchpad', FLEX_PROJECT_MANAGEMENT_LIMITS.maxScratchpadBytes);
511
+ return this.setProjectScratchpadInState(run.state, run.stored, input.content, writeContext);
512
+ }
513
+ if (input.action === 'append') {
514
+ validateUtf8String(input.content, 'project scratchpad append', FLEX_PROJECT_MANAGEMENT_LIMITS.maxScratchpadBytes);
515
+ return this.appendProjectScratchpadInState(run.state, run.stored, input.content, writeContext);
516
+ }
517
+ return this.clearProjectScratchpadInState(run.state, run.stored, writeContext);
518
+ }
519
+ createProjectTaskId(storageKey, sessionId, runId, toolCallId) {
520
+ return `task_${sha256Hex(JSON.stringify([
521
+ 'flexharness-project-task-v1',
522
+ storageKey,
523
+ sessionId,
524
+ runId,
525
+ toolCallId,
526
+ ]))}`;
527
+ }
528
+ async tombstoneProjectManagementSession(state, sessionTombstone) {
529
+ const storageKey = state.storageKey;
530
+ const store = this.core.stores.projectManagement;
531
+ const sessionId = sessionTombstone.sessionId;
532
+ const generation = requireSessionGeneration(sessionTombstone);
533
+ const sessionContext = this.createProjectManagementSessionContext(state, sessionTombstone);
534
+ let lastConflict;
535
+ for (let attempt = 0; attempt <= maxProjectManagementTombstoneConflicts; attempt++) {
536
+ const current = await store.load(storageKey, sessionId, sessionContext);
537
+ if (current !== undefined) {
538
+ assertFlexProjectManagementRecord(current);
539
+ if (current.sessionGenerationId === generation.sessionGenerationId) {
540
+ if (current.sessionGenerationSequence !== generation.sessionGenerationSequence) {
541
+ throw new FlexHarnessStoreConflictError(this.projectManagementKey(storageKey, sessionId), 0, current.revision);
542
+ }
543
+ if ('deletedAt' in current)
544
+ return;
545
+ }
546
+ else if (!('deletedAt' in current)
547
+ || current.sessionGenerationSequence >= generation.sessionGenerationSequence) {
548
+ throw new FlexHarnessStoreConflictError(this.projectManagementKey(storageKey, sessionId), 0, current.revision);
549
+ }
550
+ }
551
+ if (attempt === maxProjectManagementTombstoneConflicts)
552
+ break;
553
+ const expectedRevision = current === undefined
554
+ || current.sessionGenerationId !== generation.sessionGenerationId
555
+ ? 0
556
+ : current.revision;
557
+ const tombstone = {
558
+ schemaVersion: 1,
559
+ revision: expectedRevision + 1,
560
+ ...generation,
561
+ deletedAt: sessionTombstone.deletedAt,
562
+ };
563
+ try {
564
+ await store.tombstoneSession(storageKey, sessionId, tombstone, expectedRevision, sessionContext);
565
+ }
566
+ catch (error) {
567
+ if (!(error instanceof FlexHarnessStoreConflictError))
568
+ throw error;
569
+ lastConflict = error;
570
+ }
571
+ }
572
+ throw lastConflict ?? new FlexHarnessValidationError(`Project management tombstone for session "${sessionId}" could not be durably confirmed.`);
573
+ }
574
+ }
575
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5mbGV4aGFybmVzcy5wcm9qZWN0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuZmxleGhhcm5lc3MucHJvamVjdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUNMLHdCQUF3QixFQUN4Qiw2QkFBNkIsRUFDN0IsMEJBQTBCLEdBQzNCLE1BQU0sYUFBYSxDQUFDO0FBQ3JCLE9BQU8sRUFDTCw4QkFBOEIsR0FlL0IsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNwRCxPQUFPLEVBQ0wsaUNBQWlDLEVBQ2pDLG1DQUFtQyxFQUNuQyx3Q0FBd0MsR0FDekMsTUFBTSw4QkFBOEIsQ0FBQztBQUV0QyxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDakYsT0FBTyxFQUNMLDhCQUE4QixFQUM5QixxQkFBcUIsRUFDckIsOEJBQThCLEVBQzlCLGtCQUFrQixHQUNuQixNQUFNLHVCQUF1QixDQUFDO0FBUy9CLE9BQU8sRUFBRSxjQUFjLEVBQUUsd0JBQXdCLEVBQUUsU0FBUyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFHN0YsTUFBTSxzQ0FBc0MsR0FBRyxDQUFDLENBQUM7QUFFakQsZ0dBQWdHO0FBQ2hHLE1BQU0sT0FBTyw0QkFBNEI7SUFHVjtJQUZiLHVCQUF1QixHQUFHLElBQUksR0FBRyxFQUF5QixDQUFDO0lBRTNFLFlBQTZCLElBQTZCO1FBQTdCLFNBQUksR0FBSixJQUFJLENBQXlCO0lBQUcsQ0FBQztJQUV2RCxLQUFLLENBQUMsZUFBZSxDQUMxQixPQUFlLEVBQ2YsU0FBaUI7UUFFakIsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxPQUFP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