busy-cli 0.1.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 (128) hide show
  1. package/README.md +129 -0
  2. package/dist/builders/context.d.ts +50 -0
  3. package/dist/builders/context.d.ts.map +1 -0
  4. package/dist/builders/context.js +190 -0
  5. package/dist/cache/index.d.ts +100 -0
  6. package/dist/cache/index.d.ts.map +1 -0
  7. package/dist/cache/index.js +270 -0
  8. package/dist/cli/index.d.ts +3 -0
  9. package/dist/cli/index.d.ts.map +1 -0
  10. package/dist/cli/index.js +463 -0
  11. package/dist/commands/package.d.ts +96 -0
  12. package/dist/commands/package.d.ts.map +1 -0
  13. package/dist/commands/package.js +285 -0
  14. package/dist/index.d.ts +7 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +7 -0
  17. package/dist/loader.d.ts +6 -0
  18. package/dist/loader.d.ts.map +1 -0
  19. package/dist/loader.js +361 -0
  20. package/dist/merge.d.ts +16 -0
  21. package/dist/merge.d.ts.map +1 -0
  22. package/dist/merge.js +102 -0
  23. package/dist/package/manifest.d.ts +59 -0
  24. package/dist/package/manifest.d.ts.map +1 -0
  25. package/dist/package/manifest.js +265 -0
  26. package/dist/parser.d.ts +28 -0
  27. package/dist/parser.d.ts.map +1 -0
  28. package/dist/parser.js +220 -0
  29. package/dist/parsers/frontmatter.d.ts +14 -0
  30. package/dist/parsers/frontmatter.d.ts.map +1 -0
  31. package/dist/parsers/frontmatter.js +110 -0
  32. package/dist/parsers/imports.d.ts +48 -0
  33. package/dist/parsers/imports.d.ts.map +1 -0
  34. package/dist/parsers/imports.js +147 -0
  35. package/dist/parsers/links.d.ts +12 -0
  36. package/dist/parsers/links.d.ts.map +1 -0
  37. package/dist/parsers/links.js +79 -0
  38. package/dist/parsers/localdefs.d.ts +6 -0
  39. package/dist/parsers/localdefs.d.ts.map +1 -0
  40. package/dist/parsers/localdefs.js +132 -0
  41. package/dist/parsers/operations.d.ts +32 -0
  42. package/dist/parsers/operations.d.ts.map +1 -0
  43. package/dist/parsers/operations.js +313 -0
  44. package/dist/parsers/sections.d.ts +15 -0
  45. package/dist/parsers/sections.d.ts.map +1 -0
  46. package/dist/parsers/sections.js +173 -0
  47. package/dist/parsers/tools.d.ts +30 -0
  48. package/dist/parsers/tools.d.ts.map +1 -0
  49. package/dist/parsers/tools.js +178 -0
  50. package/dist/parsers/triggers.d.ts +35 -0
  51. package/dist/parsers/triggers.d.ts.map +1 -0
  52. package/dist/parsers/triggers.js +219 -0
  53. package/dist/providers/base.d.ts +60 -0
  54. package/dist/providers/base.d.ts.map +1 -0
  55. package/dist/providers/base.js +34 -0
  56. package/dist/providers/github.d.ts +18 -0
  57. package/dist/providers/github.d.ts.map +1 -0
  58. package/dist/providers/github.js +109 -0
  59. package/dist/providers/gitlab.d.ts +18 -0
  60. package/dist/providers/gitlab.d.ts.map +1 -0
  61. package/dist/providers/gitlab.js +101 -0
  62. package/dist/providers/index.d.ts +13 -0
  63. package/dist/providers/index.d.ts.map +1 -0
  64. package/dist/providers/index.js +17 -0
  65. package/dist/providers/local.d.ts +31 -0
  66. package/dist/providers/local.d.ts.map +1 -0
  67. package/dist/providers/local.js +116 -0
  68. package/dist/providers/url.d.ts +16 -0
  69. package/dist/providers/url.d.ts.map +1 -0
  70. package/dist/providers/url.js +45 -0
  71. package/dist/registry/index.d.ts +99 -0
  72. package/dist/registry/index.d.ts.map +1 -0
  73. package/dist/registry/index.js +320 -0
  74. package/dist/types/schema.d.ts +3259 -0
  75. package/dist/types/schema.d.ts.map +1 -0
  76. package/dist/types/schema.js +258 -0
  77. package/dist/utils/logger.d.ts +19 -0
  78. package/dist/utils/logger.d.ts.map +1 -0
  79. package/dist/utils/logger.js +23 -0
  80. package/dist/utils/slugify.d.ts +14 -0
  81. package/dist/utils/slugify.d.ts.map +1 -0
  82. package/dist/utils/slugify.js +28 -0
  83. package/package.json +61 -0
  84. package/src/__tests__/cache.test.ts +393 -0
  85. package/src/__tests__/cli-package.test.ts +667 -0
  86. package/src/__tests__/fixtures/automated-workflow.busy.md +84 -0
  87. package/src/__tests__/fixtures/concept.busy.md +30 -0
  88. package/src/__tests__/fixtures/document.busy.md +44 -0
  89. package/src/__tests__/fixtures/simple-operation.busy.md +45 -0
  90. package/src/__tests__/fixtures/tool-document.busy.md +71 -0
  91. package/src/__tests__/fixtures/tool.busy.md +54 -0
  92. package/src/__tests__/imports.test.ts +244 -0
  93. package/src/__tests__/integration.test.ts +432 -0
  94. package/src/__tests__/operations.test.ts +408 -0
  95. package/src/__tests__/package-manifest.test.ts +455 -0
  96. package/src/__tests__/providers.test.ts +672 -0
  97. package/src/__tests__/registry.test.ts +402 -0
  98. package/src/__tests__/schema.test.ts +467 -0
  99. package/src/__tests__/tools.test.ts +376 -0
  100. package/src/__tests__/triggers.test.ts +312 -0
  101. package/src/builders/context.ts +294 -0
  102. package/src/cache/index.ts +312 -0
  103. package/src/cli/index.ts +514 -0
  104. package/src/commands/package.ts +392 -0
  105. package/src/index.ts +46 -0
  106. package/src/loader.ts +474 -0
  107. package/src/merge.ts +126 -0
  108. package/src/package/manifest.ts +349 -0
  109. package/src/parser.ts +278 -0
  110. package/src/parsers/frontmatter.ts +135 -0
  111. package/src/parsers/imports.ts +196 -0
  112. package/src/parsers/links.ts +108 -0
  113. package/src/parsers/localdefs.ts +166 -0
  114. package/src/parsers/operations.ts +404 -0
  115. package/src/parsers/sections.ts +230 -0
  116. package/src/parsers/tools.ts +215 -0
  117. package/src/parsers/triggers.ts +252 -0
  118. package/src/providers/base.ts +77 -0
  119. package/src/providers/github.ts +129 -0
  120. package/src/providers/gitlab.ts +121 -0
  121. package/src/providers/index.ts +25 -0
  122. package/src/providers/local.ts +129 -0
  123. package/src/providers/url.ts +56 -0
  124. package/src/registry/index.ts +408 -0
  125. package/src/types/schema.ts +369 -0
  126. package/src/utils/logger.ts +25 -0
  127. package/src/utils/slugify.ts +31 -0
  128. package/tsconfig.json +21 -0
