Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ import { uploadSourcemapsCommand } from './src/commands/upload-sourcemaps';
import { errorTrackingCommand } from './src/commands/error-tracking';
import { skillCommand } from './src/commands/skill';
import { cliCommand } from './src/commands/cli';
import { recoverOrphanedSettingsBackups } from './src/lib/agent/claude-settings';
import { recoverOrphanedSettingsBackups } from './src/lib/claude-settings';

// Heal any .claude/settings backup a previous interrupted run left orphaned,
// before anything else reads Claude settings — conflict detection, OAuth, and
Expand Down
14 changes: 11 additions & 3 deletions scripts/tui-host.no-jest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { buildSession } from '@lib/wizard-session';
import { initLocalDev } from '@lib/local-dev';
import { configureGatewayFromCIEnvironment } from '@lib/gateway-session';
import { runAgent } from '@lib/agent/agent-runner';
import { runConfigFor } from '@lib/programs/run-config';
import { TaskStreamPush, createFileDestination } from '@lib/task-stream/index';
import { getAuditChecks } from '@lib/programs/audit/types';
import { authenticate } from '@lib/agent/runner/shared/authenticate';
Expand Down Expand Up @@ -331,16 +332,23 @@ async function main() {
if (step.screenId === 'auth') {
await authenticate(store.session, programConfig.id);
} else if (step.run) {
await step.run(await runSessionFor(step));
await runAgent(
runConfigFor(getProgramConfig(step.run.programId)),
await runSessionFor(step),
{ composed: true },
);
store.completeRunStep(step.id);
} else if (step.screenId === 'run') {
await runAgent(programConfig, await runSessionFor(step));
await runAgent(
runConfigFor(programConfig),
await runSessionFor(step),
);
} else if (step.isComplete) {
await store.waitUntil(step.isComplete);
}
}
} else {
await runAgent(programConfig, store.session);
await runAgent(runConfigFor(programConfig), store.session);
}
};

