@su-record/vibe 4.2.29 → 4.2.30
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.
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Your personal FDE in Claude and Codex. Understand the work, use the right tools, deliver and retain useful context. One entry: vibe.",
|
|
9
|
-
"version": "4.2.
|
|
9
|
+
"version": "4.2.30"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "vibe",
|
|
14
14
|
"source": "./",
|
|
15
15
|
"description": "Your personal FDE in Claude and Codex. Understand the work, use the right tools, deliver and retain useful context. One entry: vibe.",
|
|
16
|
-
"version": "4.2.
|
|
16
|
+
"version": "4.2.30",
|
|
17
17
|
"category": "productivity"
|
|
18
18
|
}
|
|
19
19
|
]
|
package/hooks/knowledge-lint.cjs
CHANGED
|
@@ -18,15 +18,19 @@ const AUTO = '<!-- vibe:auto -->';
|
|
|
18
18
|
/**
|
|
19
19
|
* The wiki's pages, and the pages of each project's shared knowledge it shows through a folder link
|
|
20
20
|
* (`projects/<name>/`). Those are kept in the project, so they resolve links and are reported as unlinked, not orphans.
|
|
21
|
+
* A folder reached twice (two links to one project) is read once; `aliases` maps the second path to the first so
|
|
22
|
+
* links through either resolve.
|
|
21
23
|
*/
|
|
22
24
|
function wikiPages(dir) {
|
|
23
25
|
const files = [];
|
|
24
26
|
const shared = new Set();
|
|
25
|
-
const seen = new
|
|
27
|
+
const seen = new Map();
|
|
28
|
+
const aliases = [];
|
|
26
29
|
let partial = false;
|
|
27
30
|
const walk = (current, linked) => {
|
|
28
|
-
|
|
29
|
-
seen.
|
|
31
|
+
const real = fs.realpathSync(current);
|
|
32
|
+
if (seen.has(real)) { aliases.push([current, seen.get(real)]); return; }
|
|
33
|
+
seen.set(real, current);
|
|
30
34
|
for (const entry of fs.readdirSync(current, { withFileTypes: true })) {
|
|
31
35
|
if (entry.name.startsWith('.')) continue;
|
|
32
36
|
if (files.length >= MAX_PAGES) { partial = true; return; }
|
|
@@ -37,7 +41,7 @@ function wikiPages(dir) {
|
|
|
37
41
|
}
|
|
38
42
|
};
|
|
39
43
|
if (fs.existsSync(dir)) walk(dir, false);
|
|
40
|
-
return { files: files.sort(), shared, partial };
|
|
44
|
+
return { files: files.sort(), shared, aliases, partial };
|
|
41
45
|
}
|
|
42
46
|
|
|
43
47
|
/** `[[target]]`, `[[target|label]]` and `[[target#heading]]` give `target`; links inside code are still counted. */
|
|
@@ -53,13 +57,19 @@ function pageTitle(text, file) {
|
|
|
53
57
|
return stated || heading || path.basename(file, '.md');
|
|
54
58
|
}
|
|
55
59
|
|
|
56
|
-
/**
|
|
57
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Each page's name as a link target, and every name a link may use for it (path from the root, the same path through
|
|
62
|
+
* another link to its folder, or file name alone).
|
|
63
|
+
*/
|
|
64
|
+
function names(dir, files, aliases = []) {
|
|
58
65
|
const name = file => path.relative(dir, file).split(path.sep).join('/').replace(/\.md$/, '');
|
|
59
66
|
const known = new Map();
|
|
60
67
|
for (const file of files) {
|
|
61
68
|
known.set(name(file).toLowerCase(), name(file));
|
|
62
69
|
known.set(path.basename(file, '.md').toLowerCase(), name(file));
|
|
70
|
+
for (const [alias, folder] of aliases) {
|
|
71
|
+
if (file.startsWith(folder + path.sep)) known.set(name(path.join(alias, path.relative(folder, file))).toLowerCase(), name(file));
|
|
72
|
+
}
|
|
63
73
|
}
|
|
64
74
|
return { name, resolve: target => known.get(target.replace(/\.md$/, '').toLowerCase()) };
|
|
65
75
|
}
|
|
@@ -69,8 +79,8 @@ function names(dir, files) {
|
|
|
69
79
|
* title. A link resolves the way Obsidian resolves it; a link from log.md finds a page but does not make it reachable.
|
|
70
80
|
*/
|
|
71
81
|
function lintWiki(dir) {
|
|
72
|
-
const { files, shared, partial } = wikiPages(dir);
|
|
73
|
-
const { name, resolve } = names(dir, files);
|
|
82
|
+
const { files, shared, aliases, partial } = wikiPages(dir);
|
|
83
|
+
const { name, resolve } = names(dir, files, aliases);
|
|
74
84
|
const broken = [], long = [], badType = [];
|
|
75
85
|
const linked = new Set();
|
|
76
86
|
const titles = new Map();
|
|
@@ -106,16 +116,16 @@ function fixWiki(dir, home) {
|
|
|
106
116
|
const created = [];
|
|
107
117
|
const log = path.join(dir, 'log.md');
|
|
108
118
|
if (fs.existsSync(log)) {
|
|
109
|
-
const { files } = wikiPages(dir);
|
|
110
|
-
const { resolve } = names(dir, files);
|
|
119
|
+
const { files, aliases } = wikiPages(dir);
|
|
120
|
+
const { resolve } = names(dir, files, aliases);
|
|
111
121
|
const roots = readNames(home);
|
|
112
122
|
for (const target of new Set(wikiLinks(fs.readFileSync(log, 'utf8')))) {
|
|
113
123
|
const project = /^projects\/([^/]+)$/.exec(target.replace(/\.md$/, ''))?.[1];
|
|
114
124
|
if (project && resolve(target) === undefined && projectPage(dir, project, roots[project])) created.push(`projects/${project}`);
|
|
115
125
|
}
|
|
116
126
|
}
|
|
117
|
-
const { files, shared } = wikiPages(dir);
|
|
118
|
-
const { name, resolve } = names(dir, files);
|
|
127
|
+
const { files, shared, aliases } = wikiPages(dir);
|
|
128
|
+
const { name, resolve } = names(dir, files, aliases);
|
|
119
129
|
const index = path.join(dir, 'index.md');
|
|
120
130
|
const text = fs.existsSync(index) ? fs.readFileSync(index, 'utf8') : '# Index\n';
|
|
121
131
|
const removed = [];
|
|
@@ -138,8 +148,8 @@ function fixWiki(dir, home) {
|
|
|
138
148
|
|
|
139
149
|
/** Pages changed since `since` (index and log aside) and the pages they link to, for a review turn. */
|
|
140
150
|
function reviewScope(dir, since) {
|
|
141
|
-
const { files } = wikiPages(dir);
|
|
142
|
-
const { name, resolve } = names(dir, files);
|
|
151
|
+
const { files, aliases } = wikiPages(dir);
|
|
152
|
+
const { name, resolve } = names(dir, files, aliases);
|
|
143
153
|
const changed = files.filter(file => !ROOTS.has(name(file)) && fs.statSync(file).mtimeMs > since);
|
|
144
154
|
const linked = new Set();
|
|
145
155
|
for (const file of changed) for (const target of wikiLinks(fs.readFileSync(file, 'utf8'))) linked.add(resolve(target));
|
package/package.json
CHANGED