total-recall-brain 3.41.2 → 3.41.4
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 +19 -4
- package/frontend/dist/assets/{index-BG9NkVUy.css → index-BIQmqDKP.css} +1 -1
- package/frontend/dist/assets/{index-BtuiZqwP.js → index-CRzjQLu7.js} +7 -7
- package/frontend/dist/index.html +2 -2
- package/frontend/dist/sw.js +8 -5
- package/frontend/src/api/auth.ts +0 -3
- package/frontend/src/components/plugins/PluginPanel.tsx +7 -3
- package/frontend/src/components/plugins/card/CardEngine.tsx +1 -1
- package/frontend/src/pages/LoginPage.tsx +1 -41
- package/frontend/src/pages/PluginsPage.tsx +14 -7
- package/package.json +7 -5
- package/scaffold/.agent/skills/plugin/scripts/record.mjs +6 -3
- package/scaffold/.agent/skills/total-recall/plugins/auth/cli.mjs +197 -31
- package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/auth/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/plugin.json +8 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/cli-secret.mjs +48 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/login-projections.mjs +42 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/mesh-secrets.mjs +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/routes/secrets.mjs +5 -2
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-carriers.mjs +76 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-prune.mjs +37 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-sync.mjs +53 -17
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/DESIGN.md +56 -8
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/card.js +1068 -204
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/panel.js +4 -2
- package/scaffold/.agent/skills/total-recall/plugins/cli-agents/ui/DESIGN.md +32 -0
- package/scaffold/.agent/skills/total-recall/plugins/cli-agents/ui/card.js +436 -274
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +12 -12
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/DESIGN.md +16 -2
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/card.js +461 -242
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +12 -12
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/plugin.json +1 -7
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/DESIGN.md +17 -2
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/card.js +426 -300
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +23 -8
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +6 -2
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/DESIGN.md +32 -0
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/card.js +350 -283
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package-lock.json +23 -8
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package.json +5 -1
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/ui/card.js +31 -19
- package/scaffold/.agent/skills/total-recall/plugins/mesh/package-lock.json +23 -10
- package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +5 -3
- package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/mesh/src/cli/grants.mjs +7 -3
- package/scaffold/.agent/skills/total-recall/plugins/mesh/src/cli/mesh.mjs +61 -38
- package/scaffold/.agent/skills/total-recall/plugins/mesh/src/core/leader-election.mjs +57 -2
- package/scaffold/.agent/skills/total-recall/plugins/mesh/src/core/mesh.mjs +220 -36
- package/scaffold/.agent/skills/total-recall/plugins/mesh/src/server/routes/mesh.mjs +7 -2
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/README.md +65 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/BRICK.md +59 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/index.mjs +534 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/cli.mjs +139 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package-lock.json +2849 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package.json +26 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/plugin.json +376 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/skills/meta-harness/SKILL.md +37 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/adapters/dsh.mjs +446 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/alerts.mjs +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/coordinator.mjs +398 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/documentation.mjs +152 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/executor.mjs +82 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/learner.mjs +90 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/router.mjs +415 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/runtime.mjs +36 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/setup.mjs +35 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/tracker.mjs +133 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worker.mjs +233 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/DESIGN.md +32 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/card.js +845 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/capability/BRICK.md +64 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/capability/index.mjs +250 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/cli.mjs +344 -14
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +2917 -140
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +9 -3
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +223 -5
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/config.mjs +129 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh.mjs +355 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/upstream-watcher.mjs +375 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/DESIGN.md +37 -10
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/card.js +986 -280
- package/scaffold/.agent/skills/total-recall/plugins/security/cli.mjs +7 -1
- package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +25 -10
- package/scaffold/.agent/skills/total-recall/plugins/security/package.json +6 -2
- package/scaffold/.agent/skills/total-recall/plugins/security/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/security/src/scanner.mjs +17 -3
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/DESIGN.md +38 -15
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/card.js +60 -34
- package/src/cli/command.mjs +23 -18
- package/src/cli/config.mjs +3 -0
- package/src/cli/connect.mjs +12 -116
- package/src/cli/daemon.mjs +23 -1
- package/src/cli/harness.mjs +0 -1
- package/src/cli/plugin/copies.mjs +8 -5
- package/src/cli/plugin/create.mjs +56 -3
- package/src/cli/plugin/index.mjs +40 -5
- package/src/cli/plugin/monetization.mjs +232 -12
- package/src/cli/preflight.mjs +161 -0
- package/src/cli/rebuild.mjs +22 -0
- package/src/cli/reset-password.mjs +3 -2
- package/src/cli/skill.mjs +8 -2
- package/src/cli/status.mjs +25 -7
- package/src/core/automatic-brain-updates.mjs +9 -3
- package/src/core/brain-updates.mjs +63 -5
- package/src/core/cli-commands.mjs +2 -0
- package/src/core/context-compiler.mjs +8 -1
- package/src/core/default-plugins.mjs +1 -1
- package/src/core/global-brain-updates.mjs +21 -1
- package/src/core/mesh-brain-updates.mjs +5 -2
- package/src/core/meta-harness.mjs +32 -79
- package/src/core/plugin-dependencies.mjs +6 -1
- package/src/core/plugin-runner.mjs +6 -1
- package/src/core/plugin-store.mjs +67 -1
- package/src/core/plugin-updates.mjs +1 -1
- package/src/core/portable-skills-maintenance.mjs +19 -0
- package/src/core/preflight-gate.mjs +77 -0
- package/src/core/preflight-receipt.mjs +123 -0
- package/src/core/required-plugins.mjs +7 -0
- package/src/core/runtime.mjs +0 -3
- package/src/core/skills-registry.mjs +33 -3
- package/src/core/surface.mjs +38 -1
- package/src/server/auth.mjs +41 -1
- package/src/server/memory-app.mjs +2 -1
- package/src/server/routes/auth.mjs +25 -1
- package/src/server/routes/plugins.mjs +17 -4
|
@@ -3,12 +3,134 @@
|
|
|
3
3
|
* OpenWiki CLI Handler
|
|
4
4
|
* Executed via: npx total-recall openwiki <subcommand>
|
|
5
5
|
*/
|
|
6
|
-
// Scaffold: report honestly what exists. Add each real subcommand to
|
|
7
|
-
// IMPLEMENTED and to plugin.json "cli.subcommands" as it is built.
|
|
8
|
-
|
|
9
6
|
import fs from "node:fs";
|
|
10
7
|
import path from "node:path";
|
|
11
8
|
import { runBootstrapCommand } from './src/bootstrap.mjs';
|
|
9
|
+
import { describeRetention, hasWiki, isDue, readProjects, refreshProject, resolveKey, staleness } from './src/refresh.mjs';
|
|
10
|
+
import { announceNewVersion, checkUpstreamStatus, propagateUpdates, readUpstreamState } from './src/upstream-watcher.mjs';
|
|
11
|
+
import { loadOpenWikiConfig, setOpenWikiConfigValue, resetOpenWikiConfig, resolveConfigPath, ALLOWED_CONFIG_KEYS, ALLOWED_PROVIDERS } from './src/config.mjs';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Regenerate the generated pages of every registered project that carries them.
|
|
15
|
+
*
|
|
16
|
+
* Fleet-wide by design: the plugin ships from the shared brain, so one
|
|
17
|
+
* implementation covers every repository and every node that resolves it.
|
|
18
|
+
* Defaults to a report; --apply performs the refreshes, because regenerating a
|
|
19
|
+
* repository's documentation is a write to that repository.
|
|
20
|
+
*/
|
|
21
|
+
async function refreshCommand(args) {
|
|
22
|
+
const json = args.includes('--json');
|
|
23
|
+
const apply = args.includes('--apply');
|
|
24
|
+
const force = args.includes('--force');
|
|
25
|
+
const repoIndex = args.indexOf('--repo');
|
|
26
|
+
const onlyArg = args.find((a) => a.startsWith('--repo='));
|
|
27
|
+
const only = onlyArg
|
|
28
|
+
? onlyArg.slice('--repo='.length)
|
|
29
|
+
: (repoIndex >= 0 && args[repoIndex + 1] && !args[repoIndex + 1].startsWith('--') ? args[repoIndex + 1] : null);
|
|
30
|
+
|
|
31
|
+
let projects;
|
|
32
|
+
try {
|
|
33
|
+
projects = readProjects();
|
|
34
|
+
} catch (err) {
|
|
35
|
+
if (json) console.log(JSON.stringify({ ok: false, error: err.message }));
|
|
36
|
+
else console.error(`OpenWiki refresh: ${err.message}`);
|
|
37
|
+
process.exitCode = 2;
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (only) projects = projects.filter((p) => p.name === only || p.root === only);
|
|
41
|
+
if (!projects.length) {
|
|
42
|
+
if (json) console.log(JSON.stringify({ ok: false, error: only ? `No registered project matches ${only}` : 'No registered projects' }));
|
|
43
|
+
else console.error(`OpenWiki refresh: ${only ? `no registered project matches ${only}` : 'no registered projects'}`);
|
|
44
|
+
process.exitCode = 2;
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const reports = [];
|
|
49
|
+
for (const project of projects) {
|
|
50
|
+
let state;
|
|
51
|
+
try {
|
|
52
|
+
state = force ? { due: true, ...staleness(project.root) } : isDue(project);
|
|
53
|
+
} catch (err) {
|
|
54
|
+
reports.push({ ...project, action: 'skipped', reason: err.message });
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (!state.due) {
|
|
58
|
+
reports.push({ ...project, action: 'current', generatedAt: state.generatedAt, commitsSince: state.commitsSince });
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
reports.push({
|
|
62
|
+
...project,
|
|
63
|
+
action: 'due',
|
|
64
|
+
uninitialized: Boolean(state.uninitialized),
|
|
65
|
+
generatedAt: state.generatedAt,
|
|
66
|
+
commitsSince: state.commitsSince,
|
|
67
|
+
reason: state.reason
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const due = reports.filter((r) => r.action === 'due');
|
|
72
|
+
let payloadBudgetNote = null;
|
|
73
|
+
if (apply && due.length) {
|
|
74
|
+
const config = loadOpenWikiConfig();
|
|
75
|
+
const { key, from } = resolveKey({ provider: config.provider });
|
|
76
|
+
if (!key) {
|
|
77
|
+
const keyName = config.provider === 'google' ? 'GOOGLE_API_KEY' : 'OPENROUTER_API_KEY';
|
|
78
|
+
const error = `No model credential for provider '${config.provider}'. Save via: total-recall auth secret set ${keyName} --stdin`;
|
|
79
|
+
if (json) console.log(JSON.stringify({ ok: false, error, reports }));
|
|
80
|
+
else console.error(`OpenWiki refresh: ${error}`);
|
|
81
|
+
process.exitCode = 1;
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const RUNNER_BUDGET_MS = 600000;
|
|
85
|
+
const REPORT_RESERVE_MS = 45000;
|
|
86
|
+
const deadline = Date.now() + RUNNER_BUDGET_MS - REPORT_RESERVE_MS;
|
|
87
|
+
let skippedForBudget = 0;
|
|
88
|
+
for (const entry of due) {
|
|
89
|
+
const remaining = deadline - Date.now();
|
|
90
|
+
if (remaining < 60000) { skippedForBudget += 1; continue; }
|
|
91
|
+
const result = refreshProject(
|
|
92
|
+
{ name: entry.name, root: entry.root },
|
|
93
|
+
{ key, model: config.model, provider: config.provider, timeoutMs: Math.min(remaining, config.timeout_ms) }
|
|
94
|
+
);
|
|
95
|
+
const index = reports.findIndex((r) => r.root === entry.root);
|
|
96
|
+
reports[index] = { ...reports[index], ...result, credential: from };
|
|
97
|
+
if (Date.now() >= deadline) { skippedForBudget += 1; }
|
|
98
|
+
}
|
|
99
|
+
if (skippedForBudget > 0) {
|
|
100
|
+
payloadBudgetNote = `${skippedForBudget} project(s) left due: one regeneration can consume this command's 600 s runner budget; run again to continue.`;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const failed = reports.filter((r) => r.action === 'failed');
|
|
105
|
+
const payload = {
|
|
106
|
+
ok: failed.length === 0,
|
|
107
|
+
applied: apply,
|
|
108
|
+
retention: describeRetention(),
|
|
109
|
+
note: payloadBudgetNote,
|
|
110
|
+
counts: {
|
|
111
|
+
registered: projects.length,
|
|
112
|
+
withPages: reports.filter((r) => r.action !== 'skipped' && !r.uninitialized).length,
|
|
113
|
+
due: due.length,
|
|
114
|
+
uninitialized: reports.filter((r) => r.uninitialized).length,
|
|
115
|
+
refreshed: reports.filter((r) => r.action === 'refreshed' || r.action === 'initialized').length,
|
|
116
|
+
failed: failed.length,
|
|
117
|
+
current: reports.filter((r) => r.action === 'current').length,
|
|
118
|
+
},
|
|
119
|
+
reports,
|
|
120
|
+
};
|
|
121
|
+
if (json) console.log(JSON.stringify(payload, null, 2));
|
|
122
|
+
else {
|
|
123
|
+
console.log(`OpenWiki refresh (${apply ? 'apply' : 'report'}): ${payload.counts.registered} registered, ${payload.counts.due} due (${payload.counts.uninitialized} uninitialized)`);
|
|
124
|
+
for (const r of reports) {
|
|
125
|
+
if (r.action === 'current') continue;
|
|
126
|
+
const age = r.uninitialized ? 'uninitialized' : (r.generatedAt ? `generated ${r.generatedAt.slice(0, 10)}` : 'never generated');
|
|
127
|
+
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}` : ''}`);
|
|
128
|
+
}
|
|
129
|
+
if (payloadBudgetNote) console.log(payloadBudgetNote);
|
|
130
|
+
if (!apply && due.length) console.log('Re-run with --apply to regenerate. Pages are a projection; vault content is never touched.');
|
|
131
|
+
}
|
|
132
|
+
if (failed.length) process.exitCode = 1;
|
|
133
|
+
}
|
|
12
134
|
|
|
13
135
|
async function probeCommand(args) {
|
|
14
136
|
const json = args.includes("--json");
|
|
@@ -79,24 +201,218 @@ async function ingestCommand(args) {
|
|
|
79
201
|
}
|
|
80
202
|
}
|
|
81
203
|
|
|
204
|
+
/**
|
|
205
|
+
* Surveillance command for monitoring the upstream open-source OpenWiki package.
|
|
206
|
+
*/
|
|
207
|
+
async function watchCommand(args) {
|
|
208
|
+
const json = args.includes('--json');
|
|
209
|
+
const checkOnly = args.includes('--check-only');
|
|
210
|
+
const announce = args.includes('--announce') || (!checkOnly && !args.includes('--no-announce'));
|
|
211
|
+
const propagate = args.includes('--propagate');
|
|
212
|
+
|
|
213
|
+
const status = await checkUpstreamStatus();
|
|
214
|
+
let announcement = null;
|
|
215
|
+
let propagation = null;
|
|
216
|
+
|
|
217
|
+
if (status.ok && status.updateAvailable) {
|
|
218
|
+
if (announce) {
|
|
219
|
+
announcement = await announceNewVersion({
|
|
220
|
+
latestVersion: status.latestVersion,
|
|
221
|
+
currentVersion: status.currentVersion,
|
|
222
|
+
releaseNotesUrl: status.releaseNotesUrl
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
if (propagate) {
|
|
226
|
+
propagation = await propagateUpdates({ force: true });
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const payload = {
|
|
231
|
+
ok: status.ok,
|
|
232
|
+
status,
|
|
233
|
+
announcement,
|
|
234
|
+
propagation
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
if (json) {
|
|
238
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
239
|
+
} else {
|
|
240
|
+
console.log('\nOpenWiki Upstream Watcher:');
|
|
241
|
+
console.log(` Active Recorded Version : v${status.currentVersion}`);
|
|
242
|
+
console.log(` Latest Upstream Version : v${status.latestVersion}`);
|
|
243
|
+
console.log(` Update Available : ${status.updateAvailable ? 'YES (Increment Detected)' : 'No (Current)'}`);
|
|
244
|
+
if (status.releaseNotesUrl) {
|
|
245
|
+
console.log(` Release Notes : ${status.releaseNotesUrl}`);
|
|
246
|
+
}
|
|
247
|
+
if (announcement?.announced) {
|
|
248
|
+
console.log(` Operator Announcement : Dispatched successfully`);
|
|
249
|
+
}
|
|
250
|
+
if (propagation) {
|
|
251
|
+
console.log(` Fleet Propagation : ${propagation.ok ? 'Completed' : 'Failed'} (${propagation.updatedCount} projects updated)`);
|
|
252
|
+
}
|
|
253
|
+
console.log('');
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (!status.ok) process.exitCode = 1;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Propagate updated generator across registered repositories.
|
|
261
|
+
*/
|
|
262
|
+
async function propagateCommand(args) {
|
|
263
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
264
|
+
console.log(`
|
|
265
|
+
Usage:
|
|
266
|
+
total-recall openwiki propagate [options]
|
|
267
|
+
|
|
268
|
+
Options:
|
|
269
|
+
--repo <name> Limit propagation to a specific repository
|
|
270
|
+
--force Force regeneration even if not due
|
|
271
|
+
--dry-run Preview propagation actions without writing
|
|
272
|
+
--json Output result as JSON
|
|
273
|
+
--help, -h Show this help
|
|
274
|
+
`);
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
const json = args.includes('--json');
|
|
278
|
+
const force = args.includes('--force');
|
|
279
|
+
const dryRun = args.includes('--dry-run');
|
|
280
|
+
const repoIndex = args.indexOf('--repo');
|
|
281
|
+
const onlyArg = args.find((a) => a.startsWith('--repo='));
|
|
282
|
+
const repo = onlyArg
|
|
283
|
+
? onlyArg.slice('--repo='.length)
|
|
284
|
+
: (repoIndex >= 0 && args[repoIndex + 1] && !args[repoIndex + 1].startsWith('--') ? args[repoIndex + 1] : null);
|
|
285
|
+
|
|
286
|
+
const result = await propagateUpdates({ repo, force, dryRun });
|
|
287
|
+
|
|
288
|
+
if (json) {
|
|
289
|
+
console.log(JSON.stringify(result, null, 2));
|
|
290
|
+
} else {
|
|
291
|
+
console.log(`\nOpenWiki Fleet Propagation (${dryRun ? 'DRY RUN' : 'APPLY'}):`);
|
|
292
|
+
console.log(` Eligible Repositories : ${result.eligibleCount || 0}`);
|
|
293
|
+
console.log(` Updated Repositories : ${result.updatedCount || 0}`);
|
|
294
|
+
console.log(` Failed Repositories : ${result.failedCount || 0}`);
|
|
295
|
+
if (Array.isArray(result.reports)) {
|
|
296
|
+
for (const r of result.reports) {
|
|
297
|
+
console.log(` • ${r.name}: ${r.action}${r.reason ? ` — ${r.reason}` : ''}`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
console.log('');
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (!result.ok) process.exitCode = 1;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Configure OpenWiki generation parameters and cheap model routing.
|
|
308
|
+
*/
|
|
309
|
+
async function configCommand(args) {
|
|
310
|
+
const json = args.includes('--json');
|
|
311
|
+
const cleanArgs = args.filter((a) => a !== '--json');
|
|
312
|
+
const verb = cleanArgs[0] || 'show';
|
|
313
|
+
|
|
314
|
+
try {
|
|
315
|
+
if (verb === 'show') {
|
|
316
|
+
const config = loadOpenWikiConfig();
|
|
317
|
+
const configPath = resolveConfigPath();
|
|
318
|
+
const payload = { ok: true, path: configPath, config };
|
|
319
|
+
if (json) console.log(JSON.stringify(payload, null, 2));
|
|
320
|
+
else {
|
|
321
|
+
console.log(`\nOpenWiki Configuration (${configPath}):`);
|
|
322
|
+
console.log(` Provider : ${config.provider}`);
|
|
323
|
+
console.log(` Model : ${config.model}`);
|
|
324
|
+
console.log(` Fallback Model : ${config.fallback_model}`);
|
|
325
|
+
console.log(` Max Tokens : ${config.max_tokens}`);
|
|
326
|
+
console.log(` Timeout (ms) : ${config.timeout_ms}\n`);
|
|
327
|
+
}
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
if (verb === 'get') {
|
|
332
|
+
const key = cleanArgs[1];
|
|
333
|
+
if (!key) {
|
|
334
|
+
throw new Error('Key argument required: openwiki config get <key>');
|
|
335
|
+
}
|
|
336
|
+
if (!ALLOWED_CONFIG_KEYS.includes(key)) {
|
|
337
|
+
throw new Error(`Unknown configuration key '${key}'. Allowed: ${ALLOWED_CONFIG_KEYS.join(', ')}`);
|
|
338
|
+
}
|
|
339
|
+
const config = loadOpenWikiConfig();
|
|
340
|
+
const value = config[key];
|
|
341
|
+
if (json) console.log(JSON.stringify({ ok: true, key, value }));
|
|
342
|
+
else console.log(value);
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
if (verb === 'set') {
|
|
347
|
+
const key = cleanArgs[1];
|
|
348
|
+
const value = cleanArgs[2];
|
|
349
|
+
if (!key || value === undefined) {
|
|
350
|
+
throw new Error('Key and value required: openwiki config set <key> <value>');
|
|
351
|
+
}
|
|
352
|
+
const updated = setOpenWikiConfigValue(key, value);
|
|
353
|
+
const payload = { ok: true, key, value: updated[key], config: updated };
|
|
354
|
+
if (json) console.log(JSON.stringify(payload, null, 2));
|
|
355
|
+
else console.log(`OpenWiki configuration updated: ${key} = ${updated[key]}`);
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
if (verb === 'reset') {
|
|
360
|
+
const reset = resetOpenWikiConfig();
|
|
361
|
+
const payload = { ok: true, message: 'Configuration reset to defaults', config: reset };
|
|
362
|
+
if (json) console.log(JSON.stringify(payload, null, 2));
|
|
363
|
+
else console.log('OpenWiki configuration reset to defaults');
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
throw new Error(`Unknown config action '${verb}'. Supported verbs: show, get, set, reset`);
|
|
368
|
+
} catch (err) {
|
|
369
|
+
if (json) console.log(JSON.stringify({ ok: false, error: err.message }));
|
|
370
|
+
else console.error(`OpenWiki config error: ${err.message}`);
|
|
371
|
+
process.exitCode = 1;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
82
375
|
const IMPLEMENTED = {};
|
|
83
376
|
IMPLEMENTED.probe = probeCommand;
|
|
84
377
|
IMPLEMENTED.hubs = hubsCommand;
|
|
85
378
|
IMPLEMENTED.ingest = ingestCommand;
|
|
86
379
|
IMPLEMENTED.bootstrap = runBootstrapCommand;
|
|
380
|
+
IMPLEMENTED.refresh = refreshCommand;
|
|
381
|
+
IMPLEMENTED.watch = watchCommand;
|
|
382
|
+
IMPLEMENTED.propagate = propagateCommand;
|
|
383
|
+
IMPLEMENTED.config = configCommand;
|
|
87
384
|
|
|
385
|
+
export async function run(argv = process.argv) {
|
|
386
|
+
let rawArgs = Array.isArray(argv) && argv.length > 0 ? [...argv] : process.argv.slice(2);
|
|
387
|
+
while (rawArgs.length > 0 && (
|
|
388
|
+
rawArgs[0].endsWith('node') ||
|
|
389
|
+
rawArgs[0].endsWith('total-recall') ||
|
|
390
|
+
rawArgs[0].endsWith('cli.mjs') ||
|
|
391
|
+
rawArgs[0] === 'openwiki'
|
|
392
|
+
)) {
|
|
393
|
+
rawArgs.shift();
|
|
394
|
+
}
|
|
88
395
|
|
|
89
|
-
|
|
90
|
-
const
|
|
91
|
-
const sub = args[0] || "status";
|
|
92
|
-
const json = args.includes("--json");
|
|
396
|
+
const sub = rawArgs[0] || "status";
|
|
397
|
+
const json = rawArgs.includes("--json");
|
|
93
398
|
|
|
94
399
|
if (sub === "status") {
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
:
|
|
400
|
+
const upstream = readUpstreamState();
|
|
401
|
+
const status = {
|
|
402
|
+
plugin: "openwiki",
|
|
403
|
+
implemented: Object.keys(IMPLEMENTED),
|
|
404
|
+
upstream: {
|
|
405
|
+
recordedVersion: upstream.currentRecordedVersion,
|
|
406
|
+
latestVersion: upstream.latestKnownVersion,
|
|
407
|
+
lastChecked: upstream.lastCheckedAt,
|
|
408
|
+
lastPropagated: upstream.lastPropagatedAt
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
if (json) console.log(JSON.stringify(status, null, 2));
|
|
412
|
+
else {
|
|
413
|
+
console.log(`OpenWiki: implemented subcommands: ${status.implemented.join(", ")}`);
|
|
414
|
+
console.log(`Upstream Status: recorded v${status.upstream.recordedVersion}, latest v${status.upstream.latestVersion}`);
|
|
415
|
+
}
|
|
100
416
|
return;
|
|
101
417
|
}
|
|
102
418
|
|
|
@@ -108,20 +424,34 @@ export async function run(argv = []) {
|
|
|
108
424
|
total-recall openwiki <subcommand> [options]
|
|
109
425
|
|
|
110
426
|
Subcommands:
|
|
111
|
-
status Show OpenWiki plugin status
|
|
427
|
+
status Show OpenWiki plugin and upstream status
|
|
112
428
|
probe [--json] Check subsystem health
|
|
113
429
|
hubs [--json] List indexed documentation hubs
|
|
114
430
|
ingest <path> [options] Ingest Markdown files into knowledge graph
|
|
115
431
|
bootstrap --brain <path> [--project-root <path>] [--dry-run] [--json]
|
|
116
432
|
Create missing plugin-owned documentation pages
|
|
433
|
+
refresh [--repo <name>] [--apply] [--force] [--json]
|
|
434
|
+
Report which registered projects' generated pages are stale;
|
|
435
|
+
--apply regenerates stale pages (writes openwiki/ only)
|
|
436
|
+
config [show|get <key>|set <key> <value>|reset] [--json]
|
|
437
|
+
Configure generator provider, model, tokens, and timeout
|
|
438
|
+
watch [--check-only] [--announce] [--propagate] [--json]
|
|
439
|
+
Watch upstream OpenWiki repository and announce new versions
|
|
440
|
+
propagate [--repo <name>] [--force] [--dry-run] [--json]
|
|
441
|
+
Propagate updated generator across registered repositories
|
|
117
442
|
`);
|
|
118
443
|
return;
|
|
119
444
|
}
|
|
120
445
|
|
|
121
|
-
if (Object.hasOwn(IMPLEMENTED, sub)) return IMPLEMENTED[sub](
|
|
446
|
+
if (Object.hasOwn(IMPLEMENTED, sub)) return IMPLEMENTED[sub](rawArgs.slice(1));
|
|
122
447
|
|
|
123
448
|
if (json) console.log(JSON.stringify({ ok: false, error: `OpenWiki operation is not implemented: ${sub}` }));
|
|
124
449
|
console.error(`OpenWiki: "${sub}" is not implemented.`);
|
|
125
450
|
process.exitCode = 2;
|
|
126
451
|
}
|
|
452
|
+
|
|
453
|
+
if (process.argv[1] && (process.argv[1].endsWith('cli.mjs') || process.argv[1].endsWith('tr-plugin-openwiki'))) {
|
|
454
|
+
run(process.argv);
|
|
455
|
+
}
|
|
456
|
+
|
|
127
457
|
export default run;
|