fix(team): use source runtime for live smoke
This commit is contained in:
parent
8b97f5c016
commit
0742bcc191
11 changed files with 148 additions and 27 deletions
|
|
@ -26,6 +26,8 @@ Live team smoke runtime:
|
|||
|
||||
- Use the orchestrator source launcher by default for live/dev smoke loops: `/Users/belief/dev/projects/claude/agent_teams_orchestrator/cli-source`
|
||||
- The source launcher runs `src/entrypoints/cli.tsx` through Bun, so it reflects local orchestrator source edits immediately and cannot accidentally test stale `dist` output.
|
||||
- The source launcher normalizes inherited `NODE_ENV=production` to `NODE_ENV=development`. Release or production-like smoke must use the built wrapper instead of preserving production mode on source.
|
||||
- Local live/prove scripts should use `scripts/lib/live-smoke-runtime.mjs`, which defaults to `cli-source` unless `CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH` is explicitly set.
|
||||
- Source-mode teammate startup can be slower than bundled startup. Live smoke harnesses may raise `CLAUDE_TEAM_PROCESS_RUNTIME_READY_TIMEOUT_MS` and `CLAUDE_TEAM_PROCESS_INBOX_POLLER_READY_TIMEOUT_MS` when the test is validating source behavior instead of watchdog latency.
|
||||
- Use the built wrapper only for release or production-like smoke checks. Build first in `/Users/belief/dev/projects/claude/agent_teams_orchestrator` with `bun run build`, then set `CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH=/Users/belief/dev/projects/claude/agent_teams_orchestrator/cli`.
|
||||
- Do not use `cli-dev` or `bun run build:dev` as proof for the production wrapper. `cli` reads `dist/local-cli/cli.js`; `cli-dev` reads `dist/local-cli-dev/cli.js`.
|
||||
|
|
|
|||
|
|
@ -95,6 +95,10 @@ export CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH=/Users/belief/dev/projects/claud
|
|||
|
||||
The source launcher executes `src/entrypoints/cli.tsx` through Bun. It is the right default for local
|
||||
debug loops, live model/provider checks, and cross-repo runtime fixes.
|
||||
It normalizes inherited `NODE_ENV=production` to `NODE_ENV=development`, because source smoke is a
|
||||
dev/runtime validation path. If you need production semantics, run the release smoke path below.
|
||||
Local live/prove scripts should resolve their default CLI through `scripts/lib/live-smoke-runtime.mjs`,
|
||||
which points at `cli-source` unless `CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH` is explicitly set.
|
||||
Source-mode teammate startup can be slower than bundled startup, so live smoke harnesses may set
|
||||
`CLAUDE_TEAM_PROCESS_RUNTIME_READY_TIMEOUT_MS` and
|
||||
`CLAUDE_TEAM_PROCESS_INBOX_POLLER_READY_TIMEOUT_MS` to larger values when they are validating source
|
||||
|
|
|
|||
37
scripts/lib/live-smoke-runtime.mjs
Normal file
37
scripts/lib/live-smoke-runtime.mjs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import path from 'node:path';
|
||||
|
||||
export function resolveLiveSmokeOrchestratorCliPath({
|
||||
env = process.env,
|
||||
repoRoot,
|
||||
} = {}) {
|
||||
const explicitCliPath = env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH?.trim();
|
||||
if (explicitCliPath) {
|
||||
return explicitCliPath;
|
||||
}
|
||||
|
||||
const configuredRuntimeRoot = env.CLAUDE_DEV_RUNTIME_ROOT?.trim();
|
||||
const baseRepoRoot = repoRoot ? path.resolve(repoRoot) : process.cwd();
|
||||
const runtimeRoot = configuredRuntimeRoot
|
||||
? path.resolve(configuredRuntimeRoot)
|
||||
: path.resolve(baseRepoRoot, '..', 'agent_teams_orchestrator');
|
||||
|
||||
return path.join(runtimeRoot, 'cli-source');
|
||||
}
|
||||
|
||||
export function resolveReleaseSmokeOrchestratorCliPath({
|
||||
env = process.env,
|
||||
repoRoot,
|
||||
} = {}) {
|
||||
const explicitCliPath = env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH?.trim();
|
||||
if (explicitCliPath) {
|
||||
return explicitCliPath;
|
||||
}
|
||||
|
||||
const configuredRuntimeRoot = env.CLAUDE_DEV_RUNTIME_ROOT?.trim();
|
||||
const baseRepoRoot = repoRoot ? path.resolve(repoRoot) : process.cwd();
|
||||
const runtimeRoot = configuredRuntimeRoot
|
||||
? path.resolve(configuredRuntimeRoot)
|
||||
: path.resolve(baseRepoRoot, '..', 'agent_teams_orchestrator');
|
||||
|
||||
return path.join(runtimeRoot, 'cli');
|
||||
}
|
||||
|
|
@ -5,18 +5,24 @@ import path from 'node:path';
|
|||
import process from 'node:process';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
import { resolveLiveSmokeOrchestratorCliPath } from './lib/live-smoke-runtime.mjs';
|
||||
|
||||
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
||||
const repoRoot = path.resolve(scriptDir, '..');
|
||||
const siblingOrchestrator = path.resolve(repoRoot, '..', 'agent_teams_orchestrator');
|
||||
|
||||
const env = {
|
||||
...process.env,
|
||||
AGENT_CLI_LAUNCH_LIVE_E2E: '1',
|
||||
CLAUDE_TEAM_CLI_FLAVOR: process.env.CLAUDE_TEAM_CLI_FLAVOR || 'agent_teams_orchestrator',
|
||||
CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH:
|
||||
process.env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH || path.join(siblingOrchestrator, 'cli'),
|
||||
};
|
||||
|
||||
if (!env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH?.trim()) {
|
||||
env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH = resolveLiveSmokeOrchestratorCliPath({
|
||||
env,
|
||||
repoRoot,
|
||||
});
|
||||
}
|
||||
|
||||
console.log('Running agent CLI launch live smoke');
|
||||
console.log(`Claude runtime: ${env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH}`);
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import path from 'node:path';
|
|||
import process from 'node:process';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
import { resolveLiveSmokeOrchestratorCliPath } from './lib/live-smoke-runtime.mjs';
|
||||
import {
|
||||
exitForSkippedPreflight,
|
||||
preflightOpenCodeLiveEnvironment,
|
||||
|
|
@ -12,8 +13,6 @@ import {
|
|||
|
||||
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
||||
const repoRoot = path.resolve(scriptDir, '..');
|
||||
const orchestratorRoot = process.env.CLAUDE_DEV_RUNTIME_ROOT?.trim();
|
||||
const siblingOrchestrator = path.resolve(repoRoot, '..', 'agent_teams_orchestrator');
|
||||
|
||||
const env = {
|
||||
...process.env,
|
||||
|
|
@ -26,8 +25,10 @@ const env = {
|
|||
};
|
||||
|
||||
if (!env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH?.trim()) {
|
||||
const runtimeRoot = orchestratorRoot ? path.resolve(orchestratorRoot) : siblingOrchestrator;
|
||||
env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH = path.join(runtimeRoot, 'cli');
|
||||
env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH = resolveLiveSmokeOrchestratorCliPath({
|
||||
env,
|
||||
repoRoot,
|
||||
});
|
||||
}
|
||||
|
||||
console.log('Running OpenCode mixed recovery live smoke');
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import path from 'node:path';
|
|||
import process from 'node:process';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
import { resolveLiveSmokeOrchestratorCliPath } from './lib/live-smoke-runtime.mjs';
|
||||
import {
|
||||
exitForSkippedPreflight,
|
||||
preflightOpenCodeLiveEnvironment,
|
||||
|
|
@ -12,8 +13,6 @@ import {
|
|||
|
||||
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
||||
const repoRoot = path.resolve(scriptDir, '..');
|
||||
const orchestratorRoot = process.env.CLAUDE_DEV_RUNTIME_ROOT?.trim();
|
||||
const siblingOrchestrator = path.resolve(repoRoot, '..', 'agent_teams_orchestrator');
|
||||
|
||||
const env = {
|
||||
...process.env,
|
||||
|
|
@ -33,8 +32,10 @@ const env = {
|
|||
};
|
||||
|
||||
if (!env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH?.trim()) {
|
||||
const runtimeRoot = orchestratorRoot ? path.resolve(orchestratorRoot) : siblingOrchestrator;
|
||||
env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH = path.join(runtimeRoot, 'cli');
|
||||
env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH = resolveLiveSmokeOrchestratorCliPath({
|
||||
env,
|
||||
repoRoot,
|
||||
});
|
||||
}
|
||||
|
||||
console.log('Running OpenCode semantic gauntlet live smoke');
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import path from 'node:path';
|
|||
import process from 'node:process';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
import { resolveLiveSmokeOrchestratorCliPath } from './lib/live-smoke-runtime.mjs';
|
||||
import {
|
||||
exitForSkippedPreflight,
|
||||
preflightOpenCodeLiveEnvironment,
|
||||
|
|
@ -12,8 +13,6 @@ import {
|
|||
|
||||
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
||||
const repoRoot = path.resolve(scriptDir, '..');
|
||||
const orchestratorRoot = process.env.CLAUDE_DEV_RUNTIME_ROOT?.trim();
|
||||
const siblingOrchestrator = path.resolve(repoRoot, '..', 'agent_teams_orchestrator');
|
||||
|
||||
const env = {
|
||||
...process.env,
|
||||
|
|
@ -25,8 +24,10 @@ const env = {
|
|||
};
|
||||
|
||||
if (!env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH?.trim()) {
|
||||
const runtimeRoot = orchestratorRoot ? path.resolve(orchestratorRoot) : siblingOrchestrator;
|
||||
env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH = path.join(runtimeRoot, 'cli');
|
||||
env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH = resolveLiveSmokeOrchestratorCliPath({
|
||||
env,
|
||||
repoRoot,
|
||||
});
|
||||
}
|
||||
|
||||
console.log('Running OpenCode semantic messaging live smoke');
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import path from 'node:path';
|
|||
import process from 'node:process';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
import { resolveLiveSmokeOrchestratorCliPath } from './lib/live-smoke-runtime.mjs';
|
||||
import {
|
||||
exitForSkippedPreflight,
|
||||
preflightOpenCodeLiveEnvironment,
|
||||
|
|
@ -12,8 +13,6 @@ import {
|
|||
|
||||
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
||||
const repoRoot = path.resolve(scriptDir, '..');
|
||||
const orchestratorRoot = process.env.CLAUDE_DEV_RUNTIME_ROOT?.trim();
|
||||
const siblingOrchestrator = path.resolve(repoRoot, '..', 'agent_teams_orchestrator');
|
||||
|
||||
const env = {
|
||||
...process.env,
|
||||
|
|
@ -24,8 +23,10 @@ const env = {
|
|||
};
|
||||
|
||||
if (!env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH?.trim()) {
|
||||
const runtimeRoot = orchestratorRoot ? path.resolve(orchestratorRoot) : siblingOrchestrator;
|
||||
env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH = path.join(runtimeRoot, 'cli');
|
||||
env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH = resolveLiveSmokeOrchestratorCliPath({
|
||||
env,
|
||||
repoRoot,
|
||||
});
|
||||
}
|
||||
|
||||
console.log('Running OpenCode semantic model matrix live smoke');
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import path from 'node:path';
|
|||
import process from 'node:process';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
import { resolveLiveSmokeOrchestratorCliPath } from './lib/live-smoke-runtime.mjs';
|
||||
import {
|
||||
exitForSkippedPreflight,
|
||||
preflightOpenCodeLiveEnvironment,
|
||||
|
|
@ -12,8 +13,6 @@ import {
|
|||
|
||||
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
||||
const repoRoot = path.resolve(scriptDir, '..');
|
||||
const orchestratorRoot = process.env.CLAUDE_DEV_RUNTIME_ROOT?.trim();
|
||||
const siblingOrchestrator = path.resolve(repoRoot, '..', 'agent_teams_orchestrator');
|
||||
|
||||
const env = {
|
||||
...process.env,
|
||||
|
|
@ -25,8 +24,10 @@ const env = {
|
|||
};
|
||||
|
||||
if (!env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH?.trim()) {
|
||||
const runtimeRoot = orchestratorRoot ? path.resolve(orchestratorRoot) : siblingOrchestrator;
|
||||
env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH = path.join(runtimeRoot, 'cli');
|
||||
env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH = resolveLiveSmokeOrchestratorCliPath({
|
||||
env,
|
||||
repoRoot,
|
||||
});
|
||||
}
|
||||
|
||||
console.log('Running OpenCode team provisioning live smoke');
|
||||
|
|
|
|||
|
|
@ -7,12 +7,11 @@ import path from 'node:path';
|
|||
import process from 'node:process';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
import { resolveLiveSmokeOrchestratorCliPath } from './lib/live-smoke-runtime.mjs';
|
||||
import { preflightOpenCodeLiveEnvironment } from './lib/opencode-live-preflight.mjs';
|
||||
|
||||
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
||||
const repoRoot = path.resolve(scriptDir, '..');
|
||||
const orchestratorRoot = process.env.CLAUDE_DEV_RUNTIME_ROOT?.trim();
|
||||
const siblingOrchestrator = path.resolve(repoRoot, '..', 'agent_teams_orchestrator');
|
||||
const requestedOrder =
|
||||
process.env.PROVIDER_LAUNCH_STRESS_ORDER?.trim() || 'anthropic,codex,opencode,mixed';
|
||||
|
||||
|
|
@ -31,8 +30,10 @@ const env = {
|
|||
};
|
||||
|
||||
if (!env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH?.trim()) {
|
||||
const runtimeRoot = orchestratorRoot ? path.resolve(orchestratorRoot) : siblingOrchestrator;
|
||||
env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH = path.join(runtimeRoot, 'cli');
|
||||
env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH = resolveLiveSmokeOrchestratorCliPath({
|
||||
env,
|
||||
repoRoot,
|
||||
});
|
||||
}
|
||||
|
||||
console.log('Running provider launch stress live smoke');
|
||||
|
|
|
|||
66
test/scripts/liveSmokeRuntime.test.ts
Normal file
66
test/scripts/liveSmokeRuntime.test.ts
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
// @vitest-environment node
|
||||
|
||||
import * as path from 'path';
|
||||
import { pathToFileURL } from 'url';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
interface LiveSmokeRuntimeModule {
|
||||
resolveLiveSmokeOrchestratorCliPath(input?: {
|
||||
env?: NodeJS.ProcessEnv;
|
||||
repoRoot?: string;
|
||||
}): string;
|
||||
resolveReleaseSmokeOrchestratorCliPath(input?: {
|
||||
env?: NodeJS.ProcessEnv;
|
||||
repoRoot?: string;
|
||||
}): string;
|
||||
}
|
||||
|
||||
describe('live smoke runtime launcher paths', () => {
|
||||
const repoRoot = '/Users/belief/dev/projects/claude/claude_team';
|
||||
const siblingRuntimeRoot = '/Users/belief/dev/projects/claude/agent_teams_orchestrator';
|
||||
|
||||
it('defaults live smoke to the source launcher', async () => {
|
||||
const { resolveLiveSmokeOrchestratorCliPath } = await loadModule();
|
||||
|
||||
expect(resolveLiveSmokeOrchestratorCliPath({ env: {}, repoRoot })).toBe(
|
||||
path.join(siblingRuntimeRoot, 'cli-source')
|
||||
);
|
||||
});
|
||||
|
||||
it('uses CLAUDE_DEV_RUNTIME_ROOT with cli-source for live smoke', async () => {
|
||||
const { resolveLiveSmokeOrchestratorCliPath } = await loadModule();
|
||||
|
||||
expect(
|
||||
resolveLiveSmokeOrchestratorCliPath({
|
||||
env: { CLAUDE_DEV_RUNTIME_ROOT: '/tmp/runtime-source' },
|
||||
repoRoot,
|
||||
})
|
||||
).toBe(path.join('/tmp/runtime-source', 'cli-source'));
|
||||
});
|
||||
|
||||
it('keeps explicit CLI path overrides authoritative', async () => {
|
||||
const { resolveLiveSmokeOrchestratorCliPath } = await loadModule();
|
||||
|
||||
expect(
|
||||
resolveLiveSmokeOrchestratorCliPath({
|
||||
env: { CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH: ' /custom/runtime/cli ' },
|
||||
repoRoot,
|
||||
})
|
||||
).toBe('/custom/runtime/cli');
|
||||
});
|
||||
|
||||
it('keeps release smoke pointed at the built wrapper', async () => {
|
||||
const { resolveReleaseSmokeOrchestratorCliPath } = await loadModule();
|
||||
|
||||
expect(resolveReleaseSmokeOrchestratorCliPath({ env: {}, repoRoot })).toBe(
|
||||
path.join(siblingRuntimeRoot, 'cli')
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
async function loadModule(): Promise<LiveSmokeRuntimeModule> {
|
||||
const moduleUrl = pathToFileURL(
|
||||
path.join(process.cwd(), 'scripts/lib/live-smoke-runtime.mjs')
|
||||
).href;
|
||||
return (await import(`${moduleUrl}?t=${Date.now()}`)) as LiveSmokeRuntimeModule;
|
||||
}
|
||||
Loading…
Reference in a new issue