@hcmai/sdk 0.3.9 → 0.3.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1068,18 +1068,18 @@ async function action(http, model, actionName, input) {
1068
1068
  if (scope === "object" && !input.id) {
1069
1069
  throw new Error(`object action ${model}.${actionName} requires id`);
1070
1070
  }
1071
- const path12 = scope === "object" ? `/api/models/${model}/${input.id}/action/${actionName}` : `/api/models/${model}/action/${actionName}`;
1071
+ const path13 = scope === "object" ? `/api/models/${model}/${input.id}/action/${actionName}` : `/api/models/${model}/action/${actionName}`;
1072
1072
  const resp = await (async () => {
1073
1073
  if (method === "GET") {
1074
- return http.get(path12, { params: queryParams(input) });
1074
+ return http.get(path13, { params: queryParams(input) });
1075
1075
  }
1076
1076
  if (method === "DELETE") {
1077
- return http.delete(path12, { params: queryParams(input) });
1077
+ return http.delete(path13, { params: queryParams(input) });
1078
1078
  }
1079
1079
  if (method === "PUT") {
1080
- return http.put(path12, scope === "object" ? objectBody(input) : classBody(input));
1080
+ return http.put(path13, scope === "object" ? objectBody(input) : classBody(input));
1081
1081
  }
1082
- return http.post(path12, scope === "object" ? objectBody(input) : classBody(input));
1082
+ return http.post(path13, scope === "object" ? objectBody(input) : classBody(input));
1083
1083
  })();
1084
1084
  return resp.data;
1085
1085
  }
@@ -5035,18 +5035,18 @@ async function listTenantMeta(http, opts = {}) {
5035
5035
  const items = payload?.items ?? payload?.list ?? payload?.records ?? [];
5036
5036
  return { items, total: payload?.total, raw: payload };
5037
5037
  }
