@miosa/cli 1.0.79 → 1.0.80

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 (90) hide show
  1. package/README.md +38 -0
  2. package/dist/bin/miosa.js +1 -0
  3. package/dist/bin/miosa.js.map +1 -1
  4. package/dist/commands/capabilities.d.ts.map +1 -1
  5. package/dist/commands/capabilities.js +85 -4
  6. package/dist/commands/capabilities.js.map +1 -1
  7. package/dist/commands/completion.d.ts.map +1 -1
  8. package/dist/commands/completion.js +12 -1
  9. package/dist/commands/completion.js.map +1 -1
  10. package/dist/commands/computers.d.ts.map +1 -1
  11. package/dist/commands/computers.js +44 -0
  12. package/dist/commands/computers.js.map +1 -1
  13. package/dist/commands/connectors.d.ts.map +1 -1
  14. package/dist/commands/connectors.js +509 -1
  15. package/dist/commands/connectors.js.map +1 -1
  16. package/dist/commands/deploy.d.ts.map +1 -1
  17. package/dist/commands/deploy.js +147 -0
  18. package/dist/commands/deploy.js.map +1 -1
  19. package/dist/commands/devices.d.ts.map +1 -1
  20. package/dist/commands/devices.js +410 -35
  21. package/dist/commands/devices.js.map +1 -1
  22. package/dist/commands/osa.d.ts +3 -0
  23. package/dist/commands/osa.d.ts.map +1 -0
  24. package/dist/commands/osa.js +663 -0
  25. package/dist/commands/osa.js.map +1 -0
  26. package/dist/osa/build.d.ts +6 -0
  27. package/dist/osa/build.d.ts.map +1 -0
  28. package/dist/osa/build.js +23 -0
  29. package/dist/osa/build.js.map +1 -0
  30. package/dist/osa/builtin-skills.d.ts +7 -0
  31. package/dist/osa/builtin-skills.d.ts.map +1 -0
  32. package/dist/osa/builtin-skills.js +85 -0
  33. package/dist/osa/builtin-skills.js.map +1 -0
  34. package/dist/osa/computer.d.ts +10 -0
  35. package/dist/osa/computer.d.ts.map +1 -0
  36. package/dist/osa/computer.js +37 -0
  37. package/dist/osa/computer.js.map +1 -0
  38. package/dist/osa/deployments.d.ts +44 -0
  39. package/dist/osa/deployments.d.ts.map +1 -0
  40. package/dist/osa/deployments.js +140 -0
  41. package/dist/osa/deployments.js.map +1 -0
  42. package/dist/osa/discovery.d.ts +8 -0
  43. package/dist/osa/discovery.d.ts.map +1 -0
  44. package/dist/osa/discovery.js +668 -0
  45. package/dist/osa/discovery.js.map +1 -0
  46. package/dist/osa/doctor.d.ts +9 -0
  47. package/dist/osa/doctor.d.ts.map +1 -0
  48. package/dist/osa/doctor.js +41 -0
  49. package/dist/osa/doctor.js.map +1 -0
  50. package/dist/osa/eval.d.ts +7 -0
  51. package/dist/osa/eval.d.ts.map +1 -0
  52. package/dist/osa/eval.js +108 -0
  53. package/dist/osa/eval.js.map +1 -0
  54. package/dist/osa/integrations.d.ts +28 -0
  55. package/dist/osa/integrations.d.ts.map +1 -0
  56. package/dist/osa/integrations.js +65 -0
  57. package/dist/osa/integrations.js.map +1 -0
  58. package/dist/osa/paths.d.ts +8 -0
  59. package/dist/osa/paths.d.ts.map +1 -0
  60. package/dist/osa/paths.js +31 -0
  61. package/dist/osa/paths.js.map +1 -0
  62. package/dist/osa/plans.d.ts +9 -0
  63. package/dist/osa/plans.d.ts.map +1 -0
  64. package/dist/osa/plans.js +55 -0
  65. package/dist/osa/plans.js.map +1 -0
  66. package/dist/osa/projects.d.ts +45 -0
  67. package/dist/osa/projects.d.ts.map +1 -0
  68. package/dist/osa/projects.js +92 -0
  69. package/dist/osa/projects.js.map +1 -0
  70. package/dist/osa/runtime.d.ts +19 -0
  71. package/dist/osa/runtime.d.ts.map +1 -0
  72. package/dist/osa/runtime.js +92 -0
  73. package/dist/osa/runtime.js.map +1 -0
  74. package/dist/osa/scaffold.d.ts +11 -0
  75. package/dist/osa/scaffold.d.ts.map +1 -0
  76. package/dist/osa/scaffold.js +245 -0
  77. package/dist/osa/scaffold.js.map +1 -0
  78. package/dist/osa/skills.d.ts +19 -0
  79. package/dist/osa/skills.d.ts.map +1 -0
  80. package/dist/osa/skills.js +55 -0
  81. package/dist/osa/skills.js.map +1 -0
  82. package/dist/osa/types.d.ts +157 -0
  83. package/dist/osa/types.d.ts.map +1 -0
  84. package/dist/osa/types.js +2 -0
  85. package/dist/osa/types.js.map +1 -0
  86. package/dist/osa/yaml.d.ts +7 -0
  87. package/dist/osa/yaml.d.ts.map +1 -0
  88. package/dist/osa/yaml.js +59 -0
  89. package/dist/osa/yaml.js.map +1 -0
  90. package/package.json +1 -1
