@2kw/ai 6.0.0-dev.4 → 6.1.0-dev.7

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.
@@ -0,0 +1,177 @@
1
+ import { Command } from "commander";
2
+ import { getClient, runAction } from "../lib/client.js";
3
+ import { formatPage, formatDetail, formatList, formatSuccess } from "../lib/output.js";
4
+ import { addPaginationOptions, paginationParams } from "../lib/pagination.js";
5
+ export function makeInstallationsCommand() {
6
+ const cmd = new Command("installations").description("Manage surface installations");
7
+ const list = new Command("list").description("List installations");
8
+ addPaginationOptions(list);
9
+ list.option("-s, --search <term>", "Filter by name");
10
+ list.option("--status <status>", "Filter by status (PENDING, ACTIVE, DISABLED)");
11
+ list.option("--agent-id <id>", "Only installations of this agent");
12
+ list.action(async (opts, command) => {
13
+ await runAction(command, async () => {
14
+ const client = getClient(command);
15
+ const { data } = await client.GET("/v1/installations", {
16
+ params: {
17
+ query: {
18
+ search: opts.search,
19
+ status: opts.status,
20
+ agentId: opts.agentId,
21
+ ...paginationParams(opts),
22
+ },
23
+ },
24
+ });
25
+ formatPage(data, command, ["id", "name", "agentId", "status", "createdAt"]);
26
+ });
27
+ });
28
+ cmd.addCommand(list);
29
+ cmd
30
+ .command("get")
31
+ .description("Get an installation by ID")
32
+ .argument("<id>", "Installation ID")
33
+ .action(async (id, _opts, command) => {
34
+ await runAction(command, async () => {
35
+ const client = getClient(command);
36
+ const { data } = await client.GET("/v1/installations/{id}", {
37
+ params: { path: { id } },
38
+ });
39
+ formatDetail(data, command);
40
+ });
41
+ });
42
+ cmd
43
+ .command("create")
44
+ .description("Register an installation. Returns a one-time pairing string/code for the host to redeem at POST /v1/surface/enrol")
45
+ .requiredOption("-n, --name <name>", "Installation name")
46
+ .requiredOption("--agent-id <id>", "Agent this installation embeds")
47
+ .option("-d, --description <text>", "Description")
48
+ .action(async (opts, command) => {
49
+ await runAction(command, async () => {
50
+ const client = getClient(command);
51
+ const { data } = await client.POST("/v1/installations", {
52
+ body: { name: opts.name, agentId: opts.agentId, description: opts.description },
53
+ });
54
+ formatDetail(data, command);
55
+ });
56
+ });
57
+ cmd
58
+ .command("update")
59
+ .description("Update an installation's name, description, or status")
60
+ .argument("<id>", "Installation ID")
61
+ .option("-n, --name <name>", "New name")
62
+ .option("-d, --description <text>", "New description")
63
+ .option("--status <status>", "New status (PENDING, ACTIVE, DISABLED)")
64
+ .action(async (id, opts, command) => {
65
+ await runAction(command, async () => {
66
+ const client = getClient(command);
67
+ const body = {};
68
+ if (opts.name)
69
+ body.name = opts.name;
70
+ if (opts.description !== undefined)
71
+ body.description = opts.description;
72
+ if (opts.status)
73
+ body.status = opts.status;
74
+ const { data } = await client.PUT("/v1/installations/{id}", {
75
+ params: { path: { id } },
76
+ body: body,
77
+ });
78
+ formatDetail(data, command);
79
+ });
80
+ });
81
+ cmd
82
+ .command("embed-config")
83
+ .description("Read the unauthenticated embed configuration for an installation")
84
+ .argument("<id>", "Installation ID")
85
+ .option("--agent <agentId>", "Also resolve this agent's display name")
86
+ .action(async (id, opts, command) => {
87
+ await runAction(command, async () => {
88
+ const client = getClient(command);
89
+ const { data } = await client.GET("/v1/installations/{id}/embed-config", {
90
+ params: { path: { id }, query: { agent: opts.agent } },
91
+ });
92
+ formatDetail(data, command);
93
+ });
94
+ });
95
+ cmd
96
+ .command("pairing-code")
97
+ .description("Issue a fresh pairing code for an installation, valid ten minutes")
98
+ .argument("<id>", "Installation ID")
99
+ .action(async (id, _opts, command) => {
100
+ await runAction(command, async () => {
101
+ const client = getClient(command);
102
+ const { data } = await client.POST("/v1/installations/{id}/pairing-code", {
103
+ params: { path: { id } },
104
+ });
105
+ formatDetail(data, command);
106
+ });
107
+ });
108
+ const origins = new Command("origins").description("Manage an installation's embed origins");
109
+ origins
110
+ .command("replace")
111
+ .description("Replace the whole list of origins allowed to frame the embeddable panel")
112
+ .argument("<id>", "Installation ID")
113
+ .requiredOption("--origins <origins...>", "Origins allowed to embed (empty list revokes all)")
114
+ .action(async (id, opts, command) => {
115
+ await runAction(command, async () => {
116
+ const client = getClient(command);
117
+ const { data } = await client.PUT("/v1/installations/{id}/origins", {
118
+ params: { path: { id } },
119
+ body: { origins: opts.origins },
120
+ });
121
+ formatDetail(data, command);
122
+ });
123
+ });
124
+ cmd.addCommand(origins);
125
+ const keys = new Command("keys").description("Manage an installation's Ed25519 verification keys");
126
+ keys
127
+ .command("list")
128
+ .description("List every verification key registered for an installation")
129
+ .requiredOption("--installation <id>", "Installation ID")
130
+ .action(async (opts, command) => {
131
+ await runAction(command, async () => {
132
+ const client = getClient(command);
133
+ const { data } = await client.GET("/v1/installations/{id}/keys", {
134
+ params: { path: { id: opts.installation } },
135
+ });
136
+ formatList(data, command, [
137
+ "kid",
138
+ "publicKeyBase64",
139
+ "createdAt",
140
+ "revokedAt",
141
+ ]);
142
+ });
143
+ });
144
+ keys
145
+ .command("create")
146
+ .description("Register the public half of an Ed25519 keypair generated on the installation host")
147
+ .requiredOption("--installation <id>", "Installation ID")
148
+ .requiredOption("--kid <kid>", "Key id stamped into assertion headers")
149
+ .requiredOption("--public-key <base64>", "Public key, base64-encoded")
150
+ .action(async (opts, command) => {
151
+ await runAction(command, async () => {
152
+ const client = getClient(command);
153
+ const { data } = await client.POST("/v1/installations/{id}/keys", {
154
+ params: { path: { id: opts.installation } },
155
+ body: { kid: opts.kid, publicKeyBase64: opts.publicKey },
156
+ });
157
+ formatDetail(data, command);
158
+ });
159
+ });
160
+ keys
161
+ .command("delete")
162
+ .description("Revoke a verification key so it can no longer verify new assertions")
163
+ .argument("<kid>", "Key id")
164
+ .requiredOption("--installation <id>", "Installation ID")
165
+ .action(async (kid, opts, command) => {
166
+ await runAction(command, async () => {
167
+ const client = getClient(command);
168
+ await client.DELETE("/v1/installations/{id}/keys/{kid}", {
169
+ params: { path: { id: opts.installation, kid } },
170
+ });
171
+ formatSuccess(`Key ${kid} revoked.`, command);
172
+ });
173
+ });
174
+ cmd.addCommand(keys);
175
+ return cmd;
176
+ }
177
+ //# sourceMappingURL=installations.js.map
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function makeKnowledgeDocumentsCommand(): Command;
3
+ //# sourceMappingURL=knowledge-documents.d.ts.map
@@ -0,0 +1,155 @@
1
+ import { Command } from "commander";
2
+ import chalk from "chalk";
3
+ import { getClient, resolveAuthHeader, runAction } from "../lib/client.js";
4
+ import { resolveConfig, isJsonOutput } from "../lib/config.js";
5
+ import { BackboneApiError } from "../lib/errors.js";
6
+ import { formatPage, formatDetail, formatSuccess, withSpinner } from "../lib/output.js";
7
+ import { addPaginationOptions, paginationParams } from "../lib/pagination.js";
8
+ import { fileToBlob } from "../lib/multipart.js";
9
+ /**
10
+ * Upload one or more local files to a knowledge base. Bypasses the typed
11
+ * client the same way convert.ts's multipartConvert does: springdoc mis-shapes
12
+ * this endpoint's `files` parameter as a query array of binary strings, but the
13
+ * controller (`KnowledgeDocumentController.upload`) actually reads it off a
14
+ * multipart/form-data body with repeated "files" parts.
15
+ */
16
+ async function uploadDocuments(command, knowledgeBaseId, paths) {
17
+ const config = resolveConfig(command);
18
+ const authHeader = await resolveAuthHeader(config);
19
+ const formData = new FormData();
20
+ for (const p of paths) {
21
+ const { blob, filename } = fileToBlob(p);
22
+ formData.append("files", blob, filename);
23
+ }
24
+ const baseUrl = config.baseUrl.replace(/\/+$/, "");
25
+ const url = `${baseUrl}/v1/knowledge-bases/${encodeURIComponent(knowledgeBaseId)}/documents`;
26
+ const res = await fetch(url, {
27
+ method: "POST",
28
+ headers: { Authorization: authHeader },
29
+ body: formData,
30
+ });
31
+ if (!res.ok) {
32
+ let body;
33
+ try {
34
+ body = await res.json();
35
+ }
36
+ catch {
37
+ body = {
38
+ error: res.statusText,
39
+ message: `HTTP ${res.status}: ${res.statusText}`,
40
+ status: res.status,
41
+ timestamp: new Date().toISOString(),
42
+ };
43
+ }
44
+ throw new BackboneApiError(body);
45
+ }
46
+ return (await res.json());
47
+ }
48
+ function printUploadResults(results, command) {
49
+ if (isJsonOutput(command)) {
50
+ console.log(JSON.stringify(results, null, 2));
51
+ return;
52
+ }
53
+ for (const r of results) {
54
+ if (r.error) {
55
+ console.log(chalk.red(` ${r.filename ?? "(unknown)"}: rejected — ${r.error}`));
56
+ }
57
+ else {
58
+ const docId = r.upload?.document?.id;
59
+ const status = r.upload?.acceptedVersion?.status ?? "PENDING";
60
+ console.log(chalk.green(` ${r.filename ?? "(unknown)"}: accepted (document ${docId}, ${status})`));
61
+ }
62
+ }
63
+ }
64
+ export function makeKnowledgeDocumentsCommand() {
65
+ const cmd = new Command("documents").description("Manage a knowledge base's documents");
66
+ const list = new Command("list").description("List documents in a knowledge base");
67
+ addPaginationOptions(list);
68
+ list.requiredOption("--kb <id>", "Knowledge base ID");
69
+ list.option("--status <status>", "Filter by status (PENDING, PARSING, CHUNKING, EMBEDDING, READY, ERROR)");
70
+ list.action(async (opts, command) => {
71
+ await runAction(command, async () => {
72
+ const client = getClient(command);
73
+ const { data } = await client.GET("/v1/knowledge-bases/{knowledgeBaseId}/documents", {
74
+ params: {
75
+ path: { knowledgeBaseId: opts.kb },
76
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
77
+ query: { status: opts.status, ...paginationParams(opts) },
78
+ },
79
+ });
80
+ formatPage(data, command, ["id", "name", "currentVersionId", "sourceUri"]);
81
+ });
82
+ });
83
+ cmd.addCommand(list);
84
+ cmd
85
+ .command("get")
86
+ .description("Get a document by ID")
87
+ .argument("<documentId>", "Document ID")
88
+ .requiredOption("--kb <id>", "Knowledge base ID")
89
+ .action(async (documentId, opts, command) => {
90
+ await runAction(command, async () => {
91
+ const client = getClient(command);
92
+ const { data } = await client.GET("/v1/knowledge-bases/{knowledgeBaseId}/documents/{documentId}", { params: { path: { knowledgeBaseId: opts.kb, documentId } } });
93
+ formatDetail(data, command);
94
+ });
95
+ });
96
+ cmd
97
+ .command("upload")
98
+ .description("Upload one or more files for asynchronous ingestion")
99
+ .argument("<paths...>", "Local file paths")
100
+ .requiredOption("--kb <id>", "Knowledge base ID")
101
+ .action(async (paths, opts, command) => {
102
+ await runAction(command, async () => {
103
+ const results = await withSpinner("Uploading...", () => uploadDocuments(command, opts.kb, paths));
104
+ printUploadResults(results, command);
105
+ });
106
+ });
107
+ cmd
108
+ .command("attach")
109
+ .description("Ingest a file uploaded earlier with purpose=knowledge")
110
+ .requiredOption("--kb <id>", "Knowledge base ID")
111
+ .requiredOption("--file-id <id>", "File ID (from `2kw files upload --purpose knowledge`)")
112
+ .action(async (opts, command) => {
113
+ await runAction(command, async () => {
114
+ const client = getClient(command);
115
+ const { data } = await client.POST("/v1/knowledge-bases/{knowledgeBaseId}/documents/attach", {
116
+ params: { path: { knowledgeBaseId: opts.kb } },
117
+ body: { fileId: opts.fileId },
118
+ });
119
+ formatDetail(data, command);
120
+ });
121
+ });
122
+ cmd
123
+ .command("delete")
124
+ .description("Delete a document and take every revision out of retrieval")
125
+ .argument("<documentId>", "Document ID")
126
+ .requiredOption("--kb <id>", "Knowledge base ID")
127
+ .action(async (documentId, opts, command) => {
128
+ await runAction(command, async () => {
129
+ const client = getClient(command);
130
+ await client.DELETE("/v1/knowledge-bases/{knowledgeBaseId}/documents/{documentId}", { params: { path: { knowledgeBaseId: opts.kb, documentId } } });
131
+ formatSuccess(`Document ${documentId} deleted.`, command);
132
+ });
133
+ });
134
+ const versions = new Command("versions").description("Inspect a document's revisions");
135
+ versions
136
+ .command("get")
137
+ .description("Get a specific document revision")
138
+ .argument("<versionId>", "Version ID")
139
+ .requiredOption("--kb <id>", "Knowledge base ID")
140
+ .requiredOption("--document <id>", "Document ID")
141
+ .action(async (versionId, opts, command) => {
142
+ await runAction(command, async () => {
143
+ const client = getClient(command);
144
+ const { data } = await client.GET("/v1/knowledge-bases/{knowledgeBaseId}/documents/{documentId}/versions/{versionId}", {
145
+ params: {
146
+ path: { knowledgeBaseId: opts.kb, documentId: opts.document, versionId },
147
+ },
148
+ });
149
+ formatDetail(data, command);
150
+ });
151
+ });
152
+ cmd.addCommand(versions);
153
+ return cmd;
154
+ }
155
+ //# sourceMappingURL=knowledge-documents.js.map
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function makeKnowledgeCommand(): Command;
3
+ //# sourceMappingURL=knowledge.d.ts.map
@@ -0,0 +1,197 @@
1
+ import { Command } from "commander";
2
+ import chalk from "chalk";
3
+ import { getClient, runAction } from "../lib/client.js";
4
+ import { isJsonOutput } from "../lib/config.js";
5
+ import { formatPage, formatDetail, formatList, formatSuccess } from "../lib/output.js";
6
+ import { addPaginationOptions, paginationParams } from "../lib/pagination.js";
7
+ import { makeKnowledgeDocumentsCommand } from "./knowledge-documents.js";
8
+ export function makeKnowledgeCommand() {
9
+ const cmd = new Command("knowledge").description("Manage knowledge bases");
10
+ const list = new Command("list").description("List knowledge bases");
11
+ addPaginationOptions(list);
12
+ list.action(async (opts, command) => {
13
+ await runAction(command, async () => {
14
+ const client = getClient(command);
15
+ const { data } = await client.GET("/v1/knowledge-bases", {
16
+ params: { query: paginationParams(opts) },
17
+ });
18
+ formatPage(data, command, ["id", "name", "slug", "embeddingModel", "status", "createdAt"]);
19
+ });
20
+ });
21
+ cmd.addCommand(list);
22
+ cmd
23
+ .command("get")
24
+ .description("Get a knowledge base by ID")
25
+ .argument("<id>", "Knowledge base ID")
26
+ .action(async (id, _opts, command) => {
27
+ await runAction(command, async () => {
28
+ const client = getClient(command);
29
+ const { data } = await client.GET("/v1/knowledge-bases/{id}", {
30
+ params: { path: { id } },
31
+ });
32
+ formatDetail(data, command);
33
+ });
34
+ });
35
+ cmd
36
+ .command("create")
37
+ .description("Create a knowledge base and its first configuration version")
38
+ .requiredOption("-n, --name <name>", "Knowledge base name")
39
+ .requiredOption("--slug <slug>", "Unique slug")
40
+ .requiredOption("--embedding-provider <id>", "Embedding provider ID")
41
+ .requiredOption("--embedding-model <model>", "Embedding model")
42
+ .requiredOption("--embedding-dim <n>", "Embedding dimension", parseInt)
43
+ .option("-d, --description <text>", "Description")
44
+ .option("--chunking-strategy <strategy>", "Chunking strategy (AUTO, FIXED, HIERARCHICAL, CUSTOM)")
45
+ .option("--chunk-size <n>", "Chunk size", parseInt)
46
+ .option("--chunk-overlap <n>", "Chunk overlap", parseInt)
47
+ .option("--parent-chunk-size <n>", "Parent chunk size (hierarchical chunking)", parseInt)
48
+ .option("--reranker-provider <id>", "Reranker provider ID")
49
+ .option("--hybrid-search <bool>", "Enable hybrid search (true/false)")
50
+ .action(async (opts, command) => {
51
+ await runAction(command, async () => {
52
+ const client = getClient(command);
53
+ const { data } = await client.POST("/v1/knowledge-bases", {
54
+ body: {
55
+ name: opts.name,
56
+ slug: opts.slug,
57
+ embeddingProviderId: opts.embeddingProvider,
58
+ embeddingModel: opts.embeddingModel,
59
+ embeddingDim: opts.embeddingDim,
60
+ description: opts.description,
61
+ chunkingStrategy: opts.chunkingStrategy,
62
+ chunkSize: opts.chunkSize,
63
+ chunkOverlap: opts.chunkOverlap,
64
+ parentChunkSize: opts.parentChunkSize,
65
+ rerankerProviderId: opts.rerankerProvider,
66
+ hybridSearchEnabled: opts.hybridSearch !== undefined ? opts.hybridSearch === "true" : undefined,
67
+ },
68
+ });
69
+ formatDetail(data, command);
70
+ });
71
+ });
72
+ cmd
73
+ .command("update")
74
+ .description("Apply mutable fields and snapshot the result as the next configuration version")
75
+ .argument("<id>", "Knowledge base ID")
76
+ .option("-n, --name <name>", "New name")
77
+ .option("-d, --description <text>", "New description")
78
+ .option("--embedding-provider <id>", "New embedding provider ID")
79
+ .option("--embedding-model <model>", "New embedding model")
80
+ .option("--chunking-strategy <strategy>", "New chunking strategy (AUTO, FIXED, HIERARCHICAL, CUSTOM)")
81
+ .option("--chunk-size <n>", "New chunk size", parseInt)
82
+ .option("--chunk-overlap <n>", "New chunk overlap", parseInt)
83
+ .option("--parent-chunk-size <n>", "New parent chunk size", parseInt)
84
+ .option("--reranker-provider <id>", "New reranker provider ID")
85
+ .option("--hybrid-search <bool>", "Enable hybrid search (true/false)")
86
+ .action(async (id, opts, command) => {
87
+ await runAction(command, async () => {
88
+ const client = getClient(command);
89
+ const body = {};
90
+ if (opts.name)
91
+ body.name = opts.name;
92
+ if (opts.description !== undefined)
93
+ body.description = opts.description;
94
+ if (opts.embeddingProvider)
95
+ body.embeddingProviderId = opts.embeddingProvider;
96
+ if (opts.embeddingModel)
97
+ body.embeddingModel = opts.embeddingModel;
98
+ if (opts.chunkingStrategy)
99
+ body.chunkingStrategy = opts.chunkingStrategy;
100
+ if (opts.chunkSize !== undefined)
101
+ body.chunkSize = opts.chunkSize;
102
+ if (opts.chunkOverlap !== undefined)
103
+ body.chunkOverlap = opts.chunkOverlap;
104
+ if (opts.parentChunkSize !== undefined)
105
+ body.parentChunkSize = opts.parentChunkSize;
106
+ if (opts.rerankerProvider)
107
+ body.rerankerProviderId = opts.rerankerProvider;
108
+ if (opts.hybridSearch !== undefined)
109
+ body.hybridSearchEnabled = opts.hybridSearch === "true";
110
+ const { data } = await client.PATCH("/v1/knowledge-bases/{id}", {
111
+ params: { path: { id } },
112
+ body: body,
113
+ });
114
+ formatDetail(data, command);
115
+ });
116
+ });
117
+ cmd
118
+ .command("delete")
119
+ .description("Soft-delete a knowledge base, releasing its slug (requires admin role)")
120
+ .argument("<id>", "Knowledge base ID")
121
+ .action(async (id, _opts, command) => {
122
+ await runAction(command, async () => {
123
+ const client = getClient(command);
124
+ await client.DELETE("/v1/knowledge-bases/{id}", {
125
+ params: { path: { id } },
126
+ });
127
+ formatSuccess(`Knowledge base ${id} deleted.`, command);
128
+ });
129
+ });
130
+ cmd
131
+ .command("search")
132
+ .description("Hybrid dense + lexical search over a knowledge base")
133
+ .argument("<knowledgeBaseId>", "Knowledge base ID")
134
+ .requiredOption("-q, --query <text>", "Search query")
135
+ .option("--top-k <n>", "Number of results (clamped 1..100)", parseInt)
136
+ .option("--metadata-filter <json>", "Metadata filter as JSON")
137
+ .action(async (knowledgeBaseId, opts, command) => {
138
+ await runAction(command, async () => {
139
+ const client = getClient(command);
140
+ const { data } = await client.POST("/v1/knowledge-bases/{knowledgeBaseId}/search", {
141
+ params: { path: { knowledgeBaseId } },
142
+ body: {
143
+ query: opts.query,
144
+ topK: opts.topK,
145
+ metadataFilter: opts.metadataFilter ? JSON.parse(opts.metadataFilter) : undefined,
146
+ },
147
+ });
148
+ if (isJsonOutput(command)) {
149
+ console.log(JSON.stringify(data, null, 2));
150
+ return;
151
+ }
152
+ const result = data;
153
+ if (result?.degraded) {
154
+ console.log(chalk.yellow(`Degraded: ${result.degraded}`));
155
+ }
156
+ formatList(result?.hits, command, ["documentName", "pageStart", "pageEnd", "score", "content"]);
157
+ });
158
+ });
159
+ const citations = new Command("citations").description("Resolve knowledge-base citations");
160
+ citations
161
+ .command("get")
162
+ .description("Resolve the passage a citation points at")
163
+ .argument("<chunkId>", "Chunk ID")
164
+ .requiredOption("--kb <id>", "Knowledge base ID")
165
+ .action(async (chunkId, opts, command) => {
166
+ await runAction(command, async () => {
167
+ const client = getClient(command);
168
+ const { data } = await client.GET("/v1/knowledge-bases/{knowledgeBaseId}/citations/{chunkId}", { params: { path: { knowledgeBaseId: opts.kb, chunkId } } });
169
+ formatDetail(data, command);
170
+ });
171
+ });
172
+ cmd.addCommand(citations);
173
+ cmd
174
+ .command("embedding-models")
175
+ .description("List embedding models a provider serves that fit a provisioned dimension")
176
+ .argument("<providerId>", "Provider ID")
177
+ .action(async (providerId, _opts, command) => {
178
+ await runAction(command, async () => {
179
+ const client = getClient(command);
180
+ const { data } = await client.GET("/v1/providers/{providerId}/embedding-models", {
181
+ params: { path: { providerId } },
182
+ });
183
+ if (isJsonOutput(command)) {
184
+ console.log(JSON.stringify(data, null, 2));
185
+ return;
186
+ }
187
+ const result = data;
188
+ formatList(result?.models, command, ["id", "dimensions"]);
189
+ if (result?.supportedDimensions?.length) {
190
+ console.log(chalk.dim(`Supported dimensions: ${result.supportedDimensions.join(", ")}`));
191
+ }
192
+ });
193
+ });
194
+ cmd.addCommand(makeKnowledgeDocumentsCommand());
195
+ return cmd;
196
+ }
197
+ //# sourceMappingURL=knowledge.js.map
@@ -1,6 +1,6 @@
1
1
  import { Command } from "commander";
