@thinkingai/ae-cli 6.1.23 → 6.1.25

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 (142) hide show
  1. package/README.md +7 -1
  2. package/README.zh.md +7 -1
  3. package/dist/{auth-XZNXFRJS.js → auth-LHM7NQPR.js} +167 -7
  4. package/dist/{capability-FYTU3X6L.js → capability-SJI5KOCK.js} +11 -6
  5. package/dist/{chunk-CCS66K4K.js → chunk-2FJM4HRV.js} +3 -3
  6. package/dist/{chunk-57RRFUEZ.js → chunk-5XRQ3CZR.js} +4 -4
  7. package/dist/{chunk-EQ255HKO.js → chunk-7WZACOAI.js} +2 -2
  8. package/dist/{chunk-DX5CDO34.js → chunk-BW7JUDEI.js} +84 -19
  9. package/dist/{chunk-7XGFSUOM.js → chunk-DU72X2IO.js} +271 -76
  10. package/dist/{chunk-V2NUHPXF.js → chunk-GK7WDY7E.js} +1 -1
  11. package/dist/{chunk-7FTTULED.js → chunk-IG3DYEIR.js} +4 -1
  12. package/dist/{chunk-HBGADCKA.js → chunk-KJDOTPYU.js} +3 -3
  13. package/dist/{chunk-4NRCTUZJ.js → chunk-KS4DE3MX.js} +4 -4
  14. package/dist/{chunk-JOCDD4ON.js → chunk-N4BLPJC7.js} +1 -1
  15. package/dist/{chunk-HFGZGYCG.js → chunk-QYXDJOLA.js} +252 -6
  16. package/dist/{chunk-DVMLWQD4.js → chunk-SO5LKIWP.js} +2 -2
  17. package/dist/{chunk-VYXXOKYS.js → chunk-XKIW3QMF.js} +7 -4
  18. package/dist/{chunk-MAPZ7VB6.js → chunk-YVGXGTD6.js} +13 -0
  19. package/dist/{community-report-client-CU22W53K.js → community-report-client-6VJDDMJJ.js} +1 -1
  20. package/dist/{config-XO3LI3SA.js → config-XQWOPDHN.js} +25 -6
  21. package/dist/{context-IFJI3LIT.js → context-M3HDGEIR.js} +4 -4
  22. package/dist/{data-integration-HNGUKFIC.js → data-integration-XBTCGXQT.js} +6 -6
  23. package/dist/index.js +78 -41
  24. package/dist/{local-data-upload-client-GTRIT64F.js → local-data-upload-client-3P7NIVQ4.js} +1 -1
  25. package/dist/{memory-QGPSNCQS.js → memory-6APEB2JB.js} +4 -4
  26. package/dist/{metadata-DI5BMYFU.js → metadata-JRYKNUS5.js} +7 -7
  27. package/dist/{model-RNPQXIBI.js → model-ZS7HVGKN.js} +4 -4
  28. package/dist/{personal-semantic-preference-5C3WUXFI.js → personal-semantic-preference-IDE2GE5T.js} +8 -6
  29. package/dist/project-semantic-36KOCYN7.js +356 -0
  30. package/dist/{sync-O45NXEQY.js → sync-EQLSTUS7.js} +7 -7
  31. package/dist/{te-agent-K5MSPNHJ.js → te-agent-Z3HCTKR7.js} +348 -55
  32. package/dist/{te-analysis-AISWCOOZ.js → te-analysis-5ZZ6YHVH.js} +940 -144
  33. package/dist/{te-community-4OYU3BDA.js → te-community-Z7JACGF3.js} +3 -3
  34. package/dist/{te-dataops-NFIPB6FX.js → te-dataops-F7GQOIS6.js} +644 -276
  35. package/dist/{te-engage-BAM3GBFX.js → te-engage-RNRMYDO3.js} +6 -6
  36. package/dist/{te-experiment-GUTZXZ5Z.js → te-experiment-BTAC2UNK.js} +6 -6
  37. package/dist/{te-kb-3TS73NO6.js → te-kb-QJLJEX5K.js} +323 -181
  38. package/dist/{te-system-STMHLS5J.js → te-system-IXC43QHZ.js} +6 -6
  39. package/dist/{te-team-3I5AOX3N.js → te-team-BIZIKIHZ.js} +6 -6
  40. package/dist/{update-RZXLPCRH.js → update-W2SGQNKT.js} +4 -4
  41. package/package.json +11 -4
  42. package/skills/ae-agent/SKILL.md +9 -4
  43. package/skills/ae-agent/references/notification.md +40 -0
  44. package/skills/ae-analysis/SKILL.md +44 -21
  45. package/skills/ae-analysis/references/adhoc_export.md +1 -1
  46. package/skills/ae-analysis/references/adhoc_run.md +1 -1
  47. package/skills/ae-analysis/references/agent_review_submit_to_page.md +3 -1
  48. package/skills/ae-analysis/references/ai_models/event.md +6 -1
  49. package/skills/ae-analysis/references/ai_models/funnel.md +7 -1
  50. package/skills/ae-analysis/references/ai_models/heat_map.md +23 -0
  51. package/skills/ae-analysis/references/ai_models/interval.md +24 -0
  52. package/skills/ae-analysis/references/ai_models/path.md +20 -0
  53. package/skills/ae-analysis/references/ai_models/prop_analysis.md +2 -0
  54. package/skills/ae-analysis/references/ai_models/rank_list.md +30 -0
  55. package/skills/ae-analysis/references/ai_models/retention.md +45 -1
  56. package/skills/ae-analysis/references/ai_models/revenue.md +20 -2
  57. package/skills/ae-analysis/references/ai_models/session.md +76 -0
  58. package/skills/ae-analysis/references/ai_models/tag.md +2 -0
  59. package/skills/ae-analysis/references/ai_models.md +76 -6
  60. package/skills/ae-analysis/references/analysis_data_retrieval.md +4 -0
  61. package/skills/ae-analysis/references/analysis_drilldown_contract.md +4 -1
  62. package/skills/ae-analysis/references/asset_batch_info_export.md +10 -0
  63. package/skills/ae-analysis/references/asset_batch_sql_export.md +13 -1
  64. package/skills/ae-analysis/references/asset_export.md +12 -1
  65. package/skills/ae-analysis/references/asset_list.md +1 -0
  66. package/skills/ae-analysis/references/asset_search.md +11 -5
  67. package/skills/ae-analysis/references/bi_panel_list.md +1 -1
  68. package/skills/ae-analysis/references/catalog_list.md +1 -1
  69. package/skills/ae-analysis/references/collaboration.md +48 -0
  70. package/skills/ae-analysis/references/command_index.md +19 -17
  71. package/skills/ae-analysis/references/dashboard_list.md +4 -4
  72. package/skills/ae-analysis/references/dashboard_report_data_export.md +2 -0
  73. package/skills/ae-analysis/references/drilldown_session_details_run.md +41 -0
  74. package/skills/ae-analysis/references/event_export.md +3 -1
  75. package/skills/ae-analysis/references/governance_recommendation_auto_review.md +77 -0
  76. package/skills/ae-analysis/references/governance_recommendation_export.md +11 -0
  77. package/skills/ae-analysis/references/metadata_resolution.md +3 -3
  78. package/skills/ae-analysis/references/metric_export.md +3 -1
  79. package/skills/ae-analysis/references/metric_list.md +1 -1
  80. package/skills/ae-analysis/references/operation_record_export.md +10 -0
  81. package/skills/ae-analysis/references/personal_semantic_preference_add.md +2 -2
  82. package/skills/ae-analysis/references/personal_semantic_preference_get.md +4 -4
  83. package/skills/ae-analysis/references/personal_semantic_preference_list.md +4 -4
  84. package/skills/ae-analysis/references/project_semantic_knowledge_wiki.md +30 -12
  85. package/skills/ae-analysis/references/project_semantic_knowledge_wiki_plan_schema.md +59 -0
  86. package/skills/ae-analysis/references/property_export.md +3 -1
  87. package/skills/ae-analysis/references/report_create.md +5 -1
  88. package/skills/ae-analysis/references/report_data_export.md +6 -0
  89. package/skills/ae-analysis/references/report_get.md +2 -0
  90. package/skills/ae-analysis/references/report_list.md +5 -5
  91. package/skills/ae-analysis/references/report_update.md +7 -1
  92. package/skills/ae-analysis/references/sql_table_columns.md +4 -4
  93. package/skills/ae-analysis/references/sql_table_list.md +5 -5
  94. package/skills/ae-analysis/references/user_cluster_models.md +8 -0
  95. package/skills/ae-analysis/references/user_tag_create.md +7 -1
  96. package/skills/ae-analysis/references/user_tag_get.md +1 -1
  97. package/skills/ae-analysis/references/user_tag_models.md +18 -2
  98. package/skills/ae-analysis/references/user_tag_refresh.md +1 -1
  99. package/skills/ae-analysis/references/user_tag_update.md +2 -2
  100. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/build-project-semantic-wiki.mjs +337 -12
  101. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/default-compile-rules.md +8 -3
  102. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/generate-build-ir.mjs +284 -24
  103. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/package-wiki-source-zip.mjs +185 -22
  104. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/precompiled-source.mjs +46 -2
  105. package/skills/ae-capability/SKILL.md +63 -1
  106. package/skills/ae-capability/references/collaboration.md +48 -0
  107. package/skills/ae-community/SKILL.md +5 -1
  108. package/skills/ae-community/references/collaboration.md +48 -0
  109. package/skills/ae-data-integration/SKILL.md +4 -0
  110. package/skills/ae-data-integration/references/collaboration.md +48 -0
  111. package/skills/ae-data-integration-helper/references/cpp_server_sdk_faq.md +2 -2
  112. package/skills/ae-data-integration-helper/references/logbus2_parser_plugin.md +6 -6
  113. package/skills/ae-data-integration-helper/references/sdk_log_guide.md +4 -4
  114. package/skills/ae-dataops/SKILL.md +54 -74
  115. package/skills/ae-dataops/references/collaboration.md +48 -0
  116. package/skills/ae-dataops/references/dataops-backfill.md +23 -18
  117. package/skills/ae-dataops/references/dataops-flow-create.md +74 -23
  118. package/skills/ae-dataops/references/dataops-flow-monitor.md +45 -13
  119. package/skills/ae-dataops/references/dataops-integration.md +57 -30
  120. package/skills/ae-dataops/references/dataops-query.md +21 -4
  121. package/skills/ae-dataops/references/dataops-table.md +143 -11
  122. package/skills/ae-engage/SKILL.md +21 -6
  123. package/skills/ae-engage/references/add-channel.md +3 -3
  124. package/skills/ae-engage/references/channel-mgmt.md +3 -3
  125. package/skills/ae-engage/references/collaboration.md +48 -0
  126. package/skills/ae-engage/references/common-metric.md +2 -2
  127. package/skills/ae-engage/references/save-task.md +2 -2
  128. package/skills/ae-engage/references/scene-config-channel.md +4 -4
  129. package/skills/ae-generate-tracking-code/SKILL.md +1 -1
  130. package/skills/ae-generate-tracking-plan/SKILL.md +4 -0
  131. package/skills/ae-generate-tracking-plan/references/collaboration.md +48 -0
  132. package/skills/ae-kb/SKILL.md +9 -1
  133. package/skills/ae-kb/references/collaboration.md +48 -0
  134. package/skills/ae-kb/references/schema-import.md +30 -0
  135. package/skills/ae-kb-discovery/SKILL.md +7 -2
  136. package/skills/ae-kb-discovery/references/collaboration.md +48 -0
  137. package/skills/ae-metadata/SKILL.md +20 -12
  138. package/skills/ae-metadata/references/collaboration.md +48 -0
  139. package/dist/project-semantic-3LF6Q6JZ.js +0 -1119
  140. package/skills/ae-project-semantic/SKILL.md +0 -193
  141. package/skills/ae-project-semantic/references/query-routing-v5.md +0 -165
  142. package/skills/ae-project-semantic/references/recommendation-quality.md +0 -68
