@otto-code/cli 0.8.19 → 0.9.2
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/bin/otto +2 -2
- package/dist/cli.js +13 -0
- package/dist/commands/architectural-view/deliver.d.ts +18 -0
- package/dist/commands/architectural-view/deliver.js +60 -0
- package/dist/commands/architectural-view/draft.d.ts +33 -0
- package/dist/commands/architectural-view/draft.js +128 -0
- package/dist/commands/architectural-view/index.d.ts +3 -0
- package/dist/commands/architectural-view/index.js +48 -0
- package/dist/commands/architectural-view/shared.d.ts +7 -0
- package/dist/commands/architectural-view/shared.js +27 -0
- package/dist/commands/artifact/cancel.d.ts +13 -0
- package/dist/commands/artifact/cancel.js +38 -0
- package/dist/commands/artifact/create.d.ts +21 -0
- package/dist/commands/artifact/create.js +56 -0
- package/dist/commands/artifact/get-data.d.ts +5 -0
- package/dist/commands/artifact/get-data.js +24 -0
- package/dist/commands/artifact/index.d.ts +3 -0
- package/dist/commands/artifact/index.js +55 -0
- package/dist/commands/artifact/ls.d.ts +20 -0
- package/dist/commands/artifact/ls.js +72 -0
- package/dist/commands/artifact/move.d.ts +15 -0
- package/dist/commands/artifact/move.js +41 -0
- package/dist/commands/artifact/regenerate.d.ts +12 -0
- package/dist/commands/artifact/regenerate.js +32 -0
- package/dist/commands/artifact/repair.d.ts +13 -0
- package/dist/commands/artifact/repair.js +38 -0
- package/dist/commands/artifact/shared.d.ts +10 -0
- package/dist/commands/artifact/shared.js +62 -0
- package/dist/commands/artifact/update-data.d.ts +13 -0
- package/dist/commands/artifact/update-data.js +43 -0
- package/dist/commands/daemon/index.js +3 -1
- package/dist/commands/daemon/reload.d.ts +10 -0
- package/dist/commands/daemon/reload.js +36 -0
- package/dist/commands/hub/daemon-client.d.ts +7 -0
- package/dist/commands/hub/hub-client/index.d.ts +3 -2
- package/dist/commands/hub/hub-client/index.js +12 -1
- package/dist/commands/hub/hub-client/internal/contracts.d.ts +17 -0
- package/dist/commands/hub/hub-client/internal/contracts.js +14 -0
- package/dist/commands/hub/index.js +3 -1
- package/dist/commands/hub/init-plan.d.ts +3 -0
- package/dist/commands/hub/init-plan.js +8 -4
- package/dist/commands/hub/init.d.ts +18 -3
- package/dist/commands/hub/init.js +218 -78
- package/dist/commands/hub/login.d.ts +2 -0
- package/dist/commands/hub/login.js +8 -2
- package/dist/commands/hub/starter-agent-runtime.d.ts +37 -0
- package/dist/commands/hub/starter-agent-runtime.js +49 -0
- package/dist/commands/hub/starter-trigger.d.ts +10 -0
- package/dist/commands/hub/starter-trigger.js +28 -0
- package/dist/commands/plugin/index.d.ts +14 -0
- package/dist/commands/plugin/index.js +84 -0
- package/dist/commands/plugin/scaffold.d.ts +6 -0
- package/dist/commands/plugin/scaffold.js +329 -0
- package/dist/commands/plugin/shared.d.ts +4 -0
- package/dist/commands/plugin/shared.js +26 -0
- package/dist/commands/project/create.d.ts +10 -0
- package/dist/commands/project/create.js +41 -0
- package/dist/commands/project/delete.d.ts +9 -0
- package/dist/commands/project/delete.js +33 -0
- package/dist/commands/project/index.d.ts +3 -0
- package/dist/commands/project/index.js +28 -0
- package/dist/commands/project/ls.d.ts +5 -0
- package/dist/commands/project/ls.js +19 -0
- package/dist/commands/project/rename.d.ts +15 -0
- package/dist/commands/project/rename.js +50 -0
- package/dist/commands/project/shared.d.ts +11 -0
- package/dist/commands/project/shared.js +18 -0
- package/dist/commands/schedule/shared.js +3 -0
- package/dist/commands/schedule/types.d.ts +4 -0
- package/dist/commands/workflow/graph.d.ts +85 -0
- package/dist/commands/workflow/graph.js +462 -0
- package/dist/commands/workflow/index.d.ts +3 -0
- package/dist/commands/workflow/index.js +43 -0
- package/dist/output/index.d.ts +1 -1
- package/dist/output/pairing.js +1 -1
- package/dist/output/render.js +6 -0
- package/dist/output/types.d.ts +14 -0
- 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,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,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
|