@coralai/sps-cli 0.50.24 → 0.51.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.
Files changed (83) hide show
  1. package/README.md +18 -1
  2. package/dist/commands/projectInit.d.ts +15 -0
  3. package/dist/commands/projectInit.d.ts.map +1 -1
  4. package/dist/commands/projectInit.js +191 -3
  5. package/dist/commands/projectInit.js.map +1 -1
  6. package/dist/commands/wikiCommand.d.ts +77 -0
  7. package/dist/commands/wikiCommand.d.ts.map +1 -0
  8. package/dist/commands/wikiCommand.js +489 -0
  9. package/dist/commands/wikiCommand.js.map +1 -0
  10. package/dist/console/routes/projects.d.ts.map +1 -1
  11. package/dist/console/routes/projects.js +1 -0
  12. package/dist/console/routes/projects.js.map +1 -1
  13. package/dist/console-assets/assets/index-DRhdpvew.css +10 -0
  14. package/dist/console-assets/assets/{index-QBai48VV.js → index-WUGCBcyb.js} +3 -3
  15. package/dist/console-assets/index.html +2 -2
  16. package/dist/core/taskPrompts.d.ts +12 -0
  17. package/dist/core/taskPrompts.d.ts.map +1 -1
  18. package/dist/core/taskPrompts.js +14 -0
  19. package/dist/core/taskPrompts.js.map +1 -1
  20. package/dist/core/wiki/frontmatter.d.ts +55 -0
  21. package/dist/core/wiki/frontmatter.d.ts.map +1 -0
  22. package/dist/core/wiki/frontmatter.js +109 -0
  23. package/dist/core/wiki/frontmatter.js.map +1 -0
  24. package/dist/core/wiki/hot.d.ts +27 -0
  25. package/dist/core/wiki/hot.d.ts.map +1 -0
  26. package/dist/core/wiki/hot.js +124 -0
  27. package/dist/core/wiki/hot.js.map +1 -0
  28. package/dist/core/wiki/index-builder.d.ts +37 -0
  29. package/dist/core/wiki/index-builder.d.ts.map +1 -0
  30. package/dist/core/wiki/index-builder.js +130 -0
  31. package/dist/core/wiki/index-builder.js.map +1 -0
  32. package/dist/core/wiki/linter.d.ts +76 -0
  33. package/dist/core/wiki/linter.d.ts.map +1 -0
  34. package/dist/core/wiki/linter.js +280 -0
  35. package/dist/core/wiki/linter.js.map +1 -0
  36. package/dist/core/wiki/log.d.ts +24 -0
  37. package/dist/core/wiki/log.d.ts.map +1 -0
  38. package/dist/core/wiki/log.js +107 -0
  39. package/dist/core/wiki/log.js.map +1 -0
  40. package/dist/core/wiki/manifest.d.ts +59 -0
  41. package/dist/core/wiki/manifest.d.ts.map +1 -0
  42. package/dist/core/wiki/manifest.js +180 -0
  43. package/dist/core/wiki/manifest.js.map +1 -0
  44. package/dist/core/wiki/page.d.ts +72 -0
  45. package/dist/core/wiki/page.d.ts.map +1 -0
  46. package/dist/core/wiki/page.js +221 -0
  47. package/dist/core/wiki/page.js.map +1 -0
  48. package/dist/core/wiki/reader.d.ts +102 -0
  49. package/dist/core/wiki/reader.d.ts.map +1 -0
  50. package/dist/core/wiki/reader.js +225 -0
  51. package/dist/core/wiki/reader.js.map +1 -0
  52. package/dist/core/wiki/scaffold.d.ts +42 -0
  53. package/dist/core/wiki/scaffold.d.ts.map +1 -0
  54. package/dist/core/wiki/scaffold.js +223 -0
  55. package/dist/core/wiki/scaffold.js.map +1 -0
  56. package/dist/core/wiki/searcher.d.ts +73 -0
  57. package/dist/core/wiki/searcher.d.ts.map +1 -0
  58. package/dist/core/wiki/searcher.js +216 -0
  59. package/dist/core/wiki/searcher.js.map +1 -0
  60. package/dist/core/wiki/sources.d.ts +84 -0
  61. package/dist/core/wiki/sources.d.ts.map +1 -0
  62. package/dist/core/wiki/sources.js +261 -0
  63. package/dist/core/wiki/sources.js.map +1 -0
  64. package/dist/core/wiki/types.d.ts +904 -0
  65. package/dist/core/wiki/types.d.ts.map +1 -0
  66. package/dist/core/wiki/types.js +109 -0
  67. package/dist/core/wiki/types.js.map +1 -0
  68. package/dist/engines/StageEngine.d.ts +17 -1
  69. package/dist/engines/StageEngine.d.ts.map +1 -1
  70. package/dist/engines/StageEngine.js +85 -0
  71. package/dist/engines/StageEngine.js.map +1 -1
  72. package/dist/main.js +78 -1
  73. package/dist/main.js.map +1 -1
  74. package/dist/services/ProjectService.d.ts +2 -0
  75. package/dist/services/ProjectService.d.ts.map +1 -1
  76. package/dist/services/ProjectService.js.map +1 -1
  77. package/dist/shared/wikiPaths.d.ts +38 -0
  78. package/dist/shared/wikiPaths.d.ts.map +1 -0
  79. package/dist/shared/wikiPaths.js +89 -0
  80. package/dist/shared/wikiPaths.js.map +1 -0
  81. package/package.json +1 -1
  82. package/skills/wiki-update/SKILL.md +300 -0
  83. package/dist/console-assets/assets/index-BgOHCIG1.css +0 -10
