@fragno-dev/pi-fragment 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/LICENSE.md +16 -0
  2. package/README.md +107 -0
  3. package/bin/run.js +72 -0
  4. package/dist/browser/client/react.d.ts +264 -0
  5. package/dist/browser/client/react.d.ts.map +1 -0
  6. package/dist/browser/client/react.js +84 -0
  7. package/dist/browser/client/react.js.map +1 -0
  8. package/dist/browser/client/solid.d.ts +266 -0
  9. package/dist/browser/client/solid.d.ts.map +1 -0
  10. package/dist/browser/client/solid.js +122 -0
  11. package/dist/browser/client/solid.js.map +1 -0
  12. package/dist/browser/client/svelte.d.ts +261 -0
  13. package/dist/browser/client/svelte.d.ts.map +1 -0
  14. package/dist/browser/client/svelte.js +126 -0
  15. package/dist/browser/client/svelte.js.map +1 -0
  16. package/dist/browser/client/vanilla.d.ts +238 -0
  17. package/dist/browser/client/vanilla.d.ts.map +1 -0
  18. package/dist/browser/client/vanilla.js +11 -0
  19. package/dist/browser/client/vanilla.js.map +1 -0
  20. package/dist/browser/client/vue.d.ts +264 -0
  21. package/dist/browser/client/vue.d.ts.map +1 -0
  22. package/dist/browser/client/vue.js +125 -0
  23. package/dist/browser/client/vue.js.map +1 -0
  24. package/dist/browser/client-Bk-J98pf.d.ts +679 -0
  25. package/dist/browser/client-Bk-J98pf.d.ts.map +1 -0
  26. package/dist/browser/factory-DKoO_lRA.js +2470 -0
  27. package/dist/browser/factory-DKoO_lRA.js.map +1 -0
  28. package/dist/browser/index.d.ts +776 -0
  29. package/dist/browser/index.d.ts.map +1 -0
  30. package/dist/browser/index.js +3 -0
  31. package/dist/cli/cli.d.ts +1 -0
  32. package/dist/cli/cli.js +10 -0
  33. package/dist/cli/cli.js.map +1 -0
  34. package/dist/cli/config.d.ts +13 -0
  35. package/dist/cli/config.d.ts.map +1 -0
  36. package/dist/cli/config.js +64 -0
  37. package/dist/cli/config.js.map +1 -0
  38. package/dist/cli/http/client.js +95 -0
  39. package/dist/cli/http/client.js.map +1 -0
  40. package/dist/cli/mod.d.ts +62 -0
  41. package/dist/cli/mod.d.ts.map +1 -0
  42. package/dist/cli/mod.js +644 -0
  43. package/dist/cli/mod.js.map +1 -0
  44. package/dist/cli/render/index.d.ts +23 -0
  45. package/dist/cli/render/index.d.ts.map +1 -0
  46. package/dist/cli/render/index.js +37 -0
  47. package/dist/cli/render/index.js.map +1 -0
  48. package/dist/node/index.d.ts +10 -0
  49. package/dist/node/index.js +9 -0
  50. package/dist/node/pi/clients.d.ts +240 -0
  51. package/dist/node/pi/clients.d.ts.map +1 -0
  52. package/dist/node/pi/clients.js +18 -0
  53. package/dist/node/pi/clients.js.map +1 -0
  54. package/dist/node/pi/constants.d.ts +9 -0
  55. package/dist/node/pi/constants.d.ts.map +1 -0
  56. package/dist/node/pi/constants.js +22 -0
  57. package/dist/node/pi/constants.js.map +1 -0
  58. package/dist/node/pi/definition.d.ts +13 -0
  59. package/dist/node/pi/definition.d.ts.map +1 -0
  60. package/dist/node/pi/definition.js +10 -0
  61. package/dist/node/pi/definition.js.map +1 -0
  62. package/dist/node/pi/dsl.d.ts +24 -0
  63. package/dist/node/pi/dsl.d.ts.map +1 -0
  64. package/dist/node/pi/dsl.js +57 -0
  65. package/dist/node/pi/dsl.js.map +1 -0
  66. package/dist/node/pi/factory.d.ts +220 -0
  67. package/dist/node/pi/factory.d.ts.map +1 -0
  68. package/dist/node/pi/factory.js +12 -0
  69. package/dist/node/pi/factory.js.map +1 -0
  70. package/dist/node/pi/mappers.js +47 -0
  71. package/dist/node/pi/mappers.js.map +1 -0
  72. package/dist/node/pi/route-schemas.js +112 -0
  73. package/dist/node/pi/route-schemas.js.map +1 -0
  74. package/dist/node/pi/types.d.ts +67 -0
  75. package/dist/node/pi/types.d.ts.map +1 -0
  76. package/dist/node/pi/workflow.d.ts +31 -0
  77. package/dist/node/pi/workflow.d.ts.map +1 -0
  78. package/dist/node/pi/workflow.js +242 -0
  79. package/dist/node/pi/workflow.js.map +1 -0
  80. package/dist/node/routes.d.ts +217 -0
  81. package/dist/node/routes.d.ts.map +1 -0
  82. package/dist/node/routes.js +328 -0
  83. package/dist/node/routes.js.map +1 -0
  84. package/dist/node/schema.js +12 -0
  85. package/dist/node/schema.js.map +1 -0
  86. package/dist/tsconfig.tsbuildinfo +1 -0
  87. package/package.json +125 -0
