@thinkingai/ae-cli 6.1.25 → 6.1.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -9
- package/README.zh.md +25 -9
- package/bin/ae-cli.js +6 -1
- package/cli-installation-guide.md +91 -0
- package/dist/{auth-LHM7NQPR.js → auth-WA7YGGRT.js} +6 -8
- package/dist/automation-VAAQBM7Y.js +459 -0
- package/dist/{capability-SJI5KOCK.js → capability-GAAYJ3IQ.js} +6 -6
- package/dist/{chunk-KJDOTPYU.js → chunk-3YVEAZUN.js} +59 -26
- package/dist/{chunk-KS4DE3MX.js → chunk-5XJYLEVC.js} +4 -4
- package/dist/{chunk-BW7JUDEI.js → chunk-6VNIR4AP.js} +514 -213
- package/dist/{chunk-5XRQ3CZR.js → chunk-7KU2WNQE.js} +43 -8
- package/dist/{chunk-7WZACOAI.js → chunk-AP7YP2NX.js} +2 -2
- package/dist/{chunk-XKIW3QMF.js → chunk-AQJPNWZF.js} +3 -3
- package/dist/chunk-CI24BDR2.js +43 -0
- package/dist/{chunk-SO5LKIWP.js → chunk-CT7QDJS6.js} +2 -2
- package/dist/{chunk-DU72X2IO.js → chunk-GHXZK54S.js} +22 -10
- package/dist/{chunk-2FJM4HRV.js → chunk-MWIA43UJ.js} +3 -3
- package/dist/{chunk-N4BLPJC7.js → chunk-OP44TT4H.js} +1 -1
- package/dist/chunk-Q5US7JC5.js +133 -0
- package/dist/chunk-RK6GLDGI.js +27 -0
- package/dist/chunk-RPBOAQQQ.js +56 -0
- package/dist/{chunk-GK7WDY7E.js → chunk-S6M42KND.js} +1 -1
- package/dist/{chunk-QYXDJOLA.js → chunk-VZZNLV3I.js} +19 -11
- package/dist/{chunk-YVGXGTD6.js → chunk-WNGFSIOB.js} +7 -1
- package/dist/{chunk-IG3DYEIR.js → chunk-ZL7SGNIA.js} +5 -3
- package/dist/{community-report-client-6VJDDMJJ.js → community-report-client-PEERQCX2.js} +1 -1
- package/dist/{config-XQWOPDHN.js → config-JOD5DOPE.js} +4 -4
- package/dist/context-NGVFPCBK.js +136 -0
- package/dist/{data-integration-XBTCGXQT.js → data-integration-BCLQFTGU.js} +6 -6
- package/dist/index.js +123 -46
- package/dist/{local-data-upload-client-3P7NIVQ4.js → local-data-upload-client-TWMHFLUA.js} +1 -1
- package/dist/memory-CQKH2JAV.js +580 -0
- package/dist/{metadata-JRYKNUS5.js → metadata-NR3PHR23.js} +7 -7
- package/dist/{model-ZS7HVGKN.js → model-VX5M2CJ6.js} +9 -5
- package/dist/{personal-semantic-preference-IDE2GE5T.js → personal-semantic-preference-2RAI36P3.js} +117 -11
- package/dist/{project-semantic-36KOCYN7.js → project-semantic-3BUGP3ZM.js} +6 -6
- package/dist/{sync-EQLSTUS7.js → sync-RZIAV37C.js} +12 -8
- package/dist/{te-agent-Z3HCTKR7.js → te-agent-AORRE2FM.js} +90 -454
- package/dist/{te-analysis-5ZZ6YHVH.js → te-analysis-GP7DSQ7Q.js} +297 -20
- package/dist/{te-community-Z7JACGF3.js → te-community-42M7ICDO.js} +3 -3
- package/dist/{te-dataops-F7GQOIS6.js → te-dataops-BNKNZ4F2.js} +5 -5
- package/dist/{te-engage-RNRMYDO3.js → te-engage-2CO6LRCX.js} +6 -6
- package/dist/{te-experiment-BTAC2UNK.js → te-experiment-652CLXMU.js} +6 -6
- package/dist/{te-kb-QJLJEX5K.js → te-kb-ULATOTQ3.js} +494 -214
- package/dist/{te-system-IXC43QHZ.js → te-system-UGHVKBVV.js} +10 -9
- package/dist/{te-team-BIZIKIHZ.js → te-team-YA6SNOJ3.js} +6 -6
- package/dist/things-DTCOQIQB.js +1091 -0
- package/dist/{update-W2SGQNKT.js → update-ESNYKUVR.js} +59 -51
- package/dist/workspace-JEOHKFPX.js +554 -0
- package/package.json +21 -9
- package/skills/ae-agent/SKILL.md +91 -139
- package/skills/ae-agent/references/add-model.md +1 -1
- package/skills/ae-agent/references/create-agent.md +1 -1
- package/skills/ae-agent/references/find-archived-conversations.md +12 -5
- package/skills/ae-agent/references/get-agent.md +1 -1
- package/skills/ae-agent/references/list-agents.md +2 -2
- package/skills/ae-agent/references/list-models.md +2 -2
- package/skills/ae-agent/references/restore-conversation.md +3 -1
- package/skills/ae-analysis/SKILL.md +15 -6
- package/skills/ae-analysis/references/ai_models/funnel.md +5 -3
- package/skills/ae-analysis/references/ai_models.md +27 -0
- package/skills/ae-analysis/references/command_index.md +12 -4
- package/skills/ae-analysis/references/dashboard_move.md +21 -0
- package/skills/ae-analysis/references/dashboard_report_add.md +2 -0
- package/skills/ae-analysis/references/dashboard_report_get.md +19 -0
- package/skills/ae-analysis/references/dashboard_report_update.md +27 -0
- package/skills/ae-analysis/references/dashboard_update.md +1 -1
- package/skills/ae-analysis/references/event_report_presentation.md +76 -0
- package/skills/ae-analysis/references/feedback_submit.md +37 -0
- package/skills/ae-analysis/references/metadata_resolution.md +15 -0
- package/skills/ae-analysis/references/personal_semantic_preference_review.md +9 -0
- package/skills/ae-analysis/references/personal_semantic_preference_review_list.md +7 -0
- package/skills/ae-analysis/references/personal_semantic_preference_submit.md +7 -0
- package/skills/ae-analysis/references/project_semantic_knowledge_wiki.md +68 -27
- package/skills/ae-analysis/references/project_semantic_knowledge_wiki_plan_schema.md +40 -1
- package/skills/ae-analysis/references/report_create.md +13 -3
- package/skills/ae-analysis/references/report_get.md +5 -1
- package/skills/ae-analysis/references/report_update.md +15 -4
- package/skills/ae-analysis/references/system_query_monitor_overview.md +2 -0
- package/skills/ae-analysis/references/system_query_task_cancel.md +2 -0
- package/skills/ae-analysis/references/system_query_task_export.md +6 -2
- package/skills/ae-analysis/references/system_query_task_get.md +2 -0
- package/skills/ae-analysis/references/system_query_task_list.md +7 -3
- package/skills/ae-analysis/references/system_query_task_options.md +2 -2
- package/skills/ae-analysis/references/system_query_task_realtime_list.md +15 -0
- package/skills/ae-analysis/references/user_tag_models.md +2 -0
- package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/build-empty-skeleton.mjs +105 -0
- package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/build-project-semantic-wiki.mjs +337 -22
- package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/company-kb.mjs +21 -8
- package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/default-compile-rules.md +24 -11
- package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/default-compile-schema.md +66 -0
- package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/generate-build-ir.mjs +1 -0
- package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/package-wiki-source-zip.mjs +109 -40
- package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/plan-kb-source-sync.mjs +1 -1
- package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/prepare-compile-schema.mjs +64 -0
- package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/refresh-state-parts.mjs +91 -0
- package/skills/ae-automation/SKILL.md +16 -0
- package/skills/ae-automation/references/cli.md +53 -0
- package/skills/ae-automation/references/command_index.md +17 -0
- package/skills/ae-capability/SKILL.md +15 -6
- package/skills/ae-current-context/SKILL.md +3 -2
- package/skills/ae-kb/SKILL.md +62 -12
- package/skills/ae-kb/references/analysis-workflow.md +73 -36
- package/skills/ae-kb/references/query-workflow.md +67 -33
- package/skills/ae-kb/references/schema-import.md +5 -3
- package/skills/ae-kb/references/source-mutations.md +6 -4
- package/skills/ae-kb/references/text-sources.md +53 -0
- package/skills/ae-kb-discovery/SKILL.md +1 -1
- package/skills/ae-team/SKILL.md +23 -17
- package/skills/ae-things/SKILL.md +85 -0
- package/skills/ae-things/references/cli.md +103 -0
- package/skills/ae-things-progress/SKILL.md +43 -0
- package/skills/ae-things-review/SKILL.md +42 -0
- package/skills/ae-workspace/SKILL.md +43 -0
- package/skills/ae-workspace/references/commands.md +51 -0
- package/dist/chunk-E2JKXMVO.js +0 -29
- package/dist/context-M3HDGEIR.js +0 -46
- package/dist/memory-6APEB2JB.js +0 -892
- package/skills/ae-agent/references/create-automation.md +0 -125
- package/skills/ae-agent/references/list-automations.md +0 -56
- package/skills/ae-agent/references/update-automation.md +0 -107
|
@@ -2,27 +2,23 @@ import { createRequire as __createRequire } from 'node:module'; const require =
|
|
|
2
2
|
import {
|
|
3
3
|
kbApi,
|
|
4
4
|
kbUpload
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-7KU2WNQE.js";
|
|
6
6
|
import {
|
|
7
7
|
TeAgentApiError
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-3YVEAZUN.js";
|
|
9
9
|
import {
|
|
10
10
|
CapabilityGatewayError
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-VZZNLV3I.js";
|
|
12
12
|
import {
|
|
13
13
|
printError
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-6VNIR4AP.js";
|
|
15
15
|
import "./chunk-Y74WTIKJ.js";
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-GHXZK54S.js";
|
|
17
|
+
import "./chunk-ZL7SGNIA.js";
|
|
18
18
|
import {
|
|
19
19
|
CliValidationError,
|
|
20
20
|
PermissionError
|
|
21
|
-
} from "./chunk-
|
|
22
|
-
|
|
23
|
-
// src/commands/te-kb/schema-import.ts
|
|
24
|
-
import { promises as fs } from "fs";
|
|
25
|
-
import path from "path";
|
|
21
|
+
} from "./chunk-WNGFSIOB.js";
|
|
26
22
|
|
|
27
23
|
// src/commands/te-kb/target-scope.ts
|
|
28
24
|
function getExternalKnowledgeBaseTargetScope(ctx) {
|
|
@@ -34,7 +30,37 @@ function getExternalKnowledgeBaseTargetScope(ctx) {
|
|
|
34
30
|
);
|
|
35
31
|
}
|
|
36
32
|
|
|
33
|
+
// src/commands/te-kb/source-check-url-updates.ts
|
|
34
|
+
var API_PATH = "/agent/api/external/knowledge-bases/sources/check-url-updates";
|
|
35
|
+
function body(ctx) {
|
|
36
|
+
const scope = getExternalKnowledgeBaseTargetScope(ctx);
|
|
37
|
+
return { name: ctx.str("name").trim(), sourceId: ctx.str("id").trim(), ...scope ? { scope } : {} };
|
|
38
|
+
}
|
|
39
|
+
var sourceCheckUrlUpdates = {
|
|
40
|
+
service: "kb",
|
|
41
|
+
resource: "source",
|
|
42
|
+
command: "check-url-updates",
|
|
43
|
+
risk: "write",
|
|
44
|
+
description: "Submit an asynchronous update check for one compiled custom URL source. Success means accepted only. Read kb +list-sources for update markers; an unchanged state does not prove completion. Does not compile.",
|
|
45
|
+
flags: [
|
|
46
|
+
{ name: "name", type: "string", required: true, minLength: 1, maxLength: 200, desc: "Knowledge base name" },
|
|
47
|
+
{ name: "id", type: "string", required: true, minLength: 1, maxLength: 191, desc: "Stable custom URL source ID from kb +list-sources" },
|
|
48
|
+
{ name: "scope", type: "string", desc: "Exact scope: personal | company (omit for personal then company lookup)" }
|
|
49
|
+
],
|
|
50
|
+
validate: (ctx) => {
|
|
51
|
+
for (const [flag2, max] of [["name", 200], ["id", 191]]) {
|
|
52
|
+
const value = ctx.str(flag2).trim();
|
|
53
|
+
if (!value || value.length > max) throw new CliValidationError(`Invalid --${flag2}: expected 1-${max} characters.`);
|
|
54
|
+
}
|
|
55
|
+
getExternalKnowledgeBaseTargetScope(ctx);
|
|
56
|
+
},
|
|
57
|
+
dryRun: (ctx) => ({ method: "POST", url: `${ctx.host().replace(/\/$/, "")}${API_PATH}`, body: body(ctx) }),
|
|
58
|
+
execute: (ctx) => kbApi(ctx, "POST", API_PATH, {}, body(ctx), { preserveErrorMetadata: true })
|
|
59
|
+
};
|
|
60
|
+
|
|
37
61
|
// src/commands/te-kb/schema-import.ts
|
|
62
|
+
import { promises as fs } from "fs";
|
|
63
|
+
import path from "path";
|
|
38
64
|
var ROOT = "/agent/api/external/knowledge-bases/schema";
|
|
39
65
|
var options = { preserveBusinessErrorCode: true, preserveErrorMetadata: true };
|
|
40
66
|
var flag = (name, type, desc, required = false) => ({ name, type, desc, required });
|
|
@@ -54,13 +80,13 @@ function endpoint(ctx, action) {
|
|
|
54
80
|
const suffix = action === "status" ? "" : action === "save" ? "content" : action === "reject" ? "reject-optimization" : action;
|
|
55
81
|
return `${ROOT}/imports/${encodeURIComponent(ctx.str("import-id"))}${suffix ? "/" + suffix : ""}`;
|
|
56
82
|
}
|
|
57
|
-
function
|
|
83
|
+
function body2(ctx, action) {
|
|
58
84
|
const result = { expectedRevision: ctx.num("revision"), requestId: ctx.str("request-id") };
|
|
59
85
|
if (["validate", "optimize", "apply"].includes(action)) result.contentHash = ctx.str("hash");
|
|
60
86
|
if (["validate", "optimize"].includes(action) && ctx.str("model")) result.model = ctx.str("model");
|
|
61
87
|
if (action === "optimize" && ctx.list("issue-id").length) result.issueIds = ctx.list("issue-id");
|
|
62
88
|
if (action === "apply") {
|
|
63
|
-
result.reportId = ctx.str("report-id");
|
|
89
|
+
if (ctx.str("report-id")) result.reportId = ctx.str("report-id");
|
|
64
90
|
result.expectedSchemaHash = ctx.bool("schema-absent") ? null : ctx.str("schema-hash");
|
|
65
91
|
}
|
|
66
92
|
return result;
|
|
@@ -120,7 +146,7 @@ async function executeSchemaImport(ctx, action, api = kbApi, upload = kbUpload)
|
|
|
120
146
|
result = await api(ctx, "GET", endpoint(ctx, action), query(ctx, action), void 0, { ...options, ...binary ? { responseType: "bytes" } : {} });
|
|
121
147
|
if (binary) {
|
|
122
148
|
const output = path.resolve(ctx.str("output"));
|
|
123
|
-
const bytes = Buffer.from(result);
|
|
149
|
+
const bytes = Buffer.from(result.bytes);
|
|
124
150
|
await fs.writeFile(output, bytes, { flag: "wx" });
|
|
125
151
|
return { output, sizeBytes: bytes.length };
|
|
126
152
|
}
|
|
@@ -130,7 +156,7 @@ async function executeSchemaImport(ctx, action, api = kbApi, upload = kbUpload)
|
|
|
130
156
|
return { ...result, output };
|
|
131
157
|
}
|
|
132
158
|
} else {
|
|
133
|
-
const input =
|
|
159
|
+
const input = body2(ctx, action);
|
|
134
160
|
if (action === "save") {
|
|
135
161
|
const { bytes } = await readMarkdown(ctx);
|
|
136
162
|
input.content = bytes.toString("utf8");
|
|
@@ -140,10 +166,10 @@ async function executeSchemaImport(ctx, action, api = kbApi, upload = kbUpload)
|
|
|
140
166
|
return ctx.bool("wait") && result.task ? waitSchemaImport(ctx, result, api) : result;
|
|
141
167
|
}
|
|
142
168
|
function command(action, name, description, flags, risk) {
|
|
143
|
-
return { service: "kb", command: name, description, flags, risk, validate: (ctx) => validate(ctx, action), dryRun: (ctx) => ({ method: action === "save" ? "PUT" : ["upload", "validate", "optimize", "reject", "apply", "abandon"].includes(action) ? "POST" : "GET", url: ctx.host().replace(/\/$/, "") + endpoint(ctx, action), params: query(ctx, action), body: action === "upload" ? { ...target(ctx), requestId: ctx.str("request-id"), file: "[REDACTED]", model: ctx.str("model") || void 0, replacesImportId: ctx.str("replaces-import-id") || void 0, expectedReplacedRevision: ctx.num("replaced-revision") || void 0 } : ["save", "validate", "optimize", "reject", "apply", "abandon"].includes(action) ? { ...
|
|
169
|
+
return { service: "kb", command: name, description, flags, risk, validate: (ctx) => validate(ctx, action), dryRun: (ctx) => ({ method: action === "save" ? "PUT" : ["upload", "validate", "optimize", "reject", "apply", "abandon"].includes(action) ? "POST" : "GET", url: ctx.host().replace(/\/$/, "") + endpoint(ctx, action), params: query(ctx, action), body: action === "upload" ? { ...target(ctx), requestId: ctx.str("request-id"), file: "[REDACTED]", model: ctx.str("model") || void 0, replacesImportId: ctx.str("replaces-import-id") || void 0, expectedReplacedRevision: ctx.num("replaced-revision") || void 0 } : ["save", "validate", "optimize", "reject", "apply", "abandon"].includes(action) ? { ...body2(ctx, action), ...action === "save" ? { content: "[REDACTED]" } : {} } : void 0 }), execute: (ctx) => executeSchemaImport(ctx, action) };
|
|
144
170
|
}
|
|
145
171
|
var schemaDownload = command("download", "+schema-download", "Download formal schema bytes without rewriting.", [...targetFlags, flag("output", "string", "New destination file; never overwrite", true)], "read");
|
|
146
|
-
var schemaImport = command("upload", "+schema-import", "Upload a candidate
|
|
172
|
+
var schemaImport = command("upload", "+schema-import", "Upload a candidate with basic checks; AI validation is explicit and formal schema is unchanged.", [...targetFlags, fileFlag, flag("request-id", "string", "Upload idempotency key", true), modelFlag, flag("replaces-import-id", "string", "Explicit pending import to replace"), flag("replaced-revision", "number", "Expected revision of replaced import"), ...waitFlags], "write");
|
|
147
173
|
var schemaImportList = command("list", "+schema-import-list", "List your pending candidates.", [...targetFlags, { ...flag("limit", "number", "Page size, 1 to 100"), default: 20, min: 1, max: 100 }, flag("cursor", "string", "Continuation cursor")], "read");
|
|
148
174
|
var schemaImportStatus = command("status", "+schema-import-status", "Read candidate status, report and durable receipt.", [...identityFlags, ...waitFlags], "read");
|
|
149
175
|
var schemaImportContent = command("content", "+schema-import-content", "Read or download unmodified candidate bytes.", [...identityFlags, flag("target", "string", "current | original | optimization-input | optimized"), flag("output", "string", "Optional new destination file")], "read");
|
|
@@ -152,13 +178,13 @@ var schemaImportSave = command("save", "+schema-import-save", "Save edits withou
|
|
|
152
178
|
var schemaImportValidate = command("validate", "+schema-import-validate", "Validate this exact saved revision.", [...identityFlags, ...mutationFlags, hashFlag, modelFlag, ...waitFlags], "write");
|
|
153
179
|
var schemaImportOptimize = command("optimize", "+schema-import-optimize", "Repair selected issues once and independently revalidate.", [...identityFlags, ...mutationFlags, hashFlag, modelFlag, { ...flag("issue-id", "string", "Repeat to select repairable issues"), variadic: true }, ...waitFlags], "write");
|
|
154
180
|
var schemaImportReject = command("reject", "+schema-import-reject", "Restore the most recent repair input.", [...identityFlags, ...mutationFlags], "write");
|
|
155
|
-
var schemaImportApply = command("apply", "+schema-import-apply", "Apply after reviewing full diff; BASE_CHANGED requires a new review.", [...identityFlags, ...mutationFlags, hashFlag, flag("report-id", "string", "
|
|
181
|
+
var schemaImportApply = command("apply", "+schema-import-apply", "Apply after reviewing full diff; BASE_CHANGED requires a new review.", [...identityFlags, ...mutationFlags, hashFlag, flag("report-id", "string", "Optional AI report ID; retained for compatibility"), flag("schema-hash", "string", "Formal hash from a recent diff"), flag("schema-absent", "boolean", "Explicitly confirm formal schema is absent")], "write");
|
|
156
182
|
var schemaImportAbandon = command("abandon", "+schema-import-abandon", "Abandon candidate and invalidate pending tasks.", [...identityFlags, ...mutationFlags], "high-risk-write");
|
|
157
183
|
var schemaImportCommands = [schemaDownload, schemaImport, schemaImportList, schemaImportStatus, schemaImportContent, schemaImportDiff, schemaImportSave, schemaImportValidate, schemaImportOptimize, schemaImportReject, schemaImportApply, schemaImportAbandon];
|
|
158
184
|
|
|
159
185
|
// src/commands/te-kb/source-check-updates.ts
|
|
160
|
-
var
|
|
161
|
-
function
|
|
186
|
+
var API_PATH2 = "/agent/api/external/knowledge-bases/sources/check-updates";
|
|
187
|
+
function body3(ctx) {
|
|
162
188
|
const scope = getExternalKnowledgeBaseTargetScope(ctx);
|
|
163
189
|
return { name: ctx.str("name").trim(), sourceId: ctx.str("id").trim(), ...scope ? { scope } : {} };
|
|
164
190
|
}
|
|
@@ -180,10 +206,10 @@ var sourceCheckUpdates = {
|
|
|
180
206
|
}
|
|
181
207
|
getExternalKnowledgeBaseTargetScope(ctx);
|
|
182
208
|
},
|
|
183
|
-
dryRun: (ctx) => ({ method: "POST", url: `${ctx.host().replace(/\/$/, "")}${
|
|
209
|
+
dryRun: (ctx) => ({ method: "POST", url: `${ctx.host().replace(/\/$/, "")}${API_PATH2}`, body: body3(ctx) }),
|
|
184
210
|
execute: async (ctx) => {
|
|
185
211
|
try {
|
|
186
|
-
return await kbApi(ctx, "POST",
|
|
212
|
+
return await kbApi(ctx, "POST", API_PATH2, {}, body3(ctx), { preserveErrorMetadata: true });
|
|
187
213
|
} catch (error) {
|
|
188
214
|
const hint = "Read kb +list-sources to confirm the current source state before retrying.";
|
|
189
215
|
if (error instanceof PermissionError) {
|
|
@@ -210,12 +236,183 @@ var sourceCheckUpdates = {
|
|
|
210
236
|
}
|
|
211
237
|
};
|
|
212
238
|
|
|
213
|
-
// src/commands/te-kb/source-
|
|
239
|
+
// src/commands/te-kb/source-text.ts
|
|
214
240
|
import { promises as fs2 } from "fs";
|
|
215
241
|
import path2 from "path";
|
|
216
242
|
var API = "/agent/api/external/knowledge-bases";
|
|
217
|
-
var
|
|
243
|
+
var textApiOptions = { preserveErrorMetadata: true, retryUnauthorized: false, redactErrorDetails: true };
|
|
218
244
|
var maxBytes = 50 * 1024 * 1024;
|
|
245
|
+
var targetFlags2 = [
|
|
246
|
+
{ name: "name", type: "string", required: true, desc: "Exact knowledge base name from kb +list" },
|
|
247
|
+
{ name: "scope", type: "string", required: true, desc: "Exact knowledge base scope: personal or company" }
|
|
248
|
+
];
|
|
249
|
+
var textInputFlags = [
|
|
250
|
+
{ name: "text", type: "string", sensitive: true, desc: "Complete text body; mutually exclusive with --file and --stdin" },
|
|
251
|
+
{ name: "file", type: "string", desc: "One UTF-8 .md, .markdown or .txt file, at most 50 MiB; creates a Markdown source" },
|
|
252
|
+
{ name: "stdin", type: "boolean", desc: "Explicitly read the complete UTF-8 body from stdin; mutually exclusive with --text and --file" }
|
|
253
|
+
];
|
|
254
|
+
function hasTextFlag(ctx) {
|
|
255
|
+
return ctx.has ? ctx.has("text") : Boolean(ctx.str("text"));
|
|
256
|
+
}
|
|
257
|
+
function validateTextInput(ctx) {
|
|
258
|
+
const hasFile = ctx.has ? ctx.has("file") : Boolean(ctx.str("file"));
|
|
259
|
+
const count = Number(hasTextFlag(ctx)) + Number(hasFile) + Number(ctx.bool("stdin"));
|
|
260
|
+
if (count !== 1) throw new CliValidationError("Provide exactly one of --text, --file or --stdin.");
|
|
261
|
+
if (hasFile && !ctx.str("file").trim()) throw new CliValidationError("--file must name a regular file.");
|
|
262
|
+
}
|
|
263
|
+
function validateTarget(ctx) {
|
|
264
|
+
const name = ctx.str("name");
|
|
265
|
+
if (!name.trim() || name.length > 200 || /[\x00-\x1f\x7f]/.test(name)) {
|
|
266
|
+
throw new CliValidationError("--name must contain 1 to 200 characters without control characters.");
|
|
267
|
+
}
|
|
268
|
+
if (!["personal", "company"].includes(ctx.str("scope"))) throw new CliValidationError("--scope must be personal or company.");
|
|
269
|
+
}
|
|
270
|
+
function tooLarge() {
|
|
271
|
+
return new CliValidationError("Text content exceeds 50 MiB (52428800 UTF-8 bytes).", { code: "SOURCE_FILE_TOO_LARGE" });
|
|
272
|
+
}
|
|
273
|
+
async function boundedBytes(stream) {
|
|
274
|
+
const chunks = [];
|
|
275
|
+
let size = 0;
|
|
276
|
+
for await (const chunk of stream) {
|
|
277
|
+
const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
278
|
+
size += bytes.length;
|
|
279
|
+
if (size > maxBytes) throw tooLarge();
|
|
280
|
+
chunks.push(bytes);
|
|
281
|
+
}
|
|
282
|
+
return Buffer.concat(chunks, size);
|
|
283
|
+
}
|
|
284
|
+
async function readTextInput(ctx) {
|
|
285
|
+
validateTextInput(ctx);
|
|
286
|
+
let content;
|
|
287
|
+
if (hasTextFlag(ctx)) {
|
|
288
|
+
content = ctx.str("text");
|
|
289
|
+
if (/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/u.test(content)) {
|
|
290
|
+
throw new CliValidationError("Text content must contain valid Unicode.", { code: "SOURCE_TEXT_ENCODING_UNSUPPORTED" });
|
|
291
|
+
}
|
|
292
|
+
} else {
|
|
293
|
+
let bytes;
|
|
294
|
+
if (ctx.bool("stdin")) {
|
|
295
|
+
if (process.stdin.isTTY) throw new CliValidationError("--stdin requires piped UTF-8 input; interactive input is not supported.");
|
|
296
|
+
bytes = await boundedBytes(process.stdin);
|
|
297
|
+
} else {
|
|
298
|
+
const filename = path2.resolve(ctx.str("file"));
|
|
299
|
+
if (![".md", ".markdown", ".txt"].includes(path2.extname(filename).toLowerCase())) {
|
|
300
|
+
throw new CliValidationError("--file must be a UTF-8 .md, .markdown or .txt file.");
|
|
301
|
+
}
|
|
302
|
+
const handle = await fs2.open(filename, "r");
|
|
303
|
+
try {
|
|
304
|
+
const stat = await handle.stat();
|
|
305
|
+
if (!stat.isFile()) throw new CliValidationError("--file must be a regular file.");
|
|
306
|
+
if (stat.size > maxBytes) throw tooLarge();
|
|
307
|
+
bytes = await boundedBytes(handle.createReadStream({ autoClose: false }));
|
|
308
|
+
} finally {
|
|
309
|
+
await handle.close();
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
try {
|
|
313
|
+
content = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes);
|
|
314
|
+
} catch {
|
|
315
|
+
throw new CliValidationError("Text input must be valid UTF-8; no encoding conversion is performed.", { code: "SOURCE_TEXT_ENCODING_UNSUPPORTED" });
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
const sizeBytes = Buffer.byteLength(content, "utf8");
|
|
319
|
+
if (sizeBytes > maxBytes) throw tooLarge();
|
|
320
|
+
if (!content.trim()) throw new CliValidationError("Text content must not be empty or whitespace-only.", { code: "SOURCE_TEXT_EMPTY" });
|
|
321
|
+
return { content, sizeBytes };
|
|
322
|
+
}
|
|
323
|
+
function target2(ctx) {
|
|
324
|
+
return { name: ctx.str("name").trim(), scope: ctx.str("scope") };
|
|
325
|
+
}
|
|
326
|
+
var sourceCreateText = {
|
|
327
|
+
service: "kb",
|
|
328
|
+
resource: "source",
|
|
329
|
+
command: "create-text",
|
|
330
|
+
risk: "write",
|
|
331
|
+
description: "Create one ordinary Markdown source from text, a UTF-8 file or stdin. Saves only; does not compile or publish.",
|
|
332
|
+
flags: [
|
|
333
|
+
...targetFlags2,
|
|
334
|
+
{ name: "title", type: "string", desc: "Optional display title (1-200 Unicode characters); the server derives it from content when omitted" },
|
|
335
|
+
...textInputFlags
|
|
336
|
+
],
|
|
337
|
+
validate: (ctx) => {
|
|
338
|
+
validateTarget(ctx);
|
|
339
|
+
validateTextInput(ctx);
|
|
340
|
+
if (ctx.has?.("title") || ctx.str("title")) {
|
|
341
|
+
const title = ctx.str("title").trim();
|
|
342
|
+
if (!title || [...title].length > 200 || /[\p{Cc}/\\]/u.test(title) || [".", ".."].includes(title)) {
|
|
343
|
+
throw new CliValidationError("--title must contain 1 to 200 Unicode characters without control characters or path separators.");
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
},
|
|
347
|
+
dryRun: async (ctx) => {
|
|
348
|
+
const { sizeBytes } = await readTextInput(ctx);
|
|
349
|
+
return {
|
|
350
|
+
method: "POST",
|
|
351
|
+
url: `${ctx.host().replace(/\/$/, "")}${API}/sources/text`,
|
|
352
|
+
body: { ...target2(ctx), ...ctx.str("title") ? { title: ctx.str("title").trim() } : {}, inputMethod: "text_input", content: "<redacted>" },
|
|
353
|
+
sizeBytes
|
|
354
|
+
};
|
|
355
|
+
},
|
|
356
|
+
execute: async (ctx) => kbApi(ctx, "POST", `${API}/sources/text`, {}, {
|
|
357
|
+
...target2(ctx),
|
|
358
|
+
...ctx.str("title") ? { title: ctx.str("title").trim() } : {},
|
|
359
|
+
content: (await readTextInput(ctx)).content,
|
|
360
|
+
inputMethod: "text_input"
|
|
361
|
+
}, textApiOptions)
|
|
362
|
+
};
|
|
363
|
+
async function outputPath(ctx) {
|
|
364
|
+
if (!ctx.str("out")) return void 0;
|
|
365
|
+
const output = path2.resolve(ctx.str("out"));
|
|
366
|
+
try {
|
|
367
|
+
await fs2.lstat(output);
|
|
368
|
+
} catch (error) {
|
|
369
|
+
if (error.code === "ENOENT") return output;
|
|
370
|
+
throw error;
|
|
371
|
+
}
|
|
372
|
+
throw new CliValidationError("--out must name a new file; existing files are never overwritten.");
|
|
373
|
+
}
|
|
374
|
+
var sourceReadText = {
|
|
375
|
+
service: "kb",
|
|
376
|
+
resource: "source",
|
|
377
|
+
command: "read-text",
|
|
378
|
+
risk: "read",
|
|
379
|
+
sensitiveOutput: true,
|
|
380
|
+
description: "Read complete ordinary UTF-8 text with its matching revision and format. Optionally save original bytes to a new local file.",
|
|
381
|
+
flags: [
|
|
382
|
+
...targetFlags2,
|
|
383
|
+
{ name: "id", type: "string", required: true, desc: "Current stable source ID from kb +list-sources" },
|
|
384
|
+
{ name: "out", type: "string", desc: "Write the complete original UTF-8 bytes to a new file; output metadata only and never overwrite" }
|
|
385
|
+
],
|
|
386
|
+
validate: (ctx) => {
|
|
387
|
+
validateTarget(ctx);
|
|
388
|
+
const id = ctx.str("id");
|
|
389
|
+
if (!id.trim() || id.length > 191 || /[\x00-\x1f\x7f]/.test(id)) throw new CliValidationError("--id must contain 1 to 191 characters without control characters.");
|
|
390
|
+
if (ctx.has?.("out") && !ctx.str("out").trim()) throw new CliValidationError("--out must name a new file.");
|
|
391
|
+
},
|
|
392
|
+
dryRun: async (ctx) => ({
|
|
393
|
+
method: "GET",
|
|
394
|
+
url: `${ctx.host().replace(/\/$/, "")}${API}/sources/${encodeURIComponent(ctx.str("id").trim())}/text`,
|
|
395
|
+
params: target2(ctx),
|
|
396
|
+
...ctx.str("out") ? { out: await outputPath(ctx) } : {}
|
|
397
|
+
}),
|
|
398
|
+
execute: async (ctx) => {
|
|
399
|
+
const output = await outputPath(ctx);
|
|
400
|
+
const result = await kbApi(ctx, "GET", `${API}/sources/${encodeURIComponent(ctx.str("id").trim())}/text`, target2(ctx), void 0, textApiOptions);
|
|
401
|
+
if (!result || typeof result.content !== "string" || !["markdown", "text"].includes(result.contentFormat) || !Number.isSafeInteger(result.item?.contentRevision) || result.item.contentRevision < 1) {
|
|
402
|
+
throw new Error("KB text protocol error: expected complete content, format and a positive contentRevision.");
|
|
403
|
+
}
|
|
404
|
+
if (!output) return result;
|
|
405
|
+
await fs2.writeFile(output, result.content, { encoding: "utf8", flag: "wx" });
|
|
406
|
+
return { item: result.item, contentFormat: result.contentFormat, out: output };
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
// src/commands/te-kb/source-mutation.ts
|
|
411
|
+
import { promises as fs3 } from "fs";
|
|
412
|
+
import path3 from "path";
|
|
413
|
+
var API2 = "/agent/api/external/knowledge-bases";
|
|
414
|
+
var apiOptions = { preserveErrorMetadata: true };
|
|
415
|
+
var maxBytes2 = 50 * 1024 * 1024;
|
|
219
416
|
var fileExtensions = /* @__PURE__ */ new Set([".md", ".markdown", ".txt", ".csv", ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp", ".svg"]);
|
|
220
417
|
var identityFlags2 = [
|
|
221
418
|
{ name: "name", type: "string", required: true, desc: "Exact knowledge base name from kb +list" },
|
|
@@ -247,27 +444,27 @@ function query2(ctx) {
|
|
|
247
444
|
return { name: ctx.str("name").trim(), scope: ctx.str("scope") };
|
|
248
445
|
}
|
|
249
446
|
function sourceEndpoint(ctx, suffix) {
|
|
250
|
-
return `${
|
|
447
|
+
return `${API2}/sources/${encodeURIComponent(ctx.str("id").trim())}/${suffix}`;
|
|
251
448
|
}
|
|
252
449
|
function previewEndpoint(ctx) {
|
|
253
450
|
return sourceEndpoint(ctx, `directory/previews/${encodeURIComponent(ctx.str("preview-id").trim())}`);
|
|
254
451
|
}
|
|
255
|
-
function dryRequest(ctx, method, endpoint3,
|
|
256
|
-
return { method, url: `${ctx.host().replace(/\/$/, "")}${endpoint3}`, params: query2(ctx), ...
|
|
452
|
+
function dryRequest(ctx, method, endpoint3, body4) {
|
|
453
|
+
return { method, url: `${ctx.host().replace(/\/$/, "")}${endpoint3}`, params: query2(ctx), ...body4 === void 0 ? {} : { body: body4 } };
|
|
257
454
|
}
|
|
258
455
|
async function replacementFile(ctx, read) {
|
|
259
|
-
const file =
|
|
260
|
-
const extension =
|
|
456
|
+
const file = path3.resolve(ctx.str("file"));
|
|
457
|
+
const extension = path3.extname(file).toLowerCase();
|
|
261
458
|
if (ctx.str("source-type") === "zip" ? extension !== ".zip" : !fileExtensions.has(extension)) {
|
|
262
459
|
throw new CliValidationError("--file must be a ZIP for a ZIP source, or a supported non-ZIP file for a file source. File sources must keep their original format.");
|
|
263
460
|
}
|
|
264
|
-
const handle = await
|
|
461
|
+
const handle = await fs3.open(file, "r");
|
|
265
462
|
try {
|
|
266
463
|
const stat = await handle.stat();
|
|
267
|
-
if (!stat.isFile() || stat.size >
|
|
464
|
+
if (!stat.isFile() || stat.size > maxBytes2) throw new CliValidationError("--file must be a regular file of at most 50 MB.");
|
|
268
465
|
const content = read ? await handle.readFile() : void 0;
|
|
269
|
-
if (content && content.length >
|
|
270
|
-
return { file, filename:
|
|
466
|
+
if (content && content.length > maxBytes2) throw new CliValidationError("--file exceeds 50 MB.");
|
|
467
|
+
return { file, filename: path3.basename(file), sizeBytes: content?.length ?? stat.size, content };
|
|
271
468
|
} finally {
|
|
272
469
|
await handle.close();
|
|
273
470
|
}
|
|
@@ -283,17 +480,31 @@ var sourceReplace = {
|
|
|
283
480
|
resource: "source",
|
|
284
481
|
command: "replace",
|
|
285
482
|
risk: "write",
|
|
286
|
-
description: "Replace a file source draft, or prepare a ZIP archive replacement preview. ZIP changes require source commit. Does not compile or publish.",
|
|
287
|
-
flags: [...identityFlags2, typeFlag, revisionFlag,
|
|
483
|
+
description: "Replace a file source draft from a file or complete text, or prepare a ZIP archive replacement preview. ZIP changes require source commit. Does not compile or publish.",
|
|
484
|
+
flags: [...identityFlags2, typeFlag, revisionFlag, ...textInputFlags.map((flag2) => flag2.name === "file" ? { ...flag2, desc: "Local replacement file, at most 50 MiB; same format, different filename allowed; mutually exclusive with --text and --stdin" } : flag2)],
|
|
288
485
|
validate: (ctx) => {
|
|
289
486
|
validateMutation(ctx);
|
|
290
|
-
|
|
487
|
+
validateTextInput(ctx);
|
|
488
|
+
if ((hasTextFlag(ctx) || ctx.bool("stdin")) && ctx.str("source-type") !== "file") {
|
|
489
|
+
throw new CliValidationError("--text and --stdin require --source-type file and an ordinary text source.");
|
|
490
|
+
}
|
|
291
491
|
},
|
|
292
492
|
dryRun: async (ctx) => {
|
|
493
|
+
if (hasTextFlag(ctx) || ctx.bool("stdin")) {
|
|
494
|
+
const { sizeBytes: sizeBytes2 } = await readTextInput(ctx);
|
|
495
|
+
return { ...dryRequest(ctx, "PUT", sourceEndpoint(ctx, "text"), { expectedRevision: ctx.num("expected-revision"), inputMethod: "text_input", content: "<redacted>" }), sizeBytes: sizeBytes2 };
|
|
496
|
+
}
|
|
293
497
|
const { file, filename, sizeBytes } = await replacementFile(ctx, false);
|
|
294
498
|
return { ...dryRequest(ctx, ctx.str("source-type") === "zip" ? "POST" : "PUT", replaceEndpoint(ctx), replaceFields(ctx)), multipart: { file, filename, sizeBytes, content: "<redacted>" } };
|
|
295
499
|
},
|
|
296
500
|
execute: async (ctx) => {
|
|
501
|
+
if (hasTextFlag(ctx) || ctx.bool("stdin")) {
|
|
502
|
+
return kbApi(ctx, "PUT", sourceEndpoint(ctx, "text"), query2(ctx), {
|
|
503
|
+
content: (await readTextInput(ctx)).content,
|
|
504
|
+
expectedRevision: ctx.num("expected-revision"),
|
|
505
|
+
inputMethod: "text_input"
|
|
506
|
+
}, textApiOptions);
|
|
507
|
+
}
|
|
297
508
|
const file = await replacementFile(ctx, true);
|
|
298
509
|
const form = new FormData();
|
|
299
510
|
form.append("file", new Blob([new Uint8Array(file.content)]), file.filename);
|
|
@@ -302,7 +513,7 @@ var sourceReplace = {
|
|
|
302
513
|
}
|
|
303
514
|
};
|
|
304
515
|
function restoreEndpoint(ctx) {
|
|
305
|
-
return `${
|
|
516
|
+
return `${API2}/versions/${ctx.num("version")}/sources/${encodeURIComponent(ctx.str("id").trim())}/restore`;
|
|
306
517
|
}
|
|
307
518
|
function restoreBody(ctx) {
|
|
308
519
|
return { expectedRevision: ctx.num("expected-revision"), ...ctx.str("source-type") === "zip" ? ctx.str("path") ? { target: "file", path: ctx.str("path") } : { target: "source" } : {} };
|
|
@@ -381,10 +592,10 @@ var sourceCancel = {
|
|
|
381
592
|
};
|
|
382
593
|
|
|
383
594
|
// src/commands/te-kb/add.ts
|
|
384
|
-
import { promises as
|
|
385
|
-
import * as
|
|
595
|
+
import { promises as fs4 } from "fs";
|
|
596
|
+
import * as path4 from "path";
|
|
386
597
|
import TurndownService from "turndown";
|
|
387
|
-
var
|
|
598
|
+
var API_PATH3 = "/agent/api/external/knowledge-bases/sources/upload";
|
|
388
599
|
var SUPPORTED_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
389
600
|
".zip",
|
|
390
601
|
".md",
|
|
@@ -431,7 +642,7 @@ function sanitizeFilename(name) {
|
|
|
431
642
|
return cleaned || "document";
|
|
432
643
|
}
|
|
433
644
|
function getMimeType(filename) {
|
|
434
|
-
const ext =
|
|
645
|
+
const ext = path4.extname(filename).toLowerCase();
|
|
435
646
|
switch (ext) {
|
|
436
647
|
case ".zip":
|
|
437
648
|
return "application/zip";
|
|
@@ -474,23 +685,23 @@ function getMimeType(filename) {
|
|
|
474
685
|
}
|
|
475
686
|
}
|
|
476
687
|
async function readLocalFile(filePath) {
|
|
477
|
-
const ext =
|
|
688
|
+
const ext = path4.extname(filePath).toLowerCase();
|
|
478
689
|
if (!SUPPORTED_EXTENSIONS.has(ext)) {
|
|
479
690
|
throw new Error(`Unsupported file extension (${ext || "none"}): ${filePath}`);
|
|
480
691
|
}
|
|
481
|
-
const content = await
|
|
482
|
-
const filename =
|
|
692
|
+
const content = await fs4.readFile(filePath);
|
|
693
|
+
const filename = path4.basename(filePath);
|
|
483
694
|
return { filename, content, mimeType: getMimeType(filename), origin: "file", source: filePath };
|
|
484
695
|
}
|
|
485
696
|
async function readDirectory(dir) {
|
|
486
|
-
const entries = await
|
|
697
|
+
const entries = await fs4.readdir(dir, { withFileTypes: true });
|
|
487
698
|
const files = [];
|
|
488
699
|
for (const entry of entries) {
|
|
489
700
|
if (!entry.isFile()) continue;
|
|
490
|
-
const ext =
|
|
701
|
+
const ext = path4.extname(entry.name).toLowerCase();
|
|
491
702
|
if (!SUPPORTED_EXTENSIONS.has(ext)) continue;
|
|
492
|
-
const full =
|
|
493
|
-
const content = await
|
|
703
|
+
const full = path4.join(dir, entry.name);
|
|
704
|
+
const content = await fs4.readFile(full);
|
|
494
705
|
files.push({ filename: entry.name, content, mimeType: getMimeType(entry.name), origin: "dir", source: full });
|
|
495
706
|
}
|
|
496
707
|
if (files.length === 0) {
|
|
@@ -525,10 +736,10 @@ async function fetchAsMarkdown(rawUrl) {
|
|
|
525
736
|
};
|
|
526
737
|
}
|
|
527
738
|
async function resolveLocalPath(p) {
|
|
528
|
-
const abs =
|
|
739
|
+
const abs = path4.resolve(p);
|
|
529
740
|
let stat;
|
|
530
741
|
try {
|
|
531
|
-
stat = await
|
|
742
|
+
stat = await fs4.stat(abs);
|
|
532
743
|
} catch {
|
|
533
744
|
throw new Error(`Path not found: ${p}`);
|
|
534
745
|
}
|
|
@@ -564,7 +775,7 @@ function dedupeByFilename(files) {
|
|
|
564
775
|
const count = used.get(f.filename) ?? 0;
|
|
565
776
|
used.set(f.filename, count + 1);
|
|
566
777
|
if (count === 0) return f;
|
|
567
|
-
const ext =
|
|
778
|
+
const ext = path4.extname(f.filename);
|
|
568
779
|
const stem = f.filename.slice(0, f.filename.length - ext.length);
|
|
569
780
|
return { ...f, filename: `${stem}-${count}${ext}` };
|
|
570
781
|
});
|
|
@@ -599,17 +810,17 @@ var add = {
|
|
|
599
810
|
},
|
|
600
811
|
dryRun: (ctx) => {
|
|
601
812
|
const items = normalizeFilesInput(ctx.json("files"));
|
|
602
|
-
const
|
|
813
|
+
const body4 = {
|
|
603
814
|
name: ctx.str("name")
|
|
604
815
|
};
|
|
605
816
|
const scope = getExternalKnowledgeBaseTargetScope(ctx);
|
|
606
|
-
if (scope)
|
|
607
|
-
|
|
608
|
-
|
|
817
|
+
if (scope) body4.scope = scope;
|
|
818
|
+
body4.files = items.map((item) => ({ value: item, type: classifyInput(item) }));
|
|
819
|
+
body4.contentType = "multipart/form-data";
|
|
609
820
|
return {
|
|
610
821
|
method: "POST",
|
|
611
|
-
url: `${ctx.host().replace(/\/$/, "")}${
|
|
612
|
-
body:
|
|
822
|
+
url: `${ctx.host().replace(/\/$/, "")}${API_PATH3}`,
|
|
823
|
+
body: body4
|
|
613
824
|
};
|
|
614
825
|
},
|
|
615
826
|
execute: async (ctx) => {
|
|
@@ -617,7 +828,7 @@ var add = {
|
|
|
617
828
|
const scope = getExternalKnowledgeBaseTargetScope(ctx);
|
|
618
829
|
const files = await collectFiles(ctx);
|
|
619
830
|
const form = buildForm(name, scope, files);
|
|
620
|
-
const result = await kbUpload(ctx,
|
|
831
|
+
const result = await kbUpload(ctx, API_PATH3, form);
|
|
621
832
|
return {
|
|
622
833
|
uploaded: files.map((f) => ({ filename: f.filename, origin: f.origin, source: f.source })),
|
|
623
834
|
result
|
|
@@ -626,7 +837,7 @@ var add = {
|
|
|
626
837
|
};
|
|
627
838
|
|
|
628
839
|
// src/commands/te-kb/compile.ts
|
|
629
|
-
var
|
|
840
|
+
var API_PATH4 = "/agent/api/external/knowledge-bases/compile";
|
|
630
841
|
var VALID_MODES = /* @__PURE__ */ new Set(["incremental", "full"]);
|
|
631
842
|
function getMode(ctx) {
|
|
632
843
|
const mode = ctx.str("mode") || "incremental";
|
|
@@ -636,15 +847,15 @@ function getMode(ctx) {
|
|
|
636
847
|
return mode;
|
|
637
848
|
}
|
|
638
849
|
function buildBody(ctx) {
|
|
639
|
-
const
|
|
850
|
+
const body4 = {
|
|
640
851
|
name: ctx.str("name"),
|
|
641
852
|
mode: getMode(ctx)
|
|
642
853
|
};
|
|
643
854
|
const scope = getExternalKnowledgeBaseTargetScope(ctx);
|
|
644
|
-
if (scope)
|
|
855
|
+
if (scope) body4.scope = scope;
|
|
645
856
|
const model = ctx.str("model");
|
|
646
|
-
if (model)
|
|
647
|
-
return
|
|
857
|
+
if (model) body4.model = model;
|
|
858
|
+
return body4;
|
|
648
859
|
}
|
|
649
860
|
var compile = {
|
|
650
861
|
service: "kb",
|
|
@@ -663,19 +874,19 @@ var compile = {
|
|
|
663
874
|
},
|
|
664
875
|
dryRun: (ctx) => ({
|
|
665
876
|
method: "POST",
|
|
666
|
-
url: `${ctx.host().replace(/\/$/, "")}${
|
|
877
|
+
url: `${ctx.host().replace(/\/$/, "")}${API_PATH4}`,
|
|
667
878
|
body: buildBody(ctx)
|
|
668
879
|
}),
|
|
669
|
-
execute: async (ctx) => kbApi(ctx, "POST",
|
|
880
|
+
execute: async (ctx) => kbApi(ctx, "POST", API_PATH4, {}, buildBody(ctx))
|
|
670
881
|
};
|
|
671
882
|
|
|
672
883
|
// src/commands/te-kb/remove.ts
|
|
673
|
-
var
|
|
884
|
+
var API_PATH5 = "/agent/api/external/knowledge-bases";
|
|
674
885
|
function buildBody2(ctx) {
|
|
675
|
-
const
|
|
886
|
+
const body4 = { name: ctx.str("name") };
|
|
676
887
|
const scope = getExternalKnowledgeBaseTargetScope(ctx);
|
|
677
|
-
if (scope)
|
|
678
|
-
return
|
|
888
|
+
if (scope) body4.scope = scope;
|
|
889
|
+
return body4;
|
|
679
890
|
}
|
|
680
891
|
var remove = {
|
|
681
892
|
service: "kb",
|
|
@@ -691,14 +902,14 @@ var remove = {
|
|
|
691
902
|
},
|
|
692
903
|
dryRun: (ctx) => ({
|
|
693
904
|
method: "DELETE",
|
|
694
|
-
url: `${ctx.host().replace(/\/$/, "")}${
|
|
905
|
+
url: `${ctx.host().replace(/\/$/, "")}${API_PATH5}`,
|
|
695
906
|
body: buildBody2(ctx)
|
|
696
907
|
}),
|
|
697
|
-
execute: async (ctx) => kbApi(ctx, "DELETE",
|
|
908
|
+
execute: async (ctx) => kbApi(ctx, "DELETE", API_PATH5, {}, buildBody2(ctx))
|
|
698
909
|
};
|
|
699
910
|
|
|
700
911
|
// src/commands/te-kb/create.ts
|
|
701
|
-
var
|
|
912
|
+
var API_PATH6 = "/agent/api/external/knowledge-bases/create";
|
|
702
913
|
var VALID_SCOPES = /* @__PURE__ */ new Set(["personal", "company"]);
|
|
703
914
|
function getScope(ctx) {
|
|
704
915
|
const scope = ctx.str("scope") || "company";
|
|
@@ -726,19 +937,19 @@ function normalizeTags(raw) {
|
|
|
726
937
|
return tags;
|
|
727
938
|
}
|
|
728
939
|
function buildBody3(ctx) {
|
|
729
|
-
const
|
|
940
|
+
const body4 = {
|
|
730
941
|
scope: getScope(ctx),
|
|
731
942
|
name: ctx.str("name")
|
|
732
943
|
};
|
|
733
944
|
const description = ctx.str("description");
|
|
734
|
-
if (description)
|
|
945
|
+
if (description) body4.description = description;
|
|
735
946
|
const tags = normalizeTags(ctx.json("tags"));
|
|
736
|
-
if (tags && tags.length > 0)
|
|
947
|
+
if (tags && tags.length > 0) body4.tags = tags;
|
|
737
948
|
const projectId = ctx.str("project-id");
|
|
738
|
-
if (projectId)
|
|
949
|
+
if (projectId) body4.projectId = projectId;
|
|
739
950
|
const projectName = ctx.str("project-name");
|
|
740
|
-
if (projectName)
|
|
741
|
-
return
|
|
951
|
+
if (projectName) body4.projectName = projectName;
|
|
952
|
+
return body4;
|
|
742
953
|
}
|
|
743
954
|
var create = {
|
|
744
955
|
service: "kb",
|
|
@@ -759,14 +970,14 @@ var create = {
|
|
|
759
970
|
},
|
|
760
971
|
dryRun: (ctx) => ({
|
|
761
972
|
method: "POST",
|
|
762
|
-
url: `${ctx.host().replace(/\/$/, "")}${
|
|
973
|
+
url: `${ctx.host().replace(/\/$/, "")}${API_PATH6}`,
|
|
763
974
|
body: buildBody3(ctx)
|
|
764
975
|
}),
|
|
765
|
-
execute: async (ctx) => kbApi(ctx, "POST",
|
|
976
|
+
execute: async (ctx) => kbApi(ctx, "POST", API_PATH6, {}, buildBody3(ctx))
|
|
766
977
|
};
|
|
767
978
|
|
|
768
979
|
// src/commands/te-kb/rm-source.ts
|
|
769
|
-
var
|
|
980
|
+
var API_PATH7 = "/agent/api/external/knowledge-bases/sources";
|
|
770
981
|
function sourceSelector(ctx) {
|
|
771
982
|
const id = ctx.str("id").trim();
|
|
772
983
|
if (id) return { id };
|
|
@@ -775,12 +986,12 @@ function sourceSelector(ctx) {
|
|
|
775
986
|
throw new CliValidationError("One of --id or --display-name is required.");
|
|
776
987
|
}
|
|
777
988
|
function buildBody4(ctx) {
|
|
778
|
-
const
|
|
989
|
+
const body4 = {
|
|
779
990
|
name: ctx.str("name")
|
|
780
991
|
};
|
|
781
992
|
const scope = getExternalKnowledgeBaseTargetScope(ctx);
|
|
782
|
-
if (scope)
|
|
783
|
-
return { ...
|
|
993
|
+
if (scope) body4.scope = scope;
|
|
994
|
+
return { ...body4, ...sourceSelector(ctx) };
|
|
784
995
|
}
|
|
785
996
|
var rmSource = {
|
|
786
997
|
service: "kb",
|
|
@@ -799,18 +1010,18 @@ var rmSource = {
|
|
|
799
1010
|
},
|
|
800
1011
|
dryRun: (ctx) => ({
|
|
801
1012
|
method: "DELETE",
|
|
802
|
-
url: `${ctx.host().replace(/\/$/, "")}${
|
|
1013
|
+
url: `${ctx.host().replace(/\/$/, "")}${API_PATH7}`,
|
|
803
1014
|
body: buildBody4(ctx)
|
|
804
1015
|
}),
|
|
805
|
-
execute: async (ctx) => kbApi(ctx, "DELETE",
|
|
1016
|
+
execute: async (ctx) => kbApi(ctx, "DELETE", API_PATH7, {}, buildBody4(ctx), {
|
|
806
1017
|
preserveErrorMetadata: true
|
|
807
1018
|
})
|
|
808
1019
|
};
|
|
809
1020
|
|
|
810
1021
|
// src/commands/te-kb/schema.ts
|
|
811
|
-
import
|
|
812
|
-
import
|
|
813
|
-
var
|
|
1022
|
+
import fs5 from "fs";
|
|
1023
|
+
import path5 from "path";
|
|
1024
|
+
var API_PATH8 = "/agent/api/external/knowledge-bases/schema";
|
|
814
1025
|
var MAX_CUSTOM_INSTRUCTIONS_CHARS = 1e4;
|
|
815
1026
|
function getCustomInstructions(ctx) {
|
|
816
1027
|
const inline = ctx.str("custom-instructions");
|
|
@@ -818,7 +1029,7 @@ function getCustomInstructions(ctx) {
|
|
|
818
1029
|
if (inline && file) {
|
|
819
1030
|
throw new Error("Use either --custom-instructions or --custom-instructions-file, not both.");
|
|
820
1031
|
}
|
|
821
|
-
const content = file ?
|
|
1032
|
+
const content = file ? fs5.readFileSync(path5.resolve(file), "utf8") : inline;
|
|
822
1033
|
if (file && !content.trim()) {
|
|
823
1034
|
throw new Error("--custom-instructions-file is empty.");
|
|
824
1035
|
}
|
|
@@ -828,20 +1039,20 @@ function getCustomInstructions(ctx) {
|
|
|
828
1039
|
return content;
|
|
829
1040
|
}
|
|
830
1041
|
function buildBody5(ctx) {
|
|
831
|
-
const
|
|
1042
|
+
const body4 = {
|
|
832
1043
|
name: ctx.str("name")
|
|
833
1044
|
};
|
|
834
1045
|
const scope = getExternalKnowledgeBaseTargetScope(ctx);
|
|
835
|
-
if (scope)
|
|
836
|
-
if (ctx.bool("force"))
|
|
1046
|
+
if (scope) body4.scope = scope;
|
|
1047
|
+
if (ctx.bool("force")) body4.force = true;
|
|
837
1048
|
const model = ctx.str("model");
|
|
838
|
-
if (model)
|
|
1049
|
+
if (model) body4.model = model;
|
|
839
1050
|
const customInstructions = getCustomInstructions(ctx);
|
|
840
|
-
if (customInstructions)
|
|
841
|
-
return
|
|
1051
|
+
if (customInstructions) body4.customInstructions = customInstructions;
|
|
1052
|
+
return body4;
|
|
842
1053
|
}
|
|
843
1054
|
async function executeSchema(ctx, api = kbApi) {
|
|
844
|
-
return api(ctx, "POST",
|
|
1055
|
+
return api(ctx, "POST", API_PATH8, {}, buildBody5(ctx), {
|
|
845
1056
|
preserveBusinessErrorCode: true
|
|
846
1057
|
});
|
|
847
1058
|
}
|
|
@@ -876,21 +1087,21 @@ var schema = {
|
|
|
876
1087
|
},
|
|
877
1088
|
dryRun: (ctx) => ({
|
|
878
1089
|
method: "POST",
|
|
879
|
-
url: `${ctx.host().replace(/\/$/, "")}${
|
|
1090
|
+
url: `${ctx.host().replace(/\/$/, "")}${API_PATH8}`,
|
|
880
1091
|
body: buildBody5(ctx)
|
|
881
1092
|
}),
|
|
882
1093
|
execute: executeSchema
|
|
883
1094
|
};
|
|
884
1095
|
|
|
885
1096
|
// src/commands/te-kb/status.ts
|
|
886
|
-
var
|
|
1097
|
+
var API_PATH9 = "/agent/api/external/knowledge-bases/status";
|
|
887
1098
|
function buildBody6(ctx) {
|
|
888
|
-
const
|
|
1099
|
+
const body4 = {
|
|
889
1100
|
name: ctx.str("name")
|
|
890
1101
|
};
|
|
891
1102
|
const scope = getExternalKnowledgeBaseTargetScope(ctx);
|
|
892
|
-
if (scope)
|
|
893
|
-
return
|
|
1103
|
+
if (scope) body4.scope = scope;
|
|
1104
|
+
return body4;
|
|
894
1105
|
}
|
|
895
1106
|
var status = {
|
|
896
1107
|
service: "kb",
|
|
@@ -906,21 +1117,21 @@ var status = {
|
|
|
906
1117
|
},
|
|
907
1118
|
dryRun: (ctx) => ({
|
|
908
1119
|
method: "POST",
|
|
909
|
-
url: `${ctx.host().replace(/\/$/, "")}${
|
|
1120
|
+
url: `${ctx.host().replace(/\/$/, "")}${API_PATH9}`,
|
|
910
1121
|
body: buildBody6(ctx)
|
|
911
1122
|
}),
|
|
912
|
-
execute: async (ctx) => kbApi(ctx, "POST",
|
|
1123
|
+
execute: async (ctx) => kbApi(ctx, "POST", API_PATH9, {}, buildBody6(ctx))
|
|
913
1124
|
};
|
|
914
1125
|
|
|
915
1126
|
// src/commands/te-kb/kb-index.ts
|
|
916
|
-
var
|
|
1127
|
+
var API_PATH10 = "/agent/api/external/knowledge-bases/index";
|
|
917
1128
|
function buildBody7(ctx) {
|
|
918
|
-
const
|
|
1129
|
+
const body4 = {};
|
|
919
1130
|
const sources = ctx.json("sources");
|
|
920
|
-
if (sources)
|
|
1131
|
+
if (sources) body4.sources = sources;
|
|
921
1132
|
const locale = ctx.str("locale");
|
|
922
|
-
if (locale)
|
|
923
|
-
return
|
|
1133
|
+
if (locale) body4.locale = locale;
|
|
1134
|
+
return body4;
|
|
924
1135
|
}
|
|
925
1136
|
var kbIndex = {
|
|
926
1137
|
service: "kb",
|
|
@@ -938,14 +1149,14 @@ var kbIndex = {
|
|
|
938
1149
|
risk: "read",
|
|
939
1150
|
dryRun: (ctx) => ({
|
|
940
1151
|
method: "POST",
|
|
941
|
-
url: `${ctx.host().replace(/\/$/, "")}${
|
|
1152
|
+
url: `${ctx.host().replace(/\/$/, "")}${API_PATH10}`,
|
|
942
1153
|
body: buildBody7(ctx)
|
|
943
1154
|
}),
|
|
944
|
-
execute: async (ctx) => kbApi(ctx, "POST",
|
|
1155
|
+
execute: async (ctx) => kbApi(ctx, "POST", API_PATH10, {}, buildBody7(ctx))
|
|
945
1156
|
};
|
|
946
1157
|
|
|
947
1158
|
// src/commands/te-kb/kb-list.ts
|
|
948
|
-
var
|
|
1159
|
+
var API_PATH11 = "/agent/api/external/knowledge-bases/list";
|
|
949
1160
|
var DEFAULT_BUILD_STATUS = "compiled";
|
|
950
1161
|
var VALID_BUILD_STATUSES = ["idle", "pending", "compiling", "compiled", "failed"];
|
|
951
1162
|
function getBuildStatus(ctx) {
|
|
@@ -962,12 +1173,12 @@ function validateBuildStatus(ctx) {
|
|
|
962
1173
|
}
|
|
963
1174
|
}
|
|
964
1175
|
function buildBody8(ctx) {
|
|
965
|
-
const
|
|
1176
|
+
const body4 = {
|
|
966
1177
|
buildStatus: getBuildStatus(ctx)
|
|
967
1178
|
};
|
|
968
1179
|
const locale = ctx.str("locale");
|
|
969
|
-
if (locale)
|
|
970
|
-
return
|
|
1180
|
+
if (locale) body4.locale = locale;
|
|
1181
|
+
return body4;
|
|
971
1182
|
}
|
|
972
1183
|
var kbList = {
|
|
973
1184
|
service: "kb",
|
|
@@ -989,23 +1200,24 @@ var kbList = {
|
|
|
989
1200
|
},
|
|
990
1201
|
dryRun: (ctx) => ({
|
|
991
1202
|
method: "POST",
|
|
992
|
-
url: `${ctx.host().replace(/\/$/, "")}${
|
|
1203
|
+
url: `${ctx.host().replace(/\/$/, "")}${API_PATH11}`,
|
|
993
1204
|
body: buildBody8(ctx)
|
|
994
1205
|
}),
|
|
995
|
-
execute: async (ctx) => kbApi(ctx, "POST",
|
|
1206
|
+
execute: async (ctx) => kbApi(ctx, "POST", API_PATH11, {}, buildBody8(ctx))
|
|
996
1207
|
};
|
|
997
1208
|
|
|
998
1209
|
// src/commands/te-kb/list-sources.ts
|
|
999
|
-
var
|
|
1210
|
+
var API_PATH12 = "/agent/api/external/knowledge-bases/sources";
|
|
1000
1211
|
var MAX_KNOWLEDGE_BASE_NAME_LENGTH = 200;
|
|
1001
1212
|
function knowledgeBaseName(ctx) {
|
|
1002
1213
|
return ctx.str("name").trim();
|
|
1003
1214
|
}
|
|
1004
1215
|
function buildUrl(ctx) {
|
|
1005
|
-
const url2 = new URL(`${ctx.host().replace(/\/$/, "")}${
|
|
1216
|
+
const url2 = new URL(`${ctx.host().replace(/\/$/, "")}${API_PATH12}`);
|
|
1006
1217
|
url2.searchParams.set("name", knowledgeBaseName(ctx));
|
|
1007
1218
|
const scope = getExternalKnowledgeBaseTargetScope(ctx);
|
|
1008
1219
|
if (scope) url2.searchParams.set("scope", scope);
|
|
1220
|
+
if (ctx.str("content-type")) url2.searchParams.set("contentType", ctx.str("content-type"));
|
|
1009
1221
|
return url2.toString();
|
|
1010
1222
|
}
|
|
1011
1223
|
var listSources = {
|
|
@@ -1026,7 +1238,8 @@ var listSources = {
|
|
|
1026
1238
|
type: "string",
|
|
1027
1239
|
required: false,
|
|
1028
1240
|
desc: "Exact knowledge base scope: personal | company (omit for personal \u2192 company fallback)"
|
|
1029
|
-
}
|
|
1241
|
+
},
|
|
1242
|
+
{ name: "content-type", type: "string", desc: "Source content filter: all (default) or text (ordinary .md, .markdown and .txt files only)" }
|
|
1030
1243
|
],
|
|
1031
1244
|
risk: "read",
|
|
1032
1245
|
validate: (ctx) => {
|
|
@@ -1040,6 +1253,9 @@ var listSources = {
|
|
|
1040
1253
|
);
|
|
1041
1254
|
}
|
|
1042
1255
|
getExternalKnowledgeBaseTargetScope(ctx);
|
|
1256
|
+
if ((ctx.has?.("content-type") || ctx.str("content-type")) && !["all", "text"].includes(ctx.str("content-type"))) {
|
|
1257
|
+
throw new CliValidationError("--content-type must be all or text.");
|
|
1258
|
+
}
|
|
1043
1259
|
},
|
|
1044
1260
|
dryRun: (ctx) => ({
|
|
1045
1261
|
method: "GET",
|
|
@@ -1049,26 +1265,82 @@ var listSources = {
|
|
|
1049
1265
|
const params = { name: knowledgeBaseName(ctx) };
|
|
1050
1266
|
const scope = getExternalKnowledgeBaseTargetScope(ctx);
|
|
1051
1267
|
if (scope) params.scope = scope;
|
|
1052
|
-
|
|
1268
|
+
if (ctx.str("content-type")) params.contentType = ctx.str("content-type");
|
|
1269
|
+
return kbApi(ctx, "GET", API_PATH12, params, void 0, {
|
|
1053
1270
|
preserveErrorMetadata: true,
|
|
1054
1271
|
retryUnauthorized: false
|
|
1055
1272
|
});
|
|
1056
1273
|
}
|
|
1057
1274
|
};
|
|
1058
1275
|
|
|
1276
|
+
// src/commands/te-kb/usage-list.ts
|
|
1277
|
+
var API_PATH13 = "/agent/api/external/knowledge-bases/usage-logs";
|
|
1278
|
+
function query3(ctx) {
|
|
1279
|
+
const scope = getExternalKnowledgeBaseTargetScope(ctx);
|
|
1280
|
+
return {
|
|
1281
|
+
name: ctx.str("name").trim(),
|
|
1282
|
+
...scope ? { scope } : {},
|
|
1283
|
+
page: ctx.num("page"),
|
|
1284
|
+
pageSize: ctx.num("page-size")
|
|
1285
|
+
};
|
|
1286
|
+
}
|
|
1287
|
+
var usageList = {
|
|
1288
|
+
service: "kb",
|
|
1289
|
+
resource: "usage",
|
|
1290
|
+
command: "list",
|
|
1291
|
+
risk: "read",
|
|
1292
|
+
description: "List one page of compilation usage logs. durationMs is elapsed time in milliseconds; null means not recorded.",
|
|
1293
|
+
flags: [
|
|
1294
|
+
{ name: "name", type: "string", required: true, minLength: 1, maxLength: 200, desc: "Exact knowledge base name from kb +list" },
|
|
1295
|
+
{ name: "scope", type: "string", desc: "Exact scope: personal | company (omit for personal then company lookup)" },
|
|
1296
|
+
{ name: "page", type: "number", default: 1, min: 1, max: 2147483647, desc: "Page number, starting at 1" },
|
|
1297
|
+
{ name: "page-size", type: "number", default: 20, min: 1, max: 100, desc: "Records per page, from 1 to 100" }
|
|
1298
|
+
],
|
|
1299
|
+
validate: (ctx) => {
|
|
1300
|
+
const name = ctx.str("name").trim();
|
|
1301
|
+
if (!name || name.length > 200) throw new CliValidationError("--name must contain 1 to 200 characters.");
|
|
1302
|
+
getExternalKnowledgeBaseTargetScope(ctx);
|
|
1303
|
+
for (const [flag2, max] of [["page", 2147483647], ["page-size", 100]]) {
|
|
1304
|
+
const value = ctx.num(flag2);
|
|
1305
|
+
if (!Number.isInteger(value) || value < 1 || value > max) {
|
|
1306
|
+
throw new CliValidationError(`--${flag2} must be an integer from 1 to ${max}.`);
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
},
|
|
1310
|
+
dryRun: (ctx) => ({ method: "GET", url: `${ctx.host().replace(/\/$/, "")}${API_PATH13}`, params: query3(ctx) }),
|
|
1311
|
+
execute: async (ctx) => {
|
|
1312
|
+
try {
|
|
1313
|
+
return await kbApi(ctx, "GET", API_PATH13, query3(ctx), void 0, { preserveErrorMetadata: true });
|
|
1314
|
+
} catch (error) {
|
|
1315
|
+
if (error instanceof PermissionError) {
|
|
1316
|
+
error.message = "Permission denied when reading knowledge base usage logs.";
|
|
1317
|
+
} else if (error instanceof CapabilityGatewayError) {
|
|
1318
|
+
const messages = {
|
|
1319
|
+
KB_USAGE_LOGS_INVALID_REQUEST: "Invalid knowledge base usage query parameters.",
|
|
1320
|
+
KB_USAGE_LOGS_RATE_LIMITED: "Knowledge base usage query rate limit exceeded. Try again later.",
|
|
1321
|
+
KB_USAGE_LOGS_NOT_FOUND: "Knowledge base not found in the requested scope.",
|
|
1322
|
+
KB_USAGE_LOGS_INTERNAL_ERROR: "Failed to read knowledge base usage logs. Try again later."
|
|
1323
|
+
};
|
|
1324
|
+
if (error.code && messages[error.code]) error.message = messages[error.code];
|
|
1325
|
+
}
|
|
1326
|
+
throw error;
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
};
|
|
1330
|
+
|
|
1059
1331
|
// src/commands/te-kb/kb-grep.ts
|
|
1060
|
-
var
|
|
1332
|
+
var API_PATH14 = "/agent/api/external/knowledge-bases/grep";
|
|
1061
1333
|
function buildBody9(ctx) {
|
|
1062
|
-
const
|
|
1334
|
+
const body4 = {
|
|
1063
1335
|
query: ctx.str("query"),
|
|
1064
1336
|
sources: ctx.json("sources"),
|
|
1065
1337
|
paths: ctx.json("paths")
|
|
1066
1338
|
};
|
|
1067
1339
|
const topK = ctx.optionalNum("top-k");
|
|
1068
|
-
if (topK !== void 0)
|
|
1340
|
+
if (topK !== void 0) body4.topK = topK;
|
|
1069
1341
|
const locale = ctx.str("locale");
|
|
1070
|
-
if (locale)
|
|
1071
|
-
return
|
|
1342
|
+
if (locale) body4.locale = locale;
|
|
1343
|
+
return body4;
|
|
1072
1344
|
}
|
|
1073
1345
|
var kbGrep = {
|
|
1074
1346
|
service: "kb",
|
|
@@ -1100,14 +1372,14 @@ var kbGrep = {
|
|
|
1100
1372
|
risk: "read",
|
|
1101
1373
|
dryRun: (ctx) => ({
|
|
1102
1374
|
method: "POST",
|
|
1103
|
-
url: `${ctx.host().replace(/\/$/, "")}${
|
|
1375
|
+
url: `${ctx.host().replace(/\/$/, "")}${API_PATH14}`,
|
|
1104
1376
|
body: buildBody9(ctx)
|
|
1105
1377
|
}),
|
|
1106
|
-
execute: async (ctx) => kbApi(ctx, "POST",
|
|
1378
|
+
execute: async (ctx) => kbApi(ctx, "POST", API_PATH14, {}, buildBody9(ctx))
|
|
1107
1379
|
};
|
|
1108
1380
|
|
|
1109
1381
|
// src/commands/te-kb/kb-read.ts
|
|
1110
|
-
var
|
|
1382
|
+
var API_PATH15 = "/agent/api/external/knowledge-bases/read";
|
|
1111
1383
|
var VALID_EXPAND_MODES = /* @__PURE__ */ new Set(["block", "none"]);
|
|
1112
1384
|
var MAX_READ_LIMIT = 2e3;
|
|
1113
1385
|
function readExpand(ctx) {
|
|
@@ -1131,20 +1403,20 @@ function readLimit(ctx) {
|
|
|
1131
1403
|
return limit;
|
|
1132
1404
|
}
|
|
1133
1405
|
function buildBody10(ctx) {
|
|
1134
|
-
const
|
|
1406
|
+
const body4 = {
|
|
1135
1407
|
source: ctx.json("source"),
|
|
1136
1408
|
path: ctx.str("path")
|
|
1137
1409
|
};
|
|
1138
1410
|
const offset = ctx.optionalNum("offset");
|
|
1139
|
-
if (offset !== void 0)
|
|
1411
|
+
if (offset !== void 0) body4.offset = offset;
|
|
1140
1412
|
const limit = ctx.optionalNum("limit");
|
|
1141
|
-
if (limit !== void 0)
|
|
1413
|
+
if (limit !== void 0) body4.limit = limit;
|
|
1142
1414
|
const expand = readExpand(ctx);
|
|
1143
|
-
if (expand)
|
|
1144
|
-
if (ctx.bool("outline"))
|
|
1415
|
+
if (expand) body4.expand = expand;
|
|
1416
|
+
if (ctx.bool("outline")) body4.outline = true;
|
|
1145
1417
|
const locale = ctx.str("locale");
|
|
1146
|
-
if (locale)
|
|
1147
|
-
return
|
|
1418
|
+
if (locale) body4.locale = locale;
|
|
1419
|
+
return body4;
|
|
1148
1420
|
}
|
|
1149
1421
|
var kbRead = {
|
|
1150
1422
|
service: "kb",
|
|
@@ -1185,10 +1457,10 @@ var kbRead = {
|
|
|
1185
1457
|
},
|
|
1186
1458
|
dryRun: (ctx) => ({
|
|
1187
1459
|
method: "POST",
|
|
1188
|
-
url: `${ctx.host().replace(/\/$/, "")}${
|
|
1460
|
+
url: `${ctx.host().replace(/\/$/, "")}${API_PATH15}`,
|
|
1189
1461
|
body: buildBody10(ctx)
|
|
1190
1462
|
}),
|
|
1191
|
-
execute: async (ctx) => kbApi(ctx, "POST",
|
|
1463
|
+
execute: async (ctx) => kbApi(ctx, "POST", API_PATH15, {}, buildBody10(ctx))
|
|
1192
1464
|
};
|
|
1193
1465
|
|
|
1194
1466
|
// src/commands/te-kb/ask-shared.ts
|
|
@@ -1269,16 +1541,16 @@ function validateLocale(locale) {
|
|
|
1269
1541
|
}
|
|
1270
1542
|
}
|
|
1271
1543
|
function buildBody11(ctx) {
|
|
1272
|
-
const
|
|
1544
|
+
const body4 = {
|
|
1273
1545
|
question: ctx.str("question")
|
|
1274
1546
|
};
|
|
1275
1547
|
const sources = ctx.json("sources");
|
|
1276
|
-
if (sources)
|
|
1548
|
+
if (sources) body4.sources = sources;
|
|
1277
1549
|
const modelId = ctx.str("model-id");
|
|
1278
|
-
if (modelId)
|
|
1550
|
+
if (modelId) body4.modelId = modelId;
|
|
1279
1551
|
const locale = ctx.str("locale");
|
|
1280
|
-
if (locale)
|
|
1281
|
-
return
|
|
1552
|
+
if (locale) body4.locale = locale;
|
|
1553
|
+
return body4;
|
|
1282
1554
|
}
|
|
1283
1555
|
var ask = {
|
|
1284
1556
|
service: "kb",
|
|
@@ -1398,24 +1670,24 @@ var askStatus = {
|
|
|
1398
1670
|
};
|
|
1399
1671
|
|
|
1400
1672
|
// src/commands/te-kb/url.ts
|
|
1401
|
-
var
|
|
1673
|
+
var API_PATH16 = "/agent/api/external/knowledge-bases/sources/url";
|
|
1402
1674
|
function validateUrl(url2) {
|
|
1403
1675
|
if (!/^https?:\/\//i.test(url2)) {
|
|
1404
1676
|
throw new Error(`Invalid --url: ${url2}. Must be an http(s) URL`);
|
|
1405
1677
|
}
|
|
1406
1678
|
}
|
|
1407
1679
|
function buildBody12(ctx) {
|
|
1408
|
-
const
|
|
1680
|
+
const body4 = {
|
|
1409
1681
|
name: ctx.str("name"),
|
|
1410
1682
|
url: ctx.str("url")
|
|
1411
1683
|
};
|
|
1412
1684
|
const scope = getExternalKnowledgeBaseTargetScope(ctx);
|
|
1413
|
-
if (scope)
|
|
1685
|
+
if (scope) body4.scope = scope;
|
|
1414
1686
|
const displayName = ctx.str("display-name");
|
|
1415
|
-
if (displayName)
|
|
1687
|
+
if (displayName) body4.displayName = displayName;
|
|
1416
1688
|
const parseInstruction = ctx.str("parse-instruction");
|
|
1417
|
-
if (parseInstruction)
|
|
1418
|
-
return
|
|
1689
|
+
if (parseInstruction) body4.parseInstruction = parseInstruction;
|
|
1690
|
+
return body4;
|
|
1419
1691
|
}
|
|
1420
1692
|
var url = {
|
|
1421
1693
|
service: "kb",
|
|
@@ -1435,16 +1707,16 @@ var url = {
|
|
|
1435
1707
|
},
|
|
1436
1708
|
dryRun: (ctx) => ({
|
|
1437
1709
|
method: "POST",
|
|
1438
|
-
url: `${ctx.host().replace(/\/$/, "")}${
|
|
1710
|
+
url: `${ctx.host().replace(/\/$/, "")}${API_PATH16}`,
|
|
1439
1711
|
body: buildBody12(ctx)
|
|
1440
1712
|
}),
|
|
1441
|
-
execute: async (ctx) => kbApi(ctx, "POST",
|
|
1713
|
+
execute: async (ctx) => kbApi(ctx, "POST", API_PATH16, {}, buildBody12(ctx))
|
|
1442
1714
|
};
|
|
1443
1715
|
|
|
1444
1716
|
// src/commands/te-kb/import.ts
|
|
1445
|
-
import { promises as
|
|
1446
|
-
import
|
|
1447
|
-
var
|
|
1717
|
+
import { promises as fs6 } from "fs";
|
|
1718
|
+
import path6 from "path";
|
|
1719
|
+
var API_PATH17 = "/agent/api/external/knowledge-bases/import";
|
|
1448
1720
|
var MAX_SNAPSHOT_ARCHIVE_BYTES = 50 * 1024 * 1024;
|
|
1449
1721
|
var VALID_SCOPES2 = /* @__PURE__ */ new Set(["personal", "company"]);
|
|
1450
1722
|
function getScope2(ctx) {
|
|
@@ -1480,16 +1752,16 @@ function normalizeTags2(raw) {
|
|
|
1480
1752
|
return tags;
|
|
1481
1753
|
}
|
|
1482
1754
|
function validateArchivePath(filePath) {
|
|
1483
|
-
if (
|
|
1755
|
+
if (path6.extname(filePath).toLocaleLowerCase("en-US") !== ".zip") {
|
|
1484
1756
|
throw new Error("--file must point to a .zip archive");
|
|
1485
1757
|
}
|
|
1486
1758
|
}
|
|
1487
1759
|
async function readArchive(filePath) {
|
|
1488
1760
|
validateArchivePath(filePath);
|
|
1489
|
-
const absolutePath =
|
|
1761
|
+
const absolutePath = path6.resolve(filePath);
|
|
1490
1762
|
let stat;
|
|
1491
1763
|
try {
|
|
1492
|
-
stat = await
|
|
1764
|
+
stat = await fs6.stat(absolutePath);
|
|
1493
1765
|
} catch {
|
|
1494
1766
|
throw new Error(`File not found: ${filePath}`);
|
|
1495
1767
|
}
|
|
@@ -1499,7 +1771,7 @@ async function readArchive(filePath) {
|
|
|
1499
1771
|
if (stat.size > MAX_SNAPSHOT_ARCHIVE_BYTES) {
|
|
1500
1772
|
throw new Error("--file must not exceed 50 MB");
|
|
1501
1773
|
}
|
|
1502
|
-
return { absolutePath, bytes: await
|
|
1774
|
+
return { absolutePath, bytes: await fs6.readFile(absolutePath) };
|
|
1503
1775
|
}
|
|
1504
1776
|
function appendOptionalFields(ctx, form) {
|
|
1505
1777
|
const description = ctx.str("description").trim();
|
|
@@ -1566,7 +1838,7 @@ var importSnapshot = {
|
|
|
1566
1838
|
form.append(
|
|
1567
1839
|
"file",
|
|
1568
1840
|
new Blob([Uint8Array.from(archive.bytes)], { type: "application/zip" }),
|
|
1569
|
-
|
|
1841
|
+
path6.basename(archive.absolutePath)
|
|
1570
1842
|
);
|
|
1571
1843
|
form.append("name", ctx.str("name").trim());
|
|
1572
1844
|
form.append("scope", getScope2(ctx));
|
|
@@ -1574,7 +1846,7 @@ var importSnapshot = {
|
|
|
1574
1846
|
try {
|
|
1575
1847
|
return await kbUpload(
|
|
1576
1848
|
ctx,
|
|
1577
|
-
|
|
1849
|
+
API_PATH17,
|
|
1578
1850
|
form,
|
|
1579
1851
|
{ scope: getScope2(ctx) },
|
|
1580
1852
|
{ preserveErrorMetadata: true, retryUnauthorized: true }
|
|
@@ -1603,7 +1875,7 @@ var importSnapshot = {
|
|
|
1603
1875
|
};
|
|
1604
1876
|
|
|
1605
1877
|
// src/commands/te-kb/import-status.ts
|
|
1606
|
-
var
|
|
1878
|
+
var API_PATH18 = "/agent/api/external/knowledge-bases/import";
|
|
1607
1879
|
var MAX_REQUEST_ID_LENGTH = 191;
|
|
1608
1880
|
function requestIdFrom(ctx) {
|
|
1609
1881
|
return ctx.str("request-id").trim();
|
|
@@ -1634,7 +1906,7 @@ var importStatus = {
|
|
|
1634
1906
|
},
|
|
1635
1907
|
dryRun: (ctx) => ({
|
|
1636
1908
|
method: "GET",
|
|
1637
|
-
url: `${ctx.host().replace(/\/$/, "")}${
|
|
1909
|
+
url: `${ctx.host().replace(/\/$/, "")}${API_PATH18}?requestId=${encodeURIComponent(requestIdFrom(ctx))}`
|
|
1638
1910
|
}),
|
|
1639
1911
|
execute: async (ctx) => {
|
|
1640
1912
|
const hint = "Verify the request ID and that the server supports kb +import-status. Do not retry the import until its status is known.";
|
|
@@ -1642,7 +1914,7 @@ var importStatus = {
|
|
|
1642
1914
|
return await kbApi(
|
|
1643
1915
|
ctx,
|
|
1644
1916
|
"GET",
|
|
1645
|
-
|
|
1917
|
+
API_PATH18,
|
|
1646
1918
|
{ requestId: requestIdFrom(ctx) },
|
|
1647
1919
|
void 0,
|
|
1648
1920
|
{ preserveErrorMetadata: true, retryUnauthorized: true }
|
|
@@ -1673,8 +1945,8 @@ var importStatus = {
|
|
|
1673
1945
|
};
|
|
1674
1946
|
|
|
1675
1947
|
// src/commands/te-kb/source-directory.ts
|
|
1676
|
-
import { promises as
|
|
1677
|
-
import
|
|
1948
|
+
import { promises as fs7 } from "fs";
|
|
1949
|
+
import path7 from "path";
|
|
1678
1950
|
var sourceFlags = [
|
|
1679
1951
|
{ name: "name", type: "string", required: true, desc: "Knowledge base name (personal then company)" },
|
|
1680
1952
|
{ name: "id", type: "string", required: true, desc: "ZIP source ID copied from +list-sources" }
|
|
@@ -1713,11 +1985,11 @@ function validateMutation2(ctx) {
|
|
|
1713
1985
|
function endpoint2(ctx, suffix = "directory") {
|
|
1714
1986
|
return `/agent/api/external/knowledge-bases/sources/${encodeURIComponent(ctx.str("id").trim())}/${suffix}`;
|
|
1715
1987
|
}
|
|
1716
|
-
function
|
|
1988
|
+
function query4(ctx) {
|
|
1717
1989
|
return { name: ctx.str("name").trim(), path: ctx.str("path") };
|
|
1718
1990
|
}
|
|
1719
|
-
function preview(ctx, method, suffix = "directory",
|
|
1720
|
-
return { method, url: `${ctx.host().replace(/\/$/, "")}${endpoint2(ctx, suffix)}`, ...
|
|
1991
|
+
function preview(ctx, method, suffix = "directory", body4) {
|
|
1992
|
+
return { method, url: `${ctx.host().replace(/\/$/, "")}${endpoint2(ctx, suffix)}`, ...body4 ? { body: body4 } : { params: query4(ctx) } };
|
|
1721
1993
|
}
|
|
1722
1994
|
function mutationBody(ctx, operation) {
|
|
1723
1995
|
return { name: ctx.str("name").trim(), expectedRevision: ctx.num("expected-revision"), operations: [operation] };
|
|
@@ -1740,9 +2012,9 @@ var sourceLs = {
|
|
|
1740
2012
|
throw new CliValidationError("--limit must be an integer from 1 to 200.");
|
|
1741
2013
|
}
|
|
1742
2014
|
},
|
|
1743
|
-
dryRun: (ctx) => ({ ...preview(ctx, "GET"), params: { ...
|
|
2015
|
+
dryRun: (ctx) => ({ ...preview(ctx, "GET"), params: { ...query4(ctx), limit: ctx.num("limit"), ...ctx.str("cursor") ? { cursor: ctx.str("cursor") } : {} } }),
|
|
1744
2016
|
execute: (ctx) => kbApi(ctx, "GET", endpoint2(ctx), {
|
|
1745
|
-
...
|
|
2017
|
+
...query4(ctx),
|
|
1746
2018
|
limit: ctx.num("limit"),
|
|
1747
2019
|
...ctx.str("cursor") ? { cursor: ctx.str("cursor") } : {}
|
|
1748
2020
|
}, void 0, apiOptions2)
|
|
@@ -1765,12 +2037,12 @@ var sourceRead = {
|
|
|
1765
2037
|
},
|
|
1766
2038
|
dryRun: (ctx) => preview(ctx, "GET", "raw"),
|
|
1767
2039
|
execute: async (ctx) => {
|
|
1768
|
-
const result = await kbApi(ctx, "GET", endpoint2(ctx, "raw"),
|
|
2040
|
+
const result = await kbApi(ctx, "GET", endpoint2(ctx, "raw"), query4(ctx), void 0, { ...apiOptions2, responseType: "bytes" });
|
|
1769
2041
|
const bytes = Buffer.from(result.bytes);
|
|
1770
2042
|
const metadata = { path: ctx.str("path"), sizeBytes: bytes.length, contentType: result.contentType };
|
|
1771
2043
|
if (ctx.str("output")) {
|
|
1772
|
-
const output =
|
|
1773
|
-
await
|
|
2044
|
+
const output = path7.resolve(ctx.str("output"));
|
|
2045
|
+
await fs7.writeFile(output, bytes, { flag: "wx" });
|
|
1774
2046
|
return { ...metadata, output };
|
|
1775
2047
|
}
|
|
1776
2048
|
if (ctx.str("encoding") === "base64") return { ...metadata, encoding: "base64", content: bytes.toString("base64") };
|
|
@@ -1782,8 +2054,8 @@ var sourceRead = {
|
|
|
1782
2054
|
}
|
|
1783
2055
|
};
|
|
1784
2056
|
async function fileOperation(ctx, dryRun) {
|
|
1785
|
-
const file =
|
|
1786
|
-
const handle = await
|
|
2057
|
+
const file = path7.resolve(ctx.str("file"));
|
|
2058
|
+
const handle = await fs7.open(file, "r");
|
|
1787
2059
|
try {
|
|
1788
2060
|
const stat = await handle.stat();
|
|
1789
2061
|
if (!stat.isFile() || stat.size > maxFileBytes) throw new CliValidationError("--file must be a regular file of at most 50 MB.");
|
|
@@ -1840,11 +2112,11 @@ var sourceRm = {
|
|
|
1840
2112
|
};
|
|
1841
2113
|
|
|
1842
2114
|
// src/commands/te-kb/version-management.ts
|
|
1843
|
-
import { promises as
|
|
1844
|
-
import
|
|
1845
|
-
var
|
|
2115
|
+
import { promises as fs8 } from "fs";
|
|
2116
|
+
import path8 from "path";
|
|
2117
|
+
var API3 = "/agent/api/external/knowledge-bases/versions";
|
|
1846
2118
|
var apiOptions3 = { preserveErrorMetadata: true, retryUnauthorized: false };
|
|
1847
|
-
var
|
|
2119
|
+
var targetFlags3 = [
|
|
1848
2120
|
{ name: "name", type: "string", required: true, minLength: 1, maxLength: 200, desc: "Exact knowledge base name copied from +list" },
|
|
1849
2121
|
{ name: "scope", type: "string", desc: "Exact personal or company scope; omit for personal then company lookup" }
|
|
1850
2122
|
];
|
|
@@ -1860,13 +2132,13 @@ function positiveInteger2(ctx, flag2) {
|
|
|
1860
2132
|
if (!Number.isSafeInteger(value) || value < 1 || value > 2147483647) throw new CliValidationError(`--${flag2} must be a positive integer no greater than 2147483647.`);
|
|
1861
2133
|
return value;
|
|
1862
2134
|
}
|
|
1863
|
-
function
|
|
2135
|
+
function validateTarget2(ctx) {
|
|
1864
2136
|
const name = ctx.str("name").trim();
|
|
1865
2137
|
if (!name || name.length > 200) throw new CliValidationError("--name must contain 1 to 200 characters.");
|
|
1866
2138
|
getExternalKnowledgeBaseTargetScope(ctx);
|
|
1867
2139
|
}
|
|
1868
2140
|
function validateVersion(ctx) {
|
|
1869
|
-
|
|
2141
|
+
validateTarget2(ctx);
|
|
1870
2142
|
positiveInteger2(ctx, "version");
|
|
1871
2143
|
}
|
|
1872
2144
|
function validateSource(ctx) {
|
|
@@ -1886,52 +2158,52 @@ function validatePath(ctx, required = false) {
|
|
|
1886
2158
|
throw new CliValidationError("--path must be a normalized relative path inside the historical source.");
|
|
1887
2159
|
}
|
|
1888
2160
|
}
|
|
1889
|
-
function
|
|
2161
|
+
function query5(ctx) {
|
|
1890
2162
|
const scope = getExternalKnowledgeBaseTargetScope(ctx);
|
|
1891
2163
|
return { name: ctx.str("name").trim(), ...scope ? { scope } : {} };
|
|
1892
2164
|
}
|
|
1893
2165
|
function pageQuery(ctx) {
|
|
1894
|
-
return { ...
|
|
2166
|
+
return { ...query5(ctx), limit: ctx.num("limit"), ...ctx.str("cursor") ? { cursor: ctx.str("cursor") } : {} };
|
|
1895
2167
|
}
|
|
1896
2168
|
function versionEndpoint(ctx, suffix = "") {
|
|
1897
|
-
return `${
|
|
2169
|
+
return `${API3}/${positiveInteger2(ctx, "version")}${suffix}`;
|
|
1898
2170
|
}
|
|
1899
2171
|
function sourceEndpoint2(ctx, action) {
|
|
1900
2172
|
return versionEndpoint(ctx, `/sources/${encodeURIComponent(ctx.str("id").trim())}/${action}`);
|
|
1901
2173
|
}
|
|
1902
|
-
function preview2(ctx, endpoint3, params,
|
|
1903
|
-
return { method:
|
|
2174
|
+
function preview2(ctx, endpoint3, params, body4) {
|
|
2175
|
+
return { method: body4 ? "POST" : "GET", url: `${ctx.host().replace(/\/$/, "")}${endpoint3}`, params, ...body4 ? { body: body4 } : {} };
|
|
1904
2176
|
}
|
|
1905
2177
|
var versions = {
|
|
1906
2178
|
service: "kb",
|
|
1907
2179
|
command: "+versions",
|
|
1908
2180
|
risk: "read",
|
|
1909
2181
|
description: "List immutable published versions and the latest version ID, one page at a time.",
|
|
1910
|
-
flags: [...
|
|
2182
|
+
flags: [...targetFlags3, ...pagingFlags],
|
|
1911
2183
|
validate: (ctx) => {
|
|
1912
|
-
|
|
2184
|
+
validateTarget2(ctx);
|
|
1913
2185
|
validatePage(ctx);
|
|
1914
2186
|
if (ctx.str("cursor") && (!/^[1-9][0-9]*$/.test(ctx.str("cursor")) || Number(ctx.str("cursor")) > 2147483647)) throw new CliValidationError("--cursor must be a version number returned as nextCursor.");
|
|
1915
2187
|
},
|
|
1916
|
-
dryRun: (ctx) => preview2(ctx,
|
|
1917
|
-
execute: (ctx) => kbApi(ctx, "GET",
|
|
2188
|
+
dryRun: (ctx) => preview2(ctx, API3, pageQuery(ctx)),
|
|
2189
|
+
execute: (ctx) => kbApi(ctx, "GET", API3, pageQuery(ctx), void 0, apiOptions3)
|
|
1918
2190
|
};
|
|
1919
2191
|
var versionShow = {
|
|
1920
2192
|
service: "kb",
|
|
1921
2193
|
command: "+version-show",
|
|
1922
2194
|
risk: "read",
|
|
1923
2195
|
description: "Read one published version summary without reading current sources.",
|
|
1924
|
-
flags: [...
|
|
2196
|
+
flags: [...targetFlags3, versionFlag],
|
|
1925
2197
|
validate: validateVersion,
|
|
1926
|
-
dryRun: (ctx) => preview2(ctx, versionEndpoint(ctx),
|
|
1927
|
-
execute: (ctx) => kbApi(ctx, "GET", versionEndpoint(ctx),
|
|
2198
|
+
dryRun: (ctx) => preview2(ctx, versionEndpoint(ctx), query5(ctx)),
|
|
2199
|
+
execute: (ctx) => kbApi(ctx, "GET", versionEndpoint(ctx), query5(ctx), void 0, apiOptions3)
|
|
1928
2200
|
};
|
|
1929
2201
|
var versionSources = {
|
|
1930
2202
|
service: "kb",
|
|
1931
2203
|
command: "+version-sources",
|
|
1932
2204
|
risk: "read",
|
|
1933
2205
|
description: "List historical sources and stable IDs from one immutable version.",
|
|
1934
|
-
flags: [...
|
|
2206
|
+
flags: [...targetFlags3, versionFlag, ...pagingFlags, { name: "source-type", type: "string", desc: "Optional source type filter: file | url | zip" }],
|
|
1935
2207
|
validate: (ctx) => {
|
|
1936
2208
|
validateVersion(ctx);
|
|
1937
2209
|
validatePage(ctx);
|
|
@@ -1945,21 +2217,21 @@ var versionDiff = {
|
|
|
1945
2217
|
command: "+version-diff",
|
|
1946
2218
|
risk: "read",
|
|
1947
2219
|
description: "Compare historical source additions, deletions, content, and metadata between two versions.",
|
|
1948
|
-
flags: [...
|
|
2220
|
+
flags: [...targetFlags3, { ...versionFlag, name: "from", desc: "Before version number" }, { ...versionFlag, name: "to", desc: "After version number" }],
|
|
1949
2221
|
validate: (ctx) => {
|
|
1950
|
-
|
|
2222
|
+
validateTarget2(ctx);
|
|
1951
2223
|
positiveInteger2(ctx, "from");
|
|
1952
2224
|
positiveInteger2(ctx, "to");
|
|
1953
2225
|
},
|
|
1954
|
-
dryRun: (ctx) => preview2(ctx, `${
|
|
1955
|
-
execute: (ctx) => kbApi(ctx, "GET", `${
|
|
2226
|
+
dryRun: (ctx) => preview2(ctx, `${API3}/compare`, { ...query5(ctx), from: ctx.num("from"), to: ctx.num("to") }),
|
|
2227
|
+
execute: (ctx) => kbApi(ctx, "GET", `${API3}/compare`, { ...query5(ctx), from: ctx.num("from"), to: ctx.num("to") }, void 0, apiOptions3)
|
|
1956
2228
|
};
|
|
1957
2229
|
var versionTree = {
|
|
1958
2230
|
service: "kb",
|
|
1959
2231
|
command: "+version-tree",
|
|
1960
2232
|
risk: "read",
|
|
1961
2233
|
description: "List a historical ZIP or URL source directory without changing current files.",
|
|
1962
|
-
flags: [...
|
|
2234
|
+
flags: [...targetFlags3, versionFlag, sourceFlag, pathFlag2, ...pagingFlags],
|
|
1963
2235
|
validate: (ctx) => {
|
|
1964
2236
|
validateSource(ctx);
|
|
1965
2237
|
validatePath(ctx);
|
|
@@ -1973,30 +2245,30 @@ var versionRead = {
|
|
|
1973
2245
|
command: "+version-read",
|
|
1974
2246
|
risk: "read",
|
|
1975
2247
|
description: "Preview one historical directory child file; unsupported or oversized files return metadata only.",
|
|
1976
|
-
flags: [...
|
|
2248
|
+
flags: [...targetFlags3, versionFlag, sourceFlag, { ...pathFlag2, required: true }],
|
|
1977
2249
|
validate: (ctx) => {
|
|
1978
2250
|
validateSource(ctx);
|
|
1979
2251
|
validatePath(ctx, true);
|
|
1980
2252
|
},
|
|
1981
|
-
dryRun: (ctx) => preview2(ctx, sourceEndpoint2(ctx, "file"), { ...
|
|
1982
|
-
execute: (ctx) => kbApi(ctx, "GET", sourceEndpoint2(ctx, "file"), { ...
|
|
2253
|
+
dryRun: (ctx) => preview2(ctx, sourceEndpoint2(ctx, "file"), { ...query5(ctx), path: ctx.str("path") }),
|
|
2254
|
+
execute: (ctx) => kbApi(ctx, "GET", sourceEndpoint2(ctx, "file"), { ...query5(ctx), path: ctx.str("path") }, void 0, apiOptions3)
|
|
1983
2255
|
};
|
|
1984
2256
|
var versionDownload = {
|
|
1985
2257
|
service: "kb",
|
|
1986
2258
|
command: "+version-download",
|
|
1987
2259
|
risk: "read",
|
|
1988
2260
|
description: "Download one ordinary historical file source to a new local file. ZIP/URL directories cannot be downloaded.",
|
|
1989
|
-
flags: [...
|
|
2261
|
+
flags: [...targetFlags3, versionFlag, sourceFlag, { name: "output", type: "string", required: true, desc: "New local output path; existing files are never overwritten" }],
|
|
1990
2262
|
validate: (ctx) => {
|
|
1991
2263
|
validateSource(ctx);
|
|
1992
2264
|
if (!ctx.str("output").trim()) throw new CliValidationError("--output is required.");
|
|
1993
2265
|
},
|
|
1994
|
-
dryRun: (ctx) => ({ ...preview2(ctx, sourceEndpoint2(ctx, "raw"),
|
|
2266
|
+
dryRun: (ctx) => ({ ...preview2(ctx, sourceEndpoint2(ctx, "raw"), query5(ctx)), output: path8.resolve(ctx.str("output")) }),
|
|
1995
2267
|
execute: async (ctx) => {
|
|
1996
|
-
const result = await kbApi(ctx, "GET", sourceEndpoint2(ctx, "raw"),
|
|
1997
|
-
const output =
|
|
2268
|
+
const result = await kbApi(ctx, "GET", sourceEndpoint2(ctx, "raw"), query5(ctx), void 0, { ...apiOptions3, responseType: "bytes" });
|
|
2269
|
+
const output = path8.resolve(ctx.str("output"));
|
|
1998
2270
|
const bytes = Buffer.from(result.bytes);
|
|
1999
|
-
await
|
|
2271
|
+
await fs8.writeFile(output, bytes, { flag: "wx" });
|
|
2000
2272
|
return { versionNumber: ctx.num("version"), sourceId: ctx.str("id").trim(), sizeBytes: String(bytes.length), output };
|
|
2001
2273
|
}
|
|
2002
2274
|
};
|
|
@@ -2009,7 +2281,7 @@ var rollback = {
|
|
|
2009
2281
|
risk: "high-risk-write",
|
|
2010
2282
|
description: "Restore an earlier version as a new publication. Replace target-source drafts, delete other compiled sources, and preserve unpublished additions. Reuse request-id on network retries.",
|
|
2011
2283
|
flags: [
|
|
2012
|
-
...
|
|
2284
|
+
...targetFlags3,
|
|
2013
2285
|
versionFlag,
|
|
2014
2286
|
{ name: "request-id", type: "string", required: true, maxLength: 191, desc: "Caller-generated stable ASCII request ID; reuse exactly for retries of this logical operation" },
|
|
2015
2287
|
{ name: "expected-latest-version-id", type: "string", required: true, maxLength: 191, desc: "latestVersionId returned by +versions; conflicts require fresh discovery and a new intentional request" }
|
|
@@ -2020,27 +2292,31 @@ var rollback = {
|
|
|
2020
2292
|
const latest = ctx.str("expected-latest-version-id");
|
|
2021
2293
|
if (!latest || latest.length > 191) throw new CliValidationError("--expected-latest-version-id must contain 1 to 191 characters.");
|
|
2022
2294
|
},
|
|
2023
|
-
dryRun: (ctx) => preview2(ctx, versionEndpoint(ctx, "/rollback"),
|
|
2024
|
-
execute: (ctx) => kbApi(ctx, "POST", versionEndpoint(ctx, "/rollback"),
|
|
2295
|
+
dryRun: (ctx) => preview2(ctx, versionEndpoint(ctx, "/rollback"), query5(ctx), rollbackBody(ctx)),
|
|
2296
|
+
execute: (ctx) => kbApi(ctx, "POST", versionEndpoint(ctx, "/rollback"), query5(ctx), rollbackBody(ctx), apiOptions3)
|
|
2025
2297
|
};
|
|
2026
2298
|
var rollbackStatus = {
|
|
2027
2299
|
service: "kb",
|
|
2028
2300
|
command: "+rollback-status",
|
|
2029
2301
|
risk: "read",
|
|
2030
2302
|
description: "Read one persisted rollback operation without polling. A running operation with errorCode requires administrator review; never retry it as a new write.",
|
|
2031
|
-
flags: [...
|
|
2303
|
+
flags: [...targetFlags3, { name: "operation-id", type: "string", required: true, minLength: 1, maxLength: 191, desc: "operationId returned by +rollback" }],
|
|
2032
2304
|
validate: (ctx) => {
|
|
2033
|
-
|
|
2305
|
+
validateTarget2(ctx);
|
|
2034
2306
|
if (!ctx.str("operation-id").trim() || ctx.str("operation-id").length > 191) throw new CliValidationError("--operation-id must contain 1 to 191 characters.");
|
|
2035
2307
|
},
|
|
2036
|
-
dryRun: (ctx) => preview2(ctx, `${
|
|
2037
|
-
execute: (ctx) => kbApi(ctx, "GET", `${
|
|
2308
|
+
dryRun: (ctx) => preview2(ctx, `${API3}/operations/${encodeURIComponent(ctx.str("operation-id").trim())}`, query5(ctx)),
|
|
2309
|
+
execute: (ctx) => kbApi(ctx, "GET", `${API3}/operations/${encodeURIComponent(ctx.str("operation-id").trim())}`, query5(ctx), void 0, apiOptions3)
|
|
2038
2310
|
};
|
|
2039
2311
|
|
|
2040
2312
|
// src/commands/te-kb/index.ts
|
|
2041
2313
|
var commands = [
|
|
2314
|
+
usageList,
|
|
2042
2315
|
...schemaImportCommands,
|
|
2043
2316
|
sourceCheckUpdates,
|
|
2317
|
+
sourceCheckUrlUpdates,
|
|
2318
|
+
sourceCreateText,
|
|
2319
|
+
sourceReadText,
|
|
2044
2320
|
sourceReplace,
|
|
2045
2321
|
sourceRestore,
|
|
2046
2322
|
sourcePreview,
|
|
@@ -2113,16 +2389,20 @@ export {
|
|
|
2113
2389
|
schemaImportValidate,
|
|
2114
2390
|
sourceCancel,
|
|
2115
2391
|
sourceCheckUpdates,
|
|
2392
|
+
sourceCheckUrlUpdates,
|
|
2116
2393
|
sourceCommit,
|
|
2394
|
+
sourceCreateText,
|
|
2117
2395
|
sourceLs,
|
|
2118
2396
|
sourcePreview,
|
|
2119
2397
|
sourcePut,
|
|
2120
2398
|
sourceRead,
|
|
2399
|
+
sourceReadText,
|
|
2121
2400
|
sourceReplace,
|
|
2122
2401
|
sourceRestore,
|
|
2123
2402
|
sourceRm,
|
|
2124
2403
|
status,
|
|
2125
2404
|
url,
|
|
2405
|
+
usageList,
|
|
2126
2406
|
versionDiff,
|
|
2127
2407
|
versionDownload,
|
|
2128
2408
|
versionRead,
|