@@ -6,11 +6,11 @@ import {
6
6
  normalizeUrl,
7
7
  safeJsonParse,
8
8
  safeReadJsonFile
9
- } from "./chunk-7FTTULED.js";
9
+ } from "./chunk-IG3DYEIR.js";
10
10
  import {
11
11
  PermissionError,
12
12
  logger
13
- } from "./chunk-MAPZ7VB6.js";
13
+ } from "./chunk-YVGXGTD6.js";
14
14
 
15
15
  // src/core/secure-store.ts
16
16
  import crypto from "crypto";
@@ -28,7 +28,7 @@ var NONCE_LEN = 12;
28
28
  function getMachineId() {
29
29
  if (process.platform === "darwin") {
30
30
  try {
31
- const out = execFileSync("ioreg", ["-rd1", "-c", "IOPlatformExpertDevice"], {
31
+ const out = execFileSync("/usr/sbin/ioreg", ["-rd1", "-c", "IOPlatformExpertDevice"], {
32
32
  encoding: "utf8",
33
33
  timeout: 3e3
34
34
  });
@@ -47,36 +47,42 @@ function getMachineId() {
47
47
  }
48
48
  }
49
49
  if (process.platform === "win32") {
50
- try {
51
- const out = execFileSync(
52
- "reg",
53
- ["query", "HKLM\\SOFTWARE\\Microsoft\\Cryptography", "/v", "MachineGuid"],
54
- { encoding: "utf8", timeout: 3e3 }
55
- );
56
- const match = out.match(/MachineGuid\s+REG_SZ\s+([0-9a-f-]+)/i);
57
- if (match?.[1]) return `win32:${match[1]}`;
58
- } catch {
50
+ const systemRoot = process.env.SystemRoot || process.env.WINDIR;
51
+ const commands = systemRoot && path.win32.isAbsolute(systemRoot) ? [path.win32.join(systemRoot, "System32", "reg.exe"), "reg"] : ["reg"];
52
+ for (const command of commands) {
53
+ try {
54
+ const out = execFileSync(
55
+ command,
56
+ ["query", "HKLM\\SOFTWARE\\Microsoft\\Cryptography", "/v", "MachineGuid"],
57
+ { encoding: "utf8", timeout: 3e3 }
58
+ );
59
+ const match = out.match(/MachineGuid\s+REG_SZ\s+([0-9a-f-]+)/i);
60
+ if (match?.[1]) return `win32:${match[1]}`;
61
+ } catch {
62
+ }
59
63
  }
60
64
  }
61
65
  logger.warn("secure-store: using fallback machine-id (HOME+hostname+platform)");
66
+ return getFallbackMachineId();
67
+ }
68
+ function getFallbackMachineId() {
62
69
  return `fallback:${os.homedir()}|${os.hostname()}|${os.platform()}`;
63
70
  }
64
- var cachedMachineId;
65
- var cachedKey;
66
- function getKey() {
67
- if (!cachedMachineId) cachedMachineId = getMachineId();
68
- if (!cachedKey) {
69
- cachedKey = crypto.scryptSync(cachedMachineId, SCRYPT_SALT, KEY_LEN, {
71
+ var cachedKeys;
72
+ function getKeys() {
73
+ if (!cachedKeys) {
74
+ const machineIds = [.../* @__PURE__ */ new Set([getMachineId(), getFallbackMachineId()])];
75
+ cachedKeys = machineIds.map((machineId) => crypto.scryptSync(machineId, SCRYPT_SALT, KEY_LEN, {
70
76
  N: SCRYPT_N,
71
77
  r: SCRYPT_R,
72
78
  p: SCRYPT_P
73
- });
79
+ }));
74
80
  }
75
- return cachedKey;
81
+ return cachedKeys;
76
82
  }
77
- function encrypt(plaintext) {
83
+ function encrypt(plaintext, key) {
78
84
  const nonce = crypto.randomBytes(NONCE_LEN);
79
- const cipher = crypto.createCipheriv("aes-256-gcm", getKey(), nonce);
85
+ const cipher = crypto.createCipheriv("aes-256-gcm", key, nonce);
80
86
  const data = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
81
87
  return {
82
88
  nonce: nonce.toString("hex"),
@@ -84,8 +90,8 @@ function encrypt(plaintext) {
84
90
  data: data.toString("hex")
85
91
  };
86
92
  }
87
- function decrypt(blob) {
88
- const decipher = crypto.createDecipheriv("aes-256-gcm", getKey(), Buffer.from(blob.nonce, "hex"));
93
+ function decrypt(blob, key) {
94
+ const decipher = crypto.createDecipheriv("aes-256-gcm", key, Buffer.from(blob.nonce, "hex"));
89
95
  decipher.setAuthTag(Buffer.from(blob.tag, "hex"));
90
96
  return Buffer.concat([
91
97
  decipher.update(Buffer.from(blob.data, "hex")),
@@ -112,41 +118,81 @@ function ensureStoreDir() {
112
118
  } catch {
113
119
  }
114
120
  }
115
- function atomicWriteEncrypted(filePath, value) {
121
+ function stageFile(filePath, contents) {
116
122
  ensureStoreDir();
117
123
  const tempPath = `${filePath}.${process.pid}.${crypto.randomBytes(6).toString("hex")}.tmp`;
118
- const blob = encrypt(JSON.stringify(value));
119
124
  try {
120
- fs.writeFileSync(tempPath, JSON.stringify(blob, null, 2), { encoding: "utf8", mode: 384 });
125
+ fs.writeFileSync(tempPath, contents, { encoding: "utf8", mode: 384, flag: "wx" });
121
126
  try {
122
127
  fs.chmodSync(tempPath, 384);
123
128
  } catch {
124
129
  }
125
- fs.renameSync(tempPath, filePath);
126
- try {
127
- fs.chmodSync(filePath, 384);
128
- } catch {
129
- }
130
+ return tempPath;
131
+ } catch (error) {
132
+ removeFile(tempPath);
133
+ throw error;
134
+ }
135
+ }
136
+ function prepareEncrypted(filePath, value, companionPath) {
137
+ const existing = readEncryptedFile(filePath);
138
+ const companion = companionPath ? readEncryptedFile(companionPath) : null;
139
+ const key = existing?.key ?? companion?.key ?? getKeys()[0];
140
+ const blob = encrypt(JSON.stringify(value), key);
141
+ return { tempPath: stageFile(filePath, JSON.stringify(blob, null, 2)), previous: existing?.raw ?? null };
142
+ }
143
+ function replaceFile(tempPath, filePath) {
144
+ fs.renameSync(tempPath, filePath);
145
+ try {
146
+ fs.chmodSync(filePath, 384);
147
+ } catch {
148
+ }
149
+ }
150
+ function atomicWriteEncrypted(filePath, value, companionPath) {
151
+ const { tempPath } = prepareEncrypted(filePath, value, companionPath);
152
+ try {
153
+ replaceFile(tempPath, filePath);
130
154
  } finally {
131
- try {
132
- fs.rmSync(tempPath, { force: true });
133
- } catch {
155
+ removeFile(tempPath);
156
+ }
157
+ }
158
+ function readEncryptedFile(filePath) {
159
+ let raw;
160
+ try {
161
+ raw = fs.readFileSync(filePath, "utf8");
162
+ } catch (error) {
163
+ if (error.code === "ENOENT") {
164
+ try {
165
+ if (!fs.lstatSync(filePath, { throwIfNoEntry: false })) return null;
166
+ } catch {
167
+ }
134
168
  }
169
+ throw new CredentialStoreUnreadableError(filePath);
135
170
  }
171
+ return decodeEncryptedFile(filePath, raw);
136
172
  }
137
- function readEncrypted(filePath, label) {
138
- if (!fs.existsSync(filePath)) return null;
173
+ function decodeEncryptedFile(filePath, raw) {
139
174
  try {
140
- const blob = safeJsonParse(fs.readFileSync(filePath, "utf8"));
141
- if (!blob?.nonce || !blob?.tag || !blob?.data) {
142
- logger.warn(`secure-store: malformed ${label}`);
143
- return null;
175
+ const blob = safeJsonParse(raw);
176
+ if (typeof blob?.nonce !== "string" || !/^[0-9a-f]{24}$/i.test(blob.nonce) || typeof blob?.tag !== "string" || !/^[0-9a-f]{32}$/i.test(blob.tag) || typeof blob?.data !== "string" || !/^(?:[0-9a-f]{2})+$/i.test(blob.data)) {
177
+ throw new Error("Malformed encrypted credential");
144
178
  }
145
- return safeJsonParse(decrypt(blob));
146
- } catch (error) {
147
- logger.error(`secure-store: decrypt failed for ${label}: ${error.message}`);
148
- return null;
179
+ for (const key of getKeys()) {
180
+ try {
181
+ return { value: safeJsonParse(decrypt(blob, key)), key, raw };
182
+ } catch {
183
+ }
184
+ }
185
+ } catch {
186
+ }
187
+ throw new CredentialStoreUnreadableError(filePath);
188
+ }
189
+ function readEncrypted(filePath) {
190
+ const result = readEncryptedFile(filePath);
191
+ if (!result) return null;
192
+ if (!result.value || typeof result.value !== "object" || Array.isArray(result.value)) {
193
+ throw new CredentialStoreUnreadableError(filePath);
149
194
  }
195
+ return result.value;
150
196
  }
151
197
  function tokenFingerprint(token) {
152
198
  return crypto.createHash("sha256").update(token).digest("hex").slice(0, 24);
@@ -162,23 +208,139 @@ function legacyProjectionPayload(cliToken) {
162
208
  cliToken
163
209
  };
164
210
  }
165
- function writeLegacyProjection(host, credential) {
166
- atomicWriteEncrypted(legacyFilePath(host), legacyProjectionPayload(credential.cliToken));
167
- return {
168
- credentialId: credential.id,
169
- tokenFingerprint: tokenFingerprint(credential.cliToken)
170
- };
211
+ var activeWrites = /* @__PURE__ */ new Set();
212
+ function recoveryFilePath(host) {
213
+ return `${vaultFilePath(host)}.rollback`;
214
+ }
215
+ function restoreFile(filePath, previous) {
216
+ let current;
217
+ try {
218
+ current = fs.readFileSync(filePath, "utf8");
219
+ } catch (error) {
220
+ if (error.code !== "ENOENT") throw error;
221
+ current = null;
222
+ }
223
+ if (current === previous) return;
224
+ if (previous === null) {
225
+ fs.rmSync(filePath, { force: true });
226
+ return;
227
+ }
228
+ const tempPath = stageFile(filePath, previous);
229
+ try {
230
+ replaceFile(tempPath, filePath);
231
+ } finally {
232
+ removeFile(tempPath);
233
+ }
234
+ }
235
+ function restoreCredentialWrite(host, recovery) {
236
+ restoreFile(legacyFilePath(host), recovery.legacy);
237
+ restoreFile(vaultFilePath(host), recovery.vault);
238
+ for (const name of [recovery.legacyTemp, recovery.vaultTemp]) {
239
+ fs.rmSync(path.join(storeDir(), name), { force: true });
240
+ }
241
+ fs.unlinkSync(recoveryFilePath(host));
242
+ }
243
+ function isRecoveryTemp(name, destination, pid) {
244
+ const prefix = `${path.basename(destination)}.${pid}.`;
245
+ return typeof name === "string" && name.startsWith(prefix) && /^[0-9a-f]{12}\.tmp$/.test(name.slice(prefix.length));
246
+ }
247
+ function recoverCredentialWrite(host) {
248
+ const filePath = recoveryFilePath(host);
249
+ let raw;
250
+ try {
251
+ raw = fs.readFileSync(filePath, "utf8");
252
+ } catch (error) {
253
+ if (error.code === "ENOENT") {
254
+ try {
255
+ if (!fs.lstatSync(filePath, { throwIfNoEntry: false })) return;
256
+ } catch {
257
+ }
258
+ }
259
+ throw new CredentialStoreUnreadableError(filePath);
260
+ }
261
+ try {
262
+ const recovery = safeJsonParse(raw);
263
+ if (recovery?.version !== 1 || !Number.isSafeInteger(recovery.pid) || recovery.pid <= 0 || !(recovery.legacy === null || typeof recovery.legacy === "string") || !(recovery.vault === null || typeof recovery.vault === "string") || !isRecoveryTemp(recovery.legacyTemp, legacyFilePath(host), recovery.pid) || !isRecoveryTemp(recovery.vaultTemp, vaultFilePath(host), recovery.pid) || activeWrites.has(filePath)) throw new Error("Invalid or active credential recovery");
264
+ if (recovery.pid !== process.pid) {
265
+ let ownerExited = false;
266
+ try {
267
+ process.kill(recovery.pid, 0);
268
+ } catch (error) {
269
+ ownerExited = error.code === "ESRCH";
270
+ }
271
+ if (!ownerExited) throw new Error("Credential writer is still running");
272
+ }
273
+ if (recovery.legacy !== null) decodeEncryptedFile(legacyFilePath(host), recovery.legacy);
274
+ if (recovery.vault !== null) decodeEncryptedFile(vaultFilePath(host), recovery.vault);
275
+ restoreCredentialWrite(host, recovery);
276
+ } catch {
277
+ throw new CredentialStoreUnreadableError(filePath);
278
+ }
279
+ }
280
+ function writeVaultAndProjection(host, vault) {
281
+ const active = vault.credentials.find((entry) => entry.id === vault.activeCredentialId);
282
+ vault.legacyProjection = { credentialId: active.id, tokenFingerprint: tokenFingerprint(active.cliToken) };
283
+ const legacyPath = legacyFilePath(host);
284
+ const vaultPath = vaultFilePath(host);
285
+ const recoveryPath = recoveryFilePath(host);
286
+ const staged = [];
287
+ try {
288
+ const legacy = prepareEncrypted(legacyPath, legacyProjectionPayload(active.cliToken), vaultPath);
289
+ staged.push(legacy.tempPath);
290
+ const nextVault = prepareEncrypted(vaultPath, vault, legacyPath);
291
+ staged.push(nextVault.tempPath);
292
+ const recovery = {
293
+ version: 1,
294
+ pid: process.pid,
295
+ legacy: legacy.previous,
296
+ vault: nextVault.previous,
297
+ legacyTemp: path.basename(legacy.tempPath),
298
+ vaultTemp: path.basename(nextVault.tempPath)
299
+ };
300
+ const fd = fs.openSync(recoveryPath, "wx", 384);
301
+ try {
302
+ try {
303
+ fs.writeFileSync(fd, JSON.stringify(recovery), "utf8");
304
+ fs.fsyncSync(fd);
305
+ } finally {
306
+ fs.closeSync(fd);
307
+ }
308
+ } catch (error) {
309
+ removeFile(recoveryPath);
310
+ throw error;
311
+ }
312
+ activeWrites.add(recoveryPath);
313
+ try {
314
+ replaceFile(legacy.tempPath, legacyPath);
315
+ replaceFile(nextVault.tempPath, vaultPath);
316
+ fs.unlinkSync(recoveryPath);
317
+ } catch (error) {
318
+ try {
319
+ restoreCredentialWrite(host, recovery);
320
+ } catch {
321
+ throw new CredentialStoreUnreadableError(recoveryPath);
322
+ }
323
+ throw error;
324
+ } finally {
325
+ activeWrites.delete(recoveryPath);
326
+ }
327
+ } finally {
328
+ for (const tempPath of staged) removeFile(tempPath);
329
+ }
171
330
  }
172
331
  function readVaultRaw(host) {
173
332
  const normalizedHost = normalizeUrl(host);
174
- const vault = readEncrypted(vaultFilePath(normalizedHost), `${normalizedHost} account vault`);
175
- if (!vault || vault.version !== 1 || !Array.isArray(vault.credentials)) return null;
176
- const credentials = vault.credentials.filter((entry) => entry?.id && entry?.cliToken);
177
- if (credentials.length === 0 || !credentials.some((entry) => entry.id === vault.activeCredentialId)) return null;
178
- return { ...vault, host: normalizedHost, credentials };
333
+ recoverCredentialWrite(normalizedHost);
334
+ const filePath = vaultFilePath(normalizedHost);
335
+ const vault = readEncrypted(filePath);
336
+ if (!vault) return null;
337
+ if (vault.version !== 1 || !Array.isArray(vault.credentials) || vault.credentials.length === 0 || !vault.credentials.every((entry) => typeof entry?.id === "string" && entry.id && typeof entry.cliToken === "string" && entry.cliToken.trim()) || !vault.credentials.some((entry) => entry.id === vault.activeCredentialId) || vault.legacyProjection !== void 0 && (!vault.legacyProjection || typeof vault.legacyProjection.credentialId !== "string" || typeof vault.legacyProjection.tokenFingerprint !== "string")) {
338
+ throw new CredentialStoreUnreadableError(filePath);
339
+ }
340
+ return { ...vault, host: normalizedHost };
179
341
  }
180
342
  function writeVault(host, vault) {
181
- atomicWriteEncrypted(vaultFilePath(host), vault);
343
+ atomicWriteEncrypted(vaultFilePath(host), vault, legacyFilePath(host));
182
344
  }
183
345
  function removeFile(filePath) {
184
346
  try {
@@ -187,12 +349,23 @@ function removeFile(filePath) {
187
349
  }
188
350
  }
189
351
  function load(host) {
190
- return readEncrypted(legacyFilePath(host), normalizeUrl(host));
352
+ recoverCredentialWrite(host);
353
+ const filePath = legacyFilePath(host);
354
+ const payload = readEncrypted(filePath);
355
+ if (payload && (typeof payload.accessToken !== "string" || typeof payload.refreshToken !== "string" || typeof payload.accessExpiresAt !== "string" || payload.cliToken !== void 0 && typeof payload.cliToken !== "string")) {
356
+ throw new CredentialStoreUnreadableError(filePath);
357
+ }
358
+ return payload;
359
+ }
360
+ function assertCredentialsReadable(host) {
361
+ readVaultRaw(host);
362
+ load(host);
191
363
  }
192
364
  function loadCredentialVault(host) {
193
365
  const normalizedHost = normalizeUrl(host);
194
366
  let vault = readVaultRaw(normalizedHost);
195
- const legacyToken = load(normalizedHost)?.cliToken?.trim();
367
+ const legacy = load(normalizedHost);
368
+ const legacyToken = legacy?.cliToken?.trim();
196
369
  if (!vault) {
197
370
  if (!legacyToken) return null;
198
371
  const imported = { id: credentialId(legacyToken), cliToken: legacyToken };
@@ -228,7 +401,7 @@ function loadCredentialVault(host) {
228
401
  if (changed) writeVault(normalizedHost, vault);
229
402
  return vault;
230
403
  }
231
- if (vault.legacyProjection) {
404
+ if (vault.legacyProjection && !legacy) {
232
405
  const projection = vault.legacyProjection;
233
406
  const projected = vault.credentials.find((entry) => entry.id === projection.credentialId && tokenFingerprint(entry.cliToken) === projection.tokenFingerprint);
234
407
  if (projected) {
@@ -244,9 +417,7 @@ function loadCredentialVault(host) {
244
417
  vault.activeCredentialId = vault.credentials[0].id;
245
418
  }
246
419
  }
247
- const active = vault.credentials.find((entry) => entry.id === vault.activeCredentialId);
248
- vault.legacyProjection = writeLegacyProjection(normalizedHost, active);
249
- writeVault(normalizedHost, vault);
420
+ writeVaultAndProjection(normalizedHost, vault);
250
421
  return vault;
251
422
  }
252
423
  function getActiveCredential(host) {
@@ -261,7 +432,7 @@ function saveCredential(host, credential, options = {}) {
261
432
  const existingVault = loadCredentialVault(normalizedHost);
262
433
  if (options.add && !credential.account) {
263
434
  throw new SecureStoreAuthError(
264
- `This host does not return account identity from CLI token validation. Upgrade the server before using auth login --add for ${normalizedHost}.`
435
+ `This host does not return account identity from CLI token validation. Upgrade the server before adding another account for ${normalizedHost}.`
265
436
  );
266
437
  }
267
438
  const sameAccount = credential.account ? existingVault?.credentials.find((entry) => entry.account?.openId === credential.account.openId || entry.account?.loginName === credential.account.loginName) : void 0;
@@ -277,13 +448,11 @@ function saveCredential(host, credential, options = {}) {
277
448
  } else {
278
449
  credentials = [saved];
279
450
  }
280
- const legacyProjection = writeLegacyProjection(normalizedHost, saved);
281
- writeVault(normalizedHost, {
451
+ writeVaultAndProjection(normalizedHost, {
282
452
  version: 1,
283
453
  host: normalizedHost,
284
454
  activeCredentialId: saved.id,
285
- credentials,
286
- legacyProjection
455
+ credentials
287
456
  });
288
457
  logger.info(`secure-store: saved CLI credential for ${normalizedHost}`);
289
458
  return saved;
@@ -322,8 +491,7 @@ function activateCredential(host, account) {
322
491
  }
323
492
  const selected = matches[0];
324
493
  vault.activeCredentialId = selected.id;
325
- vault.legacyProjection = writeLegacyProjection(normalizedHost, selected);
326
- writeVault(normalizedHost, vault);
494
+ writeVaultAndProjection(normalizedHost, vault);
327
495
  return selected;
328
496
  }
329
497
  function removeActiveCredential(host) {
@@ -339,12 +507,12 @@ function removeActiveCredential(host) {
339
507
  }
340
508
  const active = vault.credentials[0];
341
509
  vault.activeCredentialId = active.id;
342
- vault.legacyProjection = writeLegacyProjection(normalizedHost, active);
343
- writeVault(normalizedHost, vault);
510
+ writeVaultAndProjection(normalizedHost, vault);
344
511
  return { removed, active };
345
512
  }
346
513
  function clearAllCredentials(host) {
347
514
  const normalizedHost = normalizeUrl(host);
515
+ recoverCredentialWrite(normalizedHost);
348
516
  removeFile(legacyFilePath(normalizedHost));
349
517
  removeFile(vaultFilePath(normalizedHost));
350
518
  logger.info(`secure-store: all CLI credentials cleared for ${normalizedHost}`);
@@ -358,6 +526,14 @@ var SecureStoreAuthError = class extends Error {
358
526
  this.name = "SecureStoreAuthError";
359
527
  }
360
528
  };
529
+ var CredentialStoreUnreadableError = class extends Error {
530
+ code = "CREDENTIAL_STORE_UNREADABLE";
531
+ hint = "Keep the existing credential files. Retry in the original OS user and runtime with access to the machine identifier and credential directory. Do not log in again, replace tokens, or log out to fix a local credential read failure.";
532
+ constructor(filePath) {
533
+ super(`Cannot read or decrypt the existing credential file: ${filePath}`);
534
+ this.name = "CredentialStoreUnreadableError";
535
+ }
536
+ };
361
537
 
362
538
  // src/core/cli-token.ts
363
539
  import crypto2 from "crypto";
@@ -377,6 +553,15 @@ function isExplicitCliTokenRejection(data, responseText) {
377
553
  const message = String(data?.return_message ?? data?.message ?? data?.error?.message ?? responseText);
378
554
  return /cli[_-]?token[_-]?(invalid|expired)/i.test(code) || /cli[-_\s]?token.*\b(invalid|expired)\b/i.test(message) || /\b(invalid|expired)\b.*cli[-_\s]?token/i.test(message);
379
555
  }
556
+ function cliAccessDisabledDetails(data, responseText) {
557
+ const code = String(data?.code ?? data?.error?.code ?? "");
558
+ const message = String(data?.return_message ?? data?.message ?? data?.error?.message ?? responseText);
559
+ if (code !== "CLI_ACCESS_DISABLED" && !message.includes("CLI_ACCESS_DISABLED")) return void 0;
560
+ return {
561
+ message: message || "CLI access is disabled for this account.",
562
+ hint: data?.hint ?? data?.error?.hint
563
+ };
564
+ }
380
565
  function optionalNonEmptyString(...values) {
381
566
  return values.find((value) => typeof value === "string" && value.trim());
382
567
  }
@@ -511,10 +696,12 @@ async function validateCliTokenOnServer(hostUrl, cliToken) {
511
696
  } catch {
512
697
  body = void 0;
513
698
  }
699
+ const accessDisabled = cliAccessDisabledDetails(body, responseText);
700
+ if (accessDisabled) {
701
+ throw new PermissionError(accessDisabled.message, "CLI_ACCESS_DISABLED", accessDisabled.hint);
702
+ }
514
703
  if (isExplicitCliTokenRejection(body, responseText)) {
515
- throw new SecureStoreAuthError(
516
- `CLI token is invalid or expired for ${hostUrl}. Run: ae-cli auth logout --host ${hostUrl}, then ae-cli auth login --host ${hostUrl}`
517
- );
704
+ throw new SecureStoreAuthError(`CLI token is invalid or expired for ${hostUrl}.`);
518
705
  }
519
706
  if (!resp.ok) {
520
707
  throw new CliTokenValidationUnavailableError(
@@ -578,7 +765,13 @@ function peekCliToken(hostOverride) {
578
765
  const hostUrl = hostOverride || getActiveHost();
579
766
  if (!hostUrl) return void 0;
580
767
  const normalizedHost = normalizeUrl(hostUrl);
581
- const stored = loadCliToken(normalizedHost);
768
+ let stored;
769
+ try {
770
+ stored = loadCliToken(normalizedHost);
771
+ } catch (error) {
772
+ if (error instanceof CredentialStoreUnreadableError) return void 0;
773
+ throw error;
774
+ }
582
775
  if (stored) {
583
776
  cliTokenCache.set(normalizedHost, stored);
584
777
  return stored;
@@ -606,6 +799,7 @@ async function mintCliToken(hostUrl, accessToken) {
606
799
  }
607
800
 
608
801
  export {
802
+ assertCredentialsReadable,
609
803
  getActiveCredential,
610
804
  listCredentials,
611
805
  saveCredential,
@@ -614,6 +808,7 @@ export {
614
808
  removeActiveCredential,
615
809
  clearAllCredentials,
616
810
  SecureStoreAuthError,
811
+ CredentialStoreUnreadableError,
617
812
  CliTokenValidationUnavailableError,
618
813
  clearCliTokenCache,
619
814
  validateCliTokenOnServer,
@@ -2,7 +2,7 @@ import { createRequire as __createRequire } from 'node:module'; const require =
2
2
  import {
3
3
  __commonJS,
4
4
  __require
5
- } from "./chunk-MAPZ7VB6.js";
5
+ } from "./chunk-YVGXGTD6.js";
6
6
 
7
7
  // node_modules/process-nextick-args/index.js
8
8
  var require_process_nextick_args = __commonJS({
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
2
2
  import {
3
3
  logger
4
- } from "./chunk-MAPZ7VB6.js";
4
+ } from "./chunk-YVGXGTD6.js";
5
5
 
6
6
  // src/core/url-utils.ts
7
7
  function normalizeUrl(url) {
@@ -76,6 +76,9 @@ function isAeSandboxRuntime() {
76
76
  if (process.env.SANDBOX_RUNTIME_ROOT) {
77
77
  return true;
78
78
  }
79
+ if (process.platform !== "linux") {
80
+ return false;
81
+ }
79
82
  try {
80
83
  if (fs2.existsSync(getSandboxCliTokenFilePath())) {
81
84
  return true;
@@ -4,14 +4,14 @@ import {
4
4
  } from "./chunk-Y74WTIKJ.js";
5
5
  import {
6
6
  getCliToken
7
- } from "./chunk-7XGFSUOM.js";
7
+ } from "./chunk-DU72X2IO.js";
8
8
  import {
9
9
  getActiveHost,
10
10
  getSandboxRuntimeRoot
11
- } from "./chunk-7FTTULED.js";
11
+ } from "./chunk-IG3DYEIR.js";
12
12
  import {
13
13
  PermissionError
14
- } from "./chunk-MAPZ7VB6.js";
14
+ } from "./chunk-YVGXGTD6.js";
15
15
 
16
16
  // src/core/te-agent-credentials.ts
17
17
  import { readFileSync } from "fs";
@@ -1,20 +1,20 @@
1
1
  import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
2
2
  import {
3
3
  require_lib
4
- } from "./chunk-DVMLWQD4.js";
4
+ } from "./chunk-SO5LKIWP.js";
5
5
  import {
6
6
  require_archiver,
7
7
  require_string_decoder
8
- } from "./chunk-EQ255HKO.js";
8
+ } from "./chunk-7WZACOAI.js";
9
9
  import {
10
10
  require_inherits,
11
11
  require_node
12
- } from "./chunk-V2NUHPXF.js";
12
+ } from "./chunk-GK7WDY7E.js";
13
13
  import {
14
14
  __commonJS,
15
15
  __require,
16
16
  __toESM
17
- } from "./chunk-MAPZ7VB6.js";
17
+ } from "./chunk-YVGXGTD6.js";
18
18
 
19
19
  // node_modules/exceljs/lib/utils/under-dash.js
20
20
  var require_under_dash = __commonJS({
@@ -2,7 +2,7 @@ import { createRequire as __createRequire } from 'node:module'; const require =
2
2
  import {
3
3
  getActiveHost,
4
4
  normalizeUrl
5
- } from "./chunk-7FTTULED.js";
5
+ } from "./chunk-IG3DYEIR.js";
6
6
 
7
7
  // src/core/auth.ts
8
8
  function resolveHost(hostOverride) {