@thinkingai/ae-cli 6.0.52 → 6.0.54

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 (185) hide show
  1. package/README.md +35 -10
  2. package/README.zh.md +32 -10
  3. package/bin/ae-cli.js +6 -1
  4. package/cli-installation-guide.md +91 -0
  5. package/dist/{auth-XZNXFRJS.js → auth-MBWRZTB6.js} +171 -13
  6. package/dist/automation-NWWVLWG2.js +459 -0
  7. package/dist/{capability-RJZ4KRGP.js → capability-7SSN6PNZ.js} +11 -6
  8. package/dist/chunk-4655PUNX.js +43 -0
  9. package/dist/{chunk-4NRCTUZJ.js → chunk-5XJYLEVC.js} +4 -4
  10. package/dist/{chunk-JOCDD4ON.js → chunk-7QXISROD.js} +1 -1
  11. package/dist/{chunk-EQ255HKO.js → chunk-AP7YP2NX.js} +2 -2
  12. package/dist/{chunk-DVMLWQD4.js → chunk-CT7QDJS6.js} +2 -2
  13. package/dist/chunk-D6ACFILC.js +56 -0
  14. package/dist/{chunk-HFGZGYCG.js → chunk-EOYSKMXN.js} +264 -10
  15. package/dist/{chunk-57RRFUEZ.js → chunk-FMNNGNYO.js} +43 -8
  16. package/dist/{chunk-7XGFSUOM.js → chunk-GIK6EDUG.js} +291 -84
  17. package/dist/{chunk-WEPZ5M3Z.js → chunk-HBLK3ZHW.js} +7 -4
  18. package/dist/chunk-HVHR4SCP.js +133 -0
  19. package/dist/{chunk-DX5CDO34.js → chunk-KFNMQTZI.js} +580 -214
  20. package/dist/{chunk-HBGADCKA.js → chunk-PLE722AJ.js} +28 -11
  21. package/dist/chunk-RK6GLDGI.js +27 -0
  22. package/dist/{chunk-V2NUHPXF.js → chunk-S6M42KND.js} +1 -1
  23. package/dist/{chunk-7FTTULED.js → chunk-UQ77JXYH.js} +7 -3
  24. package/dist/{chunk-MAPZ7VB6.js → chunk-WNGFSIOB.js} +20 -1
  25. package/dist/{chunk-L2QUIZTS.js → chunk-ZIQWCZTS.js} +3 -3
  26. package/dist/{community-report-client-CU22W53K.js → community-report-client-PEERQCX2.js} +1 -1
  27. package/dist/{config-XO3LI3SA.js → config-FF6YVJKI.js} +29 -10
  28. package/dist/context-YAE3QXP3.js +136 -0
  29. package/dist/{data-integration-HNGUKFIC.js → data-integration-HESZET7E.js} +6 -6
  30. package/dist/index.js +169 -55
  31. package/dist/{local-data-upload-client-GTRIT64F.js → local-data-upload-client-TWMHFLUA.js} +1 -1
  32. package/dist/memory-62BJOULV.js +580 -0
  33. package/dist/{metadata-JAQW7KGZ.js → metadata-7CUMWIB4.js} +7 -7
  34. package/dist/{model-RNPQXIBI.js → model-SBV2JFJI.js} +9 -5
  35. package/dist/{personal-semantic-preference-QCZ2IZTK.js → personal-semantic-preference-6SRCYPGE.js} +119 -11
  36. package/dist/{project-semantic-64JURXKF.js → project-semantic-YYEM4OSU.js} +7 -7
  37. package/dist/{sync-O45NXEQY.js → sync-SU33KYX7.js} +12 -8
  38. package/dist/{te-agent-K5MSPNHJ.js → te-agent-F5QBZSQA.js} +423 -494
  39. package/dist/{te-analysis-KQKCAI5H.js → te-analysis-U4I2W2WC.js} +1090 -67
  40. package/dist/{te-community-4OYU3BDA.js → te-community-PFLDLPP4.js} +3 -3
  41. package/dist/{te-dataops-NFIPB6FX.js → te-dataops-FOQSRIAZ.js} +644 -276
  42. package/dist/{te-engage-HSVSRW22.js → te-engage-ZX76CNAB.js} +6 -6
  43. package/dist/{te-kb-3TS73NO6.js → te-kb-MHDOST62.js} +666 -244
  44. package/dist/{te-system-STMHLS5J.js → te-system-J2FQF5ER.js} +6 -6
  45. package/dist/{te-team-3I5AOX3N.js → te-team-5UOZPTU3.js} +6 -6
  46. package/dist/things-VPPXXLHB.js +1091 -0
  47. package/dist/{update-RZXLPCRH.js → update-EEUTEI6R.js} +59 -51
  48. package/dist/workspace-O3EEIYQM.js +554 -0
  49. package/package.json +30 -11
  50. package/skills/ae-agent/SKILL.md +95 -140
  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/notification.md +40 -0
  58. package/skills/ae-agent/references/restore-conversation.md +3 -1
  59. package/skills/ae-analysis/SKILL.md +76 -15
  60. package/skills/ae-analysis/references/agent_review_submit_to_page.md +2 -0
  61. package/skills/ae-analysis/references/ai_models/event.md +6 -1
  62. package/skills/ae-analysis/references/ai_models/funnel.md +12 -4
  63. package/skills/ae-analysis/references/ai_models/heat_map.md +23 -0
  64. package/skills/ae-analysis/references/ai_models/interval.md +24 -0
  65. package/skills/ae-analysis/references/ai_models/path.md +20 -0
  66. package/skills/ae-analysis/references/ai_models/prop_analysis.md +2 -0
  67. package/skills/ae-analysis/references/ai_models/rank_list.md +30 -0
  68. package/skills/ae-analysis/references/ai_models/retention.md +45 -1
  69. package/skills/ae-analysis/references/ai_models/revenue.md +20 -2
  70. package/skills/ae-analysis/references/ai_models/tag.md +2 -0
  71. package/skills/ae-analysis/references/ai_models.md +96 -0
  72. package/skills/ae-analysis/references/analysis_data_retrieval.md +4 -0
  73. package/skills/ae-analysis/references/asset_batch_info_export.md +10 -0
  74. package/skills/ae-analysis/references/asset_batch_sql_export.md +13 -1
  75. package/skills/ae-analysis/references/asset_export.md +12 -1
  76. package/skills/ae-analysis/references/asset_list.md +1 -0
  77. package/skills/ae-analysis/references/asset_search.md +11 -5
  78. package/skills/ae-analysis/references/bi_panel_list.md +1 -1
  79. package/skills/ae-analysis/references/catalog_list.md +1 -1
  80. package/skills/ae-analysis/references/collaboration.md +48 -0
  81. package/skills/ae-analysis/references/command_index.md +26 -17
  82. package/skills/ae-analysis/references/dashboard_list.md +4 -4
  83. package/skills/ae-analysis/references/dashboard_move.md +21 -0
  84. package/skills/ae-analysis/references/dashboard_report_add.md +2 -0
  85. package/skills/ae-analysis/references/dashboard_report_data_export.md +2 -0
  86. package/skills/ae-analysis/references/dashboard_report_get.md +19 -0
  87. package/skills/ae-analysis/references/dashboard_report_update.md +27 -0
  88. package/skills/ae-analysis/references/dashboard_update.md +1 -1
  89. package/skills/ae-analysis/references/event_export.md +3 -1
  90. package/skills/ae-analysis/references/event_report_presentation.md +76 -0
  91. package/skills/ae-analysis/references/feedback_submit.md +37 -0
  92. package/skills/ae-analysis/references/governance_recommendation_auto_review.md +71 -0
  93. package/skills/ae-analysis/references/governance_recommendation_export.md +11 -0
  94. package/skills/ae-analysis/references/metadata_resolution.md +18 -3
  95. package/skills/ae-analysis/references/metric_export.md +3 -1
  96. package/skills/ae-analysis/references/metric_list.md +1 -1
  97. package/skills/ae-analysis/references/operation_record_export.md +10 -0
  98. package/skills/ae-analysis/references/personal_semantic_preference_add.md +2 -2
  99. package/skills/ae-analysis/references/personal_semantic_preference_get.md +6 -4
  100. package/skills/ae-analysis/references/personal_semantic_preference_list.md +5 -3
  101. package/skills/ae-analysis/references/personal_semantic_preference_review.md +9 -0
  102. package/skills/ae-analysis/references/personal_semantic_preference_review_list.md +7 -0
  103. package/skills/ae-analysis/references/personal_semantic_preference_submit.md +7 -0
  104. package/skills/ae-analysis/references/project_semantic_knowledge_wiki.md +91 -32
  105. package/skills/ae-analysis/references/project_semantic_knowledge_wiki_plan_schema.md +99 -1
  106. package/skills/ae-analysis/references/property_export.md +3 -1
  107. package/skills/ae-analysis/references/report_create.md +17 -3
  108. package/skills/ae-analysis/references/report_data_export.md +6 -0
  109. package/skills/ae-analysis/references/report_get.md +7 -1
  110. package/skills/ae-analysis/references/report_list.md +5 -5
  111. package/skills/ae-analysis/references/report_update.md +20 -3
  112. package/skills/ae-analysis/references/sql_table_columns.md +4 -4
  113. package/skills/ae-analysis/references/sql_table_list.md +5 -5
  114. package/skills/ae-analysis/references/system_query_monitor_overview.md +2 -0
  115. package/skills/ae-analysis/references/system_query_task_cancel.md +2 -0
  116. package/skills/ae-analysis/references/system_query_task_export.md +6 -2
  117. package/skills/ae-analysis/references/system_query_task_get.md +2 -0
  118. package/skills/ae-analysis/references/system_query_task_list.md +7 -3
  119. package/skills/ae-analysis/references/system_query_task_options.md +2 -2
  120. package/skills/ae-analysis/references/system_query_task_realtime_list.md +15 -0
  121. package/skills/ae-analysis/references/user_cluster_models.md +8 -0
  122. package/skills/ae-analysis/references/user_tag_create.md +7 -1
  123. package/skills/ae-analysis/references/user_tag_get.md +1 -1
  124. package/skills/ae-analysis/references/user_tag_models.md +20 -2
  125. package/skills/ae-analysis/references/user_tag_refresh.md +1 -1
  126. package/skills/ae-analysis/references/user_tag_update.md +2 -2
  127. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/build-empty-skeleton.mjs +105 -0
  128. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/build-project-semantic-wiki.mjs +669 -29
  129. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/company-kb.mjs +21 -8
  130. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/default-compile-rules.md +28 -10
  131. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/default-compile-schema.md +66 -0
  132. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/generate-build-ir.mjs +285 -24
  133. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/package-wiki-source-zip.mjs +262 -30
  134. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/plan-kb-source-sync.mjs +1 -1
  135. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/precompiled-source.mjs +46 -2
  136. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/prepare-compile-schema.mjs +64 -0
  137. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/refresh-state-parts.mjs +91 -0
  138. package/skills/ae-automation/SKILL.md +16 -0
  139. package/skills/ae-automation/references/cli.md +53 -0
  140. package/skills/ae-automation/references/command_index.md +17 -0
  141. package/skills/ae-capability/SKILL.md +73 -2
  142. package/skills/ae-capability/references/collaboration.md +48 -0
  143. package/skills/ae-community/SKILL.md +5 -1
  144. package/skills/ae-community/references/collaboration.md +48 -0
  145. package/skills/ae-current-context/SKILL.md +3 -2
  146. package/skills/ae-data-integration/SKILL.md +4 -0
  147. package/skills/ae-data-integration/references/collaboration.md +48 -0
  148. package/skills/ae-dataops/SKILL.md +54 -74
  149. package/skills/ae-dataops/references/collaboration.md +48 -0
  150. package/skills/ae-dataops/references/dataops-backfill.md +23 -18
  151. package/skills/ae-dataops/references/dataops-flow-create.md +74 -23
  152. package/skills/ae-dataops/references/dataops-flow-monitor.md +45 -13
  153. package/skills/ae-dataops/references/dataops-integration.md +57 -30
  154. package/skills/ae-dataops/references/dataops-query.md +21 -4
  155. package/skills/ae-dataops/references/dataops-table.md +143 -11
  156. package/skills/ae-engage/SKILL.md +21 -6
  157. package/skills/ae-engage/references/channel-mgmt.md +3 -3
  158. package/skills/ae-engage/references/collaboration.md +48 -0
  159. package/skills/ae-engage/references/scene-config-channel.md +4 -4
  160. package/skills/ae-generate-tracking-plan/SKILL.md +4 -0
  161. package/skills/ae-generate-tracking-plan/references/collaboration.md +48 -0
  162. package/skills/ae-kb/SKILL.md +70 -12
  163. package/skills/ae-kb/references/analysis-workflow.md +73 -36
  164. package/skills/ae-kb/references/collaboration.md +48 -0
  165. package/skills/ae-kb/references/query-workflow.md +67 -33
  166. package/skills/ae-kb/references/schema-import.md +32 -0
  167. package/skills/ae-kb/references/source-mutations.md +6 -4
  168. package/skills/ae-kb/references/text-sources.md +53 -0
  169. package/skills/ae-kb-discovery/SKILL.md +8 -3
  170. package/skills/ae-kb-discovery/references/collaboration.md +48 -0
  171. package/skills/ae-metadata/SKILL.md +20 -12
  172. package/skills/ae-metadata/references/collaboration.md +48 -0
  173. package/skills/ae-team/SKILL.md +23 -17
  174. package/skills/ae-things/SKILL.md +85 -0
  175. package/skills/ae-things/references/cli.md +103 -0
  176. package/skills/ae-things-progress/SKILL.md +43 -0
  177. package/skills/ae-things-review/SKILL.md +42 -0
  178. package/skills/ae-workspace/SKILL.md +43 -0
  179. package/skills/ae-workspace/references/commands.md +51 -0
  180. package/dist/chunk-E2JKXMVO.js +0 -29
  181. package/dist/context-IFJI3LIT.js +0 -46
  182. package/dist/memory-QGPSNCQS.js +0 -892
  183. package/skills/ae-agent/references/create-automation.md +0 -125
  184. package/skills/ae-agent/references/list-automations.md +0 -56
  185. package/skills/ae-agent/references/update-automation.md +0 -107
