@robota-sdk/agent-sdk 3.0.0-beta.61 → 3.0.0-beta.62

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.
@@ -47,6 +47,7 @@ __export(index_exports, {
47
47
  DEFAULT_AUTO_COMPACT_THRESHOLD: () => DEFAULT_AUTO_COMPACT_THRESHOLD,
48
48
  DEFAULT_BACKGROUND_TASK_LOG_PAGE_SIZE: () => import_agent_runtime4.DEFAULT_BACKGROUND_TASK_LOG_PAGE_SIZE,
49
49
  DEFAULT_STATUS_LINE_COMMAND_SETTINGS: () => DEFAULT_STATUS_LINE_COMMAND_SETTINGS,
50
+ EXECUTION_ORIGIN_METADATA_KEYS: () => EXECUTION_ORIGIN_METADATA_KEYS,
50
51
  EXIT_COMMAND_DESCRIPTION: () => EXIT_COMMAND_DESCRIPTION,
51
52
  EditCheckpointStore: () => EditCheckpointStore,
52
53
  HELP_COMMAND_DESCRIPTION: () => HELP_COMMAND_DESCRIPTION,
@@ -82,11 +83,14 @@ __export(index_exports, {
82
83
  STATUSLINE_COMMAND_ARGUMENT_HINT: () => STATUSLINE_COMMAND_ARGUMENT_HINT,
83
84
  STATUSLINE_COMMAND_DESCRIPTION: () => STATUSLINE_COMMAND_DESCRIPTION,
84
85
  SkillCommandSource: () => SkillCommandSource,
85
- SubagentManager: () => import_agent_runtime7.SubagentManager,
86
+ SubagentManager: () => import_agent_runtime8.SubagentManager,
86
87
  SystemCommandExecutor: () => SystemCommandExecutor,
88
+ USER_LOCAL_MEMORY_CATEGORIES: () => USER_LOCAL_MEMORY_CATEGORIES,
89
+ USER_LOCAL_STORAGE_CATEGORIES: () => USER_LOCAL_STORAGE_CATEGORIES,
90
+ USER_LOCAL_STORAGE_CATEGORY_DEFINITIONS: () => USER_LOCAL_STORAGE_CATEGORY_DEFINITIONS,
87
91
  VALIDATE_SESSION_COMMAND_DESCRIPTION: () => VALIDATE_SESSION_COMMAND_DESCRIPTION,
88
92
  VALID_PERMISSION_MODES: () => VALID_PERMISSION_MODES,
89
- WorktreeSubagentRunner: () => import_agent_runtime8.WorktreeSubagentRunner,
93
+ WorktreeSubagentRunner: () => import_agent_runtime9.WorktreeSubagentRunner,
90
94
  addCommandContextReference: () => addCommandContextReference,
91
95
  appendPrefixedLogLines: () => import_agent_runtime4.appendPrefixedLogLines,
92
96
  assembleSubagentPrompt: () => assembleSubagentPrompt,
@@ -108,7 +112,9 @@ __export(index_exports, {
108
112
  closeCommandBackgroundTask: () => closeCommandBackgroundTask,
109
113
  compactCommandContext: () => compactCommandContext,
110
114
  createAgentTool: () => createAgentTool,
115
+ createBackgroundGroupExecutionEntryId: () => createBackgroundGroupExecutionEntryId,
111
116
  createBackgroundProcessTool: () => createBackgroundProcessTool,
117
+ createBackgroundTaskExecutionEntryId: () => createBackgroundTaskExecutionEntryId,
112
118
  createBackgroundTaskLogPage: () => import_agent_runtime4.createBackgroundTaskLogPage,
113
119
  createBuiltinCommandModule: () => createBuiltinCommandModule,
114
120
  createCommandExecutionTool: () => createCommandExecutionTool,
@@ -117,7 +123,13 @@ __export(index_exports, {
117
123
  createCommandProjectMemoryStore: () => createCommandProjectMemoryStore,
118
124
  createContextReferenceItem: () => createContextReferenceItem,
119
125
  createDefaultTools: () => createDefaultTools,
126
+ createExecutionOriginMetadata: () => createExecutionOriginMetadata,
127
+ createExecutionWorkspaceSnapshot: () => createExecutionWorkspaceSnapshot,
128
+ createExecutionWorkspaceTaskSpawner: () => createExecutionWorkspaceTaskSpawner,
120
129
  createLimitedOutputCapture: () => import_agent_runtime4.createLimitedOutputCapture,
130
+ createLineDetailPage: () => createLineDetailPage,
131
+ createMainThreadDetailPage: () => createMainThreadDetailPage,
132
+ createMainThreadExecutionEntryId: () => createMainThreadExecutionEntryId,
121
133
  createModelCommandToolProjection: () => createModelCommandToolProjection,
122
134
  createPluginRegistryReloadRequestedEffect: () => createPluginRegistryReloadRequestedEffect,
123
135
  createPluginTuiRequestedEffect: () => createPluginTuiRequestedEffect,
@@ -133,8 +145,10 @@ __export(index_exports, {
133
145
  createSubagentLogger: () => createSubagentLogger,
134
146
  createSubagentSession: () => createSubagentSession,
135
147
  createSystemCommands: () => createSystemCommands,
136
- createWorktreeSubagentRunner: () => import_agent_runtime8.createWorktreeSubagentRunner,
148
+ createWorktreeSubagentRunner: () => import_agent_runtime9.createWorktreeSubagentRunner,
137
149
  deleteProviderProfile: () => deleteProviderProfile,
150
+ deleteUserLocalMemoryItem: () => deleteUserLocalMemoryItem,
151
+ disableUserLocalMemoryItem: () => disableUserLocalMemoryItem,
138
152
  discoverTaskFiles: () => discoverTaskFiles,
139
153
  evaluateReversibleToolSafety: () => evaluateReversibleToolSafety,
140
154
  executeSkill: () => executeSkill,
@@ -164,6 +178,8 @@ __export(index_exports, {
164
178
  hasSensitiveCommandMemoryContent: () => hasSensitiveCommandMemoryContent,
165
179
  hasUsableSecretReference: () => hasUsableSecretReference,
166
180
  inspectCommandEditCheckpoint: () => inspectCommandEditCheckpoint,
181
+ inspectUserLocalMemoryItem: () => inspectUserLocalMemoryItem,
182
+ inspectUserLocalStorage: () => inspectUserLocalStorage,
167
183
  isCommandMemoryType: () => isCommandMemoryType,
168
184
  isEnvReference: () => isEnvReference,
169
185
  isMemoryType: () => isMemoryType,
@@ -177,10 +193,12 @@ __export(index_exports, {
177
193
  listCommandSessionAllowedTools: () => listCommandSessionAllowedTools,
178
194
  listCommandUsedMemoryReferences: () => listCommandUsedMemoryReferences,
179
195
  listResumableSessionSummaries: () => listResumableSessionSummaries,
196
+ listUserLocalMemoryItems: () => listUserLocalMemoryItems,
180
197
  loadTaskContext: () => loadTaskContext,
181
198
  mergeProviderPatch: () => mergeProviderPatch,
182
199
  normalizeModelCommandName: () => normalizeModelCommandName,
183
200
  parseCommandBackgroundLogCursor: () => parseCommandBackgroundLogCursor,
201
+ parseExecutionWorkspaceEntryId: () => parseExecutionWorkspaceEntryId,
184
202
  parseFrontmatter: () => parseFrontmatter,
185
203
  parseLanguageArgument: () => parseLanguageArgument,
186
204
  parsePermissionModeArgument: () => parsePermissionModeArgument,
@@ -200,6 +218,7 @@ __export(index_exports, {
200
218
  readCommandPermissionsState: () => readCommandPermissionsState,
201
219
  readCommandSessionInfo: () => readCommandSessionInfo,
202
220
  readCurrentGitBranch: () => readCurrentGitBranch,
221
+ readEnabledUserLocalMemoryItem: () => readEnabledUserLocalMemoryItem,
203
222
  recordCommandMemoryEvent: () => recordCommandMemoryEvent,
204
223
  removeCommandContextReference: () => removeCommandContextReference,
205
224
  removeContextReference: () => removeContextReference,
@@ -215,6 +234,7 @@ __export(index_exports, {
215
234
  resolveProviderSetupSelection: () => resolveProviderSetupSelection,
216
235
  resolveSessionIdByIdOrName: () => resolveSessionIdByIdOrName,
217
236
  resolveSubagentLogDir: () => resolveSubagentLogDir,
237
+ resolveUserLocalStorageRoot: () => resolveUserLocalStorageRoot,
218
238
  restoreCommandEditCheckpoint: () => restoreCommandEditCheckpoint,
219
239
  retrieveAgentToolDeps: () => retrieveAgentToolDeps,
220
240
  rollbackCommandEditCheckpoint: () => rollbackCommandEditCheckpoint,
@@ -223,6 +243,7 @@ __export(index_exports, {
223
243
  selectRelevantTasks: () => selectRelevantTasks,
224
244
  setCommandAutoCompactThreshold: () => setCommandAutoCompactThreshold,
225
245
  setCurrentProvider: () => setCurrentProvider,
246
+ setUserLocalMemoryItem: () => setUserLocalMemoryItem,
226
247
  storeAgentToolDeps: () => storeAgentToolDeps,
227
248
  submitProviderSetupValue: () => submitProviderSetupValue,
228
249
  substituteVariables: () => substituteVariables,
@@ -785,17 +806,17 @@ async function compactCommandContext(context, instructions) {
785
806
  function listCommandContextReferences(context) {
786
807
  return context.listContextReferences?.() ?? [];
787
808
  }
788
- async function addCommandContextReference(context, path) {
809
+ async function addCommandContextReference(context, path3) {
789
810
  if (!context.addContextReference) {
790
811
  return {
791
812
  evicted: [],
792
813
  diagnostics: ["Command host does not support context reference additions."]
793
814
  };
794
815
  }
795
- return context.addContextReference(path);
816
+ return context.addContextReference(path3);
796
817
  }
797
- function removeCommandContextReference(context, path) {
798
- return context.removeContextReference?.(path) ?? {};
818
+ function removeCommandContextReference(context, path3) {
819
+ return context.removeContextReference?.(path3) ?? {};
799
820
  }
800
821
  function clearCommandContextReferences(context) {
801
822
  return context.clearContextReferences?.() ?? { removed: [] };
@@ -1694,17 +1715,17 @@ var ProjectMemoryStore = class {
1694
1715
  return (0, import_path.join)(memoryRoot2(this.cwd), TOPICS_DIRNAME);
1695
1716
  }
1696
1717
  loadStartupMemory() {
1697
- const path = this.getIndexPath();
1698
- if (!(0, import_fs.existsSync)(path)) {
1699
- return { content: "", path, lineCount: 0, truncated: false };
1718
+ const path3 = this.getIndexPath();
1719
+ if (!(0, import_fs.existsSync)(path3)) {
1720
+ return { content: "", path: path3, lineCount: 0, truncated: false };
1700
1721
  }
1701
- const raw = (0, import_fs.readFileSync)(path, "utf8");
1722
+ const raw = (0, import_fs.readFileSync)(path3, "utf8");
1702
1723
  const byBytes = truncateToUtf8Bytes(raw, MEMORY_INDEX_MAX_BYTES);
1703
1724
  const byteTruncated = Buffer.byteLength(raw, "utf8") > MEMORY_INDEX_MAX_BYTES;
1704
1725
  const byLines = limitLines(byBytes, MEMORY_INDEX_MAX_LINES);
1705
1726
  return {
1706
1727
  content: byLines.content,
1707
- path,
1728
+ path: path3,
1708
1729
  lineCount: byLines.content.length === 0 ? 0 : byLines.content.split(/\r?\n/).length,
1709
1730
  truncated: byteTruncated || byLines.truncated
1710
1731
  };
@@ -1723,9 +1744,9 @@ var ProjectMemoryStore = class {
1723
1744
  }
1724
1745
  readTopic(topic) {
1725
1746
  const normalized = sanitizeTopic(topic);
1726
- const path = (0, import_path.join)(this.getTopicsPath(), `${normalized}${TOPIC_EXTENSION}`);
1727
- if (!(0, import_fs.existsSync)(path)) return "";
1728
- return (0, import_fs.readFileSync)(path, "utf8").trimEnd();
1747
+ const path3 = (0, import_path.join)(this.getTopicsPath(), `${normalized}${TOPIC_EXTENSION}`);
1748
+ if (!(0, import_fs.existsSync)(path3)) return "";
1749
+ return (0, import_fs.readFileSync)(path3, "utf8").trimEnd();
1729
1750
  }
1730
1751
  append(input) {
1731
1752
  const topic = sanitizeTopic(input.topic);
@@ -2199,7 +2220,7 @@ function getBuiltInAgent(name) {
2199
2220
  // src/tools/agent-tool.ts
2200
2221
  var import_zod2 = require("zod");
2201
2222
  var import_agent_tools2 = require("@robota-sdk/agent-tools");
2202
- var import_agent_runtime = require("@robota-sdk/agent-runtime");
2223
+ var import_agent_runtime6 = require("@robota-sdk/agent-runtime");
2203
2224
 
2204
2225
  // src/subagents/in-process-subagent-runner.ts
2205
2226
  function resolveAgentDefinition(agentType, customRegistry) {
@@ -2283,6 +2304,506 @@ function createInProcessSubagentRunner(deps) {
2283
2304
  };
2284
2305
  }
2285
2306
 
2307
+ // src/background-tasks/index.ts
2308
+ var import_agent_runtime3 = require("@robota-sdk/agent-runtime");
2309
+
2310
+ // src/background-tasks/background-job-orchestrator.ts
2311
+ var import_agent_runtime = require("@robota-sdk/agent-runtime");
2312
+ var DEFAULT_SUMMARY_LENGTH = 1e3;
2313
+ var BackgroundJobOrchestrator = class {
2314
+ manager;
2315
+ now;
2316
+ idFactory;
2317
+ unsubscribeManager;
2318
+ listeners = /* @__PURE__ */ new Set();
2319
+ groups = /* @__PURE__ */ new Map();
2320
+ sequence = 0;
2321
+ constructor(options) {
2322
+ this.manager = options.manager;
2323
+ this.now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
2324
+ this.idFactory = options.idFactory ?? (() => this.nextGroupId());
2325
+ this.sequence = options.initialGroups?.length ?? 0;
2326
+ for (const group of options.initialGroups ?? []) this.restoreGroup(group);
2327
+ this.unsubscribeManager = this.manager.subscribe((event) => this.handleTaskEvent(event));
2328
+ }
2329
+ createGroup(request) {
2330
+ const now = this.now();
2331
+ const state = {
2332
+ id: this.idFactory(request),
2333
+ parentSessionId: request.parentSessionId,
2334
+ waitPolicy: request.waitPolicy,
2335
+ taskIds: [...request.taskIds],
2336
+ status: "running",
2337
+ createdAt: now,
2338
+ updatedAt: now,
2339
+ results: [],
2340
+ ...request.label ? { label: request.label } : {}
2341
+ };
2342
+ const record = this.createRecord(state);
2343
+ this.groups.set(state.id, record);
2344
+ this.captureExistingTerminalTasks(record);
2345
+ this.emit({ type: "background_job_group_created", group: cloneGroup(record.state) });
2346
+ this.evaluateCompletion(record);
2347
+ return cloneGroup(record.state);
2348
+ }
2349
+ listGroups() {
2350
+ return [...this.groups.values()].map((record) => cloneGroup(record.state));
2351
+ }
2352
+ getGroup(groupId) {
2353
+ const record = this.groups.get(groupId);
2354
+ return record ? cloneGroup(record.state) : void 0;
2355
+ }
2356
+ waitGroup(groupId) {
2357
+ const record = this.groups.get(groupId);
2358
+ if (!record) return Promise.reject(new Error(`Unknown background job group: ${groupId}`));
2359
+ return record.completion;
2360
+ }
2361
+ subscribe(listener) {
2362
+ this.listeners.add(listener);
2363
+ return () => {
2364
+ this.listeners.delete(listener);
2365
+ };
2366
+ }
2367
+ dispose() {
2368
+ this.unsubscribeManager();
2369
+ this.listeners.clear();
2370
+ }
2371
+ nextGroupId() {
2372
+ this.sequence += 1;
2373
+ return `group_${this.sequence}`;
2374
+ }
2375
+ restoreGroup(group) {
2376
+ const record = this.createRecord(cloneGroup(group));
2377
+ this.groups.set(group.id, record);
2378
+ if (group.status === "completed") record.resolve(cloneGroup(group));
2379
+ }
2380
+ createRecord(state) {
2381
+ let resolveGroup = () => {
2382
+ };
2383
+ const completion = new Promise((resolve6) => {
2384
+ resolveGroup = resolve6;
2385
+ });
2386
+ return { state, completion, resolve: resolveGroup };
2387
+ }
2388
+ captureExistingTerminalTasks(record) {
2389
+ for (const taskId of record.state.taskIds) {
2390
+ const task = this.manager.get(taskId);
2391
+ if (task && (0, import_agent_runtime.isTerminalBackgroundTaskStatus)(task.status)) this.captureTask(record, task);
2392
+ }
2393
+ }
2394
+ handleTaskEvent(event) {
2395
+ const task = getTerminalTask(event);
2396
+ if (!task) return;
2397
+ for (const record of this.groups.values()) {
2398
+ if (!record.state.taskIds.includes(task.id)) continue;
2399
+ if (!this.captureTask(record, task)) continue;
2400
+ if (record.state.status === "running") this.evaluateCompletion(record);
2401
+ else this.emit({ type: "background_job_group_updated", group: cloneGroup(record.state) });
2402
+ }
2403
+ }
2404
+ captureTask(record, task) {
2405
+ if (record.state.results.some((result) => result.taskId === task.id)) return false;
2406
+ record.state.results = [...record.state.results, createResultEnvelope(task)];
2407
+ record.state.updatedAt = this.now();
2408
+ return true;
2409
+ }
2410
+ evaluateCompletion(record) {
2411
+ if (record.state.status === "completed") return;
2412
+ if (!shouldComplete(record.state)) {
2413
+ this.emit({ type: "background_job_group_updated", group: cloneGroup(record.state) });
2414
+ return;
2415
+ }
2416
+ const now = this.now();
2417
+ record.state.status = "completed";
2418
+ record.state.completedAt = now;
2419
+ record.state.updatedAt = now;
2420
+ const completed = cloneGroup(record.state);
2421
+ record.resolve(completed);
2422
+ this.emit({ type: "background_job_group_completed", group: completed });
2423
+ }
2424
+ emit(event) {
2425
+ for (const listener of this.listeners) listener(event);
2426
+ }
2427
+ };
2428
+ function getTerminalTask(event) {
2429
+ if (event.type === "background_task_completed" || event.type === "background_task_failed" || event.type === "background_task_cancelled") {
2430
+ return event.task;
2431
+ }
2432
+ return void 0;
2433
+ }
2434
+ function shouldComplete(group) {
2435
+ if (group.waitPolicy === "manual") return false;
2436
+ if (group.waitPolicy === "wait_any") return group.results.length > 0;
2437
+ return group.taskIds.every((taskId) => group.results.some((result) => result.taskId === taskId));
2438
+ }
2439
+ function createResultEnvelope(task) {
2440
+ return {
2441
+ taskId: task.id,
2442
+ label: task.label,
2443
+ status: task.status,
2444
+ ...task.result?.output ? { summary: summarizeOutput(task.result.output) } : {},
2445
+ ...task.transcriptPath || task.logPath ? { outputRef: task.transcriptPath ?? task.logPath } : {},
2446
+ ...task.error ? { error: { ...task.error } } : {},
2447
+ ...task.startedAt ? { startedAt: task.startedAt } : {},
2448
+ ...task.completedAt ? { completedAt: task.completedAt } : {}
2449
+ };
2450
+ }
2451
+ function summarizeOutput(output) {
2452
+ const trimmed = output.trim();
2453
+ if (trimmed.length <= DEFAULT_SUMMARY_LENGTH) return trimmed;
2454
+ return `${trimmed.slice(0, DEFAULT_SUMMARY_LENGTH)}...`;
2455
+ }
2456
+ function summarizeBackgroundJobGroup(group) {
2457
+ const completed = countResults(group, "completed");
2458
+ const failed = countResults(group, "failed");
2459
+ const cancelled = countResults(group, "cancelled");
2460
+ return {
2461
+ groupId: group.id,
2462
+ status: group.status,
2463
+ total: group.taskIds.length,
2464
+ completed,
2465
+ failed,
2466
+ cancelled,
2467
+ pending: Math.max(group.taskIds.length - group.results.length, 0),
2468
+ lines: group.results.map((result) => formatResultLine(result))
2469
+ };
2470
+ }
2471
+ function countResults(group, status) {
2472
+ return group.results.filter((result) => result.status === status).length;
2473
+ }
2474
+ function formatResultLine(result) {
2475
+ const detail = normalizeResultDetail(result);
2476
+ const output = result.outputRef && result.summary ? ` (output: ${result.outputRef})` : "";
2477
+ return `[${result.status}] ${result.label} ${result.taskId}: ${detail}${output}`;
2478
+ }
2479
+ function normalizeResultDetail(result) {
2480
+ const detail = result.error?.message ?? result.summary ?? "";
2481
+ const normalized = detail.replace(/\s+/g, " ").trim();
2482
+ return normalized.length > 0 ? normalized : "(no summary)";
2483
+ }
2484
+ function cloneGroup(group) {
2485
+ return {
2486
+ ...group,
2487
+ taskIds: [...group.taskIds],
2488
+ results: group.results.map((result) => ({
2489
+ ...result,
2490
+ ...result.error ? { error: { ...result.error } } : {}
2491
+ }))
2492
+ };
2493
+ }
2494
+
2495
+ // src/background-tasks/execution-workspace-projection.ts
2496
+ var import_agent_runtime2 = require("@robota-sdk/agent-runtime");
2497
+
2498
+ // src/background-tasks/execution-workspace-types.ts
2499
+ var MAIN_THREAD_ENTRY_PREFIX = "main";
2500
+ var BACKGROUND_TASK_ENTRY_PREFIX = "task";
2501
+ var BACKGROUND_GROUP_ENTRY_PREFIX = "group";
2502
+ var ENTRY_ID_SEPARATOR = ":";
2503
+ var EXECUTION_ORIGIN_METADATA_KEYS = {
2504
+ kind: "executionOriginKind",
2505
+ sessionId: "executionOriginSessionId",
2506
+ turnId: "executionOriginTurnId",
2507
+ commandName: "executionOriginCommandName",
2508
+ toolCallId: "executionOriginToolCallId",
2509
+ skillId: "executionOriginSkillId",
2510
+ label: "executionOriginLabel"
2511
+ };
2512
+ function createMainThreadExecutionEntryId(sessionId) {
2513
+ return [MAIN_THREAD_ENTRY_PREFIX, sessionId].join(ENTRY_ID_SEPARATOR);
2514
+ }
2515
+ function createBackgroundTaskExecutionEntryId(taskId) {
2516
+ return [BACKGROUND_TASK_ENTRY_PREFIX, taskId].join(ENTRY_ID_SEPARATOR);
2517
+ }
2518
+ function createBackgroundGroupExecutionEntryId(groupId) {
2519
+ return [BACKGROUND_GROUP_ENTRY_PREFIX, groupId].join(ENTRY_ID_SEPARATOR);
2520
+ }
2521
+ function parseExecutionWorkspaceEntryId(entryId) {
2522
+ const [prefix, sourceId] = entryId.split(ENTRY_ID_SEPARATOR, 2);
2523
+ if (!sourceId) return void 0;
2524
+ if (prefix === MAIN_THREAD_ENTRY_PREFIX) return { kind: "main_thread", sourceId };
2525
+ if (prefix === BACKGROUND_TASK_ENTRY_PREFIX) return { kind: "background_task", sourceId };
2526
+ if (prefix === BACKGROUND_GROUP_ENTRY_PREFIX) return { kind: "background_group", sourceId };
2527
+ return void 0;
2528
+ }
2529
+ function createExecutionOriginMetadata(origin) {
2530
+ return {
2531
+ [EXECUTION_ORIGIN_METADATA_KEYS.kind]: origin.kind,
2532
+ [EXECUTION_ORIGIN_METADATA_KEYS.sessionId]: origin.sessionId,
2533
+ ...origin.turnId ? { [EXECUTION_ORIGIN_METADATA_KEYS.turnId]: origin.turnId } : {},
2534
+ ...origin.commandName ? { [EXECUTION_ORIGIN_METADATA_KEYS.commandName]: origin.commandName } : {},
2535
+ ...origin.toolCallId ? { [EXECUTION_ORIGIN_METADATA_KEYS.toolCallId]: origin.toolCallId } : {},
2536
+ ...origin.skillId ? { [EXECUTION_ORIGIN_METADATA_KEYS.skillId]: origin.skillId } : {},
2537
+ ...origin.label ? { [EXECUTION_ORIGIN_METADATA_KEYS.label]: origin.label } : {}
2538
+ };
2539
+ }
2540
+
2541
+ // src/background-tasks/execution-workspace-projection.ts
2542
+ var PREVIEW_MAX_LENGTH = 120;
2543
+ var SUCCESS_EXIT_CODE = 0;
2544
+ function createExecutionWorkspaceSnapshot(input) {
2545
+ const taskGroupIds = createTaskGroupIdMap(input.groups);
2546
+ const entries = [
2547
+ createMainThreadEntry(input.mainThread),
2548
+ ...sortGroups(input.groups).map((group) => createBackgroundGroupEntry(group)),
2549
+ ...sortTasks(input.tasks).map(
2550
+ (task) => createBackgroundTaskEntry(task, taskGroupIds.get(task.id))
2551
+ )
2552
+ ].filter((entry) => matchesExecutionWorkspaceFilter(entry, input.filter));
2553
+ return {
2554
+ sessionId: input.sessionId,
2555
+ selectedEntryId: input.selectedEntryId ?? entries.find((entry) => entry.kind === "main_thread")?.id ?? createMainThreadExecutionEntryId(input.sessionId),
2556
+ updatedAt: entries[0]?.updatedAt ?? input.mainThread.updatedAt,
2557
+ entries
2558
+ };
2559
+ }
2560
+ function createMainThreadEntry(input) {
2561
+ return {
2562
+ id: createMainThreadExecutionEntryId(input.sessionId),
2563
+ sourceId: input.sessionId,
2564
+ kind: "main_thread",
2565
+ origin: { kind: "user_prompt", sessionId: input.sessionId },
2566
+ status: input.isExecuting ? "active" : "idle",
2567
+ title: "Main thread",
2568
+ subtitle: input.hasPendingPrompt ? "prompt queued" : `${input.historyLength} history entries`,
2569
+ preview: trimPreview(input.preview),
2570
+ unread: false,
2571
+ attention: "none",
2572
+ visibility: "default",
2573
+ updatedAt: input.updatedAt,
2574
+ controls: ["select"]
2575
+ };
2576
+ }
2577
+ function createBackgroundTaskEntry(state, groupId) {
2578
+ return {
2579
+ id: createBackgroundTaskExecutionEntryId(state.id),
2580
+ sourceId: state.id,
2581
+ kind: "background_task",
2582
+ parentId: state.parentTaskId ? createBackgroundTaskExecutionEntryId(state.parentTaskId) : createMainThreadExecutionEntryId(state.parentSessionId),
2583
+ ...groupId ? { groupId: createBackgroundGroupExecutionEntryId(groupId) } : {},
2584
+ origin: readExecutionOrigin(state.metadata, {
2585
+ kind: "system",
2586
+ sessionId: state.parentSessionId
2587
+ }),
2588
+ taskKind: state.kind,
2589
+ status: state.status,
2590
+ title: state.label,
2591
+ subtitle: createTaskSubtitle(state),
2592
+ preview: createTaskPreview(state),
2593
+ currentAction: state.currentAction,
2594
+ unread: state.unread,
2595
+ attention: createTaskAttention(state),
2596
+ visibility: createTaskVisibility(state),
2597
+ updatedAt: state.lastActivityAt ?? state.updatedAt,
2598
+ controls: createTaskControls(state)
2599
+ };
2600
+ }
2601
+ function createBackgroundGroupEntry(group) {
2602
+ const preview = trimPreview(
2603
+ group.results.map((result) => result.summary ?? result.error?.message).join(" ")
2604
+ );
2605
+ return {
2606
+ id: createBackgroundGroupExecutionEntryId(group.id),
2607
+ sourceId: group.id,
2608
+ kind: "background_group",
2609
+ parentId: createMainThreadExecutionEntryId(group.parentSessionId),
2610
+ origin: { kind: "system", sessionId: group.parentSessionId, label: group.label },
2611
+ status: group.status,
2612
+ title: group.label ?? group.id,
2613
+ subtitle: `${group.results.length}/${group.taskIds.length} tasks`,
2614
+ preview,
2615
+ unread: false,
2616
+ attention: createGroupAttention(group),
2617
+ visibility: group.status === "completed" ? "collapsed" : "default",
2618
+ updatedAt: group.updatedAt,
2619
+ controls: group.status === "running" ? ["select", "wait"] : ["select"]
2620
+ };
2621
+ }
2622
+ function readExecutionOrigin(metadata, fallback) {
2623
+ const kind = toExecutionOriginKind(metadata?.[EXECUTION_ORIGIN_METADATA_KEYS.kind]);
2624
+ const sessionId = toStringValue(metadata?.[EXECUTION_ORIGIN_METADATA_KEYS.sessionId]);
2625
+ return {
2626
+ kind: kind ?? fallback.kind,
2627
+ sessionId: sessionId ?? fallback.sessionId,
2628
+ turnId: toStringValue(metadata?.[EXECUTION_ORIGIN_METADATA_KEYS.turnId]) ?? fallback.turnId,
2629
+ commandName: toStringValue(metadata?.[EXECUTION_ORIGIN_METADATA_KEYS.commandName]) ?? fallback.commandName,
2630
+ toolCallId: toStringValue(metadata?.[EXECUTION_ORIGIN_METADATA_KEYS.toolCallId]) ?? fallback.toolCallId,
2631
+ skillId: toStringValue(metadata?.[EXECUTION_ORIGIN_METADATA_KEYS.skillId]) ?? fallback.skillId,
2632
+ label: toStringValue(metadata?.[EXECUTION_ORIGIN_METADATA_KEYS.label]) ?? fallback.label
2633
+ };
2634
+ }
2635
+ function createTaskGroupIdMap(groups) {
2636
+ return new Map(groups.flatMap((group) => group.taskIds.map((taskId) => [taskId, group.id])));
2637
+ }
2638
+ function createTaskControls(state) {
2639
+ const controls = ["select"];
2640
+ if ((0, import_agent_runtime2.isTerminalBackgroundTaskStatus)(state.status)) controls.push("close");
2641
+ else controls.push("cancel");
2642
+ if (state.logPath || state.transcriptPath) controls.push("read_log");
2643
+ return controls;
2644
+ }
2645
+ function createTaskSubtitle(state) {
2646
+ if (state.kind === "agent") return state.agentType ?? state.cwd;
2647
+ return state.cwd;
2648
+ }
2649
+ function createTaskPreview(state) {
2650
+ if (state.status === "failed") return trimPreview(state.error?.message);
2651
+ if (state.status === "completed") return trimPreview(state.result?.output);
2652
+ return trimPreview(state.promptPreview ?? state.commandPreview);
2653
+ }
2654
+ function createTaskAttention(state) {
2655
+ if (state.status === "failed") return "failed";
2656
+ if (state.status === "waiting_permission") return "permission";
2657
+ if (state.unread) return "unread";
2658
+ if (state.status === "completed") return "completed";
2659
+ return "none";
2660
+ }
2661
+ function createTaskVisibility(state) {
2662
+ if (state.status === "completed" && !state.unread && !state.error && (state.result?.exitCode ?? SUCCESS_EXIT_CODE) === SUCCESS_EXIT_CODE && !state.result?.signalCode && !state.worktreePath && !state.branchName) {
2663
+ return "collapsed";
2664
+ }
2665
+ return "default";
2666
+ }
2667
+ function createGroupAttention(group) {
2668
+ if (group.results.some((result) => result.status === "failed")) return "failed";
2669
+ if (group.status === "completed") return "completed";
2670
+ return "none";
2671
+ }
2672
+ function matchesExecutionWorkspaceFilter(entry, filter) {
2673
+ if (!filter) return true;
2674
+ if (filter.includeMainThread === false && entry.kind === "main_thread") return false;
2675
+ if (filter.kinds && !filter.kinds.includes(entry.kind)) return false;
2676
+ if (filter.visibility && !filter.visibility.includes(entry.visibility)) return false;
2677
+ return true;
2678
+ }
2679
+ function sortTasks(tasks) {
2680
+ return [...tasks].sort(
2681
+ (left, right) => (right.lastActivityAt ?? right.updatedAt).localeCompare(left.lastActivityAt ?? left.updatedAt)
2682
+ );
2683
+ }
2684
+ function sortGroups(groups) {
2685
+ return [...groups].sort((left, right) => right.updatedAt.localeCompare(left.updatedAt));
2686
+ }
2687
+ function trimPreview(value) {
2688
+ const normalized = value?.trim().replace(/\s+/g, " ");
2689
+ if (!normalized) return void 0;
2690
+ return normalized.length > PREVIEW_MAX_LENGTH ? `${normalized.slice(0, PREVIEW_MAX_LENGTH)}...` : normalized;
2691
+ }
2692
+ function toStringValue(value) {
2693
+ return typeof value === "string" ? value : void 0;
2694
+ }
2695
+ function toExecutionOriginKind(value) {
2696
+ if (value === "user_prompt" || value === "slash_command" || value === "model_command" || value === "tool_call" || value === "skill" || value === "transport" || value === "system") {
2697
+ return value;
2698
+ }
2699
+ return void 0;
2700
+ }
2701
+
2702
+ // src/background-tasks/execution-workspace-detail.ts
2703
+ var EXECUTION_DETAIL_PAGE_SIZE = 80;
2704
+ function createMainThreadDetailPage(input) {
2705
+ const offset = normalizeOffset(input.cursor?.offset);
2706
+ const page = input.history.slice(offset, offset + EXECUTION_DETAIL_PAGE_SIZE);
2707
+ const records = page.map((entry) => ({
2708
+ id: entry.id,
2709
+ kind: entry.category === "chat" ? "message" : "progress",
2710
+ text: formatHistoryEntry(entry),
2711
+ timestamp: entry.timestamp.toISOString(),
2712
+ sourceId: entry.type
2713
+ }));
2714
+ return {
2715
+ entryId: input.entryId,
2716
+ ...input.cursor ? { cursor: input.cursor } : {},
2717
+ ...offset + page.length < input.history.length ? { nextCursor: { offset: offset + page.length } } : {},
2718
+ records
2719
+ };
2720
+ }
2721
+ function createLineDetailPage(input) {
2722
+ const offset = input.cursor?.offset ?? 0;
2723
+ const records = input.lines.map((line, index) => ({
2724
+ id: `${input.entryId}:${offset}:${index}`,
2725
+ kind: input.kind ?? "process_output",
2726
+ text: line
2727
+ }));
2728
+ return {
2729
+ entryId: input.entryId,
2730
+ ...input.cursor ? { cursor: input.cursor } : {},
2731
+ ...input.nextCursor ? { nextCursor: input.nextCursor } : {},
2732
+ records
2733
+ };
2734
+ }
2735
+ function normalizeOffset(offset) {
2736
+ return typeof offset === "number" && Number.isFinite(offset) && offset > 0 ? Math.floor(offset) : 0;
2737
+ }
2738
+ function formatHistoryEntry(entry) {
2739
+ if (typeof entry.data === "string") return entry.data;
2740
+ return entry.type;
2741
+ }
2742
+
2743
+ // src/background-tasks/execution-workspace-spawner.ts
2744
+ function createExecutionWorkspaceTaskSpawner(options) {
2745
+ return {
2746
+ spawnAgent: (request) => options.manager.spawn(createAgentRequest(options, request)),
2747
+ spawnProcess: (request) => options.manager.spawn(createProcessRequest(options, request)),
2748
+ createGroup: (request) => options.groupOrchestrator.createGroup({
2749
+ parentSessionId: options.sessionId,
2750
+ waitPolicy: request.waitPolicy,
2751
+ taskIds: [...request.taskIds],
2752
+ label: request.label
2753
+ })
2754
+ };
2755
+ }
2756
+ function createAgentRequest(options, request) {
2757
+ return {
2758
+ kind: "agent",
2759
+ label: request.label,
2760
+ mode: request.mode ?? "background",
2761
+ parentSessionId: options.sessionId,
2762
+ parentTaskId: request.parentTaskId,
2763
+ depth: request.depth ?? 1,
2764
+ cwd: request.cwd ?? options.cwd,
2765
+ agentType: request.agentType,
2766
+ prompt: request.prompt,
2767
+ model: request.model,
2768
+ isolation: request.isolation,
2769
+ allowedTools: request.allowedTools ? [...request.allowedTools] : void 0,
2770
+ disallowedTools: request.disallowedTools ? [...request.disallowedTools] : void 0,
2771
+ permissionPolicy: request.permissionPolicy ?? "inherit-allowlist",
2772
+ timeoutMs: request.timeoutMs,
2773
+ idleTimeoutMs: request.idleTimeoutMs,
2774
+ maxRuntimeMs: request.maxRuntimeMs,
2775
+ outputLimitBytes: request.outputLimitBytes,
2776
+ maxTextDeltas: request.maxTextDeltas,
2777
+ repetitionWindow: request.repetitionWindow,
2778
+ repetitionThreshold: request.repetitionThreshold,
2779
+ metadata: createExecutionOriginMetadata(options.origin)
2780
+ };
2781
+ }
2782
+ function createProcessRequest(options, request) {
2783
+ return {
2784
+ kind: "process",
2785
+ label: request.label ?? request.command,
2786
+ mode: request.mode ?? "background",
2787
+ parentSessionId: options.sessionId,
2788
+ parentTaskId: request.parentTaskId,
2789
+ depth: request.depth ?? 0,
2790
+ cwd: request.cwd ?? options.cwd,
2791
+ command: request.command,
2792
+ shell: request.shell,
2793
+ env: request.env,
2794
+ stdin: request.stdin,
2795
+ timeoutMs: request.timeoutMs,
2796
+ idleTimeoutMs: request.idleTimeoutMs,
2797
+ maxRuntimeMs: request.maxRuntimeMs,
2798
+ outputLimitBytes: request.outputLimitBytes,
2799
+ metadata: createExecutionOriginMetadata(options.origin)
2800
+ };
2801
+ }
2802
+
2803
+ // src/background-tasks/index.ts
2804
+ var import_agent_runtime4 = require("@robota-sdk/agent-runtime");
2805
+ var import_agent_runtime5 = require("@robota-sdk/agent-runtime");
2806
+
2286
2807
  // src/tools/agent-tool-batch.ts
2287
2808
  function stringifyAgentBatchResult(input) {
2288
2809
  const successfulJobs = input.jobs.filter((job) => job.success);
@@ -2463,7 +2984,7 @@ function resolveAgentDefinition2(agentType, customRegistry) {
2463
2984
  return void 0;
2464
2985
  }
2465
2986
  function createSubagentManager(deps) {
2466
- return deps.subagentManager ?? new import_agent_runtime.SubagentManager({
2987
+ return deps.subagentManager ?? new import_agent_runtime6.SubagentManager({
2467
2988
  runner: createInProcessSubagentRunner(deps)
2468
2989
  });
2469
2990
  }
@@ -2477,7 +2998,12 @@ function createSpawnRequest(args, agentType, agentDef, deps, label = agentDef.na
2477
2998
  cwd: deps.cwd ?? process.cwd(),
2478
2999
  prompt: args.prompt,
2479
3000
  model: args.model,
2480
- isolation: args.isolation
3001
+ isolation: args.isolation,
3002
+ metadata: createExecutionOriginMetadata({
3003
+ kind: "tool_call",
3004
+ sessionId: deps.parentSessionId ?? "unknown-session",
3005
+ label
3006
+ })
2481
3007
  };
2482
3008
  }
2483
3009
  function stringifyUnknownAgentType(agentType) {
@@ -2510,284 +3036,92 @@ function stringifyAgentSuccess(result) {
2510
3036
  failedJobCount: 0,
2511
3037
  output: result.output,
2512
3038
  agentId: result.jobId,
2513
- agentIds: [result.jobId],
2514
- provenance: {
2515
- source: "agent-tool-single",
2516
- requestedJobCount: 1,
2517
- startedJobCount: 1,
2518
- failedJobCount: 0
2519
- },
2520
- metadata: result.metadata,
2521
- ...typeof worktreePath === "string" ? { worktreePath } : {},
2522
- ...typeof branchName === "string" ? { branchName } : {},
2523
- ...typeof worktreeStatus === "string" ? { worktreeStatus } : {},
2524
- ...typeof worktreeNextAction === "string" ? { worktreeNextAction } : {}
2525
- });
2526
- }
2527
- function stringifyAgentError(message, agentId) {
2528
- const startedJobCount = agentId === void 0 ? 0 : 1;
2529
- return JSON.stringify({
2530
- success: false,
2531
- mode: "single",
2532
- requestedJobCount: 1,
2533
- startedJobCount,
2534
- failedJobCount: 1,
2535
- output: "",
2536
- error: `Sub-agent error: ${message}`,
2537
- agentId,
2538
- ...agentId !== void 0 ? { agentIds: [agentId] } : {},
2539
- provenance: {
2540
- source: "agent-tool-single",
2541
- requestedJobCount: 1,
2542
- startedJobCount,
2543
- failedJobCount: 1
2544
- }
2545
- });
2546
- }
2547
- async function runManagedAgent(args, deps, manager) {
2548
- if (typeof args.prompt !== "string" || args.prompt.length === 0) {
2549
- return stringifyAgentError("prompt is required when jobs is omitted");
2550
- }
2551
- const singleArgs = { ...args, prompt: args.prompt };
2552
- const agentType = args.subagent_type ?? "general-purpose";
2553
- const agentDef = resolveAgentDefinition2(agentType, deps.customAgentRegistry);
2554
- if (!agentDef) {
2555
- return stringifyUnknownAgentType(agentType);
2556
- }
2557
- let agentId;
2558
- try {
2559
- const state = await manager.spawn(createSpawnRequest(singleArgs, agentType, agentDef, deps));
2560
- agentId = state.id;
2561
- const response = await manager.wait(state.id);
2562
- return stringifyAgentSuccess(response);
2563
- } catch (err) {
2564
- const message = err instanceof Error ? err.message : String(err);
2565
- return stringifyAgentError(message, agentId);
2566
- }
2567
- }
2568
- function createAgentTool(deps) {
2569
- const manager = createSubagentManager(deps);
2570
- return (0, import_agent_tools2.createZodFunctionTool)(
2571
- "Agent",
2572
- AGENT_TOOL_DESCRIPTION,
2573
- asZodSchema2(AgentSchema),
2574
- async (params) => {
2575
- const args = params;
2576
- if (Array.isArray(args.jobs) && args.jobs.length > 0) {
2577
- return runManagedAgentBatch({
2578
- jobs: args.jobs,
2579
- deps,
2580
- manager,
2581
- resolveAgentDefinition: resolveAgentDefinition2,
2582
- createSpawnRequest
2583
- });
2584
- }
2585
- return runManagedAgent(
2586
- {
2587
- prompt: args.prompt,
2588
- ...args.subagent_type !== void 0 ? { subagent_type: args.subagent_type } : {},
2589
- ...args.model !== void 0 ? { model: args.model } : {},
2590
- ...args.isolation !== void 0 ? { isolation: args.isolation } : {}
2591
- },
2592
- deps,
2593
- manager
2594
- );
2595
- }
2596
- );
2597
- }
2598
-
2599
- // src/background-tasks/index.ts
2600
- var import_agent_runtime3 = require("@robota-sdk/agent-runtime");
2601
-
2602
- // src/background-tasks/background-job-orchestrator.ts
2603
- var import_agent_runtime2 = require("@robota-sdk/agent-runtime");
2604
- var DEFAULT_SUMMARY_LENGTH = 1e3;
2605
- var BackgroundJobOrchestrator = class {
2606
- manager;
2607
- now;
2608
- idFactory;
2609
- unsubscribeManager;
2610
- listeners = /* @__PURE__ */ new Set();
2611
- groups = /* @__PURE__ */ new Map();
2612
- sequence = 0;
2613
- constructor(options) {
2614
- this.manager = options.manager;
2615
- this.now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
2616
- this.idFactory = options.idFactory ?? (() => this.nextGroupId());
2617
- this.sequence = options.initialGroups?.length ?? 0;
2618
- for (const group of options.initialGroups ?? []) this.restoreGroup(group);
2619
- this.unsubscribeManager = this.manager.subscribe((event) => this.handleTaskEvent(event));
2620
- }
2621
- createGroup(request) {
2622
- const now = this.now();
2623
- const state = {
2624
- id: this.idFactory(request),
2625
- parentSessionId: request.parentSessionId,
2626
- waitPolicy: request.waitPolicy,
2627
- taskIds: [...request.taskIds],
2628
- status: "running",
2629
- createdAt: now,
2630
- updatedAt: now,
2631
- results: [],
2632
- ...request.label ? { label: request.label } : {}
2633
- };
2634
- const record = this.createRecord(state);
2635
- this.groups.set(state.id, record);
2636
- this.captureExistingTerminalTasks(record);
2637
- this.emit({ type: "background_job_group_created", group: cloneGroup(record.state) });
2638
- this.evaluateCompletion(record);
2639
- return cloneGroup(record.state);
2640
- }
2641
- listGroups() {
2642
- return [...this.groups.values()].map((record) => cloneGroup(record.state));
2643
- }
2644
- getGroup(groupId) {
2645
- const record = this.groups.get(groupId);
2646
- return record ? cloneGroup(record.state) : void 0;
2647
- }
2648
- waitGroup(groupId) {
2649
- const record = this.groups.get(groupId);
2650
- if (!record) return Promise.reject(new Error(`Unknown background job group: ${groupId}`));
2651
- return record.completion;
2652
- }
2653
- subscribe(listener) {
2654
- this.listeners.add(listener);
2655
- return () => {
2656
- this.listeners.delete(listener);
2657
- };
2658
- }
2659
- dispose() {
2660
- this.unsubscribeManager();
2661
- this.listeners.clear();
2662
- }
2663
- nextGroupId() {
2664
- this.sequence += 1;
2665
- return `group_${this.sequence}`;
2666
- }
2667
- restoreGroup(group) {
2668
- const record = this.createRecord(cloneGroup(group));
2669
- this.groups.set(group.id, record);
2670
- if (group.status === "completed") record.resolve(cloneGroup(group));
2671
- }
2672
- createRecord(state) {
2673
- let resolveGroup = () => {
2674
- };
2675
- const completion = new Promise((resolve6) => {
2676
- resolveGroup = resolve6;
2677
- });
2678
- return { state, completion, resolve: resolveGroup };
2679
- }
2680
- captureExistingTerminalTasks(record) {
2681
- for (const taskId of record.state.taskIds) {
2682
- const task = this.manager.get(taskId);
2683
- if (task && (0, import_agent_runtime2.isTerminalBackgroundTaskStatus)(task.status)) this.captureTask(record, task);
2684
- }
2685
- }
2686
- handleTaskEvent(event) {
2687
- const task = getTerminalTask(event);
2688
- if (!task) return;
2689
- for (const record of this.groups.values()) {
2690
- if (!record.state.taskIds.includes(task.id)) continue;
2691
- if (!this.captureTask(record, task)) continue;
2692
- if (record.state.status === "running") this.evaluateCompletion(record);
2693
- else this.emit({ type: "background_job_group_updated", group: cloneGroup(record.state) });
2694
- }
2695
- }
2696
- captureTask(record, task) {
2697
- if (record.state.results.some((result) => result.taskId === task.id)) return false;
2698
- record.state.results = [...record.state.results, createResultEnvelope(task)];
2699
- record.state.updatedAt = this.now();
2700
- return true;
2701
- }
2702
- evaluateCompletion(record) {
2703
- if (record.state.status === "completed") return;
2704
- if (!shouldComplete(record.state)) {
2705
- this.emit({ type: "background_job_group_updated", group: cloneGroup(record.state) });
2706
- return;
2707
- }
2708
- const now = this.now();
2709
- record.state.status = "completed";
2710
- record.state.completedAt = now;
2711
- record.state.updatedAt = now;
2712
- const completed = cloneGroup(record.state);
2713
- record.resolve(completed);
2714
- this.emit({ type: "background_job_group_completed", group: completed });
2715
- }
2716
- emit(event) {
2717
- for (const listener of this.listeners) listener(event);
2718
- }
2719
- };
2720
- function getTerminalTask(event) {
2721
- if (event.type === "background_task_completed" || event.type === "background_task_failed" || event.type === "background_task_cancelled") {
2722
- return event.task;
2723
- }
2724
- return void 0;
2725
- }
2726
- function shouldComplete(group) {
2727
- if (group.waitPolicy === "manual") return false;
2728
- if (group.waitPolicy === "wait_any") return group.results.length > 0;
2729
- return group.taskIds.every((taskId) => group.results.some((result) => result.taskId === taskId));
2730
- }
2731
- function createResultEnvelope(task) {
2732
- return {
2733
- taskId: task.id,
2734
- label: task.label,
2735
- status: task.status,
2736
- ...task.result?.output ? { summary: summarizeOutput(task.result.output) } : {},
2737
- ...task.transcriptPath || task.logPath ? { outputRef: task.transcriptPath ?? task.logPath } : {},
2738
- ...task.error ? { error: { ...task.error } } : {},
2739
- ...task.startedAt ? { startedAt: task.startedAt } : {},
2740
- ...task.completedAt ? { completedAt: task.completedAt } : {}
2741
- };
2742
- }
2743
- function summarizeOutput(output) {
2744
- const trimmed = output.trim();
2745
- if (trimmed.length <= DEFAULT_SUMMARY_LENGTH) return trimmed;
2746
- return `${trimmed.slice(0, DEFAULT_SUMMARY_LENGTH)}...`;
2747
- }
2748
- function summarizeBackgroundJobGroup(group) {
2749
- const completed = countResults(group, "completed");
2750
- const failed = countResults(group, "failed");
2751
- const cancelled = countResults(group, "cancelled");
2752
- return {
2753
- groupId: group.id,
2754
- status: group.status,
2755
- total: group.taskIds.length,
2756
- completed,
2757
- failed,
2758
- cancelled,
2759
- pending: Math.max(group.taskIds.length - group.results.length, 0),
2760
- lines: group.results.map((result) => formatResultLine(result))
2761
- };
2762
- }
2763
- function countResults(group, status) {
2764
- return group.results.filter((result) => result.status === status).length;
3039
+ agentIds: [result.jobId],
3040
+ provenance: {
3041
+ source: "agent-tool-single",
3042
+ requestedJobCount: 1,
3043
+ startedJobCount: 1,
3044
+ failedJobCount: 0
3045
+ },
3046
+ metadata: result.metadata,
3047
+ ...typeof worktreePath === "string" ? { worktreePath } : {},
3048
+ ...typeof branchName === "string" ? { branchName } : {},
3049
+ ...typeof worktreeStatus === "string" ? { worktreeStatus } : {},
3050
+ ...typeof worktreeNextAction === "string" ? { worktreeNextAction } : {}
3051
+ });
2765
3052
  }
2766
- function formatResultLine(result) {
2767
- const detail = normalizeResultDetail(result);
2768
- const output = result.outputRef && result.summary ? ` (output: ${result.outputRef})` : "";
2769
- return `[${result.status}] ${result.label} ${result.taskId}: ${detail}${output}`;
3053
+ function stringifyAgentError(message, agentId) {
3054
+ const startedJobCount = agentId === void 0 ? 0 : 1;
3055
+ return JSON.stringify({
3056
+ success: false,
3057
+ mode: "single",
3058
+ requestedJobCount: 1,
3059
+ startedJobCount,
3060
+ failedJobCount: 1,
3061
+ output: "",
3062
+ error: `Sub-agent error: ${message}`,
3063
+ agentId,
3064
+ ...agentId !== void 0 ? { agentIds: [agentId] } : {},
3065
+ provenance: {
3066
+ source: "agent-tool-single",
3067
+ requestedJobCount: 1,
3068
+ startedJobCount,
3069
+ failedJobCount: 1
3070
+ }
3071
+ });
2770
3072
  }
2771
- function normalizeResultDetail(result) {
2772
- const detail = result.error?.message ?? result.summary ?? "";
2773
- const normalized = detail.replace(/\s+/g, " ").trim();
2774
- return normalized.length > 0 ? normalized : "(no summary)";
3073
+ async function runManagedAgent(args, deps, manager) {
3074
+ if (typeof args.prompt !== "string" || args.prompt.length === 0) {
3075
+ return stringifyAgentError("prompt is required when jobs is omitted");
3076
+ }
3077
+ const singleArgs = { ...args, prompt: args.prompt };
3078
+ const agentType = args.subagent_type ?? "general-purpose";
3079
+ const agentDef = resolveAgentDefinition2(agentType, deps.customAgentRegistry);
3080
+ if (!agentDef) {
3081
+ return stringifyUnknownAgentType(agentType);
3082
+ }
3083
+ let agentId;
3084
+ try {
3085
+ const state = await manager.spawn(createSpawnRequest(singleArgs, agentType, agentDef, deps));
3086
+ agentId = state.id;
3087
+ const response = await manager.wait(state.id);
3088
+ return stringifyAgentSuccess(response);
3089
+ } catch (err) {
3090
+ const message = err instanceof Error ? err.message : String(err);
3091
+ return stringifyAgentError(message, agentId);
3092
+ }
2775
3093
  }
2776
- function cloneGroup(group) {
2777
- return {
2778
- ...group,
2779
- taskIds: [...group.taskIds],
2780
- results: group.results.map((result) => ({
2781
- ...result,
2782
- ...result.error ? { error: { ...result.error } } : {}
2783
- }))
2784
- };
3094
+ function createAgentTool(deps) {
3095
+ const manager = createSubagentManager(deps);
3096
+ return (0, import_agent_tools2.createZodFunctionTool)(
3097
+ "Agent",
3098
+ AGENT_TOOL_DESCRIPTION,
3099
+ asZodSchema2(AgentSchema),
3100
+ async (params) => {
3101
+ const args = params;
3102
+ if (Array.isArray(args.jobs) && args.jobs.length > 0) {
3103
+ return runManagedAgentBatch({
3104
+ jobs: args.jobs,
3105
+ deps,
3106
+ manager,
3107
+ resolveAgentDefinition: resolveAgentDefinition2,
3108
+ createSpawnRequest
3109
+ });
3110
+ }
3111
+ return runManagedAgent(
3112
+ {
3113
+ prompt: args.prompt,
3114
+ ...args.subagent_type !== void 0 ? { subagent_type: args.subagent_type } : {},
3115
+ ...args.model !== void 0 ? { model: args.model } : {},
3116
+ ...args.isolation !== void 0 ? { isolation: args.isolation } : {}
3117
+ },
3118
+ deps,
3119
+ manager
3120
+ );
3121
+ }
3122
+ );
2785
3123
  }
2786
3124
 
2787
- // src/background-tasks/index.ts
2788
- var import_agent_runtime4 = require("@robota-sdk/agent-runtime");
2789
- var import_agent_runtime5 = require("@robota-sdk/agent-runtime");
2790
-
2791
3125
  // src/background-tasks/session-background-store.ts
2792
3126
  var sessionBackgroundTaskManagers = /* @__PURE__ */ new WeakMap();
2793
3127
  function storeSessionBackgroundTaskManager(key, manager) {
@@ -3845,10 +4179,10 @@ async function loadConfig(cwd) {
3845
4179
  rawEntries.push({ raw, path: filePath });
3846
4180
  }
3847
4181
  }
3848
- const parsedLayers = rawEntries.map(({ raw, path }) => {
4182
+ const parsedLayers = rawEntries.map(({ raw, path: path3 }) => {
3849
4183
  const result = SettingsSchema.safeParse(raw);
3850
4184
  if (!result.success) {
3851
- throw new Error(`Invalid settings in ${path}: ${result.error.message}`);
4185
+ throw new Error(`Invalid settings in ${path3}: ${result.error.message}`);
3852
4186
  }
3853
4187
  return resolveEnvRefs(result.data);
3854
4188
  });
@@ -4212,7 +4546,8 @@ async function startBackgroundProcess(args, deps) {
4212
4546
  command: args.command,
4213
4547
  stdin: args.stdin,
4214
4548
  timeoutMs: args.timeout ?? DEFAULT_PROCESS_TIMEOUT_MS,
4215
- outputLimitBytes: args.outputLimitBytes
4549
+ outputLimitBytes: args.outputLimitBytes,
4550
+ metadata: deps.metadata
4216
4551
  });
4217
4552
  return stringifyStarted(state.id, state.status, args.command);
4218
4553
  } catch (error) {
@@ -4469,7 +4804,7 @@ function createBlockedResult(report) {
4469
4804
  }
4470
4805
 
4471
4806
  // src/assembly/create-session.ts
4472
- var import_agent_runtime6 = require("@robota-sdk/agent-runtime");
4807
+ var import_agent_runtime7 = require("@robota-sdk/agent-runtime");
4473
4808
 
4474
4809
  // src/agents/agent-definition-loader.ts
4475
4810
  var import_node_fs4 = require("fs");
@@ -4722,7 +5057,7 @@ function createSession(options) {
4722
5057
  customAgentRegistry: (name) => agentLoader.getAgent(name),
4723
5058
  agentDefinitions
4724
5059
  };
4725
- const subagentManager = new import_agent_runtime6.SubagentManager({
5060
+ const subagentManager = new import_agent_runtime7.SubagentManager({
4726
5061
  runner: (options.subagentRunnerFactory ?? createInProcessSubagentRunner)(agentToolDeps),
4727
5062
  backgroundTaskRunners: options.backgroundTaskRunners
4728
5063
  });
@@ -4730,7 +5065,7 @@ function createSession(options) {
4730
5065
  backgroundTaskManager = subagentManager.getBackgroundTaskManager();
4731
5066
  agentToolDeps.backgroundTaskManager = backgroundTaskManager;
4732
5067
  } else {
4733
- backgroundTaskManager = new import_agent_runtime6.BackgroundTaskManager({
5068
+ backgroundTaskManager = new import_agent_runtime7.BackgroundTaskManager({
4734
5069
  runners: options.backgroundTaskRunners ?? []
4735
5070
  });
4736
5071
  }
@@ -4755,7 +5090,12 @@ function createSession(options) {
4755
5090
  backgroundProcessToolDeps = {
4756
5091
  backgroundTaskManager,
4757
5092
  cwd,
4758
- parentSessionId: sessionId
5093
+ parentSessionId: sessionId,
5094
+ metadata: createExecutionOriginMetadata({
5095
+ kind: "tool_call",
5096
+ sessionId,
5097
+ label: "BackgroundProcess"
5098
+ })
4759
5099
  };
4760
5100
  tools.push(createBackgroundProcessTool(backgroundProcessToolDeps));
4761
5101
  }
@@ -5031,7 +5371,7 @@ function formatTaskContext(tasks) {
5031
5371
  }
5032
5372
  function loadTaskContext(cwd, options = {}) {
5033
5373
  const currentBranch = options.currentBranch ?? readCurrentGitBranch(cwd);
5034
- const tasks = discoverTaskFiles(cwd).map((path) => parseTaskFile(path, cwd));
5374
+ const tasks = discoverTaskFiles(cwd).map((path3) => parseTaskFile(path3, cwd));
5035
5375
  return formatTaskContext(selectRelevantTasks(tasks, { ...options, currentBranch }));
5036
5376
  }
5037
5377
  function updateTaskFileStatus(taskPath, status, options = {}) {
@@ -5379,9 +5719,9 @@ var BundlePluginLoader = class {
5379
5719
  return results;
5380
5720
  }
5381
5721
  /** Read and validate a plugin.json manifest. Returns null on failure. */
5382
- readManifest(path) {
5722
+ readManifest(path3) {
5383
5723
  try {
5384
- const raw = (0, import_node_fs9.readFileSync)(path, "utf-8");
5724
+ const raw = (0, import_node_fs9.readFileSync)(path3, "utf-8");
5385
5725
  const data = JSON.parse(raw);
5386
5726
  return validateManifest(data);
5387
5727
  } catch {
@@ -5939,8 +6279,8 @@ var MarketplaceClient = class {
5939
6279
  }
5940
6280
  }
5941
6281
  /** Read and parse a marketplace.json from a file path. */
5942
- readManifestFromPath(path) {
5943
- const raw = (0, import_node_fs12.readFileSync)(path, "utf-8");
6282
+ readManifestFromPath(path3) {
6283
+ const raw = (0, import_node_fs12.readFileSync)(path3, "utf-8");
5944
6284
  const data = JSON.parse(raw);
5945
6285
  if (typeof data !== "object" || data === null) {
5946
6286
  throw new Error("Invalid marketplace manifest: not an object");
@@ -6211,8 +6551,8 @@ function isRestoredTerminalStatus(status) {
6211
6551
  }
6212
6552
 
6213
6553
  // src/interactive/interactive-session-context-references.ts
6214
- async function addInteractiveContextReference(references, path, cwd) {
6215
- const result = await resolvePromptFileReferencePaths([path], {
6554
+ async function addInteractiveContextReference(references, path3, cwd) {
6555
+ const result = await resolvePromptFileReferencePaths([path3], {
6216
6556
  cwd,
6217
6557
  reason: "manual"
6218
6558
  });
@@ -6305,9 +6645,9 @@ function toInspectionPlan(manifests) {
6305
6645
  fileCount: manifests.reduce((count, manifest) => count + manifest.fileCount, 0)
6306
6646
  };
6307
6647
  }
6308
- function statSafe(path) {
6648
+ function statSafe(path3) {
6309
6649
  try {
6310
- return (0, import_node_fs13.statSync)(path);
6650
+ return (0, import_node_fs13.statSync)(path3);
6311
6651
  } catch {
6312
6652
  return void 0;
6313
6653
  }
@@ -6478,10 +6818,10 @@ var EditCheckpointStore = class {
6478
6818
  }
6479
6819
  async writeManifest(dir, manifest) {
6480
6820
  await (0, import_promises2.mkdir)(dir, { recursive: true });
6481
- const path = (0, import_node_path18.join)(dir, MANIFEST_FILE);
6482
- const tmp = `${path}.tmp`;
6821
+ const path3 = (0, import_node_path18.join)(dir, MANIFEST_FILE);
6822
+ const tmp = `${path3}.tmp`;
6483
6823
  await (0, import_promises2.writeFile)(tmp, JSON.stringify(manifest, null, 2), "utf8");
6484
- await (0, import_promises2.rename)(tmp, path);
6824
+ await (0, import_promises2.rename)(tmp, path3);
6485
6825
  }
6486
6826
  sessionDir(sessionId) {
6487
6827
  return (0, import_node_path18.join)(this.rootDir, safePathSegment(sessionId));
@@ -6507,9 +6847,9 @@ function isInside(parent, child) {
6507
6847
  const rel = (0, import_node_path18.relative)(parent, child);
6508
6848
  return rel.length === 0 || !rel.startsWith("..") && !rel.startsWith("/");
6509
6849
  }
6510
- async function pathExists(path) {
6850
+ async function pathExists(path3) {
6511
6851
  try {
6512
- await (0, import_promises2.access)(path, import_node_fs14.constants.F_OK);
6852
+ await (0, import_promises2.access)(path3, import_node_fs14.constants.F_OK);
6513
6853
  return true;
6514
6854
  } catch {
6515
6855
  return false;
@@ -6522,9 +6862,9 @@ function readDirSyncSafe(dir) {
6522
6862
  return [];
6523
6863
  }
6524
6864
  }
6525
- function readJsonManifest(path) {
6865
+ function readJsonManifest(path3) {
6526
6866
  try {
6527
- const raw = (0, import_node_fs14.readFileSync)(path, "utf8");
6867
+ const raw = (0, import_node_fs14.readFileSync)(path3, "utf8");
6528
6868
  return JSON.parse(raw);
6529
6869
  } catch {
6530
6870
  return void 0;
@@ -6547,6 +6887,11 @@ function getQualifiedSkillName(rawInput) {
6547
6887
  const firstToken = rawInput.slice(1).trim().split(/\s+/)[0];
6548
6888
  return firstToken && firstToken.length > 0 ? firstToken : void 0;
6549
6889
  }
6890
+ function getBackgroundTaskEventEntryId(event) {
6891
+ if ("task" in event) return createBackgroundTaskExecutionEntryId(event.task.id);
6892
+ if ("taskId" in event) return createBackgroundTaskExecutionEntryId(event.taskId);
6893
+ return void 0;
6894
+ }
6550
6895
  var InteractiveSession = class {
6551
6896
  session = null;
6552
6897
  commandExecutor;
@@ -6990,18 +7335,18 @@ var InteractiveSession = class {
6990
7335
  listContextReferences() {
6991
7336
  return [...this.contextReferences];
6992
7337
  }
6993
- async addContextReference(path) {
7338
+ async addContextReference(path3) {
6994
7339
  const { references, result } = await addInteractiveContextReference(
6995
7340
  this.contextReferences,
6996
- path,
7341
+ path3,
6997
7342
  this.getCwd()
6998
7343
  );
6999
7344
  this.contextReferences = references;
7000
7345
  this.persistCurrentSession();
7001
7346
  return result;
7002
7347
  }
7003
- removeContextReference(path) {
7004
- const result = removeContextReference(this.contextReferences, path);
7348
+ removeContextReference(path3) {
7349
+ const result = removeContextReference(this.contextReferences, path3);
7005
7350
  this.contextReferences = result.references;
7006
7351
  this.persistCurrentSession();
7007
7352
  return result.result;
@@ -7051,6 +7396,53 @@ var InteractiveSession = class {
7051
7396
  await this.ensureInitialized();
7052
7397
  return this.getBackgroundJobOrchestratorOrThrow().waitGroup(groupId);
7053
7398
  }
7399
+ getExecutionWorkspaceSnapshot(options = {}) {
7400
+ const session = this.getSessionOrThrow();
7401
+ const sessionId = session.getSessionId();
7402
+ return createExecutionWorkspaceSnapshot({
7403
+ sessionId,
7404
+ mainThread: {
7405
+ sessionId,
7406
+ isExecuting: this.executing,
7407
+ hasPendingPrompt: this.pendingPrompt !== null,
7408
+ historyLength: this.history.length,
7409
+ updatedAt: this.getMainThreadUpdatedAt(),
7410
+ preview: this.getMainThreadPreview()
7411
+ },
7412
+ tasks: this.getBackgroundTaskSnapshots(),
7413
+ groups: this.getBackgroundJobGroupSnapshots(),
7414
+ selectedEntryId: options.selectedEntryId,
7415
+ filter: options.filter
7416
+ });
7417
+ }
7418
+ listExecutionWorkspaceEntries(filter) {
7419
+ return [...this.getExecutionWorkspaceSnapshot({ filter }).entries];
7420
+ }
7421
+ getExecutionWorkspaceEntry(entryId) {
7422
+ return this.getExecutionWorkspaceSnapshot().entries.find((entry) => entry.id === entryId);
7423
+ }
7424
+ async readExecutionWorkspaceDetail(entryId, cursor) {
7425
+ await this.ensureInitialized();
7426
+ const entryRef = parseExecutionWorkspaceEntryId(entryId);
7427
+ if (!entryRef) throw new Error(`Unknown execution workspace entry: ${entryId}`);
7428
+ if (entryRef.kind === "main_thread") {
7429
+ return createMainThreadDetailPage({ entryId, history: this.history, cursor });
7430
+ }
7431
+ if (entryRef.kind === "background_group") {
7432
+ return this.readBackgroundGroupDetail(entryId, entryRef.sourceId);
7433
+ }
7434
+ return this.readBackgroundTaskDetail(entryId, entryRef.sourceId, cursor);
7435
+ }
7436
+ createExecutionWorkspaceTaskSpawner(origin) {
7437
+ const sessionId = this.getSessionOrThrow().getSessionId();
7438
+ return createExecutionWorkspaceTaskSpawner({
7439
+ manager: this.getBackgroundTaskManagerOrThrow(),
7440
+ groupOrchestrator: this.getBackgroundJobOrchestratorOrThrow(),
7441
+ sessionId,
7442
+ cwd: this.getCwd(),
7443
+ origin: { ...origin, sessionId: origin.sessionId || sessionId }
7444
+ });
7445
+ }
7054
7446
  listAgentDefinitions() {
7055
7447
  const deps = retrieveAgentToolDeps(this.getSessionOrThrow());
7056
7448
  return (deps?.agentDefinitions ?? []).map((agent) => ({
@@ -7065,10 +7457,11 @@ var InteractiveSession = class {
7065
7457
  await this.ensureInitialized();
7066
7458
  const deps = this.getAgentToolDepsOrThrow();
7067
7459
  const definition = this.resolveAgentDefinition(input.agentType, deps);
7460
+ const sessionId = this.getSessionOrThrow().getSessionId();
7068
7461
  return this.getSubagentManagerOrThrow().spawn({
7069
7462
  type: input.agentType,
7070
7463
  label: input.label,
7071
- parentSessionId: this.getSessionOrThrow().getSessionId(),
7464
+ parentSessionId: sessionId,
7072
7465
  mode: input.mode,
7073
7466
  depth: (deps.subagentDepth ?? 0) + 1,
7074
7467
  cwd: deps.cwd ?? this.cwd ?? process.cwd(),
@@ -7076,7 +7469,13 @@ var InteractiveSession = class {
7076
7469
  model: input.model ?? definition.model,
7077
7470
  isolation: input.isolation,
7078
7471
  allowedTools: definition.tools,
7079
- disallowedTools: definition.disallowedTools
7472
+ disallowedTools: definition.disallowedTools,
7473
+ metadata: createExecutionOriginMetadata({
7474
+ kind: this.commandInvocationSource === "model" ? "model_command" : "slash_command",
7475
+ sessionId,
7476
+ commandName: "agent",
7477
+ label: input.label
7478
+ })
7080
7479
  });
7081
7480
  }
7082
7481
  async waitAgentJob(jobId) {
@@ -7179,6 +7578,51 @@ var InteractiveSession = class {
7179
7578
  this.finishForkSkillExecution();
7180
7579
  }
7181
7580
  }
7581
+ async readBackgroundTaskDetail(entryId, taskId, cursor) {
7582
+ const task = this.getBackgroundTaskManagerOrThrow().get(taskId);
7583
+ if (!task) throw new Error(`Unknown background task: ${taskId}`);
7584
+ if (task.logPath || task.transcriptPath) {
7585
+ const page = await this.getBackgroundTaskManagerOrThrow().readLog(taskId, cursor);
7586
+ return createLineDetailPage({
7587
+ entryId,
7588
+ lines: page.lines,
7589
+ cursor: page.cursor,
7590
+ nextCursor: page.nextCursor,
7591
+ kind: task.kind === "process" ? "process_output" : "progress"
7592
+ });
7593
+ }
7594
+ const detailKind = task.status === "failed" ? "error" : task.status === "completed" ? "result" : "progress";
7595
+ const text = task.error?.message ?? task.result?.output ?? task.currentAction ?? task.promptPreview ?? task.commandPreview ?? task.status;
7596
+ return createLineDetailPage({ entryId, lines: [text], cursor, kind: detailKind });
7597
+ }
7598
+ readBackgroundGroupDetail(entryId, groupId) {
7599
+ const group = this.getBackgroundJobOrchestratorOrThrow().getGroup(groupId);
7600
+ if (!group) throw new Error(`Unknown background job group: ${groupId}`);
7601
+ const summary = summarizeBackgroundJobGroup(group);
7602
+ return createLineDetailPage({
7603
+ entryId,
7604
+ lines: summary.lines,
7605
+ kind: "group_summary"
7606
+ });
7607
+ }
7608
+ getMainThreadUpdatedAt() {
7609
+ return this.history.at(-1)?.timestamp.toISOString() ?? (/* @__PURE__ */ new Date(0)).toISOString();
7610
+ }
7611
+ getMainThreadPreview() {
7612
+ if (this.streamingText.trim().length > 0) return this.streamingText;
7613
+ const latest = this.history.at(-1);
7614
+ if (!latest) return void 0;
7615
+ return latest.type;
7616
+ }
7617
+ emitExecutionWorkspaceUpdated(cause, entryId) {
7618
+ if (!this.session) return;
7619
+ this.emit("execution_workspace_event", {
7620
+ type: "execution_workspace_updated",
7621
+ cause,
7622
+ ...entryId ? { entryId } : {},
7623
+ snapshot: this.getExecutionWorkspaceSnapshot()
7624
+ });
7625
+ }
7182
7626
  getBackgroundTaskManagerOrThrow() {
7183
7627
  const manager = this.getBackgroundTaskManager();
7184
7628
  if (!manager) {
@@ -7244,11 +7688,16 @@ var InteractiveSession = class {
7244
7688
  this.backgroundTasks = this.getBackgroundTaskSnapshots();
7245
7689
  this.backgroundTaskEvents.push(event);
7246
7690
  this.persistCurrentSession();
7691
+ this.emitExecutionWorkspaceUpdated("background_task", getBackgroundTaskEventEntryId(event));
7247
7692
  }
7248
7693
  recordBackgroundJobGroupEvent(event) {
7249
7694
  this.backgroundJobGroups = this.getBackgroundJobGroupSnapshots();
7250
7695
  this.backgroundJobGroupEvents.push(event);
7251
7696
  this.persistCurrentSession();
7697
+ this.emitExecutionWorkspaceUpdated(
7698
+ "background_group",
7699
+ createBackgroundGroupExecutionEntryId(event.group.id)
7700
+ );
7252
7701
  }
7253
7702
  getBackgroundTaskSnapshots() {
7254
7703
  try {
@@ -7312,10 +7761,12 @@ var InteractiveSession = class {
7312
7761
  this.clearStreaming();
7313
7762
  this.emit("thinking", true);
7314
7763
  this.history.push((0, import_agent_core7.messageToHistoryEntry)((0, import_agent_core7.createUserMessage)(displayInput)));
7764
+ this.emitExecutionWorkspaceUpdated("main_thread");
7315
7765
  }
7316
7766
  finishForkSkillExecution() {
7317
7767
  this.executing = false;
7318
7768
  this.emit("thinking", false);
7769
+ this.emitExecutionWorkspaceUpdated("main_thread");
7319
7770
  this.persistCurrentSession();
7320
7771
  if (!this.shuttingDown && this.pendingPrompt) {
7321
7772
  const queued = this.pendingPrompt;
@@ -7385,6 +7836,7 @@ var InteractiveSession = class {
7385
7836
  this.executing = true;
7386
7837
  this.clearStreaming();
7387
7838
  this.emit("thinking", true);
7839
+ this.emitExecutionWorkspaceUpdated("main_thread");
7388
7840
  try {
7389
7841
  const result = await this.commandExecutor.executeCommand(command, this, args);
7390
7842
  this.emit("context_update", this.getContextState());
@@ -7398,6 +7850,7 @@ var InteractiveSession = class {
7398
7850
  } finally {
7399
7851
  this.executing = false;
7400
7852
  this.emit("thinking", false);
7853
+ this.emitExecutionWorkspaceUpdated("main_thread");
7401
7854
  this.persistCurrentSession();
7402
7855
  if (!this.shuttingDown && this.pendingPrompt) {
7403
7856
  const queued = this.pendingPrompt;
@@ -7411,8 +7864,10 @@ var InteractiveSession = class {
7411
7864
  async executePrompt(input, displayInput, rawInput) {
7412
7865
  this.executing = true;
7413
7866
  this.clearStreaming();
7867
+ this.emit("user_message", displayInput ?? input);
7414
7868
  this.emit("thinking", true);
7415
7869
  this.history.push((0, import_agent_core7.messageToHistoryEntry)((0, import_agent_core7.createUserMessage)(displayInput ?? input)));
7870
+ this.emitExecutionWorkspaceUpdated("main_thread");
7416
7871
  const historyBefore = this.getSessionOrThrow().getHistory().length;
7417
7872
  this.usedMemoryReferences = [];
7418
7873
  try {
@@ -7474,6 +7929,7 @@ var InteractiveSession = class {
7474
7929
  await this.finalizeEditCheckpointTurn();
7475
7930
  this.executing = false;
7476
7931
  this.emit("thinking", false);
7932
+ this.emitExecutionWorkspaceUpdated("main_thread");
7477
7933
  this.persistCurrentSession();
7478
7934
  if (!this.shuttingDown && this.pendingPrompt) {
7479
7935
  const queued = this.pendingPrompt;
@@ -7768,6 +8224,404 @@ function createQuery(options) {
7768
8224
  };
7769
8225
  }
7770
8226
 
8227
+ // src/user-local/storage.ts
8228
+ var import_node_fs16 = require("fs");
8229
+ var import_node_os6 = require("os");
8230
+ var import_node_path20 = __toESM(require("path"), 1);
8231
+ var USER_LOCAL_STORAGE_CATEGORIES = [
8232
+ "preferences",
8233
+ "view-state",
8234
+ "memory-projections",
8235
+ "task-associations",
8236
+ "workflow-metadata",
8237
+ "inspection-index"
8238
+ ];
8239
+ var USER_LOCAL_STORAGE_CATEGORY_DEFINITIONS = [
8240
+ {
8241
+ category: "preferences",
8242
+ purpose: "User-local UI and display preferences.",
8243
+ mayExecuteCommands: false
8244
+ },
8245
+ {
8246
+ category: "view-state",
8247
+ purpose: "Last selected panels, filters, and navigation state.",
8248
+ mayExecuteCommands: false
8249
+ },
8250
+ {
8251
+ category: "memory-projections",
8252
+ purpose: "Inspectable local memory item projections and user choices.",
8253
+ mayExecuteCommands: false
8254
+ },
8255
+ {
8256
+ category: "task-associations",
8257
+ purpose: "User-local associations between sessions, tasks, and background items.",
8258
+ mayExecuteCommands: false
8259
+ },
8260
+ {
8261
+ category: "workflow-metadata",
8262
+ purpose: "Transparent workflow metadata that is not repo-owned.",
8263
+ mayExecuteCommands: false
8264
+ },
8265
+ {
8266
+ category: "inspection-index",
8267
+ purpose: "Category and item summaries for user inspection and deletion.",
8268
+ mayExecuteCommands: false
8269
+ }
8270
+ ];
8271
+ function formatIsoDate(date) {
8272
+ return date.toISOString();
8273
+ }
8274
+ function assertAbsolutePath(name, value) {
8275
+ if (value.trim().length === 0) {
8276
+ throw new Error(`${name} must not be empty.`);
8277
+ }
8278
+ if (!import_node_path20.default.isAbsolute(value)) {
8279
+ throw new Error(`${name} must be an absolute path: ${value}`);
8280
+ }
8281
+ }
8282
+ function resolveDefaultHomeDir() {
8283
+ return process.env.HOME ?? (0, import_node_os6.homedir)();
8284
+ }
8285
+ function isEqualOrInside(parentPath, candidatePath) {
8286
+ const relative4 = import_node_path20.default.relative(parentPath, candidatePath);
8287
+ return relative4 === "" || !relative4.startsWith("..") && !import_node_path20.default.isAbsolute(relative4);
8288
+ }
8289
+ async function resolveForComparison(absPath) {
8290
+ let current = absPath;
8291
+ while (import_node_path20.default.dirname(current) !== current) {
8292
+ try {
8293
+ const realCurrent = await import_node_fs16.promises.realpath(current);
8294
+ const relativeMissingPath = import_node_path20.default.relative(current, absPath);
8295
+ return import_node_path20.default.resolve(realCurrent, relativeMissingPath);
8296
+ } catch {
8297
+ current = import_node_path20.default.dirname(current);
8298
+ }
8299
+ }
8300
+ try {
8301
+ return await import_node_fs16.promises.realpath(current);
8302
+ } catch {
8303
+ return import_node_path20.default.resolve(absPath);
8304
+ }
8305
+ }
8306
+ async function resolveUserLocalStorageRoot(options) {
8307
+ const activeRepositoryRoot = import_node_path20.default.resolve(options.activeRepositoryRoot);
8308
+ assertAbsolutePath("activeRepositoryRoot", activeRepositoryRoot);
8309
+ const candidateRoot = options.storageRoot !== void 0 ? options.storageRoot : import_node_path20.default.join(options.homeDir ?? resolveDefaultHomeDir(), ".robota");
8310
+ assertAbsolutePath("userLocalStorageRoot", candidateRoot);
8311
+ const resolvedRoot = import_node_path20.default.resolve(candidateRoot);
8312
+ const comparableRoot = await resolveForComparison(resolvedRoot);
8313
+ const comparableRepositoryRoot = await resolveForComparison(activeRepositoryRoot);
8314
+ if (isEqualOrInside(comparableRepositoryRoot, comparableRoot)) {
8315
+ throw new Error(
8316
+ `User-local storage root must be outside the active repository: ${resolvedRoot}`
8317
+ );
8318
+ }
8319
+ return resolvedRoot;
8320
+ }
8321
+ function resolveCategoryLocation(root, category) {
8322
+ return import_node_path20.default.join(root, category);
8323
+ }
8324
+ async function listItemSummaries(root, category) {
8325
+ const storageLocation = resolveCategoryLocation(root, category);
8326
+ let entries;
8327
+ try {
8328
+ entries = await import_node_fs16.promises.readdir(storageLocation, { withFileTypes: true });
8329
+ } catch {
8330
+ return [];
8331
+ }
8332
+ const summaries = await Promise.all(
8333
+ entries.map(async (entry) => {
8334
+ const itemLocation = import_node_path20.default.join(storageLocation, entry.name);
8335
+ const stats = await import_node_fs16.promises.stat(itemLocation);
8336
+ const key = entry.name;
8337
+ return {
8338
+ root,
8339
+ category,
8340
+ key,
8341
+ summary: `${category}/${key}`,
8342
+ source: "user-local-storage",
8343
+ scope: "user",
8344
+ storageLocation: itemLocation,
8345
+ createdAt: formatIsoDate(stats.birthtime),
8346
+ lastUsedAt: formatIsoDate(stats.mtime),
8347
+ enabled: true,
8348
+ deleteAvailable: true,
8349
+ disableAvailable: false
8350
+ };
8351
+ })
8352
+ );
8353
+ return summaries.sort((left, right) => left.key.localeCompare(right.key));
8354
+ }
8355
+ async function inspectUserLocalStorage(options) {
8356
+ const root = await resolveUserLocalStorageRoot(options);
8357
+ const activeRepositoryRoot = import_node_path20.default.resolve(options.activeRepositoryRoot);
8358
+ const createDirectories = options.createDirectories ?? true;
8359
+ if (createDirectories) {
8360
+ await import_node_fs16.promises.mkdir(root, { recursive: true });
8361
+ }
8362
+ const categories = await Promise.all(
8363
+ USER_LOCAL_STORAGE_CATEGORY_DEFINITIONS.map(
8364
+ async (definition) => {
8365
+ const storageLocation = resolveCategoryLocation(root, definition.category);
8366
+ if (createDirectories) {
8367
+ await import_node_fs16.promises.mkdir(storageLocation, { recursive: true });
8368
+ }
8369
+ const items = await listItemSummaries(root, definition.category);
8370
+ return {
8371
+ category: definition.category,
8372
+ purpose: definition.purpose,
8373
+ mayExecuteCommands: definition.mayExecuteCommands,
8374
+ storageLocation,
8375
+ itemCount: items.length,
8376
+ items
8377
+ };
8378
+ }
8379
+ )
8380
+ );
8381
+ return {
8382
+ root,
8383
+ activeRepositoryRoot,
8384
+ categories,
8385
+ generatedAt: formatIsoDate((options.now ?? (() => /* @__PURE__ */ new Date()))())
8386
+ };
8387
+ }
8388
+
8389
+ // src/user-local/memory.ts
8390
+ var import_node_fs17 = require("fs");
8391
+ var import_node_path21 = __toESM(require("path"), 1);
8392
+
8393
+ // src/user-local/memory-types.ts
8394
+ var USER_LOCAL_MEMORY_CATEGORIES = [
8395
+ "view-preference",
8396
+ "last-visible-cwd",
8397
+ "background-selection",
8398
+ "task-association",
8399
+ "display-preference",
8400
+ "inspection-choice"
8401
+ ];
8402
+
8403
+ // src/user-local/memory.ts
8404
+ var MEMORY_STORAGE_CATEGORY = "memory-projections";
8405
+ var FILE_EXTENSION = ".json";
8406
+ var MEMORY_SCHEMA_VERSION = 1;
8407
+ var MAX_SEGMENT_LENGTH = 80;
8408
+ var MAX_SUMMARY_LENGTH = 240;
8409
+ var MAX_SOURCE_LENGTH = 80;
8410
+ var MAX_SCOPE_LENGTH = 120;
8411
+ var MAX_VALUE_SUMMARY_LENGTH = 240;
8412
+ var DEFAULT_SCOPE = "user";
8413
+ var SAFE_SEGMENT_PATTERN = /^[a-z0-9][a-z0-9._-]*$/u;
8414
+ var DISPLAY_NAVIGATION_RULES = {
8415
+ "view-preference": "May affect UI panel, filter, density, or sorting display/navigation only.",
8416
+ "last-visible-cwd": "May display or preselect an already visible workspace context only.",
8417
+ "background-selection": "May restore the selected background entry in local UI only.",
8418
+ "task-association": "May group visible tasks by a local association only.",
8419
+ "display-preference": "May affect local text wrapping, compactness, or visibility only.",
8420
+ "inspection-choice": "May affect inspection display choices only."
8421
+ };
8422
+ function formatIsoDate2(date) {
8423
+ return date.toISOString();
8424
+ }
8425
+ function isUserLocalMemoryCategory(value) {
8426
+ return USER_LOCAL_MEMORY_CATEGORIES.includes(value);
8427
+ }
8428
+ function assertUserLocalMemoryCategory(value) {
8429
+ if (!isUserLocalMemoryCategory(value)) {
8430
+ throw new Error(`Unsupported user-local memory category: ${value}`);
8431
+ }
8432
+ return value;
8433
+ }
8434
+ function assertSafeSegment(name, value) {
8435
+ const trimmed = value.trim();
8436
+ if (trimmed.length === 0) {
8437
+ throw new Error(`${name} must not be empty.`);
8438
+ }
8439
+ if (trimmed.length > MAX_SEGMENT_LENGTH || !SAFE_SEGMENT_PATTERN.test(trimmed)) {
8440
+ throw new Error(
8441
+ `${name} must use lowercase letters, numbers, dots, underscores, or hyphens: ${value}`
8442
+ );
8443
+ }
8444
+ return trimmed;
8445
+ }
8446
+ function boundedText(name, value, maxLength) {
8447
+ const normalized = value.trim().replace(/\s+/g, " ");
8448
+ if (normalized.length === 0) {
8449
+ throw new Error(`${name} must not be empty.`);
8450
+ }
8451
+ if (normalized.length > maxLength) {
8452
+ return normalized.slice(0, maxLength);
8453
+ }
8454
+ return normalized;
8455
+ }
8456
+ function summarizeValue(value) {
8457
+ return boundedText("value", value, MAX_VALUE_SUMMARY_LENGTH);
8458
+ }
8459
+ function memoryFileName(category, key) {
8460
+ return `${category}__${key}${FILE_EXTENSION}`;
8461
+ }
8462
+ async function resolveMemoryRoot(options) {
8463
+ const root = await resolveUserLocalStorageRoot(options);
8464
+ return {
8465
+ root,
8466
+ memoryRoot: import_node_path21.default.join(root, MEMORY_STORAGE_CATEGORY)
8467
+ };
8468
+ }
8469
+ function parseMemoryRecord(raw, storageLocation) {
8470
+ const record = JSON.parse(raw);
8471
+ const category = readString(record, "category");
8472
+ const schemaVersion = record["schemaVersion"];
8473
+ if (schemaVersion !== MEMORY_SCHEMA_VERSION) {
8474
+ throw new Error(`Unsupported user-local memory schema at ${storageLocation}`);
8475
+ }
8476
+ return {
8477
+ schemaVersion: MEMORY_SCHEMA_VERSION,
8478
+ category: assertUserLocalMemoryCategory(category),
8479
+ key: readString(record, "key"),
8480
+ value: readString(record, "value"),
8481
+ summary: readString(record, "summary"),
8482
+ source: readString(record, "source"),
8483
+ scope: readString(record, "scope"),
8484
+ createdAt: readString(record, "createdAt"),
8485
+ lastUsedAt: readString(record, "lastUsedAt"),
8486
+ enabled: readBoolean(record, "enabled")
8487
+ };
8488
+ }
8489
+ function readString(record, key) {
8490
+ const value = record[key];
8491
+ if (typeof value !== "string") {
8492
+ throw new Error(`Invalid user-local memory field: ${key}`);
8493
+ }
8494
+ return value;
8495
+ }
8496
+ function readBoolean(record, key) {
8497
+ const value = record[key];
8498
+ if (typeof value !== "boolean") {
8499
+ throw new Error(`Invalid user-local memory field: ${key}`);
8500
+ }
8501
+ return value;
8502
+ }
8503
+ function projectMemoryItem(root, storageLocation, item) {
8504
+ return {
8505
+ root,
8506
+ category: item.category,
8507
+ key: item.key,
8508
+ summary: item.summary,
8509
+ valueSummary: summarizeValue(item.value),
8510
+ source: item.source,
8511
+ scope: item.scope,
8512
+ storageLocation,
8513
+ createdAt: item.createdAt,
8514
+ lastUsedAt: item.lastUsedAt,
8515
+ enabled: item.enabled,
8516
+ displayNavigationRule: DISPLAY_NAVIGATION_RULES[item.category],
8517
+ commandExecutionEffect: "none",
8518
+ deleteAvailable: true,
8519
+ disableAvailable: true
8520
+ };
8521
+ }
8522
+ async function readMemoryFile(root, storageLocation) {
8523
+ return projectMemoryItem(
8524
+ root,
8525
+ storageLocation,
8526
+ parseMemoryRecord(await import_node_fs17.promises.readFile(storageLocation, "utf8"), storageLocation)
8527
+ );
8528
+ }
8529
+ async function resolveMemoryFile(options) {
8530
+ const category = assertUserLocalMemoryCategory(options.category);
8531
+ const key = assertSafeSegment("key", options.key);
8532
+ const { root, memoryRoot: memoryRoot3 } = await resolveMemoryRoot(options);
8533
+ return {
8534
+ root,
8535
+ storageLocation: import_node_path21.default.join(memoryRoot3, memoryFileName(category, key))
8536
+ };
8537
+ }
8538
+ async function setUserLocalMemoryItem(options) {
8539
+ const category = assertUserLocalMemoryCategory(options.category);
8540
+ const key = assertSafeSegment("key", options.key);
8541
+ const summary = boundedText("summary", options.summary, MAX_SUMMARY_LENGTH);
8542
+ const source = boundedText("source", options.source, MAX_SOURCE_LENGTH);
8543
+ const scope = boundedText("scope", options.scope ?? DEFAULT_SCOPE, MAX_SCOPE_LENGTH);
8544
+ const value = summarizeValue(options.value);
8545
+ const now = formatIsoDate2((options.now ?? (() => /* @__PURE__ */ new Date()))());
8546
+ const { root, memoryRoot: memoryRoot3 } = await resolveMemoryRoot(options);
8547
+ const storageLocation = import_node_path21.default.join(memoryRoot3, memoryFileName(category, key));
8548
+ let createdAt = now;
8549
+ try {
8550
+ const existing = parseMemoryRecord(await import_node_fs17.promises.readFile(storageLocation, "utf8"), storageLocation);
8551
+ createdAt = existing.createdAt;
8552
+ } catch (error) {
8553
+ if (error instanceof Error && error.message.includes("ENOENT")) {
8554
+ createdAt = now;
8555
+ } else {
8556
+ throw error;
8557
+ }
8558
+ }
8559
+ const item = {
8560
+ schemaVersion: MEMORY_SCHEMA_VERSION,
8561
+ category,
8562
+ key,
8563
+ value,
8564
+ summary,
8565
+ source,
8566
+ scope,
8567
+ createdAt,
8568
+ lastUsedAt: now,
8569
+ enabled: true
8570
+ };
8571
+ await import_node_fs17.promises.mkdir(memoryRoot3, { recursive: true });
8572
+ await import_node_fs17.promises.writeFile(storageLocation, `${JSON.stringify(item, null, 2)}
8573
+ `, "utf8");
8574
+ return projectMemoryItem(root, storageLocation, item);
8575
+ }
8576
+ async function listUserLocalMemoryItems(options) {
8577
+ const { root, memoryRoot: memoryRoot3 } = await resolveMemoryRoot(options);
8578
+ let entries;
8579
+ try {
8580
+ entries = await import_node_fs17.promises.readdir(memoryRoot3, { withFileTypes: true });
8581
+ } catch {
8582
+ entries = [];
8583
+ }
8584
+ const items = await Promise.all(
8585
+ entries.filter((entry) => entry.isFile() && entry.name.endsWith(FILE_EXTENSION)).map((entry) => readMemoryFile(root, import_node_path21.default.join(memoryRoot3, entry.name)))
8586
+ );
8587
+ return {
8588
+ root,
8589
+ activeRepositoryRoot: import_node_path21.default.resolve(options.activeRepositoryRoot),
8590
+ items: items.sort(
8591
+ (left, right) => `${left.category}/${left.key}`.localeCompare(`${right.category}/${right.key}`)
8592
+ )
8593
+ };
8594
+ }
8595
+ async function inspectUserLocalMemoryItem(options) {
8596
+ const { root, storageLocation } = await resolveMemoryFile(options);
8597
+ return readMemoryFile(root, storageLocation);
8598
+ }
8599
+ async function disableUserLocalMemoryItem(options) {
8600
+ const { root, storageLocation } = await resolveMemoryFile(options);
8601
+ const existing = parseMemoryRecord(await import_node_fs17.promises.readFile(storageLocation, "utf8"), storageLocation);
8602
+ const disabled = {
8603
+ ...existing,
8604
+ enabled: false,
8605
+ lastUsedAt: formatIsoDate2((options.now ?? (() => /* @__PURE__ */ new Date()))())
8606
+ };
8607
+ await import_node_fs17.promises.writeFile(storageLocation, `${JSON.stringify(disabled, null, 2)}
8608
+ `, "utf8");
8609
+ return projectMemoryItem(root, storageLocation, disabled);
8610
+ }
8611
+ async function deleteUserLocalMemoryItem(options) {
8612
+ const { storageLocation } = await resolveMemoryFile(options);
8613
+ await import_node_fs17.promises.rm(storageLocation);
8614
+ return {
8615
+ category: options.category,
8616
+ key: options.key,
8617
+ deleted: true
8618
+ };
8619
+ }
8620
+ async function readEnabledUserLocalMemoryItem(options) {
8621
+ const item = await inspectUserLocalMemoryItem(options);
8622
+ return item.enabled ? item : null;
8623
+ }
8624
+
7771
8625
  // src/self-hosting/self-hosting-verification.ts
7772
8626
  var DEFAULT_BASE_REF = "origin/develop";
7773
8627
  var PACKAGE_VERIFY_COMMANDS = ["test", "typecheck", "build"];
@@ -7946,8 +8800,8 @@ function createCommandExecutionTool(deps) {
7946
8800
  }
7947
8801
 
7948
8802
  // src/subagents/index.ts
7949
- var import_agent_runtime7 = require("@robota-sdk/agent-runtime");
7950
8803
  var import_agent_runtime8 = require("@robota-sdk/agent-runtime");
8804
+ var import_agent_runtime9 = require("@robota-sdk/agent-runtime");
7951
8805
 
7952
8806
  // src/permissions/permission-prompt.ts
7953
8807
  var import_chalk = __toESM(require("chalk"), 1);
@@ -7987,6 +8841,7 @@ async function promptForApproval(terminal, toolName, toolArgs) {
7987
8841
  DEFAULT_AUTO_COMPACT_THRESHOLD,
7988
8842
  DEFAULT_BACKGROUND_TASK_LOG_PAGE_SIZE,
7989
8843
  DEFAULT_STATUS_LINE_COMMAND_SETTINGS,
8844
+ EXECUTION_ORIGIN_METADATA_KEYS,
7990
8845
  EXIT_COMMAND_DESCRIPTION,
7991
8846
  EditCheckpointStore,
7992
8847
  HELP_COMMAND_DESCRIPTION,
@@ -8024,6 +8879,9 @@ async function promptForApproval(terminal, toolName, toolArgs) {
8024
8879
  SkillCommandSource,
8025
8880
  SubagentManager,
8026
8881
  SystemCommandExecutor,
8882
+ USER_LOCAL_MEMORY_CATEGORIES,
8883
+ USER_LOCAL_STORAGE_CATEGORIES,
8884
+ USER_LOCAL_STORAGE_CATEGORY_DEFINITIONS,
8027
8885
  VALIDATE_SESSION_COMMAND_DESCRIPTION,
8028
8886
  VALID_PERMISSION_MODES,
8029
8887
  WorktreeSubagentRunner,
@@ -8048,7 +8906,9 @@ async function promptForApproval(terminal, toolName, toolArgs) {
8048
8906
  closeCommandBackgroundTask,
8049
8907
  compactCommandContext,
8050
8908
  createAgentTool,
8909
+ createBackgroundGroupExecutionEntryId,
8051
8910
  createBackgroundProcessTool,
8911
+ createBackgroundTaskExecutionEntryId,
8052
8912
  createBackgroundTaskLogPage,
8053
8913
  createBuiltinCommandModule,
8054
8914
  createCommandExecutionTool,
@@ -8057,7 +8917,13 @@ async function promptForApproval(terminal, toolName, toolArgs) {
8057
8917
  createCommandProjectMemoryStore,
8058
8918
  createContextReferenceItem,
8059
8919
  createDefaultTools,
8920
+ createExecutionOriginMetadata,
8921
+ createExecutionWorkspaceSnapshot,
8922
+ createExecutionWorkspaceTaskSpawner,
8060
8923
  createLimitedOutputCapture,
8924
+ createLineDetailPage,
8925
+ createMainThreadDetailPage,
8926
+ createMainThreadExecutionEntryId,
8061
8927
  createModelCommandToolProjection,
8062
8928
  createPluginRegistryReloadRequestedEffect,
8063
8929
  createPluginTuiRequestedEffect,
@@ -8075,6 +8941,8 @@ async function promptForApproval(terminal, toolName, toolArgs) {
8075
8941
  createSystemCommands,
8076
8942
  createWorktreeSubagentRunner,
8077
8943
  deleteProviderProfile,
8944
+ deleteUserLocalMemoryItem,
8945
+ disableUserLocalMemoryItem,
8078
8946
  discoverTaskFiles,
8079
8947
  evaluateReversibleToolSafety,
8080
8948
  executeSkill,
@@ -8104,6 +8972,8 @@ async function promptForApproval(terminal, toolName, toolArgs) {
8104
8972
  hasSensitiveCommandMemoryContent,
8105
8973
  hasUsableSecretReference,
8106
8974
  inspectCommandEditCheckpoint,
8975
+ inspectUserLocalMemoryItem,
8976
+ inspectUserLocalStorage,
8107
8977
  isCommandMemoryType,
8108
8978
  isEnvReference,
8109
8979
  isMemoryType,
@@ -8117,10 +8987,12 @@ async function promptForApproval(terminal, toolName, toolArgs) {
8117
8987
  listCommandSessionAllowedTools,
8118
8988
  listCommandUsedMemoryReferences,
8119
8989
  listResumableSessionSummaries,
8990
+ listUserLocalMemoryItems,
8120
8991
  loadTaskContext,
8121
8992
  mergeProviderPatch,
8122
8993
  normalizeModelCommandName,
8123
8994
  parseCommandBackgroundLogCursor,
8995
+ parseExecutionWorkspaceEntryId,
8124
8996
  parseFrontmatter,
8125
8997
  parseLanguageArgument,
8126
8998
  parsePermissionModeArgument,
@@ -8140,6 +9012,7 @@ async function promptForApproval(terminal, toolName, toolArgs) {
8140
9012
  readCommandPermissionsState,
8141
9013
  readCommandSessionInfo,
8142
9014
  readCurrentGitBranch,
9015
+ readEnabledUserLocalMemoryItem,
8143
9016
  recordCommandMemoryEvent,
8144
9017
  removeCommandContextReference,
8145
9018
  removeContextReference,
@@ -8155,6 +9028,7 @@ async function promptForApproval(terminal, toolName, toolArgs) {
8155
9028
  resolveProviderSetupSelection,
8156
9029
  resolveSessionIdByIdOrName,
8157
9030
  resolveSubagentLogDir,
9031
+ resolveUserLocalStorageRoot,
8158
9032
  restoreCommandEditCheckpoint,
8159
9033
  retrieveAgentToolDeps,
8160
9034
  rollbackCommandEditCheckpoint,
@@ -8163,6 +9037,7 @@ async function promptForApproval(terminal, toolName, toolArgs) {
8163
9037
  selectRelevantTasks,
8164
9038
  setCommandAutoCompactThreshold,
8165
9039
  setCurrentProvider,
9040
+ setUserLocalMemoryItem,
8166
9041
  storeAgentToolDeps,
8167
9042
  submitProviderSetupValue,
8168
9043
  substituteVariables,