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,463 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { parseDocument, resolveImports } from '../parser.js';
4
+ import { writeFile, readFile } from 'fs/promises';
5
+ import { existsSync } from 'fs';
6
+ import { resolve, basename } from 'path';
7
+ import { initWorkspace, checkWorkspace, addPackage, removePackage, upgradePackage, listPackages, getPackageInfo, } from '../commands/package.js';
8
+ const program = new Command();
9
+ program
10
+ .name('busy')
11
+ .description('BUSY Document Parser CLI')
12
+ .version('0.1.0');
13
+ // Parse command - parse a single BUSY document
14
+ program
15
+ .command('parse')
16
+ .description('Parse a BUSY document and output its structure as JSON')
17
+ .argument('<file>', 'Path to the BUSY markdown file')
18
+ .option('-o, --output <file>', 'Output file for parsed JSON')
19
+ .option('--pretty', 'Pretty-print JSON output', true)
20
+ .option('--no-pretty', 'Compact JSON output')
21
+ .action(async (file, options) => {
22
+ try {
23
+ const filePath = resolve(file);
24
+ if (!existsSync(filePath)) {
25
+ console.error(`Error: File not found: ${filePath}`);
26
+ process.exit(1);
27
+ }
28
+ const content = await readFile(filePath, 'utf-8');
29
+ const doc = parseDocument(content);
30
+ const output = options.pretty
31
+ ? JSON.stringify(doc, null, 2)
32
+ : JSON.stringify(doc);
33
+ if (options.output) {
34
+ await writeFile(options.output, output, 'utf-8');
35
+ console.log(`✓ Parsed ${basename(file)}`);
36
+ console.log(` Type: ${doc.metadata.type}`);
37
+ console.log(` Imports: ${doc.imports.length}`);
38
+ console.log(` Definitions: ${doc.definitions.length}`);
39
+ console.log(` Operations: ${doc.operations.length}`);
40
+ console.log(` Triggers: ${doc.triggers.length}`);
41
+ if ('tools' in doc) {
42
+ console.log(` Tools: ${doc.tools.length}`);
43
+ }
44
+ console.log(`✓ Written to ${options.output}`);
45
+ }
46
+ else {
47
+ console.log(output);
48
+ }
49
+ }
50
+ catch (err) {
51
+ console.error('Error parsing document:', err instanceof Error ? err.message : err);
52
+ process.exit(1);
53
+ }
54
+ });
55
+ // Validate command - validate a BUSY document
56
+ program
57
+ .command('validate')
58
+ .description('Validate a BUSY document (check frontmatter, structure, imports)')
59
+ .argument('<file>', 'Path to the BUSY markdown file')
60
+ .option('--resolve-imports', 'Also validate that imports can be resolved')
61
+ .action(async (file, options) => {
62
+ try {
63
+ const filePath = resolve(file);
64
+ if (!existsSync(filePath)) {
65
+ console.error(`✗ File not found: ${filePath}`);
66
+ process.exit(1);
67
+ }
68
+ const content = await readFile(filePath, 'utf-8');
69
+ // Parse document (this validates frontmatter and structure)
70
+ const doc = parseDocument(content);
71
+ console.log(`✓ Valid BUSY document: ${doc.metadata.name}`);
72
+ console.log(` Type: ${doc.metadata.type}`);
73
+ console.log(` Description: ${doc.metadata.description.slice(0, 60)}${doc.metadata.description.length > 60 ? '...' : ''}`);
74
+ // Check for common issues
75
+ const warnings = [];
76
+ const errors = [];
77
+ // Check if operations have steps
78
+ for (const op of doc.operations) {
79
+ if (op.steps.length === 0) {
80
+ warnings.push(`Operation "${op.name}" has no steps`);
81
+ }
82
+ }
83
+ // Check for empty imports
84
+ if (doc.imports.length === 0 && doc.operations.length > 0) {
85
+ warnings.push('Document has operations but no imports');
86
+ }
87
+ // Validate imports if requested
88
+ if (options.resolveImports) {
89
+ console.log('\nResolving imports...');
90
+ try {
91
+ const resolved = resolveImports(doc, filePath);
92
+ console.log(`✓ Resolved ${Object.keys(resolved).length} imports`);
93
+ for (const [name, resolvedDoc] of Object.entries(resolved)) {
94
+ console.log(` - ${name}: ${resolvedDoc.metadata.name} (${resolvedDoc.metadata.type})`);
95
+ }
96
+ }
97
+ catch (err) {
98
+ errors.push(`Import resolution failed: ${err instanceof Error ? err.message : err}`);
99
+ }
100
+ }
101
+ // Print warnings and errors
102
+ if (warnings.length > 0) {
103
+ console.log('\nWarnings:');
104
+ for (const warning of warnings) {
105
+ console.log(` ⚠ ${warning}`);
106
+ }
107
+ }
108
+ if (errors.length > 0) {
109
+ console.log('\nErrors:');
110
+ for (const error of errors) {
111
+ console.log(` ✗ ${error}`);
112
+ }
113
+ process.exit(1);
114
+ }
115
+ console.log('\n✓ Validation passed');
116
+ }
117
+ catch (err) {
118
+ console.error(`✗ Validation failed: ${err instanceof Error ? err.message : err}`);
119
+ process.exit(1);
120
+ }
121
+ });
122
+ // Resolve command - resolve imports in a document
123
+ program
124
+ .command('resolve')
125
+ .description('Resolve all imports in a BUSY document recursively')
126
+ .argument('<file>', 'Path to the BUSY markdown file')
127
+ .option('-o, --output <file>', 'Output file for resolved imports JSON')
128
+ .option('--flat', 'Output flat list of resolved documents')
129
+ .action(async (file, options) => {
130
+ try {
131
+ const filePath = resolve(file);
132
+ if (!existsSync(filePath)) {
133
+ console.error(`Error: File not found: ${filePath}`);
134
+ process.exit(1);
135
+ }
136
+ const content = await readFile(filePath, 'utf-8');
137
+ const doc = parseDocument(content);
138
+ console.log(`Resolving imports for: ${doc.metadata.name}`);
139
+ const resolved = resolveImports(doc, filePath);
140
+ const count = Object.keys(resolved).length;
141
+ console.log(`✓ Resolved ${count} imports`);
142
+ let output;
143
+ if (options.flat) {
144
+ // Flat list of document names and their metadata
145
+ const flat = Object.entries(resolved).map(([name, resolvedDoc]) => ({
146
+ conceptName: name,
147
+ name: resolvedDoc.metadata.name,
148
+ type: resolvedDoc.metadata.type,
149
+ operations: resolvedDoc.operations.map(op => op.name),
150
+ }));
151
+ output = JSON.stringify(flat, null, 2);
152
+ }
153
+ else {
154
+ // Full resolved documents
155
+ output = JSON.stringify(resolved, null, 2);
156
+ }
157
+ if (options.output) {
158
+ await writeFile(options.output, output, 'utf-8');
159
+ console.log(`✓ Written to ${options.output}`);
160
+ }
161
+ else {
162
+ console.log(output);
163
+ }
164
+ }
165
+ catch (err) {
166
+ console.error('Error resolving imports:', err instanceof Error ? err.message : err);
167
+ process.exit(1);
168
+ }
169
+ });
170
+ // Info command - quick document info
171
+ program
172
+ .command('info')
173
+ .description('Show quick information about a BUSY document')
174
+ .argument('<file>', 'Path to the BUSY markdown file')
175
+ .action(async (file) => {
176
+ try {
177
+ const filePath = resolve(file);
178
+ if (!existsSync(filePath)) {
179
+ console.error(`Error: File not found: ${filePath}`);
180
+ process.exit(1);
181
+ }
182
+ const content = await readFile(filePath, 'utf-8');
183
+ const doc = parseDocument(content);
184
+ console.log(`\n📄 ${doc.metadata.name}`);
185
+ console.log(`${'─'.repeat(40)}`);
186
+ console.log(`Type: ${doc.metadata.type}`);
187
+ console.log(`Description: ${doc.metadata.description}`);
188
+ if (doc.metadata.provider) {
189
+ console.log(`Provider: ${doc.metadata.provider}`);
190
+ }
191
+ console.log(`${'─'.repeat(40)}`);
192
+ console.log(`Imports: ${doc.imports.length}`);
193
+ if (doc.imports.length > 0) {
194
+ for (const imp of doc.imports) {
195
+ console.log(` - [${imp.conceptName}]: ${imp.path}${imp.anchor ? '#' + imp.anchor : ''}`);
196
+ }
197
+ }
198
+ console.log(`Definitions: ${doc.definitions.length}`);
199
+ if (doc.definitions.length > 0) {
200
+ for (const def of doc.definitions) {
201
+ console.log(` - ${def.name}`);
202
+ }
203
+ }
204
+ console.log(`Operations: ${doc.operations.length}`);
205
+ if (doc.operations.length > 0) {
206
+ for (const op of doc.operations) {
207
+ console.log(` - ${op.name} (${op.steps.length} steps${op.checklist ? `, ${op.checklist.items.length} checklist items` : ''})`);
208
+ }
209
+ }
210
+ console.log(`Triggers: ${doc.triggers.length}`);
211
+ if (doc.triggers.length > 0) {
212
+ for (const trigger of doc.triggers) {
213
+ if (trigger.triggerType === 'alarm') {
214
+ console.log(` - ⏰ ${trigger.schedule} → ${trigger.operation}`);
215
+ }
216
+ else {
217
+ console.log(` - 📡 ${trigger.eventType}${trigger.filter ? ` (filtered)` : ''} → ${trigger.operation}`);
218
+ }
219
+ }
220
+ }
221
+ if ('tools' in doc && doc.tools.length > 0) {
222
+ console.log(`Tools: ${doc.tools.length}`);
223
+ for (const tool of doc.tools) {
224
+ const providers = tool.providers ? Object.keys(tool.providers).join(', ') : 'none';
225
+ console.log(` - ${tool.name} (providers: ${providers})`);
226
+ }
227
+ }
228
+ console.log('');
229
+ }
230
+ catch (err) {
231
+ console.error('Error reading document:', err instanceof Error ? err.message : err);
232
+ process.exit(1);
233
+ }
234
+ });
235
+ // Init command - initialize a BUSY workspace
236
+ program
237
+ .command('init')
238
+ .description('Initialize a new BUSY workspace with package.busy.md')
239
+ .option('-d, --dir <directory>', 'Directory to initialize', '.')
240
+ .action(async (options) => {
241
+ try {
242
+ const workspaceRoot = resolve(options.dir);
243
+ const result = await initWorkspace(workspaceRoot);
244
+ console.log('\nInitializing BUSY workspace...\n');
245
+ if (result.created.length > 0) {
246
+ for (const item of result.created) {
247
+ console.log(` ✓ Created ${item}`);
248
+ }
249
+ }
250
+ if (result.skipped.length > 0) {
251
+ for (const item of result.skipped) {
252
+ console.log(` - Skipped ${item} (already exists)`);
253
+ }
254
+ }
255
+ console.log('\n✓ Workspace initialized');
256
+ }
257
+ catch (err) {
258
+ console.error('Error initializing workspace:', err instanceof Error ? err.message : err);
259
+ process.exit(1);
260
+ }
261
+ });
262
+ // Check command - validate workspace coherence
263
+ program
264
+ .command('check')
265
+ .description('Validate workspace coherence (check packages, links, integrity)')
266
+ .option('-d, --dir <directory>', 'Workspace directory', '.')
267
+ .option('--skip-external', 'Skip validation of external URLs')
268
+ .option('-v, --verbose', 'Show all checks, not just errors')
269
+ .action(async (options) => {
270
+ try {
271
+ const workspaceRoot = resolve(options.dir);
272
+ const result = await checkWorkspace(workspaceRoot, {
273
+ skipExternal: options.skipExternal,
274
+ });
275
+ console.log('\nChecking workspace...\n');
276
+ console.log(` Dependencies: ${result.packages}`);
277
+ if (result.errors.length > 0) {
278
+ console.log('\nErrors:');
279
+ for (const error of result.errors) {
280
+ console.log(` ✗ ${error}`);
281
+ }
282
+ }
283
+ if (result.warnings.length > 0) {
284
+ console.log('\nWarnings:');
285
+ for (const warning of result.warnings) {
286
+ console.log(` ⚠ ${warning}`);
287
+ }
288
+ }
289
+ if (result.valid) {
290
+ console.log('\n✓ Workspace is coherent');
291
+ }
292
+ else {
293
+ console.log('\n✗ Workspace has errors');
294
+ process.exit(1);
295
+ }
296
+ }
297
+ catch (err) {
298
+ console.error('✗ Check failed:', err instanceof Error ? err.message : err);
299
+ process.exit(2);
300
+ }
301
+ });
302
+ // Package command group
303
+ const packageCmd = program
304
+ .command('package')
305
+ .description('Manage packages in the workspace');
306
+ // Package add
307
+ packageCmd
308
+ .command('add')
309
+ .description('Add a package from URL')
310
+ .argument('<url>', 'URL to the BUSY document')
311
+ .option('-d, --dir <directory>', 'Workspace directory', '.')
312
+ .action(async (url, options) => {
313
+ try {
314
+ const workspaceRoot = resolve(options.dir);
315
+ console.log(`\nAdding package from: ${url}\n`);
316
+ const result = await addPackage(workspaceRoot, url);
317
+ console.log(` ID: ${result.id}`);
318
+ console.log(` Provider: ${result.provider}`);
319
+ console.log(` Version: ${result.version}`);
320
+ console.log(` Cached: ${result.cached}`);
321
+ console.log(`\n✓ Package added: ${result.id}`);
322
+ }
323
+ catch (err) {
324
+ console.error('Error adding package:', err instanceof Error ? err.message : err);
325
+ process.exit(1);
326
+ }
327
+ });
328
+ // Package remove
329
+ packageCmd
330
+ .command('remove')
331
+ .description('Remove a package')
332
+ .argument('<name>', 'Package ID to remove')
333
+ .option('-d, --dir <directory>', 'Workspace directory', '.')
334
+ .action(async (name, options) => {
335
+ try {
336
+ const workspaceRoot = resolve(options.dir);
337
+ console.log(`\nRemoving package: ${name}\n`);
338
+ const result = await removePackage(workspaceRoot, name);
339
+ if (result.removed) {
340
+ console.log(' ✓ Removed from package.busy.md');
341
+ console.log(' ✓ Removed cached file');
342
+ console.log(`\n✓ Package removed: ${name}`);
343
+ }
344
+ else {
345
+ console.log(` Package not found: ${name}`);
346
+ process.exit(1);
347
+ }
348
+ }
349
+ catch (err) {
350
+ console.error('Error removing package:', err instanceof Error ? err.message : err);
351
+ process.exit(1);
352
+ }
353
+ });
354
+ // Package upgrade
355
+ packageCmd
356
+ .command('upgrade')
357
+ .description('Upgrade a package to latest version')
358
+ .argument('[name]', 'Package ID to upgrade (omit for all)')
359
+ .option('-d, --dir <directory>', 'Workspace directory', '.')
360
+ .option('--all', 'Upgrade all packages')
361
+ .action(async (name, options) => {
362
+ try {
363
+ const workspaceRoot = resolve(options.dir);
364
+ if (options.all || !name) {
365
+ // Upgrade all packages
366
+ console.log('\nChecking for updates...\n');
367
+ const { packages } = await listPackages(workspaceRoot);
368
+ let upgraded = 0;
369
+ for (const pkg of packages) {
370
+ try {
371
+ const result = await upgradePackage(workspaceRoot, pkg.id);
372
+ if (result.upgraded) {
373
+ console.log(` ✓ ${pkg.id}: ${result.oldVersion} → ${result.newVersion}`);
374
+ upgraded++;
375
+ }
376
+ else {
377
+ console.log(` - ${pkg.id}: ${result.oldVersion} (up to date)`);
378
+ }
379
+ }
380
+ catch (err) {
381
+ console.log(` ✗ ${pkg.id}: ${err instanceof Error ? err.message : err}`);
382
+ }
383
+ }
384
+ console.log(`\n✓ Upgraded ${upgraded} package(s)`);
385
+ }
386
+ else {
387
+ // Upgrade single package
388
+ console.log(`\nUpgrading package: ${name}\n`);
389
+ const result = await upgradePackage(workspaceRoot, name);
390
+ if (result.upgraded) {
391
+ console.log(` Old version: ${result.oldVersion}`);
392
+ console.log(` New version: ${result.newVersion}`);
393
+ console.log(`\n✓ Package upgraded: ${name}`);
394
+ }
395
+ else {
396
+ console.log(` Already at latest version: ${result.newVersion}`);
397
+ }
398
+ }
399
+ }
400
+ catch (err) {
401
+ console.error('Error upgrading package:', err instanceof Error ? err.message : err);
402
+ process.exit(1);
403
+ }
404
+ });
405
+ // Package list
406
+ packageCmd
407
+ .command('list')
408
+ .description('List installed packages')
409
+ .option('-d, --dir <directory>', 'Workspace directory', '.')
410
+ .action(async (options) => {
411
+ try {
412
+ const workspaceRoot = resolve(options.dir);
413
+ const result = await listPackages(workspaceRoot);
414
+ console.log('\nDependencies:');
415
+ if (result.packages.length === 0) {
416
+ console.log(' (none)');
417
+ }
418
+ else {
419
+ for (const pkg of result.packages) {
420
+ console.log(` ${pkg.id.padEnd(20)} ${pkg.version.padEnd(12)} ${pkg.provider.padEnd(10)} ${pkg.cached}`);
421
+ }
422
+ }
423
+ console.log(`\nTotal: ${result.packages.length} dependency(s)`);
424
+ }
425
+ catch (err) {
426
+ console.error('Error listing packages:', err instanceof Error ? err.message : err);
427
+ process.exit(1);
428
+ }
429
+ });
430
+ // Package info
431
+ packageCmd
432
+ .command('info')
433
+ .description('Show package details')
434
+ .argument('<name>', 'Package ID')
435
+ .option('-d, --dir <directory>', 'Workspace directory', '.')
436
+ .action(async (name, options) => {
437
+ try {
438
+ const workspaceRoot = resolve(options.dir);
439
+ const pkg = await getPackageInfo(workspaceRoot, name);
440
+ if (!pkg) {
441
+ console.log(`Package not found: ${name}`);
442
+ process.exit(1);
443
+ }
444
+ console.log(`\nPackage: ${pkg.id}\n`);
445
+ console.log('| Field | Value |');
446
+ console.log('|-----------|-------|');
447
+ console.log(`| Source | ${pkg.source} |`);
448
+ console.log(`| Provider | ${pkg.provider} |`);
449
+ console.log(`| Cached | ${pkg.cached} |`);
450
+ console.log(`| Version | ${pkg.version} |`);
451
+ console.log(`| Fetched | ${pkg.fetched} |`);
452
+ if (pkg.integrity) {
453
+ console.log(`| Integrity | ${pkg.integrity} |`);
454
+ }
455
+ console.log('');
456
+ }
457
+ catch (err) {
458
+ console.error('Error getting package info:', err instanceof Error ? err.message : err);
459
+ process.exit(1);
460
+ }
461
+ });
462
+ program.parse();
463
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Package Management Commands
3
+ *
4
+ * Implementation of busy init, check, and package commands.
5
+ */
6
+ import { PackageEntry } from '../registry/index.js';
7
+ import '../providers/local.js';
8
+ import '../providers/github.js';
9
+ import '../providers/gitlab.js';
10
+ import '../providers/url.js';
11
+ /**
12
+ * Result of initWorkspace
13
+ */
14
+ export interface InitResult {
15
+ workspaceRoot: string;
16
+ initialized: boolean;
17
+ created: string[];
18
+ skipped: string[];
19
+ }
20
+ /**
21
+ * Result of checkWorkspace
22
+ */
23
+ export interface CheckResult {
24
+ workspaceRoot: string;
25
+ valid: boolean;
26
+ errors: string[];
27
+ warnings: string[];
28
+ packages: number;
29
+ }
30
+ /**
31
+ * Result of addPackage
32
+ */
33
+ export interface AddResult {
34
+ id: string;
35
+ source: string;
36
+ provider: string;
37
+ cached: string;
38
+ version: string;
39
+ integrity: string;
40
+ }
41
+ /**
42
+ * Result of removePackage
43
+ */
44
+ export interface RemoveResult {
45
+ id: string;
46
+ removed: boolean;
47
+ }
48
+ /**
49
+ * Result of listPackages
50
+ */
51
+ export interface ListResult {
52
+ packages: PackageEntry[];
53
+ }
54
+ /**
55
+ * Result of upgradePackage
56
+ */
57
+ export interface UpgradeResult {
58
+ id: string;
59
+ upgraded: boolean;
60
+ oldVersion: string;
61
+ newVersion: string;
62
+ }
63
+ /**
64
+ * Initialize a BUSY workspace
65
+ */
66
+ export declare function initWorkspace(workspaceRoot: string): Promise<InitResult>;
67
+ /**
68
+ * Check workspace coherence
69
+ */
70
+ export declare function checkWorkspace(workspaceRoot: string, options?: {
71
+ skipExternal?: boolean;
72
+ }): Promise<CheckResult>;
73
+ /**
74
+ * Add a package from URL
75
+ *
76
+ * If the URL points to a package.busy.md manifest, fetches the entire package.
77
+ * Otherwise, fetches a single file.
78
+ */
79
+ export declare function addPackage(workspaceRoot: string, url: string): Promise<AddResult>;
80
+ /**
81
+ * Remove a package
82
+ */
83
+ export declare function removePackage(workspaceRoot: string, packageId: string): Promise<RemoveResult>;
84
+ /**
85
+ * List all packages
86
+ */
87
+ export declare function listPackages(workspaceRoot: string): Promise<ListResult>;
88
+ /**
89
+ * Get package info
90
+ */
91
+ export declare function getPackageInfo(workspaceRoot: string, packageId: string): Promise<PackageEntry | null>;
92
+ /**
93
+ * Upgrade a package to latest version
94
+ */
95
+ export declare function upgradePackage(workspaceRoot: string, packageId: string): Promise<UpgradeResult>;
96
+ //# sourceMappingURL=package.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package.d.ts","sourceRoot":"","sources":["../../src/commands/package.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAmB,YAAY,EAAiC,MAAM,sBAAsB,CAAC;AAKpG,OAAO,uBAAuB,CAAC;AAC/B,OAAO,wBAAwB,CAAC;AAChC,OAAO,wBAAwB,CAAC;AAChC,OAAO,qBAAqB,CAAC;AAE7B;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAkC9E;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CA8CtH;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAoFvF;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAwBnG;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAQ7E;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAM3G;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA4ErG"}