@@ -2,23 +2,23 @@ import { createRequire as __createRequire } from 'node:module'; const require =
2
2
  import {
3
3
  kbApi,
4
4
  kbUpload
5
- } from "./chunk-57RRFUEZ.js";
5
+ } from "./chunk-FMNNGNYO.js";
6
6
  import {
7
7
  TeAgentApiError
8
- } from "./chunk-HBGADCKA.js";
8
+ } from "./chunk-PLE722AJ.js";
9
9
  import {
10
10
  CapabilityGatewayError
11
- } from "./chunk-HFGZGYCG.js";
11
+ } from "./chunk-EOYSKMXN.js";
12
12
  import {
13
13
  printError
14
- } from "./chunk-DX5CDO34.js";
14
+ } from "./chunk-KFNMQTZI.js";
15
15
  import "./chunk-Y74WTIKJ.js";
16
- import "./chunk-7XGFSUOM.js";
17
- import "./chunk-7FTTULED.js";
16
+ import "./chunk-GIK6EDUG.js";
17
+ import "./chunk-UQ77JXYH.js";
18
18
  import {
19
19
  CliValidationError,
20
20
  PermissionError
21
- } from "./chunk-MAPZ7VB6.js";
21
+ } from "./chunk-WNGFSIOB.js";
22
22
 
23
23
  // src/commands/te-kb/target-scope.ts
24
24
  function getExternalKnowledgeBaseTargetScope(ctx) {
@@ -30,12 +30,164 @@ function getExternalKnowledgeBaseTargetScope(ctx) {
30
30
  );
31
31
  }
32
32
 
