@thinkingai/ae-cli 6.0.53 → 6.0.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/README.md +28 -9
  2. package/README.zh.md +25 -9
  3. package/bin/ae-cli.js +6 -1
  4. package/cli-installation-guide.md +91 -0
  5. package/dist/{auth-LHM7NQPR.js → auth-RQBO6MTY.js} +9 -11
  6. package/dist/automation-VAAQBM7Y.js +459 -0
  7. package/dist/{capability-F2RIR5DS.js → capability-JRIFC4AJ.js} +6 -6
  8. package/dist/{chunk-647BRKZK.js → chunk-374V5R6N.js} +3 -3
  9. package/dist/{chunk-KJDOTPYU.js → chunk-3YVEAZUN.js} +59 -26
  10. package/dist/{chunk-KS4DE3MX.js → chunk-5XJYLEVC.js} +4 -4
  11. package/dist/{chunk-BW7JUDEI.js → chunk-6VNIR4AP.js} +514 -213
  12. package/dist/{chunk-5XRQ3CZR.js → chunk-7KU2WNQE.js} +43 -8
  13. package/dist/{chunk-7WZACOAI.js → chunk-AP7YP2NX.js} +2 -2
  14. package/dist/chunk-CI24BDR2.js +43 -0
  15. package/dist/{chunk-SO5LKIWP.js → chunk-CT7QDJS6.js} +2 -2
  16. package/dist/{chunk-DU72X2IO.js → chunk-GHXZK54S.js} +22 -10
  17. package/dist/{chunk-N4BLPJC7.js → chunk-OP44TT4H.js} +1 -1
  18. package/dist/chunk-Q5US7JC5.js +133 -0
  19. package/dist/{chunk-PGCIKZRE.js → chunk-RGYPSEYD.js} +3 -3
  20. package/dist/chunk-RK6GLDGI.js +27 -0
  21. package/dist/chunk-RPBOAQQQ.js +56 -0
  22. package/dist/{chunk-GK7WDY7E.js → chunk-S6M42KND.js} +1 -1
  23. package/dist/{chunk-QYXDJOLA.js → chunk-VZZNLV3I.js} +19 -11
  24. package/dist/{chunk-YVGXGTD6.js → chunk-WNGFSIOB.js} +7 -1
  25. package/dist/{chunk-IG3DYEIR.js → chunk-ZL7SGNIA.js} +5 -3
  26. package/dist/{community-report-client-6VJDDMJJ.js → community-report-client-PEERQCX2.js} +1 -1
  27. package/dist/{config-XQWOPDHN.js → config-SICKWZ2A.js} +8 -8
  28. package/dist/context-NGVFPCBK.js +136 -0
  29. package/dist/{data-integration-XBTCGXQT.js → data-integration-BCLQFTGU.js} +6 -6
  30. package/dist/index.js +125 -48
  31. package/dist/{local-data-upload-client-3P7NIVQ4.js → local-data-upload-client-TWMHFLUA.js} +1 -1
  32. package/dist/memory-CQKH2JAV.js +580 -0
  33. package/dist/{metadata-V5ZDTKWZ.js → metadata-EMFGUI2W.js} +7 -7
  34. package/dist/{model-ZS7HVGKN.js → model-VX5M2CJ6.js} +9 -5
  35. package/dist/{personal-semantic-preference-2XANU3F6.js → personal-semantic-preference-SLWVVYZ4.js} +117 -11
  36. package/dist/{project-semantic-LP3LY7QP.js → project-semantic-DPSZBKQD.js} +6 -6
  37. package/dist/{sync-EQLSTUS7.js → sync-RZIAV37C.js} +12 -8
  38. package/dist/{te-agent-Z3HCTKR7.js → te-agent-AORRE2FM.js} +90 -454
  39. package/dist/{te-analysis-3EVYQ3IO.js → te-analysis-ISXKJKRT.js} +297 -20
  40. package/dist/{te-community-Z7JACGF3.js → te-community-42M7ICDO.js} +3 -3
  41. package/dist/{te-dataops-F7GQOIS6.js → te-dataops-BNKNZ4F2.js} +5 -5
  42. package/dist/{te-engage-LFBU6WWH.js → te-engage-BZE3MBKT.js} +6 -6
  43. package/dist/{te-kb-QJLJEX5K.js → te-kb-ULATOTQ3.js} +494 -214
  44. package/dist/{te-system-IXC43QHZ.js → te-system-UGHVKBVV.js} +10 -9
  45. package/dist/{te-team-BIZIKIHZ.js → te-team-YA6SNOJ3.js} +6 -6
  46. package/dist/things-DTCOQIQB.js +1091 -0
  47. package/dist/{update-W2SGQNKT.js → update-ESNYKUVR.js} +59 -51
  48. package/dist/workspace-JEOHKFPX.js +554 -0
  49. package/package.json +21 -9
  50. package/skills/ae-agent/SKILL.md +91 -139
  51. package/skills/ae-agent/references/add-model.md +1 -1
  52. package/skills/ae-agent/references/create-agent.md +1 -1
  53. package/skills/ae-agent/references/find-archived-conversations.md +12 -5
  54. package/skills/ae-agent/references/get-agent.md +1 -1
  55. package/skills/ae-agent/references/list-agents.md +2 -2
  56. package/skills/ae-agent/references/list-models.md +2 -2
  57. package/skills/ae-agent/references/restore-conversation.md +3 -1
  58. package/skills/ae-analysis/SKILL.md +15 -6
  59. package/skills/ae-analysis/references/ai_models/funnel.md +5 -3
  60. package/skills/ae-analysis/references/ai_models.md +27 -0
  61. package/skills/ae-analysis/references/command_index.md +12 -4
  62. package/skills/ae-analysis/references/dashboard_move.md +21 -0
  63. package/skills/ae-analysis/references/dashboard_report_add.md +2 -0
  64. package/skills/ae-analysis/references/dashboard_report_get.md +19 -0
  65. package/skills/ae-analysis/references/dashboard_report_update.md +27 -0
  66. package/skills/ae-analysis/references/dashboard_update.md +1 -1
  67. package/skills/ae-analysis/references/event_report_presentation.md +76 -0
  68. package/skills/ae-analysis/references/feedback_submit.md +37 -0
  69. package/skills/ae-analysis/references/metadata_resolution.md +15 -0
  70. package/skills/ae-analysis/references/personal_semantic_preference_review.md +9 -0
  71. package/skills/ae-analysis/references/personal_semantic_preference_review_list.md +7 -0
  72. package/skills/ae-analysis/references/personal_semantic_preference_submit.md +7 -0
  73. package/skills/ae-analysis/references/project_semantic_knowledge_wiki.md +90 -31
  74. package/skills/ae-analysis/references/project_semantic_knowledge_wiki_plan_schema.md +99 -1
  75. package/skills/ae-analysis/references/report_create.md +13 -3
  76. package/skills/ae-analysis/references/report_get.md +5 -1
  77. package/skills/ae-analysis/references/report_update.md +15 -4
  78. package/skills/ae-analysis/references/system_query_monitor_overview.md +2 -0
  79. package/skills/ae-analysis/references/system_query_task_cancel.md +2 -0
  80. package/skills/ae-analysis/references/system_query_task_export.md +6 -2
  81. package/skills/ae-analysis/references/system_query_task_get.md +2 -0
  82. package/skills/ae-analysis/references/system_query_task_list.md +7 -3
  83. package/skills/ae-analysis/references/system_query_task_options.md +2 -2
  84. package/skills/ae-analysis/references/system_query_task_realtime_list.md +15 -0
  85. package/skills/ae-analysis/references/user_tag_models.md +2 -0
  86. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/build-empty-skeleton.mjs +105 -0
  87. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/build-project-semantic-wiki.mjs +669 -29
  88. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/company-kb.mjs +21 -8
  89. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/default-compile-rules.md +28 -10
  90. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/default-compile-schema.md +66 -0
  91. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/generate-build-ir.mjs +285 -24
  92. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/package-wiki-source-zip.mjs +262 -30
  93. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/plan-kb-source-sync.mjs +1 -1
  94. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/precompiled-source.mjs +46 -2
  95. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/prepare-compile-schema.mjs +64 -0
  96. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/refresh-state-parts.mjs +91 -0
  97. package/skills/ae-automation/SKILL.md +16 -0
  98. package/skills/ae-automation/references/cli.md +53 -0
  99. package/skills/ae-automation/references/command_index.md +17 -0
  100. package/skills/ae-capability/SKILL.md +15 -6
  101. package/skills/ae-current-context/SKILL.md +3 -2
  102. package/skills/ae-kb/SKILL.md +62 -12
  103. package/skills/ae-kb/references/analysis-workflow.md +73 -36
  104. package/skills/ae-kb/references/query-workflow.md +67 -33
  105. package/skills/ae-kb/references/schema-import.md +5 -3
  106. package/skills/ae-kb/references/source-mutations.md +6 -4
  107. package/skills/ae-kb/references/text-sources.md +53 -0
  108. package/skills/ae-kb-discovery/SKILL.md +1 -1
  109. package/skills/ae-team/SKILL.md +23 -17
  110. package/skills/ae-things/SKILL.md +85 -0
  111. package/skills/ae-things/references/cli.md +103 -0
  112. package/skills/ae-things-progress/SKILL.md +43 -0
  113. package/skills/ae-things-review/SKILL.md +42 -0
  114. package/skills/ae-workspace/SKILL.md +43 -0
  115. package/skills/ae-workspace/references/commands.md +51 -0
  116. package/dist/chunk-E2JKXMVO.js +0 -29
  117. package/dist/context-M3HDGEIR.js +0 -46
  118. package/dist/memory-6APEB2JB.js +0 -892
  119. package/skills/ae-agent/references/create-automation.md +0 -125
  120. package/skills/ae-agent/references/list-automations.md +0 -56
  121. 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-5XRQ3CZR.js";
