@robota-sdk/agent-sdk 3.0.0-beta.60 → 3.0.0-beta.61
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.
- package/README.md +133 -46
- package/dist/node/index.cjs +2037 -519
- package/dist/node/index.d.cts +339 -26
- package/dist/node/index.d.ts +339 -26
- package/dist/node/index.js +2011 -522
- package/package.json +7 -6
package/dist/node/index.cjs
CHANGED
|
@@ -45,6 +45,7 @@ __export(index_exports, {
|
|
|
45
45
|
COST_COMMAND_DESCRIPTION: () => COST_COMMAND_DESCRIPTION,
|
|
46
46
|
CommandRegistry: () => CommandRegistry,
|
|
47
47
|
DEFAULT_AUTO_COMPACT_THRESHOLD: () => DEFAULT_AUTO_COMPACT_THRESHOLD,
|
|
48
|
+
DEFAULT_BACKGROUND_TASK_LOG_PAGE_SIZE: () => import_agent_runtime4.DEFAULT_BACKGROUND_TASK_LOG_PAGE_SIZE,
|
|
48
49
|
DEFAULT_STATUS_LINE_COMMAND_SETTINGS: () => DEFAULT_STATUS_LINE_COMMAND_SETTINGS,
|
|
49
50
|
EXIT_COMMAND_DESCRIPTION: () => EXIT_COMMAND_DESCRIPTION,
|
|
50
51
|
EditCheckpointStore: () => EditCheckpointStore,
|
|
@@ -59,12 +60,14 @@ __export(index_exports, {
|
|
|
59
60
|
MEMORY_INDEX_MAX_LINES: () => MEMORY_INDEX_MAX_LINES,
|
|
60
61
|
MODEL_COMMAND_ARGUMENT_HINT: () => MODEL_COMMAND_ARGUMENT_HINT,
|
|
61
62
|
MODEL_COMMAND_DESCRIPTION: () => MODEL_COMMAND_DESCRIPTION,
|
|
63
|
+
MODEL_COMMAND_TOOL_PREFIX: () => MODEL_COMMAND_TOOL_PREFIX,
|
|
62
64
|
MarketplaceClient: () => MarketplaceClient,
|
|
63
65
|
PERMISSIONS_COMMAND_DESCRIPTION: () => PERMISSIONS_COMMAND_DESCRIPTION,
|
|
64
66
|
PERMISSION_MODE_ARGUMENT_HINT: () => PERMISSION_MODE_ARGUMENT_HINT,
|
|
65
67
|
PERMISSION_MODE_COMMAND_DESCRIPTION: () => PERMISSION_MODE_COMMAND_DESCRIPTION,
|
|
66
68
|
PLUGIN_COMMAND_ARGUMENT_HINT: () => PLUGIN_COMMAND_ARGUMENT_HINT,
|
|
67
69
|
PLUGIN_COMMAND_DESCRIPTION: () => PLUGIN_COMMAND_DESCRIPTION,
|
|
70
|
+
PROVIDER_SAFE_TOOL_NAME_PATTERN: () => PROVIDER_SAFE_TOOL_NAME_PATTERN,
|
|
68
71
|
PluginCommandSource: () => PluginCommandSource,
|
|
69
72
|
PluginSettingsStore: () => PluginSettingsStore,
|
|
70
73
|
ProjectMemoryStore: () => ProjectMemoryStore,
|
|
@@ -81,9 +84,11 @@ __export(index_exports, {
|
|
|
81
84
|
SkillCommandSource: () => SkillCommandSource,
|
|
82
85
|
SubagentManager: () => import_agent_runtime7.SubagentManager,
|
|
83
86
|
SystemCommandExecutor: () => SystemCommandExecutor,
|
|
84
|
-
|
|
87
|
+
VALIDATE_SESSION_COMMAND_DESCRIPTION: () => VALIDATE_SESSION_COMMAND_DESCRIPTION,
|
|
85
88
|
VALID_PERMISSION_MODES: () => VALID_PERMISSION_MODES,
|
|
86
89
|
WorktreeSubagentRunner: () => import_agent_runtime8.WorktreeSubagentRunner,
|
|
90
|
+
addCommandContextReference: () => addCommandContextReference,
|
|
91
|
+
appendPrefixedLogLines: () => import_agent_runtime4.appendPrefixedLogLines,
|
|
87
92
|
assembleSubagentPrompt: () => assembleSubagentPrompt,
|
|
88
93
|
buildBackgroundCommandSubcommands: () => buildBackgroundCommandSubcommands,
|
|
89
94
|
buildLanguageCommandSubcommands: () => buildLanguageCommandSubcommands,
|
|
@@ -91,26 +96,35 @@ __export(index_exports, {
|
|
|
91
96
|
buildModelCommandSubcommands: () => buildModelCommandSubcommands,
|
|
92
97
|
buildPermissionModeSubcommands: () => buildPermissionModeSubcommands,
|
|
93
98
|
buildPluginCommandSubcommands: () => buildPluginCommandSubcommands,
|
|
99
|
+
buildPromptWithFileReferences: () => buildPromptWithFileReferences,
|
|
94
100
|
buildProviderProfile: () => buildProviderProfile,
|
|
95
101
|
buildProviderSetupPatch: () => buildProviderSetupPatch,
|
|
96
102
|
buildRewindCommandSubcommands: () => buildRewindCommandSubcommands,
|
|
97
|
-
buildSkillPrompt: () => buildSkillPrompt,
|
|
98
103
|
buildStatusLineCommandSubcommands: () => buildStatusLineCommandSubcommands,
|
|
99
104
|
cancelCommandBackgroundTask: () => cancelCommandBackgroundTask,
|
|
100
|
-
|
|
105
|
+
clearCommandContextReferences: () => clearCommandContextReferences,
|
|
106
|
+
clearContextReferences: () => clearContextReferences,
|
|
101
107
|
clearConversationHistory: () => clearConversationHistory,
|
|
102
108
|
closeCommandBackgroundTask: () => closeCommandBackgroundTask,
|
|
103
109
|
compactCommandContext: () => compactCommandContext,
|
|
104
110
|
createAgentTool: () => createAgentTool,
|
|
105
111
|
createBackgroundProcessTool: () => createBackgroundProcessTool,
|
|
112
|
+
createBackgroundTaskLogPage: () => import_agent_runtime4.createBackgroundTaskLogPage,
|
|
106
113
|
createBuiltinCommandModule: () => createBuiltinCommandModule,
|
|
107
114
|
createCommandExecutionTool: () => createCommandExecutionTool,
|
|
108
115
|
createCommandMemoryStores: () => createCommandMemoryStores,
|
|
109
116
|
createCommandPendingMemoryStore: () => createCommandPendingMemoryStore,
|
|
110
117
|
createCommandProjectMemoryStore: () => createCommandProjectMemoryStore,
|
|
118
|
+
createContextReferenceItem: () => createContextReferenceItem,
|
|
111
119
|
createDefaultTools: () => createDefaultTools,
|
|
120
|
+
createLimitedOutputCapture: () => import_agent_runtime4.createLimitedOutputCapture,
|
|
121
|
+
createModelCommandToolProjection: () => createModelCommandToolProjection,
|
|
112
122
|
createPluginRegistryReloadRequestedEffect: () => createPluginRegistryReloadRequestedEffect,
|
|
113
123
|
createPluginTuiRequestedEffect: () => createPluginTuiRequestedEffect,
|
|
124
|
+
createProjectSessionStore: () => createProjectSessionStore,
|
|
125
|
+
createProjectedCommandExecutionTools: () => createProjectedCommandExecutionTools,
|
|
126
|
+
createPromptFileReferenceHistoryEntry: () => createPromptFileReferenceHistoryEntry,
|
|
127
|
+
createProviderSafeModelCommandToolName: () => createProviderSafeModelCommandToolName,
|
|
114
128
|
createProviderSetupFlow: () => createProviderSetupFlow,
|
|
115
129
|
createQuery: () => createQuery,
|
|
116
130
|
createSessionExitRequestedEffect: () => createSessionExitRequestedEffect,
|
|
@@ -120,48 +134,57 @@ __export(index_exports, {
|
|
|
120
134
|
createSubagentSession: () => createSubagentSession,
|
|
121
135
|
createSystemCommands: () => createSystemCommands,
|
|
122
136
|
createWorktreeSubagentRunner: () => import_agent_runtime8.createWorktreeSubagentRunner,
|
|
137
|
+
deleteProviderProfile: () => deleteProviderProfile,
|
|
123
138
|
discoverTaskFiles: () => discoverTaskFiles,
|
|
124
|
-
evaluatePermission: () => import_agent_core10.evaluatePermission,
|
|
125
139
|
evaluateReversibleToolSafety: () => evaluateReversibleToolSafety,
|
|
126
140
|
executeSkill: () => executeSkill,
|
|
127
141
|
formatCommandBackgroundTask: () => formatCommandBackgroundTask,
|
|
128
142
|
formatCommandBackgroundTaskList: () => formatCommandBackgroundTaskList,
|
|
129
143
|
formatCommandHelpMessage: () => formatCommandHelpMessage,
|
|
130
144
|
formatCommandPermissionsMessage: () => formatCommandPermissionsMessage,
|
|
145
|
+
formatCommandSessionReplayValidationReport: () => formatCommandSessionReplayValidationReport,
|
|
131
146
|
formatEnvReference: () => formatEnvReference,
|
|
132
147
|
formatInvalidPermissionModeMessage: () => formatInvalidPermissionModeMessage,
|
|
133
148
|
formatLanguageUsageMessage: () => formatLanguageUsageMessage,
|
|
149
|
+
formatModelCommandUsageMessage: () => formatModelCommandUsageMessage,
|
|
150
|
+
formatModelCommandUsageMessageAsync: () => formatModelCommandUsageMessageAsync,
|
|
151
|
+
formatProjectedModelCommandToolPromptDescription: () => formatProjectedModelCommandToolPromptDescription,
|
|
152
|
+
formatPromptFileReferenceDiagnostics: () => formatPromptFileReferenceDiagnostics,
|
|
134
153
|
formatProviderSetupChoiceLabel: () => formatProviderSetupChoiceLabel,
|
|
154
|
+
formatProviderSetupHelpLinks: () => formatProviderSetupHelpLinks,
|
|
135
155
|
formatProviderSetupPromptLabel: () => formatProviderSetupPromptLabel,
|
|
136
156
|
formatProviderSetupSelectionPrompt: () => formatProviderSetupSelectionPrompt,
|
|
137
157
|
formatTaskContext: () => formatTaskContext,
|
|
138
158
|
getBackgroundTaskTransitions: () => import_agent_runtime4.getBackgroundTaskTransitions,
|
|
139
159
|
getBuiltInAgent: () => getBuiltInAgent,
|
|
140
160
|
getForkWorkerSuffix: () => getForkWorkerSuffix,
|
|
141
|
-
getMessagesForAPI: () => import_agent_core9.getMessagesForAPI,
|
|
142
161
|
getProviderSetupStep: () => getProviderSetupStep,
|
|
143
162
|
getSubagentSuffix: () => getSubagentSuffix,
|
|
163
|
+
hasBlockingPromptFileReferenceDiagnostics: () => hasBlockingPromptFileReferenceDiagnostics,
|
|
144
164
|
hasSensitiveCommandMemoryContent: () => hasSensitiveCommandMemoryContent,
|
|
145
165
|
hasUsableSecretReference: () => hasUsableSecretReference,
|
|
146
166
|
inspectCommandEditCheckpoint: () => inspectCommandEditCheckpoint,
|
|
147
|
-
isChatEntry: () => import_agent_core9.isChatEntry,
|
|
148
167
|
isCommandMemoryType: () => isCommandMemoryType,
|
|
149
168
|
isEnvReference: () => isEnvReference,
|
|
150
169
|
isMemoryType: () => isMemoryType,
|
|
151
170
|
isPermissionMode: () => isPermissionMode,
|
|
152
171
|
isStatusLineCommandSettingsPatch: () => isStatusLineCommandSettingsPatch,
|
|
153
172
|
isTerminalBackgroundTaskStatus: () => import_agent_runtime4.isTerminalBackgroundTaskStatus,
|
|
173
|
+
listActiveContextReferences: () => listActiveContextReferences,
|
|
154
174
|
listCommandBackgroundTasks: () => listCommandBackgroundTasks,
|
|
175
|
+
listCommandContextReferences: () => listCommandContextReferences,
|
|
155
176
|
listCommandEditCheckpoints: () => listCommandEditCheckpoints,
|
|
156
177
|
listCommandSessionAllowedTools: () => listCommandSessionAllowedTools,
|
|
157
178
|
listCommandUsedMemoryReferences: () => listCommandUsedMemoryReferences,
|
|
179
|
+
listResumableSessionSummaries: () => listResumableSessionSummaries,
|
|
158
180
|
loadTaskContext: () => loadTaskContext,
|
|
159
181
|
mergeProviderPatch: () => mergeProviderPatch,
|
|
160
|
-
|
|
182
|
+
normalizeModelCommandName: () => normalizeModelCommandName,
|
|
161
183
|
parseCommandBackgroundLogCursor: () => parseCommandBackgroundLogCursor,
|
|
162
184
|
parseFrontmatter: () => parseFrontmatter,
|
|
163
185
|
parseLanguageArgument: () => parseLanguageArgument,
|
|
164
186
|
parsePermissionModeArgument: () => parsePermissionModeArgument,
|
|
187
|
+
parsePromptFileReferences: () => parsePromptFileReferences,
|
|
165
188
|
parseSessionNameArgument: () => parseSessionNameArgument,
|
|
166
189
|
parseTaskFile: () => parseTaskFile,
|
|
167
190
|
planSelfHostingVerification: () => planSelfHostingVerification,
|
|
@@ -178,30 +201,43 @@ __export(index_exports, {
|
|
|
178
201
|
readCommandSessionInfo: () => readCommandSessionInfo,
|
|
179
202
|
readCurrentGitBranch: () => readCurrentGitBranch,
|
|
180
203
|
recordCommandMemoryEvent: () => recordCommandMemoryEvent,
|
|
204
|
+
removeCommandContextReference: () => removeCommandContextReference,
|
|
205
|
+
removeContextReference: () => removeContextReference,
|
|
181
206
|
resetAutoCompactThresholdSetting: () => resetAutoCompactThresholdSetting,
|
|
207
|
+
resolveActiveProviderModelCatalog: () => resolveActiveProviderModelCatalog,
|
|
208
|
+
resolveActiveProviderModelCatalogState: () => resolveActiveProviderModelCatalogState,
|
|
182
209
|
resolveEnvReference: () => resolveEnvReference,
|
|
210
|
+
resolveLatestSessionId: () => resolveLatestSessionId,
|
|
183
211
|
resolvePermissionModeAdapter: () => resolvePermissionModeAdapter,
|
|
184
212
|
resolvePluginCommandAdapter: () => resolvePluginCommandAdapter,
|
|
213
|
+
resolvePromptFileReferencePaths: () => resolvePromptFileReferencePaths,
|
|
214
|
+
resolvePromptFileReferences: () => resolvePromptFileReferences,
|
|
185
215
|
resolveProviderSetupSelection: () => resolveProviderSetupSelection,
|
|
216
|
+
resolveSessionIdByIdOrName: () => resolveSessionIdByIdOrName,
|
|
186
217
|
resolveSubagentLogDir: () => resolveSubagentLogDir,
|
|
187
218
|
restoreCommandEditCheckpoint: () => restoreCommandEditCheckpoint,
|
|
188
219
|
retrieveAgentToolDeps: () => retrieveAgentToolDeps,
|
|
189
220
|
rollbackCommandEditCheckpoint: () => rollbackCommandEditCheckpoint,
|
|
190
|
-
runHooks: () => import_agent_core11.runHooks,
|
|
191
221
|
runProviderSetupPromptFlow: () => runProviderSetupPromptFlow,
|
|
222
|
+
sanitizeProviderProfileName: () => sanitizeProviderProfileName,
|
|
192
223
|
selectRelevantTasks: () => selectRelevantTasks,
|
|
193
224
|
setCommandAutoCompactThreshold: () => setCommandAutoCompactThreshold,
|
|
194
225
|
setCurrentProvider: () => setCurrentProvider,
|
|
195
226
|
storeAgentToolDeps: () => storeAgentToolDeps,
|
|
196
227
|
submitProviderSetupValue: () => submitProviderSetupValue,
|
|
197
228
|
substituteVariables: () => substituteVariables,
|
|
229
|
+
suggestProviderProfileName: () => suggestProviderProfileName,
|
|
198
230
|
summarizeBackgroundJobGroup: () => summarizeBackgroundJobGroup,
|
|
199
231
|
testProviderProfileCommand: () => testProviderProfileCommand,
|
|
232
|
+
toContextReferenceRecords: () => toContextReferenceRecords,
|
|
233
|
+
toPromptFileReferenceRecords: () => toPromptFileReferenceRecords,
|
|
200
234
|
transitionBackgroundTaskStatus: () => import_agent_runtime4.transitionBackgroundTaskStatus,
|
|
201
235
|
transitionSelfHostingLoop: () => transitionSelfHostingLoop,
|
|
202
236
|
updateTaskFileStatus: () => updateTaskFileStatus,
|
|
237
|
+
upsertContextReference: () => upsertContextReference,
|
|
203
238
|
upsertProviderProfile: () => upsertProviderProfile,
|
|
204
239
|
userPaths: () => userPaths,
|
|
240
|
+
validateCommandSessionReplayLog: () => validateCommandSessionReplayLog,
|
|
205
241
|
validateProviderProfile: () => validateProviderProfile,
|
|
206
242
|
validateProviderSetupValue: () => validateProviderSetupValue,
|
|
207
243
|
wrapEditCheckpointTools: () => wrapEditCheckpointTools,
|
|
@@ -212,6 +248,7 @@ __export(index_exports, {
|
|
|
212
248
|
module.exports = __toCommonJS(index_exports);
|
|
213
249
|
|
|
214
250
|
// src/interactive/interactive-session.ts
|
|
251
|
+
var import_node_crypto5 = require("crypto");
|
|
215
252
|
var import_agent_core7 = require("@robota-sdk/agent-core");
|
|
216
253
|
|
|
217
254
|
// src/commands/capability-descriptors.ts
|
|
@@ -223,7 +260,7 @@ function inferKind(command) {
|
|
|
223
260
|
function commandToCapabilityDescriptor(command) {
|
|
224
261
|
const skillLike = command.source === "skill" || command.source === "plugin" && Boolean(command.skillContent);
|
|
225
262
|
return {
|
|
226
|
-
name:
|
|
263
|
+
name: command.name,
|
|
227
264
|
kind: inferKind(command),
|
|
228
265
|
description: command.description,
|
|
229
266
|
userInvocable: command.userInvocable !== false,
|
|
@@ -316,7 +353,7 @@ var SystemCommandExecutor = class {
|
|
|
316
353
|
}
|
|
317
354
|
listModelInvocableCommands() {
|
|
318
355
|
return this.listCommands().filter((command) => command.modelInvocable === true).map((command) => ({
|
|
319
|
-
name:
|
|
356
|
+
name: command.name,
|
|
320
357
|
kind: "builtin-command",
|
|
321
358
|
description: command.description,
|
|
322
359
|
userInvocable: command.userInvocable !== false,
|
|
@@ -425,6 +462,32 @@ function setCurrentProvider(settings, profileName) {
|
|
|
425
462
|
currentProvider: profileName
|
|
426
463
|
};
|
|
427
464
|
}
|
|
465
|
+
function deleteProviderProfile(settings, profileName, options = {}) {
|
|
466
|
+
if (!settings.providers?.[profileName]) {
|
|
467
|
+
throw new Error(`Provider profile "${profileName}" was not found`);
|
|
468
|
+
}
|
|
469
|
+
const providers = { ...settings.providers };
|
|
470
|
+
delete providers[profileName];
|
|
471
|
+
if (options.replacementCurrentProvider !== void 0 && providers[options.replacementCurrentProvider] === void 0) {
|
|
472
|
+
throw new Error(`Provider profile "${options.replacementCurrentProvider}" was not found`);
|
|
473
|
+
}
|
|
474
|
+
const next = {
|
|
475
|
+
...settings,
|
|
476
|
+
providers
|
|
477
|
+
};
|
|
478
|
+
if (settings.currentProvider !== profileName) {
|
|
479
|
+
return next;
|
|
480
|
+
}
|
|
481
|
+
if (options.replacementCurrentProvider !== void 0) {
|
|
482
|
+
return {
|
|
483
|
+
...next,
|
|
484
|
+
currentProvider: options.replacementCurrentProvider
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
const withoutCurrentProvider = { ...next };
|
|
488
|
+
delete withoutCurrentProvider.currentProvider;
|
|
489
|
+
return withoutCurrentProvider;
|
|
490
|
+
}
|
|
428
491
|
function validateProviderProfile(profileName, profile, options = {}) {
|
|
429
492
|
if (!profile.type) {
|
|
430
493
|
throw new Error(`Provider profile "${profileName}" is missing type`);
|
|
@@ -433,8 +496,11 @@ function validateProviderProfile(profileName, profile, options = {}) {
|
|
|
433
496
|
throw new Error(`Provider profile "${profileName}" is missing model`);
|
|
434
497
|
}
|
|
435
498
|
const definition = (0, import_agent_core.findProviderDefinition)(options.providerDefinitions ?? [], profile.type);
|
|
436
|
-
|
|
437
|
-
|
|
499
|
+
const credentialRequirement = (0, import_agent_core.getProviderCredentialRequirement)(definition);
|
|
500
|
+
if (credentialRequirement !== void 0 && !hasUsableRequiredProviderCredential(profile, definition?.defaults, credentialRequirement)) {
|
|
501
|
+
throw new Error(
|
|
502
|
+
`Provider profile "${profileName}" is missing ${formatCredentialRequirement(credentialRequirement)}`
|
|
503
|
+
);
|
|
438
504
|
}
|
|
439
505
|
}
|
|
440
506
|
function buildProviderSetupPatch(input, options = {}) {
|
|
@@ -454,7 +520,7 @@ function buildProviderProfile(input, options = {}) {
|
|
|
454
520
|
return {
|
|
455
521
|
type: input.type,
|
|
456
522
|
model: input.model ?? defaults.model,
|
|
457
|
-
...apiKey
|
|
523
|
+
...isNonEmptyString(apiKey) && { apiKey },
|
|
458
524
|
...baseURL !== void 0 && { baseURL },
|
|
459
525
|
...input.timeout !== void 0 && { timeout: input.timeout }
|
|
460
526
|
};
|
|
@@ -470,6 +536,20 @@ function mergeProviderPatch(settings, patch) {
|
|
|
470
536
|
function getProviderDefaults(type, providerDefinitions) {
|
|
471
537
|
return (0, import_agent_core.findProviderDefinition)(providerDefinitions, type)?.defaults ?? {};
|
|
472
538
|
}
|
|
539
|
+
function hasUsableRequiredProviderCredential(profile, defaults, requirement) {
|
|
540
|
+
return requirement.anyOf.some(
|
|
541
|
+
(field) => hasUsableSecretReference(resolveProviderCredentialValue(field, profile, defaults))
|
|
542
|
+
);
|
|
543
|
+
}
|
|
544
|
+
function resolveProviderCredentialValue(field, profile, defaults) {
|
|
545
|
+
return profile[field] ?? defaults?.[field];
|
|
546
|
+
}
|
|
547
|
+
function formatCredentialRequirement(requirement) {
|
|
548
|
+
return requirement.anyOf.join(" or ");
|
|
549
|
+
}
|
|
550
|
+
function isNonEmptyString(value) {
|
|
551
|
+
return value !== void 0 && value.length > 0;
|
|
552
|
+
}
|
|
473
553
|
|
|
474
554
|
// src/command-api/provider/provider-command-probe.ts
|
|
475
555
|
async function testProviderProfileCommand(currentProvider, providers, profileArg, options) {
|
|
@@ -702,18 +782,64 @@ async function compactCommandContext(context, instructions) {
|
|
|
702
782
|
const after = readCommandContextState(context);
|
|
703
783
|
return { before, after };
|
|
704
784
|
}
|
|
785
|
+
function listCommandContextReferences(context) {
|
|
786
|
+
return context.listContextReferences?.() ?? [];
|
|
787
|
+
}
|
|
788
|
+
async function addCommandContextReference(context, path) {
|
|
789
|
+
if (!context.addContextReference) {
|
|
790
|
+
return {
|
|
791
|
+
evicted: [],
|
|
792
|
+
diagnostics: ["Command host does not support context reference additions."]
|
|
793
|
+
};
|
|
794
|
+
}
|
|
795
|
+
return context.addContextReference(path);
|
|
796
|
+
}
|
|
797
|
+
function removeCommandContextReference(context, path) {
|
|
798
|
+
return context.removeContextReference?.(path) ?? {};
|
|
799
|
+
}
|
|
800
|
+
function clearCommandContextReferences(context) {
|
|
801
|
+
return context.clearContextReferences?.() ?? { removed: [] };
|
|
802
|
+
}
|
|
705
803
|
function getSettingsAdapter(context) {
|
|
706
804
|
return context.getCommandHostAdapters?.().settings;
|
|
707
805
|
}
|
|
708
806
|
|
|
807
|
+
// src/command-api/provider/provider-profile-names.ts
|
|
808
|
+
var FALLBACK_PROFILE_NAME = "provider";
|
|
809
|
+
var FIRST_DUPLICATE_SUFFIX = 2;
|
|
810
|
+
function suggestProviderProfileName(input, options = {}) {
|
|
811
|
+
const baseName = sanitizeProviderProfileName(input.model) ?? sanitizeProviderProfileName(input.type) ?? FALLBACK_PROFILE_NAME;
|
|
812
|
+
const existing = new Set(options.existingProfileNames ?? []);
|
|
813
|
+
if (!existing.has(baseName)) {
|
|
814
|
+
return baseName;
|
|
815
|
+
}
|
|
816
|
+
let suffix = FIRST_DUPLICATE_SUFFIX;
|
|
817
|
+
while (existing.has(`${baseName}-${suffix}`)) {
|
|
818
|
+
suffix += 1;
|
|
819
|
+
}
|
|
820
|
+
return `${baseName}-${suffix}`;
|
|
821
|
+
}
|
|
822
|
+
function sanitizeProviderProfileName(value) {
|
|
823
|
+
const normalized = value?.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
824
|
+
return normalized !== void 0 && normalized.length > 0 ? normalized : void 0;
|
|
825
|
+
}
|
|
826
|
+
|
|
709
827
|
// src/command-api/provider/provider-setup-flow.ts
|
|
710
828
|
var import_agent_core3 = require("@robota-sdk/agent-core");
|
|
711
|
-
function createProviderSetupFlow(type, providerDefinitions) {
|
|
829
|
+
function createProviderSetupFlow(type, providerDefinitions, options = {}) {
|
|
830
|
+
const definition = getProviderSetupDefinition(type, providerDefinitions);
|
|
712
831
|
return {
|
|
713
832
|
type,
|
|
714
|
-
steps:
|
|
833
|
+
steps: applyProviderSetupInitialValues(
|
|
834
|
+
getProviderSetupSteps(definition),
|
|
835
|
+
options.initialValues
|
|
836
|
+
),
|
|
837
|
+
setupHelpLinks: definition.setupHelpLinks ?? [],
|
|
715
838
|
stepIndex: 0,
|
|
716
|
-
values: {}
|
|
839
|
+
values: {},
|
|
840
|
+
existingProfileNames: options.existingProfileNames ?? [],
|
|
841
|
+
...options.profileName !== void 0 ? { profileName: options.profileName } : {},
|
|
842
|
+
...options.setCurrent !== void 0 ? { setCurrent: options.setCurrent } : {}
|
|
717
843
|
};
|
|
718
844
|
}
|
|
719
845
|
function formatProviderSetupSelectionPrompt(providerDefinitions) {
|
|
@@ -774,12 +900,15 @@ function submitProviderSetupValue(state, rawValue) {
|
|
|
774
900
|
}
|
|
775
901
|
return { status: "complete", input: buildProviderSetupInput(nextState) };
|
|
776
902
|
}
|
|
777
|
-
async function runProviderSetupPromptFlow(type, promptInput, providerDefinitions) {
|
|
778
|
-
let state = createProviderSetupFlow(type, providerDefinitions);
|
|
903
|
+
async function runProviderSetupPromptFlow(type, promptInput, providerDefinitions, options = {}) {
|
|
904
|
+
let state = createProviderSetupFlow(type, providerDefinitions, options);
|
|
779
905
|
const stepCount = state.steps.length;
|
|
780
906
|
while (state.stepIndex < stepCount) {
|
|
781
907
|
const step = getProviderSetupStep(state);
|
|
782
|
-
const value = await promptInput(
|
|
908
|
+
const value = await promptInput(
|
|
909
|
+
formatProviderSetupPromptLabel(step, state.setupHelpLinks),
|
|
910
|
+
step.masked === true
|
|
911
|
+
);
|
|
783
912
|
const result = submitProviderSetupValue(state, value);
|
|
784
913
|
if (result.status === "complete") {
|
|
785
914
|
return result.input;
|
|
@@ -791,14 +920,25 @@ async function runProviderSetupPromptFlow(type, promptInput, providerDefinitions
|
|
|
791
920
|
}
|
|
792
921
|
throw new Error("Provider setup flow ended without completion");
|
|
793
922
|
}
|
|
794
|
-
function formatProviderSetupPromptLabel(step) {
|
|
923
|
+
function formatProviderSetupPromptLabel(step, setupHelpLinks = []) {
|
|
795
924
|
const suffix = step.defaultValue !== void 0 ? ` (default: ${step.defaultValue})` : "";
|
|
796
|
-
|
|
925
|
+
const setupHelp = formatProviderSetupHelpLinks(setupHelpLinks);
|
|
926
|
+
const prefix = setupHelp.length > 0 ? `${setupHelp}
|
|
927
|
+
` : "";
|
|
928
|
+
return `${prefix} ${step.title}${suffix}: `;
|
|
797
929
|
}
|
|
798
930
|
function formatProviderSetupChoiceLabel(definition) {
|
|
799
931
|
const label = definition.displayName !== void 0 ? `${definition.displayName} (${definition.type})` : definition.type;
|
|
800
932
|
return definition.description !== void 0 ? `${label} - ${definition.description}` : label;
|
|
801
933
|
}
|
|
934
|
+
function formatProviderSetupHelpLinks(setupHelpLinks = []) {
|
|
935
|
+
if (setupHelpLinks.length === 0) {
|
|
936
|
+
return "";
|
|
937
|
+
}
|
|
938
|
+
return setupHelpLinks.map(
|
|
939
|
+
(link) => ` Setup help: ${formatProviderSetupHelpLinkKind(link.kind)}: ${link.label} - ${link.url}`
|
|
940
|
+
).join("\n");
|
|
941
|
+
}
|
|
802
942
|
function parseProviderSelectionIndex(value) {
|
|
803
943
|
if (!/^\d+$/.test(value)) {
|
|
804
944
|
return void 0;
|
|
@@ -811,13 +951,16 @@ function validateProviderSetupValue(step, value) {
|
|
|
811
951
|
}
|
|
812
952
|
return void 0;
|
|
813
953
|
}
|
|
814
|
-
function
|
|
954
|
+
function getProviderSetupDefinition(type, providerDefinitions) {
|
|
815
955
|
const definition = (0, import_agent_core3.findProviderDefinition)(providerDefinitions, type);
|
|
816
956
|
if (definition === void 0) {
|
|
817
957
|
throw new Error(
|
|
818
958
|
`Unknown provider: ${type}. Currently supported: ${(0, import_agent_core3.formatSupportedProviderTypes)(providerDefinitions)}`
|
|
819
959
|
);
|
|
820
960
|
}
|
|
961
|
+
return definition;
|
|
962
|
+
}
|
|
963
|
+
function getProviderSetupSteps(definition) {
|
|
821
964
|
if (definition.setupSteps !== void 0) {
|
|
822
965
|
return [...definition.setupSteps];
|
|
823
966
|
}
|
|
@@ -847,14 +990,44 @@ function getProviderSetupSteps(type, providerDefinitions) {
|
|
|
847
990
|
}
|
|
848
991
|
return steps;
|
|
849
992
|
}
|
|
993
|
+
function formatProviderSetupHelpLinkKind(kind) {
|
|
994
|
+
if (kind === "api-key") {
|
|
995
|
+
return "API key";
|
|
996
|
+
}
|
|
997
|
+
if (kind === "console") {
|
|
998
|
+
return "Console";
|
|
999
|
+
}
|
|
1000
|
+
return "Official";
|
|
1001
|
+
}
|
|
1002
|
+
function applyProviderSetupInitialValues(steps, initialValues) {
|
|
1003
|
+
if (initialValues === void 0) {
|
|
1004
|
+
return [...steps];
|
|
1005
|
+
}
|
|
1006
|
+
return steps.map((step) => {
|
|
1007
|
+
const initialValue = initialValues[step.key];
|
|
1008
|
+
if (initialValue === void 0) {
|
|
1009
|
+
return step;
|
|
1010
|
+
}
|
|
1011
|
+
return {
|
|
1012
|
+
...step,
|
|
1013
|
+
defaultValue: initialValue,
|
|
1014
|
+
required: false
|
|
1015
|
+
};
|
|
1016
|
+
});
|
|
1017
|
+
}
|
|
850
1018
|
function buildProviderSetupInput(state) {
|
|
1019
|
+
const profile = state.profileName ?? suggestProviderProfileName(
|
|
1020
|
+
{ type: state.type, model: state.values.model },
|
|
1021
|
+
{ existingProfileNames: state.existingProfileNames }
|
|
1022
|
+
);
|
|
1023
|
+
const apiKey = state.values.apiKey;
|
|
851
1024
|
return {
|
|
852
|
-
profile
|
|
1025
|
+
profile,
|
|
853
1026
|
type: state.type,
|
|
854
1027
|
model: state.values.model,
|
|
855
|
-
apiKey
|
|
1028
|
+
...apiKey !== void 0 && apiKey.length > 0 && { apiKey },
|
|
856
1029
|
...state.values.baseURL !== void 0 && { baseURL: state.values.baseURL },
|
|
857
|
-
setCurrent: true
|
|
1030
|
+
setCurrent: state.setCurrent ?? true
|
|
858
1031
|
};
|
|
859
1032
|
}
|
|
860
1033
|
|
|
@@ -943,7 +1116,67 @@ function closeCommandBackgroundTask(context, taskId) {
|
|
|
943
1116
|
var import_agent_core4 = require("@robota-sdk/agent-core");
|
|
944
1117
|
var MODEL_COMMAND_DESCRIPTION = "Change AI model";
|
|
945
1118
|
var MODEL_COMMAND_ARGUMENT_HINT = "<model-id>";
|
|
946
|
-
function buildModelCommandSubcommands(
|
|
1119
|
+
function buildModelCommandSubcommands(sourceOrOptions = "model") {
|
|
1120
|
+
const options = typeof sourceOrOptions === "string" ? { source: sourceOrOptions } : sourceOrOptions;
|
|
1121
|
+
const source = options.source ?? "model";
|
|
1122
|
+
const catalog = resolveActiveProviderModelCatalog(options.settings, options.providerDefinitions);
|
|
1123
|
+
if (catalog !== void 0) {
|
|
1124
|
+
return buildCatalogSubcommands(catalog, source);
|
|
1125
|
+
}
|
|
1126
|
+
if (options.settings !== void 0) {
|
|
1127
|
+
return [];
|
|
1128
|
+
}
|
|
1129
|
+
return buildClaudeModelSubcommands(source);
|
|
1130
|
+
}
|
|
1131
|
+
function formatModelCommandUsageMessage(options = {}) {
|
|
1132
|
+
const snapshot = resolveActiveProviderModelCatalogSnapshot(
|
|
1133
|
+
options.settings,
|
|
1134
|
+
options.providerDefinitions
|
|
1135
|
+
);
|
|
1136
|
+
return formatModelUsageMessage(snapshot === void 0 ? void 0 : toCatalogState(snapshot));
|
|
1137
|
+
}
|
|
1138
|
+
async function formatModelCommandUsageMessageAsync(options = {}) {
|
|
1139
|
+
return formatModelUsageMessage(await resolveActiveProviderModelCatalogState(options));
|
|
1140
|
+
}
|
|
1141
|
+
function resolveActiveProviderModelCatalog(settings, providerDefinitions = []) {
|
|
1142
|
+
return resolveActiveProviderModelCatalogSnapshot(settings, providerDefinitions)?.catalog;
|
|
1143
|
+
}
|
|
1144
|
+
async function resolveActiveProviderModelCatalogState(options) {
|
|
1145
|
+
const snapshot = resolveActiveProviderModelCatalogSnapshot(
|
|
1146
|
+
options.settings,
|
|
1147
|
+
options.providerDefinitions
|
|
1148
|
+
);
|
|
1149
|
+
if (snapshot === void 0) return void 0;
|
|
1150
|
+
if (options.refresh !== true || snapshot.definition?.refreshModelCatalog === void 0) {
|
|
1151
|
+
return toCatalogState(snapshot);
|
|
1152
|
+
}
|
|
1153
|
+
try {
|
|
1154
|
+
const refreshed = await snapshot.definition.refreshModelCatalog({
|
|
1155
|
+
profile: resolveRefreshProfile(snapshot)
|
|
1156
|
+
});
|
|
1157
|
+
if (refreshed.status !== "unavailable") {
|
|
1158
|
+
return {
|
|
1159
|
+
providerType: snapshot.providerType,
|
|
1160
|
+
catalog: refreshed,
|
|
1161
|
+
refreshAttempted: true
|
|
1162
|
+
};
|
|
1163
|
+
}
|
|
1164
|
+
return {
|
|
1165
|
+
providerType: snapshot.providerType,
|
|
1166
|
+
catalog: snapshot.catalog ?? refreshed,
|
|
1167
|
+
refreshAttempted: true,
|
|
1168
|
+
...refreshed.message !== void 0 ? { refreshMessage: refreshed.message } : {}
|
|
1169
|
+
};
|
|
1170
|
+
} catch (error) {
|
|
1171
|
+
return {
|
|
1172
|
+
providerType: snapshot.providerType,
|
|
1173
|
+
...snapshot.catalog !== void 0 ? { catalog: snapshot.catalog } : {},
|
|
1174
|
+
refreshAttempted: true,
|
|
1175
|
+
refreshMessage: error instanceof Error ? error.message : String(error)
|
|
1176
|
+
};
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
function buildClaudeModelSubcommands(source) {
|
|
947
1180
|
const seen = /* @__PURE__ */ new Set();
|
|
948
1181
|
const commands = [];
|
|
949
1182
|
for (const model of Object.values(import_agent_core4.CLAUDE_MODELS)) {
|
|
@@ -957,6 +1190,97 @@ function buildModelCommandSubcommands(source = "model") {
|
|
|
957
1190
|
}
|
|
958
1191
|
return commands;
|
|
959
1192
|
}
|
|
1193
|
+
function buildCatalogSubcommands(catalog, source) {
|
|
1194
|
+
return (catalog.entries ?? []).filter((entry) => entry.lifecycle !== "unavailable").map((entry) => ({
|
|
1195
|
+
name: entry.id,
|
|
1196
|
+
description: formatCatalogEntryDescription(entry),
|
|
1197
|
+
source
|
|
1198
|
+
}));
|
|
1199
|
+
}
|
|
1200
|
+
function formatCatalogEntryDescription(entry) {
|
|
1201
|
+
if (entry.contextWindow === void 0) {
|
|
1202
|
+
return entry.displayName;
|
|
1203
|
+
}
|
|
1204
|
+
return `${entry.displayName} (${(0, import_agent_core4.formatTokenCount)(entry.contextWindow).toUpperCase()})`;
|
|
1205
|
+
}
|
|
1206
|
+
function resolveActiveProviderModelCatalogSnapshot(settings, providerDefinitions = []) {
|
|
1207
|
+
const profile = resolveActiveProviderProfile(settings);
|
|
1208
|
+
const providerType = profile?.type ?? profile?.name;
|
|
1209
|
+
if (providerType === void 0) {
|
|
1210
|
+
return void 0;
|
|
1211
|
+
}
|
|
1212
|
+
const definition = (0, import_agent_core4.findProviderDefinition)(providerDefinitions, providerType);
|
|
1213
|
+
return {
|
|
1214
|
+
providerType,
|
|
1215
|
+
...profile !== void 0 ? { profile } : {},
|
|
1216
|
+
...definition !== void 0 ? { definition } : {},
|
|
1217
|
+
...definition?.modelCatalog !== void 0 ? { catalog: definition.modelCatalog } : {}
|
|
1218
|
+
};
|
|
1219
|
+
}
|
|
1220
|
+
function resolveActiveProviderProfile(settings) {
|
|
1221
|
+
if (settings?.currentProvider !== void 0) {
|
|
1222
|
+
return settings.providers?.[settings.currentProvider];
|
|
1223
|
+
}
|
|
1224
|
+
return settings?.provider;
|
|
1225
|
+
}
|
|
1226
|
+
function toCatalogState(snapshot) {
|
|
1227
|
+
return {
|
|
1228
|
+
providerType: snapshot.providerType,
|
|
1229
|
+
...snapshot.catalog !== void 0 ? { catalog: snapshot.catalog } : {},
|
|
1230
|
+
refreshAttempted: false
|
|
1231
|
+
};
|
|
1232
|
+
}
|
|
1233
|
+
function resolveRefreshProfile(snapshot) {
|
|
1234
|
+
const profile = snapshot.profile;
|
|
1235
|
+
const defaults = snapshot.definition?.defaults;
|
|
1236
|
+
const apiKey = resolveOptionalEnvReference(profile?.apiKey ?? defaults?.apiKey);
|
|
1237
|
+
const model = resolveProfileValue(profile?.model, defaults?.model);
|
|
1238
|
+
const baseURL = resolveProfileValue(profile?.baseURL, defaults?.baseURL);
|
|
1239
|
+
const timeout = resolveProfileValue(profile?.timeout, defaults?.timeout);
|
|
1240
|
+
const options = resolveProfileValue(profile?.options, defaults?.options);
|
|
1241
|
+
const refreshProfile = {
|
|
1242
|
+
type: profile?.type ?? snapshot.providerType
|
|
1243
|
+
};
|
|
1244
|
+
if (model !== void 0) refreshProfile.model = model;
|
|
1245
|
+
if (apiKey !== void 0) refreshProfile.apiKey = apiKey;
|
|
1246
|
+
if (baseURL !== void 0) refreshProfile.baseURL = baseURL;
|
|
1247
|
+
if (timeout !== void 0) refreshProfile.timeout = timeout;
|
|
1248
|
+
if (options !== void 0) refreshProfile.options = options;
|
|
1249
|
+
return refreshProfile;
|
|
1250
|
+
}
|
|
1251
|
+
function resolveProfileValue(profileValue, defaultValue) {
|
|
1252
|
+
return profileValue ?? defaultValue;
|
|
1253
|
+
}
|
|
1254
|
+
function resolveOptionalEnvReference(value) {
|
|
1255
|
+
return value === void 0 ? void 0 : resolveEnvReference(value);
|
|
1256
|
+
}
|
|
1257
|
+
function formatModelUsageMessage(active) {
|
|
1258
|
+
const base = active?.providerType !== void 0 && (active.catalog?.entries === void 0 || active.catalog.entries.length === 0) ? `No model catalog available for provider ${active.providerType}. Usage: model <model-id>` : "Usage: model <model-id>";
|
|
1259
|
+
const freshness = formatCatalogFreshness(active);
|
|
1260
|
+
return freshness === void 0 ? base : `${base}
|
|
1261
|
+
${freshness}`;
|
|
1262
|
+
}
|
|
1263
|
+
function formatCatalogFreshness(active) {
|
|
1264
|
+
const catalog = active?.catalog;
|
|
1265
|
+
if (catalog === void 0) return void 0;
|
|
1266
|
+
const parts = [`Catalog: ${catalog.status}`];
|
|
1267
|
+
if (catalog.entries !== void 0) {
|
|
1268
|
+
parts.push(`${catalog.entries.length} model(s)`);
|
|
1269
|
+
}
|
|
1270
|
+
if (catalog.lastVerifiedAt !== void 0) {
|
|
1271
|
+
parts.push(`verified ${catalog.lastVerifiedAt}`);
|
|
1272
|
+
}
|
|
1273
|
+
if (catalog.sourceUrl !== void 0) {
|
|
1274
|
+
parts.push(`source ${catalog.sourceUrl}`);
|
|
1275
|
+
}
|
|
1276
|
+
const refreshMessage = active?.refreshMessage;
|
|
1277
|
+
if (refreshMessage !== void 0) {
|
|
1278
|
+
parts.push(`refresh ${refreshMessage}`);
|
|
1279
|
+
} else if (catalog.message !== void 0) {
|
|
1280
|
+
parts.push(catalog.message);
|
|
1281
|
+
}
|
|
1282
|
+
return parts.join("; ");
|
|
1283
|
+
}
|
|
960
1284
|
|
|
961
1285
|
// src/command-api/language/language-command-api.ts
|
|
962
1286
|
var LANGUAGE_COMMAND_DESCRIPTION = "Set response language";
|
|
@@ -985,7 +1309,7 @@ function formatLanguageUsageMessage(commandName = "language") {
|
|
|
985
1309
|
// src/command-api/permissions/permission-mode-command-api.ts
|
|
986
1310
|
var PERMISSION_MODE_COMMAND_DESCRIPTION = "Show/change permission mode";
|
|
987
1311
|
var PERMISSION_MODE_ARGUMENT_HINT = "plan | default | acceptEdits | bypassPermissions";
|
|
988
|
-
var PERMISSIONS_COMMAND_DESCRIPTION = "Show permission rules";
|
|
1312
|
+
var PERMISSIONS_COMMAND_DESCRIPTION = "Show/change permission mode and permission rules";
|
|
989
1313
|
var VALID_PERMISSION_MODES = [
|
|
990
1314
|
"plan",
|
|
991
1315
|
"default",
|
|
@@ -1100,12 +1424,39 @@ function buildPluginCommandSubcommands() {
|
|
|
1100
1424
|
];
|
|
1101
1425
|
}
|
|
1102
1426
|
|
|
1427
|
+
// src/command-api/session/session-command-api.ts
|
|
1428
|
+
var import_node_path3 = require("path");
|
|
1429
|
+
var import_agent_sessions2 = require("@robota-sdk/agent-sessions");
|
|
1430
|
+
|
|
1431
|
+
// src/paths.ts
|
|
1432
|
+
var import_node_path2 = require("path");
|
|
1433
|
+
var import_node_os2 = require("os");
|
|
1434
|
+
function projectPaths(cwd) {
|
|
1435
|
+
const base = (0, import_node_path2.join)(cwd, ".robota");
|
|
1436
|
+
return {
|
|
1437
|
+
settings: (0, import_node_path2.join)(base, "settings.json"),
|
|
1438
|
+
settingsLocal: (0, import_node_path2.join)(base, "settings.local.json"),
|
|
1439
|
+
logs: (0, import_node_path2.join)(base, "logs"),
|
|
1440
|
+
sessions: (0, import_node_path2.join)(base, "sessions"),
|
|
1441
|
+
memory: (0, import_node_path2.join)(base, "memory"),
|
|
1442
|
+
checkpoints: (0, import_node_path2.join)(base, "checkpoints")
|
|
1443
|
+
};
|
|
1444
|
+
}
|
|
1445
|
+
function userPaths() {
|
|
1446
|
+
const base = (0, import_node_path2.join)((0, import_node_os2.homedir)(), ".robota");
|
|
1447
|
+
return {
|
|
1448
|
+
settings: (0, import_node_path2.join)(base, "settings.json"),
|
|
1449
|
+
sessions: (0, import_node_path2.join)(base, "sessions")
|
|
1450
|
+
};
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1103
1453
|
// src/command-api/session/session-command-api.ts
|
|
1104
1454
|
var CLEAR_COMMAND_DESCRIPTION = "Clear conversation history";
|
|
1105
1455
|
var RENAME_COMMAND_DESCRIPTION = "Rename the current session";
|
|
1106
1456
|
var RENAME_COMMAND_USAGE = "Usage: rename <name>";
|
|
1107
1457
|
var RESUME_COMMAND_DESCRIPTION = "Resume a previous session";
|
|
1108
1458
|
var COST_COMMAND_DESCRIPTION = "Show session info";
|
|
1459
|
+
var VALIDATE_SESSION_COMMAND_DESCRIPTION = "Validate current session replay log";
|
|
1109
1460
|
var EXIT_COMMAND_DESCRIPTION = "Exit CLI";
|
|
1110
1461
|
function clearConversationHistory(context) {
|
|
1111
1462
|
if (context.clearConversationHistory !== void 0) {
|
|
@@ -1134,6 +1485,45 @@ function readCommandSessionInfo(context) {
|
|
|
1134
1485
|
messageCount: session.getMessageCount()
|
|
1135
1486
|
};
|
|
1136
1487
|
}
|
|
1488
|
+
function validateCommandSessionReplayLog(context) {
|
|
1489
|
+
const hostReport = context.validateCurrentSessionReplayLog?.();
|
|
1490
|
+
if (hostReport !== void 0) {
|
|
1491
|
+
return hostReport;
|
|
1492
|
+
}
|
|
1493
|
+
const sessionId = context.getSession().getSessionId();
|
|
1494
|
+
const logFile = (0, import_node_path3.join)(projectPaths(context.getCwd()).logs, `${sessionId}.jsonl`);
|
|
1495
|
+
const entries = (0, import_agent_sessions2.loadSessionLogEntries)(logFile);
|
|
1496
|
+
return {
|
|
1497
|
+
logFile,
|
|
1498
|
+
entryCount: entries.length,
|
|
1499
|
+
validation: (0, import_agent_sessions2.validateSessionReplayLogEntries)(entries)
|
|
1500
|
+
};
|
|
1501
|
+
}
|
|
1502
|
+
function formatCommandSessionReplayValidationReport(report) {
|
|
1503
|
+
const header = report.validation.ok ? "Session replay log is valid." : `Session replay log has ${report.validation.issues.length} issue(s).`;
|
|
1504
|
+
const details = [`Log: ${report.logFile}`, `Entries: ${report.entryCount}`];
|
|
1505
|
+
if (report.validation.ok) {
|
|
1506
|
+
return [header, ...details].join("\n");
|
|
1507
|
+
}
|
|
1508
|
+
const issueLines = report.validation.issues.map((issue, index) => {
|
|
1509
|
+
const location = formatReplayValidationIssueLocation(issue);
|
|
1510
|
+
return `${index + 1}. ${issue.code}${location}: ${issue.message}`;
|
|
1511
|
+
});
|
|
1512
|
+
return [header, ...details, "", ...issueLines].join("\n");
|
|
1513
|
+
}
|
|
1514
|
+
function formatReplayValidationIssueLocation(issue) {
|
|
1515
|
+
const parts = [];
|
|
1516
|
+
if (issue.executionId !== void 0) {
|
|
1517
|
+
parts.push(`execution=${issue.executionId}`);
|
|
1518
|
+
}
|
|
1519
|
+
if (issue.round !== void 0) {
|
|
1520
|
+
parts.push(`round=${issue.round}`);
|
|
1521
|
+
}
|
|
1522
|
+
if (issue.toolCallId !== void 0) {
|
|
1523
|
+
parts.push(`tool=${issue.toolCallId}`);
|
|
1524
|
+
}
|
|
1525
|
+
return parts.length > 0 ? ` (${parts.join(", ")})` : "";
|
|
1526
|
+
}
|
|
1137
1527
|
|
|
1138
1528
|
// src/command-api/checkpoint/rewind-command-api.ts
|
|
1139
1529
|
var REWIND_COMMAND_DESCRIPTION = "List, inspect, restore, or rollback edit checkpoints.";
|
|
@@ -1176,10 +1566,10 @@ function containsSensitiveMemoryContent(text) {
|
|
|
1176
1566
|
|
|
1177
1567
|
// src/memory/pending-memory-store.ts
|
|
1178
1568
|
var import_node_fs2 = require("fs");
|
|
1179
|
-
var
|
|
1569
|
+
var import_node_path4 = require("path");
|
|
1180
1570
|
var PENDING_FILENAME = "pending.json";
|
|
1181
1571
|
function memoryRoot(cwd) {
|
|
1182
|
-
return (0,
|
|
1572
|
+
return (0, import_node_path4.join)(cwd, ".robota", "memory");
|
|
1183
1573
|
}
|
|
1184
1574
|
function emptyDocument() {
|
|
1185
1575
|
return { version: 1, records: [] };
|
|
@@ -1188,7 +1578,7 @@ var PendingMemoryStore = class {
|
|
|
1188
1578
|
path;
|
|
1189
1579
|
now;
|
|
1190
1580
|
constructor(cwd, now = () => /* @__PURE__ */ new Date()) {
|
|
1191
|
-
this.path = (0,
|
|
1581
|
+
this.path = (0, import_node_path4.join)(memoryRoot(cwd), PENDING_FILENAME);
|
|
1192
1582
|
this.now = now;
|
|
1193
1583
|
}
|
|
1194
1584
|
getPath() {
|
|
@@ -1242,7 +1632,7 @@ var PendingMemoryStore = class {
|
|
|
1242
1632
|
}
|
|
1243
1633
|
}
|
|
1244
1634
|
write(document) {
|
|
1245
|
-
(0, import_node_fs2.mkdirSync)((0,
|
|
1635
|
+
(0, import_node_fs2.mkdirSync)((0, import_node_path4.dirname)(this.path), { recursive: true });
|
|
1246
1636
|
(0, import_node_fs2.writeFileSync)(this.path, JSON.stringify(document, null, 2), "utf8");
|
|
1247
1637
|
}
|
|
1248
1638
|
};
|
|
@@ -1455,24 +1845,6 @@ async function preprocessShellCommands(content) {
|
|
|
1455
1845
|
}
|
|
1456
1846
|
return result;
|
|
1457
1847
|
}
|
|
1458
|
-
async function buildSkillPrompt(input, registry, context) {
|
|
1459
|
-
const parts = input.slice(1).split(/\s+/);
|
|
1460
|
-
const cmd = parts[0]?.toLowerCase() ?? "";
|
|
1461
|
-
const skillCmd = registry.getCommands().find((c) => c.name === cmd && (c.source === "skill" || c.source === "plugin"));
|
|
1462
|
-
if (!skillCmd) return null;
|
|
1463
|
-
const args = parts.slice(1).join(" ").trim();
|
|
1464
|
-
const userInstruction = args || skillCmd.description;
|
|
1465
|
-
if (skillCmd.skillContent) {
|
|
1466
|
-
let processed = await preprocessShellCommands(skillCmd.skillContent);
|
|
1467
|
-
processed = substituteVariables(processed, args, context);
|
|
1468
|
-
return `<skill name="${cmd}">
|
|
1469
|
-
${processed}
|
|
1470
|
-
</skill>
|
|
1471
|
-
|
|
1472
|
-
Execute the "${cmd}" skill: ${userInstruction}`;
|
|
1473
|
-
}
|
|
1474
|
-
return `Use the "${cmd}" skill: ${userInstruction}`;
|
|
1475
|
-
}
|
|
1476
1848
|
|
|
1477
1849
|
// src/commands/skill-executor.ts
|
|
1478
1850
|
async function buildProcessedContent(skill, args, context) {
|
|
@@ -1495,7 +1867,9 @@ Execute the "${skill.name}" skill: ${userInstruction}`;
|
|
|
1495
1867
|
async function executeSkill(skill, args, callbacks, context) {
|
|
1496
1868
|
if (skill.context === "fork") {
|
|
1497
1869
|
if (!callbacks.runInFork) {
|
|
1498
|
-
throw new Error(
|
|
1870
|
+
throw new Error(
|
|
1871
|
+
"Fork execution is not available. Agent runtime deps may not be initialized."
|
|
1872
|
+
);
|
|
1499
1873
|
}
|
|
1500
1874
|
const content = await buildProcessedContent(skill, args, context);
|
|
1501
1875
|
const prompt2 = content ?? `Use the "${skill.name}" skill: ${args || skill.description}`;
|
|
@@ -1509,8 +1883,39 @@ async function executeSkill(skill, args, callbacks, context) {
|
|
|
1509
1883
|
return { mode: "inject", prompt };
|
|
1510
1884
|
}
|
|
1511
1885
|
|
|
1886
|
+
// src/commands/skill-activation-events.ts
|
|
1887
|
+
function getSkillActivationSource(skill) {
|
|
1888
|
+
return skill.source === "plugin" ? "plugin" : "skill";
|
|
1889
|
+
}
|
|
1890
|
+
function getSkillActivationMode(skill) {
|
|
1891
|
+
return skill.context === "fork" ? "fork" : "inject";
|
|
1892
|
+
}
|
|
1893
|
+
function createSkillActivationEvent(input) {
|
|
1894
|
+
return {
|
|
1895
|
+
type: "skill-activation",
|
|
1896
|
+
skillName: input.skill.name,
|
|
1897
|
+
source: getSkillActivationSource(input.skill),
|
|
1898
|
+
invocation: input.invocation,
|
|
1899
|
+
mode: getSkillActivationMode(input.skill),
|
|
1900
|
+
status: input.status,
|
|
1901
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1902
|
+
...input.qualifiedName !== void 0 ? { qualifiedName: input.qualifiedName } : {},
|
|
1903
|
+
...input.error !== void 0 ? { error: input.error } : {}
|
|
1904
|
+
};
|
|
1905
|
+
}
|
|
1906
|
+
function formatSkillActivationMessage(event) {
|
|
1907
|
+
const sourceLabel = event.source === "plugin" ? "plugin skill" : "skill";
|
|
1908
|
+
if (event.status === "failed") {
|
|
1909
|
+
return `Skill failed: ${event.skillName}${event.error ? ` (${event.error})` : ""}`;
|
|
1910
|
+
}
|
|
1911
|
+
if (event.status === "completed") {
|
|
1912
|
+
return `Skill completed: ${event.skillName}`;
|
|
1913
|
+
}
|
|
1914
|
+
return `Invoking ${sourceLabel}: ${event.skillName}`;
|
|
1915
|
+
}
|
|
1916
|
+
|
|
1512
1917
|
// src/assembly/create-subagent-session.ts
|
|
1513
|
-
var
|
|
1918
|
+
var import_agent_sessions3 = require("@robota-sdk/agent-sessions");
|
|
1514
1919
|
|
|
1515
1920
|
// src/assembly/subagent-prompts.ts
|
|
1516
1921
|
function getSubagentSuffix() {
|
|
@@ -1541,12 +1946,147 @@ function assembleSubagentPrompt(options) {
|
|
|
1541
1946
|
return parts.join("\n\n");
|
|
1542
1947
|
}
|
|
1543
1948
|
|
|
1949
|
+
// src/tools/model-command-tool-projection.ts
|
|
1950
|
+
var import_node_crypto = require("crypto");
|
|
1951
|
+
var import_zod = require("zod");
|
|
1952
|
+
var import_agent_tools = require("@robota-sdk/agent-tools");
|
|
1953
|
+
var MODEL_COMMAND_TOOL_PREFIX = "robota_command_";
|
|
1954
|
+
var PROVIDER_SAFE_TOOL_NAME_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;
|
|
1955
|
+
var MAX_PROVIDER_TOOL_NAME_LENGTH = 64;
|
|
1956
|
+
var HASH_LENGTH = 8;
|
|
1957
|
+
var HASH_SEPARATOR_LENGTH = 1;
|
|
1958
|
+
function asZodSchema(schema) {
|
|
1959
|
+
return schema;
|
|
1960
|
+
}
|
|
1961
|
+
function normalizeModelCommandName(command) {
|
|
1962
|
+
return command.trim().replace(/^\/+/, "").split(/\s+/)[0] ?? "";
|
|
1963
|
+
}
|
|
1964
|
+
function createProviderSafeModelCommandToolName(commandName) {
|
|
1965
|
+
const normalizedCommandName = normalizeModelCommandName(commandName);
|
|
1966
|
+
if (!normalizedCommandName) {
|
|
1967
|
+
throw new Error("Model command descriptor name must not be empty.");
|
|
1968
|
+
}
|
|
1969
|
+
const safeBody = normalizedCommandName.replace(/[^A-Za-z0-9_-]/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "");
|
|
1970
|
+
if (!safeBody) {
|
|
1971
|
+
throw new Error(`Model command descriptor name cannot be projected safely: ${commandName}`);
|
|
1972
|
+
}
|
|
1973
|
+
const rawToolName = `${MODEL_COMMAND_TOOL_PREFIX}${safeBody}`;
|
|
1974
|
+
if (PROVIDER_SAFE_TOOL_NAME_PATTERN.test(rawToolName)) {
|
|
1975
|
+
return rawToolName;
|
|
1976
|
+
}
|
|
1977
|
+
const hash = (0, import_node_crypto.createHash)("sha256").update(normalizedCommandName).digest("hex").slice(0, HASH_LENGTH);
|
|
1978
|
+
const maxBodyLength = MAX_PROVIDER_TOOL_NAME_LENGTH - MODEL_COMMAND_TOOL_PREFIX.length - HASH_SEPARATOR_LENGTH - HASH_LENGTH;
|
|
1979
|
+
if (maxBodyLength < 1) {
|
|
1980
|
+
throw new Error("Model command tool prefix leaves no room for command names.");
|
|
1981
|
+
}
|
|
1982
|
+
const truncatedBody = safeBody.slice(0, maxBodyLength).replace(/[_-]+$/g, "") || "command";
|
|
1983
|
+
const toolName = `${MODEL_COMMAND_TOOL_PREFIX}${truncatedBody}_${hash}`;
|
|
1984
|
+
if (!PROVIDER_SAFE_TOOL_NAME_PATTERN.test(toolName)) {
|
|
1985
|
+
throw new Error(`Projected model command tool name is not provider-safe: ${toolName}`);
|
|
1986
|
+
}
|
|
1987
|
+
return toolName;
|
|
1988
|
+
}
|
|
1989
|
+
function createModelCommandToolProjection(commandDescriptors) {
|
|
1990
|
+
const commandNames = /* @__PURE__ */ new Set();
|
|
1991
|
+
const toolNameToCommandName = /* @__PURE__ */ new Map();
|
|
1992
|
+
const commandNameToToolName = /* @__PURE__ */ new Map();
|
|
1993
|
+
const commandTools = [];
|
|
1994
|
+
for (const descriptor of commandDescriptors) {
|
|
1995
|
+
const commandName = normalizeModelCommandName(descriptor.name);
|
|
1996
|
+
if (!commandName) {
|
|
1997
|
+
throw new Error("Model command descriptor name must not be empty.");
|
|
1998
|
+
}
|
|
1999
|
+
if (commandNames.has(commandName)) {
|
|
2000
|
+
throw new Error(`Duplicate model command descriptor: ${commandName}`);
|
|
2001
|
+
}
|
|
2002
|
+
commandNames.add(commandName);
|
|
2003
|
+
const toolName = createProviderSafeModelCommandToolName(commandName);
|
|
2004
|
+
const existingCommandName = toolNameToCommandName.get(toolName);
|
|
2005
|
+
if (existingCommandName !== void 0) {
|
|
2006
|
+
throw new Error(
|
|
2007
|
+
`Model command projection collision: ${existingCommandName} and ${commandName} both map to ${toolName}`
|
|
2008
|
+
);
|
|
2009
|
+
}
|
|
2010
|
+
toolNameToCommandName.set(toolName, commandName);
|
|
2011
|
+
commandNameToToolName.set(commandName, toolName);
|
|
2012
|
+
commandTools.push({
|
|
2013
|
+
commandName,
|
|
2014
|
+
toolName,
|
|
2015
|
+
description: formatProjectedModelCommandToolDescription(commandName, descriptor),
|
|
2016
|
+
descriptor
|
|
2017
|
+
});
|
|
2018
|
+
}
|
|
2019
|
+
return {
|
|
2020
|
+
commandTools,
|
|
2021
|
+
toolNameToCommandName,
|
|
2022
|
+
commandNameToToolName
|
|
2023
|
+
};
|
|
2024
|
+
}
|
|
2025
|
+
function formatProjectedModelCommandToolPromptDescription(projection) {
|
|
2026
|
+
return `${projection.toolName} \u2014 ${projection.descriptor.description}`;
|
|
2027
|
+
}
|
|
2028
|
+
function stringifyModelCommandResult(command, result) {
|
|
2029
|
+
if (!result) {
|
|
2030
|
+
return JSON.stringify({
|
|
2031
|
+
success: false,
|
|
2032
|
+
command,
|
|
2033
|
+
error: `Unknown command: ${command}`
|
|
2034
|
+
});
|
|
2035
|
+
}
|
|
2036
|
+
return JSON.stringify({
|
|
2037
|
+
success: result.success,
|
|
2038
|
+
command,
|
|
2039
|
+
message: result.message,
|
|
2040
|
+
data: result.data
|
|
2041
|
+
});
|
|
2042
|
+
}
|
|
2043
|
+
function createProjectedCommandExecutionTools(deps) {
|
|
2044
|
+
const projection = createModelCommandToolProjection(deps.commandDescriptors);
|
|
2045
|
+
return projection.commandTools.map((projectedTool) => {
|
|
2046
|
+
const schema = createProjectedCommandArgsSchema(projectedTool.descriptor);
|
|
2047
|
+
return (0, import_agent_tools.createZodFunctionTool)(
|
|
2048
|
+
projectedTool.toolName,
|
|
2049
|
+
projectedTool.description,
|
|
2050
|
+
asZodSchema(schema),
|
|
2051
|
+
async (params) => {
|
|
2052
|
+
const parsedParams = schema.parse(params);
|
|
2053
|
+
if (!deps.isModelInvocable(projectedTool.commandName)) {
|
|
2054
|
+
return JSON.stringify({
|
|
2055
|
+
success: false,
|
|
2056
|
+
command: projectedTool.commandName,
|
|
2057
|
+
error: `Command is not model-invocable: ${projectedTool.commandName}`
|
|
2058
|
+
});
|
|
2059
|
+
}
|
|
2060
|
+
return stringifyModelCommandResult(
|
|
2061
|
+
projectedTool.commandName,
|
|
2062
|
+
await deps.execute(projectedTool.commandName, parsedParams.args ?? "")
|
|
2063
|
+
);
|
|
2064
|
+
}
|
|
2065
|
+
);
|
|
2066
|
+
});
|
|
2067
|
+
}
|
|
2068
|
+
function createProjectedCommandArgsSchema(descriptor) {
|
|
2069
|
+
const argsDescription = descriptor.argumentHint ? `Arguments for the command. Expected grammar: ${descriptor.argumentHint}` : "Arguments for the command as a single string.";
|
|
2070
|
+
return import_zod.z.object({
|
|
2071
|
+
args: import_zod.z.string().optional().describe(argsDescription)
|
|
2072
|
+
});
|
|
2073
|
+
}
|
|
2074
|
+
function formatProjectedModelCommandToolDescription(commandName, descriptor) {
|
|
2075
|
+
const lines = [descriptor.description.trim(), `Robota command id: ${commandName}.`];
|
|
2076
|
+
if (descriptor.argumentHint) {
|
|
2077
|
+
lines.push(`Argument grammar: ${descriptor.argumentHint}`);
|
|
2078
|
+
}
|
|
2079
|
+
return lines.filter((line) => line.length > 0).join("\n\n");
|
|
2080
|
+
}
|
|
2081
|
+
|
|
1544
2082
|
// src/assembly/create-subagent-session.ts
|
|
1545
2083
|
var MODEL_SHORTCUTS = {
|
|
1546
2084
|
sonnet: "claude-sonnet-4-6",
|
|
1547
2085
|
haiku: "claude-haiku-4-5",
|
|
1548
2086
|
opus: "claude-opus-4-6"
|
|
1549
2087
|
};
|
|
2088
|
+
var LEGACY_AGENT_TOOL_NAME = "Agent";
|
|
2089
|
+
var PROJECTED_AGENT_COMMAND_TOOL_NAME = createProviderSafeModelCommandToolName("agent");
|
|
1550
2090
|
function resolveModelId(shortName, _parentModel) {
|
|
1551
2091
|
return MODEL_SHORTCUTS[shortName] ?? shortName;
|
|
1552
2092
|
}
|
|
@@ -1560,7 +2100,9 @@ function filterTools(parentTools, agentDefinition) {
|
|
|
1560
2100
|
const allowSet = new Set(agentDefinition.tools);
|
|
1561
2101
|
tools = tools.filter((t) => allowSet.has(t.getName()));
|
|
1562
2102
|
}
|
|
1563
|
-
tools = tools.filter(
|
|
2103
|
+
tools = tools.filter(
|
|
2104
|
+
(t) => t.getName() !== LEGACY_AGENT_TOOL_NAME && t.getName() !== PROJECTED_AGENT_COMMAND_TOOL_NAME
|
|
2105
|
+
);
|
|
1564
2106
|
return tools;
|
|
1565
2107
|
}
|
|
1566
2108
|
function createSubagentSession(options) {
|
|
@@ -1574,7 +2116,7 @@ function createSubagentSession(options) {
|
|
|
1574
2116
|
isForkWorker: options.isForkWorker ?? false
|
|
1575
2117
|
});
|
|
1576
2118
|
const provider = options.provider;
|
|
1577
|
-
return new
|
|
2119
|
+
return new import_agent_sessions3.Session({
|
|
1578
2120
|
tools,
|
|
1579
2121
|
provider,
|
|
1580
2122
|
systemMessage,
|
|
@@ -1655,8 +2197,8 @@ function getBuiltInAgent(name) {
|
|
|
1655
2197
|
}
|
|
1656
2198
|
|
|
1657
2199
|
// src/tools/agent-tool.ts
|
|
1658
|
-
var
|
|
1659
|
-
var
|
|
2200
|
+
var import_zod2 = require("zod");
|
|
2201
|
+
var import_agent_tools2 = require("@robota-sdk/agent-tools");
|
|
1660
2202
|
var import_agent_runtime = require("@robota-sdk/agent-runtime");
|
|
1661
2203
|
|
|
1662
2204
|
// src/subagents/in-process-subagent-runner.ts
|
|
@@ -1886,35 +2428,21 @@ var AGENT_TOOL_DESCRIPTION = [
|
|
|
1886
2428
|
"After the tool returns, base user-facing claims on returned mode and counts; do not say parallel or multiple jobs started unless the result proves those jobs started.",
|
|
1887
2429
|
"Execution is represented by a real tool call and runtime background task event."
|
|
1888
2430
|
].join(" ");
|
|
1889
|
-
function
|
|
1890
|
-
const availableAgents = agentDefinitions.length > 0 ? ` Available agent types: ${agentDefinitions.map((agent) => `${agent.name} (${agent.description})`).join(", ")}.` : "";
|
|
1891
|
-
return [
|
|
1892
|
-
"Agent \u2014 creates isolated subagent jobs.",
|
|
1893
|
-
"Without jobs, one Agent tool call corresponds to one subagent job.",
|
|
1894
|
-
"For explicit multi-agent or parallel-agent requests, use one Agent tool call with jobs containing one entry per requested role and a stable label for each role.",
|
|
1895
|
-
"When the user explicitly asks to create, run, spawn, delegate to, or use agents/subagents, start the requested subagent job immediately.",
|
|
1896
|
-
"Do not ask a follow-up question unless execution is impossible or unsafe.",
|
|
1897
|
-
"The tool returns terminal result data with mode, requestedJobCount, startedJobCount, failedJobCount, and provenance.",
|
|
1898
|
-
"After the tool returns, base user-facing claims on returned mode and counts; do not say parallel or multiple jobs started unless the result proves those jobs started.",
|
|
1899
|
-
"Runtime mode is background.",
|
|
1900
|
-
availableAgents
|
|
1901
|
-
].join(" ").replace(/\s+/g, " ").trim();
|
|
1902
|
-
}
|
|
1903
|
-
function asZodSchema(schema) {
|
|
2431
|
+
function asZodSchema2(schema) {
|
|
1904
2432
|
return schema;
|
|
1905
2433
|
}
|
|
1906
|
-
var AgentSchema =
|
|
1907
|
-
prompt:
|
|
1908
|
-
subagent_type:
|
|
1909
|
-
model:
|
|
1910
|
-
isolation:
|
|
1911
|
-
jobs:
|
|
1912
|
-
|
|
1913
|
-
label:
|
|
1914
|
-
prompt:
|
|
1915
|
-
subagent_type:
|
|
1916
|
-
model:
|
|
1917
|
-
isolation:
|
|
2434
|
+
var AgentSchema = import_zod2.z.object({
|
|
2435
|
+
prompt: import_zod2.z.string().optional().describe("The task for a single subagent to perform. Required when jobs is omitted."),
|
|
2436
|
+
subagent_type: import_zod2.z.string().optional().describe('Agent type: "general-purpose", "Explore", "Plan", or a custom agent name'),
|
|
2437
|
+
model: import_zod2.z.string().optional().describe("Optional model override"),
|
|
2438
|
+
isolation: import_zod2.z.enum(["none", "worktree"]).optional().describe('Optional runtime isolation mode. "worktree" runs in a Git worktree.'),
|
|
2439
|
+
jobs: import_zod2.z.array(
|
|
2440
|
+
import_zod2.z.object({
|
|
2441
|
+
label: import_zod2.z.string().optional().describe("Stable role label for this batch job"),
|
|
2442
|
+
prompt: import_zod2.z.string().describe("The task for this subagent to perform"),
|
|
2443
|
+
subagent_type: import_zod2.z.string().optional().describe("Agent type for this job"),
|
|
2444
|
+
model: import_zod2.z.string().optional().describe("Optional model override for this job"),
|
|
2445
|
+
isolation: import_zod2.z.enum(["none", "worktree"]).optional().describe("Isolation for this job")
|
|
1918
2446
|
}).passthrough()
|
|
1919
2447
|
).optional().describe("Batch of subagent jobs to start in one Agent tool call")
|
|
1920
2448
|
}).passthrough();
|
|
@@ -2039,10 +2567,10 @@ async function runManagedAgent(args, deps, manager) {
|
|
|
2039
2567
|
}
|
|
2040
2568
|
function createAgentTool(deps) {
|
|
2041
2569
|
const manager = createSubagentManager(deps);
|
|
2042
|
-
return (0,
|
|
2570
|
+
return (0, import_agent_tools2.createZodFunctionTool)(
|
|
2043
2571
|
"Agent",
|
|
2044
2572
|
AGENT_TOOL_DESCRIPTION,
|
|
2045
|
-
|
|
2573
|
+
asZodSchema2(AgentSchema),
|
|
2046
2574
|
async (params) => {
|
|
2047
2575
|
const args = params;
|
|
2048
2576
|
if (Array.isArray(args.jobs) && args.jobs.length > 0) {
|
|
@@ -2144,8 +2672,8 @@ var BackgroundJobOrchestrator = class {
|
|
|
2144
2672
|
createRecord(state) {
|
|
2145
2673
|
let resolveGroup = () => {
|
|
2146
2674
|
};
|
|
2147
|
-
const completion = new Promise((
|
|
2148
|
-
resolveGroup =
|
|
2675
|
+
const completion = new Promise((resolve6) => {
|
|
2676
|
+
resolveGroup = resolve6;
|
|
2149
2677
|
});
|
|
2150
2678
|
return { state, completion, resolve: resolveGroup };
|
|
2151
2679
|
}
|
|
@@ -2270,8 +2798,385 @@ function retrieveSessionBackgroundTaskManager(key) {
|
|
|
2270
2798
|
}
|
|
2271
2799
|
|
|
2272
2800
|
// src/interactive/interactive-session-execution.ts
|
|
2273
|
-
var
|
|
2801
|
+
var import_node_crypto3 = require("crypto");
|
|
2274
2802
|
var import_agent_core5 = require("@robota-sdk/agent-core");
|
|
2803
|
+
|
|
2804
|
+
// src/context/context-reference-inventory.ts
|
|
2805
|
+
var DEFAULT_MAX_ACTIVE_REFERENCES = Number("8");
|
|
2806
|
+
var BYTES_PER_KIB = Number("1024");
|
|
2807
|
+
var DEFAULT_MAX_ACTIVE_BYTES = Number("256") * BYTES_PER_KIB;
|
|
2808
|
+
var DEFAULT_MAX_OBSERVED_REFERENCES = Number("32");
|
|
2809
|
+
function createContextReferenceItem(record, loadType, status, timestamp = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
2810
|
+
return {
|
|
2811
|
+
id: `${loadType}:${record.relativePath}`,
|
|
2812
|
+
sourcePath: record.sourcePath,
|
|
2813
|
+
relativePath: record.relativePath,
|
|
2814
|
+
originalReference: record.originalReference,
|
|
2815
|
+
loadType,
|
|
2816
|
+
status,
|
|
2817
|
+
byteLength: record.byteLength,
|
|
2818
|
+
loadedAt: timestamp,
|
|
2819
|
+
lastUsedAt: timestamp
|
|
2820
|
+
};
|
|
2821
|
+
}
|
|
2822
|
+
function upsertContextReference(references, item, limits) {
|
|
2823
|
+
const existing = references.find((reference) => reference.sourcePath === item.sourcePath);
|
|
2824
|
+
const retained = references.filter((reference) => reference.sourcePath !== item.sourcePath);
|
|
2825
|
+
const nextItem = existing ? mergeContextReference(existing, item) : item;
|
|
2826
|
+
return enforceContextReferenceLimits([...retained, nextItem], limits);
|
|
2827
|
+
}
|
|
2828
|
+
function removeContextReference(references, query) {
|
|
2829
|
+
const normalized = normalizeReferenceQuery(query);
|
|
2830
|
+
const removed = references.find((reference) => matchesContextReference(reference, normalized));
|
|
2831
|
+
if (!removed) return { references: [...references], result: {} };
|
|
2832
|
+
return {
|
|
2833
|
+
references: references.filter((reference) => reference.sourcePath !== removed.sourcePath),
|
|
2834
|
+
result: { removed }
|
|
2835
|
+
};
|
|
2836
|
+
}
|
|
2837
|
+
function clearContextReferences(references) {
|
|
2838
|
+
return { removed: [...references] };
|
|
2839
|
+
}
|
|
2840
|
+
function listActiveContextReferences(references) {
|
|
2841
|
+
return references.filter((reference) => reference.status === "active");
|
|
2842
|
+
}
|
|
2843
|
+
function toContextReferenceRecords(references) {
|
|
2844
|
+
return references.map((reference) => ({
|
|
2845
|
+
originalReference: reference.originalReference,
|
|
2846
|
+
sourcePath: reference.sourcePath,
|
|
2847
|
+
relativePath: reference.relativePath,
|
|
2848
|
+
reason: reference.loadType,
|
|
2849
|
+
depth: 0,
|
|
2850
|
+
byteLength: reference.byteLength
|
|
2851
|
+
}));
|
|
2852
|
+
}
|
|
2853
|
+
function mergeContextReference(existing, incoming) {
|
|
2854
|
+
if (incoming.status === "active") return { ...incoming, loadedAt: existing.loadedAt };
|
|
2855
|
+
return {
|
|
2856
|
+
...existing,
|
|
2857
|
+
byteLength: incoming.byteLength,
|
|
2858
|
+
originalReference: incoming.originalReference,
|
|
2859
|
+
lastUsedAt: incoming.lastUsedAt
|
|
2860
|
+
};
|
|
2861
|
+
}
|
|
2862
|
+
function enforceContextReferenceLimits(references, limits) {
|
|
2863
|
+
const maxActiveReferences = limits?.maxActiveReferences ?? DEFAULT_MAX_ACTIVE_REFERENCES;
|
|
2864
|
+
const maxActiveBytes = limits?.maxActiveBytes ?? DEFAULT_MAX_ACTIVE_BYTES;
|
|
2865
|
+
const maxObservedReferences = limits?.maxObservedReferences ?? DEFAULT_MAX_OBSERVED_REFERENCES;
|
|
2866
|
+
const evicted = [];
|
|
2867
|
+
let next = [...references];
|
|
2868
|
+
while (countActiveReferences(next) > maxActiveReferences || countActiveBytes(next) > maxActiveBytes) {
|
|
2869
|
+
const candidate = next.find((reference) => reference.status === "active");
|
|
2870
|
+
if (!candidate) break;
|
|
2871
|
+
evicted.push(candidate);
|
|
2872
|
+
next = next.filter((reference) => reference.sourcePath !== candidate.sourcePath);
|
|
2873
|
+
}
|
|
2874
|
+
const observed = next.filter((reference) => reference.status === "observed");
|
|
2875
|
+
if (observed.length > maxObservedReferences) {
|
|
2876
|
+
const overflow = observed.slice(0, observed.length - maxObservedReferences);
|
|
2877
|
+
evicted.push(...overflow);
|
|
2878
|
+
next = next.filter(
|
|
2879
|
+
(reference) => reference.status !== "observed" || !overflow.some((removed) => removed.sourcePath === reference.sourcePath)
|
|
2880
|
+
);
|
|
2881
|
+
}
|
|
2882
|
+
return { references: next, evicted };
|
|
2883
|
+
}
|
|
2884
|
+
function countActiveReferences(references) {
|
|
2885
|
+
return references.filter((reference) => reference.status === "active").length;
|
|
2886
|
+
}
|
|
2887
|
+
function countActiveBytes(references) {
|
|
2888
|
+
return references.reduce(
|
|
2889
|
+
(total, reference) => total + (reference.status === "active" ? reference.byteLength : 0),
|
|
2890
|
+
0
|
|
2891
|
+
);
|
|
2892
|
+
}
|
|
2893
|
+
function normalizeReferenceQuery(query) {
|
|
2894
|
+
return query.startsWith("@") ? query.slice(1) : query;
|
|
2895
|
+
}
|
|
2896
|
+
function matchesContextReference(reference, query) {
|
|
2897
|
+
return reference.relativePath === query || reference.sourcePath === query || reference.originalReference === query || reference.originalReference === `@${query}`;
|
|
2898
|
+
}
|
|
2899
|
+
|
|
2900
|
+
// src/context/prompt-file-reference-format.ts
|
|
2901
|
+
var import_node_crypto2 = require("crypto");
|
|
2902
|
+
function buildPromptWithFileReferences(input, references) {
|
|
2903
|
+
if (references.length === 0) return input;
|
|
2904
|
+
const blocks = references.map((reference) => {
|
|
2905
|
+
const content = reference.content.replaceAll("</file>", "<\\/file>");
|
|
2906
|
+
return [
|
|
2907
|
+
`<file path="${escapeAttribute(reference.relativePath)}" bytes="${reference.byteLength}" reason="${reference.reason}">`,
|
|
2908
|
+
content,
|
|
2909
|
+
"</file>"
|
|
2910
|
+
].join("\n");
|
|
2911
|
+
});
|
|
2912
|
+
return [input, "<robota_file_references>", ...blocks, "</robota_file_references>"].join("\n\n");
|
|
2913
|
+
}
|
|
2914
|
+
function hasBlockingPromptFileReferenceDiagnostics(diagnostics) {
|
|
2915
|
+
return diagnostics.some((diagnostic) => diagnostic.severity === "error");
|
|
2916
|
+
}
|
|
2917
|
+
function formatPromptFileReferenceDiagnostics(diagnostics) {
|
|
2918
|
+
if (diagnostics.length === 0) return "";
|
|
2919
|
+
return [
|
|
2920
|
+
"File reference error:",
|
|
2921
|
+
...diagnostics.map((diagnostic) => `- ${diagnostic.reference}: ${diagnostic.message}`)
|
|
2922
|
+
].join("\n");
|
|
2923
|
+
}
|
|
2924
|
+
function toPromptFileReferenceRecords(references) {
|
|
2925
|
+
return references.map(({ content: _content, ...record }) => record);
|
|
2926
|
+
}
|
|
2927
|
+
function createPromptFileReferenceHistoryEntry(references) {
|
|
2928
|
+
const records = toPromptFileReferenceRecords(references);
|
|
2929
|
+
return {
|
|
2930
|
+
id: `prompt_file_reference_${(0, import_node_crypto2.randomUUID)()}`,
|
|
2931
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
2932
|
+
category: "event",
|
|
2933
|
+
type: "prompt-file-reference",
|
|
2934
|
+
data: {
|
|
2935
|
+
message: formatLoadedPromptFileReferencesMessage(records),
|
|
2936
|
+
references: records
|
|
2937
|
+
}
|
|
2938
|
+
};
|
|
2939
|
+
}
|
|
2940
|
+
function escapeAttribute(value) {
|
|
2941
|
+
return value.replaceAll("&", "&").replaceAll('"', """).replaceAll("<", "<").replaceAll(">", ">");
|
|
2942
|
+
}
|
|
2943
|
+
function formatLoadedPromptFileReferencesMessage(references) {
|
|
2944
|
+
const list = references.map((reference) => `${reference.relativePath} (${reference.byteLength} B)`).join(", ");
|
|
2945
|
+
return `Loaded file references: ${list}`;
|
|
2946
|
+
}
|
|
2947
|
+
|
|
2948
|
+
// src/context/prompt-file-reference-parser.ts
|
|
2949
|
+
var REFERENCE_PATTERN = /(^|[\s([{])@([^\s)\]}>,;"'`]+)/g;
|
|
2950
|
+
function parsePromptFileReferences(input) {
|
|
2951
|
+
const references = [];
|
|
2952
|
+
for (const match of input.matchAll(REFERENCE_PATTERN)) {
|
|
2953
|
+
const token = stripTrailingPunctuation(match[2] ?? "");
|
|
2954
|
+
if (!isPathLikeReference(token)) continue;
|
|
2955
|
+
references.push({
|
|
2956
|
+
original: `@${token}`,
|
|
2957
|
+
path: token,
|
|
2958
|
+
index: match.index ?? 0
|
|
2959
|
+
});
|
|
2960
|
+
}
|
|
2961
|
+
return references;
|
|
2962
|
+
}
|
|
2963
|
+
function stripTrailingPunctuation(token) {
|
|
2964
|
+
let end = token.length;
|
|
2965
|
+
while (end > 0 && /[.,:;!?]/.test(token[end - 1] ?? "")) {
|
|
2966
|
+
end -= 1;
|
|
2967
|
+
}
|
|
2968
|
+
return token.slice(0, end);
|
|
2969
|
+
}
|
|
2970
|
+
function isPathLikeReference(referencePath) {
|
|
2971
|
+
if (referencePath.length === 0) return false;
|
|
2972
|
+
if (referencePath.includes("://")) return false;
|
|
2973
|
+
return referencePath.startsWith("./") || referencePath.startsWith("../") || referencePath.startsWith("/") || referencePath.startsWith("~/") || referencePath.startsWith(".") || referencePath.includes(".");
|
|
2974
|
+
}
|
|
2975
|
+
|
|
2976
|
+
// src/context/prompt-file-reference-resolver.ts
|
|
2977
|
+
var import_promises = require("fs/promises");
|
|
2978
|
+
var import_node_path6 = require("path");
|
|
2979
|
+
|
|
2980
|
+
// src/context/prompt-file-reference-paths.ts
|
|
2981
|
+
var import_node_os3 = require("os");
|
|
2982
|
+
var import_node_path5 = require("path");
|
|
2983
|
+
function resolveCandidatePath(referencePath, rootPath) {
|
|
2984
|
+
if (referencePath.startsWith("~/")) {
|
|
2985
|
+
return (0, import_node_path5.resolve)((0, import_node_os3.homedir)(), referencePath.slice("~/".length));
|
|
2986
|
+
}
|
|
2987
|
+
if ((0, import_node_path5.isAbsolute)(referencePath)) {
|
|
2988
|
+
return (0, import_node_path5.resolve)(referencePath);
|
|
2989
|
+
}
|
|
2990
|
+
return (0, import_node_path5.resolve)(rootPath, referencePath);
|
|
2991
|
+
}
|
|
2992
|
+
function isPathWithinRoot(candidatePath, rootPath) {
|
|
2993
|
+
const relativePath = (0, import_node_path5.relative)(rootPath, candidatePath);
|
|
2994
|
+
return relativePath === "" || !relativePath.startsWith("..") && !(0, import_node_path5.isAbsolute)(relativePath);
|
|
2995
|
+
}
|
|
2996
|
+
function normalizeRelativePath(rootPath, sourcePath) {
|
|
2997
|
+
return (0, import_node_path5.relative)(rootPath, sourcePath).split(import_node_path5.sep).join("/");
|
|
2998
|
+
}
|
|
2999
|
+
|
|
3000
|
+
// src/context/prompt-file-reference-resolver.ts
|
|
3001
|
+
var DEFAULT_MAX_DEPTH = Number("2");
|
|
3002
|
+
var DEFAULT_MAX_REFERENCES = Number("8");
|
|
3003
|
+
var BYTES_PER_KIB2 = Number("1024");
|
|
3004
|
+
var DEFAULT_MAX_FILE_BYTES = Number("64") * BYTES_PER_KIB2;
|
|
3005
|
+
var DEFAULT_MAX_TOTAL_BYTES = Number("256") * BYTES_PER_KIB2;
|
|
3006
|
+
async function resolvePromptFileReferences(input, options) {
|
|
3007
|
+
const state = await createResolveState(options);
|
|
3008
|
+
for (const reference of parsePromptFileReferences(input)) {
|
|
3009
|
+
await resolveReference(reference, 0, [], state);
|
|
3010
|
+
}
|
|
3011
|
+
return toResolvedReferences(state);
|
|
3012
|
+
}
|
|
3013
|
+
async function resolvePromptFileReferencePaths(referencePaths, options) {
|
|
3014
|
+
const state = await createResolveState(options);
|
|
3015
|
+
for (const referencePath of referencePaths) {
|
|
3016
|
+
await resolveReference(
|
|
3017
|
+
{ original: `@${referencePath}`, path: referencePath, index: 0 },
|
|
3018
|
+
0,
|
|
3019
|
+
[],
|
|
3020
|
+
state
|
|
3021
|
+
);
|
|
3022
|
+
}
|
|
3023
|
+
return toResolvedReferences(state);
|
|
3024
|
+
}
|
|
3025
|
+
async function createResolveState(options) {
|
|
3026
|
+
return {
|
|
3027
|
+
rootPath: await resolveWorkspaceRoot(options.cwd),
|
|
3028
|
+
limits: resolveLimits(options.limits),
|
|
3029
|
+
reason: options.reason ?? "prompt-reference",
|
|
3030
|
+
references: [],
|
|
3031
|
+
diagnostics: [],
|
|
3032
|
+
loadedPaths: /* @__PURE__ */ new Set(),
|
|
3033
|
+
totalBytes: 0
|
|
3034
|
+
};
|
|
3035
|
+
}
|
|
3036
|
+
function toResolvedReferences(state) {
|
|
3037
|
+
return {
|
|
3038
|
+
references: state.references,
|
|
3039
|
+
diagnostics: state.diagnostics
|
|
3040
|
+
};
|
|
3041
|
+
}
|
|
3042
|
+
function resolveLimits(limits) {
|
|
3043
|
+
return {
|
|
3044
|
+
maxDepth: limits?.maxDepth ?? DEFAULT_MAX_DEPTH,
|
|
3045
|
+
maxReferences: limits?.maxReferences ?? DEFAULT_MAX_REFERENCES,
|
|
3046
|
+
maxFileBytes: limits?.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES,
|
|
3047
|
+
maxTotalBytes: limits?.maxTotalBytes ?? DEFAULT_MAX_TOTAL_BYTES
|
|
3048
|
+
};
|
|
3049
|
+
}
|
|
3050
|
+
async function resolveWorkspaceRoot(cwd) {
|
|
3051
|
+
try {
|
|
3052
|
+
return await (0, import_promises.realpath)(cwd);
|
|
3053
|
+
} catch {
|
|
3054
|
+
return (0, import_node_path6.resolve)(cwd);
|
|
3055
|
+
}
|
|
3056
|
+
}
|
|
3057
|
+
async function resolveReference(reference, depth, activePaths, state) {
|
|
3058
|
+
if (!checkReferenceBudget(reference, depth, state)) return;
|
|
3059
|
+
const sourcePath = await resolveReferencePath(reference, state);
|
|
3060
|
+
if (sourcePath === void 0) return;
|
|
3061
|
+
if (!checkReferenceCycleAndDuplicate(reference, sourcePath, activePaths, state)) return;
|
|
3062
|
+
const fileInfo = await inspectReferenceFile(reference, sourcePath, state);
|
|
3063
|
+
if (fileInfo === void 0) return;
|
|
3064
|
+
const content = await readReferenceFile(reference, sourcePath, state);
|
|
3065
|
+
if (content === void 0) return;
|
|
3066
|
+
state.loadedPaths.add(sourcePath);
|
|
3067
|
+
state.totalBytes += fileInfo.byteLength;
|
|
3068
|
+
state.references.push(buildResolvedReference(reference, fileInfo, depth, content, state));
|
|
3069
|
+
await resolveNestedReferences(content, depth, [...activePaths, sourcePath], state);
|
|
3070
|
+
}
|
|
3071
|
+
function checkReferenceBudget(reference, depth, state) {
|
|
3072
|
+
if (state.references.length >= state.limits.maxReferences) {
|
|
3073
|
+
pushDiagnostic(state, "too-many-references", reference, "Too many file references.");
|
|
3074
|
+
return false;
|
|
3075
|
+
}
|
|
3076
|
+
if (depth > state.limits.maxDepth) {
|
|
3077
|
+
pushDiagnostic(state, "max-depth", reference, "File reference nesting is too deep.");
|
|
3078
|
+
return false;
|
|
3079
|
+
}
|
|
3080
|
+
return true;
|
|
3081
|
+
}
|
|
3082
|
+
async function resolveReferencePath(reference, state) {
|
|
3083
|
+
const candidatePath = resolveCandidatePath(reference.path, state.rootPath);
|
|
3084
|
+
if (!isPathWithinRoot(candidatePath, state.rootPath)) {
|
|
3085
|
+
pushDiagnostic(state, "outside-root", reference, "Referenced path is outside the workspace.");
|
|
3086
|
+
return void 0;
|
|
3087
|
+
}
|
|
3088
|
+
try {
|
|
3089
|
+
const sourcePath = await (0, import_promises.realpath)(candidatePath);
|
|
3090
|
+
if (isPathWithinRoot(sourcePath, state.rootPath)) return sourcePath;
|
|
3091
|
+
pushDiagnostic(
|
|
3092
|
+
state,
|
|
3093
|
+
"outside-root",
|
|
3094
|
+
reference,
|
|
3095
|
+
"Referenced path resolves outside the workspace."
|
|
3096
|
+
);
|
|
3097
|
+
} catch {
|
|
3098
|
+
pushDiagnostic(state, "not-found", reference, "Referenced file was not found.");
|
|
3099
|
+
}
|
|
3100
|
+
return void 0;
|
|
3101
|
+
}
|
|
3102
|
+
function checkReferenceCycleAndDuplicate(reference, sourcePath, activePaths, state) {
|
|
3103
|
+
if (activePaths.includes(sourcePath)) {
|
|
3104
|
+
pushDiagnostic(state, "circular-reference", reference, "Circular file reference detected.");
|
|
3105
|
+
return false;
|
|
3106
|
+
}
|
|
3107
|
+
return !state.loadedPaths.has(sourcePath);
|
|
3108
|
+
}
|
|
3109
|
+
async function inspectReferenceFile(reference, sourcePath, state) {
|
|
3110
|
+
try {
|
|
3111
|
+
const fileStat = await (0, import_promises.stat)(sourcePath);
|
|
3112
|
+
if (fileStat.isDirectory()) {
|
|
3113
|
+
pushDiagnostic(
|
|
3114
|
+
state,
|
|
3115
|
+
"directory-not-supported",
|
|
3116
|
+
reference,
|
|
3117
|
+
"Directory references are not supported."
|
|
3118
|
+
);
|
|
3119
|
+
return void 0;
|
|
3120
|
+
}
|
|
3121
|
+
if (fileStat.size > state.limits.maxFileBytes) {
|
|
3122
|
+
pushDiagnostic(
|
|
3123
|
+
state,
|
|
3124
|
+
"file-too-large",
|
|
3125
|
+
reference,
|
|
3126
|
+
"Referenced file exceeds the per-file size limit."
|
|
3127
|
+
);
|
|
3128
|
+
return void 0;
|
|
3129
|
+
}
|
|
3130
|
+
if (state.totalBytes + fileStat.size > state.limits.maxTotalBytes) {
|
|
3131
|
+
pushDiagnostic(
|
|
3132
|
+
state,
|
|
3133
|
+
"total-too-large",
|
|
3134
|
+
reference,
|
|
3135
|
+
"Referenced files exceed the total size limit."
|
|
3136
|
+
);
|
|
3137
|
+
return void 0;
|
|
3138
|
+
}
|
|
3139
|
+
return { sourcePath, byteLength: fileStat.size };
|
|
3140
|
+
} catch {
|
|
3141
|
+
pushDiagnostic(state, "unreadable", reference, "Referenced file could not be inspected.");
|
|
3142
|
+
return void 0;
|
|
3143
|
+
}
|
|
3144
|
+
}
|
|
3145
|
+
async function readReferenceFile(reference, sourcePath, state) {
|
|
3146
|
+
try {
|
|
3147
|
+
return await (0, import_promises.readFile)(sourcePath, "utf8");
|
|
3148
|
+
} catch {
|
|
3149
|
+
pushDiagnostic(state, "unreadable", reference, "Referenced file could not be read.");
|
|
3150
|
+
return void 0;
|
|
3151
|
+
}
|
|
3152
|
+
}
|
|
3153
|
+
function buildResolvedReference(reference, fileInfo, depth, content, state) {
|
|
3154
|
+
return {
|
|
3155
|
+
originalReference: reference.original,
|
|
3156
|
+
sourcePath: fileInfo.sourcePath,
|
|
3157
|
+
relativePath: normalizeRelativePath(state.rootPath, fileInfo.sourcePath),
|
|
3158
|
+
reason: state.reason,
|
|
3159
|
+
depth,
|
|
3160
|
+
byteLength: fileInfo.byteLength,
|
|
3161
|
+
content
|
|
3162
|
+
};
|
|
3163
|
+
}
|
|
3164
|
+
async function resolveNestedReferences(content, depth, activePaths, state) {
|
|
3165
|
+
for (const nestedReference of parsePromptFileReferences(content)) {
|
|
3166
|
+
await resolveReference(nestedReference, depth + 1, activePaths, state);
|
|
3167
|
+
}
|
|
3168
|
+
}
|
|
3169
|
+
function pushDiagnostic(state, code, reference, message) {
|
|
3170
|
+
state.diagnostics.push({
|
|
3171
|
+
code,
|
|
3172
|
+
severity: "error",
|
|
3173
|
+
reference: reference.original,
|
|
3174
|
+
message,
|
|
3175
|
+
path: reference.path
|
|
3176
|
+
});
|
|
3177
|
+
}
|
|
3178
|
+
|
|
3179
|
+
// src/interactive/interactive-session-execution.ts
|
|
2275
3180
|
function isAbortError(err) {
|
|
2276
3181
|
return err instanceof DOMException && err.name === "AbortError" || err instanceof Error && (err.message.includes("aborted") || err.message.includes("abort"));
|
|
2277
3182
|
}
|
|
@@ -2287,7 +3192,7 @@ function extractToolSummaries(history, historyBefore) {
|
|
|
2287
3192
|
}
|
|
2288
3193
|
return summaries;
|
|
2289
3194
|
}
|
|
2290
|
-
function buildResult(response, sessionHistory, interactiveHistory, historyBefore, contextState) {
|
|
3195
|
+
function buildResult(response, sessionHistory, interactiveHistory, historyBefore, contextState, promptFileReferences) {
|
|
2291
3196
|
const toolSummaries = extractToolSummaries(sessionHistory, historyBefore);
|
|
2292
3197
|
const usage = extractTurnUsage(sessionHistory, historyBefore, contextState);
|
|
2293
3198
|
return {
|
|
@@ -2295,7 +3200,8 @@ function buildResult(response, sessionHistory, interactiveHistory, historyBefore
|
|
|
2295
3200
|
history: interactiveHistory,
|
|
2296
3201
|
toolSummaries,
|
|
2297
3202
|
contextState,
|
|
2298
|
-
...usage && { usage }
|
|
3203
|
+
...usage && { usage },
|
|
3204
|
+
...promptFileReferences && promptFileReferences.length > 0 ? { promptFileReferences: [...promptFileReferences] } : {}
|
|
2299
3205
|
};
|
|
2300
3206
|
}
|
|
2301
3207
|
function buildInterruptedResult(sessionHistory, interactiveHistory, historyBefore, contextState) {
|
|
@@ -2316,13 +3222,50 @@ function buildInterruptedResult(sessionHistory, interactiveHistory, historyBefor
|
|
|
2316
3222
|
}
|
|
2317
3223
|
function createUsageSummaryEntry(usage) {
|
|
2318
3224
|
return {
|
|
2319
|
-
id: `usage_${(0,
|
|
3225
|
+
id: `usage_${(0, import_node_crypto3.randomUUID)()}`,
|
|
2320
3226
|
timestamp: /* @__PURE__ */ new Date(),
|
|
2321
3227
|
category: "event",
|
|
2322
3228
|
type: "usage-summary",
|
|
2323
3229
|
data: usage
|
|
2324
3230
|
};
|
|
2325
3231
|
}
|
|
3232
|
+
async function preparePromptInput(input, cwd, rawInput, contextReferences = []) {
|
|
3233
|
+
const activeReferenceResult = await resolvePromptFileReferencePaths(
|
|
3234
|
+
listActiveContextReferences(contextReferences).map((reference) => reference.sourcePath),
|
|
3235
|
+
{ cwd, reason: "manual" }
|
|
3236
|
+
);
|
|
3237
|
+
const promptFileReferenceResult = await resolvePromptFileReferences(input, { cwd });
|
|
3238
|
+
const diagnostics = [
|
|
3239
|
+
...activeReferenceResult.diagnostics,
|
|
3240
|
+
...promptFileReferenceResult.diagnostics
|
|
3241
|
+
];
|
|
3242
|
+
if (hasBlockingPromptFileReferenceDiagnostics(diagnostics)) {
|
|
3243
|
+
throw new Error(formatPromptFileReferenceDiagnostics(diagnostics));
|
|
3244
|
+
}
|
|
3245
|
+
const resolvedReferences = dedupeResolvedReferences([
|
|
3246
|
+
...activeReferenceResult.references,
|
|
3247
|
+
...promptFileReferenceResult.references
|
|
3248
|
+
]);
|
|
3249
|
+
const modelInput = buildPromptWithFileReferences(input, resolvedReferences);
|
|
3250
|
+
const hookInput = rawInput ?? (modelInput === input ? void 0 : input);
|
|
3251
|
+
const activeContextReferenceRecords = toPromptFileReferenceRecords(
|
|
3252
|
+
activeReferenceResult.references
|
|
3253
|
+
);
|
|
3254
|
+
const promptFileReferenceRecords = toPromptFileReferenceRecords(
|
|
3255
|
+
promptFileReferenceResult.references
|
|
3256
|
+
);
|
|
3257
|
+
const promptFileReferenceEntry = promptFileReferenceResult.references.length > 0 ? createPromptFileReferenceHistoryEntry(promptFileReferenceResult.references) : void 0;
|
|
3258
|
+
return {
|
|
3259
|
+
modelInput,
|
|
3260
|
+
...hookInput !== void 0 ? { hookInput } : {},
|
|
3261
|
+
activeContextReferenceRecords,
|
|
3262
|
+
promptFileReferenceRecords,
|
|
3263
|
+
...promptFileReferenceEntry !== void 0 ? { promptFileReferenceEntry } : {}
|
|
3264
|
+
};
|
|
3265
|
+
}
|
|
3266
|
+
function dedupeResolvedReferences(references) {
|
|
3267
|
+
return [...new Map(references.map((reference) => [reference.sourcePath, reference])).values()];
|
|
3268
|
+
}
|
|
2326
3269
|
function extractTurnUsage(sessionHistory, historyBefore, contextState) {
|
|
2327
3270
|
const turnMessages = sessionHistory.slice(historyBefore);
|
|
2328
3271
|
let promptTokens = 0;
|
|
@@ -2349,34 +3292,6 @@ function extractTurnUsage(sessionHistory, historyBefore, contextState) {
|
|
|
2349
3292
|
costStatus: "unknown"
|
|
2350
3293
|
};
|
|
2351
3294
|
}
|
|
2352
|
-
function persistSession(sessionStore, session, sessionName, cwd, history, backgroundState, memoryState) {
|
|
2353
|
-
try {
|
|
2354
|
-
const sessionId = session.getSessionId();
|
|
2355
|
-
const existing = sessionStore.load(sessionId);
|
|
2356
|
-
sessionStore.save({
|
|
2357
|
-
id: sessionId,
|
|
2358
|
-
name: sessionName ?? existing?.name,
|
|
2359
|
-
cwd,
|
|
2360
|
-
createdAt: existing?.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
2361
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2362
|
-
messages: session.getHistory(),
|
|
2363
|
-
history,
|
|
2364
|
-
systemPrompt: session.getSystemMessage(),
|
|
2365
|
-
toolSchemas: session.getToolSchemas(),
|
|
2366
|
-
...backgroundState ? {
|
|
2367
|
-
backgroundTasks: [...backgroundState.tasks],
|
|
2368
|
-
backgroundTaskEvents: [...backgroundState.events],
|
|
2369
|
-
backgroundJobGroups: [...backgroundState.groups ?? []],
|
|
2370
|
-
backgroundJobGroupEvents: [...backgroundState.groupEvents ?? []]
|
|
2371
|
-
} : {},
|
|
2372
|
-
...memoryState ? {
|
|
2373
|
-
memoryEvents: [...memoryState.events],
|
|
2374
|
-
usedMemoryReferences: [...memoryState.usedReferences]
|
|
2375
|
-
} : {}
|
|
2376
|
-
});
|
|
2377
|
-
} catch {
|
|
2378
|
-
}
|
|
2379
|
-
}
|
|
2380
3295
|
var NOOP_TERMINAL = {
|
|
2381
3296
|
write: () => {
|
|
2382
3297
|
},
|
|
@@ -2393,8 +3308,75 @@ var NOOP_TERMINAL = {
|
|
|
2393
3308
|
} })
|
|
2394
3309
|
};
|
|
2395
3310
|
|
|
3311
|
+
// src/interactive/interactive-session-persistence.ts
|
|
3312
|
+
function persistSession(sessionStore, session, sessionName, cwd, history, backgroundState, memoryState, skillActivationState, contextReferenceState, sandboxState) {
|
|
3313
|
+
try {
|
|
3314
|
+
const sessionId = session.getSessionId();
|
|
3315
|
+
const existing = sessionStore.load(sessionId);
|
|
3316
|
+
const sandboxSnapshotId = sandboxState?.snapshotId ?? existing?.sandboxSnapshotId;
|
|
3317
|
+
sessionStore.save(
|
|
3318
|
+
buildInteractiveSessionRecord({
|
|
3319
|
+
session,
|
|
3320
|
+
sessionId,
|
|
3321
|
+
sessionName: sessionName ?? existing?.name,
|
|
3322
|
+
cwd,
|
|
3323
|
+
history,
|
|
3324
|
+
createdAt: existing?.createdAt,
|
|
3325
|
+
backgroundState,
|
|
3326
|
+
memoryState,
|
|
3327
|
+
skillActivationState,
|
|
3328
|
+
contextReferenceState,
|
|
3329
|
+
...sandboxSnapshotId !== void 0 ? { sandboxSnapshotId } : {}
|
|
3330
|
+
})
|
|
3331
|
+
);
|
|
3332
|
+
} catch {
|
|
3333
|
+
}
|
|
3334
|
+
}
|
|
3335
|
+
function buildInteractiveSessionRecord(input) {
|
|
3336
|
+
return {
|
|
3337
|
+
id: input.sessionId,
|
|
3338
|
+
...input.sessionName !== void 0 ? { name: input.sessionName } : {},
|
|
3339
|
+
cwd: input.cwd,
|
|
3340
|
+
createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
3341
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3342
|
+
messages: input.session.getHistory(),
|
|
3343
|
+
history: input.history,
|
|
3344
|
+
systemPrompt: input.session.getSystemMessage(),
|
|
3345
|
+
toolSchemas: input.session.getToolSchemas(),
|
|
3346
|
+
...input.sandboxSnapshotId !== void 0 ? { sandboxSnapshotId: input.sandboxSnapshotId } : {},
|
|
3347
|
+
...buildBackgroundRecordFields(input.backgroundState),
|
|
3348
|
+
...buildMemoryRecordFields(input.memoryState),
|
|
3349
|
+
...buildSkillActivationRecordFields(input.skillActivationState),
|
|
3350
|
+
...buildContextReferenceRecordFields(input.contextReferenceState)
|
|
3351
|
+
};
|
|
3352
|
+
}
|
|
3353
|
+
function buildBackgroundRecordFields(state) {
|
|
3354
|
+
if (!state) return {};
|
|
3355
|
+
return {
|
|
3356
|
+
backgroundTasks: [...state.tasks],
|
|
3357
|
+
backgroundTaskEvents: [...state.events],
|
|
3358
|
+
backgroundJobGroups: [...state.groups ?? []],
|
|
3359
|
+
backgroundJobGroupEvents: [...state.groupEvents ?? []]
|
|
3360
|
+
};
|
|
3361
|
+
}
|
|
3362
|
+
function buildMemoryRecordFields(state) {
|
|
3363
|
+
if (!state) return {};
|
|
3364
|
+
return {
|
|
3365
|
+
memoryEvents: [...state.events],
|
|
3366
|
+
usedMemoryReferences: [...state.usedReferences]
|
|
3367
|
+
};
|
|
3368
|
+
}
|
|
3369
|
+
function buildSkillActivationRecordFields(state) {
|
|
3370
|
+
if (!state) return {};
|
|
3371
|
+
return { skillActivationEvents: [...state.events] };
|
|
3372
|
+
}
|
|
3373
|
+
function buildContextReferenceRecordFields(state) {
|
|
3374
|
+
if (!state) return {};
|
|
3375
|
+
return { contextReferences: [...state.references] };
|
|
3376
|
+
}
|
|
3377
|
+
|
|
2396
3378
|
// src/interactive/interactive-session-streaming.ts
|
|
2397
|
-
var
|
|
3379
|
+
var import_node_crypto4 = require("crypto");
|
|
2398
3380
|
var import_node_fs3 = require("fs");
|
|
2399
3381
|
var TOOL_ARG_DISPLAY_MAX = 80;
|
|
2400
3382
|
var TAIL_KEEP = 30;
|
|
@@ -2492,7 +3474,7 @@ function pushToolSummaryToHistory(state) {
|
|
|
2492
3474
|
return `${status} ${t.toolName}${t.firstArg ? `(${t.firstArg})` : ""}`;
|
|
2493
3475
|
}).join("\n");
|
|
2494
3476
|
state.history.push({
|
|
2495
|
-
id: (0,
|
|
3477
|
+
id: (0, import_node_crypto4.randomUUID)(),
|
|
2496
3478
|
timestamp: /* @__PURE__ */ new Date(),
|
|
2497
3479
|
category: "event",
|
|
2498
3480
|
type: "tool-summary",
|
|
@@ -2528,7 +3510,7 @@ function applyToolStart(state, event) {
|
|
|
2528
3510
|
const toolState = { toolName: event.toolName, firstArg, isRunning: true };
|
|
2529
3511
|
state.activeTools.push(toolState);
|
|
2530
3512
|
state.history.push({
|
|
2531
|
-
id: (0,
|
|
3513
|
+
id: (0, import_node_crypto4.randomUUID)(),
|
|
2532
3514
|
timestamp: /* @__PURE__ */ new Date(),
|
|
2533
3515
|
category: "event",
|
|
2534
3516
|
type: "tool-start",
|
|
@@ -2550,7 +3532,7 @@ function applyToolEnd(state, event) {
|
|
|
2550
3532
|
state.activeTools[idx] = finished;
|
|
2551
3533
|
state.activeTools = trimCompletedTools(state.activeTools);
|
|
2552
3534
|
state.history.push({
|
|
2553
|
-
id: (0,
|
|
3535
|
+
id: (0, import_node_crypto4.randomUUID)(),
|
|
2554
3536
|
timestamp: /* @__PURE__ */ new Date(),
|
|
2555
3537
|
category: "event",
|
|
2556
3538
|
type: "tool-end",
|
|
@@ -2570,110 +3552,110 @@ var import_fs2 = require("fs");
|
|
|
2570
3552
|
var import_path2 = require("path");
|
|
2571
3553
|
|
|
2572
3554
|
// src/config/config-types.ts
|
|
2573
|
-
var
|
|
2574
|
-
var UniversalValueSchema =
|
|
2575
|
-
() =>
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
3555
|
+
var import_zod3 = require("zod");
|
|
3556
|
+
var UniversalValueSchema = import_zod3.z.lazy(
|
|
3557
|
+
() => import_zod3.z.union([
|
|
3558
|
+
import_zod3.z.string(),
|
|
3559
|
+
import_zod3.z.number(),
|
|
3560
|
+
import_zod3.z.boolean(),
|
|
3561
|
+
import_zod3.z.null(),
|
|
3562
|
+
import_zod3.z.undefined(),
|
|
3563
|
+
import_zod3.z.date(),
|
|
3564
|
+
import_zod3.z.array(UniversalValueSchema),
|
|
3565
|
+
import_zod3.z.record(UniversalValueSchema)
|
|
2584
3566
|
])
|
|
2585
3567
|
);
|
|
2586
|
-
var ProviderSchema =
|
|
2587
|
-
name:
|
|
2588
|
-
model:
|
|
2589
|
-
apiKey:
|
|
2590
|
-
baseURL:
|
|
2591
|
-
timeout:
|
|
2592
|
-
options:
|
|
3568
|
+
var ProviderSchema = import_zod3.z.object({
|
|
3569
|
+
name: import_zod3.z.string().optional(),
|
|
3570
|
+
model: import_zod3.z.string().optional(),
|
|
3571
|
+
apiKey: import_zod3.z.string().optional(),
|
|
3572
|
+
baseURL: import_zod3.z.string().optional(),
|
|
3573
|
+
timeout: import_zod3.z.number().optional(),
|
|
3574
|
+
options: import_zod3.z.record(UniversalValueSchema).optional()
|
|
2593
3575
|
});
|
|
2594
|
-
var ProviderProfileSchema =
|
|
2595
|
-
type:
|
|
2596
|
-
model:
|
|
2597
|
-
apiKey:
|
|
2598
|
-
baseURL:
|
|
2599
|
-
timeout:
|
|
2600
|
-
options:
|
|
3576
|
+
var ProviderProfileSchema = import_zod3.z.object({
|
|
3577
|
+
type: import_zod3.z.string().optional(),
|
|
3578
|
+
model: import_zod3.z.string().optional(),
|
|
3579
|
+
apiKey: import_zod3.z.string().optional(),
|
|
3580
|
+
baseURL: import_zod3.z.string().optional(),
|
|
3581
|
+
timeout: import_zod3.z.number().optional(),
|
|
3582
|
+
options: import_zod3.z.record(UniversalValueSchema).optional()
|
|
2601
3583
|
});
|
|
2602
|
-
var PermissionsSchema =
|
|
3584
|
+
var PermissionsSchema = import_zod3.z.object({
|
|
2603
3585
|
/** Patterns that are always approved without prompting */
|
|
2604
|
-
allow:
|
|
3586
|
+
allow: import_zod3.z.array(import_zod3.z.string()).optional(),
|
|
2605
3587
|
/** Patterns that are always denied */
|
|
2606
|
-
deny:
|
|
3588
|
+
deny: import_zod3.z.array(import_zod3.z.string()).optional()
|
|
2607
3589
|
});
|
|
2608
|
-
var EnvSchema =
|
|
2609
|
-
var CommandHookDefinitionSchema =
|
|
2610
|
-
type:
|
|
2611
|
-
command:
|
|
2612
|
-
timeout:
|
|
3590
|
+
var EnvSchema = import_zod3.z.record(import_zod3.z.string()).optional();
|
|
3591
|
+
var CommandHookDefinitionSchema = import_zod3.z.object({
|
|
3592
|
+
type: import_zod3.z.literal("command"),
|
|
3593
|
+
command: import_zod3.z.string(),
|
|
3594
|
+
timeout: import_zod3.z.number().optional()
|
|
2613
3595
|
});
|
|
2614
|
-
var HttpHookDefinitionSchema =
|
|
2615
|
-
type:
|
|
2616
|
-
url:
|
|
2617
|
-
headers:
|
|
2618
|
-
timeout:
|
|
3596
|
+
var HttpHookDefinitionSchema = import_zod3.z.object({
|
|
3597
|
+
type: import_zod3.z.literal("http"),
|
|
3598
|
+
url: import_zod3.z.string(),
|
|
3599
|
+
headers: import_zod3.z.record(import_zod3.z.string()).optional(),
|
|
3600
|
+
timeout: import_zod3.z.number().optional()
|
|
2619
3601
|
});
|
|
2620
|
-
var PromptHookDefinitionSchema =
|
|
2621
|
-
type:
|
|
2622
|
-
prompt:
|
|
2623
|
-
model:
|
|
3602
|
+
var PromptHookDefinitionSchema = import_zod3.z.object({
|
|
3603
|
+
type: import_zod3.z.literal("prompt"),
|
|
3604
|
+
prompt: import_zod3.z.string(),
|
|
3605
|
+
model: import_zod3.z.string().optional()
|
|
2624
3606
|
});
|
|
2625
|
-
var AgentHookDefinitionSchema =
|
|
2626
|
-
type:
|
|
2627
|
-
agent:
|
|
2628
|
-
maxTurns:
|
|
2629
|
-
timeout:
|
|
3607
|
+
var AgentHookDefinitionSchema = import_zod3.z.object({
|
|
3608
|
+
type: import_zod3.z.literal("agent"),
|
|
3609
|
+
agent: import_zod3.z.string(),
|
|
3610
|
+
maxTurns: import_zod3.z.number().optional(),
|
|
3611
|
+
timeout: import_zod3.z.number().optional()
|
|
2630
3612
|
});
|
|
2631
|
-
var HookDefinitionSchema =
|
|
3613
|
+
var HookDefinitionSchema = import_zod3.z.discriminatedUnion("type", [
|
|
2632
3614
|
CommandHookDefinitionSchema,
|
|
2633
3615
|
HttpHookDefinitionSchema,
|
|
2634
3616
|
PromptHookDefinitionSchema,
|
|
2635
3617
|
AgentHookDefinitionSchema
|
|
2636
3618
|
]);
|
|
2637
|
-
var HookGroupSchema =
|
|
2638
|
-
matcher:
|
|
2639
|
-
hooks:
|
|
3619
|
+
var HookGroupSchema = import_zod3.z.object({
|
|
3620
|
+
matcher: import_zod3.z.string(),
|
|
3621
|
+
hooks: import_zod3.z.array(HookDefinitionSchema)
|
|
2640
3622
|
});
|
|
2641
|
-
var HooksSchema =
|
|
2642
|
-
PreToolUse:
|
|
2643
|
-
PostToolUse:
|
|
2644
|
-
SessionStart:
|
|
2645
|
-
SessionEnd:
|
|
2646
|
-
Stop:
|
|
2647
|
-
StopFailure:
|
|
2648
|
-
PreCompact:
|
|
2649
|
-
PostCompact:
|
|
2650
|
-
UserPromptSubmit:
|
|
2651
|
-
SubagentStart:
|
|
2652
|
-
SubagentStop:
|
|
2653
|
-
WorktreeCreate:
|
|
2654
|
-
WorktreeRemove:
|
|
3623
|
+
var HooksSchema = import_zod3.z.object({
|
|
3624
|
+
PreToolUse: import_zod3.z.array(HookGroupSchema).optional(),
|
|
3625
|
+
PostToolUse: import_zod3.z.array(HookGroupSchema).optional(),
|
|
3626
|
+
SessionStart: import_zod3.z.array(HookGroupSchema).optional(),
|
|
3627
|
+
SessionEnd: import_zod3.z.array(HookGroupSchema).optional(),
|
|
3628
|
+
Stop: import_zod3.z.array(HookGroupSchema).optional(),
|
|
3629
|
+
StopFailure: import_zod3.z.array(HookGroupSchema).optional(),
|
|
3630
|
+
PreCompact: import_zod3.z.array(HookGroupSchema).optional(),
|
|
3631
|
+
PostCompact: import_zod3.z.array(HookGroupSchema).optional(),
|
|
3632
|
+
UserPromptSubmit: import_zod3.z.array(HookGroupSchema).optional(),
|
|
3633
|
+
SubagentStart: import_zod3.z.array(HookGroupSchema).optional(),
|
|
3634
|
+
SubagentStop: import_zod3.z.array(HookGroupSchema).optional(),
|
|
3635
|
+
WorktreeCreate: import_zod3.z.array(HookGroupSchema).optional(),
|
|
3636
|
+
WorktreeRemove: import_zod3.z.array(HookGroupSchema).optional()
|
|
2655
3637
|
}).optional();
|
|
2656
|
-
var EnabledPluginsSchema =
|
|
2657
|
-
var MarketplaceSourceSchema =
|
|
2658
|
-
source:
|
|
2659
|
-
type:
|
|
2660
|
-
repo:
|
|
2661
|
-
url:
|
|
2662
|
-
path:
|
|
2663
|
-
ref:
|
|
3638
|
+
var EnabledPluginsSchema = import_zod3.z.record(import_zod3.z.boolean()).optional();
|
|
3639
|
+
var MarketplaceSourceSchema = import_zod3.z.object({
|
|
3640
|
+
source: import_zod3.z.object({
|
|
3641
|
+
type: import_zod3.z.enum(["github", "git", "local", "url"]),
|
|
3642
|
+
repo: import_zod3.z.string().optional(),
|
|
3643
|
+
url: import_zod3.z.string().optional(),
|
|
3644
|
+
path: import_zod3.z.string().optional(),
|
|
3645
|
+
ref: import_zod3.z.string().optional()
|
|
2664
3646
|
})
|
|
2665
3647
|
});
|
|
2666
|
-
var ExtraKnownMarketplacesSchema =
|
|
2667
|
-
var AutoCompactThresholdSchema =
|
|
2668
|
-
var SettingsSchema =
|
|
3648
|
+
var ExtraKnownMarketplacesSchema = import_zod3.z.record(MarketplaceSourceSchema).optional().catch(void 0);
|
|
3649
|
+
var AutoCompactThresholdSchema = import_zod3.z.union([import_zod3.z.number().gt(0).lte(1), import_zod3.z.literal(false)]).optional();
|
|
3650
|
+
var SettingsSchema = import_zod3.z.object({
|
|
2669
3651
|
/** Trust level used when no --permission-mode flag is given */
|
|
2670
|
-
defaultTrustLevel:
|
|
3652
|
+
defaultTrustLevel: import_zod3.z.enum(["safe", "moderate", "full"]).optional(),
|
|
2671
3653
|
/** Response language (e.g., "ko", "en", "ja"). Injected into system prompt. */
|
|
2672
|
-
language:
|
|
3654
|
+
language: import_zod3.z.string().optional(),
|
|
2673
3655
|
/** Active provider profile key from providers. */
|
|
2674
|
-
currentProvider:
|
|
3656
|
+
currentProvider: import_zod3.z.string().optional(),
|
|
2675
3657
|
/** Provider profiles keyed by user-facing profile name. */
|
|
2676
|
-
providers:
|
|
3658
|
+
providers: import_zod3.z.record(ProviderProfileSchema).optional(),
|
|
2677
3659
|
/** Legacy single-provider settings. Prefer currentProvider + providers for new config. */
|
|
2678
3660
|
provider: ProviderSchema.optional(),
|
|
2679
3661
|
permissions: PermissionsSchema.optional(),
|
|
@@ -2727,18 +3709,12 @@ function resolveEnvRef(value) {
|
|
|
2727
3709
|
return value;
|
|
2728
3710
|
}
|
|
2729
3711
|
function resolveEnvRefs(settings) {
|
|
2730
|
-
const provider = settings.provider?.apiKey !== void 0 ?
|
|
2731
|
-
...settings.provider,
|
|
2732
|
-
apiKey: resolveEnvRef(settings.provider.apiKey)
|
|
2733
|
-
} : settings.provider;
|
|
3712
|
+
const provider = settings.provider?.apiKey !== void 0 ? resolveProviderCredentialEnvRefs(settings.provider) : settings.provider;
|
|
2734
3713
|
if (settings.providers !== void 0) {
|
|
2735
3714
|
const providers = Object.fromEntries(
|
|
2736
3715
|
Object.entries(settings.providers).map(([name, profile]) => [
|
|
2737
3716
|
name,
|
|
2738
|
-
|
|
2739
|
-
...profile,
|
|
2740
|
-
...profile.apiKey !== void 0 && { apiKey: resolveEnvRef(profile.apiKey) }
|
|
2741
|
-
}
|
|
3717
|
+
resolveProviderCredentialEnvRefs(profile)
|
|
2742
3718
|
])
|
|
2743
3719
|
);
|
|
2744
3720
|
return {
|
|
@@ -2752,6 +3728,12 @@ function resolveEnvRefs(settings) {
|
|
|
2752
3728
|
provider
|
|
2753
3729
|
};
|
|
2754
3730
|
}
|
|
3731
|
+
function resolveProviderCredentialEnvRefs(provider) {
|
|
3732
|
+
return {
|
|
3733
|
+
...provider,
|
|
3734
|
+
...provider.apiKey !== void 0 && { apiKey: resolveEnvRef(provider.apiKey) }
|
|
3735
|
+
};
|
|
3736
|
+
}
|
|
2755
3737
|
function mergeSettings(layers) {
|
|
2756
3738
|
return layers.reduce((merged, layer) => {
|
|
2757
3739
|
return {
|
|
@@ -2785,22 +3767,32 @@ function mergeProviders(base, override) {
|
|
|
2785
3767
|
}
|
|
2786
3768
|
function resolveProvider(merged) {
|
|
2787
3769
|
if (merged.currentProvider !== void 0) {
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
name: profile.type,
|
|
2797
|
-
model: profile.model ?? DEFAULTS.provider.model,
|
|
2798
|
-
apiKey: profile.apiKey ?? DEFAULTS.provider.apiKey,
|
|
2799
|
-
...profile.baseURL !== void 0 && { baseURL: profile.baseURL },
|
|
2800
|
-
...profile.timeout !== void 0 && { timeout: profile.timeout },
|
|
2801
|
-
...profile.options !== void 0 && { options: profile.options }
|
|
2802
|
-
};
|
|
3770
|
+
return resolveActiveProviderProfile2(merged);
|
|
3771
|
+
}
|
|
3772
|
+
return resolveLegacyProvider(merged);
|
|
3773
|
+
}
|
|
3774
|
+
function resolveActiveProviderProfile2(merged) {
|
|
3775
|
+
const currentProvider = merged.currentProvider;
|
|
3776
|
+
if (currentProvider === void 0) {
|
|
3777
|
+
throw new Error("currentProvider is required");
|
|
2803
3778
|
}
|
|
3779
|
+
const profile = merged.providers?.[currentProvider];
|
|
3780
|
+
if (profile === void 0) {
|
|
3781
|
+
throw new Error(`currentProvider "${currentProvider}" was not found in providers`);
|
|
3782
|
+
}
|
|
3783
|
+
if (profile.type === void 0) {
|
|
3784
|
+
throw new Error(`Provider profile "${currentProvider}" is missing type`);
|
|
3785
|
+
}
|
|
3786
|
+
return {
|
|
3787
|
+
name: profile.type,
|
|
3788
|
+
model: profile.model ?? DEFAULTS.provider.model,
|
|
3789
|
+
apiKey: profile.apiKey ?? DEFAULTS.provider.apiKey,
|
|
3790
|
+
...profile.baseURL !== void 0 && { baseURL: profile.baseURL },
|
|
3791
|
+
...profile.timeout !== void 0 && { timeout: profile.timeout },
|
|
3792
|
+
...profile.options !== void 0 && { options: profile.options }
|
|
3793
|
+
};
|
|
3794
|
+
}
|
|
3795
|
+
function resolveLegacyProvider(merged) {
|
|
2804
3796
|
return {
|
|
2805
3797
|
name: merged.provider?.name ?? DEFAULTS.provider.name,
|
|
2806
3798
|
model: merged.provider?.model ?? DEFAULTS.provider.model,
|
|
@@ -2972,7 +3964,7 @@ Respond with JSON: { "ok": boolean, "reason"?: string }`;
|
|
|
2972
3964
|
};
|
|
2973
3965
|
|
|
2974
3966
|
// src/assembly/create-session.ts
|
|
2975
|
-
var
|
|
3967
|
+
var import_agent_sessions4 = require("@robota-sdk/agent-sessions");
|
|
2976
3968
|
|
|
2977
3969
|
// src/context/system-prompt-composer.ts
|
|
2978
3970
|
function renderSection(section) {
|
|
@@ -3077,9 +4069,15 @@ function formatCapability(descriptor) {
|
|
|
3077
4069
|
return `- ${descriptor.name}${arg}: ${descriptor.description}`;
|
|
3078
4070
|
}
|
|
3079
4071
|
function createCapabilityKindSection(kind, title, priority, source, descriptors) {
|
|
3080
|
-
const
|
|
3081
|
-
if (
|
|
3082
|
-
return createSection(
|
|
4072
|
+
const formattedDescriptors = descriptors.filter((descriptor) => descriptor.modelInvocable && descriptor.kind === kind).map(formatCapability);
|
|
4073
|
+
if (formattedDescriptors.length === 0) return void 0;
|
|
4074
|
+
return createSection(
|
|
4075
|
+
`capability-${kind}`,
|
|
4076
|
+
title,
|
|
4077
|
+
priority,
|
|
4078
|
+
formattedDescriptors.join("\n"),
|
|
4079
|
+
source
|
|
4080
|
+
);
|
|
3083
4081
|
}
|
|
3084
4082
|
function createCapabilitySections(descriptors) {
|
|
3085
4083
|
const sections = [];
|
|
@@ -3146,7 +4144,7 @@ function buildSystemPrompt(params) {
|
|
|
3146
4144
|
}
|
|
3147
4145
|
|
|
3148
4146
|
// src/assembly/create-tools.ts
|
|
3149
|
-
var
|
|
4147
|
+
var import_agent_tools3 = require("@robota-sdk/agent-tools");
|
|
3150
4148
|
var DEFAULT_TOOL_DESCRIPTIONS = [
|
|
3151
4149
|
"Bash \u2014 execute shell commands",
|
|
3152
4150
|
"Read \u2014 read file contents with line numbers",
|
|
@@ -3157,32 +4155,32 @@ var DEFAULT_TOOL_DESCRIPTIONS = [
|
|
|
3157
4155
|
"WebFetch \u2014 fetch URL content as text",
|
|
3158
4156
|
"WebSearch \u2014 search the internet through the configured local tool"
|
|
3159
4157
|
];
|
|
3160
|
-
function createDefaultTools() {
|
|
4158
|
+
function createDefaultTools(options = {}) {
|
|
3161
4159
|
return [
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
4160
|
+
(0, import_agent_tools3.createBashTool)(options),
|
|
4161
|
+
(0, import_agent_tools3.createReadTool)(options),
|
|
4162
|
+
(0, import_agent_tools3.createWriteTool)(options),
|
|
4163
|
+
(0, import_agent_tools3.createEditTool)(options),
|
|
4164
|
+
import_agent_tools3.globTool,
|
|
4165
|
+
import_agent_tools3.grepTool,
|
|
4166
|
+
import_agent_tools3.webFetchTool,
|
|
4167
|
+
import_agent_tools3.webSearchTool
|
|
3170
4168
|
];
|
|
3171
4169
|
}
|
|
3172
4170
|
|
|
3173
4171
|
// src/tools/background-process-tool.ts
|
|
3174
|
-
var
|
|
3175
|
-
var
|
|
4172
|
+
var import_zod4 = require("zod");
|
|
4173
|
+
var import_agent_tools4 = require("@robota-sdk/agent-tools");
|
|
3176
4174
|
var DEFAULT_PROCESS_TIMEOUT_MS = 12e4;
|
|
3177
|
-
function
|
|
4175
|
+
function asZodSchema3(schema) {
|
|
3178
4176
|
return schema;
|
|
3179
4177
|
}
|
|
3180
|
-
var BackgroundProcessSchema =
|
|
3181
|
-
command:
|
|
3182
|
-
timeout:
|
|
3183
|
-
workingDirectory:
|
|
3184
|
-
stdin:
|
|
3185
|
-
outputLimitBytes:
|
|
4178
|
+
var BackgroundProcessSchema = import_zod4.z.object({
|
|
4179
|
+
command: import_zod4.z.string().describe("The shell command to start in the background"),
|
|
4180
|
+
timeout: import_zod4.z.number().optional().describe("Optional timeout in milliseconds. Default is 120000."),
|
|
4181
|
+
workingDirectory: import_zod4.z.string().optional().describe("Working directory for the command. Defaults to the current project directory."),
|
|
4182
|
+
stdin: import_zod4.z.string().optional().describe("Optional stdin to write after the process starts."),
|
|
4183
|
+
outputLimitBytes: import_zod4.z.number().optional().describe("Maximum captured output bytes kept in the task result.")
|
|
3186
4184
|
});
|
|
3187
4185
|
function stringifyStarted(taskId, status, command) {
|
|
3188
4186
|
return JSON.stringify({
|
|
@@ -3222,59 +4220,11 @@ async function startBackgroundProcess(args, deps) {
|
|
|
3222
4220
|
}
|
|
3223
4221
|
}
|
|
3224
4222
|
function createBackgroundProcessTool(deps) {
|
|
3225
|
-
return (0, import_agent_tools3.createZodFunctionTool)(
|
|
3226
|
-
"BackgroundProcess",
|
|
3227
|
-
"Start a shell command as a managed background task. Use this for long-running commands that should not block the current conversation. Use /background list, /background read <taskId>, /background cancel <taskId>, or /background close <taskId> to inspect or control it.",
|
|
3228
|
-
asZodSchema2(BackgroundProcessSchema),
|
|
3229
|
-
async (params) => startBackgroundProcess(params, deps)
|
|
3230
|
-
);
|
|
3231
|
-
}
|
|
3232
|
-
|
|
3233
|
-
// src/tools/command-execution-tool.ts
|
|
3234
|
-
var import_zod4 = require("zod");
|
|
3235
|
-
var import_agent_tools4 = require("@robota-sdk/agent-tools");
|
|
3236
|
-
var CommandExecutionSchema = import_zod4.z.object({
|
|
3237
|
-
command: import_zod4.z.string().describe("Command name to execute, with or without a leading slash"),
|
|
3238
|
-
args: import_zod4.z.string().optional().describe("Arguments to pass to the command")
|
|
3239
|
-
});
|
|
3240
|
-
function asZodSchema3(schema) {
|
|
3241
|
-
return schema;
|
|
3242
|
-
}
|
|
3243
|
-
function normalizeCommand(command) {
|
|
3244
|
-
return command.trim().replace(/^\/+/, "").split(/\s+/)[0] ?? "";
|
|
3245
|
-
}
|
|
3246
|
-
function stringifyCommandResult(command, result) {
|
|
3247
|
-
if (!result) {
|
|
3248
|
-
return JSON.stringify({
|
|
3249
|
-
success: false,
|
|
3250
|
-
command,
|
|
3251
|
-
error: `Unknown command: ${command}`
|
|
3252
|
-
});
|
|
3253
|
-
}
|
|
3254
|
-
return JSON.stringify({
|
|
3255
|
-
success: result.success,
|
|
3256
|
-
command,
|
|
3257
|
-
message: result.message,
|
|
3258
|
-
data: result.data
|
|
3259
|
-
});
|
|
3260
|
-
}
|
|
3261
|
-
function createCommandExecutionTool(deps) {
|
|
3262
4223
|
return (0, import_agent_tools4.createZodFunctionTool)(
|
|
3263
|
-
"
|
|
3264
|
-
"
|
|
3265
|
-
asZodSchema3(
|
|
3266
|
-
async (params) =>
|
|
3267
|
-
const args = CommandExecutionSchema.parse(params);
|
|
3268
|
-
const command = normalizeCommand(args.command);
|
|
3269
|
-
if (!deps.isModelInvocable(command)) {
|
|
3270
|
-
return JSON.stringify({
|
|
3271
|
-
success: false,
|
|
3272
|
-
command,
|
|
3273
|
-
error: `Command is not model-invocable: ${command}`
|
|
3274
|
-
});
|
|
3275
|
-
}
|
|
3276
|
-
return stringifyCommandResult(command, await deps.execute(command, args.args ?? ""));
|
|
3277
|
-
}
|
|
4224
|
+
"BackgroundProcess",
|
|
4225
|
+
"Start a shell command as a managed background task. Use this for long-running commands that should not block the current conversation. Use /background list, /background read <taskId>, /background cancel <taskId>, or /background close <taskId> to inspect or control it.",
|
|
4226
|
+
asZodSchema3(BackgroundProcessSchema),
|
|
4227
|
+
async (params) => startBackgroundProcess(params, deps)
|
|
3278
4228
|
);
|
|
3279
4229
|
}
|
|
3280
4230
|
|
|
@@ -3338,6 +4288,9 @@ function evaluateReversibleToolSafety(input) {
|
|
|
3338
4288
|
};
|
|
3339
4289
|
}
|
|
3340
4290
|
if (FILE_MUTATION_TOOLS.has(toolName)) {
|
|
4291
|
+
if (input.context.isolation === "worktree" || input.context.isolation === "provider-sandbox") {
|
|
4292
|
+
return evaluateIsolatedSideEffect(toolName, "file-mutation", input.context);
|
|
4293
|
+
}
|
|
3341
4294
|
if (input.context.checkpointAvailable) {
|
|
3342
4295
|
return {
|
|
3343
4296
|
toolName,
|
|
@@ -3520,8 +4473,8 @@ var import_agent_runtime6 = require("@robota-sdk/agent-runtime");
|
|
|
3520
4473
|
|
|
3521
4474
|
// src/agents/agent-definition-loader.ts
|
|
3522
4475
|
var import_node_fs4 = require("fs");
|
|
3523
|
-
var
|
|
3524
|
-
var
|
|
4476
|
+
var import_node_path7 = require("path");
|
|
4477
|
+
var import_node_os4 = require("os");
|
|
3525
4478
|
var LIST_KEYS2 = /* @__PURE__ */ new Set(["tools", "disallowedTools"]);
|
|
3526
4479
|
var NUMBER_KEYS = /* @__PURE__ */ new Set(["maxTurns"]);
|
|
3527
4480
|
function parseListValue2(rawValue) {
|
|
@@ -3575,10 +4528,10 @@ function scanAgentsDir(dir) {
|
|
|
3575
4528
|
}
|
|
3576
4529
|
for (const entry of entries) {
|
|
3577
4530
|
if (!entry.isFile() || !entry.name.endsWith(".md")) continue;
|
|
3578
|
-
const filePath = (0,
|
|
4531
|
+
const filePath = (0, import_node_path7.join)(dir, entry.name);
|
|
3579
4532
|
const content = (0, import_node_fs4.readFileSync)(filePath, "utf-8");
|
|
3580
4533
|
const { frontmatter, body } = parseFrontmatter2(content);
|
|
3581
|
-
const fallbackName = (0,
|
|
4534
|
+
const fallbackName = (0, import_node_path7.basename)(entry.name, ".md");
|
|
3582
4535
|
const agent = {
|
|
3583
4536
|
name: frontmatter?.name ?? fallbackName,
|
|
3584
4537
|
description: frontmatter?.description ?? "",
|
|
@@ -3598,16 +4551,16 @@ var AgentDefinitionLoader = class {
|
|
|
3598
4551
|
home;
|
|
3599
4552
|
constructor(cwd, home) {
|
|
3600
4553
|
this.cwd = cwd;
|
|
3601
|
-
this.home = home ?? (0,
|
|
4554
|
+
this.home = home ?? (0, import_node_os4.homedir)();
|
|
3602
4555
|
}
|
|
3603
4556
|
/** Load all agent definitions, merged with built-in agents. Custom overrides built-in on name collision. */
|
|
3604
4557
|
loadAll() {
|
|
3605
4558
|
const sources = [
|
|
3606
|
-
scanAgentsDir((0,
|
|
3607
|
-
scanAgentsDir((0,
|
|
3608
|
-
scanAgentsDir((0,
|
|
3609
|
-
scanAgentsDir((0,
|
|
3610
|
-
scanAgentsDir((0,
|
|
4559
|
+
scanAgentsDir((0, import_node_path7.join)(this.cwd, ".robota", "agents")),
|
|
4560
|
+
scanAgentsDir((0, import_node_path7.join)(this.cwd, ".agents", "agents")),
|
|
4561
|
+
scanAgentsDir((0, import_node_path7.join)(this.cwd, ".claude", "agents")),
|
|
4562
|
+
scanAgentsDir((0, import_node_path7.join)(this.home, ".robota", "agents")),
|
|
4563
|
+
scanAgentsDir((0, import_node_path7.join)(this.home, ".claude", "agents"))
|
|
3611
4564
|
];
|
|
3612
4565
|
const seen = /* @__PURE__ */ new Set();
|
|
3613
4566
|
const customAgents = [];
|
|
@@ -3676,6 +4629,17 @@ function fireSubagentLifecycleHook(event, cwd, hooks, hookTypeExecutors) {
|
|
|
3676
4629
|
var ID_RADIX = 36;
|
|
3677
4630
|
var ID_RANDOM_LENGTH = 9;
|
|
3678
4631
|
var DEFAULT_PROVIDER_IDLE_TIMEOUT_MS = 12e4;
|
|
4632
|
+
function getModelInvocableCommandDescriptors(descriptors) {
|
|
4633
|
+
return (descriptors ?? []).filter(
|
|
4634
|
+
(descriptor) => descriptor.modelInvocable && descriptor.kind === "builtin-command"
|
|
4635
|
+
);
|
|
4636
|
+
}
|
|
4637
|
+
function normalizeCommandDescriptorName(name) {
|
|
4638
|
+
return name.trim().replace(/^\/+/, "").split(/\s+/)[0] ?? "";
|
|
4639
|
+
}
|
|
4640
|
+
function hasModelInvocableCommandDescriptor(descriptors, name) {
|
|
4641
|
+
return descriptors.some((descriptor) => normalizeCommandDescriptorName(descriptor.name) === name);
|
|
4642
|
+
}
|
|
3679
4643
|
function createSession(options) {
|
|
3680
4644
|
if (!options.provider) {
|
|
3681
4645
|
throw new Error(
|
|
@@ -3685,17 +4649,34 @@ function createSession(options) {
|
|
|
3685
4649
|
const provider = options.provider;
|
|
3686
4650
|
const cwd = options.cwd ?? process.cwd();
|
|
3687
4651
|
const sessionId = options.sessionId ?? createSessionId();
|
|
3688
|
-
const
|
|
4652
|
+
const skillCommandSource = new SkillCommandSource(cwd);
|
|
4653
|
+
const modelInvocableCommandDescriptors = getModelInvocableCommandDescriptors(
|
|
4654
|
+
options.commandDescriptors
|
|
4655
|
+
);
|
|
4656
|
+
const modelCommandToolsEnabled = modelInvocableCommandDescriptors.length > 0 && options.modelCommandExecutor !== void 0 && options.isModelCommandInvocable !== void 0;
|
|
4657
|
+
const modelCommandToolProjection = modelCommandToolsEnabled ? createModelCommandToolProjection(modelInvocableCommandDescriptors) : void 0;
|
|
4658
|
+
const modelVisibleSkills = hasModelInvocableCommandDescriptor(
|
|
4659
|
+
modelInvocableCommandDescriptors,
|
|
4660
|
+
"skills"
|
|
4661
|
+
) ? skillCommandSource.getModelInvocableSkills() : [];
|
|
4662
|
+
const baseDefaultTools = createDefaultTools({ sandboxClient: options.sandboxClient });
|
|
4663
|
+
const shouldWrapHostEditCheckpoints = options.editCheckpointRecorder !== void 0 && options.sandboxClient === void 0;
|
|
4664
|
+
const defaultTools = shouldWrapHostEditCheckpoints && options.editCheckpointRecorder ? wrapEditCheckpointTools(baseDefaultTools, options.editCheckpointRecorder) : baseDefaultTools;
|
|
3689
4665
|
const assembledTools = [...defaultTools, ...options.additionalTools ?? []];
|
|
3690
|
-
const
|
|
4666
|
+
const reversibleExecution = options.reversibleExecution ? {
|
|
3691
4667
|
...options.reversibleExecution,
|
|
3692
|
-
|
|
4668
|
+
isolation: options.reversibleExecution.isolation ?? (options.sandboxClient ? "provider-sandbox" : void 0)
|
|
4669
|
+
} : void 0;
|
|
4670
|
+
const tools = reversibleExecution ? wrapReversibleExecutionTools(assembledTools, {
|
|
4671
|
+
...reversibleExecution,
|
|
4672
|
+
checkpointAvailable: shouldWrapHostEditCheckpoints
|
|
3693
4673
|
}) : assembledTools;
|
|
3694
|
-
if (options.modelCommandExecutor && options.isModelCommandInvocable) {
|
|
4674
|
+
if (modelCommandToolsEnabled && options.modelCommandExecutor !== void 0 && options.isModelCommandInvocable !== void 0) {
|
|
3695
4675
|
tools.push(
|
|
3696
|
-
|
|
4676
|
+
...createProjectedCommandExecutionTools({
|
|
3697
4677
|
execute: options.modelCommandExecutor,
|
|
3698
|
-
isModelInvocable: options.isModelCommandInvocable
|
|
4678
|
+
isModelInvocable: options.isModelCommandInvocable,
|
|
4679
|
+
commandDescriptors: modelInvocableCommandDescriptors
|
|
3699
4680
|
})
|
|
3700
4681
|
);
|
|
3701
4682
|
}
|
|
@@ -3778,14 +4759,12 @@ function createSession(options) {
|
|
|
3778
4759
|
};
|
|
3779
4760
|
tools.push(createBackgroundProcessTool(backgroundProcessToolDeps));
|
|
3780
4761
|
}
|
|
3781
|
-
if (agentToolDeps) {
|
|
3782
|
-
tools.push(createAgentTool(agentToolDeps));
|
|
3783
|
-
}
|
|
3784
4762
|
const buildPrompt = options.systemPromptBuilder ?? buildSystemPrompt;
|
|
3785
4763
|
const defaultToolDescriptions = [
|
|
3786
4764
|
...DEFAULT_TOOL_DESCRIPTIONS,
|
|
3787
|
-
...
|
|
3788
|
-
|
|
4765
|
+
...modelCommandToolProjection ? modelCommandToolProjection.commandTools.map(
|
|
4766
|
+
formatProjectedModelCommandToolPromptDescription
|
|
4767
|
+
) : []
|
|
3789
4768
|
];
|
|
3790
4769
|
const systemMessage = buildPrompt({
|
|
3791
4770
|
agentsMd: options.context.agentsMd,
|
|
@@ -3800,7 +4779,7 @@ function createSession(options) {
|
|
|
3800
4779
|
projectInfo: options.projectInfo ?? { type: "unknown", language: "unknown" },
|
|
3801
4780
|
cwd,
|
|
3802
4781
|
language: options.config.language,
|
|
3803
|
-
skills:
|
|
4782
|
+
skills: modelVisibleSkills.map((skill) => ({
|
|
3804
4783
|
name: skill.name,
|
|
3805
4784
|
description: skill.description,
|
|
3806
4785
|
disableModelInvocation: skill.disableModelInvocation
|
|
@@ -3829,7 +4808,7 @@ ${options.appendSystemPrompt}` : systemMessage;
|
|
|
3829
4808
|
allow: [...defaultAllow, ...options.config.permissions.allow ?? [], ...allowedToolPatterns],
|
|
3830
4809
|
deny: options.config.permissions.deny ?? []
|
|
3831
4810
|
};
|
|
3832
|
-
const SessionWithAutoCompact =
|
|
4811
|
+
const SessionWithAutoCompact = import_agent_sessions4.Session;
|
|
3833
4812
|
const session = new SessionWithAutoCompact({
|
|
3834
4813
|
tools,
|
|
3835
4814
|
provider,
|
|
@@ -3874,41 +4853,19 @@ function logBackgroundTaskEvent(logger, sessionId, event) {
|
|
|
3874
4853
|
|
|
3875
4854
|
// src/assembly/subagent-logger.ts
|
|
3876
4855
|
var import_node_fs5 = require("fs");
|
|
3877
|
-
var
|
|
3878
|
-
var
|
|
4856
|
+
var import_node_path8 = require("path");
|
|
4857
|
+
var import_agent_sessions5 = require("@robota-sdk/agent-sessions");
|
|
3879
4858
|
function createSubagentLogger(parentSessionId, _agentId, baseLogsDir) {
|
|
3880
|
-
const subagentDir = (0,
|
|
4859
|
+
const subagentDir = (0, import_node_path8.join)(baseLogsDir, parentSessionId, "subagents");
|
|
3881
4860
|
(0, import_node_fs5.mkdirSync)(subagentDir, { recursive: true });
|
|
3882
|
-
return new
|
|
4861
|
+
return new import_agent_sessions5.FileSessionLogger(subagentDir);
|
|
3883
4862
|
}
|
|
3884
4863
|
function resolveSubagentLogDir(parentSessionId, baseLogsDir) {
|
|
3885
|
-
return (0,
|
|
4864
|
+
return (0, import_node_path8.join)(baseLogsDir, parentSessionId, "subagents");
|
|
3886
4865
|
}
|
|
3887
4866
|
|
|
3888
4867
|
// src/interactive/interactive-session-init.ts
|
|
3889
|
-
var
|
|
3890
|
-
|
|
3891
|
-
// src/paths.ts
|
|
3892
|
-
var import_node_path5 = require("path");
|
|
3893
|
-
var import_node_os3 = require("os");
|
|
3894
|
-
function projectPaths(cwd) {
|
|
3895
|
-
const base = (0, import_node_path5.join)(cwd, ".robota");
|
|
3896
|
-
return {
|
|
3897
|
-
settings: (0, import_node_path5.join)(base, "settings.json"),
|
|
3898
|
-
settingsLocal: (0, import_node_path5.join)(base, "settings.local.json"),
|
|
3899
|
-
logs: (0, import_node_path5.join)(base, "logs"),
|
|
3900
|
-
sessions: (0, import_node_path5.join)(base, "sessions"),
|
|
3901
|
-
memory: (0, import_node_path5.join)(base, "memory"),
|
|
3902
|
-
checkpoints: (0, import_node_path5.join)(base, "checkpoints")
|
|
3903
|
-
};
|
|
3904
|
-
}
|
|
3905
|
-
function userPaths() {
|
|
3906
|
-
const base = (0, import_node_path5.join)((0, import_node_os3.homedir)(), ".robota");
|
|
3907
|
-
return {
|
|
3908
|
-
settings: (0, import_node_path5.join)(base, "settings.json"),
|
|
3909
|
-
sessions: (0, import_node_path5.join)(base, "sessions")
|
|
3910
|
-
};
|
|
3911
|
-
}
|
|
4868
|
+
var import_agent_sessions6 = require("@robota-sdk/agent-sessions");
|
|
3912
4869
|
|
|
3913
4870
|
// src/context/context-loader.ts
|
|
3914
4871
|
var import_fs3 = require("fs");
|
|
@@ -3916,8 +4873,8 @@ var import_path3 = require("path");
|
|
|
3916
4873
|
|
|
3917
4874
|
// src/context/task-context.ts
|
|
3918
4875
|
var import_node_fs6 = require("fs");
|
|
3919
|
-
var
|
|
3920
|
-
var TASKS_DIR = (0,
|
|
4876
|
+
var import_node_path9 = require("path");
|
|
4877
|
+
var TASKS_DIR = (0, import_node_path9.join)(".agents", "tasks");
|
|
3921
4878
|
var README_FILENAME = "README.md";
|
|
3922
4879
|
var MARKDOWN_EXTENSION = ".md";
|
|
3923
4880
|
var DEFAULT_MAX_TASKS = Number("3");
|
|
@@ -3937,7 +4894,7 @@ function normalizeStatus(value) {
|
|
|
3937
4894
|
}
|
|
3938
4895
|
function extractTitle(content, taskPath) {
|
|
3939
4896
|
const heading = content.split(/\r?\n/).find((line) => /^#\s+/.test(line));
|
|
3940
|
-
return heading?.replace(/^#\s+/, "").trim() || (0,
|
|
4897
|
+
return heading?.replace(/^#\s+/, "").trim() || (0, import_node_path9.basename)(taskPath, MARKDOWN_EXTENSION);
|
|
3941
4898
|
}
|
|
3942
4899
|
function extractMetadata(content, key) {
|
|
3943
4900
|
const matcher = new RegExp(`^- \\*\\*${key}\\*\\*:\\s*(.+)$`, "im");
|
|
@@ -4017,18 +4974,18 @@ function appendProgressEntry(content, now, progressMessage) {
|
|
|
4017
4974
|
return lines.join("\n");
|
|
4018
4975
|
}
|
|
4019
4976
|
function resolveGitDirectory(cwd) {
|
|
4020
|
-
let current = (0,
|
|
4977
|
+
let current = (0, import_node_path9.resolve)(cwd);
|
|
4021
4978
|
let reachedRoot = false;
|
|
4022
4979
|
while (!reachedRoot) {
|
|
4023
|
-
const gitPath = (0,
|
|
4980
|
+
const gitPath = (0, import_node_path9.join)(current, ".git");
|
|
4024
4981
|
if ((0, import_node_fs6.existsSync)(gitPath)) {
|
|
4025
4982
|
const stats = (0, import_node_fs6.statSync)(gitPath);
|
|
4026
4983
|
if (stats.isDirectory()) return gitPath;
|
|
4027
4984
|
const content = (0, import_node_fs6.readFileSync)(gitPath, "utf8").trim();
|
|
4028
4985
|
const gitdir = content.match(/^gitdir:\s*(.+)$/)?.[1];
|
|
4029
|
-
if (gitdir) return (0,
|
|
4986
|
+
if (gitdir) return (0, import_node_path9.isAbsolute)(gitdir) ? gitdir : (0, import_node_path9.resolve)(current, gitdir);
|
|
4030
4987
|
}
|
|
4031
|
-
const parent = (0,
|
|
4988
|
+
const parent = (0, import_node_path9.dirname)(current);
|
|
4032
4989
|
reachedRoot = parent === current;
|
|
4033
4990
|
current = parent;
|
|
4034
4991
|
}
|
|
@@ -4037,24 +4994,24 @@ function resolveGitDirectory(cwd) {
|
|
|
4037
4994
|
function readCurrentGitBranch(cwd) {
|
|
4038
4995
|
const gitDir = resolveGitDirectory(cwd);
|
|
4039
4996
|
if (!gitDir) return void 0;
|
|
4040
|
-
const headPath = (0,
|
|
4997
|
+
const headPath = (0, import_node_path9.join)(gitDir, "HEAD");
|
|
4041
4998
|
if (!(0, import_node_fs6.existsSync)(headPath)) return void 0;
|
|
4042
4999
|
const head = (0, import_node_fs6.readFileSync)(headPath, "utf8").trim();
|
|
4043
5000
|
const branch = head.match(/^ref:\s+refs\/heads\/(.+)$/)?.[1];
|
|
4044
5001
|
return branch?.trim();
|
|
4045
5002
|
}
|
|
4046
5003
|
function discoverTaskFiles(cwd) {
|
|
4047
|
-
const tasksDir = (0,
|
|
5004
|
+
const tasksDir = (0, import_node_path9.join)(cwd, TASKS_DIR);
|
|
4048
5005
|
if (!(0, import_node_fs6.existsSync)(tasksDir)) {
|
|
4049
5006
|
return [];
|
|
4050
5007
|
}
|
|
4051
|
-
return (0, import_node_fs6.readdirSync)(tasksDir, { withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => entry.name).filter((name) => name !== README_FILENAME && name.endsWith(MARKDOWN_EXTENSION)).sort((a, b) => a.localeCompare(b)).map((name) => (0,
|
|
5008
|
+
return (0, import_node_fs6.readdirSync)(tasksDir, { withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => entry.name).filter((name) => name !== README_FILENAME && name.endsWith(MARKDOWN_EXTENSION)).sort((a, b) => a.localeCompare(b)).map((name) => (0, import_node_path9.join)(tasksDir, name));
|
|
4052
5009
|
}
|
|
4053
5010
|
function parseTaskFile(taskPath, cwd) {
|
|
4054
5011
|
const content = (0, import_node_fs6.readFileSync)(taskPath, "utf8");
|
|
4055
5012
|
return {
|
|
4056
5013
|
path: taskPath,
|
|
4057
|
-
relativePath: (0,
|
|
5014
|
+
relativePath: (0, import_node_path9.relative)(cwd, taskPath),
|
|
4058
5015
|
title: extractTitle(content, taskPath),
|
|
4059
5016
|
status: normalizeStatus(extractMetadata(content, "Status")),
|
|
4060
5017
|
branch: extractMetadata(content, "Branch"),
|
|
@@ -4209,7 +5166,7 @@ async function detectProject(cwd) {
|
|
|
4209
5166
|
|
|
4210
5167
|
// src/plugins/plugin-settings-store.ts
|
|
4211
5168
|
var import_node_fs7 = require("fs");
|
|
4212
|
-
var
|
|
5169
|
+
var import_node_path10 = require("path");
|
|
4213
5170
|
var PluginSettingsStore = class {
|
|
4214
5171
|
settingsPath;
|
|
4215
5172
|
constructor(settingsPath) {
|
|
@@ -4233,7 +5190,7 @@ var PluginSettingsStore = class {
|
|
|
4233
5190
|
}
|
|
4234
5191
|
/** Write the full settings file to disk. */
|
|
4235
5192
|
writeAll(settings) {
|
|
4236
|
-
const dir = (0,
|
|
5193
|
+
const dir = (0, import_node_path10.dirname)(this.settingsPath);
|
|
4237
5194
|
if (!(0, import_node_fs7.existsSync)(dir)) {
|
|
4238
5195
|
(0, import_node_fs7.mkdirSync)(dir, { recursive: true });
|
|
4239
5196
|
}
|
|
@@ -4310,7 +5267,7 @@ var PluginSettingsStore = class {
|
|
|
4310
5267
|
|
|
4311
5268
|
// src/plugins/bundle-plugin-loader.ts
|
|
4312
5269
|
var import_node_fs9 = require("fs");
|
|
4313
|
-
var
|
|
5270
|
+
var import_node_path11 = require("path");
|
|
4314
5271
|
|
|
4315
5272
|
// src/plugins/bundle-plugin-utils.ts
|
|
4316
5273
|
var import_node_fs8 = require("fs");
|
|
@@ -4394,22 +5351,22 @@ var BundlePluginLoader = class {
|
|
|
4394
5351
|
* For each marketplace/plugin pair, the latest version (lexicographically last) is loaded.
|
|
4395
5352
|
*/
|
|
4396
5353
|
discoverAndLoad() {
|
|
4397
|
-
const cacheDir = (0,
|
|
5354
|
+
const cacheDir = (0, import_node_path11.join)(this.pluginsDir, "cache");
|
|
4398
5355
|
if (!(0, import_node_fs9.existsSync)(cacheDir)) {
|
|
4399
5356
|
return [];
|
|
4400
5357
|
}
|
|
4401
5358
|
const results = [];
|
|
4402
5359
|
const marketplaces = getSortedSubdirs(cacheDir);
|
|
4403
5360
|
for (const marketplace of marketplaces) {
|
|
4404
|
-
const marketplaceDir = (0,
|
|
5361
|
+
const marketplaceDir = (0, import_node_path11.join)(cacheDir, marketplace);
|
|
4405
5362
|
const plugins = getSortedSubdirs(marketplaceDir);
|
|
4406
5363
|
for (const pluginName of plugins) {
|
|
4407
|
-
const pluginDir = (0,
|
|
5364
|
+
const pluginDir = (0, import_node_path11.join)(marketplaceDir, pluginName);
|
|
4408
5365
|
const versions = getSortedSubdirs(pluginDir);
|
|
4409
5366
|
if (versions.length === 0) continue;
|
|
4410
5367
|
const latestVersion = versions[versions.length - 1];
|
|
4411
|
-
const versionDir = (0,
|
|
4412
|
-
const manifestPath = (0,
|
|
5368
|
+
const versionDir = (0, import_node_path11.join)(pluginDir, latestVersion);
|
|
5369
|
+
const manifestPath = (0, import_node_path11.join)(versionDir, ".claude-plugin", "plugin.json");
|
|
4413
5370
|
if (!(0, import_node_fs9.existsSync)(manifestPath)) continue;
|
|
4414
5371
|
const manifest = this.readManifest(manifestPath);
|
|
4415
5372
|
if (!manifest) continue;
|
|
@@ -4459,13 +5416,13 @@ var BundlePluginLoader = class {
|
|
|
4459
5416
|
}
|
|
4460
5417
|
/** Load skills from the plugin's skills/ directory. */
|
|
4461
5418
|
loadSkills(pluginDir, pluginName) {
|
|
4462
|
-
const skillsDir = (0,
|
|
5419
|
+
const skillsDir = (0, import_node_path11.join)(pluginDir, "skills");
|
|
4463
5420
|
if (!(0, import_node_fs9.existsSync)(skillsDir)) return [];
|
|
4464
5421
|
const entries = (0, import_node_fs9.readdirSync)(skillsDir, { withFileTypes: true });
|
|
4465
5422
|
const skills = [];
|
|
4466
5423
|
for (const entry of entries) {
|
|
4467
5424
|
if (!entry.isDirectory()) continue;
|
|
4468
|
-
const skillFile = (0,
|
|
5425
|
+
const skillFile = (0, import_node_path11.join)(skillsDir, entry.name, "SKILL.md");
|
|
4469
5426
|
if (!(0, import_node_fs9.existsSync)(skillFile)) continue;
|
|
4470
5427
|
const raw = (0, import_node_fs9.readFileSync)(skillFile, "utf-8");
|
|
4471
5428
|
const { metadata, content } = parseSkillFrontmatter(raw);
|
|
@@ -4482,13 +5439,13 @@ var BundlePluginLoader = class {
|
|
|
4482
5439
|
}
|
|
4483
5440
|
/** Load commands from the plugin's commands/ directory (flat .md files). */
|
|
4484
5441
|
loadCommands(pluginDir, pluginName) {
|
|
4485
|
-
const commandsDir = (0,
|
|
5442
|
+
const commandsDir = (0, import_node_path11.join)(pluginDir, "commands");
|
|
4486
5443
|
if (!(0, import_node_fs9.existsSync)(commandsDir)) return [];
|
|
4487
5444
|
const entries = (0, import_node_fs9.readdirSync)(commandsDir, { withFileTypes: true });
|
|
4488
5445
|
const commands = [];
|
|
4489
5446
|
for (const entry of entries) {
|
|
4490
5447
|
if (!entry.isFile() || !entry.name.endsWith(".md")) continue;
|
|
4491
|
-
const raw = (0, import_node_fs9.readFileSync)((0,
|
|
5448
|
+
const raw = (0, import_node_fs9.readFileSync)((0, import_node_path11.join)(commandsDir, entry.name), "utf-8");
|
|
4492
5449
|
const { metadata, content } = parseSkillFrontmatter(raw);
|
|
4493
5450
|
const name = typeof metadata.name === "string" ? metadata.name : entry.name.replace(/\.md$/, "");
|
|
4494
5451
|
const description = typeof metadata.description === "string" ? metadata.description : "";
|
|
@@ -4503,7 +5460,7 @@ var BundlePluginLoader = class {
|
|
|
4503
5460
|
}
|
|
4504
5461
|
/** Load hooks from hooks/hooks.json if present. */
|
|
4505
5462
|
loadHooks(pluginDir) {
|
|
4506
|
-
const hooksPath = (0,
|
|
5463
|
+
const hooksPath = (0, import_node_path11.join)(pluginDir, "hooks", "hooks.json");
|
|
4507
5464
|
if (!(0, import_node_fs9.existsSync)(hooksPath)) return {};
|
|
4508
5465
|
try {
|
|
4509
5466
|
const raw = (0, import_node_fs9.readFileSync)(hooksPath, "utf-8");
|
|
@@ -4518,8 +5475,8 @@ var BundlePluginLoader = class {
|
|
|
4518
5475
|
}
|
|
4519
5476
|
/** Load MCP server configuration if present. Checks `.mcp.json` at plugin root first. */
|
|
4520
5477
|
loadMcpConfig(pluginDir) {
|
|
4521
|
-
const primaryPath = (0,
|
|
4522
|
-
const fallbackPath = (0,
|
|
5478
|
+
const primaryPath = (0, import_node_path11.join)(pluginDir, ".mcp.json");
|
|
5479
|
+
const fallbackPath = (0, import_node_path11.join)(pluginDir, ".claude-plugin", "mcp.json");
|
|
4523
5480
|
const mcpPath = (0, import_node_fs9.existsSync)(primaryPath) ? primaryPath : fallbackPath;
|
|
4524
5481
|
if (!(0, import_node_fs9.existsSync)(mcpPath)) return void 0;
|
|
4525
5482
|
try {
|
|
@@ -4531,7 +5488,7 @@ var BundlePluginLoader = class {
|
|
|
4531
5488
|
}
|
|
4532
5489
|
/** Load agent definitions from agents/ directory if present. */
|
|
4533
5490
|
loadAgents(pluginDir) {
|
|
4534
|
-
const agentsDir = (0,
|
|
5491
|
+
const agentsDir = (0, import_node_path11.join)(pluginDir, "agents");
|
|
4535
5492
|
if (!(0, import_node_fs9.existsSync)(agentsDir)) return [];
|
|
4536
5493
|
try {
|
|
4537
5494
|
const entries = (0, import_node_fs9.readdirSync)(agentsDir, { withFileTypes: true });
|
|
@@ -4545,7 +5502,7 @@ var BundlePluginLoader = class {
|
|
|
4545
5502
|
// src/plugins/bundle-plugin-installer.ts
|
|
4546
5503
|
var import_node_child_process2 = require("child_process");
|
|
4547
5504
|
var import_node_fs10 = require("fs");
|
|
4548
|
-
var
|
|
5505
|
+
var import_node_path12 = require("path");
|
|
4549
5506
|
var GIT_CLONE_TIMEOUT_MS = 6e4;
|
|
4550
5507
|
var BundlePluginInstaller = class {
|
|
4551
5508
|
pluginsDir;
|
|
@@ -4556,8 +5513,8 @@ var BundlePluginInstaller = class {
|
|
|
4556
5513
|
exec;
|
|
4557
5514
|
constructor(options) {
|
|
4558
5515
|
this.pluginsDir = options.pluginsDir;
|
|
4559
|
-
this.cacheDir = (0,
|
|
4560
|
-
this.registryPath = (0,
|
|
5516
|
+
this.cacheDir = (0, import_node_path12.join)(this.pluginsDir, "cache");
|
|
5517
|
+
this.registryPath = (0, import_node_path12.join)(this.pluginsDir, "installed_plugins.json");
|
|
4561
5518
|
this.settingsStore = options.settingsStore;
|
|
4562
5519
|
this.marketplaceClient = options.marketplaceClient;
|
|
4563
5520
|
this.exec = options.exec ?? this.defaultExec;
|
|
@@ -4577,7 +5534,7 @@ var BundlePluginInstaller = class {
|
|
|
4577
5534
|
throw new Error(`Plugin "${pluginName}" not found in marketplace "${marketplaceName}"`);
|
|
4578
5535
|
}
|
|
4579
5536
|
const version = this.resolveVersion(entry, marketplaceName);
|
|
4580
|
-
const targetDir = (0,
|
|
5537
|
+
const targetDir = (0, import_node_path12.join)(this.cacheDir, marketplaceName, pluginName, version);
|
|
4581
5538
|
if ((0, import_node_fs10.existsSync)(targetDir)) {
|
|
4582
5539
|
throw new Error(
|
|
4583
5540
|
`Plugin "${pluginName}" version "${version}" is already installed from "${marketplaceName}"`
|
|
@@ -4657,7 +5614,7 @@ var BundlePluginInstaller = class {
|
|
|
4657
5614
|
try {
|
|
4658
5615
|
if (typeof source === "string") {
|
|
4659
5616
|
const marketplaceDir = this.marketplaceClient.getMarketplaceDir(marketplaceName);
|
|
4660
|
-
const sourcePath = (0,
|
|
5617
|
+
const sourcePath = (0, import_node_path12.join)(marketplaceDir, source);
|
|
4661
5618
|
if (!(0, import_node_fs10.existsSync)(sourcePath)) {
|
|
4662
5619
|
throw new Error(
|
|
4663
5620
|
`Plugin source path "${source}" not found in marketplace "${marketplaceName}"`
|
|
@@ -4710,7 +5667,7 @@ var BundlePluginInstaller = class {
|
|
|
4710
5667
|
}
|
|
4711
5668
|
/** Write the installed_plugins.json registry. */
|
|
4712
5669
|
writeRegistry(registry) {
|
|
4713
|
-
const dir = (0,
|
|
5670
|
+
const dir = (0, import_node_path12.dirname)(this.registryPath);
|
|
4714
5671
|
if (!(0, import_node_fs10.existsSync)(dir)) {
|
|
4715
5672
|
(0, import_node_fs10.mkdirSync)(dir, { recursive: true });
|
|
4716
5673
|
}
|
|
@@ -4725,11 +5682,11 @@ var BundlePluginInstaller = class {
|
|
|
4725
5682
|
// src/plugins/marketplace-client.ts
|
|
4726
5683
|
var import_node_child_process3 = require("child_process");
|
|
4727
5684
|
var import_node_fs12 = require("fs");
|
|
4728
|
-
var
|
|
5685
|
+
var import_node_path14 = require("path");
|
|
4729
5686
|
|
|
4730
5687
|
// src/plugins/marketplace-registry.ts
|
|
4731
5688
|
var import_node_fs11 = require("fs");
|
|
4732
|
-
var
|
|
5689
|
+
var import_node_path13 = require("path");
|
|
4733
5690
|
function readRegistry(registryPath) {
|
|
4734
5691
|
if (!(0, import_node_fs11.existsSync)(registryPath)) {
|
|
4735
5692
|
return {};
|
|
@@ -4746,14 +5703,14 @@ function readRegistry(registryPath) {
|
|
|
4746
5703
|
}
|
|
4747
5704
|
}
|
|
4748
5705
|
function writeRegistry(registryPath, registry) {
|
|
4749
|
-
const dir = (0,
|
|
5706
|
+
const dir = (0, import_node_path13.dirname)(registryPath);
|
|
4750
5707
|
if (!(0, import_node_fs11.existsSync)(dir)) {
|
|
4751
5708
|
(0, import_node_fs11.mkdirSync)(dir, { recursive: true });
|
|
4752
5709
|
}
|
|
4753
5710
|
(0, import_node_fs11.writeFileSync)(registryPath, JSON.stringify(registry, null, 2), "utf-8");
|
|
4754
5711
|
}
|
|
4755
5712
|
function removeInstalledPluginsForMarketplace(pluginsDir, marketplaceName) {
|
|
4756
|
-
const installedPath = (0,
|
|
5713
|
+
const installedPath = (0, import_node_path13.join)(pluginsDir, "installed_plugins.json");
|
|
4757
5714
|
if (!(0, import_node_fs11.existsSync)(installedPath)) return;
|
|
4758
5715
|
let registry;
|
|
4759
5716
|
try {
|
|
@@ -4775,7 +5732,7 @@ function removeInstalledPluginsForMarketplace(pluginsDir, marketplaceName) {
|
|
|
4775
5732
|
}
|
|
4776
5733
|
}
|
|
4777
5734
|
if (changed) {
|
|
4778
|
-
const dir = (0,
|
|
5735
|
+
const dir = (0, import_node_path13.dirname)(installedPath);
|
|
4779
5736
|
if (!(0, import_node_fs11.existsSync)(dir)) {
|
|
4780
5737
|
(0, import_node_fs11.mkdirSync)(dir, { recursive: true });
|
|
4781
5738
|
}
|
|
@@ -4793,8 +5750,8 @@ var MarketplaceClient = class {
|
|
|
4793
5750
|
constructor(options) {
|
|
4794
5751
|
this.pluginsDir = options.pluginsDir;
|
|
4795
5752
|
this.exec = options.exec ?? this.defaultExec;
|
|
4796
|
-
this.marketplacesDir = (0,
|
|
4797
|
-
this.registryPath = (0,
|
|
5753
|
+
this.marketplacesDir = (0, import_node_path14.join)(this.pluginsDir, "marketplaces");
|
|
5754
|
+
this.registryPath = (0, import_node_path14.join)(this.pluginsDir, "known_marketplaces.json");
|
|
4798
5755
|
}
|
|
4799
5756
|
/**
|
|
4800
5757
|
* Add a marketplace by cloning its repository.
|
|
@@ -4807,7 +5764,7 @@ var MarketplaceClient = class {
|
|
|
4807
5764
|
*/
|
|
4808
5765
|
addMarketplace(source) {
|
|
4809
5766
|
const tempName = "temp-" + Date.now().toString(36);
|
|
4810
|
-
const tempDir = (0,
|
|
5767
|
+
const tempDir = (0, import_node_path14.join)(this.marketplacesDir, tempName);
|
|
4811
5768
|
(0, import_node_fs12.mkdirSync)(this.marketplacesDir, { recursive: true });
|
|
4812
5769
|
if (source.type === "local") {
|
|
4813
5770
|
if (!(0, import_node_fs12.existsSync)(source.path)) {
|
|
@@ -4824,7 +5781,7 @@ var MarketplaceClient = class {
|
|
|
4824
5781
|
throw new Error(`Failed to clone marketplace: ${message}`);
|
|
4825
5782
|
}
|
|
4826
5783
|
}
|
|
4827
|
-
const manifestPath = (0,
|
|
5784
|
+
const manifestPath = (0, import_node_path14.join)(tempDir, ".claude-plugin", "marketplace.json");
|
|
4828
5785
|
if (!(0, import_node_fs12.existsSync)(manifestPath)) {
|
|
4829
5786
|
(0, import_node_fs12.rmSync)(tempDir, { recursive: true, force: true });
|
|
4830
5787
|
throw new Error(
|
|
@@ -4842,7 +5799,7 @@ var MarketplaceClient = class {
|
|
|
4842
5799
|
(0, import_node_fs12.rmSync)(tempDir, { recursive: true, force: true });
|
|
4843
5800
|
throw new Error(`Marketplace "${name}" already exists`);
|
|
4844
5801
|
}
|
|
4845
|
-
const finalDir = (0,
|
|
5802
|
+
const finalDir = (0, import_node_path14.join)(this.marketplacesDir, name);
|
|
4846
5803
|
(0, import_node_fs12.renameSync)(tempDir, finalDir);
|
|
4847
5804
|
registry[name] = {
|
|
4848
5805
|
source,
|
|
@@ -4919,7 +5876,7 @@ var MarketplaceClient = class {
|
|
|
4919
5876
|
if (!entry) {
|
|
4920
5877
|
throw new Error(`Marketplace "${marketplaceName}" not found`);
|
|
4921
5878
|
}
|
|
4922
|
-
const manifestPath = (0,
|
|
5879
|
+
const manifestPath = (0, import_node_path14.join)(entry.installLocation, ".claude-plugin", "marketplace.json");
|
|
4923
5880
|
if (!(0, import_node_fs12.existsSync)(manifestPath)) {
|
|
4924
5881
|
throw new Error(
|
|
4925
5882
|
`Marketplace "${marketplaceName}" does not contain .claude-plugin/marketplace.json`
|
|
@@ -5001,9 +5958,9 @@ var MarketplaceClient = class {
|
|
|
5001
5958
|
};
|
|
5002
5959
|
|
|
5003
5960
|
// src/plugins/plugin-hooks-merger.ts
|
|
5004
|
-
var
|
|
5961
|
+
var import_node_path15 = require("path");
|
|
5005
5962
|
function buildPluginEnv(plugin) {
|
|
5006
|
-
const dataDir = (0,
|
|
5963
|
+
const dataDir = (0, import_node_path15.join)((0, import_node_path15.dirname)((0, import_node_path15.dirname)(plugin.pluginDir)), "data", plugin.manifest.name);
|
|
5007
5964
|
return {
|
|
5008
5965
|
CLAUDE_PLUGIN_ROOT: plugin.pluginDir,
|
|
5009
5966
|
CLAUDE_PLUGIN_PATH: plugin.pluginDir,
|
|
@@ -5065,8 +6022,9 @@ function mergeHooksIntoConfig(configHooks, pluginHooks) {
|
|
|
5065
6022
|
}
|
|
5066
6023
|
|
|
5067
6024
|
// src/interactive/interactive-session-init.ts
|
|
5068
|
-
var
|
|
5069
|
-
var
|
|
6025
|
+
var import_node_os5 = require("os");
|
|
6026
|
+
var import_node_path16 = require("path");
|
|
6027
|
+
var import_agent_tools5 = require("@robota-sdk/agent-tools");
|
|
5070
6028
|
async function createInteractiveSession(options) {
|
|
5071
6029
|
const cwd = options.cwd;
|
|
5072
6030
|
const [config, context, projectInfo] = await Promise.all([
|
|
@@ -5074,7 +6032,7 @@ async function createInteractiveSession(options) {
|
|
|
5074
6032
|
options.bare ? Promise.resolve({ agentsMd: "", claudeMd: "" }) : loadContext(cwd),
|
|
5075
6033
|
options.bare ? Promise.resolve({ type: "unknown", language: "unknown" }) : detectProject(cwd)
|
|
5076
6034
|
]);
|
|
5077
|
-
const pluginsDir = (0,
|
|
6035
|
+
const pluginsDir = (0, import_node_path16.join)((0, import_node_os5.homedir)(), ".robota", "plugins");
|
|
5078
6036
|
const pluginLoader = new BundlePluginLoader(pluginsDir);
|
|
5079
6037
|
let mergedConfig = config;
|
|
5080
6038
|
if (!options.bare) {
|
|
@@ -5094,6 +6052,10 @@ async function createInteractiveSession(options) {
|
|
|
5094
6052
|
}
|
|
5095
6053
|
}
|
|
5096
6054
|
const paths = projectPaths(cwd);
|
|
6055
|
+
const sandboxRestored = await restoreInteractiveSandboxSnapshot(options);
|
|
6056
|
+
if (!sandboxRestored) {
|
|
6057
|
+
await applyInteractiveWorkspaceManifest(options, cwd);
|
|
6058
|
+
}
|
|
5097
6059
|
const sessionId = options.resumeSessionId && !options.forkSession ? options.resumeSessionId : void 0;
|
|
5098
6060
|
return createSession({
|
|
5099
6061
|
config: mergedConfig,
|
|
@@ -5103,7 +6065,7 @@ async function createInteractiveSession(options) {
|
|
|
5103
6065
|
permissionMode: options.permissionMode,
|
|
5104
6066
|
maxTurns: options.maxTurns,
|
|
5105
6067
|
terminal: NOOP_TERMINAL,
|
|
5106
|
-
sessionLogger: new
|
|
6068
|
+
sessionLogger: new import_agent_sessions6.FileSessionLogger(paths.logs),
|
|
5107
6069
|
permissionHandler: options.permissionHandler,
|
|
5108
6070
|
provider: options.provider,
|
|
5109
6071
|
onTextDelta: options.onTextDelta,
|
|
@@ -5127,20 +6089,37 @@ async function createInteractiveSession(options) {
|
|
|
5127
6089
|
modelCommandExecutor: options.modelCommandExecutor,
|
|
5128
6090
|
isModelCommandInvocable: options.isModelCommandInvocable,
|
|
5129
6091
|
editCheckpointRecorder: options.editCheckpointRecorder,
|
|
5130
|
-
reversibleExecution: options.reversibleExecution
|
|
6092
|
+
reversibleExecution: options.reversibleExecution,
|
|
6093
|
+
sandboxClient: options.sandboxClient
|
|
5131
6094
|
});
|
|
5132
6095
|
}
|
|
6096
|
+
async function applyInteractiveWorkspaceManifest(options, cwd) {
|
|
6097
|
+
if (!options.workspaceManifest) return;
|
|
6098
|
+
if (!options.sandboxClient) {
|
|
6099
|
+
throw new Error("workspaceManifest requires sandboxClient.");
|
|
6100
|
+
}
|
|
6101
|
+
await (0, import_agent_tools5.applyWorkspaceManifest)(options.sandboxClient, options.workspaceManifest, {
|
|
6102
|
+
hostRoot: cwd,
|
|
6103
|
+
...options.sandboxWorkspaceRoot ? { targetRoot: options.sandboxWorkspaceRoot } : {}
|
|
6104
|
+
});
|
|
6105
|
+
}
|
|
6106
|
+
async function restoreInteractiveSandboxSnapshot(options) {
|
|
6107
|
+
if (!options.sandboxSnapshotId) return false;
|
|
6108
|
+
if (!options.sandboxClient?.restore) {
|
|
6109
|
+
throw new Error("sandboxSnapshotId requires sandboxClient with restore().");
|
|
6110
|
+
}
|
|
6111
|
+
await options.sandboxClient.restore(options.sandboxSnapshotId);
|
|
6112
|
+
return true;
|
|
6113
|
+
}
|
|
5133
6114
|
function injectSavedMessage(session, msg) {
|
|
5134
|
-
if (
|
|
5135
|
-
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
session.injectMessage(
|
|
5142
|
-
} else if (role === "user" || role === "assistant" || role === "system") {
|
|
5143
|
-
session.injectMessage(role, m.content);
|
|
6115
|
+
if (typeof msg.content !== "string") return;
|
|
6116
|
+
if (msg.role === "tool") {
|
|
6117
|
+
session.injectMessage("tool", msg.content, {
|
|
6118
|
+
toolCallId: msg.toolCallId,
|
|
6119
|
+
...msg.name !== void 0 ? { name: msg.name } : {}
|
|
6120
|
+
});
|
|
6121
|
+
} else {
|
|
6122
|
+
session.injectMessage(msg.role, msg.content);
|
|
5144
6123
|
}
|
|
5145
6124
|
}
|
|
5146
6125
|
function loadSessionRecord(sessionStore, resumeSessionId, forkSession, existingSession) {
|
|
@@ -5154,8 +6133,11 @@ function loadSessionRecord(sessionStore, resumeSessionId, forkSession, existingS
|
|
|
5154
6133
|
backgroundTaskEvents: [],
|
|
5155
6134
|
backgroundJobGroups: [],
|
|
5156
6135
|
backgroundJobGroupEvents: [],
|
|
6136
|
+
skillActivationEvents: [],
|
|
5157
6137
|
memoryEvents: [],
|
|
5158
|
-
usedMemoryReferences: []
|
|
6138
|
+
usedMemoryReferences: [],
|
|
6139
|
+
contextReferences: [],
|
|
6140
|
+
sandboxSnapshotId: void 0
|
|
5159
6141
|
};
|
|
5160
6142
|
}
|
|
5161
6143
|
const history = record.history ?? [];
|
|
@@ -5163,8 +6145,11 @@ function loadSessionRecord(sessionStore, resumeSessionId, forkSession, existingS
|
|
|
5163
6145
|
const restoredBackgroundTaskEvents = record.backgroundTaskEvents ?? [];
|
|
5164
6146
|
const backgroundJobGroups = record.backgroundJobGroups ?? [];
|
|
5165
6147
|
const backgroundJobGroupEvents = record.backgroundJobGroupEvents ?? [];
|
|
6148
|
+
const skillActivationEvents = record.skillActivationEvents ?? [];
|
|
5166
6149
|
const memoryEvents = record.memoryEvents ?? [];
|
|
5167
6150
|
const usedMemoryReferences = record.usedMemoryReferences ?? [];
|
|
6151
|
+
const contextReferences = record.contextReferences ?? [];
|
|
6152
|
+
const sandboxSnapshotId = record.sandboxSnapshotId;
|
|
5168
6153
|
const { backgroundTasks, backgroundTaskEvents } = reconcileRestoredBackgroundTasks(
|
|
5169
6154
|
restoredBackgroundTasks,
|
|
5170
6155
|
restoredBackgroundTaskEvents
|
|
@@ -5188,8 +6173,11 @@ function loadSessionRecord(sessionStore, resumeSessionId, forkSession, existingS
|
|
|
5188
6173
|
backgroundTaskEvents,
|
|
5189
6174
|
backgroundJobGroups,
|
|
5190
6175
|
backgroundJobGroupEvents,
|
|
6176
|
+
skillActivationEvents,
|
|
5191
6177
|
memoryEvents,
|
|
5192
|
-
usedMemoryReferences
|
|
6178
|
+
usedMemoryReferences,
|
|
6179
|
+
contextReferences,
|
|
6180
|
+
sandboxSnapshotId
|
|
5193
6181
|
};
|
|
5194
6182
|
}
|
|
5195
6183
|
function reconcileRestoredBackgroundTasks(tasks, events) {
|
|
@@ -5222,14 +6210,62 @@ function isRestoredTerminalStatus(status) {
|
|
|
5222
6210
|
return status === "completed" || status === "failed" || status === "cancelled";
|
|
5223
6211
|
}
|
|
5224
6212
|
|
|
6213
|
+
// src/interactive/interactive-session-context-references.ts
|
|
6214
|
+
async function addInteractiveContextReference(references, path, cwd) {
|
|
6215
|
+
const result = await resolvePromptFileReferencePaths([path], {
|
|
6216
|
+
cwd,
|
|
6217
|
+
reason: "manual"
|
|
6218
|
+
});
|
|
6219
|
+
if (hasBlockingPromptFileReferenceDiagnostics(result.diagnostics)) {
|
|
6220
|
+
return {
|
|
6221
|
+
references: [...references],
|
|
6222
|
+
result: {
|
|
6223
|
+
evicted: [],
|
|
6224
|
+
diagnostics: [formatPromptFileReferenceDiagnostics(result.diagnostics)]
|
|
6225
|
+
}
|
|
6226
|
+
};
|
|
6227
|
+
}
|
|
6228
|
+
const reference = result.references[0];
|
|
6229
|
+
if (!reference) {
|
|
6230
|
+
return {
|
|
6231
|
+
references: [...references],
|
|
6232
|
+
result: { evicted: [], diagnostics: ["No context reference was resolved."] }
|
|
6233
|
+
};
|
|
6234
|
+
}
|
|
6235
|
+
const item = createContextReferenceItem(
|
|
6236
|
+
toPromptFileReferenceRecords([reference])[0],
|
|
6237
|
+
"manual",
|
|
6238
|
+
"active"
|
|
6239
|
+
);
|
|
6240
|
+
const upserted = upsertContextReference(references, item);
|
|
6241
|
+
return {
|
|
6242
|
+
references: upserted.references,
|
|
6243
|
+
result: {
|
|
6244
|
+
reference: item,
|
|
6245
|
+
evicted: upserted.evicted,
|
|
6246
|
+
diagnostics: []
|
|
6247
|
+
}
|
|
6248
|
+
};
|
|
6249
|
+
}
|
|
6250
|
+
function recordInteractiveContextReferences(references, records, options) {
|
|
6251
|
+
if (records.length === 0) return [...references];
|
|
6252
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
6253
|
+
let next = [...references];
|
|
6254
|
+
for (const record of records) {
|
|
6255
|
+
const item = createContextReferenceItem(record, options.loadType, options.status, now);
|
|
6256
|
+
next = upsertContextReference(next, item).references;
|
|
6257
|
+
}
|
|
6258
|
+
return next;
|
|
6259
|
+
}
|
|
6260
|
+
|
|
5225
6261
|
// src/checkpoints/edit-checkpoint-store.ts
|
|
5226
|
-
var
|
|
6262
|
+
var import_promises2 = require("fs/promises");
|
|
5227
6263
|
var import_node_fs14 = require("fs");
|
|
5228
|
-
var
|
|
6264
|
+
var import_node_path18 = require("path");
|
|
5229
6265
|
|
|
5230
6266
|
// src/checkpoints/edit-checkpoint-inspection.ts
|
|
5231
6267
|
var import_node_fs13 = require("fs");
|
|
5232
|
-
var
|
|
6268
|
+
var import_node_path17 = require("path");
|
|
5233
6269
|
function buildEditCheckpointInspection(input) {
|
|
5234
6270
|
const later = input.manifests.filter((manifest) => manifest.sequence > input.target.sequence);
|
|
5235
6271
|
const rollbackRange = input.manifests.filter(
|
|
@@ -5238,11 +6274,11 @@ function buildEditCheckpointInspection(input) {
|
|
|
5238
6274
|
return {
|
|
5239
6275
|
target: toSummary(input.target),
|
|
5240
6276
|
capturedFiles: input.target.files.map((file) => {
|
|
5241
|
-
const snapshotPath = file.snapshotFile ? (0,
|
|
6277
|
+
const snapshotPath = file.snapshotFile ? (0, import_node_path17.join)(input.checkpointDir(input.sessionId, input.target.id), file.snapshotFile) : void 0;
|
|
5242
6278
|
const snapshotStats = snapshotPath ? statSafe(snapshotPath) : void 0;
|
|
5243
6279
|
return {
|
|
5244
6280
|
originalPath: file.originalPath,
|
|
5245
|
-
relativePath: (0,
|
|
6281
|
+
relativePath: (0, import_node_path17.relative)(input.cwd, file.originalPath),
|
|
5246
6282
|
existed: file.existed,
|
|
5247
6283
|
restoreAction: file.existed ? "restore-preimage" : "delete-created-file",
|
|
5248
6284
|
snapshotAvailable: file.existed ? snapshotStats !== void 0 : false,
|
|
@@ -5288,7 +6324,7 @@ var EditCheckpointStore = class {
|
|
|
5288
6324
|
now;
|
|
5289
6325
|
activeTurn = null;
|
|
5290
6326
|
constructor(options) {
|
|
5291
|
-
this.cwd = (0,
|
|
6327
|
+
this.cwd = (0, import_node_path18.resolve)(options.cwd);
|
|
5292
6328
|
this.rootDir = projectPaths(this.cwd).checkpoints;
|
|
5293
6329
|
this.now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
5294
6330
|
}
|
|
@@ -5298,8 +6334,8 @@ var EditCheckpointStore = class {
|
|
|
5298
6334
|
}
|
|
5299
6335
|
const nextSequence = this.nextSequence(input.sessionId);
|
|
5300
6336
|
const id = `turn-${String(nextSequence).padStart(ID_PAD, "0")}`;
|
|
5301
|
-
const dir = (0,
|
|
5302
|
-
await (0,
|
|
6337
|
+
const dir = (0, import_node_path18.join)(this.sessionDir(input.sessionId), id);
|
|
6338
|
+
await (0, import_promises2.mkdir)((0, import_node_path18.join)(dir, SNAPSHOT_DIR), { recursive: true });
|
|
5303
6339
|
const manifest = {
|
|
5304
6340
|
version: 1,
|
|
5305
6341
|
id,
|
|
@@ -5319,7 +6355,7 @@ var EditCheckpointStore = class {
|
|
|
5319
6355
|
}
|
|
5320
6356
|
async captureFile(filePath) {
|
|
5321
6357
|
if (!this.activeTurn) return;
|
|
5322
|
-
const originalPath = (0,
|
|
6358
|
+
const originalPath = (0, import_node_path18.resolve)(this.cwd, filePath);
|
|
5323
6359
|
if (this.activeTurn.capturedPaths.has(originalPath)) return;
|
|
5324
6360
|
if (isInside(this.rootDir, originalPath)) return;
|
|
5325
6361
|
const record = await this.createFileRecord(originalPath, this.activeTurn);
|
|
@@ -5366,7 +6402,7 @@ var EditCheckpointStore = class {
|
|
|
5366
6402
|
}
|
|
5367
6403
|
}
|
|
5368
6404
|
for (const manifest of later) {
|
|
5369
|
-
await (0,
|
|
6405
|
+
await (0, import_promises2.rm)(this.checkpointDir(sessionId, manifest.id), { recursive: true, force: true });
|
|
5370
6406
|
}
|
|
5371
6407
|
return {
|
|
5372
6408
|
target: toSummary2(target),
|
|
@@ -5390,7 +6426,7 @@ var EditCheckpointStore = class {
|
|
|
5390
6426
|
}
|
|
5391
6427
|
}
|
|
5392
6428
|
for (const manifest of rollbackRange) {
|
|
5393
|
-
await (0,
|
|
6429
|
+
await (0, import_promises2.rm)(this.checkpointDir(sessionId, manifest.id), { recursive: true, force: true });
|
|
5394
6430
|
}
|
|
5395
6431
|
return {
|
|
5396
6432
|
target: toSummary2(target),
|
|
@@ -5407,11 +6443,11 @@ var EditCheckpointStore = class {
|
|
|
5407
6443
|
existed: false
|
|
5408
6444
|
};
|
|
5409
6445
|
}
|
|
5410
|
-
const snapshotFile = (0,
|
|
6446
|
+
const snapshotFile = (0, import_node_path18.join)(
|
|
5411
6447
|
SNAPSHOT_DIR,
|
|
5412
6448
|
`${String(active.manifest.files.length + 1).padStart(SNAPSHOT_PAD, "0")}.content`
|
|
5413
6449
|
);
|
|
5414
|
-
await (0,
|
|
6450
|
+
await (0, import_promises2.copyFile)(originalPath, (0, import_node_path18.join)(active.dir, snapshotFile));
|
|
5415
6451
|
return {
|
|
5416
6452
|
originalPath,
|
|
5417
6453
|
existed: true,
|
|
@@ -5420,38 +6456,38 @@ var EditCheckpointStore = class {
|
|
|
5420
6456
|
}
|
|
5421
6457
|
async restoreFile(sessionId, checkpointId, record) {
|
|
5422
6458
|
if (!record.existed) {
|
|
5423
|
-
await (0,
|
|
6459
|
+
await (0, import_promises2.rm)(record.originalPath, { force: true });
|
|
5424
6460
|
return;
|
|
5425
6461
|
}
|
|
5426
6462
|
if (!record.snapshotFile) {
|
|
5427
6463
|
throw new Error(`Checkpoint file record is missing a snapshot: ${record.originalPath}`);
|
|
5428
6464
|
}
|
|
5429
|
-
await (0,
|
|
5430
|
-
await (0,
|
|
5431
|
-
(0,
|
|
6465
|
+
await (0, import_promises2.mkdir)((0, import_node_path18.dirname)(record.originalPath), { recursive: true });
|
|
6466
|
+
await (0, import_promises2.copyFile)(
|
|
6467
|
+
(0, import_node_path18.join)(this.checkpointDir(sessionId, checkpointId), record.snapshotFile),
|
|
5432
6468
|
record.originalPath
|
|
5433
6469
|
);
|
|
5434
6470
|
}
|
|
5435
6471
|
loadManifests(sessionId) {
|
|
5436
6472
|
const dir = this.sessionDir(sessionId);
|
|
5437
|
-
return readDirSyncSafe(dir).map((entry) => (0,
|
|
6473
|
+
return readDirSyncSafe(dir).map((entry) => (0, import_node_path18.join)(dir, entry, MANIFEST_FILE)).map((manifestPath) => readJsonManifest(manifestPath)).filter((manifest) => manifest !== void 0).sort((a, b) => a.sequence - b.sequence);
|
|
5438
6474
|
}
|
|
5439
6475
|
nextSequence(sessionId) {
|
|
5440
6476
|
const last = this.list(sessionId).at(-1);
|
|
5441
6477
|
return (last?.sequence ?? 0) + 1;
|
|
5442
6478
|
}
|
|
5443
6479
|
async writeManifest(dir, manifest) {
|
|
5444
|
-
await (0,
|
|
5445
|
-
const path = (0,
|
|
6480
|
+
await (0, import_promises2.mkdir)(dir, { recursive: true });
|
|
6481
|
+
const path = (0, import_node_path18.join)(dir, MANIFEST_FILE);
|
|
5446
6482
|
const tmp = `${path}.tmp`;
|
|
5447
|
-
await (0,
|
|
5448
|
-
await (0,
|
|
6483
|
+
await (0, import_promises2.writeFile)(tmp, JSON.stringify(manifest, null, 2), "utf8");
|
|
6484
|
+
await (0, import_promises2.rename)(tmp, path);
|
|
5449
6485
|
}
|
|
5450
6486
|
sessionDir(sessionId) {
|
|
5451
|
-
return (0,
|
|
6487
|
+
return (0, import_node_path18.join)(this.rootDir, safePathSegment(sessionId));
|
|
5452
6488
|
}
|
|
5453
6489
|
checkpointDir(sessionId, checkpointId) {
|
|
5454
|
-
return (0,
|
|
6490
|
+
return (0, import_node_path18.join)(this.sessionDir(sessionId), safePathSegment(checkpointId));
|
|
5455
6491
|
}
|
|
5456
6492
|
};
|
|
5457
6493
|
function toSummary2(manifest) {
|
|
@@ -5468,12 +6504,12 @@ function safePathSegment(value) {
|
|
|
5468
6504
|
return value.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
5469
6505
|
}
|
|
5470
6506
|
function isInside(parent, child) {
|
|
5471
|
-
const rel = (0,
|
|
6507
|
+
const rel = (0, import_node_path18.relative)(parent, child);
|
|
5472
6508
|
return rel.length === 0 || !rel.startsWith("..") && !rel.startsWith("/");
|
|
5473
6509
|
}
|
|
5474
6510
|
async function pathExists(path) {
|
|
5475
6511
|
try {
|
|
5476
|
-
await (0,
|
|
6512
|
+
await (0, import_promises2.access)(path, import_node_fs14.constants.F_OK);
|
|
5477
6513
|
return true;
|
|
5478
6514
|
} catch {
|
|
5479
6515
|
return false;
|
|
@@ -5496,6 +6532,21 @@ function readJsonManifest(path) {
|
|
|
5496
6532
|
}
|
|
5497
6533
|
|
|
5498
6534
|
// src/interactive/interactive-session.ts
|
|
6535
|
+
function normalizeSkillName(name) {
|
|
6536
|
+
return name.trim().replace(/^\/+/, "").split(/\s+/)[0] ?? "";
|
|
6537
|
+
}
|
|
6538
|
+
function normalizeCommandName(name) {
|
|
6539
|
+
return name.trim().replace(/^\/+/, "").split(/\s+/)[0] ?? "";
|
|
6540
|
+
}
|
|
6541
|
+
function formatSkillCommandArgs(skillName, args) {
|
|
6542
|
+
const trimmedArgs = args.trim();
|
|
6543
|
+
return trimmedArgs.length > 0 ? `${skillName} ${trimmedArgs}` : skillName;
|
|
6544
|
+
}
|
|
6545
|
+
function getQualifiedSkillName(rawInput) {
|
|
6546
|
+
if (!rawInput?.startsWith("/")) return void 0;
|
|
6547
|
+
const firstToken = rawInput.slice(1).trim().split(/\s+/)[0];
|
|
6548
|
+
return firstToken && firstToken.length > 0 ? firstToken : void 0;
|
|
6549
|
+
}
|
|
5499
6550
|
var InteractiveSession = class {
|
|
5500
6551
|
session = null;
|
|
5501
6552
|
commandExecutor;
|
|
@@ -5520,6 +6571,7 @@ var InteractiveSession = class {
|
|
|
5520
6571
|
backgroundJobGroupEvents = [];
|
|
5521
6572
|
memoryEvents = [];
|
|
5522
6573
|
usedMemoryReferences = [];
|
|
6574
|
+
contextReferences = [];
|
|
5523
6575
|
editCheckpointStore = null;
|
|
5524
6576
|
resumeSessionId;
|
|
5525
6577
|
forkSession;
|
|
@@ -5528,15 +6580,16 @@ var InteractiveSession = class {
|
|
|
5528
6580
|
backgroundJobOrchestrator = null;
|
|
5529
6581
|
commandModules;
|
|
5530
6582
|
commandHostAdapters;
|
|
6583
|
+
skillCommandSource;
|
|
6584
|
+
skillActivationEvents = [];
|
|
5531
6585
|
autoCompactThresholdSource = "default";
|
|
5532
6586
|
shuttingDown = false;
|
|
5533
6587
|
shutdownPromise = null;
|
|
6588
|
+
sandboxClient;
|
|
6589
|
+
sandboxSnapshotId;
|
|
6590
|
+
commandInvocationSource = "user";
|
|
5534
6591
|
constructor(options) {
|
|
5535
|
-
|
|
5536
|
-
this.commandModules = [
|
|
5537
|
-
sdkBuiltinModule,
|
|
5538
|
-
..."commandModules" in options ? options.commandModules ?? [] : []
|
|
5539
|
-
];
|
|
6592
|
+
this.commandModules = [..."commandModules" in options ? options.commandModules ?? [] : []];
|
|
5540
6593
|
this.commandExecutor = new SystemCommandExecutor(
|
|
5541
6594
|
this.commandModules.flatMap((module2) => module2.systemCommands ?? [])
|
|
5542
6595
|
);
|
|
@@ -5549,34 +6602,48 @@ var InteractiveSession = class {
|
|
|
5549
6602
|
this.resumeSessionId = options.resumeSessionId;
|
|
5550
6603
|
this.forkSession = options.forkSession ?? false;
|
|
5551
6604
|
this.commandHostAdapters = "commandHostAdapters" in options ? options.commandHostAdapters : void 0;
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
this.initPromise = this.initializeAsync(stdOpts);
|
|
5559
|
-
}
|
|
5560
|
-
if (options.resumeSessionId && this.sessionStore) {
|
|
5561
|
-
const restored = loadSessionRecord(
|
|
5562
|
-
this.sessionStore,
|
|
5563
|
-
options.resumeSessionId,
|
|
5564
|
-
this.forkSession,
|
|
5565
|
-
this.session
|
|
5566
|
-
);
|
|
5567
|
-
if (restored.history.length > 0) this.history = restored.history;
|
|
5568
|
-
if (restored.sessionName) this.sessionName = restored.sessionName;
|
|
5569
|
-
this.backgroundTasks = restored.backgroundTasks;
|
|
5570
|
-
this.backgroundTaskEvents = restored.backgroundTaskEvents;
|
|
5571
|
-
this.backgroundJobGroups = restored.backgroundJobGroups;
|
|
5572
|
-
this.backgroundJobGroupEvents = restored.backgroundJobGroupEvents;
|
|
5573
|
-
this.memoryEvents = restored.memoryEvents;
|
|
5574
|
-
this.usedMemoryReferences = restored.usedMemoryReferences;
|
|
5575
|
-
this.pendingRestoreMessages = restored.pendingRestoreMessages;
|
|
5576
|
-
}
|
|
6605
|
+
this.sandboxClient = "sandboxClient" in options ? options.sandboxClient : void 0;
|
|
6606
|
+
this.sandboxSnapshotId = "sandboxSnapshotId" in options ? options.sandboxSnapshotId : void 0;
|
|
6607
|
+
this.skillCommandSource = new SkillCommandSource(this.cwd || process.cwd());
|
|
6608
|
+
const hasInjectedSession = this.configureInjectedSession(options);
|
|
6609
|
+
this.restoreSessionRecordIfNeeded(options);
|
|
6610
|
+
this.startAsyncInitializationIfNeeded(options, hasInjectedSession);
|
|
5577
6611
|
if (this.initialized) this.subscribeBackgroundTaskEvents();
|
|
5578
6612
|
if (this.initialized) this.persistCurrentSession();
|
|
5579
6613
|
}
|
|
6614
|
+
configureInjectedSession(options) {
|
|
6615
|
+
if (!("session" in options && options.session)) return false;
|
|
6616
|
+
this.session = options.session;
|
|
6617
|
+
this.autoCompactThresholdSource = "session";
|
|
6618
|
+
this.initialized = true;
|
|
6619
|
+
return true;
|
|
6620
|
+
}
|
|
6621
|
+
restoreSessionRecordIfNeeded(options) {
|
|
6622
|
+
if (!options.resumeSessionId || !this.sessionStore) return;
|
|
6623
|
+
const restored = loadSessionRecord(
|
|
6624
|
+
this.sessionStore,
|
|
6625
|
+
options.resumeSessionId,
|
|
6626
|
+
this.forkSession,
|
|
6627
|
+
this.session
|
|
6628
|
+
);
|
|
6629
|
+
if (restored.history.length > 0) this.history = restored.history;
|
|
6630
|
+
if (restored.sessionName) this.sessionName = restored.sessionName;
|
|
6631
|
+
this.backgroundTasks = restored.backgroundTasks;
|
|
6632
|
+
this.backgroundTaskEvents = restored.backgroundTaskEvents;
|
|
6633
|
+
this.backgroundJobGroups = restored.backgroundJobGroups;
|
|
6634
|
+
this.backgroundJobGroupEvents = restored.backgroundJobGroupEvents;
|
|
6635
|
+
this.skillActivationEvents = restored.skillActivationEvents;
|
|
6636
|
+
this.memoryEvents = restored.memoryEvents;
|
|
6637
|
+
this.usedMemoryReferences = restored.usedMemoryReferences;
|
|
6638
|
+
this.contextReferences = restored.contextReferences;
|
|
6639
|
+
this.pendingRestoreMessages = restored.pendingRestoreMessages;
|
|
6640
|
+
this.sandboxSnapshotId = this.forkSession ? void 0 : restored.sandboxSnapshotId;
|
|
6641
|
+
}
|
|
6642
|
+
startAsyncInitializationIfNeeded(options, hasInjectedSession) {
|
|
6643
|
+
if (hasInjectedSession) return;
|
|
6644
|
+
const stdOpts = options;
|
|
6645
|
+
this.initPromise = this.initializeAsync(stdOpts);
|
|
6646
|
+
}
|
|
5580
6647
|
async initializeAsync(options) {
|
|
5581
6648
|
const config = options.config ?? await loadConfig(options.cwd);
|
|
5582
6649
|
this.autoCompactThresholdSource = config.autoCompactThreshold === void 0 ? "default" : "settings";
|
|
@@ -5602,6 +6669,10 @@ var InteractiveSession = class {
|
|
|
5602
6669
|
...options.commandModules ? { commandModules: options.commandModules } : {},
|
|
5603
6670
|
editCheckpointRecorder: this.editCheckpointStore,
|
|
5604
6671
|
...options.reversibleExecution ? { reversibleExecution: options.reversibleExecution } : {},
|
|
6672
|
+
...options.sandboxClient ? { sandboxClient: options.sandboxClient } : {},
|
|
6673
|
+
...options.workspaceManifest ? { workspaceManifest: options.workspaceManifest } : {},
|
|
6674
|
+
...options.sandboxWorkspaceRoot ? { sandboxWorkspaceRoot: options.sandboxWorkspaceRoot } : {},
|
|
6675
|
+
...this.sandboxSnapshotId ? { sandboxSnapshotId: this.sandboxSnapshotId } : {},
|
|
5605
6676
|
commandDescriptors: this.commandExecutor.listModelInvocableCommands(),
|
|
5606
6677
|
...this.commandExecutor.listModelInvocableCommands().length > 0 ? {
|
|
5607
6678
|
modelCommandExecutor: (command, args) => this.executeModelCommand(command, args),
|
|
@@ -5648,36 +6719,102 @@ var InteractiveSession = class {
|
|
|
5648
6719
|
}
|
|
5649
6720
|
async executeCommand(name, args) {
|
|
5650
6721
|
await this.ensureInitialized();
|
|
5651
|
-
const
|
|
5652
|
-
|
|
6722
|
+
const normalizedName = normalizeCommandName(name);
|
|
6723
|
+
const command = this.commandExecutor.getCommand(normalizedName);
|
|
6724
|
+
const commandArgs = args.trim();
|
|
6725
|
+
if (!command) {
|
|
6726
|
+
const skill = this.findSkillCommand(normalizedName);
|
|
6727
|
+
const skillsCommand = this.commandExecutor.getCommand("skills");
|
|
6728
|
+
if (!skill || !skillsCommand) return null;
|
|
6729
|
+
return this.executeCommandWithInvocationSource(
|
|
6730
|
+
"user",
|
|
6731
|
+
skillsCommand,
|
|
6732
|
+
formatSkillCommandArgs(skill.name, commandArgs)
|
|
6733
|
+
);
|
|
6734
|
+
}
|
|
6735
|
+
return this.executeCommandWithInvocationSource("user", command, commandArgs);
|
|
6736
|
+
}
|
|
6737
|
+
async executeCommandWithInvocationSource(source, command, args) {
|
|
5653
6738
|
if (this.executing) {
|
|
5654
6739
|
return {
|
|
5655
6740
|
success: false,
|
|
5656
6741
|
message: "Another prompt or command is already running. Wait for it to finish."
|
|
5657
6742
|
};
|
|
5658
6743
|
}
|
|
5659
|
-
|
|
5660
|
-
|
|
6744
|
+
const previousSource = this.commandInvocationSource;
|
|
6745
|
+
this.commandInvocationSource = source;
|
|
6746
|
+
try {
|
|
6747
|
+
if (command.lifecycle === "blocking") {
|
|
6748
|
+
return this.executeForegroundCommand(command, args);
|
|
6749
|
+
}
|
|
6750
|
+
return await this.commandExecutor.executeCommand(command, this, args);
|
|
6751
|
+
} finally {
|
|
6752
|
+
this.commandInvocationSource = previousSource;
|
|
5661
6753
|
}
|
|
5662
|
-
return this.commandExecutor.executeCommand(command, this, args);
|
|
5663
6754
|
}
|
|
5664
6755
|
async executeModelCommand(name, args) {
|
|
5665
6756
|
await this.ensureInitialized();
|
|
5666
|
-
|
|
6757
|
+
const previousSource = this.commandInvocationSource;
|
|
6758
|
+
this.commandInvocationSource = "model";
|
|
6759
|
+
try {
|
|
6760
|
+
return await this.commandExecutor.executeModelInvocable(name, this, args);
|
|
6761
|
+
} finally {
|
|
6762
|
+
this.commandInvocationSource = previousSource;
|
|
6763
|
+
}
|
|
5667
6764
|
}
|
|
5668
|
-
|
|
6765
|
+
getCommandInvocationSource() {
|
|
6766
|
+
return this.commandInvocationSource;
|
|
6767
|
+
}
|
|
6768
|
+
async executeSkillCommandByName(name, args, request) {
|
|
5669
6769
|
await this.ensureInitialized();
|
|
5670
|
-
|
|
5671
|
-
|
|
6770
|
+
const skill = this.findSkillCommand(name);
|
|
6771
|
+
if (!skill) return null;
|
|
6772
|
+
if (request.invocationSource === "model") {
|
|
6773
|
+
if (skill.disableModelInvocation === true) {
|
|
6774
|
+
return {
|
|
6775
|
+
success: false,
|
|
6776
|
+
message: `Skill is not model-invocable: ${skill.name}`
|
|
6777
|
+
};
|
|
6778
|
+
}
|
|
6779
|
+
const result = await this.executeSkillWithActivation(skill, args, "model-tool");
|
|
6780
|
+
return {
|
|
6781
|
+
success: true,
|
|
6782
|
+
message: `Skill activated: ${skill.name}`,
|
|
6783
|
+
data: {
|
|
6784
|
+
skill: skill.name,
|
|
6785
|
+
mode: result.mode,
|
|
6786
|
+
...result.prompt !== void 0 ? { prompt: result.prompt } : {},
|
|
6787
|
+
...result.result !== void 0 ? { result: result.result } : {}
|
|
6788
|
+
}
|
|
6789
|
+
};
|
|
5672
6790
|
}
|
|
5673
|
-
|
|
6791
|
+
await this.executeUserResolvedSkillCommand(
|
|
5674
6792
|
skill,
|
|
5675
6793
|
args,
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
{ sessionId: this.getSessionOrThrow().getSessionId() }
|
|
6794
|
+
request.displayInput,
|
|
6795
|
+
request.rawInput,
|
|
6796
|
+
"user-slash"
|
|
5680
6797
|
);
|
|
6798
|
+
return {
|
|
6799
|
+
success: true,
|
|
6800
|
+
message: "",
|
|
6801
|
+
data: {
|
|
6802
|
+
skill: skill.name,
|
|
6803
|
+
sessionExecution: true
|
|
6804
|
+
},
|
|
6805
|
+
effects: [{ type: "session-execution-started" }]
|
|
6806
|
+
};
|
|
6807
|
+
}
|
|
6808
|
+
async executeUserResolvedSkillCommand(skill, args, displayInput, rawInput, invocation) {
|
|
6809
|
+
await this.ensureInitialized();
|
|
6810
|
+
if (skill.userInvocable === false) {
|
|
6811
|
+
throw new Error(`Skill is not user-invocable: ${skill.name}`);
|
|
6812
|
+
}
|
|
6813
|
+
const qualifiedName = getQualifiedSkillName(rawInput);
|
|
6814
|
+
if (skill.context === "fork") {
|
|
6815
|
+
return this.executeForkSkillCommand(skill, args, displayInput, qualifiedName, invocation);
|
|
6816
|
+
}
|
|
6817
|
+
const result = await this.executeSkillWithActivation(skill, args, invocation, qualifiedName);
|
|
5681
6818
|
if (result.mode === "inject") {
|
|
5682
6819
|
if (result.prompt) {
|
|
5683
6820
|
await this.submit(result.prompt, displayInput, rawInput);
|
|
@@ -5693,12 +6830,31 @@ var InteractiveSession = class {
|
|
|
5693
6830
|
description: cmd.description
|
|
5694
6831
|
}));
|
|
5695
6832
|
}
|
|
6833
|
+
listSkills() {
|
|
6834
|
+
return this.skillCommandSource.getCommands().map((skill) => ({
|
|
6835
|
+
name: skill.name,
|
|
6836
|
+
description: skill.description,
|
|
6837
|
+
source: skill.source,
|
|
6838
|
+
modelInvocable: skill.disableModelInvocation !== true,
|
|
6839
|
+
userInvocable: skill.userInvocable !== false,
|
|
6840
|
+
...skill.argumentHint !== void 0 ? { argumentHint: skill.argumentHint } : {},
|
|
6841
|
+
...skill.context !== void 0 ? { context: skill.context } : {},
|
|
6842
|
+
...skill.agent !== void 0 ? { agent: skill.agent } : {}
|
|
6843
|
+
}));
|
|
6844
|
+
}
|
|
5696
6845
|
listModelInvocableCommands() {
|
|
5697
6846
|
return this.commandExecutor.listModelInvocableCommands().map((cmd) => ({
|
|
5698
6847
|
name: cmd.name,
|
|
5699
6848
|
description: cmd.description
|
|
5700
6849
|
}));
|
|
5701
6850
|
}
|
|
6851
|
+
getSkillActivationEvents() {
|
|
6852
|
+
return [...this.skillActivationEvents];
|
|
6853
|
+
}
|
|
6854
|
+
findSkillCommand(name) {
|
|
6855
|
+
const normalizedName = normalizeSkillName(name);
|
|
6856
|
+
return this.skillCommandSource.getCommands().find((skill) => skill.name.toLowerCase() === normalizedName.toLowerCase());
|
|
6857
|
+
}
|
|
5702
6858
|
abort() {
|
|
5703
6859
|
this.clearPendingQueue();
|
|
5704
6860
|
this.session?.abort();
|
|
@@ -5718,6 +6874,7 @@ var InteractiveSession = class {
|
|
|
5718
6874
|
this.backgroundJobUnsubscribe = null;
|
|
5719
6875
|
this.backgroundJobOrchestrator?.dispose();
|
|
5720
6876
|
this.backgroundJobOrchestrator = null;
|
|
6877
|
+
await this.captureSandboxSnapshot();
|
|
5721
6878
|
this.persistCurrentSession();
|
|
5722
6879
|
await session?.shutdown({ reason: options.reason ?? "other" });
|
|
5723
6880
|
})();
|
|
@@ -5830,6 +6987,31 @@ var InteractiveSession = class {
|
|
|
5830
6987
|
this.memoryEvents.push(event);
|
|
5831
6988
|
this.persistCurrentSession();
|
|
5832
6989
|
}
|
|
6990
|
+
listContextReferences() {
|
|
6991
|
+
return [...this.contextReferences];
|
|
6992
|
+
}
|
|
6993
|
+
async addContextReference(path) {
|
|
6994
|
+
const { references, result } = await addInteractiveContextReference(
|
|
6995
|
+
this.contextReferences,
|
|
6996
|
+
path,
|
|
6997
|
+
this.getCwd()
|
|
6998
|
+
);
|
|
6999
|
+
this.contextReferences = references;
|
|
7000
|
+
this.persistCurrentSession();
|
|
7001
|
+
return result;
|
|
7002
|
+
}
|
|
7003
|
+
removeContextReference(path) {
|
|
7004
|
+
const result = removeContextReference(this.contextReferences, path);
|
|
7005
|
+
this.contextReferences = result.references;
|
|
7006
|
+
this.persistCurrentSession();
|
|
7007
|
+
return result.result;
|
|
7008
|
+
}
|
|
7009
|
+
clearContextReferences() {
|
|
7010
|
+
const result = clearContextReferences(this.contextReferences);
|
|
7011
|
+
this.contextReferences = [];
|
|
7012
|
+
this.persistCurrentSession();
|
|
7013
|
+
return result;
|
|
7014
|
+
}
|
|
5833
7015
|
listBackgroundTasks(filter) {
|
|
5834
7016
|
return this.getBackgroundTaskManagerOrThrow().list(filter);
|
|
5835
7017
|
}
|
|
@@ -5931,18 +7113,63 @@ var InteractiveSession = class {
|
|
|
5931
7113
|
attachTransport(transport) {
|
|
5932
7114
|
transport.attach(this);
|
|
5933
7115
|
}
|
|
5934
|
-
async
|
|
5935
|
-
|
|
5936
|
-
throw new Error("Cannot execute fork skill while another prompt is running.");
|
|
5937
|
-
}
|
|
5938
|
-
this.startForkSkillExecution(displayInput ?? `/${skill.name}`);
|
|
7116
|
+
async executeSkillWithActivation(skill, args, invocation, qualifiedName) {
|
|
7117
|
+
this.recordSkillActivation(skill, invocation, "started", qualifiedName);
|
|
5939
7118
|
try {
|
|
5940
7119
|
const result = await executeSkill(
|
|
5941
7120
|
skill,
|
|
5942
7121
|
args,
|
|
5943
|
-
{
|
|
7122
|
+
{
|
|
7123
|
+
runInFork: (content, options) => this.runSkillInFork(content, options)
|
|
7124
|
+
},
|
|
5944
7125
|
{ sessionId: this.getSessionOrThrow().getSessionId() }
|
|
5945
7126
|
);
|
|
7127
|
+
this.recordSkillActivation(skill, invocation, "completed", qualifiedName, {
|
|
7128
|
+
appendHistory: false
|
|
7129
|
+
});
|
|
7130
|
+
return result;
|
|
7131
|
+
} catch (err) {
|
|
7132
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
7133
|
+
this.recordSkillActivation(skill, invocation, "failed", qualifiedName, {
|
|
7134
|
+
error: error.message
|
|
7135
|
+
});
|
|
7136
|
+
throw error;
|
|
7137
|
+
}
|
|
7138
|
+
}
|
|
7139
|
+
recordSkillActivation(skill, invocation, status, qualifiedName, options = {}) {
|
|
7140
|
+
const event = createSkillActivationEvent({
|
|
7141
|
+
skill,
|
|
7142
|
+
invocation,
|
|
7143
|
+
status,
|
|
7144
|
+
...qualifiedName !== void 0 ? { qualifiedName } : {},
|
|
7145
|
+
...options.error !== void 0 ? { error: options.error } : {}
|
|
7146
|
+
});
|
|
7147
|
+
this.recordSkillActivationEvent(event, options.appendHistory ?? status !== "completed");
|
|
7148
|
+
}
|
|
7149
|
+
recordSkillActivationEvent(event, appendHistory) {
|
|
7150
|
+
this.skillActivationEvents.push(event);
|
|
7151
|
+
if (appendHistory) {
|
|
7152
|
+
this.history.push({
|
|
7153
|
+
id: (0, import_node_crypto5.randomUUID)(),
|
|
7154
|
+
timestamp: new Date(event.timestamp),
|
|
7155
|
+
category: "event",
|
|
7156
|
+
type: "skill-activation",
|
|
7157
|
+
data: {
|
|
7158
|
+
...event,
|
|
7159
|
+
message: formatSkillActivationMessage(event)
|
|
7160
|
+
}
|
|
7161
|
+
});
|
|
7162
|
+
}
|
|
7163
|
+
this.emit("skill_activation", event);
|
|
7164
|
+
this.persistCurrentSession();
|
|
7165
|
+
}
|
|
7166
|
+
async executeForkSkillCommand(skill, args, displayInput, qualifiedName, invocation = "user-slash") {
|
|
7167
|
+
if (this.executing) {
|
|
7168
|
+
throw new Error("Cannot execute fork skill while another prompt is running.");
|
|
7169
|
+
}
|
|
7170
|
+
this.startForkSkillExecution(displayInput ?? `/${skill.name}`);
|
|
7171
|
+
try {
|
|
7172
|
+
const result = await this.executeSkillWithActivation(skill, args, invocation, qualifiedName);
|
|
5946
7173
|
await this.applyForkSkillResult(result.result ?? "(empty response)");
|
|
5947
7174
|
return result;
|
|
5948
7175
|
} catch (err) {
|
|
@@ -6056,9 +7283,30 @@ var InteractiveSession = class {
|
|
|
6056
7283
|
{
|
|
6057
7284
|
events: this.memoryEvents,
|
|
6058
7285
|
usedReferences: this.usedMemoryReferences
|
|
7286
|
+
},
|
|
7287
|
+
{
|
|
7288
|
+
events: this.skillActivationEvents
|
|
7289
|
+
},
|
|
7290
|
+
{
|
|
7291
|
+
references: this.contextReferences
|
|
7292
|
+
},
|
|
7293
|
+
{
|
|
7294
|
+
snapshotId: this.sandboxSnapshotId
|
|
6059
7295
|
}
|
|
6060
7296
|
);
|
|
6061
7297
|
}
|
|
7298
|
+
async captureSandboxSnapshot() {
|
|
7299
|
+
if (!this.sandboxClient?.snapshot) return;
|
|
7300
|
+
try {
|
|
7301
|
+
this.sandboxSnapshotId = await this.sandboxClient.snapshot();
|
|
7302
|
+
} catch (error) {
|
|
7303
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
7304
|
+
this.history.push(
|
|
7305
|
+
(0, import_agent_core7.messageToHistoryEntry)((0, import_agent_core7.createSystemMessage)(`Sandbox snapshot error: ${err.message}`))
|
|
7306
|
+
);
|
|
7307
|
+
this.emit("error", err);
|
|
7308
|
+
}
|
|
7309
|
+
}
|
|
6062
7310
|
startForkSkillExecution(displayInput) {
|
|
6063
7311
|
this.executing = true;
|
|
6064
7312
|
this.clearStreaming();
|
|
@@ -6074,7 +7322,7 @@ var InteractiveSession = class {
|
|
|
6074
7322
|
const queuedDisplay = this.pendingDisplayInput;
|
|
6075
7323
|
const queuedRaw = this.pendingRawInput;
|
|
6076
7324
|
this.clearPendingQueue();
|
|
6077
|
-
setTimeout(() => this.
|
|
7325
|
+
setTimeout(() => void this.submit(queued, queuedDisplay, queuedRaw), 0);
|
|
6078
7326
|
}
|
|
6079
7327
|
}
|
|
6080
7328
|
recordForkSkillError(err) {
|
|
@@ -6096,7 +7344,9 @@ var InteractiveSession = class {
|
|
|
6096
7344
|
const parentSession = this.getSessionOrThrow();
|
|
6097
7345
|
const deps = retrieveAgentToolDeps(parentSession);
|
|
6098
7346
|
if (!deps) {
|
|
6099
|
-
throw new Error(
|
|
7347
|
+
throw new Error(
|
|
7348
|
+
"Fork execution is not available. Agent runtime deps may not be initialized."
|
|
7349
|
+
);
|
|
6100
7350
|
}
|
|
6101
7351
|
const agentType = options.agent ?? "general-purpose";
|
|
6102
7352
|
const agentDefinition = this.resolveForkAgentDefinition(agentType, options);
|
|
@@ -6154,7 +7404,7 @@ var InteractiveSession = class {
|
|
|
6154
7404
|
const queuedDisplay = this.pendingDisplayInput;
|
|
6155
7405
|
const queuedRaw = this.pendingRawInput;
|
|
6156
7406
|
this.clearPendingQueue();
|
|
6157
|
-
setTimeout(() => this.
|
|
7407
|
+
setTimeout(() => void this.submit(queued, queuedDisplay, queuedRaw), 0);
|
|
6158
7408
|
}
|
|
6159
7409
|
}
|
|
6160
7410
|
}
|
|
@@ -6166,8 +7416,22 @@ var InteractiveSession = class {
|
|
|
6166
7416
|
const historyBefore = this.getSessionOrThrow().getHistory().length;
|
|
6167
7417
|
this.usedMemoryReferences = [];
|
|
6168
7418
|
try {
|
|
7419
|
+
const preparedPrompt = await preparePromptInput(
|
|
7420
|
+
input,
|
|
7421
|
+
this.getCwd(),
|
|
7422
|
+
rawInput,
|
|
7423
|
+
this.contextReferences
|
|
7424
|
+
);
|
|
7425
|
+
if (preparedPrompt.promptFileReferenceEntry) {
|
|
7426
|
+
this.history.push(preparedPrompt.promptFileReferenceEntry);
|
|
7427
|
+
}
|
|
7428
|
+
this.recordContextReferenceUsage(preparedPrompt.activeContextReferenceRecords);
|
|
7429
|
+
this.recordPromptContextReferences(preparedPrompt.promptFileReferenceRecords);
|
|
6169
7430
|
await this.beginEditCheckpointTurn(displayInput ?? input);
|
|
6170
|
-
const response = await this.getSessionOrThrow().run(
|
|
7431
|
+
const response = await this.getSessionOrThrow().run(
|
|
7432
|
+
preparedPrompt.modelInput,
|
|
7433
|
+
preparedPrompt.hookInput
|
|
7434
|
+
);
|
|
6171
7435
|
this.flushStreaming();
|
|
6172
7436
|
pushToolSummaryToHistory({ activeTools: this.activeTools, history: this.history });
|
|
6173
7437
|
this.clearStreaming();
|
|
@@ -6176,7 +7440,8 @@ var InteractiveSession = class {
|
|
|
6176
7440
|
this.getSessionOrThrow().getHistory(),
|
|
6177
7441
|
this.history,
|
|
6178
7442
|
historyBefore,
|
|
6179
|
-
this.getContextState()
|
|
7443
|
+
this.getContextState(),
|
|
7444
|
+
preparedPrompt.promptFileReferenceRecords
|
|
6180
7445
|
);
|
|
6181
7446
|
this.history.push((0, import_agent_core7.messageToHistoryEntry)((0, import_agent_core7.createAssistantMessage)(result.response)));
|
|
6182
7447
|
if (result.usage) this.history.push(createUsageSummaryEntry(result.usage));
|
|
@@ -6215,10 +7480,24 @@ var InteractiveSession = class {
|
|
|
6215
7480
|
const queuedDisplay = this.pendingDisplayInput;
|
|
6216
7481
|
const queuedRaw = this.pendingRawInput;
|
|
6217
7482
|
this.clearPendingQueue();
|
|
6218
|
-
setTimeout(() => this.
|
|
7483
|
+
setTimeout(() => void this.submit(queued, queuedDisplay, queuedRaw), 0);
|
|
6219
7484
|
}
|
|
6220
7485
|
}
|
|
6221
7486
|
}
|
|
7487
|
+
recordContextReferenceUsage(records) {
|
|
7488
|
+
this.contextReferences = recordInteractiveContextReferences(this.contextReferences, records, {
|
|
7489
|
+
loadType: "manual",
|
|
7490
|
+
status: "active"
|
|
7491
|
+
});
|
|
7492
|
+
this.persistCurrentSession();
|
|
7493
|
+
}
|
|
7494
|
+
recordPromptContextReferences(records) {
|
|
7495
|
+
this.contextReferences = recordInteractiveContextReferences(this.contextReferences, records, {
|
|
7496
|
+
loadType: "prompt-reference",
|
|
7497
|
+
status: "observed"
|
|
7498
|
+
});
|
|
7499
|
+
this.persistCurrentSession();
|
|
7500
|
+
}
|
|
6222
7501
|
getEditCheckpointStore() {
|
|
6223
7502
|
if (!this.editCheckpointStore) {
|
|
6224
7503
|
this.editCheckpointStore = new EditCheckpointStore({ cwd: this.getCwd() });
|
|
@@ -6294,6 +7573,159 @@ var InteractiveSession = class {
|
|
|
6294
7573
|
}
|
|
6295
7574
|
};
|
|
6296
7575
|
|
|
7576
|
+
// src/interactive/session-persistence.ts
|
|
7577
|
+
var import_agent_sessions7 = require("@robota-sdk/agent-sessions");
|
|
7578
|
+
var import_node_fs15 = require("fs");
|
|
7579
|
+
var import_node_path19 = require("path");
|
|
7580
|
+
function createProjectSessionStore(cwd) {
|
|
7581
|
+
const paths = projectPaths(cwd);
|
|
7582
|
+
return new ProjectSessionStoreFacade(paths.sessions, paths.logs);
|
|
7583
|
+
}
|
|
7584
|
+
function listResumableSessionSummaries(sessionStore, cwd) {
|
|
7585
|
+
return (sessionStore?.list() ?? []).filter((session) => session.cwd === cwd).sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()).map((session) => ({
|
|
7586
|
+
id: session.id,
|
|
7587
|
+
...session.name !== void 0 ? { name: session.name } : {},
|
|
7588
|
+
cwd: session.cwd,
|
|
7589
|
+
updatedAt: session.updatedAt,
|
|
7590
|
+
messageCount: session.messages.length,
|
|
7591
|
+
preview: getLastAssistantPreview(session.messages)
|
|
7592
|
+
}));
|
|
7593
|
+
}
|
|
7594
|
+
function resolveLatestSessionId(sessionStore, cwd) {
|
|
7595
|
+
return listResumableSessionSummaries(sessionStore, cwd)[0]?.id;
|
|
7596
|
+
}
|
|
7597
|
+
function resolveSessionIdByIdOrName(sessionStore, idOrName) {
|
|
7598
|
+
const match = (sessionStore?.list() ?? []).find(
|
|
7599
|
+
(session) => session.id === idOrName || session.name === idOrName
|
|
7600
|
+
);
|
|
7601
|
+
return match?.id;
|
|
7602
|
+
}
|
|
7603
|
+
var ProjectSessionStoreFacade = class {
|
|
7604
|
+
store;
|
|
7605
|
+
logsDir;
|
|
7606
|
+
constructor(baseDir, logsDir) {
|
|
7607
|
+
this.store = new import_agent_sessions7.SessionStore(baseDir);
|
|
7608
|
+
this.logsDir = logsDir;
|
|
7609
|
+
}
|
|
7610
|
+
save(session) {
|
|
7611
|
+
this.store.save(toSessionRecord(session));
|
|
7612
|
+
}
|
|
7613
|
+
load(id) {
|
|
7614
|
+
const session = this.store.load(id);
|
|
7615
|
+
if (session !== void 0) {
|
|
7616
|
+
return fromSessionRecord(session);
|
|
7617
|
+
}
|
|
7618
|
+
return this.loadFromReplayLog(id);
|
|
7619
|
+
}
|
|
7620
|
+
list() {
|
|
7621
|
+
const records = this.store.list().map(fromSessionRecord);
|
|
7622
|
+
const seen = new Set(records.map((record) => record.id));
|
|
7623
|
+
for (const replayRecord of this.listReplayLogRecords()) {
|
|
7624
|
+
if (!seen.has(replayRecord.id)) {
|
|
7625
|
+
records.push(replayRecord);
|
|
7626
|
+
}
|
|
7627
|
+
}
|
|
7628
|
+
return records.sort(
|
|
7629
|
+
(a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
|
|
7630
|
+
);
|
|
7631
|
+
}
|
|
7632
|
+
delete(id) {
|
|
7633
|
+
this.store.delete(id);
|
|
7634
|
+
}
|
|
7635
|
+
loadFromReplayLog(id) {
|
|
7636
|
+
if (!this.logsDir) return void 0;
|
|
7637
|
+
const replay = (0, import_agent_sessions7.replaySessionLogEntries)(
|
|
7638
|
+
(0, import_agent_sessions7.loadSessionLogEntries)((0, import_node_path19.join)(this.logsDir, `${id}.jsonl`))
|
|
7639
|
+
);
|
|
7640
|
+
if (!replay.sessionId || replay.messages.length === 0) {
|
|
7641
|
+
return void 0;
|
|
7642
|
+
}
|
|
7643
|
+
const backgroundTaskEvents = replay.backgroundTaskEvents;
|
|
7644
|
+
const backgroundJobGroupEvents = replay.backgroundJobGroupEvents;
|
|
7645
|
+
return {
|
|
7646
|
+
id: replay.sessionId,
|
|
7647
|
+
cwd: replay.cwd ?? "",
|
|
7648
|
+
createdAt: replay.createdAt ?? replay.updatedAt ?? (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
7649
|
+
updatedAt: replay.updatedAt ?? replay.createdAt ?? (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
7650
|
+
messages: replay.messages,
|
|
7651
|
+
history: replay.history,
|
|
7652
|
+
backgroundTasks: deriveBackgroundTasks(backgroundTaskEvents),
|
|
7653
|
+
backgroundTaskEvents,
|
|
7654
|
+
backgroundJobGroups: deriveBackgroundJobGroups(backgroundJobGroupEvents),
|
|
7655
|
+
backgroundJobGroupEvents,
|
|
7656
|
+
skillActivationEvents: [],
|
|
7657
|
+
memoryEvents: replay.memoryEvents
|
|
7658
|
+
};
|
|
7659
|
+
}
|
|
7660
|
+
listReplayLogRecords() {
|
|
7661
|
+
if (!this.logsDir || !(0, import_node_fs15.existsSync)(this.logsDir)) {
|
|
7662
|
+
return [];
|
|
7663
|
+
}
|
|
7664
|
+
return (0, import_node_fs15.readdirSync)(this.logsDir).filter((file) => file.endsWith(".jsonl")).map((file) => this.loadFromReplayLog(file.slice(0, -".jsonl".length))).filter((record) => record !== void 0);
|
|
7665
|
+
}
|
|
7666
|
+
};
|
|
7667
|
+
function getLastAssistantPreview(messages) {
|
|
7668
|
+
for (const message of [...messages].reverse()) {
|
|
7669
|
+
if (message.role !== "assistant") continue;
|
|
7670
|
+
if (typeof message.content !== "string") continue;
|
|
7671
|
+
return message.content.replace(/[\n\r]+/g, " ").trim();
|
|
7672
|
+
}
|
|
7673
|
+
return "";
|
|
7674
|
+
}
|
|
7675
|
+
function toSessionRecord(session) {
|
|
7676
|
+
return { ...session };
|
|
7677
|
+
}
|
|
7678
|
+
function fromSessionRecord(session) {
|
|
7679
|
+
return {
|
|
7680
|
+
id: session.id,
|
|
7681
|
+
...session.name !== void 0 ? { name: session.name } : {},
|
|
7682
|
+
cwd: session.cwd,
|
|
7683
|
+
createdAt: session.createdAt,
|
|
7684
|
+
updatedAt: session.updatedAt,
|
|
7685
|
+
messages: session.messages,
|
|
7686
|
+
...session.history !== void 0 ? { history: session.history } : {},
|
|
7687
|
+
...session.systemPrompt !== void 0 ? { systemPrompt: session.systemPrompt } : {},
|
|
7688
|
+
...session.toolSchemas !== void 0 ? { toolSchemas: session.toolSchemas } : {},
|
|
7689
|
+
...session.backgroundTasks !== void 0 ? { backgroundTasks: session.backgroundTasks } : {},
|
|
7690
|
+
...session.backgroundTaskEvents !== void 0 ? { backgroundTaskEvents: session.backgroundTaskEvents } : {},
|
|
7691
|
+
...session.backgroundJobGroups !== void 0 ? { backgroundJobGroups: session.backgroundJobGroups } : {},
|
|
7692
|
+
...session.backgroundJobGroupEvents !== void 0 ? { backgroundJobGroupEvents: session.backgroundJobGroupEvents } : {},
|
|
7693
|
+
...session.skillActivationEvents !== void 0 ? { skillActivationEvents: session.skillActivationEvents } : {},
|
|
7694
|
+
...session.memoryEvents !== void 0 ? { memoryEvents: session.memoryEvents } : {},
|
|
7695
|
+
...session.usedMemoryReferences !== void 0 ? { usedMemoryReferences: session.usedMemoryReferences } : {},
|
|
7696
|
+
...session.contextReferences !== void 0 ? { contextReferences: session.contextReferences } : {},
|
|
7697
|
+
...session.sandboxSnapshotId !== void 0 ? { sandboxSnapshotId: session.sandboxSnapshotId } : {}
|
|
7698
|
+
};
|
|
7699
|
+
}
|
|
7700
|
+
function deriveBackgroundTasks(events) {
|
|
7701
|
+
const tasks = /* @__PURE__ */ new Map();
|
|
7702
|
+
for (const event of events) {
|
|
7703
|
+
const task = getBackgroundTaskSnapshot(event);
|
|
7704
|
+
if (task) tasks.set(task.id, task);
|
|
7705
|
+
}
|
|
7706
|
+
return [...tasks.values()];
|
|
7707
|
+
}
|
|
7708
|
+
function getBackgroundTaskSnapshot(event) {
|
|
7709
|
+
switch (event.type) {
|
|
7710
|
+
case "background_task_created":
|
|
7711
|
+
case "background_task_started":
|
|
7712
|
+
case "background_task_updated":
|
|
7713
|
+
case "background_task_completed":
|
|
7714
|
+
case "background_task_failed":
|
|
7715
|
+
case "background_task_cancelled":
|
|
7716
|
+
return event.task;
|
|
7717
|
+
default:
|
|
7718
|
+
return void 0;
|
|
7719
|
+
}
|
|
7720
|
+
}
|
|
7721
|
+
function deriveBackgroundJobGroups(events) {
|
|
7722
|
+
const groups = /* @__PURE__ */ new Map();
|
|
7723
|
+
for (const event of events) {
|
|
7724
|
+
groups.set(event.group.id, event.group);
|
|
7725
|
+
}
|
|
7726
|
+
return [...groups.values()];
|
|
7727
|
+
}
|
|
7728
|
+
|
|
6297
7729
|
// src/query.ts
|
|
6298
7730
|
function createQuery(options) {
|
|
6299
7731
|
const session = new InteractiveSession({
|
|
@@ -6307,14 +7739,14 @@ function createQuery(options) {
|
|
|
6307
7739
|
session.on("text_delta", options.onTextDelta);
|
|
6308
7740
|
}
|
|
6309
7741
|
return async (prompt) => {
|
|
6310
|
-
return new Promise((
|
|
7742
|
+
return new Promise((resolve6, reject) => {
|
|
6311
7743
|
const onComplete = (result) => {
|
|
6312
7744
|
cleanup();
|
|
6313
|
-
|
|
7745
|
+
resolve6(result.response);
|
|
6314
7746
|
};
|
|
6315
7747
|
const onInterrupted = (result) => {
|
|
6316
7748
|
cleanup();
|
|
6317
|
-
|
|
7749
|
+
resolve6(result.response);
|
|
6318
7750
|
};
|
|
6319
7751
|
const onError = (error) => {
|
|
6320
7752
|
cleanup();
|
|
@@ -6336,12 +7768,6 @@ function createQuery(options) {
|
|
|
6336
7768
|
};
|
|
6337
7769
|
}
|
|
6338
7770
|
|
|
6339
|
-
// src/types.ts
|
|
6340
|
-
var import_agent_core8 = require("@robota-sdk/agent-core");
|
|
6341
|
-
|
|
6342
|
-
// src/index.ts
|
|
6343
|
-
var import_agent_core9 = require("@robota-sdk/agent-core");
|
|
6344
|
-
|
|
6345
7771
|
// src/self-hosting/self-hosting-verification.ts
|
|
6346
7772
|
var DEFAULT_BASE_REF = "origin/develop";
|
|
6347
7773
|
var PACKAGE_VERIFY_COMMANDS = ["test", "typecheck", "build"];
|
|
@@ -6457,13 +7883,72 @@ function transitionSelfHostingLoop(state, event) {
|
|
|
6457
7883
|
return nextState;
|
|
6458
7884
|
}
|
|
6459
7885
|
|
|
7886
|
+
// src/tools/command-execution-tool.ts
|
|
7887
|
+
var import_zod5 = require("zod");
|
|
7888
|
+
var import_agent_tools6 = require("@robota-sdk/agent-tools");
|
|
7889
|
+
function asZodSchema4(schema) {
|
|
7890
|
+
return schema;
|
|
7891
|
+
}
|
|
7892
|
+
function toNonEmptyCommandNames(commandNames) {
|
|
7893
|
+
if (!commandNames || commandNames.length === 0) return void 0;
|
|
7894
|
+
const [first, ...rest] = commandNames;
|
|
7895
|
+
if (first === void 0) return void 0;
|
|
7896
|
+
return [first, ...rest];
|
|
7897
|
+
}
|
|
7898
|
+
function createCommandExecutionSchema(commandNames) {
|
|
7899
|
+
const validCommandNames = toNonEmptyCommandNames(commandNames);
|
|
7900
|
+
const commandSchema = validCommandNames !== void 0 ? import_zod5.z.enum(validCommandNames).describe("Registered model-invocable command name to execute") : import_zod5.z.string().describe("Registered model-invocable command name to execute");
|
|
7901
|
+
return import_zod5.z.object({
|
|
7902
|
+
command: commandSchema,
|
|
7903
|
+
args: import_zod5.z.string().optional().describe("Arguments to pass to the command")
|
|
7904
|
+
});
|
|
7905
|
+
}
|
|
7906
|
+
function getCommandNames(deps) {
|
|
7907
|
+
if (deps.commandNames !== void 0) return deps.commandNames;
|
|
7908
|
+
if (deps.commandDescriptors === void 0) return void 0;
|
|
7909
|
+
return deps.commandDescriptors.map((descriptor) => normalizeModelCommandName(descriptor.name));
|
|
7910
|
+
}
|
|
7911
|
+
function formatCommandDescriptor(descriptor) {
|
|
7912
|
+
const commandName = normalizeModelCommandName(descriptor.name);
|
|
7913
|
+
const argumentHint = descriptor.argumentHint ? ` ${descriptor.argumentHint}` : "";
|
|
7914
|
+
return `- ${commandName}${argumentHint}: ${descriptor.description}`;
|
|
7915
|
+
}
|
|
7916
|
+
function createToolDescription(commandDescriptors) {
|
|
7917
|
+
const base = "Executes a registered model-invocable Robota command through the command registry. Accepted command names and argument grammar come from registered command descriptors.";
|
|
7918
|
+
if (commandDescriptors === void 0 || commandDescriptors.length === 0) return base;
|
|
7919
|
+
return [
|
|
7920
|
+
base,
|
|
7921
|
+
"Use the registered command descriptors below as the authority for when to call this tool.",
|
|
7922
|
+
"",
|
|
7923
|
+
"Registered model-invocable commands:",
|
|
7924
|
+
...commandDescriptors.map(formatCommandDescriptor)
|
|
7925
|
+
].join("\n");
|
|
7926
|
+
}
|
|
7927
|
+
function createCommandExecutionTool(deps) {
|
|
7928
|
+
const commandExecutionSchema = createCommandExecutionSchema(getCommandNames(deps));
|
|
7929
|
+
return (0, import_agent_tools6.createZodFunctionTool)(
|
|
7930
|
+
"ExecuteCommand",
|
|
7931
|
+
createToolDescription(deps.commandDescriptors),
|
|
7932
|
+
asZodSchema4(commandExecutionSchema),
|
|
7933
|
+
async (params) => {
|
|
7934
|
+
const args = commandExecutionSchema.parse(params);
|
|
7935
|
+
const command = normalizeModelCommandName(args.command);
|
|
7936
|
+
if (!deps.isModelInvocable(command)) {
|
|
7937
|
+
return JSON.stringify({
|
|
7938
|
+
success: false,
|
|
7939
|
+
command,
|
|
7940
|
+
error: `Command is not model-invocable: ${command}`
|
|
7941
|
+
});
|
|
7942
|
+
}
|
|
7943
|
+
return stringifyModelCommandResult(command, await deps.execute(command, args.args ?? ""));
|
|
7944
|
+
}
|
|
7945
|
+
);
|
|
7946
|
+
}
|
|
7947
|
+
|
|
6460
7948
|
// src/subagents/index.ts
|
|
6461
7949
|
var import_agent_runtime7 = require("@robota-sdk/agent-runtime");
|
|
6462
7950
|
var import_agent_runtime8 = require("@robota-sdk/agent-runtime");
|
|
6463
7951
|
|
|
6464
|
-
// src/index.ts
|
|
6465
|
-
var import_agent_core10 = require("@robota-sdk/agent-core");
|
|
6466
|
-
|
|
6467
7952
|
// src/permissions/permission-prompt.ts
|
|
6468
7953
|
var import_chalk = __toESM(require("chalk"), 1);
|
|
6469
7954
|
var PERMISSION_OPTIONS = ["Allow", "Deny"];
|
|
@@ -6483,9 +7968,6 @@ async function promptForApproval(terminal, toolName, toolArgs) {
|
|
|
6483
7968
|
const selected = await terminal.select(PERMISSION_OPTIONS, ALLOW_INDEX);
|
|
6484
7969
|
return selected === ALLOW_INDEX;
|
|
6485
7970
|
}
|
|
6486
|
-
|
|
6487
|
-
// src/index.ts
|
|
6488
|
-
var import_agent_core11 = require("@robota-sdk/agent-core");
|
|
6489
7971
|
// Annotate the CommonJS export names for ESM import in node:
|
|
6490
7972
|
0 && (module.exports = {
|
|
6491
7973
|
AUTO_COMPACT_THRESHOLD_SETTINGS_KEY,
|
|
@@ -6503,6 +7985,7 @@ var import_agent_core11 = require("@robota-sdk/agent-core");
|
|
|
6503
7985
|
COST_COMMAND_DESCRIPTION,
|
|
6504
7986
|
CommandRegistry,
|
|
6505
7987
|
DEFAULT_AUTO_COMPACT_THRESHOLD,
|
|
7988
|
+
DEFAULT_BACKGROUND_TASK_LOG_PAGE_SIZE,
|
|
6506
7989
|
DEFAULT_STATUS_LINE_COMMAND_SETTINGS,
|
|
6507
7990
|
EXIT_COMMAND_DESCRIPTION,
|
|
6508
7991
|
EditCheckpointStore,
|
|
@@ -6517,12 +8000,14 @@ var import_agent_core11 = require("@robota-sdk/agent-core");
|
|
|
6517
8000
|
MEMORY_INDEX_MAX_LINES,
|
|
6518
8001
|
MODEL_COMMAND_ARGUMENT_HINT,
|
|
6519
8002
|
MODEL_COMMAND_DESCRIPTION,
|
|
8003
|
+
MODEL_COMMAND_TOOL_PREFIX,
|
|
6520
8004
|
MarketplaceClient,
|
|
6521
8005
|
PERMISSIONS_COMMAND_DESCRIPTION,
|
|
6522
8006
|
PERMISSION_MODE_ARGUMENT_HINT,
|
|
6523
8007
|
PERMISSION_MODE_COMMAND_DESCRIPTION,
|
|
6524
8008
|
PLUGIN_COMMAND_ARGUMENT_HINT,
|
|
6525
8009
|
PLUGIN_COMMAND_DESCRIPTION,
|
|
8010
|
+
PROVIDER_SAFE_TOOL_NAME_PATTERN,
|
|
6526
8011
|
PluginCommandSource,
|
|
6527
8012
|
PluginSettingsStore,
|
|
6528
8013
|
ProjectMemoryStore,
|
|
@@ -6539,9 +8024,11 @@ var import_agent_core11 = require("@robota-sdk/agent-core");
|
|
|
6539
8024
|
SkillCommandSource,
|
|
6540
8025
|
SubagentManager,
|
|
6541
8026
|
SystemCommandExecutor,
|
|
6542
|
-
|
|
8027
|
+
VALIDATE_SESSION_COMMAND_DESCRIPTION,
|
|
6543
8028
|
VALID_PERMISSION_MODES,
|
|
6544
8029
|
WorktreeSubagentRunner,
|
|
8030
|
+
addCommandContextReference,
|
|
8031
|
+
appendPrefixedLogLines,
|
|
6545
8032
|
assembleSubagentPrompt,
|
|
6546
8033
|
buildBackgroundCommandSubcommands,
|
|
6547
8034
|
buildLanguageCommandSubcommands,
|
|
@@ -6549,26 +8036,35 @@ var import_agent_core11 = require("@robota-sdk/agent-core");
|
|
|
6549
8036
|
buildModelCommandSubcommands,
|
|
6550
8037
|
buildPermissionModeSubcommands,
|
|
6551
8038
|
buildPluginCommandSubcommands,
|
|
8039
|
+
buildPromptWithFileReferences,
|
|
6552
8040
|
buildProviderProfile,
|
|
6553
8041
|
buildProviderSetupPatch,
|
|
6554
8042
|
buildRewindCommandSubcommands,
|
|
6555
|
-
buildSkillPrompt,
|
|
6556
8043
|
buildStatusLineCommandSubcommands,
|
|
6557
8044
|
cancelCommandBackgroundTask,
|
|
6558
|
-
|
|
8045
|
+
clearCommandContextReferences,
|
|
8046
|
+
clearContextReferences,
|
|
6559
8047
|
clearConversationHistory,
|
|
6560
8048
|
closeCommandBackgroundTask,
|
|
6561
8049
|
compactCommandContext,
|
|
6562
8050
|
createAgentTool,
|
|
6563
8051
|
createBackgroundProcessTool,
|
|
8052
|
+
createBackgroundTaskLogPage,
|
|
6564
8053
|
createBuiltinCommandModule,
|
|
6565
8054
|
createCommandExecutionTool,
|
|
6566
8055
|
createCommandMemoryStores,
|
|
6567
8056
|
createCommandPendingMemoryStore,
|
|
6568
8057
|
createCommandProjectMemoryStore,
|
|
8058
|
+
createContextReferenceItem,
|
|
6569
8059
|
createDefaultTools,
|
|
8060
|
+
createLimitedOutputCapture,
|
|
8061
|
+
createModelCommandToolProjection,
|
|
6570
8062
|
createPluginRegistryReloadRequestedEffect,
|
|
6571
8063
|
createPluginTuiRequestedEffect,
|
|
8064
|
+
createProjectSessionStore,
|
|
8065
|
+
createProjectedCommandExecutionTools,
|
|
8066
|
+
createPromptFileReferenceHistoryEntry,
|
|
8067
|
+
createProviderSafeModelCommandToolName,
|
|
6572
8068
|
createProviderSetupFlow,
|
|
6573
8069
|
createQuery,
|
|
6574
8070
|
createSessionExitRequestedEffect,
|
|
@@ -6578,48 +8074,57 @@ var import_agent_core11 = require("@robota-sdk/agent-core");
|
|
|
6578
8074
|
createSubagentSession,
|
|
6579
8075
|
createSystemCommands,
|
|
6580
8076
|
createWorktreeSubagentRunner,
|
|
8077
|
+
deleteProviderProfile,
|
|
6581
8078
|
discoverTaskFiles,
|
|
6582
|
-
evaluatePermission,
|
|
6583
8079
|
evaluateReversibleToolSafety,
|
|
6584
8080
|
executeSkill,
|
|
6585
8081
|
formatCommandBackgroundTask,
|
|
6586
8082
|
formatCommandBackgroundTaskList,
|
|
6587
8083
|
formatCommandHelpMessage,
|
|
6588
8084
|
formatCommandPermissionsMessage,
|
|
8085
|
+
formatCommandSessionReplayValidationReport,
|
|
6589
8086
|
formatEnvReference,
|
|
6590
8087
|
formatInvalidPermissionModeMessage,
|
|
6591
8088
|
formatLanguageUsageMessage,
|
|
8089
|
+
formatModelCommandUsageMessage,
|
|
8090
|
+
formatModelCommandUsageMessageAsync,
|
|
8091
|
+
formatProjectedModelCommandToolPromptDescription,
|
|
8092
|
+
formatPromptFileReferenceDiagnostics,
|
|
6592
8093
|
formatProviderSetupChoiceLabel,
|
|
8094
|
+
formatProviderSetupHelpLinks,
|
|
6593
8095
|
formatProviderSetupPromptLabel,
|
|
6594
8096
|
formatProviderSetupSelectionPrompt,
|
|
6595
8097
|
formatTaskContext,
|
|
6596
8098
|
getBackgroundTaskTransitions,
|
|
6597
8099
|
getBuiltInAgent,
|
|
6598
8100
|
getForkWorkerSuffix,
|
|
6599
|
-
getMessagesForAPI,
|
|
6600
8101
|
getProviderSetupStep,
|
|
6601
8102
|
getSubagentSuffix,
|
|
8103
|
+
hasBlockingPromptFileReferenceDiagnostics,
|
|
6602
8104
|
hasSensitiveCommandMemoryContent,
|
|
6603
8105
|
hasUsableSecretReference,
|
|
6604
8106
|
inspectCommandEditCheckpoint,
|
|
6605
|
-
isChatEntry,
|
|
6606
8107
|
isCommandMemoryType,
|
|
6607
8108
|
isEnvReference,
|
|
6608
8109
|
isMemoryType,
|
|
6609
8110
|
isPermissionMode,
|
|
6610
8111
|
isStatusLineCommandSettingsPatch,
|
|
6611
8112
|
isTerminalBackgroundTaskStatus,
|
|
8113
|
+
listActiveContextReferences,
|
|
6612
8114
|
listCommandBackgroundTasks,
|
|
8115
|
+
listCommandContextReferences,
|
|
6613
8116
|
listCommandEditCheckpoints,
|
|
6614
8117
|
listCommandSessionAllowedTools,
|
|
6615
8118
|
listCommandUsedMemoryReferences,
|
|
8119
|
+
listResumableSessionSummaries,
|
|
6616
8120
|
loadTaskContext,
|
|
6617
8121
|
mergeProviderPatch,
|
|
6618
|
-
|
|
8122
|
+
normalizeModelCommandName,
|
|
6619
8123
|
parseCommandBackgroundLogCursor,
|
|
6620
8124
|
parseFrontmatter,
|
|
6621
8125
|
parseLanguageArgument,
|
|
6622
8126
|
parsePermissionModeArgument,
|
|
8127
|
+
parsePromptFileReferences,
|
|
6623
8128
|
parseSessionNameArgument,
|
|
6624
8129
|
parseTaskFile,
|
|
6625
8130
|
planSelfHostingVerification,
|
|
@@ -6636,30 +8141,43 @@ var import_agent_core11 = require("@robota-sdk/agent-core");
|
|
|
6636
8141
|
readCommandSessionInfo,
|
|
6637
8142
|
readCurrentGitBranch,
|
|
6638
8143
|
recordCommandMemoryEvent,
|
|
8144
|
+
removeCommandContextReference,
|
|
8145
|
+
removeContextReference,
|
|
6639
8146
|
resetAutoCompactThresholdSetting,
|
|
8147
|
+
resolveActiveProviderModelCatalog,
|
|
8148
|
+
resolveActiveProviderModelCatalogState,
|
|
6640
8149
|
resolveEnvReference,
|
|
8150
|
+
resolveLatestSessionId,
|
|
6641
8151
|
resolvePermissionModeAdapter,
|
|
6642
8152
|
resolvePluginCommandAdapter,
|
|
8153
|
+
resolvePromptFileReferencePaths,
|
|
8154
|
+
resolvePromptFileReferences,
|
|
6643
8155
|
resolveProviderSetupSelection,
|
|
8156
|
+
resolveSessionIdByIdOrName,
|
|
6644
8157
|
resolveSubagentLogDir,
|
|
6645
8158
|
restoreCommandEditCheckpoint,
|
|
6646
8159
|
retrieveAgentToolDeps,
|
|
6647
8160
|
rollbackCommandEditCheckpoint,
|
|
6648
|
-
runHooks,
|
|
6649
8161
|
runProviderSetupPromptFlow,
|
|
8162
|
+
sanitizeProviderProfileName,
|
|
6650
8163
|
selectRelevantTasks,
|
|
6651
8164
|
setCommandAutoCompactThreshold,
|
|
6652
8165
|
setCurrentProvider,
|
|
6653
8166
|
storeAgentToolDeps,
|
|
6654
8167
|
submitProviderSetupValue,
|
|
6655
8168
|
substituteVariables,
|
|
8169
|
+
suggestProviderProfileName,
|
|
6656
8170
|
summarizeBackgroundJobGroup,
|
|
6657
8171
|
testProviderProfileCommand,
|
|
8172
|
+
toContextReferenceRecords,
|
|
8173
|
+
toPromptFileReferenceRecords,
|
|
6658
8174
|
transitionBackgroundTaskStatus,
|
|
6659
8175
|
transitionSelfHostingLoop,
|
|
6660
8176
|
updateTaskFileStatus,
|
|
8177
|
+
upsertContextReference,
|
|
6661
8178
|
upsertProviderProfile,
|
|
6662
8179
|
userPaths,
|
|
8180
|
+
validateCommandSessionReplayLog,
|
|
6663
8181
|
validateProviderProfile,
|
|
6664
8182
|
validateProviderSetupValue,
|
|
6665
8183
|
wrapEditCheckpointTools,
|