total-recall-brain 3.41.3 → 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 +10 -1
- package/frontend/dist/assets/{index-DFenQQEQ.js → index-CRzjQLu7.js} +77 -72
- package/frontend/dist/index.html +1 -1
- package/package.json +7 -5
- package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +2 -2
- package/scaffold/.agent/skills/total-recall/plugins/auth/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/plugin.json +1 -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/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/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/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/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/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 +35 -22
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/card.js +947 -323
- package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +23 -8
- package/scaffold/.agent/skills/total-recall/plugins/security/package.json +5 -1
- package/src/cli/config.mjs +3 -0
- package/src/cli/connect.mjs +12 -116
- package/src/cli/harness.mjs +0 -1
- package/src/cli/plugin/create.mjs +56 -3
- package/src/cli/plugin/index.mjs +15 -3
- package/src/cli/plugin/monetization.mjs +232 -12
- package/src/cli/preflight.mjs +161 -0
- 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/meta-harness.mjs +16 -38
- package/src/core/plugin-dependencies.mjs +6 -1
- package/src/core/preflight-gate.mjs +77 -0
- package/src/core/preflight-receipt.mjs +123 -0
- package/src/core/runtime.mjs +0 -3
- package/src/core/surface.mjs +38 -1
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenWiki Upstream Watcher & Fleet Propagation Engine
|
|
3
|
+
*
|
|
4
|
+
* Monitors the open-source OpenWiki package (langchain-ai/openwiki on GitHub & npm),
|
|
5
|
+
* detects new releases, announces updates via operator alerts, and coordinates
|
|
6
|
+
* fleet-wide documentation regeneration across registered user repositories.
|
|
7
|
+
*/
|
|
8
|
+
import fs from 'node:fs';
|
|
9
|
+
import os from 'node:os';
|
|
10
|
+
import path from 'node:path';
|
|
11
|
+
import { spawnSync } from 'node:child_process';
|
|
12
|
+
import { compareSemanticVersions, formatPropagationReceipt } from '../capability/index.mjs';
|
|
13
|
+
import { hasWiki, readProjects, refreshProject, resolveKey } from './refresh.mjs';
|
|
14
|
+
|
|
15
|
+
export const UPSTREAM_NPM_URL = 'https://registry.npmjs.org/openwiki/latest';
|
|
16
|
+
export const UPSTREAM_GITHUB_URL = 'https://api.github.com/repos/langchain-ai/openwiki/releases/latest';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Resolves the path to the persistent upstream state file.
|
|
20
|
+
* @param {string} [home] Home directory override
|
|
21
|
+
* @returns {string}
|
|
22
|
+
*/
|
|
23
|
+
export function stateFile(home = os.homedir()) {
|
|
24
|
+
if (process.env.TR_PLUGIN_STATE_DIR) {
|
|
25
|
+
return path.join(process.env.TR_PLUGIN_STATE_DIR, 'openwiki-upstream.json');
|
|
26
|
+
}
|
|
27
|
+
return path.join(home, '.agent', 'skills', 'total-recall', 'config', 'openwiki-upstream.json');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Reads persistent upstream release state.
|
|
32
|
+
* @param {object} options
|
|
33
|
+
* @param {string} [options.statePath] Custom state path
|
|
34
|
+
* @returns {{ currentRecordedVersion: string, latestKnownVersion: string, lastCheckedAt: string | null, announcements: Array<object> }}
|
|
35
|
+
*/
|
|
36
|
+
export function readUpstreamState({ statePath = stateFile() } = {}) {
|
|
37
|
+
try {
|
|
38
|
+
const raw = fs.readFileSync(statePath, 'utf8');
|
|
39
|
+
const parsed = JSON.parse(raw);
|
|
40
|
+
return {
|
|
41
|
+
currentRecordedVersion: typeof parsed.currentRecordedVersion === 'string' ? parsed.currentRecordedVersion : '0.7.2',
|
|
42
|
+
latestKnownVersion: typeof parsed.latestKnownVersion === 'string' ? parsed.latestKnownVersion : '0.7.2',
|
|
43
|
+
lastCheckedAt: typeof parsed.lastCheckedAt === 'string' ? parsed.lastCheckedAt : null,
|
|
44
|
+
lastPropagatedAt: typeof parsed.lastPropagatedAt === 'string' ? parsed.lastPropagatedAt : null,
|
|
45
|
+
announcements: Array.isArray(parsed.announcements) ? parsed.announcements : []
|
|
46
|
+
};
|
|
47
|
+
} catch {
|
|
48
|
+
return {
|
|
49
|
+
currentRecordedVersion: '0.7.2',
|
|
50
|
+
latestKnownVersion: '0.7.2',
|
|
51
|
+
lastCheckedAt: null,
|
|
52
|
+
lastPropagatedAt: null,
|
|
53
|
+
announcements: []
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Saves upstream release state atomically.
|
|
60
|
+
* @param {object} state State data object
|
|
61
|
+
* @param {object} options
|
|
62
|
+
* @param {string} [options.statePath] Custom state path
|
|
63
|
+
*/
|
|
64
|
+
export function saveUpstreamState(state = {}, { statePath = stateFile() } = {}) {
|
|
65
|
+
const dir = path.dirname(statePath);
|
|
66
|
+
if (!fs.existsSync(dir)) {
|
|
67
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
68
|
+
}
|
|
69
|
+
const payload = {
|
|
70
|
+
currentRecordedVersion: state.currentRecordedVersion || '0.7.2',
|
|
71
|
+
latestKnownVersion: state.latestKnownVersion || '0.7.2',
|
|
72
|
+
lastCheckedAt: state.lastCheckedAt || new Date().toISOString(),
|
|
73
|
+
lastPropagatedAt: state.lastPropagatedAt || null,
|
|
74
|
+
announcements: Array.isArray(state.announcements) ? state.announcements.slice(-20) : []
|
|
75
|
+
};
|
|
76
|
+
const tempPath = `${statePath}.${process.pid}.tmp`;
|
|
77
|
+
fs.writeFileSync(tempPath, JSON.stringify(payload, null, 2), 'utf8');
|
|
78
|
+
fs.renameSync(tempPath, statePath);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Queries the latest published OpenWiki release from npm registry or GitHub.
|
|
83
|
+
* @param {object} options
|
|
84
|
+
* @param {typeof fetch} [options.fetch=globalThis.fetch] Fetch implementation
|
|
85
|
+
* @param {number} [options.timeoutMs=8000] Network timeout in milliseconds
|
|
86
|
+
* @param {string} [options.npmUrl] npm registry URL override
|
|
87
|
+
* @param {string} [options.githubUrl] GitHub release API URL override
|
|
88
|
+
* @returns {Promise<{ ok: boolean, version?: string, publishedAt?: string, releaseNotesUrl?: string, source?: string, error?: string }>}
|
|
89
|
+
*/
|
|
90
|
+
export async function fetchUpstreamRelease({
|
|
91
|
+
fetch = globalThis.fetch,
|
|
92
|
+
timeoutMs = 8000,
|
|
93
|
+
npmUrl = UPSTREAM_NPM_URL,
|
|
94
|
+
githubUrl = UPSTREAM_GITHUB_URL
|
|
95
|
+
} = {}) {
|
|
96
|
+
// Strategy 1: npm registry endpoint
|
|
97
|
+
try {
|
|
98
|
+
const res = await fetch(npmUrl, {
|
|
99
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
100
|
+
headers: { accept: 'application/json' }
|
|
101
|
+
});
|
|
102
|
+
if (res.ok) {
|
|
103
|
+
const data = await res.json();
|
|
104
|
+
if (data?.version) {
|
|
105
|
+
return {
|
|
106
|
+
ok: true,
|
|
107
|
+
source: 'npm',
|
|
108
|
+
version: data.version,
|
|
109
|
+
publishedAt: data.dist?.time || new Date().toISOString(),
|
|
110
|
+
releaseNotesUrl: data.bugs?.url ? data.bugs.url.replace(/\/issues$/, '') : 'https://github.com/langchain-ai/openwiki',
|
|
111
|
+
description: data.description || ''
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
} catch {
|
|
116
|
+
// Registry query failed, fall back to repository releases
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Strategy 2: GitHub Releases API
|
|
120
|
+
try {
|
|
121
|
+
const res = await fetch(githubUrl, {
|
|
122
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
123
|
+
headers: {
|
|
124
|
+
accept: 'application/vnd.github.v3+json',
|
|
125
|
+
'User-Agent': 'total-recall-openwiki-watcher'
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
if (res.ok) {
|
|
129
|
+
const data = await res.json();
|
|
130
|
+
const rawTag = data.tag_name || data.name || '';
|
|
131
|
+
const version = rawTag.replace(/^v/, '').trim();
|
|
132
|
+
if (version) {
|
|
133
|
+
return {
|
|
134
|
+
ok: true,
|
|
135
|
+
source: 'github',
|
|
136
|
+
version,
|
|
137
|
+
publishedAt: data.published_at || new Date().toISOString(),
|
|
138
|
+
releaseNotesUrl: data.html_url || 'https://github.com/langchain-ai/openwiki',
|
|
139
|
+
description: data.body || ''
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
} catch {
|
|
144
|
+
// Both network queries exhausted
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
ok: false,
|
|
149
|
+
error: 'Failed to retrieve release from upstream registries'
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Checks upstream status and computes version increment delta.
|
|
155
|
+
* @param {object} options
|
|
156
|
+
* @param {typeof fetch} [options.fetch] Fetch implementation
|
|
157
|
+
* @param {string} [options.statePath] Custom state path
|
|
158
|
+
* @returns {Promise<{ ok: boolean, updateAvailable: boolean, currentVersion: string, latestVersion: string, publishedAt: string | null, releaseNotesUrl: string | null, error?: string }>}
|
|
159
|
+
*/
|
|
160
|
+
export async function checkUpstreamStatus({
|
|
161
|
+
fetch = globalThis.fetch,
|
|
162
|
+
statePath = stateFile()
|
|
163
|
+
} = {}) {
|
|
164
|
+
const state = readUpstreamState({ statePath });
|
|
165
|
+
const release = await fetchUpstreamRelease({ fetch });
|
|
166
|
+
|
|
167
|
+
if (!release.ok || !release.version) {
|
|
168
|
+
return {
|
|
169
|
+
ok: false,
|
|
170
|
+
updateAvailable: false,
|
|
171
|
+
currentVersion: state.currentRecordedVersion,
|
|
172
|
+
latestVersion: state.latestKnownVersion,
|
|
173
|
+
publishedAt: null,
|
|
174
|
+
releaseNotesUrl: null,
|
|
175
|
+
error: release.error || 'Upstream release check failed'
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const updateAvailable = compareSemanticVersions(release.version, state.currentRecordedVersion) > 0;
|
|
180
|
+
|
|
181
|
+
// Persist check time and latest known version
|
|
182
|
+
saveUpstreamState({
|
|
183
|
+
...state,
|
|
184
|
+
latestKnownVersion: release.version,
|
|
185
|
+
lastCheckedAt: new Date().toISOString()
|
|
186
|
+
}, { statePath });
|
|
187
|
+
|
|
188
|
+
return {
|
|
189
|
+
ok: true,
|
|
190
|
+
updateAvailable,
|
|
191
|
+
currentVersion: state.currentRecordedVersion,
|
|
192
|
+
latestVersion: release.version,
|
|
193
|
+
publishedAt: release.publishedAt || null,
|
|
194
|
+
releaseNotesUrl: release.releaseNotesUrl || null
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Dispatches an operator announcement when a new upstream release is detected.
|
|
200
|
+
* @param {object} options
|
|
201
|
+
* @param {string} options.latestVersion Discovered version string
|
|
202
|
+
* @param {string} options.currentVersion Active version string
|
|
203
|
+
* @param {string} [options.releaseNotesUrl] Optional release notes link
|
|
204
|
+
* @param {boolean} [options.dryRun=false] When true, skips alert dispatch
|
|
205
|
+
* @param {Function} [options.alertDispatcher] Optional alert dispatch stub
|
|
206
|
+
* @param {string} [options.statePath] Custom state path
|
|
207
|
+
* @returns {Promise<{ announced: boolean, title: string, message: string }>}
|
|
208
|
+
*/
|
|
209
|
+
export async function announceNewVersion({
|
|
210
|
+
latestVersion,
|
|
211
|
+
currentVersion,
|
|
212
|
+
releaseNotesUrl = 'https://github.com/langchain-ai/openwiki',
|
|
213
|
+
dryRun = false,
|
|
214
|
+
alertDispatcher,
|
|
215
|
+
statePath = stateFile()
|
|
216
|
+
} = {}) {
|
|
217
|
+
const title = `OpenWiki Update: v${latestVersion} Available`;
|
|
218
|
+
const message = `Upstream OpenWiki published v${latestVersion} (currently recording v${currentVersion}). Documentation propagation is ready across registered user repositories.`;
|
|
219
|
+
|
|
220
|
+
if (!dryRun) {
|
|
221
|
+
if (typeof alertDispatcher === 'function') {
|
|
222
|
+
try {
|
|
223
|
+
await alertDispatcher({ title, message, source: 'openwiki', severity: 'info' });
|
|
224
|
+
} catch {
|
|
225
|
+
// Dispatcher failure logged cleanly
|
|
226
|
+
}
|
|
227
|
+
} else {
|
|
228
|
+
// Dispatch via Total Recall alerts CLI
|
|
229
|
+
try {
|
|
230
|
+
spawnSync('npx', [
|
|
231
|
+
'total-recall', 'alerts', 'send',
|
|
232
|
+
'--title', title,
|
|
233
|
+
'--message', message,
|
|
234
|
+
'--source', 'openwiki',
|
|
235
|
+
'--severity', 'info'
|
|
236
|
+
], { stdio: 'ignore', timeout: 15000 });
|
|
237
|
+
} catch {
|
|
238
|
+
// External alert execution failure
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const state = readUpstreamState({ statePath });
|
|
243
|
+
state.announcements.push({
|
|
244
|
+
version: latestVersion,
|
|
245
|
+
announcedAt: new Date().toISOString(),
|
|
246
|
+
releaseNotesUrl
|
|
247
|
+
});
|
|
248
|
+
saveUpstreamState(state, { statePath });
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return {
|
|
252
|
+
announced: !dryRun,
|
|
253
|
+
title,
|
|
254
|
+
message
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Propagates updated OpenWiki generator execution across registered user repositories.
|
|
260
|
+
* @param {object} options
|
|
261
|
+
* @param {string} [options.repo] Filter to a specific repository name
|
|
262
|
+
* @param {boolean} [options.force=false] Force regeneration even if not due
|
|
263
|
+
* @param {boolean} [options.dryRun=false] Preview actions without executing updates
|
|
264
|
+
* @param {string} [options.statePath] Custom state path
|
|
265
|
+
* @param {typeof readProjects} [options.projectsReader=readProjects] Projects reader stub
|
|
266
|
+
* @param {typeof refreshProject} [options.refresher=refreshProject] Project refresher stub
|
|
267
|
+
* @param {typeof resolveKey} [options.keyResolver=resolveKey] Credential resolver stub
|
|
268
|
+
* @returns {Promise<object>}
|
|
269
|
+
*/
|
|
270
|
+
export async function propagateUpdates({
|
|
271
|
+
repo = null,
|
|
272
|
+
force = false,
|
|
273
|
+
dryRun = false,
|
|
274
|
+
statePath = stateFile(),
|
|
275
|
+
projectsReader = readProjects,
|
|
276
|
+
refresher = refreshProject,
|
|
277
|
+
keyResolver = resolveKey
|
|
278
|
+
} = {}) {
|
|
279
|
+
let projects;
|
|
280
|
+
try {
|
|
281
|
+
projects = projectsReader();
|
|
282
|
+
} catch (err) {
|
|
283
|
+
return { ok: false, error: err.message, updatedCount: 0, reports: [] };
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
if (repo) {
|
|
287
|
+
projects = projects.filter(p => p.name === repo || p.root === repo);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Filter to repositories with existing openwiki directories
|
|
291
|
+
const eligible = projects.filter(p => hasWiki(p.root));
|
|
292
|
+
if (eligible.length === 0) {
|
|
293
|
+
return {
|
|
294
|
+
ok: true,
|
|
295
|
+
eligibleCount: 0,
|
|
296
|
+
updatedCount: 0,
|
|
297
|
+
reports: [],
|
|
298
|
+
message: 'No registered user repositories carry openwiki documentation'
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const state = readUpstreamState({ statePath });
|
|
303
|
+
const targetVersion = state.latestKnownVersion || '0.7.3';
|
|
304
|
+
|
|
305
|
+
if (dryRun) {
|
|
306
|
+
const planned = eligible.map(p => ({
|
|
307
|
+
name: p.name,
|
|
308
|
+
root: p.root,
|
|
309
|
+
action: 'planned',
|
|
310
|
+
targetVersion
|
|
311
|
+
}));
|
|
312
|
+
return {
|
|
313
|
+
ok: true,
|
|
314
|
+
dryRun: true,
|
|
315
|
+
eligibleCount: eligible.length,
|
|
316
|
+
updatedCount: 0,
|
|
317
|
+
targetVersion,
|
|
318
|
+
reports: planned
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const { key, from } = keyResolver();
|
|
323
|
+
const reports = [];
|
|
324
|
+
|
|
325
|
+
for (const project of eligible) {
|
|
326
|
+
try {
|
|
327
|
+
const outcome = refresher(project, {
|
|
328
|
+
key,
|
|
329
|
+
force,
|
|
330
|
+
targetVersion
|
|
331
|
+
});
|
|
332
|
+
reports.push({
|
|
333
|
+
...outcome,
|
|
334
|
+
credential: from,
|
|
335
|
+
generatorVersion: targetVersion
|
|
336
|
+
});
|
|
337
|
+
} catch (err) {
|
|
338
|
+
reports.push({
|
|
339
|
+
name: project.name,
|
|
340
|
+
root: project.root,
|
|
341
|
+
action: 'failed',
|
|
342
|
+
reason: err.message,
|
|
343
|
+
generatorVersion: targetVersion
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const failedCount = reports.filter(r => r.action === 'failed').length;
|
|
349
|
+
const updatedCount = reports.filter(r => r.action === 'refreshed' || r.action === 'partial').length;
|
|
350
|
+
|
|
351
|
+
// Record successful propagation in persistent state
|
|
352
|
+
saveUpstreamState({
|
|
353
|
+
...state,
|
|
354
|
+
currentRecordedVersion: targetVersion,
|
|
355
|
+
lastPropagatedAt: new Date().toISOString()
|
|
356
|
+
}, { statePath });
|
|
357
|
+
|
|
358
|
+
const receipt = formatPropagationReceipt({
|
|
359
|
+
previousVersion: state.currentRecordedVersion,
|
|
360
|
+
newVersion: targetVersion,
|
|
361
|
+
totalProjects: eligible.length,
|
|
362
|
+
updatedProjects: updatedCount,
|
|
363
|
+
failedProjects: failedCount,
|
|
364
|
+
ok: failedCount === 0
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
return {
|
|
368
|
+
ok: receipt.ok,
|
|
369
|
+
receipt,
|
|
370
|
+
eligibleCount: eligible.length,
|
|
371
|
+
updatedCount,
|
|
372
|
+
failedCount,
|
|
373
|
+
reports
|
|
374
|
+
};
|
|
375
|
+
}
|
|
@@ -1,32 +1,45 @@
|
|
|
1
|
-
# DESIGN.md —
|
|
1
|
+
# DESIGN.md — OpenWiki Knowledge Graph
|
|
2
|
+
|
|
3
|
+
Documentation hub discovery, semantic knowledge graph visualization, and repository memory ingestion console.
|
|
2
4
|
|
|
3
5
|
```yaml
|
|
4
6
|
tokens:
|
|
5
|
-
brand-name: "
|
|
7
|
+
brand-name: "OpenWiki"
|
|
6
8
|
wordmark: "[BRAIN//DUMP]"
|
|
7
|
-
|
|
9
|
+
badge: "Knowledge Graph"
|
|
10
|
+
color-primary: "#b45309"
|
|
11
|
+
color-primary-hover: "#d97706"
|
|
8
12
|
color-background: "#0f172a"
|
|
9
13
|
color-surface: "#1e293b"
|
|
10
|
-
color-
|
|
11
|
-
color-
|
|
12
|
-
color-warn: "#f59e0b"
|
|
13
|
-
color-danger: "#ef4444"
|
|
14
|
+
color-surface-subtle: "#334155"
|
|
15
|
+
color-border: "#475569"
|
|
14
16
|
color-text: "#f8fafc"
|
|
15
|
-
color-muted: "#94a3b8"
|
|
16
|
-
color-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
color-text-muted: "#94a3b8"
|
|
18
|
+
color-accent: "#f59e0b"
|
|
19
|
+
color-success: "#10b981"
|
|
20
|
+
color-danger: "#ef4444"
|
|
21
|
+
font-mono: "'JetBrains Mono', 'Fira Code', ui-monospace, monospace"
|
|
22
|
+
font-sans: "system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif"
|
|
19
23
|
border-radius: "8px"
|
|
24
|
+
min-touch-target: "44px"
|
|
20
25
|
```
|
|
21
26
|
|
|
22
|
-
## Brand &
|
|
23
|
-
|
|
24
|
-
- **
|
|
25
|
-
- **
|
|
26
|
-
- **
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
## 1. Brand Identity & Visual Language
|
|
28
|
+
|
|
29
|
+
- **Entity**: OpenWiki Documentation & Knowledge Graph Engine
|
|
30
|
+
- **Typographic Badge**: `[BRAIN//DUMP]`
|
|
31
|
+
- **Color System**: Deep slate foundation with amber gold illumination
|
|
32
|
+
- **Typography**: Clean monospace badges paired with legible system sans-serif headers
|
|
33
|
+
|
|
34
|
+
## 2. Card Architecture & Views
|
|
35
|
+
|
|
36
|
+
1. **Header Bar**: Displays the typographic mark, hub counter, and operational state indicator.
|
|
37
|
+
2. **Hub Roster Deck (`hub-list`)**: Displays discovered Markdown documentation hubs, line counts, and storage metrics.
|
|
38
|
+
3. **Ingestion Controller (`ingest-deck`)**: Provides direct path configuration, preview dry-run toggles, and execution controls.
|
|
39
|
+
4. **Execution Summary Deck**: Displays structured result telemetry, scanned file counts, and error descriptions without raw terminal dumps.
|
|
40
|
+
|
|
41
|
+
## 3. Ergonomics & Accessibility
|
|
42
|
+
|
|
43
|
+
- **Touch Ergonomics**: All interactive buttons, inputs, and toggles declare minimum 44px heights.
|
|
44
|
+
- **Motion Restraint**: Media query `@media (prefers-reduced-motion: reduce)` disables all animations and transitions.
|
|
45
|
+
- **Host Token Binding**: Binds directly to `--text-primary` and `--border` dashboard custom properties.
|