5038
- async function getTenantMeta(http, path12) {
5039
- const resp = await http.get("/api/tenant-meta/meta", { params: { path: path12 } });
5038
+ async function getTenantMeta(http, path13) {
5039
+ const resp = await http.get("/api/tenant-meta/meta", { params: { path: path13 } });
5040
5040
  const payload = resp.data?.data ?? resp.data;
5041
5041
  if (typeof payload === "string") return payload;
5042
5042
  return String(payload?.content ?? "");
5043
5043
  }
5044
- async function saveTenantMeta(http, path12, content) {
5045
- const resp = await http.put("/api/tenant-meta/meta", { content }, { params: { path: path12 } });
5044
+ async function saveTenantMeta(http, path13, content) {
5045
+ const resp = await http.put("/api/tenant-meta/meta", { content }, { params: { path: path13 } });
5046
5046
  return resp.data?.data ?? resp.data;
5047
5047
  }
5048
- async function deleteTenantMeta(http, path12) {
5049
- const resp = await http.delete("/api/tenant-meta/meta", { params: { path: path12 } });
5048
+ async function deleteTenantMeta(http, path13) {
5049
+ const resp = await http.delete("/api/tenant-meta/meta", { params: { path: path13 } });
5050
5050
  return resp.data?.data ?? resp.data;
5051
5051
  }
5052
5052
 
@@ -5148,14 +5148,14 @@ function resolveSkillInstallOrder(manifest2, targetId) {
5148
5148
  throw invalid(`\u6280\u80FD\u76EE\u5F55\u4E2D\u4E0D\u5B58\u5728 ${targetId}`);
5149
5149
  }
5150
5150
  const state = /* @__PURE__ */ new Map();
5151
- const path12 = [];
5151
+ const path13 = [];
5152
5152
  const order = [];
5153
5153
  const visit = (id, requiredBy) => {
5154
5154
  const current = state.get(id);
5155
5155
  if (current === "done") return;
5156
5156
  if (current === "visiting") {
5157
- const cycleStart = path12.indexOf(id);
5158
- const cycle = [...path12.slice(Math.max(0, cycleStart)), id];
5157
+ const cycleStart = path13.indexOf(id);
5158
+ const cycle = [...path13.slice(Math.max(0, cycleStart)), id];
5159
5159
  throw invalid(`\u6280\u80FD\u4F9D\u8D56\u5B58\u5728\u73AF: ${cycle.join(" -> ")}`);
5160
5160
  }
5161
5161
  const skill = byId.get(id);
@@ -5164,11 +5164,11 @@ function resolveSkillInstallOrder(manifest2, targetId) {
5164
5164
  }
5165
5165
  assertSafeSkillId(skill.id);
5166
5166
  state.set(id, "visiting");
5167
- path12.push(id);
5167
+ path13.push(id);
5168
5168
  for (const required of normalizeRequirements(skill.requires, skill.id)) {
5169
5169
  visit(required, skill.id);
5170
5170
  }
5171
- path12.pop();
5171
+ path13.pop();
5172
5172
  state.set(id, "done");
5173
5173
  order.push(skill);
5174
5174
  };
@@ -5259,11 +5259,11 @@ async function resetSettingItem(http, domain, namespace, settingKey, revision) {
5259
5259
  function parseSettingAssignment(raw) {
5260
5260
  const eq = raw.indexOf("=");
5261
5261
  if (eq <= 0) throw new Error(`--set \u9700\u8981 namespace.key=value \u5F62\u6001\uFF0C\u6536\u5230 "${raw}"`);
5262
- const path12 = raw.slice(0, eq).trim();
5262
+ const path13 = raw.slice(0, eq).trim();
5263
5263
  const value = raw.slice(eq + 1);
5264
- const dot = path12.lastIndexOf(".");
5265
- if (dot <= 0) throw new Error(`--set \u7684\u952E\u9700\u542B namespace\uFF0C\u5982 security.password.passwordPolicy=complex\uFF0C\u6536\u5230 "${path12}"`);
5266
- return { namespace: path12.slice(0, dot), settingKey: path12.slice(dot + 1), value };
5264
+ const dot = path13.lastIndexOf(".");
5265
+ if (dot <= 0) throw new Error(`--set \u7684\u952E\u9700\u542B namespace\uFF0C\u5982 security.password.passwordPolicy=complex\uFF0C\u6536\u5230 "${path13}"`);
5266
+ return { namespace: path13.slice(0, dot), settingKey: path13.slice(dot + 1), value };
5267
5267
  }
5268
5268
 
5269
5269
  // src/fde/layout.ts
@@ -5657,11 +5657,11 @@ function classifyStatus(status) {
5657
5657
  return "bad-response";
5658
5658
  }
5659
5659
  var CAPABILITIES_HEADER = "x-hcm-capabilities";
5660
- function buildUrl(path12, params) {
5660
+ function buildUrl(path13, params) {
5661
5661
  const entries = Object.entries(params ?? {}).filter(([, v]) => v !== void 0 && v !== null);
5662
- if (entries.length === 0) return path12;
5662
+ if (entries.length === 0) return path13;
5663
5663
  const qs = entries.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`).join("&");
5664
- return `${path12}${path12.includes("?") ? "&" : "?"}${qs}`;
5664
+ return `${path13}${path13.includes("?") ? "&" : "?"}${qs}`;
5665
5665
  }
5666
5666
  function lowerHeaders(raw) {
5667
5667
  const out = {};
@@ -5703,14 +5703,14 @@ function httpProbe(http, capabilities) {
5703
5703
  const headers = { [CAPABILITIES_HEADER]: capabilities };
5704
5704
  const probe = {
5705
5705
  capabilities,
5706
- get(path12, params) {
5706
+ get(path13, params) {
5707
5707
  return once(
5708
- () => http.get(buildUrl(path12, params), { headers, validateStatus: () => true })
5708
+ () => http.get(buildUrl(path13, params), { headers, validateStatus: () => true })
5709
5709
  );
5710
5710
  },
5711
- post(path12, body) {
5711
+ post(path13, body) {
5712
5712
  return once(
5713
- () => http.post(path12, body, {
5713
+ () => http.post(path13, body, {
5714
5714
  headers: { ...headers, "content-type": "application/json" },
5715
5715
  validateStatus: () => true
5716
5716
  })
@@ -5781,8 +5781,8 @@ function noteFor(error) {
5781
5781
  // src/fde/recon/crawl.ts
5782
5782
  var KIT_PREMISE_KEY = "_kitPremiseCheck";
5783
5783
  var DEFAULT_META_TYPE = "model";
5784
- function metaPath(modelKey, metaType = DEFAULT_META_TYPE) {
5785
- const base = `/api/models/${modelKey}/meta`;
5784
+ function metaPath(modelKey2, metaType = DEFAULT_META_TYPE) {
5785
+ const base = `/api/models/${modelKey2}/meta`;
5786
5786
  return metaType === DEFAULT_META_TYPE ? base : `${base}?type=${metaType}`;
5787
5787
  }
5788
5788
  function modelRows(body) {
@@ -5822,8 +5822,8 @@ async function crawlMeta(probe, modelKeys2, metaType = DEFAULT_META_TYPE) {
5822
5822
  const results = probe.getMany ? await probe.getMany([...paths.keys()]) : await sequentialGet(probe, [...paths.keys()]);
5823
5823
  const metas = {};
5824
5824
  const unavailable = [];
5825
- for (const [path12, key] of paths) {
5826
- const out = results[path12];
5825
+ for (const [path13, key] of paths) {
5826
+ const out = results[path13];
5827
5827
  if (out === void 0) {
5828
5828
  unavailable.push({
5829
5829
  modelKey: key,
@@ -5950,9 +5950,9 @@ function extractFieldRows(metas) {
5950
5950
  const rows = [];
5951
5951
  const dropped = [];
5952
5952
  for (const [model, body] of Object.entries(metas)) {
5953
- const { fields, problem } = metaFields(body);
5954
- if (problem) {
5955
- dropped.push(`${model}: ${problem}\uFF0C\u6574\u4E2A\u6A21\u578B\u6CA1\u6709\u5B57\u6BB5\u8FDB\u7D22\u5F15`);
5953
+ const { fields, problem: problem2 } = metaFields(body);
5954
+ if (problem2) {
5955
+ dropped.push(`${model}: ${problem2}\uFF0C\u6574\u4E2A\u6A21\u578B\u6CA1\u6709\u5B57\u6BB5\u8FDB\u7D22\u5F15`);
5956
5956
  continue;
5957
5957
  }
5958
5958
  fields.forEach((f, index) => {
@@ -6011,8 +6011,8 @@ var REJECT_NOTES = {
6011
6011
  "malformed-key": "\u52A8\u4F5C\u6CA1\u6709\u53EF\u7528\u7684 key \u2014\u2014 \u6CA1\u6709 key \u5C31\u65E0\u6CD5\u8C03\u7528\uFF0C\u4E5F\u65E0\u6CD5\u4E0E\u4EA7\u54C1\u4FA7\u5BF9\u8D26",
6012
6012
  "malformed-action": "\u52A8\u4F5C\u6761\u76EE\u4E0D\u662F\u5BF9\u8C61\uFF0C\u65E0\u6CD5\u5224\u8BFB\u5B83\u662F\u4E0D\u662F\u53EA\u8BFB\u95F8"
6013
6013
  };
6014
- function actionsPath(modelKey, state = "") {
6015
- const base = `/api/models/${modelKey}/actions`;
6014
+ function actionsPath(modelKey2, state = "") {
6015
+ const base = `/api/models/${modelKey2}/actions`;
6016
6016
  if (!state) return base;
6017
6017
  return `${base}?${new URLSearchParams({ state }).toString()}`;
6018
6018
  }
@@ -6039,8 +6039,8 @@ async function collectActionGates(probe, modelKeys2, state = "") {
6039
6039
  const statesEchoed = /* @__PURE__ */ new Set();
6040
6040
  let noStateEcho = 0;
6041
6041
  let answered = 0;
6042
- for (const [path12, model] of paths) {
6043
- const out = results[path12];
6042
+ for (const [path13, model] of paths) {
6043
+ const out = results[path13];
6044
6044
  if (out === void 0) {
6045
6045
  unavailable.push({
6046
6046
  modelKey: model,
@@ -6419,8 +6419,8 @@ async function collectMutation(probe, modelKeys2) {
6419
6419
  const results = probe.getMany ? await probe.getMany([...paths.keys()]) : await sequentialGet(probe, [...paths.keys()]);
6420
6420
  const mutation = {};
6421
6421
  const problems = [];
6422
- for (const [path12, key] of paths) {
6423
- const out = results[path12];
6422
+ for (const [path13, key] of paths) {
6423
+ const out = results[path13];
6424
6424
  if (out === void 0) {
6425
6425
  problems.push(`${key}: mutation-capability ${BATCH_LOST}`);
6426
6426
  mutation[key] = Object.fromEntries(
@@ -6490,15 +6490,15 @@ function buildMapping(metas, edges, mutation, codeTables = []) {
6490
6490
  const byField = /* @__PURE__ */ new Map();
6491
6491
  for (const e of edges) byField.set(`${e.fromModel} ${e.fromField}`, e);
6492
6492
  const sheets = [];
6493
- for (const modelKey of Object.keys(metas).sort()) {
6494
- const { fields, problem } = metaFields(metas[modelKey]);
6493
+ for (const modelKey2 of Object.keys(metas).sort()) {
6494
+ const { fields, problem: problem2 } = metaFields(metas[modelKey2]);
6495
6495
  const rows = [];
6496
6496
  for (const f of fields) {
6497
6497
  if (!isRecord2(f)) continue;
6498
6498
  const key = f.key;
6499
6499
  if (typeof key !== "string" || !key) continue;
6500
6500
  const { writable, reason } = writability(f);
6501
- const edge = byField.get(`${modelKey} ${key}`);
6501
+ const edge = byField.get(`${modelKey2} ${key}`);
6502
6502
  const ref = edge ? {
6503
6503
  toModel: edge.toModel,
6504
6504
  carrier: edge.carrier,
@@ -6533,15 +6533,15 @@ function buildMapping(metas, edges, mutation, codeTables = []) {
6533
6533
  });
6534
6534
  }
6535
6535
  sheets.push({
6536
- model: modelKey,
6536
+ model: modelKey2,
6537
6537
  // 「爬过且这个模型确实没有字段」必须与「没爬过」(文件不存在)区分开。
6538
6538
  crawled: true,
6539
6539
  wording: WORDING3,
6540
- mutation: mutationSection(isRecord2(mutation) ? mutation[modelKey] : mutation),
6540
+ mutation: mutationSection(isRecord2(mutation) ? mutation[modelKey2] : mutation),
6541
6541
  fieldCount: rows.length,
6542
6542
  // 🔴 `null` = 载荷判读正常(fieldCount=0 就是「这个模型确实没字段」);
6543
6543
  // 非 null = **爬过、但判不出字段**,此时 fieldCount=0 不代表「没字段」。
6544
- fieldsProblem: problem ?? null,
6544
+ fieldsProblem: problem2 ?? null,
6545
6545
  fields: rows
6546
6546
  });
6547
6547
  }
@@ -6553,14 +6553,14 @@ function allowedIn(sheet, op) {
6553
6553
  return isRecord2(cell) ? cell.allowed : "unknown";
6554
6554
  }
6555
6555
  var PATH_SEPARATORS = ["/", String.fromCharCode(92)];
6556
- function unsafeKeyReason(modelKey) {
6557
- if (typeof modelKey !== "string" || !modelKey) return `modelKey \u4E0D\u662F\u975E\u7A7A\u5B57\u7B26\u4E32\uFF08${JSON.stringify(modelKey)}\uFF09`;
6558
- if (PATH_SEPARATORS.some((s) => modelKey.includes(s))) {
6559
- return `modelKey \u542B\u8DEF\u5F84\u5206\u9694\u7B26\uFF0C\u4E0D\u80FD\u5F53\u6587\u4EF6\u540D\uFF1A${JSON.stringify(modelKey)}`;
6556
+ function unsafeKeyReason(modelKey2) {
6557
+ if (typeof modelKey2 !== "string" || !modelKey2) return `modelKey \u4E0D\u662F\u975E\u7A7A\u5B57\u7B26\u4E32\uFF08${JSON.stringify(modelKey2)}\uFF09`;
6558
+ if (PATH_SEPARATORS.some((s) => modelKey2.includes(s))) {
6559
+ return `modelKey \u542B\u8DEF\u5F84\u5206\u9694\u7B26\uFF0C\u4E0D\u80FD\u5F53\u6587\u4EF6\u540D\uFF1A${JSON.stringify(modelKey2)}`;
6560
6560
  }
6561
- if (modelKey === "." || modelKey === "..") return `modelKey \u6307\u5411\u76EE\u5F55\u672C\u8EAB\u6216\u4E0A\u7EA7\uFF1A${JSON.stringify(modelKey)}`;
6562
- if (modelKey.startsWith(".") || modelKey.startsWith("_")) {
6563
- return `modelKey \u4EE5 . \u6216 _ \u5F00\u5934\uFF0C\u4E0D\u80FD\u5F53\u6587\u4EF6\u540D\uFF1A${JSON.stringify(modelKey)} \u2014\u2014 \u524D\u8005\u4EA7\u51FA ls \u770B\u4E0D\u89C1\u7684\u9690\u85CF\u6587\u4EF6\u3001\u540E\u8005\u4F1A\u9876\u6389\u5DE5\u5177\u81EA\u5DF1\u7684 _index.json`;
6561
+ if (modelKey2 === "." || modelKey2 === "..") return `modelKey \u6307\u5411\u76EE\u5F55\u672C\u8EAB\u6216\u4E0A\u7EA7\uFF1A${JSON.stringify(modelKey2)}`;
6562
+ if (modelKey2.startsWith(".") || modelKey2.startsWith("_")) {
6563
+ return `modelKey \u4EE5 . \u6216 _ \u5F00\u5934\uFF0C\u4E0D\u80FD\u5F53\u6587\u4EF6\u540D\uFF1A${JSON.stringify(modelKey2)} \u2014\u2014 \u524D\u8005\u4EA7\u51FA ls \u770B\u4E0D\u89C1\u7684\u9690\u85CF\u6587\u4EF6\u3001\u540E\u8005\u4F1A\u9876\u6389\u5DE5\u5177\u81EA\u5DF1\u7684 _index.json`;
6564
6564
  }
6565
6565
  return null;
6566
6566
  }
@@ -6578,11 +6578,11 @@ function writeMapping(layout, sheets, opts = {}) {
6578
6578
  const written = [];
6579
6579
  const unsafe = [];
6580
6580
  for (const sheet of sheets) {
6581
- const modelKey = sheet.model;
6582
- let reason = unsafeKeyReason(modelKey);
6581
+ const modelKey2 = sheet.model;
6582
+ let reason = unsafeKeyReason(modelKey2);
6583
6583
  if (reason === null) {
6584
6584
  try {
6585
- written.push(layout.writeJson(`mapping/${modelKey}.json`, sheet));
6585
+ written.push(layout.writeJson(`mapping/${modelKey2}.json`, sheet));
6586
6586
  continue;
6587
6587
  } catch (err) {
6588
6588
  if (!(err instanceof LayoutContainmentError)) throw err;
@@ -6590,7 +6590,7 @@ function writeMapping(layout, sheets, opts = {}) {
6590
6590
  }
6591
6591
  }
6592
6592
  unsafe.push({
6593
- model: typeof modelKey === "string" ? modelKey : JSON.stringify(modelKey),
6593
+ model: typeof modelKey2 === "string" ? modelKey2 : JSON.stringify(modelKey2),
6594
6594
  reason,
6595
6595
  fieldCount: sheet.fieldCount
6596
6596
  });
@@ -6698,9 +6698,9 @@ function renderModelsMd(modelsBody, metas, gates, dropped = []) {
6698
6698
  if (!Object.prototype.hasOwnProperty.call(metas, key)) {
6699
6699
  parts.push(FIELDS_NOT_CRAWLED);
6700
6700
  } else {
6701
- const { fields, problem } = metaFields(metas[key]);
6701
+ const { fields, problem: problem2 } = metaFields(metas[key]);
6702
6702
  parts.push(
6703
- problem === void 0 ? `- \u5B57\u6BB5\u6570\uFF1A${fields.length}` : `- \u5B57\u6BB5\u6570\uFF1A\u65E0\u6CD5\u5224\u8BFB\uFF08${problem}\uFF09\uFF0C\u8BE5\u6A21\u578B\u6CA1\u6709\u5B57\u6BB5\u8FDB\u7D22\u5F15`
6703
+ problem2 === void 0 ? `- \u5B57\u6BB5\u6570\uFF1A${fields.length}` : `- \u5B57\u6BB5\u6570\uFF1A\u65E0\u6CD5\u5224\u8BFB\uFF08${problem2}\uFF09\uFF0C\u8BE5\u6A21\u578B\u6CA1\u6709\u5B57\u6BB5\u8FDB\u7D22\u5F15`
6704
6704
  );
6705
6705
  }
6706
6706
  const gs = byModel.get(key) ?? [];
@@ -6762,8 +6762,8 @@ function refEdges(metas, knownModels) {
6762
6762
  const known = new Set(knownModels);
6763
6763
  const edges = [];
6764
6764
  const dangling = [];
6765
- for (const modelKey of Object.keys(metas).sort()) {
6766
- const { fields } = metaFields(metas[modelKey]);
6765
+ for (const modelKey2 of Object.keys(metas).sort()) {
6766
+ const { fields } = metaFields(metas[modelKey2]);
6767
6767
  for (const field of fields) {
6768
6768
  if (!field || typeof field !== "object" || Array.isArray(field)) continue;
6769
6769
  const rec = field;
@@ -6774,7 +6774,7 @@ function refEdges(metas, knownModels) {
6774
6774
  const target = rec[carrier];
6775
6775
  if (typeof target !== "string") {
6776
6776
  dangling.push({
6777
- fromModel: modelKey,
6777
+ fromModel: modelKey2,
6778
6778
  fromField: fieldKey,
6779
6779
  toModel: reprOf(target),
6780
6780
  carrier,
@@ -6783,13 +6783,13 @@ function refEdges(metas, knownModels) {
6783
6783
  continue;
6784
6784
  }
6785
6785
  if (!known.has(target)) {
6786
- dangling.push({ fromModel: modelKey, fromField: fieldKey, toModel: target, carrier, reason: "not-in-registry" });
6786
+ dangling.push({ fromModel: modelKey2, fromField: fieldKey, toModel: target, carrier, reason: "not-in-registry" });
6787
6787
  continue;
6788
6788
  }
6789
6789
  const label = rec.objectLabel;
6790
6790
  const declared = typeof label === "string" && label.length > 0;
6791
6791
  edges.push({
6792
- fromModel: modelKey,
6792
+ fromModel: modelKey2,
6793
6793
  fromField: fieldKey,
6794
6794
  // 🔴 字段中文名,是「grep 部门 → 落到 {model, key}」这条链上唯一的人话。
6795
6795
  // 接错成 key 会让产物里全是英文键名——语法完好、不报错,
@@ -6829,8 +6829,8 @@ var DYNAMIC_TYPE = "DYNAMIC";
6829
6829
  var MAX_REQUESTS_PER_TABLE = 40;
6830
6830
  var MAX_SECONDS_PER_TABLE = 30;
6831
6831
  var WORDING4 = "rows = \u672C\u8F6E\u4EE5\u5F53\u524D\u767B\u5F55\u8EAB\u4EFD\u8BFB\u5230\u7684\u7801\u8868\u884C\uFF1B\u6BCF\u884C\u539F\u6837\u4FDD\u7559\u670D\u52A1\u7AEF\u8FD4\u56DE\u7684\u5168\u90E8\u952E\u3002\u5F15\u7528\u5B57\u6BB5\u5B58\u7684\u662F\u8FD9\u91CC\u7684 `id`\uFF0C\u4E0D\u662F `code`\u3002completeness: visible-complete = **\u5F53\u524D\u89D2\u8272\u53EF\u89C1\u8303\u56F4\u5185**\u53D6\u6EE1\uFF08\u4E0D\u662F\u5168\u96C6\uFF0CRBAC \u88C1\u526A\u5148\u4E8E count\uFF09\uFF1Bpartial = \u6CA1\u53D6\u6EE1\u6216\u6709\u9875\u5931\u8D25**\u6216\u89E6\u53D1\u4E86\u5DE5\u5177\u7684\u6BCF\u8868\u4E0A\u9650**\uFF08\u540E\u8005\u770B\u8FD9\u5F20\u8868\u7684 `truncatedBy`\uFF1Anull = \u6CA1\u89E6\u53D1\uFF0C\u5BF9\u8C61 = \u505C\u5728\u7B2C\u51E0\u9875 / \u5DF2\u6536\u591A\u5C11\u884C / \u89E6\u53D1\u7684\u662F\u54EA\u4E2A\u4E0A\u9650 \u2014\u2014 \u90A3\u662F**\u5DE5\u5177**\u7684\u622A\u65AD\uFF0C\u4E0D\u662F\u670D\u52A1\u7AEF\u7684\u6BDB\u75C5\uFF0C\u6539\u4E0A\u9650\u91CD\u8DD1\u5C31\u80FD\u53D6\u5168\uFF09\uFF1Bunavailable = \u8FDE\u8BA1\u6570\u90FD\u6CA1\u8BFB\u5230\uFF08crawled=false\uFF0C\u4E0E\u300C\u8FD9\u5F20\u7801\u8868\u662F\u7A7A\u7684\u300D\u662F\u4E24\u56DE\u4E8B\uFF09\uFF1Bauthoritative-complete = \u9700\u8981\u4EA7\u54C1\u4FA7\u6743\u5A01\u503C\u57DF\u51FA\u53E3\uFF0C**\u672C\u7248\u672C\u6C38\u8FDC\u4E0D\u4F1A\u4EA7\u51FA**\u3002partial / unavailable \u65F6\u7981\u6B62\u636E\u6B64\u751F\u6210\u5199\u811A\u672C\u3002";
6832
- function listPath(modelKey) {
6833
- return `/api/models/${modelKey}/list/dsl`;
6832
+ function listPath(modelKey2) {
6833
+ return `/api/models/${modelKey2}/list/dsl`;
6834
6834
  }
6835
6835
  function isRecord4(v) {
6836
6836
  return Boolean(v) && typeof v === "object" && !Array.isArray(v);
@@ -6865,11 +6865,11 @@ async function collectCodeTables(probe, modelEntries2, opts = {}) {
6865
6865
  keys.push(key);
6866
6866
  }
6867
6867
  for (const key of [...new Set(keys)].sort()) {
6868
- const path12 = listPath(key);
6868
+ const path13 = listPath(key);
6869
6869
  const started = tick();
6870
6870
  let requests = 0;
6871
6871
  let truncatedBy = null;
6872
- const probeOut = await post.call(probe, path12, { page: 0, size: 0 });
6872
+ const probeOut = await post.call(probe, path13, { page: 0, size: 0 });
6873
6873
  requests += 1;
6874
6874
  let total = null;
6875
6875
  let reason = null;
@@ -6918,7 +6918,7 @@ async function collectCodeTables(probe, modelEntries2, opts = {}) {
6918
6918
  failed = `\u89E6\u53D1\u5DE5\u5177\u7684\u6BCF\u8868${which === "requests" ? "\u8BF7\u6C42" : "\u5899\u949F"}\u4E0A\u9650\uFF08${which === "requests" ? `\u5DF2\u53D1 ${requests} \u6B21\u8BF7\u6C42` : `\u5DF2\u82B1 ${elapsed.toFixed(3)}s`}\uFF09\uFF0C\u505C\u5728\u7B2C ${page} \u9875\uFF0C\u5DF2\u6536 ${rows.length} \u884C / \u8BA1\u6570 ${total} \u884C\uFF0C\u672C\u8868\u6807 partial\u3002**\u8FD9\u662F\u5DE5\u5177\u7684\u622A\u65AD\uFF0C\u4E0D\u662F\u670D\u52A1\u7AEF\u7684\u6BDB\u75C5** \u2014\u2014 \u8C03\u5927 valuedomain.${which === "requests" ? "MAX_REQUESTS_PER_TABLE" : "MAX_SECONDS_PER_TABLE"} \u6216\u7ED9 collectCodeTables \u4F20 ${which === "requests" ? "maxRequests" : "maxSeconds"} \u540E\u91CD\u8DD1\u5C31\u80FD\u53D6\u5168`;
6919
6919
  break;
6920
6920
  }
6921
- const out = await post.call(probe, path12, { page, size: PAGE_SIZE });
6921
+ const out = await post.call(probe, path13, { page, size: PAGE_SIZE });
6922
6922
  requests += 1;
6923
6923
  if (out.error !== "ok") {
6924
6924
  failed = `\u7B2C ${page} \u9875\u5931\u8D25\uFF08HTTP ${out.status} / ${out.error}\uFF09`;
@@ -6987,8 +6987,8 @@ async function collectCodeTables(probe, modelEntries2, opts = {}) {
6987
6987
  }
6988
6988
  function collectEnumDomains(metas) {
6989
6989
  const rows = [];
6990
- for (const modelKey of Object.keys(metas).sort()) {
6991
- const { fields } = metaFields(metas[modelKey]);
6990
+ for (const modelKey2 of Object.keys(metas).sort()) {
6991
+ const { fields } = metaFields(metas[modelKey2]);
6992
6992
  for (const field of fields) {
6993
6993
  if (!isRecord4(field)) continue;
6994
6994
  const fieldKey = field.key;
@@ -6997,7 +6997,7 @@ function collectEnumDomains(metas) {
6997
6997
  if (!Array.isArray(enums) || enums.length === 0) continue;
6998
6998
  const kept = enums.filter(isRecord4).map((e) => ({ ...e }));
6999
6999
  rows.push({
7000
- model: modelKey,
7000
+ model: modelKey2,
7001
7001
  field: fieldKey,
7002
7002
  fieldName: typeof field.name === "string" && field.name || "",
7003
7003
  count: kept.length,
@@ -7658,13 +7658,13 @@ var REASON_EMPTY = "empty";
7658
7658
  var CLASS_REASONS = [REASON_UNREAD, REASON_EMPTY];
7659
7659
  function unguardedKinds(problems) {
7660
7660
  const out = /* @__PURE__ */ new Set();
7661
- for (const problem of problems) {
7662
- if (!SCOPES.includes(problem.scope)) {
7661
+ for (const problem2 of problems) {
7662
+ if (!SCOPES.includes(problem2.scope)) {
7663
7663
  throw new Error(
7664
- `\u53F0\u8D26\u7684 scope \u53EA\u6709 ${SCOPES.join("/")} \u4E24\u4E2A\u53D6\u503C\uFF0C\u62FF\u5230\u7684\u662F ${JSON.stringify(problem.scope)}\uFF08${problem.message}\uFF09`
7664
+ `\u53F0\u8D26\u7684 scope \u53EA\u6709 ${SCOPES.join("/")} \u4E24\u4E2A\u53D6\u503C\uFF0C\u62FF\u5230\u7684\u662F ${JSON.stringify(problem2.scope)}\uFF08${problem2.message}\uFF09`
7665
7665
  );
7666
7666
  }
7667
- if (problem.scope === CLASS_SCOPE) for (const kind of problem.kinds) out.add(kind);
7667
+ if (problem2.scope === CLASS_SCOPE) for (const kind of problem2.kinds) out.add(kind);
7668
7668
  }
7669
7669
  return out;
7670
7670
  }
@@ -8156,10 +8156,10 @@ function checkGaps(gaps) {
8156
8156
  return [...gaps];
8157
8157
  }
8158
8158
  function checkPremise(problems) {
8159
- for (const problem of problems) {
8160
- if (!PREMISE_REASONS.includes(problem.reason)) {
8159
+ for (const problem2 of problems) {
8160
+ if (!PREMISE_REASONS.includes(problem2.reason)) {
8161
8161
  throw new Error(
8162
- `\u524D\u63D0\u7EA7\u53F0\u8D26\u7684 reason \u4E0D\u5728\u53D6\u503C\u57DF\u91CC\uFF1A${JSON.stringify(problem.reason)}\uFF08${problem.message}\uFF09`
8162
+ `\u524D\u63D0\u7EA7\u53F0\u8D26\u7684 reason \u4E0D\u5728\u53D6\u503C\u57DF\u91CC\uFF1A${JSON.stringify(problem2.reason)}\uFF08${problem2.message}\uFF09`
8163
8163
  );
8164
8164
  }
8165
8165
  }
@@ -8340,9 +8340,9 @@ var Matcher = class {
8340
8340
  };
8341
8341
  function classReasons(problems) {
8342
8342
  const out = /* @__PURE__ */ new Map();
8343
- for (const problem of problems ?? []) {
8344
- if (problem.scope === CLASS_SCOPE) {
8345
- for (const kind of problem.kinds) out.set(kind, problem.reason);
8343
+ for (const problem2 of problems ?? []) {
8344
+ if (problem2.scope === CLASS_SCOPE) {
8345
+ for (const kind of problem2.kinds) out.set(kind, problem2.reason);
8346
8346
  }
8347
8347
  }
8348
8348
  return out;
@@ -8518,11 +8518,11 @@ function scan(skillRoot, aclass, facts, options = {}) {
8518
8518
  message: `A \u7C7B\u5B50\u96C6 ${kind} \u662F\u7A7A\u7684${why} \u21D2 \u95E8 0 \u5BF9\u8FD9\u4E00\u7C7B**\u6052\u7EFF**\uFF0C\u8FD9\u4E00\u8F6E\u7684\u7EFF\u4E0D\u7B97\u6570`
8519
8519
  });
8520
8520
  }
8521
- for (const problem of options.aclassProblems ?? []) {
8522
- if (problem.scope !== ENTRY_SCOPE) continue;
8521
+ for (const problem2 of options.aclassProblems ?? []) {
8522
+ if (problem2.scope !== ENTRY_SCOPE) continue;
8523
8523
  premise.push({
8524
8524
  reason: REASON_ACLASS_PARTIALLY_UNREAD,
8525
- message: `A \u7C7B\u5B50\u96C6 ${problem.kinds.join("/")} \u5C11\u4E86\u4E00\u90E8\u5206\uFF08${problem.reason}\uFF09\uFF1A${problem.message} \u21D2 \u5C11\u6389\u7684\u90A3\u90E8\u5206\u95E8 0 \u5224\u4E0D\u51FA\u6765\uFF0C\u8FD9\u4E00\u8F6E\u7684\u7EFF\u4E0D\u7B97\u6570`
8525
+ message: `A \u7C7B\u5B50\u96C6 ${problem2.kinds.join("/")} \u5C11\u4E86\u4E00\u90E8\u5206\uFF08${problem2.reason}\uFF09\uFF1A${problem2.message} \u21D2 \u5C11\u6389\u7684\u90A3\u90E8\u5206\u95E8 0 \u5224\u4E0D\u51FA\u6765\uFF0C\u8FD9\u4E00\u8F6E\u7684\u7EFF\u4E0D\u7B97\u6570`
8526
8526
  });
8527
8527
  }
8528
8528
  let factsProblems = options.factsProblems;
@@ -8533,24 +8533,24 @@ function scan(skillRoot, aclass, facts, options = {}) {
8533
8533
  });
8534
8534
  factsProblems = [];
8535
8535
  }
8536
- for (const problem of factsProblems) {
8537
- if (problem.scope === REGISTRY_SCOPE && PREMISE_REGISTRY_REASONS.includes(problem.reason)) {
8536
+ for (const problem2 of factsProblems) {
8537
+ if (problem2.scope === REGISTRY_SCOPE && PREMISE_REGISTRY_REASONS.includes(problem2.reason)) {
8538
8538
  premise.push({
8539
8539
  reason: REASON_REGISTRY,
8540
- message: `\u767B\u8BB0\u518C\u8FD9\u4E00\u5C42\u6CA1\u7ACB\u4F4F\uFF08${problem.reason}\uFF09\uFF1A${problem.message} \u21D2 \u8C41\u514D\u901A\u9053 P \u4E0D\u53EF\u4FE1`
8540
+ message: `\u767B\u8BB0\u518C\u8FD9\u4E00\u5C42\u6CA1\u7ACB\u4F4F\uFF08${problem2.reason}\uFF09\uFF1A${problem2.message} \u21D2 \u8C41\u514D\u901A\u9053 P \u4E0D\u53EF\u4FE1`
8541
8541
  });
8542
8542
  }
8543
8543
  }
8544
- for (const problem of factsProblems) {
8545
- if (problem.scope === REGISTRY_SCOPE) continue;
8544
+ for (const problem2 of factsProblems) {
8545
+ if (problem2.scope === REGISTRY_SCOPE) continue;
8546
8546
  reds.push({
8547
8547
  channel: CHANNEL_NO_PROBE,
8548
8548
  reason: REASON_REJECTED_REGISTRATION,
8549
- token: problem.token ?? `(\u7B2C${problem.index}\u6761)`,
8549
+ token: problem2.token ?? `(\u7B2C${problem2.index}\u6761)`,
8550
8550
  path: null,
8551
8551
  line: 0,
8552
8552
  kinds: [],
8553
- message: `\u767B\u8BB0\u518C\u7B2C ${problem.index} \u6761\u88AB\u62D2\uFF08${problem.reason}\uFF09\uFF1A${problem.message}`
8553
+ message: `\u767B\u8BB0\u518C\u7B2C ${problem2.index} \u6761\u88AB\u62D2\uFF08${problem2.reason}\uFF09\uFF1A${problem2.message}`
8554
8554
  });
8555
8555
  }
8556
8556
  for (const token2 of [...facts].sort()) {
@@ -8666,6 +8666,412 @@ function exitCode(result) {
8666
8666
  if (result.red.length > 0) return 1;
8667
8667
  return 0;
8668
8668
  }
8669
+
8670
+ // src/fde/triage/carriers.ts
8671
+ var CARRIER_KEYS = [
8672
+ "config-surface",
8673
+ "flex-model",
8674
+ "json-model",
8675
+ "graaljs-spi",
8676
+ "flex-data",
8677
+ "data-package"
8678
+ ];
8679
+ var CARRIER_LABELS = {
8680
+ "config-surface": "\u914D\u7F6E\u9762 \u2014\u2014 \u4EA7\u54C1\u81EA\u5E26\u7684\u5143\u6570\u636E\u914D\u7F6E\u9879",
8681
+ "flex-model": "\u5F39\u6027\u6A21\u578B \u2014\u2014 \u79DF\u6237\u5143\u6570\u636E\u9A71\u52A8\u3001\u8FD0\u884C\u65F6\u521B\u5EFA\u7684\u6A21\u578B",
8682
+ "json-model": "JSON Model \u2014\u2014 \u968F\u4EA7\u54C1\u8D70\u7684\u9759\u6001\u7801\u8868\uFF0C\u53EA\u8BFB",
8683
+ "graaljs-spi": "GraalJS SPI \u2014\u2014 \u5F00\u53D1\u7A7A\u95F4\u91CC\u7684\u79DF\u6237\u6269\u5C55\u811A\u672C",
8684
+ "flex-data": "\u5F39\u6027\u5B57\u6BB5 \u2014\u2014 \u6302\u5728\u65E2\u6709\u6A21\u578B\u4E0A\u7684\u79DF\u6237\u81EA\u5B9A\u4E49\u5B57\u6BB5",
8685
+ "data-package": "DataPackage \u2014\u2014 \u53EF\u590D\u5236\u7684\u573A\u666F\u6570\u636E\u5305"
8686
+ };
8687
+ var CARRIER_HIT = "hit";
8688
+ var CARRIER_MISS = "miss";
8689
+ var CARRIER_BLIND = "blind";
8690
+ var CARRIER_UNAVAILABLE = "unavailable";
8691
+ var CARRIER_VERDICTS = [
8692
+ CARRIER_HIT,
8693
+ CARRIER_MISS,
8694
+ CARRIER_BLIND,
8695
+ CARRIER_UNAVAILABLE
8696
+ ];
8697
+ function buildCarrierResult(carrier, verdict, options = {}) {
8698
+ const { note = "", evidence = null, error = "" } = options;
8699
+ if (!CARRIER_KEYS.includes(carrier)) {
8700
+ throw new Error(`\u672A\u77E5\u627F\u8F7D\u7269 ${JSON.stringify(carrier)}\uFF0C\u53D6\u503C\u57DF\u662F ${CARRIER_KEYS.join("\u3001")}`);
8701
+ }
8702
+ if (!CARRIER_VERDICTS.includes(verdict)) {
8703
+ throw new Error(
8704
+ `\u627F\u8F7D\u7269 ${carrier} \u7684\u7ED3\u8BBA ${JSON.stringify(verdict)} \u4E0D\u5728\u53D6\u503C\u57DF ${CARRIER_VERDICTS.join("\u3001")} \u5185 \u2014\u2014 \u56DB\u6863\u4E4B\u5916\u6CA1\u6709\u7B2C\u4E94\u79CD\u8BF4\u6CD5`
8705
+ );
8706
+ }
8707
+ if (verdict === CARRIER_BLIND && !note.trim()) {
8708
+ throw new Error(
8709
+ `${carrier} \u5224\u4E3A\u76F2\u533A\uFF08${CARRIER_BLIND}\uFF09\u65F6\u5FC5\u987B\u8BF4\u660E**\u4E3A\u4EC0\u4E48\u770B\u4E0D\u89C1** \u2014\u2014 \u4E0D\u5E26\u8BF4\u660E\u7684\u76F2\u533A\u4E0E\u300C\u8DF3\u6B65\u6CA1\u67E5\u300D\u9010\u5B57\u540C\u5F62`
8710
+ );
8711
+ }
8712
+ if (verdict === CARRIER_UNAVAILABLE && !error.trim()) {
8713
+ throw new Error(
8714
+ `${carrier} \u5224\u4E3A ${CARRIER_UNAVAILABLE} \u65F6\u5FC5\u987B\u5E26\u539F\u59CB error \u2014\u2014 \u63A2\u4E0D\u5230\u8981\u8BF4\u660E\u4E3A\u4EC0\u4E48\u63A2\u4E0D\u5230\uFF0C\u4E0D\u8BB8\u9759\u9ED8\u7F6E\u7A7A`
8715
+ );
8716
+ }
8717
+ const row = {
8718
+ carrier,
8719
+ label: CARRIER_LABELS[carrier],
8720
+ verdict
8721
+ };
8722
+ if (note) row.note = note;
8723
+ if (evidence !== null) row.evidence = [...evidence];
8724
+ if (error) row.error = error;
8725
+ return row;
8726
+ }
8727
+
8728
+ // src/fde/triage/probe.ts
8729
+ import { readFileSync as readFileSync8 } from "fs";
8730
+ import * as path12 from "path";
8731
+ var WORKSPACES_PATH = "/api/tenant-extension/workspaces";
8732
+ var MODELS_REL = "models.json";
8733
+ var FIELDS_REL = "index/fields.jsonl";
8734
+ var DYNAMIC_TYPE2 = "DYNAMIC";
8735
+ var WRITE_OPS = ["create", "update", "delete"];
8736
+ var DATA_PACKAGE_BLIND_NOTE = "DataPackage \u5728 HTTP \u9762\u4E0A\u6CA1\u6709\u53D1\u73B0\u5165\u53E3 \u2014\u2014 \u5168 modules/ \u65E0\u5BF9\u5E94 Controller\u3002\u21D2 \u8FD9\u4E00\u683C**\u770B\u4E0D\u89C1**\uFF0C\u4E0D\u7B49\u4E8E\u300C\u5BA2\u6237\u8FD9\u6761\u9700\u6C42\u6CA1\u6709 DataPackage \u53EF\u7528\u300D\u3002\u8FD9\u4E00\u683C\u8981\u843D\u5730\uFF0C\u5F97\u8D70\u4EA7\u54C1\u56E2\u961F\uFF0C\u6216\u7B49\u4E00\u4E2A\u53EA\u8BFB\u53D1\u73B0\u9762\u3002";
8737
+ var UNAVAILABLE_HINT = {
8738
+ "config-surface": "\u6CA1\u8BFB\u5230\u6A21\u578B\u6E05\u5355\u4EA7\u7269 \u2014\u2014 \u5148\u8DD1\u4E00\u6B21 recon",
8739
+ "flex-model": "\u6CA1\u8BFB\u5230\u6A21\u578B\u6E05\u5355\u4EA7\u7269 \u2014\u2014 \u5148\u8DD1\u4E00\u6B21 recon",
8740
+ "json-model": "\u6CA1\u8BFB\u5230\u6A21\u578B\u6E05\u5355\u4EA7\u7269 \u2014\u2014 \u5148\u8DD1\u4E00\u6B21 recon",
8741
+ "flex-data": "\u6CA1\u8BFB\u5230\u5B57\u6BB5\u7D22\u5F15\u4EA7\u7269 \u2014\u2014 \u5148\u8DD1\u4E00\u6B21 recon",
8742
+ "graaljs-spi": "\u5F00\u53D1\u7A7A\u95F4\u6E05\u5355\u6CA1\u53D6\u5230"
8743
+ };
8744
+ function unavailableCell(carrier, err) {
8745
+ const name = err instanceof Error ? err.constructor.name : typeof err;
8746
+ const message = err instanceof Error ? err.message : String(err);
8747
+ return buildCarrierResult(carrier, CARRIER_UNAVAILABLE, {
8748
+ error: `${name}: ${message}`,
8749
+ note: UNAVAILABLE_HINT[carrier] ?? ""
8750
+ });
8751
+ }
8752
+ function readArtifactJson(dir, rel) {
8753
+ return JSON.parse(readFileSync8(path12.join(dir, rel), "utf8"));
8754
+ }
8755
+ function readArtifactJsonl(dir, rel) {
8756
+ const body = readFileSync8(path12.join(dir, rel), "utf8");
8757
+ const rows = [];
8758
+ for (const line of body.split("\n")) {
8759
+ const trimmed = line.trim();
8760
+ if (trimmed) rows.push(JSON.parse(trimmed));
8761
+ }
8762
+ return rows;
8763
+ }
8764
+ function modelRows2(dir) {
8765
+ const body = readArtifactJson(dir, MODELS_REL);
8766
+ const rows = body && typeof body === "object" ? body.models : null;
8767
+ return Array.isArray(rows) ? rows : [];
8768
+ }
8769
+ function modelKey(row) {
8770
+ if (!row || typeof row !== "object") return null;
8771
+ const key = row.key;
8772
+ return typeof key === "string" && key ? key : null;
8773
+ }
8774
+ function probeConfigSurface(dir) {
8775
+ let rows;
8776
+ try {
8777
+ rows = modelRows2(dir);
8778
+ } catch (err) {
8779
+ return unavailableCell("config-surface", err);
8780
+ }
8781
+ const keys = rows.map(modelKey).filter((k) => k !== null);
8782
+ if (keys.length === 0) {
8783
+ return buildCarrierResult("config-surface", CARRIER_MISS, {
8784
+ note: "\u6A21\u578B\u6E05\u5355\u662F\u7A7A\u7684 \u2014\u2014 \u8FD9\u4E2A\u73AF\u5883\u4E0A\u6CA1\u6709\u53EF\u914D\u7F6E\u7684\u6A21\u578B\u9762"
8785
+ });
8786
+ }
8787
+ return buildCarrierResult("config-surface", CARRIER_HIT, {
8788
+ evidence: keys.slice(0, 20),
8789
+ note: `\u5171 ${keys.length} \u4E2A\u6A21\u578B\u5E26\u5143\u6570\u636E\u9762\uFF1B\u54EA\u4E00\u4E2A\u627F\u8F7D\u8FD9\u6761\u9700\u6C42\u8981\u9010\u4E2A\u770B`
8790
+ });
8791
+ }
8792
+ function probeFlexModel(dir) {
8793
+ let rows;
8794
+ try {
8795
+ rows = modelRows2(dir);
8796
+ } catch (err) {
8797
+ return unavailableCell("flex-model", err);
8798
+ }
8799
+ const hits = rows.filter((r) => r && typeof r === "object" && r.type === DYNAMIC_TYPE2).map(modelKey).filter((k) => k !== null);
8800
+ if (hits.length === 0) {
8801
+ return buildCarrierResult("flex-model", CARRIER_MISS, {
8802
+ note: `\u8FD9\u4E2A\u73AF\u5883\u4E0A\u6CA1\u6709 ${DYNAMIC_TYPE2} \u578B\u6A21\u578B`
8803
+ });
8804
+ }
8805
+ return buildCarrierResult("flex-model", CARRIER_HIT, { evidence: hits.slice(0, 20) });
8806
+ }
8807
+ function isReadOnly(mapping) {
8808
+ const mut = mapping && typeof mapping === "object" ? mapping.mutation : null;
8809
+ if (!mut || typeof mut !== "object") return false;
8810
+ for (const op of WRITE_OPS) {
8811
+ const cell = mut[op];
8812
+ if (!cell || typeof cell !== "object") return false;
8813
+ if (cell.allowed !== false) return false;
8814
+ }
8815
+ return true;
8816
+ }
8817
+ function probeJsonModel(dir) {
8818
+ let rows;
8819
+ try {
8820
+ rows = modelRows2(dir);
8821
+ } catch (err) {
8822
+ return unavailableCell("json-model", err);
8823
+ }
8824
+ const hits = [];
8825
+ for (const row of rows) {
8826
+ const key = modelKey(row);
8827
+ if (key === null) continue;
8828
+ let mapping;
8829
+ try {
8830
+ mapping = readArtifactJson(dir, `mapping/${key}.json`);
8831
+ } catch {
8832
+ continue;
8833
+ }
8834
+ if (isReadOnly(mapping)) hits.push(key);
8835
+ }
8836
+ if (hits.length === 0) {
8837
+ return buildCarrierResult("json-model", CARRIER_MISS, {
8838
+ note: "\u6CA1\u6709\u627E\u5230\u4E09\u4E2A\u5199\u80FD\u529B\u5168\u90E8\u4E0D\u5141\u8BB8\u7684\u6A21\u578B"
8839
+ });
8840
+ }
8841
+ return buildCarrierResult("json-model", CARRIER_HIT, { evidence: hits.slice(0, 20) });
8842
+ }
8843
+ async function probeGraaljs(client) {
8844
+ const out = await client.get(WORKSPACES_PATH);
8845
+ if (out.error !== "ok") {
8846
+ return buildCarrierResult("graaljs-spi", CARRIER_UNAVAILABLE, {
8847
+ error: out.error,
8848
+ note: UNAVAILABLE_HINT["graaljs-spi"] ?? ""
8849
+ });
8850
+ }
8851
+ const body = out.body;
8852
+ const data = body && typeof body === "object" ? body.data : void 0;
8853
+ if (data === void 0 || data === null) {
8854
+ return buildCarrierResult("graaljs-spi", CARRIER_UNAVAILABLE, {
8855
+ error: `\u54CD\u5E94\u91CC\u6CA1\u6709 data \u90A3\u4E00\u683C\uFF08status=${out.status}\uFF09`,
8856
+ note: UNAVAILABLE_HINT["graaljs-spi"] ?? ""
8857
+ });
8858
+ }
8859
+ if (!Array.isArray(data) || data.length === 0) {
8860
+ return buildCarrierResult("graaljs-spi", CARRIER_MISS, {
8861
+ note: "\u8FD9\u4E2A\u79DF\u6237\u8FD8\u6CA1\u6709\u5F00\u53D1\u7A7A\u95F4 \u2014\u2014 \u5EFA\u4E00\u4E2A\u5C31\u80FD\u8D70\u811A\u672C\u8FD9\u6761\u8DEF"
8862
+ });
8863
+ }
8864
+ const ids = data.map((w) => {
8865
+ if (!w || typeof w !== "object") return null;
8866
+ const row = w;
8867
+ const picked = row.id ?? row.name;
8868
+ return typeof picked === "string" && picked ? picked : null;
8869
+ }).filter((x) => x !== null);
8870
+ return buildCarrierResult("graaljs-spi", CARRIER_HIT, { evidence: ids.slice(0, 20) });
8871
+ }
8872
+ function probeFlexData(dir) {
8873
+ let rows;
8874
+ try {
8875
+ rows = readArtifactJsonl(dir, FIELDS_REL);
8876
+ } catch (err) {
8877
+ return unavailableCell("flex-data", err);
8878
+ }
8879
+ const hits = rows.filter((r) => !!r && typeof r === "object").filter((r) => r.isFlex).map((r) => `${String(r.model)}.${String(r.key)}`);
8880
+ if (hits.length === 0) {
8881
+ return buildCarrierResult("flex-data", CARRIER_MISS, { note: "\u5B57\u6BB5\u7D22\u5F15\u91CC\u6CA1\u6709\u5F39\u6027\u5B57\u6BB5" });
8882
+ }
8883
+ return buildCarrierResult("flex-data", CARRIER_HIT, { evidence: hits.slice(0, 20) });
8884
+ }
8885
+ function probeDataPackage() {
8886
+ return buildCarrierResult("data-package", CARRIER_BLIND, { note: DATA_PACKAGE_BLIND_NOTE });
8887
+ }
8888
+ async function probeAll(client, artifactsDir) {
8889
+ return {
8890
+ "config-surface": probeConfigSurface(artifactsDir),
8891
+ "flex-model": probeFlexModel(artifactsDir),
8892
+ "json-model": probeJsonModel(artifactsDir),
8893
+ "graaljs-spi": await probeGraaljs(client),
8894
+ "flex-data": probeFlexData(artifactsDir),
8895
+ "data-package": probeDataPackage()
8896
+ };
8897
+ }
8898
+
8899
+ // src/fde/triage/coherence.ts
8900
+ var REQUIRED_SECTIONS = ["request", "cells", "verdict", "evidence"];
8901
+ var R1_MISSING_SECTION = "\u7F3A\u300C{}\u300D\u8FD9\u4E00\u6BB5 \u2014\u2014 \u56DB\u6BB5\u7F3A\u4E00\u4E0D\u53EF";
8902
+ var R1_EMPTY_CELL = "\u627F\u8F7D\u7269 {} \u90A3\u4E00\u683C\u6CA1\u6709\u7ED3\u8BBA \u2014\u2014 \u7559\u7A7A\u5C31\u662F\u8DF3\u6B65\uFF1B\u67E5\u4E0D\u5230\u8981\u586B\u76F2\u533A\u6216\u300C\u8FD9\u6B21\u6CA1\u53D6\u5230\u300D\uFF0C\u4E0D\u662F\u4E0D\u586B";
8903
+ var R2_HITS_UNDER_GAP = "\u5224\u4E86\u4EA7\u54C1\u7F3A\u53E3\uFF0C\u4F46\u8FD9\u51E0\u683C\u662F\u547D\u4E2D\u7684\uFF1A{} \u2014\u2014 \u6709\u8DEF\u8D70\u901A\u8FD8\u5224\u7F3A\u53E3\uFF0C\u7ED3\u8BBA\u548C\u8BC1\u636E\u5728\u6253\u67B6";
8904
+ var R3_CONFIG_WITHOUT_HIT = "\u5224\u4E86\u300C\u914D\u7F6E\u80FD\u505A\u300D\uFF0C\u4F46\u516D\u683C\u91CC\u6CA1\u6709\u4EFB\u4F55\u4E00\u683C\u547D\u4E2D \u2014\u2014 \u8BF4\u5F97\u51FA\u914D\u5728\u54EA\uFF0C\u8FD9\u4E2A\u7ED3\u8BBA\u624D\u7ACB\u5F97\u4F4F";
8905
+ var R4_BLIND_AS_GAP = "\u5224\u4E86\u4EA7\u54C1\u7F3A\u53E3\uFF0C\u4F46\u8FD9\u51E0\u683C\u662F\u76F2\u533A\uFF1A{} \u2014\u2014 \u76F2\u533A\u662F\u300C\u6CA1\u770B\u89C1\u300D\uFF0C\u4E0D\u662F\u300C\u6CA1\u6709\u300D\u3002\u8981\u5224\u7F3A\u53E3\uFF0C\u5F97\u5148\u663E\u5F0F\u627F\u8BA4\u8FD9\u4E00\u683C\u6CA1\u770B\u89C1\uFF08\u7F6E blindAcknowledged\uFF09\uFF0C\u522B\u628A\u65E0\u77E5\u5199\u6210\u7ED3\u8BBA";
8906
+ var GAP = "GAP";
8907
+ var CONFIG = "CONFIG";
8908
+ function fill(template, value) {
8909
+ return template.replace("{}", value);
8910
+ }
8911
+ function problem(rule, note) {
8912
+ return { rule, note };
8913
+ }
8914
+ function cellsOf(entry) {
8915
+ return entry.cells ?? {};
8916
+ }
8917
+ function withVerdict(cells, want) {
8918
+ return CARRIER_KEYS.filter((k) => {
8919
+ const cell = cells[k];
8920
+ return !!cell && typeof cell === "object" && cell.verdict === want;
8921
+ });
8922
+ }
8923
+ function checkR1(entry) {
8924
+ const out = [];
8925
+ for (const field of REQUIRED_SECTIONS) {
8926
+ if (!entry[field]) out.push(problem("R1", fill(R1_MISSING_SECTION, field)));
8927
+ }
8928
+ const cells = cellsOf(entry);
8929
+ for (const key of CARRIER_KEYS) {
8930
+ const cell = cells[key];
8931
+ if (!cell || typeof cell !== "object" || !cell.verdict) {
8932
+ out.push(problem("R1", fill(R1_EMPTY_CELL, key)));
8933
+ }
8934
+ }
8935
+ return out;
8936
+ }
8937
+ function checkR2(entry) {
8938
+ if (entry.verdict !== GAP) return [];
8939
+ const hits = withVerdict(cellsOf(entry), CARRIER_HIT);
8940
+ if (hits.length === 0) return [];
8941
+ return [problem("R2", fill(R2_HITS_UNDER_GAP, hits.join("\u3001")))];
8942
+ }
8943
+ function checkR3(entry) {
8944
+ if (entry.verdict !== CONFIG) return [];
8945
+ if (withVerdict(cellsOf(entry), CARRIER_HIT).length > 0) return [];
8946
+ return [problem("R3", R3_CONFIG_WITHOUT_HIT)];
8947
+ }
8948
+ function checkR4(entry) {
8949
+ if (entry.verdict !== GAP) return [];
8950
+ const blinds = withVerdict(cellsOf(entry), CARRIER_BLIND);
8951
+ if (blinds.length === 0) return [];
8952
+ if (entry.blindAcknowledged) return [];
8953
+ return [problem("R4", fill(R4_BLIND_AS_GAP, blinds.join("\u3001")))];
8954
+ }
8955
+ var RULES = [checkR1, checkR2, checkR3, checkR4];
8956
+ function checkCoherence(entry) {
8957
+ const out = [];
8958
+ for (const rule of RULES) out.push(...rule(entry));
8959
+ return out;
8960
+ }
8961
+
8962
+ // src/fde/triage/report.ts
8963
+ var VERDICTS = ["REUSE", "CONFIG", "EXTEND", "GAP"];
8964
+ var GAP2 = "GAP";
8965
+ var DEBT_PREFIX = "# DEBT: \u7F3A ";
8966
+ var DEBT_UNKNOWN = "\uFF08\u8FD8\u8BF4\u4E0D\u51FA\u7F3A\u54EA\u4E2A Action \u2014\u2014 \u7559\u75D5\u5148\uFF0C\u522B\u8BA9\u8FD9\u6761 GAP \u4ECE\u6E05\u5355\u91CC\u6D88\u5931\uFF09";
8967
+ var VERDICT_LABEL = {
8968
+ REUSE: "\u590D\u7528\u73B0\u6210\u7684",
8969
+ CONFIG: "\u914D\u7F6E\u80FD\u505A",
8970
+ EXTEND: "\u8D70\u4E8C\u6B21\u5F00\u53D1",
8971
+ GAP: "\u4EA7\u54C1\u7F3A\u53E3 \u2014\u2014 \u56DE\u540E\u53F0\u7ACB\u6848"
8972
+ };
8973
+ var CELL_MARK = {
8974
+ hit: "\u547D\u4E2D",
8975
+ miss: "\u770B\u4E86\uFF0C\u6CA1\u6709",
8976
+ [CARRIER_BLIND]: "\u76F2\u533A\uFF08\u770B\u4E0D\u89C1\uFF0C\u4E0D\u7B49\u4E8E\u6CA1\u6709\uFF09",
8977
+ unavailable: "\u8FD9\u6B21\u6CA1\u53D6\u5230"
8978
+ };
8979
+ function require_(entry, idx) {
8980
+ for (const field of ["request", "cells", "verdict", "evidence"]) {
8981
+ if (!entry[field]) {
8982
+ throw new Error(
8983
+ `\u7B2C ${idx} \u6761\u5206\u8BCA\u7F3A\u300C${field}\u300D\u8FD9\u4E00\u6BB5 \u2014\u2014 \u56DB\u6BB5\u7F3A\u4E00\u4E0D\u53EF\uFF0C\u7F3A\u6BB5\u7684\u4EA7\u51FA\u7269\u4E0E\u8D70\u5B8C\u5168\u7A0B\u7684\u90A3\u4EFD\u957F\u5F97\u4E00\u6837`
8984
+ );
8985
+ }
8986
+ }
8987
+ const verdict = entry.verdict;
8988
+ if (!VERDICTS.includes(verdict)) {
8989
+ throw new Error(
8990
+ `\u7B2C ${idx} \u6761\u7684\u7ED3\u8BBA ${JSON.stringify(verdict)} \u4E0D\u5728\u53D6\u503C\u57DF ${VERDICTS.join("\u3001")} \u5185`
8991
+ );
8992
+ }
8993
+ const cells = entry.cells ?? {};
8994
+ const missing = CARRIER_KEYS.filter((k) => !(k in cells));
8995
+ if (missing.length > 0) {
8996
+ throw new Error(
8997
+ `\u7B2C ${idx} \u6761\u7684\u627F\u8F7D\u7269\u6838\u67E5\u8868\u7F3A\u8FD9\u51E0\u683C\uFF1A${missing.join("\u3001")} \u2014\u2014 \u7559\u7A7A\u5C31\u662F\u8DF3\u6B65\uFF1B\u67E5\u4E0D\u5230\u8981\u586B\u76F2\u533A\u6216\u300C\u8FD9\u6B21\u6CA1\u53D6\u5230\u300D\uFF0C\u4E0D\u662F\u4E0D\u586B`
8998
+ );
8999
+ }
9000
+ const blank = CARRIER_KEYS.filter((k) => {
9001
+ const cell = cells[k];
9002
+ return !cell || typeof cell !== "object" || !cell.verdict;
9003
+ });
9004
+ if (blank.length > 0) {
9005
+ throw new Error(`\u7B2C ${idx} \u6761\u8FD9\u51E0\u683C\u586B\u4E86\u4F46\u6CA1\u6709\u7ED3\u8BBA\uFF1A${blank.join("\u3001")}`);
9006
+ }
9007
+ }
9008
+ function cellLine(key, cell) {
9009
+ const verdict = String(cell.verdict ?? "");
9010
+ const mark = CELL_MARK[verdict] ?? verdict;
9011
+ const evidence = cell.evidence;
9012
+ const tail = Array.isArray(evidence) && evidence.length > 0 ? evidence.slice(0, 5).map(String).join("\u3001") : String(cell.note ?? cell.error ?? "");
9013
+ return `| \`${key}\` | ${CARRIER_LABELS[key]} | ${mark} | ${tail} |`;
9014
+ }
9015
+ function renderTriage(entries) {
9016
+ if (entries.length === 0) {
9017
+ throw new Error(
9018
+ "\u6CA1\u6709\u4EFB\u4F55\u5206\u8BCA\u6761\u76EE \u2014\u2014 \u672C\u6A21\u5757\u4E0D\u4EA7\u51FA\u7A7A\u6587\u6863\uFF1A\u7A7A\u6587\u6863\u4E0E\u300C\u67E5\u8FC7\u4E86\u3001\u6CA1\u95EE\u9898\u300D\u5728\u8BFB\u8005\u90A3\u8FB9\u662F\u540C\u4E00\u4E2A\u6837\u5B50\u3002\u771F\u6CA1\u6709\u9700\u6C42\u8981\u5206\u8BCA\u5C31\u522B\u4EA7\u51FA\u8FD9\u4EFD\u6587\u4EF6"
9019
+ );
9020
+ }
9021
+ const out = [
9022
+ "# \u9700\u6C42\u5206\u8BCA",
9023
+ "",
9024
+ "> \u672C\u6587\u4EF6\u5224\u7684\u662F**\u6709\u6CA1\u6709\u628A\u516D\u6761\u627F\u8F7D\u7269\u8DEF\u5F84\u8D70\u5B8C**\uFF0C\u4E0D\u66FF\u4F60\u5224\u7ED3\u8BBA\u5BF9\u4E0D\u5BF9\u3002",
9025
+ "> \u516D\u683C\u91CC\u4EFB\u4F55\u4E00\u683C\u7A7A\u7740\u5C31\u662F\u8DF3\u6B65\uFF1B\u76F2\u533A\u662F\u5408\u6CD5\u7ED3\u679C\uFF0C\u7A7A\u767D\u4E0D\u662F\u3002",
9026
+ ""
9027
+ ];
9028
+ entries.forEach((entry, i) => {
9029
+ const idx = i + 1;
9030
+ require_(entry, idx);
9031
+ const verdict = entry.verdict;
9032
+ const request = String(entry.request);
9033
+ const cells = entry.cells;
9034
+ out.push(`## ${idx}. ${request.slice(0, 60)}`);
9035
+ out.push("");
9036
+ out.push("### \u5BA2\u6237\u539F\u8BDD");
9037
+ out.push("");
9038
+ out.push(`> ${request}`);
9039
+ out.push("");
9040
+ out.push("### \u627F\u8F7D\u7269\u6838\u67E5");
9041
+ out.push("");
9042
+ out.push("| \u627F\u8F7D\u7269 | \u662F\u4EC0\u4E48 | \u7ED3\u8BBA | \u4F9D\u636E |");
9043
+ out.push("|---|---|---|---|");
9044
+ for (const key of CARRIER_KEYS) out.push(cellLine(key, cells[key] ?? {}));
9045
+ out.push("");
9046
+ out.push("### \u7ED3\u8BBA");
9047
+ out.push("");
9048
+ out.push(`**${verdict}** \u2014\u2014 ${VERDICT_LABEL[verdict]}`);
9049
+ out.push("");
9050
+ out.push("### \u8BC1\u636E");
9051
+ out.push("");
9052
+ out.push(String(entry.evidence));
9053
+ out.push("");
9054
+ if (verdict === GAP2) {
9055
+ out.push(DEBT_PREFIX + (entry.debtAction ? String(entry.debtAction) : DEBT_UNKNOWN));
9056
+ out.push("");
9057
+ }
9058
+ });
9059
+ return out.join("\n");
9060
+ }
9061
+
9062
+ // src/fde/triage/round.ts
9063
+ async function runTriageRound(probe, artifactsDir, entriesIn) {
9064
+ const cells = await probeAll(probe, artifactsDir);
9065
+ const entries = entriesIn.map((raw) => ({ ...raw, cells }));
9066
+ const problems = [];
9067
+ entries.forEach((entry, i) => {
9068
+ for (const p of checkCoherence(entry)) {
9069
+ problems.push({ idx: i + 1, request: String(entry.request ?? ""), rule: p.rule, note: p.note });
9070
+ }
9071
+ });
9072
+ if (problems.length > 0) return { cells, entries, problems, body: null };
9073
+ return { cells, entries, problems, body: renderTriage(entries) };
9074
+ }
8669
9075
  export {
8670
9076
  ACLASS_EMPTY_WHY,
8671
9077
  ACLASS_KINDS,
@@ -8674,6 +9080,13 @@ export {
8674
9080
  ARTIFACT_WORDING,
8675
9081
  AUTH_INFO_PATH,
8676
9082
  BLIND_SPOTS,
9083
+ CARRIER_BLIND,
9084
+ CARRIER_HIT,
9085
+ CARRIER_KEYS,
9086
+ CARRIER_LABELS,
9087
+ CARRIER_MISS,
9088
+ CARRIER_UNAVAILABLE,
9089
+ CARRIER_VERDICTS,
8677
9090
  CHANNELS,
8678
9091
  CHANNEL_ACLASS,
8679
9092
  CHANNEL_ARTIFACT,
@@ -8684,6 +9097,9 @@ export {
8684
9097
  CLASS_SCOPE,
8685
9098
  CliError,
8686
9099
  CliErrorCode,
9100
+ DATA_PACKAGE_BLIND_NOTE,
9101
+ DEBT_PREFIX,
9102
+ DEBT_UNKNOWN,
8687
9103
  DEFAULT_AGENT_ID,
8688
9104
  DEFAULT_SESSION_TTL_SECONDS,
8689
9105
  DOCTOR_ANCHORS,
@@ -8738,6 +9154,7 @@ export {
8738
9154
  RED_REASONS,
8739
9155
  REGISTRY_REASONS,
8740
9156
  REGISTRY_SCOPE,
9157
+ REQUIRED_SECTIONS,
8741
9158
  ROUND_EXIT_CODES,
8742
9159
  ROUND_STAMPED_PRODUCTS,
8743
9160
  ROUND_STATES,
@@ -8747,9 +9164,13 @@ export {
8747
9164
  SCOPES,
8748
9165
  SDK_VERSION,
8749
9166
  SEGMENT_SEPARATOR,
9167
+ CONFIG as TRIAGE_CONFIG,
9168
+ GAP as TRIAGE_GAP,
9169
+ VERDICTS as TRIAGE_VERDICTS,
8750
9170
  TargetModelNotFound,
8751
9171
  TokenStore,
8752
9172
  VERSION_PATH,
9173
+ WORKSPACES_PATH,
8753
9174
  WsClient,
8754
9175
  absoluteDownloadUrl,
8755
9176
  adminResetPassword,
@@ -8762,6 +9183,7 @@ export {
8762
9183
  bootstrapTenant,
8763
9184
  boundedFind,
8764
9185
  buildAnswer,
9186
+ buildCarrierResult,
8765
9187
  buildConfirm,
8766
9188
  buildInterrupt,
8767
9189
  buildMiniAppTemplateFiles,
@@ -8772,6 +9194,7 @@ export {
8772
9194
  buildSteer,
8773
9195
  camelizeKeys,
8774
9196
  changePassword,
9197
+ checkCoherence,
8775
9198
  checkGaps,
8776
9199
  checkPremise,
8777
9200
  checkReds,
@@ -8848,6 +9271,7 @@ export {
8848
9271
  inspectRound,
8849
9272
  isCjk,
8850
9273
  isDelegationToolName,
9274
+ isReadOnly,
8851
9275
  isServerSlidingSession,
8852
9276
  listEnvs,
8853
9277
  listIdentities,
@@ -8883,6 +9307,7 @@ export {
8883
9307
  parseSkillFrontmatter,
8884
9308
  parseSkillRequirements,
8885
9309
  patchSettingDomain,
9310
+ probeAll,
8886
9311
  probeExtensionSource,
8887
9312
  profileDir,
8888
9313
  profileFile,
@@ -8894,6 +9319,7 @@ export {
8894
9319
  refreshToken,
8895
9320
  remove,
8896
9321
  renderRound,
9322
+ renderTriage,
8897
9323
  replHistoryFile,
8898
9324
  resetSettingItem,
8899
9325
  resolveActiveEnv,
@@ -8908,6 +9334,7 @@ export {
8908
9334
  runImport,
8909
9335
  runMiniSmokeChecks,
8910
9336
  runRecon,
9337
+ runTriageRound,
8911
9338
  safeSegment,
8912
9339
  saveConversationState,
8913
9340
  saveEnv,