@2kw/ai 8.0.0-dev.4 → 8.0.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.
- package/dist/agent-config/schema.d.ts +50 -0
- package/dist/agent-config/schema.js +17 -0
- package/dist/agent-config/template.js +2 -0
- package/dist/commands/files.js +21 -6
- package/dist/commands/knowledge.js +16 -1
- package/dist/commands/skills.js +10 -2
- package/dist/index.js +17 -2
- package/dist/lib/agent-run.d.ts +14 -1
- package/dist/lib/agent-run.js +66 -1
- package/dist/lib/skill-bundle.js +4 -3
- package/package.json +1 -1
|
@@ -301,6 +301,32 @@ export declare const agentSchema: {
|
|
|
301
301
|
};
|
|
302
302
|
};
|
|
303
303
|
};
|
|
304
|
+
readonly showTableTool: {
|
|
305
|
+
readonly type: "object";
|
|
306
|
+
readonly additionalProperties: false;
|
|
307
|
+
readonly required: readonly ["type"];
|
|
308
|
+
readonly properties: {
|
|
309
|
+
readonly type: {
|
|
310
|
+
readonly const: "backbone.show_table";
|
|
311
|
+
};
|
|
312
|
+
readonly requiresConfirmation: {
|
|
313
|
+
readonly type: "boolean";
|
|
314
|
+
};
|
|
315
|
+
};
|
|
316
|
+
};
|
|
317
|
+
readonly showChartTool: {
|
|
318
|
+
readonly type: "object";
|
|
319
|
+
readonly additionalProperties: false;
|
|
320
|
+
readonly required: readonly ["type"];
|
|
321
|
+
readonly properties: {
|
|
322
|
+
readonly type: {
|
|
323
|
+
readonly const: "backbone.show_chart";
|
|
324
|
+
};
|
|
325
|
+
readonly requiresConfirmation: {
|
|
326
|
+
readonly type: "boolean";
|
|
327
|
+
};
|
|
328
|
+
};
|
|
329
|
+
};
|
|
304
330
|
readonly skillTool: {
|
|
305
331
|
readonly type: "object";
|
|
306
332
|
readonly additionalProperties: false;
|
|
@@ -493,6 +519,30 @@ export declare const agentSchema: {
|
|
|
493
519
|
readonly then: {
|
|
494
520
|
readonly $ref: "#/$defs/bashTool";
|
|
495
521
|
};
|
|
522
|
+
}, {
|
|
523
|
+
readonly if: {
|
|
524
|
+
required: string[];
|
|
525
|
+
properties: {
|
|
526
|
+
type: {
|
|
527
|
+
const: string;
|
|
528
|
+
};
|
|
529
|
+
};
|
|
530
|
+
};
|
|
531
|
+
readonly then: {
|
|
532
|
+
readonly $ref: "#/$defs/showTableTool";
|
|
533
|
+
};
|
|
534
|
+
}, {
|
|
535
|
+
readonly if: {
|
|
536
|
+
required: string[];
|
|
537
|
+
properties: {
|
|
538
|
+
type: {
|
|
539
|
+
const: string;
|
|
540
|
+
};
|
|
541
|
+
};
|
|
542
|
+
};
|
|
543
|
+
readonly then: {
|
|
544
|
+
readonly $ref: "#/$defs/showChartTool";
|
|
545
|
+
};
|
|
496
546
|
}, {
|
|
497
547
|
readonly if: {
|
|
498
548
|
required: string[];
|
|
@@ -44,6 +44,8 @@ const BUILTIN_TYPES = [
|
|
|
44
44
|
"backbone.todo",
|
|
45
45
|
"backbone.skill",
|
|
46
46
|
"backbone.bash",
|
|
47
|
+
"backbone.show_table",
|
|
48
|
+
"backbone.show_chart",
|
|
47
49
|
"function",
|
|
48
50
|
];
|
|
49
51
|
const typeIs = (t) => ({ required: ["type"], properties: { type: { const: t } } });
|
|
@@ -207,6 +209,19 @@ export const agentSchema = {
|
|
|
207
209
|
required: ["type"],
|
|
208
210
|
properties: { type: { const: "backbone.todo" }, requiresConfirmation: { type: "boolean" } },
|
|
209
211
|
},
|
|
212
|
+
// #1419: no options; requiresConfirmation as todoTool, since an author may tighten a read tool.
|
|
213
|
+
showTableTool: {
|
|
214
|
+
type: "object",
|
|
215
|
+
additionalProperties: false,
|
|
216
|
+
required: ["type"],
|
|
217
|
+
properties: { type: { const: "backbone.show_table" }, requiresConfirmation: { type: "boolean" } },
|
|
218
|
+
},
|
|
219
|
+
showChartTool: {
|
|
220
|
+
type: "object",
|
|
221
|
+
additionalProperties: false,
|
|
222
|
+
required: ["type"],
|
|
223
|
+
properties: { type: { const: "backbone.show_chart" }, requiresConfirmation: { type: "boolean" } },
|
|
224
|
+
},
|
|
210
225
|
skillTool: {
|
|
211
226
|
type: "object",
|
|
212
227
|
additionalProperties: false,
|
|
@@ -266,6 +281,8 @@ export const agentSchema = {
|
|
|
266
281
|
{ if: typeIs("backbone.todo"), then: { $ref: "#/$defs/todoTool" } },
|
|
267
282
|
{ if: typeIs("backbone.skill"), then: { $ref: "#/$defs/skillTool" } },
|
|
268
283
|
{ if: typeIs("backbone.bash"), then: { $ref: "#/$defs/bashTool" } },
|
|
284
|
+
{ if: typeIs("backbone.show_table"), then: { $ref: "#/$defs/showTableTool" } },
|
|
285
|
+
{ if: typeIs("backbone.show_chart"), then: { $ref: "#/$defs/showChartTool" } },
|
|
269
286
|
{ if: typeIs("function"), then: { $ref: "#/$defs/functionTool" } },
|
|
270
287
|
{
|
|
271
288
|
// The validator reports these with the reason from NON_AUTHORABLE_TOOL_TYPES; this keeps the published schema honest.
|
package/dist/commands/files.js
CHANGED
|
@@ -2,10 +2,9 @@ import { Command } from "commander";
|
|
|
2
2
|
import { writeFileSync } from "node:fs";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { getClient, resolveAuthHeader, runAction } from "../lib/client.js";
|
|
5
|
-
import { resolveConfig } from "../lib/config.js";
|
|
5
|
+
import { isJsonOutput, resolveConfig } from "../lib/config.js";
|
|
6
6
|
import { BackboneApiError } from "../lib/errors.js";
|
|
7
|
-
import {
|
|
8
|
-
import { addPaginationOptions, paginationParams } from "../lib/pagination.js";
|
|
7
|
+
import { formatDetail, formatList, formatSuccess, withSpinner } from "../lib/output.js";
|
|
9
8
|
import { fileToBlob } from "../lib/multipart.js";
|
|
10
9
|
/**
|
|
11
10
|
* Upload a single file with purpose=agent_input|knowledge. Both are multipart
|
|
@@ -59,15 +58,31 @@ async function downloadFile(command, fileId) {
|
|
|
59
58
|
export function makeFilesCommand() {
|
|
60
59
|
const cmd = new Command("files").description("Manage uploaded files");
|
|
61
60
|
const list = new Command("list").description("List files");
|
|
62
|
-
addPaginationOptions(list);
|
|
63
61
|
list.option("--purpose <purpose>", "Filter by purpose (agent_input, knowledge)");
|
|
62
|
+
list.option("--limit <number>", "How many files to list (1-100)", "20");
|
|
63
|
+
list.option("--after <fileId>", "List the files after this one (the previous list's last id)");
|
|
64
|
+
list.option("--order <order>", "asc (oldest first) or desc (newest first)", "desc");
|
|
64
65
|
list.action(async (opts, command) => {
|
|
65
66
|
await runAction(command, async () => {
|
|
66
67
|
const client = getClient(command);
|
|
67
68
|
const { data } = await client.GET("/v1/files", {
|
|
68
|
-
params: {
|
|
69
|
+
params: {
|
|
70
|
+
query: {
|
|
71
|
+
purpose: opts.purpose,
|
|
72
|
+
limit: parseInt(opts.limit, 10),
|
|
73
|
+
after: opts.after,
|
|
74
|
+
order: opts.order,
|
|
75
|
+
},
|
|
76
|
+
},
|
|
69
77
|
});
|
|
70
|
-
|
|
78
|
+
if (isJsonOutput(command)) {
|
|
79
|
+
console.log(JSON.stringify(data, null, 2));
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
formatList(data?.data, command, ["id", "filename", "purpose", "bytes", "created_at"]);
|
|
83
|
+
if (data?.has_more) {
|
|
84
|
+
console.log(chalk.dim(`More files: --after ${data.last_id}`));
|
|
85
|
+
}
|
|
71
86
|
});
|
|
72
87
|
});
|
|
73
88
|
cmd.addCommand(list);
|
|
@@ -86,10 +86,23 @@ export function makeKnowledgeCommand() {
|
|
|
86
86
|
.option("--reranker-provider <id>", "New reranker provider ID")
|
|
87
87
|
.option("--hybrid-search <bool>", "Enable hybrid search (true/false)")
|
|
88
88
|
.option("--text-search-language <name>", "Change the text-search language (reindexes in the background); omit to leave it untouched")
|
|
89
|
+
.option("--cancel-text-search-reindex", "Abandon the text-search reindex in progress and keep the active language")
|
|
89
90
|
.action(async (id, opts, command) => {
|
|
90
91
|
await runAction(command, async () => {
|
|
91
92
|
const client = getClient(command);
|
|
92
|
-
|
|
93
|
+
// The update takes the full body: name, slug, provider, model and dimension are required on
|
|
94
|
+
// every PATCH, so start from the stored values and overlay the flags. Optional fields left
|
|
95
|
+
// out keep their stored values server-side.
|
|
96
|
+
const { data: current } = await client.GET("/v1/knowledge-bases/{id}", {
|
|
97
|
+
params: { path: { id } },
|
|
98
|
+
});
|
|
99
|
+
const body = {
|
|
100
|
+
name: current?.name,
|
|
101
|
+
slug: current?.slug,
|
|
102
|
+
embeddingProviderId: current?.embeddingProviderId,
|
|
103
|
+
embeddingModel: current?.embeddingModel,
|
|
104
|
+
embeddingDim: current?.embeddingDim,
|
|
105
|
+
};
|
|
93
106
|
if (opts.name)
|
|
94
107
|
body.name = opts.name;
|
|
95
108
|
if (opts.description !== undefined)
|
|
@@ -112,6 +125,8 @@ export function makeKnowledgeCommand() {
|
|
|
112
125
|
body.hybridSearchEnabled = opts.hybridSearch === "true";
|
|
113
126
|
if (opts.textSearchLanguage)
|
|
114
127
|
body.textSearchLanguage = opts.textSearchLanguage;
|
|
128
|
+
if (opts.cancelTextSearchReindex)
|
|
129
|
+
body.cancelTextSearchReindex = true;
|
|
115
130
|
const { data } = await client.PATCH("/v1/knowledge-bases/{id}", {
|
|
116
131
|
params: { path: { id } },
|
|
117
132
|
body: body,
|
package/dist/commands/skills.js
CHANGED
|
@@ -138,7 +138,7 @@ export function makeSkillsCommand() {
|
|
|
138
138
|
const bundle = packSkillDirectory(path);
|
|
139
139
|
if (bundle.skipped.length > 0) {
|
|
140
140
|
// The server reports what it was sent; only the CLI can name what never left the disk.
|
|
141
|
-
console.error(`Left out of the bundle (the importer takes SKILL.md, references/, assets/, scripts/): ${bundle.skipped.join(", ")}`);
|
|
141
|
+
console.error(`Left out of the bundle (the importer takes SKILL.md, references/, assets/, scripts/, examples/): ${bundle.skipped.join(", ")}`);
|
|
142
142
|
}
|
|
143
143
|
blob = new Blob([bundle.bytes], { type: "application/zip" });
|
|
144
144
|
filename = bundle.filename;
|
|
@@ -171,6 +171,7 @@ export function makeSkillsCommand() {
|
|
|
171
171
|
.option("-o, --output <file>", "Output path (default: <skill-name>-v<n>.zip)")
|
|
172
172
|
.option("-d, --extract-to <dir>", "Unpack the bundle into this directory instead of writing a zip")
|
|
173
173
|
.option("--force", "Write into a non-empty --extract-to directory")
|
|
174
|
+
.option("--include-examples", "Keep the confidential examples/ files (needs ADMIN or OWNER)")
|
|
174
175
|
.action(async (id, versionNumber, opts, command) => {
|
|
175
176
|
await runAction(command, async () => {
|
|
176
177
|
if (opts.output && opts.extractTo)
|
|
@@ -189,14 +190,21 @@ export function makeSkillsCommand() {
|
|
|
189
190
|
}
|
|
190
191
|
const config = resolveConfig(command);
|
|
191
192
|
const authHeader = await resolveAuthHeader(config);
|
|
193
|
+
let omitted = 0;
|
|
192
194
|
const bytes = await withSpinner("Exporting skill...", async () => {
|
|
193
195
|
const baseUrl = config.baseUrl.replace(/\/+$/, "");
|
|
194
|
-
const
|
|
196
|
+
const query = opts.includeExamples ? "?includeExamples=true" : "";
|
|
197
|
+
const res = await fetch(`${baseUrl}/v1/skills/${encodeURIComponent(id)}/versions/${encodeURIComponent(versionNumber)}/export${query}`, {
|
|
195
198
|
headers: { Authorization: authHeader },
|
|
196
199
|
});
|
|
197
200
|
await checkResponse(res);
|
|
201
|
+
omitted = Number(res.headers.get("X-Skill-Examples-Omitted") ?? 0);
|
|
198
202
|
return Buffer.from(await res.arrayBuffer());
|
|
199
203
|
});
|
|
204
|
+
if (omitted > 0) {
|
|
205
|
+
// #926: a re-import of this bundle would drop them, so say so where the user looks.
|
|
206
|
+
console.error(`${omitted} confidential example file(s) left out; --include-examples (admin) keeps them`);
|
|
207
|
+
}
|
|
200
208
|
if (opts.extractTo) {
|
|
201
209
|
mkdirSync(opts.extractTo, { recursive: true });
|
|
202
210
|
const written = unpackSkillBundle(new Uint8Array(bytes), opts.extractTo);
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
|
-
import { Command } from "commander";
|
|
3
|
+
import { Command, CommanderError } from "commander";
|
|
4
4
|
import { makeAuthCommand } from "./commands/auth.js";
|
|
5
5
|
const require = createRequire(import.meta.url);
|
|
6
6
|
const pkg = require("../package.json");
|
|
@@ -78,5 +78,20 @@ program.addCommand(makeConnectorsCommand());
|
|
|
78
78
|
program.addCommand(makeRelaysCommand());
|
|
79
79
|
program.addCommand(makeBridgeCommand());
|
|
80
80
|
program.addCommand(makeDocsCommand());
|
|
81
|
-
|
|
81
|
+
// Commander exits 1 on its own parse errors, and 1 is the exit code for API and network failures.
|
|
82
|
+
// Every command throws instead, so a usage error exits 2 like a CliUsageError (#697).
|
|
83
|
+
const throwOnExit = (cmd) => {
|
|
84
|
+
cmd.exitOverride();
|
|
85
|
+
cmd.commands.forEach(throwOnExit);
|
|
86
|
+
};
|
|
87
|
+
throwOnExit(program);
|
|
88
|
+
program
|
|
89
|
+
.parseAsync()
|
|
90
|
+
.then(() => updater.notify())
|
|
91
|
+
.catch((err) => {
|
|
92
|
+
if (!(err instanceof CommanderError))
|
|
93
|
+
throw err;
|
|
94
|
+
// --help, --version and a command group's help without a subcommand succeed.
|
|
95
|
+
process.exit(err.exitCode === 0 || err.code === "commander.help" ? 0 : 2);
|
|
96
|
+
});
|
|
82
97
|
//# sourceMappingURL=index.js.map
|
package/dist/lib/agent-run.d.ts
CHANGED
|
@@ -53,6 +53,18 @@ export interface PendingInput {
|
|
|
53
53
|
mode: InputMode;
|
|
54
54
|
answerUrl: string;
|
|
55
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* A table or chart the agent showed the user (#1419): a `backbone:ui` item, its validated `props` as the
|
|
58
|
+
* server sent them. A client renders from `props`, never from the call's arguments.
|
|
59
|
+
*/
|
|
60
|
+
export interface ShownComponent {
|
|
61
|
+
id: string;
|
|
62
|
+
callId: string;
|
|
63
|
+
/** `table` or `chart`; another value is a component this build does not know. */
|
|
64
|
+
component: string;
|
|
65
|
+
schemaVersion: number;
|
|
66
|
+
props: unknown;
|
|
67
|
+
}
|
|
56
68
|
/** The end user's conversation mode (epic &59); the server matches these three values exactly. */
|
|
57
69
|
export type ConversationMode = "plan" | "ask" | "auto";
|
|
58
70
|
export declare const CONVERSATION_MODES: readonly ConversationMode[];
|
|
@@ -60,7 +72,7 @@ export declare const CONVERSATION_MODES: readonly ConversationMode[];
|
|
|
60
72
|
export declare const MODE_OPTION_HELP: string;
|
|
61
73
|
/**
|
|
62
74
|
* The `--mode` value, checked before any request is sent: anything but the three exact values is a
|
|
63
|
-
* usage error (exit 2).
|
|
75
|
+
* usage error (exit 2).
|
|
64
76
|
*/
|
|
65
77
|
export declare function parseModeOption(raw: string | undefined): ConversationMode | undefined;
|
|
66
78
|
/** The `backbone:mode` input item (S1 D7); always appended last. */
|
|
@@ -87,6 +99,7 @@ export interface RunEnvelope {
|
|
|
87
99
|
pendingToolCalls: PendingToolCall[];
|
|
88
100
|
pendingConnections: PendingConnection[];
|
|
89
101
|
pendingInputs: PendingInput[];
|
|
102
|
+
components: ShownComponent[];
|
|
90
103
|
incompleteReason: string | null;
|
|
91
104
|
usage: {
|
|
92
105
|
inputTokens: number;
|
package/dist/lib/agent-run.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
+
import Table from "cli-table3";
|
|
2
3
|
import { DEFAULT_CHAT_URL } from "./config.js";
|
|
3
4
|
import { answerUrlFor, connectCallIds, connectionsPhrase, inputLabelsPhrase, pendingConnectionsOf, pendingInputsOf, } from "./connect-pause.js";
|
|
4
5
|
import { CliUsageError } from "./errors.js";
|
|
@@ -13,7 +14,7 @@ function isConversationMode(value) {
|
|
|
13
14
|
}
|
|
14
15
|
/**
|
|
15
16
|
* The `--mode` value, checked before any request is sent: anything but the three exact values is a
|
|
16
|
-
* usage error (exit 2).
|
|
17
|
+
* usage error (exit 2).
|
|
17
18
|
*/
|
|
18
19
|
export function parseModeOption(raw) {
|
|
19
20
|
if (raw === undefined)
|
|
@@ -186,6 +187,8 @@ const DECODED_ITEM_TYPES = new Set([
|
|
|
186
187
|
"backbone:connector_auth_request",
|
|
187
188
|
"backbone:input_request",
|
|
188
189
|
"backbone:tool_image",
|
|
190
|
+
// A table or chart a finished ShowTable or ShowChart call showed (#1419): it never holds a run either.
|
|
191
|
+
"backbone:ui",
|
|
189
192
|
"mcp_approval_request",
|
|
190
193
|
"mcp_call",
|
|
191
194
|
"mcp_list_tools",
|
|
@@ -337,6 +340,15 @@ export function buildRunEnvelope(result, agentRef, chatUrl = DEFAULT_CHAT_URL) {
|
|
|
337
340
|
pendingToolCalls,
|
|
338
341
|
pendingConnections,
|
|
339
342
|
pendingInputs,
|
|
343
|
+
components: output
|
|
344
|
+
.filter((i) => i.type === "backbone:ui")
|
|
345
|
+
.map((i) => ({
|
|
346
|
+
id: String(i.id),
|
|
347
|
+
callId: String(i.call_id),
|
|
348
|
+
component: String(i.component),
|
|
349
|
+
schemaVersion: Number(i.schema_version),
|
|
350
|
+
props: i.props ?? null,
|
|
351
|
+
})),
|
|
340
352
|
incompleteReason: result?.incomplete_details?.reason ?? null,
|
|
341
353
|
usage: result?.usage
|
|
342
354
|
? { inputTokens: result.usage.input_tokens ?? 0, outputTokens: result.usage.output_tokens ?? 0 }
|
|
@@ -351,11 +363,64 @@ const INPUT_MODE_WORDS = {
|
|
|
351
363
|
mixed: "form and link",
|
|
352
364
|
unknown: "question",
|
|
353
365
|
};
|
|
366
|
+
/** The `schema_version` of `backbone:ui` this build prints (#1419 D8). */
|
|
367
|
+
const UI_SCHEMA_VERSION = 1;
|
|
368
|
+
/** A cell as plain text: empty for null, a percent fraction as `25%`, a currency amount with its code. */
|
|
369
|
+
function cellText(value, column = {}) {
|
|
370
|
+
if (value === null || value === undefined)
|
|
371
|
+
return "";
|
|
372
|
+
if (typeof value === "number" && column.format === "percent")
|
|
373
|
+
return `${Number((value * 100).toPrecision(12))}%`;
|
|
374
|
+
if (typeof value === "number" && column.format === "currency")
|
|
375
|
+
return `${value} ${String(column.currency ?? "")}`.trimEnd();
|
|
376
|
+
return stripControl(String(value));
|
|
377
|
+
}
|
|
378
|
+
function plainTable(head, colAligns) {
|
|
379
|
+
return new Table({
|
|
380
|
+
head: head.map((h) => stripControl(h)),
|
|
381
|
+
colAligns,
|
|
382
|
+
style: { head: [], border: [] },
|
|
383
|
+
// No rule between rows: a table may have 200.
|
|
384
|
+
chars: { mid: "", "left-mid": "", "mid-mid": "", "right-mid": "" },
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* A shown table as aligned columns under its title, a chart as its data table: labels down, one column per
|
|
389
|
+
* series. Null for an unknown component, a newer schema version or props of another shape.
|
|
390
|
+
*/
|
|
391
|
+
function componentTable(c) {
|
|
392
|
+
const p = (c.props ?? {});
|
|
393
|
+
if (c.schemaVersion > UI_SCHEMA_VERSION)
|
|
394
|
+
return null;
|
|
395
|
+
if (c.component === "table" && Array.isArray(p.columns) && Array.isArray(p.rows)) {
|
|
396
|
+
const columns = p.columns;
|
|
397
|
+
const table = plainTable(columns.map((col) => String(col.label)), columns.map((col) => (col.align === "right" ? "right" : "left")));
|
|
398
|
+
for (const row of p.rows)
|
|
399
|
+
table.push(columns.map((col) => cellText(row?.[col.key], col)));
|
|
400
|
+
return { title: String(p.title ?? "Table"), table };
|
|
401
|
+
}
|
|
402
|
+
if (c.component === "chart" && Array.isArray(p.labels) && Array.isArray(p.series)) {
|
|
403
|
+
const series = p.series;
|
|
404
|
+
const table = plainTable(["", ...series.map((x) => String(x.name))], ["left", ...series.map(() => "right")]);
|
|
405
|
+
p.labels.forEach((label, i) => table.push([cellText(label), ...series.map((x) => cellText(Array.isArray(x.values) ? x.values[i] : null))]));
|
|
406
|
+
return { title: `${String(p.title ?? "Chart")}${p.unit ? ` (${String(p.unit)})` : ""}`, table };
|
|
407
|
+
}
|
|
408
|
+
return null;
|
|
409
|
+
}
|
|
354
410
|
/** Human-readable rendering of an envelope on stdout. Every value printed is passed through {@link stripControl}. */
|
|
355
411
|
export function printRunText(env) {
|
|
356
412
|
const s = stripControl;
|
|
357
413
|
if (env.text)
|
|
358
414
|
console.log(s(env.text));
|
|
415
|
+
for (const component of env.components) {
|
|
416
|
+
const shown = componentTable(component);
|
|
417
|
+
if (!shown) {
|
|
418
|
+
console.log(chalk.dim("\nThis content needs a newer version of the CLI."));
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
console.log(chalk.bold(`\n${s(shown.title)}`));
|
|
422
|
+
console.log(shown.table.toString());
|
|
423
|
+
}
|
|
359
424
|
const head = [
|
|
360
425
|
env.agent ? `${env.agent}${env.version !== null ? `@${env.version}` : ""}` : null,
|
|
361
426
|
env.responseId,
|
package/dist/lib/skill-bundle.js
CHANGED
|
@@ -2,11 +2,12 @@ import { mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
|
2
2
|
import { basename, dirname, join, resolve } from "node:path";
|
|
3
3
|
import { unzipSync, zipSync } from "fflate";
|
|
4
4
|
/**
|
|
5
|
-
* The importer takes SKILL.md plus these
|
|
5
|
+
* The importer takes SKILL.md plus these four directories and reports anything else as
|
|
6
6
|
* `unsupported-path` (spec §4). Packing only these keeps a stray .git or node_modules out of
|
|
7
|
-
* the upload instead of spending the 20 MB bundle cap on it.
|
|
7
|
+
* the upload instead of spending the 20 MB bundle cap on it. `examples/` holds confidential
|
|
8
|
+
* files (#926): imported like the rest, left out of a plain export.
|
|
8
9
|
*/
|
|
9
|
-
const RESOURCE_DIRS = ["references", "assets", "scripts"];
|
|
10
|
+
const RESOURCE_DIRS = ["references", "assets", "scripts", "examples"];
|
|
10
11
|
function byName(left, right) {
|
|
11
12
|
return left.name < right.name ? -1 : left.name > right.name ? 1 : 0;
|
|
12
13
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@2kw/ai",
|
|
3
|
-
"version": "8.0.0
|
|
3
|
+
"version": "8.0.0",
|
|
4
4
|
"description": "CLI for 2kw.ai — schema-driven document extraction, an OpenAI-compatible EU LLM gateway, transcription, prompts, datasets, and experiments from your terminal or agentic workflows. Ships as 2kw, backbone, and bb.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|