@@ -0,0 +1,216 @@
1
+ const DEFAULT_OPTS = {
2
+ k1: 1.5,
3
+ b: 0.75,
4
+ fieldWeights: { title: 3, tags: 2, tldr: 2, body: 1 },
5
+ };
6
+ // ─── Tokenization ─────────────────────────────────────────────────
7
+ /**
8
+ * 把文本切成 token:
9
+ * - ASCII 单词组(含数字、`_`、`-`),≥ 2 字符
10
+ * - 单个汉字
11
+ * - lowercase 归一化
12
+ * - 去 stop words
13
+ *
14
+ * **不**做 stemming(pipelining → pipeline)—— SPS 文档技术词多,stemming
15
+ * 引入更多噪声而不是信号。
16
+ */
17
+ const STOP_WORDS = new Set([
18
+ // English stop words
19
+ 'a',
20
+ 'an',
21
+ 'and',
22
+ 'are',
23
+ 'as',
24
+ 'at',
25
+ 'be',
26
+ 'but',
27
+ 'by',
28
+ 'do',
29
+ 'for',
30
+ 'has',
31
+ 'have',
32
+ 'in',
33
+ 'is',
34
+ 'it',
35
+ 'its',
36
+ 'of',
37
+ 'on',
38
+ 'or',
39
+ 'that',
40
+ 'the',
41
+ 'this',
42
+ 'to',
43
+ 'was',
44
+ 'were',
45
+ 'will',
46
+ 'with',
47
+ // Chinese stop words (常见高频虚词)
48
+ '的',
49
+ '了',
50
+ '是',
51
+ '和',
52
+ '或',
53
+ '在',
54
+ '有',
55
+ '我',
56
+ '你',
57
+ '他',
58
+ '它',
59
+ '这',
60
+ '那',
61
+ '与',
62
+ ]);
63
+ const TOKEN_RE = /[a-z0-9_-]{2,}|[一-鿿]/g;
64
+ export function tokenize(text) {
65
+ if (!text)
66
+ return [];
67
+ const lower = text.toLowerCase();
68
+ const tokens = [];
69
+ const matches = lower.matchAll(TOKEN_RE);
70
+ for (const m of matches) {
71
+ const t = m[0];
72
+ if (STOP_WORDS.has(t))
73
+ continue;
74
+ tokens.push(t);
75
+ }
76
+ return tokens;
77
+ }
78
+ /**
79
+ * 从 Page 对象抽 IndexedDoc。
80
+ * TL;DR 提取规则:找 `## TL;DR\n...\n##` 之间的内容;找不到取 body 前 200 字符。
81
+ */
82
+ export function pageToIndexed(page) {
83
+ return {
84
+ pageId: page.pageId,
85
+ title: page.frontmatter.title,
86
+ tags: page.frontmatter.tags,
87
+ tldr: extractTLDR(page.body),
88
+ body: page.body,
89
+ type: page.frontmatter.type,
90
+ };
91
+ }
92
+ const TLDR_RE = /^##\s+TL;DR\s*\r?\n([\s\S]*?)(?=\r?\n##\s+|\s*$)/m;
93
+ export function extractTLDR(body) {
94
+ const m = body.match(TLDR_RE);
95
+ if (m)
96
+ return m[1].trim();
97
+ // Fallback:第一个段落或前 200 字
98
+ const firstPara = body.split(/\n\s*\n/)[0]?.trim() ?? '';
99
+ return firstPara.slice(0, 200);
100
+ }
101
+ // ─── BM25F searcher ───────────────────────────────────────────────
102
+ export class WikiSearcher {
103
+ docs;
104
+ opts;
105
+ postings = new Map();
106
+ docLengths = [];
107
+ avgDocLength;
108
+ constructor(docs, opts = {}) {
109
+ this.docs = docs;
110
+ this.opts = mergeOpts(opts);
111
+ let totalLen = 0;
112
+ for (let i = 0; i < docs.length; i++) {
113
+ const tokens = this.tokenizeDoc(docs[i]);
114
+ const tf = countTF(tokens);
115
+ for (const [term, count] of tf) {
116
+ let pl = this.postings.get(term);
117
+ if (!pl) {
118
+ pl = new Map();
119
+ this.postings.set(term, pl);
120
+ }
121
+ pl.set(i, count);
122
+ }
123
+ this.docLengths[i] = tokens.length;
124
+ totalLen += tokens.length;
125
+ }
126
+ this.avgDocLength = docs.length > 0 ? totalLen / docs.length : 1;
127
+ }
128
+ /**
129
+ * 全字段加权的 token stream。同一个 token 在 title 出现一次 = title weight 个副本。
130
+ */
131
+ tokenizeDoc(doc) {
132
+ const w = this.opts.fieldWeights;
133
+ return [
134
+ ...repeat(tokenize(doc.title), w.title),
135
+ ...repeat(tokenize(doc.tags.join(' ')), w.tags),
136
+ ...repeat(tokenize(doc.tldr), w.tldr),
137
+ ...repeat(tokenize(doc.body), w.body),
138
+ ];
139
+ }
140
+ search(query, limit = 10) {
141
+ const queryTerms = unique(tokenize(query));
142
+ if (queryTerms.length === 0 || this.docs.length === 0)
143
+ return [];
144
+ const scores = new Map();
145
+ const N = this.docs.length;
146
+ for (const term of queryTerms) {
147
+ const postings = this.postings.get(term);
148
+ if (!postings)
149
+ continue;
150
+ const df = postings.size;
151
+ const idf = Math.log((N - df + 0.5) / (df + 0.5) + 1);
152
+ for (const [docIdx, tf] of postings) {
153
+ const docLen = this.docLengths[docIdx];
154
+ const norm = 1 - this.opts.b + this.opts.b * (docLen / this.avgDocLength);
155
+ const tfPart = (tf * (this.opts.k1 + 1)) / (tf + this.opts.k1 * norm);
156
+ const contribution = idf * tfPart;
157
+ scores.set(docIdx, (scores.get(docIdx) ?? 0) + contribution);
158
+ }
159
+ }
160
+ return [...scores.entries()]
161
+ .sort((a, b) => b[1] - a[1])
162
+ .slice(0, limit)
163
+ .map(([idx, score]) => ({ pageId: this.docs[idx].pageId, score }));
164
+ }
165
+ /** 按 tag 集合过滤(OR 语义)—— 用于 reader.ts 的 skill-match layer */
166
+ searchByTags(tags, limit = 10) {
167
+ if (tags.length === 0)
168
+ return [];
169
+ const tagSet = new Set(tags.map((t) => t.toLowerCase()));
170
+ const matches = [];
171
+ for (let i = 0; i < this.docs.length; i++) {
172
+ const doc = this.docs[i];
173
+ const overlap = doc.tags.filter((t) => tagSet.has(t.toLowerCase())).length;
174
+ if (overlap > 0) {
175
+ // 命中 tag 多 = 分数高
176
+ matches.push({ pageId: doc.pageId, score: overlap });
177
+ }
178
+ }
179
+ return matches.sort((a, b) => b.score - a.score).slice(0, limit);
180
+ }
181
+ /** 按 type 列出(不打分;reader.ts 排序用) */
182
+ byType(type) {
183
+ return this.docs.filter((d) => d.type === type);
184
+ }
185
+ }
186
+ // ─── Pure helpers ─────────────────────────────────────────────────
187
+ function countTF(tokens) {
188
+ const m = new Map();
189
+ for (const t of tokens)
190
+ m.set(t, (m.get(t) ?? 0) + 1);
191
+ return m;
192
+ }
193
+ function repeat(arr, n) {
194
+ if (n <= 1)
195
+ return arr.slice();
196
+ const out = [];
197
+ for (let i = 0; i < n; i++)
198
+ out.push(...arr);
199
+ return out;
200
+ }
201
+ function unique(arr) {
202
+ return [...new Set(arr)];
203
+ }
204
+ function mergeOpts(input) {
205
+ return {
206
+ k1: input.k1 ?? DEFAULT_OPTS.k1,
207
+ b: input.b ?? DEFAULT_OPTS.b,
208
+ fieldWeights: {
209
+ title: input.fieldWeights?.title ?? DEFAULT_OPTS.fieldWeights.title,
210
+ tags: input.fieldWeights?.tags ?? DEFAULT_OPTS.fieldWeights.tags,
211
+ tldr: input.fieldWeights?.tldr ?? DEFAULT_OPTS.fieldWeights.tldr,
212
+ body: input.fieldWeights?.body ?? DEFAULT_OPTS.fieldWeights.body,
213
+ },
214
+ };
215
+ }
216
+ //# sourceMappingURL=searcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searcher.js","sourceRoot":"","sources":["../../../src/core/wiki/searcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ import type { Manifest, SourceDiff } from './types.js';
2
+ /** WIKI.md sources 字段定义的 4 个 bucket */
3
+ export type SourceCategory = 'code' | 'doc' | 'raw' | 'data';
4
+ export interface DiscoveredSource {
5
+ /** Path relative to repoDir, posix-style */
6
+ readonly path: string;
7
+ /** Which sources bucket the file belongs to */
8
+ readonly category: SourceCategory;
9
+ /** sha256 hex; computed lazily by callers (use hashSource) */
10
+ readonly hash?: string;
11
+ }
12
+ export interface SourcesConfig {
13
+ /** Globs per bucket; absent bucket = empty array */
14
+ readonly code: readonly string[];
15
+ readonly doc: readonly string[];
16
+ readonly raw: readonly string[];
17
+ readonly data: readonly string[];
18
+ }
19
+ /**
20
+ * 从 WIKI.md 顶部 frontmatter 抽 sources 配置。
21
+ *
22
+ * 容错:
23
+ * - WIKI.md 不存在 → 返默认(空配置)
24
+ * - frontmatter 缺失 / sources 字段缺失 → 返默认
25
+ * - 类型不对(非数组 / 非字符串)→ 跳过该 bucket
26
+ */
27
+ export declare function readSourcesConfig(repoDir: string): SourcesConfig;
28
+ interface ParsedPattern {
29
+ /** Anchor directory relative to repoDir (no trailing slash) */
30
+ readonly base: string;
31
+ /** Should match recursively? (true if pattern contains ** ) */
32
+ readonly recursive: boolean;
33
+ /** Optional file extension filter (e.g. ".ts"); '' for all files */
34
+ readonly extension: string;
35
+ /** Original pattern (for debug) */
36
+ readonly raw: string;
37
+ }
38
+ /**
39
+ * Parse a simple glob pattern into base + recursion + extension filter.
40
+ *
41
+ * Examples:
42
+ * "src/**\/*.ts" → base=src, recursive=true, ext=.ts
43
+ * "src/**" → base=src, recursive=true, ext=''
44
+ * "docs/*.md" → base=docs, recursive=false, ext=.md
45
+ * "README.md" → base=., recursive=false, ext=.md (treated as flat single)
46
+ *
47
+ * Unsupported patterns (e.g. with `{}`) are passed through but won't match anything.
48
+ */
49
+ export declare function parsePattern(pattern: string): ParsedPattern;
50
+ /**
51
+ * Walk filesystem from `repoDir/<base>` and collect files that match the pattern.
52
+ *
53
+ * - Skips dotfiles starting with `.` UNLESS the base itself starts with `.`
54
+ * (e.g. wiki/.raw/** — user wants those).
55
+ * - Always skips node_modules / .git anywhere in the tree.
56
+ *
57
+ * Returns paths relative to repoDir, posix-normalized.
58
+ */
59
+ export declare function expandPattern(repoDir: string, pattern: string): string[];
60
+ export interface DiscoverResult {
61
+ /** Discovered sources with hashes */
62
+ readonly sources: readonly DiscoveredSource[];
63
+ /** Patterns that returned 0 files (warning candidates) */
64
+ readonly emptyPatterns: readonly string[];
65
+ }
66
+ /**
67
+ * Discover all sources from WIKI.md config + hash them.
68
+ *
69
+ * Buckets are merged; if the same path is matched by multiple buckets, the first
70
+ * winning bucket (in code → doc → data → raw order) is used.
71
+ *
72
+ * Caller is responsible for I/O fault tolerance — this throws on individual hash
73
+ * failures only via `tryHashFile` semantics (skip).
74
+ */
75
+ export declare function discoverSources(repoDir: string): DiscoverResult;
76
+ /**
77
+ * Compute diff between current discovered sources and saved manifest.
78
+ *
79
+ * Wraps diffSources() with a typed input so callers don't have to remember
80
+ * the DiffInputSource shape.
81
+ */
82
+ export declare function diffAgainstManifest(sources: readonly DiscoveredSource[], manifest: Manifest): SourceDiff;
83
+ export {};
84
+ //# sourceMappingURL=sources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sources.d.ts","sourceRoot":"","sources":["../../../src/core/wiki/sources.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAIvD,uCAAuC;AACvC,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;AAE7D,MAAM,WAAW,gBAAgB;IAC/B,4CAA4C;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,8DAA8D;IAC9D,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAID,MAAM,WAAW,aAAa;IAC5B,oDAAoD;IACpD,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,QAAQ,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAID;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CA2BhE;AASD,UAAU,aAAa;IACrB,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,oEAAoE;IACpE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,mCAAmC;IACnC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAgC3D;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAsCxE;AAqDD,MAAM,WAAW,cAAc;IAC7B,qCAAqC;IACrC,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC9C,0DAA0D;IAC1D,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3C;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CAuC/D;AAID;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,SAAS,gBAAgB,EAAE,EACpC,QAAQ,EAAE,QAAQ,GACjB,UAAU,CAKZ"}
@@ -0,0 +1,261 @@
1
+ /**
2
+ * @module core/wiki/sources
3
+ * @description Wiki 源材料发现:扫 WIKI.md sources 模式 → 文件列表 + diff
4
+ *
5
+ * @layer core
6
+ *
7
+ * 不依赖 micromatch / fast-glob —— SPS 模式很简单(**+扩展名过滤),手写够用且
8
+ * 避免再多 50 KB 依赖。
9
+ *
10
+ * 支持的模式:
11
+ * - "src/**\/*.ts" 递归 + 扩展名过滤
12
+ * - "src/**" 递归全部
13
+ * - "docs/*.md" 平铺扩展名过滤
14
+ * - "README.md" 字面量
15
+ *
16
+ * 不支持(也不需要):
17
+ * - { } alternation, [chars] character class, ! negation
18
+ * - 多扩展名("*.{ts,tsx}")—— 用两条 pattern 代替
19
+ *
20
+ * **路径都相对 repoDir**——manifest 里也用相对路径,跨机器一致。
21
+ */
22
+ import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
23
+ import { relative, resolve, sep } from 'node:path';
24
+ import { parse as parseYaml } from 'yaml';
25
+ import { wikiMetaFile } from '../../shared/wikiPaths.js';
26
+ import { diffSources, hashFile } from './manifest.js';
27
+ const EMPTY_SOURCES = { code: [], doc: [], raw: [], data: [] };
28
+ /**
29
+ * 从 WIKI.md 顶部 frontmatter 抽 sources 配置。
30
+ *
31
+ * 容错:
32
+ * - WIKI.md 不存在 → 返默认(空配置)
33
+ * - frontmatter 缺失 / sources 字段缺失 → 返默认
34
+ * - 类型不对(非数组 / 非字符串)→ 跳过该 bucket
35
+ */
36
+ export function readSourcesConfig(repoDir) {
37
+ const path = wikiMetaFile(repoDir);
38
+ if (!existsSync(path))
39
+ return EMPTY_SOURCES;
40
+ const content = readFileSync(path, 'utf-8');
41
+ const fmMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
42
+ if (!fmMatch)
43
+ return EMPTY_SOURCES;
44
+ let parsed;
45
+ try {
46
+ parsed = parseYaml(fmMatch[1]);
47
+ }
48
+ catch {
49
+ return EMPTY_SOURCES;
50
+ }
51
+ if (!parsed || typeof parsed !== 'object')
52
+ return EMPTY_SOURCES;
53
+ const obj = parsed;
54
+ const sources = obj.sources;
55
+ if (!sources || typeof sources !== 'object')
56
+ return EMPTY_SOURCES;
57
+ const buckets = sources;
58
+ return {
59
+ code: pickStringArray(buckets.code),
60
+ doc: pickStringArray(buckets.doc),
61
+ raw: pickStringArray(buckets.raw),
62
+ data: pickStringArray(buckets.data),
63
+ };
64
+ }
65
+ function pickStringArray(v) {
66
+ if (!Array.isArray(v))
67
+ return [];
68
+ return v.filter((x) => typeof x === 'string');
69
+ }
70
+ /**
71
+ * Parse a simple glob pattern into base + recursion + extension filter.
72
+ *
73
+ * Examples:
74
+ * "src/**\/*.ts" → base=src, recursive=true, ext=.ts
75
+ * "src/**" → base=src, recursive=true, ext=''
76
+ * "docs/*.md" → base=docs, recursive=false, ext=.md
77
+ * "README.md" → base=., recursive=false, ext=.md (treated as flat single)
78
+ *
79
+ * Unsupported patterns (e.g. with `{}`) are passed through but won't match anything.
80
+ */
81
+ export function parsePattern(pattern) {
82
+ const norm = pattern.replace(/\\/g, '/').trim();
83
+ const recursive = norm.includes('**');
84
+ // Strip trailing pattern segments
85
+ let base = norm;
86
+ let ext = '';
87
+ // Pull off the file pattern (last segment)
88
+ const lastSlash = norm.lastIndexOf('/');
89
+ const lastSeg = lastSlash >= 0 ? norm.slice(lastSlash + 1) : norm;
90
+ const beforeLast = lastSlash >= 0 ? norm.slice(0, lastSlash) : '';
91
+ if (lastSeg === '*' || lastSeg === '**') {
92
+ ext = '';
93
+ base = beforeLast.replace(/\/\*\*$/, '');
94
+ }
95
+ else if (/^\*\.[a-z0-9]+$/i.test(lastSeg)) {
96
+ ext = lastSeg.slice(1);
97
+ base = beforeLast.replace(/\/\*\*$/, '');
98
+ }
99
+ else if (recursive) {
100
+ // pattern like "src/**/file.md" or "src/**/foo/bar.md" — we don't fully
101
+ // support; treat as recursive over base, no ext filter, callers can post-filter.
102
+ ext = '';
103
+ base = norm.replace(/\/\*\*.*$/, '');
104
+ }
105
+ else {
106
+ // Literal path
107
+ ext = '';
108
+ base = norm;
109
+ }
110
+ if (base === '' || base === '.')
111
+ base = '.';
112
+ return { base, recursive, extension: ext, raw: pattern };
113
+ }
114
+ /**
115
+ * Walk filesystem from `repoDir/<base>` and collect files that match the pattern.
116
+ *
117
+ * - Skips dotfiles starting with `.` UNLESS the base itself starts with `.`
118
+ * (e.g. wiki/.raw/** — user wants those).
119
+ * - Always skips node_modules / .git anywhere in the tree.
120
+ *
121
+ * Returns paths relative to repoDir, posix-normalized.
122
+ */
123
+ export function expandPattern(repoDir, pattern) {
124
+ const parsed = parsePattern(pattern);
125
+ const baseAbs = resolve(repoDir, parsed.base);
126
+ // Literal file (e.g. README.md): just check existence
127
+ if (!parsed.recursive && parsed.extension === '' && parsed.base !== '.') {
128
+ if (existsSync(baseAbs)) {
129
+ try {
130
+ const st = statSync(baseAbs);
131
+ if (st.isFile()) {
132
+ return [toRelPosix(repoDir, baseAbs)];
133
+ }
134
+ if (st.isDirectory()) {
135
+ return walkDir(repoDir, baseAbs, false, '', baseStartsWithDot(parsed.base));
136
+ }
137
+ }
138
+ catch {
139
+ return [];
140
+ }
141
+ }
142
+ return [];
143
+ }
144
+ if (!existsSync(baseAbs))
145
+ return [];
146
+ let st;
147
+ try {
148
+ st = statSync(baseAbs);
149
+ }
150
+ catch {
151
+ return [];
152
+ }
153
+ if (!st.isDirectory())
154
+ return [];
155
+ return walkDir(repoDir, baseAbs, parsed.recursive, parsed.extension, baseStartsWithDot(parsed.base));
156
+ }
157
+ function baseStartsWithDot(base) {
158
+ // Any segment of base starts with `.` (e.g. ".raw" or "wiki/.raw")
159
+ return base.split('/').some((s) => s.startsWith('.'));
160
+ }
161
+ const SKIP_DIRS = new Set(['node_modules', '.git', 'dist', 'build', 'coverage']);
162
+ function walkDir(repoDir, dir, recursive, extension, allowDotFiles) {
163
+ const out = [];
164
+ let entries;
165
+ try {
166
+ entries = readdirSync(dir);
167
+ }
168
+ catch {
169
+ return out;
170
+ }
171
+ for (const name of entries) {
172
+ if (SKIP_DIRS.has(name))
173
+ continue;
174
+ if (!allowDotFiles && name.startsWith('.'))
175
+ continue;
176
+ const abs = resolve(dir, name);
177
+ let st;
178
+ try {
179
+ st = statSync(abs);
180
+ }
181
+ catch {
182
+ continue;
183
+ }
184
+ if (st.isDirectory()) {
185
+ if (recursive) {
186
+ out.push(...walkDir(repoDir, abs, recursive, extension, allowDotFiles));
187
+ }
188
+ }
189
+ else if (st.isFile()) {
190
+ if (extension && !name.endsWith(extension))
191
+ continue;
192
+ out.push(toRelPosix(repoDir, abs));
193
+ }
194
+ }
195
+ return out;
196
+ }
197
+ function toRelPosix(repoDir, abs) {
198
+ const rel = relative(repoDir, abs);
199
+ return sep === '\\' ? rel.replace(/\\/g, '/') : rel;
200
+ }
201
+ /**
202
+ * Discover all sources from WIKI.md config + hash them.
203
+ *
204
+ * Buckets are merged; if the same path is matched by multiple buckets, the first
205
+ * winning bucket (in code → doc → data → raw order) is used.
206
+ *
207
+ * Caller is responsible for I/O fault tolerance — this throws on individual hash
208
+ * failures only via `tryHashFile` semantics (skip).
209
+ */
210
+ export function discoverSources(repoDir) {
211
+ const config = readSourcesConfig(repoDir);
212
+ const seen = new Map();
213
+ const emptyPatterns = [];
214
+ const buckets = [
215
+ ['code', config.code],
216
+ ['doc', config.doc],
217
+ ['data', config.data],
218
+ ['raw', config.raw],
219
+ ];
220
+ for (const [category, patterns] of buckets) {
221
+ for (const pattern of patterns) {
222
+ const matched = expandPattern(repoDir, pattern);
223
+ if (matched.length === 0) {
224
+ emptyPatterns.push(pattern);
225
+ continue;
226
+ }
227
+ for (const p of matched) {
228
+ if (!seen.has(p))
229
+ seen.set(p, category);
230
+ }
231
+ }
232
+ }
233
+ const sources = [];
234
+ for (const [path, category] of seen) {
235
+ let hash;
236
+ try {
237
+ hash = hashFile(resolve(repoDir, path));
238
+ }
239
+ catch {
240
+ continue; // unreadable file = drop silently
241
+ }
242
+ sources.push({ path, category, hash });
243
+ }
244
+ // Stable sort for deterministic output
245
+ sources.sort((a, b) => a.path.localeCompare(b.path));
246
+ return { sources, emptyPatterns };
247
+ }
248
+ // ─── Diff helper (manifest aware) ─────────────────────────────────
249
+ /**
250
+ * Compute diff between current discovered sources and saved manifest.
251
+ *
252
+ * Wraps diffSources() with a typed input so callers don't have to remember
253
+ * the DiffInputSource shape.
254
+ */
255
+ export function diffAgainstManifest(sources, manifest) {
256
+ const inputs = sources
257
+ .filter((s) => typeof s.hash === 'string')
258
+ .map((s) => ({ path: s.path, hash: s.hash }));
259
+ return diffSources(inputs, manifest);
260
+ }
261
+ //# sourceMappingURL=sources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sources.js","sourceRoot":"","sources":["../../../src/core/wiki/sources.ts"],"names":[],"mappings":"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"}