@amodalai/amodal 0.3.87 → 0.3.88

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amodalai/amodal",
3
- "version": "0.3.87",
3
+ "version": "0.3.88",
4
4
  "description": "Amodal CLI",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -27,12 +27,12 @@
27
27
  "react": "^19.2.4",
28
28
  "yargs": "^17.7.2",
29
29
  "zod": "^4.3.6",
30
- "@amodalai/types": "0.3.87",
31
- "@amodalai/core": "0.3.87",
32
- "@amodalai/db": "0.3.87",
33
- "@amodalai/runtime": "0.3.87",
34
- "@amodalai/studio": "0.3.87",
35
- "@amodalai/runtime-app": "0.3.87"
30
+ "@amodalai/types": "0.3.88",
31
+ "@amodalai/core": "0.3.88",
32
+ "@amodalai/db": "0.3.88",
33
+ "@amodalai/runtime": "0.3.88",
34
+ "@amodalai/studio": "0.3.88",
35
+ "@amodalai/runtime-app": "0.3.88"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/node": "^20.11.24",
@@ -328,14 +328,25 @@ function spawnStudio(opts: {
328
328
  log.debug('studio_prebuilt', {path: prebuiltEntry});
329
329
  spawnArgs = [prebuiltEntry];
330
330
  } else if (existsSync(sourceEntry)) {
331
- // Resolve tsx from the studio package's dependency tree
331
+ // Resolve tsx from the studio package's dependency tree. tsx 4.x
332
+ // walls off `./dist/cli.mjs` in its `exports` field, so we resolve
333
+ // its package.json (always exposed via `./package.json`) and read
334
+ // the `bin` entry to find the CLI runner.
332
335
  const studioRequire = createRequire(path.join(studioDir, 'package.json'));
333
336
  let tsxBin: string;
334
337
  try {
335
- tsxBin = studioRequire.resolve('tsx/dist/cli.mjs');
336
- } catch {
338
+ const tsxPkgPath = studioRequire.resolve('tsx/package.json');
339
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- tsx's package.json shape; we read bin field with a guarded fallback below.
340
+ const tsxPkg = JSON.parse(readFileSync(tsxPkgPath, 'utf-8')) as {bin?: string | Record<string, string>};
341
+ const binRel = typeof tsxPkg.bin === 'string'
342
+ ? tsxPkg.bin
343
+ : tsxPkg.bin?.['tsx'];
344
+ if (!binRel) throw new Error('tsx package.json has no usable bin entry');
345
+ tsxBin = path.resolve(path.dirname(tsxPkgPath), binRel);
346
+ } catch (err) {
337
347
  log.info('studio_tsx_not_found', {
338
348
  hint: 'tsx not resolvable from @amodalai/studio — Studio subprocess skipped',
349
+ error: err instanceof Error ? err.message : String(err),
339
350
  });
340
351
  return null;
341
352
  }
@@ -6,12 +6,19 @@
6
6
 
7
7
  import {describe, it, expect, vi, beforeEach} from 'vitest';
8
8
 
9
- vi.mock('@amodalai/runtime', () => ({
10
- createLocalServer: vi.fn().mockResolvedValue({
11
- start: vi.fn().mockResolvedValue({address: () => ({port: 9999})}),
12
- stop: vi.fn().mockResolvedValue(undefined),
13
- }),
14
- }));
9
+ vi.mock('@amodalai/runtime', async () => {
10
+ const actual = await vi.importActual<typeof import('@amodalai/runtime')>('@amodalai/runtime');
11
+ return {
12
+ ...actual,
13
+ createLocalServer: vi.fn().mockResolvedValue({
14
+ start: vi.fn().mockResolvedValue({address: () => ({port: 9999})}),
15
+ stop: vi.fn().mockResolvedValue(undefined),
16
+ }),
17
+ // eval.ts now does `await import('@amodalai/runtime')` for loadAgentRepo;
18
+ // route it through mockLoadRepo so the test controls the bundle.
19
+ loadAgentRepo: (...args: unknown[]) => mockLoadRepo(...args),
20
+ };
21
+ });
15
22
 
16
23
  vi.mock('../shared/repo-discovery.js', () => ({
17
24
  findRepoRoot: vi.fn(() => '/test/repo'),
@@ -20,7 +27,7 @@ vi.mock('../shared/repo-discovery.js', () => ({
20
27
  const mockLoadRepo = vi.fn();
21
28
  const mockRunEvalSuite = vi.fn();
22
29
  vi.mock('@amodalai/core', async () => {
23
- const actual = await vi.importActual('@amodalai/core');
30
+ const actual = await vi.importActual<typeof import('@amodalai/core')>('@amodalai/core');
24
31
  return {
25
32
  ...actual,
26
33
  loadRepoFromDisk: mockLoadRepo,
@@ -59,9 +59,10 @@ export async function runEval(options: EvalOptions): Promise<void> {
59
59
  const baseUrl = `http://127.0.0.1:${actualPort}`;
60
60
 
61
61
  try {
62
- // Load repo to get evals
63
- const {loadRepoFromDisk} = await import('@amodalai/core');
64
- const repo = await loadRepoFromDisk(repoPath);
62
+ // Load repo to get evals — use the runtime wrapper so first-party
63
+ // built-ins (SQL connection driver) register cleanly.
64
+ const {loadAgentRepo} = await import('@amodalai/runtime');
65
+ const repo = await loadAgentRepo({localPath: repoPath});
65
66
 
66
67
  if (repo.evals.length === 0) {
67
68
  process.stderr.write('[eval] No evals found in evals/\n');
@@ -13,9 +13,12 @@ vi.mock('../shared/repo-discovery.js', () => ({
13
13
  findRepoRoot: mockFindRepoRoot,
14
14
  }));
15
15
 
16
- vi.mock('@amodalai/core', () => ({
17
- resolveAllPackages: mockResolveAllPackages,
18
- loadRepo: vi.fn().mockResolvedValue({
16
+ vi.mock('@amodalai/core', async () => {
17
+ const actual = await vi.importActual<typeof import('@amodalai/core')>('@amodalai/core');
18
+ return {
19
+ ...actual,
20
+ resolveAllPackages: mockResolveAllPackages,
21
+ loadRepo: vi.fn().mockResolvedValue({
19
22
  config: {models: {main: {provider: 'anthropic', model: 'test'}}},
20
23
  connections: new Map([['crm', {spec: {auth: {type: 'bearer'}}, surface: [{}, {}]}]]),
21
24
  skills: [{name: 'triage'}],
@@ -42,7 +45,8 @@ vi.mock('@amodalai/core', () => ({
42
45
  connections: new Map([['crm', {spec: {auth: {type: 'bearer'}}, surface: [{}, {}]}]]),
43
46
  },
44
47
  })),
45
- }));
48
+ };
49
+ });
46
50
 
47
51
  describe('runInspect', () => {
48
52
  let stdoutOutput: string[];
@@ -5,7 +5,8 @@
5
5
  */
6
6
 
7
7
  import type {CommandModule} from 'yargs';
8
- import {loadRepo, setupSession, resolveAllPackages} from '@amodalai/core';
8
+ import {setupSession, resolveAllPackages} from '@amodalai/core';
9
+ import {loadAgentRepo} from '@amodalai/runtime';
9
10
  import {findRepoRoot} from '../shared/repo-discovery.js';
10
11
 
11
12
  export interface InspectOptions {
@@ -34,7 +35,7 @@ export async function runInspect(options: InspectOptions = {}): Promise<void> {
34
35
 
35
36
  process.stderr.write(`[inspect] Loading repo from ${repoPath}\n`);
36
37
 
37
- const repo = await loadRepo({localPath: repoPath});
38
+ const repo = await loadAgentRepo({localPath: repoPath});
38
39
  const runtime = setupSession({repo});
39
40
 
40
41
  const showAll = !options.context && !options.explore && !options.tools && !options.connections && !options.resolved;
@@ -20,11 +20,15 @@ const mockMcpManager = {
20
20
  shutdown: vi.fn().mockResolvedValue(undefined),
21
21
  };
22
22
 
23
- vi.mock('@amodalai/core', () => ({
24
- loadRepo: mockLoadRepo,
25
- resolveAllPackages: mockResolveAllPackages,
26
- McpManager: vi.fn(() => mockMcpManager),
27
- }));
23
+ vi.mock('@amodalai/core', async () => {
24
+ const actual = await vi.importActual<typeof import('@amodalai/core')>('@amodalai/core');
25
+ return {
26
+ ...actual,
27
+ loadRepo: mockLoadRepo,
28
+ resolveAllPackages: mockResolveAllPackages,
29
+ McpManager: vi.fn(() => mockMcpManager),
30
+ };
31
+ });
28
32
 
29
33
  describe('runValidate', () => {
30
34
  beforeEach(() => {
@@ -7,8 +7,9 @@
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, resolveAllPackages, McpManager} from '@amodalai/core';
10
+ import {resolveAllPackages, McpManager} from '@amodalai/core';
11
11
  import type {ConnectionSpec} from '@amodalai/core';
12
+ import {loadAgentRepo} from '@amodalai/runtime';
12
13
  import {findRepoRoot} from '../shared/repo-discovery.js';
13
14
 
14
15
  export interface ValidateOptions {
@@ -256,7 +257,7 @@ export async function runValidate(options: ValidateOptions = {}): Promise<number
256
257
  process.stderr.write(`[validate] Loading repo from ${repoPath}\n`);
257
258
 
258
259
  try {
259
- const repo = await loadRepo({localPath: repoPath});
260
+ const repo = await loadAgentRepo({localPath: repoPath});
260
261
 
261
262
  // Check: at least one connection
262
263
  if (repo.connections.size === 0) {
@@ -6,8 +6,9 @@
6
6
 
7
7
  import {join} from 'node:path';
8
8
  import {readFile} from 'node:fs/promises';
9
- import {loadRepo, McpManager} from '@amodalai/core';
9
+ import {McpManager} from '@amodalai/core';
10
10
  import type {ConnectionSpec} from '@amodalai/core';
11
+ import {loadAgentRepo} from '@amodalai/runtime';
11
12
 
12
13
  export interface LiveTestResult {
13
14
  name: string;
@@ -220,7 +221,7 @@ export async function runConnectionPreflight(repoPath: string): Promise<Prefligh
220
221
 
221
222
  let repo;
222
223
  try {
223
- repo = await loadRepo({localPath: repoPath});
224
+ repo = await loadAgentRepo({localPath: repoPath});
224
225
  } catch {
225
226
  return {results: [], hasFailures: false};
226
227
  }