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
@@ -0,0 +1,270 @@
1
+ /**
2
+ * Cache Manager for .libraries/
3
+ *
4
+ * Manages local cache of fetched packages.
5
+ */
6
+ import { promises as fs } from 'node:fs';
7
+ import * as path from 'node:path';
8
+ import * as crypto from 'node:crypto';
9
+ /**
10
+ * Calculate SHA256 integrity hash of content
11
+ */
12
+ export function calculateIntegrity(content) {
13
+ const hash = crypto.createHash('sha256').update(content, 'utf-8').digest('hex');
14
+ return `sha256:${hash}`;
15
+ }
16
+ /**
17
+ * Verify content matches integrity hash
18
+ */
19
+ export function verifyIntegrity(content, integrity) {
20
+ if (!integrity.startsWith('sha256:')) {
21
+ return false;
22
+ }
23
+ const calculated = calculateIntegrity(content);
24
+ return calculated === integrity;
25
+ }
26
+ /**
27
+ * Derive cache path from parsed URL
28
+ *
29
+ * For GitHub/GitLab: {repo}/{path-from-blob}
30
+ * For generic URLs: {domain}/{path}
31
+ */
32
+ export function deriveCachePath(parsed) {
33
+ if (parsed.provider === 'github' || parsed.provider === 'gitlab') {
34
+ // Use repo name + path
35
+ return `${parsed.repo}/${parsed.path}`;
36
+ }
37
+ // Generic URL - extract domain and path
38
+ if (parsed.rawUrl) {
39
+ try {
40
+ const url = new URL(parsed.rawUrl);
41
+ // Combine hostname with pathname (remove leading slash)
42
+ const pathname = parsed.path.startsWith('/') ? parsed.path.slice(1) : parsed.path;
43
+ return `${url.hostname}/${pathname}`;
44
+ }
45
+ catch {
46
+ // Fallback to just using the path
47
+ return parsed.path.startsWith('/') ? parsed.path.slice(1) : parsed.path;
48
+ }
49
+ }
50
+ return parsed.path.startsWith('/') ? parsed.path.slice(1) : parsed.path;
51
+ }
52
+ /**
53
+ * Cache Manager
54
+ *
55
+ * Manages the .libraries/ cache directory.
56
+ */
57
+ export class CacheManager {
58
+ _workspaceRoot;
59
+ _librariesPath;
60
+ constructor(workspaceRoot) {
61
+ this._workspaceRoot = workspaceRoot;
62
+ this._librariesPath = path.join(workspaceRoot, '.libraries');
63
+ }
64
+ /**
65
+ * Get workspace root path
66
+ */
67
+ get workspaceRoot() {
68
+ return this._workspaceRoot;
69
+ }
70
+ /**
71
+ * Get .libraries path
72
+ */
73
+ get librariesPath() {
74
+ return this._librariesPath;
75
+ }
76
+ /**
77
+ * Initialize cache directory
78
+ */
79
+ async init() {
80
+ await fs.mkdir(this._librariesPath, { recursive: true });
81
+ }
82
+ /**
83
+ * Save content to cache
84
+ */
85
+ async save(cachePath, content) {
86
+ const fullPath = this.getFullPath(cachePath);
87
+ // Create parent directories
88
+ await fs.mkdir(path.dirname(fullPath), { recursive: true });
89
+ // Write content
90
+ await fs.writeFile(fullPath, content, 'utf-8');
91
+ // Calculate integrity
92
+ const integrity = calculateIntegrity(content);
93
+ return {
94
+ path: cachePath,
95
+ fullPath,
96
+ integrity,
97
+ };
98
+ }
99
+ /**
100
+ * Read content from cache
101
+ */
102
+ async read(cachePath) {
103
+ const fullPath = this.getFullPath(cachePath);
104
+ return fs.readFile(fullPath, 'utf-8');
105
+ }
106
+ /**
107
+ * Check if file exists in cache
108
+ */
109
+ async exists(cachePath) {
110
+ const fullPath = this.getFullPath(cachePath);
111
+ try {
112
+ await fs.stat(fullPath);
113
+ return true;
114
+ }
115
+ catch {
116
+ return false;
117
+ }
118
+ }
119
+ /**
120
+ * Delete file from cache
121
+ */
122
+ async delete(cachePath) {
123
+ const fullPath = this.getFullPath(cachePath);
124
+ try {
125
+ await fs.unlink(fullPath);
126
+ }
127
+ catch (error) {
128
+ // Ignore if file doesn't exist
129
+ if (error.code !== 'ENOENT') {
130
+ throw error;
131
+ }
132
+ return;
133
+ }
134
+ // Clean up empty parent directories
135
+ await this.cleanEmptyDirs(path.dirname(fullPath));
136
+ }
137
+ /**
138
+ * List all cached files
139
+ */
140
+ async list() {
141
+ const files = [];
142
+ try {
143
+ await this.walkDir(this._librariesPath, files);
144
+ }
145
+ catch (error) {
146
+ // Return empty if .libraries doesn't exist
147
+ if (error.code === 'ENOENT') {
148
+ return [];
149
+ }
150
+ throw error;
151
+ }
152
+ return files;
153
+ }
154
+ /**
155
+ * Remove all cached files
156
+ */
157
+ async clean() {
158
+ const files = await this.list();
159
+ for (const file of files) {
160
+ const fullPath = this.getFullPath(file);
161
+ await fs.unlink(fullPath);
162
+ }
163
+ // Clean up all empty directories
164
+ try {
165
+ await this.cleanAllEmptyDirs(this._librariesPath);
166
+ }
167
+ catch {
168
+ // Ignore errors during cleanup
169
+ }
170
+ return files.length;
171
+ }
172
+ /**
173
+ * Verify integrity of cached file
174
+ */
175
+ async verifyIntegrity(cachePath, integrity) {
176
+ try {
177
+ const content = await this.read(cachePath);
178
+ return verifyIntegrity(content, integrity);
179
+ }
180
+ catch {
181
+ return false;
182
+ }
183
+ }
184
+ /**
185
+ * Get full filesystem path from cache path
186
+ */
187
+ getFullPath(cachePath) {
188
+ return path.join(this._librariesPath, cachePath);
189
+ }
190
+ /**
191
+ * Get cache path from full filesystem path
192
+ */
193
+ getCachePath(fullPath) {
194
+ if (!fullPath.startsWith(this._librariesPath)) {
195
+ return null;
196
+ }
197
+ const relativePath = path.relative(this._librariesPath, fullPath);
198
+ // Make sure it's not outside (no .. components)
199
+ if (relativePath.startsWith('..')) {
200
+ return null;
201
+ }
202
+ return relativePath;
203
+ }
204
+ /**
205
+ * Walk directory recursively to collect files
206
+ */
207
+ async walkDir(dir, files) {
208
+ const entries = await fs.readdir(dir, { withFileTypes: true });
209
+ for (const entry of entries) {
210
+ const fullPath = path.join(dir, entry.name);
211
+ if (entry.isDirectory()) {
212
+ await this.walkDir(fullPath, files);
213
+ }
214
+ else if (entry.isFile()) {
215
+ const cachePath = this.getCachePath(fullPath);
216
+ if (cachePath) {
217
+ files.push(cachePath);
218
+ }
219
+ }
220
+ }
221
+ }
222
+ /**
223
+ * Clean up empty directories from a path up to .libraries
224
+ */
225
+ async cleanEmptyDirs(dir) {
226
+ // Don't go above .libraries
227
+ if (dir === this._librariesPath || !dir.startsWith(this._librariesPath)) {
228
+ return;
229
+ }
230
+ try {
231
+ const entries = await fs.readdir(dir);
232
+ if (entries.length === 0) {
233
+ await fs.rmdir(dir);
234
+ // Recurse to parent
235
+ await this.cleanEmptyDirs(path.dirname(dir));
236
+ }
237
+ }
238
+ catch {
239
+ // Ignore errors
240
+ }
241
+ }
242
+ /**
243
+ * Clean all empty directories under .libraries
244
+ */
245
+ async cleanAllEmptyDirs(dir) {
246
+ try {
247
+ const entries = await fs.readdir(dir, { withFileTypes: true });
248
+ for (const entry of entries) {
249
+ if (entry.isDirectory()) {
250
+ const subDir = path.join(dir, entry.name);
251
+ await this.cleanAllEmptyDirs(subDir);
252
+ // Try to remove if empty
253
+ try {
254
+ const subEntries = await fs.readdir(subDir);
255
+ if (subEntries.length === 0) {
256
+ await fs.rmdir(subDir);
257
+ }
258
+ }
259
+ catch {
260
+ // Ignore
261
+ }
262
+ }
263
+ }
264
+ }
265
+ catch {
266
+ // Ignore errors
267
+ }
268
+ }
269
+ }
270
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}