openlore 2.0.1 → 2.0.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.
Files changed (84) hide show
  1. package/README.md +29 -0
  2. package/dist/cli/index.js +15 -9
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/cli/install/adapters/agents-md.d.ts +8 -0
  5. package/dist/cli/install/adapters/agents-md.d.ts.map +1 -0
  6. package/dist/cli/install/adapters/agents-md.js +21 -0
  7. package/dist/cli/install/adapters/agents-md.js.map +1 -0
  8. package/dist/cli/install/adapters/claude-code.d.ts +8 -0
  9. package/dist/cli/install/adapters/claude-code.d.ts.map +1 -0
  10. package/dist/cli/install/adapters/claude-code.js +184 -0
  11. package/dist/cli/install/adapters/claude-code.js.map +1 -0
  12. package/dist/cli/install/adapters/cline.d.ts +6 -0
  13. package/dist/cli/install/adapters/cline.d.ts.map +1 -0
  14. package/dist/cli/install/adapters/cline.js +19 -0
  15. package/dist/cli/install/adapters/cline.js.map +1 -0
  16. package/dist/cli/install/adapters/continue.d.ts +13 -0
  17. package/dist/cli/install/adapters/continue.d.ts.map +1 -0
  18. package/dist/cli/install/adapters/continue.js +119 -0
  19. package/dist/cli/install/adapters/continue.js.map +1 -0
  20. package/dist/cli/install/adapters/cursor.d.ts +8 -0
  21. package/dist/cli/install/adapters/cursor.d.ts.map +1 -0
  22. package/dist/cli/install/adapters/cursor.js +195 -0
  23. package/dist/cli/install/adapters/cursor.js.map +1 -0
  24. package/dist/cli/install/adapters/markdown-block.d.ts +20 -0
  25. package/dist/cli/install/adapters/markdown-block.d.ts.map +1 -0
  26. package/dist/cli/install/adapters/markdown-block.js +114 -0
  27. package/dist/cli/install/adapters/markdown-block.js.map +1 -0
  28. package/dist/cli/install/adapters/types.d.ts +39 -0
  29. package/dist/cli/install/adapters/types.d.ts.map +1 -0
  30. package/dist/cli/install/adapters/types.js +10 -0
  31. package/dist/cli/install/adapters/types.js.map +1 -0
  32. package/dist/cli/install/block.d.ts +53 -0
  33. package/dist/cli/install/block.d.ts.map +1 -0
  34. package/dist/cli/install/block.js +106 -0
  35. package/dist/cli/install/block.js.map +1 -0
  36. package/dist/cli/install/detect.d.ts +23 -0
  37. package/dist/cli/install/detect.d.ts.map +1 -0
  38. package/dist/cli/install/detect.js +115 -0
  39. package/dist/cli/install/detect.js.map +1 -0
  40. package/dist/cli/install/diff.d.ts +12 -0
  41. package/dist/cli/install/diff.d.ts.map +1 -0
  42. package/dist/cli/install/diff.js +51 -0
  43. package/dist/cli/install/diff.js.map +1 -0
  44. package/dist/cli/install/index.d.ts +19 -0
  45. package/dist/cli/install/index.d.ts.map +1 -0
  46. package/dist/cli/install/index.js +133 -0
  47. package/dist/cli/install/index.js.map +1 -0
  48. package/dist/cli/install/json-managed.d.ts +43 -0
  49. package/dist/cli/install/json-managed.d.ts.map +1 -0
  50. package/dist/cli/install/json-managed.js +137 -0
  51. package/dist/cli/install/json-managed.js.map +1 -0
  52. package/dist/cli/install/templates/agent-instructions.md +12 -0
  53. package/dist/cli/install/templates/cursor-openlore.mdc +7 -0
  54. package/dist/cli/preflight/diff.d.ts +42 -0
  55. package/dist/cli/preflight/diff.d.ts.map +1 -0
  56. package/dist/cli/preflight/diff.js +162 -0
  57. package/dist/cli/preflight/diff.js.map +1 -0
  58. package/dist/cli/preflight/index.d.ts +31 -0
  59. package/dist/cli/preflight/index.d.ts.map +1 -0
  60. package/dist/cli/preflight/index.js +126 -0
  61. package/dist/cli/preflight/index.js.map +1 -0
  62. package/dist/cli/preflight/report.d.ts +50 -0
  63. package/dist/cli/preflight/report.d.ts.map +1 -0
  64. package/dist/cli/preflight/report.js +174 -0
  65. package/dist/cli/preflight/report.js.map +1 -0
  66. package/dist/cli/preflight/score.d.ts +43 -0
  67. package/dist/cli/preflight/score.d.ts.map +1 -0
  68. package/dist/cli/preflight/score.js +102 -0
  69. package/dist/cli/preflight/score.js.map +1 -0
  70. package/dist/core/analyzer/file-walker.d.ts.map +1 -1
  71. package/dist/core/analyzer/file-walker.js +20 -13
  72. package/dist/core/analyzer/file-walker.js.map +1 -1
  73. package/dist/core/analyzer/vector-index.d.ts +2 -0
  74. package/dist/core/analyzer/vector-index.d.ts.map +1 -1
  75. package/dist/core/analyzer/vector-index.js +30 -20
  76. package/dist/core/analyzer/vector-index.js.map +1 -1
  77. package/dist/core/services/mcp-handlers/utils.d.ts +2 -0
  78. package/dist/core/services/mcp-handlers/utils.d.ts.map +1 -1
  79. package/dist/core/services/mcp-handlers/utils.js +18 -2
  80. package/dist/core/services/mcp-handlers/utils.js.map +1 -1
  81. package/examples/ci/openlore-preflight.gitlab.yml +16 -0
  82. package/examples/ci/openlore-preflight.sh +16 -0
  83. package/examples/ci/openlore-preflight.yml +30 -0
  84. package/package.json +4 -2
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Detect which agent surfaces are present in a project tree.
3
+ *
4
+ * We walk up from `cwd` checking up to 3 parent directories for marker files.
5
+ * The first directory that has any marker becomes the "project root" for that
6
+ * surface. `agents-md` is the universal fallback and is always included.
7
+ */
8
+ import { access, stat, readFile } from 'node:fs/promises';
9
+ import { join, resolve } from 'node:path';
10
+ export const ALL_AGENTS = [
11
+ 'claude-code',
12
+ 'cursor',
13
+ 'cline',
14
+ 'continue',
15
+ 'agents-md',
16
+ ];
17
+ const PARENTS_TO_CHECK = 3;
18
+ async function exists(p) {
19
+ try {
20
+ await access(p);
21
+ return true;
22
+ }
23
+ catch {
24
+ return false;
25
+ }
26
+ }
27
+ async function isDir(p) {
28
+ try {
29
+ return (await stat(p)).isDirectory();
30
+ }
31
+ catch {
32
+ return false;
33
+ }
34
+ }
35
+ async function hasClineSettings(p) {
36
+ const settings = join(p, '.vscode', 'settings.json');
37
+ if (!(await exists(settings)))
38
+ return false;
39
+ try {
40
+ const raw = await readFile(settings, 'utf8');
41
+ return /"cline\./.test(raw);
42
+ }
43
+ catch {
44
+ return false;
45
+ }
46
+ }
47
+ async function detectInDir(dir) {
48
+ const found = [];
49
+ // claude-code
50
+ {
51
+ const markers = [];
52
+ if (await isDir(join(dir, '.claude')))
53
+ markers.push('.claude/');
54
+ if (await exists(join(dir, 'CLAUDE.md')))
55
+ markers.push('CLAUDE.md');
56
+ if (markers.length)
57
+ found.push({ agent: 'claude-code', root: dir, markers });
58
+ }
59
+ // cursor
60
+ {
61
+ const markers = [];
62
+ if (await isDir(join(dir, '.cursor')))
63
+ markers.push('.cursor/');
64
+ if (await exists(join(dir, '.cursorrules')))
65
+ markers.push('.cursorrules');
66
+ if (markers.length)
67
+ found.push({ agent: 'cursor', root: dir, markers });
68
+ }
69
+ // cline
70
+ {
71
+ const markers = [];
72
+ if (await exists(join(dir, '.clinerules')))
73
+ markers.push('.clinerules');
74
+ if (await hasClineSettings(dir))
75
+ markers.push('.vscode/settings.json (cline.*)');
76
+ if (markers.length)
77
+ found.push({ agent: 'cline', root: dir, markers });
78
+ }
79
+ // continue
80
+ {
81
+ const markers = [];
82
+ if (await isDir(join(dir, '.continue')))
83
+ markers.push('.continue/');
84
+ if (markers.length)
85
+ found.push({ agent: 'continue', root: dir, markers });
86
+ }
87
+ return found;
88
+ }
89
+ /**
90
+ * Detect surfaces by walking up from `startDir` up to PARENTS_TO_CHECK levels.
91
+ * Each surface is reported at most once, anchored at the deepest dir where its
92
+ * marker was found. `agents-md` is always appended last as a universal fallback.
93
+ */
94
+ export async function detect(startDir) {
95
+ const seen = new Set();
96
+ const out = [];
97
+ let dir = resolve(startDir);
98
+ for (let i = 0; i <= PARENTS_TO_CHECK; i++) {
99
+ for (const s of await detectInDir(dir)) {
100
+ if (seen.has(s.agent))
101
+ continue;
102
+ seen.add(s.agent);
103
+ out.push(s);
104
+ }
105
+ const parent = resolve(dir, '..');
106
+ if (parent === dir)
107
+ break;
108
+ dir = parent;
109
+ }
110
+ // Universal fallback — anchored at the first detected root, or cwd.
111
+ const fallbackRoot = out[0]?.root ?? resolve(startDir);
112
+ out.push({ agent: 'agents-md', root: fallbackRoot, markers: ['(fallback)'] });
113
+ return out;
114
+ }
115
+ //# sourceMappingURL=detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.js","sourceRoot":"","sources":["../../../src/cli/install/detect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Tiny line-oriented diff helper used to populate `--dry-run` previews.
3
+ *
4
+ * This is not a full Myers diff — it's the cheapest output that still lets a
5
+ * user see what `openlore install --dry-run` would do without us shelling out
6
+ * to `diff(1)`. Lines that match are skipped (with a `...` separator if there
7
+ * are unchanged runs between hunks); changed lines are prefixed with `+` /
8
+ * `-`. The result is meant for human eyeballing, not machine consumption.
9
+ */
10
+ export declare function previewCreate(filePath: string, content: string): string;
11
+ export declare function previewDiff(filePath: string, before: string, after: string): string;
12
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../../src/cli/install/diff.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAOvE;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAiCnF"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Tiny line-oriented diff helper used to populate `--dry-run` previews.
3
+ *
4
+ * This is not a full Myers diff — it's the cheapest output that still lets a
5
+ * user see what `openlore install --dry-run` would do without us shelling out
6
+ * to `diff(1)`. Lines that match are skipped (with a `...` separator if there
7
+ * are unchanged runs between hunks); changed lines are prefixed with `+` /
8
+ * `-`. The result is meant for human eyeballing, not machine consumption.
9
+ */
10
+ const MAX_PREVIEW_LINES = 60;
11
+ export function previewCreate(filePath, content) {
12
+ const lines = content.split('\n');
13
+ const truncated = lines.length > MAX_PREVIEW_LINES;
14
+ const shown = truncated ? lines.slice(0, MAX_PREVIEW_LINES) : lines;
15
+ const body = shown.map((l) => `+ ${l}`).join('\n');
16
+ const suffix = truncated ? `\n ... (${lines.length - MAX_PREVIEW_LINES} more lines)` : '';
17
+ return `--- (new file) ${filePath}\n${body}${suffix}`;
18
+ }
19
+ export function previewDiff(filePath, before, after) {
20
+ const a = before.split('\n');
21
+ const b = after.split('\n');
22
+ // Trim common prefix and suffix so we focus on the changed region.
23
+ let prefix = 0;
24
+ while (prefix < a.length && prefix < b.length && a[prefix] === b[prefix])
25
+ prefix++;
26
+ let suffix = 0;
27
+ while (suffix < a.length - prefix &&
28
+ suffix < b.length - prefix &&
29
+ a[a.length - 1 - suffix] === b[b.length - 1 - suffix])
30
+ suffix++;
31
+ const removed = a.slice(prefix, a.length - suffix);
32
+ const added = b.slice(prefix, b.length - suffix);
33
+ const truncatedRemoved = removed.length > MAX_PREVIEW_LINES;
34
+ const truncatedAdded = added.length > MAX_PREVIEW_LINES;
35
+ const shownRemoved = truncatedRemoved ? removed.slice(0, MAX_PREVIEW_LINES) : removed;
36
+ const shownAdded = truncatedAdded ? added.slice(0, MAX_PREVIEW_LINES) : added;
37
+ const header = `--- ${filePath} @ line ${prefix + 1}`;
38
+ const minus = shownRemoved.map((l) => `- ${l}`).join('\n');
39
+ const plus = shownAdded.map((l) => `+ ${l}`).join('\n');
40
+ const parts = [header];
41
+ if (minus)
42
+ parts.push(minus);
43
+ if (truncatedRemoved)
44
+ parts.push(` ... (${removed.length - MAX_PREVIEW_LINES} more removed lines)`);
45
+ if (plus)
46
+ parts.push(plus);
47
+ if (truncatedAdded)
48
+ parts.push(` ... (${added.length - MAX_PREVIEW_LINES} more added lines)`);
49
+ return parts.join('\n');
50
+ }
51
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../../src/cli/install/diff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * `openlore install` — auto-configure popular agent surfaces so they call
3
+ * `orient()` automatically.
4
+ *
5
+ * Dispatches to one or more adapters depending on `--agent` / detection,
6
+ * supports `--dry-run`, `--force`, and `--uninstall`.
7
+ */
8
+ import { Command } from 'commander';
9
+ import { type AgentName } from './detect.js';
10
+ export interface InstallOptions {
11
+ agent?: AgentName;
12
+ dryRun?: boolean;
13
+ force?: boolean;
14
+ uninstall?: boolean;
15
+ cwd?: string;
16
+ }
17
+ export declare function runInstall(opts: InstallOptions): Promise<number>;
18
+ export declare const installCommand: Command;
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/install/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAsB,KAAK,SAAS,EAAwB,MAAM,aAAa,CAAC;AAqCvF,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAmDtE;AAsCD,eAAO,MAAM,cAAc,SASvB,CAAC"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * `openlore install` — auto-configure popular agent surfaces so they call
3
+ * `orient()` automatically.
4
+ *
5
+ * Dispatches to one or more adapters depending on `--agent` / detection,
6
+ * supports `--dry-run`, `--force`, and `--uninstall`.
7
+ */
8
+ import { readFile } from 'node:fs/promises';
9
+ import { fileURLToPath } from 'node:url';
10
+ import { dirname, join } from 'node:path';
11
+ import { Command } from 'commander';
12
+ import { logger } from '../../utils/logger.js';
13
+ import { detect, ALL_AGENTS } from './detect.js';
14
+ import { agentsMdAdapter } from './adapters/agents-md.js';
15
+ import { claudeCodeAdapter } from './adapters/claude-code.js';
16
+ import { cursorAdapter } from './adapters/cursor.js';
17
+ import { clineAdapter } from './adapters/cline.js';
18
+ import { continueAdapter } from './adapters/continue.js';
19
+ const ADAPTERS = {
20
+ 'agents-md': agentsMdAdapter,
21
+ 'claude-code': claudeCodeAdapter,
22
+ cursor: cursorAdapter,
23
+ cline: clineAdapter,
24
+ continue: continueAdapter,
25
+ };
26
+ async function loadTemplate() {
27
+ // Template lives next to this file in the source tree, but at runtime we
28
+ // resolve via the compiled dist path.
29
+ const here = dirname(fileURLToPath(import.meta.url));
30
+ const candidates = [
31
+ join(here, 'templates', 'agent-instructions.md'),
32
+ // tsx / source-run fallback
33
+ join(here, '..', '..', '..', 'src', 'cli', 'install', 'templates', 'agent-instructions.md'),
34
+ ];
35
+ for (const p of candidates) {
36
+ try {
37
+ return await readFile(p, 'utf8');
38
+ }
39
+ catch {
40
+ /* try next */
41
+ }
42
+ }
43
+ throw new Error('openlore install: could not locate agent-instructions.md template (looked in dist + src)');
44
+ }
45
+ export async function runInstall(opts) {
46
+ const cwd = opts.cwd ?? process.cwd();
47
+ const template = await loadTemplate();
48
+ let surfaces;
49
+ if (opts.agent) {
50
+ if (!ALL_AGENTS.includes(opts.agent)) {
51
+ logger.error(`Unknown agent surface "${opts.agent}". Known: ${ALL_AGENTS.join(', ')}`);
52
+ return 2;
53
+ }
54
+ surfaces = [{ agent: opts.agent, root: cwd, markers: ['(explicit --agent)'] }];
55
+ }
56
+ else {
57
+ surfaces = await detect(cwd);
58
+ }
59
+ logger.discovery(`${opts.uninstall ? 'Uninstalling' : 'Installing'} for ${surfaces.length} surface(s): ${surfaces
60
+ .map((s) => s.agent)
61
+ .join(', ')}`);
62
+ let conflict = false;
63
+ const allChanges = [];
64
+ const allWarnings = [];
65
+ for (const surface of surfaces) {
66
+ const adapter = ADAPTERS[surface.agent];
67
+ const ctx = {
68
+ root: surface.root,
69
+ instructionTemplate: template,
70
+ dryRun: !!opts.dryRun,
71
+ force: !!opts.force,
72
+ };
73
+ const result = opts.uninstall
74
+ ? await adapter.uninstall(ctx)
75
+ : await adapter.apply(ctx);
76
+ if (result.conflict)
77
+ conflict = true;
78
+ allChanges.push(...result.changes);
79
+ allWarnings.push(...result.warnings);
80
+ }
81
+ printSummary(allChanges, allWarnings, !!opts.dryRun, !!opts.uninstall);
82
+ if (conflict) {
83
+ logger.error('Hand-edited OpenLore block(s) detected. Re-run with --force to overwrite, or revert your edits.');
84
+ return 1;
85
+ }
86
+ return 0;
87
+ }
88
+ function printSummary(changes, warnings, dryRun, uninstall) {
89
+ const verb = dryRun ? 'would' : 'did';
90
+ for (const c of changes) {
91
+ const tag = c.kind === 'create'
92
+ ? `[${verb} create]`
93
+ : c.kind === 'update'
94
+ ? `[${verb} update]`
95
+ : c.kind === 'delete'
96
+ ? `[${verb} delete]`
97
+ : '[noop]';
98
+ if (c.kind === 'noop')
99
+ logger.discovery(`${tag} ${c.summary}`);
100
+ else
101
+ logger.success(`${tag} ${c.summary}`);
102
+ if (dryRun && c.preview) {
103
+ const indented = c.preview
104
+ .split('\n')
105
+ .map((l) => ' ' + l)
106
+ .join('\n');
107
+ process.stderr.write(indented + '\n');
108
+ }
109
+ }
110
+ for (const w of warnings)
111
+ logger.warning(w);
112
+ if (dryRun) {
113
+ logger.discovery('Dry run — no files were written.');
114
+ }
115
+ else if (!uninstall) {
116
+ logger.success('OpenLore install complete.');
117
+ }
118
+ else {
119
+ logger.success('OpenLore uninstall complete.');
120
+ }
121
+ }
122
+ export const installCommand = new Command('install')
123
+ .description('Auto-configure agent surfaces to call orient() (Claude Code, Cursor, Cline, Continue, AGENTS.md).')
124
+ .option('--agent <name>', 'Install only for a specific surface (claude-code, cursor, cline, continue, agents-md)')
125
+ .option('--dry-run', 'Print the planned changes without writing any files', false)
126
+ .option('--force', 'Overwrite OpenLore-managed blocks even if hand-edited', false)
127
+ .option('--uninstall', 'Remove OpenLore-managed blocks and entries', false)
128
+ .action(async (opts) => {
129
+ const code = await runInstall(opts);
130
+ if (code !== 0)
131
+ process.exit(code);
132
+ });
133
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/install/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Safe merge of an OpenLore-managed entry into a JSON config file.
3
+ *
4
+ * We store our additions under a top-level `_openlore` key for bookkeeping
5
+ * (fingerprint of the merged subtree, version), while writing the actual
6
+ * config under whatever path the host tool reads (e.g. `mcpServers.openlore`,
7
+ * `hooks.SessionStart`). The fingerprint lets us detect hand-edits.
8
+ */
9
+ export interface ManagedJsonMeta {
10
+ managed: true;
11
+ version: number;
12
+ fingerprint: string;
13
+ /**
14
+ * Dotted paths into the JSON document that OpenLore manages. Used by
15
+ * `--uninstall` to remove only what we added.
16
+ */
17
+ paths: string[];
18
+ }
19
+ export declare function canonicalJsonHash(value: unknown): string;
20
+ export interface ManagedEntry {
21
+ /** Dotted path into the JSON document (e.g. "mcpServers.openlore"). */
22
+ path: string;
23
+ /** Value to write at that path. */
24
+ value: unknown;
25
+ }
26
+ export interface MergeResult {
27
+ next: Record<string, unknown>;
28
+ action: 'created' | 'updated' | 'noop';
29
+ /** If the existing meta fingerprint didn't match what was on disk. */
30
+ handEdited: boolean;
31
+ }
32
+ export declare function readMeta(doc: Record<string, unknown>): ManagedJsonMeta | null;
33
+ /**
34
+ * Verify the meta fingerprint still matches the values we previously wrote.
35
+ * If not, the user has hand-edited one of our managed paths.
36
+ */
37
+ export declare function isHandEdited(doc: Record<string, unknown>, meta: ManagedJsonMeta): boolean;
38
+ export declare function mergeEntries(existing: Record<string, unknown>, entries: ManagedEntry[]): MergeResult;
39
+ export declare function removeManaged(doc: Record<string, unknown>): {
40
+ next: Record<string, unknown>;
41
+ removed: boolean;
42
+ };
43
+ //# sourceMappingURL=json-managed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-managed.d.ts","sourceRoot":"","sources":["../../../src/cli/install/json-managed.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAKD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAExD;AAeD,MAAM,WAAW,YAAY;IAC3B,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,sEAAsE;IACtE,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,eAAe,GAAG,IAAI,CAW7E;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAOzF;AAED,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,OAAO,EAAE,YAAY,EAAE,GACtB,WAAW,CA4Bb;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAC3D,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,EAAE,OAAO,CAAC;CAClB,CAOA"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Safe merge of an OpenLore-managed entry into a JSON config file.
3
+ *
4
+ * We store our additions under a top-level `_openlore` key for bookkeeping
5
+ * (fingerprint of the merged subtree, version), while writing the actual
6
+ * config under whatever path the host tool reads (e.g. `mcpServers.openlore`,
7
+ * `hooks.SessionStart`). The fingerprint lets us detect hand-edits.
8
+ */
9
+ import { createHash } from 'node:crypto';
10
+ const META_KEY = '_openlore';
11
+ const META_VERSION = 1;
12
+ export function canonicalJsonHash(value) {
13
+ return createHash('sha256').update(canonicalize(value), 'utf8').digest('hex').slice(0, 16);
14
+ }
15
+ function canonicalize(value) {
16
+ if (value === null || typeof value !== 'object')
17
+ return JSON.stringify(value);
18
+ if (Array.isArray(value))
19
+ return '[' + value.map(canonicalize).join(',') + ']';
20
+ const keys = Object.keys(value).sort();
21
+ return ('{' +
22
+ keys
23
+ .map((k) => JSON.stringify(k) + ':' + canonicalize(value[k]))
24
+ .join(',') +
25
+ '}');
26
+ }
27
+ export function readMeta(doc) {
28
+ const meta = doc[META_KEY];
29
+ if (!meta || typeof meta !== 'object')
30
+ return null;
31
+ const m = meta;
32
+ if (m.managed !== true || typeof m.fingerprint !== 'string')
33
+ return null;
34
+ return {
35
+ managed: true,
36
+ version: typeof m.version === 'number' ? m.version : 1,
37
+ fingerprint: m.fingerprint,
38
+ paths: Array.isArray(m.paths) ? m.paths.filter((p) => typeof p === 'string') : [],
39
+ };
40
+ }
41
+ /**
42
+ * Verify the meta fingerprint still matches the values we previously wrote.
43
+ * If not, the user has hand-edited one of our managed paths.
44
+ */
45
+ export function isHandEdited(doc, meta) {
46
+ const subset = {};
47
+ for (const path of meta.paths) {
48
+ const value = getPath(doc, path);
49
+ if (value !== undefined)
50
+ setPath(subset, path, value);
51
+ }
52
+ return canonicalJsonHash(subset) !== meta.fingerprint;
53
+ }
54
+ export function mergeEntries(existing, entries) {
55
+ const next = structuredClone(existing);
56
+ const prevMeta = readMeta(next);
57
+ const handEdited = prevMeta ? isHandEdited(next, prevMeta) : false;
58
+ for (const e of entries)
59
+ setPath(next, e.path, e.value);
60
+ const subset = {};
61
+ for (const e of entries)
62
+ setPath(subset, e.path, e.value);
63
+ const newMeta = {
64
+ managed: true,
65
+ version: META_VERSION,
66
+ fingerprint: canonicalJsonHash(subset),
67
+ paths: entries.map((e) => e.path),
68
+ };
69
+ next[META_KEY] = newMeta;
70
+ // Did anything actually change vs `existing`?
71
+ const before = canonicalize(existing);
72
+ const after = canonicalize(next);
73
+ const action = prevMeta
74
+ ? before === after
75
+ ? 'noop'
76
+ : 'updated'
77
+ : 'created';
78
+ return { next, action, handEdited };
79
+ }
80
+ export function removeManaged(doc) {
81
+ const meta = readMeta(doc);
82
+ if (!meta)
83
+ return { next: doc, removed: false };
84
+ const next = structuredClone(doc);
85
+ for (const path of meta.paths)
86
+ deletePath(next, path);
87
+ delete next[META_KEY];
88
+ return { next, removed: true };
89
+ }
90
+ // ---------- path helpers ----------
91
+ function getPath(obj, path) {
92
+ const parts = path.split('.');
93
+ let cur = obj;
94
+ for (const p of parts) {
95
+ if (cur === null || typeof cur !== 'object')
96
+ return undefined;
97
+ cur = cur[p];
98
+ }
99
+ return cur;
100
+ }
101
+ function setPath(obj, path, value) {
102
+ const parts = path.split('.');
103
+ let cur = obj;
104
+ for (let i = 0; i < parts.length - 1; i++) {
105
+ const k = parts[i];
106
+ const next = cur[k];
107
+ if (next === null || typeof next !== 'object' || Array.isArray(next)) {
108
+ cur[k] = {};
109
+ }
110
+ cur = cur[k];
111
+ }
112
+ cur[parts[parts.length - 1]] = value;
113
+ }
114
+ function deletePath(obj, path) {
115
+ const parts = path.split('.');
116
+ const chain = [];
117
+ let cur = obj;
118
+ for (let i = 0; i < parts.length - 1; i++) {
119
+ const k = parts[i];
120
+ const next = cur[k];
121
+ if (next === null || typeof next !== 'object' || Array.isArray(next))
122
+ return;
123
+ chain.push({ container: cur, key: k });
124
+ cur = next;
125
+ }
126
+ delete cur[parts[parts.length - 1]];
127
+ // Prune empty parent objects we walked through.
128
+ for (let i = chain.length - 1; i >= 0; i--) {
129
+ const { container, key } = chain[i];
130
+ const child = container[key];
131
+ if (Object.keys(child).length === 0)
132
+ delete container[key];
133
+ else
134
+ break;
135
+ }
136
+ }
137
+ //# sourceMappingURL=json-managed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-managed.js","sourceRoot":"","sources":["../../../src/cli/install/json-managed.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ This project uses OpenLore for persistent architectural memory.
2
+
3
+ ALWAYS call `orient()` (via the openlore MCP server, or `npx openlore orient --json`)
4
+ before reading source files when starting a new task. This returns the relevant
5
+ functions, callers, spec sections, and insertion points for the task at hand and
6
+ saves you 15,000–50,000 tokens of file-by-file rediscovery.
7
+
8
+ Re-orient whenever the Epistemic Lease indicates staleness (you'll see a prefix
9
+ on tool responses telling you to do so).
10
+
11
+ For the MCP setup, ensure `openlore mcp` is configured as an MCP server.
12
+ See https://github.com/clay-good/OpenLore for details.
@@ -0,0 +1,7 @@
1
+ ---
2
+ description: OpenLore orient() workflow
3
+ alwaysApply: true
4
+ openlore-fingerprint: {{fingerprint}}
5
+ ---
6
+
7
+ {{instructions}}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Compute the set of source files that have changed since the graph was built.
3
+ *
4
+ * Two paths:
5
+ *
6
+ * 1. `--since <git-ref>` (CI-friendly) — `git diff --name-only <ref>...HEAD`
7
+ * plus uncommitted modifications. The merge-base form is intentional:
8
+ * it captures every file the PR touched, not just the latest commit.
9
+ *
10
+ * 2. No `--since` flag — fall back to comparing file mtimes against
11
+ * `fingerprint.json.computedAt`. Slower but works without git history.
12
+ *
13
+ * Either path returns paths relative to the repo root. Non-source files
14
+ * (anything not tracked by the analyzer's language config) are filtered out
15
+ * by the caller via the node table.
16
+ */
17
+ export interface DiffResult {
18
+ /** Repo-relative paths of files that may have changed since graph build. */
19
+ changed: string[];
20
+ /** Which mechanism produced the list. */
21
+ mechanism: 'git' | 'mtime';
22
+ /** Any non-fatal warnings (e.g. "no .git found, used mtime"). */
23
+ warnings: string[];
24
+ /** The short commit hash of HEAD at the moment of the check, if available. */
25
+ workingCommit: string | null;
26
+ }
27
+ export interface DiffOptions {
28
+ repoRoot: string;
29
+ /** Iso8601 timestamp the graph was built — used by mtime fallback. */
30
+ graphBuiltAt: string | null;
31
+ /** Optional git ref to diff against (e.g. "origin/main"). */
32
+ since?: string;
33
+ }
34
+ export declare function hasGitDirectory(repoRoot: string): Promise<boolean>;
35
+ export declare function refExists(repoRoot: string, ref: string): Promise<boolean>;
36
+ export declare function computeDiff(opts: DiffOptions): Promise<DiffResult>;
37
+ /** Read `fingerprint.json` if present. */
38
+ export declare function readGraphFingerprint(repoRoot: string): Promise<{
39
+ computedAt: string | null;
40
+ fileCount: number | null;
41
+ } | null>;
42
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../../src/cli/preflight/diff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAUH,MAAM,WAAW,UAAU;IACzB,4EAA4E;IAC5E,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,yCAAyC;IACzC,SAAS,EAAE,KAAK,GAAG,OAAO,CAAC;IAC3B,iEAAiE;IACjE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,8EAA8E;IAC9E,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOxE;AAOD,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/E;AAsED,wBAAsB,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAwCxE;AAED,0CAA0C;AAC1C,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IACpE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,GAAG,IAAI,CAAC,CAYR"}