33
- // src/commands/te-kb/source-check-updates.ts
34
- var API_PATH = "/agent/api/external/knowledge-bases/sources/check-updates";
33
+ // src/commands/te-kb/source-check-url-updates.ts
34
+ var API_PATH = "/agent/api/external/knowledge-bases/sources/check-url-updates";
35
35
  function body(ctx) {
36
36
  const scope = getExternalKnowledgeBaseTargetScope(ctx);
37
37
  return { name: ctx.str("name").trim(), sourceId: ctx.str("id").trim(), ...scope ? { scope } : {} };
38
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
+
61
+ // src/commands/te-kb/schema-import.ts
62
+ import { promises as fs } from "fs";
63
+ import path from "path";
64
+ var ROOT = "/agent/api/external/knowledge-bases/schema";
65
+ var options = { preserveBusinessErrorCode: true, preserveErrorMetadata: true };
66
+ var flag = (name, type, desc, required = false) => ({ name, type, desc, required });
67
+ var targetFlags = [flag("name", "string", "Knowledge base name", true), flag("scope", "string", "Exact scope: personal | company")];
68
+ var identityFlags = [flag("import-id", "string", "Stable import ID", true)];
69
+ var mutationFlags = [flag("revision", "number", "Expected candidate revision", true), flag("request-id", "string", "Idempotency key; reuse only for identical retries", true)];
70
+ var hashFlag = flag("hash", "string", "Expected candidate SHA256", true);
71
+ var fileFlag = { ...flag("file", "string", "Local UTF-8 Markdown file, at most 256 KiB", true), sensitive: true };
72
+ var waitFlags = [flag("wait", "boolean", "Poll until this task finishes; never abandon on timeout"), { ...flag("timeout", "number", "Wait timeout in seconds"), default: 300, min: 1, max: 3600 }];
73
+ var modelFlag = flag("model", "string", "Optional stable model reference");
74
+ function target(ctx) {
75
+ return { name: ctx.str("name"), scope: getExternalKnowledgeBaseTargetScope(ctx) };
76
+ }
77
+ function endpoint(ctx, action) {
78
+ if (action === "download") return ROOT;
79
+ if (action === "upload" || action === "list") return ROOT + "/imports";
80
+ const suffix = action === "status" ? "" : action === "save" ? "content" : action === "reject" ? "reject-optimization" : action;
81
+ return `${ROOT}/imports/${encodeURIComponent(ctx.str("import-id"))}${suffix ? "/" + suffix : ""}`;
82
+ }
83
+ function body2(ctx, action) {
84
+ const result = { expectedRevision: ctx.num("revision"), requestId: ctx.str("request-id") };
85
+ if (["validate", "optimize", "apply"].includes(action)) result.contentHash = ctx.str("hash");
86
+ if (["validate", "optimize"].includes(action) && ctx.str("model")) result.model = ctx.str("model");
87
+ if (action === "optimize" && ctx.list("issue-id").length) result.issueIds = ctx.list("issue-id");
88
+ if (action === "apply") {
89
+ if (ctx.str("report-id")) result.reportId = ctx.str("report-id");
90
+ result.expectedSchemaHash = ctx.bool("schema-absent") ? null : ctx.str("schema-hash");
91
+ }
92
+ return result;
93
+ }
94
+ function query(ctx, action) {
95
+ if (action === "download") return { ...target(ctx), download: "1" };
96
+ if (action === "list") return { ...target(ctx), limit: ctx.num("limit") || 20, cursor: ctx.str("cursor") || void 0 };
97
+ if (action === "content") return { target: ctx.str("target") || "current", download: ctx.str("output") ? "1" : void 0 };
98
+ if (action === "diff") return { baseline: ctx.str("baseline") || "current-schema" };
99
+ return {};
100
+ }
101
+ function validate(ctx, action) {
102
+ if (["upload", "list", "download"].includes(action)) getExternalKnowledgeBaseTargetScope(ctx);
103
+ for (const name of ["import-id", "request-id", "replaces-import-id"]) if (ctx.str(name) && !/^[A-Za-z0-9_-]{1,191}$/.test(ctx.str(name))) throw new CliValidationError(`Invalid --${name}`);
104
+ for (const name of ["hash", "schema-hash", "report-id"]) if (ctx.str(name) && !/^[a-f0-9]{64}$/.test(ctx.str(name))) throw new CliValidationError(`Invalid --${name}; expected SHA256`);
105
+ for (const name of ["revision", "replaced-revision"]) if (ctx.num(name) && (!Number.isInteger(ctx.num(name)) || ctx.num(name) < 1)) throw new CliValidationError(`Invalid --${name}`);
106
+ if (action === "apply" && Boolean(ctx.str("schema-hash")) === ctx.bool("schema-absent")) throw new CliValidationError("Specify exactly one of --schema-hash or --schema-absent");
107
+ if (action === "upload" && Boolean(ctx.str("replaces-import-id")) !== Boolean(ctx.num("replaced-revision"))) throw new CliValidationError("Replacement requires --replaces-import-id and --replaced-revision");
108
+ if (action === "content" && !["current", "original", "optimization-input", "optimized"].includes(ctx.str("target") || "current")) throw new CliValidationError("Invalid --target");
109
+ if (action === "diff" && !["original", "optimization-input", "current-schema"].includes(ctx.str("baseline") || "current-schema")) throw new CliValidationError("Invalid --baseline");
110
+ }
111
+ async function readMarkdown(ctx) {
112
+ const absolute = path.resolve(ctx.str("file")), stat = await fs.stat(absolute);
113
+ if (!stat.isFile() || stat.size > 262144 || path.extname(absolute).toLowerCase() !== ".md") throw new CliValidationError("--file must be a Markdown file of at most 256 KiB");
114
+ const bytes = await fs.readFile(absolute);
115
+ if (bytes.length > 262144) throw new CliValidationError("--file exceeds 256 KiB");
116
+ new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes);
117
+ return { absolute, bytes };
118
+ }
119
+ async function waitSchemaImport(ctx, initial, api = kbApi, sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms))) {
120
+ const deadline = Date.now() + (ctx.num("timeout") || 300) * 1e3;
121
+ let current = initial;
122
+ while (current.task && Date.now() < deadline) {
123
+ await sleep(Math.min(2e3, Math.max(1, deadline - Date.now())));
124
+ current = await api(ctx, "GET", `${ROOT}/imports/${encodeURIComponent(initial.id)}`, {}, void 0, options);
125
+ }
126
+ return { ...current, waitTimedOut: Boolean(current.task) };
127
+ }
128
+ async function executeSchemaImport(ctx, action, api = kbApi, upload = kbUpload) {
129
+ let result;
130
+ if (action === "upload") {
131
+ const { absolute, bytes } = await readMarkdown(ctx);
132
+ const form = new FormData();
133
+ form.set("file", new Blob([new Uint8Array(bytes)]), path.basename(absolute));
134
+ form.set("name", ctx.str("name"));
135
+ form.set("requestId", ctx.str("request-id"));
136
+ const scope = getExternalKnowledgeBaseTargetScope(ctx);
137
+ if (scope) form.set("scope", scope);
138
+ if (ctx.str("model")) form.set("model", ctx.str("model"));
139
+ if (ctx.str("replaces-import-id")) {
140
+ form.set("replacesImportId", ctx.str("replaces-import-id"));
141
+ form.set("expectedReplacedRevision", String(ctx.num("replaced-revision")));
142
+ }
143
+ result = await upload(ctx, endpoint(ctx, action), form, {}, options);
144
+ } else if (["download", "list", "status", "content", "diff"].includes(action)) {
145
+ const binary = action === "download" || action === "content" && Boolean(ctx.str("output"));
146
+ result = await api(ctx, "GET", endpoint(ctx, action), query(ctx, action), void 0, { ...options, ...binary ? { responseType: "bytes" } : {} });
147
+ if (binary) {
148
+ const output = path.resolve(ctx.str("output"));
149
+ const bytes = Buffer.from(result.bytes);
150
+ await fs.writeFile(output, bytes, { flag: "wx" });
151
+ return { output, sizeBytes: bytes.length };
152
+ }
153
+ if (action === "diff" && ctx.str("output")) {
154
+ const output = path.resolve(ctx.str("output"));
155
+ await fs.writeFile(output, result.diff, { flag: "wx" });
156
+ return { ...result, output };
157
+ }
158
+ } else {
159
+ const input = body2(ctx, action);
160
+ if (action === "save") {
161
+ const { bytes } = await readMarkdown(ctx);
162
+ input.content = bytes.toString("utf8");
163
+ }
164
+ result = await api(ctx, action === "save" ? "PUT" : "POST", endpoint(ctx, action), {}, input, options);
165
+ }
166
+ return ctx.bool("wait") && result.task ? waitSchemaImport(ctx, result, api) : result;
167
+ }
168
+ function command(action, name, description, flags, risk) {
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) };
170
+ }
171
+ var schemaDownload = command("download", "+schema-download", "Download formal schema bytes without rewriting.", [...targetFlags, flag("output", "string", "New destination file; never overwrite", true)], "read");
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");
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");
174
+ var schemaImportStatus = command("status", "+schema-import-status", "Read candidate status, report and durable receipt.", [...identityFlags, ...waitFlags], "read");
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");
176
+ var schemaImportDiff = command("diff", "+schema-import-diff", "Read full actual diff and current formal hash.", [...identityFlags, flag("baseline", "string", "original | optimization-input | current-schema"), flag("output", "string", "Optional new diff file")], "read");
177
+ var schemaImportSave = command("save", "+schema-import-save", "Save edits without calling a model.", [...identityFlags, ...mutationFlags, fileFlag], "write");
178
+ var schemaImportValidate = command("validate", "+schema-import-validate", "Validate this exact saved revision.", [...identityFlags, ...mutationFlags, hashFlag, modelFlag, ...waitFlags], "write");
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");
180
+ var schemaImportReject = command("reject", "+schema-import-reject", "Restore the most recent repair input.", [...identityFlags, ...mutationFlags], "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");
182
+ var schemaImportAbandon = command("abandon", "+schema-import-abandon", "Abandon candidate and invalidate pending tasks.", [...identityFlags, ...mutationFlags], "high-risk-write");
183
+ var schemaImportCommands = [schemaDownload, schemaImport, schemaImportList, schemaImportStatus, schemaImportContent, schemaImportDiff, schemaImportSave, schemaImportValidate, schemaImportOptimize, schemaImportReject, schemaImportApply, schemaImportAbandon];
184
+
185
+ // src/commands/te-kb/source-check-updates.ts
186
+ var API_PATH2 = "/agent/api/external/knowledge-bases/sources/check-updates";
187
+ function body3(ctx) {
188
+ const scope = getExternalKnowledgeBaseTargetScope(ctx);
189
+ return { name: ctx.str("name").trim(), sourceId: ctx.str("id").trim(), ...scope ? { scope } : {} };
190
+ }
39
191
  var sourceCheckUpdates = {
40
192
  service: "kb",
41
193
  resource: "source",
@@ -48,16 +200,16 @@ var sourceCheckUpdates = {
48
200
  { name: "scope", type: "string", desc: "Exact scope: personal | company (omit for personal then company lookup)" }
49
201
  ],
50
202
  validate: (ctx) => {
51
- for (const [flag, max] of [["name", 200], ["id", 191]]) {
52
- const value = ctx.str(flag).trim();
53
- if (!value || value.length > max) throw new CliValidationError(`Invalid --${flag}: expected 1-${max} characters.`);
203
+ for (const [flag2, max] of [["name", 200], ["id", 191]]) {
204
+ const value = ctx.str(flag2).trim();
205
+ if (!value || value.length > max) throw new CliValidationError(`Invalid --${flag2}: expected 1-${max} characters.`);
54
206
  }
55
207
  getExternalKnowledgeBaseTargetScope(ctx);
56
208
  },
57
- dryRun: (ctx) => ({ method: "POST", url: `${ctx.host().replace(/\/$/, "")}${API_PATH}`, body: body(ctx) }),
209
+ dryRun: (ctx) => ({ method: "POST", url: `${ctx.host().replace(/\/$/, "")}${API_PATH2}`, body: body3(ctx) }),
58
210
  execute: async (ctx) => {
59
211
  try {
60
- return await kbApi(ctx, "POST", API_PATH, {}, body(ctx), { preserveErrorMetadata: true });
212
+ return await kbApi(ctx, "POST", API_PATH2, {}, body3(ctx), { preserveErrorMetadata: true });
61
213
  } catch (error) {
62
214
  const hint = "Read kb +list-sources to confirm the current source state before retrying.";
63
215
  if (error instanceof PermissionError) {
@@ -84,14 +236,185 @@ var sourceCheckUpdates = {
84
236
  }
85
237
  };
86
238
 
87
- // src/commands/te-kb/source-mutation.ts
88
- import { promises as fs } from "fs";
89
- import path from "path";
239
+ // src/commands/te-kb/source-text.ts
240
+ import { promises as fs2 } from "fs";
241
+ import path2 from "path";
90
242
  var API = "/agent/api/external/knowledge-bases";
91
- var apiOptions = { preserveErrorMetadata: true };
243
+ var textApiOptions = { preserveErrorMetadata: true, retryUnauthorized: false, redactErrorDetails: true };
92
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;
93
416
  var fileExtensions = /* @__PURE__ */ new Set([".md", ".markdown", ".txt", ".csv", ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp", ".svg"]);
94
- var identityFlags = [
417
+ var identityFlags2 = [
95
418
  { name: "name", type: "string", required: true, desc: "Exact knowledge base name from kb +list" },
96
419
  { name: "scope", type: "string", required: true, desc: "Exact knowledge base scope: personal or company" },
97
420
  { name: "id", type: "string", required: true, desc: "Current stable source ID from kb +list-sources" }
@@ -100,48 +423,48 @@ var typeFlag = { name: "source-type", type: "string", required: true, desc: "Cur
100
423
  var revisionFlag = { name: "expected-revision", type: "number", required: true, min: 1, max: 2147483647, desc: "Current contentRevision from kb +list-sources; never automatically retry a conflict" };
101
424
  var previewFlag = { name: "preview-id", type: "string", required: true, desc: "Exact previewId returned by ZIP replace or restore" };
102
425
  function validateIdentity(ctx) {
103
- for (const [flag, max] of [["name", 200], ["id", 191], ["preview-id", 191]]) {
104
- const value = ctx.str(flag);
105
- if ((flag !== "preview-id" || value) && (!value.trim() || value.length > max || /[\x00-\x1f\x7f]/.test(value))) {
106
- throw new CliValidationError(`--${flag} must contain 1 to ${max} characters without control characters.`);
426
+ for (const [flag2, max] of [["name", 200], ["id", 191], ["preview-id", 191]]) {
427
+ const value = ctx.str(flag2);
428
+ if ((flag2 !== "preview-id" || value) && (!value.trim() || value.length > max || /[\x00-\x1f\x7f]/.test(value))) {
429
+ throw new CliValidationError(`--${flag2} must contain 1 to ${max} characters without control characters.`);
107
430
  }
108
431
  }
109
432
  if (!["personal", "company"].includes(ctx.str("scope"))) throw new CliValidationError("--scope must be personal or company.");
110
433
  }
111
- function positiveInteger(ctx, flag) {
112
- const value = ctx.num(flag);
113
- if (!Number.isSafeInteger(value) || value < 1 || value > 2147483647) throw new CliValidationError(`--${flag} must be an integer from 1 to 2147483647.`);
434
+ function positiveInteger(ctx, flag2) {
435
+ const value = ctx.num(flag2);
436
+ if (!Number.isSafeInteger(value) || value < 1 || value > 2147483647) throw new CliValidationError(`--${flag2} must be an integer from 1 to 2147483647.`);
114
437
  }
115
438
  function validateMutation(ctx) {
116
439
  validateIdentity(ctx);
117
440
  positiveInteger(ctx, "expected-revision");
118
441
  if (!["file", "zip"].includes(ctx.str("source-type"))) throw new CliValidationError("--source-type must be file or zip; URL sources cannot be replaced or restored.");
119
442
  }
120
- function query(ctx) {
443
+ function query2(ctx) {
121
444
  return { name: ctx.str("name").trim(), scope: ctx.str("scope") };
122
445
  }
123
446
  function sourceEndpoint(ctx, suffix) {
124
- return `${API}/sources/${encodeURIComponent(ctx.str("id").trim())}/${suffix}`;
447
+ return `${API2}/sources/${encodeURIComponent(ctx.str("id").trim())}/${suffix}`;
125
448
  }
126
449
  function previewEndpoint(ctx) {
127
450
  return sourceEndpoint(ctx, `directory/previews/${encodeURIComponent(ctx.str("preview-id").trim())}`);
128
451
  }
129
- function dryRequest(ctx, method, endpoint2, body2) {
130
- return { method, url: `${ctx.host().replace(/\/$/, "")}${endpoint2}`, params: query(ctx), ...body2 === void 0 ? {} : { body: body2 } };
452
+ function dryRequest(ctx, method, endpoint3, body4) {
453
+ return { method, url: `${ctx.host().replace(/\/$/, "")}${endpoint3}`, params: query2(ctx), ...body4 === void 0 ? {} : { body: body4 } };
131
454
  }
132
455
  async function replacementFile(ctx, read) {
133
- const file = path.resolve(ctx.str("file"));
134
- const extension = path.extname(file).toLowerCase();
456
+ const file = path3.resolve(ctx.str("file"));
457
+ const extension = path3.extname(file).toLowerCase();
135
458
  if (ctx.str("source-type") === "zip" ? extension !== ".zip" : !fileExtensions.has(extension)) {
136
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.");
137
460
  }
138
- const handle = await fs.open(file, "r");
461
+ const handle = await fs3.open(file, "r");
139
462
  try {
140
463
  const stat = await handle.stat();
141
- 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.");
142
465
  const content = read ? await handle.readFile() : void 0;
143
- if (content && content.length > maxBytes) throw new CliValidationError("--file exceeds 50 MB.");
144
- return { file, filename: path.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 };
145
468
  } finally {
146
469
  await handle.close();
147
470
  }
@@ -157,26 +480,40 @@ var sourceReplace = {
157
480
  resource: "source",
158
481
  command: "replace",
159
482
  risk: "write",
160
- description: "Replace a file source draft, or prepare a ZIP archive replacement preview. ZIP changes require source commit. Does not compile or publish.",
161
- flags: [...identityFlags, 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)],
162
485
  validate: (ctx) => {
163
486
  validateMutation(ctx);
164
- 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
+ }
165
491
  },
166
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
+ }
167
497
  const { file, filename, sizeBytes } = await replacementFile(ctx, false);
168
498
  return { ...dryRequest(ctx, ctx.str("source-type") === "zip" ? "POST" : "PUT", replaceEndpoint(ctx), replaceFields(ctx)), multipart: { file, filename, sizeBytes, content: "<redacted>" } };
169
499
  },
170
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
+ }
171
508
  const file = await replacementFile(ctx, true);
172
509
  const form = new FormData();
173
510
  form.append("file", new Blob([new Uint8Array(file.content)]), file.filename);
174
511
  for (const [key, value] of Object.entries(replaceFields(ctx))) form.append(key, String(value));
175
- return kbUpload(ctx, replaceEndpoint(ctx), form, query(ctx), { ...apiOptions, method: ctx.str("source-type") === "zip" ? "POST" : "PUT" });
512
+ return kbUpload(ctx, replaceEndpoint(ctx), form, query2(ctx), { ...apiOptions, method: ctx.str("source-type") === "zip" ? "POST" : "PUT" });
176
513
  }
177
514
  };
178
515
  function restoreEndpoint(ctx) {
179
- 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`;
180
517
  }
181
518
  function restoreBody(ctx) {
182
519
  return { expectedRevision: ctx.num("expected-revision"), ...ctx.str("source-type") === "zip" ? ctx.str("path") ? { target: "file", path: ctx.str("path") } : { target: "source" } : {} };
@@ -188,7 +525,7 @@ var sourceRestore = {
188
525
  risk: "write",
189
526
  description: "Restore one current source draft from a published version. File sources restore immediately; ZIP source or child restores return a preview. Does not roll back the whole knowledge base or publish.",
190
527
  flags: [
191
- ...identityFlags,
528
+ ...identityFlags2,
192
529
  typeFlag,
193
530
  revisionFlag,
194
531
  { name: "version", type: "number", required: true, min: 1, max: 2147483647, desc: "Published version number from kb +versions; use the latest number to discard unpublished changes" },
@@ -203,7 +540,7 @@ var sourceRestore = {
203
540
  }
204
541
  },
205
542
  dryRun: (ctx) => dryRequest(ctx, "POST", restoreEndpoint(ctx), restoreBody(ctx)),
206
- execute: (ctx) => kbApi(ctx, "POST", restoreEndpoint(ctx), query(ctx), restoreBody(ctx), apiOptions)
543
+ execute: (ctx) => kbApi(ctx, "POST", restoreEndpoint(ctx), query2(ctx), restoreBody(ctx), apiOptions)
207
544
  };
208
545
  var sourcePreview = {
209
546
  service: "kb",
@@ -212,7 +549,7 @@ var sourcePreview = {
212
549
  risk: "read",
213
550
  description: "Read one page of a ZIP replacement or restore preview, including additions, modifications and deletions.",
214
551
  flags: [
215
- ...identityFlags,
552
+ ...identityFlags2,
216
553
  previewFlag,
217
554
  { name: "cursor", type: "string", desc: "Opaque nextCursor returned by the previous preview page" },
218
555
  { name: "limit", type: "number", default: 100, min: 1, max: 200, desc: "Preview page size from 1 to 200" }
@@ -222,8 +559,8 @@ var sourcePreview = {
222
559
  if (!Number.isInteger(ctx.num("limit")) || ctx.num("limit") < 1 || ctx.num("limit") > 200) throw new CliValidationError("--limit must be an integer from 1 to 200.");
223
560
  if (ctx.str("cursor").length > 4096) throw new CliValidationError("--cursor must be at most 4096 characters.");
224
561
  },
225
- dryRun: (ctx) => ({ ...dryRequest(ctx, "GET", previewEndpoint(ctx)), params: { ...query(ctx), limit: ctx.num("limit"), ...ctx.str("cursor") ? { cursor: ctx.str("cursor") } : {} } }),
226
- execute: (ctx) => kbApi(ctx, "GET", previewEndpoint(ctx), { ...query(ctx), limit: ctx.num("limit"), ...ctx.str("cursor") ? { cursor: ctx.str("cursor") } : {} }, void 0, apiOptions)
562
+ dryRun: (ctx) => ({ ...dryRequest(ctx, "GET", previewEndpoint(ctx)), params: { ...query2(ctx), limit: ctx.num("limit"), ...ctx.str("cursor") ? { cursor: ctx.str("cursor") } : {} } }),
563
+ execute: (ctx) => kbApi(ctx, "GET", previewEndpoint(ctx), { ...query2(ctx), limit: ctx.num("limit"), ...ctx.str("cursor") ? { cursor: ctx.str("cursor") } : {} }, void 0, apiOptions)
227
564
  };
228
565
  var sourceCommit = {
229
566
  service: "kb",
@@ -231,13 +568,13 @@ var sourceCommit = {
231
568
  command: "commit",
232
569
  risk: "high-risk-write",
233
570
  description: "Confirm a reviewed ZIP replacement or restore preview. May delete missing files; changes only the draft. On uncertain outcome, inspect state before any retry.",
234
- flags: [...identityFlags, previewFlag, revisionFlag],
571
+ flags: [...identityFlags2, previewFlag, revisionFlag],
235
572
  validate: (ctx) => {
236
573
  validateIdentity(ctx);
237
574
  positiveInteger(ctx, "expected-revision");
238
575
  },
239
576
  dryRun: (ctx) => dryRequest(ctx, "POST", `${previewEndpoint(ctx)}/commit`, { expectedRevision: ctx.num("expected-revision"), confirmed: true }),
240
- execute: (ctx) => kbApi(ctx, "POST", `${previewEndpoint(ctx)}/commit`, query(ctx), { expectedRevision: ctx.num("expected-revision"), confirmed: true }, apiOptions)
577
+ execute: (ctx) => kbApi(ctx, "POST", `${previewEndpoint(ctx)}/commit`, query2(ctx), { expectedRevision: ctx.num("expected-revision"), confirmed: true }, apiOptions)
241
578
  };
242
579
  var sourceCancel = {
243
580
  service: "kb",
@@ -245,20 +582,20 @@ var sourceCancel = {
245
582
  command: "cancel",
246
583
  risk: "high-risk-write",
247
584
  description: "Discard an uncommitted ZIP replacement or restore preview; leaves the source draft unchanged.",
248
- flags: [...identityFlags, previewFlag],
585
+ flags: [...identityFlags2, previewFlag],
249
586
  validate: validateIdentity,
250
587
  dryRun: (ctx) => dryRequest(ctx, "DELETE", previewEndpoint(ctx)),
251
588
  execute: async (ctx) => {
252
- await kbApi(ctx, "DELETE", previewEndpoint(ctx), query(ctx), void 0, { ...apiOptions, responseType: "empty" });
589
+ await kbApi(ctx, "DELETE", previewEndpoint(ctx), query2(ctx), void 0, { ...apiOptions, responseType: "empty" });
253
590
  return { previewId: ctx.str("preview-id"), cancelled: true };
254
591
  }
255
592
  };
256
593
 
257
594
  // src/commands/te-kb/add.ts
258
- import { promises as fs2 } from "fs";
259
- import * as path2 from "path";
595
+ import { promises as fs4 } from "fs";
596
+ import * as path4 from "path";
260
597
  import TurndownService from "turndown";
261
- var API_PATH2 = "/agent/api/external/knowledge-bases/sources/upload";
598
+ var API_PATH3 = "/agent/api/external/knowledge-bases/sources/upload";
262
599
  var SUPPORTED_EXTENSIONS = /* @__PURE__ */ new Set([
263
600
  ".zip",
264
601
  ".md",
@@ -305,7 +642,7 @@ function sanitizeFilename(name) {
305
642
  return cleaned || "document";
306
643
  }
307
644
  function getMimeType(filename) {
308
- const ext = path2.extname(filename).toLowerCase();
645
+ const ext = path4.extname(filename).toLowerCase();
309
646
  switch (ext) {
310
647
  case ".zip":
311
648
  return "application/zip";
@@ -348,23 +685,23 @@ function getMimeType(filename) {
348
685
  }
349
686
  }
350
687
  async function readLocalFile(filePath) {
351
- const ext = path2.extname(filePath).toLowerCase();
688
+ const ext = path4.extname(filePath).toLowerCase();
352
689
  if (!SUPPORTED_EXTENSIONS.has(ext)) {
353
690
  throw new Error(`Unsupported file extension (${ext || "none"}): ${filePath}`);
354
691
  }
355
- const content = await fs2.readFile(filePath);
356
- const filename = path2.basename(filePath);
692
+ const content = await fs4.readFile(filePath);
693
+ const filename = path4.basename(filePath);
357
694
  return { filename, content, mimeType: getMimeType(filename), origin: "file", source: filePath };
358
695
  }
359
696
  async function readDirectory(dir) {
360
- const entries = await fs2.readdir(dir, { withFileTypes: true });
697
+ const entries = await fs4.readdir(dir, { withFileTypes: true });
361
698
  const files = [];
362
699
  for (const entry of entries) {
363
700
  if (!entry.isFile()) continue;
364
- const ext = path2.extname(entry.name).toLowerCase();
701
+ const ext = path4.extname(entry.name).toLowerCase();
365
702
  if (!SUPPORTED_EXTENSIONS.has(ext)) continue;
366
- const full = path2.join(dir, entry.name);
367
- const content = await fs2.readFile(full);
703
+ const full = path4.join(dir, entry.name);
704
+ const content = await fs4.readFile(full);
368
705
  files.push({ filename: entry.name, content, mimeType: getMimeType(entry.name), origin: "dir", source: full });
369
706
  }
370
707
  if (files.length === 0) {
@@ -399,10 +736,10 @@ async function fetchAsMarkdown(rawUrl) {
399
736
  };
400
737
  }
401
738
  async function resolveLocalPath(p) {
402
- const abs = path2.resolve(p);
739
+ const abs = path4.resolve(p);
403
740
  let stat;
404
741
  try {
405
- stat = await fs2.stat(abs);
742
+ stat = await fs4.stat(abs);
406
743
  } catch {
407
744
  throw new Error(`Path not found: ${p}`);
408
745
  }
@@ -438,7 +775,7 @@ function dedupeByFilename(files) {
438
775
  const count = used.get(f.filename) ?? 0;
439
776
  used.set(f.filename, count + 1);
440
777
  if (count === 0) return f;
441
- const ext = path2.extname(f.filename);
778
+ const ext = path4.extname(f.filename);
442
779
  const stem = f.filename.slice(0, f.filename.length - ext.length);
443
780
  return { ...f, filename: `${stem}-${count}${ext}` };
444
781
  });
@@ -473,17 +810,17 @@ var add = {
473
810
  },
474
811
  dryRun: (ctx) => {
475
812
  const items = normalizeFilesInput(ctx.json("files"));
476
- const body2 = {
813
+ const body4 = {
477
814
  name: ctx.str("name")
478
815
  };
479
816
  const scope = getExternalKnowledgeBaseTargetScope(ctx);
480
- if (scope) body2.scope = scope;
481
- body2.files = items.map((item) => ({ value: item, type: classifyInput(item) }));
482
- body2.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";
483
820
  return {
484
821
  method: "POST",
485
- url: `${ctx.host().replace(/\/$/, "")}${API_PATH2}`,
486
- body: body2
822
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH3}`,
823
+ body: body4
487
824
  };
488
825
  },
489
826
  execute: async (ctx) => {
@@ -491,7 +828,7 @@ var add = {
491
828
  const scope = getExternalKnowledgeBaseTargetScope(ctx);
492
829
  const files = await collectFiles(ctx);
493
830
  const form = buildForm(name, scope, files);
494
- const result = await kbUpload(ctx, API_PATH2, form);
831
+ const result = await kbUpload(ctx, API_PATH3, form);
495
832
  return {
496
833
  uploaded: files.map((f) => ({ filename: f.filename, origin: f.origin, source: f.source })),
497
834
  result
@@ -500,7 +837,7 @@ var add = {
500
837
  };
501
838
 
502
839
  // src/commands/te-kb/compile.ts
503
- var API_PATH3 = "/agent/api/external/knowledge-bases/compile";
840
+ var API_PATH4 = "/agent/api/external/knowledge-bases/compile";
504
841
  var VALID_MODES = /* @__PURE__ */ new Set(["incremental", "full"]);
505
842
  function getMode(ctx) {
506
843
  const mode = ctx.str("mode") || "incremental";
@@ -510,15 +847,15 @@ function getMode(ctx) {
510
847
  return mode;
511
848
  }
512
849
  function buildBody(ctx) {
513
- const body2 = {
850
+ const body4 = {
514
851
  name: ctx.str("name"),
515
852
  mode: getMode(ctx)
516
853
  };
517
854
  const scope = getExternalKnowledgeBaseTargetScope(ctx);
518
- if (scope) body2.scope = scope;
855
+ if (scope) body4.scope = scope;
519
856
  const model = ctx.str("model");
520
- if (model) body2.model = model;
521
- return body2;
857
+ if (model) body4.model = model;
858
+ return body4;
522
859
  }
523
860
  var compile = {
524
861
  service: "kb",
@@ -537,19 +874,19 @@ var compile = {
537
874
  },
538
875
  dryRun: (ctx) => ({
539
876
  method: "POST",
540
- url: `${ctx.host().replace(/\/$/, "")}${API_PATH3}`,
877
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH4}`,
541
878
  body: buildBody(ctx)
542
879
  }),
543
- execute: async (ctx) => kbApi(ctx, "POST", API_PATH3, {}, buildBody(ctx))
880
+ execute: async (ctx) => kbApi(ctx, "POST", API_PATH4, {}, buildBody(ctx))
544
881
  };
545
882
 
546
883
  // src/commands/te-kb/remove.ts
547
- var API_PATH4 = "/agent/api/external/knowledge-bases";
884
+ var API_PATH5 = "/agent/api/external/knowledge-bases";
548
885
  function buildBody2(ctx) {
549
- const body2 = { name: ctx.str("name") };
886
+ const body4 = { name: ctx.str("name") };
550
887
  const scope = getExternalKnowledgeBaseTargetScope(ctx);
551
- if (scope) body2.scope = scope;
552
- return body2;
888
+ if (scope) body4.scope = scope;
889
+ return body4;
553
890
  }
554
891
  var remove = {
555
892
  service: "kb",
@@ -565,14 +902,14 @@ var remove = {
565
902
  },
566
903
  dryRun: (ctx) => ({
567
904
  method: "DELETE",
568
- url: `${ctx.host().replace(/\/$/, "")}${API_PATH4}`,
905
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH5}`,
569
906
  body: buildBody2(ctx)
570
907
  }),
571
- execute: async (ctx) => kbApi(ctx, "DELETE", API_PATH4, {}, buildBody2(ctx))
908
+ execute: async (ctx) => kbApi(ctx, "DELETE", API_PATH5, {}, buildBody2(ctx))
572
909
  };
573
910
 
574
911
  // src/commands/te-kb/create.ts
575
- var API_PATH5 = "/agent/api/external/knowledge-bases/create";
912
+ var API_PATH6 = "/agent/api/external/knowledge-bases/create";
576
913
  var VALID_SCOPES = /* @__PURE__ */ new Set(["personal", "company"]);
577
914
  function getScope(ctx) {
578
915
  const scope = ctx.str("scope") || "company";
@@ -600,19 +937,19 @@ function normalizeTags(raw) {
600
937
  return tags;
601
938
  }
602
939
  function buildBody3(ctx) {
603
- const body2 = {
940
+ const body4 = {
604
941
  scope: getScope(ctx),
605
942
  name: ctx.str("name")
606
943
  };
607
944
  const description = ctx.str("description");
608
- if (description) body2.description = description;
945
+ if (description) body4.description = description;
609
946
  const tags = normalizeTags(ctx.json("tags"));
610
- if (tags && tags.length > 0) body2.tags = tags;
947
+ if (tags && tags.length > 0) body4.tags = tags;
611
948
  const projectId = ctx.str("project-id");
612
- if (projectId) body2.projectId = projectId;
949
+ if (projectId) body4.projectId = projectId;
613
950
  const projectName = ctx.str("project-name");
614
- if (projectName) body2.projectName = projectName;
615
- return body2;
951
+ if (projectName) body4.projectName = projectName;
952
+ return body4;
616
953
  }
617
954
  var create = {
618
955
  service: "kb",
@@ -633,14 +970,14 @@ var create = {
633
970
  },
634
971
  dryRun: (ctx) => ({
635
972
  method: "POST",
636
- url: `${ctx.host().replace(/\/$/, "")}${API_PATH5}`,
973
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH6}`,
637
974
  body: buildBody3(ctx)
638
975
  }),
639
- execute: async (ctx) => kbApi(ctx, "POST", API_PATH5, {}, buildBody3(ctx))
976
+ execute: async (ctx) => kbApi(ctx, "POST", API_PATH6, {}, buildBody3(ctx))
640
977
  };
641
978
 
642
979
  // src/commands/te-kb/rm-source.ts
643
- var API_PATH6 = "/agent/api/external/knowledge-bases/sources";
980
+ var API_PATH7 = "/agent/api/external/knowledge-bases/sources";
644
981
  function sourceSelector(ctx) {
645
982
  const id = ctx.str("id").trim();
646
983
  if (id) return { id };
@@ -649,12 +986,12 @@ function sourceSelector(ctx) {
649
986
  throw new CliValidationError("One of --id or --display-name is required.");
650
987
  }
651
988
  function buildBody4(ctx) {
652
- const body2 = {
989
+ const body4 = {
653
990
  name: ctx.str("name")
654
991
  };
655
992
  const scope = getExternalKnowledgeBaseTargetScope(ctx);
656
- if (scope) body2.scope = scope;
657
- return { ...body2, ...sourceSelector(ctx) };
993
+ if (scope) body4.scope = scope;
994
+ return { ...body4, ...sourceSelector(ctx) };
658
995
  }
659
996
  var rmSource = {
660
997
  service: "kb",
@@ -673,18 +1010,18 @@ var rmSource = {
673
1010
  },
674
1011
  dryRun: (ctx) => ({
675
1012
  method: "DELETE",
676
- url: `${ctx.host().replace(/\/$/, "")}${API_PATH6}`,
1013
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH7}`,
677
1014
  body: buildBody4(ctx)
678
1015
  }),
679
- execute: async (ctx) => kbApi(ctx, "DELETE", API_PATH6, {}, buildBody4(ctx), {
1016
+ execute: async (ctx) => kbApi(ctx, "DELETE", API_PATH7, {}, buildBody4(ctx), {
680
1017
  preserveErrorMetadata: true
681
1018
  })
682
1019
  };
683
1020
 
684
1021
  // src/commands/te-kb/schema.ts
685
- import fs3 from "fs";
686
- import path3 from "path";
687
- 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";
688
1025
  var MAX_CUSTOM_INSTRUCTIONS_CHARS = 1e4;
689
1026
  function getCustomInstructions(ctx) {
690
1027
  const inline = ctx.str("custom-instructions");
@@ -692,7 +1029,7 @@ function getCustomInstructions(ctx) {
692
1029
  if (inline && file) {
693
1030
  throw new Error("Use either --custom-instructions or --custom-instructions-file, not both.");
694
1031
  }
695
- const content = file ? fs3.readFileSync(path3.resolve(file), "utf8") : inline;
1032
+ const content = file ? fs5.readFileSync(path5.resolve(file), "utf8") : inline;
696
1033
  if (file && !content.trim()) {
697
1034
  throw new Error("--custom-instructions-file is empty.");
698
1035
  }
@@ -702,20 +1039,20 @@ function getCustomInstructions(ctx) {
702
1039
  return content;
703
1040
  }
704
1041
  function buildBody5(ctx) {
705
- const body2 = {
1042
+ const body4 = {
706
1043
  name: ctx.str("name")
707
1044
  };
708
1045
  const scope = getExternalKnowledgeBaseTargetScope(ctx);
709
- if (scope) body2.scope = scope;
710
- if (ctx.bool("force")) body2.force = true;
1046
+ if (scope) body4.scope = scope;
1047
+ if (ctx.bool("force")) body4.force = true;
711
1048
  const model = ctx.str("model");
712
- if (model) body2.model = model;
1049
+ if (model) body4.model = model;
713
1050
  const customInstructions = getCustomInstructions(ctx);
714
- if (customInstructions) body2.customInstructions = customInstructions;
715
- return body2;
1051
+ if (customInstructions) body4.customInstructions = customInstructions;
1052
+ return body4;
716
1053
  }
717
1054
  async function executeSchema(ctx, api = kbApi) {
718
- return api(ctx, "POST", API_PATH7, {}, buildBody5(ctx), {
1055
+ return api(ctx, "POST", API_PATH8, {}, buildBody5(ctx), {
719
1056
  preserveBusinessErrorCode: true
720
1057
  });
721
1058
  }
@@ -750,21 +1087,21 @@ var schema = {
750
1087
  },
751
1088
  dryRun: (ctx) => ({
752
1089
  method: "POST",
753
- url: `${ctx.host().replace(/\/$/, "")}${API_PATH7}`,
1090
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH8}`,
754
1091
  body: buildBody5(ctx)
755
1092
  }),
756
1093
  execute: executeSchema
757
1094
  };
758
1095
 
759
1096
  // src/commands/te-kb/status.ts
760
- var API_PATH8 = "/agent/api/external/knowledge-bases/status";
1097
+ var API_PATH9 = "/agent/api/external/knowledge-bases/status";
761
1098
  function buildBody6(ctx) {
762
- const body2 = {
1099
+ const body4 = {
763
1100
  name: ctx.str("name")
764
1101
  };
765
1102
  const scope = getExternalKnowledgeBaseTargetScope(ctx);
766
- if (scope) body2.scope = scope;
767
- return body2;
1103
+ if (scope) body4.scope = scope;
1104
+ return body4;
768
1105
  }
769
1106
  var status = {
770
1107
  service: "kb",
@@ -780,21 +1117,21 @@ var status = {
780
1117
  },
781
1118
  dryRun: (ctx) => ({
782
1119
  method: "POST",
783
- url: `${ctx.host().replace(/\/$/, "")}${API_PATH8}`,
1120
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH9}`,
784
1121
  body: buildBody6(ctx)
785
1122
  }),
786
- execute: async (ctx) => kbApi(ctx, "POST", API_PATH8, {}, buildBody6(ctx))
1123
+ execute: async (ctx) => kbApi(ctx, "POST", API_PATH9, {}, buildBody6(ctx))
787
1124
  };
788
1125
 
789
1126
  // src/commands/te-kb/kb-index.ts
790
- var API_PATH9 = "/agent/api/external/knowledge-bases/index";
1127
+ var API_PATH10 = "/agent/api/external/knowledge-bases/index";
791
1128
  function buildBody7(ctx) {
792
- const body2 = {};
1129
+ const body4 = {};
793
1130
  const sources = ctx.json("sources");
794
- if (sources) body2.sources = sources;
1131
+ if (sources) body4.sources = sources;
795
1132
  const locale = ctx.str("locale");
796
- if (locale) body2.locale = locale;
797
- return body2;
1133
+ if (locale) body4.locale = locale;
1134
+ return body4;
798
1135
  }
799
1136
  var kbIndex = {
800
1137
  service: "kb",
@@ -812,14 +1149,14 @@ var kbIndex = {
812
1149
  risk: "read",
813
1150
  dryRun: (ctx) => ({
814
1151
  method: "POST",
815
- url: `${ctx.host().replace(/\/$/, "")}${API_PATH9}`,
1152
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH10}`,
816
1153
  body: buildBody7(ctx)
817
1154
  }),
818
- execute: async (ctx) => kbApi(ctx, "POST", API_PATH9, {}, buildBody7(ctx))
1155
+ execute: async (ctx) => kbApi(ctx, "POST", API_PATH10, {}, buildBody7(ctx))
819
1156
  };
820
1157
 
821
1158
  // src/commands/te-kb/kb-list.ts
822
- var API_PATH10 = "/agent/api/external/knowledge-bases/list";
1159
+ var API_PATH11 = "/agent/api/external/knowledge-bases/list";
823
1160
  var DEFAULT_BUILD_STATUS = "compiled";
824
1161
  var VALID_BUILD_STATUSES = ["idle", "pending", "compiling", "compiled", "failed"];
825
1162
  function getBuildStatus(ctx) {
@@ -836,12 +1173,12 @@ function validateBuildStatus(ctx) {
836
1173
  }
837
1174
  }
838
1175
  function buildBody8(ctx) {
839
- const body2 = {
1176
+ const body4 = {
840
1177
  buildStatus: getBuildStatus(ctx)
841
1178
  };
842
1179
  const locale = ctx.str("locale");
843
- if (locale) body2.locale = locale;
844
- return body2;
1180
+ if (locale) body4.locale = locale;
1181
+ return body4;
845
1182
  }
846
1183
  var kbList = {
847
1184
  service: "kb",
@@ -863,23 +1200,24 @@ var kbList = {
863
1200
  },
864
1201
  dryRun: (ctx) => ({
865
1202
  method: "POST",
866
- url: `${ctx.host().replace(/\/$/, "")}${API_PATH10}`,
1203
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH11}`,
867
1204
  body: buildBody8(ctx)
868
1205
  }),
869
- execute: async (ctx) => kbApi(ctx, "POST", API_PATH10, {}, buildBody8(ctx))
1206
+ execute: async (ctx) => kbApi(ctx, "POST", API_PATH11, {}, buildBody8(ctx))
870
1207
  };
871
1208
 
872
1209
  // src/commands/te-kb/list-sources.ts
873
- var API_PATH11 = "/agent/api/external/knowledge-bases/sources";
1210
+ var API_PATH12 = "/agent/api/external/knowledge-bases/sources";
874
1211
  var MAX_KNOWLEDGE_BASE_NAME_LENGTH = 200;
875
1212
  function knowledgeBaseName(ctx) {
876
1213
  return ctx.str("name").trim();
877
1214
  }
878
1215
  function buildUrl(ctx) {
879
- const url2 = new URL(`${ctx.host().replace(/\/$/, "")}${API_PATH11}`);
1216
+ const url2 = new URL(`${ctx.host().replace(/\/$/, "")}${API_PATH12}`);
880
1217
  url2.searchParams.set("name", knowledgeBaseName(ctx));
881
1218
  const scope = getExternalKnowledgeBaseTargetScope(ctx);
882
1219
  if (scope) url2.searchParams.set("scope", scope);
1220
+ if (ctx.str("content-type")) url2.searchParams.set("contentType", ctx.str("content-type"));
883
1221
  return url2.toString();
884
1222
  }
885
1223
  var listSources = {
@@ -900,7 +1238,8 @@ var listSources = {
900
1238
  type: "string",
901
1239
  required: false,
902
1240
  desc: "Exact knowledge base scope: personal | company (omit for personal \u2192 company fallback)"
903
- }
1241
+ },
1242
+ { name: "content-type", type: "string", desc: "Source content filter: all (default) or text (ordinary .md, .markdown and .txt files only)" }
904
1243
  ],
905
1244
  risk: "read",
906
1245
  validate: (ctx) => {
@@ -914,6 +1253,9 @@ var listSources = {
914
1253
  );
915
1254
  }
916
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
+ }
917
1259
  },
918
1260
  dryRun: (ctx) => ({
919
1261
  method: "GET",
@@ -923,26 +1265,82 @@ var listSources = {
923
1265
  const params = { name: knowledgeBaseName(ctx) };
924
1266
  const scope = getExternalKnowledgeBaseTargetScope(ctx);
925
1267
  if (scope) params.scope = scope;
926
- 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, {
927
1270
  preserveErrorMetadata: true,
928
1271
  retryUnauthorized: false
929
1272
  });
930
1273
  }
931
1274
  };
932
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
+
933
1331
  // src/commands/te-kb/kb-grep.ts
934
- var API_PATH12 = "/agent/api/external/knowledge-bases/grep";
1332
+ var API_PATH14 = "/agent/api/external/knowledge-bases/grep";
935
1333
  function buildBody9(ctx) {
936
- const body2 = {
1334
+ const body4 = {
937
1335
  query: ctx.str("query"),
938
1336
  sources: ctx.json("sources"),
939
1337
  paths: ctx.json("paths")
940
1338
  };
941
1339
  const topK = ctx.optionalNum("top-k");
942
- if (topK !== void 0) body2.topK = topK;
1340
+ if (topK !== void 0) body4.topK = topK;
943
1341
  const locale = ctx.str("locale");
944
- if (locale) body2.locale = locale;
945
- return body2;
1342
+ if (locale) body4.locale = locale;
1343
+ return body4;
946
1344
  }
947
1345
  var kbGrep = {
948
1346
  service: "kb",
@@ -974,14 +1372,14 @@ var kbGrep = {
974
1372
  risk: "read",
975
1373
  dryRun: (ctx) => ({
976
1374
  method: "POST",
977
- url: `${ctx.host().replace(/\/$/, "")}${API_PATH12}`,
1375
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH14}`,
978
1376
  body: buildBody9(ctx)
979
1377
  }),
980
- execute: async (ctx) => kbApi(ctx, "POST", API_PATH12, {}, buildBody9(ctx))
1378
+ execute: async (ctx) => kbApi(ctx, "POST", API_PATH14, {}, buildBody9(ctx))
981
1379
  };
982
1380
 
983
1381
  // src/commands/te-kb/kb-read.ts
984
- var API_PATH13 = "/agent/api/external/knowledge-bases/read";
1382
+ var API_PATH15 = "/agent/api/external/knowledge-bases/read";
985
1383
  var VALID_EXPAND_MODES = /* @__PURE__ */ new Set(["block", "none"]);
986
1384
  var MAX_READ_LIMIT = 2e3;
987
1385
  function readExpand(ctx) {
@@ -1005,20 +1403,20 @@ function readLimit(ctx) {
1005
1403
  return limit;
1006
1404
  }
1007
1405
  function buildBody10(ctx) {
1008
- const body2 = {
1406
+ const body4 = {
1009
1407
  source: ctx.json("source"),
1010
1408
  path: ctx.str("path")
1011
1409
  };
1012
1410
  const offset = ctx.optionalNum("offset");
1013
- if (offset !== void 0) body2.offset = offset;
1411
+ if (offset !== void 0) body4.offset = offset;
1014
1412
  const limit = ctx.optionalNum("limit");
1015
- if (limit !== void 0) body2.limit = limit;
1413
+ if (limit !== void 0) body4.limit = limit;
1016
1414
  const expand = readExpand(ctx);
1017
- if (expand) body2.expand = expand;
1018
- if (ctx.bool("outline")) body2.outline = true;
1415
+ if (expand) body4.expand = expand;
1416
+ if (ctx.bool("outline")) body4.outline = true;
1019
1417
  const locale = ctx.str("locale");
1020
- if (locale) body2.locale = locale;
1021
- return body2;
1418
+ if (locale) body4.locale = locale;
1419
+ return body4;
1022
1420
  }
1023
1421
  var kbRead = {
1024
1422
  service: "kb",
@@ -1059,10 +1457,10 @@ var kbRead = {
1059
1457
  },
1060
1458
  dryRun: (ctx) => ({
1061
1459
  method: "POST",
1062
- url: `${ctx.host().replace(/\/$/, "")}${API_PATH13}`,
1460
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH15}`,
1063
1461
  body: buildBody10(ctx)
1064
1462
  }),
1065
- execute: async (ctx) => kbApi(ctx, "POST", API_PATH13, {}, buildBody10(ctx))
1463
+ execute: async (ctx) => kbApi(ctx, "POST", API_PATH15, {}, buildBody10(ctx))
1066
1464
  };
1067
1465
 
1068
1466
  // src/commands/te-kb/ask-shared.ts
@@ -1081,12 +1479,12 @@ function isTransientAskPollError(error) {
1081
1479
  error.message
1082
1480
  );
1083
1481
  }
1084
- async function pollUntilSettled(getStatus, executionId, options = {}) {
1085
- const intervalMs = options.intervalMs ?? ASK_POLL_INTERVAL_MS;
1086
- const timeoutMs = options.timeoutMs ?? ASK_POLL_TIMEOUT_MS;
1087
- const maxTransientFailures = options.maxTransientFailures ?? ASK_MAX_TRANSIENT_POLL_FAILURES;
1088
- const now = options.now ?? Date.now;
1089
- const sleep = options.sleep ?? ((ms) => new Promise((resolve2) => setTimeout(resolve2, ms)));
1482
+ async function pollUntilSettled(getStatus, executionId, options2 = {}) {
1483
+ const intervalMs = options2.intervalMs ?? ASK_POLL_INTERVAL_MS;
1484
+ const timeoutMs = options2.timeoutMs ?? ASK_POLL_TIMEOUT_MS;
1485
+ const maxTransientFailures = options2.maxTransientFailures ?? ASK_MAX_TRANSIENT_POLL_FAILURES;
1486
+ const now = options2.now ?? Date.now;
1487
+ const sleep = options2.sleep ?? ((ms) => new Promise((resolve2) => setTimeout(resolve2, ms)));
1090
1488
  const startTime = now();
1091
1489
  let transientFailures = 0;
1092
1490
  while (true) {
@@ -1143,16 +1541,16 @@ function validateLocale(locale) {
1143
1541
  }
1144
1542
  }
1145
1543
  function buildBody11(ctx) {
1146
- const body2 = {
1544
+ const body4 = {
1147
1545
  question: ctx.str("question")
1148
1546
  };
1149
1547
  const sources = ctx.json("sources");
1150
- if (sources) body2.sources = sources;
1548
+ if (sources) body4.sources = sources;
1151
1549
  const modelId = ctx.str("model-id");
1152
- if (modelId) body2.modelId = modelId;
1550
+ if (modelId) body4.modelId = modelId;
1153
1551
  const locale = ctx.str("locale");
1154
- if (locale) body2.locale = locale;
1155
- return body2;
1552
+ if (locale) body4.locale = locale;
1553
+ return body4;
1156
1554
  }
1157
1555
  var ask = {
1158
1556
  service: "kb",
@@ -1272,24 +1670,24 @@ var askStatus = {
1272
1670
  };
1273
1671
 
1274
1672
  // src/commands/te-kb/url.ts
1275
- var API_PATH14 = "/agent/api/external/knowledge-bases/sources/url";
1673
+ var API_PATH16 = "/agent/api/external/knowledge-bases/sources/url";
1276
1674
  function validateUrl(url2) {
1277
1675
  if (!/^https?:\/\//i.test(url2)) {
1278
1676
  throw new Error(`Invalid --url: ${url2}. Must be an http(s) URL`);
1279
1677
  }
1280
1678
  }
1281
1679
  function buildBody12(ctx) {
1282
- const body2 = {
1680
+ const body4 = {
1283
1681
  name: ctx.str("name"),
1284
1682
  url: ctx.str("url")
1285
1683
  };
1286
1684
  const scope = getExternalKnowledgeBaseTargetScope(ctx);
1287
- if (scope) body2.scope = scope;
1685
+ if (scope) body4.scope = scope;
1288
1686
  const displayName = ctx.str("display-name");
1289
- if (displayName) body2.displayName = displayName;
1687
+ if (displayName) body4.displayName = displayName;
1290
1688
  const parseInstruction = ctx.str("parse-instruction");
1291
- if (parseInstruction) body2.parseInstruction = parseInstruction;
1292
- return body2;
1689
+ if (parseInstruction) body4.parseInstruction = parseInstruction;
1690
+ return body4;
1293
1691
  }
1294
1692
  var url = {
1295
1693
  service: "kb",
@@ -1309,16 +1707,16 @@ var url = {
1309
1707
  },
1310
1708
  dryRun: (ctx) => ({
1311
1709
  method: "POST",
1312
- url: `${ctx.host().replace(/\/$/, "")}${API_PATH14}`,
1710
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH16}`,
1313
1711
  body: buildBody12(ctx)
1314
1712
  }),
1315
- execute: async (ctx) => kbApi(ctx, "POST", API_PATH14, {}, buildBody12(ctx))
1713
+ execute: async (ctx) => kbApi(ctx, "POST", API_PATH16, {}, buildBody12(ctx))
1316
1714
  };
1317
1715
 
1318
1716
  // src/commands/te-kb/import.ts
1319
- import { promises as fs4 } from "fs";
1320
- import path4 from "path";
1321
- 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";
1322
1720
  var MAX_SNAPSHOT_ARCHIVE_BYTES = 50 * 1024 * 1024;
1323
1721
  var VALID_SCOPES2 = /* @__PURE__ */ new Set(["personal", "company"]);
1324
1722
  function getScope2(ctx) {
@@ -1354,16 +1752,16 @@ function normalizeTags2(raw) {
1354
1752
  return tags;
1355
1753
  }
1356
1754
  function validateArchivePath(filePath) {
1357
- if (path4.extname(filePath).toLocaleLowerCase("en-US") !== ".zip") {
1755
+ if (path6.extname(filePath).toLocaleLowerCase("en-US") !== ".zip") {
1358
1756
  throw new Error("--file must point to a .zip archive");
1359
1757
  }
1360
1758
  }
1361
1759
  async function readArchive(filePath) {
1362
1760
  validateArchivePath(filePath);
1363
- const absolutePath = path4.resolve(filePath);
1761
+ const absolutePath = path6.resolve(filePath);
1364
1762
  let stat;
1365
1763
  try {
1366
- stat = await fs4.stat(absolutePath);
1764
+ stat = await fs6.stat(absolutePath);
1367
1765
  } catch {
1368
1766
  throw new Error(`File not found: ${filePath}`);
1369
1767
  }
@@ -1373,7 +1771,7 @@ async function readArchive(filePath) {
1373
1771
  if (stat.size > MAX_SNAPSHOT_ARCHIVE_BYTES) {
1374
1772
  throw new Error("--file must not exceed 50 MB");
1375
1773
  }
1376
- return { absolutePath, bytes: await fs4.readFile(absolutePath) };
1774
+ return { absolutePath, bytes: await fs6.readFile(absolutePath) };
1377
1775
  }
1378
1776
  function appendOptionalFields(ctx, form) {
1379
1777
  const description = ctx.str("description").trim();
@@ -1440,7 +1838,7 @@ var importSnapshot = {
1440
1838
  form.append(
1441
1839
  "file",
1442
1840
  new Blob([Uint8Array.from(archive.bytes)], { type: "application/zip" }),
1443
- path4.basename(archive.absolutePath)
1841
+ path6.basename(archive.absolutePath)
1444
1842
  );
1445
1843
  form.append("name", ctx.str("name").trim());
1446
1844
  form.append("scope", getScope2(ctx));
@@ -1448,7 +1846,7 @@ var importSnapshot = {
1448
1846
  try {
1449
1847
  return await kbUpload(
1450
1848
  ctx,
1451
- API_PATH15,
1849
+ API_PATH17,
1452
1850
  form,
1453
1851
  { scope: getScope2(ctx) },
1454
1852
  { preserveErrorMetadata: true, retryUnauthorized: true }
@@ -1477,7 +1875,7 @@ var importSnapshot = {
1477
1875
  };
1478
1876
 
1479
1877
  // src/commands/te-kb/import-status.ts
1480
- var API_PATH16 = "/agent/api/external/knowledge-bases/import";
1878
+ var API_PATH18 = "/agent/api/external/knowledge-bases/import";
1481
1879
  var MAX_REQUEST_ID_LENGTH = 191;
1482
1880
  function requestIdFrom(ctx) {
1483
1881
  return ctx.str("request-id").trim();
@@ -1508,7 +1906,7 @@ var importStatus = {
1508
1906
  },
1509
1907
  dryRun: (ctx) => ({
1510
1908
  method: "GET",
1511
- url: `${ctx.host().replace(/\/$/, "")}${API_PATH16}?requestId=${encodeURIComponent(requestIdFrom(ctx))}`
1909
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH18}?requestId=${encodeURIComponent(requestIdFrom(ctx))}`
1512
1910
  }),
1513
1911
  execute: async (ctx) => {
1514
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.";
@@ -1516,7 +1914,7 @@ var importStatus = {
1516
1914
  return await kbApi(
1517
1915
  ctx,
1518
1916
  "GET",
1519
- API_PATH16,
1917
+ API_PATH18,
1520
1918
  { requestId: requestIdFrom(ctx) },
1521
1919
  void 0,
1522
1920
  { preserveErrorMetadata: true, retryUnauthorized: true }
@@ -1547,8 +1945,8 @@ var importStatus = {
1547
1945
  };
1548
1946
 
1549
1947
  // src/commands/te-kb/source-directory.ts
1550
- import { promises as fs5 } from "fs";
1551
- import path5 from "path";
1948
+ import { promises as fs7 } from "fs";
1949
+ import path7 from "path";
1552
1950
  var sourceFlags = [
1553
1951
  { name: "name", type: "string", required: true, desc: "Knowledge base name (personal then company)" },
1554
1952
  { name: "id", type: "string", required: true, desc: "ZIP source ID copied from +list-sources" }
@@ -1564,9 +1962,9 @@ var revisionFlag2 = {
1564
1962
  var apiOptions2 = { preserveErrorMetadata: true, retryUnauthorized: false };
1565
1963
  var maxFileBytes = 50 * 1024 * 1024;
1566
1964
  function validateIdentity2(ctx) {
1567
- for (const [flag, max] of [["name", 200], ["id", 191]]) {
1568
- const value = ctx.str(flag).trim();
1569
- if (!value || value.length > max) throw new CliValidationError(`Invalid --${flag}.`);
1965
+ for (const [flag2, max] of [["name", 200], ["id", 191]]) {
1966
+ const value = ctx.str(flag2).trim();
1967
+ if (!value || value.length > max) throw new CliValidationError(`Invalid --${flag2}.`);
1570
1968
  }
1571
1969
  }
1572
1970
  function relativePath(ctx, allowRoot = false) {
@@ -1584,14 +1982,14 @@ function validateMutation2(ctx) {
1584
1982
  throw new CliValidationError("--expected-revision must be a positive safe integer.");
1585
1983
  }
1586
1984
  }
1587
- function endpoint(ctx, suffix = "directory") {
1985
+ function endpoint2(ctx, suffix = "directory") {
1588
1986
  return `/agent/api/external/knowledge-bases/sources/${encodeURIComponent(ctx.str("id").trim())}/${suffix}`;
1589
1987
  }
1590
- function query2(ctx) {
1988
+ function query4(ctx) {
1591
1989
  return { name: ctx.str("name").trim(), path: ctx.str("path") };
1592
1990
  }
1593
- function preview(ctx, method, suffix = "directory", body2) {
1594
- return { method, url: `${ctx.host().replace(/\/$/, "")}${endpoint(ctx, suffix)}`, ...body2 ? { body: body2 } : { params: query2(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) } };
1595
1993
  }
1596
1994
  function mutationBody(ctx, operation) {
1597
1995
  return { name: ctx.str("name").trim(), expectedRevision: ctx.num("expected-revision"), operations: [operation] };
@@ -1614,9 +2012,9 @@ var sourceLs = {
1614
2012
  throw new CliValidationError("--limit must be an integer from 1 to 200.");
1615
2013
  }
1616
2014
  },
1617
- dryRun: (ctx) => ({ ...preview(ctx, "GET"), params: { ...query2(ctx), limit: ctx.num("limit"), ...ctx.str("cursor") ? { cursor: ctx.str("cursor") } : {} } }),
1618
- execute: (ctx) => kbApi(ctx, "GET", endpoint(ctx), {
1619
- ...query2(ctx),
2015
+ dryRun: (ctx) => ({ ...preview(ctx, "GET"), params: { ...query4(ctx), limit: ctx.num("limit"), ...ctx.str("cursor") ? { cursor: ctx.str("cursor") } : {} } }),
2016
+ execute: (ctx) => kbApi(ctx, "GET", endpoint2(ctx), {
2017
+ ...query4(ctx),
1620
2018
  limit: ctx.num("limit"),
1621
2019
  ...ctx.str("cursor") ? { cursor: ctx.str("cursor") } : {}
1622
2020
  }, void 0, apiOptions2)
@@ -1639,12 +2037,12 @@ var sourceRead = {
1639
2037
  },
1640
2038
  dryRun: (ctx) => preview(ctx, "GET", "raw"),
1641
2039
  execute: async (ctx) => {
1642
- const result = await kbApi(ctx, "GET", endpoint(ctx, "raw"), query2(ctx), void 0, { ...apiOptions2, responseType: "bytes" });
2040
+ const result = await kbApi(ctx, "GET", endpoint2(ctx, "raw"), query4(ctx), void 0, { ...apiOptions2, responseType: "bytes" });
1643
2041
  const bytes = Buffer.from(result.bytes);
1644
2042
  const metadata = { path: ctx.str("path"), sizeBytes: bytes.length, contentType: result.contentType };
1645
2043
  if (ctx.str("output")) {
1646
- const output = path5.resolve(ctx.str("output"));
1647
- await fs5.writeFile(output, bytes, { flag: "wx" });
2044
+ const output = path7.resolve(ctx.str("output"));
2045
+ await fs7.writeFile(output, bytes, { flag: "wx" });
1648
2046
  return { ...metadata, output };
1649
2047
  }
1650
2048
  if (ctx.str("encoding") === "base64") return { ...metadata, encoding: "base64", content: bytes.toString("base64") };
@@ -1656,8 +2054,8 @@ var sourceRead = {
1656
2054
  }
1657
2055
  };
1658
2056
  async function fileOperation(ctx, dryRun) {
1659
- const file = path5.resolve(ctx.str("file"));
1660
- const handle = await fs5.open(file, "r");
2057
+ const file = path7.resolve(ctx.str("file"));
2058
+ const handle = await fs7.open(file, "r");
1661
2059
  try {
1662
2060
  const stat = await handle.stat();
1663
2061
  if (!stat.isFile() || stat.size > maxFileBytes) throw new CliValidationError("--file must be a regular file of at most 50 MB.");
@@ -1692,7 +2090,7 @@ var sourcePut = {
1692
2090
  if (!["add", "replace"].includes(ctx.str("action"))) throw new CliValidationError("--action must be add or replace.");
1693
2091
  },
1694
2092
  dryRun: async (ctx) => preview(ctx, "POST", "directory", mutationBody(ctx, await fileOperation(ctx, true))),
1695
- execute: async (ctx) => kbApi(ctx, "POST", endpoint(ctx), {}, mutationBody(ctx, await fileOperation(ctx, false)), apiOptions2)
2093
+ execute: async (ctx) => kbApi(ctx, "POST", endpoint2(ctx), {}, mutationBody(ctx, await fileOperation(ctx, false)), apiOptions2)
1696
2094
  };
1697
2095
  function deleteOperation(ctx) {
1698
2096
  return { action: "delete", path: ctx.str("path"), confirmed: true, ...ctx.bool("recursive") ? { recursive: true } : {} };
@@ -1710,15 +2108,15 @@ var sourceRm = {
1710
2108
  ],
1711
2109
  validate: validateMutation2,
1712
2110
  dryRun: (ctx) => preview(ctx, "POST", "directory", mutationBody(ctx, deleteOperation(ctx))),
1713
- execute: (ctx) => kbApi(ctx, "POST", endpoint(ctx), {}, mutationBody(ctx, deleteOperation(ctx)), apiOptions2)
2111
+ execute: (ctx) => kbApi(ctx, "POST", endpoint2(ctx), {}, mutationBody(ctx, deleteOperation(ctx)), apiOptions2)
1714
2112
  };
1715
2113
 
1716
2114
  // src/commands/te-kb/version-management.ts
1717
- import { promises as fs6 } from "fs";
1718
- import path6 from "path";
1719
- 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";
1720
2118
  var apiOptions3 = { preserveErrorMetadata: true, retryUnauthorized: false };
1721
- var targetFlags = [
2119
+ var targetFlags3 = [
1722
2120
  { name: "name", type: "string", required: true, minLength: 1, maxLength: 200, desc: "Exact knowledge base name copied from +list" },
1723
2121
  { name: "scope", type: "string", desc: "Exact personal or company scope; omit for personal then company lookup" }
1724
2122
  ];
@@ -1729,18 +2127,18 @@ var pagingFlags = [
1729
2127
  { name: "limit", type: "number", default: 100, min: 1, max: 200, desc: "Page size from 1 to 200" }
1730
2128
  ];
1731
2129
  var pathFlag2 = { name: "path", type: "string", desc: "Exact path relative to the historical source directory" };
1732
- function positiveInteger2(ctx, flag) {
1733
- const value = ctx.num(flag);
1734
- if (!Number.isSafeInteger(value) || value < 1 || value > 2147483647) throw new CliValidationError(`--${flag} must be a positive integer no greater than 2147483647.`);
2130
+ function positiveInteger2(ctx, flag2) {
2131
+ const value = ctx.num(flag2);
2132
+ if (!Number.isSafeInteger(value) || value < 1 || value > 2147483647) throw new CliValidationError(`--${flag2} must be a positive integer no greater than 2147483647.`);
1735
2133
  return value;
1736
2134
  }
1737
- function validateTarget(ctx) {
2135
+ function validateTarget2(ctx) {
1738
2136
  const name = ctx.str("name").trim();
1739
2137
  if (!name || name.length > 200) throw new CliValidationError("--name must contain 1 to 200 characters.");
1740
2138
  getExternalKnowledgeBaseTargetScope(ctx);
1741
2139
  }
1742
2140
  function validateVersion(ctx) {
1743
- validateTarget(ctx);
2141
+ validateTarget2(ctx);
1744
2142
  positiveInteger2(ctx, "version");
1745
2143
  }
1746
2144
  function validateSource(ctx) {
@@ -1760,52 +2158,52 @@ function validatePath(ctx, required = false) {
1760
2158
  throw new CliValidationError("--path must be a normalized relative path inside the historical source.");
1761
2159
  }
1762
2160
  }
1763
- function query3(ctx) {
2161
+ function query5(ctx) {
1764
2162
  const scope = getExternalKnowledgeBaseTargetScope(ctx);
1765
2163
  return { name: ctx.str("name").trim(), ...scope ? { scope } : {} };
1766
2164
  }
1767
2165
  function pageQuery(ctx) {
1768
- return { ...query3(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") } : {} };
1769
2167
  }
1770
2168
  function versionEndpoint(ctx, suffix = "") {
1771
- return `${API2}/${positiveInteger2(ctx, "version")}${suffix}`;
2169
+ return `${API3}/${positiveInteger2(ctx, "version")}${suffix}`;
1772
2170
  }
1773
2171
  function sourceEndpoint2(ctx, action) {
1774
2172
  return versionEndpoint(ctx, `/sources/${encodeURIComponent(ctx.str("id").trim())}/${action}`);
1775
2173
  }
1776
- function preview2(ctx, endpoint2, params, body2) {
1777
- return { method: body2 ? "POST" : "GET", url: `${ctx.host().replace(/\/$/, "")}${endpoint2}`, params, ...body2 ? { body: body2 } : {} };
2174
+ function preview2(ctx, endpoint3, params, body4) {
2175
+ return { method: body4 ? "POST" : "GET", url: `${ctx.host().replace(/\/$/, "")}${endpoint3}`, params, ...body4 ? { body: body4 } : {} };
1778
2176
  }
1779
2177
  var versions = {
1780
2178
  service: "kb",
1781
2179
  command: "+versions",
1782
2180
  risk: "read",
1783
2181
  description: "List immutable published versions and the latest version ID, one page at a time.",
1784
- flags: [...targetFlags, ...pagingFlags],
2182
+ flags: [...targetFlags3, ...pagingFlags],
1785
2183
  validate: (ctx) => {
1786
- validateTarget(ctx);
2184
+ validateTarget2(ctx);
1787
2185
  validatePage(ctx);
1788
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.");
1789
2187
  },
1790
- dryRun: (ctx) => preview2(ctx, API2, pageQuery(ctx)),
1791
- 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)
1792
2190
  };
1793
2191
  var versionShow = {
1794
2192
  service: "kb",
1795
2193
  command: "+version-show",
1796
2194
  risk: "read",
1797
2195
  description: "Read one published version summary without reading current sources.",
1798
- flags: [...targetFlags, versionFlag],
2196
+ flags: [...targetFlags3, versionFlag],
1799
2197
  validate: validateVersion,
1800
- dryRun: (ctx) => preview2(ctx, versionEndpoint(ctx), query3(ctx)),
1801
- execute: (ctx) => kbApi(ctx, "GET", versionEndpoint(ctx), query3(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)
1802
2200
  };
1803
2201
  var versionSources = {
1804
2202
  service: "kb",
1805
2203
  command: "+version-sources",
1806
2204
  risk: "read",
1807
2205
  description: "List historical sources and stable IDs from one immutable version.",
1808
- flags: [...targetFlags, 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" }],
1809
2207
  validate: (ctx) => {
1810
2208
  validateVersion(ctx);
1811
2209
  validatePage(ctx);
@@ -1819,21 +2217,21 @@ var versionDiff = {
1819
2217
  command: "+version-diff",
1820
2218
  risk: "read",
1821
2219
  description: "Compare historical source additions, deletions, content, and metadata between two versions.",
1822
- flags: [...targetFlags, { ...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" }],
1823
2221
  validate: (ctx) => {
1824
- validateTarget(ctx);
2222
+ validateTarget2(ctx);
1825
2223
  positiveInteger2(ctx, "from");
1826
2224
  positiveInteger2(ctx, "to");
1827
2225
  },
1828
- dryRun: (ctx) => preview2(ctx, `${API2}/compare`, { ...query3(ctx), from: ctx.num("from"), to: ctx.num("to") }),
1829
- execute: (ctx) => kbApi(ctx, "GET", `${API2}/compare`, { ...query3(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)
1830
2228
  };
1831
2229
  var versionTree = {
1832
2230
  service: "kb",
1833
2231
  command: "+version-tree",
1834
2232
  risk: "read",
1835
2233
  description: "List a historical ZIP or URL source directory without changing current files.",
1836
- flags: [...targetFlags, versionFlag, sourceFlag, pathFlag2, ...pagingFlags],
2234
+ flags: [...targetFlags3, versionFlag, sourceFlag, pathFlag2, ...pagingFlags],
1837
2235
  validate: (ctx) => {
1838
2236
  validateSource(ctx);
1839
2237
  validatePath(ctx);
@@ -1847,30 +2245,30 @@ var versionRead = {
1847
2245
  command: "+version-read",
1848
2246
  risk: "read",
1849
2247
  description: "Preview one historical directory child file; unsupported or oversized files return metadata only.",
1850
- flags: [...targetFlags, versionFlag, sourceFlag, { ...pathFlag2, required: true }],
2248
+ flags: [...targetFlags3, versionFlag, sourceFlag, { ...pathFlag2, required: true }],
1851
2249
  validate: (ctx) => {
1852
2250
  validateSource(ctx);
1853
2251
  validatePath(ctx, true);
1854
2252
  },
1855
- dryRun: (ctx) => preview2(ctx, sourceEndpoint2(ctx, "file"), { ...query3(ctx), path: ctx.str("path") }),
1856
- execute: (ctx) => kbApi(ctx, "GET", sourceEndpoint2(ctx, "file"), { ...query3(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)
1857
2255
  };
1858
2256
  var versionDownload = {
1859
2257
  service: "kb",
1860
2258
  command: "+version-download",
1861
2259
  risk: "read",
1862
2260
  description: "Download one ordinary historical file source to a new local file. ZIP/URL directories cannot be downloaded.",
1863
- flags: [...targetFlags, 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" }],
1864
2262
  validate: (ctx) => {
1865
2263
  validateSource(ctx);
1866
2264
  if (!ctx.str("output").trim()) throw new CliValidationError("--output is required.");
1867
2265
  },
1868
- dryRun: (ctx) => ({ ...preview2(ctx, sourceEndpoint2(ctx, "raw"), query3(ctx)), output: path6.resolve(ctx.str("output")) }),
2266
+ dryRun: (ctx) => ({ ...preview2(ctx, sourceEndpoint2(ctx, "raw"), query5(ctx)), output: path8.resolve(ctx.str("output")) }),
1869
2267
  execute: async (ctx) => {
1870
- const result = await kbApi(ctx, "GET", sourceEndpoint2(ctx, "raw"), query3(ctx), void 0, { ...apiOptions3, responseType: "bytes" });
1871
- const output = path6.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"));
1872
2270
  const bytes = Buffer.from(result.bytes);
1873
- await fs6.writeFile(output, bytes, { flag: "wx" });
2271
+ await fs8.writeFile(output, bytes, { flag: "wx" });
1874
2272
  return { versionNumber: ctx.num("version"), sourceId: ctx.str("id").trim(), sizeBytes: String(bytes.length), output };
1875
2273
  }
1876
2274
  };
@@ -1883,7 +2281,7 @@ var rollback = {
1883
2281
  risk: "high-risk-write",
1884
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.",
1885
2283
  flags: [
1886
- ...targetFlags,
2284
+ ...targetFlags3,
1887
2285
  versionFlag,
1888
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" },
1889
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" }
@@ -1894,26 +2292,31 @@ var rollback = {
1894
2292
  const latest = ctx.str("expected-latest-version-id");
1895
2293
  if (!latest || latest.length > 191) throw new CliValidationError("--expected-latest-version-id must contain 1 to 191 characters.");
1896
2294
  },
1897
- dryRun: (ctx) => preview2(ctx, versionEndpoint(ctx, "/rollback"), query3(ctx), rollbackBody(ctx)),
1898
- execute: (ctx) => kbApi(ctx, "POST", versionEndpoint(ctx, "/rollback"), query3(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)
1899
2297
  };
1900
2298
  var rollbackStatus = {
1901
2299
  service: "kb",
1902
2300
  command: "+rollback-status",
1903
2301
  risk: "read",
1904
2302
  description: "Read one persisted rollback operation without polling. A running operation with errorCode requires administrator review; never retry it as a new write.",
1905
- flags: [...targetFlags, { 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" }],
1906
2304
  validate: (ctx) => {
1907
- validateTarget(ctx);
2305
+ validateTarget2(ctx);
1908
2306
  if (!ctx.str("operation-id").trim() || ctx.str("operation-id").length > 191) throw new CliValidationError("--operation-id must contain 1 to 191 characters.");
1909
2307
  },
1910
- dryRun: (ctx) => preview2(ctx, `${API2}/operations/${encodeURIComponent(ctx.str("operation-id").trim())}`, query3(ctx)),
1911
- execute: (ctx) => kbApi(ctx, "GET", `${API2}/operations/${encodeURIComponent(ctx.str("operation-id").trim())}`, query3(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)
1912
2310
  };
1913
2311
 
1914
2312
  // src/commands/te-kb/index.ts
1915
2313
  var commands = [
2314
+ usageList,
2315
+ ...schemaImportCommands,
1916
2316
  sourceCheckUpdates,
2317
+ sourceCheckUrlUpdates,
2318
+ sourceCreateText,
2319
+ sourceReadText,
1917
2320
  sourceReplace,
1918
2321
  sourceRestore,
1919
2322
  sourcePreview,
@@ -1958,6 +2361,7 @@ export {
1958
2361
  compile,
1959
2362
  create,
1960
2363
  te_kb_default as default,
2364
+ executeSchemaImport,
1961
2365
  importSnapshot,
1962
2366
  importStatus,
1963
2367
  kbGrep,
@@ -1970,23 +2374,41 @@ export {
1970
2374
  rollback,
1971
2375
  rollbackStatus,
1972
2376
  schema,
2377
+ schemaDownload,
2378
+ schemaImport,
2379
+ schemaImportAbandon,
2380
+ schemaImportApply,
2381
+ schemaImportCommands,
2382
+ schemaImportContent,
2383
+ schemaImportDiff,
2384
+ schemaImportList,
2385
+ schemaImportOptimize,
2386
+ schemaImportReject,
2387
+ schemaImportSave,
2388
+ schemaImportStatus,
2389
+ schemaImportValidate,
1973
2390
  sourceCancel,
1974
2391
  sourceCheckUpdates,
2392
+ sourceCheckUrlUpdates,
1975
2393
  sourceCommit,
2394
+ sourceCreateText,
1976
2395
  sourceLs,
1977
2396
  sourcePreview,
1978
2397
  sourcePut,
1979
2398
  sourceRead,
2399
+ sourceReadText,
1980
2400
  sourceReplace,
1981
2401
  sourceRestore,
1982
2402
  sourceRm,
1983
2403
  status,
1984
2404
  url,
2405
+ usageList,
1985
2406
  versionDiff,
1986
2407
  versionDownload,
1987
2408
  versionRead,
1988
2409
  versionShow,
1989
2410
  versionSources,
1990
2411
  versionTree,
1991
- versions
2412
+ versions,
2413
+ waitSchemaImport
1992
2414
  };