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.
Files changed (80) hide show
  1. package/bin/total-recall.mjs +10 -1
  2. package/frontend/dist/assets/{index-DFenQQEQ.js → index-CRzjQLu7.js} +77 -72
  3. package/frontend/dist/index.html +1 -1
  4. package/package.json +7 -5
  5. package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +2 -2
  6. package/scaffold/.agent/skills/total-recall/plugins/auth/package.json +1 -1
  7. package/scaffold/.agent/skills/total-recall/plugins/auth/plugin.json +1 -1
  8. package/scaffold/.agent/skills/total-recall/plugins/auth/src/cli-secret.mjs +48 -0
  9. package/scaffold/.agent/skills/total-recall/plugins/auth/src/login-projections.mjs +42 -0
  10. package/scaffold/.agent/skills/total-recall/plugins/auth/src/mesh-secrets.mjs +18 -0
  11. package/scaffold/.agent/skills/total-recall/plugins/auth/src/routes/secrets.mjs +5 -2
  12. package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-carriers.mjs +76 -0
  13. package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-prune.mjs +37 -0
  14. package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-sync.mjs +53 -17
  15. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +12 -12
  16. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +1 -1
  17. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +12 -12
  18. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +1 -1
  19. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +23 -8
  20. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +6 -2
  21. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package-lock.json +23 -8
  22. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package.json +5 -1
  23. package/scaffold/.agent/skills/total-recall/plugins/mesh/package-lock.json +23 -10
  24. package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +5 -3
  25. package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +1 -1
  26. package/scaffold/.agent/skills/total-recall/plugins/mesh/src/cli/grants.mjs +7 -3
  27. package/scaffold/.agent/skills/total-recall/plugins/mesh/src/cli/mesh.mjs +61 -38
  28. package/scaffold/.agent/skills/total-recall/plugins/mesh/src/core/leader-election.mjs +57 -2
  29. package/scaffold/.agent/skills/total-recall/plugins/mesh/src/core/mesh.mjs +220 -36
  30. package/scaffold/.agent/skills/total-recall/plugins/mesh/src/server/routes/mesh.mjs +7 -2
  31. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/README.md +65 -0
  32. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/BRICK.md +59 -0
  33. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/index.mjs +534 -0
  34. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/cli.mjs +139 -0
  35. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package-lock.json +2849 -0
  36. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package.json +26 -0
  37. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/plugin.json +376 -0
  38. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/skills/meta-harness/SKILL.md +37 -0
  39. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/adapters/dsh.mjs +446 -0
  40. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/alerts.mjs +23 -0
  41. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/coordinator.mjs +398 -0
  42. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/documentation.mjs +152 -0
  43. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/executor.mjs +82 -0
  44. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/learner.mjs +90 -0
  45. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/router.mjs +415 -0
  46. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/runtime.mjs +36 -0
  47. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/setup.mjs +35 -0
  48. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/tracker.mjs +133 -0
  49. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worker.mjs +233 -0
  50. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/DESIGN.md +32 -0
  51. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/card.js +845 -0
  52. package/scaffold/.agent/skills/total-recall/plugins/openwiki/capability/BRICK.md +64 -0
  53. package/scaffold/.agent/skills/total-recall/plugins/openwiki/capability/index.mjs +250 -0
  54. package/scaffold/.agent/skills/total-recall/plugins/openwiki/cli.mjs +344 -14
  55. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +2917 -140
  56. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +9 -3
  57. package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +223 -5
  58. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/config.mjs +129 -0
  59. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh.mjs +355 -0
  60. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/upstream-watcher.mjs +375 -0
  61. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/DESIGN.md +35 -22
  62. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/card.js +947 -323
  63. package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +23 -8
  64. package/scaffold/.agent/skills/total-recall/plugins/security/package.json +5 -1
  65. package/src/cli/config.mjs +3 -0
  66. package/src/cli/connect.mjs +12 -116
  67. package/src/cli/harness.mjs +0 -1
  68. package/src/cli/plugin/create.mjs +56 -3
  69. package/src/cli/plugin/index.mjs +15 -3
  70. package/src/cli/plugin/monetization.mjs +232 -12
  71. package/src/cli/preflight.mjs +161 -0
  72. package/src/core/cli-commands.mjs +2 -0
  73. package/src/core/context-compiler.mjs +8 -1
  74. package/src/core/default-plugins.mjs +1 -1
  75. package/src/core/meta-harness.mjs +16 -38
  76. package/src/core/plugin-dependencies.mjs +6 -1
  77. package/src/core/preflight-gate.mjs +77 -0
  78. package/src/core/preflight-receipt.mjs +123 -0
  79. package/src/core/runtime.mjs +0 -3
  80. package/src/core/surface.mjs +38 -1