Expand Down
36 changes: 1 addition & 35 deletions src/__tests__/architecture/known-violations.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,72 +5,38 @@
"src/lib/agent/mcp-prompt-streaming.ts -> src/ui/tui/services/mcp-suggested-prompts-services.ts",
"src/lib/detection/agentic.ts -> src/lib/agent/agent-interface.ts",
"src/lib/detection/project-scope.ts -> src/lib/agent/runner/shared/authenticate.ts",
"src/lib/errors/agent-map.ts -> src/lib/agent/signals.ts",
"src/lib/programs/agent-skill/index.ts -> src/lib/agent/agent-runner.ts",
"src/lib/programs/agent-skill/index.ts -> src/lib/programs/agent-skill/content/index.tsx",
"src/lib/programs/ai-observability/index.ts -> src/lib/programs/agent-skill/content/index.tsx",
"src/lib/programs/audit/detect.ts -> src/lib/agent/agent-runner.ts",
"src/lib/programs/audit/index.ts -> src/lib/agent/agent-runner.ts",
"src/lib/programs/dispatch-family.ts -> src/commands/command.ts",
"src/lib/programs/dispatch-family.ts -> src/commands/factories/shared.ts",
"src/lib/programs/error-tracking-upload-source-maps/detect.ts -> src/lib/agent/agent-runner.ts",
"src/lib/programs/error-tracking-upload-source-maps/index.ts -> src/lib/agent/agent-runner.ts",
"src/lib/programs/error-tracking-upload-source-maps/index.ts -> src/lib/programs/error-tracking-upload-source-maps/content/index.tsx",
"src/lib/programs/error-tracking-upload-source-maps/prompt.ts -> src/lib/agent/agent-interface.ts",
"src/lib/programs/error-tracking/index.ts -> src/lib/agent/runner/shared/types.ts",
"src/lib/programs/error-tracking/index.ts -> src/lib/programs/error-tracking/content/index.tsx",
"src/lib/programs/error-tracking/index.ts -> src/lib/programs/error-tracking/content/tips.ts",
"src/lib/programs/events-audit/index.ts -> src/lib/agent/agent-runner.ts",
"src/lib/programs/mcp-analytics/index.ts -> src/lib/agent/agent-runner.ts",
"src/lib/programs/metrics/index.ts -> src/lib/programs/agent-skill/content/index.tsx",
"src/lib/programs/migration/index.ts -> src/lib/agent/agent-runner.ts",
"src/lib/programs/migration/index.ts -> src/lib/programs/migration/content/index.tsx",
"src/lib/programs/posthog-integration/index.ts -> src/lib/agent/agent-interface.ts",
"src/lib/programs/posthog-integration/index.ts -> src/lib/agent/agent-runner.ts",
"src/lib/programs/posthog-integration/index.ts -> src/lib/agent/runner/shared/bootstrap.ts",
"src/lib/programs/posthog-integration/index.ts -> src/lib/programs/posthog-integration/content/index.tsx",
"src/lib/programs/program-registry.ts -> src/lib/programs/agent-skill/content/index.tsx",
"src/lib/programs/program-step.ts -> src/lib/agent/agent-runner.ts",
"src/lib/programs/program-step.ts -> src/ui/tui/components/TipsCard.tsx",
"src/lib/programs/program-step.ts -> src/ui/tui/primitives/index.ts",
"src/lib/programs/program-step.ts -> src/ui/tui/store.ts",
"src/lib/programs/replay-vision/index.ts -> src/lib/agent/agent-runner.ts",
"src/lib/programs/revenue-analytics/detect.ts -> src/lib/agent/agent-runner.ts",
"src/lib/programs/revenue-analytics/index.ts -> src/lib/programs/revenue-analytics/content/index.tsx",
"src/lib/programs/self-driving/detect.ts -> src/lib/agent/agent-runner.ts",
"src/lib/programs/self-driving/index.ts -> src/lib/agent/agent-runner.ts",
"src/lib/programs/self-driving/index.ts -> src/lib/programs/self-driving/content/index.tsx",
"src/lib/programs/self-driving/index.ts -> src/lib/programs/self-driving/content/pricing.ts",
"src/lib/programs/self-driving/index.ts -> src/lib/programs/self-driving/content/tips.ts",
"src/lib/programs/self-driving/prompt.ts -> src/lib/agent/agent-interface.ts",
"src/lib/programs/self-driving/prompt.ts -> src/lib/agent/agent-runner.ts",
"src/lib/programs/warehouse-source/detect.ts -> src/lib/agent/agent-runner.ts",
"src/lib/programs/warehouse-source/index.ts -> src/lib/agent/agent-runner.ts",
"src/lib/programs/warehouse-source/index.ts -> src/lib/programs/warehouse-source/content/index.tsx",
"src/lib/programs/web-analytics-doctor/detect.ts -> src/lib/agent/agent-runner.ts",
"src/lib/task-stream/event-plan-watcher.ts -> src/ui/tui/store.ts",
"src/lib/task-stream/task-stream-push.ts -> src/ui/tui/store.ts",
"src/lib/wizard-session.ts -> src/lib/agent/claude-settings.ts",
"src/lib/wizard-tools/index.ts -> src/lib/wizard-tools/mcp.ts",
"src/lib/wizard-tools/tools.ts -> src/lib/yara-hooks.ts",
"src/steps/add-mcp-server-to-clients/index.ts -> src/telemetry.ts",
"src/steps/add-or-update-environment-variables.ts -> src/telemetry.ts",
"src/steps/run-prettier.ts -> src/telemetry.ts",
"src/steps/upload-environment-variables/index.ts -> src/telemetry.ts",
"src/ui/index.ts -> src/ui/logging-ui.ts",
"src/ui/logging-ui.ts -> src/lib/agent/claude-settings.ts",
"src/ui/tui/components/PhaseVisuals.tsx -> src/lib/agent/agent-phase.ts",
"src/ui/tui/components/TokenCostHud.tsx -> src/lib/agent/token-pricing.ts",
"src/ui/tui/exit-line.ts -> src/lib/agent/token-pricing.ts",
"src/ui/tui/ink-ui.ts -> src/lib/agent/claude-settings.ts",
"src/ui/tui/playground/demos/RunScreenDemo.tsx -> src/lib/agent/agent-phase.ts",
"src/ui/tui/screens/ManagedSettingsScreen.tsx -> src/lib/agent/claude-settings.ts",
"src/ui/tui/services/mcp-suggested-prompts-services.ts -> src/lib/agent/mcp-prompt-streaming.ts",
"src/ui/tui/store.ts -> src/lib/agent/claude-settings.ts",
"src/ui/tui/store.ts -> src/lib/agent/token-pricing.ts",
"src/ui/wizard-ui.ts -> src/lib/agent/claude-settings.ts",
"src/utils/package-manager.ts -> src/telemetry.ts",
"src/utils/setup-utils.ts -> src/telemetry.ts",
"src/utils/wizard-abort.ts -> src/ui/logging-ui.ts"
"src/utils/setup-utils.ts -> src/telemetry.ts"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {
sanitizeAgentSubprocessEnv,
isBlockedAgentEnvKey,
BLOCKED_AGENT_ENV_KEYS,
} from '@lib/agent/agent-env-isolation';
} from '@lib/agent-env-isolation';

