total-recall-brain 3.46.2 → 3.47.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.
- package/bin/total-recall.mjs +5 -0
- package/frontend/dist/assets/index-CpsWeV4X.css +1 -0
- package/frontend/dist/assets/{index-D1goIPjC.js → index-poecbHSl.js} +100 -100
- package/frontend/dist/brand/total-recall-lockup-transparent.png +0 -0
- package/frontend/dist/index.html +2 -2
- package/frontend/dist/sw.js +1 -1
- package/frontend/src/App.tsx +15 -81
- package/frontend/src/components/DashboardOverview.tsx +164 -0
- package/frontend/src/components/brand/BrandMark.tsx +8 -6
- package/frontend/src/components/plugins/PluginWorkspace.tsx +112 -57
- package/frontend/src/components/workspace/PluginHome.tsx +3 -3
- package/frontend/src/index.css +43 -11
- package/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +4 -4
- package/scaffold/.agent/skills/total-recall/plugins/auth/package.json +3 -2
- package/scaffold/.agent/skills/total-recall/plugins/auth/plugin.json +30 -5
- package/scaffold/.agent/skills/total-recall/plugins/auth/skills/auth/SKILL.md +35 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/home.js +494 -79
- package/scaffold/.agent/skills/total-recall/plugins/automations/package-lock.json +4 -4
- package/scaffold/.agent/skills/total-recall/plugins/automations/package.json +3 -2
- package/scaffold/.agent/skills/total-recall/plugins/automations/plugin.json +33 -8
- package/scaffold/.agent/skills/total-recall/plugins/automations/skills/automations/SKILL.md +29 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/dream-consolidation.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +4 -4
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +3 -2
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/plugin.json +31 -4
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/skills/code-quality/SKILL.md +27 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +4 -4
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/plugin.json +17 -3
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +4 -4
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +3 -2
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/plugin.json +24 -4
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/skills/embeddings/SKILL.md +25 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/git/package.json +3 -2
- package/scaffold/.agent/skills/total-recall/plugins/git/plugin.json +300 -58
- package/scaffold/.agent/skills/total-recall/plugins/git/skills/git/SKILL.md +36 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/commit-memory.mjs +5 -33
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/git-fleet-ops.md +16 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/git-publish.md +16 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/package-lock.json +4 -4
- package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +3 -2
- package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +47 -14
- package/scaffold/.agent/skills/total-recall/plugins/mesh/skills/mesh/SKILL.md +36 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/cli.mjs +6 -3
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/plugin.json +5 -2
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/cascade.mjs +4 -2
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/coordinator.mjs +28 -9
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/dispatch.mjs +7 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/model-selection.mjs +59 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/remote-operation.mjs +3 -3
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/router.mjs +9 -3
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worker.mjs +50 -6
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/session-controls.md +16 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/cli.mjs +175 -17
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +3 -2
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +242 -31
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/skills/openwiki/SKILL.md +32 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/config.mjs +41 -15
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/generate.mjs +29 -22
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/graph.mjs +20 -33
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/lint.mjs +42 -49
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/markdown-links.mjs +112 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/mesh-vaults.mjs +3 -2
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh.mjs +219 -65
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/search.mjs +2 -1
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/upstream-watcher.mjs +21 -3
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/panel.js +51 -2
- package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +4 -4
- package/scaffold/.agent/skills/total-recall/plugins/security/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/security/plugin.json +22 -5
- package/scaffold/.agent/skills/total-recall/plugins/ssss/package.json +3 -2
- package/scaffold/.agent/skills/total-recall/plugins/ssss/plugin.json +169 -37
- package/scaffold/.agent/skills/total-recall/plugins/ssss/skills/ssss/SKILL.md +30 -0
- package/src/cli/context.mjs +6 -2
- package/src/cli/plugin/create.mjs +2 -1
- package/src/cli/plugin/monetization.mjs +66 -32
- package/src/cli/plugin/search.mjs +25 -3
- package/src/cli/preflight.mjs +40 -6
- package/src/core/context-compactor.mjs +2 -0
- package/src/core/gate-mode.mjs +13 -24
- package/src/core/plugin-distribution.mjs +35 -1
- package/src/core/preflight-gate.mjs +28 -8
- package/src/core/preflight-receipt.mjs +11 -0
- package/src/server/routes/vault.mjs +1 -0
- package/frontend/dist/assets/index-BRYE1jmv.css +0 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://github.com/gregiteen/total-recall/blob/main/metadata.plugin.schema.json",
|
|
3
3
|
"id": "openwiki",
|
|
4
4
|
"name": "OpenWiki",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.4.1",
|
|
6
6
|
"description": "Multi-repo knowledge graph and documentation wiki engine for Total Recall.",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"runtime": {
|
|
@@ -17,10 +17,11 @@
|
|
|
17
17
|
"command": "watch"
|
|
18
18
|
},
|
|
19
19
|
{
|
|
20
|
-
"intent": "
|
|
21
|
-
"schedule": "
|
|
20
|
+
"intent": "Refresh OpenWiki documentation nightly for repositories with real code changes, on the selected node",
|
|
21
|
+
"schedule": "20 1-5 * * *",
|
|
22
22
|
"command": "auto-refresh",
|
|
23
|
-
"timeout_ms": 600000
|
|
23
|
+
"timeout_ms": 600000,
|
|
24
|
+
"placement": "selected-node"
|
|
24
25
|
}
|
|
25
26
|
],
|
|
26
27
|
"branding": {
|
|
@@ -71,7 +72,11 @@
|
|
|
71
72
|
]
|
|
72
73
|
},
|
|
73
74
|
"gate": {
|
|
74
|
-
"tasks": [
|
|
75
|
+
"tasks": [
|
|
76
|
+
"Search or read a repository's wiki",
|
|
77
|
+
"Generate or refresh wiki pages",
|
|
78
|
+
"Ingest documentation into memory"
|
|
79
|
+
],
|
|
75
80
|
"owned_commands": []
|
|
76
81
|
},
|
|
77
82
|
"cli": {
|
|
@@ -84,8 +89,19 @@
|
|
|
84
89
|
"effect": "read",
|
|
85
90
|
"output": "json",
|
|
86
91
|
"args": [
|
|
87
|
-
{
|
|
88
|
-
|
|
92
|
+
{
|
|
93
|
+
"name": "task",
|
|
94
|
+
"label": "Task description",
|
|
95
|
+
"type": "string",
|
|
96
|
+
"positional": true,
|
|
97
|
+
"required": true
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"name": "json",
|
|
101
|
+
"label": "JSON output",
|
|
102
|
+
"type": "boolean",
|
|
103
|
+
"flag": "--json"
|
|
104
|
+
}
|
|
89
105
|
]
|
|
90
106
|
},
|
|
91
107
|
{
|
|
@@ -94,11 +110,37 @@
|
|
|
94
110
|
"effect": "read",
|
|
95
111
|
"output": "json",
|
|
96
112
|
"args": [
|
|
97
|
-
{
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
113
|
+
{
|
|
114
|
+
"name": "query",
|
|
115
|
+
"label": "Search terms",
|
|
116
|
+
"type": "string",
|
|
117
|
+
"positional": true,
|
|
118
|
+
"required": true
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"name": "allVaults",
|
|
122
|
+
"label": "Search all registered vaults",
|
|
123
|
+
"type": "boolean",
|
|
124
|
+
"flag": "--all-vaults"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"name": "node",
|
|
128
|
+
"label": "Mesh node",
|
|
129
|
+
"type": "string",
|
|
130
|
+
"flag": "--node"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"name": "limit",
|
|
134
|
+
"label": "Maximum results",
|
|
135
|
+
"type": "number",
|
|
136
|
+
"flag": "--limit"
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"name": "json",
|
|
140
|
+
"label": "JSON output",
|
|
141
|
+
"type": "boolean",
|
|
142
|
+
"flag": "--json"
|
|
143
|
+
}
|
|
102
144
|
]
|
|
103
145
|
},
|
|
104
146
|
{
|
|
@@ -107,10 +149,35 @@
|
|
|
107
149
|
"effect": "read",
|
|
108
150
|
"output": "json",
|
|
109
151
|
"args": [
|
|
110
|
-
{
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
152
|
+
{
|
|
153
|
+
"name": "allVaults",
|
|
154
|
+
"label": "Inspect all registered vaults",
|
|
155
|
+
"type": "boolean",
|
|
156
|
+
"flag": "--all-vaults"
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"name": "node",
|
|
160
|
+
"label": "Mesh node",
|
|
161
|
+
"type": "string",
|
|
162
|
+
"flag": "--node"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"name": "format",
|
|
166
|
+
"label": "Graph format",
|
|
167
|
+
"type": "choice",
|
|
168
|
+
"options": [
|
|
169
|
+
"json",
|
|
170
|
+
"mermaid",
|
|
171
|
+
"dot"
|
|
172
|
+
],
|
|
173
|
+
"flag": "--format"
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"name": "json",
|
|
177
|
+
"label": "JSON output",
|
|
178
|
+
"type": "boolean",
|
|
179
|
+
"flag": "--json"
|
|
180
|
+
}
|
|
114
181
|
]
|
|
115
182
|
},
|
|
116
183
|
{
|
|
@@ -120,11 +187,36 @@
|
|
|
120
187
|
"output": "json",
|
|
121
188
|
"timeout_ms": 600000,
|
|
122
189
|
"args": [
|
|
123
|
-
{
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
190
|
+
{
|
|
191
|
+
"name": "repo",
|
|
192
|
+
"label": "Registered repository",
|
|
193
|
+
"type": "string",
|
|
194
|
+
"flag": "--repo"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"name": "node",
|
|
198
|
+
"label": "Mesh node",
|
|
199
|
+
"type": "string",
|
|
200
|
+
"flag": "--node"
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
"name": "force",
|
|
204
|
+
"label": "Regenerate existing pages",
|
|
205
|
+
"type": "boolean",
|
|
206
|
+
"flag": "--force"
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"name": "dryRun",
|
|
210
|
+
"label": "Describe generation without writing",
|
|
211
|
+
"type": "boolean",
|
|
212
|
+
"flag": "--dry-run"
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
"name": "json",
|
|
216
|
+
"label": "JSON output",
|
|
217
|
+
"type": "boolean",
|
|
218
|
+
"flag": "--json"
|
|
219
|
+
}
|
|
128
220
|
]
|
|
129
221
|
},
|
|
130
222
|
{
|
|
@@ -133,11 +225,44 @@
|
|
|
133
225
|
"effect": "write",
|
|
134
226
|
"output": "json",
|
|
135
227
|
"args": [
|
|
136
|
-
{
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
228
|
+
{
|
|
229
|
+
"name": "action",
|
|
230
|
+
"label": "Credential action",
|
|
231
|
+
"type": "choice",
|
|
232
|
+
"options": [
|
|
233
|
+
"status",
|
|
234
|
+
"set"
|
|
235
|
+
],
|
|
236
|
+
"positional": true
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
"name": "provider",
|
|
240
|
+
"label": "Credential provider",
|
|
241
|
+
"type": "choice",
|
|
242
|
+
"options": [
|
|
243
|
+
"openrouter",
|
|
244
|
+
"google"
|
|
245
|
+
],
|
|
246
|
+
"positional": true
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
"name": "value",
|
|
250
|
+
"label": "Secret value through stdin",
|
|
251
|
+
"type": "string",
|
|
252
|
+
"secret": true
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
"name": "stdin",
|
|
256
|
+
"label": "Read secret from stdin",
|
|
257
|
+
"type": "boolean",
|
|
258
|
+
"flag": "--stdin"
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
"name": "json",
|
|
262
|
+
"label": "JSON output",
|
|
263
|
+
"type": "boolean",
|
|
264
|
+
"flag": "--json"
|
|
265
|
+
}
|
|
141
266
|
]
|
|
142
267
|
},
|
|
143
268
|
{
|
|
@@ -146,9 +271,24 @@
|
|
|
146
271
|
"effect": "read",
|
|
147
272
|
"output": "json",
|
|
148
273
|
"args": [
|
|
149
|
-
{
|
|
150
|
-
|
|
151
|
-
|
|
274
|
+
{
|
|
275
|
+
"name": "allVaults",
|
|
276
|
+
"label": "Inspect all registered vaults",
|
|
277
|
+
"type": "boolean",
|
|
278
|
+
"flag": "--all-vaults"
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
"name": "node",
|
|
282
|
+
"label": "Mesh node",
|
|
283
|
+
"type": "string",
|
|
284
|
+
"flag": "--node"
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
"name": "json",
|
|
288
|
+
"label": "JSON output",
|
|
289
|
+
"type": "boolean",
|
|
290
|
+
"flag": "--json"
|
|
291
|
+
}
|
|
152
292
|
]
|
|
153
293
|
},
|
|
154
294
|
{
|
|
@@ -268,7 +408,7 @@
|
|
|
268
408
|
},
|
|
269
409
|
{
|
|
270
410
|
"name": "refresh",
|
|
271
|
-
"description": "Report which registered projects' generated OpenWiki pages are stale; --apply
|
|
411
|
+
"description": "Report which registered projects' generated OpenWiki pages are stale; --apply updates existing wikis (openwiki/ only), never creates one, and skips excluded repositories",
|
|
272
412
|
"timeout_ms": 600000,
|
|
273
413
|
"effect": "write",
|
|
274
414
|
"output": "json",
|
|
@@ -291,6 +431,12 @@
|
|
|
291
431
|
"label": "Force regeneration",
|
|
292
432
|
"type": "boolean"
|
|
293
433
|
},
|
|
434
|
+
{
|
|
435
|
+
"name": "budgetMs",
|
|
436
|
+
"flag": "--budget-ms",
|
|
437
|
+
"label": "Start no generation that cannot finish within this many milliseconds",
|
|
438
|
+
"type": "number"
|
|
439
|
+
},
|
|
294
440
|
{
|
|
295
441
|
"name": "json",
|
|
296
442
|
"flag": "--json",
|
|
@@ -422,6 +568,57 @@
|
|
|
422
568
|
"type": "boolean"
|
|
423
569
|
}
|
|
424
570
|
]
|
|
571
|
+
},
|
|
572
|
+
{
|
|
573
|
+
"name": "schedule",
|
|
574
|
+
"description": "Show or choose the node that runs the nightly wiki refresh (task auto-refresh)",
|
|
575
|
+
"effect": "write",
|
|
576
|
+
"output": "json",
|
|
577
|
+
"args": [
|
|
578
|
+
{
|
|
579
|
+
"name": "node",
|
|
580
|
+
"flag": "--node",
|
|
581
|
+
"label": "Mesh hostname, or self for this machine",
|
|
582
|
+
"type": "string"
|
|
583
|
+
},
|
|
584
|
+
{
|
|
585
|
+
"name": "off",
|
|
586
|
+
"flag": "--off",
|
|
587
|
+
"label": "Stop the nightly refresh on every node",
|
|
588
|
+
"type": "boolean"
|
|
589
|
+
},
|
|
590
|
+
{
|
|
591
|
+
"name": "json",
|
|
592
|
+
"flag": "--json",
|
|
593
|
+
"label": "JSON output",
|
|
594
|
+
"type": "boolean"
|
|
595
|
+
}
|
|
596
|
+
]
|
|
597
|
+
},
|
|
598
|
+
{
|
|
599
|
+
"name": "exclude",
|
|
600
|
+
"description": "List, add or remove repositories the wiki refresh and generate never touch (clones, forks, backups)",
|
|
601
|
+
"effect": "write",
|
|
602
|
+
"args": [
|
|
603
|
+
{
|
|
604
|
+
"name": "targets",
|
|
605
|
+
"type": "string",
|
|
606
|
+
"label": "Registered project name or absolute path",
|
|
607
|
+
"positional": true
|
|
608
|
+
},
|
|
609
|
+
{
|
|
610
|
+
"name": "remove",
|
|
611
|
+
"flag": "--remove",
|
|
612
|
+
"label": "Take the repositories off the list",
|
|
613
|
+
"type": "boolean"
|
|
614
|
+
},
|
|
615
|
+
{
|
|
616
|
+
"name": "json",
|
|
617
|
+
"flag": "--json",
|
|
618
|
+
"label": "JSON output",
|
|
619
|
+
"type": "boolean"
|
|
620
|
+
}
|
|
621
|
+
]
|
|
425
622
|
}
|
|
426
623
|
]
|
|
427
624
|
},
|
|
@@ -463,5 +660,19 @@
|
|
|
463
660
|
"status": {
|
|
464
661
|
"command": "status",
|
|
465
662
|
"refresh_seconds": 300
|
|
466
|
-
}
|
|
663
|
+
},
|
|
664
|
+
"reuse": {
|
|
665
|
+
"commands": [
|
|
666
|
+
"total-recall auth secret",
|
|
667
|
+
"total-recall ssss status"
|
|
668
|
+
],
|
|
669
|
+
"owned": "Documentation hub discovery, wiki page auditing, staleness tracking, and OpenWiki knowledge ingestion."
|
|
670
|
+
},
|
|
671
|
+
"skills": [
|
|
672
|
+
{
|
|
673
|
+
"id": "openwiki",
|
|
674
|
+
"path": "./skills/openwiki/SKILL.md",
|
|
675
|
+
"description": "Multi-repo knowledge graph and documentation wiki engine for Total Recall."
|
|
676
|
+
}
|
|
677
|
+
]
|
|
467
678
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: openwiki
|
|
3
|
+
description: "Multi-repo knowledge graph and documentation wiki engine for Total Recall."
|
|
4
|
+
version: 0.4.0
|
|
5
|
+
repo_scoped: false
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# OpenWiki
|
|
9
|
+
|
|
10
|
+
Multi-repo knowledge graph and documentation wiki engine for Total Recall.
|
|
11
|
+
|
|
12
|
+
## When to Use
|
|
13
|
+
|
|
14
|
+
Use the `openwiki` Total Recall plugin (`total-recall openwiki`) instead of ad-hoc scripts or raw commands whenever working on openwiki tasks.
|
|
15
|
+
|
|
16
|
+
## Commands
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
total-recall openwiki --help
|
|
20
|
+
total-recall openwiki context # Retrieve task-relevant wiki and explicitly linked source evidence with provenance and freshness
|
|
21
|
+
total-recall openwiki search # Search evidence passages in workspace, registered-vault or mesh documentation hubs
|
|
22
|
+
total-recall openwiki graph # Extract documentation link topology as JSON, Mermaid or DOT
|
|
23
|
+
total-recall openwiki generate # Generate documentation for the selected registered repository or current workspace
|
|
24
|
+
total-recall openwiki token # Inspect provider credential status or save a provider key through the shared auth owner
|
|
25
|
+
total-recall openwiki lint # Inspect documentation links and orphaned hubs without rewriting files
|
|
26
|
+
total-recall openwiki status # Show which OpenWiki subcommands are implemented
|
|
27
|
+
total-recall openwiki hubs # List indexed OpenWiki hubs and page counts
|
|
28
|
+
total-recall openwiki ingest # Ingest markdown documentation into the semantic knowledge graph
|
|
29
|
+
total-recall openwiki bootstrap # Create missing OpenWiki documentation pages in explicit brain and project directories
|
|
30
|
+
total-recall openwiki probe # Run HTTP 200 health verification probe
|
|
31
|
+
total-recall openwiki refresh # Report which registered projects' generated OpenWiki pages are stale; --apply updates existing wikis (openwiki/ only), never creates one, and skips excluded repositories
|
|
32
|
+
```
|
|
@@ -6,14 +6,31 @@ import fs from 'node:fs';
|
|
|
6
6
|
import os from 'node:os';
|
|
7
7
|
import path from 'node:path';
|
|
8
8
|
|
|
9
|
+
// No model default: models and prices change too often to fix one in code, and a stale
|
|
10
|
+
// default (deepseek/deepseek-chat) cost about 5x a current model of the same family.
|
|
11
|
+
// A refresh with no configured model stops before it calls a provider.
|
|
12
|
+
//
|
|
13
|
+
// exclude lists repository roots the refresh never touches: upstream clones,
|
|
14
|
+
// forks, backups and test probes. Registering a repository with Total Recall
|
|
15
|
+
// gives it a brain; it does not make its code something to document.
|
|
9
16
|
export const DEFAULT_OPENWIKI_CONFIG = Object.freeze({
|
|
10
17
|
provider: 'openrouter',
|
|
11
|
-
model:
|
|
12
|
-
fallback_model:
|
|
18
|
+
model: null,
|
|
19
|
+
fallback_model: null,
|
|
13
20
|
max_tokens: 4096,
|
|
14
|
-
timeout_ms: 300000
|
|
21
|
+
timeout_ms: 300000,
|
|
22
|
+
exclude: Object.freeze([])
|
|
15
23
|
});
|
|
16
24
|
|
|
25
|
+
/** Absolute, de-duplicated, sorted repository roots. */
|
|
26
|
+
export function normalizeExclude(list) {
|
|
27
|
+
if (!Array.isArray(list)) return [];
|
|
28
|
+
const roots = list
|
|
29
|
+
.filter((entry) => typeof entry === 'string' && entry.trim() && path.isAbsolute(entry.trim()))
|
|
30
|
+
.map((entry) => path.resolve(entry.trim()));
|
|
31
|
+
return [...new Set(roots)].sort();
|
|
32
|
+
}
|
|
33
|
+
|
|
17
34
|
export const ALLOWED_CONFIG_KEYS = Object.freeze([
|
|
18
35
|
'provider',
|
|
19
36
|
'model',
|
|
@@ -41,12 +58,12 @@ export function loadOpenWikiConfig(options = {}) {
|
|
|
41
58
|
const filePath = resolveConfigPath(options);
|
|
42
59
|
try {
|
|
43
60
|
if (!fs.existsSync(filePath)) {
|
|
44
|
-
return { ...DEFAULT_OPENWIKI_CONFIG };
|
|
61
|
+
return { ...DEFAULT_OPENWIKI_CONFIG, exclude: [] };
|
|
45
62
|
}
|
|
46
63
|
const raw = fs.readFileSync(filePath, 'utf8');
|
|
47
64
|
const parsed = JSON.parse(raw);
|
|
48
65
|
if (!parsed || typeof parsed !== 'object') {
|
|
49
|
-
return { ...DEFAULT_OPENWIKI_CONFIG };
|
|
66
|
+
return { ...DEFAULT_OPENWIKI_CONFIG, exclude: [] };
|
|
50
67
|
}
|
|
51
68
|
return {
|
|
52
69
|
provider: typeof parsed.provider === 'string' && parsed.provider ? parsed.provider : DEFAULT_OPENWIKI_CONFIG.provider,
|
|
@@ -57,10 +74,11 @@ export function loadOpenWikiConfig(options = {}) {
|
|
|
57
74
|
: DEFAULT_OPENWIKI_CONFIG.max_tokens,
|
|
58
75
|
timeout_ms: Number.isInteger(parsed.timeout_ms) && parsed.timeout_ms >= 30000 && parsed.timeout_ms <= 1800000
|
|
59
76
|
? parsed.timeout_ms
|
|
60
|
-
: DEFAULT_OPENWIKI_CONFIG.timeout_ms
|
|
77
|
+
: DEFAULT_OPENWIKI_CONFIG.timeout_ms,
|
|
78
|
+
exclude: normalizeExclude(parsed.exclude)
|
|
61
79
|
};
|
|
62
80
|
} catch {
|
|
63
|
-
return { ...DEFAULT_OPENWIKI_CONFIG };
|
|
81
|
+
return { ...DEFAULT_OPENWIKI_CONFIG, exclude: [] };
|
|
64
82
|
}
|
|
65
83
|
}
|
|
66
84
|
|
|
@@ -69,18 +87,16 @@ export function saveOpenWikiConfig(config, options = {}) {
|
|
|
69
87
|
const filePath = resolveConfigPath(options);
|
|
70
88
|
const validated = {
|
|
71
89
|
provider: String(config.provider || DEFAULT_OPENWIKI_CONFIG.provider).toLowerCase(),
|
|
72
|
-
model:
|
|
73
|
-
fallback_model:
|
|
90
|
+
model: config.model ? String(config.model).trim() || null : null,
|
|
91
|
+
fallback_model: config.fallback_model ? String(config.fallback_model).trim() || null : null,
|
|
74
92
|
max_tokens: Number.isInteger(Number(config.max_tokens)) ? Math.max(512, Math.min(131072, Number(config.max_tokens))) : DEFAULT_OPENWIKI_CONFIG.max_tokens,
|
|
75
|
-
timeout_ms: Number.isInteger(Number(config.timeout_ms)) ? Math.max(30000, Math.min(1800000, Number(config.timeout_ms))) : DEFAULT_OPENWIKI_CONFIG.timeout_ms
|
|
93
|
+
timeout_ms: Number.isInteger(Number(config.timeout_ms)) ? Math.max(30000, Math.min(1800000, Number(config.timeout_ms))) : DEFAULT_OPENWIKI_CONFIG.timeout_ms,
|
|
94
|
+
exclude: normalizeExclude(config.exclude)
|
|
76
95
|
};
|
|
77
96
|
|
|
78
97
|
if (!ALLOWED_PROVIDERS.includes(validated.provider)) {
|
|
79
98
|
throw new Error(`Invalid provider: ${validated.provider}. Allowed: ${ALLOWED_PROVIDERS.join(', ')}`);
|
|
80
99
|
}
|
|
81
|
-
if (!validated.model) {
|
|
82
|
-
throw new Error('Model identifier cannot be empty');
|
|
83
|
-
}
|
|
84
100
|
|
|
85
101
|
const dir = path.dirname(filePath);
|
|
86
102
|
if (!fs.existsSync(dir)) {
|
|
@@ -123,7 +139,17 @@ export function setOpenWikiConfigValue(key, value, options = {}) {
|
|
|
123
139
|
return saveOpenWikiConfig(current, options);
|
|
124
140
|
}
|
|
125
141
|
|
|
126
|
-
/**
|
|
142
|
+
/**
|
|
143
|
+
* Reset the generator settings to defaults. The exclude list is kept: a reset
|
|
144
|
+
* must not put clones and backups back into a paid refresh.
|
|
145
|
+
*/
|
|
127
146
|
export function resetOpenWikiConfig(options = {}) {
|
|
128
|
-
|
|
147
|
+
const { exclude } = loadOpenWikiConfig(options);
|
|
148
|
+
return saveOpenWikiConfig({ ...DEFAULT_OPENWIKI_CONFIG, exclude }, options);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** Replace the list of repository roots the refresh never touches. */
|
|
152
|
+
export function setExcludedRoots(roots, options = {}) {
|
|
153
|
+
const current = loadOpenWikiConfig(options);
|
|
154
|
+
return saveOpenWikiConfig({ ...current, exclude: roots }, options);
|
|
129
155
|
}
|
|
@@ -8,7 +8,7 @@ import fs from 'node:fs';
|
|
|
8
8
|
import path from 'node:path';
|
|
9
9
|
import { spawn } from 'node:child_process';
|
|
10
10
|
import { loadOpenWikiConfig } from './config.mjs';
|
|
11
|
-
import { readProjects, resolveGenerator, resolveKey } from './refresh.mjs';
|
|
11
|
+
import { buildGeneratorInvocation, ensureDefaultIgnores, readProjects, redact, resolveGenerator, resolveKey } from './refresh.mjs';
|
|
12
12
|
import { execOnMeshNode, getMeshNodes } from './mesh-vaults.mjs';
|
|
13
13
|
|
|
14
14
|
export async function generateWiki({
|
|
@@ -70,6 +70,12 @@ export async function generateWiki({
|
|
|
70
70
|
throw new Error(`Target path does not exist: ${resolvedTarget}`);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
// An excluded repository (an upstream clone, fork, backup or probe) is never
|
|
74
|
+
// documented, even from inside its own checkout.
|
|
75
|
+
if ((loadOpenWikiConfig().exclude || []).includes(path.resolve(resolvedTarget))) {
|
|
76
|
+
throw new Error(`${repoName} is excluded from OpenWiki. To document it, first run: total-recall openwiki exclude --remove ${repoName}`);
|
|
77
|
+
}
|
|
78
|
+
|
|
73
79
|
const outPath = outputDir ? path.resolve(resolvedTarget, outputDir) : path.join(resolvedTarget, 'openwiki');
|
|
74
80
|
|
|
75
81
|
if (dryRun) {
|
|
@@ -92,31 +98,30 @@ export async function generateWiki({
|
|
|
92
98
|
}
|
|
93
99
|
|
|
94
100
|
const gen = resolveGenerator();
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
// Pass --init or update mode
|
|
98
|
-
const isInit = !fs.existsSync(outPath) || force;
|
|
99
|
-
if (isInit) {
|
|
100
|
-
generatorArgs.push('--init');
|
|
101
|
+
if (!gen.command) {
|
|
102
|
+
throw new Error('No openwiki generator available (missing bundled generator, local .bin, PATH entry, or npx)');
|
|
101
103
|
}
|
|
102
104
|
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
105
|
+
const mode = (!fs.existsSync(outPath) || force) ? 'init' : 'update';
|
|
106
|
+
const timeoutMs = config.timeout_ms || 300000;
|
|
107
|
+
const { cmdArgs, childEnv } = buildGeneratorInvocation({
|
|
108
|
+
baseArgs: gen.args,
|
|
109
|
+
mode,
|
|
110
|
+
config,
|
|
111
|
+
key,
|
|
112
|
+
});
|
|
113
|
+
ensureDefaultIgnores(resolvedTarget);
|
|
110
114
|
|
|
111
115
|
const startedAt = Date.now();
|
|
112
116
|
if (typeof onProgress === 'function') {
|
|
113
|
-
onProgress(`Starting generator for ${repoName} (${gen.via})...`);
|
|
117
|
+
onProgress(`Starting generator for ${repoName} (${gen.via}, ${mode})...`);
|
|
114
118
|
}
|
|
115
119
|
|
|
116
120
|
return new Promise((resolve, reject) => {
|
|
117
|
-
const child = spawn(gen.command,
|
|
121
|
+
const child = spawn(gen.command, cmdArgs, {
|
|
118
122
|
cwd: resolvedTarget,
|
|
119
|
-
env,
|
|
123
|
+
env: childEnv,
|
|
124
|
+
timeout: timeoutMs,
|
|
120
125
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
121
126
|
});
|
|
122
127
|
|
|
@@ -127,7 +132,7 @@ export async function generateWiki({
|
|
|
127
132
|
const str = chunk.toString();
|
|
128
133
|
stdout += str;
|
|
129
134
|
if (typeof onProgress === 'function') {
|
|
130
|
-
onProgress(str.trim());
|
|
135
|
+
onProgress(redact(str.trim(), key));
|
|
131
136
|
}
|
|
132
137
|
});
|
|
133
138
|
|
|
@@ -135,7 +140,7 @@ export async function generateWiki({
|
|
|
135
140
|
stderr += chunk.toString();
|
|
136
141
|
});
|
|
137
142
|
|
|
138
|
-
child.on('close', (code) => {
|
|
143
|
+
child.on('close', (code, signal) => {
|
|
139
144
|
const durationMs = Date.now() - startedAt;
|
|
140
145
|
if (code === 0) {
|
|
141
146
|
resolve({
|
|
@@ -144,17 +149,19 @@ export async function generateWiki({
|
|
|
144
149
|
targetPath: resolvedTarget,
|
|
145
150
|
outputDir: outPath,
|
|
146
151
|
generatorVia: gen.via,
|
|
152
|
+
mode,
|
|
147
153
|
durationMs,
|
|
148
154
|
credential: from,
|
|
149
|
-
stdout: stdout.trim(),
|
|
155
|
+
stdout: redact(stdout.trim(), key),
|
|
150
156
|
});
|
|
151
157
|
} else {
|
|
152
|
-
|
|
158
|
+
const detail = redact(stderr || stdout || (signal ? `terminated by ${signal}` : 'Unknown error'), key);
|
|
159
|
+
reject(new Error(`Generator exited with code ${code ?? signal ?? 1}: ${detail}`));
|
|
153
160
|
}
|
|
154
161
|
});
|
|
155
162
|
|
|
156
163
|
child.on('error', (err) => {
|
|
157
|
-
reject(new Error(`Failed to spawn generator: ${err.message}`));
|
|
164
|
+
reject(new Error(`Failed to spawn generator: ${redact(err.message, key)}`));
|
|
158
165
|
});
|
|
159
166
|
});
|
|
160
167
|
}
|