5
+ } from "./chunk-7KU2WNQE.js";
6
6
  import {
7
7
  TeAgentApiError
8
- } from "./chunk-KJDOTPYU.js";
8
+ } from "./chunk-3YVEAZUN.js";
9
9
  import {
10
10
  CapabilityGatewayError
11
- } from "./chunk-QYXDJOLA.js";
11
+ } from "./chunk-VZZNLV3I.js";
12
12
  import {
13
13
  printError
14
- } from "./chunk-BW7JUDEI.js";
14
+ } from "./chunk-6VNIR4AP.js";
15
15
  import "./chunk-Y74WTIKJ.js";
16
- import "./chunk-DU72X2IO.js";
17
- import "./chunk-IG3DYEIR.js";
16
+ import "./chunk-GHXZK54S.js";
17
+ import "./chunk-ZL7SGNIA.js";
18
18
  import {
19
19
  CliValidationError,
20
20
  PermissionError
21
- } from "./chunk-YVGXGTD6.js";
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 body(ctx, action) {
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 = body(ctx, action);
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) ? { ...body(ctx, action), ...action === "save" ? { content: "[REDACTED]" } : {} } : void 0 }), execute: (ctx) => executeSchemaImport(ctx, 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 and start validation; 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");
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", "Current passing report ID", true), flag("schema-hash", "string", "Formal hash from a recent diff"), flag("schema-absent", "boolean", "Explicitly confirm formal schema is absent")], "write");
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 API_PATH = "/agent/api/external/knowledge-bases/sources/check-updates";
161
- function body2(ctx) {
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(/\/$/, "")}${API_PATH}`, body: body2(ctx) }),
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", API_PATH, {}, body2(ctx), { preserveErrorMetadata: true });
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-mutation.ts
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 apiOptions = { preserveErrorMetadata: true };
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 `${API}/sources/${encodeURIComponent(ctx.str("id").trim())}/${suffix}`;
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, body3) {
256
- return { method, url: `${ctx.host().replace(/\/$/, "")}${endpoint3}`, params: query2(ctx), ...body3 === void 0 ? {} : { body: body3 } };
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 = path2.resolve(ctx.str("file"));
260
- const extension = path2.extname(file).toLowerCase();
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 fs2.open(file, "r");
461
+ const handle = await fs3.open(file, "r");
265
462
  try {
266
463
  const stat = await handle.stat();
267
- if (!stat.isFile() || stat.size > maxBytes) throw new CliValidationError("--file must be a regular file of at most 50 MB.");
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 > maxBytes) throw new CliValidationError("--file exceeds 50 MB.");
270
- return { file, filename: path2.basename(file), sizeBytes: content?.length ?? stat.size, content };
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, { name: "file", type: "string", required: true, desc: "Local replacement file, at most 50 MB; same format, different filename allowed" }],
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
- if (!ctx.str("file").trim()) throw new CliValidationError("--file is required.");
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 `${API}/versions/${ctx.num("version")}/sources/${encodeURIComponent(ctx.str("id").trim())}/restore`;
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 fs3 } from "fs";
385
- import * as path3 from "path";
595
+ import { promises as fs4 } from "fs";
596
+ import * as path4 from "path";
386
597
  import TurndownService from "turndown";
387
- var API_PATH2 = "/agent/api/external/knowledge-bases/sources/upload";
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 = path3.extname(filename).toLowerCase();
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 = path3.extname(filePath).toLowerCase();
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 fs3.readFile(filePath);
482
- const filename = path3.basename(filePath);
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 fs3.readdir(dir, { withFileTypes: true });
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 = path3.extname(entry.name).toLowerCase();
701
+ const ext = path4.extname(entry.name).toLowerCase();
491
702
  if (!SUPPORTED_EXTENSIONS.has(ext)) continue;
492
- const full = path3.join(dir, entry.name);
493
- const content = await fs3.readFile(full);
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 = path3.resolve(p);
739
+ const abs = path4.resolve(p);
529
740
  let stat;
530
741
  try {
531
- stat = await fs3.stat(abs);
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 = path3.extname(f.filename);
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 body3 = {
813
+ const body4 = {
603
814
  name: ctx.str("name")
604
815
  };
605
816
  const scope = getExternalKnowledgeBaseTargetScope(ctx);
606
- if (scope) body3.scope = scope;
607
- body3.files = items.map((item) => ({ value: item, type: classifyInput(item) }));
608
- body3.contentType = "multipart/form-data";
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(/\/$/, "")}${API_PATH2}`,
612
- body: body3
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, API_PATH2, form);
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 API_PATH3 = "/agent/api/external/knowledge-bases/compile";
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 body3 = {
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) body3.scope = scope;
855
+ if (scope) body4.scope = scope;
645
856
  const model = ctx.str("model");