2
2
  import { getClient, runAction } from "../lib/client.js";
3
- import { formatPage, formatDetail } from "../lib/output.js";
3
+ import { formatPage, formatDetail, formatSuccess } from "../lib/output.js";
4
4
  import { addPaginationOptions, paginationParams } from "../lib/pagination.js";
5
5
  export function makePromptVersionsCommand() {
6
6
  const cmd = new Command("versions").description("Manage prompt versions");
@@ -32,6 +32,29 @@ export function makePromptVersionsCommand() {
32
32
  formatDetail(data, command);
33
33
  });
34
34
  });
35
+ cmd
36
+ .command("latest")
37
+ .description("Get the latest version of a prompt")
38
+ .requiredOption("--prompt <id>", "Prompt ID")
39
+ .action(async (opts, command) => {
40
+ await runAction(command, async () => {
41
+ const client = getClient(command);
42
+ const { data } = await client.GET("/v1/prompts/{promptId}/versions/latest", { params: { path: { promptId: opts.prompt } } });
43
+ formatDetail(data, command);
44
+ });
45
+ });
46
+ cmd
47
+ .command("delete")
48
+ .description("Delete (deactivate) a prompt version")
49
+ .argument("<versionId>", "Version ID")
50
+ .requiredOption("--prompt <id>", "Prompt ID")
51
+ .action(async (versionId, opts, command) => {
52
+ await runAction(command, async () => {
53
+ const client = getClient(command);
54
+ await client.DELETE("/v1/prompts/{promptId}/versions/{versionId}", { params: { path: { promptId: opts.prompt, versionId } } });
55
+ formatSuccess(`Prompt version ${versionId} deleted.`, command);
56
+ });
57
+ });
35
58
  cmd
