@amodalai/amodal 0.2.1 → 0.2.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 (92) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/src/commands/connect-channel.d.ts +11 -0
  3. package/dist/src/commands/connect-channel.d.ts.map +1 -0
  4. package/dist/src/commands/connect-channel.js +169 -0
  5. package/dist/src/commands/connect-channel.js.map +1 -0
  6. package/dist/src/commands/connect.d.ts +3 -1
  7. package/dist/src/commands/connect.d.ts.map +1 -1
  8. package/dist/src/commands/connect.js +27 -16
  9. package/dist/src/commands/connect.js.map +1 -1
  10. package/dist/src/commands/groups/connect.d.ts +8 -0
  11. package/dist/src/commands/groups/connect.d.ts.map +1 -0
  12. package/dist/src/commands/groups/connect.js +17 -0
  13. package/dist/src/commands/groups/connect.js.map +1 -0
  14. package/dist/src/commands/groups/pkg.d.ts.map +1 -1
  15. package/dist/src/commands/groups/pkg.js +0 -12
  16. package/dist/src/commands/groups/pkg.js.map +1 -1
  17. package/dist/src/commands/index.d.ts +1 -1
  18. package/dist/src/commands/index.d.ts.map +1 -1
  19. package/dist/src/commands/index.js +3 -1
  20. package/dist/src/commands/index.js.map +1 -1
  21. package/dist/src/commands/init.d.ts.map +1 -1
  22. package/dist/src/commands/init.js +4 -1
  23. package/dist/src/commands/init.js.map +1 -1
  24. package/dist/src/commands/inspect.d.ts.map +1 -1
  25. package/dist/src/commands/inspect.js +32 -38
  26. package/dist/src/commands/inspect.js.map +1 -1
  27. package/dist/src/commands/install-pkg.d.ts +5 -5
  28. package/dist/src/commands/install-pkg.d.ts.map +1 -1
  29. package/dist/src/commands/install-pkg.js +35 -77
  30. package/dist/src/commands/install-pkg.js.map +1 -1
  31. package/dist/src/commands/uninstall.d.ts +2 -2
  32. package/dist/src/commands/uninstall.d.ts.map +1 -1
  33. package/dist/src/commands/uninstall.js +6 -32
  34. package/dist/src/commands/uninstall.js.map +1 -1
  35. package/dist/src/commands/validate.d.ts.map +1 -1
  36. package/dist/src/commands/validate.js +15 -21
  37. package/dist/src/commands/validate.js.map +1 -1
  38. package/dist/src/shared/tarball.js +1 -1
  39. package/dist/src/shared/tarball.js.map +1 -1
  40. package/dist/tsconfig.tsbuildinfo +1 -1
  41. package/package.json +5 -5
  42. package/src/commands/command-exports.test.ts +1 -1
  43. package/src/commands/connect-channel.ts +197 -0
  44. package/src/commands/connect.test.ts +28 -40
  45. package/src/commands/connect.ts +30 -24
  46. package/src/commands/groups/connect.ts +20 -0
  47. package/src/commands/groups/pkg.ts +0 -12
  48. package/src/commands/index.ts +5 -1
  49. package/src/commands/init.test.ts +2 -2
  50. package/src/commands/init.ts +5 -1
  51. package/src/commands/inspect.test.ts +1 -18
  52. package/src/commands/inspect.ts +31 -36
  53. package/src/commands/install-pkg.test.ts +39 -73
  54. package/src/commands/install-pkg.ts +38 -87
  55. package/src/commands/uninstall.test.ts +11 -51
  56. package/src/commands/uninstall.ts +7 -36
  57. package/src/commands/validate.test.ts +5 -26
  58. package/src/commands/validate.ts +15 -20
  59. package/src/e2e-commands.test.ts +0 -1
  60. package/src/e2e-plugins.test.ts +0 -1
  61. package/src/e2e.test.ts +0 -89
  62. package/src/shared/tarball.ts +1 -1
  63. package/dist/src/commands/diff.d.ts +0 -17
  64. package/dist/src/commands/diff.d.ts.map +0 -1
  65. package/dist/src/commands/diff.js +0 -118
  66. package/dist/src/commands/diff.js.map +0 -1
  67. package/dist/src/commands/list.d.ts +0 -18
  68. package/dist/src/commands/list.d.ts.map +0 -1
  69. package/dist/src/commands/list.js +0 -82
  70. package/dist/src/commands/list.js.map +0 -1
  71. package/dist/src/commands/publish.d.ts +0 -18
  72. package/dist/src/commands/publish.d.ts.map +0 -1
  73. package/dist/src/commands/publish.js +0 -121
  74. package/dist/src/commands/publish.js.map +0 -1
  75. package/dist/src/commands/search.d.ts +0 -19
  76. package/dist/src/commands/search.d.ts.map +0 -1
  77. package/dist/src/commands/search.js +0 -97
  78. package/dist/src/commands/search.js.map +0 -1
  79. package/dist/src/commands/update.d.ts +0 -19
  80. package/dist/src/commands/update.d.ts.map +0 -1
  81. package/dist/src/commands/update.js +0 -158
  82. package/dist/src/commands/update.js.map +0 -1
  83. package/src/commands/diff.test.ts +0 -165
  84. package/src/commands/diff.ts +0 -141
  85. package/src/commands/list.test.ts +0 -141
  86. package/src/commands/list.ts +0 -99
  87. package/src/commands/publish.test.ts +0 -169
  88. package/src/commands/publish.ts +0 -141
  89. package/src/commands/search.test.ts +0 -171
  90. package/src/commands/search.ts +0 -120
  91. package/src/commands/update.test.ts +0 -256
  92. package/src/commands/update.ts +0 -196
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright 2025 Amodal Labs, Inc.
3
+ * Copyright 2026 Amodal Labs, Inc.
4
4
  * SPDX-License-Identifier: MIT