646
- if (model) body3.model = model;
647
- return body3;
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(/\/$/, "")}${API_PATH3}`,
877
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH4}`,
667
878
  body: buildBody(ctx)
668
879
  }),
669
- execute: async (ctx) => kbApi(ctx, "POST", API_PATH3, {}, buildBody(ctx))
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 API_PATH4 = "/agent/api/external/knowledge-bases";
884
+ var API_PATH5 = "/agent/api/external/knowledge-bases";
674
885
  function buildBody2(ctx) {
675
- const body3 = { name: ctx.str("name") };
886
+ const body4 = { name: ctx.str("name") };
676
887
  const scope = getExternalKnowledgeBaseTargetScope(ctx);
677
- if (scope) body3.scope = scope;
678
- return body3;
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(/\/$/, "")}${API_PATH4}`,
905
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH5}`,
695
906
  body: buildBody2(ctx)
696
907
  }),
697
- execute: async (ctx) => kbApi(ctx, "DELETE", API_PATH4, {}, buildBody2(ctx))
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 API_PATH5 = "/agent/api/external/knowledge-bases/create";
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 body3 = {
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) body3.description = description;
945
+ if (description) body4.description = description;
735
946
  const tags = normalizeTags(ctx.json("tags"));
736
- if (tags && tags.length > 0) body3.tags = tags;
947
+ if (tags && tags.length > 0) body4.tags = tags;
737
948
  const projectId = ctx.str("project-id");
