openlore 2.0.1 → 2.0.3

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 (137) hide show
  1. package/README.md +57 -0
  2. package/dist/cli/commands/mcp.d.ts.map +1 -1
  3. package/dist/cli/commands/mcp.js +18 -1
  4. package/dist/cli/commands/mcp.js.map +1 -1
  5. package/dist/cli/export/index.d.ts +10 -0
  6. package/dist/cli/export/index.d.ts.map +1 -0
  7. package/dist/cli/export/index.js +27 -0
  8. package/dist/cli/export/index.js.map +1 -0
  9. package/dist/cli/export/scip.d.ts +22 -0
  10. package/dist/cli/export/scip.d.ts.map +1 -0
  11. package/dist/cli/export/scip.js +95 -0
  12. package/dist/cli/export/scip.js.map +1 -0
  13. package/dist/cli/index.js +19 -9
  14. package/dist/cli/index.js.map +1 -1
  15. package/dist/cli/install/adapters/agents-md.d.ts +8 -0
  16. package/dist/cli/install/adapters/agents-md.d.ts.map +1 -0
  17. package/dist/cli/install/adapters/agents-md.js +21 -0
  18. package/dist/cli/install/adapters/agents-md.js.map +1 -0
  19. package/dist/cli/install/adapters/claude-code.d.ts +8 -0
  20. package/dist/cli/install/adapters/claude-code.d.ts.map +1 -0
  21. package/dist/cli/install/adapters/claude-code.js +184 -0
  22. package/dist/cli/install/adapters/claude-code.js.map +1 -0
  23. package/dist/cli/install/adapters/cline.d.ts +6 -0
  24. package/dist/cli/install/adapters/cline.d.ts.map +1 -0
  25. package/dist/cli/install/adapters/cline.js +19 -0
  26. package/dist/cli/install/adapters/cline.js.map +1 -0
  27. package/dist/cli/install/adapters/continue.d.ts +13 -0
  28. package/dist/cli/install/adapters/continue.d.ts.map +1 -0
  29. package/dist/cli/install/adapters/continue.js +119 -0
  30. package/dist/cli/install/adapters/continue.js.map +1 -0
  31. package/dist/cli/install/adapters/cursor.d.ts +8 -0
  32. package/dist/cli/install/adapters/cursor.d.ts.map +1 -0
  33. package/dist/cli/install/adapters/cursor.js +195 -0
  34. package/dist/cli/install/adapters/cursor.js.map +1 -0
  35. package/dist/cli/install/adapters/markdown-block.d.ts +20 -0
  36. package/dist/cli/install/adapters/markdown-block.d.ts.map +1 -0
  37. package/dist/cli/install/adapters/markdown-block.js +114 -0
  38. package/dist/cli/install/adapters/markdown-block.js.map +1 -0
  39. package/dist/cli/install/adapters/types.d.ts +39 -0
  40. package/dist/cli/install/adapters/types.d.ts.map +1 -0
  41. package/dist/cli/install/adapters/types.js +10 -0
  42. package/dist/cli/install/adapters/types.js.map +1 -0
  43. package/dist/cli/install/block.d.ts +53 -0
  44. package/dist/cli/install/block.d.ts.map +1 -0
  45. package/dist/cli/install/block.js +106 -0
  46. package/dist/cli/install/block.js.map +1 -0
  47. package/dist/cli/install/detect.d.ts +23 -0
  48. package/dist/cli/install/detect.d.ts.map +1 -0
  49. package/dist/cli/install/detect.js +115 -0
  50. package/dist/cli/install/detect.js.map +1 -0
  51. package/dist/cli/install/diff.d.ts +12 -0
  52. package/dist/cli/install/diff.d.ts.map +1 -0
  53. package/dist/cli/install/diff.js +51 -0
  54. package/dist/cli/install/diff.js.map +1 -0
  55. package/dist/cli/install/index.d.ts +19 -0
  56. package/dist/cli/install/index.d.ts.map +1 -0
  57. package/dist/cli/install/index.js +133 -0
  58. package/dist/cli/install/index.js.map +1 -0
  59. package/dist/cli/install/json-managed.d.ts +43 -0
  60. package/dist/cli/install/json-managed.d.ts.map +1 -0
  61. package/dist/cli/install/json-managed.js +137 -0
  62. package/dist/cli/install/json-managed.js.map +1 -0
  63. package/dist/cli/install/templates/agent-instructions.md +12 -0
  64. package/dist/cli/install/templates/cursor-openlore.mdc +7 -0
  65. package/dist/cli/manifest/detect/events.d.ts +31 -0
  66. package/dist/cli/manifest/detect/events.d.ts.map +1 -0
  67. package/dist/cli/manifest/detect/events.js +22 -0
  68. package/dist/cli/manifest/detect/events.js.map +1 -0
  69. package/dist/cli/manifest/detect/http-routes.d.ts +22 -0
  70. package/dist/cli/manifest/detect/http-routes.d.ts.map +1 -0
  71. package/dist/cli/manifest/detect/http-routes.js +18 -0
  72. package/dist/cli/manifest/detect/http-routes.js.map +1 -0
  73. package/dist/cli/manifest/detect/public-symbols.d.ts +46 -0
  74. package/dist/cli/manifest/detect/public-symbols.d.ts.map +1 -0
  75. package/dist/cli/manifest/detect/public-symbols.js +144 -0
  76. package/dist/cli/manifest/detect/public-symbols.js.map +1 -0
  77. package/dist/cli/manifest/emit.d.ts +103 -0
  78. package/dist/cli/manifest/emit.d.ts.map +1 -0
  79. package/dist/cli/manifest/emit.js +272 -0
  80. package/dist/cli/manifest/emit.js.map +1 -0
  81. package/dist/cli/manifest/index.d.ts +11 -0
  82. package/dist/cli/manifest/index.d.ts.map +1 -0
  83. package/dist/cli/manifest/index.js +31 -0
  84. package/dist/cli/manifest/index.js.map +1 -0
  85. package/dist/cli/manifest/schema-validator.d.ts +18 -0
  86. package/dist/cli/manifest/schema-validator.d.ts.map +1 -0
  87. package/dist/cli/manifest/schema-validator.js +77 -0
  88. package/dist/cli/manifest/schema-validator.js.map +1 -0
  89. package/dist/cli/manifest/validate.d.ts +15 -0
  90. package/dist/cli/manifest/validate.d.ts.map +1 -0
  91. package/dist/cli/manifest/validate.js +51 -0
  92. package/dist/cli/manifest/validate.js.map +1 -0
  93. package/dist/cli/preflight/diff.d.ts +42 -0
  94. package/dist/cli/preflight/diff.d.ts.map +1 -0
  95. package/dist/cli/preflight/diff.js +162 -0
  96. package/dist/cli/preflight/diff.js.map +1 -0
  97. package/dist/cli/preflight/index.d.ts +31 -0
  98. package/dist/cli/preflight/index.d.ts.map +1 -0
  99. package/dist/cli/preflight/index.js +126 -0
  100. package/dist/cli/preflight/index.js.map +1 -0
  101. package/dist/cli/preflight/report.d.ts +50 -0
  102. package/dist/cli/preflight/report.d.ts.map +1 -0
  103. package/dist/cli/preflight/report.js +174 -0
  104. package/dist/cli/preflight/report.js.map +1 -0
  105. package/dist/cli/preflight/score.d.ts +43 -0
  106. package/dist/cli/preflight/score.d.ts.map +1 -0
  107. package/dist/cli/preflight/score.js +102 -0
  108. package/dist/cli/preflight/score.js.map +1 -0
  109. package/dist/core/analyzer/file-walker.d.ts.map +1 -1
  110. package/dist/core/analyzer/file-walker.js +20 -13
  111. package/dist/core/analyzer/file-walker.js.map +1 -1
  112. package/dist/core/analyzer/vector-index.d.ts +2 -0
  113. package/dist/core/analyzer/vector-index.d.ts.map +1 -1
  114. package/dist/core/analyzer/vector-index.js +30 -20
  115. package/dist/core/analyzer/vector-index.js.map +1 -1
  116. package/dist/core/scip/index.d.ts +51 -0
  117. package/dist/core/scip/index.d.ts.map +1 -0
  118. package/dist/core/scip/index.js +210 -0
  119. package/dist/core/scip/index.js.map +1 -0
  120. package/dist/core/scip/moniker.d.ts +48 -0
  121. package/dist/core/scip/moniker.d.ts.map +1 -0
  122. package/dist/core/scip/moniker.js +109 -0
  123. package/dist/core/scip/moniker.js.map +1 -0
  124. package/dist/core/scip/schema.d.ts +34 -0
  125. package/dist/core/scip/schema.d.ts.map +1 -0
  126. package/dist/core/scip/schema.js +48 -0
  127. package/dist/core/scip/schema.js.map +1 -0
  128. package/dist/core/scip/vendor/scip.proto +910 -0
  129. package/dist/core/services/mcp-handlers/utils.d.ts +2 -0
  130. package/dist/core/services/mcp-handlers/utils.d.ts.map +1 -1
  131. package/dist/core/services/mcp-handlers/utils.js +18 -2
  132. package/dist/core/services/mcp-handlers/utils.js.map +1 -1
  133. package/examples/ci/openlore-preflight.gitlab.yml +16 -0
  134. package/examples/ci/openlore-preflight.sh +16 -0
  135. package/examples/ci/openlore-preflight.yml +30 -0
  136. package/package.json +6 -2
  137. package/schemas/openlore-manifest-v1.json +191 -0
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Shared helper for adapters that append/update a managed markdown block in
3
+ * a single file at the project root (CLAUDE.md, AGENTS.md, .cursorrules,
4
+ * .clinerules). Centralises the read/upsert/write logic so each adapter is
5
+ * just a one-liner.
6
+ */
7
+ import { readFile, writeFile, unlink } from 'node:fs/promises';
8
+ import { join } from 'node:path';
9
+ import { upsertBlock, extractBlock, isHandEdited, removeBlock, renderBlock, } from '../block.js';
10
+ import { previewCreate, previewDiff } from '../diff.js';
11
+ export async function applyMarkdownBlock(ctx, opts) {
12
+ const filePath = join(ctx.root, opts.fileName);
13
+ const warnings = [];
14
+ let existing = null;
15
+ try {
16
+ existing = await readFile(filePath, 'utf8');
17
+ }
18
+ catch {
19
+ existing = null;
20
+ }
21
+ if (existing === null && !opts.createIfMissing) {
22
+ return { changes: [], warnings, conflict: false };
23
+ }
24
+ const base = existing ?? '';
25
+ const block = existing ? extractBlock(existing) : null;
26
+ const handEdited = block ? isHandEdited(block) : false;
27
+ if (handEdited && !ctx.force) {
28
+ return {
29
+ changes: [
30
+ {
31
+ path: filePath,
32
+ kind: 'noop',
33
+ summary: `${opts.fileName}: refused to overwrite hand-edited OpenLore block (use --force)`,
34
+ },
35
+ ],
36
+ warnings: [`${opts.fileName} has hand-edits inside the OpenLore block — pass --force to overwrite`],
37
+ conflict: true,
38
+ };
39
+ }
40
+ let next;
41
+ let action;
42
+ if (handEdited && ctx.force && block) {
43
+ // Force-overwrite a tampered block regardless of fingerprint match.
44
+ const rendered = renderBlock(opts.blockBody);
45
+ next = base.slice(0, block.beginIndex) + rendered + base.slice(block.endIndex);
46
+ action = 'updated';
47
+ }
48
+ else {
49
+ ({ next, action } = upsertBlock(base, opts.blockBody));
50
+ }
51
+ const change = {
52
+ path: filePath,
53
+ kind: existing === null
54
+ ? 'create'
55
+ : action === 'noop'
56
+ ? 'noop'
57
+ : 'update',
58
+ summary: existing === null
59
+ ? `create ${opts.fileName} with OpenLore block`
60
+ : action === 'noop'
61
+ ? `${opts.fileName}: already up to date`
62
+ : `update OpenLore block in ${opts.fileName}`,
63
+ preview: existing === null
64
+ ? previewCreate(filePath, next)
65
+ : action === 'noop'
66
+ ? undefined
67
+ : previewDiff(filePath, base, next),
68
+ };
69
+ if (!ctx.dryRun && action !== 'noop') {
70
+ await writeFile(filePath, next, 'utf8');
71
+ }
72
+ return { changes: [change], warnings, conflict: false };
73
+ }
74
+ export async function uninstallMarkdownBlock(ctx, fileName,
75
+ /** If true, delete the file when removing the block empties it. */
76
+ deleteIfBlockOnly) {
77
+ const filePath = join(ctx.root, fileName);
78
+ let existing;
79
+ try {
80
+ existing = await readFile(filePath, 'utf8');
81
+ }
82
+ catch {
83
+ return { changes: [], warnings: [], conflict: false };
84
+ }
85
+ const removed = removeBlock(existing);
86
+ if (removed === null)
87
+ return { changes: [], warnings: [], conflict: false };
88
+ // Trim whitespace-only artifacts to decide if the file is now "empty".
89
+ const stripped = removed.trim();
90
+ if (stripped.length === 0 && deleteIfBlockOnly) {
91
+ if (!ctx.dryRun)
92
+ await unlink(filePath);
93
+ return {
94
+ changes: [{ path: filePath, kind: 'delete', summary: `remove ${fileName} (was OpenLore-only)` }],
95
+ warnings: [],
96
+ conflict: false,
97
+ };
98
+ }
99
+ if (!ctx.dryRun)
100
+ await writeFile(filePath, removed, 'utf8');
101
+ return {
102
+ changes: [
103
+ {
104
+ path: filePath,
105
+ kind: 'update',
106
+ summary: `strip OpenLore block from ${fileName}`,
107
+ preview: previewDiff(filePath, existing, removed),
108
+ },
109
+ ],
110
+ warnings: [],
111
+ conflict: false,
112
+ };
113
+ }
114
+ //# sourceMappingURL=markdown-block.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-block.js","sourceRoot":"","sources":["../../../../src/cli/install/adapters/markdown-block.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Shared types for OpenLore install adapters.
3
+ *
4
+ * An adapter knows how to plan, apply, and uninstall OpenLore's footprint on
5
+ * one specific agent surface. Adapters never write to disk directly when
6
+ * `dryRun` is true; instead they return a list of `PlannedChange` entries that
7
+ * the caller renders.
8
+ */
9
+ import type { AgentName } from '../detect.js';
10
+ export interface PlannedChange {
11
+ /** Absolute path the change applies to. */
12
+ path: string;
13
+ /** What we'd do to that file. */
14
+ kind: 'create' | 'update' | 'noop' | 'delete';
15
+ /** Short human-readable summary (one line). */
16
+ summary: string;
17
+ /** Optional unified-diff-ish preview for `--dry-run`. */
18
+ preview?: string;
19
+ }
20
+ export interface ApplyContext {
21
+ root: string;
22
+ /** Template content for the markdown instruction block. */
23
+ instructionTemplate: string;
24
+ dryRun: boolean;
25
+ force: boolean;
26
+ }
27
+ export interface ApplyResult {
28
+ changes: PlannedChange[];
29
+ /** Warnings to surface to the user (e.g. hand-edited block, unsure-of-path TODO). */
30
+ warnings: string[];
31
+ /** If true, install should exit non-zero (hand-edit conflict without --force). */
32
+ conflict: boolean;
33
+ }
34
+ export interface Adapter {
35
+ name: AgentName;
36
+ apply(ctx: ApplyContext): Promise<ApplyResult>;
37
+ uninstall(ctx: ApplyContext): Promise<ApplyResult>;
38
+ }
39
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/cli/install/adapters/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,WAAW,aAAa;IAC5B,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;IAC9C,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,mBAAmB,EAAE,MAAM,CAAC;IAC5B,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,qFAAqF;IACrF,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,kFAAkF;IAClF,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/C,SAAS,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CACpD"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Shared types for OpenLore install adapters.
3
+ *
4
+ * An adapter knows how to plan, apply, and uninstall OpenLore's footprint on
5
+ * one specific agent surface. Adapters never write to disk directly when
6
+ * `dryRun` is true; instead they return a list of `PlannedChange` entries that
7
+ * the caller renders.
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/cli/install/adapters/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * OpenLore managed-block utilities.
3
+ *
4
+ * A "managed block" is a region inside an existing text file (typically Markdown)
5
+ * delimited by canonical comments. Re-running `openlore install` rewrites the
6
+ * block in place. A SHA-256 fingerprint over the canonical content lets us
7
+ * detect hand-edits and refuse to clobber them unless `--force` is passed.
8
+ */
9
+ export declare const BLOCK_BEGIN = "<!-- BEGIN OPENLORE (managed \u2014 edits inside this block will be overwritten) -->";
10
+ export declare const BLOCK_END = "<!-- END OPENLORE -->";
11
+ export interface ExtractedBlock {
12
+ /** Index of the BEGIN marker in the source file. */
13
+ beginIndex: number;
14
+ /** Index just past the END marker. */
15
+ endIndex: number;
16
+ /** The raw text between BEGIN and END markers (excluding markers themselves). */
17
+ inner: string;
18
+ /** The fingerprint we previously wrote, if present. */
19
+ fingerprint: string | null;
20
+ }
21
+ export declare function fingerprint(content: string): string;
22
+ /** Build the full managed block (markers + fingerprint comment + content). */
23
+ export declare function renderBlock(content: string): string;
24
+ export declare function extractBlock(source: string): ExtractedBlock | null;
25
+ /**
26
+ * Compute the fingerprint of the *current* inner content as it would be if we
27
+ * had written `expectedContent`. Used to decide whether the block on disk
28
+ * still matches what we last wrote.
29
+ */
30
+ export declare function blockMatchesExpected(block: ExtractedBlock, expectedContent: string): boolean;
31
+ export interface UpsertResult {
32
+ /** The file contents to write back. */
33
+ next: string;
34
+ /** What happened: 'created' (file/block was new), 'updated' (re-rendered), 'noop' (already matched). */
35
+ action: 'created' | 'updated' | 'noop';
36
+ }
37
+ /**
38
+ * Upsert the managed block in `existing`. If a block exists, replace it; otherwise
39
+ * append. If the existing block's fingerprint matches the new content, do nothing.
40
+ *
41
+ * Caller is responsible for the `--force` / hand-edit check (use `isHandEdited`).
42
+ */
43
+ export declare function upsertBlock(existing: string, content: string): UpsertResult;
44
+ /**
45
+ * True iff a block exists on disk and its inner contents no longer hash to its
46
+ * fingerprint (i.e. someone edited inside the markers).
47
+ */
48
+ export declare function isHandEdited(block: ExtractedBlock): boolean;
49
+ /**
50
+ * Remove the managed block from `existing`. Returns null if no block was present.
51
+ */
52
+ export declare function removeBlock(existing: string): string | null;
53
+ //# sourceMappingURL=block.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block.d.ts","sourceRoot":"","sources":["../../../src/cli/install/block.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,eAAO,MAAM,WAAW,yFAC2D,CAAC;AACpF,eAAO,MAAM,SAAS,0BAA0B,CAAC;AAKjD,MAAM,WAAW,cAAc;IAC7B,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CASnD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAgBlE;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAG5F;AAED,MAAM,WAAW,YAAY;IAC3B,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,wGAAwG;IACxG,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;CACxC;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,YAAY,CAiB3E;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAO3D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS3D"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * OpenLore managed-block utilities.
3
+ *
4
+ * A "managed block" is a region inside an existing text file (typically Markdown)
5
+ * delimited by canonical comments. Re-running `openlore install` rewrites the
6
+ * block in place. A SHA-256 fingerprint over the canonical content lets us
7
+ * detect hand-edits and refuse to clobber them unless `--force` is passed.
8
+ */
9
+ import { createHash } from 'node:crypto';
10
+ export const BLOCK_BEGIN = '<!-- BEGIN OPENLORE (managed — edits inside this block will be overwritten) -->';
11
+ export const BLOCK_END = '<!-- END OPENLORE -->';
12
+ const FINGERPRINT_PREFIX = '<!-- openlore-fingerprint: ';
13
+ const FINGERPRINT_SUFFIX = ' -->';
14
+ export function fingerprint(content) {
15
+ return createHash('sha256').update(content, 'utf8').digest('hex').slice(0, 16);
16
+ }
17
+ /** Build the full managed block (markers + fingerprint comment + content). */
18
+ export function renderBlock(content) {
19
+ const trimmed = content.trimEnd();
20
+ const fp = fingerprint(trimmed);
21
+ return [
22
+ BLOCK_BEGIN,
23
+ `${FINGERPRINT_PREFIX}${fp}${FINGERPRINT_SUFFIX}`,
24
+ trimmed,
25
+ BLOCK_END,
26
+ ].join('\n');
27
+ }
28
+ export function extractBlock(source) {
29
+ const beginIndex = source.indexOf(BLOCK_BEGIN);
30
+ if (beginIndex === -1)
31
+ return null;
32
+ const endMarkerIndex = source.indexOf(BLOCK_END, beginIndex + BLOCK_BEGIN.length);
33
+ if (endMarkerIndex === -1)
34
+ return null;
35
+ const endIndex = endMarkerIndex + BLOCK_END.length;
36
+ const inner = source.slice(beginIndex + BLOCK_BEGIN.length, endMarkerIndex);
37
+ const fpMatch = inner.match(/<!-- openlore-fingerprint: ([0-9a-f]+) -->/);
38
+ return {
39
+ beginIndex,
40
+ endIndex,
41
+ inner,
42
+ fingerprint: fpMatch ? fpMatch[1] : null,
43
+ };
44
+ }
45
+ /**
46
+ * Compute the fingerprint of the *current* inner content as it would be if we
47
+ * had written `expectedContent`. Used to decide whether the block on disk
48
+ * still matches what we last wrote.
49
+ */
50
+ export function blockMatchesExpected(block, expectedContent) {
51
+ if (!block.fingerprint)
52
+ return false;
53
+ return block.fingerprint === fingerprint(expectedContent.trimEnd());
54
+ }
55
+ /**
56
+ * Upsert the managed block in `existing`. If a block exists, replace it; otherwise
57
+ * append. If the existing block's fingerprint matches the new content, do nothing.
58
+ *
59
+ * Caller is responsible for the `--force` / hand-edit check (use `isHandEdited`).
60
+ */
61
+ export function upsertBlock(existing, content) {
62
+ const rendered = renderBlock(content);
63
+ const block = extractBlock(existing);
64
+ if (!block) {
65
+ const sep = existing.length === 0 || existing.endsWith('\n') ? '' : '\n';
66
+ const leading = existing.length === 0 ? '' : '\n';
67
+ return { next: `${existing}${sep}${leading}${rendered}\n`, action: 'created' };
68
+ }
69
+ if (blockMatchesExpected(block, content)) {
70
+ return { next: existing, action: 'noop' };
71
+ }
72
+ const before = existing.slice(0, block.beginIndex);
73
+ const after = existing.slice(block.endIndex);
74
+ return { next: `${before}${rendered}${after}`, action: 'updated' };
75
+ }
76
+ /**
77
+ * True iff a block exists on disk and its inner contents no longer hash to its
78
+ * fingerprint (i.e. someone edited inside the markers).
79
+ */
80
+ export function isHandEdited(block) {
81
+ if (!block.fingerprint)
82
+ return false;
83
+ const innerWithoutFingerprintLine = block.inner
84
+ .replace(/<!-- openlore-fingerprint: [0-9a-f]+ -->\n?/, '')
85
+ .replace(/^\n+/, '')
86
+ .trimEnd();
87
+ return fingerprint(innerWithoutFingerprintLine) !== block.fingerprint;
88
+ }
89
+ /**
90
+ * Remove the managed block from `existing`. Returns null if no block was present.
91
+ */
92
+ export function removeBlock(existing) {
93
+ const block = extractBlock(existing);
94
+ if (!block)
95
+ return null;
96
+ const before = existing.slice(0, block.beginIndex).replace(/\n+$/, '');
97
+ const after = existing.slice(block.endIndex).replace(/^\n+/, '');
98
+ if (before.length === 0 && after.length === 0)
99
+ return '';
100
+ if (before.length === 0)
101
+ return after.endsWith('\n') ? after : after + '\n';
102
+ if (after.length === 0)
103
+ return before + '\n';
104
+ return `${before}\n\n${after}`;
105
+ }
106
+ //# sourceMappingURL=block.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block.js","sourceRoot":"","sources":["../../../src/cli/install/block.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
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
+ export type AgentName = 'claude-code' | 'cursor' | 'cline' | 'continue' | 'agents-md';
9
+ export declare const ALL_AGENTS: AgentName[];
10
+ export interface DetectedSurface {
11
+ agent: AgentName;
12
+ /** Absolute path to the directory we will treat as the project root. */
13
+ root: string;
14
+ /** Which marker(s) triggered detection (for the dry-run summary). */
15
+ markers: string[];
16
+ }
17
+ /**
18
+ * Detect surfaces by walking up from `startDir` up to PARENTS_TO_CHECK levels.
19
+ * Each surface is reported at most once, anchored at the deepest dir where its
20
+ * marker was found. `agents-md` is always appended last as a universal fallback.
21
+ */
22
+ export declare function detect(startDir: string): Promise<DetectedSurface[]>;
23
+ //# sourceMappingURL=detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../../src/cli/install/detect.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,QAAQ,GAAG,OAAO,GAAG,UAAU,GAAG,WAAW,CAAC;AAEtF,eAAO,MAAM,UAAU,EAAE,SAAS,EAMjC,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,SAAS,CAAC;IACjB,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAqED;;;;GAIG;AACH,wBAAsB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAkBzE"}
@@ -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"}