@@ -0,0 +1,644 @@
1
+ import { resolveConfig } from "./config.js";
2
+ import { createHttpClient } from "./http/client.js";
3
+ import { renderOutput } from "./render/index.js";
4
+ import { readFile } from "node:fs/promises";
5
+
6
+ //#region src/cli/mod.ts
7
+ const USAGE = `fragno-pi <command> [options]
8
+
9
+ Commands:
10
+ sessions list List pi-fragment sessions
11
+ sessions create Create a pi-fragment session
12
+ sessions get Fetch session detail/status
13
+ sessions send-message Send a user message to a session
14
+
15
+ Global options:
16
+ -b, --base-url <url> Fragment base URL (FRAGNO_PI_BASE_URL)
17
+ -H, --header <header> Extra HTTP header (repeatable)
18
+ --timeout <ms> Request timeout in ms (default: 15000)
19
+ --retries <n> Retry count (default: 2)
20
+ --retry-delay <ms> Delay between retries (default: 500)
21
+ --json Output raw JSON
22
+ --debug Log request metadata to stderr
23
+ -h, --help Show this help message
24
+
25
+ sessions list:
26
+ --limit <n> Limit results (default server: 50)
27
+
28
+ sessions create:
29
+ --agent <name> Agent name (required)
30
+ --name <label> Session label
31
+ --tag <tag> Tag (repeatable)
32
+ --metadata <json> Metadata JSON string
33
+ --steering-mode <mode> all|one-at-a-time
34
+
35
+ sessions get:
36
+ -s, --session <id> Session id (or positional)
37
+ --status-only Only output status fields
38
+
39
+ sessions send-message:
40
+ -s, --session <id> Session id (or positional)
41
+ --text <message> Message text
42
+ --file <path> Read message text from file
43
+ --done Mark session done
44
+ --steering-mode <mode> all|one-at-a-time`;
45
+ const buildErrorResult = (message, usage = USAGE) => ({
46
+ stderr: `${message}\n\n${usage}`,
47
+ exitCode: 1
48
+ });
49
+ const requireBaseUrl = (config) => {
50
+ if (config.baseUrl) return null;
51
+ return buildErrorResult("Missing required option: --base-url (or FRAGNO_PI_BASE_URL)");
52
+ };
53
+ const debugLog = (config, logger, message) => {
54
+ if (!config.debug) return;
55
+ if (logger?.error) {
56
+ logger.error(message);
57
+ return;
58
+ }
59
+ console.error(message);
60
+ };
61
+ const readResponseBody = async (response) => {
62
+ const text = await response.text();
63
+ if (!text) return;
64
+ try {
65
+ return JSON.parse(text);
66
+ } catch {
67
+ return text;
68
+ }
69
+ };
70
+ const formatErrorMessage = (status, body) => {
71
+ if (body && typeof body === "object" && "message" in body) {
72
+ const message = body.message;
73
+ if (message) return `Request failed (${status}): ${message}`;
74
+ }
75
+ if (typeof body === "string" && body.trim()) return `Request failed (${status}): ${body}`;
76
+ return `Request failed (${status}).`;
77
+ };
78
+ const buildClient = (config) => createHttpClient({
79
+ baseUrl: config.baseUrl ?? "",
80
+ headers: config.headers,
81
+ timeoutMs: config.timeoutMs,
82
+ retries: config.retries,
83
+ retryDelayMs: config.retryDelayMs
84
+ });
85
+ const requestJson = async (config, logger, options) => {
86
+ const baseError = requireBaseUrl(config);
87
+ if (baseError) return {
88
+ ok: false,
89
+ error: baseError
90
+ };
91
+ const client = buildClient(config);
92
+ debugLog(config, logger, `request ${options.method} ${options.path}`);
93
+ try {
94
+ const response = await client.request({
95
+ method: options.method,
96
+ path: options.path,
97
+ body: options.body
98
+ });
99
+ const body = await readResponseBody(response);
100
+ debugLog(config, logger, `response ${response.status} ${options.method} ${options.path}`);
101
+ if (!response.ok) return {
102
+ ok: false,
103
+ error: {
104
+ stderr: formatErrorMessage(response.status, body),
105
+ exitCode: 2
106
+ }
107
+ };
108
+ return {
109
+ ok: true,
110
+ data: body
111
+ };
112
+ } catch (error) {
113
+ return {
114
+ ok: false,
115
+ error: {
116
+ stderr: error instanceof Error ? error.message : String(error),
117
+ exitCode: 2
118
+ }
119
+ };
120
+ }
121
+ };
122
+ const getRecordValue = (record, key) => {
123
+ const value = record[key];
124
+ return value === null || value === void 0 ? "" : String(value);
125
+ };
126
+ const buildSessionsListOutput = (data, json) => {
127
+ if (!Array.isArray(data)) return {
128
+ stderr: "Unexpected response for sessions list.",
129
+ exitCode: 2
130
+ };
131
+ if (json) return { output: {
132
+ format: "json",
133
+ data
134
+ } };
135
+ return { output: {
136
+ format: "table",
137
+ columns: [
138
+ {
139
+ key: "id",
140
+ label: "ID"
141
+ },
142
+ {
143
+ key: "agent",
144
+ label: "Agent"
145
+ },
146
+ {
147
+ key: "name",
148
+ label: "Name"
149
+ },
150
+ {
151
+ key: "status",
152
+ label: "Status"
153
+ },
154
+ {
155
+ key: "updated",
156
+ label: "Updated"
157
+ }
158
+ ],
159
+ rows: data.map((session) => {
160
+ if (session && typeof session === "object") {
161
+ const record = session;
162
+ return {
163
+ id: getRecordValue(record, "id"),
164
+ agent: getRecordValue(record, "agent"),
165
+ name: getRecordValue(record, "name"),
166
+ status: getRecordValue(record, "status"),
167
+ updated: getRecordValue(record, "updatedAt")
168
+ };
169
+ }
170
+ return {
171
+ id: "",
172
+ agent: "",
173
+ name: "",
174
+ status: "",
175
+ updated: ""
176
+ };
177
+ })
178
+ } };
179
+ };
180
+ const buildDetailOutput = (data, json) => {
181
+ if (json) return { output: {
182
+ format: "json",
183
+ data
184
+ } };
185
+ return { output: {
186
+ format: "pretty-json",
187
+ data
188
+ } };
189
+ };
190
+ const buildSendMessageOutput = (data, json) => {
191
+ if (json) return { output: {
192
+ format: "json",
193
+ data
194
+ } };
195
+ if (!data || typeof data !== "object") return { output: {
196
+ format: "pretty-json",
197
+ data
198
+ } };
199
+ const record = data;
200
+ const status = record["status"];
201
+ const assistant = record["assistant"];
202
+ const hasAssistant = assistant !== void 0 && assistant !== null;
203
+ const lines = [];
204
+ if (status !== void 0) lines.push(`Status: ${String(status)}`);
205
+ if (hasAssistant) {
206
+ const assistantText = typeof assistant === "string" ? assistant : JSON.stringify(assistant, null, 2);
207
+ lines.push(assistantText);
208
+ } else if (status !== void 0) lines.push("Message accepted. Use `sessions get` to fetch the response.");
209
+ if (lines.length === 0) return { output: {
210
+ format: "pretty-json",
211
+ data
212
+ } };
213
+ return { output: {
214
+ format: "text",
215
+ text: lines.join("\n\n")
216
+ } };
217
+ };
218
+ const resolveMessageText = async (args) => {
219
+ if (args.text) return {
220
+ ok: true,
221
+ text: args.text
222
+ };
223
+ if (!args.file) return {
224
+ ok: false,
225
+ error: buildErrorResult("Missing required option: --text (or --file)")
226
+ };
227
+ try {
228
+ return {
229
+ ok: true,
230
+ text: await readFile(args.file, "utf8")
231
+ };
232
+ } catch (error) {
233
+ const message = error instanceof Error ? error.message : String(error);
234
+ return {
235
+ ok: false,
236
+ error: buildErrorResult(`Unable to read --file ${args.file}: ${message}`)
237
+ };
238
+ }
239
+ };
240
+ const defaultActions = {
241
+ sessionsList: async (args, ctx) => {
242
+ const query = new URLSearchParams();
243
+ if (args.limit !== void 0) query.set("limit", String(args.limit));
244
+ const path = query.size ? `/sessions?${query.toString()}` : "/sessions";
245
+ const response = await requestJson(ctx.config, ctx.logger, {
246
+ method: "GET",
247
+ path
248
+ });
249
+ if (!response.ok) return response.error;
250
+ return buildSessionsListOutput(response.data, ctx.config.json);
251
+ },
252
+ sessionsCreate: async (args, ctx) => {
253
+ const body = { agent: args.agent };
254
+ if (args.name) body["name"] = args.name;
255
+ if (args.tags && args.tags.length > 0) body["tags"] = args.tags;
256
+ if (args.metadata !== void 0) body["metadata"] = args.metadata;
257
+ if (args.steeringMode) body["steeringMode"] = args.steeringMode;
258
+ const response = await requestJson(ctx.config, ctx.logger, {
259
+ method: "POST",
260
+ path: "/sessions",
261
+ body
262
+ });
263
+ if (!response.ok) return response.error;
264
+ return buildDetailOutput(response.data, ctx.config.json);
265
+ },
266
+ sessionsGet: async (args, ctx) => {
267
+ const path = `/sessions/${encodeURIComponent(args.sessionId)}`;
268
+ const response = await requestJson(ctx.config, ctx.logger, {
269
+ method: "GET",
270
+ path
271
+ });
272
+ if (!response.ok) return response.error;
273
+ const data = response.data;
274
+ return buildDetailOutput(args.statusOnly && data && typeof data === "object" ? {
275
+ status: data["status"],
276
+ workflow: data["workflow"],
277
+ summaries: data["summaries"]
278
+ } : data, ctx.config.json);
279
+ },
280
+ sessionsSendMessage: async (args, ctx) => {
281
+ const resolved = await resolveMessageText(args);
282
+ if (!resolved.ok) return resolved.error;
283
+ const body = { text: resolved.text };
284
+ if (args.done) body["done"] = true;
285
+ if (args.steeringMode) body["steeringMode"] = args.steeringMode;
286
+ const path = `/sessions/${encodeURIComponent(args.sessionId)}/messages`;
287
+ const response = await requestJson(ctx.config, ctx.logger, {
288
+ method: "POST",
289
+ path,
290
+ body
291
+ });
292
+ if (!response.ok) return response.error;
293
+ return buildSendMessageOutput(response.data, ctx.config.json);
294
+ }
295
+ };
296
+ const VALUE_OPTIONS = new Set([
297
+ "base-url",
298
+ "header",
299
+ "timeout",
300
+ "retries",
301
+ "retry-delay",
302
+ "limit",
303
+ "agent",
304
+ "name",
305
+ "tag",
306
+ "metadata",
307
+ "steering-mode",
308
+ "session",
309
+ "text",
310
+ "file"
311
+ ]);
312
+ const SHORT_OPTIONS = {
313
+ "-b": "base-url",
314
+ "-H": "header",
315
+ "-s": "session"
316
+ };
317
+ const ALL_LONG_OPTIONS = new Set([
318
+ ...VALUE_OPTIONS,
319
+ "json",
320
+ "debug",
321
+ "status-only",
322
+ "done"
323
+ ]);
324
+ const ALL_SHORT_OPTIONS = new Set(Object.keys(SHORT_OPTIONS));
325
+ const editDistance = (left, right) => {
326
+ const leftLen = left.length;
327
+ const rightLen = right.length;
328
+ const dp = Array.from({ length: rightLen + 1 }, (_, index) => index);
329
+ for (let i = 1; i <= leftLen; i += 1) {
330
+ let prev = dp[0] ?? 0;
331
+ dp[0] = i;
332
+ const leftChar = left[i - 1];
333
+ for (let j = 1; j <= rightLen; j += 1) {
334
+ const temp = dp[j] ?? 0;
335
+ const cost = leftChar === right[j - 1] ? 0 : 1;
336
+ dp[j] = Math.min((dp[j] ?? 0) + 1, (dp[j - 1] ?? 0) + 1, prev + cost);
337
+ prev = temp;
338
+ }
339
+ }
340
+ return dp[rightLen] ?? Math.max(leftLen, rightLen);
341
+ };
342
+ const suggestLongOption = (key) => {
343
+ let best = null;
344
+ for (const candidate of ALL_LONG_OPTIONS) {
345
+ const score = editDistance(key, candidate);
346
+ if (!best || score < best.score) best = {
347
+ key: candidate,
348
+ score
349
+ };
350
+ }
351
+ if (best && best.score <= 3) return best.key;
352
+ return null;
353
+ };
354
+ const addOption = (options, key, value) => {
355
+ if (typeof value === "boolean") {
356
+ options[key] = value;
357
+ return;
358
+ }
359
+ const current = options[key];
360
+ if (!current) {
361
+ options[key] = value;
362
+ return;
363
+ }
364
+ if (Array.isArray(current)) {
365
+ current.push(value);
366
+ return;
367
+ }
368
+ options[key] = [String(current), value];
369
+ };
370
+ const coerceBooleanValue = (value) => {
371
+ const normalized = value.trim().toLowerCase();
372
+ if (normalized === "false" || normalized === "0" || normalized === "no") return false;
373
+ if (normalized === "true" || normalized === "1" || normalized === "yes") return true;
374
+ return value;
375
+ };
376
+ const parseArgs = (argv) => {
377
+ const options = {};
378
+ const positionals = [];
379
+ const errors = [];
380
+ let help = false;
381
+ let i = 0;
382
+ while (i < argv.length) {
383
+ const arg = argv[i];
384
+ if (arg === "--") {
385
+ positionals.push(...argv.slice(i + 1));
386
+ break;
387
+ }
388
+ if (arg === "--help" || arg === "-h") {
389
+ help = true;
390
+ i += 1;
391
+ continue;
392
+ }
393
+ if (arg.startsWith("--")) {
394
+ const [rawKey, rawValue] = arg.split("=", 2);
395
+ const key = rawKey.slice(2);
396
+ if (!ALL_LONG_OPTIONS.has(key)) {
397
+ const suggestion = suggestLongOption(key);
398
+ errors.push(`Unknown option: --${key}${suggestion ? ` (did you mean --${suggestion}?)` : ""}`);
399
+ if (rawValue !== void 0) {
400
+ i += 1;
401
+ continue;
402
+ }
403
+ const next = argv[i + 1];
404
+ if (next && !next.startsWith("-")) i += 2;
405
+ else i += 1;
406
+ continue;
407
+ }
408
+ if (rawValue !== void 0) {
409
+ addOption(options, key, VALUE_OPTIONS.has(key) ? rawValue : coerceBooleanValue(rawValue));
410
+ i += 1;
411
+ continue;
412
+ }
413
+ if (VALUE_OPTIONS.has(key)) {
414
+ const next = argv[i + 1];
415
+ if (!next || next.startsWith("-")) {
416
+ errors.push(`Missing value for --${key}`);
417
+ i += 1;
418
+ continue;
419
+ }
420
+ addOption(options, key, next);
421
+ i += 2;
422
+ continue;
423
+ }
424
+ addOption(options, key, true);
425
+ i += 1;
426
+ continue;
427
+ }
428
+ if (arg.startsWith("-") && arg.length > 1) {
429
+ if (arg === "-h") {
430
+ help = true;
431
+ i += 1;
432
+ continue;
433
+ }
434
+ if (!ALL_SHORT_OPTIONS.has(arg)) {
435
+ errors.push(`Unknown option: ${arg}`);
436
+ i += 1;
437
+ continue;
438
+ }
439
+ const key = SHORT_OPTIONS[arg];
440
+ if (key) {
441
+ const next = argv[i + 1];
442
+ if (!next || next.startsWith("-")) {
443
+ errors.push(`Missing value for ${arg}`);
444
+ i += 1;
445
+ continue;
446
+ }
447
+ addOption(options, key, next);
448
+ i += 2;
449
+ continue;
450
+ }
451
+ positionals.push(arg);
452
+ i += 1;
453
+ continue;
454
+ }
455
+ positionals.push(arg);
456
+ i += 1;
457
+ }
458
+ const [command, action, ...rest] = positionals;
459
+ return {
460
+ command,
461
+ action,
462
+ options,
463
+ positionals: rest,
464
+ help,
465
+ errors
466
+ };
467
+ };
468
+ const getStringOption = (options, key) => {
469
+ const value = options[key];
470
+ if (Array.isArray(value)) return value[0];
471
+ if (typeof value === "string") return value;
472
+ };
473
+ const getStringArrayOption = (options, key) => {
474
+ const value = options[key];
475
+ if (Array.isArray(value)) return value.map(String);
476
+ if (typeof value === "string") return [value];
477
+ };
478
+ const getBooleanOption = (options, key) => Boolean(options[key]);
479
+ const parseNumberOption = (options, key) => {
480
+ const value = getStringOption(options, key);
481
+ if (!value) return;
482
+ const parsed = Number(value);
483
+ if (!Number.isFinite(parsed)) throw new Error(`Invalid value for --${key}`);
484
+ return parsed;
485
+ };
486
+ const parseSteeringMode = (value) => {
487
+ if (!value) return;
488
+ if (value === "all" || value === "one-at-a-time") return value;
489
+ throw new Error("Invalid --steering-mode. Expected: all|one-at-a-time");
490
+ };
491
+ const resolveRunOptions = (loggerOrOptions) => {
492
+ if (!loggerOrOptions) return {};
493
+ if ("log" in loggerOrOptions) return { logger: loggerOrOptions };
494
+ return loggerOrOptions;
495
+ };
496
+ const buildConfig = (options) => {
497
+ return resolveConfig({
498
+ baseUrl: getStringOption(options, "base-url"),
499
+ headers: getStringArrayOption(options, "header"),
500
+ timeoutMs: getStringOption(options, "timeout"),
501
+ retries: getStringOption(options, "retries"),
502
+ retryDelayMs: getStringOption(options, "retry-delay"),
503
+ json: getBooleanOption(options, "json"),
504
+ debug: getBooleanOption(options, "debug")
505
+ });
506
+ };
507
+ const renderResult = (result, config) => {
508
+ if (!result) return {};
509
+ if (!result.stdout && result.output) return {
510
+ ...result,
511
+ stdout: renderOutput(result.output, config.json)
512
+ };
513
+ return result;
514
+ };
515
+ async function run(argv, loggerOrOptions = console) {
516
+ const options = resolveRunOptions(loggerOrOptions);
517
+ const logger = options.logger ?? console;
518
+ const actions = options.actions ?? defaultActions;
519
+ const parsed = parseArgs(argv.slice(2));
520
+ if (parsed.errors.length > 0) {
521
+ const result = buildErrorResult(parsed.errors.join("\n"));
522
+ logger.error(result.stderr ?? "");
523
+ return result.exitCode ?? 1;
524
+ }
525
+ if (parsed.help || !parsed.command || parsed.command === "help") {
526
+ logger.log(USAGE);
527
+ return parsed.command && !parsed.help ? 1 : 0;
528
+ }
529
+ let config;
530
+ try {
531
+ config = buildConfig(parsed.options);
532
+ } catch (error) {
533
+ const result = buildErrorResult(error instanceof Error ? error.message : String(error));
534
+ logger.error(result.stderr ?? "");
535
+ return result.exitCode ?? 1;
536
+ }
537
+ const ctx = {
538
+ config,
539
+ logger
540
+ };
541
+ const command = parsed.command;
542
+ const action = parsed.action;
543
+ const opts = parsed.options;
544
+ try {
545
+ let result;
546
+ switch (command) {
547
+ case "sessions":
548
+ if (!action) {
549
+ result = buildErrorResult("Missing sessions action.");
550
+ break;
551
+ }
552
+ switch (action) {
553
+ case "list": {
554
+ const limit = parseNumberOption(opts, "limit");
555
+ result = await actions.sessionsList({ limit }, ctx);
556
+ break;
557
+ }
558
+ case "create": {
559
+ const agent = getStringOption(opts, "agent");
560
+ if (!agent) {
561
+ result = buildErrorResult("Missing required option: --agent");
562
+ break;
563
+ }
564
+ const steeringMode = parseSteeringMode(getStringOption(opts, "steering-mode"));
565
+ const metadataRaw = getStringOption(opts, "metadata");
566
+ let metadata;
567
+ if (metadataRaw) try {
568
+ metadata = JSON.parse(metadataRaw);
569
+ } catch {
570
+ result = buildErrorResult("Invalid JSON for --metadata");
571
+ break;
572
+ }
573
+ result = await actions.sessionsCreate({
574
+ agent,
575
+ name: getStringOption(opts, "name"),
576
+ tags: getStringArrayOption(opts, "tag"),
577
+ metadata,
578
+ steeringMode
579
+ }, ctx);
580
+ break;
581
+ }
582
+ case "get": {
583
+ const sessionId = getStringOption(opts, "session") ?? parsed.positionals[0];
584
+ if (!sessionId) {
585
+ result = buildErrorResult("Missing required option: --session");
586
+ break;
587
+ }
588
+ result = await actions.sessionsGet({
589
+ sessionId,
590
+ statusOnly: getBooleanOption(opts, "status-only")
591
+ }, ctx);
592
+ break;
593
+ }
594
+ case "send-message": {
595
+ const sessionId = getStringOption(opts, "session") ?? parsed.positionals[0];
596
+ if (!sessionId) {
597
+ result = buildErrorResult("Missing required option: --session");
598
+ break;
599
+ }
600
+ const steeringMode = parseSteeringMode(getStringOption(opts, "steering-mode"));
601
+ const text = getStringOption(opts, "text");
602
+ const file = getStringOption(opts, "file");
603
+ if (!text && !file) {
604
+ result = buildErrorResult("Missing required option: --text (or --file)");
605
+ break;
606
+ }
607
+ result = await actions.sessionsSendMessage({
608
+ sessionId,
609
+ text,
610
+ file,
611
+ done: getBooleanOption(opts, "done"),
612
+ steeringMode
613
+ }, ctx);
614
+ break;
615
+ }
616
+ default:
617
+ result = buildErrorResult(`Unknown sessions action: ${action}`);
618
+ break;
619
+ }
620
+ break;
621
+ default:
622
+ result = buildErrorResult(`Unknown command: ${command}`);
623
+ break;
624
+ }
625
+ const resolved = renderResult(result, config);
626
+ if (resolved.stdout) logger.log(resolved.stdout);
627
+ if (resolved.stderr) logger.error(resolved.stderr);
628
+ if (typeof resolved.exitCode === "number") return resolved.exitCode;
629
+ return resolved.stderr ? 1 : 0;
630
+ } catch (error) {
631
+ const message = error instanceof Error ? error.message : String(error);
632
+ logger.error(`${message}\n\n${USAGE}`);
633
+ return 1;
634
+ }
635
+ }
636
+ const __testing = {
637
+ USAGE,
638
+ parseArgs,
639
+ renderOutput
640
+ };
641
+
642
+ //#endregion
643
+ export { __testing, run };
644
+ //# sourceMappingURL=mod.js.map