@otto-code/cli 0.8.18 → 0.9.0

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 (78) hide show
  1. package/bin/otto +2 -2
  2. package/dist/cli.js +13 -0
  3. package/dist/commands/architectural-view/deliver.d.ts +18 -0
  4. package/dist/commands/architectural-view/deliver.js +60 -0
  5. package/dist/commands/architectural-view/draft.d.ts +33 -0
  6. package/dist/commands/architectural-view/draft.js +128 -0
  7. package/dist/commands/architectural-view/index.d.ts +3 -0
  8. package/dist/commands/architectural-view/index.js +48 -0
  9. package/dist/commands/architectural-view/shared.d.ts +7 -0
  10. package/dist/commands/architectural-view/shared.js +27 -0
  11. package/dist/commands/artifact/cancel.d.ts +13 -0
  12. package/dist/commands/artifact/cancel.js +38 -0
  13. package/dist/commands/artifact/create.d.ts +21 -0
  14. package/dist/commands/artifact/create.js +56 -0
  15. package/dist/commands/artifact/get-data.d.ts +5 -0
  16. package/dist/commands/artifact/get-data.js +24 -0
  17. package/dist/commands/artifact/index.d.ts +3 -0
  18. package/dist/commands/artifact/index.js +55 -0
  19. package/dist/commands/artifact/ls.d.ts +20 -0
  20. package/dist/commands/artifact/ls.js +72 -0
  21. package/dist/commands/artifact/move.d.ts +15 -0
  22. package/dist/commands/artifact/move.js +41 -0
  23. package/dist/commands/artifact/regenerate.d.ts +12 -0
  24. package/dist/commands/artifact/regenerate.js +32 -0
  25. package/dist/commands/artifact/repair.d.ts +13 -0
  26. package/dist/commands/artifact/repair.js +38 -0
  27. package/dist/commands/artifact/shared.d.ts +10 -0
  28. package/dist/commands/artifact/shared.js +62 -0
  29. package/dist/commands/artifact/update-data.d.ts +13 -0
  30. package/dist/commands/artifact/update-data.js +43 -0
  31. package/dist/commands/daemon/index.js +3 -1
  32. package/dist/commands/daemon/reload.d.ts +10 -0
  33. package/dist/commands/daemon/reload.js +36 -0
  34. package/dist/commands/hub/daemon-client.d.ts +7 -0
  35. package/dist/commands/hub/hub-client/index.d.ts +3 -2
  36. package/dist/commands/hub/hub-client/index.js +12 -1
  37. package/dist/commands/hub/hub-client/internal/contracts.d.ts +17 -0
  38. package/dist/commands/hub/hub-client/internal/contracts.js +14 -0
  39. package/dist/commands/hub/index.js +3 -1
  40. package/dist/commands/hub/init-plan.d.ts +3 -0
  41. package/dist/commands/hub/init-plan.js +8 -4
  42. package/dist/commands/hub/init.d.ts +18 -3
  43. package/dist/commands/hub/init.js +218 -78
  44. package/dist/commands/hub/login.d.ts +2 -0
  45. package/dist/commands/hub/login.js +8 -2
  46. package/dist/commands/hub/starter-agent-runtime.d.ts +37 -0
  47. package/dist/commands/hub/starter-agent-runtime.js +49 -0
  48. package/dist/commands/hub/starter-trigger.d.ts +10 -0
  49. package/dist/commands/hub/starter-trigger.js +28 -0
  50. package/dist/commands/plugin/index.d.ts +14 -0
  51. package/dist/commands/plugin/index.js +84 -0
  52. package/dist/commands/plugin/scaffold.d.ts +6 -0
  53. package/dist/commands/plugin/scaffold.js +329 -0
  54. package/dist/commands/plugin/shared.d.ts +4 -0
  55. package/dist/commands/plugin/shared.js +26 -0
  56. package/dist/commands/project/create.d.ts +10 -0
  57. package/dist/commands/project/create.js +41 -0
  58. package/dist/commands/project/delete.d.ts +9 -0
  59. package/dist/commands/project/delete.js +33 -0
  60. package/dist/commands/project/index.d.ts +3 -0
  61. package/dist/commands/project/index.js +28 -0
  62. package/dist/commands/project/ls.d.ts +5 -0
  63. package/dist/commands/project/ls.js +19 -0
  64. package/dist/commands/project/rename.d.ts +15 -0
  65. package/dist/commands/project/rename.js +50 -0
  66. package/dist/commands/project/shared.d.ts +11 -0
  67. package/dist/commands/project/shared.js +18 -0
  68. package/dist/commands/schedule/shared.js +3 -0
  69. package/dist/commands/schedule/types.d.ts +4 -0
  70. package/dist/commands/workflow/graph.d.ts +85 -0
  71. package/dist/commands/workflow/graph.js +462 -0
  72. package/dist/commands/workflow/index.d.ts +3 -0
  73. package/dist/commands/workflow/index.js +43 -0
  74. package/dist/output/index.d.ts +1 -1
  75. package/dist/output/pairing.js +1 -1
  76. package/dist/output/render.js +6 -0
  77. package/dist/output/types.d.ts +14 -0
  78. package/package.json +5 -5