738
- if (projectId) body3.projectId = projectId;
949
+ if (projectId) body4.projectId = projectId;
739
950
  const projectName = ctx.str("project-name");
740
- if (projectName) body3.projectName = projectName;
741
- return body3;
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(/\/$/, "")}${API_PATH5}`,
973
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH6}`,
763
974
  body: buildBody3(ctx)
764
975
  }),
765
- execute: async (ctx) => kbApi(ctx, "POST", API_PATH5, {}, buildBody3(ctx))
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 API_PATH6 = "/agent/api/external/knowledge-bases/sources";
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 body3 = {
989
+ const body4 = {
779
990
  name: ctx.str("name")
780
991
  };
781
992
  const scope = getExternalKnowledgeBaseTargetScope(ctx);
782
- if (scope) body3.scope = scope;
783
- return { ...body3, ...sourceSelector(ctx) };
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(/\/$/, "")}${API_PATH6}`,
1013
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH7}`,
803
1014
  body: buildBody4(ctx)
804
1015
  }),
805
- execute: async (ctx) => kbApi(ctx, "DELETE", API_PATH6, {}, buildBody4(ctx), {
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 fs4 from "fs";
812
- import path4 from "path";
813
- var API_PATH7 = "/agent/api/external/knowledge-bases/schema";
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 ? fs4.readFileSync(path4.resolve(file), "utf8") : inline;
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 body3 = {
1042
+ const body4 = {
832
1043
  name: ctx.str("name")
833
1044
  };
834
1045
  const scope = getExternalKnowledgeBaseTargetScope(ctx);
835
- if (scope) body3.scope = scope;
836
- if (ctx.bool("force")) body3.force = true;
1046
+ if (scope) body4.scope = scope;
1047
+ if (ctx.bool("force")) body4.force = true;
837
1048
  const model = ctx.str("model");
838
- if (model) body3.model = model;
1049
+ if (model) body4.model = model;
839
1050
  const customInstructions = getCustomInstructions(ctx);
840
- if (customInstructions) body3.customInstructions = customInstructions;
841
- return body3;
1051
+ if (customInstructions) body4.customInstructions = customInstructions;
1052
+ return body4;
842
1053
  }
843
1054
  async function executeSchema(ctx, api = kbApi) {
844
- return api(ctx, "POST", API_PATH7, {}, buildBody5(ctx), {
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(/\/$/, "")}${API_PATH7}`,
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 API_PATH8 = "/agent/api/external/knowledge-bases/status";
1097
+ var API_PATH9 = "/agent/api/external/knowledge-bases/status";
887
1098
  function buildBody6(ctx) {
888
- const body3 = {
1099
+ const body4 = {
889
1100
  name: ctx.str("name")
890
1101
  };
891
1102
  const scope = getExternalKnowledgeBaseTargetScope(ctx);
892
- if (scope) body3.scope = scope;
893
- return body3;
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(/\/$/, "")}${API_PATH8}`,
1120
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH9}`,
910
1121
  body: buildBody6(ctx)
911
1122
  }),
912
- execute: async (ctx) => kbApi(ctx, "POST", API_PATH8, {}, buildBody6(ctx))
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 API_PATH9 = "/agent/api/external/knowledge-bases/index";
1127
+ var API_PATH10 = "/agent/api/external/knowledge-bases/index";
917
1128
  function buildBody7(ctx) {
918
- const body3 = {};
1129
+ const body4 = {};
919
1130
  const sources = ctx.json("sources");
920
- if (sources) body3.sources = sources;
1131
+ if (sources) body4.sources = sources;
921
1132
  const locale = ctx.str("locale");
922
- if (locale) body3.locale = locale;
923
- return body3;
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(/\/$/, "")}${API_PATH9}`,
1152
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH10}`,
942
1153
  body: buildBody7(ctx)
943
1154
  }),
944
- execute: async (ctx) => kbApi(ctx, "POST", API_PATH9, {}, buildBody7(ctx))
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 API_PATH10 = "/agent/api/external/knowledge-bases/list";
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 body3 = {
1176
+ const body4 = {
966
1177
  buildStatus: getBuildStatus(ctx)
967
1178
  };
968
1179
  const locale = ctx.str("locale");
969
- if (locale) body3.locale = locale;
970
- return body3;
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(/\/$/, "")}${API_PATH10}`,
1203
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH11}`,
993
1204
  body: buildBody8(ctx)
994
1205
  }),
995
- execute: async (ctx) => kbApi(ctx, "POST", API_PATH10, {}, buildBody8(ctx))
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 API_PATH11 = "/agent/api/external/knowledge-bases/sources";
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(/\/$/, "")}${API_PATH11}`);
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
- return kbApi(ctx, "GET", API_PATH11, params, void 0, {
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 API_PATH12 = "/agent/api/external/knowledge-bases/grep";
1332
+ var API_PATH14 = "/agent/api/external/knowledge-bases/grep";
1061
1333
  function buildBody9(ctx) {
1062
- const body3 = {
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) body3.topK = topK;
1340
+ if (topK !== void 0) body4.topK = topK;
1069
1341
  const locale = ctx.str("locale");
1070
- if (locale) body3.locale = locale;
1071
- return body3;
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(/\/$/, "")}${API_PATH12}`,
1375
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH14}`,
1104
1376
  body: buildBody9(ctx)
1105
1377
  }),