5
5
  */
6
6
 
@@ -8,7 +8,6 @@ import {describe, it, expect, vi, beforeEach} from 'vitest';
8
8
 
9
9
  const mockFindRepoRoot = vi.fn(() => '/test/repo');
10
10
  const mockLoadRepo = vi.fn();
11
- const mockReadLockFile = vi.fn();
12
11
  const mockResolveAllPackages = vi.fn();
13
12
 
14
13
  vi.mock('../shared/repo-discovery.js', () => ({
@@ -23,7 +22,6 @@ const mockMcpManager = {
23
22
 
24
23
  vi.mock('@amodalai/core', () => ({
25
24
  loadRepo: mockLoadRepo,
26
- readLockFile: mockReadLockFile,
27
25
  resolveAllPackages: mockResolveAllPackages,
28
26
  McpManager: vi.fn(() => mockMcpManager),
29
27
  }));
@@ -149,7 +147,6 @@ describe('runValidate', () => {
149
147
  skills: [{name: 'test', body: 'content'}],
150
148
  automations: [],
151
149
  });
152
- mockReadLockFile.mockResolvedValue({lockVersion: 2, packages: {}});
153
150
  mockResolveAllPackages.mockResolvedValue({
154
151
  connections: new Map(),
155
152
  skills: [],
@@ -161,7 +158,7 @@ describe('runValidate', () => {
161
158
  const {runValidate} = await import('./validate.js');
162
159
  const result = await runValidate({packages: true, skipTest: true});
163
160
  expect(result).toBe(0);
164
- expect(mockResolveAllPackages).toHaveBeenCalled();
161
+ expect(mockResolveAllPackages).toHaveBeenCalledWith({repoPath: '/test/repo'});
165
162
  });
166
163
 
167
164
  it('should report resolution warnings as validation warnings', async () => {
@@ -170,7 +167,6 @@ describe('runValidate', () => {
170
167
  skills: [],
171
168
  automations: [],
172
169
  });
173
- mockReadLockFile.mockResolvedValue({lockVersion: 2, packages: {'@amodalai/connection-salesforce': {version: '1.0.0', integrity: 'sha512-x'}}});
174
170
  mockResolveAllPackages.mockResolvedValue({
175
171
  connections: new Map(),
176
172
  skills: [],
@@ -190,7 +186,6 @@ describe('runValidate', () => {
190
186
  skills: [],
191
187
  automations: [],
192
188
  });
193
- mockReadLockFile.mockResolvedValue({lockVersion: 2, packages: {}});
194
189
  mockResolveAllPackages.mockResolvedValue({
195
190
  connections: new Map(),
196
191
  skills: [{name: 'bad-skill', body: ' '}],
@@ -204,20 +199,6 @@ describe('runValidate', () => {
204
199
  expect(result).toBe(1);
205
200
  });
206
201
 
207
- it('should skip package validation when no lock file', async () => {
208
- mockLoadRepo.mockResolvedValue({
209
- connections: new Map([['api', {surface: [{method: 'GET', path: '/test'}], access: {}}]]),
210
- skills: [],
211
- automations: [],
212
- });
213
- mockReadLockFile.mockResolvedValue(null);
214
-
215
- const {runValidate} = await import('./validate.js');
216
- const result = await runValidate({packages: true, skipTest: true});
217
- expect(result).toBe(0);
218
- expect(mockResolveAllPackages).not.toHaveBeenCalled();
219
- });
220
-
221
202
  it('should not run package checks without packages flag', async () => {
222
203
  mockLoadRepo.mockResolvedValue({
223
204
  connections: new Map([['api', {surface: [{method: 'GET', path: '/test'}], access: {}}]]),
@@ -228,7 +209,7 @@ describe('runValidate', () => {
228
209
  const {runValidate} = await import('./validate.js');
229
210
  const result = await runValidate({skipTest: true});
230
211
  expect(result).toBe(0);
231
- expect(mockReadLockFile).not.toHaveBeenCalled();
212
+ expect(mockResolveAllPackages).not.toHaveBeenCalled();
232
213
  });
233
214
 
234
215
  it('should handle package resolution failure', async () => {
@@ -237,7 +218,6 @@ describe('runValidate', () => {
237
218
  skills: [],
238
219
  automations: [],
239
220
  });
240
- mockReadLockFile.mockResolvedValue({lockVersion: 2, packages: {}});
241
221
  mockResolveAllPackages.mockRejectedValue(new Error('Disk error'));
242
222
 
243
223
  const {runValidate} = await import('./validate.js');
@@ -251,7 +231,6 @@ describe('runValidate', () => {
251
231
  skills: [],
252
232
  automations: [],
253
233
  });
254
- mockReadLockFile.mockResolvedValue({lockVersion: 2, packages: {}});
255
234
  mockResolveAllPackages.mockResolvedValue({
256
235
  connections: new Map([['empty-conn', {surface: [], spec: {auth: null}}]]),
257
236
  skills: [],
@@ -396,8 +375,8 @@ describe('runValidate', () => {
396
375
  skills: [],
397
376
  automations: [],
398
377
  });
399
- // First call: redirected, lost auth 401
400
- // Second call: retry with auth 200
378
+ // First call: redirected, lost auth -> 401
379
+ // Second call: retry with auth -> 200
401
380
  mockFetch
402
381
  .mockResolvedValueOnce({status: 401, redirected: true, url: 'https://api.example.com/v2/'})
403
382
  .mockResolvedValueOnce({status: 200, redirected: false});
@@ -7,7 +7,7 @@
7
7
  import {join} from 'node:path';
8
8
  import {readFile} from 'node:fs/promises';
9
9
  import type {CommandModule} from 'yargs';
10
- import {loadRepo, readLockFile, resolveAllPackages, McpManager} from '@amodalai/core';
10
+ import {loadRepo, resolveAllPackages, McpManager} from '@amodalai/core';
11
11
  import type {ConnectionSpec} from '@amodalai/core';
12
12
  import {findRepoRoot} from '../shared/repo-discovery.js';
13
13
 
@@ -337,30 +337,25 @@ export async function runValidate(options: ValidateOptions = {}): Promise<number
337
337
  // Package-aware validation
338
338
  if (options.packages) {
339
339
  try {
340
- const lockFile = await readLockFile(repoPath);
341
- if (lockFile) {
342
- const resolved = await resolveAllPackages({repoPath, lockFile});
340
+ const resolved = await resolveAllPackages({repoPath});
343
341
 
344
- // Report warnings from resolution (missing packages, broken symlinks)
345
- for (const warning of resolved.warnings) {
346
- issues.push({level: 'warning', message: warning});
347
- }
342
+ // Report warnings from resolution (missing packages, broken symlinks)
343
+ for (const warning of resolved.warnings) {
344
+ issues.push({level: 'warning', message: warning});
345
+ }
348
346
 
349
- // Check for empty resolved connections
350
- for (const [name, conn] of resolved.connections) {
351
- if (conn.surface.length === 0) {
352
- issues.push({level: 'warning', message: `Resolved connection "${name}" has no surface endpoints.`});
353
- }
347
+ // Check for empty resolved connections
348
+ for (const [name, conn] of resolved.connections) {
349
+ if (conn.surface.length === 0) {
350
+ issues.push({level: 'warning', message: `Resolved connection "${name}" has no surface endpoints.`});
354
351
  }
352
+ }
355
353
 
356
- // Check for empty resolved skills
357
- for (const skill of resolved.skills) {
358
- if (!skill.body.trim()) {
359
- issues.push({level: 'error', message: `Resolved skill "${skill.name}" has an empty body.`});
360
- }
354
+ // Check for empty resolved skills
355
+ for (const skill of resolved.skills) {
356
+ if (!skill.body.trim()) {
357
+ issues.push({level: 'error', message: `Resolved skill "${skill.name}" has an empty body.`});
361
358
  }
362
- } else {
363
- process.stderr.write('[validate] No lock file found, skipping package validation.\n');
364
359
  }
365
360
  } catch (err) {
366
361
  const msg = err instanceof Error ? err.message : String(err);
@@ -29,7 +29,6 @@ import {runValidate} from './commands/validate.js';
29
29
  import {runInspect} from './commands/inspect.js';
30
30
  import {runBuild} from './commands/build.js';
31
31
  import {runDeploy} from './commands/deploy.js';
32
- import {runList} from './commands/list.js';
33
32
  import {runDocker} from './commands/docker.js';
34
33
  import {runStatus} from './commands/status.js';
35
34
  import {runDeployments} from './commands/deployments.js';
@@ -35,7 +35,6 @@ import {runInit} from './commands/init.js';
35
35
  import {runInstallPkg} from './commands/install-pkg.js';
36
36
  import {runValidate} from './commands/validate.js';
37
37
  import {runBuild} from './commands/build.js';
38
- import {runList} from './commands/list.js';
39
38
  import {runUninstall} from './commands/uninstall.js';
40
39
  import {loadRepo} from '@amodalai/core';
41
40
 
package/src/e2e.test.ts CHANGED
@@ -20,11 +20,6 @@ import type {ArgumentsCamelCase, CommandModule} from 'yargs';
20
20
  import {connectCommand} from './commands/connect.js';
21
21
  import {installPkgCommand} from './commands/install-pkg.js';
22
22
  import {uninstallCommand} from './commands/uninstall.js';
23
- import {listCommand} from './commands/list.js';
24
- import {updateCommand} from './commands/update.js';
25
- import {diffCommand} from './commands/diff.js';
26
- import {searchCommand} from './commands/search.js';
27
- import {publishCommand} from './commands/publish.js';
28
23
  import {loginCommand} from './commands/login.js';
29
24
  import {linkCommand} from './commands/link.js';
30
25
  import {secretsCommand} from './commands/secrets.js';
@@ -134,90 +129,6 @@ describe('amodal CLI e2e', () => {
134
129
  });
135
130
  });
136
131
 
137
- // --- list ---
138
-
139
- describe('list', () => {
140
- it('defaults to json=false', async () => {
141
- const args = await parseArgs(listCommand, ['list']);
142
- expect(args['json']).toBe(false);
143
- expect(args['filter']).toBeUndefined();
144
- });
145
-
146
- it('parses --filter and --json', async () => {
147
- const args = await parseArgs(listCommand, ['list', '--filter', 'skill', '--json']);
148
- expect(args['filter']).toBe('skill');
149
- expect(args['json']).toBe(true);
150
- });
151
- });
152
-
153
- // --- update ---
154
-
155
- describe('update', () => {
156
- it('optional positional defaults to undefined', async () => {
157
- const args = await parseArgs(updateCommand, ['update']);
158
- expect(args['name']).toBeUndefined();
159
- expect(args['latest']).toBe(false);
160
- expect(args['dryRun']).toBe(false);
161
- });
162
-
163
- it('parses name', async () => {
164
- const args = await parseArgs(updateCommand, ['update', 'stripe']);
165
- expect(args['name']).toBe('stripe');
166
- });
167
-
168
- it('parses --latest and --dry-run', async () => {
169
- const args = await parseArgs(updateCommand, ['update', '--latest', '--dry-run']);
170
- expect(args['latest']).toBe(true);
171
- expect(args['dryRun']).toBe(true);
172
- });
173
- });
174
-
175
- // --- diff ---
176
-
177
- describe('diff', () => {
178
- it('parses name', async () => {
179
- const args = await parseArgs(diffCommand, ['diff', 'triage']);
180
- expect(args['name']).toBe('triage');
181
- });
182
- });
183
-
184
- // --- search ---
185
-
186
- describe('search', () => {
187
- it('optional query defaults to undefined', async () => {
188
- const args = await parseArgs(searchCommand, ['search']);
189
- expect(args['query']).toBeUndefined();
190
- expect(args['json']).toBe(false);
191
- });
192
-
193
- it('parses query and --type', async () => {
194
- const args = await parseArgs(searchCommand, ['search', 'stripe', '--type', 'connection']);
195
- expect(args['query']).toBe('stripe');
196
- expect(args['type']).toBe('connection');
197
- });
198
-
199
- it('parses --json', async () => {
200
- const args = await parseArgs(searchCommand, ['search', '--json']);
201
- expect(args['json']).toBe(true);
202
- });
203
- });
204
-
205
- // --- publish ---
206
-
207
- describe('publish', () => {
208
- it('defaults', async () => {
209
- const args = await parseArgs(publishCommand, ['publish']);
210
- expect(args['dryRun']).toBe(false);
211
- expect(args['registry']).toBeUndefined();
212
- });
213
-
214
- it('parses --dry-run and --registry', async () => {
215
- const args = await parseArgs(publishCommand, ['publish', '--dry-run', '--registry', 'https://my-registry.dev']);
216
- expect(args['dryRun']).toBe(true);
217
- expect(args['registry']).toBe('https://my-registry.dev');
218
- });
219
- });
220
-
221
132
  // --- login ---
222
133
 
223
134
  describe('login', () => {
@@ -22,7 +22,7 @@ export async function createRepoTarball(repoPath: string): Promise<string> {
22
22
  );
23
23
 
24
24
  execSync(
25
- `tar -czf "${tarballPath}" --exclude=node_modules --exclude=.git --exclude=amodal_packages --exclude=.amodal -C "${repoPath}" .`,
25
+ `tar -czf "${tarballPath}" --exclude=node_modules --exclude=.git --exclude=.amodal -C "${repoPath}" .`,
26
26
  {stdio: 'pipe', timeout: 30_000},
27
27
  );
28
28
 
@@ -1,17 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2025 Amodal Labs, Inc.
4
- * SPDX-License-Identifier: MIT
5
- */
6
- import type { CommandModule } from 'yargs';
7
- export interface DiffOptions {
8
- cwd?: string;
9
- name: string;
10
- }
11
- /**
12
- * Show diff between installed version and latest available.
13
- * Returns 0 on success, 1 on error.
14
- */
15
- export declare function runDiff(options: DiffOptions): Promise<number>;
16
- export declare const diffCommand: CommandModule;
17
- //# sourceMappingURL=diff.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../../src/commands/diff.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,OAAO,CAAC;AAazC,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAiGnE;AAED,eAAO,MAAM,WAAW,EAAE,aAWzB,CAAC"}
@@ -1,118 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2025 Amodal Labs, Inc.
4
- * SPDX-License-Identifier: MIT
5
- */
6
- import { join } from 'node:path';
7
- import { ensureNpmContext, fromNpmName, getLockEntry, getNpmContextPaths, npmView, readPackageFile, listPackageFiles, toNpmName, } from '@amodalai/core';
8
- import { findRepoRoot } from '../shared/repo-discovery.js';
9
- /**
10
- * Show diff between installed version and latest available.
11
- * Returns 0 on success, 1 on error.
12
- */
13
- export async function runDiff(options) {
14
- let repoPath;
15
- try {
16
- repoPath = findRepoRoot(options.cwd);
17
- }
18
- catch (err) {
19
- const msg = err instanceof Error ? err.message : String(err);
20
- process.stderr.write(`[diff] ${msg}\n`);
21
- return 1;
22
- }
23
- const paths = await ensureNpmContext(repoPath);
24
- const npmName = toNpmName(options.name);
25
- const shortName = fromNpmName(npmName);
26
- // Check if installed
27
- const lockEntry = await getLockEntry(repoPath, npmName);
28
- if (!lockEntry) {
29
- process.stderr.write(`[diff] Package ${npmName} is not installed.\n`);
30
- return 1;
31
- }
32
- // Get latest version info
33
- let latestVersion;
34
- try {
35
- const viewResult = await npmView(paths, npmName);
36
- latestVersion = viewResult.version;
37
- }
38
- catch (err) {
39
- const msg = err instanceof Error ? err.message : String(err);
40
- process.stderr.write(`[diff] Failed to query registry: ${msg}\n`);
41
- return 1;
42
- }
43
- if (latestVersion === lockEntry.version) {
44
- process.stderr.write(`[diff] ${npmName}@${lockEntry.version} is already the latest version.\n`);
45
- return 0;
46
- }
47
- process.stderr.write(`[diff] Comparing ${npmName}: ${lockEntry.version} (installed) → ${latestVersion} (latest)\n`);
48
- // Get installed package directory
49
- const contextPaths = getNpmContextPaths(repoPath);
50
- const packageDir = join(contextPaths.nodeModules, npmName);
51
- // List installed files
52
- let installedFiles;
53
- try {
54
- installedFiles = await listPackageFiles(packageDir);
55
- }
56
- catch {
57
- installedFiles = [];
58
- }
59
- // Print diff report
60
- process.stdout.write(`\n ${npmName}\n`);
61
- process.stdout.write(` Installed: ${lockEntry.version}\n`);
62
- process.stdout.write(` Latest: ${latestVersion}\n\n`);
63
- // Show file-level summary
64
- process.stdout.write(' Files in installed version:\n');
65
- for (const file of installedFiles) {
66
- const content = await readPackageFile(packageDir, file);
67
- if (content !== null) {
68
- const lineCount = content.split('\n').length;
69
- let detail = `${lineCount} lines`;
70
- // Add type-specific details
71
- if (file === 'surface.md') {
72
- const endpointCount = (content.match(/^##\s/gm) ?? []).length;
73
- detail += `, ${endpointCount} endpoint${endpointCount === 1 ? '' : 's'}`;
74
- }
75
- else if (file === 'spec.json') {
76
- try {
77
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
78
- const spec = JSON.parse(content);
79
- const keys = Object.keys(spec);
80
- detail += `, keys: ${keys.join(', ')}`;
81
- }
82
- catch {
83
- // Not valid JSON
84
- }
85
- }
86
- else if (file === 'access.json') {
87
- try {
88
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
89
- const access = JSON.parse(content);
90
- const ruleCount = Object.keys(access).length;
91
- detail += `, ${ruleCount} rule${ruleCount === 1 ? '' : 's'}`;
92
- }
93
- catch {
94
- // Not valid JSON
95
- }
96
- }
97
- else if (file === 'entities.md') {
98
- const sectionCount = (content.match(/^##\s/gm) ?? []).length;
99
- detail += `, ${sectionCount} entit${sectionCount === 1 ? 'y' : 'ies'}`;
100
- }
101
- process.stdout.write(` ${file} (${detail})\n`);
102
- }
103
- }
104
- process.stdout.write(`\n Run \`amodal update ${shortName}\` to upgrade.\n\n`);
105
- return 0;
106
- }
107
- export const diffCommand = {
108
- command: 'diff <name>',
109
- describe: 'Show diff between installed and latest version',
110
- builder: (yargs) => yargs
111
- .positional('name', { type: 'string', demandOption: true, describe: 'Package name' }),
112
- handler: async (argv) => {
113
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
114
- const code = await runDiff({ name: argv['name'] });
115
- process.exit(code);
116
- },
117
- };
118
- //# sourceMappingURL=diff.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../../src/commands/diff.ts"],"names":[],"mappings":"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"}
@@ -1,18 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2025 Amodal Labs, Inc.
4
- * SPDX-License-Identifier: MIT
5
- */
6
- import type { CommandModule } from 'yargs';
7
- export interface ListOptions {
8
- cwd?: string;
9
- filter?: string;
10
- json?: boolean;
11
- }
12
- /**
13
- * List installed packages from the lock file.
14
- * Returns 0 on success, 1 on error.
15
- */
16
- export declare function runList(options?: ListOptions): Promise<number>;
17
- export declare const listCommand: CommandModule;
18
- //# sourceMappingURL=list.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/list.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,OAAO,CAAC;AAIzC,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAgExE;AAED,eAAO,MAAM,WAAW,EAAE,aAYzB,CAAC"}
@@ -1,82 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2025 Amodal Labs, Inc.
4
- * SPDX-License-Identifier: MIT
5
- */
6
- import { fromNpmName, listLockEntries } from '@amodalai/core';
7
- import { findRepoRoot } from '../shared/repo-discovery.js';
8
- /**
9
- * List installed packages from the lock file.
10
- * Returns 0 on success, 1 on error.
11
- */
12
- export async function runList(options = {}) {
13
- let repoPath;
14
- try {
15
- repoPath = findRepoRoot(options.cwd);
16
- }
17
- catch (err) {
18
- const msg = err instanceof Error ? err.message : String(err);
19
- process.stderr.write(`[list] ${msg}\n`);
20
- return 1;
21
- }
22
- let entries = await listLockEntries(repoPath);
23
- // Optional string filter on npm name
24
- if (options.filter) {
25
- const f = options.filter.toLowerCase();
26
- entries = entries.filter((e) => e.npmName.toLowerCase().includes(f));
27
- }
28
- if (entries.length === 0) {
29
- if (options.filter) {
30
- process.stderr.write(`[list] No packages matching "${options.filter}" installed.\n`);
31
- }
32
- else {
33
- process.stderr.write('[list] No packages installed.\n');
34
- }
35
- return 0;
36
- }
37
- if (options.json) {
38
- const output = entries.map((e) => ({
39
- name: fromNpmName(e.npmName),
40
- npmName: e.npmName,
41
- version: e.entry.version,
42
- integrity: e.entry.integrity,
43
- }));
44
- process.stdout.write(JSON.stringify(output, null, 2) + '\n');
45
- return 0;
46
- }
47
- // Formatted table
48
- const names = entries.map((e) => fromNpmName(e.npmName));
49
- const nameWidth = Math.max(4, ...names.map((n) => n.length));
50
- const npmWidth = Math.max(3, ...entries.map((e) => e.npmName.length));
51
- const versionWidth = Math.max(7, ...entries.map((e) => e.entry.version.length));
52
- const header = [
53
- 'NAME'.padEnd(nameWidth),
54
- 'VERSION'.padEnd(versionWidth),
55
- 'NPM'.padEnd(npmWidth),
56
- ].join(' ');
57
- process.stdout.write(header + '\n');
58
- for (let i = 0; i < entries.length; i++) {
59
- const e = entries[i];
60
- const row = [
61
- names[i].padEnd(nameWidth),
62
- e.entry.version.padEnd(versionWidth),
63
- e.npmName.padEnd(npmWidth),
64
- ].join(' ');
65
- process.stdout.write(row + '\n');
66
- }
67
- process.stderr.write(`[list] ${entries.length} package${entries.length === 1 ? '' : 's'} installed.\n`);
68
- return 0;
69
- }
70
- export const listCommand = {
71
- command: 'list',
72
- describe: 'List installed packages',
73
- builder: (yargs) => yargs
74
- .option('filter', { type: 'string', describe: 'Filter by name substring' })
75
- .option('json', { type: 'boolean', default: false, describe: 'Output as JSON' }),
76
- handler: async (argv) => {
77
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
78
- const code = await runList({ filter: argv['filter'], json: argv['json'] });
79
- process.exit(code);
80
- },
81
- };
82
- //# sourceMappingURL=list.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/list.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAC,WAAW,EAAE,eAAe,EAAC,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAC,YAAY,EAAC,MAAM,6BAA6B,CAAC;AAQzD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,UAAuB,EAAE;IACrD,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACvC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;QACxC,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,OAAO,GAAG,MAAM,eAAe,CAAC,QAAQ,CAAC,CAAC;IAE9C,qCAAqC;IACrC,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QACvC,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,OAAO,CAAC,MAAM,gBAAgB,CAAC,CAAC;QACvF,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;QAC1D,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACjC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC;YAC5B,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO;YACxB,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS;SAC7B,CAAC,CAAC,CAAC;QACJ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAC7D,OAAO,CAAC,CAAC;IACX,CAAC;IAED,kBAAkB;IAClB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACzD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IACtE,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAEhF,MAAM,MAAM,GAAG;QACb,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;QACxB,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC;QAC9B,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC;KACvB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAEd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACrB,MAAM,GAAG,GAAG;YACV,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC;YAC1B,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC;YACpC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC;SAC3B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,OAAO,CAAC,MAAM,WAAW,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC;IACxG,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAkB;IACxC,OAAO,EAAE,MAAM;IACf,QAAQ,EAAE,yBAAyB;IACnC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CACjB,KAAK;SACF,MAAM,CAAC,QAAQ,EAAE,EAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,0BAA0B,EAAC,CAAC;SACxE,MAAM,CAAC,MAAM,EAAE,EAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAC,CAAC;IAClF,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACtB,uEAAuE;QACvE,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,EAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAuB,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAY,EAAC,CAAC,CAAC;QAC1G,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;CACF,CAAC"}
@@ -1,18 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2025 Amodal Labs, Inc.
4
- * SPDX-License-Identifier: MIT
5
- */
6
- import type { CommandModule } from 'yargs';
7
- export interface PublishOptions {
8
- cwd?: string;
9
- dryRun?: boolean;
10
- registry?: string;
11
- }
12
- /**
13
- * Publish a package to the registry.
14
- * Returns 0 on success, 1 on error.
15
- */
16
- export declare function runPublish(options?: PublishOptions): Promise<number>;
17
- export declare const publishCommand: CommandModule;
18
- //# sourceMappingURL=publish.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../../src/commands/publish.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,OAAO,CAAC;AAOzC,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CA8F9E;AAED,eAAO,MAAM,cAAc,EAAE,aAgB5B,CAAC"}