describe('isBlockedAgentEnvKey', () => {
it('blocks the direct API key that outranks the gateway auth token', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/__tests__/agent-interface.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
reportMcpSetup,
} from '@lib/agent/agent-interface';
import { AgentOutputSignals } from '@lib/agent/output-signals';
import { RESUME_INSTRUCTION } from '@lib/agent/signals';
import { RESUME_INSTRUCTION } from '@lib/agent-signals';
import { analytics } from '@utils/analytics';
import { wizardAbort } from '@utils/wizard-abort';
import { Sequence } from '@lib/constants';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
backupAndFixClaudeSettings,
restoreClaudeSettings,
recoverOrphanedSettingsBackups,
} from '@lib/agent/claude-settings';
} from '@lib/claude-settings';

const SETTINGS = 'settings.json';
const BACKUP = 'settings.json.wizard-backup';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
* isolation surface — a diff here means a credential path changed disposition.
*/

import { sanitizeAgentSubprocessEnv } from '@lib/agent/agent-env-isolation';
import { classifySettingsConflicts } from '@lib/agent/claude-settings';
import type { SettingsConflict } from '@lib/agent/claude-settings';
import { sanitizeAgentSubprocessEnv } from '@lib/agent-env-isolation';
import { classifySettingsConflicts } from '@lib/claude-settings';
import type { SettingsConflict } from '@lib/claude-settings';

// Every env-based avenue (one key each), plus the gateway routing and benign
// env that must survive. Grouped by avenue for readability; the snapshot sorts.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import {
checkAllSettingsConflicts,
managedSettingsPath,
classifySettingsConflicts,
} from '@lib/agent/claude-settings';
import type { SettingsConflict } from '@lib/agent/claude-settings';
} from '@lib/claude-settings';
import type { SettingsConflict } from '@lib/claude-settings';
import { buildAuthErrorContext } from '@lib/agent/agent-interface';

const OVERRIDE = JSON.stringify({ apiKeyHelper: 'echo sk-x' });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
pricePerMtokForModel,
formatTokenCount,
formatCostUsd,
} from '@lib/agent/token-pricing';
} from '@lib/token-pricing';