36
59
  .command("create")
37
60
  .description("Create a new prompt version")
@@ -88,6 +88,44 @@ export function makeProvidersCommand() {
88
88
  formatSuccess(`Provider ${id} deleted.`, command);
89
89
  });
90
90
  });
91
+ cmd
92
+ .command("all")
93
+ .description("List all providers, unpaginated")
94
+ .action(async (_opts, command) => {
95
+ await runAction(command, async () => {
96
+ const client = getClient(command);
97
+ const { data } = await client.GET("/v1/providers/all");
98
+ formatList(data, command, [
99
+ "id",
100
+ "name",
101
+ "provider",
102
+ "enabled",
103
+ "createdAt",
104
+ ]);
105
+ });
106
+ });
107
+ cmd
108
+ .command("test")
109
+ .description("Test connection to an AI provider using given or stored credentials")
110
+ .requiredOption("--type <type>", "Provider type (openai, azure_openai, anthropic, xai, mistral, vertex_ai, ollama)")
111
+ .option("--provider-api-key <key>", "API key to test (omit to use --provider-id's stored key)")
112
+ .option("--provider-id <id>", "Existing provider ID whose stored credentials should be used")
113
+ .option("-c, --config <json>", "Provider config as JSON")
114
+ .action(async (opts, command) => {
115
+ await runAction(command, async () => {
116
+ const client = getClient(command);
117
+ const config = opts.config ? JSON.parse(opts.config) : {};
118
+ const { data } = await client.POST("/v1/providers/test", {
119
+ body: {
120
+ provider: opts.type.toUpperCase(),
121
+ apiKey: opts.providerApiKey,
122
+ providerId: opts.providerId,
123
+ config,
124
+ },
125
+ });
126
+ formatDetail(data, command);
127
+ });
128
+ });
91
129
  cmd