package/bin/otto CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env -S node --disable-warning=DEP0040
2
- import '../dist/index.js'
3
-
2
+ import '../dist/index.js'
3
+
package/dist/cli.js CHANGED
@@ -3,13 +3,18 @@ import { createAgentCommand } from "./commands/agent/index.js";
3
3
  import { createDaemonCommand } from "./commands/daemon/index.js";
4
4
  import { createPermitCommand } from "./commands/permit/index.js";
5
5
  import { createProviderCommand } from "./commands/provider/index.js";
6
+ import { createPluginCommand } from "./commands/plugin/index.js";
7
+ import { createProjectCommand } from "./commands/project/index.js";
6
8
  import { createScheduleCommand } from "./commands/schedule/index.js";
7
9
  import { createSpeechCommand } from "./commands/speech/index.js";
8
10
  import { createScriptCommand } from "./commands/script/index.js";
9
11
  import { createTerminalCommand } from "./commands/terminal/index.js";
10
12
  import { createWorktreeCommand } from "./commands/worktree/index.js";
11
13
  import { createWorkspaceCommand } from "./commands/workspace/index.js";
14
+ import { createWorkflowCommand } from "./commands/workflow/index.js";
12
15
  import { createHeartbeatCommand } from "./commands/heartbeat/index.js";
16
+ import { createArtifactCommand } from "./commands/artifact/index.js";
17
+ import { createArchitecturalViewCommand } from "./commands/architectural-view/index.js";
13
18
  // DISABLED(hub): specifier redirected away from "./commands/hub/index.js".
14
19
  import { createHubCommand } from "./commands/hub-disabled.js";
15
20
  import { createHooksCommand } from "./commands/hooks.js";
@@ -17,6 +22,7 @@ import { createBrainCommand } from "@otto-code/brain";
17
22
  import { startCommand as daemonStartCommand } from "./commands/daemon/start.js";
18
23
  import { runStatusCommand as runDaemonStatusCommand } from "./commands/daemon/status.js";
19
24
  import { runRestartCommand as runDaemonRestartCommand } from "./commands/daemon/restart.js";
25
+ import { runDaemonReloadCommand } from "./commands/daemon/reload.js";
20
26
  import { addLsOptions, runLsCommand } from "./commands/agent/ls.js";
21
27
  import { addRunOptions, runRunCommand } from "./commands/agent/run.js";
22
28
  import { addLogsOptions, runLogsCommand } from "./commands/agent/logs.js";
@@ -81,6 +87,7 @@ export function createCli() {
81
87
  .description('Show local daemon status (alias for "otto daemon status")'))
82
88
  .option("--home <path>", "Otto home directory (default: ~/.otto)")
83
89
  .action(withOutput(runDaemonStatusCommand));
90
+ addJsonAndDaemonHostOptions(program.command("reload").description('Reload daemon config (alias for "otto daemon reload")')).action(withOutput(runDaemonReloadCommand));
84
91
  addJsonOption(program
85
92
  .command("restart")
86
93
  .description('Restart local daemon (alias for "otto daemon restart")'))