package/README.md ADDED
@@ -0,0 +1,129 @@
1
+ # @busy/parser
2
+
3
+ TypeScript library + CLI that parses Busy markdown workspaces into a typed graph.
4
+
5
+ ## Features
6
+
7
+ - ✅ Parse Busy markdown files with YAML frontmatter
8
+ - ✅ Build hierarchical section trees
9
+ - ✅ Extract Local Definitions with inheritance
10
+ - ✅ Resolve reference-style imports
11
+ - ✅ Create typed edge graph (ref, calls, extends, imports)
12
+ - ✅ Build minimal execution contexts for operations
13
+ - ✅ Export to JSON and DOT graph formats
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @busy/parser
19
+ ```
20
+
21
+ ## CLI Usage
22
+
23
+ ### Load and validate workspace
24
+
25
+ ```bash
26
+ busyctx load "busy-v2/**/*.busy.md" --dump repo.json
27
+ ```
28
+
29
+ ### Build operation context
30
+
31
+ ```bash
32
+ busyctx context "Document#evaluatedocument" -o context.json --maxDefChars 2000
33
+ ```
34
+
35
+ ### Export graph
36
+
37
+ ```bash
38
+ busyctx graph --format dot > repo.dot
39
+ ```
40
+
41
+ ## API Usage
42
+
43
+ ```typescript
44
+ import { loadRepo, buildContext } from '@busy/parser';
45
+
46
+ // Load workspace
47
+ const repo = await loadRepo(['busy-v2/**/*.busy.md']);
48
+
49
+ console.log(`Loaded ${repo.docs.length} documents`);
50
+ console.log(`Found ${Object.keys(repo.localdefs).length} local definitions`);
51
+ console.log(`Created ${repo.edges.length} edges`);
52
+
53
+ // Build execution context for an operation
54
+ const context = buildContext(repo, 'Document#evaluatedocument', {
55
+ maxDefChars: 2000,
56
+ includeChildren: true
57
+ });
58
+
59
+ console.log(`Operation: ${context.operation.title}`);
60
+ console.log(`Definitions: ${context.defs.length}`);
61
+ console.log(`Calls: ${context.calls.length}`);
62
+ ```
63
+
64
+ ## Data Model
65
+
66
+ ### Documents & Sections
67
+
68
+ - **BusyDocument**: Top-level markdown file with frontmatter
69
+ - **Section**: Hierarchical heading structure (`#` - `######`)
70
+ - **LocalDef**: Definitions under "Local Definitions" section
71
+
72
+ ### Edges
73
+
74
+ - **imports**: Document imports another document
75
+ - **calls**: Section/operation calls another operation
76
+ - **extends**: LocalDef extends another definition
77
+ - **ref**: General reference link
78
+
79
+ ### Context Payload
80
+
81
+ Minimal execution context for an operation:
82
+ - Operation section (ref, title, content)
83
+ - Required local definitions (with transitive closure)
84
+ - Callable sub-operations
85
+ - Symbol table for imports
86
+
87
+ ## Frontmatter Support
88
+
89
+ Handles both plain strings and markdown link syntax:
90
+
91
+ ```yaml
92
+ ---
93
+ Name: Document
94
+ Type: [Concept]
95
+ Description: The core document type
96
+ Tags: [core, foundation]
97
+ Extends: [ConceptBase]
98
+ ---
99
+ ```
100
+
101
+ Automatically strips brackets: `[Concept]` → `Concept`
102
+
103
+ ## File Extensions
104
+
105
+ Supports both `.md` and `.busy.md` extensions. Import references to `.md` files automatically resolve to `.busy.md` files.
106
+
107
+ ## Example Output
108
+
109
+ For `busy-v2/**/*.busy.md`:
110
+ - ✓ 15 documents loaded
111
+ - ✓ 45 local definitions
112
+ - ✓ 137 imports resolved
113
+ - ✓ 173 edges created
114
+ - 137 import edges
115
+ - 26 call edges
116
+ - 10 ref edges
117
+
118
+ ## Development
119
+
120
+ ```bash
121
+ npm install
122
+ npm run build
123
+ npm run dev # watch mode
124
+ npm test
125
+ ```
126
+
127
+ ## License
128
+
129
+ ISC
@@ -0,0 +1,50 @@
1
+ import { Repo, ContextPayload, Section, LocalDef, Operation, ConceptBase } from '../types/schema.js';
2
+ export interface BuildOpts {
3
+ includeChildren?: boolean;
4
+ maxDefChars?: number;
5
+ }
6
+ /**
7
+ * Build minimal execution context for an operation
8
+ */
9
+ export declare function buildContext(repo: Repo, opRef: string, opts?: BuildOpts): ContextPayload;
10
+ /**
11
+ * Lookup helpers
12
+ */
13
+ export declare function get(repo: Repo, ref: string): Section | LocalDef | Operation | ConceptBase | undefined;
14
+ export declare function parentsOf(repo: Repo, nameOrRef: string): string[];
15
+ export declare function childrenOf(repo: Repo, nameOrRef: string): string[];
16
+ /**
17
+ * Context for a specific concept
18
+ */
19
+ export interface ConceptContext {
20
+ concept: Section | LocalDef | Operation | ConceptBase;
21
+ calls: string[];
22
+ extends: string[];
23
+ imports: string[];
24
+ refs: string[];
25
+ calledBy: string[];
26
+ extendedBy: string[];
27
+ importedBy: string[];
28
+ referencedBy: string[];
29
+ allEdges: {
30
+ outgoing: Array<{
31
+ to: string;
32
+ role: string;
33
+ }>;
34
+ incoming: Array<{
35
+ from: string;
36
+ role: string;
37
+ }>;
38
+ };
39
+ contentMap: Record<string, string>;
40
+ }
41
+ /**
42
+ * Get comprehensive context for any concept by ID
43
+ * Returns all relationships (calls, extends, imports, refs) both outgoing and incoming
44
+ */
45
+ export declare function getConceptContext(repo: Repo, conceptId: string): ConceptContext;
46
+ /**
47
+ * Write context to JSON file
48
+ */
49
+ export declare function writeContext(file: string, ctx: ContextPayload): Promise<void>;
50
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/builders/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGrG,MAAM,WAAW,SAAS;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,SAAc,GACnB,cAAc,CA2EhB;AA4BD;;GAEG;AACH,wBAAgB,GAAG,CACjB,IAAI,EAAE,IAAI,EACV,GAAG,EAAE,MAAM,GACV,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAE1D;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAKjE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAKlE;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;IAEtD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,EAAE,MAAM,EAAE,CAAC;IAEf,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,YAAY,EAAE,MAAM,EAAE,CAAC;IAEvB,QAAQ,EAAE;QACR,QAAQ,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC9C,QAAQ,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACjD,CAAC;IAEF,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,MAAM,GAChB,cAAc,CA4GhB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,IAAI,CAAC,CAIf"}
@@ -0,0 +1,190 @@
1
+ import { debug } from '../utils/logger.js';
2
+ /**
3
+ * Build minimal execution context for an operation
4
+ */
5
+ export function buildContext(repo, opRef, opts = {}) {
6
+ debug.context('Building context for operation: %s', opRef);
7
+ const { includeChildren = false, maxDefChars } = opts;
8
+ // 1. Seed: resolve opRef to a Section or Operation
9
+ const opNode = repo.byId[opRef];
10
+ if (!opNode || (opNode.kind !== 'section' && opNode.kind !== 'operation')) {
11
+ throw new Error(`Operation not found: ${opRef}`);
12
+ }
13
+ // Get the full Operation object
14
+ let operation;
15
+ if (opNode.kind === 'operation') {
16
+ operation = opNode;
17
+ }
18
+ else {
19
+ // If it's a section, we need to find the operation or throw
20
+ throw new Error(`Expected operation but got section: ${opRef}`);
21
+ }
22
+ // 2. Collect outgoing edges from the operation section
23
+ const edges = repo.edges.filter((edge) => {
24
+ if (edge.from === opNode.id) {
25
+ return true;
26
+ }
27
+ // Optionally include edges from child sections
28
+ if (includeChildren) {
29
+ return edge.from.startsWith(`${opNode.docId}#`);
30
+ }
31
+ return false;
32
+ });
33
+ debug.context('Found %d outgoing edges', edges.length);
34
+ // 3. Calls (just array of concept IDs)
35
+ const calls = [];
36
+ for (const edge of edges) {
37
+ if (edge.role === 'calls') {
38
+ calls.push(edge.to);
39
+ }
40
+ }
41
+ debug.context('Found %d calls', calls.length);
42
+ // 4. Symbols
43
+ // Get the document's import symbol table
44
+ const fileInfo = repo.byFile[opNode.docId];
45
+ const docImports = repo.imports.filter((imp) => imp.docId === opNode.docId);
46
+ const symbols = {};
47
+ for (const imp of docImports) {
48
+ if (imp.resolved) {
49
+ // Parse ConceptId string back to { docId, slug }
50
+ const parts = imp.resolved.split('#');
51
+ symbols[imp.label] = {
52
+ docId: parts[0],
53
+ slug: parts[1],
54
+ };
55
+ }
56
+ }
57
+ const payload = {
58
+ operation,
59
+ calls,
60
+ symbols,
61
+ };
62
+ debug.context('Context built successfully');
63
+ return payload;
64
+ }
65
+ /**
66
+ * Trim content to max characters, preserving structure
67
+ */
68
+ function trimContent(content, maxChars) {
69
+ if (content.length <= maxChars) {
70
+ return content;
71
+ }
72
+ // Try to preserve headings and code fences
73
+ const lines = content.split('\n');
74
+ let result = '';
75
+ let charCount = 0;
76
+ for (const line of lines) {
77
+ if (charCount + line.length > maxChars) {
78
+ result += '\n\n[... trimmed ...]';
79
+ break;
80
+ }
81
+ result += line + '\n';
82
+ charCount += line.length + 1;
83
+ }
84
+ return result.trim();
85
+ }
86
+ /**
87
+ * Lookup helpers
88
+ */
89
+ export function get(repo, ref) {
90
+ return repo.byId[ref];
91
+ }
92
+ export function parentsOf(repo, nameOrRef) {
93
+ const edges = repo.edges.filter((edge) => edge.from === nameOrRef && edge.role === 'extends');
94
+ return edges.map((edge) => edge.to);
95
+ }
96
+ export function childrenOf(repo, nameOrRef) {
97
+ const edges = repo.edges.filter((edge) => edge.to === nameOrRef && edge.role === 'extends');
98
+ return edges.map((edge) => edge.from);
99
+ }
100
+ /**
101
+ * Get comprehensive context for any concept by ID
102
+ * Returns all relationships (calls, extends, imports, refs) both outgoing and incoming
103
+ */
104
+ export function getConceptContext(repo, conceptId) {
105
+ debug.context('Building concept context for: %s', conceptId);
106
+ // 1. Get the concept
107
+ const concept = repo.byId[conceptId];
108
+ if (!concept) {
109
+ throw new Error(`Concept not found: ${conceptId}`);
110
+ }
111
+ // 2. Get all outgoing edges
112
+ // For operations and localdefs, also include edges from their parent section and document
113
+ let edgeSources = [conceptId];
114
+ if (concept.kind === 'operation' || concept.kind === 'localdef') {
115
+ // Add the section
116
+ if ('sectionRef' in concept && concept.sectionRef) {
117
+ edgeSources.push(concept.sectionRef);
118
+ }
119
+ // Add the document
120
+ if ('docId' in concept && concept.docId) {
121
+ edgeSources.push(concept.docId);
122
+ }
123
+ }
124
+ const outgoingEdges = repo.edges.filter((edge) => edgeSources.includes(edge.from));
125
+ // 3. Get all incoming edges
126
+ const incomingEdges = repo.edges.filter((edge) => edge.to === conceptId);
127
+ // 4. Group outgoing edges by role
128
+ const calls = outgoingEdges
129
+ .filter((e) => e.role === 'calls')
130
+ .map((e) => e.to);
131
+ const extendsEdges = outgoingEdges
132
+ .filter((e) => e.role === 'extends')
133
+ .map((e) => e.to);
134
+ const importsEdges = outgoingEdges
135
+ .filter((e) => e.role === 'imports')
136
+ .map((e) => e.to);
137
+ const refs = outgoingEdges
138
+ .filter((e) => e.role === 'ref')
139
+ .map((e) => e.to);
140
+ // 5. Group incoming edges by role
141
+ const calledBy = incomingEdges
142
+ .filter((e) => e.role === 'calls')
143
+ .map((e) => e.from);
144
+ const extendedBy = incomingEdges
145
+ .filter((e) => e.role === 'extends')
146
+ .map((e) => e.from);
147
+ const importedBy = incomingEdges
148
+ .filter((e) => e.role === 'imports')
149
+ .map((e) => e.from);
150
+ const referencedBy = incomingEdges
151
+ .filter((e) => e.role === 'ref')
152
+ .map((e) => e.from);
153
+ debug.context('Found: %d calls, %d extends, %d imports, %d refs (outgoing)', calls.length, extendsEdges.length, importsEdges.length, refs.length);
154
+ debug.context('Found: %d calledBy, %d extendedBy, %d importedBy, %d referencedBy (incoming)', calledBy.length, extendedBy.length, importedBy.length, referencedBy.length);
155
+ // 6. Build content map for imports and refs
156
+ const contentMap = {};
157
+ const contentConceptIds = new Set([...importsEdges, ...refs]);
158
+ for (const id of contentConceptIds) {
159
+ const relatedConcept = repo.byId[id];
160
+ if (relatedConcept && 'content' in relatedConcept) {
161
+ contentMap[id] = relatedConcept.content;
162
+ }
163
+ }
164
+ debug.context('Built content map with %d entries', Object.keys(contentMap).length);
165
+ return {
166
+ concept,
167
+ calls,
168
+ extends: extendsEdges,
169
+ imports: importsEdges,
170
+ refs,
171
+ calledBy,
172
+ extendedBy,
173
+ importedBy,
174
+ referencedBy,
175
+ allEdges: {
176
+ outgoing: outgoingEdges.map((e) => ({ to: e.to, role: e.role })),
177
+ incoming: incomingEdges.map((e) => ({ from: e.from, role: e.role })),
178
+ },
179
+ contentMap,
180
+ };
181
+ }
182
+ /**
183
+ * Write context to JSON file
184
+ */
185
+ export async function writeContext(file, ctx) {
186
+ const { writeFile } = await import('fs/promises');
187
+ await writeFile(file, JSON.stringify(ctx, null, 2), 'utf-8');
188
+ debug.context('Context written to %s', file);
189
+ }
190
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Cache Manager for .libraries/
3
+ *
4
+ * Manages local cache of fetched packages.
5
+ */
6
+ import type { ParsedURL } from '../providers/base.js';
7
+ /**
8
+ * Result of saving a file to cache
9
+ */
10
+ export interface CachedFile {
11
+ path: string;
12
+ fullPath: string;
13
+ integrity: string;
14
+ }
15
+ /**
16
+ * Calculate SHA256 integrity hash of content
17
+ */
18
+ export declare function calculateIntegrity(content: string): string;
19
+ /**
20
+ * Verify content matches integrity hash
21
+ */
22
+ export declare function verifyIntegrity(content: string, integrity: string): boolean;
23
+ /**
24
+ * Derive cache path from parsed URL
25
+ *
26
+ * For GitHub/GitLab: {repo}/{path-from-blob}
27
+ * For generic URLs: {domain}/{path}
28
+ */
29
+ export declare function deriveCachePath(parsed: ParsedURL): string;
30
+ /**
31
+ * Cache Manager
32
+ *
33
+ * Manages the .libraries/ cache directory.
34
+ */
35
+ export declare class CacheManager {
36
+ private _workspaceRoot;
37
+ private _librariesPath;
38
+ constructor(workspaceRoot: string);
39
+ /**
40
+ * Get workspace root path
41
+ */
42
+ get workspaceRoot(): string;
43
+ /**
44
+ * Get .libraries path
45
+ */
46
+ get librariesPath(): string;
47
+ /**
48
+ * Initialize cache directory
49
+ */
50
+ init(): Promise<void>;
51
+ /**
52
+ * Save content to cache
53
+ */
54
+ save(cachePath: string, content: string): Promise<CachedFile>;
55
+ /**
56
+ * Read content from cache
57
+ */
58
+ read(cachePath: string): Promise<string>;
59
+ /**
60
+ * Check if file exists in cache
61
+ */
62
+ exists(cachePath: string): Promise<boolean>;
63
+ /**
64
+ * Delete file from cache
65
+ */
66
+ delete(cachePath: string): Promise<void>;
67
+ /**
68
+ * List all cached files
69
+ */
70
+ list(): Promise<string[]>;
71
+ /**
72
+ * Remove all cached files
73
+ */
74
+ clean(): Promise<number>;
75
+ /**
76
+ * Verify integrity of cached file
77
+ */
78
+ verifyIntegrity(cachePath: string, integrity: string): Promise<boolean>;
79
+ /**
80
+ * Get full filesystem path from cache path
81
+ */
82
+ getFullPath(cachePath: string): string;
83
+ /**
84
+ * Get cache path from full filesystem path
85
+ */
86
+ getCachePath(fullPath: string): string | null;
87
+ /**
88
+ * Walk directory recursively to collect files
89
+ */
90
+ private walkDir;
91
+ /**
92
+ * Clean up empty directories from a path up to .libraries
93
+ */
94
+ private cleanEmptyDirs;
95
+ /**
96
+ * Clean all empty directories under .libraries
97
+ */
98
+ private cleanAllEmptyDirs;
99
+ }
100
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAG1D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAO3E;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAoBzD;AAED;;;;GAIG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,cAAc,CAAS;gBAEnB,aAAa,EAAE,MAAM;IAKjC;;OAEG;IACH,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED;;OAEG;IACH,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B;;OAEG;IACG,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAmBnE;;OAEG;IACG,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK9C;;OAEG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUjD;;OAEG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB9C;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAgB/B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAkB9B;;OAEG;IACG,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAS7E;;OAEG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAItC;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAe7C;;OAEG;YACW,OAAO;IAiBrB;;OAEG;YACW,cAAc;IAkB5B;;OAEG;YACW,iBAAiB;CAwBhC"}