1106
- execute: async (ctx) => kbApi(ctx, "POST", API_PATH12, {}, buildBody9(ctx))
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 API_PATH13 = "/agent/api/external/knowledge-bases/read";
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 body3 = {
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) body3.offset = offset;
1411
+ if (offset !== void 0) body4.offset = offset;
1140
1412
  const limit = ctx.optionalNum("limit");
1141
- if (limit !== void 0) body3.limit = limit;
1413
+ if (limit !== void 0) body4.limit = limit;
1142
1414
  const expand = readExpand(ctx);
1143
- if (expand) body3.expand = expand;
1144
- if (ctx.bool("outline")) body3.outline = true;
1415
+ if (expand) body4.expand = expand;
1416
+ if (ctx.bool("outline")) body4.outline = true;
1145
1417
  const locale = ctx.str("locale");
1146
- if (locale) body3.locale = locale;
1147
- return body3;
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(/\/$/, "")}${API_PATH13}`,
1460
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH15}`,
1189
1461
  body: buildBody10(ctx)
1190
1462
  }),
1191
- execute: async (ctx) => kbApi(ctx, "POST", API_PATH13, {}, buildBody10(ctx))
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 body3 = {
1544
+ const body4 = {
1273
1545
  question: ctx.str("question")
1274
1546
  };
1275
1547
  const sources = ctx.json("sources");
1276
- if (sources) body3.sources = sources;
1548
+ if (sources) body4.sources = sources;
1277
1549
  const modelId = ctx.str("model-id");
1278
- if (modelId) body3.modelId = modelId;
1550
+ if (modelId) body4.modelId = modelId;
1279
1551
  const locale = ctx.str("locale");
1280
- if (locale) body3.locale = locale;
1281
- return body3;
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 API_PATH14 = "/agent/api/external/knowledge-bases/sources/url";
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 body3 = {
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) body3.scope = scope;
1685
+ if (scope) body4.scope = scope;
1414
1686
  const displayName = ctx.str("display-name");
1415
- if (displayName) body3.displayName = displayName;
1687
+ if (displayName) body4.displayName = displayName;
1416
1688
  const parseInstruction = ctx.str("parse-instruction");
1417
- if (parseInstruction) body3.parseInstruction = parseInstruction;
1418
- return body3;
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(/\/$/, "")}${API_PATH14}`,
1710
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH16}`,
1439
1711
  body: buildBody12(ctx)
