ygl-trees 0.76.1 → 0.77.0

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.
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const require_rolldown_runtime = require("./rolldown-runtime-C96Ew50Q.cjs");
4
+ const require_text = require("./text-Bce0wNAD.cjs");
4
5
  let node_os = require("node:os");
5
6
  node_os = require_rolldown_runtime.__toESM(node_os);
6
7
  let node_path = require("node:path");
@@ -19,123 +20,6 @@ let node_child_process = require("node:child_process");
19
20
  let _deepseek_ai_dsh_atomic_write = require("@deepseek-ai/dsh-atomic-write");
20
21
  let _deepseek_ai_schemastery = require("@deepseek-ai/schemastery");
21
22
  _deepseek_ai_schemastery = require_rolldown_runtime.__toESM(_deepseek_ai_schemastery);
22
- //#region packages/core/text/src/text.ts
23
- var text_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
24
- clip: () => clip,
25
- contentHash: () => contentHash,
26
- ngram: () => ngram,
27
- nowIso: () => nowIso,
28
- parseFrontmatter: () => parseFrontmatter,
29
- sha1: () => sha1,
30
- shortId: () => shortId,
31
- slug: () => slug,
32
- splitTags: () => splitTags,
33
- stampId: () => stampId
34
- });
35
- function nowIso() {
36
- const d = /* @__PURE__ */ new Date();
37
- const p = (n) => String(n).padStart(2, "0");
38
- return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`;
39
- }
40
- function stampId() {
41
- const d = /* @__PURE__ */ new Date();
42
- const p = (n) => String(n).padStart(2, "0");
43
- return `${d.getFullYear()}${p(d.getMonth() + 1)}${p(d.getDate())}-${p(d.getHours())}${p(d.getMinutes())}${p(d.getSeconds())}`;
44
- }
45
- function slug(text, limit = 40) {
46
- const s = (text || "").trim().toLowerCase().replace(new RegExp(`[^\\w${CJK}]+`, "gu"), "-").replace(/^-+|-+$/g, "");
47
- if (s.length <= limit) return s || "item";
48
- return s.slice(0, limit).replace(/-+$/, "") || "item";
49
- }
50
- /**
51
- * Tokenize mixed Chinese/English text for SQLite FTS5.
52
- *
53
- * FTS5's default unicode61 tokenizer treats a whole CJK sentence as one token,
54
- * which makes Chinese search degrade to exact match. We expand CJK runs into
55
- * character bigrams and keep latin words intact.
56
- */
57
- function ngram(text) {
58
- const src = (text || "").normalize("NFKC").toLowerCase();
59
- const out = [];
60
- const segs = src.match(CJK_RUN_RE) || [];
61
- for (const seg of segs) if (CJK_ONLY_RE.test(seg)) {
62
- if (seg.length === 1) out.push(seg);
63
- else for (let i = 0; i < seg.length - 1; i++) out.push(seg.slice(i, i + 2));
64
- } else {
65
- const w = seg.replace(/^[^\w]+|[^\w]+$/gu, "");
66
- if (w) out.push(w);
67
- }
68
- return out.join(" ");
69
- }
70
- function sha1(text) {
71
- return require("node:crypto").createHash("sha1").update(text || "").digest("hex");
72
- }
73
- /** Content hash for idempotent writes (single source: store writes and the
74
- * TypeORM write service must produce identical hashes); --force salts it
75
- * so a duplicate row is explicitly distinct (queryable via `db dups`). */
76
- function contentHash(content, force) {
77
- return sha1(content) + (force ? `#f${Date.now()}${Math.random()}` : "");
78
- }
79
- function shortId(parts, n = 8) {
80
- return sha1(parts.join("|") + Date.now() + Math.random()).slice(0, n);
81
- }
82
- /** Truncate for table display, collapsing newlines. */
83
- function clip(text, n = 40) {
84
- const one = (text || "").replace(/\s+/g, " ").trim();
85
- return one.length <= n ? one : one.slice(0, Math.max(1, n - 1)) + "…";
86
- }
87
- /**
88
- * Minimal SKILL.md frontmatter parser: supports `key: value`, quoted scalars,
89
- * folded blocks (`>-` / `>`) and inline `a,b` lists.
90
- */
91
- function parseFrontmatter(raw) {
92
- const text = raw.replace(/^/, "");
93
- const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/.exec(text);
94
- if (!m) return {
95
- meta: {},
96
- body: text
97
- };
98
- const meta = {};
99
- const lines = m[1].split(/\r?\n/);
100
- let key = null;
101
- let folded = null;
102
- const flush = () => {
103
- if (key && folded) meta[key] = folded.join(" ").replace(/\s+/g, " ").trim();
104
- key = null;
105
- folded = null;
106
- };
107
- for (const line of lines) {
108
- const kv = /^([A-Za-z_][\w-]*)\s*:\s*(.*)$/.exec(line);
109
- if (kv && !/^\s/.test(line)) {
110
- flush();
111
- key = kv[1];
112
- const v = kv[2].trim();
113
- if (v === ">-" || v === ">" || v === "|" || v === "|-") folded = [];
114
- else {
115
- meta[key] = v.replace(/^["']|["']$/g, "");
116
- key = null;
117
- }
118
- continue;
119
- }
120
- if (key && folded) folded.push(line.trim());
121
- }
122
- flush();
123
- return {
124
- meta,
125
- body: text.slice(m[0].length)
126
- };
127
- }
128
- function splitTags(v) {
129
- return (v || "").split(/[,,;;\s]+/).map((s) => s.trim()).filter(Boolean);
130
- }
131
- var CJK, CJK_RUN_RE, CJK_ONLY_RE;
132
- var init_text = require_rolldown_runtime.__esmMin((() => {
133
- CJK = "\\u4e00-\\u9fff\\u3400-\\u4dbf\\uf900-\\ufaff";
134
- new RegExp(`[${CJK}]`, "u");
135
- CJK_RUN_RE = new RegExp(`[${CJK}]+|[^\\s${CJK}]+`, "gu");
136
- CJK_ONLY_RE = new RegExp(`^[${CJK}]+$`, "u");
137
- }));
138
- //#endregion
139
23
  //#region packages/core/database/src/db.ts
140
24
  /**
141
25
  * Database: single source of truth for ygl-trees.
@@ -158,7 +42,7 @@ function dbPath(home) {
158
42
  }
159
43
  var SCHEMA_SQL, DB, EDGE_RELS, EDGE_MODES, COND_KINDS;
160
44
  var init_db = require_rolldown_runtime.__esmMin((() => {
161
- init_text();
45
+ require_text.init_text();
162
46
  SCHEMA_SQL = `
163
47
  -- ---------------------------------------------------------------- meta
164
48
  -- runtime state the tool writes itself (current selections, bookkeeping);
@@ -688,7 +572,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS uq_skill_refs ON skill_refs(skill_id, path);
688
572
  const group = (s.scope ? `${r[s.scope]}|` : "") + content;
689
573
  const n = (seen.get(group) || 0) + 1;
690
574
  seen.set(group, n);
691
- const h = n > 1 ? `${sha1(content)}#dup${n}` : sha1(content);
575
+ const h = n > 1 ? `${require_text.sha1(content)}#dup${n}` : require_text.sha1(content);
692
576
  this.run(`UPDATE ${s.t} SET content_hash=? WHERE rowid=?`, [h, r.__rid]);
693
577
  }
694
578
  }
@@ -2011,7 +1895,7 @@ var init_eval = require_rolldown_runtime.__esmMin((() => {
2011
1895
  //#endregion
2012
1896
  //#region packages/techtree/model/src/reads.ts
2013
1897
  init_db();
2014
- init_text();
1898
+ require_text.init_text();
2015
1899
  init_eval();
2016
1900
  var TreeStore = class {
2017
1901
  db;
@@ -2089,7 +1973,7 @@ var TreeStore = class {
2089
1973
  if (p.id === c.id) throw new Error("self-loop rejected");
2090
1974
  if (this.reaches(treeId, c.id, p.id)) throw new Error(`cycle rejected: ${childKey} already reaches ${parentKey}`);
2091
1975
  }
2092
- const id = shortId([
1976
+ const id = require_text.shortId([
2093
1977
  "edge",
2094
1978
  p.id,
2095
1979
  c.id,
@@ -2171,7 +2055,7 @@ var TreeStore = class {
2171
2055
  this.db.run("DELETE FROM node_conditions WHERE id=?", [condId]);
2172
2056
  }
2173
2057
  markDirty(treeId) {
2174
- this.db.run("INSERT INTO node_index(tree_id,built_at,dirty) VALUES(?,?,1) ON CONFLICT(tree_id) DO UPDATE SET dirty=1", [treeId, nowIso()]);
2058
+ this.db.run("INSERT INTO node_index(tree_id,built_at,dirty) VALUES(?,?,1) ON CONFLICT(tree_id) DO UPDATE SET dirty=1", [treeId, require_text.nowIso()]);
2175
2059
  }
2176
2060
  /** Rebuild the transitive closure (BFS from every node). */
2177
2061
  rebuildClosure(treeId) {
@@ -2288,7 +2172,7 @@ var TreeStore = class {
2288
2172
  JSON.stringify(topo),
2289
2173
  JSON.stringify(tiers),
2290
2174
  JSON.stringify(inDegree),
2291
- nowIso()
2175
+ require_text.nowIso()
2292
2176
  ]);
2293
2177
  return {
2294
2178
  topo,
@@ -2515,7 +2399,7 @@ var TreeStore = class {
2515
2399
  /** Full-text search over nodes. Title/key substring hits outrank same-hit
2516
2400
  * rows (same ranking semantics as kb/skill/source search). */
2517
2401
  nodeSearch(treeId, q, limit = 20) {
2518
- const tokens = Array.from(new Set(String((init_text(), require_rolldown_runtime.__toCommonJS(text_exports)).ngram(q) || "").split(/\s+/).filter(Boolean)));
2402
+ const tokens = Array.from(new Set(String((require_text.init_text(), require_rolldown_runtime.__toCommonJS(require_text.text_exports)).ngram(q) || "").split(/\s+/).filter(Boolean)));
2519
2403
  if (!tokens.length) return [];
2520
2404
  const agg = /* @__PURE__ */ new Map();
2521
2405
  const st = this.db.db.prepare(`SELECT n.id,n.key,n.name,n.tier, bm25(nodes_fts) AS score
@@ -2737,7 +2621,7 @@ function apply$1(ctx) {
2737
2621
  }
2738
2622
  //#endregion
2739
2623
  //#region packages/research/pipeline/src/reads.ts
2740
- init_text();
2624
+ require_text.init_text();
2741
2625
  var Store = class {
2742
2626
  db;
2743
2627
  constructor(db) {
@@ -2745,8 +2629,8 @@ var Store = class {
2745
2629
  }
2746
2630
  log(kind, entity = "", entityId = "", payload = "", actor = "cli") {
2747
2631
  this.db.run("INSERT INTO events(id,ts,actor,kind,entity,entity_id,payload) VALUES(?,?,?,?,?,?,?)", [
2748
- shortId([kind, entity], 12),
2749
- nowIso(),
2632
+ require_text.shortId([kind, entity], 12),
2633
+ require_text.nowIso(),
2750
2634
  actor,
2751
2635
  kind,
2752
2636
  entity,
@@ -2868,7 +2752,7 @@ var Store = class {
2868
2752
  skillEnabled(name, on) {
2869
2753
  return this.db.run("UPDATE skills SET enabled=?, updated=? WHERE name=?", [
2870
2754
  on ? 1 : 0,
2871
- nowIso(),
2755
+ require_text.nowIso(),
2872
2756
  name
2873
2757
  ]).changes > 0;
2874
2758
  }
@@ -2944,7 +2828,7 @@ var Store = class {
2944
2828
  * works for CJK and latin alike.
2945
2829
  */
2946
2830
  fts(o) {
2947
- const tokens = Array.from(new Set(ngram(o.q).split(/\s+/).filter(Boolean)));
2831
+ const tokens = Array.from(new Set(require_text.ngram(o.q).split(/\s+/).filter(Boolean)));
2948
2832
  if (!tokens.length) return o.fallback();
2949
2833
  const cond = [o.where, `${o.table} MATCH ?`].filter(Boolean).join(" AND ");
2950
2834
  const agg = /* @__PURE__ */ new Map();
@@ -3017,7 +2901,7 @@ var Store = class {
3017
2901
  relate(srcType, srcId, dstType, dstId, rel = "related", weight = 1) {
3018
2902
  this.db.run(`INSERT INTO relations(id,src_type,src_id,dst_type,dst_id,rel,weight) VALUES(?,?,?,?,?,?,?)
3019
2903
  ON CONFLICT(src_type,src_id,dst_type,dst_id,rel) DO UPDATE SET weight=excluded.weight`, [
3020
- shortId([
2904
+ require_text.shortId([
3021
2905
  srcType,
3022
2906
  srcId,
3023
2907
  dstType,
@@ -3068,25 +2952,25 @@ var Store = class {
3068
2952
  const p = (n) => String(n).padStart(2, "0");
3069
2953
  const cut = `${cutoff.getFullYear()}-${p(cutoff.getMonth() + 1)}-${p(cutoff.getDate())} ${p(cutoff.getHours())}:${p(cutoff.getMinutes())}:${p(cutoff.getSeconds())}`;
3070
2954
  return this.db.run(`UPDATE runs SET finished=?, rc=126, output=COALESCE(NULLIF(output,''),'') || '(reaped: process was killed mid-run)'
3071
- WHERE finished='' AND started < ?`, [nowIso(), cut]).changes;
2955
+ WHERE finished='' AND started < ?`, [require_text.nowIso(), cut]).changes;
3072
2956
  }
3073
2957
  jobStart(jobId) {
3074
- const id = shortId(["run", jobId], 12);
2958
+ const id = require_text.shortId(["run", jobId], 12);
3075
2959
  this.db.run("INSERT INTO runs(id,job_id,started) VALUES(?,?,?)", [
3076
2960
  id,
3077
2961
  jobId,
3078
- nowIso()
2962
+ require_text.nowIso()
3079
2963
  ]);
3080
2964
  return id;
3081
2965
  }
3082
2966
  jobFinish(runId, rc, output) {
3083
2967
  this.db.run("UPDATE runs SET finished=?, rc=?, output=? WHERE id=?", [
3084
- nowIso(),
2968
+ require_text.nowIso(),
3085
2969
  rc,
3086
2970
  output.slice(0, 8e3)
3087
2971
  ]);
3088
2972
  this.db.run("UPDATE jobs SET runs=runs+1, last_run=?, status=? WHERE id=(SELECT job_id FROM runs WHERE id=?)", [
3089
- nowIso(),
2973
+ require_text.nowIso(),
3090
2974
  rc === 0 ? "ok" : "failed",
3091
2975
  runId
3092
2976
  ]);
@@ -3129,7 +3013,8 @@ function str(v) {
3129
3013
  */
3130
3014
  function deriveL1(body, title) {
3131
3015
  const lines = body.split("\n").map((l) => l.replace(/\*\*/g, "").trim()).filter(Boolean).filter((l) => !/^#{1,6}\s/.test(l)).filter((l) => !/^_generated/i.test(l) && !/^generated/i.test(l));
3132
- return `${clip((lines.slice(0, 20).find((l) => /^[-*]\s+|^\d+[.)]\s+/.test(l)) || lines[0] || title).replace(/^[-*]\s+|^\d+[.)]\s+/, "").replace(/^[✓✗⚠?*☐☑]\s*/, "").replace(/\s*\[\d+\]/g, "").replace(/\s+/g, " ").trim(), 200)}(提炼自《${clip(title, 60)}》)`;
3016
+ const pick = (lines.slice(0, 20).find((l) => /^[-*]\s+|^\d+[.)]\s+/.test(l)) || lines[0] || title).replace(/^[-*]\s+|^\d+[.)]\s+/, "").replace(/^[✓✗⚠?*☐☑]\s*/, "").replace(/\s*\[\d+\]/g, "").replace(/\s+/g, " ").trim();
3017
+ return `${require_text.clip(pick, 200)}(提炼自《${require_text.clip(title, 60)}》)`;
3133
3018
  }
3134
3019
  //#endregion
3135
3020
  //#region packages/research/pipeline/src/plugin.ts
@@ -3249,18 +3134,21 @@ function writeUserBundle(home, specs) {
3249
3134
  function pnpm(home, args) {
3250
3135
  const pm = process.env.YGL_PACKAGE_MANAGER || "pnpm";
3251
3136
  if (process.platform === "win32") {
3252
- const q = (s) => `"${String(s).replace(/["&|<>^]/g, "")}"`;
3253
3137
  const exe = resolvePm(pm);
3254
- (0, node_child_process.execFileSync)([
3255
- q(exe),
3256
- ...args.map(q),
3138
+ const { spawnSync } = require("node:child_process");
3139
+ const r = spawnSync("cmd", [
3140
+ "/c",
3141
+ exe,
3142
+ ...args,
3257
3143
  "--dir",
3258
- q(profileDir(home)),
3144
+ profileDir(home),
3259
3145
  "--ignore-workspace"
3260
- ].join(" "), {
3261
- stdio: "pipe",
3262
- shell: true
3263
- });
3146
+ ], { stdio: "pipe" });
3147
+ if (r.status !== 0) {
3148
+ const err = new Error(String(r.stderr || r.stdout || `pnpm exited ${r.status}`));
3149
+ err.status = r.status;
3150
+ throw err;
3151
+ }
3264
3152
  return;
3265
3153
  }
3266
3154
  (0, node_child_process.execFileSync)(pm, [
@@ -3294,6 +3182,16 @@ function resolvePm(pm) {
3294
3182
  async function installPlugin(home, spec) {
3295
3183
  initProfile(home);
3296
3184
  const abs = node_path.resolve(spec);
3185
+ if (node_fs.existsSync(abs) && node_fs.statSync(abs).isDirectory()) {
3186
+ const pkgPath = node_path.join(abs, "package.json");
3187
+ if (!node_fs.existsSync(pkgPath)) throw new Error(`local plugin directory has no package.json: ${abs}`);
3188
+ try {
3189
+ const pkg = JSON.parse(node_fs.readFileSync(pkgPath, "utf8"));
3190
+ if (!pkg.name || typeof pkg.name !== "string") throw new Error(`package.json missing "name" field: ${abs}`);
3191
+ } catch (e) {
3192
+ throw new Error(`invalid package.json in ${abs}: ${e?.message || e}`);
3193
+ }
3194
+ } else if (spec.startsWith(".") || spec.startsWith("/") || spec.startsWith("\\") || /^[A-Z]:/.test(spec)) throw new Error(`plugin path not found: ${abs}`);
3297
3195
  const installSpec = node_fs.existsSync(abs) && node_fs.statSync(abs).isDirectory() ? `link:${abs}` : spec;
3298
3196
  const existing = readUserBundle(home).find((p) => p.spec === installSpec || p.spec === spec);
3299
3197
  if (existing) return existing;
@@ -3578,6 +3476,7 @@ function createProcessShutdown(dispose, forceExit = (code) => process.exit(code)
3578
3476
  }
3579
3477
  //#endregion
3580
3478
  //#region apps/cli/src/plugin.ts
3479
+ var plugin_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({ runPluginCommand: () => runPluginCommand });
3581
3480
  init_plugins();
3582
3481
  function runPluginCommand(env, action, rest, args) {
3583
3482
  const { ctx } = env;
@@ -3701,7 +3600,7 @@ function runPluginCommand(env, action, rest, args) {
3701
3600
  }
3702
3601
  //#endregion
3703
3602
  //#region packages/ops/tools/src/pgsync.ts
3704
- init_text();
3603
+ require_text.init_text();
3705
3604
  /** Mirror targets, FK-dependency-safe order (same list as `db export`). */
3706
3605
  const MIRROR_TABLES = [
3707
3606
  "meta",
@@ -3760,7 +3659,7 @@ async function copyTable(client, db, t) {
3760
3659
  const v = r[c];
3761
3660
  return v === void 0 ? null : v;
3762
3661
  });
3763
- if (NGRAM_INPUT[t]) vals.push(ngram(NGRAM_INPUT[t](r)));
3662
+ if (NGRAM_INPUT[t]) vals.push(require_text.ngram(NGRAM_INPUT[t](r)));
3764
3663
  params.push(...vals);
3765
3664
  return `(${vals.map((_, j) => `$${params.length - vals.length + j + 1}`).join(",")})`;
3766
3665
  });
@@ -4089,8 +3988,8 @@ async function logEvent$1(mgr, kind, entity, entityId, payload, level = "info")
4089
3988
  };
4090
3989
  const p = typeof obj === "string" ? obj : JSON.stringify(obj);
4091
3990
  await mgr.insert(Event, {
4092
- id: shortId([kind, entity], 12),
4093
- ts: nowIso(),
3991
+ id: require_text.shortId([kind, entity], 12),
3992
+ ts: require_text.nowIso(),
4094
3993
  actor: "cli",
4095
3994
  kind,
4096
3995
  entity,
@@ -4110,7 +4009,7 @@ async function logEvent$1(mgr, kind, entity, entityId, payload, level = "info")
4110
4009
  } catch {}
4111
4010
  }
4112
4011
  async function queryAdd(ds, projectId, text, engine = "", force = false) {
4113
- const hash = contentHash(text, force);
4012
+ const hash = require_text.contentHash(text, force);
4114
4013
  return ds.transaction(async (mgr) => {
4115
4014
  const ex = await mgr.findOne(Query, { where: {
4116
4015
  projectId,
@@ -4121,7 +4020,7 @@ async function queryAdd(ds, projectId, text, engine = "", force = false) {
4121
4020
  dup: true
4122
4021
  };
4123
4022
  const q = new Query();
4124
- q.id = shortId([
4023
+ q.id = require_text.shortId([
4125
4024
  "q",
4126
4025
  projectId,
4127
4026
  text
@@ -4132,7 +4031,7 @@ async function queryAdd(ds, projectId, text, engine = "", force = false) {
4132
4031
  q.status = "pending";
4133
4032
  q.note = "";
4134
4033
  q.contentHash = hash;
4135
- q.created = nowIso();
4034
+ q.created = require_text.nowIso();
4136
4035
  await mgr.save(q);
4137
4036
  await logEvent$1(mgr, "query.add", "query", q.id, text);
4138
4037
  return {
@@ -4155,7 +4054,7 @@ function mapQuery(q) {
4155
4054
  }
4156
4055
  async function sourceAdd(ds, projectId, o) {
4157
4056
  const url = o.url || "";
4158
- const urlHash = sha1(url || o.title || "");
4057
+ const urlHash = require_text.sha1(url || o.title || "");
4159
4058
  return ds.transaction(async (mgr) => {
4160
4059
  const ex = await mgr.findOne(Source, { where: {
4161
4060
  projectId,
@@ -4170,7 +4069,7 @@ async function sourceAdd(ds, projectId, o) {
4170
4069
  const abstract_ = o.abstract || "";
4171
4070
  const content = o.content || "";
4172
4071
  const s = new Source();
4173
- s.id = shortId([
4072
+ s.id = require_text.shortId([
4174
4073
  "src",
4175
4074
  projectId,
4176
4075
  urlHash
@@ -4179,22 +4078,22 @@ async function sourceAdd(ds, projectId, o) {
4179
4078
  s.url = url;
4180
4079
  s.title = title;
4181
4080
  s.urlHash = urlHash;
4182
- s.contentHash = sha1(content || abstract_);
4081
+ s.contentHash = require_text.sha1(content || abstract_);
4183
4082
  s.abstract = abstract_;
4184
4083
  s.content = content;
4185
4084
  s.engine = o.engine || "";
4186
4085
  s.relevance = o.relevance ?? 0;
4187
4086
  s.confidence = o.confidence || "B";
4188
4087
  s.tags = o.tags || "";
4189
- s.retrievedAt = nowIso();
4190
- s.created = nowIso();
4088
+ s.retrievedAt = require_text.nowIso();
4089
+ s.created = require_text.nowIso();
4191
4090
  await mgr.save(s);
4192
4091
  await mgr.query(`INSERT INTO sources_fts(id,title,abstract,content,ngram) VALUES(?,?,?,?,?)`, [
4193
4092
  s.id,
4194
4093
  title,
4195
4094
  abstract_,
4196
4095
  content,
4197
- ngram(`${title} ${abstract_} ${content} ${o.tags || ""}`)
4096
+ require_text.ngram(`${title} ${abstract_} ${content} ${o.tags || ""}`)
4198
4097
  ]);
4199
4098
  await logEvent$1(mgr, "source.add", "source", s.id, title);
4200
4099
  return {
@@ -4222,7 +4121,7 @@ function mapSource(s) {
4222
4121
  };
4223
4122
  }
4224
4123
  async function evidenceAdd(ds, projectId, sourceId, quote, note = "", locator = "", force = false) {
4225
- const hash = contentHash(quote, force);
4124
+ const hash = require_text.contentHash(quote, force);
4226
4125
  return ds.transaction(async (mgr) => {
4227
4126
  if (!await mgr.findOne(Source, { where: {
4228
4127
  id: sourceId,
@@ -4237,7 +4136,7 @@ async function evidenceAdd(ds, projectId, sourceId, quote, note = "", locator =
4237
4136
  dup: true
4238
4137
  };
4239
4138
  const e = new Evidence();
4240
- e.id = shortId([
4139
+ e.id = require_text.shortId([
4241
4140
  "ev",
4242
4141
  sourceId,
4243
4142
  quote
@@ -4248,12 +4147,12 @@ async function evidenceAdd(ds, projectId, sourceId, quote, note = "", locator =
4248
4147
  e.note = note;
4249
4148
  e.locator = locator;
4250
4149
  e.contentHash = hash;
4251
- e.created = nowIso();
4150
+ e.created = require_text.nowIso();
4252
4151
  await mgr.save(e);
4253
4152
  await mgr.query(`INSERT INTO evidence_fts(id,quote,ngram) VALUES(?,?,?)`, [
4254
4153
  e.id,
4255
4154
  quote,
4256
- ngram(quote)
4155
+ require_text.ngram(quote)
4257
4156
  ]);
4258
4157
  await logEvent$1(mgr, "evidence.add", "evidence", e.id, quote.slice(0, 60));
4259
4158
  return {
@@ -4275,7 +4174,7 @@ function mapEvidence(e) {
4275
4174
  };
4276
4175
  }
4277
4176
  async function claimAdd(ds, projectId, text, confidence = "B", force = false) {
4278
- const hash = contentHash(text, force);
4177
+ const hash = require_text.contentHash(text, force);
4279
4178
  return ds.transaction(async (mgr) => {
4280
4179
  const ex = await mgr.findOne(Claim, { where: {
4281
4180
  projectId,
@@ -4286,7 +4185,7 @@ async function claimAdd(ds, projectId, text, confidence = "B", force = false) {
4286
4185
  dup: true
4287
4186
  };
4288
4187
  const c = new Claim();
4289
- c.id = shortId([
4188
+ c.id = require_text.shortId([
4290
4189
  "cl",
4291
4190
  projectId,
4292
4191
  text
@@ -4296,8 +4195,8 @@ async function claimAdd(ds, projectId, text, confidence = "B", force = false) {
4296
4195
  c.status = "unverified";
4297
4196
  c.confidence = confidence;
4298
4197
  c.contentHash = hash;
4299
- c.created = nowIso();
4300
- c.updated = nowIso();
4198
+ c.created = require_text.nowIso();
4199
+ c.updated = require_text.nowIso();
4301
4200
  await mgr.save(c);
4302
4201
  await logEvent$1(mgr, "claim.add", "claim", c.id, text.slice(0, 60));
4303
4202
  return {
@@ -4341,7 +4240,7 @@ async function claimResolve(ds, claimId, status, note = "") {
4341
4240
  return ds.transaction(async (mgr) => {
4342
4241
  await mgr.update(Claim, { id: claimId }, {
4343
4242
  status,
4344
- updated: nowIso()
4243
+ updated: require_text.nowIso()
4345
4244
  });
4346
4245
  await logEvent$1(mgr, "claim.resolve", "claim", claimId, `${status}${note ? " | " + note : ""}`);
4347
4246
  });
@@ -4370,7 +4269,7 @@ async function queryAttach(ds, projectId, queryIdOrText, sourceId, note = "") {
4370
4269
  qs.queryId = q.id;
4371
4270
  qs.sourceId = s.id;
4372
4271
  qs.note = note;
4373
- qs.created = nowIso();
4272
+ qs.created = require_text.nowIso();
4374
4273
  await mgr.save(qs);
4375
4274
  await logEvent$1(mgr, "query.attach", "query", q.id, s.id);
4376
4275
  }
@@ -4383,15 +4282,15 @@ async function queryAttach(ds, projectId, queryIdOrText, sourceId, note = "") {
4383
4282
  });
4384
4283
  }
4385
4284
  async function kbAdd(ds, o) {
4386
- const hash = contentHash(`${o.title}\n${o.body}`, !!o.force);
4285
+ const hash = require_text.contentHash(`${o.title}\n${o.body}`, !!o.force);
4387
4286
  return ds.transaction(async (mgr) => {
4388
4287
  const ex = await mgr.query(`SELECT * FROM kb_notes WHERE content_hash=?`, [hash]);
4389
4288
  if (ex.length) return {
4390
4289
  row: ex[0],
4391
4290
  dup: true
4392
4291
  };
4393
- const id = shortId(["kb", o.title], 10);
4394
- const now = nowIso();
4292
+ const id = require_text.shortId(["kb", o.title], 10);
4293
+ const now = require_text.nowIso();
4395
4294
  await mgr.query(`INSERT INTO kb_notes(id,title,body,source_url,origin,tags,confidence,reuse,content_hash,created,updated)
4396
4295
  VALUES(?,?,?,?,?,?,?,0,?,?,?)`, [
4397
4296
  id,
@@ -4409,7 +4308,7 @@ async function kbAdd(ds, o) {
4409
4308
  id,
4410
4309
  o.title,
4411
4310
  o.tags || "",
4412
- ngram(`${o.title} ${o.tags || ""} ${o.body}`)
4311
+ require_text.ngram(`${o.title} ${o.tags || ""} ${o.body}`)
4413
4312
  ]);
4414
4313
  await logEvent$1(mgr, "kb.add", "kb_note", id, o.title);
4415
4314
  return {
@@ -4447,13 +4346,13 @@ async function kbImportBulk(ds, items) {
4447
4346
  let added = 0;
4448
4347
  let dups = 0;
4449
4348
  for (const o of items) {
4450
- const hash = contentHash(`${o.title}\n${o.body}`, false);
4349
+ const hash = require_text.contentHash(`${o.title}\n${o.body}`, false);
4451
4350
  if ((await mgr.query(`SELECT id FROM kb_notes WHERE content_hash=?`, [hash])).length) {
4452
4351
  dups++;
4453
4352
  continue;
4454
4353
  }
4455
- const id = shortId(["kb", o.title], 10);
4456
- const now = nowIso();
4354
+ const id = require_text.shortId(["kb", o.title], 10);
4355
+ const now = require_text.nowIso();
4457
4356
  await mgr.query(`INSERT INTO kb_notes(id,title,body,source_url,origin,tags,confidence,reuse,content_hash,created,updated)
4458
4357
  VALUES(?,?,?,?,?,?,?,0,?,?,?)`, [
4459
4358
  id,
@@ -4471,7 +4370,7 @@ async function kbImportBulk(ds, items) {
4471
4370
  id,
4472
4371
  o.title,
4473
4372
  o.tags || "",
4474
- ngram(`${o.title} ${o.tags || ""} ${o.body}`)
4373
+ require_text.ngram(`${o.title} ${o.tags || ""} ${o.body}`)
4475
4374
  ]);
4476
4375
  await logEvent$1(mgr, "kb.add", "kb_note", id, o.title);
4477
4376
  added++;
@@ -4494,8 +4393,8 @@ async function jobAdd(ds, o) {
4494
4393
  let i = 2;
4495
4394
  while ((await mgr.query(`SELECT 1 AS hit FROM jobs WHERE title=?`, [title])).length) title = `${o.title}-${i++}`;
4496
4395
  }
4497
- const id = shortId(["job", title], 10);
4498
- const created = nowIso();
4396
+ const id = require_text.shortId(["job", title], 10);
4397
+ const created = require_text.nowIso();
4499
4398
  await mgr.query(`INSERT INTO jobs(id,title,command,every_minutes,at,enabled,runs,last_run,status,created)
4500
4399
  VALUES(?,?,?,?,?,1,0,'','pending',?)`, [
4501
4400
  id,
@@ -4531,14 +4430,14 @@ async function artifactAdd(ds, projectId, kind, title, content, format = "markdo
4531
4430
  title
4532
4431
  ]);
4533
4432
  const ver = Number(max?.[0]?.m ?? 0) + 1;
4534
- const id = shortId([
4433
+ const id = require_text.shortId([
4535
4434
  "art",
4536
4435
  projectId,
4537
4436
  kind,
4538
4437
  title,
4539
4438
  String(ver)
4540
4439
  ], 10);
4541
- const created = nowIso();
4440
+ const created = require_text.nowIso();
4542
4441
  await mgr.query(`INSERT INTO artifacts(id,project_id,kind,title,format,content,version,created,meta) VALUES(?,?,?,?,?,?,?,?,?)`, [
4543
4442
  id,
4544
4443
  projectId,
@@ -4587,7 +4486,7 @@ async function taskSetStatus(ds, taskId, status) {
4587
4486
  ...meta,
4588
4487
  status
4589
4488
  }),
4590
- nowIso(),
4489
+ require_text.nowIso(),
4591
4490
  taskId
4592
4491
  ]);
4593
4492
  await logEvent$1(mgr, "task.status", "task", taskId, `${from} → ${status}`, status === "done" ? "info" : "info");
@@ -4601,13 +4500,13 @@ async function taskSetStatus(ds, taskId, status) {
4601
4500
  }
4602
4501
  async function skillUpsert(ds, o) {
4603
4502
  return ds.transaction(async (mgr) => {
4604
- const now = nowIso();
4503
+ const now = require_text.nowIso();
4605
4504
  await mgr.query(`INSERT INTO skills(id,name,version,description,body,tags,origin,created,updated)
4606
4505
  VALUES(?,?,?,?,?,?,?,?,?)
4607
4506
  ON CONFLICT(name) DO UPDATE SET
4608
4507
  version=excluded.version, description=excluded.description, body=excluded.body,
4609
4508
  tags=excluded.tags, origin=excluded.origin, updated=excluded.updated`, [
4610
- shortId(["skill", o.name], 10),
4509
+ require_text.shortId(["skill", o.name], 10),
4611
4510
  o.name,
4612
4511
  o.version || "0.1.0",
4613
4512
  o.description || "",
@@ -4624,7 +4523,7 @@ async function skillUpsert(ds, o) {
4624
4523
  s.name,
4625
4524
  s.description,
4626
4525
  s.tags,
4627
- ngram(`${s.name} ${s.description} ${s.tags} ${s.body}`)
4526
+ require_text.ngram(`${s.name} ${s.description} ${s.tags} ${s.body}`)
4628
4527
  ]);
4629
4528
  await logEvent$1(mgr, "skill.upsert", "skill", s.id, s.name);
4630
4529
  return s;
@@ -4644,7 +4543,7 @@ async function skillEnabled(ds, name, on) {
4644
4543
  if (!rows.length) return false;
4645
4544
  await mgr.query(`UPDATE skills SET enabled=?, updated=? WHERE id=?`, [
4646
4545
  on ? 1 : 0,
4647
- nowIso(),
4546
+ require_text.nowIso(),
4648
4547
  rows[0].id
4649
4548
  ]);
4650
4549
  return true;
@@ -4654,7 +4553,7 @@ async function skillRefAdd(ds, skillName, refPath, content) {
4654
4553
  return ds.transaction(async (mgr) => {
4655
4554
  const s = await mgr.query(`SELECT id FROM skills WHERE name=?`, [skillName]);
4656
4555
  if (!s.length) throw new Error(`skill not found: ${skillName}`);
4657
- const id = shortId([
4556
+ const id = require_text.shortId([
4658
4557
  "ref",
4659
4558
  s[0].id,
4660
4559
  refPath
@@ -4679,8 +4578,8 @@ async function projectCreate(ds, name, question = "") {
4679
4578
  duplicate: true
4680
4579
  };
4681
4580
  }
4682
- const now = nowIso();
4683
- const id = shortId(["proj", name], 10);
4581
+ const now = require_text.nowIso();
4582
+ const id = require_text.shortId(["proj", name], 10);
4684
4583
  await mgr.query(`INSERT INTO projects(id,name,question,status,created,updated) VALUES(?,?,?,'active',?,?)`, [
4685
4584
  id,
4686
4585
  name,
@@ -4697,7 +4596,7 @@ var TASK_STATUSES;
4697
4596
  var init_writes = require_rolldown_runtime.__esmMin((() => {
4698
4597
  init_entities$1();
4699
4598
  init_entities();
4700
- init_text();
4599
+ require_text.init_text();
4701
4600
  TASK_STATUSES = [
4702
4601
  "todo",
4703
4602
  "doing",
@@ -4738,7 +4637,7 @@ async function autoImportBuiltinSkills(env, dbFile) {
4738
4637
  }
4739
4638
  const { getOrm } = (init_orm(), require_rolldown_runtime.__toCommonJS(orm_exports));
4740
4639
  const writes = (init_writes(), require_rolldown_runtime.__toCommonJS(writes_exports));
4741
- const { parseFrontmatter } = (init_text(), require_rolldown_runtime.__toCommonJS(text_exports));
4640
+ const { parseFrontmatter } = (require_text.init_text(), require_rolldown_runtime.__toCommonJS(require_text.text_exports));
4742
4641
  const ds = await getOrm(dbFile);
4743
4642
  let count = 0;
4744
4643
  for (const entry of fs2.readdirSync(skillsDir)) {
@@ -5269,7 +5168,7 @@ function sqlLit(v) {
5269
5168
  }
5270
5169
  //#endregion
5271
5170
  //#region packages/ops/tools/src/config.ts
5272
- init_text();
5171
+ require_text.init_text();
5273
5172
  const CONFIG_REGISTRY = [
5274
5173
  {
5275
5174
  key: "eval.pass_threshold",
@@ -5382,11 +5281,11 @@ function configSet(db, key, value) {
5382
5281
  key,
5383
5282
  v,
5384
5283
  spec.note,
5385
- nowIso()
5284
+ require_text.nowIso()
5386
5285
  ]);
5387
5286
  db.run("INSERT INTO events(id,ts,actor,kind,entity,entity_id,payload) VALUES(?,?,?,?,?,?,?)", [
5388
5287
  `${key}-${Date.now()}-${Math.random().toString(16).slice(2, 8)}`,
5389
- nowIso(),
5288
+ require_text.nowIso(),
5390
5289
  "cli",
5391
5290
  "config.set",
5392
5291
  "config",
@@ -5499,7 +5398,7 @@ function run$11(env, action, rest, args) {
5499
5398
  * Writes (add) run on the TypeORM write service (src/writes.ts). */
5500
5399
  var job_cmds_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({ run: () => run$10 });
5501
5400
  init_fmt();
5502
- init_text();
5401
+ require_text.init_text();
5503
5402
  init_orm();
5504
5403
  init_writes();
5505
5404
  function run$10(env, action, rest, args) {
@@ -5647,7 +5546,7 @@ function execute(env, job) {
5647
5546
  store.jobFinish(runId, rc, output);
5648
5547
  if (rc === 0) ok(ctx, `${job.title} ok ${ms}ms`);
5649
5548
  else bad(ctx, `${job.title} rc=${rc} ${output.slice(0, 160)}`);
5650
- store.log("job.run", "job", job.id, `rc=${rc} ${nowIso()}`);
5549
+ store.log("job.run", "job", job.id, `rc=${rc} ${require_text.nowIso()}`);
5651
5550
  }
5652
5551
  /**
5653
5552
  * Concurrency guard for `job tick`: mkdir-based lock (same primitive the
@@ -5707,7 +5606,7 @@ var agent_cmds_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
5707
5606
  run: () => run$9
5708
5607
  });
5709
5608
  init_fmt();
5710
- init_text();
5609
+ require_text.init_text();
5711
5610
  /** Build the brief payload (where am I / what exists / what next).
5712
5611
  * Shared by the `agent brief` command and the WebUI dashboard. */
5713
5612
  function buildBrief(env) {
@@ -5725,7 +5624,7 @@ function buildBrief(env) {
5725
5624
  counts: stats,
5726
5625
  top_skills: skills.map((s) => ({
5727
5626
  name: s.name,
5728
- description: clip(s.description, 120)
5627
+ description: require_text.clip(s.description, 120)
5729
5628
  })),
5730
5629
  recent_notes: notes.map((n) => ({
5731
5630
  id: n.id,
@@ -5752,7 +5651,7 @@ function buildBrief(env) {
5752
5651
  };
5753
5652
  payload.unverified_claims = claims.filter((c) => c.status !== "supported").map((c) => ({
5754
5653
  id: c.id,
5755
- text: clip(c.text, 80),
5654
+ text: require_text.clip(c.text, 80),
5756
5655
  status: c.status
5757
5656
  }));
5758
5657
  if (!src.length) payload.next_actions.push(`ygl-trees research source add --title "..." --url "..."`);
@@ -5960,7 +5859,7 @@ function run$9(env, action, rest, args) {
5960
5859
  out(ctx, ` counts skills ${stats.skills} · kb ${stats.kb_notes} · jobs ${stats.jobs} · events ${stats.events}`);
5961
5860
  if (skills.length) {
5962
5861
  out(ctx, paint(C.bold, "\n available skills", ctx.color));
5963
- for (const s of skills) out(ctx, ` - ${s.name} ${paint(C.dim, clip(s.description, 90), ctx.color)}`);
5862
+ for (const s of skills) out(ctx, ` - ${s.name} ${paint(C.dim, require_text.clip(s.description, 90), ctx.color)}`);
5964
5863
  }
5965
5864
  out(ctx, paint(C.bold, "\n next actions", ctx.color));
5966
5865
  for (const a of payload.next_actions) out(ctx, ` → ${a}`);
@@ -6250,7 +6149,7 @@ var init_eval_enhance = require_rolldown_runtime.__esmMin((() => {
6250
6149
  * List commands run on TypeORM (src/orm.ts); search stays raw SQL (FTS5). */
6251
6150
  var cmds_exports$2 = /* @__PURE__ */ require_rolldown_runtime.__exportAll({ run: () => run$8 });
6252
6151
  init_fmt();
6253
- init_text();
6152
+ require_text.init_text();
6254
6153
  init_orm();
6255
6154
  init_writes();
6256
6155
  init_entities$1();
@@ -6291,7 +6190,7 @@ function run$8(env, action, rest, args) {
6291
6190
  return 2;
6292
6191
  }
6293
6192
  const engine = String(args.flags.engine || "");
6294
- return runWrite(env, (ds) => queryAdd(ds, project.id, text, engine, force), (r) => `query registered: ${r.id} ${clip(text, 60)}`);
6193
+ return runWrite(env, (ds) => queryAdd(ds, project.id, text, engine, force), (r) => `query registered: ${r.id} ${require_text.clip(text, 60)}`);
6295
6194
  }
6296
6195
  if (subAction === "attach") {
6297
6196
  if (!rest[1] || !rest[2]) {
@@ -6301,7 +6200,7 @@ function run$8(env, action, rest, args) {
6301
6200
  const note = String(args.flags.note || "");
6302
6201
  return getOrm(env.db.path).then((ds) => queryAttach(ds, project.id, rest[1], rest[2], note)).then((r) => {
6303
6202
  if (r.dup) out(ctx, paint(C.yellow, ` ! already attached: ${r.sourceId}`, ctx.color));
6304
- else ok(ctx, `attached: ${clip(r.sourceTitle || r.sourceId, 40)} → "${clip(r.queryText, 40)}"`);
6203
+ else ok(ctx, `attached: ${require_text.clip(r.sourceTitle || r.sourceId, 40)} → "${require_text.clip(r.queryText, 40)}"`);
6305
6204
  return 0;
6306
6205
  }).catch((e) => {
6307
6206
  bad(ctx, e?.message || String(e));
@@ -6387,7 +6286,7 @@ function run$8(env, action, rest, args) {
6387
6286
  return 2;
6388
6287
  }
6389
6288
  if (url && !/^https?:\/\/|^file:\/\//.test(url)) {
6390
- bad(ctx, `--url must be http(s):// or file:// (got: "${clip(url, 30)}")`);
6289
+ bad(ctx, `--url must be http(s):// or file:// (got: "${require_text.clip(url, 30)}")`);
6391
6290
  return 2;
6392
6291
  }
6393
6292
  const spec = {
@@ -6403,10 +6302,10 @@ function run$8(env, action, rest, args) {
6403
6302
  const qRef = String(args.flags.query || "");
6404
6303
  return getOrm(env.db.path).then(async (ds) => {
6405
6304
  const r = await sourceAdd(ds, project.id, spec);
6406
- writeResult(ctx, r, (row) => `source added: ${row.id} ${clip(row.title, 60)}`);
6305
+ writeResult(ctx, r, (row) => `source added: ${row.id} ${require_text.clip(row.title, 60)}`);
6407
6306
  if (qRef) {
6408
6307
  const at = await queryAttach(ds, project.id, qRef, r.row.id);
6409
- if (!ctx.json && !at.dup) out(ctx, paint(C.dim, ` attached to query: "${clip(at.queryText, 40)}"`, ctx.color));
6308
+ if (!ctx.json && !at.dup) out(ctx, paint(C.dim, ` attached to query: "${require_text.clip(at.queryText, 40)}"`, ctx.color));
6410
6309
  }
6411
6310
  return 0;
6412
6311
  }).catch((e) => {
@@ -6449,7 +6348,7 @@ function run$8(env, action, rest, args) {
6449
6348
  confidence: String(args.flags.confidence || configGet(env.db, "default_confidence")),
6450
6349
  tags: String(args.flags.tags || (thin ? "needs_review" : ""))
6451
6350
  });
6452
- writeResult(ctx, r, (row) => `fetched: ${row.id} ${clip(title, 60)}`);
6351
+ writeResult(ctx, r, (row) => `fetched: ${row.id} ${require_text.clip(title, 60)}`);
6453
6352
  if (!ctx.json) out(ctx, paint(C.dim, ` ${(text.length / 1e3).toFixed(1)}k chars text · ${metaDesc ? "meta description" : "no meta"}${thin ? " · thin content → tagged needs_review" : ""}`, ctx.color));
6454
6353
  return 0;
6455
6354
  }).catch((e) => {
@@ -6507,7 +6406,7 @@ function run$8(env, action, rest, args) {
6507
6406
  }
6508
6407
  table(ctx, store.sourceSearch(project.id, q).map((r) => ({
6509
6408
  id: r.id,
6510
- title: clip(r.title, 50),
6409
+ title: require_text.clip(r.title, 50),
6511
6410
  rel: r.relevance,
6512
6411
  conf: r.confidence,
6513
6412
  score: typeof r.score === "number" ? r.score.toFixed(2) : "-"
@@ -6561,7 +6460,7 @@ function run$8(env, action, rest, args) {
6561
6460
  }
6562
6461
  const note = String(args.flags.note || "");
6563
6462
  const locator = String(args.flags.locator || "");
6564
- return runWrite(env, (ds) => evidenceAdd(ds, project.id, sourceId, quote, note, locator, force), (r) => `evidence added: ${r.id} ${clip(quote, 50)}`);
6463
+ return runWrite(env, (ds) => evidenceAdd(ds, project.id, sourceId, quote, note, locator, force), (r) => `evidence added: ${r.id} ${require_text.clip(quote, 50)}`);
6565
6464
  }
6566
6465
  if (action === "evidence" && subAction === "assess") {
6567
6466
  const id = rest[1];
@@ -6594,7 +6493,7 @@ function run$8(env, action, rest, args) {
6594
6493
  else {
6595
6494
  head(ctx, `evidence assess: ${id}`);
6596
6495
  show(ctx, {
6597
- 引文: clip(ev.quote, 60),
6496
+ 引文: require_text.clip(ev.quote, 60),
6598
6497
  来源: ev.source_title || "-",
6599
6498
  模型评分: result.quality_score !== null ? `${result.quality_score}/5` : "离线",
6600
6499
  可靠性: result.reliability
@@ -6616,7 +6515,7 @@ function run$8(env, action, rest, args) {
6616
6515
  id: e.id,
6617
6516
  source: e.source?.title ?? "",
6618
6517
  locator: e.locator,
6619
- quote: clip(e.quote, 60),
6518
+ quote: require_text.clip(e.quote, 60),
6620
6519
  used_by: e.claimEvidence?.length ?? 0
6621
6520
  }));
6622
6521
  table(ctx, rows, [
@@ -6652,7 +6551,7 @@ function run$8(env, action, rest, args) {
6652
6551
  return 2;
6653
6552
  }
6654
6553
  const confidence = String(args.flags.confidence || configGet(env.db, "default_confidence"));
6655
- return runWrite(env, (ds) => claimAdd(ds, project.id, text, confidence, force), (r) => `claim added: ${r.id} ${clip(text, 60)}`);
6554
+ return runWrite(env, (ds) => claimAdd(ds, project.id, text, confidence, force), (r) => `claim added: ${r.id} ${require_text.clip(text, 60)}`);
6656
6555
  }
6657
6556
  if (subAction === "link") {
6658
6557
  if (!rest[1] || !rest[2]) {
@@ -6774,7 +6673,7 @@ function run$8(env, action, rest, args) {
6774
6673
  else {
6775
6674
  head(ctx, `claim evaluate: ${id}`);
6776
6675
  show(ctx, {
6777
- 断言: clip(claim.text, 60),
6676
+ 断言: require_text.clip(claim.text, 60),
6778
6677
  当前状态: claim.status,
6779
6678
  当前置信度: claim.confidence,
6780
6679
  模型评分: result.confidence_score !== null ? `${result.confidence_score}/5` : "离线",
@@ -6793,7 +6692,7 @@ function run$8(env, action, rest, args) {
6793
6692
  order: { created: "ASC" }
6794
6693
  })).map((c) => ({
6795
6694
  id: c.id,
6796
- text: clip(c.text, 60),
6695
+ text: require_text.clip(c.text, 60),
6797
6696
  status: c.status,
6798
6697
  confidence: c.confidence,
6799
6698
  sup: (c.claimEvidence ?? []).filter((ce) => ce.stance === "supports").length,
@@ -6966,7 +6865,7 @@ function run$7(env, action, rest, args) {
6966
6865
  * Store until their own migration batch. */
6967
6866
  var produce_cmds_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({ run: () => run$6 });
6968
6867
  init_fmt();
6969
- init_text();
6868
+ require_text.init_text();
6970
6869
  init_orm();
6971
6870
  init_writes();
6972
6871
  function run$6(env, action, rest, args) {
@@ -7013,7 +6912,7 @@ function run$6(env, action, rest, args) {
7013
6912
  lines.push("", "## 证据基础", "");
7014
6913
  const ev = store.evidenceList(pid);
7015
6914
  if (!ev.length) lines.push("_(尚无 evidence)_", "");
7016
- ev.forEach((e, i) => lines.push(`- [${i + 1}] ${e.source}:${clip(e.quote, 80)}`));
6915
+ ev.forEach((e, i) => lines.push(`- [${i + 1}] ${e.source}:${require_text.clip(e.quote, 80)}`));
7017
6916
  const content = lines.join("\n");
7018
6917
  return getOrm(env.db.path).then((ds) => artifactAdd(ds, pid, "outline", `${project.name} outline`, content)).then((r) => {
7019
6918
  if (ctx.json) console.log(JSON.stringify(r.row, null, 2));
@@ -7259,9 +7158,9 @@ function run$6(env, action, rest, args) {
7259
7158
  //#endregion
7260
7159
  //#region packages/techtree/model/src/writes.ts
7261
7160
  init_db();
7262
- init_text();
7161
+ require_text.init_text();
7263
7162
  async function markDirty(mgr, treeId) {
7264
- await mgr.query(`INSERT INTO node_index(tree_id,built_at,dirty) VALUES(?,?,1) ON CONFLICT(tree_id) DO UPDATE SET dirty=1`, [treeId, nowIso()]);
7163
+ await mgr.query(`INSERT INTO node_index(tree_id,built_at,dirty) VALUES(?,?,1) ON CONFLICT(tree_id) DO UPDATE SET dirty=1`, [treeId, require_text.nowIso()]);
7265
7164
  }
7266
7165
  /** R10.1 (0.30): tree-domain audit trail — overturns the 0.12 "no events"
7267
7166
  * exception. Same shape as the research-domain logEvent (raw SQL here since
@@ -7273,8 +7172,8 @@ async function logEvent(mgr, kind, entityId, payload, level = "info") {
7273
7172
  run
7274
7173
  }) : JSON.stringify(payload ?? {});
7275
7174
  await mgr.query(`INSERT INTO events(id,ts,actor,kind,entity,entity_id,payload,level) VALUES(?,?,?,?,?,?,?,?)`, [
7276
- shortId([kind, entityId], 12),
7277
- nowIso(),
7175
+ require_text.shortId([kind, entityId], 12),
7176
+ require_text.nowIso(),
7278
7177
  "cli",
7279
7178
  kind,
7280
7179
  "node",
@@ -7403,7 +7302,7 @@ async function buildIndex(mgr, treeId) {
7403
7302
  JSON.stringify(topo),
7404
7303
  JSON.stringify(tiers),
7405
7304
  JSON.stringify(inDegree),
7406
- nowIso()
7305
+ require_text.nowIso()
7407
7306
  ]);
7408
7307
  return {
7409
7308
  topo,
@@ -7418,13 +7317,13 @@ async function treeCreate(ds, name, projectId = "", note = "") {
7418
7317
  ...existing[0],
7419
7318
  duplicate: true
7420
7319
  };
7421
- const id = shortId(["tree", name], 10);
7320
+ const id = require_text.shortId(["tree", name], 10);
7422
7321
  await mgr.query(`INSERT INTO trees(id,project_id,name,note,created) VALUES(?,?,?,?,?)`, [
7423
7322
  id,
7424
7323
  projectId || null,
7425
7324
  name,
7426
7325
  note,
7427
- nowIso()
7326
+ require_text.nowIso()
7428
7327
  ]);
7429
7328
  await markDirty(mgr, id);
7430
7329
  return (await mgr.query(`SELECT * FROM trees WHERE id=?`, [id]))[0];
@@ -7437,7 +7336,7 @@ async function nodeAdd(ds, treeId, o) {
7437
7336
  row: ex[0],
7438
7337
  created: false
7439
7338
  };
7440
- const id = shortId([
7339
+ const id = require_text.shortId([
7441
7340
  "node",
7442
7341
  treeId,
7443
7342
  o.key
@@ -7454,14 +7353,14 @@ async function nodeAdd(ds, treeId, o) {
7454
7353
  o.cost_unit || "",
7455
7354
  o.payload || "",
7456
7355
  o.tags || "",
7457
- nowIso()
7356
+ require_text.nowIso()
7458
7357
  ]);
7459
7358
  await mgr.query(`INSERT INTO nodes_fts(id,key,name,tags,ngram) VALUES(?,?,?,?,?)`, [
7460
7359
  id,
7461
7360
  o.key,
7462
7361
  name,
7463
7362
  o.tags || "",
7464
- ngram(`${o.key} ${name} ${o.tags || ""}`)
7363
+ require_text.ngram(`${o.key} ${name} ${o.tags || ""}`)
7465
7364
  ]);
7466
7365
  await markDirty(mgr, treeId);
7467
7366
  await logEvent(mgr, "node.add", id, {
@@ -7522,7 +7421,7 @@ async function link(ds, treeId, parentKey, childKey, o = {}) {
7522
7421
  rel
7523
7422
  ]);
7524
7423
  const duplicate = before.length > 0;
7525
- const id = duplicate ? before[0].id : shortId([
7424
+ const id = duplicate ? before[0].id : require_text.shortId([
7526
7425
  "edge",
7527
7426
  p[0].id,
7528
7427
  c[0].id,
@@ -7543,7 +7442,7 @@ async function link(ds, treeId, parentKey, childKey, o = {}) {
7543
7442
  o.min_level ?? 1,
7544
7443
  o.weight ?? 1,
7545
7444
  o.note || "",
7546
- nowIso()
7445
+ require_text.nowIso()
7547
7446
  ]);
7548
7447
  await rebuildClosure(mgr, treeId);
7549
7448
  await logEvent(mgr, "node.link", id, {
@@ -7604,7 +7503,7 @@ async function condAdd(ds, treeId, keyOrId, o) {
7604
7503
  if (!n.length) throw new Error(`node not found: ${keyOrId}`);
7605
7504
  const kind = o.kind || "flag";
7606
7505
  if (!COND_KINDS.includes(kind)) throw new Error(`kind must be one of ${COND_KINDS.join("|")}`);
7607
- const id = shortId([
7506
+ const id = require_text.shortId([
7608
7507
  "cond",
7609
7508
  n[0].id,
7610
7509
  o.name
@@ -7651,7 +7550,7 @@ async function stateSet(ds, treeId, keyOrId, status, context = "default", level
7651
7550
  status,
7652
7551
  level,
7653
7552
  status === "unlocked" ? 1 : 0,
7654
- nowIso()
7553
+ require_text.nowIso()
7655
7554
  ]);
7656
7555
  await logEvent(mgr, status === "unlocked" ? "node.unlock" : "node.lock", n[0].id, {
7657
7556
  tree: treeId,
@@ -7744,13 +7643,13 @@ async function importTree(ds, spec, opts = {}) {
7744
7643
  let tid;
7745
7644
  if (existing.length) tid = existing[0].id;
7746
7645
  else {
7747
- tid = shortId(["tree", name], 10);
7646
+ tid = require_text.shortId(["tree", name], 10);
7748
7647
  await mgr.query(`INSERT INTO trees(id,project_id,name,note,created) VALUES(?,?,?,?,?)`, [
7749
7648
  tid,
7750
7649
  null,
7751
7650
  name,
7752
7651
  String(spec.tree?.note || ""),
7753
- nowIso()
7652
+ require_text.nowIso()
7754
7653
  ]);
7755
7654
  }
7756
7655
  const nodeId = /* @__PURE__ */ new Map();
@@ -7760,7 +7659,7 @@ async function importTree(ds, spec, opts = {}) {
7760
7659
  nodeId.set(String(n.key), ex[0].id);
7761
7660
  continue;
7762
7661
  }
7763
- const id = shortId([
7662
+ const id = require_text.shortId([
7764
7663
  "node",
7765
7664
  tid,
7766
7665
  String(n.key)
@@ -7778,14 +7677,14 @@ async function importTree(ds, spec, opts = {}) {
7778
7677
  n.cost_unit === void 0 ? "" : String(n.cost_unit),
7779
7678
  n.payload === void 0 || n.payload === null ? "" : typeof n.payload === "object" ? JSON.stringify(n.payload) : String(n.payload),
7780
7679
  n.tags === void 0 ? "" : String(n.tags),
7781
- nowIso()
7680
+ require_text.nowIso()
7782
7681
  ]);
7783
7682
  await mgr.query(`INSERT INTO nodes_fts(id,key,name,tags,ngram) VALUES(?,?,?,?,?)`, [
7784
7683
  id,
7785
7684
  String(n.key),
7786
7685
  nm,
7787
7686
  n.tags === void 0 ? "" : String(n.tags),
7788
- ngram(`${n.key} ${nm} ${n.tags || ""}`)
7687
+ require_text.ngram(`${n.key} ${nm} ${n.tags || ""}`)
7789
7688
  ]);
7790
7689
  }
7791
7690
  for (const e of edges) {
@@ -7796,7 +7695,7 @@ async function importTree(ds, spec, opts = {}) {
7796
7695
  ON CONFLICT(parent_id,child_id,rel) DO UPDATE SET
7797
7696
  mode=excluded.mode, required=excluded.required, min_level=excluded.min_level,
7798
7697
  weight=excluded.weight, note=excluded.note`, [
7799
- shortId([
7698
+ require_text.shortId([
7800
7699
  "edge",
7801
7700
  tid,
7802
7701
  pid,
@@ -7812,7 +7711,7 @@ async function importTree(ds, spec, opts = {}) {
7812
7711
  Number(e.min_level ?? 1),
7813
7712
  Number(e.weight ?? 1),
7814
7713
  String(e.note || ""),
7815
- nowIso()
7714
+ require_text.nowIso()
7816
7715
  ]);
7817
7716
  }
7818
7717
  for (const c of conds) {
@@ -7820,7 +7719,7 @@ async function importTree(ds, spec, opts = {}) {
7820
7719
  await mgr.query(`DELETE FROM node_conditions WHERE node_id=? AND name=?`, [nid, String(c.name)]);
7821
7720
  await mgr.query(`INSERT INTO node_conditions(id,node_id,name,kind,expr,op,value,required,effect,weight,note)
7822
7721
  VALUES(?,?,?,?,?,?,?,?,?,?,?)`, [
7823
- shortId([
7722
+ require_text.shortId([
7824
7723
  "cond",
7825
7724
  tid,
7826
7725
  nid,
@@ -7869,7 +7768,7 @@ var cmds_exports$1 = /* @__PURE__ */ require_rolldown_runtime.__exportAll({ run:
7869
7768
  init_fmt();
7870
7769
  init_orm();
7871
7770
  init_eval();
7872
- init_text();
7771
+ require_text.init_text();
7873
7772
  function run$5(env, action, rest, args) {
7874
7773
  const { ctx, db } = env;
7875
7774
  const trees = new TreeStore(db);
@@ -8223,12 +8122,12 @@ function run$5(env, action, rest, args) {
8223
8122
  try {
8224
8123
  const run = process.env.YGL_RUN_ID || "";
8225
8124
  db.run("INSERT INTO events(id,ts,actor,kind,entity,entity_id,payload,level) VALUES(?,?,?,?,?,?,?,'info')", [
8226
- shortId([
8125
+ require_text.shortId([
8227
8126
  "eval.gate",
8228
8127
  "node",
8229
8128
  key
8230
8129
  ], 12),
8231
- nowIso(),
8130
+ require_text.nowIso(),
8232
8131
  "cli",
8233
8132
  "eval.gate",
8234
8133
  "node",
@@ -8406,12 +8305,12 @@ function run$5(env, action, rest, args) {
8406
8305
  try {
8407
8306
  const run = process.env.YGL_RUN_ID || "";
8408
8307
  db.run("INSERT INTO events(id,ts,actor,kind,entity,entity_id,payload,level) VALUES(?,?,?,?,?,?,?,'info')", [
8409
- shortId([
8308
+ require_text.shortId([
8410
8309
  "eval.ready",
8411
8310
  "tree",
8412
8311
  tid
8413
8312
  ], 12),
8414
- nowIso(),
8313
+ require_text.nowIso(),
8415
8314
  "cli",
8416
8315
  "eval.ready",
8417
8316
  "tree",
@@ -8714,7 +8613,7 @@ function parseState(args) {
8714
8613
  * Writes run on the TypeORM write service (src/writes.ts). */
8715
8614
  var skill_cmds_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({ run: () => run$4 });
8716
8615
  init_fmt();
8717
- init_text();
8616
+ require_text.init_text();
8718
8617
  init_orm();
8719
8618
  init_writes();
8720
8619
  function run$4(env, action, rest, args) {
@@ -8730,7 +8629,8 @@ function run$4(env, action, rest, args) {
8730
8629
  switch (action) {
8731
8630
  case "import": {
8732
8631
  if (!need(name, "file")) return 2;
8733
- const { meta, body } = parseFrontmatter(node_fs.readFileSync(name, "utf8"));
8632
+ const raw = node_fs.readFileSync(name, "utf8");
8633
+ const { meta, body } = require_text.parseFrontmatter(raw);
8734
8634
  const spec = {
8735
8635
  name: meta.name || node_path.basename(name, ".md"),
8736
8636
  description: meta.description || "",
@@ -9048,7 +8948,7 @@ function wrap(text, indent = 4) {
9048
8948
  * Writes (add/ingest) run on the TypeORM write service (src/writes.ts). */
9049
8949
  var cmds_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({ run: () => run$3 });
9050
8950
  init_fmt();
9051
- init_text();
8951
+ require_text.init_text();
9052
8952
  init_orm();
9053
8953
  init_writes();
9054
8954
  function run$3(env, action, rest, args) {
@@ -9081,7 +8981,7 @@ function run$3(env, action, rest, args) {
9081
8981
  confidence: String(args.flags.confidence || configGet(env.db, "default_confidence")),
9082
8982
  force
9083
8983
  })).then((r) => {
9084
- writeResult(ctx, r, (row) => `note stored: ${row.id} ${clip(title, 50)}`);
8984
+ writeResult(ctx, r, (row) => `note stored: ${row.id} ${require_text.clip(title, 50)}`);
9085
8985
  return 0;
9086
8986
  }).catch((e) => {
9087
8987
  bad(ctx, e?.message || String(e));
@@ -9107,7 +9007,7 @@ function run$3(env, action, rest, args) {
9107
9007
  const orig = idToRaw.get(rr.id);
9108
9008
  return {
9109
9009
  id: rr.id,
9110
- title: clip(orig.title, 42),
9010
+ title: require_text.clip(orig.title, 42),
9111
9011
  semantic: rr.semantic_relevance !== null ? rr.semantic_relevance.toFixed(2) : "离线",
9112
9012
  orig_rank: rr.original_rank,
9113
9013
  tags: orig.tags || "-",
@@ -9139,7 +9039,7 @@ function run$3(env, action, rest, args) {
9139
9039
  }
9140
9040
  table(ctx, raw.map((r) => ({
9141
9041
  id: r.id,
9142
- title: clip(r.title, 46),
9042
+ title: require_text.clip(r.title, 46),
9143
9043
  tags: r.tags || "-",
9144
9044
  conf: r.confidence,
9145
9045
  reuse: r.reuse,
@@ -9240,7 +9140,7 @@ function run$3(env, action, rest, args) {
9240
9140
  }
9241
9141
  const forceKb = args.flags.force === true || args.flags.force === "true";
9242
9142
  return getOrm(env.db.path).then((ds) => kbIngestArtifact(ds, rest[0], forceKb)).then((r) => {
9243
- writeResult(ctx, r, (row) => `artifact ingested into kb: ${row.id} ${clip(row.title, 50)}`);
9143
+ writeResult(ctx, r, (row) => `artifact ingested into kb: ${row.id} ${require_text.clip(row.title, 50)}`);
9244
9144
  return 0;
9245
9145
  }).catch((e) => {
9246
9146
  bad(ctx, e?.message || String(e));
@@ -9266,7 +9166,7 @@ function run$3(env, action, rest, args) {
9266
9166
  origin: `kb:${note.id}`
9267
9167
  })).then((s) => {
9268
9168
  ok(ctx, `promoted to skill: ${s.name}`);
9269
- out(ctx, paint(C.dim, ` L1: ${clip(String(s.description), 100)}`, ctx.color));
9169
+ out(ctx, paint(C.dim, ` L1: ${require_text.clip(String(s.description), 100)}`, ctx.color));
9270
9170
  return 0;
9271
9171
  }).catch((e) => {
9272
9172
  bad(ctx, e?.message || String(e));
@@ -9316,7 +9216,8 @@ function run$3(env, action, rest, args) {
9316
9216
  return 1;
9317
9217
  }
9318
9218
  const items = importable.map((f) => {
9319
- const { meta, body } = parseFrontmatter(node_fs.readFileSync(f, "utf8"));
9219
+ const raw = node_fs.readFileSync(f, "utf8");
9220
+ const { meta, body } = require_text.parseFrontmatter(raw);
9320
9221
  const heading = /^#\s+(.+)\s*$/m.exec(body)?.[1]?.trim();
9321
9222
  return {
9322
9223
  title: meta.title || meta.name || heading || node_path.basename(f, ".md"),
@@ -9361,7 +9262,7 @@ var rels_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
9361
9262
  run: () => run$2
9362
9263
  });
9363
9264
  init_fmt();
9364
- init_text();
9265
+ require_text.init_text();
9365
9266
  init_orm();
9366
9267
  const REL_TYPES = [
9367
9268
  "node",
@@ -9494,7 +9395,7 @@ async function relAdd(env, srcRef, dstRef, rel = "related") {
9494
9395
  row: (await mgr.query(`SELECT * FROM relations WHERE id=?`, [ex[0].id]))[0],
9495
9396
  duplicate: true
9496
9397
  };
9497
- const id = shortId([
9398
+ const id = require_text.shortId([
9498
9399
  "rel",
9499
9400
  src.id,
9500
9401
  dst.id,
@@ -9507,15 +9408,15 @@ async function relAdd(env, srcRef, dstRef, rel = "related") {
9507
9408
  dst.type,
9508
9409
  dst.id,
9509
9410
  rel,
9510
- nowIso()
9411
+ require_text.nowIso()
9511
9412
  ]);
9512
9413
  await mgr.query(`INSERT INTO events(id,ts,actor,kind,entity,entity_id,payload) VALUES(?,?,?,?,?,?,?)`, [
9513
- shortId([
9414
+ require_text.shortId([
9514
9415
  "ev",
9515
9416
  "rel.add",
9516
9417
  id
9517
9418
  ], 12),
9518
- nowIso(),
9419
+ require_text.nowIso(),
9519
9420
  "cli",
9520
9421
  "rel.add",
9521
9422
  "relation",
@@ -11159,6 +11060,20 @@ async function main(argv) {
11159
11060
  });
11160
11061
  } catch (e) {
11161
11062
  if (e instanceof StartupError) {
11063
+ if (group === "plugin") {
11064
+ const pluginCmds = await Promise.resolve().then(() => plugin_exports);
11065
+ const { dbPath } = await Promise.resolve().then(() => (init_db(), db_exports));
11066
+ const env2 = {
11067
+ home,
11068
+ dbFile: dbPath(home),
11069
+ ctx,
11070
+ db: null,
11071
+ store: null,
11072
+ cordis: null
11073
+ };
11074
+ out(ctx, paint(C.yellow, " ! degraded mode: user plugins failed to load — plugin commands only", ctx.color));
11075
+ return pluginCmds.runPluginCommand(env2, action || "list", args._.slice(2), args);
11076
+ }
11162
11077
  reportStartupFailure(e, home, VERSION);
11163
11078
  return 1;
11164
11079
  }