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