@@ -0,0 +1,663 @@
1
+ import chalk from "chalk";
2
+ import { handleError, isJsonMode, printJson } from "./util.js";
3
+ import { initOsaProject } from "../osa/scaffold.js";
4
+ import { discoverOsaProject } from "../osa/discovery.js";
5
+ import { addSkill, listSkills, searchSkills } from "../osa/skills.js";
6
+ import { enableComputer } from "../osa/computer.js";
7
+ import { runOsaDoctor } from "../osa/doctor.js";
8
+ import { buildOsaProject } from "../osa/build.js";
9
+ import { runOsaEvals } from "../osa/eval.js";
10
+ import { createOsaPlan } from "../osa/plans.js";
11
+ import { addChannel, addConnection } from "../osa/integrations.js";
12
+ import { dispatchOsaRun } from "../osa/runtime.js";
13
+ import { cancelOsaDeployment, deployOsaProject, getOsaDeployment, listOsaDeployments, retryOsaDeployment, } from "../osa/deployments.js";
14
+ import { getOsaProject, listOsaProjects, publishOsaProject } from "../osa/projects.js";
15
+ import { UserError } from "../errors.js";
16
+ export function register(program) {
17
+ const osa = program
18
+ .command("osa")
19
+ .description("Manage filesystem-defined OSA Projects");
20
+ osa
21
+ .command("init [target]")
22
+ .description("Scaffold an OSA Project")
23
+ .option("-f, --force", "Overwrite existing scaffolded OSA files")
24
+ .option("--json", "Output JSON")
25
+ .action((target, opts) => {
26
+ try {
27
+ const result = initOsaProject({ target, force: opts.force });
28
+ if (isJsonMode(opts)) {
29
+ printJson({ ok: true, data: result });
30
+ return;
31
+ }
32
+ console.log(chalk.green(`Created OSA project at ${result.projectRoot}`));
33
+ if (result.created.length > 0) {
34
+ console.log(chalk.dim(` ${result.created.length} file(s) written`));
35
+ }
36
+ }
37
+ catch (err) {
38
+ handleError(err);
39
+ }
40
+ });
41
+ osa
42
+ .command("info [target]")
43
+ .description("Inspect an OSA Project and write discovery artifacts")
44
+ .option("--json", "Output JSON")
45
+ .action((target, opts) => {
46
+ try {
47
+ const discovery = discoverOsaProject({ target });
48
+ if (isJsonMode(opts)) {
49
+ printJson({ ok: discovery.manifest.diagnostics.errors === 0, data: discovery });
50
+ if (discovery.manifest.diagnostics.errors > 0)
51
+ process.exitCode = 1;
52
+ return;
53
+ }
54
+ renderInfo(discovery.manifest, discovery.diagnostics);
55
+ if (discovery.manifest.diagnostics.errors > 0)
56
+ process.exitCode = 1;
57
+ }
58
+ catch (err) {
59
+ handleError(err);
60
+ }
61
+ });
62
+ osa
63
+ .command("doctor [target]")
64
+ .description("Diagnose OSA Project shape and local readiness")
65
+ .option("--json", "Output JSON")
66
+ .action((target, opts) => {
67
+ try {
68
+ const result = runOsaDoctor({ target });
69
+ const ok = result.checks.every((check) => check.ok || check.warn);
70
+ if (isJsonMode(opts)) {
71
+ printJson({ ok, data: result });
72
+ if (!ok)
73
+ process.exitCode = 1;
74
+ return;
75
+ }
76
+ renderDoctor(result.checks);
77
+ if (!ok)
78
+ process.exitCode = 1;
79
+ }
80
+ catch (err) {
81
+ handleError(err);
82
+ }
83
+ });
84
+ osa
85
+ .command("build [target]")
86
+ .description("Build OSA discovery artifacts for runtime consumption")
87
+ .option("--json", "Output JSON")
88
+ .action((target, opts) => {
89
+ try {
90
+ const artifact = buildOsaProject({ target });
91
+ if (isJsonMode(opts)) {
92
+ printJson({ ok: true, data: artifact });
93
+ return;
94
+ }
95
+ console.log(chalk.green("Built OSA project"));
96
+ console.log(chalk.dim(` ${artifact.manifestPath}`));
97
+ }
98
+ catch (err) {
99
+ handleError(err);
100
+ }
101
+ });
102
+ osa
103
+ .command("publish [target]")
104
+ .description("Publish an OSA Project manifest to MIOSA")
105
+ .option("--workspace <id>", "Workspace ID for the OSA Project")
106
+ .option("--project-id <id>", "Canonical MIOSA project ID to link")
107
+ .option("--name <name>", "Override published OSA project name")
108
+ .option("--slug <slug>", "Override published OSA project slug")
109
+ .option("--source <source>", "Publish source label", "miosa-cli")
110
+ .option("--dry-run", "Build and print the publish request without contacting the backend")
111
+ .option("--json", "Output JSON")
112
+ .action(async (target, opts) => {
113
+ try {
114
+ const result = await publishOsaProject({
115
+ target,
116
+ workspace: opts.workspace,
117
+ projectId: opts.projectId,
118
+ name: opts.name,
119
+ slug: opts.slug,
120
+ source: opts.source,
121
+ dryRun: opts.dryRun,
122
+ });
123
+ if (isJsonMode(opts)) {
124
+ printJson({ ok: true, data: result });
125
+ return;
126
+ }
127
+ if (result.project) {
128
+ console.log(chalk.green(`Published OSA project ${String(result.project["id"] ?? "")}`));
129
+ console.log(chalk.dim(` ${String(result.project["name"] ?? result.request.name ?? "")}`));
130
+ }
131
+ else {
132
+ console.log(chalk.bold("OSA publish request"));
133
+ console.log(chalk.dim(`Manifest: ${result.build.manifestPath}`));
134
+ console.log(JSON.stringify(result.request, null, 2));
135
+ }
136
+ }
137
+ catch (err) {
138
+ handleError(err);
139
+ }
140
+ });
141
+ osa
142
+ .command("eval [target]")
143
+ .description("Run OSA project eval descriptor checks")
144
+ .option("--strict", "Fail when no evals are present")
145
+ .option("--json", "Output JSON")
146
+ .action((target, opts) => {
147
+ try {
148
+ const report = runOsaEvals({ target, strict: opts.strict });
149
+ if (isJsonMode(opts)) {
150
+ printJson({ ok: report.ok, data: report });
151
+ if (!report.ok)
152
+ process.exitCode = 1;
153
+ return;
154
+ }
155
+ for (const result of report.results) {
156
+ const marker = result.status === "passed" ? chalk.green("pass") : chalk.red("fail");
157
+ console.log(`${marker} ${result.name}`);
158
+ for (const check of result.checks) {
159
+ console.log(chalk.dim(` ${check.status}: ${check.name} - ${check.detail}`));
160
+ }
161
+ }
162
+ if (!report.ok)
163
+ process.exitCode = 1;
164
+ }
165
+ catch (err) {
166
+ handleError(err);
167
+ }
168
+ });
169
+ osa
170
+ .command("run <task...>")
171
+ .description("Dispatch an OSA task to a Sandbox or Computer")
172
+ .option("--project <path>", "OSA project root")
173
+ .option("--sandbox <id>", "Sandbox runtime target ID")
174
+ .option("--computer <id>", "Computer runtime target ID")
175
+ .option("--provider <provider>", "Override configured harness/provider")
176
+ .option("--model <model>", "Model identifier")
177
+ .option("--cwd <path>", "Runtime working directory")
178
+ .option("--timeout <seconds>", "Runtime timeout in seconds")
179
+ .option("--dry-run", "Print and write the dispatch plan without contacting the backend")
180
+ .option("--json", "Output JSON")
181
+ .action(async (taskParts, opts) => {
182
+ try {
183
+ const result = await dispatchOsaRun({
184
+ project: opts.project,
185
+ task: taskParts.join(" "),
186
+ sandbox: opts.sandbox,
187
+ computer: opts.computer,
188
+ provider: opts.provider,
189
+ model: opts.model,
190
+ cwd: opts.cwd,
191
+ timeout: opts.timeout,
192
+ dryRun: opts.dryRun,
193
+ });
194
+ if (isJsonMode(opts)) {
195
+ printJson({ ok: true, data: result });
196
+ return;
197
+ }
198
+ if (result.run) {
199
+ console.log(chalk.green("Dispatched OSA run"));
200
+ console.log(JSON.stringify(result.run, null, 2));
201
+ }
202
+ else {
203
+ renderPlan(result.plan);
204
+ }
205
+ }
206
+ catch (err) {
207
+ handleError(err);
208
+ }
209
+ });
210
+ osa
211
+ .command("dev [target]")
212
+ .description("Prepare an OSA local development runtime plan")
213
+ .option("--runtime-target <target>", "Runtime target: local, miosa-cloud, opencomputer, byoc")
214
+ .option("--dry-run", "Print and write the dev plan without starting a runtime")
215
+ .option("--json", "Output JSON")
216
+ .action((target, opts) => {
217
+ try {
218
+ const plan = createOsaPlan({
219
+ kind: "dev",
220
+ target,
221
+ runtimeTarget: opts.runtimeTarget ?? "local",
222
+ });
223
+ if (!opts.dryRun) {
224
+ throw new UserError("OSA dev runtime is not wired in this CLI release.", "Re-run with --dry-run to inspect the exact local runtime plan.");
225
+ }
226
+ if (isJsonMode(opts)) {
227
+ printJson({ ok: true, data: plan });
228
+ return;
229
+ }
230
+ renderPlan(plan);
231
+ }
232
+ catch (err) {
233
+ handleError(err);
234
+ }
235
+ });
236
+ osa
237
+ .command("deploy [target]")
238
+ .description("Deploy an OSA Project through MIOSA")
239
+ .option("--deploy-target <target>", "Deployment target: miosa-cloud, opencomputer, byoc")
240
+ .option("--workspace <id>", "Workspace ID for first publish")
241
+ .option("--project-id <id>", "Canonical MIOSA project ID to link on first publish")
242
+ .option("--osa-project-id <id>", "Existing published OSA Project ID")
243
+ .option("--sandbox <id>", "Deploy/bootstrap against an explicit Sandbox target")
244
+ .option("--computer <id>", "Deploy/bootstrap against an explicit Computer target")
245
+ .option("--wait", "Wait for the deployment to reach deployed, failed, or canceled")
246
+ .option("--wait-timeout <seconds>", "Maximum seconds to wait for deployment", "600")
247
+ .option("--dry-run", "Print and write the deploy plan without deploying")
248
+ .option("--json", "Output JSON")
249
+ .action(async (target, opts) => {
250
+ try {
251
+ const plan = createOsaPlan({
252
+ kind: "deploy",
253
+ target,
254
+ runtimeTarget: opts.sandbox ? "sandbox" : opts.computer ? "computer" : opts.deployTarget,
255
+ });
256
+ if (!opts.dryRun) {
257
+ const result = await deployOsaProject({
258
+ target,
259
+ workspace: opts.workspace,
260
+ projectId: opts.projectId,
261
+ osaProjectId: opts.osaProjectId,
262
+ deployTarget: opts.deployTarget,
263
+ sandbox: opts.sandbox,
264
+ computer: opts.computer,
265
+ wait: opts.wait,
266
+ waitTimeout: opts.waitTimeout,
267
+ });
268
+ const status = String(result.deployment["status"] ?? "");
269
+ const ok = !opts.wait || status === "deployed";
270
+ if (isJsonMode(opts)) {
271
+ printJson({ ok, data: result });
272
+ if (!ok)
273
+ process.exitCode = 1;
274
+ return;
275
+ }
276
+ console.log(chalk.green(`Created OSA deployment ${String(result.deployment["id"] ?? "")}`));
277
+ console.log(chalk.dim(` OSA project: ${result.osaProjectId}`));
278
+ console.log(chalk.dim(` Status: ${status}`));
279
+ if (result.deployment["runtime_url"]) {
280
+ console.log(chalk.dim(` Runtime URL: ${String(result.deployment["runtime_url"])}`));
281
+ }
282
+ if (!ok)
283
+ process.exitCode = 1;
284
+ return;
285
+ }
286
+ if (isJsonMode(opts)) {
287
+ printJson({ ok: true, data: plan });
288
+ return;
289
+ }
290
+ renderPlan(plan);
291
+ }
292
+ catch (err) {
293
+ handleError(err);
294
+ }
295
+ });
296
+ const projects = osa.command("projects").description("Inspect published OSA Projects");
297
+ projects
298
+ .command("list")
299
+ .description("List published OSA Projects")
300
+ .option("--workspace <id>", "Workspace ID filter")
301
+ .option("--project-id <id>", "Canonical MIOSA project ID filter")
302
+ .option("--status <status>", "Status filter")
303
+ .option("--limit <n>", "Maximum rows")
304
+ .option("--json", "Output JSON")
305
+ .action(async (opts) => {
306
+ try {
307
+ const rows = await listOsaProjects({
308
+ workspace: opts.workspace,
309
+ projectId: opts.projectId,
310
+ status: opts.status,
311
+ limit: opts.limit,
312
+ });
313
+ if (isJsonMode(opts)) {
314
+ printJson({ ok: true, data: rows });
315
+ return;
316
+ }
317
+ renderPublishedProjects(rows);
318
+ }
319
+ catch (err) {
320
+ handleError(err);
321
+ }
322
+ });
323
+ projects
324
+ .command("show <id>")
325
+ .description("Show a published OSA Project")
326
+ .option("--json", "Output JSON")
327
+ .action(async (id, opts) => {
328
+ try {
329
+ const project = await getOsaProject(id);
330
+ if (isJsonMode(opts)) {
331
+ printJson({ ok: true, data: project });
332
+ return;
333
+ }
334
+ renderPublishedProjects([project]);
335
+ }
336
+ catch (err) {
337
+ handleError(err);
338
+ }
339
+ });
340
+ const deployments = osa.command("deployments").description("Inspect OSA Project deployments");
341
+ deployments
342
+ .command("list <osaProjectId>")
343
+ .description("List deployments for a published OSA Project")
344
+ .option("--status <status>", "Status filter")
345
+ .option("--limit <n>", "Maximum rows")
346
+ .option("--json", "Output JSON")
347
+ .action(async (osaProjectId, opts) => {
348
+ try {
349
+ const rows = await listOsaDeployments(osaProjectId, {
350
+ status: opts.status,
351
+ limit: opts.limit,
352
+ });
353
+ if (isJsonMode(opts)) {
354
+ printJson({ ok: true, data: rows });
355
+ return;
356
+ }
357
+ renderDeployments(rows);
358
+ }
359
+ catch (err) {
360
+ handleError(err);
361
+ }
362
+ });
363
+ deployments
364
+ .command("show <osaProjectId> <deploymentId>")
365
+ .description("Show an OSA Project deployment")
366
+ .option("--json", "Output JSON")
367
+ .action(async (osaProjectId, deploymentId, opts) => {
368
+ try {
369
+ const deployment = await getOsaDeployment(osaProjectId, deploymentId);
370
+ if (isJsonMode(opts)) {
371
+ printJson({ ok: true, data: deployment });
372
+ return;
373
+ }
374
+ renderDeployments([deployment]);
375
+ }
376
+ catch (err) {
377
+ handleError(err);
378
+ }
379
+ });
380
+ deployments
381
+ .command("retry <osaProjectId> <deploymentId>")
382
+ .description("Retry a failed or canceled OSA Project deployment")
383
+ .option("--json", "Output JSON")
384
+ .action(async (osaProjectId, deploymentId, opts) => {
385
+ try {
386
+ const deployment = await retryOsaDeployment(osaProjectId, deploymentId);
387
+ if (isJsonMode(opts)) {
388
+ printJson({ ok: true, data: deployment });
389
+ return;
390
+ }
391
+ console.log(chalk.green(`Retried OSA deployment ${String(deployment["id"] ?? "")}`));
392
+ console.log(chalk.dim(` Status: ${String(deployment["status"] ?? "")}`));
393
+ }
394
+ catch (err) {
395
+ handleError(err);
396
+ }
397
+ });
398
+ deployments
399
+ .command("cancel <osaProjectId> <deploymentId>")
400
+ .description("Cancel a queued or preparing OSA Project deployment")
401
+ .option("--json", "Output JSON")
402
+ .action(async (osaProjectId, deploymentId, opts) => {
403
+ try {
404
+ const deployment = await cancelOsaDeployment(osaProjectId, deploymentId);
405
+ if (isJsonMode(opts)) {
406
+ printJson({ ok: true, data: deployment });
407
+ return;
408
+ }
409
+ console.log(chalk.green(`Canceled OSA deployment ${String(deployment["id"] ?? "")}`));
410
+ console.log(chalk.dim(` Status: ${String(deployment["status"] ?? "")}`));
411
+ }
412
+ catch (err) {
413
+ handleError(err);
414
+ }
415
+ });
416
+ const skills = osa.command("skills").description("Manage OSA Project skills");
417
+ skills
418
+ .command("list [target]")
419
+ .description("List project and built-in OSA skills")
420
+ .option("--json", "Output JSON")
421
+ .action((target, opts) => {
422
+ try {
423
+ const rows = listSkills({ target });
424
+ if (isJsonMode(opts)) {
425
+ printJson({ ok: true, data: rows });
426
+ return;
427
+ }
428
+ renderSkills(rows);
429
+ }
430
+ catch (err) {
431
+ handleError(err);
432
+ }
433
+ });
434
+ skills
435
+ .command("search <query>")
436
+ .description("Search project and built-in OSA skills")
437
+ .option("--target <path>", "OSA project root")
438
+ .option("--json", "Output JSON")
439
+ .action((query, opts) => {
440
+ try {
441
+ const rows = searchSkills(query, { target: opts.target });
442
+ if (isJsonMode(opts)) {
443
+ printJson({ ok: true, data: rows });
444
+ return;
445
+ }
446
+ renderSkills(rows);
447
+ }
448
+ catch (err) {
449
+ handleError(err);
450
+ }
451
+ });
452
+ skills
453
+ .command("add <nameOrSource>")
454
+ .description("Install an OSA skill into agent/skills")
455
+ .option("--target <path>", "OSA project root")
456
+ .option("-f, --force", "Overwrite an existing skill")
457
+ .option("--json", "Output JSON")
458
+ .action((nameOrSource, opts) => {
459
+ try {
460
+ const result = addSkill({
461
+ nameOrSource,
462
+ target: opts.target,
463
+ force: opts.force,
464
+ });
465
+ if (isJsonMode(opts)) {
466
+ printJson({ ok: true, data: result.installed });
467
+ return;
468
+ }
469
+ console.log(chalk.green(`Installed OSA skill ${result.installed.name}`));
470
+ console.log(chalk.dim(` ${result.installed.path}`));
471
+ }
472
+ catch (err) {
473
+ handleError(err);
474
+ }
475
+ });
476
+ const computer = osa.command("computer").description("Manage OSA Computer profiles");
477
+ computer
478
+ .command("enable [name]")
479
+ .description("Enable a Computer profile for this OSA Project")
480
+ .option("--target <path>", "OSA project root")
481
+ .option("--json", "Output JSON")
482
+ .action((name, opts) => {
483
+ try {
484
+ const result = enableComputer({ name, target: opts.target });
485
+ if (isJsonMode(opts)) {
486
+ printJson({ ok: true, data: result });
487
+ return;
488
+ }
489
+ console.log(chalk.green(`${result.updated ? "Updated" : "Created"} OSA Computer profile ${result.name}`));
490
+ }
491
+ catch (err) {
492
+ handleError(err);
493
+ }
494
+ });
495
+ const connections = osa.command("connections").description("Manage OSA connection descriptors");
496
+ connections
497
+ .command("add <kind> [name]")
498
+ .description("Scaffold an OSA TypeScript connection")
499
+ .option("--target <path>", "OSA project root")
500
+ .option("--url <url>", "MCP server URL")
501
+ .option("--spec <pathOrUrl>", "OpenAPI spec path or URL")
502
+ .option("--description <text>", "Connection description")
503
+ .option("--auth <mode>", "Auth mode: none, env, oauth")
504
+ .option("-f, --force", "Overwrite an existing connection")
505
+ .option("--json", "Output JSON")
506
+ .action((kind, name, opts) => {
507
+ try {
508
+ if (kind !== "mcp" && kind !== "openapi" && kind !== "linear" && kind !== "github" && kind !== "http") {
509
+ throw new UserError("Invalid connection kind.", "Use mcp, openapi, linear, github, or http.");
510
+ }
511
+ const result = addConnection({
512
+ kind,
513
+ name,
514
+ target: opts.target,
515
+ url: opts.url,
516
+ spec: opts.spec,
517
+ description: opts.description,
518
+ auth: opts.auth,
519
+ force: opts.force,
520
+ });
521
+ if (isJsonMode(opts)) {
522
+ printJson({ ok: true, data: result });
523
+ return;
524
+ }
525
+ console.log(chalk.green(`Added OSA connection ${result.name}`));
526
+ }
527
+ catch (err) {
528
+ handleError(err);
529
+ }
530
+ });
531
+ const channels = osa.command("channels").description("Manage OSA channel descriptors");
532
+ channels
533
+ .command("add <kind> [name]")
534
+ .description("Scaffold an OSA channel descriptor")
535
+ .option("--target <path>", "OSA project root")
536
+ .option("--description <text>", "Channel description")
537
+ .option("-f, --force", "Overwrite an existing channel")
538
+ .option("--json", "Output JSON")
539
+ .action((kind, name, opts) => {
540
+ try {
541
+ if (kind !== "web" && kind !== "slack" && kind !== "github" && kind !== "api") {
542
+ throw new UserError("Invalid channel kind.", "Use web, slack, github, or api.");
543
+ }
544
+ const result = addChannel({
545
+ kind,
546
+ name,
547
+ target: opts.target,
548
+ description: opts.description,
549
+ force: opts.force,
550
+ });
551
+ if (isJsonMode(opts)) {
552
+ printJson({ ok: true, data: result });
553
+ return;
554
+ }
555
+ console.log(chalk.green(`Added OSA channel ${result.name}`));
556
+ }
557
+ catch (err) {
558
+ handleError(err);
559
+ }
560
+ });
561
+ }
562
+ function renderInfo(manifest, diagnostics) {
563
+ console.log(chalk.bold(manifest.agent.name));
564
+ if (manifest.agent.description)
565
+ console.log(chalk.dim(manifest.agent.description));
566
+ console.log();
567
+ console.log(`OSA root: ${manifest.osaRoot}`);
568
+ console.log(`Source root: ${manifest.sourceRoot}`);
569
+ console.log(`Model: ${profileModel(manifest.runtimeProfile) ?? manifest.agent.model ?? "default"}`);
570
+ console.log(`Harness: ${profileField(manifest.runtimeProfile.harness, "engine") ?? manifest.runtimeProfile.provider ?? "auto"}`);
571
+ console.log(`Runtime: ${profileField(manifest.runtimeProfile.runtime, "target") ?? "local"}`);
572
+ console.log(`Sandbox: ${profileField(manifest.runtimeProfile.sandbox, "backend") ?? "auto"}`);
573
+ console.log(`Skills: ${manifest.skills.length}`);
574
+ console.log(`Connections: ${manifest.connections.length}`);
575
+ console.log(`Channels: ${manifest.channels.length}`);
576
+ console.log(`Schedules: ${manifest.schedules.length}`);
577
+ console.log(`Computers: ${manifest.computers.length}`);
578
+ console.log(`Subagents: ${manifest.subagents.length}`);
579
+ console.log(`Hooks: ${manifest.hooks.length}`);
580
+ console.log(`Evals: ${manifest.evals.length}`);
581
+ console.log(`Diagnostics: ${manifest.diagnostics.errors} error(s), ${manifest.diagnostics.warnings} warning(s)`);
582
+ if (diagnostics.length > 0) {
583
+ console.log();
584
+ for (const item of diagnostics) {
585
+ const color = item.severity === "error" ? chalk.red : chalk.yellow;
586
+ console.log(color(`${item.severity.toUpperCase()} ${item.code}`));
587
+ console.log(` ${item.message}`);
588
+ if (item.path)
589
+ console.log(chalk.dim(` ${item.path}`));
590
+ }
591
+ }
592
+ }
593
+ function renderDoctor(checks) {
594
+ for (const check of checks) {
595
+ const marker = check.ok ? chalk.green("ok") : check.warn ? chalk.yellow("warn") : chalk.red("fail");
596
+ console.log(`${marker} ${check.name}: ${check.detail}`);
597
+ if (!check.ok && check.fix)
598
+ console.log(chalk.dim(` fix: ${check.fix}`));
599
+ }
600
+ }
601
+ function renderSkills(skills) {
602
+ if (skills.length === 0) {
603
+ console.log(chalk.dim("No OSA skills found."));
604
+ return;
605
+ }
606
+ for (const skill of skills) {
607
+ console.log(`${chalk.bold(skill.name)} ${chalk.dim(`[${skill.source}/${skill.trust}]`)}`);
608
+ console.log(` ${skill.description}`);
609
+ }
610
+ }
611
+ function renderPublishedProjects(projects) {
612
+ if (projects.length === 0) {
613
+ console.log(chalk.dim("No OSA projects found."));
614
+ return;
615
+ }
616
+ for (const project of projects) {
617
+ console.log(`${chalk.bold(String(project["name"] ?? project["id"] ?? "osa-project"))}`);
618
+ console.log(chalk.dim(` id: ${String(project["id"] ?? "")}`));
619
+ console.log(chalk.dim(` workspace: ${String(project["workspace_id"] ?? "")}`));
620
+ console.log(chalk.dim(` status: ${String(project["status"] ?? "")}`));
621
+ }
622
+ }
623
+ function renderDeployments(deployments) {
624
+ if (deployments.length === 0) {
625
+ console.log(chalk.dim("No OSA deployments found."));
626
+ return;
627
+ }
628
+ for (const deployment of deployments) {
629
+ console.log(chalk.bold(String(deployment["id"] ?? "")));
630
+ console.log(chalk.dim(` OSA project: ${String(deployment["osa_project_id"] ?? "")}`));
631
+ console.log(chalk.dim(` status: ${String(deployment["status"] ?? "")}`));
632
+ console.log(chalk.dim(` target: ${String(deployment["target_kind"] ?? "")}`));
633
+ if (deployment["runtime_url"]) {
634
+ console.log(chalk.dim(` runtime URL: ${String(deployment["runtime_url"])}`));
635
+ }
636
+ }
637
+ }
638
+ function renderPlan(plan) {
639
+ console.log(chalk.bold(`${plan.kind} plan for ${plan.agentName}`));
640
+ console.log(`Target: ${plan.target}`);
641
+ console.log(`Harness: ${profileField(plan.runtimeProfile.harness, "engine") ?? plan.runtimeProfile.provider ?? "auto"}`);
642
+ console.log(`Model: ${profileModel(plan.runtimeProfile) ?? "default"}`);
643
+ if (plan.task)
644
+ console.log(`Task: ${plan.task}`);
645
+ console.log(chalk.dim(`Manifest: ${plan.manifestPath}`));
646
+ for (const step of plan.steps) {
647
+ console.log(`- ${step.id}: ${step.description}`);
648
+ }
649
+ }
650
+ function profileField(value, key) {
651
+ if (!value || typeof value !== "object" || Array.isArray(value))
652
+ return undefined;
653
+ const field = value[key];
654
+ return typeof field === "string" ? field : undefined;
655
+ }
656
+ function profileModel(profile) {
657
+ if (typeof profile.model === "string")
658
+ return profile.model;
659
+ return (profileField(profile.model, "primary") ??
660
+ profileField(profile.model, "id") ??
661
+ profileField(profile.model, "default"));
662
+ }
663
+ //# sourceMappingURL=osa.js.map