92
130
  .command("models")
93
131
  .description("List available models across all providers")
@@ -1,6 +1,6 @@
1
1
  import { Command } from "commander";
2
2
  import { getClient, runAction } from "../lib/client.js";
3
- import { formatPage, formatDetail } from "../lib/output.js";
3
+ import { formatPage, formatDetail, formatSuccess } from "../lib/output.js";
4
4
  import { addPaginationOptions, paginationParams } from "../lib/pagination.js";
5
5
  export function makeSchemaVersionsCommand() {
6
6
  const cmd = new Command("versions").description("Manage schema versions");
@@ -32,6 +32,29 @@ export function makeSchemaVersionsCommand() {
32
32
  formatDetail(data, command);
33
33
  });
34
34
  });
35
+ cmd
36
+ .command("latest")
37
+ .description("Get the latest active version of a schema")
38
+ .requiredOption("--schema <id>", "Schema ID")
39
+ .action(async (opts, command) => {
40
+ await runAction(command, async () => {
41
+ const client = getClient(command);
42
+ const { data } = await client.GET("/v1/schemas/{schemaId}/versions/latest", { params: { path: { schemaId: opts.schema } } });
43
+ formatDetail(data, command);
44
+ });
45
+ });
46
+ cmd
47
+ .command("delete")
48
+ .description("Delete (deactivate) a schema version")
49
+ .argument("<versionId>", "Version ID")
50
+ .requiredOption("--schema <id>", "Schema ID")
51
+ .action(async (versionId, opts, command) => {
52
+ await runAction(command, async () => {
53
+ const client = getClient(command);
54
+ await client.DELETE("/v1/schemas/{schemaId}/versions/{versionId}", { params: { path: { schemaId: opts.schema, versionId } } });
55
+ formatSuccess(`Schema version ${versionId} deleted.`, command);
56
+ });
57
+ });
35
58
  cmd
36
59
  .command("create")
37
60
  .description("Create a new schema version")