total-recall-brain 3.47.0 → 3.47.2
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/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 +4 -4
- package/scaffold/.agent/skills/total-recall/plugins/git/package.json +3 -2
- package/scaffold/.agent/skills/total-recall/plugins/git/plugin.json +293 -58
- package/scaffold/.agent/skills/total-recall/plugins/git/skills/git/SKILL.md +36 -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-lock.json +6 -6
- 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 +8 -2
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/included-usage.mjs +2 -2
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/learner.mjs +7 -0
- 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/pool.mjs +2 -2
- 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 +11 -5
- 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 +56 -7
- 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 +199 -36
- 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 +34 -8
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/generate.mjs +6 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh.mjs +15 -7
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/upstream-watcher.mjs +4 -3
- 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/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/cli/update.mjs +20 -1
- package/src/core/automatic-brain-updates.mjs +8 -4
- package/src/core/brain-updates.mjs +25 -6
- 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/core/release-defaults-handoff.mjs +89 -0
|
@@ -11,7 +11,7 @@ import { CREDIT_REFUSAL, NO_MODEL, describeRetention, hasWiki, isDue, readProjec
|
|
|
11
11
|
|
|
12
12
|
const DEFAULT_REPO_CONCURRENCY = 2;
|
|
13
13
|
import { watchUpstream, propagateUpdates, readUpstreamState, bundledGeneratorVersion } from './src/upstream-watcher.mjs';
|
|
14
|
-
import { loadOpenWikiConfig, setOpenWikiConfigValue, resetOpenWikiConfig, resolveConfigPath, ALLOWED_CONFIG_KEYS, ALLOWED_PROVIDERS } from './src/config.mjs';
|
|
14
|
+
import { loadOpenWikiConfig, setOpenWikiConfigValue, resetOpenWikiConfig, resolveConfigPath, setExcludedRoots, ALLOWED_CONFIG_KEYS, ALLOWED_PROVIDERS } from './src/config.mjs';
|
|
15
15
|
import { discoverAllHubs } from './src/mesh-vaults.mjs';
|
|
16
16
|
import { searchWikiHubs } from './src/search.mjs';
|
|
17
17
|
import { buildKnowledgeGraph } from './src/graph.mjs';
|
|
@@ -83,8 +83,12 @@ export async function refreshCommand(args, {
|
|
|
83
83
|
continue;
|
|
84
84
|
}
|
|
85
85
|
if (!state.due) {
|
|
86
|
-
if (state.
|
|
86
|
+
if (state.excluded) {
|
|
87
|
+
reports.push({ ...project, action: 'excluded', reason: state.reason });
|
|
88
|
+
} else if (state.skipped) {
|
|
87
89
|
reports.push({ ...project, action: 'skipped', reason: state.reason });
|
|
90
|
+
} else if (state.uninitialized && !state.held) {
|
|
91
|
+
reports.push({ ...project, action: 'no-wiki', uninitialized: true, reason: state.reason, generatedAt: state.generatedAt });
|
|
88
92
|
} else if (state.held) {
|
|
89
93
|
reports.push({ ...project, action: 'held', uninitialized: Boolean(state.uninitialized), reason: state.reason, generationCommit: state.generationCommit, generationTime: state.generationTime, generatedAt: state.generatedAt, commitsSince: state.commitsSince });
|
|
90
94
|
} else {
|
|
@@ -202,9 +206,10 @@ export async function refreshCommand(args, {
|
|
|
202
206
|
note: payloadBudgetNote,
|
|
203
207
|
counts: {
|
|
204
208
|
registered: projects.length,
|
|
205
|
-
withPages: reports.filter((r) => r.action
|
|
209
|
+
withPages: reports.filter((r) => !['skipped', 'excluded'].includes(r.action) && !r.uninitialized).length,
|
|
206
210
|
due: due.length,
|
|
207
211
|
uninitialized: reports.filter((r) => r.uninitialized).length,
|
|
212
|
+
excluded: reports.filter((r) => r.action === 'excluded').length,
|
|
208
213
|
refreshed: reports.filter((r) => r.action === 'refreshed' || r.action === 'initialized').length,
|
|
209
214
|
failed: failed.length,
|
|
210
215
|
partial: partial.length,
|
|
@@ -217,11 +222,11 @@ export async function refreshCommand(args, {
|
|
|
217
222
|
};
|
|
218
223
|
if (json) console.log(JSON.stringify(payload, null, 2));
|
|
219
224
|
else {
|
|
220
|
-
console.log(`OpenWiki refresh (${apply ? 'apply' : 'report'}): ${payload.counts.registered} registered, ${payload.counts.due} due
|
|
225
|
+
console.log(`OpenWiki refresh (${apply ? 'apply' : 'report'}): ${payload.counts.registered} registered, ${payload.counts.due} due, ${payload.counts.uninitialized} without a finished wiki, ${payload.counts.excluded} excluded`);
|
|
221
226
|
// Put failures last so bounded scheduler tails retain their causes.
|
|
222
227
|
for (const r of [...reports].sort((a, b) => Number(['failed', 'partial'].includes(a.action)) - Number(['failed', 'partial'].includes(b.action)))) {
|
|
223
|
-
if (r.action === 'current') continue;
|
|
224
|
-
const age = r.action === 'skipped' ? 'outside repository generation' : r.generationTime ? `generated ${r.generationTime} at ${r.generationCommit}` : r.uninitialized ? '
|
|
228
|
+
if (r.action === 'current' || r.action === 'excluded') continue;
|
|
229
|
+
const age = r.action === 'skipped' ? 'outside repository generation' : r.generationTime ? `generated ${r.generationTime} at ${r.generationCommit}` : r.uninitialized ? 'no finished wiki' : (r.generatedAt ? `last attempt ${r.generatedAt}; generation commit unknown` : 'never generated');
|
|
225
230
|
console.log(` ${r.action.padEnd(9)} ${r.name.padEnd(28)} ${age}${Number.isFinite(r.commitsSince) && r.commitsSince !== Infinity ? `, ${r.commitsSince} commits since` : ''}${r.reason ? ` — ${r.reason}` : ''}`);
|
|
226
231
|
}
|
|
227
232
|
if (payloadBudgetNote) console.log(payloadBudgetNote);
|
|
@@ -730,6 +735,46 @@ export async function scheduleCommand(args = [], { core = null, config = loadOpe
|
|
|
730
735
|
}
|
|
731
736
|
}
|
|
732
737
|
|
|
738
|
+
/**
|
|
739
|
+
* List, add or remove repositories the refresh never touches. Takes registered
|
|
740
|
+
* project names or absolute paths; with none, lists the current exclusions.
|
|
741
|
+
*/
|
|
742
|
+
export async function excludeCommand(args = [], { read = readProjects, load = loadOpenWikiConfig, save = setExcludedRoots } = {}) {
|
|
743
|
+
const json = args.includes('--json');
|
|
744
|
+
const usage = 'Usage: total-recall openwiki exclude [<name|absolute path>...] [--remove] [--json]';
|
|
745
|
+
if (args.includes('--help') || args.includes('-h')) { console.log(usage); return; }
|
|
746
|
+
const remove = args.includes('--remove');
|
|
747
|
+
const targets = args.filter((a) => !a.startsWith('--'));
|
|
748
|
+
try {
|
|
749
|
+
if (remove && !targets.length) throw new Error(usage);
|
|
750
|
+
let roots = load().exclude || [];
|
|
751
|
+
if (targets.length) {
|
|
752
|
+
let projects = [];
|
|
753
|
+
try { projects = read({ exclude: [] }); } catch { projects = []; }
|
|
754
|
+
const chosen = [];
|
|
755
|
+
for (const target of targets) {
|
|
756
|
+
const matches = projects.filter((p) => p.name === target || (path.isAbsolute(target) && path.resolve(p.root) === path.resolve(target)));
|
|
757
|
+
if (matches.length > 1) throw new Error(`${target} names ${matches.length} registered projects; pass its absolute path`);
|
|
758
|
+
if (matches.length === 1) chosen.push(path.resolve(matches[0].root));
|
|
759
|
+
else if (path.isAbsolute(target)) chosen.push(path.resolve(target));
|
|
760
|
+
else throw new Error(`${target} is not a registered project name or an absolute path`);
|
|
761
|
+
}
|
|
762
|
+
roots = save(remove ? roots.filter((root) => !chosen.includes(root)) : [...roots, ...chosen]).exclude;
|
|
763
|
+
}
|
|
764
|
+
const payload = { ok: true, changed: targets.length > 0, exclude: roots };
|
|
765
|
+
if (json) console.log(JSON.stringify(payload, null, 2));
|
|
766
|
+
else {
|
|
767
|
+
console.log(`OpenWiki never refreshes ${roots.length} ${roots.length === 1 ? 'repository' : 'repositories'}${roots.length ? ':' : '.'}`);
|
|
768
|
+
for (const root of roots) console.log(` ${root}`);
|
|
769
|
+
}
|
|
770
|
+
return payload;
|
|
771
|
+
} catch (err) {
|
|
772
|
+
if (json) console.log(JSON.stringify({ ok: false, error: err.message }));
|
|
773
|
+
else console.error(`OpenWiki exclude: ${err.message}`);
|
|
774
|
+
process.exitCode = 1;
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
|
|
733
778
|
async function autoRefreshCommand(args = []) {
|
|
734
779
|
const forwardArgs = args.includes('--apply') ? [...args] : ['--apply', ...args];
|
|
735
780
|
if (!forwardArgs.some((a) => a === '--budget-ms' || a.startsWith('--budget-ms='))) {
|
|
@@ -760,6 +805,7 @@ IMPLEMENTED.watch = watchCommand;
|
|
|
760
805
|
IMPLEMENTED.propagate = propagateCommand;
|
|
761
806
|
IMPLEMENTED.config = configCommand;
|
|
762
807
|
IMPLEMENTED.schedule = scheduleCommand;
|
|
808
|
+
IMPLEMENTED.exclude = excludeCommand;
|
|
763
809
|
IMPLEMENTED.search = searchCommand;
|
|
764
810
|
IMPLEMENTED.graph = graphCommand;
|
|
765
811
|
IMPLEMENTED.token = tokenCommand;
|
|
@@ -830,7 +876,10 @@ export async function run(argv = process.argv) {
|
|
|
830
876
|
Create missing plugin-owned documentation pages
|
|
831
877
|
refresh [--repo <name>] [--apply] [--force] [--json]
|
|
832
878
|
Report which registered projects' generated pages are stale;
|
|
833
|
-
--apply regenerates stale pages (writes openwiki/ only)
|
|
879
|
+
--apply regenerates stale pages (writes openwiki/ only).
|
|
880
|
+
Never creates a wiki: use generate for that
|
|
881
|
+
exclude [<name|path>...] [--remove] [--json]
|
|
882
|
+
List, add or remove repositories the refresh never touches
|
|
834
883
|
auto-refresh [--repo <name>] [--force] [--json]
|
|
835
884
|
Automated daemon trigger to regenerate stale pages across repositories
|
|
836
885
|
config [show|get <key>|set <key> <value>|reset] [--json]
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tr-plugin-openwiki",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "tr-plugin-openwiki",
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.4.0",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@gregiteen/ssss-cli": "0.14.5"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
|
-
"total-recall-brain": "3.
|
|
15
|
+
"total-recall-brain": "3.47.0"
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
18
|
"node_modules/@alcalzone/ansi-tokenize": {
|
|
@@ -5529,9 +5529,9 @@
|
|
|
5529
5529
|
}
|
|
5530
5530
|
},
|
|
5531
5531
|
"node_modules/total-recall-brain": {
|
|
5532
|
-
"version": "3.
|
|
5533
|
-
"resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.
|
|
5534
|
-
"integrity": "sha512-
|
|
5532
|
+
"version": "3.47.0",
|
|
5533
|
+
"resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.47.0.tgz",
|
|
5534
|
+
"integrity": "sha512-S4UIdbbTyxw7C4+rix+7oHMm/6gYkcxwNBcP6kRDySX40p5IgqVTKgHk1n8rmaKiyYFoIX/HZHlHSjNrHgn0Gw==",
|
|
5535
5535
|
"dev": true,
|
|
5536
5536
|
"license": "MIT",
|
|
5537
5537
|
"workspaces": [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tr-plugin-openwiki",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Multi-repo knowledge graph and documentation wiki engine for Total Recall",
|
|
6
6
|
"scripts": {
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
"src/",
|
|
19
19
|
"vendor/",
|
|
20
20
|
"capability/",
|
|
21
|
-
"templates/"
|
|
21
|
+
"templates/",
|
|
22
|
+
"skills/"
|
|
22
23
|
],
|
|
23
24
|
"dependencies": {
|
|
24
25
|
"@gregiteen/ssss-cli": "0.14.5"
|
|
@@ -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": {
|
|
@@ -72,7 +72,11 @@
|
|
|
72
72
|
]
|
|
73
73
|
},
|
|
74
74
|
"gate": {
|
|
75
|
-
"tasks": [
|
|
75
|
+
"tasks": [
|
|
76
|
+
"Search or read a repository's wiki",
|
|
77
|
+
"Generate or refresh wiki pages",
|
|
78
|
+
"Ingest documentation into memory"
|
|
79
|
+
],
|
|
76
80
|
"owned_commands": []
|
|
77
81
|
},
|
|
78
82
|
"cli": {
|
|
@@ -85,8 +89,19 @@
|
|
|
85
89
|
"effect": "read",
|
|
86
90
|
"output": "json",
|
|
87
91
|
"args": [
|
|
88
|
-
{
|
|
89
|
-
|
|
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
|
+
}
|
|
90
105
|
]
|
|
91
106
|
},
|
|
92
107
|
{
|
|
@@ -95,11 +110,37 @@
|
|
|
95
110
|
"effect": "read",
|
|
96
111
|
"output": "json",
|
|
97
112
|
"args": [
|
|
98
|
-
{
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
+
}
|
|
103
144
|
]
|
|
104
145
|
},
|
|
105
146
|
{
|
|
@@ -108,10 +149,35 @@
|
|
|
108
149
|
"effect": "read",
|
|
109
150
|
"output": "json",
|
|
110
151
|
"args": [
|
|
111
|
-
{
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
+
}
|
|
115
181
|
]
|
|
116
182
|
},
|
|
117
183
|
{
|
|
@@ -121,11 +187,36 @@
|
|
|
121
187
|
"output": "json",
|
|
122
188
|
"timeout_ms": 600000,
|
|
123
189
|
"args": [
|
|
124
|
-
{
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
+
}
|
|
129
220
|
]
|
|
130
221
|
},
|
|
131
222
|
{
|
|
@@ -134,11 +225,44 @@
|
|
|
134
225
|
"effect": "write",
|
|
135
226
|
"output": "json",
|
|
136
227
|
"args": [
|
|
137
|
-
{
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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
|
+
}
|
|
142
266
|
]
|
|
143
267
|
},
|
|
144
268
|
{
|
|
@@ -147,9 +271,24 @@
|
|
|
147
271
|
"effect": "read",
|
|
148
272
|
"output": "json",
|
|
149
273
|
"args": [
|
|
150
|
-
{
|
|
151
|
-
|
|
152
|
-
|
|
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
|
+
}
|
|
153
292
|
]
|
|
154
293
|
},
|
|
155
294
|
{
|
|
@@ -269,7 +408,7 @@
|
|
|
269
408
|
},
|
|
270
409
|
{
|
|
271
410
|
"name": "refresh",
|
|
272
|
-
"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",
|
|
273
412
|
"timeout_ms": 600000,
|
|
274
413
|
"effect": "write",
|
|
275
414
|
"output": "json",
|
|
@@ -455,6 +594,31 @@
|
|
|
455
594
|
"type": "boolean"
|
|
456
595
|
}
|
|
457
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
|
+
]
|
|
458
622
|
}
|
|
459
623
|
]
|
|
460
624
|
},
|
|
@@ -493,14 +657,6 @@
|
|
|
493
657
|
"formatPropagationReceipt"
|
|
494
658
|
]
|
|
495
659
|
},
|
|
496
|
-
"auth": {
|
|
497
|
-
"plugin": "auth",
|
|
498
|
-
"methods": [
|
|
499
|
-
"passkey",
|
|
500
|
-
"google-oauth2"
|
|
501
|
-
],
|
|
502
|
-
"session_verification": true
|
|
503
|
-
},
|
|
504
660
|
"status": {
|
|
505
661
|
"command": "status",
|
|
506
662
|
"refresh_seconds": 300
|
|
@@ -511,5 +667,12 @@
|
|
|
511
667
|
"total-recall ssss status"
|
|
512
668
|
],
|
|
513
669
|
"owned": "Documentation hub discovery, wiki page auditing, staleness tracking, and OpenWiki knowledge ingestion."
|
|
514
|
-
}
|
|
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
|
+
]
|
|
515
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
|
+
```
|
|
@@ -9,14 +9,28 @@ import path from 'node:path';
|
|
|
9
9
|
// No model default: models and prices change too often to fix one in code, and a stale
|
|
10
10
|
// default (deepseek/deepseek-chat) cost about 5x a current model of the same family.
|
|
11
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.
|
|
12
16
|
export const DEFAULT_OPENWIKI_CONFIG = Object.freeze({
|
|
13
17
|
provider: 'openrouter',
|
|
14
18
|
model: null,
|
|
15
19
|
fallback_model: null,
|
|
16
20
|
max_tokens: 4096,
|
|
17
|
-
timeout_ms: 300000
|
|
21
|
+
timeout_ms: 300000,
|
|
22
|
+
exclude: Object.freeze([])
|
|
18
23
|
});
|
|
19
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
|
+
|
|
20
34
|
export const ALLOWED_CONFIG_KEYS = Object.freeze([
|
|
21
35
|
'provider',
|
|
22
36
|
'model',
|
|
@@ -44,12 +58,12 @@ export function loadOpenWikiConfig(options = {}) {
|
|
|
44
58
|
const filePath = resolveConfigPath(options);
|
|
45
59
|
try {
|
|
46
60
|
if (!fs.existsSync(filePath)) {
|
|
47
|
-
return { ...DEFAULT_OPENWIKI_CONFIG };
|
|
61
|
+
return { ...DEFAULT_OPENWIKI_CONFIG, exclude: [] };
|
|
48
62
|
}
|
|
49
63
|
const raw = fs.readFileSync(filePath, 'utf8');
|
|
50
64
|
const parsed = JSON.parse(raw);
|
|
51
65
|
if (!parsed || typeof parsed !== 'object') {
|
|
52
|
-
return { ...DEFAULT_OPENWIKI_CONFIG };
|
|
66
|
+
return { ...DEFAULT_OPENWIKI_CONFIG, exclude: [] };
|
|
53
67
|
}
|
|
54
68
|
return {
|
|
55
69
|
provider: typeof parsed.provider === 'string' && parsed.provider ? parsed.provider : DEFAULT_OPENWIKI_CONFIG.provider,
|
|
@@ -60,10 +74,11 @@ export function loadOpenWikiConfig(options = {}) {
|
|
|
60
74
|
: DEFAULT_OPENWIKI_CONFIG.max_tokens,
|
|
61
75
|
timeout_ms: Number.isInteger(parsed.timeout_ms) && parsed.timeout_ms >= 30000 && parsed.timeout_ms <= 1800000
|
|
62
76
|
? parsed.timeout_ms
|
|
63
|
-
: DEFAULT_OPENWIKI_CONFIG.timeout_ms
|
|
77
|
+
: DEFAULT_OPENWIKI_CONFIG.timeout_ms,
|
|
78
|
+
exclude: normalizeExclude(parsed.exclude)
|
|
64
79
|
};
|
|
65
80
|
} catch {
|
|
66
|
-
return { ...DEFAULT_OPENWIKI_CONFIG };
|
|
81
|
+
return { ...DEFAULT_OPENWIKI_CONFIG, exclude: [] };
|
|
67
82
|
}
|
|
68
83
|
}
|
|
69
84
|
|
|
@@ -75,7 +90,8 @@ export function saveOpenWikiConfig(config, options = {}) {
|
|
|
75
90
|
model: config.model ? String(config.model).trim() || null : null,
|
|
76
91
|
fallback_model: config.fallback_model ? String(config.fallback_model).trim() || null : null,
|
|
77
92
|
max_tokens: Number.isInteger(Number(config.max_tokens)) ? Math.max(512, Math.min(131072, Number(config.max_tokens))) : DEFAULT_OPENWIKI_CONFIG.max_tokens,
|
|
78
|
-
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)
|
|
79
95
|
};
|
|
80
96
|
|
|
81
97
|
if (!ALLOWED_PROVIDERS.includes(validated.provider)) {
|
|
@@ -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
|
}
|
|
@@ -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) {
|