@ijfw/memory-server 1.3.0
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/ijfw +27 -0
- package/bin/ijfw-dashboard +180 -0
- package/bin/ijfw-dispatch-plan +41 -0
- package/bin/ijfw-memorize +273 -0
- package/bin/ijfw-memory +51 -0
- package/fixtures/demo-target.js +28 -0
- package/package.json +53 -0
- package/src/api-client.js +190 -0
- package/src/audit-roster.js +315 -0
- package/src/caps.js +37 -0
- package/src/cold-scan-runner.mjs +37 -0
- package/src/compute/edges.js +155 -0
- package/src/compute/extract.js +560 -0
- package/src/compute/fts5.js +420 -0
- package/src/compute/graph-auto-index.js +191 -0
- package/src/compute/graph-lock.js +114 -0
- package/src/compute/index.js +18 -0
- package/src/compute/migration-runner.js +116 -0
- package/src/compute/migrations/001-initial.js +23 -0
- package/src/compute/migrations/002-porter-stemming-source.js +139 -0
- package/src/compute/migrations/003-tier-semantic.js +69 -0
- package/src/compute/migrations/004-kg-tables.js +83 -0
- package/src/compute/migrations/005-stale-candidate.js +72 -0
- package/src/compute/python-resolver.js +106 -0
- package/src/compute/runner-vm.js +185 -0
- package/src/compute/runner.js +416 -0
- package/src/compute/sandbox-detect.js +122 -0
- package/src/compute/sandbox-linux.js +164 -0
- package/src/compute/sandbox-macos.js +167 -0
- package/src/compute/sandbox-windows.js +63 -0
- package/src/compute/schema.sql +118 -0
- package/src/compute/staleness.js +239 -0
- package/src/compute/synonyms.js +367 -0
- package/src/compute/traverse.js +180 -0
- package/src/cost/aggregator.js +229 -0
- package/src/cost/pricing.js +134 -0
- package/src/cost/readers/claude.js +179 -0
- package/src/cost/readers/codex.js +131 -0
- package/src/cost/readers/gemini.js +111 -0
- package/src/cost/savings.js +243 -0
- package/src/cross-dispatcher.js +437 -0
- package/src/cross-orchestrator-cli.js +1885 -0
- package/src/cross-orchestrator.js +598 -0
- package/src/cross-project-search.js +114 -0
- package/src/dashboard-client.html +1180 -0
- package/src/dashboard-server.js +895 -0
- package/src/design-companion.js +81 -0
- package/src/dispatch/colon-syntax.js +732 -0
- package/src/dispatch-planner.js +235 -0
- package/src/dream/cooldown.js +105 -0
- package/src/dream/runner.mjs +373 -0
- package/src/dream/staleness-wiring.js +195 -0
- package/src/feedback-detector.js +57 -0
- package/src/hero-line.js +115 -0
- package/src/importers/claude-mem.js +152 -0
- package/src/importers/cli.js +311 -0
- package/src/importers/common.js +84 -0
- package/src/importers/discover.js +235 -0
- package/src/importers/rtk.js +107 -0
- package/src/intent-router.js +221 -0
- package/src/lib/atomic-io.js +201 -0
- package/src/lib/cache.js +33 -0
- package/src/lib/npm-view.js +104 -0
- package/src/lib/status-card.js +95 -0
- package/src/lib/token.js +85 -0
- package/src/memory/fts5.js +349 -0
- package/src/memory/migration-runner.js +116 -0
- package/src/memory/migrations/001-fts5-init.js +26 -0
- package/src/memory/migrations/002-tier-semantic.js +60 -0
- package/src/memory/migrations/003-stale-candidate.js +60 -0
- package/src/memory/reader.js +300 -0
- package/src/memory/recall-counter.js +76 -0
- package/src/memory/schema.sql +79 -0
- package/src/memory/search.js +431 -0
- package/src/memory/staleness.js +237 -0
- package/src/memory/tier-promotion.js +377 -0
- package/src/memory/tokenize.js +63 -0
- package/src/project-type-detector.js +866 -0
- package/src/prompt-check.js +171 -0
- package/src/ralph-allowlist.js +88 -0
- package/src/receipts.js +129 -0
- package/src/redactor.js +107 -0
- package/src/sandbox.js +275 -0
- package/src/sanitizer.js +69 -0
- package/src/scan-resume.js +167 -0
- package/src/schema.js +82 -0
- package/src/search-bm25.js +108 -0
- package/src/server.js +1414 -0
- package/src/swarm-config.js +80 -0
- package/src/trident/dispatch.js +211 -0
- package/src/trident/lens-health.js +253 -0
- package/src/update-apply.js +79 -0
- package/src/update-check.js +136 -0
- package/src/vectors.js +178 -0
- package/templates/design/bento-grid.md +84 -0
- package/templates/design/brutalist-luxe.md +82 -0
- package/templates/design/cinematic-dark.md +82 -0
- package/templates/design/data-dense-dashboard.md +88 -0
- package/templates/design/editorial-warm.md +81 -0
- package/templates/design/glassmorphic.md +84 -0
- package/templates/design/magazine-editorial.md +84 -0
- package/templates/design/maximalist-vibrant.md +85 -0
- package/templates/design/neo-swiss-tech.md +85 -0
- package/templates/design/swiss-minimal.md +80 -0
- package/templates/design/terminal-native.md +83 -0
- package/templates/design/warm-organic.md +84 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// --- cross-project-search: BM25 search across every registered IJFW project ---
|
|
2
|
+
//
|
|
3
|
+
// Complements the existing naive keyword-count searchAcrossProjects in
|
|
4
|
+
// server.js. Builds a corpus of (project, source, line) docs from each
|
|
5
|
+
// registered project's memory files, hands it to the BM25 ranker in
|
|
6
|
+
// search-bm25.js, and returns hits tagged with [project:<basename>].
|
|
7
|
+
//
|
|
8
|
+
// Pure + injectable. The caller supplies the registry reader and the
|
|
9
|
+
// per-project memory reader so this module can be unit-tested without
|
|
10
|
+
// touching the home directory.
|
|
11
|
+
|
|
12
|
+
import { basename } from 'node:path';
|
|
13
|
+
import { searchCorpus } from './search-bm25.js';
|
|
14
|
+
|
|
15
|
+
// Build a corpus of line-level docs from the provided projects.
|
|
16
|
+
// projects: [{ path, hash?, iso? }]
|
|
17
|
+
// readProjectMemory(path) -> { knowledge, journal, handoff } (strings)
|
|
18
|
+
// Returns [{ id, text, meta }] where meta carries project + source + lineNo.
|
|
19
|
+
export function buildCorpus(projects, readProjectMemory) {
|
|
20
|
+
const docs = [];
|
|
21
|
+
for (const entry of projects) {
|
|
22
|
+
const tag = basename(entry.path);
|
|
23
|
+
const mem = readProjectMemory(entry.path) || {};
|
|
24
|
+
for (const [source, content] of Object.entries(mem)) {
|
|
25
|
+
if (typeof content !== 'string' || content.length === 0) continue;
|
|
26
|
+
const lines = content.split('\n');
|
|
27
|
+
for (let i = 0; i < lines.length; i++) {
|
|
28
|
+
const line = lines[i];
|
|
29
|
+
if (line.trim().length === 0) continue;
|
|
30
|
+
docs.push({
|
|
31
|
+
id: `${tag}:${source}:${i + 1}`,
|
|
32
|
+
text: line,
|
|
33
|
+
meta: { project: tag, projectPath: entry.path, source, lineNo: i + 1 },
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return docs;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Run a BM25-ranked search across the corpus produced from `projects`.
|
|
42
|
+
// Returns [{ content, source, line, project, score, snippet }], capped at limit.
|
|
43
|
+
export function crossProjectSearch(query, projects, readProjectMemory, opts = {}) {
|
|
44
|
+
const limit = clamp(opts.limit, 1, 50, 10);
|
|
45
|
+
if (!query || typeof query !== 'string') return [];
|
|
46
|
+
|
|
47
|
+
const docs = buildCorpus(projects, readProjectMemory);
|
|
48
|
+
if (docs.length === 0) return [];
|
|
49
|
+
|
|
50
|
+
const hits = searchCorpus(query, docs, { limit });
|
|
51
|
+
return hits.map((h) => ({
|
|
52
|
+
content: `[project:${h.meta.project}] ${h.snippet || ''}`.trim(),
|
|
53
|
+
source: `${h.meta.source}@${h.meta.project}`,
|
|
54
|
+
project: h.meta.project,
|
|
55
|
+
projectPath: h.meta.projectPath,
|
|
56
|
+
line: h.meta.lineNo,
|
|
57
|
+
score: Math.round(h.score * 1000) / 1000,
|
|
58
|
+
snippet: h.snippet,
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function clamp(n, lo, hi, dflt) {
|
|
63
|
+
const v = Number.isFinite(n) ? n | 0 : dflt;
|
|
64
|
+
return Math.min(hi, Math.max(lo, v));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Render a portfolio-findings markdown doc from per-project audit results.
|
|
68
|
+
// results: [{ project, path, status, findings, error? }]
|
|
69
|
+
// status: 'ok' | 'failed' | 'skipped'
|
|
70
|
+
// findings: free-form string (per-project audit stdout)
|
|
71
|
+
// Returns a markdown body. Section per project, summary table on top.
|
|
72
|
+
export function aggregatePortfolioFindings(results, { rule, startedAt, finishedAt } = {}) {
|
|
73
|
+
const total = results.length;
|
|
74
|
+
const okN = results.filter(r => r.status === 'ok').length;
|
|
75
|
+
const failN = results.filter(r => r.status === 'failed').length;
|
|
76
|
+
const skipN = results.filter(r => r.status === 'skipped').length;
|
|
77
|
+
|
|
78
|
+
const head = [
|
|
79
|
+
`# Portfolio audit -- ${rule || '(rule unspecified)'}`,
|
|
80
|
+
'',
|
|
81
|
+
`- Projects audited: ${okN} / ${total} (failed: ${failN}, skipped: ${skipN})`,
|
|
82
|
+
startedAt ? `- Started: ${startedAt}` : null,
|
|
83
|
+
finishedAt ? `- Finished: ${finishedAt}` : null,
|
|
84
|
+
'',
|
|
85
|
+
'## Summary',
|
|
86
|
+
'',
|
|
87
|
+
'| Project | Status | Notes |',
|
|
88
|
+
'|---------|--------|-------|',
|
|
89
|
+
...results.map(r => `| ${r.project} | ${r.status} | ${(r.error || firstLine(r.findings) || '').replace(/\|/g, '\\|')} |`),
|
|
90
|
+
'',
|
|
91
|
+
'## Per-project findings',
|
|
92
|
+
'',
|
|
93
|
+
].filter(Boolean);
|
|
94
|
+
|
|
95
|
+
const bodies = results.map(r => [
|
|
96
|
+
`### ${r.project} (${r.path})`,
|
|
97
|
+
'',
|
|
98
|
+
`**Status:** ${r.status}`,
|
|
99
|
+
r.error ? `**Error:** ${r.error}` : null,
|
|
100
|
+
'',
|
|
101
|
+
'```',
|
|
102
|
+
(r.findings || '(no output)').trim(),
|
|
103
|
+
'```',
|
|
104
|
+
'',
|
|
105
|
+
].filter(Boolean).join('\n'));
|
|
106
|
+
|
|
107
|
+
return head.join('\n') + bodies.join('\n');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function firstLine(s) {
|
|
111
|
+
if (!s) return '';
|
|
112
|
+
const idx = s.indexOf('\n');
|
|
113
|
+
return idx < 0 ? s.trim() : s.slice(0, idx).trim();
|
|
114
|
+
}
|