1440
1712
  }),
1441
- execute: async (ctx) => kbApi(ctx, "POST", API_PATH14, {}, buildBody12(ctx))
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 fs5 } from "fs";
1446
- import path5 from "path";
1447
- var API_PATH15 = "/agent/api/external/knowledge-bases/import";
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 (path5.extname(filePath).toLocaleLowerCase("en-US") !== ".zip") {
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 = path5.resolve(filePath);
1761
+ const absolutePath = path6.resolve(filePath);
1490
1762
  let stat;
1491
1763
  try {
1492
- stat = await fs5.stat(absolutePath);
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 fs5.readFile(absolutePath) };
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
- path5.basename(archive.absolutePath)
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
- API_PATH15,
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 API_PATH16 = "/agent/api/external/knowledge-bases/import";
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(/\/$/, "")}${API_PATH16}?requestId=${encodeURIComponent(requestIdFrom(ctx))}`
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
- API_PATH16,
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 fs6 } from "fs";
1677
- import path6 from "path";
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 query3(ctx) {
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", body3) {
1720
- return { method, url: `${ctx.host().replace(/\/$/, "")}${endpoint2(ctx, suffix)}`, ...body3 ? { body: body3 } : { params: query3(ctx) } };
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: { ...query3(ctx), limit: ctx.num("limit"), ...ctx.str("cursor") ? { cursor: ctx.str("cursor") } : {} } }),
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
- ...query3(ctx),
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"), query3(ctx), void 0, { ...apiOptions2, responseType: "bytes" });
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 = path6.resolve(ctx.str("output"));
1773
- await fs6.writeFile(output, bytes, { flag: "wx" });
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 = path6.resolve(ctx.str("file"));
1786
- const handle = await fs6.open(file, "r");
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 fs7 } from "fs";
1844
- import path7 from "path";
1845
- var API2 = "/agent/api/external/knowledge-bases/versions";
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 targetFlags2 = [
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 validateTarget(ctx) {
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
- validateTarget(ctx);
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 query4(ctx) {
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 { ...query4(ctx), limit: ctx.num("limit"), ...ctx.str("cursor") ? { cursor: ctx.str("cursor") } : {} };
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 `${API2}/${positiveInteger2(ctx, "version")}${suffix}`;
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, body3) {
1903
- return { method: body3 ? "POST" : "GET", url: `${ctx.host().replace(/\/$/, "")}${endpoint3}`, params, ...body3 ? { body: body3 } : {} };
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: [...targetFlags2, ...pagingFlags],
2182
+ flags: [...targetFlags3, ...pagingFlags],
1911
2183
  validate: (ctx) => {
1912
- validateTarget(ctx);
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, API2, pageQuery(ctx)),
1917
- execute: (ctx) => kbApi(ctx, "GET", API2, pageQuery(ctx), void 0, apiOptions3)
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: [...targetFlags2, versionFlag],
2196
+ flags: [...targetFlags3, versionFlag],
1925
2197
  validate: validateVersion,
1926
- dryRun: (ctx) => preview2(ctx, versionEndpoint(ctx), query4(ctx)),
1927
- execute: (ctx) => kbApi(ctx, "GET", versionEndpoint(ctx), query4(ctx), void 0, apiOptions3)
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: [...targetFlags2, versionFlag, ...pagingFlags, { name: "source-type", type: "string", desc: "Optional source type filter: file | url | zip" }],
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: [...targetFlags2, { ...versionFlag, name: "from", desc: "Before version number" }, { ...versionFlag, name: "to", desc: "After version number" }],
2220
+ flags: [...targetFlags3, { ...versionFlag, name: "from", desc: "Before version number" }, { ...versionFlag, name: "to", desc: "After version number" }],
1949
2221
  validate: (ctx) => {
1950
- validateTarget(ctx);
2222
+ validateTarget2(ctx);
1951
2223
  positiveInteger2(ctx, "from");
1952
2224
  positiveInteger2(ctx, "to");
1953
2225
  },
1954
- dryRun: (ctx) => preview2(ctx, `${API2}/compare`, { ...query4(ctx), from: ctx.num("from"), to: ctx.num("to") }),
1955
- execute: (ctx) => kbApi(ctx, "GET", `${API2}/compare`, { ...query4(ctx), from: ctx.num("from"), to: ctx.num("to") }, void 0, apiOptions3)
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: [...targetFlags2, versionFlag, sourceFlag, pathFlag2, ...pagingFlags],
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: [...targetFlags2, versionFlag, sourceFlag, { ...pathFlag2, required: true }],
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"), { ...query4(ctx), path: ctx.str("path") }),
1982
- execute: (ctx) => kbApi(ctx, "GET", sourceEndpoint2(ctx, "file"), { ...query4(ctx), path: ctx.str("path") }, void 0, apiOptions3)
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: [...targetFlags2, versionFlag, sourceFlag, { name: "output", type: "string", required: true, desc: "New local output path; existing files are never overwritten" }],
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"), query4(ctx)), output: path7.resolve(ctx.str("output")) }),
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"), query4(ctx), void 0, { ...apiOptions3, responseType: "bytes" });
1997
- const output = path7.resolve(ctx.str("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 fs7.writeFile(output, bytes, { flag: "wx" });
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
- ...targetFlags2,
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"), query4(ctx), rollbackBody(ctx)),
2024
- execute: (ctx) => kbApi(ctx, "POST", versionEndpoint(ctx, "/rollback"), query4(ctx), rollbackBody(ctx), apiOptions3)
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: [...targetFlags2, { name: "operation-id", type: "string", required: true, minLength: 1, maxLength: 191, desc: "operationId returned by +rollback" }],
2303
+ flags: [...targetFlags3, { name: "operation-id", type: "string", required: true, minLength: 1, maxLength: 191, desc: "operationId returned by +rollback" }],
2032
2304
  validate: (ctx) => {
2033
- validateTarget(ctx);
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, `${API2}/operations/${encodeURIComponent(ctx.str("operation-id").trim())}`, query4(ctx)),
2037
- execute: (ctx) => kbApi(ctx, "GET", `${API2}/operations/${encodeURIComponent(ctx.str("operation-id").trim())}`, query4(ctx), void 0, apiOptions3)
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,