@@ -114,14 +121,20 @@ export function createCli() {
114
121
  // Schedule commands
115
122
  program.addCommand(createScheduleCommand());
116
123
  program.addCommand(createHeartbeatCommand());
124
+ program.addCommand(createArtifactCommand());
125
+ program.addCommand(createArchitecturalViewCommand());
117
126
  // Permission commands
118
127
  program.addCommand(createPermitCommand());
119
128
  // Provider commands
120
129
  program.addCommand(createProviderCommand());
130
+ program.addCommand(createPluginCommand());
121
131
  // Speech model commands
122
132
  program.addCommand(createSpeechCommand());
123
133
  // Workspace commands
134
+ program.addCommand(createProjectCommand());
124
135
  program.addCommand(createWorkspaceCommand());
136
+ // Workflow commands
137
+ program.addCommand(createWorkflowCommand());
125
138
  // COMPAT(worktreeCli): legacy command alias added before workspace was the product unit.
126
139
  // Added in v0.2.0; remove after 2027-01-17.
127
140
  program.addCommand(createWorktreeCommand(), { hidden: true });
@@ -0,0 +1,18 @@
1
+ import type { Command } from "commander";
2
+ import type { SingleResult } from "../../output/index.js";
3
+ import { type ArchitecturalViewCommandOptions } from "./shared.js";
4
+ interface DeliverArchitecturalViewOptions extends ArchitecturalViewCommandOptions {
5
+ workspace?: string;
6
+ source?: string;
7
+ title?: string;
8
+ link?: string[];
9
+ quality?: "standard" | "showcase";
10
+ }
11
+ interface DeliveredArchitecturalViewResult {
12
+ id: string;
13
+ location: "repository" | "host" | null;
14
+ htmlPath: string | null;
15
+ }
16
+ export declare function runDeliverArchitecturalViewCommand(viewId: string, options: DeliverArchitecturalViewOptions, _command: Command): Promise<SingleResult<DeliveredArchitecturalViewResult>>;
17
+ export {};
18
+ //# sourceMappingURL=deliver.d.ts.map
@@ -0,0 +1,60 @@
1
+ import { connectArchitecturalViewsClient } from "./shared.js";
2
+ const deliveredArchitecturalViewSchema = {
3
+ idField: "id",
4
+ columns: [
5
+ { header: "ID", field: "id", width: 24 },
6
+ { header: "STORED", field: "location", width: 14 },
7
+ { header: "HTML", field: "htmlPath", width: 48 },
8
+ ],
9
+ };
10
+ function requiredOption(value, option) {
11
+ const trimmed = value?.trim();
12
+ if (!trimmed)
13
+ throw { code: "MISSING_ARCHITECTURAL_VIEW_OPTION", message: `${option} is required.` };
14
+ return trimmed;
15
+ }
16
+ function parseKnowledgeReferences(values) {
17
+ const references = values ?? [];
18
+ if (references.length === 0) {
19
+ throw {
20
+ code: "MISSING_ARCHITECTURAL_VIEW_LINK",
21
+ message: "At least one --link root:<id> or record:<id> is required.",
22
+ };
23
+ }
24
+ return references.map((value) => {
25
+ const separator = value.indexOf(":");
26
+ const kind = value.slice(0, separator);
27
+ const id = value.slice(separator + 1).trim();
28
+ if ((kind !== "root" && kind !== "record") || !id) {
29
+ throw {
30
+ code: "INVALID_ARCHITECTURAL_VIEW_LINK",
31
+ message: `Invalid Knowledge link "${value}". Use root:<id> or record:<id>.`,
32
+ };
33
+ }
34
+ return { kind, id };
35
+ });
36
+ }
37
+ export async function runDeliverArchitecturalViewCommand(viewId, options, _command) {
38
+ const client = await connectArchitecturalViewsClient(options.host);
39
+ try {
40
+ const payload = await client.deliverArchitecturalView({
41
+ workspaceId: requiredOption(options.workspace, "--workspace"),
42
+ viewId: requiredOption(viewId, "Architectural View ID"),
43
+ title: requiredOption(options.title, "--title"),
44
+ sourcePath: requiredOption(options.source, "--source"),
45
+ knowledgeReferences: parseKnowledgeReferences(options.link),
46
+ ...(options.quality ? { quality: options.quality } : {}),
47
+ });
48
+ if (!payload.success)
49
+ throw new Error(payload.error ?? "Architectural View delivery failed.");
50
+ return {
51
+ type: "single",
52
+ data: { id: payload.viewId, location: payload.storeLocation, htmlPath: payload.htmlPath },
53
+ schema: deliveredArchitecturalViewSchema,
54
+ };
55
+ }
56
+ finally {
57
+ await client.close().catch(() => { });
58
+ }
59
+ }
60
+ //# sourceMappingURL=deliver.js.map
@@ -0,0 +1,33 @@
1
+ import type { Command } from "commander";
2
+ import type { SingleResult } from "../../output/index.js";
3
+ import { type ArchitecturalViewCommandOptions } from "./shared.js";
4
+ interface DraftCreateOptions extends ArchitecturalViewCommandOptions {
5
+ workspace?: string;
6
+ title?: string;
7
+ link?: string[];
8
+ source?: string;
9
+ quality?: "standard" | "showcase";
10
+ }
11
+ interface DraftOperationOptions extends ArchitecturalViewCommandOptions {
12
+ workspace?: string;
13
+ }
14
+ interface DraftResult {
15
+ id: string;
16
+ viewId: string;
17
+ updatedAt: string;
18
+ }
19
+ interface PublishResult {
20
+ id: string;
21
+ htmlPath: string;
22
+ renderedAt: string;
23
+ }
24
+ interface DiscardResult {
25
+ id: string;
26
+ discarded: boolean;
27
+ }
28
+ export declare function runDraftCreate(viewId: string, draftId: string, options: DraftCreateOptions, _command: Command): Promise<SingleResult<DraftResult>>;
29
+ export declare function runDraftPublish(viewId: string, draftId: string, options: DraftOperationOptions, _command: Command): Promise<SingleResult<PublishResult>>;
30
+ export declare function runDraftUpdate(viewId: string, draftId: string, options: DraftCreateOptions, _command: Command): Promise<SingleResult<DraftResult>>;
31
+ export declare function runDraftDiscard(viewId: string, draftId: string, options: DraftOperationOptions, _command: Command): Promise<SingleResult<DiscardResult>>;
32
+ export {};
33
+ //# sourceMappingURL=draft.d.ts.map
@@ -0,0 +1,128 @@
1
+ import { connectArchitecturalViewsClient } from "./shared.js";
2
+ const draftSchema = {
3
+ idField: "id",
4
+ columns: [
5
+ { header: "DRAFT", field: "id", width: 24 },
6
+ { header: "VIEW", field: "viewId", width: 24 },
7
+ { header: "UPDATED", field: "updatedAt", width: 24 },
8
+ ],
9
+ };
10
+ const publishSchema = {
11
+ idField: "id",
12
+ columns: [
13
+ { header: "VIEW", field: "id", width: 24 },
14
+ { header: "HTML", field: "htmlPath", width: 48 },
15
+ { header: "PUBLISHED", field: "renderedAt", width: 24 },
16
+ ],
17
+ };
18
+ const discardSchema = {
19
+ idField: "id",
20
+ columns: [
21
+ { header: "DRAFT", field: "id", width: 24 },
22
+ { header: "DISCARDED", field: "discarded", width: 12 },
23
+ ],
24
+ };
25
+ function required(value, option) {
26
+ if (!value?.trim())
27
+ throw new Error(`${option} is required.`);
28
+ return value.trim();
29
+ }
30
+ function links(values) {
31
+ const result = values ?? [];
32
+ if (!result.length)
33
+ throw new Error("At least one --link root:<id> or record:<id> is required.");
34
+ return result.map((value) => {
35
+ const [kind, ...parts] = value.split(":");
36
+ const id = parts.join(":").trim();
37
+ if ((kind !== "root" && kind !== "record") || !id)
38
+ throw new Error(`Invalid Knowledge link "${value}".`);
39
+ return { kind, id };
40
+ });
41
+ }
42
+ export async function runDraftCreate(viewId, draftId, options, _command) {
43
+ const client = await connectArchitecturalViewsClient(options.host);
44
+ try {
45
+ const result = await client.createArchitecturalViewDraft({
46
+ workspaceId: required(options.workspace, "--workspace"),
47
+ viewId,
48
+ draftId,
49
+ title: required(options.title, "--title"),
50
+ knowledgeReferences: links(options.link),
51
+ ...(options.source ? { sourcePath: options.source } : {}),
52
+ ...(options.quality ? { quality: options.quality } : {}),
53
+ });
54
+ if (!result.success || !result.draft)
55
+ throw new Error(result.error ?? "Could not create Architectural View draft.");
56
+ return {
57
+ type: "single",
58
+ data: { id: result.draft.id, viewId: result.draft.viewId, updatedAt: result.draft.updatedAt },
59
+ schema: draftSchema,
60
+ };
61
+ }
62
+ finally {
63
+ await client.close().catch(() => { });
64
+ }
65
+ }
66
+ export async function runDraftPublish(viewId, draftId, options, _command) {
67
+ const client = await connectArchitecturalViewsClient(options.host);
68
+ try {
69
+ const result = await client.publishArchitecturalViewDraft({
70
+ workspaceId: required(options.workspace, "--workspace"),
71
+ viewId,
72
+ draftId,
73
+ });
74
+ if (!result.success || !result.view)
75
+ throw new Error(result.error ?? "Could not publish Architectural View draft.");
76
+ return {
77
+ type: "single",
78
+ data: {
79
+ id: result.view.id,
80
+ htmlPath: result.view.htmlPath,
81
+ renderedAt: result.view.renderedAt,
82
+ },
83
+ schema: publishSchema,
84
+ };
85
+ }
86
+ finally {
87
+ await client.close().catch(() => { });
88
+ }
89
+ }
90
+ export async function runDraftUpdate(viewId, draftId, options, _command) {
91
+ const client = await connectArchitecturalViewsClient(options.host);
92
+ try {
93
+ const result = await client.updateArchitecturalViewDraft({
94
+ workspaceId: required(options.workspace, "--workspace"),
95
+ viewId,
96
+ draftId,
97
+ sourcePath: required(options.source, "--source"),
98
+ ...(options.quality ? { quality: options.quality } : {}),
99
+ });
100
+ if (!result.success || !result.draft)
101
+ throw new Error(result.error ?? "Could not update Architectural View draft.");
102
+ return {
103
+ type: "single",
104
+ data: { id: result.draft.id, viewId: result.draft.viewId, updatedAt: result.draft.updatedAt },
105
+ schema: draftSchema,
106
+ };
107
+ }
108
+ finally {
109
+ await client.close().catch(() => { });
110
+ }
111
+ }
112
+ export async function runDraftDiscard(viewId, draftId, options, _command) {
113
+ const client = await connectArchitecturalViewsClient(options.host);
114
+ try {
115
+ const result = await client.discardArchitecturalViewDraft({
116
+ workspaceId: required(options.workspace, "--workspace"),
117
+ viewId,
118
+ draftId,
119
+ });
120
+ if (!result.success)
121
+ throw new Error(result.error ?? "Could not discard Architectural View draft.");
122
+ return { type: "single", data: { id: draftId, discarded: true }, schema: discardSchema };
123
+ }
124
+ finally {
125
+ await client.close().catch(() => { });
126
+ }
127
+ }
128
+ //# sourceMappingURL=draft.js.map
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function createArchitecturalViewCommand(): Command;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,48 @@
1
+ import { Command, Option } from "commander";
2
+ import { withOutput } from "../../output/index.js";
3
+ import { addJsonAndDaemonHostOptions } from "../../utils/command-options.js";
4
+ import { runDeliverArchitecturalViewCommand } from "./deliver.js";
5
+ import { runDraftCreate, runDraftDiscard, runDraftPublish, runDraftUpdate } from "./draft.js";
6
+ export function createArchitecturalViewCommand() {
7
+ const architecturalView = new Command("architectural-view").description("Create and inspect Knowledge-packaged Architectural Views");
8
+ addJsonAndDaemonHostOptions(architecturalView
9
+ .command("deliver")
10
+ .description("Validate and deliver a Knowledge-packaged Architectural View through the daemon")
11
+ .argument("<id>", "Stable Architectural View ID")
12
+ .requiredOption("--workspace <id>", "Workspace that owns the project Knowledge")
13
+ .requiredOption("--source <path>", "Workspace-relative Architecture JSON source")
14
+ .requiredOption("--title <text>", "Architectural View title")
15
+ .option("--link <kind:id>", "Knowledge link: root:<id> or record:<id>", (value, values) => values.concat(value), [])
16
+ .addOption(new Option("--quality <profile>").choices(["standard", "showcase"]))).action(withOutput(runDeliverArchitecturalViewCommand));
17
+ const draft = architecturalView
18
+ .command("draft")
19
+ .description("Manage staged Architectural View drafts");
20
+ addJsonAndDaemonHostOptions(draft
21
+ .command("create")
22
+ .argument("<view-id>")
23
+ .argument("<draft-id>")
24
+ .requiredOption("--workspace <id>")
25
+ .requiredOption("--title <text>")
26
+ .option("--source <path>")
27
+ .option("--link <kind:id>", "Knowledge link", (value, values) => values.concat(value), [])
28
+ .addOption(new Option("--quality <profile>").choices(["standard", "showcase"]))).action(withOutput(runDraftCreate));
29
+ addJsonAndDaemonHostOptions(draft
30
+ .command("update")
31
+ .argument("<view-id>")
32
+ .argument("<draft-id>")
33
+ .requiredOption("--workspace <id>")
34
+ .requiredOption("--source <path>")
35
+ .addOption(new Option("--quality <profile>").choices(["standard", "showcase"]))).action(withOutput(runDraftUpdate));
36
+ addJsonAndDaemonHostOptions(draft
37
+ .command("publish")
38
+ .argument("<view-id>")
39
+ .argument("<draft-id>")
40
+ .requiredOption("--workspace <id>")).action(withOutput(runDraftPublish));
41
+ addJsonAndDaemonHostOptions(draft
42
+ .command("discard")
43
+ .argument("<view-id>")
44
+ .argument("<draft-id>")
45
+ .requiredOption("--workspace <id>")).action(withOutput(runDraftDiscard));
46
+ return architecturalView;
47
+ }
48
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ import type { DaemonClient } from "@otto-code/client/internal/daemon-client";
2
+ import type { CommandOptions } from "../../output/index.js";
3
+ export interface ArchitecturalViewCommandOptions extends CommandOptions {
4
+ host?: string;
5
+ }
6
+ export declare function connectArchitecturalViewsClient(host?: string): Promise<DaemonClient>;
7
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1,27 @@
1
+ import { connectToDaemon, getDaemonHost } from "../../utils/client.js";
2
+ export async function connectArchitecturalViewsClient(host) {
3
+ const daemonHost = getDaemonHost({ host });
4
+ try {
5
+ const client = await connectToDaemon({ host });
6
+ // COMPAT(architecturalViews): added in v0.9.0, remove after 2027-02-28.
7
+ if (!client.getLastServerInfoMessage()?.features?.architecturalViews) {
8
+ await client.close().catch(() => { });
9
+ throw {
10
+ code: "DAEMON_UPDATE_REQUIRED",
11
+ message: "Update the host to use Architectural Views.",
12
+ };
13
+ }
14
+ return client;
15
+ }
16
+ catch (error) {
17
+ if (error && typeof error === "object" && "code" in error && "message" in error)
18
+ throw error;
19
+ const message = error instanceof Error ? error.message : String(error);
20
+ throw {
21
+ code: "DAEMON_NOT_RUNNING",
22
+ message: `Cannot connect to daemon at ${daemonHost}: ${message}`,
23
+ details: "Start the daemon with: otto daemon start",
24
+ };
25
+ }
26
+ }
27
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1,13 @@
1
+ import type { ArtifactMetadata } from "@otto-code/protocol/artifacts/types";
2
+ import type { Command } from "commander";
3
+ import type { SingleResult } from "../../output/index.js";
4
+ import { type ArtifactCommandOptions } from "./shared.js";
5
+ export interface CancelledArtifactResult {
6
+ id: string;
7
+ status: string;
8
+ updatedAt: string;
9
+ error: string | null;
10
+ }
11
+ export declare function toCancelledArtifactResult(artifact: ArtifactMetadata): CancelledArtifactResult;
12
+ export declare function runCancelCommand(id: string, options: ArtifactCommandOptions, _command: Command): Promise<SingleResult<CancelledArtifactResult>>;
13
+ //# sourceMappingURL=cancel.d.ts.map
@@ -0,0 +1,38 @@
1
+ import { connectArtifactClient, toArtifactCommandError, } from "./shared.js";
2
+ const cancelledArtifactSchema = {
3
+ idField: "id",
4
+ columns: [
5
+ { header: "ID", field: "id", width: 16 },
6
+ { header: "STATUS", field: "status", width: 12 },
7
+ { header: "UPDATED", field: "updatedAt", width: 24 },
8
+ { header: "RECOVERY", field: "error", width: 36 },
9
+ ],
10
+ };
11
+ export function toCancelledArtifactResult(artifact) {
12
+ return {
13
+ id: artifact.id,
14
+ status: artifact.status,
15
+ updatedAt: artifact.updatedAt,
16
+ error: artifact.errorMessage,
17
+ };
18
+ }
19
+ export async function runCancelCommand(id, options, _command) {
20
+ const client = await connectArtifactClient(options.host, "artifacts");
21
+ try {
22
+ const payload = await client.artifactCancel({ artifactId: id });
23
+ if (!payload.success)
24
+ throw new Error(payload.error ?? "Artifact cancellation failed");
25
+ return {
26
+ type: "single",
27
+ data: toCancelledArtifactResult(payload.artifact),
28
+ schema: cancelledArtifactSchema,
29
+ };
30
+ }
31
+ catch (error) {
32
+ throw toArtifactCommandError("ARTIFACT_CANCEL_FAILED", "cancel artifact generation", error);
33
+ }
34
+ finally {
35
+ await client.close().catch(() => { });
36
+ }
37
+ }
38
+ //# sourceMappingURL=cancel.js.map
@@ -0,0 +1,21 @@
1
+ import type { ArtifactMetadata } from "@otto-code/protocol/artifacts/types";
2
+ import type { Command } from "commander";
3
+ import type { SingleResult } from "../../output/index.js";
4
+ import { type ArtifactCommandOptions } from "./shared.js";
5
+ interface CreateArtifactOptions extends ArtifactCommandOptions {
6
+ project?: string;
7
+ provider?: string;
8
+ description?: string;
9
+ model?: string;
10
+ thinking?: string;
11
+ }
12
+ interface CreatedArtifactResult {
13
+ id: string;
14
+ status: string;
15
+ storageLocation: "repository" | "host" | null;
16
+ updatedAt: string;
17
+ }
18
+ export declare function toCreatedArtifactResult(artifact: ArtifactMetadata): CreatedArtifactResult;
19
+ export declare function runCreateCommand(name: string, options: CreateArtifactOptions, _command: Command): Promise<SingleResult<CreatedArtifactResult>>;
20
+ export {};
21
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1,56 @@
1
+ import { connectArtifactClient, toArtifactCommandError, } from "./shared.js";
2
+ const createdArtifactSchema = {
3
+ idField: "id",
4
+ columns: [
5
+ { header: "ID", field: "id", width: 16 },
6
+ { header: "STATUS", field: "status", width: 12 },
7
+ { header: "STORED", field: "storageLocation", width: 14 },
8
+ { header: "UPDATED", field: "updatedAt", width: 24 },
9
+ ],
10
+ };
11
+ function requiredOption(value, option) {
12
+ const trimmed = value?.trim();
13
+ if (!trimmed) {
14
+ throw { code: "MISSING_ARTIFACT_CREATE_OPTION", message: `${option} is required.` };
15
+ }
16
+ return trimmed;
17
+ }
18
+ export function toCreatedArtifactResult(artifact) {
19
+ return {
20
+ id: artifact.id,
21
+ status: artifact.status,
22
+ storageLocation: artifact.storageLocation ?? null,
23
+ updatedAt: artifact.updatedAt,
24
+ };
25
+ }
26
+ export async function runCreateCommand(name, options, _command) {
27
+ const projectId = requiredOption(options.project, "--project");
28
+ const provider = requiredOption(options.provider, "--provider");
29
+ const description = requiredOption(options.description, "--description");
30
+ const artifactName = requiredOption(name, "Artifact name");
31
+ const client = await connectArtifactClient(options.host, "artifacts");
32
+ try {
33
+ const payload = await client.artifactCreate({
34
+ name: artifactName,
35
+ description,
36
+ projectId,
37
+ provider,
38
+ ...(options.model?.trim() ? { model: options.model.trim() } : {}),
39
+ ...(options.thinking?.trim() ? { thinkingOptionId: options.thinking.trim() } : {}),
40
+ });
41
+ if (!payload.success)
42
+ throw new Error(payload.error ?? "Artifact creation failed");
43
+ return {
44
+ type: "single",
45
+ data: toCreatedArtifactResult(payload.artifact),
46
+ schema: createdArtifactSchema,
47
+ };
48
+ }
49
+ catch (error) {
50
+ throw toArtifactCommandError("ARTIFACT_CREATE_FAILED", "create artifact", error);
51
+ }
52
+ finally {
53
+ await client.close().catch(() => { });
54
+ }
55
+ }
56
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1,5 @@
1
+ import type { Command } from "commander";
2
+ import type { SingleResult } from "../../output/index.js";
3
+ import { type ArtifactCommandOptions } from "./shared.js";
4
+ export declare function runGetDataCommand(id: string, options: ArtifactCommandOptions, _command: Command): Promise<SingleResult<unknown>>;
5
+ //# sourceMappingURL=get-data.d.ts.map
@@ -0,0 +1,24 @@
1
+ import { connectArtifactClient, toArtifactCommandError, } from "./shared.js";
2
+ const artifactDataSchema = {
3
+ idField: () => "",
4
+ columns: [{ header: "DATA", field: (data) => JSON.stringify(data) }],
5
+ };
6
+ export async function runGetDataCommand(id, options, _command) {
7
+ const client = await connectArtifactClient(options.host, "data");
8
+ try {
9
+ const payload = await client.artifactGetData({ artifactId: id });
10
+ if (!payload.success)
11
+ throw new Error(payload.error ?? "Artifact data is unavailable");
12
+ if (payload.data === null) {
13
+ throw new Error("Artifact has no explicit data contract; regenerate it to add one");
14
+ }
15
+ return { type: "single", data: payload.data, schema: artifactDataSchema };
16
+ }
17
+ catch (error) {
18
+ throw toArtifactCommandError("ARTIFACT_DATA_GET_FAILED", "read artifact data", error);
19
+ }
20
+ finally {
21
+ await client.close().catch(() => { });
22
+ }
23
+ }
24
+ //# sourceMappingURL=get-data.js.map
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function createArtifactCommand(): Command;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,55 @@
1
+ import { Command } from "commander";
2
+ import { withOutput } from "../../output/index.js";
3
+ import { addJsonAndDaemonHostOptions } from "../../utils/command-options.js";
4
+ import { runCancelCommand } from "./cancel.js";
5
+ import { runCreateCommand } from "./create.js";
6
+ import { runGetDataCommand } from "./get-data.js";
7
+ import { runArtifactListCommand } from "./ls.js";
8
+ import { runMoveCommand } from "./move.js";
9
+ import { runRepairCommand } from "./repair.js";
10
+ import { runRegenerateCommand } from "./regenerate.js";
11
+ import { runUpdateDataCommand } from "./update-data.js";
12
+ export function createArtifactCommand() {
13
+ const artifact = new Command("artifact").description("Inspect and update durable artifacts");
14
+ addJsonAndDaemonHostOptions(artifact
15
+ .command("create")
16
+ .description("Create a durable artifact through the selected daemon host")
17
+ .argument("<name>")
18
+ .requiredOption("--project <root>", "Project root that owns the artifact")
19
+ .requiredOption("--provider <provider>", "Provider used for generation")
20
+ .requiredOption("--description <text>", "Self-contained deliverable description")
21
+ .option("--model <model>", "Optional provider model")
22
+ .option("--thinking <id>", "Optional provider thinking option")).action(withOutput(runCreateCommand));
23
+ addJsonAndDaemonHostOptions(artifact
24
+ .command("ls")
25
+ .description("List durable artifacts on the selected daemon host")
26
+ .option("--project <root>", "Limit to one project root (absolute path)")).action(withOutput(runArtifactListCommand));
27
+ addJsonAndDaemonHostOptions(artifact
28
+ .command("data")
29
+ .description("Read an artifact's explicit JSON data contract")
30
+ .argument("<id>")).action(withOutput(runGetDataCommand));
31
+ addJsonAndDaemonHostOptions(artifact
32
+ .command("update-data")
33
+ .description("Replace only an artifact's explicit JSON data contract without regenerating")
34
+ .argument("<id>")
35
+ .requiredOption("--data <json>", "Complete JSON replacement data")).action(withOutput(runUpdateDataCommand));
36
+ addJsonAndDaemonHostOptions(artifact
37
+ .command("cancel")
38
+ .description("Cancel a generating artifact and preserve any last known good output")
39
+ .argument("<id>")).action(withOutput(runCancelCommand));
40
+ addJsonAndDaemonHostOptions(artifact
41
+ .command("regenerate")
42
+ .description("Explicitly regenerate an artifact's visual output from its stored definition")
43
+ .argument("<id>")).action(withOutput(runRegenerateCommand));
44
+ addJsonAndDaemonHostOptions(artifact
45
+ .command("move")
46
+ .description("Move a settled artifact between repository and host storage")
47
+ .argument("<id>")
48
+ .requiredOption("--to <location>", "Destination: repository or host")).action(withOutput(runMoveCommand));
49
+ addJsonAndDaemonHostOptions(artifact
50
+ .command("repair")
51
+ .description("Restore an artifact's last known good output")
52
+ .argument("<id>")).action(withOutput(runRepairCommand));
53
+ return artifact;
54
+ }
55
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,20 @@
1
+ import type { Command } from "commander";
2
+ import type { ArtifactMetadata } from "@otto-code/protocol/artifacts/types";
3
+ import type { ListResult } from "../../output/index.js";
4
+ import { type ArtifactCommandOptions } from "./shared.js";
5
+ interface ArtifactListOptions extends ArtifactCommandOptions {
6
+ project?: string;
7
+ }
8
+ export interface ArtifactRow {
9
+ id: string;
10
+ name: string;
11
+ project: string;
12
+ stored: string;
13
+ source: string;
14
+ status: string;
15
+ updatedAt: string;
16
+ }
17
+ export declare function toArtifactRow(artifact: ArtifactMetadata): ArtifactRow;
18
+ export declare function runArtifactListCommand(options: ArtifactListOptions, _command: Command): Promise<ListResult<ArtifactRow>>;
19
+ export {};
20
+ //# sourceMappingURL=ls.d.ts.map