describe('pricePerMtokForModel', () => {
it('defaults to Sonnet pricing (DEFAULT_AGENT_MODEL) when no model is given', () => {
Expand Down
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion src/lib/agent/__tests__/output-signals.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AgentOutputSignals } from '@lib/agent/output-signals';
import { AgentSignals, REMARK_INSTRUCTION } from '@lib/agent/signals';
import { AgentSignals, REMARK_INSTRUCTION } from '@lib/agent-signals';

describe('REMARK_INSTRUCTION', () => {
it('carries the marker but no literal placeholder a model could echo', () => {
Expand Down
10 changes: 5 additions & 5 deletions src/lib/agent/agent-interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,28 +53,28 @@ import {
AgentErrorType,
REMARK_INSTRUCTION,
RESUME_INSTRUCTION,
} from './signals';
} from '@lib/agent-signals';
import { classifyAuthFailure } from '@lib/errors';
import { isGrantRevoked } from '@lib/auth-session-state';
import { AgentOutputSignals } from './output-signals';

// Signal vocabulary and the output parser live in dedicated modules; re-export
// so existing importers of these from agent-interface keep working.
export { AgentSignals, AgentErrorType } from './signals';
export type { AgentSignal } from './signals';
export { AgentSignals, AgentErrorType } from '@lib/agent-signals';
export type { AgentSignal } from '@lib/agent-signals';
export { AgentOutputSignals } from './output-signals';
import {
checkAllSettingsConflicts,
type SettingsConflict,
type SettingsConflictSource,
} from './claude-settings';
} from '@lib/claude-settings';
import {
detectStoredClaudeLogin,
hasStoredClaudeLogin,
claudeConfigDir,
createIsolatedAgentConfigDir,
} from './stored-login';
import { sanitizeAgentSubprocessEnv } from './agent-env-isolation';
import { sanitizeAgentSubprocessEnv } from '@lib/agent-env-isolation';

// Dynamic import cache for ESM module
let _sdkModule: any = null;
Expand Down
32 changes: 2 additions & 30 deletions src/lib/agent/agent-prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,9 @@
* 3. Skill prompt — "follow SKILL.md" instructions (if a skill was installed)
*/

import type { ProgramRun } from './agent-runner.js';
import type { HostResolution } from '@lib/host-resolution';
import type { ProgramRun, PromptContext } from '@lib/program-run';

/**
* Values available to prompt builders after OAuth completes.
*/
export interface PromptContext {
projectId: number;
projectApiKey: string;
host: HostResolution;
/** Set when skillId was provided and the skill was installed successfully. */
skillPath?: string;
/**
* Org-level AI consent (`is_ai_data_processing_approved`) read from the
* `/api/users/@me/` payload at auth time. `null` = unknown (older orgs,
* or the user fetch failed). Lets prompts pre-resolve consent state so
* agents only ask the user when it is actually off or unknown.
*/
orgAiDataProcessingApproved?: boolean | null;
/**
* Team product opt-ins from the `/api/projects/:id/` payload at auth
* time. Project-level truth for "is this product enabled" — products
* can be instrumented from other repos or the snippet, so repo-local
* evidence must never rule them out. `null` field = unknown.
*/
teamProductOptIns?: {
sessionReplay?: boolean | null;
exceptionAutocapture?: boolean | null;
surveys?: boolean | null;
} | null;
}
export type { PromptContext };

function defaultProjectPrompt(ctx: PromptContext): string {
return `You have access to the PostHog MCP server.
Expand Down
1 change: 1 addition & 0 deletions src/lib/agent/agent-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export {
runProgram,
shouldDisableAsk,
type ProgramRun,
type ProgramRunConfig,
type BootstrapResult,
type AbortCase,
type PromptContext,
Expand Down
2 changes: 1 addition & 1 deletion src/lib/agent/mcp-prompt-streaming.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { DEFAULT_AGENT_MODEL, WIZARD_USER_AGENT } from '@lib/constants';
import { logToFile } from '@utils/debug';
import { gatewayAuth } from '@lib/gateway-session';
import { buildAgentEnv, buildRunTags } from '@lib/agent/agent-interface';
import { sanitizeAgentSubprocessEnv } from '@lib/agent/agent-env-isolation';
import { sanitizeAgentSubprocessEnv } from '@lib/agent-env-isolation';
import { createIsolatedAgentConfigDir } from '@lib/agent/stored-login';
import { analytics } from '@utils/analytics';

Expand Down
2 changes: 1 addition & 1 deletion src/lib/agent/output-signals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* hooks' onTerminate callback (`yaraViolationReason` in runAgent) instead.
*/

import { AgentSignals, REMARK_INSTRUCTION } from './signals';
import { AgentSignals, REMARK_INSTRUCTION } from '@lib/agent-signals';

/**
* Single source of truth for the substrings runAgent scans agent output for.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { completionFailure, runErrorType } from '../completion';
import { AgentErrorType } from '@lib/agent/signals';
import { AgentErrorType } from '@lib/agent-signals';

describe('completionFailure', () => {
it('fails a no-op run (zero tool calls) as NO_PROGRESS', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

import { describe, it, expect } from 'vitest';
import { AgentSignals } from '@lib/agent/signals';
import { AgentSignals } from '@lib/agent-signals';
import { lastStatusLine } from '..';

const S = AgentSignals.STATUS; // '[STATUS]'
Expand Down
2 changes: 1 addition & 1 deletion src/lib/agent/runner/harness/pi/completion.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AgentErrorType } from '@lib/agent/signals';
import { AgentErrorType } from '@lib/agent-signals';

/** Which completion guard should fail a pi run, or undefined for a clean finish. */
export function completionFailure(args: {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/agent/runner/harness/pi/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
} from '@lib/constants';
import { analytics } from '@utils/analytics';
import { AgentErrorType } from '@lib/agent/agent-interface';
import { AgentSignals, REMARK_INSTRUCTION } from '@lib/agent/signals';
import { AgentSignals, REMARK_INSTRUCTION } from '@lib/agent-signals';
import { AgentOutputSignals } from '@lib/agent/output-signals';
import { assembleCommandments } from '../../switchboard/commandments';
import { gatewayAuth, type GatewayAuth } from '@lib/gateway-session';
Expand Down
2 changes: 1 addition & 1 deletion src/lib/agent/runner/harness/pi/task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {
renderToolInventory,
} from '@lib/agent/agent-prompt-loader';
import { AgentErrorType } from '@lib/agent/agent-interface';
import { REMARK_INSTRUCTION } from '@lib/agent/signals';
import { REMARK_INSTRUCTION } from '@lib/agent-signals';
import { AgentOutputSignals } from '@lib/agent/output-signals';
import { TaskStatus } from '../../sequence/orchestrator/queue';
import type { OrchestratorToolsContext } from '../../sequence/orchestrator/queue-tools';
Expand Down
6 changes: 3 additions & 3 deletions src/lib/agent/runner/harness/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import type { WizardSession } from '@lib/wizard-session';
import type { AdditionalFeature } from '@lib/wizard-session';
import type { Harness } from '@lib/constants';
import type { ProgramConfig } from '@lib/programs/program-step';
import type { ProgramRunConfig } from '@lib/program-run';
import type { SpinnerHandle } from '@ui';
import type { WizardAskBridge } from '@lib/wizard-ask-bridge';
import type { AgentErrorType } from '@lib/agent/agent-interface';
Expand Down Expand Up @@ -46,7 +46,7 @@ export interface RunMiddleware {
export interface BackendRunInputs {
session: WizardSession;
config: ProgramRun;
programConfig: ProgramConfig;
programConfig: ProgramRunConfig;
boot: BootstrapResult;
/** The fully assembled prompt. */
prompt: string;
Expand Down Expand Up @@ -76,7 +76,7 @@ export type AgentResult = { error?: AgentErrorType; message?: string };
*/
export interface TaskRunInputs {
session: WizardSession;
programConfig: ProgramConfig;
programConfig: ProgramRunConfig;
boot: BootstrapResult;
/** The fully assembled per-task or seed prompt. */
prompt: string;
Expand Down
Loading
Loading