@robota-sdk/agent-cli 3.0.0-beta.63 → 3.0.0-beta.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +3 -3
  2. package/dist/node/bin.d.ts +1 -1
  3. package/dist/node/bin.js +19 -2220
  4. package/dist/node/bin.js.map +1 -0
  5. package/dist/node/child-process-subagent-ipc--Vp2dk1v.js +2 -0
  6. package/dist/node/child-process-subagent-ipc--Vp2dk1v.js.map +1 -0
  7. package/dist/node/child-process-subagent-ipc-Aitv2i6E.cjs +1 -0
  8. package/dist/node/child-process-subagent-ipc-CEy8bLN6.cjs +1 -0
  9. package/dist/node/child-process-subagent-ipc-DVpVp43R.js +2 -0
  10. package/dist/node/child-process-subagent-ipc-DVpVp43R.js.map +1 -0
  11. package/dist/node/index.cjs +17 -2188
  12. package/dist/node/index.d.ts +30 -58
  13. package/dist/node/index.d.ts.map +1 -0
  14. package/dist/node/index.js +18 -2005
  15. package/dist/node/index.js.map +1 -0
  16. package/dist/node/subagents/child-process-subagent-worker.cjs +1 -249
  17. package/dist/node/subagents/child-process-subagent-worker.d.ts +1 -2
  18. package/dist/node/subagents/child-process-subagent-worker.js +2 -123
  19. package/dist/node/subagents/child-process-subagent-worker.js.map +1 -0
  20. package/package.json +12 -37
  21. package/README.ko.md +0 -297
  22. package/dist/node/chunk-6US65UBD.js +0 -5740
  23. package/dist/node/chunk-7D75HL37.js +0 -287
  24. package/dist/node/chunk-BENOH47A.js +0 -287
  25. package/dist/node/cli-N6TYREZG.js +0 -9
  26. package/dist/node/index.d.cts +0 -70
  27. package/dist/node/subagents/child-process-subagent-worker.d.cts +0 -2
  28. package/dist/web/assets/index-B2N-LjvM.css +0 -2
  29. package/dist/web/assets/index-B5tu6JSD.js +0 -37
  30. package/dist/web/assets/index-B8VHZ-wb.css +0 -2
  31. package/dist/web/assets/index-BSadCc8W.js +0 -37
  32. package/dist/web/assets/index-CIgpKdFz.js +0 -37
  33. package/dist/web/assets/index-CTx5Gdk4.js +0 -37
  34. package/dist/web/assets/index-CUJJsgxp.js +0 -37
  35. package/dist/web/assets/index-Ck-mdN6u.css +0 -2
  36. package/dist/web/assets/index-CqPdNxqk.css +0 -2
  37. package/dist/web/assets/index-CyJ7yl0E.js +0 -37
  38. package/dist/web/assets/index-DFBoQ601.css +0 -2
  39. package/dist/web/assets/index-Dc3tp-Ci.js +0 -37
  40. package/dist/web/assets/index-DtSuwV8l.js +0 -37
  41. package/dist/web/index.html +0 -13
