ygl-trees 0.76.1 → 0.77.1

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.
@@ -0,0 +1,172 @@
1
+ const require_rolldown_runtime = require("./rolldown-runtime-C96Ew50Q.cjs");
2
+ //#region packages/core/text/src/text.ts
3
+ var text_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
4
+ clip: () => clip,
5
+ contentHash: () => contentHash,
6
+ ngram: () => ngram,
7
+ nowIso: () => nowIso,
8
+ parseFrontmatter: () => parseFrontmatter,
9
+ sha1: () => sha1,
10
+ shortId: () => shortId,
11
+ slug: () => slug,
12
+ splitTags: () => splitTags,
13
+ stampId: () => stampId
14
+ });
15
+ function nowIso() {
16
+ const d = /* @__PURE__ */ new Date();
17
+ const p = (n) => String(n).padStart(2, "0");
18
+ return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`;
19
+ }
20
+ function stampId() {
21
+ const d = /* @__PURE__ */ new Date();
22
+ const p = (n) => String(n).padStart(2, "0");
23
+ return `${d.getFullYear()}${p(d.getMonth() + 1)}${p(d.getDate())}-${p(d.getHours())}${p(d.getMinutes())}${p(d.getSeconds())}`;
24
+ }
25
+ function slug(text, limit = 40) {
26
+ const s = (text || "").trim().toLowerCase().replace(new RegExp(`[^\\w${CJK}]+`, "gu"), "-").replace(/^-+|-+$/g, "");
27
+ if (s.length <= limit) return s || "item";
28
+ return s.slice(0, limit).replace(/-+$/, "") || "item";
29
+ }
30
+ /**
31
+ * Tokenize mixed Chinese/English text for SQLite FTS5.
32
+ *
33
+ * FTS5's default unicode61 tokenizer treats a whole CJK sentence as one token,
34
+ * which makes Chinese search degrade to exact match. We expand CJK runs into
35
+ * character bigrams and keep latin words intact.
36
+ */
37
+ function ngram(text) {
38
+ const src = (text || "").normalize("NFKC").toLowerCase();
39
+ const out = [];
40
+ const segs = src.match(CJK_RUN_RE) || [];
41
+ for (const seg of segs) if (CJK_ONLY_RE.test(seg)) {
42
+ if (seg.length === 1) out.push(seg);
43
+ else for (let i = 0; i < seg.length - 1; i++) out.push(seg.slice(i, i + 2));
44
+ } else {
45
+ const w = seg.replace(/^[^\w]+|[^\w]+$/gu, "");
46
+ if (w) out.push(w);
47
+ }
48
+ return out.join(" ");
49
+ }
50
+ function sha1(text) {
51
+ return require("node:crypto").createHash("sha1").update(text || "").digest("hex");
52
+ }
53
+ /** Content hash for idempotent writes (single source: store writes and the
54
+ * TypeORM write service must produce identical hashes); --force salts it
55
+ * so a duplicate row is explicitly distinct (queryable via `db dups`). */
56
+ function contentHash(content, force) {
57
+ return sha1(content) + (force ? `#f${Date.now()}${Math.random()}` : "");
58
+ }
59
+ function shortId(parts, n = 8) {
60
+ return sha1(parts.join("|") + Date.now() + Math.random()).slice(0, n);
61
+ }
62
+ /** Truncate for table display, collapsing newlines. */
63
+ function clip(text, n = 40) {
64
+ const one = (text || "").replace(/\s+/g, " ").trim();
65
+ return one.length <= n ? one : one.slice(0, Math.max(1, n - 1)) + "…";
66
+ }
67
+ /**
68
+ * Minimal SKILL.md frontmatter parser: supports `key: value`, quoted scalars,
69
+ * folded blocks (`>-` / `>`) and inline `a,b` lists.
70
+ */
71
+ function parseFrontmatter(raw) {
72
+ const text = raw.replace(/^/, "");
73
+ const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/.exec(text);
74
+ if (!m) return {
75
+ meta: {},
76
+ body: text
77
+ };
78
+ const meta = {};
79
+ const lines = m[1].split(/\r?\n/);
80
+ let key = null;
81
+ let folded = null;
82
+ const flush = () => {
83
+ if (key && folded) meta[key] = folded.join(" ").replace(/\s+/g, " ").trim();
84
+ key = null;
85
+ folded = null;
86
+ };
87
+ for (const line of lines) {
88
+ const kv = /^([A-Za-z_][\w-]*)\s*:\s*(.*)$/.exec(line);
89
+ if (kv && !/^\s/.test(line)) {
90
+ flush();
91
+ key = kv[1];
92
+ const v = kv[2].trim();
93
+ if (v === ">-" || v === ">" || v === "|" || v === "|-") folded = [];
94
+ else {
95
+ meta[key] = v.replace(/^["']|["']$/g, "");
96
+ key = null;
97
+ }
98
+ continue;
99
+ }
100
+ if (key && folded) folded.push(line.trim());
101
+ }
102
+ flush();
103
+ return {
104
+ meta,
105
+ body: text.slice(m[0].length)
106
+ };
107
+ }
108
+ function splitTags(v) {
109
+ return (v || "").split(/[,,;;\s]+/).map((s) => s.trim()).filter(Boolean);
110
+ }
111
+ var CJK, CJK_RUN_RE, CJK_ONLY_RE;
112
+ var init_text = require_rolldown_runtime.__esmMin((() => {
113
+ CJK = "\\u4e00-\\u9fff\\u3400-\\u4dbf\\uf900-\\ufaff";
114
+ new RegExp(`[${CJK}]`, "u");
115
+ CJK_RUN_RE = new RegExp(`[${CJK}]+|[^\\s${CJK}]+`, "gu");
116
+ CJK_ONLY_RE = new RegExp(`^[${CJK}]+$`, "u");
117
+ }));
118
+ //#endregion
119
+ Object.defineProperty(exports, "clip", {
120
+ enumerable: true,
121
+ get: function() {
122
+ return clip;
123
+ }
124
+ });
125
+ Object.defineProperty(exports, "contentHash", {
126
+ enumerable: true,
127
+ get: function() {
128
+ return contentHash;
129
+ }
130
+ });
131
+ Object.defineProperty(exports, "init_text", {
132
+ enumerable: true,
133
+ get: function() {
134
+ return init_text;
135
+ }
136
+ });
137
+ Object.defineProperty(exports, "ngram", {
138
+ enumerable: true,
139
+ get: function() {
140
+ return ngram;
141
+ }
142
+ });
143
+ Object.defineProperty(exports, "nowIso", {
144
+ enumerable: true,
145
+ get: function() {
146
+ return nowIso;
147
+ }
148
+ });
149
+ Object.defineProperty(exports, "parseFrontmatter", {
150
+ enumerable: true,
151
+ get: function() {
152
+ return parseFrontmatter;
153
+ }
154
+ });
155
+ Object.defineProperty(exports, "sha1", {
156
+ enumerable: true,
157
+ get: function() {
158
+ return sha1;
159
+ }
160
+ });
161
+ Object.defineProperty(exports, "shortId", {
162
+ enumerable: true,
163
+ get: function() {
164
+ return shortId;
165
+ }
166
+ });
167
+ Object.defineProperty(exports, "text_exports", {
168
+ enumerable: true,
169
+ get: function() {
170
+ return text_exports;
171
+ }
172
+ });
@@ -162,9 +162,16 @@ function pnpm(home, args) {
162
162
  // there. Requires pnpm >= 9.4.
163
163
  const pm = process.env.YGL_PACKAGE_MANAGER || "pnpm";
164
164
  if (process.platform === "win32") {
165
- const q = (s) => `"${String(s).replace(/["&|<>^]/g, "")}"`;
166
165
  const exe = resolvePm(pm);
167
- (0, node_child_process_1.execFileSync)([q(exe), ...args.map(q), "--dir", q(profileDir(home)), "--ignore-workspace"].join(" "), { stdio: "pipe", shell: true });
166
+ // DEP0190 fix (a2a 7aa5c871 cosmetic): avoid shell:true with args —
167
+ // invoke cmd explicitly instead, args are properly escaped by spawnSync.
168
+ const { spawnSync } = require("node:child_process");
169
+ const r = spawnSync("cmd", ["/c", exe, ...args, "--dir", profileDir(home), "--ignore-workspace"], { stdio: "pipe" });
170
+ if (r.status !== 0) {
171
+ const err = new Error(String(r.stderr || r.stdout || `pnpm exited ${r.status}`));
172
+ err.status = r.status;
173
+ throw err;
174
+ }
168
175
  return;
169
176
  }
170
177
  (0, node_child_process_1.execFileSync)(pm, [...args, "--dir", profileDir(home), "--ignore-workspace"], { stdio: "pipe" });
@@ -175,10 +182,10 @@ function resolvePm(pm) {
175
182
  return cachedPm || pm;
176
183
  cachedPm = null;
177
184
  try {
178
- const where = (0, node_child_process_1.execFileSync)("where", [pm], { stdio: "pipe", shell: true }).toString().split(/\r?\n/).filter(Boolean);
185
+ const where = (0, node_child_process_1.execFileSync)("where", [pm], { stdio: "pipe", shell: false }).toString().split(/\r?\n/).filter(Boolean);
179
186
  for (const candidate of where) {
180
187
  try {
181
- (0, node_child_process_1.execFileSync)([q2(candidate), "--version"].join(" "), { stdio: "pipe", shell: true });
188
+ (0, node_child_process_1.execFileSync)("cmd", ["/c", candidate, "--version"], { stdio: "pipe" });
182
189
  cachedPm = candidate;
183
190
  return candidate;
184
191
  }
@@ -194,6 +201,28 @@ const q2 = (s) => `"${String(s).replace(/["&|<>^]/g, "")}"`;
194
201
  async function installPlugin(home, spec) {
195
202
  initProfile(home);
196
203
  const abs = path.resolve(spec);
204
+ // P0 fix (a2a 7aa5c871): validate local paths BEFORE recording anything —
205
+ // a bad path previously degraded to basename "plugin" and bricked the home.
206
+ if (fs.existsSync(abs) && fs.statSync(abs).isDirectory()) {
207
+ // P2 fix: read the real package name, never trust basename
208
+ const pkgPath = path.join(abs, "package.json");
209
+ if (!fs.existsSync(pkgPath)) {
210
+ throw new Error(`local plugin directory has no package.json: ${abs}`);
211
+ }
212
+ try {
213
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
214
+ if (!pkg.name || typeof pkg.name !== "string") {
215
+ throw new Error(`package.json missing "name" field: ${abs}`);
216
+ }
217
+ }
218
+ catch (e) {
219
+ throw new Error(`invalid package.json in ${abs}: ${e?.message || e}`);
220
+ }
221
+ }
222
+ else if (spec.startsWith(".") || spec.startsWith("/") || spec.startsWith("\\") || /^[A-Z]:/.test(spec)) {
223
+ // Looks like a path but doesn't exist — reject before recording
224
+ throw new Error(`plugin path not found: ${abs}`);
225
+ }
197
226
  const installSpec = fs.existsSync(abs) && fs.statSync(abs).isDirectory() ? `link:${abs}` : spec;
198
227
  const existing = readUserBundle(home).find((p) => p.spec === installSpec || p.spec === spec);
199
228
  if (existing)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ygl-trees",
3
- "version": "0.76.1",
3
+ "version": "0.77.1",
4
4
  "description": "猿光 · 科技树 — database-centric CLI for research → production → knowledge reuse, built for AI agents.",
5
5
  "type": "commonjs",
6
6
  "main": "dist/apps/cli/index.js",
@@ -25,9 +25,9 @@
25
25
  "node-sqlite3-wasm": "^0.8.61",
26
26
  "reflect-metadata": "^0.2.2",
27
27
  "typeorm": "^1.1.2",
28
+ "@deepseek-ai/cordis": "~4.0.5-alpha.2",
28
29
  "@deepseek-ai/cordis-plugin-timer": "~1.1.7-alpha.2",
29
30
  "@deepseek-ai/cosmokit": "~1.8.6-alpha.2",
30
- "@deepseek-ai/cordis": "~4.0.5-alpha.2",
31
31
  "@deepseek-ai/schemastery": "~3.18.5-alpha.2"
32
32
  },
33
33
  "devDependencies": {