@miosa/cli 1.0.78 → 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.
- package/README.md +38 -0
- package/dist/bin/miosa.js +1 -0
- package/dist/bin/miosa.js.map +1 -1
- package/dist/commands/agent-runs.d.ts.map +1 -1
- package/dist/commands/agent-runs.js +20 -0
- package/dist/commands/agent-runs.js.map +1 -1
- package/dist/commands/agent.d.ts.map +1 -1
- package/dist/commands/agent.js +15 -0
- package/dist/commands/agent.js.map +1 -1
- package/dist/commands/capabilities.d.ts.map +1 -1
- package/dist/commands/capabilities.js +85 -4
- package/dist/commands/capabilities.js.map +1 -1
- package/dist/commands/completion.d.ts.map +1 -1
- package/dist/commands/completion.js +12 -1
- package/dist/commands/completion.js.map +1 -1
- package/dist/commands/computers.d.ts.map +1 -1
- package/dist/commands/computers.js +44 -0
- package/dist/commands/computers.js.map +1 -1
- package/dist/commands/connectors.d.ts.map +1 -1
- package/dist/commands/connectors.js +509 -1
- package/dist/commands/connectors.js.map +1 -1
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +147 -0
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/devices.d.ts.map +1 -1
- package/dist/commands/devices.js +410 -35
- package/dist/commands/devices.js.map +1 -1
- package/dist/commands/osa.d.ts +3 -0
- package/dist/commands/osa.d.ts.map +1 -0
- package/dist/commands/osa.js +663 -0
- package/dist/commands/osa.js.map +1 -0
- package/dist/commands/sandbox.d.ts.map +1 -1
- package/dist/commands/sandbox.js +12 -0
- package/dist/commands/sandbox.js.map +1 -1
- package/dist/osa/build.d.ts +6 -0
- package/dist/osa/build.d.ts.map +1 -0
- package/dist/osa/build.js +23 -0
- package/dist/osa/build.js.map +1 -0
- package/dist/osa/builtin-skills.d.ts +7 -0
- package/dist/osa/builtin-skills.d.ts.map +1 -0
- package/dist/osa/builtin-skills.js +85 -0
- package/dist/osa/builtin-skills.js.map +1 -0
- package/dist/osa/computer.d.ts +10 -0
- package/dist/osa/computer.d.ts.map +1 -0
- package/dist/osa/computer.js +37 -0
- package/dist/osa/computer.js.map +1 -0
- package/dist/osa/deployments.d.ts +44 -0
- package/dist/osa/deployments.d.ts.map +1 -0
- package/dist/osa/deployments.js +140 -0
- package/dist/osa/deployments.js.map +1 -0
- package/dist/osa/discovery.d.ts +8 -0
- package/dist/osa/discovery.d.ts.map +1 -0
- package/dist/osa/discovery.js +668 -0
- package/dist/osa/discovery.js.map +1 -0
- package/dist/osa/doctor.d.ts +9 -0
- package/dist/osa/doctor.d.ts.map +1 -0
- package/dist/osa/doctor.js +41 -0
- package/dist/osa/doctor.js.map +1 -0
- package/dist/osa/eval.d.ts +7 -0
- package/dist/osa/eval.d.ts.map +1 -0
- package/dist/osa/eval.js +108 -0
- package/dist/osa/eval.js.map +1 -0
- package/dist/osa/integrations.d.ts +28 -0
- package/dist/osa/integrations.d.ts.map +1 -0
- package/dist/osa/integrations.js +65 -0
- package/dist/osa/integrations.js.map +1 -0
- package/dist/osa/paths.d.ts +8 -0
- package/dist/osa/paths.d.ts.map +1 -0
- package/dist/osa/paths.js +31 -0
- package/dist/osa/paths.js.map +1 -0
- package/dist/osa/plans.d.ts +9 -0
- package/dist/osa/plans.d.ts.map +1 -0
- package/dist/osa/plans.js +55 -0
- package/dist/osa/plans.js.map +1 -0
- package/dist/osa/projects.d.ts +45 -0
- package/dist/osa/projects.d.ts.map +1 -0
- package/dist/osa/projects.js +92 -0
- package/dist/osa/projects.js.map +1 -0
- package/dist/osa/runtime.d.ts +19 -0
- package/dist/osa/runtime.d.ts.map +1 -0
- package/dist/osa/runtime.js +92 -0
- package/dist/osa/runtime.js.map +1 -0
- package/dist/osa/scaffold.d.ts +11 -0
- package/dist/osa/scaffold.d.ts.map +1 -0
- package/dist/osa/scaffold.js +245 -0
- package/dist/osa/scaffold.js.map +1 -0
- package/dist/osa/skills.d.ts +19 -0
- package/dist/osa/skills.d.ts.map +1 -0
- package/dist/osa/skills.js +55 -0
- package/dist/osa/skills.js.map +1 -0
- package/dist/osa/types.d.ts +157 -0
- package/dist/osa/types.d.ts.map +1 -0
- package/dist/osa/types.js +2 -0
- package/dist/osa/types.js.map +1 -0
- package/dist/osa/yaml.d.ts +7 -0
- package/dist/osa/yaml.d.ts.map +1 -0
- package/dist/osa/yaml.js +59 -0
- package/dist/osa/yaml.js.map +1 -0
- 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
|