@@ -0,0 +1,64 @@
1
+ # OpenWiki Capability Brick
2
+
3
+ Portable documentation discovery, markdown knowledge hub parsing, upstream version comparison, and directory scaffolding without host dependencies.
4
+
5
+ ## Installation & Vendoring
6
+
7
+ Vendor this brick into any standalone project using Total Recall:
8
+
9
+ ```bash
10
+ total-recall plugin vendor openwiki
11
+ ```
12
+
13
+ ## API Usage
14
+
15
+ ```javascript
16
+ import {
17
+ discoverWikiHubs,
18
+ parseWikiHub,
19
+ inspectWikiStaleness,
20
+ bootstrapWikiPages,
21
+ compareSemanticVersions,
22
+ createPropagationPlan,
23
+ formatPropagationReceipt
24
+ } from './capability/index.mjs';
25
+
26
+ // 1. Discover all documentation hubs in a project
27
+ const hubs = discoverWikiHubs({ root: process.cwd() });
28
+ console.log(`Discovered ${hubs.length} hubs`);
29
+
30
+ // 2. Parse a hub document
31
+ const hubData = parseWikiHub('# Architecture\n\nSystem overview [Details](details.md)');
32
+ console.log(hubData.title); // "Architecture"
33
+
34
+ // 3. Inspect directory staleness
35
+ const staleness = inspectWikiStaleness({ root: process.cwd() });
36
+ console.log(staleness.isStale);
37
+
38
+ // 4. Compare version strings
39
+ const comparison = compareSemanticVersions('0.7.3', '0.7.2');
40
+ console.log(comparison > 0); // true
41
+
42
+ // 5. Build propagation plan across registered repositories
43
+ const plan = createPropagationPlan({
44
+ projects: [{ name: 'api', root: '/repos/api' }],
45
+ latestVersion: '0.7.3',
46
+ currentVersion: '0.7.2'
47
+ });
48
+ console.log(plan.updateRequired); // true
49
+
50
+ // 6. Bootstrap wiki skeleton
51
+ const result = bootstrapWikiPages({
52
+ targetDirectory: './openwiki',
53
+ templates: {
54
+ 'README.md': '# Project Knowledge Base\n'
55
+ },
56
+ dryRun: false
57
+ });
58
+ ```
59
+
60
+ ## Invariants
61
+
62
+ - Zero Total Recall runtime dependencies
63
+ - Zero network requests
64
+ - Pure filesystem and text operations
@@ -0,0 +1,250 @@
1
+ /**
2
+ * OpenWiki Core Capability Brick
3
+ *
4
+ * Standalone knowledge graph hub discovery, markdown wiki parsing,
5
+ * staleness auditing, and structural bootstrap operations.
6
+ * Operates with zero host coupling and zero runtime dependencies.
7
+ */
8
+ import fs from 'node:fs';
9
+ import path from 'node:path';
10
+
11
+ /**
12
+ * Discovers markdown wiki hubs within a specified directory.
13
+ * @param {object} options
14
+ * @param {string} options.root Base directory to inspect
15
+ * @param {string} [options.subfolder='openwiki'] Documentation folder name
16
+ * @returns {Array<{ name: string, title: string, path: string, lines: number, size_bytes: number }>}
17
+ */
18
+ export function discoverWikiHubs({ root = '.', subfolder = 'openwiki' } = {}) {
19
+ const targetDir = path.resolve(root, subfolder);
20
+ if (!fs.existsSync(targetDir)) return [];
21
+
22
+ const stat = fs.statSync(targetDir, { throwIfNoEntry: false });
23
+ if (!stat || !stat.isDirectory()) return [];
24
+
25
+ const hubs = [];
26
+ const entries = fs.readdirSync(targetDir, { withFileTypes: true });
27
+
28
+ for (const entry of entries) {
29
+ if (!entry.isFile() || !entry.name.endsWith('.md')) continue;
30
+ const fullPath = path.join(targetDir, entry.name);
31
+ try {
32
+ const content = fs.readFileSync(fullPath, 'utf8');
33
+ const titleMatch = content.match(/^#\s+(.+)$/m);
34
+ const title = titleMatch ? titleMatch[1].trim() : entry.name.replace(/\.md$/, '');
35
+ const lines = content.split('\n').length;
36
+ hubs.push({
37
+ name: entry.name,
38
+ title,
39
+ path: path.relative(root, fullPath),
40
+ lines,
41
+ size_bytes: Buffer.byteLength(content, 'utf8')
42
+ });
43
+ } catch {
44
+ // Unreadable file skipped cleanly
45
+ }
46
+ }
47
+
48
+ return hubs.sort((a, b) => a.name.localeCompare(b.name));
49
+ }
50
+
51
+ /**
52
+ * Parses markdown hub content into structured headings, internal links, and statistics.
53
+ * @param {string} content Markdown document content
54
+ * @returns {{ title: string, headings: string[], links: string[], lineCount: number, wordCount: number }}
55
+ */
56
+ export function parseWikiHub(content = '') {
57
+ if (typeof content !== 'string') {
58
+ return { title: 'Untitled', headings: [], links: [], lineCount: 0, wordCount: 0 };
59
+ }
60
+
61
+ const lines = content.split('\n');
62
+ const lineCount = lines.length;
63
+ const wordCount = content.trim().length ? content.trim().split(/\s+/).length : 0;
64
+
65
+ const headings = [];
66
+ let title = 'Untitled';
67
+
68
+ for (const line of lines) {
69
+ const match = line.match(/^(#{1,6})\s+(.+)$/);
70
+ if (match) {
71
+ const text = match[2].trim();
72
+ headings.push(text);
73
+ if (match[1].length === 1 && title === 'Untitled') {
74
+ title = text;
75
+ }
76
+ }
77
+ }
78
+
79
+ const links = [];
80
+ const linkRegex = /\[([^\]]+)\]\(([^)]+)\)/g;
81
+ let linkMatch;
82
+ while ((linkMatch = linkRegex.exec(content)) !== null) {
83
+ links.push({ text: linkMatch[1], href: linkMatch[2] });
84
+ }
85
+
86
+ return {
87
+ title,
88
+ headings,
89
+ links,
90
+ lineCount,
91
+ wordCount
92
+ };
93
+ }
94
+
95
+ /**
96
+ * Inspects documentation directory staleness by checking generation marker state.
97
+ * @param {object} options
98
+ * @param {string} options.root Project root containing an openwiki directory
99
+ * @returns {{ hasWiki: boolean, isStale: boolean, generatedAt: string | null, status: string | null, fileCount: number }}
100
+ */
101
+ export function inspectWikiStaleness({ root = '.' } = {}) {
102
+ const wikiDir = path.resolve(root, 'openwiki');
103
+ if (!fs.existsSync(wikiDir)) {
104
+ return { hasWiki: false, isStale: true, generatedAt: null, status: null, fileCount: 0 };
105
+ }
106
+
107
+ let fileCount = 0;
108
+ try {
109
+ const entries = fs.readdirSync(wikiDir, { withFileTypes: true });
110
+ fileCount = entries.filter(e => e.isFile() && e.name.endsWith('.md')).length;
111
+ } catch {
112
+ fileCount = 0;
113
+ }
114
+
115
+ const markerPath = path.join(wikiDir, '.last-update.json');
116
+ let generatedAt = null;
117
+ let status = null;
118
+
119
+ try {
120
+ const raw = fs.readFileSync(markerPath, 'utf8');
121
+ const parsed = JSON.parse(raw);
122
+ generatedAt = typeof parsed.updatedAt === 'string' ? parsed.updatedAt : null;
123
+ status = typeof parsed.status === 'string' ? parsed.status : null;
124
+ } catch {
125
+ // Marker missing or unreadable
126
+ }
127
+
128
+ const isStale = generatedAt === null || fileCount === 0;
129
+
130
+ return {
131
+ hasWiki: true,
132
+ isStale,
133
+ generatedAt,
134
+ status,
135
+ fileCount
136
+ };
137
+ }
138
+
139
+ /**
140
+ * Ensures standard wiki files exist without overwriting authored work.
141
+ * @param {object} options
142
+ * @param {string} options.targetDirectory Destination directory path
143
+ * @param {Record<string, string>} [options.templates={}] Filename to markdown content map
144
+ * @param {boolean} [options.dryRun=false] When true, computes actions without filesystem modification
145
+ * @returns {{ created: string[], preserved: string[], directory: string }}
146
+ */
147
+ export function bootstrapWikiPages({ targetDirectory, templates = {}, dryRun = false } = {}) {
148
+ if (!targetDirectory || typeof targetDirectory !== 'string') {
149
+ throw new Error('Target directory must be a valid path string');
150
+ }
151
+
152
+ const destination = path.resolve(targetDirectory);
153
+ const created = [];
154
+ const preserved = [];
155
+
156
+ if (!dryRun && !fs.existsSync(destination)) {
157
+ fs.mkdirSync(destination, { recursive: true });
158
+ }
159
+
160
+ for (const [filename, content] of Object.entries(templates)) {
161
+ const filePath = path.join(destination, filename);
162
+ if (fs.existsSync(filePath)) {
163
+ preserved.push(filename);
164
+ } else {
165
+ created.push(filename);
166
+ if (!dryRun) {
167
+ fs.writeFileSync(filePath, String(content), 'utf8');
168
+ }
169
+ }
170
+ }
171
+
172
+ return {
173
+ directory: destination,
174
+ created,
175
+ preserved
176
+ };
177
+ }
178
+
179
+ /**
180
+ * Compares two semantic version strings.
181
+ * Returns 1 if v1 > v2, -1 if v1 < v2, and 0 when versions match.
182
+ * @param {string} v1 First version string
183
+ * @param {string} v2 Second version string
184
+ * @returns {number}
185
+ */
186
+ export function compareSemanticVersions(v1 = '', v2 = '') {
187
+ const parse = (v) => {
188
+ const clean = String(v || '').replace(/^[^\d]*/, '').split('-')[0];
189
+ const parts = clean.split('.').map(n => Number.parseInt(n, 10) || 0);
190
+ while (parts.length < 3) parts.push(0);
191
+ return parts;
192
+ };
193
+
194
+ const [maj1, min1, pat1] = parse(v1);
195
+ const [maj2, min2, pat2] = parse(v2);
196
+
197
+ if (maj1 !== maj2) return maj1 > maj2 ? 1 : -1;
198
+ if (min1 !== min2) return min1 > min2 ? 1 : -1;
199
+ if (pat1 !== pat2) return pat1 > pat2 ? 1 : -1;
200
+ return 0;
201
+ }
202
+
203
+ /**
204
+ * Creates an execution plan for propagating an updated OpenWiki generator across projects.
205
+ * @param {object} options
206
+ * @param {Array<{ name: string, root: string }>} options.projects Registered projects
207
+ * @param {string} options.latestVersion Upstream generator version
208
+ * @param {string} [options.currentVersion] Currently recorded generator version
209
+ * @returns {{ updateRequired: boolean, eligibleCount: number, plannedActions: Array<{ name: string, root: string, action: string, generatorVersion: string }> }}
210
+ */
211
+ export function createPropagationPlan({ projects = [], latestVersion = '', currentVersion = '' } = {}) {
212
+ const updateRequired = compareSemanticVersions(latestVersion, currentVersion) > 0;
213
+ const plannedActions = [];
214
+
215
+ for (const project of projects) {
216
+ if (!project || typeof project.root !== 'string') continue;
217
+ const staleness = inspectWikiStaleness({ root: project.root });
218
+ if (!staleness.hasWiki) continue;
219
+
220
+ plannedActions.push({
221
+ name: project.name || path.basename(project.root),
222
+ root: project.root,
223
+ action: updateRequired ? 'regenerate' : 'verify',
224
+ generatorVersion: latestVersion || currentVersion || 'latest'
225
+ });
226
+ }
227
+
228
+ return {
229
+ updateRequired,
230
+ eligibleCount: plannedActions.length,
231
+ plannedActions
232
+ };
233
+ }
234
+
235
+ /**
236
+ * Standardizes a propagation execution receipt for persistent audit logs.
237
+ * @param {object} receipt
238
+ * @returns {{ timestamp: string, previousVersion: string, newVersion: string, totalProjects: number, updatedProjects: number, failedProjects: number, ok: boolean }}
239
+ */
240
+ export function formatPropagationReceipt(receipt = {}) {
241
+ return {
242
+ timestamp: receipt.timestamp || new Date().toISOString(),
243
+ previousVersion: String(receipt.previousVersion || 'unknown'),
244
+ newVersion: String(receipt.newVersion || 'unknown'),
245
+ totalProjects: Number.isInteger(receipt.totalProjects) ? receipt.totalProjects : 0,
246
+ updatedProjects: Number.isInteger(receipt.updatedProjects) ? receipt.updatedProjects : 0,
247
+ failedProjects: Number.isInteger(receipt.failedProjects) ? receipt.failedProjects : 0,
248
+ ok: Boolean(receipt.ok ?? (receipt.failedProjects === 0))
249
+ };
250
+ }