@@ -1,55 +1,4 @@
1
- import {
2
- DEFAULT_PROVIDER_DEFINITIONS,
3
- createProviderFromSettings,
4
- findProviderDefinition,
5
- formatSupportedProviderTypes,
6
- getProviderCredentialRequirement,
7
- getProviderSettingsPaths,
8
- hasUsableSecretReference,
9
- isSubagentWorkerChildMessage,
10
- readMergedProviderSettings,
11
- readMergedProviderSettingsFromPaths,
12
- readProviderSettings
13
- } from "./chunk-BENOH47A.js";
14
-
15
- // src/cli.ts
16
- import { readFileSync as readFileSync6 } from "fs";
17
- import { join as join9, dirname as dirname5, resolve as resolve2 } from "path";
18
- import { fileURLToPath } from "url";
19
- import { createAgentCommandModule } from "@robota-sdk/agent-command-agent";
20
- import { createBackgroundCommandModule } from "@robota-sdk/agent-command-background";
21
- import { createProviderCommandModule } from "@robota-sdk/agent-command-provider";
22
- import { createCompactCommandModule } from "@robota-sdk/agent-command-compact";
23
- import { createContextCommandModule } from "@robota-sdk/agent-command-context";
24
- import { createExitCommandModule } from "@robota-sdk/agent-command-exit";
25
- import { createHelpCommandModule } from "@robota-sdk/agent-command-help";
26
- import { createLanguageCommandModule } from "@robota-sdk/agent-command-language";
27
- import { createMemoryCommandModule } from "@robota-sdk/agent-command-memory";
28
- import { createModelCommandModule } from "@robota-sdk/agent-command-model";
29
- import { createPermissionsCommandModule } from "@robota-sdk/agent-command-permissions";
30
- import { createPluginCommandModule } from "@robota-sdk/agent-command-plugin";
31
- import { createResetCommandModule } from "@robota-sdk/agent-command-reset";
32
- import { createRewindCommandModule } from "@robota-sdk/agent-command-rewind";
33
- import { createStatusLineCommandModule } from "@robota-sdk/agent-command-statusline";
34
- import { createSessionCommandModule } from "@robota-sdk/agent-command-session";
35
- import { createSkillsCommandModule } from "@robota-sdk/agent-command-skills";
36
- import { createUserLocalCommandModule } from "@robota-sdk/agent-command-user-local";
37
- import { createModeCommandModule } from "@robota-sdk/agent-command-mode";
38
- import { createSettingsCommandModule } from "@robota-sdk/agent-command-settings";
39
- import {
40
- InteractiveSession,
41
- createProjectSessionStore,
42
- projectPaths,
43
- resolveLatestSessionId,
44
- resolveSessionIdByIdOrName
45
- } from "@robota-sdk/agent-sdk";
46
-
47
- // src/utils/cli-args.ts
48
- import { parseArgs } from "util";
49
- var VALID_MODES = ["plan", "default", "acceptEdits", "bypassPermissions"];
50
- var VALID_OUTPUT_FORMATS = ["text", "json", "stream-json"];
51
- function printHelp() {
52
- process.stdout.write(`
1
+ import{r as e,t}from"./child-process-subagent-ipc-DVpVp43R.js";import{execSync as n,fork as r}from"node:child_process";import{existsSync as i,lstatSync as a,mkdirSync as o,readFileSync as s,unlinkSync as c,writeFileSync as l}from"node:fs";import{dirname as u,isAbsolute as d,join as f,resolve as p}from"node:path";import{fileURLToPath as m}from"node:url";import{BundlePluginInstaller as h,BundlePluginLoader as g,DEFAULT_STATUS_LINE_COMMAND_SETTINGS as _,InteractiveSession as v,MarketplaceClient as y,PluginCommandSource as ee,PluginSettingsStore as te,buildProviderSetupPatch as ne,checkSettingsDocument as b,createProjectSessionStore as re,findProviderDefinition as ie,getBuiltInAgent as ae,mergeProviderPatch as oe,projectPaths as se,readMergedProviderSettingsFromPaths as ce,readMergedProviderSettingsFromPaths as le,resolveActiveProvider as ue,resolveLatestSessionId as de,resolveSessionIdByIdOrName as fe,setCurrentProvider as pe}from"@robota-sdk/agent-framework";import{createAgentCommandModule as me,createBackgroundCommandModule as he,createCompactCommandModule as ge,createContextCommandModule as _e,createExitCommandModule as ve,createHelpCommandModule as ye,createLanguageCommandModule as be,createMemoryCommandModule as xe,createModeCommandModule as Se,createModelCommandModule as Ce,createPermissionsCommandModule as we,createPluginCommandModule as Te,createProviderCommandModule as Ee,createResetCommandModule as De,createRewindCommandModule as Oe,createSessionCommandModule as ke,createSettingsCommandModule as Ae,createSkillsCommandModule as je,createStatusLineCommandModule as Me,createUserLocalCommandModule as Ne,executeUserLocalDirectCommand as Pe,formatProviderSetupSelectionPrompt as Fe,resolveProviderSetupSelection as Ie,runProviderSetupPromptFlow as Le}from"@robota-sdk/agent-command";import{parseArgs as Re}from"node:util";import{BackgroundTaskError as x,GitWorktreeIsolationAdapter as ze,createBackgroundTaskLogPage as Be,createDefaultBackgroundTaskRunners as Ve,createGitWorktreeIsolationAdapter as He,createGitWorktreeIsolationAdapter as Ue,createProviderFromConfig as We,createWorktreeSubagentRunner as Ge}from"@robota-sdk/agent-executor";import{formatSupportedProviderTypes as Ke}from"@robota-sdk/agent-core";import{createHeadlessTransport as qe}from"@robota-sdk/agent-transport/headless";import{WsTransport as Je}from"@robota-sdk/agent-transport/ws";import{TuiTransport as Ye}from"@robota-sdk/agent-transport/tui";import{homedir as S}from"node:os";const C=[`plan`,`default`,`acceptEdits`,`bypassPermissions`],w=[`text`,`json`,`stream-json`];function Xe(){process.stdout.write(`
53
2
  Usage: robota [options] [-p <prompt>]
54
3
 
55
4
  Options:
@@ -77,1956 +26,20 @@ Examples:
77
26
  robota -p "Hello" Print mode: send prompt and exit
78
27
  robota -p "Hello" --output-format json
79
28
  robota --continue Resume the last session
80
- `);
81
- }
82
- function parseOutputFormat(raw) {
83
- if (raw === void 0) return void 0;
84
- if (!VALID_OUTPUT_FORMATS.includes(raw)) {
85
- process.stderr.write(
86
- `Invalid --output-format "${raw}". Valid: ${VALID_OUTPUT_FORMATS.join(" | ")}
87
- `
88
- );
89
- process.exit(1);
90
- }
91
- return raw;
92
- }
93
- function parsePermissionMode(raw) {
94
- if (raw === void 0) return void 0;
95
- if (!VALID_MODES.includes(raw)) {
96
- process.stderr.write(`Invalid --permission-mode "${raw}". Valid: ${VALID_MODES.join(" | ")}
97
- `);
98
- process.exit(1);
99
- }
100
- return raw;
101
- }
102
- function parseMaxTurns(raw) {
103
- if (raw === void 0) return void 0;
104
- const n = parseInt(raw, 10);
105
- if (isNaN(n) || n <= 0) {
106
- process.stderr.write(`Invalid --max-turns "${raw}". Must be a positive integer.
107
- `);
108
- process.exit(1);
109
- }
110
- return n;
111
- }
112
- function parseCliArgs() {
113
- const { values, positionals } = parseArgs({
114
- allowPositionals: true,
115
- options: {
116
- help: { type: "boolean", short: "h", default: false },
117
- p: { type: "boolean", short: "p", default: false },
118
- continue: { type: "boolean", short: "c", default: false },
119
- resume: { type: "string", short: "r" },
120
- model: { type: "string" },
121
- language: { type: "string" },
122
- "permission-mode": { type: "string" },
123
- "max-turns": { type: "string" },
124
- "fork-session": { type: "boolean", default: false },
125
- name: { type: "string", short: "n" },
126
- "output-format": { type: "string" },
127
- format: { type: "string" },
128
- summary: { type: "string" },
129
- source: { type: "string" },
130
- "system-prompt": { type: "string" },
131
- "append-system-prompt": { type: "string" },
132
- "task-file": { type: "string" },
133
- version: { type: "boolean", default: false },
134
- reset: { type: "boolean", default: false },
135
- bare: { type: "boolean", default: false },
136
- "allowed-tools": { type: "string" },
137
- "no-session-persistence": { type: "boolean", default: false },
138
- "json-schema": { type: "string" },
139
- configure: { type: "boolean", default: false },
140
- "configure-provider": { type: "string" },
141
- provider: { type: "string" },
142
- type: { type: "string" },
143
- "base-url": { type: "string" },
144
- "api-key": { type: "string" },
145
- "api-key-env": { type: "string" },
146
- "set-current": { type: "boolean", default: false },
147
- "settings-scope": { type: "string" },
148
- "check-update": { type: "boolean", default: false },
149
- "disable-update-check": { type: "boolean", default: false }
150
- }
151
- });
152
- return {
153
- positional: positionals,
154
- help: values["help"] ?? false,
155
- printMode: values["p"] ?? false,
156
- continueMode: values["continue"] ?? false,
157
- resumeId: values["resume"],
158
- model: values["model"],
159
- language: values["language"],
160
- permissionMode: parsePermissionMode(values["permission-mode"]),
161
- maxTurns: parseMaxTurns(values["max-turns"]),
162
- forkSession: values["fork-session"] ?? false,
163
- sessionName: values["name"],
164
- outputFormat: parseOutputFormat(values["output-format"]),
165
- format: values["format"],
166
- summary: values["summary"],
167
- source: values["source"],
168
- systemPrompt: values["system-prompt"],
169
- appendSystemPrompt: values["append-system-prompt"],
170
- taskFile: values["task-file"],
171
- version: values["version"] ?? false,
172
- reset: values["reset"] ?? false,
173
- bare: values["bare"] ?? false,
174
- allowedTools: values["allowed-tools"],
175
- noSessionPersistence: values["no-session-persistence"] ?? false,
176
- jsonSchema: values["json-schema"],
177
- configure: values["configure"] ?? false,
178
- configureProvider: values["configure-provider"],
179
- provider: values["provider"],
180
- providerType: values["type"],
181
- baseURL: values["base-url"],
182
- apiKey: values["api-key"],
183
- apiKeyEnv: values["api-key-env"],
184
- setCurrent: values["set-current"] ?? false,
185
- settingsScope: values["settings-scope"],
186
- checkUpdate: values["check-update"] ?? false,
187
- disableUpdateCheck: values["disable-update-check"] ?? false
188
- };
189
- }
190
-
191
- // src/utils/settings-io.ts
192
- import { existsSync, readFileSync, writeFileSync, mkdirSync, unlinkSync } from "fs";
193
- import { join, dirname } from "path";
194
- function getUserSettingsPath() {
195
- const home = process.env.HOME ?? process.env.USERPROFILE ?? "/";
196
- return join(home, ".robota", "settings.json");
197
- }
198
- function readSettings(path) {
199
- if (!existsSync(path)) return {};
200
- const raw = readFileSync(path, "utf8");
201
- try {
202
- return JSON.parse(raw);
203
- } catch {
204
- process.stderr.write(`Warning: corrupt settings file at ${path}, resetting to defaults
205
- `);
206
- return {};
207
- }
208
- }
209
- function writeSettings(path, settings) {
210
- mkdirSync(dirname(path), { recursive: true });
211
- writeFileSync(path, JSON.stringify(settings, null, 2) + "\n", "utf8");
212
- }
213
- function deleteSettings(path) {
214
- if (existsSync(path)) {
215
- unlinkSync(path);
216
- return true;
217
- }
218
- return false;
219
- }
220
-
221
- // src/utils/provider-setup.ts
222
- import { join as join2 } from "path";
223
-
224
- // src/utils/settings-check.ts
225
- import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
226
- function checkSettingsDocument(settings, providerDefinitions = []) {
227
- return hasUsableProviderConfig(settings, providerDefinitions) ? "valid" : "incomplete";
228
- }
229
- function hasUsableProviderConfig(settings, providerDefinitions) {
230
- if (typeof settings.currentProvider === "string") {
231
- const profile = settings.providers?.[settings.currentProvider];
232
- return isUsableProviderProfile(profile?.type, profile, providerDefinitions);
233
- }
234
- if (settings.provider && isUsableProviderProfile(settings.provider.name, settings.provider, providerDefinitions)) {
235
- return true;
236
- }
237
- return false;
238
- }
239
- function isUsableProviderProfile(type, profile, providerDefinitions) {
240
- if (!profile) {
241
- return false;
242
- }
243
- if (!type) {
244
- return hasUsableSecretReference(profile.apiKey);
245
- }
246
- const definition = findProviderDefinition(providerDefinitions, type);
247
- if (definition === void 0) {
248
- return false;
249
- }
250
- const credentialRequirement = getProviderCredentialRequirement(definition);
251
- if (credentialRequirement === void 0) {
252
- return true;
253
- }
254
- return hasUsableRequiredProviderCredential(profile, definition, credentialRequirement);
255
- }
256
- function hasUsableRequiredProviderCredential(profile, definition, requirement) {
257
- return requirement.anyOf.some(
258
- (field) => hasUsableSecretReference(resolveProviderCredentialValue(field, profile, definition))
259
- );
260
- }
261
- function resolveProviderCredentialValue(field, profile, definition) {
262
- return profile[field] ?? definition.defaults?.[field];
263
- }
264
-
265
- // src/utils/provider-settings.ts
266
- import {
267
- buildProviderProfile,
268
- buildProviderSetupPatch,
269
- deleteProviderProfile,
270
- mergeProviderPatch,
271
- setCurrentProvider,
272
- upsertProviderProfile,
273
- validateProviderProfile
274
- } from "@robota-sdk/agent-sdk";
275
-
276
- // src/utils/provider-configuration.ts
277
- function resolveProviderSettingsWriteTargetPath(cwd, options = {}) {
278
- const settingsPaths = options.settingsPaths ?? getProviderSettingsPaths(cwd);
279
- const targetPath = findLastPathWithCurrentProvider(settingsPaths) ?? settingsPaths[0];
280
- if (targetPath === void 0) {
281
- throw new Error("No settings path available for provider update");
282
- }
283
- return targetPath;
284
- }
285
- function readProviderDocument(settingsPath) {
286
- return readSettings(settingsPath);
287
- }
288
- function applyProviderConfiguration(settingsPath, input, options = {}) {
289
- const settings = readProviderDocument(settingsPath);
290
- const patch = buildProviderSetupPatch(input, options);
291
- const next = mergeProviderPatch(settings, patch);
292
- writeSettings(settingsPath, next);
293
- return next;
294
- }
295
- function applyProviderSwitch(settingsPath, profileName, options = {}) {
296
- const settings = readProviderDocument(settingsPath);
297
- const hasLocalProfile = settings.providers?.[profileName] !== void 0;
298
- const hasKnownProfile = options.knownProviders?.[profileName] !== void 0;
299
- const next = hasLocalProfile || hasKnownProfile ? { ...settings, currentProvider: profileName } : setCurrentProvider(settings, profileName);
300
- writeSettings(settingsPath, next);
301
- return next;
302
- }
303
- function applyActiveModelChange(cwd, modelId, options = {}) {
304
- const settingsPaths = options.settingsPaths ?? getProviderSettingsPaths(cwd);
305
- const merged = readMergedProviderSettingsFromPaths(settingsPaths);
306
- const activeProfileName = options.providerOverride ?? merged.currentProvider;
307
- if (typeof activeProfileName !== "string") {
308
- throw new Error(
309
- 'Cannot update model: no active provider profile. Set "currentProvider" in settings.'
310
- );
311
- }
312
- return updateActiveProviderProfileModel(settingsPaths, activeProfileName, modelId);
313
- }
314
- function updateActiveProviderProfileModel(settingsPaths, profileName, modelId) {
315
- const settingsPath = findLastPathWithProviderProfile(settingsPaths, profileName) ?? settingsPaths[0];
316
- if (settingsPath === void 0) {
317
- throw new Error("No settings path available for model update");
318
- }
319
- const settings = readProviderDocument(settingsPath);
320
- const providers = settings.providers ?? {};
321
- const existing = providers[profileName] ?? {};
322
- const next = {
323
- ...settings,
324
- providers: {
325
- ...providers,
326
- [profileName]: {
327
- ...existing,
328
- model: modelId
329
- }
330
- }
331
- };
332
- writeSettings(settingsPath, next);
333
- return { settingsPath, settings: next, profileName };
334
- }
335
- function findLastPathWithProviderProfile(settingsPaths, profileName) {
336
- for (let index = settingsPaths.length - 1; index >= 0; index -= 1) {
337
- const settingsPath = settingsPaths[index];
338
- if (settingsPath === void 0) continue;
339
- const settings = readProviderDocument(settingsPath);
340
- if (settings.providers?.[profileName] !== void 0) return settingsPath;
341
- }
342
- return void 0;
343
- }
344
- function findLastPathWithCurrentProvider(settingsPaths) {
345
- for (let index = settingsPaths.length - 1; index >= 0; index -= 1) {
346
- const settingsPath = settingsPaths[index];
347
- if (settingsPath === void 0) continue;
348
- const settings = readProviderDocument(settingsPath);
349
- if (settings.currentProvider !== void 0) return settingsPath;
350
- }
351
- return void 0;
352
- }
353
-
354
- // src/utils/provider-setup-flow.ts
355
- import {
356
- createProviderSetupFlow,
357
- formatProviderSetupChoiceLabel,
358
- formatProviderSetupHelpLinks,
359
- formatProviderSetupPromptLabel,
360
- formatProviderSetupSelectionPrompt,
361
- getProviderSetupStep,
362
- resolveProviderSetupSelection,
363
- runProviderSetupPromptFlow,
364
- submitProviderSetupValue,
365
- validateProviderSetupValue
366
- } from "@robota-sdk/agent-sdk";
367
-
368
- // src/utils/provider-setup.ts
369
- function getSettingsPathForScope(cwd, scope) {
370
- if (scope === void 0 || scope === "user") {
371
- return getUserSettingsPath();
372
- }
373
- if (scope === "project-local") {
374
- return join2(cwd, ".robota", "settings.local.json");
375
- }
376
- throw new Error(`Invalid --settings-scope "${scope}". Valid: user | project-local`);
377
- }
378
- function handleProviderConfigurationArgs(cwd, args, providerDefinitions = DEFAULT_PROVIDER_DEFINITIONS) {
379
- const settingsPath = getSettingsPathForScope(cwd, args.settingsScope);
380
- if (args.configureProvider) {
381
- applyProviderConfiguration(settingsPath, buildSetupInputFromArgs(args), {
382
- providerDefinitions
383
- });
384
- process.stdout.write(`Provider profile saved to ${settingsPath}
385
- `);
386
- return !args.printMode && args.positional.length === 0;
387
- }
388
- if (args.provider && args.setCurrent) {
389
- const switchSettingsPath = args.settingsScope === void 0 ? resolveProviderSettingsWriteTargetPath(cwd) : settingsPath;
390
- applyProviderSwitch(switchSettingsPath, args.provider, {
391
- knownProviders: readMergedProviderSettings(cwd).providers
392
- });
393
- process.stdout.write(`Current provider set to ${args.provider}
394
- `);
395
- return !args.printMode && args.positional.length === 0;
396
- }
397
- return false;
398
- }
399
- async function ensureConfig(cwd, args, promptInput2, providerDefinitions = DEFAULT_PROVIDER_DEFINITIONS) {
400
- const merged = readMergedProviderSettings(cwd);
401
- const selectedSettings = args.provider !== void 0 ? { ...merged, currentProvider: args.provider } : merged;
402
- if (checkSettingsDocument(selectedSettings, providerDefinitions) === "valid") {
403
- return;
404
- }
405
- if (!isInteractiveTerminal()) {
406
- throw new Error(formatMissingProviderConfigMessage(providerDefinitions));
407
- }
408
- await runInteractiveProviderSetup(
409
- cwd,
410
- selectStartupSetupArgs(cwd, args),
411
- promptInput2,
412
- providerDefinitions
413
- );
414
- const updated = readMergedProviderSettings(cwd);
415
- const updatedSettings = args.provider !== void 0 ? { ...updated, currentProvider: args.provider } : updated;
416
- if (checkSettingsDocument(updatedSettings, providerDefinitions) !== "valid") {
417
- throw new Error(formatMissingProviderConfigMessage(providerDefinitions));
418
- }
419
- }
420
- async function runInteractiveProviderSetup(cwd, args, promptInput2, providerDefinitions = DEFAULT_PROVIDER_DEFINITIONS) {
421
- const providerChoice = await promptInput2(formatProviderSetupSelectionPrompt(providerDefinitions));
422
- const type = resolveProviderSetupSelection(providerChoice, providerDefinitions);
423
- const settingsPath = getSettingsPathForScope(cwd, args.settingsScope);
424
- const input = await runProviderSetupPromptFlow(type, promptInput2, providerDefinitions, {
425
- existingProfileNames: Object.keys(readMergedProviderSettings(cwd).providers ?? {})
426
- });
427
- applyProviderConfiguration(settingsPath, input, {
428
- providerDefinitions
429
- });
430
- const language = await promptInput2(" Response language (ko/en/ja/zh, default: en): ");
431
- if (language) {
432
- const settings = readSettings(settingsPath);
433
- settings.language = language;
434
- writeSettings(settingsPath, settings);
435
- }
436
- process.stdout.write(`
437
- Config saved to ${settingsPath}
438
-
439
- `);
440
- }
441
- function buildSetupInputFromArgs(args) {
442
- const type = args.providerType ?? args.configureProvider;
443
- if (!args.configureProvider || !type) {
444
- throw new Error("--configure-provider requires a provider profile and --type");
445
- }
446
- return {
447
- profile: args.configureProvider,
448
- type,
449
- ...args.model !== void 0 && { model: args.model },
450
- ...args.apiKey !== void 0 && { apiKey: args.apiKey },
451
- ...args.apiKeyEnv !== void 0 && { apiKeyEnv: args.apiKeyEnv },
452
- ...args.baseURL !== void 0 && { baseURL: args.baseURL },
453
- setCurrent: args.setCurrent
454
- };
455
- }
456
- function selectStartupSetupArgs(cwd, args) {
457
- if (args.settingsScope !== void 0 || args.provider !== void 0) {
458
- return args;
459
- }
460
- const currentProviderPath = findHighestPriorityCurrentProviderPath(getProviderSettingsPaths(cwd));
461
- if (currentProviderPath === void 0) {
462
- return args;
463
- }
464
- const projectSettingsPath = join2(cwd, ".robota", "settings.json");
465
- const projectLocalSettingsPath = join2(cwd, ".robota", "settings.local.json");
466
- if (currentProviderPath === projectSettingsPath || currentProviderPath === projectLocalSettingsPath) {
467
- return { ...args, settingsScope: "project-local" };
468
- }
469
- return args;
470
- }
471
- function findHighestPriorityCurrentProviderPath(settingsPaths) {
472
- for (let index = settingsPaths.length - 1; index >= 0; index -= 1) {
473
- const settingsPath = settingsPaths[index];
474
- if (settingsPath === void 0) continue;
475
- const settings = readSettings(settingsPath);
476
- if (typeof settings.currentProvider === "string") {
477
- return settingsPath;
478
- }
479
- }
480
- return void 0;
481
- }
482
- function isInteractiveTerminal() {
483
- return process.stdin.isTTY === true && process.stdout.isTTY === true;
484
- }
485
- function formatMissingProviderConfigMessage(providerDefinitions = DEFAULT_PROVIDER_DEFINITIONS) {
486
- return [
487
- "No provider configuration found.",
488
- "Run `robota --configure` in an interactive terminal, or configure a provider:",
489
- `Supported providers: ${formatSupportedProviderTypes(providerDefinitions)}`,
490
- ...providerDefinitions.map(formatConfigureProviderExample)
491
- ].join("\n");
492
- }
493
- function formatConfigureProviderExample(definition) {
494
- const flags = [
495
- `robota --configure-provider ${definition.type}`,
496
- `--type ${definition.type}`,
497
- ...definition.defaults?.baseURL !== void 0 ? ["--base-url <url>"] : [],
498
- "--model <model>",
499
- ...definition.requiresApiKey === true ? ["--api-key-env <ENV_NAME>"] : [],
500
- "--set-current"
501
- ];
502
- return ` ${flags.join(" ")}`;
503
- }
504
-
505
- // src/cli.ts
506
- import { createHeadlessTransport } from "@robota-sdk/agent-transport-headless";
507
- import { WsTransport } from "@robota-sdk/agent-transport-ws";
508
- import { TuiTransport } from "@robota-sdk/agent-transport-tui";
509
-
510
- // src/transports/transport-registry.ts
511
- var TransportRegistry = class {
512
- entries = /* @__PURE__ */ new Map();
513
- settingsPath;
514
- constructor(settingsPath) {
515
- this.settingsPath = settingsPath;
516
- }
517
- register(transport) {
518
- this.entries.set(transport.name, transport);
519
- }
520
- getAll() {
521
- const saved = this.readTransportSettings();
522
- return Array.from(this.entries.values()).map((transport) => ({
523
- transport,
524
- config: this.resolveConfig(transport, saved[transport.name])
525
- }));
526
- }
527
- getEnabled() {
528
- return this.getAll().filter((e) => e.config.enabled).map((e) => e.transport);
529
- }
530
- async setEnabled(name, enabled) {
531
- const settings = readSettings(this.settingsPath);
532
- const transports = settings.transports ?? {};
533
- const entry = transports[name] ?? {};
534
- transports[name] = { ...entry, enabled };
535
- settings.transports = transports;
536
- writeSettings(this.settingsPath, settings);
537
- }
538
- async setOptions(name, options) {
539
- const settings = readSettings(this.settingsPath);
540
- const transports = settings.transports ?? {};
541
- const entry = transports[name] ?? {};
542
- transports[name] = { ...entry, options };
543
- settings.transports = transports;
544
- writeSettings(this.settingsPath, settings);
545
- }
546
- async startAll(session) {
547
- const enabled = this.getEnabled();
548
- for (const transport of enabled) {
549
- transport.attach(session);
550
- await transport.start();
551
- }
552
- }
553
- async stopAll() {
554
- for (const transport of this.entries.values()) {
555
- await transport.stop();
556
- }
557
- }
558
- resolveConfig(transport, saved) {
559
- const enabled = saved?.enabled ?? transport.defaultEnabled;
560
- const options = saved?.options ?? {};
561
- return { enabled, options };
562
- }
563
- readTransportSettings() {
564
- const settings = readSettings(this.settingsPath);
565
- const raw = settings.transports;
566
- if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
567
- return raw;
568
- }
569
- };
570
-
571
- // src/background/managed-shell-process-runner.ts
572
- import { spawn } from "child_process";
573
- import {
574
- BackgroundTaskError,
575
- appendPrefixedLogLines,
576
- createBackgroundTaskLogPage,
577
- createLimitedOutputCapture
578
- } from "@robota-sdk/agent-sdk";
579
- var DEFAULT_OUTPUT_LIMIT_BYTES = 3e4;
580
- var DEFAULT_KILL_GRACE_MS = 2e3;
581
- function resolveShell(request) {
582
- return { command: request.shell ?? "sh", args: ["-c", request.command] };
583
- }
584
- function sendInput(child, input) {
585
- return new Promise((resolve3, reject) => {
586
- const onError = (error) => {
587
- child.stdin.off("error", onError);
588
- reject(error);
589
- };
590
- child.stdin.once("error", onError);
591
- child.stdin.end(input, () => {
592
- child.stdin.off("error", onError);
593
- resolve3();
594
- });
595
- });
596
- }
597
- function createManagedShellProcessRunner(options = {}) {
598
- const killGraceMs = options.killGraceMs ?? DEFAULT_KILL_GRACE_MS;
599
- return {
600
- kind: "process",
601
- start(task) {
602
- if (task.request.kind !== "process") {
603
- throw new BackgroundTaskError("runner", `Invalid process task kind: ${task.request.kind}`);
604
- }
605
- return startProcessTask(task.taskId, task.request, killGraceMs);
606
- }
607
- };
608
- }
609
- function startProcessTask(taskId, request, killGraceMs) {
610
- const shell = resolveShell(request);
611
- const runtime = {
612
- taskId,
613
- request,
614
- child: spawn(shell.command, shell.args, {
615
- cwd: request.cwd,
616
- env: { ...process.env, ...request.env ?? {} },
617
- stdio: ["pipe", "pipe", "pipe"]
618
- }),
619
- logs: [],
620
- capture: createLimitedOutputCapture({
621
- limitBytes: request.outputLimitBytes ?? DEFAULT_OUTPUT_LIMIT_BYTES
622
- }),
623
- killGraceMs
624
- };
625
- const result = createProcessResult(runtime);
626
- return createProcessHandle(runtime, result);
627
- }
628
- function createProcessResult(runtime) {
629
- let settled = false;
630
- return new Promise((resolve3, reject) => {
631
- const timeoutTimer = runtime.request.timeoutMs ? setTimeout(() => {
632
- appendPrefixedLogLines(
633
- runtime.logs,
634
- "system",
635
- `timed out after ${runtime.request.timeoutMs}ms`
636
- );
637
- runtime.child.kill("SIGTERM");
638
- rejectOnceLocal(new BackgroundTaskError("timeout", "Background process timed out"));
639
- }, runtime.request.timeoutMs) : void 0;
640
- function clearTimers() {
641
- if (timeoutTimer) clearTimeout(timeoutTimer);
642
- if (runtime.killTimer) clearTimeout(runtime.killTimer);
643
- }
644
- function resolveOnce(exitCode, signalCode) {
645
- if (settled) return;
646
- settled = true;
647
- clearTimers();
648
- resolve3({
649
- taskId: runtime.taskId,
650
- kind: "process",
651
- output: runtime.capture.getOutput(),
652
- exitCode,
653
- signalCode
654
- });
655
- }
656
- function rejectOnceLocal(error) {
657
- if (settled) return;
658
- settled = true;
659
- clearTimers();
660
- reject(error);
661
- }
662
- attachOutputListeners(runtime);
663
- runtime.child.on("error", (error) => {
664
- appendPrefixedLogLines(runtime.logs, "system", error.message);
665
- rejectOnceLocal(new BackgroundTaskError("process", error.message));
666
- });
667
- runtime.child.on("close", (code, signal) => {
668
- resolveOnce(code ?? void 0, signal ?? void 0);
669
- });
670
- if (runtime.request.stdin) {
671
- runtime.child.stdin.write(runtime.request.stdin);
672
- runtime.child.stdin.end();
673
- }
674
- });
675
- }
676
- function createProcessHandle(runtime, result) {
677
- return {
678
- taskId: runtime.taskId,
679
- ...runtime.child.pid !== void 0 ? { pid: runtime.child.pid } : {},
680
- result,
681
- cancel: async (reason) => {
682
- cancelProcess(runtime, reason);
683
- },
684
- send: async (input) => {
685
- if (!input.stdin) return;
686
- await sendInput(runtime.child, input.stdin);
687
- },
688
- readLog: (cursor) => Promise.resolve(readProcessLog(runtime, cursor))
689
- };
690
- }
691
- function attachOutputListeners(runtime) {
692
- runtime.child.stdout.on("data", (chunk) => {
693
- const text = chunk.toString("utf8");
694
- runtime.capture.appendOutput(text);
695
- appendPrefixedLogLines(runtime.logs, "stdout", text);
696
- });
697
- runtime.child.stderr.on("data", (chunk) => {
698
- const text = chunk.toString("utf8");
699
- runtime.capture.appendOutput(text);
700
- appendPrefixedLogLines(runtime.logs, "stderr", text);
701
- });
702
- }
703
- function cancelProcess(runtime, reason) {
704
- appendPrefixedLogLines(
705
- runtime.logs,
706
- "system",
707
- reason ? `cancel requested: ${reason}` : "cancel requested"
708
- );
709
- if (!runtime.child.killed) runtime.child.kill("SIGTERM");
710
- runtime.killTimer = setTimeout(() => {
711
- if (!runtime.child.killed) runtime.child.kill("SIGKILL");
712
- }, runtime.killGraceMs);
713
- }
714
- function readProcessLog(runtime, cursor) {
715
- return createBackgroundTaskLogPage(runtime.taskId, runtime.logs, cursor);
716
- }
717
-
718
- // src/subagents/child-process-subagent-runner.ts
719
- import { fork } from "child_process";
720
- import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
721
- import { dirname as dirname2, join as join4 } from "path";
722
- import {
723
- BackgroundTaskError as BackgroundTaskError5,
724
- createBackgroundTaskLogPage as createBackgroundTaskLogPage2,
725
- getBuiltInAgent,
726
- createWorktreeSubagentRunner
727
- } from "@robota-sdk/agent-sdk";
728
-
729
- // src/subagents/child-process-subagent-runner-result.ts
730
- import {
731
- BackgroundTaskError as BackgroundTaskError3
732
- } from "@robota-sdk/agent-sdk";
733
-
734
- // src/subagents/child-process-subagent-transport.ts
735
- import {
736
- BackgroundTaskError as BackgroundTaskError2
737
- } from "@robota-sdk/agent-sdk";
738
- function handleWorkerMessage(message, startWorker, resolveOnce, rejectOnce, emit) {
739
- switch (message.type) {
740
- case "ready":
741
- startWorker();
742
- break;
743
- case "result":
744
- resolveOnce(message.output);
745
- break;
746
- case "error":
747
- rejectOnce(new BackgroundTaskError2("runner", message.message));
748
- break;
749
- case "cancelled":
750
- rejectOnce(new BackgroundTaskError2("runner", message.reason ?? "Subagent worker cancelled"));
751
- break;
752
- case "text_delta":
753
- emit?.({ type: "background_task_text_delta", delta: message.delta });
754
- break;
755
- case "tool_start":
756
- emit?.({
757
- type: "background_task_tool_start",
758
- toolName: message.toolName,
759
- firstArg: extractFirstArg(message.toolArgs)
760
- });
761
- break;
762
- case "tool_end":
763
- emit?.({
764
- type: "background_task_tool_end",
765
- toolName: message.toolName,
766
- success: message.success
767
- });
768
- break;
769
- default:
770
- rejectOnce(new BackgroundTaskError2("runner", "Unhandled subagent worker message"));
771
- }
772
- }
773
- function extractFirstArg(toolArgs) {
774
- if (!toolArgs) return void 0;
775
- const firstValue = Object.values(toolArgs)[0];
776
- if (firstValue === void 0) return void 0;
777
- return typeof firstValue === "object" ? JSON.stringify(firstValue) : String(firstValue);
778
- }
779
- function sendWorkerMessage(child, message) {
780
- return new Promise((resolve3, reject) => {
781
- if (!child.connected) {
782
- reject(new BackgroundTaskError2("crash", "Subagent worker IPC channel is closed"));
783
- return;
784
- }
785
- child.send(message, (error) => {
786
- if (error) {
787
- reject(error);
788
- return;
789
- }
790
- resolve3();
791
- });
792
- });
793
- }
794
- async function cancelChildProcess(runtime, reason) {
795
- if (runtime.child.connected) {
796
- await sendWorkerMessage(runtime.child, { type: "cancel", reason }).catch(() => void 0);
797
- }
798
- runtime.killTimer = setTimeout(() => {
799
- if (!runtime.child.killed) {
800
- runtime.child.kill("SIGTERM");
801
- }
802
- }, runtime.killGraceMs);
803
- }
804
-
805
- // src/subagents/child-process-subagent-runner-result.ts
806
- function createChildProcessSubagentResult(options) {
807
- return new Promise((resolve3, reject) => {
808
- new ChildProcessSubagentResultController(options, resolve3, reject).start();
809
- });
810
- }
811
- var ChildProcessSubagentResultController = class {
812
- constructor(options, resolve3, reject) {
813
- this.options = options;
814
- this.resolve = resolve3;
815
- this.reject = reject;
816
- this.timeoutTimer = createTimeoutTimer(this.options.runtime, (error) => this.rejectOnce(error));
817
- }
818
- settled = false;
819
- started = false;
820
- timeoutTimer;
821
- start() {
822
- const { child } = this.options.runtime;
823
- child.on("message", this.onMessage);
824
- child.on("error", this.onError);
825
- child.on("exit", this.onExit);
826
- child.once("spawn", () => {
827
- setImmediate(this.startWorker);
828
- });
829
- }
830
- startWorker = () => {
831
- if (this.started) return;
832
- this.started = true;
833
- const { child } = this.options.runtime;
834
- void sendWorkerMessage(child, { type: "start", payload: this.options.payload }).catch(
835
- (error) => {
836
- this.rejectOnce(error instanceof Error ? error : new Error(String(error)));
837
- }
838
- );
839
- };
840
- onMessage = (message) => {
841
- if (!isSubagentWorkerChildMessage(message)) {
842
- this.rejectOnce(
843
- new BackgroundTaskError3("runner", "Received malformed subagent worker message")
844
- );
845
- return;
846
- }
847
- const { job } = this.options.runtime;
848
- handleWorkerMessage(message, this.startWorker, this.resolveOnce, this.rejectOnce, job.emit);
849
- };
850
- onError = (error) => {
851
- this.rejectOnce(new BackgroundTaskError3("crash", error.message));
852
- };
853
- onExit = (code, signal) => {
854
- if (this.settled) return;
855
- this.rejectOnce(new BackgroundTaskError3("crash", formatEarlyExitMessage(code, signal)));
856
- };
857
- resolveOnce = (output) => {
858
- if (this.settled) return;
859
- this.settled = true;
860
- this.clearTimers();
861
- this.cleanup();
862
- const { runtime, resolveTranscriptPath } = this.options;
863
- this.resolve(toSubagentResult(runtime.job, output, resolveTranscriptPath));
864
- };
865
- rejectOnce = (error) => {
866
- if (this.settled) return;
867
- this.settled = true;
868
- this.clearTimers();
869
- this.cleanup();
870
- this.reject(error);
871
- };
872
- clearTimers() {
873
- if (this.timeoutTimer) clearTimeout(this.timeoutTimer);
874
- if (this.options.runtime.killTimer) clearTimeout(this.options.runtime.killTimer);
875
- }
876
- cleanup() {
877
- const { child } = this.options.runtime;
878
- child.off("message", this.onMessage);
879
- child.off("error", this.onError);
880
- child.off("exit", this.onExit);
881
- }
882
- };
883
- function createCancellationResult(jobId) {
884
- let settled = false;
885
- let rejectFn = () => {
886
- };
887
- const promise = new Promise((_resolve, reject) => {
888
- rejectFn = reject;
889
- });
890
- return {
891
- promise,
892
- reject(reason) {
893
- if (settled) return;
894
- settled = true;
895
- rejectFn(new BackgroundTaskError3("runner", reason ?? `Subagent job cancelled: ${jobId}`));
896
- }
897
- };
898
- }
899
- function createTimeoutTimer(runtime, rejectOnce) {
900
- if (!runtime.job.request.timeoutMs) return void 0;
901
- return setTimeout(() => {
902
- void cancelChildProcess(runtime, "Subagent worker timed out");
903
- rejectOnce(new BackgroundTaskError3("timeout", "Subagent worker timed out"));
904
- }, runtime.job.request.timeoutMs);
905
- }
906
- function toSubagentResult(job, output, resolveTranscriptPath) {
907
- const transcriptPath = resolveTranscriptPath(job);
908
- return {
909
- jobId: job.jobId,
910
- output,
911
- ...transcriptPath ? { metadata: { transcriptPath, logPath: transcriptPath } } : {}
912
- };
913
- }
914
- function formatEarlyExitMessage(code, signal) {
915
- const detail = signal !== null ? `signal ${signal}` : `exit code ${code === null ? "unknown" : code}`;
916
- return `Subagent worker exited before result: ${detail}`;
917
- }
918
-
919
- // src/subagents/git-worktree-isolation-adapter.ts
920
- import { execFileSync } from "child_process";
921
- import { randomUUID } from "crypto";
922
- import { mkdirSync as mkdirSync2 } from "fs";
923
- import { join as join3 } from "path";
924
- import {
925
- BackgroundTaskError as BackgroundTaskError4
926
- } from "@robota-sdk/agent-sdk";
927
- var WORKTREE_DIR = ".robota/worktrees";
928
- var BRANCH_PREFIX = "robota";
929
- var GIT_ENCODING = "utf8";
930
- var SHORT_ID_LENGTH = 8;
931
- var DEFAULT_MAX_CREATE_ATTEMPTS = 5;
932
- var COLLISION_ERROR_PATTERN = /already exists|is already checked out|missing but already registered/i;
933
- function createGitWorktreeIsolationAdapter(options) {
934
- return new GitWorktreeIsolationAdapter(options);
935
- }
936
- var GitWorktreeIsolationAdapter = class {
937
- worktreeDir;
938
- branchPrefix;
939
- idFactory;
940
- maxCreateAttempts;
941
- constructor(options = {}) {
942
- this.worktreeDir = options.worktreeDir ?? WORKTREE_DIR;
943
- this.branchPrefix = options.branchPrefix ?? BRANCH_PREFIX;
944
- this.idFactory = options.idFactory ?? createShortId;
945
- this.maxCreateAttempts = options.maxCreateAttempts ?? DEFAULT_MAX_CREATE_ATTEMPTS;
946
- }
947
- prepare(request) {
948
- if (this.maxCreateAttempts < 1) {
949
- throw new BackgroundTaskError4("runner", "Git worktree creation attempts must be at least 1");
950
- }
951
- const repoRoot = resolveRepoRoot(request.cwd);
952
- const baseRevision = runGit(repoRoot, ["rev-parse", "HEAD"]).trim();
953
- const parentStatus = runGit(repoRoot, ["status", "--porcelain"]).trimEnd();
954
- const worktreeRoot = join3(repoRoot, this.worktreeDir);
955
- mkdirSync2(worktreeRoot, { recursive: true });
956
- let lastError;
957
- for (let attempt = 0; attempt < this.maxCreateAttempts; attempt += 1) {
958
- const shortId = normalizeShortId(this.idFactory());
959
- const jobId = sanitizePathSegment(request.jobId);
960
- const branchName = `${this.branchPrefix}/${jobId}-${shortId}`;
961
- const worktreePath = join3(worktreeRoot, `${jobId}-${shortId}`);
962
- try {
963
- runGit(repoRoot, ["worktree", "add", "-b", branchName, worktreePath, "HEAD"]);
964
- return { repoRoot, worktreePath, branchName, baseRevision, parentStatus };
965
- } catch (error) {
966
- lastError = toError(error);
967
- if (!isCollisionError(lastError)) throw lastError;
968
- }
969
- }
970
- throw new BackgroundTaskError4(
971
- "runner",
972
- `Unable to create Git worktree after ${this.maxCreateAttempts} attempts due to branch or path collisions. Last error: ${lastError?.message ?? "unknown error"}`
973
- );
974
- }
975
- isClean(worktree) {
976
- return this.getStatus(worktree).trim().length === 0;
977
- }
978
- getStatus(worktree) {
979
- return runGit(worktree.worktreePath, ["status", "--porcelain"]);
980
- }
981
- remove(worktree) {
982
- runGit(worktree.repoRoot, ["worktree", "remove", "--force", worktree.worktreePath]);
983
- runGit(worktree.repoRoot, ["branch", "-D", worktree.branchName]);
984
- }
985
- };
986
- function runGit(cwd, args) {
987
- try {
988
- return execFileSync("git", args, {
989
- cwd,
990
- encoding: GIT_ENCODING,
991
- stdio: ["ignore", "pipe", "pipe"],
992
- env: createGitEnvironment()
993
- });
994
- } catch (error) {
995
- const message = error instanceof Error ? error.message : String(error);
996
- throw new BackgroundTaskError4("runner", `git ${args.join(" ")} failed: ${message}`);
997
- }
998
- }
999
- function createGitEnvironment() {
1000
- const env = { ...process.env };
1001
- for (const key of Object.keys(env)) {
1002
- if (key.startsWith("GIT_")) {
1003
- delete env[key];
1004
- }
1005
- }
1006
- return env;
1007
- }
1008
- function resolveRepoRoot(cwd) {
1009
- try {
1010
- return runGit(cwd, ["rev-parse", "--show-toplevel"]).trim();
1011
- } catch (error) {
1012
- const message = error instanceof Error ? error.message : String(error);
1013
- throw new BackgroundTaskError4(
1014
- "runner",
1015
- `Worktree isolation requires a Git repository. Run from a Git worktree or request isolation "none". Details: ${message}`
1016
- );
1017
- }
1018
- }
1019
- function createShortId() {
1020
- return randomUUID().slice(0, SHORT_ID_LENGTH);
1021
- }
1022
- function normalizeShortId(value) {
1023
- const sanitized = sanitizePathSegment(value).slice(0, SHORT_ID_LENGTH);
1024
- return sanitized.length > 0 ? sanitized : createShortId();
1025
- }
1026
- function sanitizePathSegment(value) {
1027
- const sanitized = value.replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
1028
- return sanitized.length > 0 ? sanitized : "agent";
1029
- }
1030
- function toError(error) {
1031
- return error instanceof Error ? error : new Error(String(error));
1032
- }
1033
- function isCollisionError(error) {
1034
- return COLLISION_ERROR_PATTERN.test(error.message);
1035
- }
1036
-
1037
- // src/subagents/child-process-subagent-runner.ts
1038
- var DEFAULT_KILL_GRACE_MS2 = 2e3;
1039
- function createChildProcessSubagentRunnerFactory(options = {}) {
1040
- return (deps) => {
1041
- const runner = new ChildProcessSubagentRunner(deps, options);
1042
- if (options.worktreeIsolation === false) return runner;
1043
- return createWorktreeSubagentRunner({
1044
- runner,
1045
- worktreeAdapter: options.worktreeAdapter ?? createGitWorktreeIsolationAdapter(),
1046
- hooks: deps.config.hooks,
1047
- hookTypeExecutors: deps.hookTypeExecutors
1048
- });
1049
- };
1050
- }
1051
- var ChildProcessSubagentRunner = class {
1052
- constructor(deps, options = {}) {
1053
- this.deps = deps;
1054
- this.workerPath = options.workerPath ?? resolveDefaultWorkerPath();
1055
- this.execArgv = options.execArgv;
1056
- this.killGraceMs = options.killGraceMs ?? DEFAULT_KILL_GRACE_MS2;
1057
- this.providerConfig = options.providerConfig;
1058
- this.env = options.env;
1059
- this.logsDir = options.logsDir;
1060
- }
1061
- workerPath;
1062
- execArgv;
1063
- killGraceMs;
1064
- providerConfig;
1065
- env;
1066
- logsDir;
1067
- start(job) {
1068
- const child = fork(this.workerPath, [], {
1069
- cwd: job.request.cwd,
1070
- env: { ...process.env, ...this.env ?? {} },
1071
- execArgv: this.execArgv ?? resolveDefaultExecArgv(this.workerPath),
1072
- stdio: ["ignore", "ignore", "ignore", "ipc"]
1073
- });
1074
- const runtime = {
1075
- job,
1076
- child,
1077
- killGraceMs: this.killGraceMs
1078
- };
1079
- const payload = this.createStartPayload(job);
1080
- const workerResult = createChildProcessSubagentResult({
1081
- runtime,
1082
- payload,
1083
- resolveTranscriptPath: (request) => this.resolveTranscriptPath(request)
1084
- });
1085
- const cancellation = createCancellationResult(job.jobId);
1086
- void workerResult.catch(() => void 0);
1087
- const result = Promise.race([workerResult, cancellation.promise]);
1088
- const transcriptPath = this.resolveTranscriptPath(job);
1089
- return {
1090
- jobId: job.jobId,
1091
- ...child.pid !== void 0 && { pid: child.pid },
1092
- ...transcriptPath !== void 0 && { transcriptPath, logPath: transcriptPath },
1093
- result,
1094
- cancel: async (reason) => {
1095
- cancellation.reject(reason);
1096
- await cancelChildProcess(runtime, reason);
1097
- },
1098
- send: async (prompt) => {
1099
- await sendWorkerMessage(child, { type: "send", prompt });
1100
- },
1101
- ...transcriptPath !== void 0 && {
1102
- readLog: async (cursor) => readTranscriptLog(job.jobId, transcriptPath, cursor)
1103
- }
1104
- };
1105
- }
1106
- createStartPayload(job) {
1107
- const definition = resolveAgentDefinition(job.request.type, this.deps.customAgentRegistry);
1108
- return {
1109
- jobId: job.jobId,
1110
- request: job.request,
1111
- agentDefinition: applyRequestOverrides(definition, job),
1112
- parentConfig: this.deps.config,
1113
- parentContext: this.deps.context,
1114
- providerProfile: createProviderProfile(this.providerConfig, this.deps, job),
1115
- permissionMode: this.deps.permissionMode,
1116
- ...this.logsDir ? { logsDir: this.logsDir } : {}
1117
- };
1118
- }
1119
- resolveTranscriptPath(job) {
1120
- if (!this.logsDir) return void 0;
1121
- return join4(this.logsDir, job.request.parentSessionId, "subagents", `${job.jobId}.jsonl`);
1122
- }
1123
- };
1124
- function resolveAgentDefinition(agentType, customRegistry) {
1125
- const definition = customRegistry?.(agentType) ?? getBuiltInAgent(agentType);
1126
- if (!definition) {
1127
- throw new BackgroundTaskError5("validation", `Unknown agent type: ${agentType}`);
1128
- }
1129
- return definition;
1130
- }
1131
- function applyRequestOverrides(definition, job) {
1132
- return {
1133
- ...definition,
1134
- ...job.request.model ? { model: job.request.model } : {},
1135
- ...job.request.allowedTools ? { tools: job.request.allowedTools } : {},
1136
- ...job.request.disallowedTools ? { disallowedTools: job.request.disallowedTools } : {}
1137
- };
1138
- }
1139
- function createProviderProfile(providerConfig, deps, job) {
1140
- const provider = providerConfig ?? deps.config.provider;
1141
- return {
1142
- profileName: deps.config.currentProvider,
1143
- type: provider.name,
1144
- model: job.request.model ?? provider.model,
1145
- apiKey: provider.apiKey,
1146
- baseURL: provider.baseURL,
1147
- timeout: provider.timeout,
1148
- options: provider.options
1149
- };
1150
- }
1151
- function resolveDefaultWorkerPath() {
1152
- const entryPoint = process.argv[1] ?? "";
1153
- const entryDir = entryPoint ? dirname2(entryPoint) : process.cwd();
1154
- const extension = entryPoint.endsWith(".ts") || entryPoint.endsWith(".tsx") ? ".ts" : ".js";
1155
- const candidates = [
1156
- join4(entryDir, "subagents", `child-process-subagent-worker${extension}`),
1157
- join4(entryDir, `child-process-subagent-worker${extension}`)
1158
- ];
1159
- for (const candidate of candidates) {
1160
- if (existsSync3(candidate)) {
1161
- return candidate;
1162
- }
1163
- }
1164
- return candidates[0];
1165
- }
1166
- function resolveDefaultExecArgv(workerPath) {
1167
- if (!workerPath.endsWith(".ts")) {
1168
- return process.execArgv;
1169
- }
1170
- if (process.execArgv.some((arg) => arg.includes("tsx"))) {
1171
- return process.execArgv;
1172
- }
1173
- return [...process.execArgv, "--import", "tsx"];
1174
- }
1175
- function readTranscriptLog(jobId, transcriptPath, cursor) {
1176
- if (!existsSync3(transcriptPath)) {
1177
- return {
1178
- taskId: jobId,
1179
- cursor,
1180
- lines: []
1181
- };
1182
- }
1183
- const lines = readFileSync3(transcriptPath, "utf8").split(/\r?\n/).filter(Boolean);
1184
- return createBackgroundTaskLogPage2(jobId, lines, cursor);
1185
- }
1186
-
1187
- // src/utils/update-check.ts
1188
- import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
1189
- import { dirname as dirname3, join as join5 } from "path";
1190
-
1191
- // src/utils/semver-compare.ts
1192
- function compareSemverVersions(left, right) {
1193
- const parsedLeft = parseSemver(left);
1194
- const parsedRight = parseSemver(right);
1195
- if (parsedLeft === void 0 || parsedRight === void 0) {
1196
- return Math.sign(left.localeCompare(right));
1197
- }
1198
- const coreCompare = compareNumber(parsedLeft.major, parsedRight.major) || compareNumber(parsedLeft.minor, parsedRight.minor) || compareNumber(parsedLeft.patch, parsedRight.patch);
1199
- if (coreCompare !== 0) {
1200
- return coreCompare;
1201
- }
1202
- return comparePrerelease(parsedLeft.prerelease, parsedRight.prerelease);
1203
- }
1204
- function isNewerSemverVersion(candidate, current) {
1205
- return compareSemverVersions(candidate, current) > 0;
1206
- }
1207
- function parseSemver(value) {
1208
- const normalized = value.trim().replace(/^v/, "").split("+")[0] ?? "";
1209
- const [core, prereleaseText] = normalized.split("-", 2);
1210
- const [majorText, minorText, patchText] = core.split(".");
1211
- const major = parseNumericIdentifier(majorText);
1212
- const minor = parseNumericIdentifier(minorText);
1213
- const patch = parseNumericIdentifier(patchText);
1214
- if (major === void 0 || minor === void 0 || patch === void 0) {
1215
- return void 0;
1216
- }
1217
- return {
1218
- major,
1219
- minor,
1220
- patch,
1221
- prerelease: prereleaseText ? prereleaseText.split(".") : []
1222
- };
1223
- }
1224
- function parseNumericIdentifier(value) {
1225
- if (value === void 0 || !/^\d+$/.test(value)) {
1226
- return void 0;
1227
- }
1228
- return Number(value);
1229
- }
1230
- function compareNumber(left, right) {
1231
- return Math.sign(left - right);
1232
- }
1233
- function comparePrerelease(left, right) {
1234
- if (left.length === 0 && right.length === 0) {
1235
- return 0;
1236
- }
1237
- if (left.length === 0) {
1238
- return 1;
1239
- }
1240
- if (right.length === 0) {
1241
- return -1;
1242
- }
1243
- const max = Math.max(left.length, right.length);
1244
- for (let index = 0; index < max; index += 1) {
1245
- const leftPart = left[index];
1246
- const rightPart = right[index];
1247
- if (leftPart === void 0) {
1248
- return -1;
1249
- }
1250
- if (rightPart === void 0) {
1251
- return 1;
1252
- }
1253
- const partCompare = comparePrereleaseIdentifier(leftPart, rightPart);
1254
- if (partCompare !== 0) {
1255
- return partCompare;
1256
- }
1257
- }
1258
- return 0;
1259
- }
1260
- function comparePrereleaseIdentifier(left, right) {
1261
- const leftNumber = parseNumericIdentifier(left);
1262
- const rightNumber = parseNumericIdentifier(right);
1263
- if (leftNumber !== void 0 && rightNumber !== void 0) {
1264
- return compareNumber(leftNumber, rightNumber);
1265
- }
1266
- if (leftNumber !== void 0) {
1267
- return -1;
1268
- }
1269
- if (rightNumber !== void 0) {
1270
- return 1;
1271
- }
1272
- return Math.sign(left.localeCompare(right));
1273
- }
1274
-
1275
- // src/utils/update-check.ts
1276
- var CLI_UPDATE_PACKAGE_NAME = "@robota-sdk/agent-cli";
1277
- var CLI_UPDATE_REGISTRY_URL = "https://registry.npmjs.org";
1278
- var HOURS_PER_DAY = 24;
1279
- var MINUTES_PER_HOUR = 60;
1280
- var SECONDS_PER_MINUTE = 60;
1281
- var MS_PER_SECOND = 1e3;
1282
- var CLI_UPDATE_CACHE_TTL_MS = HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MS_PER_SECOND;
1283
- var CLI_UPDATE_TIMEOUT_MS = 1500;
1284
- var DEFAULT_INSTALL_COMMAND = "npm install -g '@robota-sdk/agent-cli@latest'";
1285
- function getUserUpdateCheckCachePath(home = process.env.HOME ?? process.env.USERPROFILE ?? "/") {
1286
- return join5(home, ".robota", "update-check.json");
1287
- }
1288
- function readUpdateCheckCache(path) {
1289
- if (!existsSync4(path)) {
1290
- return void 0;
1291
- }
1292
- try {
1293
- const parsed = JSON.parse(readFileSync4(path, "utf8"));
1294
- return parseUpdateCheckCache(parsed);
1295
- } catch {
1296
- return void 0;
1297
- }
1298
- }
1299
- function writeUpdateCheckCache(path, cache) {
1300
- mkdirSync3(dirname3(path), { recursive: true });
1301
- writeFileSync2(path, JSON.stringify(cache, null, 2) + "\n", "utf8");
1302
- }
1303
- async function checkForCliUpdate(options) {
1304
- if (options.disabled === true) {
1305
- return { status: "skipped", reason: "disabled" };
1306
- }
1307
- const packageName = options.packageName ?? CLI_UPDATE_PACKAGE_NAME;
1308
- const cachePath = options.cachePath ?? getUserUpdateCheckCachePath();
1309
- const now = options.now ?? /* @__PURE__ */ new Date();
1310
- const ttlMs = options.ttlMs ?? CLI_UPDATE_CACHE_TTL_MS;
1311
- if (options.force !== true) {
1312
- const cached = readUpdateCheckCache(cachePath);
1313
- if (cached !== void 0 && isFreshCache(cached, now, ttlMs, packageName)) {
1314
- return resultFromCache(cached, options.currentVersion);
1315
- }
1316
- }
1317
- try {
1318
- const latestVersion = await fetchLatestVersion({
1319
- fetchImpl: options.fetchImpl ?? fetch,
1320
- packageName,
1321
- registryUrl: options.registryUrl ?? CLI_UPDATE_REGISTRY_URL,
1322
- timeoutMs: options.timeoutMs ?? CLI_UPDATE_TIMEOUT_MS
1323
- });
1324
- tryWriteUpdateCheckCache(cachePath, {
1325
- packageName,
1326
- checkedAt: now.toISOString(),
1327
- currentVersion: options.currentVersion,
1328
- latestVersion
1329
- });
1330
- return resultFromLatestVersion(options.currentVersion, latestVersion);
1331
- } catch (error) {
1332
- const errorMessage = error instanceof Error ? error.message : String(error);
1333
- tryWriteUpdateCheckCache(cachePath, {
1334
- packageName,
1335
- checkedAt: now.toISOString(),
1336
- currentVersion: options.currentVersion,
1337
- errorMessage
1338
- });
1339
- return { status: "error", errorMessage };
1340
- }
1341
- }
1342
- function tryWriteUpdateCheckCache(path, cache) {
1343
- try {
1344
- writeUpdateCheckCache(path, cache);
1345
- } catch {
1346
- }
1347
- }
1348
- async function getStartupCliUpdateNotice(options) {
1349
- const result = await checkForCliUpdate(options);
1350
- return result.status === "update_available" ? result.notice : void 0;
1351
- }
1352
- function shouldRunStartupCliUpdateCheck(input) {
1353
- return input.printMode === false && input.disableUpdateCheck === false;
1354
- }
1355
- function formatCliUpdateNotice(notice) {
1356
- return [
1357
- `Robota update available: ${notice.currentVersion} -> ${notice.latestVersion}.`,
1358
- `Run ${notice.installCommand}`
1359
- ].join(" ");
1360
- }
1361
- function formatCliUpdateCheckMessage(result) {
1362
- if (result.status === "update_available") {
1363
- return formatCliUpdateNotice(result.notice);
1364
- }
1365
- if (result.status === "current") {
1366
- return `Robota is up to date (${result.currentVersion}).`;
1367
- }
1368
- if (result.status === "skipped") {
1369
- return "Robota update check skipped.";
1370
- }
1371
- return `Robota update check failed: ${result.errorMessage}`;
1372
- }
1373
- function resultFromCache(cache, currentVersion) {
1374
- if (cache.errorMessage !== void 0) {
1375
- return { status: "error", errorMessage: cache.errorMessage };
1376
- }
1377
- if (cache.latestVersion === void 0) {
1378
- return { status: "error", errorMessage: "Cached update check has no latest version" };
1379
- }
1380
- return resultFromLatestVersion(currentVersion, cache.latestVersion);
1381
- }
1382
- function resultFromLatestVersion(currentVersion, latestVersion) {
1383
- if (isNewerSemverVersion(latestVersion, currentVersion)) {
1384
- return {
1385
- status: "update_available",
1386
- notice: {
1387
- currentVersion,
1388
- latestVersion,
1389
- installCommand: DEFAULT_INSTALL_COMMAND
1390
- }
1391
- };
1392
- }
1393
- return { status: "current", currentVersion, latestVersion };
1394
- }
1395
- function isFreshCache(cache, now, ttlMs, packageName) {
1396
- if (cache.packageName !== packageName) {
1397
- return false;
1398
- }
1399
- const checkedAt = Date.parse(cache.checkedAt);
1400
- if (!Number.isFinite(checkedAt)) {
1401
- return false;
1402
- }
1403
- return now.getTime() - checkedAt < ttlMs;
1404
- }
1405
- async function fetchLatestVersion(options) {
1406
- const controller = new AbortController();
1407
- const timeout = setTimeout(() => controller.abort(), options.timeoutMs);
1408
- try {
1409
- const packageUrl = buildPackageMetadataUrl(options.registryUrl, options.packageName);
1410
- const response = await options.fetchImpl(packageUrl, {
1411
- headers: { accept: "application/json" },
1412
- signal: controller.signal
1413
- });
1414
- if (!response.ok) {
1415
- throw new Error(`registry responded with HTTP ${response.status}`);
1416
- }
1417
- const metadata = await response.json();
1418
- const latest = metadata["dist-tags"]?.latest;
1419
- if (typeof latest !== "string" || latest.trim().length === 0) {
1420
- throw new Error("registry metadata is missing dist-tags.latest");
1421
- }
1422
- return latest;
1423
- } finally {
1424
- clearTimeout(timeout);
1425
- }
1426
- }
1427
- function buildPackageMetadataUrl(registryUrl, packageName) {
1428
- return `${registryUrl.replace(/\/+$/, "")}/${encodeURIComponent(packageName)}`;
1429
- }
1430
- function parseUpdateCheckCache(value) {
1431
- if (!isJsonObject(value)) {
1432
- return void 0;
1433
- }
1434
- const candidate = value;
1435
- if (typeof candidate.packageName === "string" && typeof candidate.checkedAt === "string" && typeof candidate.currentVersion === "string" && (candidate.latestVersion === void 0 || typeof candidate.latestVersion === "string") && (candidate.errorMessage === void 0 || typeof candidate.errorMessage === "string")) {
1436
- return {
1437
- packageName: candidate.packageName,
1438
- checkedAt: candidate.checkedAt,
1439
- currentVersion: candidate.currentVersion,
1440
- ...candidate.latestVersion !== void 0 && { latestVersion: candidate.latestVersion },
1441
- ...candidate.errorMessage !== void 0 && { errorMessage: candidate.errorMessage }
1442
- };
1443
- }
1444
- return void 0;
1445
- }
1446
- function isJsonObject(value) {
1447
- return value !== null && typeof value === "object" && !Array.isArray(value);
1448
- }
1449
-
1450
- // src/utils/statusline-settings.ts
1451
- import { DEFAULT_STATUS_LINE_COMMAND_SETTINGS } from "@robota-sdk/agent-sdk";
1452
- var DEFAULT_STATUS_LINE_SETTINGS = {
1453
- ...DEFAULT_STATUS_LINE_COMMAND_SETTINGS
1454
- };
1455
- function readStatusLineSettings(settings) {
1456
- const raw = settings.statusline;
1457
- if (!isRecord(raw)) {
1458
- return { ...DEFAULT_STATUS_LINE_SETTINGS };
1459
- }
1460
- return {
1461
- enabled: typeof raw.enabled === "boolean" ? raw.enabled : DEFAULT_STATUS_LINE_SETTINGS.enabled,
1462
- gitBranch: typeof raw.gitBranch === "boolean" ? raw.gitBranch : DEFAULT_STATUS_LINE_SETTINGS.gitBranch
1463
- };
1464
- }
1465
- function applyStatusLineSettings(settingsPath, patch) {
1466
- const settings = readSettings(settingsPath);
1467
- const next = {
1468
- ...readStatusLineSettings(settings),
1469
- ...patch
1470
- };
1471
- settings.statusline = next;
1472
- writeSettings(settingsPath, settings);
1473
- return next;
1474
- }
1475
- function isRecord(value) {
1476
- return value !== null && typeof value === "object" && !Array.isArray(value) && !(value instanceof Date);
1477
- }
1478
-
1479
- // src/utils/git-branch.ts
1480
- import { existsSync as existsSync5, lstatSync, readFileSync as readFileSync5 } from "fs";
1481
- import { dirname as dirname4, isAbsolute, join as join6, resolve } from "path";
1482
- var DETACHED_HEAD_LENGTH = 7;
1483
- function resolveGitBranch(cwd) {
1484
- try {
1485
- const gitDir = findGitDir(cwd);
1486
- if (!gitDir) return void 0;
1487
- const head = readFileSync5(join6(gitDir, "HEAD"), "utf8").trim();
1488
- if (!head) return void 0;
1489
- if (head.startsWith("ref: ")) {
1490
- const ref = head.slice("ref: ".length).trim();
1491
- const branchPrefix = "refs/heads/";
1492
- return ref.startsWith(branchPrefix) ? ref.slice(branchPrefix.length) : ref;
1493
- }
1494
- return head.slice(0, DETACHED_HEAD_LENGTH);
1495
- } catch {
1496
- return void 0;
1497
- }
1498
- }
1499
- function findGitDir(start) {
1500
- let current = resolve(start);
1501
- let parent = dirname4(current);
1502
- while (parent !== current) {
1503
- const candidate = join6(current, ".git");
1504
- const resolved = resolveGitMetadata(candidate, current);
1505
- if (resolved) return resolved;
1506
- current = parent;
1507
- parent = dirname4(current);
1508
- }
1509
- const rootCandidate = join6(current, ".git");
1510
- return resolveGitMetadata(rootCandidate, current);
1511
- }
1512
- function resolveGitMetadata(candidate, repoDir) {
1513
- if (!existsSync5(candidate)) return void 0;
1514
- const stat = lstatSync(candidate);
1515
- if (stat.isDirectory()) return candidate;
1516
- if (!stat.isFile()) return void 0;
1517
- const content = readFileSync5(candidate, "utf8").trim();
1518
- const prefix = "gitdir:";
1519
- if (!content.startsWith(prefix)) return void 0;
1520
- const rawPath = content.slice(prefix.length).trim();
1521
- return isAbsolute(rawPath) ? rawPath : resolve(repoDir, rawPath);
1522
- }
1523
-
1524
- // src/plugins/plugin-command-source-loader.ts
1525
- import { homedir } from "os";
1526
- import { join as join7 } from "path";
1527
- import { BundlePluginLoader, PluginCommandSource } from "@robota-sdk/agent-sdk";
1528
- var PLUGIN_SOURCE_NAME = "plugin";
1529
- function getHomeDir() {
1530
- return process.env.HOME ?? homedir();
1531
- }
1532
- function reloadPluginCommandSource(registry) {
1533
- const pluginsDir = join7(getHomeDir(), ".robota", "plugins");
1534
- const loader = new BundlePluginLoader(pluginsDir);
1535
- try {
1536
- const plugins = loader.loadPluginsSync();
1537
- if (plugins.length === 0) {
1538
- registry.replaceSource(PLUGIN_SOURCE_NAME);
1539
- return 0;
1540
- }
1541
- registry.replaceSource(PLUGIN_SOURCE_NAME, new PluginCommandSource(plugins));
1542
- return plugins.length;
1543
- } catch {
1544
- registry.replaceSource(PLUGIN_SOURCE_NAME);
1545
- return 0;
1546
- }
1547
- }
1548
-
1549
- // src/plugins/plugin-command-adapter.ts
1550
- import { homedir as homedir2 } from "os";
1551
- import { join as join8 } from "path";
1552
- import {
1553
- BundlePluginInstaller,
1554
- BundlePluginLoader as BundlePluginLoader2,
1555
- MarketplaceClient,
1556
- PluginSettingsStore
1557
- } from "@robota-sdk/agent-sdk";
1558
- function createCliPluginServices(cwd) {
1559
- const home = homedir2();
1560
- const pluginsDir = join8(home, ".robota", "plugins");
1561
- const userSettingsPath = join8(home, ".robota", "settings.json");
1562
- const settingsStore = new PluginSettingsStore(userSettingsPath);
1563
- const marketplace = new MarketplaceClient({ pluginsDir });
1564
- const installer = new BundlePluginInstaller({
1565
- pluginsDir,
1566
- settingsStore,
1567
- marketplaceClient: marketplace
1568
- });
1569
- const loader = new BundlePluginLoader2(pluginsDir);
1570
- return {
1571
- cwd,
1572
- marketplace,
1573
- installer,
1574
- loader,
1575
- settingsStore
1576
- };
1577
- }
1578
- async function listInstalledPlugins(services) {
1579
- const plugins = await services.loader.loadAll();
1580
- const enabledMap = services.settingsStore.getEnabledPlugins();
1581
- return plugins.map((plugin) => {
1582
- const parts = plugin.pluginDir.split("/");
1583
- const cacheIdx = parts.indexOf("cache");
1584
- const marketplaceName = cacheIdx >= 0 ? parts[cacheIdx + 1] ?? "" : "";
1585
- const fullId = marketplaceName ? `${plugin.manifest.name}@${marketplaceName}` : plugin.manifest.name;
1586
- return {
1587
- name: fullId,
1588
- description: plugin.manifest.description,
1589
- enabled: enabledMap[fullId] !== false && enabledMap[plugin.manifest.name] !== false
1590
- };
1591
- });
1592
- }
1593
- async function listAvailablePlugins(services, marketplaceName) {
1594
- let manifest;
1595
- try {
1596
- manifest = services.marketplace.fetchManifest(marketplaceName);
1597
- } catch {
1598
- return [];
1599
- }
1600
- const installed = services.installer.getInstalledPlugins();
1601
- const installedNames = new Set(Object.values(installed).map((record) => record.pluginName));
1602
- return manifest.plugins.map((plugin) => ({
1603
- name: plugin.name,
1604
- description: plugin.description,
1605
- installed: installedNames.has(plugin.name)
1606
- }));
1607
- }
1608
- async function installPlugin(services, pluginId, scope) {
1609
- const [name, marketplaceName] = pluginId.split("@");
1610
- if (!name || !marketplaceName) {
1611
- throw new Error("Plugin ID must be in format: name@marketplace");
1612
- }
1613
- if (scope === "project") {
1614
- const projectPluginsDir = join8(services.cwd, ".robota", "plugins");
1615
- const projectInstaller = new BundlePluginInstaller({
1616
- pluginsDir: projectPluginsDir,
1617
- settingsStore: services.settingsStore,
1618
- marketplaceClient: services.marketplace
1619
- });
1620
- await projectInstaller.install(name, marketplaceName);
1621
- return;
1622
- }
1623
- await services.installer.install(name, marketplaceName);
1624
- }
1625
- async function removeMarketplace(services, name) {
1626
- const installedFromMarketplace = services.installer.getPluginsByMarketplace(name);
1627
- for (const record of installedFromMarketplace) {
1628
- await services.installer.uninstall(`${record.pluginName}@${record.marketplace}`);
1629
- }
1630
- services.marketplace.removeMarketplace(name);
1631
- }
1632
- function listMarketplaces(services) {
1633
- return services.marketplace.listMarketplaces().map((marketplaceEntry) => ({
1634
- name: marketplaceEntry.name,
1635
- type: marketplaceEntry.source.type
1636
- }));
1637
- }
1638
- function createCliPluginCommandAdapter(cwd) {
1639
- const services = createCliPluginServices(cwd);
1640
- return {
1641
- listInstalled: () => listInstalledPlugins(services),
1642
- listAvailablePlugins: (marketplaceName) => listAvailablePlugins(services, marketplaceName),
1643
- install: (pluginId, scope) => installPlugin(services, pluginId, scope),
1644
- uninstall: async (pluginId) => services.installer.uninstall(pluginId),
1645
- enable: async (pluginId) => services.installer.enable(pluginId),
1646
- disable: async (pluginId) => services.installer.disable(pluginId),
1647
- marketplaceAdd: async (source) => {
1648
- if (source.includes("/") && !source.includes(":")) {
1649
- return services.marketplace.addMarketplace({ type: "github", repo: source });
1650
- }
1651
- return services.marketplace.addMarketplace({ type: "git", url: source });
1652
- },
1653
- marketplaceRemove: (name) => removeMarketplace(services, name),
1654
- marketplaceUpdate: async (name) => services.marketplace.updateMarketplace(name),
1655
- marketplaceList: async () => listMarketplaces(services),
1656
- reloadPlugins: async () => ({
1657
- loadedPluginCount: (await services.loader.loadAll()).length
1658
- })
1659
- };
1660
- }
1661
-
1662
- // src/user-local-direct-command.ts
1663
- import { executeUserLocalDirectCommand } from "@robota-sdk/agent-command-user-local";
1664
- async function runUserLocalDirectCommandIfRequested(args, cwd) {
1665
- if (args.positional[0] !== "user-local") {
1666
- return false;
1667
- }
1668
- const result = await executeUserLocalDirectCommand({
1669
- cwd,
1670
- argv: args.positional.slice(1),
1671
- format: args.format,
1672
- summary: args.summary,
1673
- source: args.source
1674
- });
1675
- const output = result.message.endsWith("\n") ? result.message : `${result.message}
1676
- `;
1677
- if (!result.success) {
1678
- process.stderr.write(output);
1679
- process.exit(1);
1680
- }
1681
- process.stdout.write(output);
1682
- return true;
1683
- }
1684
-
1685
- // src/cli.ts
1686
- var PRINTABLE_ASCII_START = 32;
1687
- function readVersion() {
1688
- try {
1689
- const thisFile = fileURLToPath(import.meta.url);
1690
- const dir = dirname5(thisFile);
1691
- const candidates = [join9(dir, "..", "..", "package.json"), join9(dir, "..", "package.json")];
1692
- for (const pkgPath of candidates) {
1693
- try {
1694
- const raw = readFileSync6(pkgPath, "utf-8");
1695
- const pkg = JSON.parse(raw);
1696
- if (pkg.version !== void 0 && pkg.name !== void 0) {
1697
- return pkg.version;
1698
- }
1699
- } catch {
1700
- }
1701
- }
1702
- return "0.0.0";
1703
- } catch {
1704
- return "0.0.0";
1705
- }
1706
- }
1707
- function promptInput(label, masked = false) {
1708
- return new Promise((resolve3, reject) => {
1709
- process.stdout.write(label);
1710
- let input = "";
1711
- const stdin = process.stdin;
1712
- const wasRaw = stdin.isRaw;
1713
- if (!stdin.isTTY) {
1714
- reject(
1715
- new Error(
1716
- "Cannot prompt for input: stdin is not a TTY.\nSet your API key via environment variable instead:\n ANTHROPIC_API_KEY=<key> robota\n OPENAI_API_KEY=<key> robota"
1717
- )
1718
- );
1719
- return;
1720
- }
1721
- stdin.setRawMode(true);
1722
- stdin.resume();
1723
- stdin.setEncoding("utf8");
1724
- const onData = (data) => {
1725
- for (const ch of data) {
1726
- if (ch === "\r" || ch === "\n") {
1727
- stdin.removeListener("data", onData);
1728
- stdin.setRawMode(wasRaw ?? false);
1729
- stdin.pause();
1730
- process.stdout.write("\n");
1731
- resolve3(input.trim());
1732
- return;
1733
- } else if (ch === "\x7F" || ch === "\b") {
1734
- if (input.length > 0) {
1735
- input = input.slice(0, -1);
1736
- process.stdout.write("\b \b");
1737
- }
1738
- } else if (ch === "") {
1739
- stdin.removeListener("data", onData);
1740
- stdin.setRawMode(wasRaw ?? false);
1741
- stdin.pause();
1742
- process.stdout.write("\n");
1743
- process.exit(0);
1744
- } else if (ch.charCodeAt(0) >= PRINTABLE_ASCII_START) {
1745
- input += ch;
1746
- process.stdout.write(masked ? "*" : ch);
1747
- }
1748
- }
1749
- };
1750
- stdin.on("data", onData);
1751
- });
1752
- }
1753
- function readTaskFilePrompt(cwd, taskFile) {
1754
- const taskPath = resolve2(cwd, taskFile);
1755
- const content = readFileSync6(taskPath, "utf8").trim();
1756
- if (content.length === 0) {
1757
- throw new Error(`Task file is empty: ${taskFile}`);
1758
- }
1759
- return `Task file (${taskFile}):
1760
- ${content}`;
1761
- }
1762
- function resetConfig() {
1763
- const userPath = getUserSettingsPath();
1764
- if (deleteSettings(userPath)) {
1765
- process.stdout.write(`Deleted ${userPath}
1766
- `);
1767
- } else {
1768
- process.stdout.write("No user settings found.\n");
1769
- }
1770
- }
1771
- function createDefaultCliCommandModules({
1772
- cwd,
1773
- providerDefinitions
1774
- }) {
1775
- return [
1776
- createSkillsCommandModule({ cwd }),
1777
- createHelpCommandModule(),
1778
- createAgentCommandModule(),
1779
- createModelCommandModule({
1780
- providerDefinitions,
1781
- settings: {
1782
- readMergedSettings: () => readMergedProviderSettings(cwd)
1783
- }
1784
- }),
1785
- createPermissionsCommandModule(),
1786
- createModeCommandModule(),
1787
- createLanguageCommandModule(),
1788
- createBackgroundCommandModule(),
1789
- createMemoryCommandModule(),
1790
- createUserLocalCommandModule(),
1791
- createCompactCommandModule(),
1792
- createContextCommandModule(),
1793
- createExitCommandModule(),
1794
- createSessionCommandModule(),
1795
- createResetCommandModule(),
1796
- createRewindCommandModule(),
1797
- createStatusLineCommandModule(),
1798
- createPluginCommandModule(),
1799
- createSettingsCommandModule(),
1800
- createProviderCommandModule({
1801
- providerDefinitions,
1802
- settings: {
1803
- readMergedSettings: () => readMergedProviderSettings(cwd),
1804
- readTargetSettings: () => readSettings(resolveProviderSettingsWriteTargetPath(cwd)),
1805
- writeTargetSettings: (settings) => writeSettings(resolveProviderSettingsWriteTargetPath(cwd), settings)
1806
- }
1807
- })
1808
- ];
1809
- }
1810
- function buildCommandSetup(cwd, args, options, version) {
1811
- const commandHostAdapters = {
1812
- settings: {
1813
- read: () => readSettings(getUserSettingsPath()),
1814
- write: (settings) => writeSettings(getUserSettingsPath(), settings)
1815
- },
1816
- plugin: createCliPluginCommandAdapter(cwd)
1817
- };
1818
- const providerDefinitions = options.providerDefinitions ?? DEFAULT_PROVIDER_DEFINITIONS;
1819
- const commandModules = [
1820
- ...createDefaultCliCommandModules({ cwd, providerDefinitions }),
1821
- ...options.commandModules ?? []
1822
- ];
1823
- const startupUpdateNoticePromise = shouldRunStartupCliUpdateCheck(args) ? getStartupCliUpdateNotice({ currentVersion: version }) : void 0;
1824
- return { commandHostAdapters, providerDefinitions, commandModules, startupUpdateNoticePromise };
1825
- }
1826
- function buildAppendSystemPrompt(cwd, args) {
1827
- const appendParts = [];
1828
- if (args.appendSystemPrompt) appendParts.push(args.appendSystemPrompt);
1829
- if (args.taskFile) {
1830
- try {
1831
- appendParts.push(readTaskFilePrompt(cwd, args.taskFile));
1832
- } catch (error) {
1833
- process.stderr.write(`${error instanceof Error ? error.message : String(error)}
1834
- `);
1835
- process.exit(1);
1836
- }
1837
- }
1838
- if (args.jsonSchema)
1839
- appendParts.push(
1840
- `Respond with valid JSON only, matching this JSON schema:
1841
- ${args.jsonSchema}`
1842
- );
1843
- return appendParts.length > 0 ? appendParts.join("\n\n") : void 0;
1844
- }
1845
- async function runPrintMode(cwd, args, provider, sessionStore, backgroundTaskRunners, subagentRunnerFactory, commandModules, commandHostAdapters) {
1846
- let prompt = args.positional.join(" ").trim();
1847
- if (!prompt && !process.stdin.isTTY) {
1848
- const chunks = [];
1849
- for await (const chunk of process.stdin) {
1850
- chunks.push(chunk);
1851
- }
1852
- prompt = Buffer.concat(chunks).toString("utf-8").trim();
1853
- }
1854
- if (!prompt) {
1855
- process.stderr.write("Print mode (-p) requires a prompt argument.\n");
1856
- process.exit(1);
1857
- }
1858
- const appendSystemPrompt = buildAppendSystemPrompt(cwd, args);
1859
- if (args.systemPrompt) {
1860
- process.stderr.write("Warning: --system-prompt is not yet functional and will be ignored.\n");
1861
- }
1862
- const session = new InteractiveSession({
1863
- cwd,
1864
- provider,
1865
- permissionMode: args.permissionMode ?? "bypassPermissions",
1866
- maxTurns: args.maxTurns,
1867
- sessionStore: args.noSessionPersistence ? void 0 : sessionStore,
1868
- sessionName: args.sessionName,
1869
- bare: args.bare || void 0,
1870
- allowedTools: args.allowedTools ? args.allowedTools.split(",").map((t) => t.trim()).filter((t) => t.length > 0) : void 0,
1871
- appendSystemPrompt,
1872
- backgroundTaskRunners,
1873
- subagentRunnerFactory,
1874
- commandModules,
1875
- commandHostAdapters
1876
- });
1877
- const transport = createHeadlessTransport({
1878
- outputFormat: args.outputFormat ?? "text",
1879
- prompt
1880
- });
1881
- session.attachTransport(transport);
1882
- await transport.start();
1883
- await session.shutdown({ reason: "prompt_input_exit", message: "Headless transport complete" });
1884
- process.exit(transport.getExitCode());
1885
- }
1886
- async function startCli(options = {}) {
1887
- const args = parseCliArgs();
1888
- const version = readVersion();
1889
- if (args.help) {
1890
- printHelp();
1891
- return;
1892
- }
1893
- if (args.version) {
1894
- process.stdout.write(`robota ${version}
1895
- `);
1896
- return;
1897
- }
1898
- if (args.checkUpdate) {
1899
- const result = await checkForCliUpdate({ currentVersion: version, force: true });
1900
- const message = formatCliUpdateCheckMessage(result);
1901
- if (result.status === "error") {
1902
- process.stderr.write(`${message}
1903
- `);
1904
- process.exit(1);
1905
- }
1906
- process.stdout.write(`${message}
1907
- `);
1908
- return;
1909
- }
1910
- if (args.reset) {
1911
- resetConfig();
1912
- return;
1913
- }
1914
- const cwd = process.cwd();
1915
- if (await runUserLocalDirectCommandIfRequested(args, cwd)) {
1916
- return;
1917
- }
1918
- const { commandHostAdapters, providerDefinitions, commandModules, startupUpdateNoticePromise } = buildCommandSetup(cwd, args, options, version);
1919
- if (args.configure) {
1920
- await runInteractiveProviderSetup(cwd, args, promptInput, providerDefinitions);
1921
- return;
1922
- }
1923
- if (handleProviderConfigurationArgs(cwd, args, providerDefinitions)) {
1924
- return;
1925
- }
1926
- try {
1927
- await ensureConfig(cwd, args, promptInput, providerDefinitions);
1928
- } catch (error) {
1929
- process.stderr.write(`${error instanceof Error ? error.message : String(error)}
1930
- `);
1931
- process.exit(1);
1932
- }
1933
- const providerOptions = args.provider ? { providerOverride: args.provider, providerDefinitions } : { providerDefinitions };
1934
- const activeProviderSettings = readMergedProviderSettings(cwd);
1935
- const providerProfileName = args.provider ?? activeProviderSettings.currentProvider;
1936
- const providerSettings = readProviderSettings(cwd, providerOptions);
1937
- const modelId = args.model ?? providerSettings.model;
1938
- const provider = createProviderFromSettings(cwd, args.model, providerOptions);
1939
- const backgroundTaskRunners = [createManagedShellProcessRunner()];
1940
- const paths = projectPaths(cwd);
1941
- const subagentRunnerFactory = createChildProcessSubagentRunnerFactory({
1942
- providerConfig: { ...providerSettings, model: modelId },
1943
- logsDir: paths.logs
1944
- });
1945
- const sessionStore = createProjectSessionStore(cwd);
1946
- let resumeSessionId;
1947
- let showSessionPickerOnStart = false;
1948
- if (args.continueMode) {
1949
- resumeSessionId = resolveLatestSessionId(sessionStore, cwd);
1950
- } else if (args.resumeId !== void 0) {
1951
- if (args.resumeId === "") {
1952
- showSessionPickerOnStart = true;
1953
- } else {
1954
- resumeSessionId = resolveSessionIdByIdOrName(sessionStore, args.resumeId);
1955
- if (resumeSessionId === void 0) {
1956
- process.stderr.write(`Session not found: ${args.resumeId}
1957
- `);
1958
- process.exit(1);
1959
- }
1960
- }
1961
- }
1962
- if (args.printMode) {
1963
- await runPrintMode(
1964
- cwd,
1965
- args,
1966
- provider,
1967
- sessionStore,
1968
- backgroundTaskRunners,
1969
- subagentRunnerFactory,
1970
- commandModules,
1971
- commandHostAdapters
1972
- );
1973
- return;
1974
- }
1975
- const tuiTransport = new TuiTransport({
1976
- cwd,
1977
- provider,
1978
- providerOverride: args.provider,
1979
- providerProfileName,
1980
- providerType: providerSettings.name,
1981
- modelId,
1982
- language: args.language,
1983
- permissionMode: args.permissionMode,
1984
- maxTurns: args.maxTurns,
1985
- version,
1986
- sessionStore: args.noSessionPersistence ? void 0 : sessionStore,
1987
- resumeSessionId,
1988
- showSessionPickerOnStart,
1989
- forkSession: args.forkSession,
1990
- sessionName: args.sessionName,
1991
- backgroundTaskRunners,
1992
- subagentRunnerFactory,
1993
- commandModules,
1994
- commandHostAdapters,
1995
- startupUpdateNotice: startupUpdateNoticePromise ? startupUpdateNoticePromise.then((n) => n ? formatCliUpdateNotice(n) : void 0) : void 0,
1996
- transportRegistry: createTransportRegistry(),
1997
- cliAdapter: createTuiCliAdapter(),
1998
- reloadPluginCommandSource
1999
- });
2000
- await tuiTransport.start();
2001
- process.exit(0);
2002
- }
2003
- function createTuiCliAdapter() {
2004
- return {
2005
- getUserSettingsPath: () => getUserSettingsPath(),
2006
- readSettings: (path) => readSettings(path),
2007
- writeSettings: (path, settings) => writeSettings(path, settings),
2008
- deleteSettings: (path) => deleteSettings(path),
2009
- applyStatusLineSettings: (path, patch) => applyStatusLineSettings(path, patch),
2010
- reloadPluginCommandSource: (registry) => {
2011
- reloadPluginCommandSource(registry);
2012
- },
2013
- applyActiveModelChange: (cwd, modelId, options) => {
2014
- applyActiveModelChange(cwd, modelId, options);
2015
- return { applied: true };
2016
- },
2017
- getGitBranch: (cwd) => resolveGitBranch(cwd)
2018
- };
2019
- }
2020
- function createTransportRegistry() {
2021
- const registry = new TransportRegistry(getUserSettingsPath());
2022
- registry.register(new WsTransport());
2023
- return registry;
2024
- }
2025
- export {
2026
- ChildProcessSubagentRunner,
2027
- GitWorktreeIsolationAdapter,
2028
- createChildProcessSubagentRunnerFactory,
2029
- createGitWorktreeIsolationAdapter,
2030
- createManagedShellProcessRunner,
2031
- startCli
2032
- };
29
+ `)}function Ze(e){if(e!==void 0)return w.includes(e)||(process.stderr.write(`Invalid --output-format "${e}". Valid: ${w.join(` | `)}\n`),process.exit(1)),e}function Qe(e){if(e!==void 0)return C.includes(e)||(process.stderr.write(`Invalid --permission-mode "${e}". Valid: ${C.join(` | `)}\n`),process.exit(1)),e}function $e(e){if(e===void 0)return;let t=parseInt(e,10);return(isNaN(t)||t<=0)&&(process.stderr.write(`Invalid --max-turns "${e}". Must be a positive integer.\n`),process.exit(1)),t}function et(){let{values:e,positionals:t}=Re({allowPositionals:!0,options:{help:{type:`boolean`,short:`h`,default:!1},p:{type:`boolean`,short:`p`,default:!1},continue:{type:`boolean`,short:`c`,default:!1},resume:{type:`string`,short:`r`},model:{type:`string`},language:{type:`string`},"permission-mode":{type:`string`},"max-turns":{type:`string`},"fork-session":{type:`boolean`,default:!1},name:{type:`string`,short:`n`},"output-format":{type:`string`},format:{type:`string`},summary:{type:`string`},source:{type:`string`},"system-prompt":{type:`string`},"append-system-prompt":{type:`string`},"task-file":{type:`string`},version:{type:`boolean`,default:!1},reset:{type:`boolean`,default:!1},bare:{type:`boolean`,default:!1},"allowed-tools":{type:`string`},"no-session-persistence":{type:`boolean`,default:!1},"json-schema":{type:`string`},configure:{type:`boolean`,default:!1},"configure-provider":{type:`string`},provider:{type:`string`},type:{type:`string`},"base-url":{type:`string`},"api-key":{type:`string`},"api-key-env":{type:`string`},"set-current":{type:`boolean`,default:!1},"settings-scope":{type:`string`},"check-update":{type:`boolean`,default:!1},"disable-update-check":{type:`boolean`,default:!1}}});return{positional:t,help:e.help??!1,printMode:e.p??!1,continueMode:e.continue??!1,resumeId:e.resume,model:e.model,language:e.language,permissionMode:Qe(e[`permission-mode`]),maxTurns:$e(e[`max-turns`]),forkSession:e[`fork-session`]??!1,sessionName:e.name,outputFormat:Ze(e[`output-format`]),format:e.format,summary:e.summary,source:e.source,systemPrompt:e[`system-prompt`],appendSystemPrompt:e[`append-system-prompt`],taskFile:e[`task-file`],version:e.version??!1,reset:e.reset??!1,bare:e.bare??!1,allowedTools:e[`allowed-tools`],noSessionPersistence:e[`no-session-persistence`]??!1,jsonSchema:e[`json-schema`],configure:e.configure??!1,configureProvider:e[`configure-provider`],provider:e.provider,providerType:e.type,baseURL:e[`base-url`],apiKey:e[`api-key`],apiKeyEnv:e[`api-key-env`],setCurrent:e[`set-current`]??!1,settingsScope:e[`settings-scope`],checkUpdate:e[`check-update`]??!1,disableUpdateCheck:e[`disable-update-check`]??!1}}function T(){return f(process.env.HOME??process.env.USERPROFILE??`/`,`.robota`,`settings.json`)}function E(e){if(!i(e))return{};let t=s(e,`utf8`);try{return JSON.parse(t)}catch{return process.stderr.write(`Warning: corrupt settings file at ${e}, resetting to defaults\n`),{}}}function D(e,t){o(u(e),{recursive:!0}),l(e,JSON.stringify(t,null,2)+`
30
+ `,`utf8`)}function O(e){return i(e)?(c(e),!0):!1}function k(e){let t=tt();return[f(t,`.robota`,`settings.json`),f(t,`.claude`,`settings.json`),f(e,`.robota`,`settings.json`),f(e,`.robota`,`settings.local.json`),f(e,`.claude`,`settings.json`),f(e,`.claude`,`settings.local.json`)]}function tt(){return process.env.HOME??process.env.USERPROFILE??`/`}function A(e){return ce(k(e))}function j(e,t={}){let n=ue(A(e),t.providerOverride,M(t));if(n!==void 0)return n;throw Error("No provider configuration found. Run `robota` to set up.")}function nt(e,t,n={}){let r=M(n),i=j(e,{...n,providerDefinitions:r}),a=t??i.model;return We({...i,model:a},r)}function M(t){return t.providerDefinitions??e}function N(e,t={}){let n=t.settingsPaths??k(e),r=st(n)??n[0];if(r===void 0)throw Error(`No settings path available for provider update`);return r}function P(e){return E(e)}function F(e,t,n={}){let r=oe(P(e),ne(t,n));return D(e,r),r}function rt(e,t,n={}){let r=P(e),i=r.providers?.[t]!==void 0,a=n.knownProviders?.[t]!==void 0,o=i||a?{...r,currentProvider:t}:pe(r,t);return D(e,o),o}function it(e,t,n={}){let r=n.settingsPaths??k(e),i=le(r),a=n.providerOverride??i.currentProvider;if(typeof a!=`string`)throw Error(`Cannot update model: no active provider profile. Set "currentProvider" in settings.`);return at(r,a,t)}function at(e,t,n){let r=ot(e,t)??e[0];if(r===void 0)throw Error(`No settings path available for model update`);let i=P(r),a=i.providers??{},o=a[t]??{},s={...i,providers:{...a,[t]:{...o,model:n}}};return D(r,s),{settingsPath:r,settings:s,profileName:t}}function ot(e,t){for(let n=e.length-1;n>=0;--n){let r=e[n];if(r!==void 0&&P(r).providers?.[t]!==void 0)return r}}function st(e){for(let t=e.length-1;t>=0;--t){let n=e[t];if(n!==void 0&&P(n).currentProvider!==void 0)return n}}function I(e,t){if(t===void 0||t===`user`)return T();if(t===`project-local`)return f(e,`.robota`,`settings.local.json`);throw Error(`Invalid --settings-scope "${t}". Valid: user | project-local`)}function ct(t,n,r=e){let i=I(t,n.settingsScope);return n.configureProvider?(F(i,ut(n),{providerDefinitions:r}),process.stdout.write(`Provider profile saved to ${i}\n`),!n.printMode&&n.positional.length===0):n.provider&&n.setCurrent?(rt(n.settingsScope===void 0?N(t):i,n.provider,{knownProviders:A(t).providers}),process.stdout.write(`Current provider set to ${n.provider}\n`),!n.printMode&&n.positional.length===0):!1}async function lt(t,n,r,i=e){let a=A(t);if(b(n.provider===void 0?a:{...a,currentProvider:n.provider},i)===`valid`)return;if(!pt())throw Error(R(i));await L(t,dt(t,n),r,i);let o=A(t);if(b(n.provider===void 0?o:{...o,currentProvider:n.provider},i)!==`valid`)throw Error(R(i))}async function L(t,n,r,i=e){let a=Ie(await r(Fe(i)),i),o=I(t,n.settingsScope);F(o,await Le(a,r,i,{existingProfileNames:Object.keys(A(t).providers??{})}),{providerDefinitions:i});let s=await r(` Response language (ko/en/ja/zh, default: en): `);if(s){let e=E(o);e.language=s,D(o,e)}process.stdout.write(`\n Config saved to ${o}\n\n`)}function ut(e){let t=e.providerType??e.configureProvider;if(!e.configureProvider||!t)throw Error(`--configure-provider requires a provider profile and --type`);return{profile:e.configureProvider,type:t,...e.model!==void 0&&{model:e.model},...e.apiKey!==void 0&&{apiKey:e.apiKey},...e.apiKeyEnv!==void 0&&{apiKeyEnv:e.apiKeyEnv},...e.baseURL!==void 0&&{baseURL:e.baseURL},setCurrent:e.setCurrent}}function dt(e,t){if(t.settingsScope!==void 0||t.provider!==void 0)return t;let n=ft(k(e));if(n===void 0)return t;let r=f(e,`.robota`,`settings.json`),i=f(e,`.robota`,`settings.local.json`);return n===r||n===i?{...t,settingsScope:`project-local`}:t}function ft(e){for(let t=e.length-1;t>=0;--t){let n=e[t];if(n!==void 0&&typeof E(n).currentProvider==`string`)return n}}function pt(){return process.stdin.isTTY===!0&&process.stdout.isTTY===!0}function R(t=e){return[`No provider configuration found.`,"Run `robota --configure` in an interactive terminal, or configure a provider:",`Supported providers: ${Ke(t)}`,...t.map(mt)].join(`
31
+ `)}function mt(e){return` ${[`robota --configure-provider ${e.type}`,`--type ${e.type}`,...e.defaults?.baseURL===void 0?[]:[`--base-url <url>`],`--model <model>`,...e.requiresApiKey===!0?[`--api-key-env <ENV_NAME>`]:[],`--set-current`].join(` `)}`}var ht=class{entries=new Map;settingsPath;constructor(e){this.settingsPath=e}register(e){this.entries.set(e.name,e)}getAll(){let e=this.readTransportSettings();return Array.from(this.entries.values()).map(t=>({transport:t,config:this.resolveConfig(t,e[t.name])}))}getEnabled(){return this.getAll().filter(e=>e.config.enabled).map(e=>e.transport)}async setEnabled(e,t){let n=E(this.settingsPath),r=n.transports??{};r[e]={...r[e]??{},enabled:t},n.transports=r,D(this.settingsPath,n)}async setOptions(e,t){let n=E(this.settingsPath),r=n.transports??{};r[e]={...r[e]??{},options:t},n.transports=r,D(this.settingsPath,n)}async startAll(e){let t=this.getEnabled();for(let n of t)n.attach(e),await n.start()}async stopAll(){for(let e of this.entries.values())await e.stop()}resolveConfig(e,t){return{enabled:t?.enabled??e.defaultEnabled,options:t?.options??{}}}readTransportSettings(){let e=E(this.settingsPath).transports;return!e||typeof e!=`object`||Array.isArray(e)?{}:e}};function gt(e,t,n,r,i){switch(e.type){case`ready`:t();break;case`result`:n(e.output);break;case`error`:r(new x(`runner`,e.message));break;case`cancelled`:r(new x(`runner`,e.reason??`Subagent worker cancelled`));break;case`text_delta`:i?.({type:`background_task_text_delta`,delta:e.delta});break;case`tool_start`:i?.({type:`background_task_tool_start`,toolName:e.toolName,firstArg:_t(e.toolArgs)});break;case`tool_end`:i?.({type:`background_task_tool_end`,toolName:e.toolName,success:e.success});break;default:r(new x(`runner`,`Unhandled subagent worker message`))}}function _t(e){if(!e)return;let t=Object.values(e)[0];if(t!==void 0)return typeof t==`object`?JSON.stringify(t):String(t)}function z(e,t){return new Promise((n,r)=>{if(!e.connected){r(new x(`crash`,`Subagent worker IPC channel is closed`));return}e.send(t,e=>{if(e){r(e);return}n()})})}async function B(e,t){e.child.connected&&await z(e.child,{type:`cancel`,reason:t}).catch(()=>void 0),e.killTimer=setTimeout(()=>{e.child.killed||e.child.kill(`SIGTERM`)},e.killGraceMs)}function vt(e){return new Promise((t,n)=>{new yt(e,t,n).start()})}var yt=class{options;resolve;reject;settled=!1;started=!1;timeoutTimer;constructor(e,t,n){this.options=e,this.resolve=t,this.reject=n,this.timeoutTimer=xt(this.options.runtime,e=>this.rejectOnce(e))}start(){let{child:e}=this.options.runtime;e.on(`message`,this.onMessage),e.on(`error`,this.onError),e.on(`exit`,this.onExit),e.once(`spawn`,()=>{setImmediate(this.startWorker)})}startWorker=()=>{if(this.started)return;this.started=!0;let{child:e}=this.options.runtime;z(e,{type:`start`,payload:this.options.payload}).catch(e=>{this.rejectOnce(e instanceof Error?e:Error(String(e)))})};onMessage=e=>{if(!t(e)){this.rejectOnce(new x(`runner`,`Received malformed subagent worker message`));return}let{job:n}=this.options.runtime;gt(e,this.startWorker,this.resolveOnce,this.rejectOnce,n.emit)};onError=e=>{this.rejectOnce(new x(`crash`,e.message))};onExit=(e,t)=>{this.settled||this.rejectOnce(new x(`crash`,Ct(e,t)))};resolveOnce=e=>{if(this.settled)return;this.settled=!0,this.clearTimers(),this.cleanup();let{runtime:t,resolveTranscriptPath:n}=this.options;this.resolve(St(t.job,e,n))};rejectOnce=e=>{this.settled||(this.settled=!0,this.clearTimers(),this.cleanup(),this.reject(e))};clearTimers(){this.timeoutTimer&&clearTimeout(this.timeoutTimer),this.options.runtime.killTimer&&clearTimeout(this.options.runtime.killTimer)}cleanup(){let{child:e}=this.options.runtime;e.off(`message`,this.onMessage),e.off(`error`,this.onError),e.off(`exit`,this.onExit)}};function bt(e){let t=!1,n=()=>{};return{promise:new Promise((e,t)=>{n=t}),reject(r){t||(t=!0,n(new x(`runner`,r??`Subagent job cancelled: ${e}`)))}}}function xt(e,t){if(e.job.request.timeoutMs)return setTimeout(()=>{B(e,`Subagent worker timed out`),t(new x(`timeout`,`Subagent worker timed out`))},e.job.request.timeoutMs)}function St(e,t,n){let r=n(e);return{jobId:e.jobId,output:t,...r?{metadata:{transcriptPath:r,logPath:r}}:{}}}function Ct(e,t){return`Subagent worker exited before result: ${t===null?`exit code ${e===null?`unknown`:e}`:`signal ${t}`}`}function V(e={}){return t=>{let n=new H(t,e);return e.worktreeIsolation===!1?n:Ge({runner:n,worktreeAdapter:e.worktreeAdapter??Ue(),hooks:t.config.hooks,hookTypeExecutors:t.hookTypeExecutors})}}var H=class{deps;workerPath;execArgv;killGraceMs;providerConfig;env;logsDir;constructor(e,t={}){this.deps=e,this.workerPath=t.workerPath??Dt(),this.execArgv=t.execArgv,this.killGraceMs=t.killGraceMs??2e3,this.providerConfig=t.providerConfig,this.env=t.env,this.logsDir=t.logsDir}start(e){let t=r(this.workerPath,[],{cwd:e.request.cwd,env:{...process.env,...this.env??{}},execArgv:this.execArgv??Ot(this.workerPath),stdio:[`ignore`,`ignore`,`ignore`,`ipc`]}),n={job:e,child:t,killGraceMs:this.killGraceMs},i=vt({runtime:n,payload:this.createStartPayload(e),resolveTranscriptPath:e=>this.resolveTranscriptPath(e)}),a=bt(e.jobId);i.catch(()=>void 0);let o=Promise.race([i,a.promise]),s=this.resolveTranscriptPath(e);return{jobId:e.jobId,...t.pid!==void 0&&{pid:t.pid},...s!==void 0&&{transcriptPath:s,logPath:s},result:o,cancel:async e=>{a.reject(e),await B(n,e)},send:async e=>{await z(t,{type:`send`,prompt:e})},...s!==void 0&&{readLog:async t=>kt(e.jobId,s,t)}}}createStartPayload(e){let t=wt(e.request.type,this.deps.customAgentRegistry);return{jobId:e.jobId,request:e.request,agentDefinition:Tt(t,e),parentConfig:this.deps.config,parentContext:this.deps.context,providerProfile:Et(this.providerConfig,this.deps,e),permissionMode:this.deps.permissionMode,...this.logsDir?{logsDir:this.logsDir}:{}}}resolveTranscriptPath(e){if(this.logsDir)return f(this.logsDir,e.request.parentSessionId,`subagents`,`${e.jobId}.jsonl`)}};function wt(e,t){let n=t?.(e)??ae(e);if(!n)throw new x(`validation`,`Unknown agent type: ${e}`);return n}function Tt(e,t){return{...e,...t.request.model?{model:t.request.model}:{},...t.request.allowedTools?{tools:t.request.allowedTools}:{},...t.request.disallowedTools?{disallowedTools:t.request.disallowedTools}:{}}}function Et(e,t,n){let r=e??t.config.provider;return{profileName:t.config.currentProvider,type:r.name,model:n.request.model??r.model,apiKey:r.apiKey,baseURL:r.baseURL,timeout:r.timeout,options:r.options}}function Dt(){let e=process.argv[1]??``,t=e?u(e):process.cwd(),n=e.endsWith(`.ts`)||e.endsWith(`.tsx`)?`.ts`:`.js`,r=[f(t,`subagents`,`child-process-subagent-worker${n}`),f(t,`child-process-subagent-worker${n}`)];for(let e of r)if(i(e))return e;return r[0]}function Ot(e){return!e.endsWith(`.ts`)||process.execArgv.some(e=>e.includes(`tsx`))?process.execArgv:[...process.execArgv,`--import`,`tsx`]}function kt(e,t,n){return i(t)?Be(e,s(t,`utf8`).split(/\r?\n/).filter(Boolean),n):{taskId:e,cursor:n,lines:[]}}function At(e,t){let n=U(e),r=U(t);if(n===void 0||r===void 0)return Math.sign(e.localeCompare(t));let i=G(n.major,r.major)||G(n.minor,r.minor)||G(n.patch,r.patch);return i===0?Mt(n.prerelease,r.prerelease):i}function jt(e,t){return At(e,t)>0}function U(e){let[t,n]=(e.trim().replace(/^v/,``).split(`+`)[0]??``).split(`-`,2),[r,i,a]=t.split(`.`),o=W(r),s=W(i),c=W(a);if(!(o===void 0||s===void 0||c===void 0))return{major:o,minor:s,patch:c,prerelease:n?n.split(`.`):[]}}function W(e){if(!(e===void 0||!/^\d+$/.test(e)))return Number(e)}function G(e,t){return Math.sign(e-t)}function Mt(e,t){if(e.length===0&&t.length===0)return 0;if(e.length===0)return 1;if(t.length===0)return-1;let n=Math.max(e.length,t.length);for(let r=0;r<n;r+=1){let n=e[r],i=t[r];if(n===void 0)return-1;if(i===void 0)return 1;let a=Nt(n,i);if(a!==0)return a}return 0}function Nt(e,t){let n=W(e),r=W(t);return n!==void 0&&r!==void 0?G(n,r):n===void 0?r===void 0?Math.sign(e.localeCompare(t)):1:-1}function Pt(e=process.env.HOME??process.env.USERPROFILE??`/`){return f(e,`.robota`,`update-check.json`)}function Ft(e){if(i(e))try{return Wt(JSON.parse(s(e,`utf8`)))}catch{return}}function It(e,t){o(u(e),{recursive:!0}),l(e,JSON.stringify(t,null,2)+`
32
+ `,`utf8`)}async function K(e){if(e.disabled===!0)return{status:`skipped`,reason:`disabled`};let t=e.packageName??`@robota-sdk/agent-cli`,n=e.cachePath??Pt(),r=e.now??new Date,i=e.ttlMs??864e5;if(e.force!==!0){let a=Ft(n);if(a!==void 0&&Vt(a,r,i,t))return Bt(a,e.currentVersion)}try{let i=await Ht({fetchImpl:e.fetchImpl??fetch,packageName:t,registryUrl:e.registryUrl??`https://registry.npmjs.org`,timeoutMs:e.timeoutMs??1500});return q(n,{packageName:t,checkedAt:r.toISOString(),currentVersion:e.currentVersion,latestVersion:i}),Y(e.currentVersion,i)}catch(i){let a=i instanceof Error?i.message:String(i);return q(n,{packageName:t,checkedAt:r.toISOString(),currentVersion:e.currentVersion,errorMessage:a}),{status:`error`,errorMessage:a}}}function q(e,t){try{It(e,t)}catch{}}async function Lt(e){let t=await K(e);return t.status===`update_available`?t.notice:void 0}function Rt(e){return e.printMode===!1&&e.disableUpdateCheck===!1}function J(e){return[`Robota update available: ${e.currentVersion} -> ${e.latestVersion}.`,`Run ${e.installCommand}`].join(` `)}function zt(e){return e.status===`update_available`?J(e.notice):e.status===`current`?`Robota is up to date (${e.currentVersion}).`:e.status===`skipped`?`Robota update check skipped.`:`Robota update check failed: ${e.errorMessage}`}function Bt(e,t){return e.errorMessage===void 0?e.latestVersion===void 0?{status:`error`,errorMessage:`Cached update check has no latest version`}:Y(t,e.latestVersion):{status:`error`,errorMessage:e.errorMessage}}function Y(e,t){return jt(t,e)?{status:`update_available`,notice:{currentVersion:e,latestVersion:t,installCommand:`npm install -g '@robota-sdk/agent-cli@latest'`}}:{status:`current`,currentVersion:e,latestVersion:t}}function Vt(e,t,n,r){if(e.packageName!==r)return!1;let i=Date.parse(e.checkedAt);return Number.isFinite(i)?t.getTime()-i<n:!1}async function Ht(e){let t=new AbortController,n=setTimeout(()=>t.abort(),e.timeoutMs);try{let n=Ut(e.registryUrl,e.packageName),r=await e.fetchImpl(n,{headers:{accept:`application/json`},signal:t.signal});if(!r.ok)throw Error(`registry responded with HTTP ${r.status}`);let i=(await r.json())[`dist-tags`]?.latest;if(typeof i!=`string`||i.trim().length===0)throw Error(`registry metadata is missing dist-tags.latest`);return i}finally{clearTimeout(n)}}function Ut(e,t){return`${e.replace(/\/+$/,``)}/${encodeURIComponent(t)}`}function Wt(e){if(!Gt(e))return;let t=e;if(typeof t.packageName==`string`&&typeof t.checkedAt==`string`&&typeof t.currentVersion==`string`&&(t.latestVersion===void 0||typeof t.latestVersion==`string`)&&(t.errorMessage===void 0||typeof t.errorMessage==`string`))return{packageName:t.packageName,checkedAt:t.checkedAt,currentVersion:t.currentVersion,...t.latestVersion!==void 0&&{latestVersion:t.latestVersion},...t.errorMessage!==void 0&&{errorMessage:t.errorMessage}}}function Gt(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}const X={..._};function Kt(e){let t=e.statusline;return Jt(t)?{enabled:typeof t.enabled==`boolean`?t.enabled:X.enabled,gitBranch:typeof t.gitBranch==`boolean`?t.gitBranch:X.gitBranch}:{...X}}function qt(e,t){let n=E(e),r={...Kt(n),...t};return n.statusline=r,D(e,n),r}function Jt(e){return typeof e==`object`&&!!e&&!Array.isArray(e)&&!(e instanceof Date)}function Yt(e){try{let t=Xt(e);if(!t)return;let n=s(f(t,`HEAD`),`utf8`).trim();if(!n)return;if(n.startsWith(`ref: `)){let e=n.slice(5).trim();return e.startsWith(`refs/heads/`)?e.slice(11):e}return n.slice(0,7)}catch{return}}function Xt(e){let t=p(e),n=u(t);for(;n!==t;){let e=Z(f(t,`.git`),t);if(e)return e;t=n,n=u(t)}return Z(f(t,`.git`),t)}function Z(e,t){if(!i(e))return;let n=a(e);if(n.isDirectory())return e;if(!n.isFile())return;let r=s(e,`utf8`).trim();if(!r.startsWith(`gitdir:`))return;let o=r.slice(7).trim();return d(o)?o:p(t,o)}const Q=`plugin`;function Zt(){return process.env.HOME??S()}function Qt(e){let t=new g(f(Zt(),`.robota`,`plugins`));try{let n=t.loadPluginsSync();return n.length===0?(e.replaceSource(Q),0):(e.replaceSource(Q,new ee(n)),n.length)}catch{return e.replaceSource(Q),0}}function $t(e){let t=S(),r=f(t,`.robota`,`plugins`),i=f(t,`.robota`,`settings.json`),a=(e,t)=>n(e,{timeout:t.timeout,stdio:t.stdio??`pipe`}),o=new te(i),s=new y({pluginsDir:r,exec:a});return{cwd:e,marketplace:s,installer:new h({pluginsDir:r,settingsStore:o,marketplaceClient:s,exec:a}),loader:new g(r),settingsStore:o}}async function en(e){let t=await e.loader.loadAll(),n=e.settingsStore.getEnabledPlugins();return t.map(e=>{let t=e.pluginDir.split(`/`),r=t.indexOf(`cache`),i=r>=0?t[r+1]??``:``,a=i?`${e.manifest.name}@${i}`:e.manifest.name;return{name:a,description:e.manifest.description,enabled:n[a]!==!1&&n[e.manifest.name]!==!1}})}async function tn(e,t){let n;try{n=e.marketplace.fetchManifest(t)}catch{return[]}let r=e.installer.getInstalledPlugins(),i=new Set(Object.values(r).map(e=>e.pluginName));return n.plugins.map(e=>({name:e.name,description:e.description,installed:i.has(e.name)}))}async function nn(e,t,r){let[i,a]=t.split(`@`);if(!i||!a)throw Error(`Plugin ID must be in format: name@marketplace`);if(r===`project`){await new h({pluginsDir:f(e.cwd,`.robota`,`plugins`),settingsStore:e.settingsStore,marketplaceClient:e.marketplace,exec:(e,t)=>n(e,{timeout:t.timeout,stdio:t.stdio??`pipe`})}).install(i,a);return}await e.installer.install(i,a)}async function rn(e,t){let n=e.installer.getPluginsByMarketplace(t);for(let t of n)await e.installer.uninstall(`${t.pluginName}@${t.marketplace}`);e.marketplace.removeMarketplace(t)}function an(e){return e.marketplace.listMarketplaces().map(e=>({name:e.name,type:e.source.type}))}function on(e){let t=$t(e);return{listInstalled:()=>en(t),listAvailablePlugins:e=>tn(t,e),install:(e,n)=>nn(t,e,n),uninstall:async e=>t.installer.uninstall(e),enable:async e=>t.installer.enable(e),disable:async e=>t.installer.disable(e),marketplaceAdd:async e=>e.includes(`/`)&&!e.includes(`:`)?t.marketplace.addMarketplace({type:`github`,repo:e}):t.marketplace.addMarketplace({type:`git`,url:e}),marketplaceRemove:e=>rn(t,e),marketplaceUpdate:async e=>t.marketplace.updateMarketplace(e),marketplaceList:async()=>an(t),reloadPlugins:async()=>({loadedPluginCount:(await t.loader.loadAll()).length})}}async function sn(e,t){if(e.positional[0]!==`user-local`)return!1;let n=await Pe({cwd:t,argv:e.positional.slice(1),format:e.format,summary:e.summary,source:e.source}),r=n.message.endsWith(`
33
+ `)?n.message:`${n.message}\n`;return n.success||(process.stderr.write(r),process.exit(1)),process.stdout.write(r),!0}function cn(){return[{label:`plan`,value:`plan`,description:`Plan only, no execution`},{label:`default`,value:`default`,description:`Ask before risky actions`},{label:`acceptEdits`,value:`acceptEdits`,description:`Auto-approve file edits`},{label:`bypassPermissions`,value:`bypassPermissions`,description:`Skip all permission checks`}]}function ln(){return[{label:`ko Korean`,value:`ko`,description:`한국어`},{label:`en English`,value:`en`,description:`English`},{label:`ja Japanese`,value:`ja`,description:`日本語`},{label:`zh Chinese`,value:`zh`,description:`中文`}]}function un(){return[{label:`current`,value:`current`,description:`Show current provider`},{label:`list`,value:`list`,description:`List available providers`},{label:`use`,value:`use`,description:`Switch to a provider`},{label:`add`,value:`add`,description:`Add a new provider`},{label:`test`,value:`test`,description:`Test provider connection`}]}const dn={agent:void 0,background:void 0,clear:{onMissingArgs:`confirm`,message:`Clear conversation history?`},compact:void 0,context:void 0,cost:void 0,exit:{onMissingArgs:`confirm`,message:`Exit the session?`},help:void 0,language:{onMissingArgs:`picker`,getItems:ln},memory:void 0,mode:{onMissingArgs:`picker`,getItems:cn},model:void 0,permissions:void 0,plugin:void 0,provider:{onMissingArgs:`picker`,getItems:un},rename:void 0,reset:void 0,resume:void 0,rewind:void 0,settings:void 0,skills:void 0,statusline:void 0,"user-local":void 0,"validate-session":void 0};function fn(e){return dn[e]}function pn(){try{let e=u(m(import.meta.url)),t=[f(e,`..`,`..`,`package.json`),f(e,`..`,`package.json`)];for(let e of t)try{let t=s(e,`utf-8`),n=JSON.parse(t);if(n.version!==void 0&&n.name!==void 0)return n.version}catch{}return`0.0.0`}catch{return`0.0.0`}}function $(e,t=!1){return new Promise((n,r)=>{process.stdout.write(e);let i=``,a=process.stdin,o=a.isRaw;if(!a.isTTY){r(Error(`Cannot prompt for input: stdin is not a TTY.
34
+ Set your API key via environment variable instead:
35
+ ANTHROPIC_API_KEY=<key> robota
36
+ OPENAI_API_KEY=<key> robota`));return}a.setRawMode(!0),a.resume(),a.setEncoding(`utf8`);let s=e=>{for(let r of e)if(r===`\r`||r===`
37
+ `){a.removeListener(`data`,s),a.setRawMode(o??!1),a.pause(),process.stdout.write(`
38
+ `),n(i.trim());return}else r===``||r===`\b`?i.length>0&&(i=i.slice(0,-1),process.stdout.write(`\b \b`)):r===``?(a.removeListener(`data`,s),a.setRawMode(o??!1),a.pause(),process.stdout.write(`
39
+ `),process.exit(0)):r.charCodeAt(0)>=32&&(i+=r,process.stdout.write(t?`*`:r))};a.on(`data`,s)})}function mn(e,t){let n=s(p(e,t),`utf8`).trim();if(n.length===0)throw Error(`Task file is empty: ${t}`);return`Task file (${t}):\n${n}`}function hn(){let e=T();O(e)?process.stdout.write(`Deleted ${e}\n`):process.stdout.write(`No user settings found.
40
+ `)}function gn({cwd:e,providerDefinitions:t}){return[je({cwd:e}),ye(),me(),Ce({providerDefinitions:t,settings:{readMergedSettings:()=>A(e)}}),we(),Se(),be(),he(),xe(),Ne(),ge(),_e(),ve(),ke(),De(),Oe(),Me(),Te(),Ae(),Ee({providerDefinitions:t,settings:{readMergedSettings:()=>A(e),readTargetSettings:()=>E(N(e)),writeTargetSettings:t=>D(N(e),t)}})]}function _n(t,n,r,i){let a={settings:{read:()=>E(T()),write:e=>D(T(),e)},plugin:on(t)},o=r.providerDefinitions??e;return{commandHostAdapters:a,providerDefinitions:o,commandModules:[...gn({cwd:t,providerDefinitions:o}),...r.commandModules??[]],startupUpdateNoticePromise:Rt(n)?Lt({currentVersion:i}):void 0}}function vn(e,t){let n=[];if(t.appendSystemPrompt&&n.push(t.appendSystemPrompt),t.taskFile)try{n.push(mn(e,t.taskFile))}catch(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exit(1)}return t.jsonSchema&&n.push(`Respond with valid JSON only, matching this JSON schema:\n${t.jsonSchema}`),n.length>0?n.join(`
41
+
42
+ `):void 0}async function yn(e,t,r,i,a,o,s,c){let l=t.positional.join(` `).trim();if(!l&&!process.stdin.isTTY){let e=[];for await(let t of process.stdin)e.push(t);l=Buffer.concat(e).toString(`utf-8`).trim()}l||(process.stderr.write(`Print mode (-p) requires a prompt argument.
43
+ `),process.exit(1));let u=vn(e,t);t.systemPrompt&&process.stderr.write(`Warning: --system-prompt is not yet functional and will be ignored.
44
+ `);let d=new v({cwd:e,provider:r,permissionMode:t.permissionMode??`bypassPermissions`,maxTurns:t.maxTurns,sessionStore:t.noSessionPersistence?void 0:i,sessionName:t.sessionName,bare:t.bare||void 0,allowedTools:t.allowedTools?t.allowedTools.split(`,`).map(e=>e.trim()).filter(e=>e.length>0):void 0,appendSystemPrompt:u,backgroundTaskRunners:a,subagentRunnerFactory:o,commandModules:s,commandHostAdapters:c,shellExec:e=>n(e,{timeout:5e3,encoding:`utf-8`,stdio:`pipe`}).trimEnd(),agentName:`robota-cli`}),f=qe({outputFormat:t.outputFormat??`text`,prompt:l});d.attachTransport(f),await f.start(),await d.shutdown({reason:`prompt_input_exit`,message:`Headless transport complete`}),process.exit(f.getExitCode())}async function bn(e={}){let t=et(),r=pn();if(t.help){Xe();return}if(t.version){process.stdout.write(`robota ${r}\n`);return}if(t.checkUpdate){let e=await K({currentVersion:r,force:!0}),t=zt(e);e.status===`error`&&(process.stderr.write(`${t}\n`),process.exit(1)),process.stdout.write(`${t}\n`);return}if(t.reset){hn();return}let i=process.cwd();if(await sn(t,i))return;let{commandHostAdapters:a,providerDefinitions:o,commandModules:s,startupUpdateNoticePromise:c}=_n(i,t,e,r);if(t.configure){await L(i,t,$,o);return}if(ct(i,t,o))return;try{await lt(i,t,$,o)}catch(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exit(1)}let l=t.provider?{providerOverride:t.provider,providerDefinitions:o}:{providerDefinitions:o},u=A(i);t.provider??u.currentProvider;let d=j(i,l),f=t.model??d.model,p=nt(i,t.model,l),m=Ve(),h=se(i),g=V({providerConfig:{...d,model:f},logsDir:h.logs}),_=re(i),v,y=!1;if(t.continueMode?v=de(_,i):t.resumeId!==void 0&&(t.resumeId===``?y=!0:(v=fe(_,t.resumeId),v===void 0&&(process.stderr.write(`Session not found: ${t.resumeId}\n`),process.exit(1)))),t.printMode){await yn(i,t,p,_,m,g,s,a);return}await new Ye({cwd:i,provider:p,providerOverride:t.provider,providerType:d.name,modelId:f,language:t.language,permissionMode:t.permissionMode,maxTurns:t.maxTurns,version:r,sessionStore:t.noSessionPersistence?void 0:_,resumeSessionId:v,showSessionPickerOnStart:y,forkSession:t.forkSession,sessionName:t.sessionName,backgroundTaskRunners:m,subagentRunnerFactory:g,commandModules:s,commandHostAdapters:a,shellExec:e=>n(e,{timeout:5e3,encoding:`utf-8`,stdio:`pipe`}).trimEnd(),startupUpdateNotice:c?c.then(e=>e?J(e):void 0):void 0,transportRegistry:Sn(),cliAdapter:xn(o),reloadPluginCommandSource:Qt,agentName:`robota-cli`,resolveInteraction:fn}).start(),process.exit(0)}function xn(e){return{getUserSettingsPath:()=>T(),readSettings:e=>E(e),writeSettings:(e,t)=>D(e,t),deleteSettings:e=>O(e),applyStatusLineSettings:(e,t)=>qt(e,t),reloadPluginCommandSource:e=>{Qt(e)},applyActiveModelChange:(e,t,n)=>(it(e,t,n),{applied:!0}),getGitBranch:e=>Yt(e),getProviderDisplayName:t=>ie(e,t)?.displayName??t}}function Sn(){let e=new ht(T());return e.register(new Je),e}export{H as ChildProcessSubagentRunner,ze as GitWorktreeIsolationAdapter,V as createChildProcessSubagentRunnerFactory,He as createGitWorktreeIsolationAdapter,bn as startCli};
45
+ //# sourceMappingURL=index.js.map