diff --git a/.claude/skills/adding-framework-support/SKILL.md b/.claude/skills/adding-framework-support/SKILL.md index 671b0ad24..903ef23f0 100644 --- a/.claude/skills/adding-framework-support/SKILL.md +++ b/.claude/skills/adding-framework-support/SKILL.md @@ -20,8 +20,8 @@ creating its own runner or changing existing routing defaults. ## Extend the framework configuration -Start with [FrameworkConfig](../../../src/lib/framework-config.ts) and a nearby -example under [src/frameworks](../../../src/frameworks/). Framework-specific +Start with [FrameworkConfig](../../../src/programs/framework-config.ts) and a nearby +example under [src/programs/frameworks](../../../src/programs/frameworks/). Framework-specific detection, context, environment conventions, and UI metadata belong here. Integration instructions and examples belong in context-mill. @@ -29,16 +29,16 @@ Integration instructions and examples belong in context-mill. order controls first-match detection and the framework picker. Keep specific frameworks before language fallbacks and generic Node last; preserve the overlap rules in the - [detection checks](../../../src/lib/detection/__tests__/framework.test.ts). -2. Add the config under `src/frameworks//-wizard-agent.ts`. Use a + [detection checks](../../../src/programs/detection/__tests__/framework.test.ts). +2. Add the config under `src/programs/frameworks//-wizard-agent.ts`. Use a `type` for framework context so it satisfies `Record`. Export the config; the integration program already supplies execution. -3. Import the config into [FRAMEWORK_REGISTRY](../../../src/lib/registry.ts). +3. Import the config into [FRAMEWORK_REGISTRY](../../../src/programs/frameworks/registry.ts). The display label comes from `metadata.name`. Read the current interface for the complete required fields. In particular, `detection.detectPackageManager` is required: reuse an adapter from -[package-manager detection](../../../src/lib/detection/package-manager.ts). Use +[package-manager detection](../../../src/programs/detection/package-manager.ts). Use `metadata.setup.questions` for unresolved project variants; `gatherContext` collects framework context. Optional notices and extra MCP servers also belong in metadata. @@ -46,7 +46,7 @@ in metadata. Use `usesPackageJson: false` for frameworks without a package.json dependency. Their required `getVersion` callback can return `undefined`. Minimum-version checking requires both `minimumVersion` and `getInstalledVersion`; unknown -versions pass. [Context detection](../../../src/lib/detection/context.ts) +versions pass. [Context detection](../../../src/programs/detection/context.ts) returns unsupported-version data for the integration UI rather than aborting itself. @@ -54,10 +54,10 @@ itself. | Starting point | Pattern to reuse | | ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | -| [Next.js](../../../src/frameworks/nextjs/) | `hasDeclaredDependency` from `utils/package-json`, `tryGetPackageJson` from `utils/setup-utils`, and router setup questions | -| [Django](../../../src/frameworks/django/) | Python project files, context gathering, and Python package-manager detection | -| [Laravel](../../../src/frameworks/laravel/) | Composer and framework-specific filesystem signals | -| [Rails](../../../src/frameworks/rails/) | Gemfile detection and Ruby conventions | +| [Next.js](../../../src/programs/frameworks/nextjs/) | `hasDeclaredDependency` from `utils/package-json`, `tryGetPackageJson` from `utils/setup-utils`, and router setup questions | +| [Django](../../../src/programs/frameworks/django/) | Python project files, context gathering, and Python package-manager detection | +| [Laravel](../../../src/programs/frameworks/laravel/) | Composer and framework-specific filesystem signals | +| [Rails](../../../src/programs/frameworks/rails/) | Gemfile detection and Ruby conventions | Use [bounded filesystem helpers](../../../src/shared/utils/bounded-fs.ts) for project scans and reads. They bound traversal and skip dependency/build directories; add @@ -88,7 +88,7 @@ content-mill variants. For an end-to-end run, use a disposable test app and the [exploration guide](../exploring-the-wizard/SKILL.md). For prompt, environment-upload, or outro changes, inspect the current -[integration program](../../../src/lib/programs/posthog-integration/) and the +[integration program](../../../src/programs/posthog-integration/) and the selected sequence. Some fields remain in the interface without a current consumer: `getOutroNextSteps` is not used by the integration outro. Linear post-run/outro hooks are not shared by the orchestrator; see the diff --git a/.claude/skills/adding-skill-program/SKILL.md b/.claude/skills/adding-skill-program/SKILL.md index 60c3f8fb3..3aedd8778 100644 --- a/.claude/skills/adding-skill-program/SKILL.md +++ b/.claude/skills/adding-skill-program/SKILL.md @@ -32,10 +32,10 @@ them. [Context-mill](https://github.com/PostHog/context-mill) owns skill content and `cliEntries`. A new skill-backed child of an existing family ships through context-mill; inspect - [family dispatch](../../../src/lib/programs/dispatch-family.ts). Unpromoted + [family dispatch](../../../src/programs/dispatch-family.ts). Unpromoted skills run through [the skill command](../../../src/commands/skill.ts). - **Native program:** use a - [ProgramConfig](../../../src/lib/programs/program-step.ts) when the wizard + [ProgramConfig](../../../src/programs/program-step.ts) when the wizard needs its own flow, screens, detection, composition, or other native behavior. Keep product instructions in context-mill. @@ -45,12 +45,12 @@ is `id`, not the retired `flowKey`. ## Build a native orchestrator program -Use [metrics](../../../src/lib/programs/metrics/) as the current Pi/orchestrator +Use [metrics](../../../src/programs/metrics/) as the current Pi/orchestrator example and read the [runner architecture](../wizard-development/references/ARCHITECTURE.md) when changing execution behavior. -1. Add the program config under `src/lib/programs//`. Set `agentFlow` when +1. Add the program config under `src/programs//`. Set `agentFlow` when its content-mill flow differs from `id`; setting it explicitly also documents the content dependency. Keep a `run` definition so the outer runner executes agent work. @@ -60,7 +60,7 @@ changing execution behavior. loads `agentFlow ?? id`, requires a seed prompt, and checks task-skill variants before running. `run.skillId` alone does not define this flow. 3. Register the config in - [PROGRAM_REGISTRY](../../../src/lib/programs/program-registry.ts) and add its + [PROGRAM_REGISTRY](../../../src/programs/program-registry.ts) and add its Pi/orchestrator entry to [PROGRAM_BINDINGS](../../../src/agent/runner/switchboard/index.ts). [Existing binding checks](../../../src/agent/runner/__tests__/switchboard.test.ts) @@ -70,7 +70,7 @@ changing execution behavior. and register it in [bin.ts](../../../bin.ts). A native family child uses the handlers in family dispatch. Program registration derives screen sequences and store lookup, not the top-level CLI `.use()` chain. -5. Check [program OAuth scopes](../../../src/lib/oauth/program-scopes.ts) +5. Check [program OAuth scopes](../../../src/programs/oauth/program-scopes.ts) against the tools the program needs; add scopes only when the base set is insufficient. @@ -82,13 +82,13 @@ or changing gateway-required prompt material. ## Simple linear programs and existing flows For a very simple linear flow, use -[createSkillProgram](../../../src/lib/programs/agent-skill/index.ts) to +[createSkillProgram](../../../src/programs/agent-skill/index.ts) to configure installation of one skill. Register the native program as above with an explicit Pi/linear binding; the factory does not select a sequence. Read `SkillProgramOptions` for required fields; -[audit](../../../src/lib/programs/audit/) demonstrates factory customization and +[audit](../../../src/programs/audit/) demonstrates factory customization and a dynamic `run(session)` that seeds a ledger. -[Revenue analytics](../../../src/lib/programs/revenue-analytics/) builds its +[Revenue analytics](../../../src/programs/revenue-analytics/) builds its config directly and adds prerequisite detection. `ProgramRun.customPrompt`, `abortCases`, `postRun`, and `buildOutroData` are @@ -102,9 +102,9 @@ does not preserve these behaviors automatically. ## Screens, prerequisites, and composition -Reuse [AGENT_SKILL_STEPS](../../../src/lib/programs/agent-skill/steps.ts): +Reuse [AGENT_SKILL_STEPS](../../../src/programs/agent-skill/steps.ts): intro, health check, auth, run, outro, and keep-skills. Auth also applies the -shared [AI opt-in gate](../../../src/lib/programs/ai-opt-in-gate.ts) for agent +shared [AI opt-in gate](../../../src/programs/ai-opt-in-gate.ts) for agent programs. Override `screenId`, not `screen`, when adapting a step. New screens need an entry in [ScreenId](../../../src/ui/tui/screen-sequences.ts), a component, and registration in @@ -123,12 +123,12 @@ prerequisite strategy. `requires` currently records metadata; it does not execute or enforce prior programs. Compose real work through `ProgramStep.run`, with `onRunPrep` and `targetDir` when needed. The -[integration run step](../../../src/lib/programs/posthog-integration/index.ts) -and [self-driving](../../../src/lib/programs/self-driving/) demonstrate this. +[integration run step](../../../src/programs/posthog-integration/index.ts) +and [self-driving](../../../src/programs/self-driving/) demonstrate this. Composed sub-runs are structurally linear; orchestrators cannot nest. A host run step without `run` can also set `targetDir` and `onRunPrep` to scope the program's own agent to a picked project and keep its sequence, as -[error-tracking](../../../src/lib/programs/error-tracking/) does. +[error-tracking](../../../src/programs/error-tracking/) does. ## Validate the affected path diff --git a/.claude/skills/exploring-the-wizard/SKILL.md b/.claude/skills/exploring-the-wizard/SKILL.md index 2dc754f74..4ac32d73f 100644 --- a/.claude/skills/exploring-the-wizard/SKILL.md +++ b/.claude/skills/exploring-the-wizard/SKILL.md @@ -129,5 +129,5 @@ The shared log is `/tmp/posthog-wizard.log`. Record its byte count before a run and read from that count plus one afterward. Run sweeps serially so their logs remain attributable. `read_state` omits `frameworkContext`; an empty `setupQuestions` list alone does not prove a router mode. When necessary, -inspect the detector under [`src/frameworks/`](../../../src/frameworks/) against +inspect the detector under [`src/programs/frameworks/`](../../../src/programs/frameworks/) against the same fixture. diff --git a/.claude/skills/ink-tui/SKILL.md b/.claude/skills/ink-tui/SKILL.md index 590640ee6..d7a1f2247 100644 --- a/.claude/skills/ink-tui/SKILL.md +++ b/.claude/skills/ink-tui/SKILL.md @@ -40,7 +40,7 @@ conventions rather than copying upstream component manuals. 3. Register the component in [screen-registry.tsx](../../../src/ui/tui/screen-registry.tsx). 4. Reference it through `screenId` in the owning - [program's steps](../../../src/lib/programs/), with the appropriate + [program's steps](../../../src/programs/), with the appropriate visibility, completion, and gate predicates. Screen sequences derive from program steps. Do not hand-maintain a second diff --git a/.claude/skills/ink-tui/references/ARCHITECTURE.md b/.claude/skills/ink-tui/references/ARCHITECTURE.md index fdf59395c..9521fac74 100644 --- a/.claude/skills/ink-tui/references/ARCHITECTURE.md +++ b/.claude/skills/ink-tui/references/ARCHITECTURE.md @@ -5,7 +5,7 @@ | Surface | Owns | | ----------------------------------------------------------------- | ----------------------------------------------------------------------------- | | [WizardSession](../../../../src/lib/wizard-session.ts) | Run configuration, decisions, credentials, and lifecycle state | -| [ProgramStep](../../../../src/lib/programs/program-step.ts) | Screens, visibility/completion predicates, gates, and initialization hooks | +| [ProgramStep](../../../../src/programs/program-step.ts) | Screens, visibility/completion predicates, gates, and initialization hooks | | [screen-sequences.ts](../../../../src/ui/tui/screen-sequences.ts) | `ScreenId`, `Screen`, `Sequence`, and the derived `PROGRAM_SEQUENCES` | | [WizardRouter](../../../../src/ui/tui/router.ts) | Resolution and the `Overlay` stack | | [WizardStore](../../../../src/ui/tui/store.ts) | Reactive state, gate promises, display observations, and pending interactions | @@ -17,7 +17,7 @@ entries: `id`, `show`, and `isComplete`. Completion defaults to the step's `gate` when no separate `isComplete` is provided. Steps without a screen are omitted, and the exit screen is appended. The projection applies -[withAiOptInGate](../../../../src/lib/programs/ai-opt-in-gate.ts) consistently +[withAiOptInGate](../../../../src/programs/ai-opt-in-gate.ts) consistently with store gate creation. `WizardRouter.resolve(session)` first checks the overlay stack, then returns the diff --git a/.claude/skills/wizard-development/SKILL.md b/.claude/skills/wizard-development/SKILL.md index cde67b09b..5fee5c7a5 100644 --- a/.claude/skills/wizard-development/SKILL.md +++ b/.claude/skills/wizard-development/SKILL.md @@ -19,9 +19,9 @@ infrastructure should consume those boundaries. | Concern | Owner | | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Framework detection, context, env conventions | [FrameworkConfig](../../../src/lib/framework-config.ts) and [framework configs](../../../src/frameworks/) | +| Framework detection, context, env conventions | [FrameworkConfig](../../../src/programs/framework-config.ts) and [framework configs](../../../src/programs/frameworks/) | | Integration instructions and orchestrator flows/tasks | [context-mill](https://github.com/PostHog/context-mill) | -| Programs, steps, prerequisites and outcomes | [programs](../../../src/lib/programs/) | +| Programs, steps, prerequisites and outcomes | [programs](../../../src/programs/) | | Sequence, harness, model and effort selection | [switchboard](../../../src/agent/runner/switchboard/) | | Local tool permissions and scanner adapters | [agent-interface](../../../src/agent/agent-interface.ts), [YARA hooks](../../../src/agent/yara-hooks.ts), [Pi security](../../../src/agent/runner/harness/pi/security.ts) | | Scanner rules | [warlock](https://github.com/PostHog/warlock) | @@ -34,7 +34,7 @@ infrastructure should consume those boundaries. are separate: Pi supports gateway-backed Anthropic and OpenAI transports. - **Prefer orchestration.** A seed agent plans work, then task agents execute focused conversations. Start from - [metrics](../../../src/lib/programs/metrics/) and its context-mill flow. + [metrics](../../../src/programs/metrics/) and its context-mill flow. - **Linear is for very simple tasks and legacy support.** Composed program sub-runs are also structurally clamped to linear; orchestration cannot nest through that seam. diff --git a/.claude/skills/wizard-development/references/ARCHITECTURE.md b/.claude/skills/wizard-development/references/ARCHITECTURE.md index c29badcf2..570d1e5e1 100644 --- a/.claude/skills/wizard-development/references/ARCHITECTURE.md +++ b/.claude/skills/wizard-development/references/ARCHITECTURE.md @@ -54,7 +54,7 @@ signatures. Do not migrate a linear program merely by changing its binding if it depends on these hooks. Inspect the orchestrator's flow and completion path instead. -[Metrics](../../../../src/lib/programs/metrics/) is a current Pi/orchestrator +[Metrics](../../../../src/programs/metrics/) is a current Pi/orchestrator example. Native command modules still need registration in [bin.ts](../../../../bin.ts); screen sequences derive from the program registry. diff --git a/.eslintrc.cjs b/.eslintrc.cjs index e6eb9c9e1..a60c79a0a 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -34,8 +34,8 @@ module.exports = { // The agent surface. It takes resolved data in, reports through // progress events and asks through an injected answerer, so nothing // here may import a UI, the session, detection, the CLI or a program. - // Only direct static imports are checked. Program types stay importable - // until B1 moves PROGRAM_BINDINGS to programs. + // Only direct static imports are checked. ProgramId remains a type-only + // exception until PROGRAM_BINDINGS moves to programs. files: ['src/agent/**/*.ts'], excludedFiles: ['**/__tests__/**'], rules: { @@ -64,9 +64,7 @@ module.exports = { '**/ui', '**/ui/**', '@lib/**', - '!@lib/programs/**', '**/lib/**', - '!**/lib/programs/**', '**/wizard-session', '**/detection', '**/detection/**', @@ -77,7 +75,6 @@ module.exports = { '@steps/**', '**/steps', '**/steps/**', - '@frameworks/**', '**/frameworks/**', '@utils/setup-utils', '@shared/utils/setup-utils', @@ -90,10 +87,10 @@ module.exports = { 'The agent reports through progress events and asks through AgentInteraction; it takes everything else through RunConfig and RunInput.', }, { - group: ['@lib/programs/**', '**/programs/**'], + group: ['@programs', '@programs/**', '**/programs/**'], allowTypeImports: true, message: - 'The agent takes program data through RunConfig. Types only, until B1 moves PROGRAM_BINDINGS to programs.', + 'The agent takes program data through RunConfig. ProgramId types remain until PROGRAM_BINDINGS moves to programs.', }, ], }, diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 48f68a2a9..7bceb017f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -8,16 +8,22 @@ * @PostHog/team-wizard-docs # Team-owned programs -/src/lib/programs/ai-observability/ @PostHog/team-ai-observability -/src/lib/programs/error-tracking-upload-source-maps/ @PostHog/team-error-tracking -/src/lib/programs/mcp-analytics/ @PostHog/team-mcp-analytics -/src/lib/programs/metrics/ @PostHog/apm -/src/lib/programs/posthog-integration/ @PostHog/team-wizard-docs -/src/lib/programs/replay-vision/ @PostHog/team-replay -/src/lib/programs/revenue-analytics/ @PostHog/team-web-analytics -/src/lib/programs/self-driving/ @PostHog/team-self-driving -/src/lib/programs/warehouse-source/ @PostHog/team-warehouse-sources -/src/lib/programs/web-analytics-doctor/ @PostHog/team-web-analytics +/src/programs/ai-observability/ @PostHog/team-ai-observability +/src/programs/error-tracking-upload-source-maps/ @PostHog/team-error-tracking +/src/programs/mcp-analytics/ @PostHog/team-mcp-analytics +/src/programs/metrics/ @PostHog/apm +/src/programs/posthog-integration/ @PostHog/team-wizard-docs +/src/programs/replay-vision/ @PostHog/team-replay +/src/programs/revenue-analytics/ @PostHog/team-web-analytics +/src/programs/self-driving/ @PostHog/team-self-driving +/src/programs/warehouse-source/ @PostHog/team-warehouse-sources +/src/programs/web-analytics-doctor/ @PostHog/team-web-analytics + +# Team-owned program decks +/src/ui/tui/decks/error-tracking-upload-source-maps/ @PostHog/team-error-tracking +/src/ui/tui/decks/revenue-analytics/ @PostHog/team-web-analytics +/src/ui/tui/decks/self-driving/ @PostHog/team-self-driving +/src/ui/tui/decks/warehouse-source/ @PostHog/team-warehouse-sources # Agent runner (harness, model, and tools) /src/agent/ @PostHog/team-wizard-docs diff --git a/AGENTS.md b/AGENTS.md index ad66039db..773faf9cf 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -19,7 +19,7 @@ configuration surfaces. Each domain has a dedicated boundary: -- **Frameworks** → `FrameworkConfig` in `src/frameworks//` +- **Frameworks** → `FrameworkConfig` in `src/programs/frameworks//` - **Integration knowledge** → markdown skills in the [context-mill](https://github.com/PostHog/context-mill) repo - **Security policy** → YARA-X rules in the @@ -34,8 +34,10 @@ Each domain has a dedicated boundary: `@agent/types` (types); see [src/agent/README.md](src/agent/README.md) - **Shared** → `src/shared/`, stateless library code with no upward imports; see [src/shared/README.md](src/shared/README.md) -- **Programs** → step arrays in `src/lib/programs/` -- **TUI** → screen components and primitives in `src/ui/tui/` +- **Programs** → configs, detection, framework registry and task stream in + `src/programs/`; runtime and type entries are `@programs` and + `@programs/types` +- **TUI** → screens, primitives and content decks in `src/ui/tui/` Adding a new concern means finding the narrowest existing surface, not adding logic to the runner. Keep changes local to the boundary that owns them. @@ -131,7 +133,7 @@ confuse it with the top-level `wizard skill` command. ([`src/commands/factories/native-command-factory.ts`](src/commands/factories/native-command-factory.ts)). - **Family commands** (e.g. `audit`) resolve subcommands at runtime against the `cliEntries` in `skill-menu.json`. Logic lives in - [`src/lib/programs/dispatch-family.ts`](src/lib/programs/dispatch-family.ts). + [`src/programs/dispatch-family.ts`](src/programs/dispatch-family.ts). Adding a skill-backed subcommand is a **context-mill** release, not a wizard change. diff --git a/README.md b/README.md index ff6e05260..f08942c45 100644 --- a/README.md +++ b/README.md @@ -149,20 +149,27 @@ npx @posthog/wizard@latest skill # run one by name Reviews are auto-requested via [`.github/CODEOWNERS`](.github/CODEOWNERS) — the file is the source of truth; this table just mirrors it for readability. -`team-wizard-docs` is the default reviewer; the team-owned programs below +`team-wizard-docs` is the default reviewer; the team-owned paths below route review to their owning team instead. | Path | Owning team | |---|---| | `*` (everything else, including all other programs) | `@PostHog/team-wizard-docs` | | `src/agent/` | `@PostHog/team-wizard-docs` | -| `src/lib/programs/posthog-integration/` | `@PostHog/team-wizard-docs` | -| `src/lib/programs/error-tracking-upload-source-maps/` | `@PostHog/team-error-tracking` | -| `src/lib/programs/mcp-analytics/` | `@PostHog/team-mcp-analytics` | -| `src/lib/programs/revenue-analytics/` | `@PostHog/team-web-analytics` | -| `src/lib/programs/self-driving/` | `@PostHog/team-self-driving` | -| `src/lib/programs/warehouse-source/` | `@PostHog/team-warehouse-sources` | -| `src/lib/programs/web-analytics-doctor/` | `@PostHog/team-web-analytics` | +| `src/programs/ai-observability/` | `@PostHog/team-ai-observability` | +| `src/programs/posthog-integration/` | `@PostHog/team-wizard-docs` | +| `src/programs/error-tracking-upload-source-maps/` | `@PostHog/team-error-tracking` | +| `src/programs/mcp-analytics/` | `@PostHog/team-mcp-analytics` | +| `src/programs/metrics/` | `@PostHog/apm` | +| `src/programs/replay-vision/` | `@PostHog/team-replay` | +| `src/programs/revenue-analytics/` | `@PostHog/team-web-analytics` | +| `src/programs/self-driving/` | `@PostHog/team-self-driving` | +| `src/programs/warehouse-source/` | `@PostHog/team-warehouse-sources` | +| `src/programs/web-analytics-doctor/` | `@PostHog/team-web-analytics` | +| `src/ui/tui/decks/error-tracking-upload-source-maps/` | `@PostHog/team-error-tracking` | +| `src/ui/tui/decks/revenue-analytics/` | `@PostHog/team-web-analytics` | +| `src/ui/tui/decks/self-driving/` | `@PostHog/team-self-driving` | +| `src/ui/tui/decks/warehouse-source/` | `@PostHog/team-warehouse-sources` | Ownership is by directory. Programs not listed above (`agent-skill`, `audit`, `events-audit`, `mcp`, `migration`, `posthog-doctor`, @@ -273,7 +280,7 @@ health_issue:read wizard_session:read wizard_session:write wizard_run:write The source of truth is `WIZARD_OAUTH_SCOPES` in `src/shared/constants.ts`, which documents why each scope is needed — if this block drifts, trust the code. Some programs request more on top (`PROGRAM_SCOPE_ADDITIONS` in -`src/lib/oauth/program-scopes.ts`); the default integration flow adds +`src/programs/oauth/program-scopes.ts`); the default integration flow adds `integration:read` and `external_data_source:read` / `external_data_source:write`. @@ -292,7 +299,7 @@ does not add the grant. Run synchronization needs no read scope. The wizard's OAuth app on the PostHog side caps the scopes its tokens may carry (`OAuthApplication.scopes`). Any scope requested in this repo (see -`src/lib/oauth/program-scopes.ts`) must be grantable under that ceiling, or +`src/programs/oauth/program-scopes.ts`) must be grantable under that ceiling, or `/authorize` drops it and the call that needs it 403s. **A granted token can be narrower than the request even with a correct @@ -518,11 +525,13 @@ Path aliases defined in `tsconfig.build.json`, resolved by tsdown: | `@agent` | `src/agent/index.ts`, the agent's runtime entry; the only agent import outside `src/agent` besides types | | `@agent/types` | `src/agent/types.ts`, type-only | | `@agent/*` | `src/agent/*`, inside `src/agent` and its tests only | +| `@programs` | `src/programs/index.ts`, the programs runtime entry | +| `@programs/types` | `src/programs/types.ts`, type-only | +| `@programs/*` | `src/programs/*`, retained for internal imports and tracked migration edges | | `@shared/*` | `src/shared/*` | | `@utils/*` | `src/shared/utils/*` | | `@ui/*` | `src/ui/*` | | `@steps/*` | `src/steps/*` | -| `@frameworks/*` | `src/frameworks/*` | ## Running locally diff --git a/docs/error-catalog.md b/docs/error-catalog.md index c162e2897..ef7592a48 100644 --- a/docs/error-catalog.md +++ b/docs/error-catalog.md @@ -11,7 +11,7 @@ classify failures without parsing human-readable messages. [`src/shared/errors/catalog.ts`](../src/shared/errors/catalog.ts) - **Consumers:** `wizardAbort()` ([`src/shared/utils/wizard-abort.ts`](../src/shared/utils/wizard-abort.ts)), the task stream - ([`src/lib/task-stream/`](../src/lib/task-stream/)), and non-interactive hosts + ([`src/programs/task-stream/`](../src/programs/task-stream/)), and non-interactive hosts reading stderr. ## Stability contract @@ -117,7 +117,7 @@ guarantee. Program detect steps write `{ kind, ...detail }` into `session.frameworkContext.detectError`. `detectErrorCode()` -([`src/lib/programs/detect-map.ts`](../src/lib/programs/detect-map.ts)) maps `kind` +([`src/programs/detect-map.ts`](../src/programs/detect-map.ts)) maps `kind` → code, and the whole object — `kind` included — rides along as `OutroData.errorDetail`. diff --git a/docs/runbooks/agentic-monorepo-detection.md b/docs/runbooks/agentic-monorepo-detection.md index 36fbd8664..6bb3f3212 100644 --- a/docs/runbooks/agentic-monorepo-detection.md +++ b/docs/runbooks/agentic-monorepo-detection.md @@ -17,7 +17,9 @@ it. - We take the recommended supported project, else the first supported PostHog-free one, and re-point the install dir there. - On a single-repo project it recommends `.`, so nothing moves. -- If the scan errors, times out (60s, `AGENTIC_DETECTION_TIMEOUT_MS`), or finds +- The scan gets two attempts, 60s then 90s + (`AGENTIC_DETECTION_FIRST_ATTEMPT_TIMEOUT_MS`, + `AGENTIC_DETECTION_RETRY_TIMEOUT_MS`). If both error or time out, or it finds nothing, `session.installDir` is left untouched and the run falls back to the old root detection, exactly like flag-off. @@ -35,10 +37,10 @@ it. - Only non-interactive basic-integration runs — headless and `--ci`. Interactive runs have their own detect step and never enter it. -- Phase: `scopeInstallDirToProject` in `src/lib/detection/project-scope.ts`, +- Phase: `scopeInstallDirToProject` in `src/programs/detection/project-scope.ts`, called from the top of `ciPreRun` in - `src/lib/programs/posthog-integration/index.ts`. -- Detector: `detectProjectsWithAgent` in `src/lib/detection/agentic.ts`; + `src/programs/posthog-integration/index.ts`. +- Detector: `detectProjectsWithAgent` in `src/programs/detection/agentic.ts`; self-driving uses the same detector with its own chooser. - Each run fires one `wizard: agentic detection` event tagged with the outcome (`flag-off | error | timeout | no-project | recommended | first-instrumentable`). diff --git a/e2e-harness/__tests__/e2e-flow-snapshot.test.ts b/e2e-harness/__tests__/e2e-flow-snapshot.test.ts index 272105bc6..ab0c24fcc 100644 --- a/e2e-harness/__tests__/e2e-flow-snapshot.test.ts +++ b/e2e-harness/__tests__/e2e-flow-snapshot.test.ts @@ -19,15 +19,15 @@ import { setUI } from '@ui/index'; import { buildSession, RunPhase } from '@lib/wizard-session'; import { Integration } from '@shared/constants'; import { HostResolution } from '@shared/host-resolution'; -import { FRAMEWORK_REGISTRY } from '@lib/registry'; +import { FRAMEWORK_REGISTRY } from '@programs/frameworks/registry'; import { WizardReadiness } from '@shared/health-checks/readiness'; import { Program, getProgramConfig, type ProgramId, -} from '@lib/programs/program-registry'; +} from '@programs'; import { ScreenId } from '@ui/tui/router'; -import { SELF_DRIVING_INTEGRATE_PATH_KEY } from '@lib/programs/self-driving/detect'; +import { SELF_DRIVING_INTEGRATE_PATH_KEY } from '@programs/self-driving/detect'; import { WizardCiDriver } from '../wizard-ci-driver'; import { decideE2eAction, type WizardE2eProfile } from '../e2e-profile'; import { profileFor } from '../profiles'; diff --git a/e2e-harness/__tests__/e2e-profile-ask.test.ts b/e2e-harness/__tests__/e2e-profile-ask.test.ts index 5bc8fdf97..447d21e0b 100644 --- a/e2e-harness/__tests__/e2e-profile-ask.test.ts +++ b/e2e-harness/__tests__/e2e-profile-ask.test.ts @@ -18,7 +18,7 @@ import { type WizardE2eProfile, } from '../e2e-profile'; import { profileFor, resolveE2eProfile } from '../profiles'; -import { Program } from '@lib/programs/program-registry'; +import { Program } from '@programs'; import type { CiState } from '../wizard-ci-driver'; const text = (id: string, prompt = id): AskQuestion => ({ diff --git a/e2e-harness/__tests__/e2e-result.test.ts b/e2e-harness/__tests__/e2e-result.test.ts index 961c1dda5..2757c7530 100644 --- a/e2e-harness/__tests__/e2e-result.test.ts +++ b/e2e-harness/__tests__/e2e-result.test.ts @@ -13,7 +13,7 @@ import os from 'os'; import path from 'path'; import { OutroKind, RunPhase } from '@lib/wizard-session'; import type { AskQuestion, WizardSession } from '@lib/wizard-session'; -import { DETECTED_WAREHOUSE_SOURCES_KEY } from '@lib/programs/warehouse-source/detect'; +import { DETECTED_WAREHOUSE_SOURCES_KEY } from '@programs/warehouse-source/detect'; import { Overlay } from '@ui/tui/router'; import { TASK_OUTCOMES_KEY } from '@agent'; import { diff --git a/e2e-harness/__tests__/wizard-ci-driver.test.ts b/e2e-harness/__tests__/wizard-ci-driver.test.ts index 7462b213f..474cacbb6 100644 --- a/e2e-harness/__tests__/wizard-ci-driver.test.ts +++ b/e2e-harness/__tests__/wizard-ci-driver.test.ts @@ -15,13 +15,13 @@ import { setUI } from '@ui/index'; import { buildSession, RunPhase, McpOutcome } from '@lib/wizard-session'; import { HostResolution } from '@shared/host-resolution'; import { Integration } from '@shared/constants'; -import { FRAMEWORK_REGISTRY } from '@lib/registry'; +import { FRAMEWORK_REGISTRY } from '@programs/frameworks/registry'; import { WizardReadiness } from '@shared/health-checks/readiness'; import { ScreenId, Overlay } from '@ui/tui/router'; -import { Program } from '@lib/programs/program-registry'; +import { Program } from '@programs'; import { WizardCiDriver, UnknownActionError } from '../wizard-ci-driver'; import { ACTION_REGISTRY, NO_ACTION_SCREENS } from '../action-registry'; -import { SOURCE_MAPS_CONTEXT_KEYS } from '@lib/programs/error-tracking-upload-source-maps/index'; +import { SOURCE_MAPS_CONTEXT_KEYS } from '@programs/error-tracking-upload-source-maps/index'; import { OutroKind } from '@lib/wizard-session'; function freshStore(): WizardStore { diff --git a/e2e-harness/action-registry.ts b/e2e-harness/action-registry.ts index 63c48870c..2449deee4 100644 --- a/e2e-harness/action-registry.ts +++ b/e2e-harness/action-registry.ts @@ -19,11 +19,11 @@ import type { AskAnswers } from '@lib/wizard-session'; import { SOURCE_MAPS_CONTEXT_KEYS, VARIANT_DISPLAY_NAME, -} from '@lib/programs/error-tracking-upload-source-maps/index'; +} from '@programs/error-tracking-upload-source-maps/index'; import { GITHUB_REQUIRED_BODY, GITHUB_REQUIRED_MESSAGE, -} from '@lib/programs/self-driving/detect'; +} from '@programs/self-driving/detect'; /** One commit action legal on a given screen. */ export interface DriverAction { diff --git a/e2e-harness/e2e-result.ts b/e2e-harness/e2e-result.ts index 1ba4b9d88..8e6b27171 100644 --- a/e2e-harness/e2e-result.ts +++ b/e2e-harness/e2e-result.ts @@ -24,8 +24,8 @@ import path from 'path'; import { OutroKind, type WizardSession } from '@lib/wizard-session'; import { TASK_OUTCOMES_KEY } from '@agent'; import type { TaskOutcome } from '@agent/types'; -import { DETECTED_WAREHOUSE_SOURCES_KEY } from '@lib/programs/warehouse-source/detect'; -import type { DetectedSource } from '@lib/warehouse-sources/types'; +import { DETECTED_WAREHOUSE_SOURCES_KEY } from '@programs/warehouse-source/detect'; +import type { DetectedSource } from '@programs/warehouse-sources/types'; import type { E2eDecisionReport } from './e2e-profile.js'; /** One `wizard_ask` batch the run was shown. */ diff --git a/e2e-harness/profiles.ts b/e2e-harness/profiles.ts index 3cc126d33..d0c343e6e 100644 --- a/e2e-harness/profiles.ts +++ b/e2e-harness/profiles.ts @@ -3,7 +3,7 @@ * program's flow. * * Each program declares its test path as JSON next to it - * (`src/lib/programs//test/e2e.json`): a `profile` (the options the run + * (`src/programs//test/e2e.json`): a `profile` (the options the run * auto-takes) plus a documented `path`. {@link profileFor} loads the `profile` * and maps it by program id. * @@ -11,7 +11,7 @@ * so `decideE2eAction` stays a pure function of (state, profile). */ -import { Program, type ProgramId } from '@lib/programs/program-registry'; +import { Program, type ProgramId } from '@programs'; import { DEFAULT_E2E_PROFILE, DEFAULT_E2E_VARIATION, @@ -19,15 +19,15 @@ import { type WizardE2eProfile, type WizardE2eVariation, } from './e2e-profile.js'; -import posthogIntegrationE2e from '@lib/programs/posthog-integration/test/e2e.json'; -import aiObservabilityE2e from '@lib/programs/ai-observability/test/e2e.json'; -import metricsE2e from '@lib/programs/metrics/test/e2e.json'; -import replayVisionE2e from '@lib/programs/replay-vision/test/e2e.json'; -import selfDrivingE2e from '@lib/programs/self-driving/test/e2e.json'; -import sourceMapsE2e from '@lib/programs/error-tracking-upload-source-maps/test/e2e.json'; -import errorTrackingE2e from '@lib/programs/error-tracking/test/e2e.json'; -import warehouseSourceE2e from '@lib/programs/warehouse-source/test/e2e.json'; -import auditE2e from '@lib/programs/audit/test/e2e.json'; +import posthogIntegrationE2e from '@programs/posthog-integration/test/e2e.json'; +import aiObservabilityE2e from '@programs/ai-observability/test/e2e.json'; +import metricsE2e from '@programs/metrics/test/e2e.json'; +import replayVisionE2e from '@programs/replay-vision/test/e2e.json'; +import selfDrivingE2e from '@programs/self-driving/test/e2e.json'; +import sourceMapsE2e from '@programs/error-tracking-upload-source-maps/test/e2e.json'; +import errorTrackingE2e from '@programs/error-tracking/test/e2e.json'; +import warehouseSourceE2e from '@programs/warehouse-source/test/e2e.json'; +import auditE2e from '@programs/audit/test/e2e.json'; const PROFILES: Partial> = { [Program.PostHogIntegration]: diff --git a/package.json b/package.json index 81603121d..4fe8bf62a 100644 --- a/package.json +++ b/package.json @@ -134,6 +134,7 @@ "test": "pnpm build && vitest run", "test:legacy": "vitest run --project legacy", "test:agent": "vitest run --project agent", + "test:programs": "vitest run --project programs", "test:tui": "vitest run --project tui", "test:cli": "vitest run --project cli", "test:harness": "vitest run --project harness", diff --git a/scripts/tui-host.no-jest.ts b/scripts/tui-host.no-jest.ts index 75b246b8e..2d61ec23e 100644 --- a/scripts/tui-host.no-jest.ts +++ b/scripts/tui-host.no-jest.ts @@ -22,27 +22,27 @@ import { Program, getProgramConfig, type ProgramId, -} from '@lib/programs/program-registry'; +} from '@programs'; import type { Harness, Sequence } from '@shared/constants'; import { buildSession } from '@lib/wizard-session'; import { initLocalDev } from '@shared/local-dev'; import { configureGatewayFromCIEnvironment } from '@agent/gateway-session'; -import { runProgramAgent } from '@lib/programs/run-agent-legacy'; -import { TaskStreamPush, createFileDestination } from '@lib/task-stream/index'; -import { getAuditChecks } from '@lib/programs/audit/types'; -import { authenticate } from '@lib/programs/authenticate'; +import { runProgramAgent } from '@programs/run-agent-legacy'; +import { TaskStreamPush, createFileDestination } from '@programs/task-stream/index'; +import { getAuditChecks } from '@programs/audit/types'; +import { authenticate } from '@programs/authenticate'; import { getOrAskForProjectData } from '@utils/setup-utils'; import { logToFile } from '@utils/debug'; import { join } from 'path'; -import { detectFramework } from '@lib/detection/index'; -import { FRAMEWORK_REGISTRY } from '@lib/registry'; +import { detectFramework } from '@programs/detection/index'; +import { FRAMEWORK_REGISTRY } from '@programs/frameworks/registry'; import type { Integration } from '@shared/constants'; -import { SELF_DRIVING_INTEGRATE_PATH_KEY } from '@lib/programs/self-driving/detect'; -import { ERROR_TRACKING_PROJECT_PATH_KEY } from '@lib/programs/error-tracking/detect-agentic'; +import { SELF_DRIVING_INTEGRATE_PATH_KEY } from '@programs/self-driving/detect'; +import { ERROR_TRACKING_PROJECT_PATH_KEY } from '@programs/error-tracking/detect-agentic'; import { detectSourceMapsPrerequisites, SOURCE_MAPS_CONTEXT_KEYS, -} from '@lib/programs/error-tracking-upload-source-maps/index'; +} from '@programs/error-tracking-upload-source-maps/index'; import { ScreenId, Overlay } from '@ui/tui/router'; import { WizardCiDriver } from '@e2e-harness/wizard-ci-driver'; import { diff --git a/src/__tests__/architecture/import-boundaries.test.ts b/src/__tests__/architecture/import-boundaries.test.ts index 9ba7d9236..64874af0c 100644 --- a/src/__tests__/architecture/import-boundaries.test.ts +++ b/src/__tests__/architecture/import-boundaries.test.ts @@ -2,7 +2,14 @@ import * as fs from 'fs'; import * as path from 'path'; import { fileURLToPath } from 'url'; -export type Surface = 'env' | 'shared' | 'legacy' | 'agent' | 'tui' | 'cli'; +export type Surface = + | 'env' + | 'shared' + | 'legacy' + | 'agent' + | 'programs' + | 'tui' + | 'cli'; const HERE = path.dirname(fileURLToPath(import.meta.url)); const REPO_ROOT = path.resolve(HERE, '../../..'); @@ -12,15 +19,12 @@ const SURFACE_RULES: ReadonlyArray boolean]> = ['env', (p) => p === 'src/env.ts'], ['shared', (p) => p.startsWith('src/shared/')], ['agent', (p) => p.startsWith('src/agent/')], + ['programs', (p) => p.startsWith('src/programs/')], [ 'tui', (p) => p.startsWith('src/ui/tui/') || - p === 'src/ui/logging-ui.ts' || - p === 'src/ui/headless-ui.ts' || - p === 'src/commands/factories/family-picker.tsx' || - /^src\/lib\/programs\/[^/]+\/content\//.test(p) || - /^src\/lib\/programs\/[^/]+\/tips\.ts$/.test(p), + p === 'src/commands/factories/family-picker.tsx', ], [ 'cli', @@ -43,17 +47,20 @@ export function classifySurface(relPath: string): Surface { export const ALLOWED_IMPORTS: Record = { env: [], shared: ['env', 'shared'], - legacy: ['env', 'shared', 'legacy'], - // Program types stay importable from the agent until B1 moves the bindings. - agent: ['env', 'shared', 'legacy', 'agent'], - tui: ['env', 'shared', 'legacy', 'tui'], - cli: ['env', 'shared', 'legacy', 'agent', 'tui', 'cli'], + legacy: ['env', 'shared', 'legacy', 'programs'], + // Moving the bindings to programs removes the agent's ProgramId type imports. + agent: ['env', 'shared', 'agent'], + programs: ['env', 'shared', 'agent', 'programs'], + tui: ['env', 'shared', 'legacy', 'programs', 'tui'], + cli: ['env', 'shared', 'legacy', 'agent', 'programs', 'tui', 'cli'], }; // The agent's public entries. Outside `src/agent`, an import into the agent // must land on one of these; `types.ts` is type-only, so the TUI may take it. const AGENT_VALUES_ENTRY = 'src/agent/index.ts'; const AGENT_TYPES_ENTRY = 'src/agent/types.ts'; +const PROGRAMS_VALUES_ENTRY = 'src/programs/index.ts'; +const PROGRAMS_TYPES_ENTRY = 'src/programs/types.ts'; /** The rule an edge breaks, or null when it is allowed. */ export function ruleFor(fromFile: string, toFile: string): string | null { @@ -69,6 +76,12 @@ export function ruleFor(fromFile: string, toFile: string): string | null { } return null; } + if (to === 'programs' && from !== 'programs') { + const target = toFile.split(path.sep).join('/'); + if (target !== PROGRAMS_VALUES_ENTRY && target !== PROGRAMS_TYPES_ENTRY) { + return 'programs-deep-import'; + } + } return ALLOWED_IMPORTS[from].includes(to) ? null : `matrix:${from}->${to}`; } @@ -401,7 +414,12 @@ describe('surface classification', () => { expect(classifySurface('src/shared/utils/analytics.ts')).toBe('shared'); expect(classifySurface('src/shared/errors/codes.ts')).toBe('shared'); expect(classifySurface('src/agent/agent-runner.ts')).toBe('agent'); + expect(classifySurface('src/programs/program-registry.ts')).toBe( + 'programs', + ); expect(classifySurface('src/ui/tui/App.tsx')).toBe('tui'); + expect(classifySurface('src/ui/index.ts')).toBe('legacy'); + expect(classifySurface('src/steps/index.ts')).toBe('legacy'); expect(classifySurface('bin.ts')).toBe('cli'); expect(classifySurface('src/agent/tools/mcp.ts')).toBe('agent'); expect(classifySurface('src/agent/tools/tools.ts')).toBe('agent'); @@ -409,32 +427,32 @@ describe('surface classification', () => { 'tui', ); expect( - classifySurface('src/lib/programs/posthog-integration/content/index.tsx'), + classifySurface('src/ui/tui/decks/posthog-integration/index.tsx'), ).toBe('tui'); - expect( - classifySurface('src/lib/programs/posthog-integration/index.ts'), - ).toBe('legacy'); + expect(classifySurface('src/programs/posthog-integration/index.ts')).toBe( + 'programs', + ); }); }); describe('agent entry modules', () => { const rule = (from: string, to: string) => ruleFor(from, to); - it('lets legacy and cli code reach the agent through its entries only', () => { - expect(rule('src/lib/programs/audit/index.ts', 'src/agent/index.ts')).toBe( + it('lets programs and cli code reach the agent through its entries only', () => { + expect(rule('src/programs/audit/index.ts', 'src/agent/index.ts')).toBe( null, ); - expect(rule('src/lib/programs/audit/index.ts', 'src/agent/types.ts')).toBe( + expect(rule('src/programs/audit/index.ts', 'src/agent/types.ts')).toBe( null, ); expect(rule('src/commands/skill.ts', 'src/agent/index.ts')).toBe(null); expect( - rule('src/lib/programs/audit/index.ts', 'src/agent/agent-runner.ts'), + rule('src/programs/audit/index.ts', 'src/agent/agent-runner.ts'), ).toBe('agent-deep-import'); expect(rule('src/commands/skill.ts', 'src/agent/runner/index.ts')).toBe( 'agent-deep-import', ); - expect(rule('src/shared/errors/agent-map.ts', 'src/agent/signals.ts')).toBe( + expect(rule('src/shared/claude-settings.ts', 'src/agent/signals.ts')).toBe( 'agent-deep-import', ); }); @@ -453,11 +471,46 @@ describe('agent entry modules', () => { expect(rule('src/agent/runner/index.ts', 'src/agent/progress.ts')).toBe( null, ); - expect(rule('src/lib/programs/audit/index.ts', 'src/ui/tui/store.ts')).toBe( - 'matrix:legacy->tui', + expect(rule('src/programs/audit/index.ts', 'src/ui/tui/store.ts')).toBe( + 'matrix:programs->tui', ); expect(rule('src/agent/runner/index.ts', 'src/ui/tui/store.ts')).toBe( 'matrix:agent->tui', ); }); }); + +describe('programs entry modules', () => { + const rule = (from: string, to: string) => ruleFor(from, to); + + it('lets the CLI and TUI reach programs through its entries', () => { + expect(rule('src/commands/audit.ts', 'src/programs/index.ts')).toBe(null); + expect(rule('src/ui/tui/store.ts', 'src/programs/types.ts')).toBe(null); + expect(rule('src/commands/audit.ts', 'src/programs/audit/index.ts')).toBe( + 'programs-deep-import', + ); + }); + + it('keeps programs from reaching the TUI and CLI', () => { + expect(rule('src/programs/audit/index.ts', 'src/ui/tui/store.ts')).toBe( + 'matrix:programs->tui', + ); + expect( + rule('src/programs/dispatch-family.ts', 'src/commands/command.ts'), + ).toBe('matrix:programs->cli'); + }); +}); + +describe('migration matrix', () => { + it('lets legacy code use the programs entry', () => { + expect(ruleFor('src/lib/wizard-session.ts', 'src/programs/index.ts')).toBe( + null, + ); + }); + + it('keeps agent code out of legacy session state', () => { + expect( + ruleFor('src/agent/runner/index.ts', 'src/lib/wizard-session.ts'), + ).toBe('matrix:agent->legacy'); + }); +}); diff --git a/src/__tests__/architecture/known-violations.json b/src/__tests__/architecture/known-violations.json index 629085454..415a808a1 100644 --- a/src/__tests__/architecture/known-violations.json +++ b/src/__tests__/architecture/known-violations.json @@ -1,42 +1,175 @@ { "violations": [ + "src/agent/runner/switchboard/flags/index.ts -> src/programs/types.ts", + "src/agent/runner/switchboard/flags/schemes.ts -> src/programs/types.ts", + "src/agent/runner/switchboard/index.ts -> src/programs/types.ts", + "src/commands/ai-observability.ts -> src/programs/ai-observability/index.ts", + "src/commands/audit.ts -> src/programs/audit/index.ts", + "src/commands/basic-integration/ci-install.ts -> src/programs/posthog-integration/index.ts", + "src/commands/basic-integration/interactive.ts -> src/programs/posthog-integration/index.ts", + "src/commands/basic-integration/skill.ts -> src/programs/agent-skill/index.ts", + "src/commands/doctor.ts -> src/programs/posthog-doctor/index.ts", + "src/commands/error-tracking.ts -> src/programs/error-tracking/index.ts", + "src/commands/factories/family-command-factory.ts -> src/programs/dispatch-family.ts", "src/commands/factories/family-picker.tsx -> src/commands/command.ts", + "src/commands/mcp-analytics.ts -> src/programs/mcp-analytics/index.ts", + "src/commands/metrics.ts -> src/programs/metrics/index.ts", + "src/commands/migrate.ts -> src/programs/migration/index.ts", + "src/commands/replay-vision.ts -> src/programs/replay-vision/index.ts", + "src/commands/revenue.ts -> src/programs/revenue-analytics/index.ts", + "src/commands/self-driving.ts -> src/programs/self-driving/index.ts", + "src/commands/upload-sourcemaps.ts -> src/programs/error-tracking-upload-source-maps/index.ts", + "src/commands/warehouse.ts -> src/programs/warehouse-source/index.ts", "src/env.ts -> src/lib/headless-mode.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/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/index.ts -> src/lib/programs/error-tracking-upload-source-maps/content/index.tsx", - "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/metrics/index.ts -> src/lib/programs/agent-skill/content/index.tsx", - "src/lib/programs/migration/index.ts -> src/lib/programs/migration/content/index.tsx", - "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/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/revenue-analytics/index.ts -> src/lib/programs/revenue-analytics/content/index.tsx", - "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/warehouse-source/index.ts -> src/lib/programs/warehouse-source/content/index.tsx", - "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/runners/run-non-interactive.ts -> src/programs/audit/types.ts", + "src/lib/runners/run-non-interactive.ts -> src/programs/detect-map.ts", + "src/lib/runners/run-non-interactive.ts -> src/programs/run-agent-legacy.ts", + "src/lib/runners/run-non-interactive.ts -> src/programs/task-stream/index.ts", + "src/lib/runners/run-non-interactive.ts -> src/programs/task-stream/task-stream-push.ts", + "src/lib/runners/run-non-interactive.ts -> src/programs/task-stream/wizard-run-sync.ts", + "src/lib/runners/run-wizard.ts -> src/programs/audit/types.ts", + "src/lib/runners/run-wizard.ts -> src/programs/authenticate.ts", + "src/lib/runners/run-wizard.ts -> src/programs/posthog-integration/detect.ts", + "src/lib/runners/run-wizard.ts -> src/programs/run-agent-legacy.ts", + "src/lib/runners/run-wizard.ts -> src/programs/task-stream/destinations/file.ts", + "src/lib/runners/run-wizard.ts -> src/programs/task-stream/destinations/posthog.ts", + "src/lib/runners/run-wizard.ts -> src/programs/task-stream/index.ts", + "src/lib/runners/run-wizard.ts -> src/programs/task-stream/task-stream-push.ts", + "src/lib/runners/run-wizard.ts -> src/programs/task-stream/wizard-run-sync.ts", "src/lib/wizard-session.ts -> src/agent/progress.ts", - "src/shared/claude-settings.ts -> src/agent/agent-env-isolation.ts", - "src/shared/errors/agent-map.ts -> src/agent/signals.ts", + "src/programs/agent-skill/index.ts -> src/ui/tui/decks/agent-skill/index.tsx", + "src/programs/agent-skill/steps.ts -> src/lib/wizard-session.ts", + "src/programs/ai-observability/index.ts -> src/lib/headless-mode.ts", + "src/programs/ai-observability/index.ts -> src/ui/tui/decks/agent-skill/index.tsx", + "src/programs/ai-opt-in-gate.ts -> src/lib/wizard-session.ts", + "src/programs/audit/index.ts -> src/lib/headless-mode.ts", + "src/programs/audit/index.ts -> src/lib/wizard-session.ts", + "src/programs/audit/ledger-watcher.ts -> src/lib/file-watcher.ts", + "src/programs/audit/ledger-watcher.ts -> src/ui/index.ts", + "src/programs/audit/types.ts -> src/lib/wizard-session.ts", + "src/programs/authenticate.ts -> src/lib/wizard-session.ts", + "src/programs/authenticate.ts -> src/ui/index.ts", + "src/programs/detection/agentic.ts -> src/lib/wizard-session.ts", + "src/programs/detection/agentic.ts -> src/ui/agent-progress.ts", + "src/programs/detection/agentic.ts -> src/ui/index.ts", + "src/programs/detection/features.ts -> src/lib/wizard-session.ts", + "src/programs/detection/project-scope.ts -> src/lib/wizard-session.ts", + "src/programs/detection/project-scope.ts -> src/ui/index.ts", + "src/programs/dispatch-family.ts -> src/commands/command.ts", + "src/programs/dispatch-family.ts -> src/commands/factories/shared.ts", + "src/programs/error-tracking-upload-source-maps/detect-agentic.ts -> src/lib/wizard-session.ts", + "src/programs/error-tracking-upload-source-maps/detect.ts -> src/lib/wizard-session.ts", + "src/programs/error-tracking-upload-source-maps/index.ts -> src/lib/wizard-session.ts", + "src/programs/error-tracking-upload-source-maps/index.ts -> src/ui/index.ts", + "src/programs/error-tracking-upload-source-maps/index.ts -> src/ui/tui/decks/error-tracking-upload-source-maps/index.tsx", + "src/programs/error-tracking-upload-source-maps/steps.ts -> src/lib/wizard-session.ts", + "src/programs/error-tracking/detect-agentic.ts -> src/lib/wizard-session.ts", + "src/programs/error-tracking/index.ts -> src/lib/wizard-session.ts", + "src/programs/error-tracking/index.ts -> src/ui/tui/decks/error-tracking/index.tsx", + "src/programs/error-tracking/index.ts -> src/ui/tui/decks/error-tracking/tips.ts", + "src/programs/events-audit/index.ts -> src/lib/wizard-session.ts", + "src/programs/events-audit/steps.ts -> src/lib/wizard-session.ts", + "src/programs/frameworks/astro/astro-wizard-agent.ts -> src/ui/index.ts", + "src/programs/frameworks/django/utils.ts -> src/ui/index.ts", + "src/programs/frameworks/fastapi/utils.ts -> src/ui/index.ts", + "src/programs/frameworks/flask/utils.ts -> src/ui/index.ts", + "src/programs/frameworks/laravel/utils.ts -> src/ui/index.ts", + "src/programs/frameworks/nextjs/nextjs-wizard-agent.ts -> src/ui/index.ts", + "src/programs/frameworks/rails/utils.ts -> src/ui/index.ts", + "src/programs/frameworks/react-native/utils.ts -> src/ui/index.ts", + "src/programs/frameworks/react-router/react-router-wizard-agent.ts -> src/ui/index.ts", + "src/programs/frameworks/tanstack-router/tanstack-router-wizard-agent.ts -> src/ui/index.ts", + "src/programs/mcp/index.ts -> src/lib/wizard-session.ts", + "src/programs/metrics/index.ts -> src/ui/tui/decks/agent-skill/index.tsx", + "src/programs/migration/index.ts -> src/ui/tui/decks/migration/index.tsx", + "src/programs/migration/steps.ts -> src/lib/wizard-session.ts", + "src/programs/posthog-integration/detect.ts -> src/lib/wizard-session.ts", + "src/programs/posthog-integration/index.ts -> src/lib/wizard-session.ts", + "src/programs/posthog-integration/index.ts -> src/steps/index.ts", + "src/programs/posthog-integration/index.ts -> src/ui/index.ts", + "src/programs/posthog-integration/index.ts -> src/ui/tui/decks/posthog-integration/index.tsx", + "src/programs/posthog-integration/steps.ts -> src/lib/wizard-session.ts", + "src/programs/program-registry.ts -> src/ui/tui/decks/agent-skill/index.tsx", + "src/programs/program-run.ts -> src/lib/wizard-session.ts", + "src/programs/program-step.ts -> src/lib/wizard-session.ts", + "src/programs/program-step.ts -> src/ui/tui/components/TipsCard.tsx", + "src/programs/program-step.ts -> src/ui/tui/primitives/index.ts", + "src/programs/program-step.ts -> src/ui/tui/store.ts", + "src/programs/replay-vision/index.ts -> src/lib/wizard-session.ts", + "src/programs/revenue-analytics/detect.ts -> src/lib/wizard-session.ts", + "src/programs/revenue-analytics/index.ts -> src/ui/tui/decks/revenue-analytics/index.tsx", + "src/programs/revenue-analytics/steps.ts -> src/lib/wizard-session.ts", + "src/programs/run-agent-legacy.ts -> src/lib/wizard-session.ts", + "src/programs/run-agent-legacy.ts -> src/ui/agent-progress.ts", + "src/programs/run-agent-legacy.ts -> src/ui/index.ts", + "src/programs/self-driving/detect-agentic.ts -> src/lib/wizard-session.ts", + "src/programs/self-driving/detect.ts -> src/lib/wizard-session.ts", + "src/programs/self-driving/index.ts -> src/lib/wizard-session.ts", + "src/programs/self-driving/index.ts -> src/ui/tui/decks/self-driving/index.tsx", + "src/programs/self-driving/index.ts -> src/ui/tui/decks/self-driving/pricing.ts", + "src/programs/self-driving/index.ts -> src/ui/tui/decks/self-driving/tips.ts", + "src/programs/self-driving/steps.ts -> src/lib/wizard-session.ts", + "src/programs/shared/health-check-step.ts -> src/lib/wizard-session.ts", + "src/programs/shared/posthog-cli-preinstall.ts -> src/steps/install-cli-steering/index.ts", + "src/programs/shared/posthog-cli-preinstall.ts -> src/ui/index.ts", + "src/programs/task-stream/destinations/posthog.ts -> src/lib/wizard-session.ts", + "src/programs/task-stream/event-plan-watcher.ts -> src/lib/file-watcher.ts", + "src/programs/task-stream/event-plan-watcher.ts -> src/ui/tui/store.ts", + "src/programs/task-stream/task-stream-push.ts -> src/lib/wizard-session.ts", + "src/programs/task-stream/task-stream-push.ts -> src/ui/tui/store.ts", + "src/programs/task-stream/task-stream-push.ts -> src/ui/wizard-ui.ts", + "src/programs/task-stream/types.ts -> src/lib/wizard-session.ts", + "src/programs/task-stream/wizard-run-sync.ts -> src/lib/wizard-session.ts", + "src/programs/warehouse-source/detect.ts -> src/lib/wizard-session.ts", + "src/programs/warehouse-source/index.ts -> src/lib/wizard-session.ts", + "src/programs/warehouse-source/index.ts -> src/ui/tui/decks/warehouse-source/index.tsx", + "src/programs/warehouse-source/steps.ts -> src/lib/wizard-session.ts", + "src/programs/web-analytics-doctor/detect.ts -> src/lib/wizard-session.ts", "src/shared/utils/analytics.ts -> src/lib/wizard-session.ts", "src/shared/utils/oauth.ts -> src/ui/index.ts", - "src/shared/utils/setup-utils.ts -> src/lib/oauth/program-scopes.ts", - "src/shared/utils/setup-utils.ts -> src/lib/programs/program-registry.ts", "src/shared/utils/setup-utils.ts -> src/lib/wizard-session.ts", + "src/shared/utils/setup-utils.ts -> src/programs/oauth/program-scopes.ts", + "src/shared/utils/setup-utils.ts -> src/programs/types.ts", "src/shared/utils/setup-utils.ts -> src/ui/index.ts", "src/shared/utils/wizard-abort.ts -> src/lib/wizard-session.ts", "src/shared/utils/wizard-abort.ts -> src/ui/index.ts", "src/shared/utils/wizard-abort.ts -> src/ui/logging-ui.ts", - "src/ui/index.ts -> src/ui/logging-ui.ts", + "src/ui/headless-ui.ts -> src/ui/tui/store.ts", + "src/ui/tui/decks/error-tracking/tips.ts -> src/programs/replay-vision/index.ts", + "src/ui/tui/playground/demos/AuditChecksDemo.tsx -> src/programs/audit/types.ts", + "src/ui/tui/playground/demos/DoctorReportDemo.tsx -> src/programs/posthog-doctor/index.ts", + "src/ui/tui/screen-sequences.ts -> src/programs/ai-opt-in-gate.ts", + "src/ui/tui/screen-sequences.ts -> src/programs/program-step.ts", + "src/ui/tui/screens/ErrorTrackingDetectScreen.tsx -> src/programs/error-tracking/detect-agentic.ts", + "src/ui/tui/screens/ErrorTrackingDetectScreen.tsx -> src/programs/frameworks/registry.ts", + "src/ui/tui/screens/PostHogIntegrationIntroScreen.tsx -> src/programs/frameworks/registry.ts", + "src/ui/tui/screens/RevenueIntroScreen.tsx -> src/programs/revenue-analytics/index.ts", + "src/ui/tui/screens/SelfDrivingGitHubScreen.tsx -> src/programs/self-driving/detect.ts", + "src/ui/tui/screens/SelfDrivingHandoffScreen.tsx -> src/programs/posthog-integration/index.ts", + "src/ui/tui/screens/SelfDrivingHandoffScreen.tsx -> src/programs/self-driving/detect.ts", + "src/ui/tui/screens/SelfDrivingIntegrationDetectScreen.tsx -> src/programs/frameworks/registry.ts", + "src/ui/tui/screens/SelfDrivingIntegrationDetectScreen.tsx -> src/programs/self-driving/detect-agentic.ts", + "src/ui/tui/screens/SelfDrivingIntegrationDetectScreen.tsx -> src/programs/self-driving/detect.ts", + "src/ui/tui/screens/SelfDrivingIntroScreen.tsx -> src/programs/self-driving/index.ts", + "src/ui/tui/screens/SourceMapsDetectScreen.tsx -> src/programs/error-tracking-upload-source-maps/detect-agentic.ts", + "src/ui/tui/screens/SourceMapsDetectScreen.tsx -> src/programs/error-tracking-upload-source-maps/index.ts", + "src/ui/tui/screens/WarehouseIntroScreen.tsx -> src/programs/warehouse-source/index.ts", + "src/ui/tui/screens/audit/AuditAreaPane.tsx -> src/programs/audit/types.ts", + "src/ui/tui/screens/audit/AuditChecksOutroSection.tsx -> src/programs/audit/types.ts", + "src/ui/tui/screens/audit/AuditChecksViewer/AuditChecksViewer.tsx -> src/programs/audit/types.ts", + "src/ui/tui/screens/audit/AuditChecksViewer/CheckRow.tsx -> src/programs/audit/types.ts", + "src/ui/tui/screens/audit/AuditChecksViewer/DetailRow.tsx -> src/programs/audit/types.ts", + "src/ui/tui/screens/audit/AuditChecksViewer/Footer.tsx -> src/programs/audit/types.ts", + "src/ui/tui/screens/audit/AuditChecksViewer/Header.tsx -> src/programs/audit/types.ts", + "src/ui/tui/screens/audit/AuditChecksViewer/sort.ts -> src/programs/audit/types.ts", + "src/ui/tui/screens/audit/AuditOutroScreen.tsx -> src/programs/audit/types.ts", + "src/ui/tui/screens/audit/AuditRunScreen.tsx -> src/programs/audit/types.ts", + "src/ui/tui/screens/audit/PendingChecksList.tsx -> src/programs/audit/types.ts", + "src/ui/tui/screens/doctor/DoctorReportScreen.tsx -> src/programs/posthog-doctor/index.ts", + "src/ui/tui/screens/doctor/IssueTable.tsx -> src/programs/posthog-doctor/index.ts", "src/ui/tui/screens/health/HealthCheckScreen.tsx -> src/agent/index.ts", - "src/ui/tui/services/mcp-suggested-prompts-services.ts -> src/agent/index.ts" + "src/ui/tui/services/mcp-suggested-prompts-services.ts -> src/agent/index.ts", + "src/ui/tui/store.ts -> src/programs/ai-opt-in-gate.ts", + "src/ui/tui/store.ts -> src/programs/posthog-integration/detect.ts" ] } diff --git a/src/__tests__/cli.test.ts b/src/__tests__/cli.test.ts index 8870e7999..6275e16d4 100644 --- a/src/__tests__/cli.test.ts +++ b/src/__tests__/cli.test.ts @@ -18,7 +18,7 @@ const { mockStreamAttach, mockStreamShutdown, mockStreamDestinations } = // destinations, not about whether a stream exists. mockStreamDestinations: vi.fn(), })); -vi.mock('../lib/task-stream/index', () => ({ +vi.mock('../programs/task-stream', () => ({ // shutdown() hardcodes a resolved Promise (not a bare vi.fn) so the // interactive runWizard's dangling SIGTERM handler — which calls // shutdown().catch() and outlives these tests — never hits undefined.catch. @@ -76,7 +76,7 @@ vi.mock('../ui/tui/start-tui', () => ({ }, }), })); -vi.mock('../lib/programs/posthog-integration/index', () => ({ +vi.mock('../programs/posthog-integration', () => ({ posthogIntegrationConfig: { id: 'posthog-integration', steps: [], @@ -102,8 +102,8 @@ vi.mock('@utils/debug', () => ({ logToFile: vi.fn(), setDebugSink: vi.fn(), })); -vi.mock('../lib/registry', () => ({ FRAMEWORK_REGISTRY: {} })); -vi.mock('../lib/detection/index', () => ({ +vi.mock('../programs/frameworks/registry', () => ({ FRAMEWORK_REGISTRY: {} })); +vi.mock('../programs/detection', () => ({ detectFramework: vi.fn().mockResolvedValue(null), gatherFrameworkContext: vi.fn().mockResolvedValue({}), })); @@ -117,7 +117,7 @@ vi.mock('@utils/wizard-abort', async (importOriginal) => ({ ...(await importOriginal()), wizardAbort: vi.fn(), })); -vi.mock('../lib/programs/run-agent-legacy', () => ({ +vi.mock('../programs/run-agent-legacy', () => ({ runProgramAgent: vi.fn().mockResolvedValue(undefined), })); diff --git a/src/__tests__/mcp-cli.test.ts b/src/__tests__/mcp-cli.test.ts index e9b41f8b3..98b7afa8a 100644 --- a/src/__tests__/mcp-cli.test.ts +++ b/src/__tests__/mcp-cli.test.ts @@ -25,7 +25,7 @@ vi.mock('@ui/tui/start-tui', () => ({ vi.mock('@utils/env-api-key', () => ({ readApiKeyFromEnv: mockReadApiKeyFromEnvMcp, })); -vi.mock('@lib/programs/program-registry', () => ({ +vi.mock('@programs', () => ({ Program: { McpAdd: 'mcp-add', McpRemove: 'mcp-remove', diff --git a/src/__tests__/programs-cli.test.ts b/src/__tests__/programs-cli.test.ts index c7a5e074e..998808992 100644 --- a/src/__tests__/programs-cli.test.ts +++ b/src/__tests__/programs-cli.test.ts @@ -29,11 +29,11 @@ import { selfDrivingCommand } from '../commands/self-driving'; import { dispatchFamily, pickerChildrenToShow, -} from '@lib/programs/dispatch-family'; +} from '@programs/dispatch-family'; import type { Command } from '../commands/command'; import { fetchSkillMenu, type CliEntry } from '@shared/skill-menu'; -import { auditConfig } from '@lib/programs/audit/index'; -import { webAnalyticsDoctorConfig } from '@lib/programs/web-analytics-doctor/index'; +import { auditConfig } from '@programs/audit/index'; +import { webAnalyticsDoctorConfig } from '@programs/web-analytics-doctor/index'; import { parseCommand } from './helpers/parse-command.no-jest'; const mockFetchSkillMenu = fetchSkillMenu as MockedFunction< diff --git a/src/__tests__/provision-cli.test.ts b/src/__tests__/provision-cli.test.ts index 94b76cb25..1f3429d5e 100644 --- a/src/__tests__/provision-cli.test.ts +++ b/src/__tests__/provision-cli.test.ts @@ -27,7 +27,7 @@ vi.mock('../ui/tui/start-tui', () => ({ }, }), })); -vi.mock('../lib/programs/posthog-integration/index', () => ({ +vi.mock('../programs/posthog-integration', () => ({ posthogIntegrationConfig: { id: 'posthog-integration', steps: [], @@ -52,8 +52,8 @@ vi.mock('@utils/debug', () => ({ logToFile: vi.fn(), setDebugSink: vi.fn(), })); -vi.mock('../lib/registry', () => ({ FRAMEWORK_REGISTRY: {} })); -vi.mock('../lib/detection/index', () => ({ +vi.mock('../programs/frameworks/registry', () => ({ FRAMEWORK_REGISTRY: {} })); +vi.mock('../programs/detection', () => ({ detectFramework: vi.fn().mockResolvedValue(null), gatherFrameworkContext: vi.fn().mockResolvedValue({}), })); @@ -64,7 +64,7 @@ vi.mock('@utils/wizard-abort', async (importOriginal) => ({ ...(await importOriginal()), wizardAbort: vi.fn(), })); -vi.mock('../lib/programs/run-agent-legacy', () => ({ +vi.mock('../programs/run-agent-legacy', () => ({ runProgramAgent: vi.fn().mockResolvedValue(undefined), })); diff --git a/src/agent/README.md b/src/agent/README.md index f73939952..4116171cd 100644 --- a/src/agent/README.md +++ b/src/agent/README.md @@ -83,7 +83,7 @@ store and no registry. Programs call the agent to do the work a skill describes. The TUI and the headless runner observe the run through `onProgress` and answer it through -`interaction`; today `src/lib/programs/run-agent-legacy.ts` does both on top of +`interaction`; today `src/programs/run-agent-legacy.ts` does both on top of the session. Without `onProgress` the run completes and its snapshot still comes back in the diff --git a/src/agent/__tests__/credential-isolation-snapshot.test.ts b/src/agent/__tests__/credential-isolation-snapshot.test.ts index 40649ebcb..7fbe8be98 100644 --- a/src/agent/__tests__/credential-isolation-snapshot.test.ts +++ b/src/agent/__tests__/credential-isolation-snapshot.test.ts @@ -13,7 +13,7 @@ * isolation surface — a diff here means a credential path changed disposition. */ -import { sanitizeAgentSubprocessEnv } from '@agent/agent-env-isolation'; +import { sanitizeAgentSubprocessEnv } from '@shared/agent-env-isolation'; import { classifySettingsConflicts } from '@shared/claude-settings'; import type { SettingsConflict } from '@shared/claude-settings'; diff --git a/src/agent/__tests__/run-agent-standalone.test.ts b/src/agent/__tests__/run-agent-standalone.test.ts index e6dbb9000..35b3676ee 100644 --- a/src/agent/__tests__/run-agent-standalone.test.ts +++ b/src/agent/__tests__/run-agent-standalone.test.ts @@ -16,7 +16,8 @@ import { type AskAnswers, type PendingQuestion, } from '@lib/wizard-session'; -import { AGENT_ERROR_CODE, ErrorCodes, WizardError } from '@shared/errors'; +import { ErrorCodes, WizardError } from '@shared/errors'; +import { AGENT_ERROR_CODE } from '@agent/error-map'; import { AgentErrorType } from '@agent/signals'; import { CANCELLED_SENTINEL, type AskResponse } from '@agent/wizard-ask-bridge'; import type { AgentFailure } from '@agent/runner/shared/types'; diff --git a/src/agent/__tests__/wizard-tools.test.ts b/src/agent/__tests__/wizard-tools.test.ts index 1ce282533..b9912537b 100644 --- a/src/agent/__tests__/wizard-tools.test.ts +++ b/src/agent/__tests__/wizard-tools.test.ts @@ -31,7 +31,7 @@ import { resolveEnvPath, templateEnvWriteRefusal, } from '@agent/tools'; -import type { AuditCheck } from '@lib/programs/audit/types'; +import type { AuditCheck } from '@programs/audit/types'; function makeTmpDir(): string { return fs.mkdtempSync(path.join(os.tmpdir(), 'wizard-tools-')); diff --git a/src/agent/agent-interface.ts b/src/agent/agent-interface.ts index 7749eaa44..9915b2284 100644 --- a/src/agent/agent-interface.ts +++ b/src/agent/agent-interface.ts @@ -75,7 +75,7 @@ import { claudeConfigDir, createIsolatedAgentConfigDir, } from './stored-login'; -import { sanitizeAgentSubprocessEnv } from './agent-env-isolation'; +import { sanitizeAgentSubprocessEnv } from '@shared/agent-env-isolation'; // Dynamic import cache for ESM module let _sdkModule: any = null; diff --git a/src/agent/agent-runner.ts b/src/agent/agent-runner.ts index 7ffac5145..06a907fab 100644 --- a/src/agent/agent-runner.ts +++ b/src/agent/agent-runner.ts @@ -2,7 +2,7 @@ * Re-export shim. The runner has been split into agent/runner/. * Import from there directly; this shim keeps existing importers working. * The session-driven `runProgramAgent(programConfig, session)` lives in - * `src/lib/programs/run-agent-legacy.ts`. + * `src/programs/run-agent-legacy.ts`. */ export { diff --git a/src/shared/errors/agent-map.ts b/src/agent/error-map.ts similarity index 66% rename from src/shared/errors/agent-map.ts rename to src/agent/error-map.ts index f9c982420..4a3bfeee0 100644 --- a/src/shared/errors/agent-map.ts +++ b/src/agent/error-map.ts @@ -1,8 +1,5 @@ -// Leaf module on purpose: every module imports the errors, so the agent entry -// would form a module cycle here. -// eslint-disable-next-line @typescript-eslint/no-restricted-imports -- B1: error codes move next to their owners -import { AgentErrorType } from '@agent/signals'; -import { ErrorCodes, type ErrorCode } from './codes'; +import { AgentErrorType } from './signals'; +import { ErrorCodes, type ErrorCode } from '@shared/errors'; export const AGENT_ERROR_CODE: Record = { [AgentErrorType.AGENTIC_DETECTION_TIMEOUT]: diff --git a/src/agent/index.ts b/src/agent/index.ts index a6446cd3e..3d5c77d46 100644 --- a/src/agent/index.ts +++ b/src/agent/index.ts @@ -19,7 +19,8 @@ export { AgentSignals } from './agent-interface'; export { WIZARD_TOOL_NAMES } from './tools'; /** - * Leaves in B1. Bindings and program data move to programs: resolveBinding + * Leaves when the bindings move to programs. Bindings and program data move to + * programs: resolveBinding * is keyed by PROGRAM_BINDINGS and the agent keeps only "run from an * already-resolved binding"; shouldDisableAsk is a flags policy programs * decide and pass in; LONGER_ASK_TIMEOUT_MS is a tuning number programs own diff --git a/src/agent/mcp-prompt-streaming.ts b/src/agent/mcp-prompt-streaming.ts index 6bafc82fb..2c1586550 100644 --- a/src/agent/mcp-prompt-streaming.ts +++ b/src/agent/mcp-prompt-streaming.ts @@ -17,7 +17,7 @@ import { DEFAULT_AGENT_MODEL, WIZARD_USER_AGENT } from '@shared/constants'; import { logToFile } from '@utils/debug'; import { gatewayAuth } from '@agent/gateway-session'; import { buildAgentEnv, buildRunTags } from '@agent/agent-interface'; -import { sanitizeAgentSubprocessEnv } from '@agent/agent-env-isolation'; +import { sanitizeAgentSubprocessEnv } from '@shared/agent-env-isolation'; import { createIsolatedAgentConfigDir } from '@agent/stored-login'; import { analytics } from '@utils/analytics'; diff --git a/src/agent/progress.ts b/src/agent/progress.ts index 2788c565e..62fc43dc0 100644 --- a/src/agent/progress.ts +++ b/src/agent/progress.ts @@ -4,7 +4,7 @@ * `runAgent` reports through one optional callback and asks through one * optional set of capabilities. Neither reaches into a UI singleton, a store, * or a session: every payload is copied data, every question is awaited on an - * injected answerer. The legacy adapter in `src/lib/programs/run-agent-legacy.ts` + * injected answerer. The legacy adapter in `src/programs/run-agent-legacy.ts` * maps these back onto `WizardUI` one call per event, so the terminal output of * every existing runner is unchanged. */ diff --git a/src/agent/runner/README.md b/src/agent/runner/README.md index 8e8cc4388..480c1280b 100644 --- a/src/agent/runner/README.md +++ b/src/agent/runner/README.md @@ -45,7 +45,7 @@ resolved execution data and an invocation snapshot (`shared/types.ts`), reports through `onProgress` and asks through `interaction` (`../progress.ts`), and returns every ending as a result. It never renders, reads a session or exits. The gates, OAuth, flags and binding lookup that used to run here live in -`src/lib/programs/run-agent-legacy.ts`, which also maps progress back onto +`src/programs/run-agent-legacy.ts`, which also maps progress back onto `getUI()` for today's runners. **Prepare** (`shared/bootstrap.ts`) is the on-ramp inside the agent: logging diff --git a/src/agent/runner/__tests__/switchboard.test.ts b/src/agent/runner/__tests__/switchboard.test.ts index 6b4f0e8fd..0a16a2048 100644 --- a/src/agent/runner/__tests__/switchboard.test.ts +++ b/src/agent/runner/__tests__/switchboard.test.ts @@ -10,7 +10,7 @@ * asserted directly. */ import { describe, it, expect } from 'vitest'; -import { PROGRAM_REGISTRY } from '@lib/programs/program-registry'; +import { PROGRAM_REGISTRY } from '@programs'; import { DEFAULT_AGENT_MODEL, GPT5_6_LUNA_MODEL, diff --git a/src/agent/runner/index.ts b/src/agent/runner/index.ts index 666d94a19..91d35dedc 100644 --- a/src/agent/runner/index.ts +++ b/src/agent/runner/index.ts @@ -19,7 +19,7 @@ * agent did not decide (a refused mint, an SDK crash) comes back as * `outcome: RunOutcome.Crashed` with the original error attached, so a caller can keep * handling it the way it always did. The legacy adapter in - * `src/lib/programs/run-agent-legacy.ts` rebuilds today's session-driven + * `src/programs/run-agent-legacy.ts` rebuilds today's session-driven * behavior on top of this call for every existing caller. */ diff --git a/src/agent/runner/sequence/linear.ts b/src/agent/runner/sequence/linear.ts index a1da4d7fd..1e5c651ae 100644 --- a/src/agent/runner/sequence/linear.ts +++ b/src/agent/runner/sequence/linear.ts @@ -14,7 +14,8 @@ import { OutroKind, type OutroData } from '@agent/progress'; import { AgentErrorType } from '../../agent-interface'; import { logToFile } from '@utils/debug'; import { createBenchmarkPipeline } from '@agent/middleware/benchmark'; -import { AGENT_ERROR_CODE, ErrorCodes } from '@shared/errors'; +import { ErrorCodes } from '@shared/errors'; +import { AGENT_ERROR_CODE } from '@agent/error-map'; import { analytics } from '@utils/analytics'; import { formatYaraAbortMessage } from '@agent/yara-hooks'; import { installSkillById } from '@agent/tools'; diff --git a/src/agent/runner/sequence/orchestrator/__tests__/excluded-task-types.test.ts b/src/agent/runner/sequence/orchestrator/__tests__/excluded-task-types.test.ts index 5187ae500..c7ff35b68 100644 --- a/src/agent/runner/sequence/orchestrator/__tests__/excluded-task-types.test.ts +++ b/src/agent/runner/sequence/orchestrator/__tests__/excluded-task-types.test.ts @@ -6,7 +6,7 @@ */ import { WIZARD_DEFAULT_AIO_LOGS_FLAG_KEY } from '@shared/constants'; -import { posthogIntegrationConfig } from '@lib/programs/posthog-integration/index'; +import { posthogIntegrationConfig } from '@programs/posthog-integration/index'; import { effectiveExcludedTaskTypes } from '../orchestrator-runner'; describe('effectiveExcludedTaskTypes', () => { diff --git a/src/agent/runner/sequence/orchestrator/orchestrator-runner.ts b/src/agent/runner/sequence/orchestrator/orchestrator-runner.ts index 237272b2d..36b2125bb 100644 --- a/src/agent/runner/sequence/orchestrator/orchestrator-runner.ts +++ b/src/agent/runner/sequence/orchestrator/orchestrator-runner.ts @@ -35,12 +35,8 @@ import { analytics } from '@utils/analytics'; import { ciExcludedTaskTypes } from '@utils/ci-flag-overrides'; import { logToFile } from '@utils/debug'; import { ringTerminalBell } from '@utils/terminal-bell'; -import { - AGENT_ERROR_CODE, - classifyRunFailure, - ErrorCodes, - WizardError, -} from '@shared/errors'; +import { AGENT_ERROR_CODE } from '@agent/error-map'; +import { classifyRunFailure, ErrorCodes, WizardError } from '@shared/errors'; import type { AgentResult } from '../../harness/types'; import type { AgentInteraction } from '@agent/progress'; import type { diff --git a/src/agent/runner/shared/types.ts b/src/agent/runner/shared/types.ts index a3e3fa7f7..ecde56600 100644 --- a/src/agent/runner/shared/types.ts +++ b/src/agent/runner/shared/types.ts @@ -5,7 +5,7 @@ * invocation snapshot, reports through `options.onProgress`, asks through * `options.interaction`, and returns a `RunResult`. Nothing here names a UI, * a store, a session or a program registry: the caller resolves those and - * hands over plain data. `src/lib/programs/run-agent-legacy.ts` is the caller + * hands over plain data. `src/programs/run-agent-legacy.ts` is the caller * that rebuilds today's session-driven behavior on top of this contract. */ @@ -41,7 +41,7 @@ export interface AbortCase { * * Every program provides one of these as `RunConfig.run`. The runner assembles * the final prompt from `customPrompt` + `skillId`. Programs extend it with - * their session-taking completion hooks in `src/lib/programs/program-run.ts`; + * their session-taking completion hooks in `src/programs/program-run.ts`; * the caller binds those and hands the agent `RunConfig.hooks` instead. */ export interface AgentRunDefinition { diff --git a/src/agent/runner/switchboard/flags/__tests__/flags.test.ts b/src/agent/runner/switchboard/flags/__tests__/flags.test.ts index 616ed2135..8c04f0983 100644 --- a/src/agent/runner/switchboard/flags/__tests__/flags.test.ts +++ b/src/agent/runner/switchboard/flags/__tests__/flags.test.ts @@ -3,7 +3,7 @@ import { readFileSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { join, dirname } from 'node:path'; import { describe, it, expect, vi } from 'vitest'; -import { PROGRAM_REGISTRY } from '@lib/programs/program-registry'; +import { PROGRAM_REGISTRY } from '@programs'; import * as constants from '@shared/constants'; import { DEFAULT_AGENT_MODEL, diff --git a/src/agent/runner/switchboard/flags/index.ts b/src/agent/runner/switchboard/flags/index.ts index 5b376d3ef..23a03503f 100644 --- a/src/agent/runner/switchboard/flags/index.ts +++ b/src/agent/runner/switchboard/flags/index.ts @@ -7,7 +7,7 @@ import { RUN_SURFACE } from '@env'; import { logToFile } from '@utils/debug'; import type { Sequence } from '@shared/constants'; -import type { ProgramId } from '@lib/programs/program-registry'; +import type { ProgramId } from '@programs/types'; import { ORCHESTRATOR_HARNESS_ROUTE, ORCHESTRATOR_SEQUENCE_ROUTE, diff --git a/src/agent/runner/switchboard/flags/schemes.ts b/src/agent/runner/switchboard/flags/schemes.ts index e30f48c0e..99f9c4a97 100644 --- a/src/agent/runner/switchboard/flags/schemes.ts +++ b/src/agent/runner/switchboard/flags/schemes.ts @@ -13,7 +13,7 @@ import { Sequence, SONNET_5_MODEL, } from '@shared/constants'; -import type { ProgramId } from '@lib/programs/program-registry'; +import type { ProgramId } from '@programs/types'; import { logToFile } from '@utils/debug'; import type { EffortLevel } from '../models'; diff --git a/src/agent/runner/switchboard/index.ts b/src/agent/runner/switchboard/index.ts index 842176c16..b2d84add2 100644 --- a/src/agent/runner/switchboard/index.ts +++ b/src/agent/runner/switchboard/index.ts @@ -7,7 +7,7 @@ import { Harness, Sequence, } from '@shared/constants'; -import type { ProgramId } from '@lib/programs/program-registry'; +import type { ProgramId } from '@programs/types'; import { resolveHarness } from './harness'; import type { EffortLevel } from './models'; import { resolveSequence } from './sequence'; diff --git a/src/agent/types.ts b/src/agent/types.ts index c1367885f..b23200cfb 100644 --- a/src/agent/types.ts +++ b/src/agent/types.ts @@ -28,7 +28,7 @@ export type { TokenUsageDelta, } from './progress'; -/** Leaves in B1 with the bindings table. */ +/** Leaves when the bindings table moves to programs. */ export type { ProgramBinding, SwitchboardCtx } from './runner'; /** Leaves in B2 with downloadSkill. */ diff --git a/src/commands/ai-observability.ts b/src/commands/ai-observability.ts index abf436c45..c51fe2b0a 100644 --- a/src/commands/ai-observability.ts +++ b/src/commands/ai-observability.ts @@ -1,4 +1,4 @@ -import { aiObservabilityConfig } from '@lib/programs/ai-observability/index'; +import { aiObservabilityConfig } from '@programs/ai-observability/index'; import type { Command } from './command'; import { nativeCommandFactory } from './factories/native-command-factory'; diff --git a/src/commands/audit.ts b/src/commands/audit.ts index e838bbe28..39ed26dfe 100644 --- a/src/commands/audit.ts +++ b/src/commands/audit.ts @@ -1,4 +1,4 @@ -import { auditConfig } from '@lib/programs/audit/index'; +import { auditConfig } from '@programs/audit/index'; import type { Command } from './command'; import { familyCommandFactory } from './factories/family-command-factory'; diff --git a/src/commands/basic-integration/ci-install.ts b/src/commands/basic-integration/ci-install.ts index 9c24bc880..a1974e7a0 100644 --- a/src/commands/basic-integration/ci-install.ts +++ b/src/commands/basic-integration/ci-install.ts @@ -4,7 +4,7 @@ import { LoggingUI } from '@ui/logging-ui'; import { API_KEY_HINT, runWizardCI, runWizardHeadless } from '@lib/runners'; import type { NonInteractiveMode } from '@lib/runners'; import { provisionNewAccount } from '@utils/provisioning'; -import { posthogIntegrationConfig } from '@lib/programs/posthog-integration/index'; +import { posthogIntegrationConfig } from '@programs/posthog-integration/index'; import { ErrorCodes, type ErrorCode } from '@shared/errors'; import { emitWizardError } from '@shared/errors'; diff --git a/src/commands/basic-integration/interactive.ts b/src/commands/basic-integration/interactive.ts index ee143f5d9..6191cf745 100644 --- a/src/commands/basic-integration/interactive.ts +++ b/src/commands/basic-integration/interactive.ts @@ -1,6 +1,6 @@ import type { Arguments } from 'yargs'; import { runWizard } from '@lib/runners'; -import { posthogIntegrationConfig } from '@lib/programs/posthog-integration/index'; +import { posthogIntegrationConfig } from '@programs/posthog-integration/index'; /** Default flow: run the posthog-integration program through the TUI. */ export function runInteractive(argv: Arguments): void { diff --git a/src/commands/basic-integration/skill.ts b/src/commands/basic-integration/skill.ts index 5b41a205d..083f2dba2 100644 --- a/src/commands/basic-integration/skill.ts +++ b/src/commands/basic-integration/skill.ts @@ -1,7 +1,7 @@ import type { Arguments } from 'yargs'; import { POSTHOG_DOCS_URL } from '@shared/constants'; import { runWizard, runWizardCI } from '@lib/runners'; -import { createSkillProgram } from '@lib/programs/agent-skill/index'; +import { createSkillProgram } from '@programs/agent-skill/index'; /** Run an arbitrary context-mill skill by id (`wizard skill `, headless with `--ci`). */ export function runSkillMode(argv: Arguments): void { diff --git a/src/commands/doctor.ts b/src/commands/doctor.ts index 3b9385b97..979c29116 100644 --- a/src/commands/doctor.ts +++ b/src/commands/doctor.ts @@ -8,7 +8,7 @@ import { posthogDoctorConfig, fetchHealthIssues, getKindMeta, -} from '@lib/programs/posthog-doctor/index'; +} from '@programs/posthog-doctor/index'; import { skillProgramOptions } from './skill-program-options'; import type { Command } from './command'; diff --git a/src/commands/error-tracking.ts b/src/commands/error-tracking.ts index 3db0b2816..962b1d612 100644 --- a/src/commands/error-tracking.ts +++ b/src/commands/error-tracking.ts @@ -1,4 +1,4 @@ -import { errorTrackingConfig } from '@lib/programs/error-tracking/index'; +import { errorTrackingConfig } from '@programs/error-tracking/index'; import type { Command } from './command'; import { nativeCommandFactory } from './factories/native-command-factory'; diff --git a/src/commands/factories/__tests__/native-command-factory.test.ts b/src/commands/factories/__tests__/native-command-factory.test.ts index 9539cc3bd..0cdc69e63 100644 --- a/src/commands/factories/__tests__/native-command-factory.test.ts +++ b/src/commands/factories/__tests__/native-command-factory.test.ts @@ -10,7 +10,7 @@ vi.mock('@lib/runners', () => ({ import type { Arguments } from 'yargs'; -import type { ProgramConfig } from '@lib/programs/program-step'; +import type { ProgramConfig } from '@programs/types'; import { nativeCommandFactory } from '../native-command-factory'; diff --git a/src/commands/factories/family-command-factory.ts b/src/commands/factories/family-command-factory.ts index 087bd5d21..e26a38f55 100644 --- a/src/commands/factories/family-command-factory.ts +++ b/src/commands/factories/family-command-factory.ts @@ -1,11 +1,11 @@ import type { Arguments } from 'yargs'; -import type { ProgramConfig } from '@lib/programs/program-step'; +import type { ProgramConfig } from '@programs/types'; import { buildFamilyPickerChildren, dispatchFamily, pickerChildrenToShow, -} from '@lib/programs/dispatch-family'; +} from '@programs/dispatch-family'; import { getSkillsBaseUrl } from '@shared/constants'; import { fetchSkillMenu } from '@shared/skill-menu'; diff --git a/src/commands/factories/native-command-factory.ts b/src/commands/factories/native-command-factory.ts index d9fd65a22..1cb4ae068 100644 --- a/src/commands/factories/native-command-factory.ts +++ b/src/commands/factories/native-command-factory.ts @@ -1,4 +1,4 @@ -import type { ProgramConfig } from '@lib/programs/program-step'; +import type { ProgramConfig } from '@programs/types'; import type { Command } from '../command'; diff --git a/src/commands/factories/shared.ts b/src/commands/factories/shared.ts index cf2e73951..e38e96717 100644 --- a/src/commands/factories/shared.ts +++ b/src/commands/factories/shared.ts @@ -2,7 +2,7 @@ import type { Arguments, Options } from 'yargs'; import { runWizard, runWizardCI, runWizardHeadless } from '@lib/runners'; import { isHeadless } from '@lib/headless-mode'; -import type { ProgramConfig } from '@lib/programs/program-step'; +import type { ProgramConfig } from '@programs/types'; import { skillProgramOptions } from '../skill-program-options'; import { ErrorCodes } from '@shared/errors'; diff --git a/src/commands/mcp-analytics.ts b/src/commands/mcp-analytics.ts index 6d49b114e..4b36a2f95 100644 --- a/src/commands/mcp-analytics.ts +++ b/src/commands/mcp-analytics.ts @@ -1,4 +1,4 @@ -import { mcpAnalyticsConfig } from '@lib/programs/mcp-analytics/index'; +import { mcpAnalyticsConfig } from '@programs/mcp-analytics/index'; import type { Command } from './command'; import { nativeCommandFactory } from './factories/native-command-factory'; diff --git a/src/commands/mcp/add.ts b/src/commands/mcp/add.ts index f9b22e7a0..887bc0bc1 100644 --- a/src/commands/mcp/add.ts +++ b/src/commands/mcp/add.ts @@ -2,7 +2,7 @@ import type { Arguments } from 'yargs'; import { setUI } from '@ui'; import { LoggingUI } from '@ui/logging-ui'; import { headlessOption, isHeadless } from '@lib/headless-mode'; -import { Program } from '@lib/programs/program-registry'; +import { Program } from '@programs'; import { VERSION } from '@shared/version'; import type { Command } from '../command'; import { isTUIUnavailable } from './tui-availability'; diff --git a/src/commands/mcp/remove.ts b/src/commands/mcp/remove.ts index 26e34291e..9b82c728f 100644 --- a/src/commands/mcp/remove.ts +++ b/src/commands/mcp/remove.ts @@ -2,7 +2,7 @@ import type { Arguments } from 'yargs'; import { setUI } from '@ui'; import { LoggingUI } from '@ui/logging-ui'; import { headlessOption, isHeadless } from '@lib/headless-mode'; -import { Program } from '@lib/programs/program-registry'; +import { Program } from '@programs'; import { VERSION } from '@shared/version'; import type { Command } from '../command'; import { isTUIUnavailable } from './tui-availability'; diff --git a/src/commands/mcp/tutorial.ts b/src/commands/mcp/tutorial.ts index eb6c0b495..6d2919142 100644 --- a/src/commands/mcp/tutorial.ts +++ b/src/commands/mcp/tutorial.ts @@ -1,7 +1,7 @@ import type { Arguments } from 'yargs'; import { getUI, setUI } from '@ui'; import { LoggingUI } from '@ui/logging-ui'; -import { Program } from '@lib/programs/program-registry'; +import { Program } from '@programs'; import { VERSION } from '@shared/version'; import { ErrorCodes } from '@shared/errors'; import { emitWizardError } from '@shared/errors'; diff --git a/src/commands/metrics.ts b/src/commands/metrics.ts index a889bd24c..0f0978b1a 100644 --- a/src/commands/metrics.ts +++ b/src/commands/metrics.ts @@ -1,4 +1,4 @@ -import { metricsConfig } from '@lib/programs/metrics/index'; +import { metricsConfig } from '@programs/metrics/index'; import type { Command } from './command'; import { nativeCommandFactory } from './factories/native-command-factory'; diff --git a/src/commands/migrate.ts b/src/commands/migrate.ts index e7389efcf..ec937197d 100644 --- a/src/commands/migrate.ts +++ b/src/commands/migrate.ts @@ -1,4 +1,4 @@ -import { migrationConfig } from '@lib/programs/migration/index'; +import { migrationConfig } from '@programs/migration/index'; import type { Command } from './command'; import { nativeCommandFactory } from './factories/native-command-factory'; diff --git a/src/commands/replay-vision.ts b/src/commands/replay-vision.ts index 10e8e2db9..8b13e19c2 100644 --- a/src/commands/replay-vision.ts +++ b/src/commands/replay-vision.ts @@ -1,4 +1,4 @@ -import { replayVisionConfig } from '@lib/programs/replay-vision/index'; +import { replayVisionConfig } from '@programs/replay-vision/index'; import type { Command } from './command'; import { nativeCommandFactory } from './factories/native-command-factory'; diff --git a/src/commands/revenue.ts b/src/commands/revenue.ts index a41f6af09..76f50c629 100644 --- a/src/commands/revenue.ts +++ b/src/commands/revenue.ts @@ -1,4 +1,4 @@ -import { revenueAnalyticsConfig } from '@lib/programs/revenue-analytics/index'; +import { revenueAnalyticsConfig } from '@programs/revenue-analytics/index'; import type { Command } from './command'; import { nativeCommandFactory } from './factories/native-command-factory'; diff --git a/src/commands/self-driving.ts b/src/commands/self-driving.ts index 5f38f40e4..5a585e9b0 100644 --- a/src/commands/self-driving.ts +++ b/src/commands/self-driving.ts @@ -1,5 +1,5 @@ import { runWizard, runWizardCI } from '@lib/runners'; -import { selfDrivingConfig } from '@lib/programs/self-driving/index'; +import { selfDrivingConfig } from '@programs/self-driving/index'; import { skillProgramOptions } from './skill-program-options'; import type { Command } from './command'; diff --git a/src/commands/slack.ts b/src/commands/slack.ts index cd857e6c2..c65060356 100644 --- a/src/commands/slack.ts +++ b/src/commands/slack.ts @@ -1,7 +1,7 @@ import type { Arguments } from 'yargs'; import { getUI, setUI } from '@ui'; import { LoggingUI } from '@ui/logging-ui'; -import { Program } from '@lib/programs/program-registry'; +import { Program } from '@programs'; import { VERSION } from '@shared/version'; import { ErrorCodes } from '@shared/errors'; import { emitWizardError } from '@shared/errors'; diff --git a/src/commands/upload-sourcemaps.ts b/src/commands/upload-sourcemaps.ts index 22e6f96c1..1ffc65079 100644 --- a/src/commands/upload-sourcemaps.ts +++ b/src/commands/upload-sourcemaps.ts @@ -1,5 +1,5 @@ import { runWizard, runWizardCI } from '@lib/runners'; -import { errorTrackingUploadSourceMapsConfig } from '@lib/programs/error-tracking-upload-source-maps/index'; +import { errorTrackingUploadSourceMapsConfig } from '@programs/error-tracking-upload-source-maps/index'; import { skillProgramOptions } from './skill-program-options'; import type { Command } from './command'; diff --git a/src/commands/warehouse.ts b/src/commands/warehouse.ts index b6c53e0df..1b9c52637 100644 --- a/src/commands/warehouse.ts +++ b/src/commands/warehouse.ts @@ -1,4 +1,4 @@ -import { warehouseSourceConfig } from '@lib/programs/warehouse-source/index'; +import { warehouseSourceConfig } from '@programs/warehouse-source/index'; import type { Command } from './command'; import { nativeCommandFactory } from './factories/native-command-factory'; diff --git a/src/lib/__tests__/wizard-spellbook.test.ts b/src/lib/__tests__/wizard-spellbook.test.ts index 2f15a66b7..0d0889c6f 100644 --- a/src/lib/__tests__/wizard-spellbook.test.ts +++ b/src/lib/__tests__/wizard-spellbook.test.ts @@ -2,7 +2,7 @@ import fs from 'fs/promises'; import os from 'os'; import path from 'path'; import { Integration } from '@shared/constants'; -import type { ProgramConfig } from '../programs/program-step'; +import type { ProgramConfig } from '../../programs/program-step'; import { buildSession } from '../wizard-session'; import { writeWizardSpellbook } from '../wizard-spellbook'; import { downloadSkill } from '@agent/tools/tools'; diff --git a/src/lib/registry.ts b/src/lib/registry.ts deleted file mode 100644 index 0c1ae0b1c..000000000 --- a/src/lib/registry.ts +++ /dev/null @@ -1,59 +0,0 @@ -import type { FrameworkConfig } from './framework-config'; -import { Integration } from '@shared/constants'; -import { NEXTJS_AGENT_CONFIG } from '@frameworks/nextjs/nextjs-wizard-agent'; -import { NUXT_AGENT_CONFIG } from '@frameworks/nuxt/nuxt-wizard-agent'; -import { VUE_AGENT_CONFIG } from '@frameworks/vue/vue-wizard-agent'; -import { REACT_ROUTER_AGENT_CONFIG } from '@frameworks/react-router/react-router-wizard-agent'; -import { TANSTACK_ROUTER_AGENT_CONFIG } from '@frameworks/tanstack-router/tanstack-router-wizard-agent'; -import { TANSTACK_START_AGENT_CONFIG } from '@frameworks/tanstack-start/tanstack-start-wizard-agent'; -import { REACT_NATIVE_AGENT_CONFIG } from '@frameworks/react-native/react-native-wizard-agent'; -import { ANGULAR_AGENT_CONFIG } from '@frameworks/angular/angular-wizard-agent'; -import { ASTRO_AGENT_CONFIG } from '@frameworks/astro/astro-wizard-agent'; -import { DJANGO_AGENT_CONFIG } from '@frameworks/django/django-wizard-agent'; -import { FLASK_AGENT_CONFIG } from '@frameworks/flask/flask-wizard-agent'; -import { FASTAPI_AGENT_CONFIG } from '@frameworks/fastapi/fastapi-wizard-agent'; -import { LARAVEL_AGENT_CONFIG } from '@frameworks/laravel/laravel-wizard-agent'; -import { SVELTEKIT_AGENT_CONFIG } from '@frameworks/svelte/svelte-wizard-agent'; -import { FLUTTER_AGENT_CONFIG } from '@frameworks/flutter/flutter-wizard-agent'; -import { SWIFT_AGENT_CONFIG } from '@frameworks/swift/swift-wizard-agent'; -import { KMP_AGENT_CONFIG } from '@frameworks/kmp/kmp-wizard-agent'; -import { ANDROID_AGENT_CONFIG } from '@frameworks/android/android-wizard-agent'; -import { RAILS_AGENT_CONFIG } from '@frameworks/rails/rails-wizard-agent'; -import { ELIXIR_AGENT_CONFIG } from '@frameworks/elixir/elixir-wizard-agent'; -import { GO_AGENT_CONFIG } from '@frameworks/go/go-wizard-agent'; -import { JAVA_AGENT_CONFIG } from '@frameworks/java/java-wizard-agent'; -import { RUST_AGENT_CONFIG } from '@frameworks/rust/rust-wizard-agent'; -import { PYTHON_AGENT_CONFIG } from '@frameworks/python/python-wizard-agent'; -import { RUBY_AGENT_CONFIG } from '@frameworks/ruby/ruby-wizard-agent'; -import { JAVASCRIPT_NODE_AGENT_CONFIG } from '@frameworks/javascript-node/javascript-node-wizard-agent'; -import { JAVASCRIPT_WEB_AGENT_CONFIG } from '@frameworks/javascript-web/javascript-web-wizard-agent'; - -export const FRAMEWORK_REGISTRY: Record = { - [Integration.nextjs]: NEXTJS_AGENT_CONFIG, - [Integration.nuxt]: NUXT_AGENT_CONFIG, - [Integration.vue]: VUE_AGENT_CONFIG, - [Integration.tanstackStart]: TANSTACK_START_AGENT_CONFIG, - [Integration.reactRouter]: REACT_ROUTER_AGENT_CONFIG, - [Integration.tanstackRouter]: TANSTACK_ROUTER_AGENT_CONFIG, - [Integration.reactNative]: REACT_NATIVE_AGENT_CONFIG, - [Integration.angular]: ANGULAR_AGENT_CONFIG, - [Integration.astro]: ASTRO_AGENT_CONFIG, - [Integration.django]: DJANGO_AGENT_CONFIG, - [Integration.flask]: FLASK_AGENT_CONFIG, - [Integration.fastapi]: FASTAPI_AGENT_CONFIG, - [Integration.laravel]: LARAVEL_AGENT_CONFIG, - [Integration.sveltekit]: SVELTEKIT_AGENT_CONFIG, - [Integration.flutter]: FLUTTER_AGENT_CONFIG, - [Integration.kmp]: KMP_AGENT_CONFIG, - [Integration.swift]: SWIFT_AGENT_CONFIG, - [Integration.android]: ANDROID_AGENT_CONFIG, - [Integration.rails]: RAILS_AGENT_CONFIG, - [Integration.elixir]: ELIXIR_AGENT_CONFIG, - [Integration.go]: GO_AGENT_CONFIG, - [Integration.rust]: RUST_AGENT_CONFIG, - [Integration.java]: JAVA_AGENT_CONFIG, - [Integration.python]: PYTHON_AGENT_CONFIG, - [Integration.ruby]: RUBY_AGENT_CONFIG, - [Integration.javascriptNode]: JAVASCRIPT_NODE_AGENT_CONFIG, - [Integration.javascript_web]: JAVASCRIPT_WEB_AGENT_CONFIG, -}; diff --git a/src/lib/runners/__tests__/mint-recovery.test.ts b/src/lib/runners/__tests__/mint-recovery.test.ts index 70dfc189c..423eb9d4b 100644 --- a/src/lib/runners/__tests__/mint-recovery.test.ts +++ b/src/lib/runners/__tests__/mint-recovery.test.ts @@ -1,11 +1,11 @@ import { vi, it, expect, afterEach } from 'vitest'; import { runWizard } from '../run-wizard'; -import { runProgramAgent } from '@lib/programs/run-agent-legacy'; +import { runProgramAgent } from '@programs/run-agent-legacy'; import { startTUI } from '@ui/tui/start-tui'; import { WizardStore } from '@ui/tui/store'; import { InkUI } from '@ui/tui/ink-ui'; import { setUI } from '@ui'; -import { posthogIntegrationConfig } from '@lib/programs/posthog-integration'; +import { posthogIntegrationConfig } from '@programs/posthog-integration'; import { ScreenId } from '@ui/tui/router'; import { HostResolution } from '@shared/host-resolution'; import { analytics } from '@utils/analytics'; @@ -13,7 +13,7 @@ import { RunPhase } from '@lib/wizard-session'; const streamShutdown = vi.hoisted(() => vi.fn().mockResolvedValue(undefined)); -vi.mock('@lib/programs/run-agent-legacy', () => ({ runProgramAgent: vi.fn() })); +vi.mock('@programs/run-agent-legacy', () => ({ runProgramAgent: vi.fn() })); vi.mock('@ui/tui/start-tui', () => ({ startTUI: vi.fn() })); vi.mock('@shared/local-dev', async (original) => ({ ...(await original()), @@ -30,14 +30,14 @@ vi.mock('@utils/analytics', () => ({ }, sessionProperties: () => ({}), })); -vi.mock('@lib/task-stream/index', () => ({ +vi.mock('@programs/task-stream/index', () => ({ TaskStreamPush: class { attach = vi.fn(); finishRun = vi.fn().mockResolvedValue(undefined); shutdown = streamShutdown; }, })); -vi.mock('@lib/task-stream/destinations/posthog', () => ({ +vi.mock('@programs/task-stream/destinations/posthog', () => ({ PostHogDestination: class {}, })); diff --git a/src/lib/runners/run-non-interactive.ts b/src/lib/runners/run-non-interactive.ts index 8f215ed27..e78e40bf3 100644 --- a/src/lib/runners/run-non-interactive.ts +++ b/src/lib/runners/run-non-interactive.ts @@ -6,7 +6,7 @@ import { import { createWizardRunSync, type RunOutcome, -} from '@lib/task-stream/wizard-run-sync'; +} from '@programs/task-stream/wizard-run-sync'; import { runtimeEnv } from '@env'; import { registerShutdown, runCleanups } from '@utils/wizard-abort'; import { @@ -17,19 +17,19 @@ import { import type { CloudRegion } from '@utils/types'; import { getUI, setUI } from '@ui'; import { LoggingUI } from '@ui/logging-ui'; -import type { ProgramConfig } from '@lib/programs/program-step'; -import { getAuditChecks } from '@lib/programs/audit/types'; +import type { ProgramConfig } from '@programs/types'; +import { getAuditChecks } from '@programs/audit/types'; import { analytics } from '@utils/analytics'; import { resolveNoTelemetry } from './resolve-no-telemetry'; import type { WizardStore } from '@ui/tui/store'; -import type { TaskStreamPush } from '@lib/task-stream/task-stream-push'; +import type { TaskStreamPush } from '@programs/task-stream/task-stream-push'; import { join } from 'node:path'; import { ErrorCodes, classifyRunFailure, emitWizardError, } from '@shared/errors'; -import { detectErrorCode } from '@lib/programs/detect-map'; +import { detectErrorCode } from '@programs/detect-map'; import type { OutroData, RunPhase as RunPhaseT } from '@lib/wizard-session'; /** @@ -193,7 +193,7 @@ export function runNonInteractive( const { WizardStore } = await import('@ui/tui/store'); const { HeadlessUI } = await import('@ui/headless-ui'); const { TaskStreamPush, PostHogDestination, createFileDestination } = - await import('@lib/task-stream/index'); + await import('@programs/task-stream/index'); // `''` resolves to the default path, so `--ci` always dumps. const logTarget = @@ -375,9 +375,7 @@ export function runNonInteractive( } } - const { runProgramAgent } = await import( - '@lib/programs/run-agent-legacy' - ); + const { runProgramAgent } = await import('@programs/run-agent-legacy'); await runProgramAgent(config, session); if (signalled) return; await settleStream(RunPhase.Completed); diff --git a/src/lib/runners/run-wizard-ci.ts b/src/lib/runners/run-wizard-ci.ts index e278bd5f5..247f558f9 100644 --- a/src/lib/runners/run-wizard-ci.ts +++ b/src/lib/runners/run-wizard-ci.ts @@ -1,4 +1,4 @@ -import type { ProgramConfig } from '@lib/programs/program-step'; +import type { ProgramConfig } from '@programs/types'; import { runNonInteractive } from './run-non-interactive'; /** diff --git a/src/lib/runners/run-wizard-headless.ts b/src/lib/runners/run-wizard-headless.ts index 20916c8eb..c88744019 100644 --- a/src/lib/runners/run-wizard-headless.ts +++ b/src/lib/runners/run-wizard-headless.ts @@ -1,4 +1,4 @@ -import type { ProgramConfig } from '@lib/programs/program-step'; +import type { ProgramConfig } from '@programs/types'; import { runNonInteractive } from './run-non-interactive'; /** diff --git a/src/lib/runners/run-wizard.ts b/src/lib/runners/run-wizard.ts index 0524620ab..16272caf5 100644 --- a/src/lib/runners/run-wizard.ts +++ b/src/lib/runners/run-wizard.ts @@ -1,19 +1,19 @@ import { VERSION } from '@shared/version'; import { logToFile, getLogFilePath } from '@utils/debug'; -import { runProgramAgent } from '@lib/programs/run-agent-legacy'; -import { authenticate } from '@lib/programs/authenticate'; -import { getProgramConfig } from '@lib/programs/program-registry'; -import { getAuditChecks } from '@lib/programs/audit/types'; -import { maybeStampAiSdkDetected } from '@lib/programs/posthog-integration/detect'; -import type { ProgramConfig } from '@lib/programs/program-step'; +import { runProgramAgent } from '@programs/run-agent-legacy'; +import { authenticate } from '@programs/authenticate'; +import { getProgramConfig } from '@programs'; +import { getAuditChecks } from '@programs/audit/types'; +import { maybeStampAiSdkDetected } from '@programs/posthog-integration/detect'; +import type { ProgramConfig } from '@programs/types'; import type { Harness, Sequence } from '@shared/constants'; import type { startTUI as StartTUIFn } from '@ui/tui/start-tui'; import type { WizardStore } from '@ui/tui/store'; import { OutroKind, type WizardSession } from '@lib/wizard-session'; -import type { TaskStreamPush as TaskStreamPushClass } from '@lib/task-stream/task-stream-push'; +import type { TaskStreamPush as TaskStreamPushClass } from '@programs/task-stream/task-stream-push'; import { resolveNoTelemetry } from './resolve-no-telemetry'; import { checkLocalServices, getLocalDev } from '@shared/local-dev'; -import { createWizardRunSync } from '@lib/task-stream/wizard-run-sync'; +import { createWizardRunSync } from '@programs/task-stream/wizard-run-sync'; import { runtimeEnv } from '@env'; import { runCleanups, registerShutdown } from '@utils/wizard-abort'; import { classifyRunFailure, emitWizardError } from '@shared/errors'; @@ -90,12 +90,12 @@ export function runWizard( const { startTUI } = await import('@ui/tui/start-tui'); const { buildSession, RunPhase } = await import('@lib/wizard-session'); - const { TaskStreamPush } = await import('@lib/task-stream/index'); + const { TaskStreamPush } = await import('@programs/task-stream/index'); const { PostHogDestination } = await import( - '@lib/task-stream/destinations/posthog' + '@programs/task-stream/destinations/posthog' ); const { createFileDestination } = await import( - '@lib/task-stream/destinations/file' + '@programs/task-stream/destinations/file' ); // Before the TUI mounts: once Ink owns the alt screen, anything written diff --git a/src/lib/wizard-session.ts b/src/lib/wizard-session.ts index a36020f68..548eacb01 100644 --- a/src/lib/wizard-session.ts +++ b/src/lib/wizard-session.ts @@ -12,7 +12,7 @@ import { POSTHOG_LOCAL_URL, resolveLocalDev } from '@shared/local-dev'; import type { Harness, Integration, Sequence } from '@shared/constants'; -import type { FrameworkConfig } from './framework-config'; +import type { FrameworkConfig } from '@programs/types'; import type { WizardReadinessResult } from '@shared/health-checks/readiness'; import type { SettingsConflict } from '@shared/claude-settings'; import type { ApiUser, ApiProject, Credentials } from '@shared/api'; diff --git a/src/lib/wizard-spellbook.ts b/src/lib/wizard-spellbook.ts index 8473d8096..36af8c739 100644 --- a/src/lib/wizard-spellbook.ts +++ b/src/lib/wizard-spellbook.ts @@ -1,7 +1,7 @@ import fs from 'fs/promises'; import path from 'path'; import { getSkillsBaseUrl, POSTHOG_DOCS_URL } from '@shared/constants'; -import type { ProgramConfig } from './programs/program-step'; +import type { ProgramConfig } from '@programs/types'; import type { WizardSession } from './wizard-session'; import { downloadSkill } from '@agent'; import { diff --git a/src/lib/programs/__tests__/__snapshots__/flow-traces.test.ts.snap b/src/programs/__tests__/__snapshots__/flow-traces.test.ts.snap similarity index 100% rename from src/lib/programs/__tests__/__snapshots__/flow-traces.test.ts.snap rename to src/programs/__tests__/__snapshots__/flow-traces.test.ts.snap diff --git a/src/lib/programs/__tests__/__snapshots__/post-auth-gates.test.ts.snap b/src/programs/__tests__/__snapshots__/post-auth-gates.test.ts.snap similarity index 100% rename from src/lib/programs/__tests__/__snapshots__/post-auth-gates.test.ts.snap rename to src/programs/__tests__/__snapshots__/post-auth-gates.test.ts.snap diff --git a/src/lib/programs/__tests__/agent-skill.test.ts b/src/programs/__tests__/agent-skill.test.ts similarity index 96% rename from src/lib/programs/__tests__/agent-skill.test.ts rename to src/programs/__tests__/agent-skill.test.ts index 913ce5d01..9f2111917 100644 --- a/src/lib/programs/__tests__/agent-skill.test.ts +++ b/src/programs/__tests__/agent-skill.test.ts @@ -2,8 +2,8 @@ import { createSkillProgram, AGENT_SKILL_STEPS, type SkillProgramOptions, -} from '@lib/programs/agent-skill/index'; -import type { ProgramRun } from '@lib/programs/program-run'; +} from '@programs/agent-skill/index'; +import type { ProgramRun } from '@programs/program-run'; import { buildSession, RunPhase } from '@lib/wizard-session'; import { HostResolution } from '@shared/host-resolution'; diff --git a/src/lib/programs/__tests__/audit-seed.test.ts b/src/programs/__tests__/audit-seed.test.ts similarity index 94% rename from src/lib/programs/__tests__/audit-seed.test.ts rename to src/programs/__tests__/audit-seed.test.ts index 1897a2b19..d8a92aa06 100644 --- a/src/lib/programs/__tests__/audit-seed.test.ts +++ b/src/programs/__tests__/audit-seed.test.ts @@ -2,8 +2,8 @@ import * as fs from 'fs'; import * as os from 'os'; import * as path from 'path'; -import { AUDIT_SEED_CHECKS, seedAuditLedger } from '@lib/programs/audit/seed'; -import { AUDIT_CHECKS_FILE, type AuditCheck } from '@lib/programs/audit/types'; +import { AUDIT_SEED_CHECKS, seedAuditLedger } from '@programs/audit/seed'; +import { AUDIT_CHECKS_FILE, type AuditCheck } from '@programs/audit/types'; import { COL_AREA_WIDTH } from '@ui/tui/screens/audit/AuditChecksViewer/layout'; const ids = (checks: AuditCheck[]) => checks.map((c) => c.id); diff --git a/src/lib/__tests__/cloudflare-detection.test.ts b/src/programs/__tests__/cloudflare-detection.test.ts similarity index 97% rename from src/lib/__tests__/cloudflare-detection.test.ts rename to src/programs/__tests__/cloudflare-detection.test.ts index b7c33cf7e..acaac9e20 100644 --- a/src/lib/__tests__/cloudflare-detection.test.ts +++ b/src/programs/__tests__/cloudflare-detection.test.ts @@ -1,7 +1,7 @@ import * as fs from 'fs'; import * as path from 'path'; import * as os from 'os'; -import { detectCloudflareTarget } from '@lib/cloudflare-detection'; +import { detectCloudflareTarget } from '@programs/cloudflare-detection'; vi.mock('@utils/debug'); diff --git a/src/lib/programs/__tests__/detect-map.test.ts b/src/programs/__tests__/detect-map.test.ts similarity index 100% rename from src/lib/programs/__tests__/detect-map.test.ts rename to src/programs/__tests__/detect-map.test.ts diff --git a/src/lib/programs/__tests__/error-tracking.test.ts b/src/programs/__tests__/error-tracking.test.ts similarity index 88% rename from src/lib/programs/__tests__/error-tracking.test.ts rename to src/programs/__tests__/error-tracking.test.ts index bf49fb9c5..47f6b912b 100644 --- a/src/lib/programs/__tests__/error-tracking.test.ts +++ b/src/programs/__tests__/error-tracking.test.ts @@ -1,35 +1,37 @@ import { beforeEach, describe, expect, test, vi } from 'vitest'; -import type { ProgramRun } from '@lib/programs/program-run'; +import type { ProgramRun } from '@programs/program-run'; import { Integration } from '@shared/constants'; -import type { AgenticDetectionReport } from '@lib/detection/agentic'; -import { detectFramework } from '@lib/detection/index'; +import type { AgenticDetectionReport } from '@programs/detection/agentic'; +import { detectFramework } from '@programs/detection/index'; import { ErrorCodes } from '@shared/errors'; -import { ERROR_TRACKING_TIPS } from '@lib/programs/error-tracking/content/tips'; +import { ERROR_TRACKING_TIPS } from '@ui/tui/decks/error-tracking/tips'; import { ERROR_TRACKING_PROJECT_PATH_KEY, toErrorTrackingReport, -} from '@lib/programs/error-tracking/detect-agentic'; +} from '@programs/error-tracking/detect-agentic'; import { errorTrackingConfig, SYMBOL_UPLOAD_CLI_FRAMEWORKS, -} from '@lib/programs/error-tracking/index'; -import { VARIANTS_REQUIRING_POSTHOG_CLI } from '@lib/programs/error-tracking-upload-source-maps/detect'; -import { preinstallPostHogCliOnce } from '@lib/programs/shared/posthog-cli-preinstall'; +} from '@programs/error-tracking/index'; +import { VARIANTS_REQUIRING_POSTHOG_CLI } from '@programs/error-tracking-upload-source-maps/detect'; +import { preinstallPostHogCliOnce } from '@programs/shared/posthog-cli-preinstall'; import type { WizardSession } from '@lib/wizard-session'; import { analytics } from '@utils/analytics'; import { wizardAbort } from '@utils/wizard-abort'; -vi.mock('@lib/detection/index', async (importOriginal) => ({ - ...(await importOriginal()), +vi.mock('@programs/detection/index', async (importOriginal) => ({ + ...(await importOriginal()), detectFramework: vi.fn(), })); -vi.mock('@lib/detection/project-scope', async (importOriginal) => ({ - ...(await importOriginal()), +vi.mock('@programs/detection/project-scope', async (importOriginal) => ({ + ...(await importOriginal< + typeof import('@programs/detection/project-scope') + >()), scopeInstallDirToProject: vi.fn(), detectIntegrationProjects: vi.fn(), })); -vi.mock('@lib/programs/shared/posthog-cli-preinstall', () => ({ +vi.mock('@programs/shared/posthog-cli-preinstall', () => ({ preinstallPostHogCliOnce: vi.fn(), })); vi.mock('@utils/wizard-abort', async (importOriginal) => ({ diff --git a/src/lib/programs/__tests__/flow-traces.test.ts b/src/programs/__tests__/flow-traces.test.ts similarity index 99% rename from src/lib/programs/__tests__/flow-traces.test.ts rename to src/programs/__tests__/flow-traces.test.ts index 769c1759e..f48428f3c 100644 --- a/src/lib/programs/__tests__/flow-traces.test.ts +++ b/src/programs/__tests__/flow-traces.test.ts @@ -19,7 +19,7 @@ import { type WizardSession, } from '@lib/wizard-session'; import { Integration } from '@shared/constants'; -import { FRAMEWORK_REGISTRY } from '@lib/registry'; +import { FRAMEWORK_REGISTRY } from '@programs/frameworks/registry'; import { HostResolution } from '@shared/host-resolution'; import { WizardReadiness } from '@shared/health-checks/readiness'; import { analytics } from '@utils/analytics'; diff --git a/src/lib/programs/__tests__/helpers/integration-prompt.no-jest.ts b/src/programs/__tests__/helpers/integration-prompt.no-jest.ts similarity index 88% rename from src/lib/programs/__tests__/helpers/integration-prompt.no-jest.ts rename to src/programs/__tests__/helpers/integration-prompt.no-jest.ts index 72758ac55..7169f6db5 100644 --- a/src/lib/programs/__tests__/helpers/integration-prompt.no-jest.ts +++ b/src/programs/__tests__/helpers/integration-prompt.no-jest.ts @@ -4,10 +4,10 @@ * `posthog-integration-prompt.test.ts`). */ -import { posthogIntegrationConfig } from '@lib/programs/posthog-integration/index'; -import { DETECTED_WAREHOUSE_SOURCES_KEY } from '@lib/programs/warehouse-source/detect'; +import { posthogIntegrationConfig } from '@programs/posthog-integration/index'; +import { DETECTED_WAREHOUSE_SOURCES_KEY } from '@programs/warehouse-source/detect'; import { buildSession, type WizardSession } from '@lib/wizard-session'; -import type { DetectedSource } from '@lib/warehouse-sources/types'; +import type { DetectedSource } from '@programs/warehouse-sources/types'; export const CREDENTIALS = { accessToken: 'tok', diff --git a/src/lib/programs/__tests__/mcp-analytics.test.ts b/src/programs/__tests__/mcp-analytics.test.ts similarity index 97% rename from src/lib/programs/__tests__/mcp-analytics.test.ts rename to src/programs/__tests__/mcp-analytics.test.ts index a2c822c00..726515d6e 100644 --- a/src/lib/programs/__tests__/mcp-analytics.test.ts +++ b/src/programs/__tests__/mcp-analytics.test.ts @@ -1,7 +1,7 @@ import { MCP_ANALYTICS_ABORT_CASES, mcpAnalyticsConfig, -} from '@lib/programs/mcp-analytics/index'; +} from '@programs/mcp-analytics/index'; describe('MCP_ANALYTICS_ABORT_CASES', () => { // These are the exact `[ABORT] ` strings the mcp-analytics skill diff --git a/src/lib/programs/__tests__/metrics-program.test.ts b/src/programs/__tests__/metrics-program.test.ts similarity index 86% rename from src/lib/programs/__tests__/metrics-program.test.ts rename to src/programs/__tests__/metrics-program.test.ts index 46f381471..88657fd1a 100644 --- a/src/lib/programs/__tests__/metrics-program.test.ts +++ b/src/programs/__tests__/metrics-program.test.ts @@ -1,9 +1,9 @@ -import { AGENT_SKILL_STEPS } from '@lib/programs/agent-skill/index'; -import { getProgramConfig, Program } from '@lib/programs/program-registry'; -import { metricsConfig } from '@lib/programs/metrics/index'; -import type { ProgramRun } from '@lib/programs/program-run'; +import { AGENT_SKILL_STEPS } from '@programs/agent-skill/index'; +import { getProgramConfig, Program } from '@programs'; +import { metricsConfig } from '@programs/metrics/index'; +import type { ProgramRun } from '@programs/program-run'; -import { metricsCommand } from '../../../commands/metrics'; +import { metricsCommand } from '../../commands/metrics'; function staticRun(config: typeof metricsConfig): ProgramRun { if (typeof config.run === 'function') { diff --git a/src/lib/programs/__tests__/post-auth-gates.test.ts b/src/programs/__tests__/post-auth-gates.test.ts similarity index 100% rename from src/lib/programs/__tests__/post-auth-gates.test.ts rename to src/programs/__tests__/post-auth-gates.test.ts diff --git a/src/lib/programs/__tests__/posthog-cli-preinstall.test.ts b/src/programs/__tests__/posthog-cli-preinstall.test.ts similarity index 97% rename from src/lib/programs/__tests__/posthog-cli-preinstall.test.ts rename to src/programs/__tests__/posthog-cli-preinstall.test.ts index 355fd10b1..0da57bf9b 100644 --- a/src/lib/programs/__tests__/posthog-cli-preinstall.test.ts +++ b/src/programs/__tests__/posthog-cli-preinstall.test.ts @@ -3,7 +3,7 @@ import { beforeEach, describe, expect, test, vi } from 'vitest'; import { preinstallPostHogCliOnce, resetPostHogCliPreinstallForTests, -} from '@lib/programs/shared/posthog-cli-preinstall'; +} from '@programs/shared/posthog-cli-preinstall'; import { installOrUpdatePostHogCli } from '@steps/install-cli-steering'; import { getUI } from '@ui'; import { analytics } from '@utils/analytics'; diff --git a/src/lib/programs/__tests__/posthog-integration-detect.test.ts b/src/programs/__tests__/posthog-integration-detect.test.ts similarity index 96% rename from src/lib/programs/__tests__/posthog-integration-detect.test.ts rename to src/programs/__tests__/posthog-integration-detect.test.ts index 7249ee81e..cb1e63416 100644 --- a/src/lib/programs/__tests__/posthog-integration-detect.test.ts +++ b/src/programs/__tests__/posthog-integration-detect.test.ts @@ -1,7 +1,7 @@ import * as fs from 'fs'; import * as path from 'path'; import * as os from 'os'; -import { detectExistingPostHog } from '@lib/programs/posthog-integration/detect'; +import { detectExistingPostHog } from '@programs/posthog-integration/detect'; function makeTmpDir(): string { return fs.mkdtempSync(path.join(os.tmpdir(), 'ph-detect-')); diff --git a/src/lib/programs/__tests__/posthog-integration-prompt.test.ts b/src/programs/__tests__/posthog-integration-prompt.test.ts similarity index 97% rename from src/lib/programs/__tests__/posthog-integration-prompt.test.ts rename to src/programs/__tests__/posthog-integration-prompt.test.ts index 11978acbf..df6fb83da 100644 --- a/src/lib/programs/__tests__/posthog-integration-prompt.test.ts +++ b/src/programs/__tests__/posthog-integration-prompt.test.ts @@ -8,7 +8,7 @@ */ import { WIZARD_DEFAULT_AIO_LOGS_FLAG_KEY } from '@shared/constants'; -import { posthogIntegrationConfig } from '@lib/programs/posthog-integration/index'; +import { posthogIntegrationConfig } from '@programs/posthog-integration/index'; import { analytics } from '@utils/analytics'; import { promptFor } from './helpers/integration-prompt.no-jest'; diff --git a/src/lib/programs/__tests__/program-registry.test.ts b/src/programs/__tests__/program-registry.test.ts similarity index 99% rename from src/lib/programs/__tests__/program-registry.test.ts rename to src/programs/__tests__/program-registry.test.ts index 90f3e472d..0450dccb4 100644 --- a/src/lib/programs/__tests__/program-registry.test.ts +++ b/src/programs/__tests__/program-registry.test.ts @@ -5,7 +5,7 @@ import { getLaunchablePrograms, getProgramConfig, getSubcommandPrograms, -} from '@lib/programs/program-registry'; +} from '../program-registry'; import type { WizardSession } from '@lib/wizard-session'; describe('PROGRAM_REGISTRY', () => { diff --git a/src/lib/programs/__tests__/program-step.test.ts b/src/programs/__tests__/program-step.test.ts similarity index 98% rename from src/lib/programs/__tests__/program-step.test.ts rename to src/programs/__tests__/program-step.test.ts index 57c4ac054..7bd68b2d4 100644 --- a/src/lib/programs/__tests__/program-step.test.ts +++ b/src/programs/__tests__/program-step.test.ts @@ -1,7 +1,7 @@ import { createProgramSequence, type ProgramStep, -} from '@lib/programs/program-step'; +} from '@programs/program-step'; describe('createProgramSequence', () => { it('filters out headless steps and keeps only screen-bearing ones', () => { diff --git a/src/lib/programs/__tests__/refresh-access-token-if-needed.test.ts b/src/programs/__tests__/refresh-access-token-if-needed.test.ts similarity index 100% rename from src/lib/programs/__tests__/refresh-access-token-if-needed.test.ts rename to src/programs/__tests__/refresh-access-token-if-needed.test.ts diff --git a/src/lib/programs/__tests__/replay-vision.test.ts b/src/programs/__tests__/replay-vision.test.ts similarity index 97% rename from src/lib/programs/__tests__/replay-vision.test.ts rename to src/programs/__tests__/replay-vision.test.ts index c049a66b4..ec97a39fd 100644 --- a/src/lib/programs/__tests__/replay-vision.test.ts +++ b/src/programs/__tests__/replay-vision.test.ts @@ -4,7 +4,7 @@ import { Integration } from '@shared/constants'; import { replayVisionConfig, REPLAY_VISION_SUPPORTED, -} from '@lib/programs/replay-vision/index'; +} from '@programs/replay-vision/index'; describe('replay-vision program', () => { test('runs the replay-vision agent flow', () => { diff --git a/src/lib/programs/__tests__/revenue-analytics-detect.test.ts b/src/programs/__tests__/revenue-analytics-detect.test.ts similarity index 97% rename from src/lib/programs/__tests__/revenue-analytics-detect.test.ts rename to src/programs/__tests__/revenue-analytics-detect.test.ts index 5907dc4fa..33d6fabcb 100644 --- a/src/lib/programs/__tests__/revenue-analytics-detect.test.ts +++ b/src/programs/__tests__/revenue-analytics-detect.test.ts @@ -1,7 +1,7 @@ import * as fs from 'fs'; import * as path from 'path'; import * as os from 'os'; -import { detectRevenuePrerequisites } from '@lib/programs/revenue-analytics/index'; +import { detectRevenuePrerequisites } from '@programs/revenue-analytics/index'; import { buildSession } from '@lib/wizard-session'; function makeTmpDir(): string { diff --git a/src/lib/programs/__tests__/run-agent-legacy.test.ts b/src/programs/__tests__/run-agent-legacy.test.ts similarity index 99% rename from src/lib/programs/__tests__/run-agent-legacy.test.ts rename to src/programs/__tests__/run-agent-legacy.test.ts index 3c1a33e35..b33f278e6 100644 --- a/src/lib/programs/__tests__/run-agent-legacy.test.ts +++ b/src/programs/__tests__/run-agent-legacy.test.ts @@ -3,7 +3,7 @@ import os from 'os'; import path from 'path'; import { runNonInteractive } from '@lib/runners/run-non-interactive'; import { runWizard } from '@lib/runners/run-wizard'; -import { authenticate } from '@lib/programs/authenticate'; +import { authenticate } from '@programs/authenticate'; import { runProgramAgent } from '../run-agent-legacy'; import { runAgent, RunOutcome, type RunResult } from '@agent/runner'; import { Harness, Sequence } from '@shared/constants'; @@ -38,7 +38,7 @@ vi.mock('@agent/gateway-session', async (original) => ({ ...(await original()), configureGatewayFromCIEnvironment: vi.fn(), })); -vi.mock('@lib/task-stream/index', () => ({ +vi.mock('@programs/task-stream/index', () => ({ TaskStreamPush: class { attach = vi.fn(); finishRun = vi.fn().mockResolvedValue(undefined); @@ -66,7 +66,7 @@ vi.mock('@agent/runner', async (original) => ({ ...(await original()), runAgent: vi.fn(), })); -vi.mock('@lib/programs/authenticate', () => ({ +vi.mock('@programs/authenticate', () => ({ authenticate: vi.fn().mockResolvedValue(undefined), refreshAccessTokenIfNeeded: vi.fn().mockResolvedValue(undefined), })); diff --git a/src/lib/programs/__tests__/self-driving-deck.test.ts b/src/programs/__tests__/self-driving-deck.test.ts similarity index 96% rename from src/lib/programs/__tests__/self-driving-deck.test.ts rename to src/programs/__tests__/self-driving-deck.test.ts index d4c552a23..94a39e55c 100644 --- a/src/lib/programs/__tests__/self-driving-deck.test.ts +++ b/src/programs/__tests__/self-driving-deck.test.ts @@ -7,7 +7,7 @@ */ import type { ReactNode, ReactElement } from 'react'; -import { getContentBlocks } from '@lib/programs/self-driving/content/index'; +import { getContentBlocks } from '@ui/tui/decks/self-driving/index'; /** paneWidth in LearnCard at 80 cols: (min(120, 80) - 2) / 2 - 2 */ const PANE_WIDTH_80COL = 37; diff --git a/src/lib/programs/__tests__/self-driving-detect.test.ts b/src/programs/__tests__/self-driving-detect.test.ts similarity index 98% rename from src/lib/programs/__tests__/self-driving-detect.test.ts rename to src/programs/__tests__/self-driving-detect.test.ts index 54b27d0fd..efc678f72 100644 --- a/src/lib/programs/__tests__/self-driving-detect.test.ts +++ b/src/programs/__tests__/self-driving-detect.test.ts @@ -5,23 +5,23 @@ import { detectSelfDrivingPrerequisites, selfDrivingConfig, SELF_DRIVING_ABORT_CASES, -} from '@lib/programs/self-driving/index'; +} from '@programs/self-driving/index'; import { detectPostHogPresent, POSTHOG_MANIFESTS, SELF_DRIVING_DETECTED_TOOLS_KEY, SELF_DRIVING_TOOL_KINDS, getSelfDrivingDetectedTools, -} from '@lib/programs/self-driving/detect'; -import { getDetectedWarehouseSources } from '@lib/programs/warehouse-source/detect'; +} from '@programs/self-driving/detect'; +import { getDetectedWarehouseSources } from '@programs/warehouse-source/detect'; import { WizardStore } from '@ui/tui/store'; -import { SOURCE_DETECTORS } from '@lib/warehouse-sources/registry'; -import type { DetectedSource } from '@lib/warehouse-sources/types'; -import { toIntegrationReport } from '@lib/programs/self-driving/detect-agentic'; +import { SOURCE_DETECTORS } from '@programs/warehouse-sources/registry'; +import type { DetectedSource } from '@programs/warehouse-sources/types'; +import { toIntegrationReport } from '@programs/self-driving/detect-agentic'; import { PROJECT_MANIFESTS, type AgenticDetectionReport, -} from '@lib/detection/agentic'; +} from '@programs/detection/agentic'; import { Integration } from '@shared/constants'; import { WIZARD_TOOL_NAMES } from '@agent/tools'; import { buildSession } from '@lib/wizard-session'; diff --git a/src/lib/programs/__tests__/self-driving-prompt.test.ts b/src/programs/__tests__/self-driving-prompt.test.ts similarity index 97% rename from src/lib/programs/__tests__/self-driving-prompt.test.ts rename to src/programs/__tests__/self-driving-prompt.test.ts index a2b886c5d..8d8cacf8f 100644 --- a/src/lib/programs/__tests__/self-driving-prompt.test.ts +++ b/src/programs/__tests__/self-driving-prompt.test.ts @@ -1,7 +1,7 @@ -import { buildSelfDrivingPrompt } from '@lib/programs/self-driving/prompt'; +import { buildSelfDrivingPrompt } from '@programs/self-driving/prompt'; import type { PromptContext } from '@agent/agent-runner'; import { HostResolution } from '@shared/host-resolution'; -import type { DetectedSource } from '@lib/warehouse-sources/types'; +import type { DetectedSource } from '@programs/warehouse-sources/types'; const ctx: PromptContext = { projectId: 123, diff --git a/src/lib/programs/__tests__/source-maps-detect-agentic.test.ts b/src/programs/__tests__/source-maps-detect-agentic.test.ts similarity index 99% rename from src/lib/programs/__tests__/source-maps-detect-agentic.test.ts rename to src/programs/__tests__/source-maps-detect-agentic.test.ts index a64c6973f..e0b6590d9 100644 --- a/src/lib/programs/__tests__/source-maps-detect-agentic.test.ts +++ b/src/programs/__tests__/source-maps-detect-agentic.test.ts @@ -6,8 +6,8 @@ import { goSdkVerifier, rustSdkVerifier, SOURCE_MAPS_TARGETS, -} from '@lib/programs/error-tracking-upload-source-maps/detect-agentic'; -import { AUTOMATABLE_VARIANTS } from '@lib/programs/error-tracking-upload-source-maps/detect'; +} from '@programs/error-tracking-upload-source-maps/detect-agentic'; +import { AUTOMATABLE_VARIANTS } from '@programs/error-tracking-upload-source-maps/detect'; describe('SOURCE_MAPS_TARGETS precedence', () => { const ids = SOURCE_MAPS_TARGETS.map((t) => t.id); diff --git a/src/lib/programs/__tests__/source-maps-detect.test.ts b/src/programs/__tests__/source-maps-detect.test.ts similarity index 99% rename from src/lib/programs/__tests__/source-maps-detect.test.ts rename to src/programs/__tests__/source-maps-detect.test.ts index 456933ad1..95546d373 100644 --- a/src/lib/programs/__tests__/source-maps-detect.test.ts +++ b/src/programs/__tests__/source-maps-detect.test.ts @@ -4,7 +4,7 @@ import * as os from 'os'; import { detectSourceMapsPrerequisites, SOURCE_MAPS_CONTEXT_KEYS, -} from '@lib/programs/error-tracking-upload-source-maps/index'; +} from '@programs/error-tracking-upload-source-maps/index'; import { buildSession } from '@lib/wizard-session'; function makeTmpDir(): string { diff --git a/src/lib/programs/__tests__/source-maps-prompt.test.ts b/src/programs/__tests__/source-maps-prompt.test.ts similarity index 97% rename from src/lib/programs/__tests__/source-maps-prompt.test.ts rename to src/programs/__tests__/source-maps-prompt.test.ts index 3945fdc50..588510502 100644 --- a/src/lib/programs/__tests__/source-maps-prompt.test.ts +++ b/src/programs/__tests__/source-maps-prompt.test.ts @@ -1,4 +1,4 @@ -import { buildSourceMapsUploadPrompt } from '@lib/programs/error-tracking-upload-source-maps/prompt'; +import { buildSourceMapsUploadPrompt } from '@programs/error-tracking-upload-source-maps/prompt'; const baseParams = { displayName: 'Node.js', diff --git a/src/lib/programs/__tests__/warehouse-ask-timeout.test.ts b/src/programs/__tests__/warehouse-ask-timeout.test.ts similarity index 94% rename from src/lib/programs/__tests__/warehouse-ask-timeout.test.ts rename to src/programs/__tests__/warehouse-ask-timeout.test.ts index 77850402d..55c9a781e 100644 --- a/src/lib/programs/__tests__/warehouse-ask-timeout.test.ts +++ b/src/programs/__tests__/warehouse-ask-timeout.test.ts @@ -18,7 +18,7 @@ vi.mock('@utils/analytics', () => ({ }, })); -import { warehouseSourceConfig } from '@lib/programs/warehouse-source/index'; +import { warehouseSourceConfig } from '@programs/warehouse-source/index'; import { LONGER_ASK_TIMEOUT_MS, DEFAULT_ASK_TIMEOUT_MS, diff --git a/src/lib/programs/__tests__/warehouse-seed-task.test.ts b/src/programs/__tests__/warehouse-seed-task.test.ts similarity index 94% rename from src/lib/programs/__tests__/warehouse-seed-task.test.ts rename to src/programs/__tests__/warehouse-seed-task.test.ts index 2e8aa6d30..085ca549f 100644 --- a/src/lib/programs/__tests__/warehouse-seed-task.test.ts +++ b/src/programs/__tests__/warehouse-seed-task.test.ts @@ -4,7 +4,7 @@ * to answer — and the wizard, not the planner, is what decides that. */ import type { WizardSession } from '@lib/wizard-session'; -import type { DetectedSource } from '@lib/warehouse-sources/types'; +import type { DetectedSource } from '@programs/warehouse-sources/types'; vi.mock('@utils/analytics', () => ({ analytics: { @@ -15,8 +15,8 @@ vi.mock('@utils/analytics', () => ({ }, })); -import { posthogIntegrationConfig } from '@lib/programs/posthog-integration/index'; -import { DETECTED_WAREHOUSE_SOURCES_KEY } from '@lib/programs/warehouse-source/detect'; +import { posthogIntegrationConfig } from '@programs/posthog-integration/index'; +import { DETECTED_WAREHOUSE_SOURCES_KEY } from '@programs/warehouse-source/detect'; const POSTGRES: DetectedSource = { kind: 'Postgres', diff --git a/src/lib/programs/__tests__/warehouse-suggestion.test.ts b/src/programs/__tests__/warehouse-suggestion.test.ts similarity index 98% rename from src/lib/programs/__tests__/warehouse-suggestion.test.ts rename to src/programs/__tests__/warehouse-suggestion.test.ts index 6d9f9d0fb..3acd66212 100644 --- a/src/lib/programs/__tests__/warehouse-suggestion.test.ts +++ b/src/programs/__tests__/warehouse-suggestion.test.ts @@ -13,9 +13,9 @@ * say the run already connected the sources. */ -import { POSTHOG_INTEGRATION_PROGRAM } from '@lib/programs/posthog-integration/steps'; +import { POSTHOG_INTEGRATION_PROGRAM } from '@programs/posthog-integration/steps'; import type { WizardSession } from '@lib/wizard-session'; -import type { DetectedSource } from '@lib/warehouse-sources/types'; +import type { DetectedSource } from '@programs/warehouse-sources/types'; import { analytics } from '@utils/analytics'; import { diff --git a/src/lib/programs/__tests__/web-analytics-doctor-detect.test.ts b/src/programs/__tests__/web-analytics-doctor-detect.test.ts similarity index 98% rename from src/lib/programs/__tests__/web-analytics-doctor-detect.test.ts rename to src/programs/__tests__/web-analytics-doctor-detect.test.ts index 65f338d87..d755925a0 100644 --- a/src/lib/programs/__tests__/web-analytics-doctor-detect.test.ts +++ b/src/programs/__tests__/web-analytics-doctor-detect.test.ts @@ -5,7 +5,7 @@ import { detectWebAnalyticsPrerequisites, webAnalyticsDoctorConfig, WEB_ANALYTICS_ABORT_CASES, -} from '@lib/programs/web-analytics-doctor/index'; +} from '@programs/web-analytics-doctor/index'; import { WIZARD_TOOL_NAMES } from '@agent/tools'; import { buildSession } from '@lib/wizard-session'; diff --git a/src/lib/programs/agent-skill/index.ts b/src/programs/agent-skill/index.ts similarity index 92% rename from src/lib/programs/agent-skill/index.ts rename to src/programs/agent-skill/index.ts index e59f3fdf1..75752731e 100644 --- a/src/lib/programs/agent-skill/index.ts +++ b/src/programs/agent-skill/index.ts @@ -19,11 +19,11 @@ * }) */ -import type { ProgramConfig } from '@lib/programs/program-step'; +import type { ProgramConfig } from '@programs/program-step'; import type { AbortCase } from '@agent/types'; -import type { ProgramRun } from '@lib/programs/program-run'; +import type { ProgramRun } from '@programs/program-run'; import { AGENT_SKILL_STEPS } from './steps.js'; -import { getContentBlocks } from './content/index.js'; +import { getContentBlocks } from '../../ui/tui/decks/agent-skill/index.js'; export interface SkillProgramOptions { /** Context-mill skill ID to install */ diff --git a/src/lib/programs/agent-skill/steps.ts b/src/programs/agent-skill/steps.ts similarity index 87% rename from src/lib/programs/agent-skill/steps.ts rename to src/programs/agent-skill/steps.ts index 992726616..faafee60b 100644 --- a/src/lib/programs/agent-skill/steps.ts +++ b/src/programs/agent-skill/steps.ts @@ -5,9 +5,9 @@ * No detection, no setup, no MCP. */ -import type { ProgramStep } from '@lib/programs/program-step'; +import type { ProgramStep } from '@programs/program-step'; import { RunPhase } from '@lib/wizard-session'; -import { HEALTH_CHECK_STEP } from '@lib/programs/shared/health-check-step'; +import { HEALTH_CHECK_STEP } from '@programs/shared/health-check-step'; export const AGENT_SKILL_STEPS: ProgramStep[] = [ { diff --git a/src/lib/programs/ai-observability/index.ts b/src/programs/ai-observability/index.ts similarity index 93% rename from src/lib/programs/ai-observability/index.ts rename to src/programs/ai-observability/index.ts index ed391defb..b71697d30 100644 --- a/src/lib/programs/ai-observability/index.ts +++ b/src/programs/ai-observability/index.ts @@ -1,6 +1,6 @@ -import type { ProgramConfig, ProgramStep } from '@lib/programs/program-step'; -import { AGENT_SKILL_STEPS } from '@lib/programs/agent-skill/index'; -import { getContentBlocks } from '@lib/programs/agent-skill/content/index'; +import type { ProgramConfig, ProgramStep } from '@programs/program-step'; +import { AGENT_SKILL_STEPS } from '@programs/agent-skill/index'; +import { getContentBlocks } from '@ui/tui/decks/agent-skill/index'; import { headlessOption, regionOption } from '@lib/headless-mode'; const AI_OBSERVABILITY_STEPS: ProgramStep[] = AGENT_SKILL_STEPS.map((step) => diff --git a/src/lib/programs/ai-observability/test/e2e.json b/src/programs/ai-observability/test/e2e.json similarity index 100% rename from src/lib/programs/ai-observability/test/e2e.json rename to src/programs/ai-observability/test/e2e.json diff --git a/src/lib/programs/ai-opt-in-gate.ts b/src/programs/ai-opt-in-gate.ts similarity index 100% rename from src/lib/programs/ai-opt-in-gate.ts rename to src/programs/ai-opt-in-gate.ts diff --git a/src/lib/programs/audit/detect.ts b/src/programs/audit/detect.ts similarity index 100% rename from src/lib/programs/audit/detect.ts rename to src/programs/audit/detect.ts diff --git a/src/lib/programs/audit/index.ts b/src/programs/audit/index.ts similarity index 95% rename from src/lib/programs/audit/index.ts rename to src/programs/audit/index.ts index a5921edbe..770668c17 100644 --- a/src/lib/programs/audit/index.ts +++ b/src/programs/audit/index.ts @@ -1,9 +1,9 @@ import { AGENT_SKILL_STEPS, createSkillProgram, -} from '@lib/programs/agent-skill/index'; -import type { ProgramStep, ProgramConfig } from '@lib/programs/program-step'; -import type { ProgramRun } from '@lib/programs/program-run'; +} from '@programs/agent-skill/index'; +import type { ProgramStep, ProgramConfig } from '@programs/program-step'; +import type { ProgramRun } from '@programs/program-run'; import type { WizardSession } from '@lib/wizard-session'; import { OutroKind } from '@lib/wizard-session'; import { WIZARD_TOOL_NAMES } from '@agent'; diff --git a/src/lib/programs/audit/ledger-watcher.ts b/src/programs/audit/ledger-watcher.ts similarity index 100% rename from src/lib/programs/audit/ledger-watcher.ts rename to src/programs/audit/ledger-watcher.ts diff --git a/src/lib/programs/audit/seed.ts b/src/programs/audit/seed.ts similarity index 100% rename from src/lib/programs/audit/seed.ts rename to src/programs/audit/seed.ts diff --git a/src/lib/programs/audit/test/e2e.json b/src/programs/audit/test/e2e.json similarity index 100% rename from src/lib/programs/audit/test/e2e.json rename to src/programs/audit/test/e2e.json diff --git a/src/lib/programs/audit/types.ts b/src/programs/audit/types.ts similarity index 100% rename from src/lib/programs/audit/types.ts rename to src/programs/audit/types.ts diff --git a/src/lib/programs/authenticate.ts b/src/programs/authenticate.ts similarity index 98% rename from src/lib/programs/authenticate.ts rename to src/programs/authenticate.ts index 752eafa92..09aedd452 100644 --- a/src/lib/programs/authenticate.ts +++ b/src/programs/authenticate.ts @@ -11,7 +11,7 @@ */ import type { Credentials, WizardSession } from '@lib/wizard-session'; -import type { ProgramId } from '@lib/programs/program-registry'; +import type { ProgramId } from '@programs/program-registry'; import { getOrAskForProjectData } from '@utils/setup-utils'; import { refreshAccessToken, missingOAuthScopes } from '@utils/oauth'; import { WIZARD_OAUTH_SCOPES } from '@shared/constants'; diff --git a/src/lib/cloudflare-detection.ts b/src/programs/cloudflare-detection.ts similarity index 100% rename from src/lib/cloudflare-detection.ts rename to src/programs/cloudflare-detection.ts diff --git a/src/lib/programs/detect-map.ts b/src/programs/detect-map.ts similarity index 81% rename from src/lib/programs/detect-map.ts rename to src/programs/detect-map.ts index aaf4e25e2..ba1228d79 100644 --- a/src/lib/programs/detect-map.ts +++ b/src/programs/detect-map.ts @@ -1,9 +1,9 @@ import { ErrorCodes, type ErrorCode } from '@shared/errors'; -import type { RevenueDetectError } from '@lib/programs/revenue-analytics/detect'; -import type { SelfDrivingDetectError } from '@lib/programs/self-driving/detect'; -import type { SourceMapsDetectError } from '@lib/programs/error-tracking-upload-source-maps/detect'; -import type { WarehouseDetectError } from '@lib/programs/warehouse-source/detect'; -import type { WebAnalyticsDetectError } from '@lib/programs/web-analytics-doctor/detect'; +import type { RevenueDetectError } from '@programs/revenue-analytics/detect'; +import type { SelfDrivingDetectError } from '@programs/self-driving/detect'; +import type { SourceMapsDetectError } from '@programs/error-tracking-upload-source-maps/detect'; +import type { WarehouseDetectError } from '@programs/warehouse-source/detect'; +import type { WebAnalyticsDetectError } from '@programs/web-analytics-doctor/detect'; /** * Every `kind` a program detect step can write into diff --git a/src/lib/detection/__tests__/agentic-progress.test.ts b/src/programs/detection/__tests__/agentic-progress.test.ts similarity index 100% rename from src/lib/detection/__tests__/agentic-progress.test.ts rename to src/programs/detection/__tests__/agentic-progress.test.ts diff --git a/src/lib/detection/__tests__/agentic-retry.test.ts b/src/programs/detection/__tests__/agentic-retry.test.ts similarity index 99% rename from src/lib/detection/__tests__/agentic-retry.test.ts rename to src/programs/detection/__tests__/agentic-retry.test.ts index 82ab1c161..2ebd05bea 100644 --- a/src/lib/detection/__tests__/agentic-retry.test.ts +++ b/src/programs/detection/__tests__/agentic-retry.test.ts @@ -1,7 +1,7 @@ import { AgenticDetectionTimeoutError, detectProjectsWithAgent, -} from '@lib/detection/agentic'; +} from '@programs/detection/agentic'; import { AgentErrorType, initializeAgent, diff --git a/src/lib/detection/__tests__/agentic.test.ts b/src/programs/detection/__tests__/agentic.test.ts similarity index 99% rename from src/lib/detection/__tests__/agentic.test.ts rename to src/programs/detection/__tests__/agentic.test.ts index c63335c74..876b617f4 100644 --- a/src/lib/detection/__tests__/agentic.test.ts +++ b/src/programs/detection/__tests__/agentic.test.ts @@ -3,7 +3,7 @@ import { deriveReportJson, manifestGlob, resolveProjectDir, -} from '@lib/detection/agentic'; +} from '@programs/detection/agentic'; const TARGETS = ['nextjs', 'node', 'vite']; diff --git a/src/lib/detection/__tests__/context.test.ts b/src/programs/detection/__tests__/context.test.ts similarity index 96% rename from src/lib/detection/__tests__/context.test.ts rename to src/programs/detection/__tests__/context.test.ts index 138b94d0c..acb64478d 100644 --- a/src/lib/detection/__tests__/context.test.ts +++ b/src/programs/detection/__tests__/context.test.ts @@ -1,8 +1,8 @@ import { gatherFrameworkContext, checkFrameworkVersion, -} from '@lib/detection/context'; -import type { FrameworkConfig } from '@lib/framework-config'; +} from '@programs/detection/context'; +import type { FrameworkConfig } from '@programs/types'; import type { WizardRunOptions } from '@utils/types'; const baseOptions: WizardRunOptions = { diff --git a/src/lib/detection/__tests__/features.test.ts b/src/programs/detection/__tests__/features.test.ts similarity index 98% rename from src/lib/detection/__tests__/features.test.ts rename to src/programs/detection/__tests__/features.test.ts index a5a21ff7f..35602ab8f 100644 --- a/src/lib/detection/__tests__/features.test.ts +++ b/src/programs/detection/__tests__/features.test.ts @@ -1,7 +1,7 @@ import * as fs from 'fs'; import * as path from 'path'; import * as os from 'os'; -import { discoverFeatures } from '@lib/detection/features'; +import { discoverFeatures } from '@programs/detection/features'; import { DiscoveredFeature } from '@lib/wizard-session'; function makeTmpDir(): string { diff --git a/src/lib/detection/__tests__/framework.test.ts b/src/programs/detection/__tests__/framework.test.ts similarity index 96% rename from src/lib/detection/__tests__/framework.test.ts rename to src/programs/detection/__tests__/framework.test.ts index cd2a333f0..80217cedc 100644 --- a/src/lib/detection/__tests__/framework.test.ts +++ b/src/programs/detection/__tests__/framework.test.ts @@ -1,15 +1,15 @@ import * as fs from 'node:fs'; import * as os from 'node:os'; import * as path from 'node:path'; -import { detectFramework } from '@lib/detection/framework'; +import { detectFramework } from '@programs/detection/framework'; import { Integration } from '@shared/constants'; -import { ANDROID_AGENT_CONFIG } from '../../../frameworks/android/android-wizard-agent'; -import { KMP_AGENT_CONFIG } from '../../../frameworks/kmp/kmp-wizard-agent'; -import { ELIXIR_AGENT_CONFIG } from '../../../frameworks/elixir/elixir-wizard-agent'; -import { GO_AGENT_CONFIG } from '../../../frameworks/go/go-wizard-agent'; -import { JAVA_AGENT_CONFIG } from '../../../frameworks/java/java-wizard-agent'; -import { RUST_AGENT_CONFIG } from '../../../frameworks/rust/rust-wizard-agent'; -import { FLUTTER_AGENT_CONFIG } from '../../../frameworks/flutter/flutter-wizard-agent'; +import { ANDROID_AGENT_CONFIG } from '../../frameworks/android/android-wizard-agent'; +import { KMP_AGENT_CONFIG } from '../../frameworks/kmp/kmp-wizard-agent'; +import { ELIXIR_AGENT_CONFIG } from '../../frameworks/elixir/elixir-wizard-agent'; +import { GO_AGENT_CONFIG } from '../../frameworks/go/go-wizard-agent'; +import { JAVA_AGENT_CONFIG } from '../../frameworks/java/java-wizard-agent'; +import { RUST_AGENT_CONFIG } from '../../frameworks/rust/rust-wizard-agent'; +import { FLUTTER_AGENT_CONFIG } from '../../frameworks/flutter/flutter-wizard-agent'; /** A throwaway project dir seeded with the given files. */ function makeProject(files: Record): string { diff --git a/src/lib/detection/__tests__/package-manager.test.ts b/src/programs/detection/__tests__/package-manager.test.ts similarity index 99% rename from src/lib/detection/__tests__/package-manager.test.ts rename to src/programs/detection/__tests__/package-manager.test.ts index 3200bf4fd..ae102520a 100644 --- a/src/lib/detection/__tests__/package-manager.test.ts +++ b/src/programs/detection/__tests__/package-manager.test.ts @@ -12,7 +12,7 @@ import { mixPackageManager, goModulesPackageManager, pubPackageManager, -} from '@lib/detection/package-manager'; +} from '@programs/detection/package-manager'; vi.mock('@utils/debug'); vi.mock('../../../telemetry', () => ({ diff --git a/src/lib/detection/__tests__/project-scope.test.ts b/src/programs/detection/__tests__/project-scope.test.ts similarity index 96% rename from src/lib/detection/__tests__/project-scope.test.ts rename to src/programs/detection/__tests__/project-scope.test.ts index dd7e626c3..207c41724 100644 --- a/src/lib/detection/__tests__/project-scope.test.ts +++ b/src/programs/detection/__tests__/project-scope.test.ts @@ -2,22 +2,22 @@ import { detectProjectsWithAgent, AgenticDetectionTimeoutError, type AgenticProject, -} from '@lib/detection/agentic'; +} from '@programs/detection/agentic'; import { chooseIntegrationProject, scopeInstallDirToProject, -} from '@lib/detection/project-scope'; +} from '@programs/detection/project-scope'; import { WIZARD_BASIC_INTEGRATION_AGENTIC_DETECTION_FLAG_KEY } from '@shared/constants'; -import { authenticate } from '@lib/programs/authenticate'; +import { authenticate } from '@programs/authenticate'; import { buildSession } from '@lib/wizard-session'; import { analytics } from '@utils/analytics'; // Mock only the two network edges of scopeInstallDirToProject; everything else runs real. -vi.mock('@lib/programs/authenticate', () => ({ +vi.mock('@programs/authenticate', () => ({ authenticate: vi.fn().mockResolvedValue(undefined), })); -vi.mock('@lib/detection/agentic', async (importOriginal) => ({ - ...(await importOriginal()), +vi.mock('@programs/detection/agentic', async (importOriginal) => ({ + ...(await importOriginal()), detectProjectsWithAgent: vi.fn(), })); diff --git a/src/lib/detection/agentic.ts b/src/programs/detection/agentic.ts similarity index 99% rename from src/lib/detection/agentic.ts rename to src/programs/detection/agentic.ts index 5be6704fa..33c94a341 100644 --- a/src/lib/detection/agentic.ts +++ b/src/programs/detection/agentic.ts @@ -74,7 +74,7 @@ export type DetectEvent = (line: string) => void; * are identified by. One brace-expansion Glob over all of these locates every * project root in the repo in a single call, regardless of language. * - * Counterpart: POSTHOG_MANIFESTS in @lib/programs/self-driving/detect (SDK + * Counterpart: POSTHOG_MANIFESTS in @programs/self-driving/detect (SDK * grep); keep the two in sync. */ export const PROJECT_MANIFESTS: readonly string[] = [ diff --git a/src/lib/detection/context.ts b/src/programs/detection/context.ts similarity index 97% rename from src/lib/detection/context.ts rename to src/programs/detection/context.ts index 8e0d845d7..23ab66832 100644 --- a/src/lib/detection/context.ts +++ b/src/programs/detection/context.ts @@ -8,7 +8,7 @@ import * as semver from 'semver'; import { DETECTION_TIMEOUT_MS } from '@shared/constants'; -import type { FrameworkConfig } from '@lib/framework-config'; +import type { FrameworkConfig } from '@programs/framework-config'; import type { WizardRunOptions } from '@utils/types'; /** diff --git a/src/lib/detection/features.ts b/src/programs/detection/features.ts similarity index 100% rename from src/lib/detection/features.ts rename to src/programs/detection/features.ts diff --git a/src/lib/detection/framework.ts b/src/programs/detection/framework.ts similarity index 94% rename from src/lib/detection/framework.ts rename to src/programs/detection/framework.ts index 07dfa2c35..a06ddd0dd 100644 --- a/src/lib/detection/framework.ts +++ b/src/programs/detection/framework.ts @@ -7,7 +7,7 @@ */ import { Integration, DETECTION_TIMEOUT_MS } from '@shared/constants'; -import { FRAMEWORK_REGISTRY } from '@lib/registry'; +import { FRAMEWORK_REGISTRY } from '@programs/frameworks/registry'; /** * Loop through all registered frameworks and return the first one diff --git a/src/lib/detection/index.ts b/src/programs/detection/index.ts similarity index 100% rename from src/lib/detection/index.ts rename to src/programs/detection/index.ts diff --git a/src/lib/detection/package-manager.ts b/src/programs/detection/package-manager.ts similarity index 99% rename from src/lib/detection/package-manager.ts rename to src/programs/detection/package-manager.ts index 8212dd1f7..b4af311ae 100644 --- a/src/lib/detection/package-manager.ts +++ b/src/programs/detection/package-manager.ts @@ -29,7 +29,7 @@ export type { import { detectPackageManager as detectPythonPM, PythonPackageManager, -} from '@frameworks/python/utils'; +} from '@programs/frameworks/python/utils'; // --------------------------------------------------------------------------- // Python helper diff --git a/src/lib/detection/project-scope.ts b/src/programs/detection/project-scope.ts similarity index 98% rename from src/lib/detection/project-scope.ts rename to src/programs/detection/project-scope.ts index fd81cca08..3842944a9 100644 --- a/src/lib/detection/project-scope.ts +++ b/src/programs/detection/project-scope.ts @@ -9,8 +9,8 @@ import { type DetectEvent, type DetectTarget, } from './agentic.js'; -import { authenticate } from '@lib/programs/authenticate'; -import { FRAMEWORK_REGISTRY } from '@lib/registry'; +import { authenticate } from '@programs/authenticate'; +import { FRAMEWORK_REGISTRY } from '@programs/frameworks/registry'; import { Integration, WIZARD_BASIC_INTEGRATION_AGENTIC_DETECTION_FLAG_KEY, diff --git a/src/lib/programs/dispatch-family.ts b/src/programs/dispatch-family.ts similarity index 93% rename from src/lib/programs/dispatch-family.ts rename to src/programs/dispatch-family.ts index b9da9d39f..b92a25b6a 100644 --- a/src/lib/programs/dispatch-family.ts +++ b/src/programs/dispatch-family.ts @@ -1,17 +1,17 @@ import type { Arguments } from 'yargs'; -import { auditConfig } from '@lib/programs/audit/index'; -import { AUDIT_CHECKS_FILE } from '@lib/programs/audit/types'; +import { auditConfig } from '@programs/audit/index'; +import { AUDIT_CHECKS_FILE } from '@programs/audit/types'; import { WIZARD_TOOL_NAMES } from '@agent'; -import { agentSkillConfig } from '@lib/programs/program-registry'; -import { webAnalyticsDoctorConfig } from '@lib/programs/web-analytics-doctor/index'; -import type { ProgramConfig } from '@lib/programs/program-step'; +import { agentSkillConfig } from '@programs/program-registry'; +import { webAnalyticsDoctorConfig } from '@programs/web-analytics-doctor/index'; +import type { ProgramConfig } from '@programs/program-step'; import { getSkillsBaseUrl } from '@shared/constants'; import { fetchSkillMenu, type CliEntry } from '@shared/skill-menu'; import { analytics } from '@utils/analytics'; -import { dispatchProgram } from '../../commands/factories/shared'; -import type { Command } from '../../commands/command'; +import { dispatchProgram } from '../commands/factories/shared'; +import type { Command } from '../commands/command'; import { ErrorCodes } from '@shared/errors'; import { emitWizardError } from '@shared/errors'; diff --git a/src/lib/programs/error-tracking-upload-source-maps/detect-agentic.ts b/src/programs/error-tracking-upload-source-maps/detect-agentic.ts similarity index 99% rename from src/lib/programs/error-tracking-upload-source-maps/detect-agentic.ts rename to src/programs/error-tracking-upload-source-maps/detect-agentic.ts index 17d3561c0..033635b19 100644 --- a/src/lib/programs/error-tracking-upload-source-maps/detect-agentic.ts +++ b/src/programs/error-tracking-upload-source-maps/detect-agentic.ts @@ -1,6 +1,6 @@ /** * Source-maps adapter over the generic agentic detector - * (`@lib/detection/agentic`). The detector itself is product-knowledge-free; + * (`@programs/detection/agentic`). The detector itself is product-knowledge-free; * this file supplies the source-maps targets (the automatable skill variants), * maps the result back to variants, and classifies each project as * instrumentable or not. The screen renders the result and the run step @@ -16,7 +16,7 @@ import { type DetectTarget, type AgenticDetectionReport, type DetectEvent, -} from '@lib/detection/agentic'; +} from '@programs/detection/agentic'; import type { WizardSession } from '@lib/wizard-session'; import { VARIANT_DISPLAY_NAME, diff --git a/src/lib/programs/error-tracking-upload-source-maps/detect.ts b/src/programs/error-tracking-upload-source-maps/detect.ts similarity index 100% rename from src/lib/programs/error-tracking-upload-source-maps/detect.ts rename to src/programs/error-tracking-upload-source-maps/detect.ts diff --git a/src/lib/programs/error-tracking-upload-source-maps/index.ts b/src/programs/error-tracking-upload-source-maps/index.ts similarity index 94% rename from src/lib/programs/error-tracking-upload-source-maps/index.ts rename to src/programs/error-tracking-upload-source-maps/index.ts index afdc17007..101d42594 100644 --- a/src/lib/programs/error-tracking-upload-source-maps/index.ts +++ b/src/programs/error-tracking-upload-source-maps/index.ts @@ -1,5 +1,5 @@ -import type { ProgramConfig } from '@lib/programs/program-step'; -import type { ProgramRun } from '@lib/programs/program-run'; +import type { ProgramConfig } from '@programs/program-step'; +import type { ProgramRun } from '@programs/program-run'; import type { WizardSession } from '@lib/wizard-session'; import { OutroKind } from '@lib/wizard-session'; import { ERROR_TRACKING_UPLOAD_SOURCE_MAPS_PROGRAM } from './steps.js'; @@ -13,9 +13,9 @@ import { VARIANTS_REQUIRING_POSTHOG_CLI, type SkillVariant, } from './detect.js'; -import { getContentBlocks } from './content/index.js'; +import { getContentBlocks } from '../../ui/tui/decks/error-tracking-upload-source-maps/index.js'; import { getUI } from '@ui'; -import { preinstallPostHogCliOnce } from '@lib/programs/shared/posthog-cli-preinstall'; +import { preinstallPostHogCliOnce } from '@programs/shared/posthog-cli-preinstall'; const REPORT_FILE = 'posthog-source-maps-report.md'; const DOCS_URL = 'https://posthog.com/docs/error-tracking/upload-source-maps'; diff --git a/src/lib/programs/error-tracking-upload-source-maps/prompt.ts b/src/programs/error-tracking-upload-source-maps/prompt.ts similarity index 100% rename from src/lib/programs/error-tracking-upload-source-maps/prompt.ts rename to src/programs/error-tracking-upload-source-maps/prompt.ts diff --git a/src/lib/programs/error-tracking-upload-source-maps/steps.ts b/src/programs/error-tracking-upload-source-maps/steps.ts similarity index 96% rename from src/lib/programs/error-tracking-upload-source-maps/steps.ts rename to src/programs/error-tracking-upload-source-maps/steps.ts index 33bfc7449..466ae9074 100644 --- a/src/lib/programs/error-tracking-upload-source-maps/steps.ts +++ b/src/programs/error-tracking-upload-source-maps/steps.ts @@ -7,7 +7,7 @@ * needs credentials. */ -import type { ProgramStep } from '@lib/programs/program-step'; +import type { ProgramStep } from '@programs/program-step'; import type { WizardSession } from '@lib/wizard-session'; import { RunPhase } from '@lib/wizard-session'; import { SOURCE_MAPS_CONTEXT_KEYS } from './detect.js'; diff --git a/src/lib/programs/error-tracking-upload-source-maps/test/e2e.json b/src/programs/error-tracking-upload-source-maps/test/e2e.json similarity index 100% rename from src/lib/programs/error-tracking-upload-source-maps/test/e2e.json rename to src/programs/error-tracking-upload-source-maps/test/e2e.json diff --git a/src/lib/programs/error-tracking/detect-agentic.ts b/src/programs/error-tracking/detect-agentic.ts similarity index 96% rename from src/lib/programs/error-tracking/detect-agentic.ts rename to src/programs/error-tracking/detect-agentic.ts index 1967b79c4..654de6c68 100644 --- a/src/lib/programs/error-tracking/detect-agentic.ts +++ b/src/programs/error-tracking/detect-agentic.ts @@ -16,12 +16,12 @@ import { resolveProjectDir, type AgenticDetectionReport, type DetectEvent, -} from '@lib/detection/agentic'; -import { gatherFrameworkContext } from '@lib/detection/index'; +} from '@programs/detection/agentic'; +import { gatherFrameworkContext } from '@programs/detection/index'; import { detectIntegrationProjects, toIntegrationCandidates, -} from '@lib/detection/project-scope'; +} from '@programs/detection/project-scope'; import type { WizardSession } from '@lib/wizard-session'; /** frameworkContext key for the picked project's path, relative to the repo root. */ diff --git a/src/lib/programs/error-tracking/index.ts b/src/programs/error-tracking/index.ts similarity index 92% rename from src/lib/programs/error-tracking/index.ts rename to src/programs/error-tracking/index.ts index b28ae779d..ebfc4db78 100644 --- a/src/lib/programs/error-tracking/index.ts +++ b/src/programs/error-tracking/index.ts @@ -1,19 +1,19 @@ import { Integration } from '@shared/constants'; -import { detectFramework } from '@lib/detection/index'; -import { scopeInstallDirToProject } from '@lib/detection/project-scope'; -import { FRAMEWORK_REGISTRY } from '@lib/registry'; -import type { ProgramRun } from '@lib/programs/program-run'; -import { AGENT_SKILL_STEPS } from '@lib/programs/agent-skill/steps'; -import { getContentBlocks } from '@lib/programs/error-tracking/content/index'; -import { getTips } from '@lib/programs/error-tracking/content/tips'; +import { detectFramework } from '@programs/detection/index'; +import { scopeInstallDirToProject } from '@programs/detection/project-scope'; +import { FRAMEWORK_REGISTRY } from '@programs/frameworks/registry'; +import type { ProgramRun } from '@programs/program-run'; +import { AGENT_SKILL_STEPS } from '@programs/agent-skill/steps'; +import { getContentBlocks } from '@ui/tui/decks/error-tracking/index'; +import { getTips } from '@ui/tui/decks/error-tracking/tips'; import { ERROR_TRACKING_UNSUPPORTED, errorTrackingProjectDir, gatherErrorTrackingContext, -} from '@lib/programs/error-tracking/detect-agentic'; -import type { ProgramConfig, ProgramStep } from '@lib/programs/program-step'; +} from '@programs/error-tracking/detect-agentic'; +import type { ProgramConfig, ProgramStep } from '@programs/program-step'; import type { WizardSession } from '@lib/wizard-session'; -import { preinstallPostHogCliOnce } from '@lib/programs/shared/posthog-cli-preinstall'; +import { preinstallPostHogCliOnce } from '@programs/shared/posthog-cli-preinstall'; import { analytics } from '@utils/analytics'; import { wizardAbort } from '@utils/wizard-abort'; import { ErrorCodes } from '@shared/errors'; diff --git a/src/lib/programs/error-tracking/test/e2e.json b/src/programs/error-tracking/test/e2e.json similarity index 100% rename from src/lib/programs/error-tracking/test/e2e.json rename to src/programs/error-tracking/test/e2e.json diff --git a/src/lib/programs/events-audit/constants.ts b/src/programs/events-audit/constants.ts similarity index 100% rename from src/lib/programs/events-audit/constants.ts rename to src/programs/events-audit/constants.ts diff --git a/src/lib/programs/events-audit/index.ts b/src/programs/events-audit/index.ts similarity index 91% rename from src/lib/programs/events-audit/index.ts rename to src/programs/events-audit/index.ts index ac8cfd832..29e945944 100644 --- a/src/lib/programs/events-audit/index.ts +++ b/src/programs/events-audit/index.ts @@ -1,17 +1,17 @@ -import type { ProgramConfig } from '@lib/programs/program-step'; -import type { ProgramRun } from '@lib/programs/program-run'; +import type { ProgramConfig } from '@programs/program-step'; +import type { ProgramRun } from '@programs/program-run'; import type { WizardSession } from '@lib/wizard-session'; import { OutroKind } from '@lib/wizard-session'; -import { SPINNER_MESSAGE } from '@lib/framework-config'; +import { SPINNER_MESSAGE } from '@programs/framework-config'; import { isUsingTypeScript } from '@utils/setup-utils'; import { WIZARD_TOOL_NAMES } from '@agent'; import { EVENTS_AUDIT_PROGRAM } from './steps.js'; -import { AUDIT_CHECKS_FILE, AUDIT_CHECKS_KEY } from '@lib/programs/audit/types'; -import { seedAuditLedger } from '@lib/programs/audit/seed'; +import { AUDIT_CHECKS_FILE, AUDIT_CHECKS_KEY } from '@programs/audit/types'; +import { seedAuditLedger } from '@programs/audit/seed'; import { EVENTS_AUDIT_SEED_CHECKS } from './seed.js'; // SETUP_REPORT_FILE is also re-exported for backward compat with existing -// imports from `@lib/programs/events-audit`. EVENT_INVENTORY_FILE and +// imports from `@programs/events-audit`. EVENT_INVENTORY_FILE and // EVENT_INVENTORY_PART_PATTERN are only used by yara-hooks, which imports // them directly from `./constants` — no re-export needed. import { SETUP_REPORT_FILE } from './constants.js'; diff --git a/src/lib/programs/events-audit/seed.ts b/src/programs/events-audit/seed.ts similarity index 96% rename from src/lib/programs/events-audit/seed.ts rename to src/programs/events-audit/seed.ts index f2c0df189..ef480aac0 100644 --- a/src/lib/programs/events-audit/seed.ts +++ b/src/programs/events-audit/seed.ts @@ -1,4 +1,4 @@ -import type { AuditCheck } from '@lib/programs/audit/types'; +import type { AuditCheck } from '@programs/audit/types'; /** * The 7 phases the events-audit skill marches through. One check per area diff --git a/src/lib/programs/events-audit/steps.ts b/src/programs/events-audit/steps.ts similarity index 92% rename from src/lib/programs/events-audit/steps.ts rename to src/programs/events-audit/steps.ts index b9e07298a..53b2f59a2 100644 --- a/src/lib/programs/events-audit/steps.ts +++ b/src/programs/events-audit/steps.ts @@ -8,10 +8,10 @@ * logic) instead of the integration intro. */ -import type { ProgramStep } from '@lib/programs/program-step'; +import type { ProgramStep } from '@programs/program-step'; import type { WizardSession } from '@lib/wizard-session'; import { RunPhase } from '@lib/wizard-session'; -import { HEALTH_CHECK_STEP } from '@lib/programs/shared/health-check-step'; +import { HEALTH_CHECK_STEP } from '@programs/shared/health-check-step'; function needsSetup(session: WizardSession): boolean { const config = session.frameworkConfig; diff --git a/src/lib/framework-config.ts b/src/programs/framework-config.ts similarity index 100% rename from src/lib/framework-config.ts rename to src/programs/framework-config.ts diff --git a/src/frameworks/android/android-wizard-agent.ts b/src/programs/frameworks/android/android-wizard-agent.ts similarity index 96% rename from src/frameworks/android/android-wizard-agent.ts rename to src/programs/frameworks/android/android-wizard-agent.ts index 789cf3746..f2f81227b 100644 --- a/src/frameworks/android/android-wizard-agent.ts +++ b/src/programs/frameworks/android/android-wizard-agent.ts @@ -1,6 +1,6 @@ /* Android (Kotlin) wizard using posthog-agent with PostHog MCP */ import type { WizardRunOptions } from '@utils/types'; -import type { FrameworkConfig } from '@lib/framework-config'; +import type { FrameworkConfig } from '@programs/framework-config'; import { Integration } from '@shared/constants'; import { boundedGlob } from '@utils/bounded-fs'; import * as fs from 'node:fs'; @@ -10,7 +10,7 @@ import { getKotlinVersionBucket, getMinSdkVersion, } from './utils'; -import { gradlePackageManager } from '@lib/detection/package-manager'; +import { gradlePackageManager } from '@programs/detection/package-manager'; type AndroidContext = { kotlinVersion?: string; diff --git a/src/frameworks/android/utils.ts b/src/programs/frameworks/android/utils.ts similarity index 100% rename from src/frameworks/android/utils.ts rename to src/programs/frameworks/android/utils.ts diff --git a/src/frameworks/angular/angular-wizard-agent.ts b/src/programs/frameworks/angular/angular-wizard-agent.ts similarity index 94% rename from src/frameworks/angular/angular-wizard-agent.ts rename to src/programs/frameworks/angular/angular-wizard-agent.ts index bd1fdc675..e746a1851 100644 --- a/src/frameworks/angular/angular-wizard-agent.ts +++ b/src/programs/frameworks/angular/angular-wizard-agent.ts @@ -1,7 +1,7 @@ /* Angular wizard using posthog-agent with PostHog MCP */ import type { WizardRunOptions } from '@utils/types'; -import type { FrameworkConfig } from '@lib/framework-config'; -import { detectNodePackageManagers } from '@lib/detection/package-manager'; +import type { FrameworkConfig } from '@programs/framework-config'; +import { detectNodePackageManagers } from '@programs/detection/package-manager'; import { Integration } from '@shared/constants'; import { getDeclaredVersion, diff --git a/src/frameworks/angular/utils.ts b/src/programs/frameworks/angular/utils.ts similarity index 100% rename from src/frameworks/angular/utils.ts rename to src/programs/frameworks/angular/utils.ts diff --git a/src/frameworks/astro/astro-wizard-agent.ts b/src/programs/frameworks/astro/astro-wizard-agent.ts similarity index 97% rename from src/frameworks/astro/astro-wizard-agent.ts rename to src/programs/frameworks/astro/astro-wizard-agent.ts index f8052cc30..a84ad23b3 100644 --- a/src/frameworks/astro/astro-wizard-agent.ts +++ b/src/programs/frameworks/astro/astro-wizard-agent.ts @@ -1,7 +1,7 @@ /* Astro wizard using posthog-agent with PostHog MCP */ import type { WizardRunOptions } from '@utils/types'; -import type { FrameworkConfig } from '@lib/framework-config'; -import { detectNodePackageManagers } from '@lib/detection/package-manager'; +import type { FrameworkConfig } from '@programs/framework-config'; +import { detectNodePackageManagers } from '@programs/detection/package-manager'; import { Integration } from '@shared/constants'; import { getDeclaredVersion, diff --git a/src/frameworks/astro/utils.ts b/src/programs/frameworks/astro/utils.ts similarity index 100% rename from src/frameworks/astro/utils.ts rename to src/programs/frameworks/astro/utils.ts diff --git a/src/frameworks/django/django-wizard-agent.ts b/src/programs/frameworks/django/django-wizard-agent.ts similarity index 95% rename from src/frameworks/django/django-wizard-agent.ts rename to src/programs/frameworks/django/django-wizard-agent.ts index 6abe33c2a..6c93bbc4e 100644 --- a/src/frameworks/django/django-wizard-agent.ts +++ b/src/programs/frameworks/django/django-wizard-agent.ts @@ -1,8 +1,8 @@ /* Django wizard using posthog-agent with PostHog MCP */ import type { WizardRunOptions } from '@utils/types'; -import type { FrameworkConfig } from '@lib/framework-config'; -import { PYTHON_PACKAGE_INSTALLATION } from '@lib/framework-config'; -import { detectPythonPackageManagers } from '@lib/detection/package-manager'; +import type { FrameworkConfig } from '@programs/framework-config'; +import { PYTHON_PACKAGE_INSTALLATION } from '@programs/framework-config'; +import { detectPythonPackageManagers } from '@programs/detection/package-manager'; import { Integration } from '@shared/constants'; import { boundedGlob, readProjectFile } from '@utils/bounded-fs'; import * as path from 'node:path'; diff --git a/src/frameworks/django/utils.ts b/src/programs/frameworks/django/utils.ts similarity index 100% rename from src/frameworks/django/utils.ts rename to src/programs/frameworks/django/utils.ts diff --git a/src/frameworks/elixir/elixir-wizard-agent.ts b/src/programs/frameworks/elixir/elixir-wizard-agent.ts similarity index 96% rename from src/frameworks/elixir/elixir-wizard-agent.ts rename to src/programs/frameworks/elixir/elixir-wizard-agent.ts index f74b4e38e..b617f74b9 100644 --- a/src/frameworks/elixir/elixir-wizard-agent.ts +++ b/src/programs/frameworks/elixir/elixir-wizard-agent.ts @@ -2,8 +2,8 @@ import * as fs from 'node:fs'; import * as path from 'node:path'; import type { WizardRunOptions } from '@utils/types'; -import type { FrameworkConfig } from '@lib/framework-config'; -import { mixPackageManager } from '@lib/detection/package-manager'; +import type { FrameworkConfig } from '@programs/framework-config'; +import { mixPackageManager } from '@programs/detection/package-manager'; import { Integration } from '@shared/constants'; type ElixirContext = { diff --git a/src/frameworks/fastapi/fastapi-wizard-agent.ts b/src/programs/frameworks/fastapi/fastapi-wizard-agent.ts similarity index 96% rename from src/frameworks/fastapi/fastapi-wizard-agent.ts rename to src/programs/frameworks/fastapi/fastapi-wizard-agent.ts index 1a6763dbd..22326fc49 100644 --- a/src/frameworks/fastapi/fastapi-wizard-agent.ts +++ b/src/programs/frameworks/fastapi/fastapi-wizard-agent.ts @@ -1,8 +1,8 @@ /* FastAPI wizard using posthog-agent with PostHog MCP */ import type { WizardRunOptions } from '@utils/types'; -import type { FrameworkConfig } from '@lib/framework-config'; -import { PYTHON_PACKAGE_INSTALLATION } from '@lib/framework-config'; -import { detectPythonPackageManagers } from '@lib/detection/package-manager'; +import type { FrameworkConfig } from '@programs/framework-config'; +import { PYTHON_PACKAGE_INSTALLATION } from '@programs/framework-config'; +import { detectPythonPackageManagers } from '@programs/detection/package-manager'; import { Integration } from '@shared/constants'; import { getFastAPIVersion, diff --git a/src/frameworks/fastapi/utils.ts b/src/programs/frameworks/fastapi/utils.ts similarity index 100% rename from src/frameworks/fastapi/utils.ts rename to src/programs/frameworks/fastapi/utils.ts diff --git a/src/frameworks/flask/flask-wizard-agent.ts b/src/programs/frameworks/flask/flask-wizard-agent.ts similarity index 95% rename from src/frameworks/flask/flask-wizard-agent.ts rename to src/programs/frameworks/flask/flask-wizard-agent.ts index 8d143fda6..b781777fb 100644 --- a/src/frameworks/flask/flask-wizard-agent.ts +++ b/src/programs/frameworks/flask/flask-wizard-agent.ts @@ -1,8 +1,8 @@ /* Flask wizard using posthog-agent with PostHog MCP */ import type { WizardRunOptions } from '@utils/types'; -import type { FrameworkConfig } from '@lib/framework-config'; -import { PYTHON_PACKAGE_INSTALLATION } from '@lib/framework-config'; -import { detectPythonPackageManagers } from '@lib/detection/package-manager'; +import type { FrameworkConfig } from '@programs/framework-config'; +import { PYTHON_PACKAGE_INSTALLATION } from '@programs/framework-config'; +import { detectPythonPackageManagers } from '@programs/detection/package-manager'; import { Integration } from '@shared/constants'; import { boundedGlob, readProjectFile } from '@utils/bounded-fs'; import * as path from 'node:path'; diff --git a/src/frameworks/flask/utils.ts b/src/programs/frameworks/flask/utils.ts similarity index 100% rename from src/frameworks/flask/utils.ts rename to src/programs/frameworks/flask/utils.ts diff --git a/src/frameworks/flutter/flutter-wizard-agent.ts b/src/programs/frameworks/flutter/flutter-wizard-agent.ts similarity index 96% rename from src/frameworks/flutter/flutter-wizard-agent.ts rename to src/programs/frameworks/flutter/flutter-wizard-agent.ts index c2fb22371..5a2e5e0a8 100644 --- a/src/frameworks/flutter/flutter-wizard-agent.ts +++ b/src/programs/frameworks/flutter/flutter-wizard-agent.ts @@ -1,10 +1,10 @@ /* Flutter wizard using posthog-agent with PostHog MCP */ import type { WizardRunOptions } from '@utils/types'; -import type { FrameworkConfig } from '@lib/framework-config'; +import type { FrameworkConfig } from '@programs/framework-config'; import { Integration } from '@shared/constants'; import * as fs from 'node:fs'; import * as path from 'node:path'; -import { pubPackageManager } from '@lib/detection/package-manager'; +import { pubPackageManager } from '@programs/detection/package-manager'; /** Platform subtrees `flutter create` scaffolds; each needs its own setup notes. */ const FLUTTER_PLATFORM_DIRS = [ diff --git a/src/frameworks/go/go-wizard-agent.ts b/src/programs/frameworks/go/go-wizard-agent.ts similarity index 95% rename from src/frameworks/go/go-wizard-agent.ts rename to src/programs/frameworks/go/go-wizard-agent.ts index f9e630506..ae704da5b 100644 --- a/src/frameworks/go/go-wizard-agent.ts +++ b/src/programs/frameworks/go/go-wizard-agent.ts @@ -2,8 +2,8 @@ import * as fs from 'node:fs'; import * as path from 'node:path'; import type { WizardRunOptions } from '@utils/types'; -import type { FrameworkConfig } from '@lib/framework-config'; -import { goModulesPackageManager } from '@lib/detection/package-manager'; +import type { FrameworkConfig } from '@programs/framework-config'; +import { goModulesPackageManager } from '@programs/detection/package-manager'; import { Integration } from '@shared/constants'; type GoContext = { diff --git a/src/frameworks/java/java-wizard-agent.ts b/src/programs/frameworks/java/java-wizard-agent.ts similarity index 97% rename from src/frameworks/java/java-wizard-agent.ts rename to src/programs/frameworks/java/java-wizard-agent.ts index 1c9e26828..8b27ab160 100644 --- a/src/frameworks/java/java-wizard-agent.ts +++ b/src/programs/frameworks/java/java-wizard-agent.ts @@ -3,8 +3,8 @@ import fg from 'fast-glob'; import * as fs from 'node:fs'; import * as path from 'node:path'; import type { WizardRunOptions } from '@utils/types'; -import type { FrameworkConfig } from '@lib/framework-config'; -import { detectJavaPackageManagers } from '@lib/detection/package-manager'; +import type { FrameworkConfig } from '@programs/framework-config'; +import { detectJavaPackageManagers } from '@programs/detection/package-manager'; import { Integration } from '@shared/constants'; type JavaContext = { diff --git a/src/frameworks/javascript-node/javascript-node-wizard-agent.ts b/src/programs/frameworks/javascript-node/javascript-node-wizard-agent.ts similarity index 94% rename from src/frameworks/javascript-node/javascript-node-wizard-agent.ts rename to src/programs/frameworks/javascript-node/javascript-node-wizard-agent.ts index 62519d721..4fc410be3 100644 --- a/src/frameworks/javascript-node/javascript-node-wizard-agent.ts +++ b/src/programs/frameworks/javascript-node/javascript-node-wizard-agent.ts @@ -1,8 +1,8 @@ /* Generic Node.js language wizard using posthog-agent with PostHog MCP */ -import type { FrameworkConfig } from '@lib/framework-config'; +import type { FrameworkConfig } from '@programs/framework-config'; import { Integration } from '@shared/constants'; import { tryGetPackageJson } from '@utils/setup-utils'; -import { detectNodePackageManagers } from '@lib/detection/package-manager'; +import { detectNodePackageManagers } from '@programs/detection/package-manager'; type JavaScriptNodeContext = Record; diff --git a/src/frameworks/javascript-web/javascript-web-wizard-agent.ts b/src/programs/frameworks/javascript-web/javascript-web-wizard-agent.ts similarity index 96% rename from src/frameworks/javascript-web/javascript-web-wizard-agent.ts rename to src/programs/frameworks/javascript-web/javascript-web-wizard-agent.ts index cc3899c06..1a662796c 100644 --- a/src/frameworks/javascript-web/javascript-web-wizard-agent.ts +++ b/src/programs/frameworks/javascript-web/javascript-web-wizard-agent.ts @@ -1,6 +1,6 @@ /* Generic JavaScript Web (client-side) wizard using posthog-agent with PostHog MCP */ import type { WizardRunOptions } from '@utils/types'; -import type { FrameworkConfig } from '@lib/framework-config'; +import type { FrameworkConfig } from '@programs/framework-config'; import { Integration } from '@shared/constants'; import * as fs from 'node:fs'; import * as path from 'node:path'; @@ -13,7 +13,7 @@ import { hasIndexHtml, type JavaScriptContext, } from './utils'; -import { detectNodePackageManagers } from '@lib/detection/package-manager'; +import { detectNodePackageManagers } from '@programs/detection/package-manager'; export const JAVASCRIPT_WEB_AGENT_CONFIG: FrameworkConfig = { metadata: { diff --git a/src/frameworks/javascript-web/utils.ts b/src/programs/frameworks/javascript-web/utils.ts similarity index 100% rename from src/frameworks/javascript-web/utils.ts rename to src/programs/frameworks/javascript-web/utils.ts diff --git a/src/frameworks/kmp/kmp-wizard-agent.ts b/src/programs/frameworks/kmp/kmp-wizard-agent.ts similarity index 96% rename from src/frameworks/kmp/kmp-wizard-agent.ts rename to src/programs/frameworks/kmp/kmp-wizard-agent.ts index be2a3e969..87328a0f4 100644 --- a/src/frameworks/kmp/kmp-wizard-agent.ts +++ b/src/programs/frameworks/kmp/kmp-wizard-agent.ts @@ -1,7 +1,7 @@ /* Kotlin Multiplatform (KMP) wizard using posthog-agent with PostHog MCP */ -import type { FrameworkConfig } from '../../lib/framework-config'; +import type { FrameworkConfig } from '../../framework-config'; import { Integration } from '@shared/constants'; -import { gradlePackageManager } from '../../lib/detection/package-manager'; +import { gradlePackageManager } from '../../detection/package-manager'; import { boundedGlob, readProjectFile } from '@utils/bounded-fs'; import * as path from 'node:path'; diff --git a/src/frameworks/laravel/laravel-wizard-agent.ts b/src/programs/frameworks/laravel/laravel-wizard-agent.ts similarity index 97% rename from src/frameworks/laravel/laravel-wizard-agent.ts rename to src/programs/frameworks/laravel/laravel-wizard-agent.ts index b7c0c1651..cc0849617 100644 --- a/src/frameworks/laravel/laravel-wizard-agent.ts +++ b/src/programs/frameworks/laravel/laravel-wizard-agent.ts @@ -1,7 +1,7 @@ /* Laravel wizard using posthog-agent with PostHog MCP */ import type { WizardRunOptions } from '@utils/types'; -import type { FrameworkConfig } from '@lib/framework-config'; -import { composerPackageManager } from '@lib/detection/package-manager'; +import type { FrameworkConfig } from '@programs/framework-config'; +import { composerPackageManager } from '@programs/detection/package-manager'; import { Integration } from '@shared/constants'; import { boundedGlob } from '@utils/bounded-fs'; import * as fs from 'node:fs'; diff --git a/src/frameworks/laravel/utils.ts b/src/programs/frameworks/laravel/utils.ts similarity index 100% rename from src/frameworks/laravel/utils.ts rename to src/programs/frameworks/laravel/utils.ts diff --git a/src/frameworks/nextjs/nextjs-wizard-agent.ts b/src/programs/frameworks/nextjs/nextjs-wizard-agent.ts similarity index 96% rename from src/frameworks/nextjs/nextjs-wizard-agent.ts rename to src/programs/frameworks/nextjs/nextjs-wizard-agent.ts index 614d9e7aa..83c180672 100644 --- a/src/frameworks/nextjs/nextjs-wizard-agent.ts +++ b/src/programs/frameworks/nextjs/nextjs-wizard-agent.ts @@ -1,7 +1,7 @@ /* Simplified Next.js wizard using posthog-agent with PostHog MCP */ import type { WizardRunOptions } from '@utils/types'; -import type { FrameworkConfig } from '@lib/framework-config'; -import { detectNodePackageManagers } from '@lib/detection/package-manager'; +import type { FrameworkConfig } from '@programs/framework-config'; +import { detectNodePackageManagers } from '@programs/detection/package-manager'; import { Integration } from '@shared/constants'; import { getDeclaredVersion, diff --git a/src/frameworks/nextjs/utils.ts b/src/programs/frameworks/nextjs/utils.ts similarity index 100% rename from src/frameworks/nextjs/utils.ts rename to src/programs/frameworks/nextjs/utils.ts diff --git a/src/frameworks/nuxt/nuxt-wizard-agent.ts b/src/programs/frameworks/nuxt/nuxt-wizard-agent.ts similarity index 95% rename from src/frameworks/nuxt/nuxt-wizard-agent.ts rename to src/programs/frameworks/nuxt/nuxt-wizard-agent.ts index 94edb5173..7e197aca6 100644 --- a/src/frameworks/nuxt/nuxt-wizard-agent.ts +++ b/src/programs/frameworks/nuxt/nuxt-wizard-agent.ts @@ -1,7 +1,7 @@ /* Nuxt wizard using posthog-agent with PostHog MCP */ import type { WizardRunOptions } from '@utils/types'; -import type { FrameworkConfig } from '@lib/framework-config'; -import { detectNodePackageManagers } from '@lib/detection/package-manager'; +import type { FrameworkConfig } from '@programs/framework-config'; +import { detectNodePackageManagers } from '@programs/detection/package-manager'; import { Integration } from '@shared/constants'; import { getDeclaredVersion, diff --git a/src/frameworks/python/python-wizard-agent.ts b/src/programs/frameworks/python/python-wizard-agent.ts similarity index 96% rename from src/frameworks/python/python-wizard-agent.ts rename to src/programs/frameworks/python/python-wizard-agent.ts index 15d88cd69..63fcf83aa 100644 --- a/src/frameworks/python/python-wizard-agent.ts +++ b/src/programs/frameworks/python/python-wizard-agent.ts @@ -1,8 +1,8 @@ /* Generic Python language wizard using posthog-agent with PostHog MCP */ import type { WizardRunOptions } from '@utils/types'; -import type { FrameworkConfig } from '@lib/framework-config'; -import { PYTHON_PACKAGE_INSTALLATION } from '@lib/framework-config'; -import { detectPythonPackageManagers } from '@lib/detection/package-manager'; +import type { FrameworkConfig } from '@programs/framework-config'; +import { PYTHON_PACKAGE_INSTALLATION } from '@programs/framework-config'; +import { detectPythonPackageManagers } from '@programs/detection/package-manager'; import { Integration } from '@shared/constants'; import fg from 'fast-glob'; import * as fs from 'node:fs'; diff --git a/src/frameworks/python/utils.ts b/src/programs/frameworks/python/utils.ts similarity index 100% rename from src/frameworks/python/utils.ts rename to src/programs/frameworks/python/utils.ts diff --git a/src/frameworks/rails/rails-wizard-agent.ts b/src/programs/frameworks/rails/rails-wizard-agent.ts similarity index 96% rename from src/frameworks/rails/rails-wizard-agent.ts rename to src/programs/frameworks/rails/rails-wizard-agent.ts index e2df48c59..08c8c39a6 100644 --- a/src/frameworks/rails/rails-wizard-agent.ts +++ b/src/programs/frameworks/rails/rails-wizard-agent.ts @@ -1,7 +1,7 @@ /* Ruby on Rails wizard using posthog-agent with PostHog MCP */ import type { WizardRunOptions } from '@utils/types'; -import type { FrameworkConfig } from '@lib/framework-config'; -import { bundlerPackageManager } from '@lib/detection/package-manager'; +import type { FrameworkConfig } from '@programs/framework-config'; +import { bundlerPackageManager } from '@programs/detection/package-manager'; import { Integration } from '@shared/constants'; import { getRailsVersion, diff --git a/src/frameworks/rails/utils.ts b/src/programs/frameworks/rails/utils.ts similarity index 100% rename from src/frameworks/rails/utils.ts rename to src/programs/frameworks/rails/utils.ts diff --git a/src/frameworks/react-native/react-native-wizard-agent.ts b/src/programs/frameworks/react-native/react-native-wizard-agent.ts similarity index 96% rename from src/frameworks/react-native/react-native-wizard-agent.ts rename to src/programs/frameworks/react-native/react-native-wizard-agent.ts index c4a489c71..2ba1b8f85 100644 --- a/src/frameworks/react-native/react-native-wizard-agent.ts +++ b/src/programs/frameworks/react-native/react-native-wizard-agent.ts @@ -1,7 +1,7 @@ /* React Native wizard using posthog-agent with PostHog MCP */ import type { WizardRunOptions } from '@utils/types'; -import type { FrameworkConfig } from '@lib/framework-config'; -import { detectNodePackageManagers } from '@lib/detection/package-manager'; +import type { FrameworkConfig } from '@programs/framework-config'; +import { detectNodePackageManagers } from '@programs/detection/package-manager'; import { Integration } from '@shared/constants'; import { getDeclaredVersion, diff --git a/src/frameworks/react-native/utils.ts b/src/programs/frameworks/react-native/utils.ts similarity index 100% rename from src/frameworks/react-native/utils.ts rename to src/programs/frameworks/react-native/utils.ts diff --git a/src/frameworks/react-router/react-router-wizard-agent.ts b/src/programs/frameworks/react-router/react-router-wizard-agent.ts similarity index 96% rename from src/frameworks/react-router/react-router-wizard-agent.ts rename to src/programs/frameworks/react-router/react-router-wizard-agent.ts index 4c19a4ac4..b4dd9b38a 100644 --- a/src/frameworks/react-router/react-router-wizard-agent.ts +++ b/src/programs/frameworks/react-router/react-router-wizard-agent.ts @@ -1,7 +1,7 @@ /* React Router wizard using posthog-agent with PostHog MCP */ import type { WizardRunOptions } from '@utils/types'; -import type { FrameworkConfig } from '@lib/framework-config'; -import { detectNodePackageManagers } from '@lib/detection/package-manager'; +import type { FrameworkConfig } from '@programs/framework-config'; +import { detectNodePackageManagers } from '@programs/detection/package-manager'; import { Integration } from '@shared/constants'; import { getDeclaredVersion, diff --git a/src/frameworks/react-router/utils.ts b/src/programs/frameworks/react-router/utils.ts similarity index 100% rename from src/frameworks/react-router/utils.ts rename to src/programs/frameworks/react-router/utils.ts diff --git a/src/programs/frameworks/registry.ts b/src/programs/frameworks/registry.ts new file mode 100644 index 000000000..4c2a79a70 --- /dev/null +++ b/src/programs/frameworks/registry.ts @@ -0,0 +1,59 @@ +import type { FrameworkConfig } from '@programs/framework-config'; +import { Integration } from '@shared/constants'; +import { NEXTJS_AGENT_CONFIG } from '@programs/frameworks/nextjs/nextjs-wizard-agent'; +import { NUXT_AGENT_CONFIG } from '@programs/frameworks/nuxt/nuxt-wizard-agent'; +import { VUE_AGENT_CONFIG } from '@programs/frameworks/vue/vue-wizard-agent'; +import { REACT_ROUTER_AGENT_CONFIG } from '@programs/frameworks/react-router/react-router-wizard-agent'; +import { TANSTACK_ROUTER_AGENT_CONFIG } from '@programs/frameworks/tanstack-router/tanstack-router-wizard-agent'; +import { TANSTACK_START_AGENT_CONFIG } from '@programs/frameworks/tanstack-start/tanstack-start-wizard-agent'; +import { REACT_NATIVE_AGENT_CONFIG } from '@programs/frameworks/react-native/react-native-wizard-agent'; +import { ANGULAR_AGENT_CONFIG } from '@programs/frameworks/angular/angular-wizard-agent'; +import { ASTRO_AGENT_CONFIG } from '@programs/frameworks/astro/astro-wizard-agent'; +import { DJANGO_AGENT_CONFIG } from '@programs/frameworks/django/django-wizard-agent'; +import { FLASK_AGENT_CONFIG } from '@programs/frameworks/flask/flask-wizard-agent'; +import { FASTAPI_AGENT_CONFIG } from '@programs/frameworks/fastapi/fastapi-wizard-agent'; +import { LARAVEL_AGENT_CONFIG } from '@programs/frameworks/laravel/laravel-wizard-agent'; +import { SVELTEKIT_AGENT_CONFIG } from '@programs/frameworks/svelte/svelte-wizard-agent'; +import { FLUTTER_AGENT_CONFIG } from '@programs/frameworks/flutter/flutter-wizard-agent'; +import { SWIFT_AGENT_CONFIG } from '@programs/frameworks/swift/swift-wizard-agent'; +import { KMP_AGENT_CONFIG } from '@programs/frameworks/kmp/kmp-wizard-agent'; +import { ANDROID_AGENT_CONFIG } from '@programs/frameworks/android/android-wizard-agent'; +import { RAILS_AGENT_CONFIG } from '@programs/frameworks/rails/rails-wizard-agent'; +import { ELIXIR_AGENT_CONFIG } from '@programs/frameworks/elixir/elixir-wizard-agent'; +import { GO_AGENT_CONFIG } from '@programs/frameworks/go/go-wizard-agent'; +import { JAVA_AGENT_CONFIG } from '@programs/frameworks/java/java-wizard-agent'; +import { RUST_AGENT_CONFIG } from '@programs/frameworks/rust/rust-wizard-agent'; +import { PYTHON_AGENT_CONFIG } from '@programs/frameworks/python/python-wizard-agent'; +import { RUBY_AGENT_CONFIG } from '@programs/frameworks/ruby/ruby-wizard-agent'; +import { JAVASCRIPT_NODE_AGENT_CONFIG } from '@programs/frameworks/javascript-node/javascript-node-wizard-agent'; +import { JAVASCRIPT_WEB_AGENT_CONFIG } from '@programs/frameworks/javascript-web/javascript-web-wizard-agent'; + +export const FRAMEWORK_REGISTRY: Record = { + [Integration.nextjs]: NEXTJS_AGENT_CONFIG, + [Integration.nuxt]: NUXT_AGENT_CONFIG, + [Integration.vue]: VUE_AGENT_CONFIG, + [Integration.tanstackStart]: TANSTACK_START_AGENT_CONFIG, + [Integration.reactRouter]: REACT_ROUTER_AGENT_CONFIG, + [Integration.tanstackRouter]: TANSTACK_ROUTER_AGENT_CONFIG, + [Integration.reactNative]: REACT_NATIVE_AGENT_CONFIG, + [Integration.angular]: ANGULAR_AGENT_CONFIG, + [Integration.astro]: ASTRO_AGENT_CONFIG, + [Integration.django]: DJANGO_AGENT_CONFIG, + [Integration.flask]: FLASK_AGENT_CONFIG, + [Integration.fastapi]: FASTAPI_AGENT_CONFIG, + [Integration.laravel]: LARAVEL_AGENT_CONFIG, + [Integration.sveltekit]: SVELTEKIT_AGENT_CONFIG, + [Integration.flutter]: FLUTTER_AGENT_CONFIG, + [Integration.kmp]: KMP_AGENT_CONFIG, + [Integration.swift]: SWIFT_AGENT_CONFIG, + [Integration.android]: ANDROID_AGENT_CONFIG, + [Integration.rails]: RAILS_AGENT_CONFIG, + [Integration.elixir]: ELIXIR_AGENT_CONFIG, + [Integration.go]: GO_AGENT_CONFIG, + [Integration.rust]: RUST_AGENT_CONFIG, + [Integration.java]: JAVA_AGENT_CONFIG, + [Integration.python]: PYTHON_AGENT_CONFIG, + [Integration.ruby]: RUBY_AGENT_CONFIG, + [Integration.javascriptNode]: JAVASCRIPT_NODE_AGENT_CONFIG, + [Integration.javascript_web]: JAVASCRIPT_WEB_AGENT_CONFIG, +}; diff --git a/src/frameworks/ruby/ruby-wizard-agent.ts b/src/programs/frameworks/ruby/ruby-wizard-agent.ts similarity index 96% rename from src/frameworks/ruby/ruby-wizard-agent.ts rename to src/programs/frameworks/ruby/ruby-wizard-agent.ts index 508ab33a5..c2907a536 100644 --- a/src/frameworks/ruby/ruby-wizard-agent.ts +++ b/src/programs/frameworks/ruby/ruby-wizard-agent.ts @@ -1,7 +1,7 @@ /* Generic Ruby language wizard using posthog-agent with PostHog MCP */ import type { WizardRunOptions } from '@utils/types'; -import type { FrameworkConfig } from '@lib/framework-config'; -import { bundlerPackageManager } from '@lib/detection/package-manager'; +import type { FrameworkConfig } from '@programs/framework-config'; +import { bundlerPackageManager } from '@programs/detection/package-manager'; import { Integration } from '@shared/constants'; import { getRubyVersion, diff --git a/src/frameworks/ruby/utils.ts b/src/programs/frameworks/ruby/utils.ts similarity index 100% rename from src/frameworks/ruby/utils.ts rename to src/programs/frameworks/ruby/utils.ts diff --git a/src/frameworks/rust/rust-wizard-agent.ts b/src/programs/frameworks/rust/rust-wizard-agent.ts similarity index 96% rename from src/frameworks/rust/rust-wizard-agent.ts rename to src/programs/frameworks/rust/rust-wizard-agent.ts index 3113a6708..a1dd2711d 100644 --- a/src/frameworks/rust/rust-wizard-agent.ts +++ b/src/programs/frameworks/rust/rust-wizard-agent.ts @@ -2,8 +2,8 @@ import * as fs from 'node:fs'; import * as path from 'node:path'; import type { WizardRunOptions } from '@utils/types'; -import type { FrameworkConfig } from '@lib/framework-config'; -import { cargoPackageManager } from '@lib/detection/package-manager'; +import type { FrameworkConfig } from '@programs/framework-config'; +import { cargoPackageManager } from '@programs/detection/package-manager'; import { Integration } from '@shared/constants'; type RustContext = { diff --git a/src/frameworks/svelte/svelte-wizard-agent.ts b/src/programs/frameworks/svelte/svelte-wizard-agent.ts similarity index 93% rename from src/frameworks/svelte/svelte-wizard-agent.ts rename to src/programs/frameworks/svelte/svelte-wizard-agent.ts index 5d7777fdc..1c5088c3c 100644 --- a/src/frameworks/svelte/svelte-wizard-agent.ts +++ b/src/programs/frameworks/svelte/svelte-wizard-agent.ts @@ -1,6 +1,6 @@ /* SvelteKit wizard using posthog-agent with PostHog MCP */ -import type { FrameworkConfig } from '@lib/framework-config'; -import { detectNodePackageManagers } from '@lib/detection/package-manager'; +import type { FrameworkConfig } from '@programs/framework-config'; +import { detectNodePackageManagers } from '@programs/detection/package-manager'; import { Integration } from '@shared/constants'; import { getDeclaredVersion, diff --git a/src/frameworks/swift/__tests__/utils.test.ts b/src/programs/frameworks/swift/__tests__/utils.test.ts similarity index 100% rename from src/frameworks/swift/__tests__/utils.test.ts rename to src/programs/frameworks/swift/__tests__/utils.test.ts diff --git a/src/frameworks/swift/swift-wizard-agent.ts b/src/programs/frameworks/swift/swift-wizard-agent.ts similarity index 96% rename from src/frameworks/swift/swift-wizard-agent.ts rename to src/programs/frameworks/swift/swift-wizard-agent.ts index 049255b64..58dd25782 100644 --- a/src/frameworks/swift/swift-wizard-agent.ts +++ b/src/programs/frameworks/swift/swift-wizard-agent.ts @@ -1,7 +1,7 @@ /* Swift wizard using posthog-agent with PostHog MCP */ import type { WizardRunOptions } from '@utils/types'; -import type { FrameworkConfig } from '@lib/framework-config'; -import { swiftPackageManager } from '@lib/detection/package-manager'; +import type { FrameworkConfig } from '@programs/framework-config'; +import { swiftPackageManager } from '@programs/detection/package-manager'; import { Integration } from '@shared/constants'; import { boundedGlob } from '@utils/bounded-fs'; import fg from 'fast-glob'; diff --git a/src/frameworks/swift/utils.ts b/src/programs/frameworks/swift/utils.ts similarity index 100% rename from src/frameworks/swift/utils.ts rename to src/programs/frameworks/swift/utils.ts diff --git a/src/frameworks/tanstack-router/tanstack-router-wizard-agent.ts b/src/programs/frameworks/tanstack-router/tanstack-router-wizard-agent.ts similarity index 96% rename from src/frameworks/tanstack-router/tanstack-router-wizard-agent.ts rename to src/programs/frameworks/tanstack-router/tanstack-router-wizard-agent.ts index 07e43d0ad..d93e337bf 100644 --- a/src/frameworks/tanstack-router/tanstack-router-wizard-agent.ts +++ b/src/programs/frameworks/tanstack-router/tanstack-router-wizard-agent.ts @@ -1,7 +1,7 @@ /* TanStack Router wizard using posthog-agent with PostHog MCP */ import type { WizardRunOptions } from '@utils/types'; -import type { FrameworkConfig } from '@lib/framework-config'; -import { detectNodePackageManagers } from '@lib/detection/package-manager'; +import type { FrameworkConfig } from '@programs/framework-config'; +import { detectNodePackageManagers } from '@programs/detection/package-manager'; import { Integration } from '@shared/constants'; import { getDeclaredVersion, diff --git a/src/frameworks/tanstack-router/utils.ts b/src/programs/frameworks/tanstack-router/utils.ts similarity index 100% rename from src/frameworks/tanstack-router/utils.ts rename to src/programs/frameworks/tanstack-router/utils.ts diff --git a/src/frameworks/tanstack-start/tanstack-start-wizard-agent.ts b/src/programs/frameworks/tanstack-start/tanstack-start-wizard-agent.ts similarity index 95% rename from src/frameworks/tanstack-start/tanstack-start-wizard-agent.ts rename to src/programs/frameworks/tanstack-start/tanstack-start-wizard-agent.ts index f28eaa4a9..fcb52a0d6 100644 --- a/src/frameworks/tanstack-start/tanstack-start-wizard-agent.ts +++ b/src/programs/frameworks/tanstack-start/tanstack-start-wizard-agent.ts @@ -1,7 +1,7 @@ /* TanStack Start wizard using posthog-agent with PostHog MCP */ import type { WizardRunOptions } from '@utils/types'; -import type { FrameworkConfig } from '@lib/framework-config'; -import { detectNodePackageManagers } from '@lib/detection/package-manager'; +import type { FrameworkConfig } from '@programs/framework-config'; +import { detectNodePackageManagers } from '@programs/detection/package-manager'; import { Integration } from '@shared/constants'; import { getDeclaredVersion, diff --git a/src/frameworks/tanstack-start/utils.ts b/src/programs/frameworks/tanstack-start/utils.ts similarity index 100% rename from src/frameworks/tanstack-start/utils.ts rename to src/programs/frameworks/tanstack-start/utils.ts diff --git a/src/frameworks/vue/vue-wizard-agent.ts b/src/programs/frameworks/vue/vue-wizard-agent.ts similarity index 93% rename from src/frameworks/vue/vue-wizard-agent.ts rename to src/programs/frameworks/vue/vue-wizard-agent.ts index dd61b3ab4..0f2ae5cee 100644 --- a/src/frameworks/vue/vue-wizard-agent.ts +++ b/src/programs/frameworks/vue/vue-wizard-agent.ts @@ -1,6 +1,6 @@ /* Vue wizard using posthog-agent with PostHog MCP */ -import type { FrameworkConfig } from '@lib/framework-config'; -import { detectNodePackageManagers } from '@lib/detection/package-manager'; +import type { FrameworkConfig } from '@programs/framework-config'; +import { detectNodePackageManagers } from '@programs/detection/package-manager'; import { Integration } from '@shared/constants'; import { getDeclaredVersion, diff --git a/src/programs/index.ts b/src/programs/index.ts new file mode 100644 index 000000000..68a7e3d1e --- /dev/null +++ b/src/programs/index.ts @@ -0,0 +1,10 @@ +/** Public runtime entry for the programs surface. */ +export type * from './types'; +export { + Program, + PROGRAM_REGISTRY, + getProgramConfig, + getSubcommandPrograms, + getCommandPath, + getLaunchablePrograms, +} from './program-registry'; diff --git a/src/lib/programs/mcp-analytics/index.ts b/src/programs/mcp-analytics/index.ts similarity index 98% rename from src/lib/programs/mcp-analytics/index.ts rename to src/programs/mcp-analytics/index.ts index 458ba18e7..faa9afd1c 100644 --- a/src/lib/programs/mcp-analytics/index.ts +++ b/src/programs/mcp-analytics/index.ts @@ -1,6 +1,6 @@ import type { AbortCase } from '@agent/types'; import { ErrorCodes } from '@shared/errors'; -import { createSkillProgram } from '@lib/programs/agent-skill/index'; +import { createSkillProgram } from '@programs/agent-skill/index'; const MCP_ANALYTICS_REPORT_FILE = 'posthog-mcp-analytics-report.md'; diff --git a/src/lib/programs/mcp/index.ts b/src/programs/mcp/index.ts similarity index 98% rename from src/lib/programs/mcp/index.ts rename to src/programs/mcp/index.ts index 819e19e8e..5c0e35ce5 100644 --- a/src/lib/programs/mcp/index.ts +++ b/src/programs/mcp/index.ts @@ -8,7 +8,7 @@ * screen-sequences.ts). */ -import type { ProgramConfig } from '@lib/programs/program-step'; +import type { ProgramConfig } from '@programs/program-step'; import { McpOutcome } from '@lib/wizard-session'; export const mcpAddConfig: ProgramConfig = { diff --git a/src/lib/programs/metrics/index.ts b/src/programs/metrics/index.ts similarity index 93% rename from src/lib/programs/metrics/index.ts rename to src/programs/metrics/index.ts index 859eb6d19..c96612ae3 100644 --- a/src/lib/programs/metrics/index.ts +++ b/src/programs/metrics/index.ts @@ -1,6 +1,6 @@ -import type { ProgramConfig, ProgramStep } from '@lib/programs/program-step'; -import { AGENT_SKILL_STEPS } from '@lib/programs/agent-skill/index'; -import { getContentBlocks } from '@lib/programs/agent-skill/content/index'; +import type { ProgramConfig, ProgramStep } from '@programs/program-step'; +import { AGENT_SKILL_STEPS } from '@programs/agent-skill/index'; +import { getContentBlocks } from '@ui/tui/decks/agent-skill/index'; const METRICS_STEPS: ProgramStep[] = AGENT_SKILL_STEPS.map((step) => step.id === 'intro' ? { ...step, screenId: 'metrics-intro' } : step, diff --git a/src/lib/programs/metrics/test/e2e.json b/src/programs/metrics/test/e2e.json similarity index 100% rename from src/lib/programs/metrics/test/e2e.json rename to src/programs/metrics/test/e2e.json diff --git a/src/lib/programs/migration/index.ts b/src/programs/migration/index.ts similarity index 94% rename from src/lib/programs/migration/index.ts rename to src/programs/migration/index.ts index 173e007be..907160f6d 100644 --- a/src/lib/programs/migration/index.ts +++ b/src/programs/migration/index.ts @@ -1,8 +1,8 @@ -import type { ProgramConfig } from '@lib/programs/program-step'; +import type { ProgramConfig } from '@programs/program-step'; import type { AbortCase } from '@agent/types'; import { WIZARD_TOOL_NAMES } from '@agent'; import { MIGRATION_PROGRAM } from './steps.js'; -import { getContentBlocks } from './content/index.js'; +import { getContentBlocks } from '../../ui/tui/decks/migration/index.js'; const MIGRATION_REPORT_FILE = 'migration-report.md'; diff --git a/src/lib/programs/migration/steps.ts b/src/programs/migration/steps.ts similarity index 84% rename from src/lib/programs/migration/steps.ts rename to src/programs/migration/steps.ts index 33635d863..cb41d5bc0 100644 --- a/src/lib/programs/migration/steps.ts +++ b/src/programs/migration/steps.ts @@ -1,6 +1,6 @@ -import type { ProgramStep } from '@lib/programs/program-step'; +import type { ProgramStep } from '@programs/program-step'; import { RunPhase } from '@lib/wizard-session'; -import { HEALTH_CHECK_STEP } from '@lib/programs/shared/health-check-step'; +import { HEALTH_CHECK_STEP } from '@programs/shared/health-check-step'; export const MIGRATION_PROGRAM: ProgramStep[] = [ { diff --git a/src/lib/oauth/__tests__/program-scopes.test.ts b/src/programs/oauth/__tests__/program-scopes.test.ts similarity index 98% rename from src/lib/oauth/__tests__/program-scopes.test.ts rename to src/programs/oauth/__tests__/program-scopes.test.ts index 773a7f15d..1200b444b 100644 --- a/src/lib/oauth/__tests__/program-scopes.test.ts +++ b/src/programs/oauth/__tests__/program-scopes.test.ts @@ -6,7 +6,7 @@ import { getOAuthScopesForProgram, getProvisioningScopesForProgram, -} from '@lib/oauth/program-scopes'; +} from '@programs/oauth/program-scopes'; describe('posthog-integration scopes', () => { it('includes the warehouse pair for the orchestrator warehouse task', () => { diff --git a/src/lib/oauth/program-scopes.ts b/src/programs/oauth/program-scopes.ts similarity index 99% rename from src/lib/oauth/program-scopes.ts rename to src/programs/oauth/program-scopes.ts index 453b3c48b..8d8f57d2f 100644 --- a/src/lib/oauth/program-scopes.ts +++ b/src/programs/oauth/program-scopes.ts @@ -31,7 +31,7 @@ // read as `undefined` at module init. Keep this type-only and reference // program IDs by their string-literal value below — TypeScript still // catches renames via the `Partial>` keying. -import type { ProgramId } from '@lib/programs/program-registry'; +import type { ProgramId } from '@programs/program-registry'; import { WIZARD_OAUTH_SCOPES, WIZARD_PROVISIONING_SCOPES, diff --git a/src/lib/programs/posthog-doctor/__tests__/doctor-schema.test.ts b/src/programs/posthog-doctor/__tests__/doctor-schema.test.ts similarity index 95% rename from src/lib/programs/posthog-doctor/__tests__/doctor-schema.test.ts rename to src/programs/posthog-doctor/__tests__/doctor-schema.test.ts index cc23b479f..9fb87640c 100644 --- a/src/lib/programs/posthog-doctor/__tests__/doctor-schema.test.ts +++ b/src/programs/posthog-doctor/__tests__/doctor-schema.test.ts @@ -1,12 +1,12 @@ import { HealthIssueListResponseSchema, HealthIssueSchema, -} from '@lib/programs/posthog-doctor/types'; +} from '@programs/posthog-doctor/types'; import { getKindMeta, KIND_METADATA, UNKNOWN_KIND_META, -} from '@lib/programs/posthog-doctor/kind-metadata'; +} from '@programs/posthog-doctor/kind-metadata'; describe('posthog-doctor schema', () => { const canned = { diff --git a/src/lib/programs/posthog-doctor/fetch.ts b/src/programs/posthog-doctor/fetch.ts similarity index 100% rename from src/lib/programs/posthog-doctor/fetch.ts rename to src/programs/posthog-doctor/fetch.ts diff --git a/src/lib/programs/posthog-doctor/index.ts b/src/programs/posthog-doctor/index.ts similarity index 91% rename from src/lib/programs/posthog-doctor/index.ts rename to src/programs/posthog-doctor/index.ts index a6ad9f10e..f5a7c5f96 100644 --- a/src/lib/programs/posthog-doctor/index.ts +++ b/src/programs/posthog-doctor/index.ts @@ -1,4 +1,4 @@ -import type { ProgramConfig } from '@lib/programs/program-step'; +import type { ProgramConfig } from '@programs/program-step'; import { WIZARD_TOOL_NAMES } from '@agent'; import { POSTHOG_DOCTOR_PROGRAM } from './steps.js'; diff --git a/src/lib/programs/posthog-doctor/kind-metadata.ts b/src/programs/posthog-doctor/kind-metadata.ts similarity index 100% rename from src/lib/programs/posthog-doctor/kind-metadata.ts rename to src/programs/posthog-doctor/kind-metadata.ts diff --git a/src/lib/programs/posthog-doctor/steps.ts b/src/programs/posthog-doctor/steps.ts similarity index 81% rename from src/lib/programs/posthog-doctor/steps.ts rename to src/programs/posthog-doctor/steps.ts index fe0ef895c..3a97bc42a 100644 --- a/src/lib/programs/posthog-doctor/steps.ts +++ b/src/programs/posthog-doctor/steps.ts @@ -1,5 +1,5 @@ -import type { ProgramStep } from '@lib/programs/program-step'; -import { HEALTH_CHECK_STEP } from '@lib/programs/shared/health-check-step'; +import type { ProgramStep } from '@programs/program-step'; +import { HEALTH_CHECK_STEP } from '@programs/shared/health-check-step'; export const POSTHOG_DOCTOR_PROGRAM: ProgramStep[] = [ { diff --git a/src/lib/programs/posthog-doctor/types.ts b/src/programs/posthog-doctor/types.ts similarity index 100% rename from src/lib/programs/posthog-doctor/types.ts rename to src/programs/posthog-doctor/types.ts diff --git a/src/lib/programs/posthog-integration/__tests__/detect.test.ts b/src/programs/posthog-integration/__tests__/detect.test.ts similarity index 96% rename from src/lib/programs/posthog-integration/__tests__/detect.test.ts rename to src/programs/posthog-integration/__tests__/detect.test.ts index 456abdfd8..4c57c314d 100644 --- a/src/lib/programs/posthog-integration/__tests__/detect.test.ts +++ b/src/programs/posthog-integration/__tests__/detect.test.ts @@ -17,9 +17,9 @@ vi.mock('@utils/analytics', () => ({ })); // Wrapped so one test can force a throw; the rest use the real scanner. -vi.mock('@lib/warehouse-sources/detect', async (importOriginal) => { +vi.mock('@programs/warehouse-sources/detect', async (importOriginal) => { const actual = await importOriginal< - typeof import('@lib/warehouse-sources/detect') + typeof import('@programs/warehouse-sources/detect') >(); return { ...actual, @@ -28,22 +28,22 @@ vi.mock('@lib/warehouse-sources/detect', async (importOriginal) => { }); import { analytics } from '@utils/analytics'; -import { detectWarehouseSources } from '@lib/warehouse-sources/detect'; +import { detectWarehouseSources } from '@programs/warehouse-sources/detect'; import { detectPostHogIntegration, maybeStampAiSdkDetected, reportWarehouseSourcesDetected, -} from '@lib/programs/posthog-integration/detect'; -import { posthogIntegrationConfig } from '@lib/programs/posthog-integration/index'; -import { DETECTED_WAREHOUSE_SOURCES_KEY } from '@lib/programs/warehouse-source/detect'; -import type { ProgramReadyContext } from '@lib/programs/program-step'; +} from '@programs/posthog-integration/detect'; +import { posthogIntegrationConfig } from '@programs/posthog-integration/index'; +import { DETECTED_WAREHOUSE_SOURCES_KEY } from '@programs/warehouse-source/detect'; +import type { ProgramReadyContext } from '@programs/types'; import { buildSession, DiscoveredFeature, ScanConsent, type WizardSession, } from '@lib/wizard-session'; -import type { DetectedSource } from '@lib/warehouse-sources/types'; +import type { DetectedSource } from '@programs/warehouse-sources/types'; function makeTmpDir(): string { return fs.mkdtempSync(path.join(os.tmpdir(), 'warehouse-reporting-')); @@ -290,7 +290,7 @@ describe('reportWarehouseSourcesDetected', () => { // scanned". const session = buildSession({ installDir: tmpDir, ci: true }); const { detectWarehousePrerequisites } = await import( - '@lib/programs/warehouse-source/detect' + '@programs/warehouse-source/detect' ); detectWarehousePrerequisites(session, (key, value) => { session.frameworkContext[key] = value; diff --git a/src/lib/programs/posthog-integration/__tests__/handoff.test.ts b/src/programs/posthog-integration/__tests__/handoff.test.ts similarity index 100% rename from src/lib/programs/posthog-integration/__tests__/handoff.test.ts rename to src/programs/posthog-integration/__tests__/handoff.test.ts diff --git a/src/lib/programs/posthog-integration/__tests__/index.test.ts b/src/programs/posthog-integration/__tests__/index.test.ts similarity index 96% rename from src/lib/programs/posthog-integration/__tests__/index.test.ts rename to src/programs/posthog-integration/__tests__/index.test.ts index 576125180..5c24f8ad3 100644 --- a/src/lib/programs/posthog-integration/__tests__/index.test.ts +++ b/src/programs/posthog-integration/__tests__/index.test.ts @@ -6,7 +6,7 @@ * state, so the value rides on every later capture either way. */ -import { posthogIntegrationConfig } from '@lib/programs/posthog-integration/index'; +import { posthogIntegrationConfig } from '@programs/posthog-integration/index'; import { buildSession, type WizardSession } from '@lib/wizard-session'; import { analytics } from '@utils/analytics'; import { isUsingTypeScript } from '@utils/setup-utils'; diff --git a/src/lib/programs/posthog-integration/constants.ts b/src/programs/posthog-integration/constants.ts similarity index 100% rename from src/lib/programs/posthog-integration/constants.ts rename to src/programs/posthog-integration/constants.ts diff --git a/src/lib/programs/posthog-integration/detect.ts b/src/programs/posthog-integration/detect.ts similarity index 95% rename from src/lib/programs/posthog-integration/detect.ts rename to src/programs/posthog-integration/detect.ts index f27faa6a9..09be0515d 100644 --- a/src/lib/programs/posthog-integration/detect.ts +++ b/src/programs/posthog-integration/detect.ts @@ -9,29 +9,29 @@ * extracted here so the `integrate` subcommand can reuse it. */ -import type { ProgramReadyContext } from '@lib/programs/program-step'; +import type { ProgramReadyContext } from '@programs/program-step'; import { DiscoveredFeature, mayReportScanResults, ScanConsent, type WizardSession, } from '@lib/wizard-session'; -import { FRAMEWORK_REGISTRY } from '@lib/registry'; +import { FRAMEWORK_REGISTRY } from '@programs/frameworks/registry'; import { detectFramework, discoverFeatures, gatherFrameworkContext, checkFrameworkVersion, -} from '@lib/detection/index'; +} from '@programs/detection/index'; import { analytics } from '@utils/analytics'; -import { detectWarehouseSources } from '@lib/warehouse-sources/detect'; -import { AI_SOURCE_KINDS } from '@lib/warehouse-sources/registry'; -import type { DetectedSource } from '@lib/warehouse-sources/types'; +import { detectWarehouseSources } from '@programs/warehouse-sources/detect'; +import { AI_SOURCE_KINDS } from '@programs/warehouse-sources/registry'; +import type { DetectedSource } from '@programs/warehouse-sources/types'; import { DETECTED_WAREHOUSE_SOURCES_KEY, getDetectedWarehouseSources, -} from '@lib/programs/warehouse-source/detect'; -import { findPackageJsons } from '@lib/programs/shared/package-scanning'; +} from '@programs/warehouse-source/detect'; +import { findPackageJsons } from '@programs/shared/package-scanning'; export async function detectPostHogIntegration( ctx: ProgramReadyContext, diff --git a/src/lib/programs/posthog-integration/handoff.ts b/src/programs/posthog-integration/handoff.ts similarity index 100% rename from src/lib/programs/posthog-integration/handoff.ts rename to src/programs/posthog-integration/handoff.ts diff --git a/src/lib/programs/posthog-integration/index.ts b/src/programs/posthog-integration/index.ts similarity index 97% rename from src/lib/programs/posthog-integration/index.ts rename to src/programs/posthog-integration/index.ts index 29afa37a7..03f63624c 100644 --- a/src/lib/programs/posthog-integration/index.ts +++ b/src/programs/posthog-integration/index.ts @@ -1,18 +1,21 @@ -import type { ProgramConfig, ProgramStep } from '@lib/programs/program-step'; -import { runProgramAgent } from '@lib/programs/run-agent-legacy'; -import type { ProgramRun } from '@lib/programs/program-run'; +import type { ProgramConfig, ProgramStep } from '@programs/program-step'; +import { runProgramAgent } from '@programs/run-agent-legacy'; +import type { ProgramRun } from '@programs/program-run'; import { AgentSignals, shouldDisableAsk, WIZARD_TOOL_NAMES } from '@agent'; import type { WizardSession } from '@lib/wizard-session'; import { mayReportScanResults, OutroKind, RunPhase } from '@lib/wizard-session'; import { DEFAULT_PACKAGE_INSTALLATION, SPINNER_MESSAGE, -} from '@lib/framework-config'; +} from '@programs/framework-config'; import { tryGetPackageJson, isUsingTypeScript } from '@utils/setup-utils'; import { analytics } from '@utils/analytics'; -import { detectFramework, gatherFrameworkContext } from '@lib/detection/index'; -import { scopeInstallDirToProject } from '@lib/detection/project-scope'; -import { FRAMEWORK_REGISTRY } from '@lib/registry'; +import { + detectFramework, + gatherFrameworkContext, +} from '@programs/detection/index'; +import { scopeInstallDirToProject } from '@programs/detection/project-scope'; +import { FRAMEWORK_REGISTRY } from '@programs/frameworks/registry'; import { wizardAbort } from '@utils/wizard-abort'; import { ErrorCodes } from '@shared/errors'; import { @@ -23,9 +26,9 @@ import { getUI } from '@ui/index'; import { requestDeepLink } from '@utils/provisioning'; import { openTrackedLink, withUtm } from '@utils/links'; import type { HostResolution } from '@shared/host-resolution'; -import { getDetectedWarehouseSources } from '@lib/programs/warehouse-source/detect'; +import { getDetectedWarehouseSources } from '@programs/warehouse-source/detect'; import { POSTHOG_INTEGRATION_PROGRAM } from './steps.js'; -import { getContentBlocks } from './content/index.js'; +import { getContentBlocks } from '../../ui/tui/decks/posthog-integration/index.js'; import { buildCodingAgentPrompt } from './handoff.js'; import { EVENT_PLAN_FILE } from './constants.js'; diff --git a/src/lib/programs/posthog-integration/steps.ts b/src/programs/posthog-integration/steps.ts similarity index 94% rename from src/lib/programs/posthog-integration/steps.ts rename to src/programs/posthog-integration/steps.ts index bc5adc3b0..3c4e9dc5b 100644 --- a/src/lib/programs/posthog-integration/steps.ts +++ b/src/programs/posthog-integration/steps.ts @@ -6,10 +6,10 @@ * definitions — no hardcoded per-flow logic in the store. */ -import type { ProgramStep } from '@lib/programs/program-step'; +import type { ProgramStep } from '@programs/program-step'; import type { WizardSession } from '@lib/wizard-session'; import { RunPhase } from '@lib/wizard-session'; -import { HEALTH_CHECK_STEP } from '@lib/programs/shared/health-check-step'; +import { HEALTH_CHECK_STEP } from '@programs/shared/health-check-step'; import { detectPostHogIntegration } from './detect.js'; function needsSetup(session: WizardSession): boolean { diff --git a/src/lib/programs/posthog-integration/test/README.md b/src/programs/posthog-integration/test/README.md similarity index 90% rename from src/lib/programs/posthog-integration/test/README.md rename to src/programs/posthog-integration/test/README.md index 34a008a65..211f6c3dc 100644 --- a/src/lib/programs/posthog-integration/test/README.md +++ b/src/programs/posthog-integration/test/README.md @@ -6,7 +6,7 @@ documented `path` of every screen and what it does. - **`profile`** — the machine-read part. The harness loads it via `profileFor(Program.PostHogIntegration)` - ([`e2e-harness/profiles.ts`](../../../../../e2e-harness/profiles.ts)) and asks + ([`e2e-harness/profiles.ts`](../../../../e2e-harness/profiles.ts)) and asks `decideE2eAction` what to commit on each screen. - **`path`** — the human-read part: each screen in order and the auto-decision, so you can see the whole walk at a glance. diff --git a/src/lib/programs/posthog-integration/test/e2e.json b/src/programs/posthog-integration/test/e2e.json similarity index 100% rename from src/lib/programs/posthog-integration/test/e2e.json rename to src/programs/posthog-integration/test/e2e.json diff --git a/src/lib/programs/program-registry.ts b/src/programs/program-registry.ts similarity index 97% rename from src/lib/programs/program-registry.ts rename to src/programs/program-registry.ts index 2b001e56c..be63b4b8a 100644 --- a/src/lib/programs/program-registry.ts +++ b/src/programs/program-registry.ts @@ -2,7 +2,7 @@ * Central registry of all wizard programs. * * Adding a new program: - * 1. Create src/lib/programs// with index.ts exporting a ProgramConfig + * 1. Create src/programs// with index.ts exporting a ProgramConfig * 2. Import and add it to PROGRAM_REGISTRY below * 3. (If custom intro screen) add to src/ui/tui/screen-registry.tsx * @@ -24,7 +24,7 @@ import { errorTrackingUploadSourceMapsConfig } from './error-tracking-upload-sou import { errorTrackingConfig } from './error-tracking/index.js'; import { selfDrivingConfig } from './self-driving/index.js'; import { AGENT_SKILL_STEPS } from './agent-skill/index.js'; -import { getContentBlocks as agentSkillContentBlocks } from './agent-skill/content/index.js'; +import { getContentBlocks as agentSkillContentBlocks } from '../ui/tui/decks/agent-skill/index.js'; import { mcpAddConfig, mcpRemoveConfig, diff --git a/src/lib/programs/program-run.ts b/src/programs/program-run.ts similarity index 100% rename from src/lib/programs/program-run.ts rename to src/programs/program-run.ts diff --git a/src/lib/programs/program-step.ts b/src/programs/program-step.ts similarity index 99% rename from src/lib/programs/program-step.ts rename to src/programs/program-step.ts index 641fa9a0e..59b726d06 100644 --- a/src/lib/programs/program-step.ts +++ b/src/programs/program-step.ts @@ -4,9 +4,9 @@ import type { TaskNotice, } from '@lib/wizard-session'; import type { WizardReadinessResult } from '@shared/health-checks/readiness'; -import type { ProgramRun } from '@lib/programs/program-run'; +import type { ProgramRun } from '@programs/program-run'; import type { Integration } from '@shared/constants'; -import type { FrameworkConfig } from '@lib/framework-config'; +import type { FrameworkConfig } from '@programs/framework-config'; import type { ContentBlock } from '@ui/tui/primitives/index'; import type { WizardStore } from '@ui/tui/store'; import type { Tip } from '@ui/tui/components/TipsCard'; diff --git a/src/lib/programs/replay-vision/index.ts b/src/programs/replay-vision/index.ts similarity index 94% rename from src/lib/programs/replay-vision/index.ts rename to src/programs/replay-vision/index.ts index ef01e6a9d..c266f6f51 100644 --- a/src/lib/programs/replay-vision/index.ts +++ b/src/programs/replay-vision/index.ts @@ -1,16 +1,19 @@ import type { AbortCase } from '@agent/types'; import { Integration } from '@shared/constants'; -import { detectFramework, gatherFrameworkContext } from '@lib/detection/index'; -import { scopeInstallDirToProject } from '@lib/detection/project-scope'; -import { FRAMEWORK_REGISTRY } from '@lib/registry'; -import { createSkillProgram } from '@lib/programs/agent-skill/index'; -import { AGENT_SKILL_STEPS } from '@lib/programs/agent-skill/steps'; -import { detectPostHogIntegration } from '@lib/programs/posthog-integration/detect'; +import { + detectFramework, + gatherFrameworkContext, +} from '@programs/detection/index'; +import { scopeInstallDirToProject } from '@programs/detection/project-scope'; +import { FRAMEWORK_REGISTRY } from '@programs/frameworks/registry'; +import { createSkillProgram } from '@programs/agent-skill/index'; +import { AGENT_SKILL_STEPS } from '@programs/agent-skill/steps'; +import { detectPostHogIntegration } from '@programs/posthog-integration/detect'; import type { ProgramConfig, ProgramReadyContext, ProgramStep, -} from '@lib/programs/program-step'; +} from '@programs/program-step'; import type { WizardSession } from '@lib/wizard-session'; import { analytics } from '@utils/analytics'; import { wizardAbort } from '@utils/wizard-abort'; diff --git a/src/lib/programs/replay-vision/test/e2e.json b/src/programs/replay-vision/test/e2e.json similarity index 100% rename from src/lib/programs/replay-vision/test/e2e.json rename to src/programs/replay-vision/test/e2e.json diff --git a/src/lib/programs/revenue-analytics/detect.ts b/src/programs/revenue-analytics/detect.ts similarity index 97% rename from src/lib/programs/revenue-analytics/detect.ts rename to src/programs/revenue-analytics/detect.ts index d63ef3c6a..b81090ffd 100644 --- a/src/lib/programs/revenue-analytics/detect.ts +++ b/src/programs/revenue-analytics/detect.ts @@ -8,14 +8,14 @@ import { existsSync, statSync } from 'fs'; import type { WizardSession } from '@lib/wizard-session'; import type { AbortCase } from '@agent/types'; -import { findPackageJsons } from '@lib/programs/shared/package-scanning'; +import { findPackageJsons } from '@programs/shared/package-scanning'; export { findPackageJsons, POSTHOG_SDKS, STRIPE_SDKS, type PackageMatch, -} from '@lib/programs/shared/package-scanning'; +} from '@programs/shared/package-scanning'; /** * Structured detection errors. The screen renders each kind into JSX diff --git a/src/lib/programs/revenue-analytics/index.ts b/src/programs/revenue-analytics/index.ts similarity index 89% rename from src/lib/programs/revenue-analytics/index.ts rename to src/programs/revenue-analytics/index.ts index fade6e3fc..4fae357ac 100644 --- a/src/lib/programs/revenue-analytics/index.ts +++ b/src/programs/revenue-analytics/index.ts @@ -1,8 +1,8 @@ -import type { ProgramConfig } from '@lib/programs/program-step'; +import type { ProgramConfig } from '@programs/program-step'; import { WIZARD_TOOL_NAMES } from '@agent'; import { REVENUE_ANALYTICS_PROGRAM } from './steps.js'; import { REVENUE_ABORT_CASES } from './detect.js'; -import { getContentBlocks } from './content/index.js'; +import { getContentBlocks } from '../../ui/tui/decks/revenue-analytics/index.js'; export const revenueAnalyticsConfig: ProgramConfig = { command: 'revenue-analytics', diff --git a/src/lib/programs/revenue-analytics/steps.ts b/src/programs/revenue-analytics/steps.ts similarity index 91% rename from src/lib/programs/revenue-analytics/steps.ts rename to src/programs/revenue-analytics/steps.ts index 7e983ab9d..b53926536 100644 --- a/src/lib/programs/revenue-analytics/steps.ts +++ b/src/programs/revenue-analytics/steps.ts @@ -5,9 +5,9 @@ * and agent run live in the program runner (see agent-runner.ts). */ -import type { ProgramStep } from '@lib/programs/program-step'; +import type { ProgramStep } from '@programs/program-step'; import { RunPhase } from '@lib/wizard-session'; -import { HEALTH_CHECK_STEP } from '@lib/programs/shared/health-check-step'; +import { HEALTH_CHECK_STEP } from '@programs/shared/health-check-step'; import { detectRevenuePrerequisites } from './detect.js'; export const REVENUE_ANALYTICS_PROGRAM: ProgramStep[] = [ diff --git a/src/lib/programs/run-agent-legacy.ts b/src/programs/run-agent-legacy.ts similarity index 99% rename from src/lib/programs/run-agent-legacy.ts rename to src/programs/run-agent-legacy.ts index 598cc57c7..ee4134fd9 100644 --- a/src/lib/programs/run-agent-legacy.ts +++ b/src/programs/run-agent-legacy.ts @@ -57,7 +57,7 @@ import { WIZARD_SELF_DRIVING_USE_PI_HARNESS_FLAG_KEY, type Integration, } from '@shared/constants'; -import { FRAMEWORK_REGISTRY } from '@lib/registry'; +import { FRAMEWORK_REGISTRY } from '@programs/frameworks/registry'; import { postAuthGateSteps, type ProgramConfig } from './program-step'; import { authenticate, refreshAccessTokenIfNeeded } from './authenticate'; import { maybeStampAiSdkDetected } from './posthog-integration/detect'; diff --git a/src/lib/programs/self-driving/ARCHITECTURE.md b/src/programs/self-driving/ARCHITECTURE.md similarity index 98% rename from src/lib/programs/self-driving/ARCHITECTURE.md rename to src/programs/self-driving/ARCHITECTURE.md index 3b23569ea..aded532e8 100644 --- a/src/lib/programs/self-driving/ARCHITECTURE.md +++ b/src/programs/self-driving/ARCHITECTURE.md @@ -22,11 +22,11 @@ anchors are point-in-time — the symbol names are the durable part. | Need | Go to | | -------------------------------------- | ---------------------------------------------------------- | -| The ordered steps | `src/lib/programs/self-driving/prompt.ts` | +| The ordered steps | `src/programs/self-driving/prompt.ts` | | What each step _does_ | `context-mill/context/skills/self-driving/references/*.md` | -| Program registration / lifecycle | `src/lib/programs/self-driving/index.ts` | +| Program registration / lifecycle | `src/programs/self-driving/index.ts` | | `wizard_ask` / `.env` tools | `src/agent/tools/tools.ts`, `src/agent/wizard-ask-bridge.ts` | -| OAuth scopes (+ prod ceiling) | `src/lib/oauth/program-scopes.ts` (§3, §7) | +| OAuth scopes (+ prod ceiling) | `src/programs/oauth/program-scopes.ts` (§3, §7) | | Signals models / MCP / sync | `posthog/products/signals/backend/…` (§5) | | Why a team gets no findings | §6 | | What to change for prod | §7 | @@ -146,16 +146,16 @@ repos. ## 3. Wizard internals -**Program definition** (`src/lib/programs/self-driving/`, five files): +**Program definition** (`src/programs/self-driving/`, four core files): `index.ts` (config + lifecycle), `prompt.ts` (the 10 steps + mechanics + project URLs), `detect.ts` (prerequisite check + abort vocabulary), `steps.ts` (TUI screen sequence `detect → intro → health-check → auth → self-driving-github → -run → outro`), and -`content/tips.ts` (the program-owned `Tips`-sidebar copy that defines signal +run → outro`). The TUI deck at +`src/ui/tui/decks/self-driving/tips.ts` (the `Tips`-sidebar copy that defines signal sources + scouts + scanners in plain language, wired via `getTips`; `RunScreen` falls back to `DEFAULT_TIPS` for every other program, so nothing else is affected). `selfDrivingConfig` is built from the `createSkillProgram` factory -(`src/lib/programs/agent-skill/`) with overrides. Notables in `index.ts`: +(`src/programs/agent-skill/`) with overrides. Notables in `index.ts`: `SELF_DRIVING_SKILL_ID = 'self-driving-setup'`, `REPORT_FILE = 'posthog-self-driving-report.md'`, `maxQuestions: 13` (tracker picks + custom-scout proposal), `richLinks: true` (OSC-8 links so long @@ -200,7 +200,7 @@ returns an error telling the agent to default or emit brokers into the TUI overlay; cancelled/timed-out fields resolve to `CANCELLED_SENTINEL = '__cancelled__'`. -**OAuth scopes** (`src/lib/oauth/program-scopes.ts`). Base `WIZARD_OAUTH_SCOPES` +**OAuth scopes** (`src/programs/oauth/program-scopes.ts`). Base `WIZARD_OAUTH_SCOPES` (`src/shared/constants.ts`) ∪ `SELF_DRIVING_SCOPE_ADDITIONS` — **12 strings**, requested via a PKCE auth-code flow: @@ -374,7 +374,7 @@ source is enabled. (`posthog/models/organization.py`, default `True`, nullable; admin toggle at `/settings/organization#organization-ai-consent`). Fail-closed; without it findings are silently dropped. Enforced for this program by the **base - wizard's AI opt-in gate** (`src/lib/programs/ai-opt-in-gate.ts`, + wizard's AI opt-in gate** (`src/programs/ai-opt-in-gate.ts`, `withAiOptInGate`): it injects an `ai-opt-in` step after `auth` for every program that doesn't set `requiresAi: false` (self-driving doesn't), and `store.getGate('ai-opt-in')` parks the agent until approval lands — so the @@ -583,11 +583,11 @@ must be running, or no scout ever dispatches. > (plus its own `startDelay` of 2 s); `ContentSequencer.handleComplete` > fires `onSequenceComplete` **only after the last block's `pause` > elapses**; the deck self-driving plays is the **shared factory default** > -> `agent-skill/content/index.tsx` (`getContentBlocks`, last block +> `src/ui/tui/decks/agent-skill/index.tsx` (`getContentBlocks`, last block > `pause: 60000`) — self-driving does **not** override it today. **Scoping > caveat (the whole reason this is a TODO, not a one-liner):** that deck is > inherited by _every_ skill program (audit, revenue-analytics, migration, -> bare `wizard skill `), so editing `agent-skill/content/index.tsx` +> bare `wizard skill `), so editing `src/ui/tui/decks/agent-skill/index.tsx` > changes all of them. Fix self-driving alone the way `getTips` already is — > add a **self-driving-owned `getContentBlocks`** override to > `selfDrivingConfig` (`self-driving/index.ts`, right next to the `getTips` @@ -958,7 +958,7 @@ Code anchors: posthog `products/replay_vision/backend/models/replay_scanner.py`, `api/scanners.py`, `temporal/scanners/prompts/signals_step.jinja` (the fixed defect-detection turn that `emits_signals` appends — the *why* the skill cares more about a scanner's `query` than its prompt); wizard `program-scopes.ts` + -`prompt.ts` + `content/tips.ts`; skill `6c-replay-vision-scanners.md`. +`prompt.ts` + `src/ui/tui/decks/self-driving/tips.ts`; skill `6c-replay-vision-scanners.md`. --- diff --git a/src/lib/programs/self-driving/__tests__/step-keys.test.ts b/src/programs/self-driving/__tests__/step-keys.test.ts similarity index 100% rename from src/lib/programs/self-driving/__tests__/step-keys.test.ts rename to src/programs/self-driving/__tests__/step-keys.test.ts diff --git a/src/lib/programs/self-driving/detect-agentic.ts b/src/programs/self-driving/detect-agentic.ts similarity index 94% rename from src/lib/programs/self-driving/detect-agentic.ts rename to src/programs/self-driving/detect-agentic.ts index 3822359de..2df306bf7 100644 --- a/src/lib/programs/self-driving/detect-agentic.ts +++ b/src/programs/self-driving/detect-agentic.ts @@ -3,7 +3,7 @@ * * Mirrors source-maps: the integration-detect screen runs `detectSelfDriving- * IntegrationProjects` (the shared integration scan from - * @lib/detection/project-scope), shows a project map, and the user picks one. + * @programs/detection/project-scope), shows a project map, and the user picks one. * `toIntegrationCandidates` matches each project to an `Integration`; this file * classifies it as instrumentable (a framework the wizard supports that doesn't * already have PostHog). The screen writes the choice to the session; `prepSelfDriving- @@ -14,12 +14,12 @@ import type { AgenticDetectionReport, DetectEvent, -} from '@lib/detection/agentic'; +} from '@programs/detection/agentic'; import { detectIntegrationProjects, toIntegrationCandidates, -} from '@lib/detection/project-scope'; -import { gatherFrameworkContext } from '@lib/detection/index'; +} from '@programs/detection/project-scope'; +import { gatherFrameworkContext } from '@programs/detection/index'; import type { Integration } from '@shared/constants'; import type { WizardSession } from '@lib/wizard-session'; diff --git a/src/lib/programs/self-driving/detect.ts b/src/programs/self-driving/detect.ts similarity index 98% rename from src/lib/programs/self-driving/detect.ts rename to src/programs/self-driving/detect.ts index a5dbdb546..e53598ed7 100644 --- a/src/lib/programs/self-driving/detect.ts +++ b/src/programs/self-driving/detect.ts @@ -31,8 +31,8 @@ import { analytics } from '@utils/analytics'; import type { WizardSession } from '@lib/wizard-session'; import type { AbortCase } from '@agent/types'; import { ErrorCodes } from '@shared/errors'; -import { detectWarehouseSources } from '@lib/warehouse-sources/detect'; -import type { DetectedSource } from '@lib/warehouse-sources/types'; +import { detectWarehouseSources } from '@programs/warehouse-sources/detect'; +import type { DetectedSource } from '@programs/warehouse-sources/types'; /** frameworkContext key holding the deterministic PostHog-presence result. */ export const POSTHOG_PRESENT_KEY = 'postHogPresent'; @@ -65,7 +65,7 @@ export function getSelfDrivingDetectedTools( const POSTHOG_PACKAGE_RE = /(^|["'\s/=:.@])posthog/im; // Manifests grepped for a posthog dependency. Distinct from PROJECT_MANIFESTS -// in @lib/detection/agentic (project-root discovery); keep the two in sync +// in @programs/detection/agentic (project-root discovery); keep the two in sync // (a test asserts the shared ecosystem names appear in both). Exported for it. export const POSTHOG_MANIFESTS = [ 'package.json', diff --git a/src/lib/programs/self-driving/index.ts b/src/programs/self-driving/index.ts similarity index 94% rename from src/lib/programs/self-driving/index.ts rename to src/programs/self-driving/index.ts index 38a0ad930..b43e00fce 100644 --- a/src/lib/programs/self-driving/index.ts +++ b/src/programs/self-driving/index.ts @@ -1,7 +1,7 @@ import { join } from 'path'; import { access, rm } from 'node:fs/promises'; -import type { ProgramConfig } from '@lib/programs/program-step'; -import type { ProgramRun } from '@lib/programs/program-run'; +import type { ProgramConfig } from '@programs/program-step'; +import type { ProgramRun } from '@programs/program-run'; import { OutroKind, type WizardSession } from '@lib/wizard-session'; import { createSkillProgram } from '../agent-skill/index.js'; import { SELF_DRIVING_PROGRAM } from './steps.js'; @@ -15,9 +15,9 @@ import { NO_DEFAULT_LIMIT, PRICE_PER_PR_USD, PRICING_LONG, -} from './content/pricing.js'; -import { getTips } from './content/tips.js'; -import { getContentBlocks } from './content/index.js'; +} from '../../ui/tui/decks/self-driving/pricing.js'; +import { getTips } from '../../ui/tui/decks/self-driving/tips.js'; +import { getContentBlocks } from '../../ui/tui/decks/self-driving/index.js'; export const SELF_DRIVING_SKILL_ID = 'self-driving-setup'; const REPORT_FILE = 'posthog-self-driving-report.md'; diff --git a/src/lib/programs/self-driving/prompt.ts b/src/programs/self-driving/prompt.ts similarity index 99% rename from src/lib/programs/self-driving/prompt.ts rename to src/programs/self-driving/prompt.ts index db629ea28..393586dc4 100644 --- a/src/lib/programs/self-driving/prompt.ts +++ b/src/programs/self-driving/prompt.ts @@ -1,6 +1,6 @@ import { AgentSignals } from '@agent'; import type { PromptContext } from '@agent/types'; -import type { DetectedSource } from '@lib/warehouse-sources/types'; +import type { DetectedSource } from '@programs/warehouse-sources/types'; /** * Render the deterministic codebase-tool scan for the prompt. STEP 4 and diff --git a/src/lib/programs/self-driving/step-keys.ts b/src/programs/self-driving/step-keys.ts similarity index 100% rename from src/lib/programs/self-driving/step-keys.ts rename to src/programs/self-driving/step-keys.ts diff --git a/src/lib/programs/self-driving/steps.ts b/src/programs/self-driving/steps.ts similarity index 95% rename from src/lib/programs/self-driving/steps.ts rename to src/programs/self-driving/steps.ts index 4eeceb5d4..2bad6952c 100644 --- a/src/lib/programs/self-driving/steps.ts +++ b/src/programs/self-driving/steps.ts @@ -14,11 +14,11 @@ * gates on the GitHub App connection the run cannot proceed without. No keep-skills step: the setup skill is transient, so postRun removes it. */ -import type { ProgramStep } from '@lib/programs/program-step'; -import { resolveProjectDir } from '@lib/detection/agentic'; +import type { ProgramStep } from '@programs/program-step'; +import { resolveProjectDir } from '@programs/detection/agentic'; import { RunPhase, type WizardSession } from '@lib/wizard-session'; -import { HEALTH_CHECK_STEP } from '@lib/programs/shared/health-check-step'; -import { integrationRunStep } from '@lib/programs/posthog-integration/index'; +import { HEALTH_CHECK_STEP } from '@programs/shared/health-check-step'; +import { integrationRunStep } from '@programs/posthog-integration/index'; import { detectSelfDrivingPrerequisites, POSTHOG_PRESENT_KEY, diff --git a/src/lib/programs/self-driving/test/e2e.json b/src/programs/self-driving/test/e2e.json similarity index 100% rename from src/lib/programs/self-driving/test/e2e.json rename to src/programs/self-driving/test/e2e.json diff --git a/src/lib/programs/shared/health-check-step.ts b/src/programs/shared/health-check-step.ts similarity index 97% rename from src/lib/programs/shared/health-check-step.ts rename to src/programs/shared/health-check-step.ts index 8a42179eb..d7a147159 100644 --- a/src/lib/programs/shared/health-check-step.ts +++ b/src/programs/shared/health-check-step.ts @@ -11,7 +11,7 @@ * render the OutroScreen. */ -import type { ProgramStep } from '@lib/programs/program-step'; +import type { ProgramStep } from '@programs/program-step'; import type { WizardSession } from '@lib/wizard-session'; import { evaluateWizardReadiness, diff --git a/src/lib/programs/shared/package-scanning.ts b/src/programs/shared/package-scanning.ts similarity index 100% rename from src/lib/programs/shared/package-scanning.ts rename to src/programs/shared/package-scanning.ts diff --git a/src/lib/programs/shared/posthog-cli-preinstall.ts b/src/programs/shared/posthog-cli-preinstall.ts similarity index 100% rename from src/lib/programs/shared/posthog-cli-preinstall.ts rename to src/programs/shared/posthog-cli-preinstall.ts diff --git a/src/lib/programs/slack/index.ts b/src/programs/slack/index.ts similarity index 91% rename from src/lib/programs/slack/index.ts rename to src/programs/slack/index.ts index 43823ef7d..e62a7f0b3 100644 --- a/src/lib/programs/slack/index.ts +++ b/src/programs/slack/index.ts @@ -6,7 +6,7 @@ * happens in the browser, so a wizard login adds nothing for the user. */ -import type { ProgramConfig } from '@lib/programs/program-step'; +import type { ProgramConfig } from '@programs/program-step'; export const slackConnectConfig: ProgramConfig = { id: 'slack', diff --git a/src/lib/task-stream/__tests__/audit-areas.test.ts b/src/programs/task-stream/__tests__/audit-areas.test.ts similarity index 92% rename from src/lib/task-stream/__tests__/audit-areas.test.ts rename to src/programs/task-stream/__tests__/audit-areas.test.ts index 4996c1c19..02c989f9c 100644 --- a/src/lib/task-stream/__tests__/audit-areas.test.ts +++ b/src/programs/task-stream/__tests__/audit-areas.test.ts @@ -1,9 +1,9 @@ import { rollUpAuditAreas, MAX_AUDIT_AREAS, -} from '@lib/task-stream/audit-areas'; -import { StreamTaskStatus } from '@lib/task-stream/types'; -import type { AuditCheck } from '@lib/programs/audit/types'; +} from '@programs/task-stream/audit-areas'; +import { StreamTaskStatus } from '@programs/task-stream/types'; +import type { AuditCheck } from '@programs/audit/types'; const check = (over: Partial): AuditCheck => ({ id: 'id', diff --git a/src/lib/task-stream/__tests__/event-plan-watcher.test.ts b/src/programs/task-stream/__tests__/event-plan-watcher.test.ts similarity index 97% rename from src/lib/task-stream/__tests__/event-plan-watcher.test.ts rename to src/programs/task-stream/__tests__/event-plan-watcher.test.ts index 81bde5be2..af68b9838 100644 --- a/src/lib/task-stream/__tests__/event-plan-watcher.test.ts +++ b/src/programs/task-stream/__tests__/event-plan-watcher.test.ts @@ -10,8 +10,8 @@ import { join } from 'node:path'; import { EventPlanWatcher, normalizeEventPlan, -} from '@lib/task-stream/event-plan-watcher'; -import { EVENT_PLAN_FILE } from '@lib/programs/posthog-integration/constants'; +} from '@programs/task-stream/event-plan-watcher'; +import { EVENT_PLAN_FILE } from '@programs/posthog-integration/constants'; import type { PlannedEvent, WizardStore } from '@ui/tui/store'; const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); diff --git a/src/lib/task-stream/__tests__/file-destination.test.ts b/src/programs/task-stream/__tests__/file-destination.test.ts similarity index 94% rename from src/lib/task-stream/__tests__/file-destination.test.ts rename to src/programs/task-stream/__tests__/file-destination.test.ts index ecb97622d..f86700e8d 100644 --- a/src/lib/task-stream/__tests__/file-destination.test.ts +++ b/src/programs/task-stream/__tests__/file-destination.test.ts @@ -4,8 +4,11 @@ import { join } from 'node:path'; import { FileDestination, createFileDestination, -} from '@lib/task-stream/destinations/file'; -import { StreamEvent, type TaskStreamUpdate } from '@lib/task-stream/types'; +} from '@programs/task-stream/destinations/file'; +import { + StreamEvent, + type TaskStreamUpdate, +} from '@programs/task-stream/types'; import { WIZARD_TASK_STREAM_FILE } from '@utils/paths'; import { RunPhase } from '@lib/wizard-session'; diff --git a/src/lib/task-stream/__tests__/posthog-destination.test.ts b/src/programs/task-stream/__tests__/posthog-destination.test.ts similarity index 99% rename from src/lib/task-stream/__tests__/posthog-destination.test.ts rename to src/programs/task-stream/__tests__/posthog-destination.test.ts index 48035d7f6..d7325ab50 100644 --- a/src/lib/task-stream/__tests__/posthog-destination.test.ts +++ b/src/programs/task-stream/__tests__/posthog-destination.test.ts @@ -1,6 +1,6 @@ import { PostHogDestination } from '../destinations/posthog'; import { StreamEvent, type TaskStreamUpdate } from '../types'; -import { RunPhase, type Credentials } from '../../wizard-session'; +import { RunPhase, type Credentials } from '../../../lib/wizard-session'; import { HostResolution } from '@shared/host-resolution'; const SAMPLE_CREDS: Credentials = { diff --git a/src/lib/task-stream/__tests__/task-stream-push.test.ts b/src/programs/task-stream/__tests__/task-stream-push.test.ts similarity index 98% rename from src/lib/task-stream/__tests__/task-stream-push.test.ts rename to src/programs/task-stream/__tests__/task-stream-push.test.ts index 52272ffd5..cfae3e18b 100644 --- a/src/lib/task-stream/__tests__/task-stream-push.test.ts +++ b/src/programs/task-stream/__tests__/task-stream-push.test.ts @@ -1,16 +1,16 @@ -import { TaskStreamPush } from '@lib/task-stream/task-stream-push'; -import { StreamEvent, StreamTaskStatus } from '@lib/task-stream/types'; +import { TaskStreamPush } from '@programs/task-stream/task-stream-push'; +import { StreamEvent, StreamTaskStatus } from '@programs/task-stream/types'; import type { TaskStreamDestination, TaskStreamUpdate, -} from '@lib/task-stream/types'; +} from '@programs/task-stream/types'; import type { WizardStore, TaskItem } from '@ui/tui/store'; import { TaskStatus } from '@ui/wizard-ui'; import { RunPhase, type PendingQuestion } from '@lib/wizard-session'; import { mkdtempSync, rmSync, writeFileSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; -import { EVENT_PLAN_FILE } from '@lib/programs/posthog-integration/constants'; +import { EVENT_PLAN_FILE } from '@programs/posthog-integration/constants'; type Listener = () => void; diff --git a/src/lib/task-stream/__tests__/wizard-run-sync.test.ts b/src/programs/task-stream/__tests__/wizard-run-sync.test.ts similarity index 100% rename from src/lib/task-stream/__tests__/wizard-run-sync.test.ts rename to src/programs/task-stream/__tests__/wizard-run-sync.test.ts diff --git a/src/lib/task-stream/audit-areas.ts b/src/programs/task-stream/audit-areas.ts similarity index 96% rename from src/lib/task-stream/audit-areas.ts rename to src/programs/task-stream/audit-areas.ts index db77679cb..53b24440b 100644 --- a/src/lib/task-stream/audit-areas.ts +++ b/src/programs/task-stream/audit-areas.ts @@ -6,7 +6,7 @@ * A finding is progress, not a failure, so an area never reports `failed`. */ -import type { AuditCheck, AuditStatus } from '@lib/programs/audit/types'; +import type { AuditCheck, AuditStatus } from '@programs/audit/types'; import { StreamTaskStatus, type StreamTask } from './types'; export const MAX_AUDIT_AREAS = 24; diff --git a/src/lib/task-stream/destinations/file.ts b/src/programs/task-stream/destinations/file.ts similarity index 98% rename from src/lib/task-stream/destinations/file.ts rename to src/programs/task-stream/destinations/file.ts index 966024ce6..c082c6d36 100644 --- a/src/lib/task-stream/destinations/file.ts +++ b/src/programs/task-stream/destinations/file.ts @@ -16,7 +16,7 @@ import type { StreamEvent, TaskStreamDestination, TaskStreamUpdate, -} from '@lib/task-stream/types'; +} from '@programs/task-stream/types'; export interface FileDestinationOptions { path: string; diff --git a/src/lib/task-stream/destinations/posthog.ts b/src/programs/task-stream/destinations/posthog.ts similarity index 99% rename from src/lib/task-stream/destinations/posthog.ts rename to src/programs/task-stream/destinations/posthog.ts index e3dadb354..42238a138 100644 --- a/src/lib/task-stream/destinations/posthog.ts +++ b/src/programs/task-stream/destinations/posthog.ts @@ -21,7 +21,7 @@ import type { TaskStreamDestination, TaskStreamUpdate, StreamEvent, -} from '@lib/task-stream/types'; +} from '@programs/task-stream/types'; import type { Credentials } from '@lib/wizard-session'; import { logToFile } from '@utils/debug'; diff --git a/src/lib/task-stream/event-plan-watcher.ts b/src/programs/task-stream/event-plan-watcher.ts similarity index 100% rename from src/lib/task-stream/event-plan-watcher.ts rename to src/programs/task-stream/event-plan-watcher.ts diff --git a/src/lib/task-stream/index.ts b/src/programs/task-stream/index.ts similarity index 100% rename from src/lib/task-stream/index.ts rename to src/programs/task-stream/index.ts diff --git a/src/lib/task-stream/task-stream-push.ts b/src/programs/task-stream/task-stream-push.ts similarity index 100% rename from src/lib/task-stream/task-stream-push.ts rename to src/programs/task-stream/task-stream-push.ts diff --git a/src/lib/task-stream/types.ts b/src/programs/task-stream/types.ts similarity index 100% rename from src/lib/task-stream/types.ts rename to src/programs/task-stream/types.ts diff --git a/src/lib/task-stream/wizard-run-sync.ts b/src/programs/task-stream/wizard-run-sync.ts similarity index 100% rename from src/lib/task-stream/wizard-run-sync.ts rename to src/programs/task-stream/wizard-run-sync.ts diff --git a/src/programs/types.ts b/src/programs/types.ts new file mode 100644 index 000000000..620e94d18 --- /dev/null +++ b/src/programs/types.ts @@ -0,0 +1,9 @@ +/** Public type entry for the programs surface. */ +export type { ProgramId, SubcommandProgram } from './program-registry'; +export type { + ProgramConfig, + ProgramStep, + ProgramReadyContext, + StoreInitContext, +} from './program-step'; +export type { FrameworkConfig, SetupQuestion } from './framework-config'; diff --git a/src/lib/programs/warehouse-source/detect.ts b/src/programs/warehouse-source/detect.ts similarity index 96% rename from src/lib/programs/warehouse-source/detect.ts rename to src/programs/warehouse-source/detect.ts index 22a7b79ab..0fa74c37e 100644 --- a/src/lib/programs/warehouse-source/detect.ts +++ b/src/programs/warehouse-source/detect.ts @@ -10,8 +10,8 @@ import { existsSync, statSync } from 'fs'; import { analytics } from '@utils/analytics'; import type { WizardSession } from '@lib/wizard-session'; import type { AbortCase } from '@agent/types'; -import { detectWarehouseSources } from '@lib/warehouse-sources/detect'; -import type { DetectedSource } from '@lib/warehouse-sources/types'; +import { detectWarehouseSources } from '@programs/warehouse-sources/detect'; +import type { DetectedSource } from '@programs/warehouse-sources/types'; /** Structured detection errors rendered by the intro screen. */ export type WarehouseDetectError = diff --git a/src/lib/programs/warehouse-source/index.ts b/src/programs/warehouse-source/index.ts similarity index 93% rename from src/lib/programs/warehouse-source/index.ts rename to src/programs/warehouse-source/index.ts index a2fb7db06..fb23dd28c 100644 --- a/src/lib/programs/warehouse-source/index.ts +++ b/src/programs/warehouse-source/index.ts @@ -1,5 +1,5 @@ -import type { ProgramConfig } from '@lib/programs/program-step'; -import type { ProgramRun } from '@lib/programs/program-run'; +import type { ProgramConfig } from '@programs/program-step'; +import type { ProgramRun } from '@programs/program-run'; import type { WizardSession } from '@lib/wizard-session'; import { LONGER_ASK_TIMEOUT_MS } from '@agent'; import { WAREHOUSE_SOURCE_PROGRAM } from './steps.js'; @@ -7,7 +7,7 @@ import { WAREHOUSE_ABORT_CASES, getDetectedWarehouseSources, } from './detect.js'; -import { getContentBlocks } from './content/index.js'; +import { getContentBlocks } from '../../ui/tui/decks/warehouse-source/index.js'; /** * Inject the detected sources (and their creation mode) into the prompt so the diff --git a/src/lib/programs/warehouse-source/steps.ts b/src/programs/warehouse-source/steps.ts similarity index 95% rename from src/lib/programs/warehouse-source/steps.ts rename to src/programs/warehouse-source/steps.ts index 1a64bfebd..0a8ed69db 100644 --- a/src/lib/programs/warehouse-source/steps.ts +++ b/src/programs/warehouse-source/steps.ts @@ -6,7 +6,7 @@ * both in-CLI source creation and deep-link emission per detected source. */ -import type { ProgramStep } from '@lib/programs/program-step'; +import type { ProgramStep } from '@programs/program-step'; import { RunPhase } from '@lib/wizard-session'; import { detectWarehousePrerequisites } from './detect.js'; diff --git a/src/lib/programs/warehouse-source/test/e2e.json b/src/programs/warehouse-source/test/e2e.json similarity index 100% rename from src/lib/programs/warehouse-source/test/e2e.json rename to src/programs/warehouse-source/test/e2e.json diff --git a/src/lib/warehouse-sources/__tests__/detect.test.ts b/src/programs/warehouse-sources/__tests__/detect.test.ts similarity index 99% rename from src/lib/warehouse-sources/__tests__/detect.test.ts rename to src/programs/warehouse-sources/__tests__/detect.test.ts index a69eec825..6379f67d3 100644 --- a/src/lib/warehouse-sources/__tests__/detect.test.ts +++ b/src/programs/warehouse-sources/__tests__/detect.test.ts @@ -5,9 +5,9 @@ import { detectWarehouseSources, parseGemfile, parseEnvKeys, -} from '@lib/warehouse-sources/detect'; +} from '@programs/warehouse-sources/detect'; import { MAX_REPORTED_PATH_LENGTH } from '@utils/env-scan'; -import { SOURCE_DETECTORS } from '@lib/warehouse-sources/registry'; +import { SOURCE_DETECTORS } from '@programs/warehouse-sources/registry'; function makeTmpDir(): string { return fs.mkdtempSync(path.join(os.tmpdir(), 'warehouse-detect-')); diff --git a/src/lib/warehouse-sources/detect.ts b/src/programs/warehouse-sources/detect.ts similarity index 99% rename from src/lib/warehouse-sources/detect.ts rename to src/programs/warehouse-sources/detect.ts index fc155e644..a8fcfa199 100644 --- a/src/lib/warehouse-sources/detect.ts +++ b/src/programs/warehouse-sources/detect.ts @@ -23,7 +23,7 @@ import { parseRequirementsTxt, parsePyprojectToml, parsePipfile, -} from '@lib/detection/features'; +} from '@programs/detection/features'; import { SOURCE_DETECTORS } from './registry.js'; import type { DetectedSource, SourceDetector } from './types.js'; diff --git a/src/lib/warehouse-sources/registry.ts b/src/programs/warehouse-sources/registry.ts similarity index 100% rename from src/lib/warehouse-sources/registry.ts rename to src/programs/warehouse-sources/registry.ts diff --git a/src/lib/warehouse-sources/types.ts b/src/programs/warehouse-sources/types.ts similarity index 96% rename from src/lib/warehouse-sources/types.ts rename to src/programs/warehouse-sources/types.ts index 4a1dacf44..b31d2a038 100644 --- a/src/lib/warehouse-sources/types.ts +++ b/src/programs/warehouse-sources/types.ts @@ -24,7 +24,7 @@ export interface SourceSignals { npm?: string[]; /** * Python dependency names as normalized by the parsers in - * `@lib/detection/features` (lowercased, `_`→`-`), e.g. ['psycopg', 'psycopg2']. + * `@programs/detection/features` (lowercased, `_`→`-`), e.g. ['psycopg', 'psycopg2']. */ python?: string[]; /** Gemfile gem names, e.g. ['pg']. */ diff --git a/src/lib/programs/web-analytics-doctor/detect.ts b/src/programs/web-analytics-doctor/detect.ts similarity index 97% rename from src/lib/programs/web-analytics-doctor/detect.ts rename to src/programs/web-analytics-doctor/detect.ts index 9a05bbc00..e7df63673 100644 --- a/src/lib/programs/web-analytics-doctor/detect.ts +++ b/src/programs/web-analytics-doctor/detect.ts @@ -2,7 +2,7 @@ import { existsSync, statSync } from 'fs'; import type { WizardSession } from '@lib/wizard-session'; import type { AbortCase } from '@agent/types'; import { ErrorCodes } from '@shared/errors'; -import { findPackageJsons } from '@lib/programs/shared/package-scanning'; +import { findPackageJsons } from '@programs/shared/package-scanning'; export type WebAnalyticsDetectError = | { diff --git a/src/lib/programs/web-analytics-doctor/index.ts b/src/programs/web-analytics-doctor/index.ts similarity index 96% rename from src/lib/programs/web-analytics-doctor/index.ts rename to src/programs/web-analytics-doctor/index.ts index ee360dd0e..4d11413c2 100644 --- a/src/lib/programs/web-analytics-doctor/index.ts +++ b/src/programs/web-analytics-doctor/index.ts @@ -1,4 +1,4 @@ -import type { ProgramConfig } from '@lib/programs/program-step'; +import type { ProgramConfig } from '@programs/program-step'; import { createSkillProgram } from '../agent-skill/index.js'; import { WEB_ANALYTICS_DOCTOR_PROGRAM } from './steps.js'; import { WEB_ANALYTICS_ABORT_CASES } from './detect.js'; diff --git a/src/lib/programs/web-analytics-doctor/steps.ts b/src/programs/web-analytics-doctor/steps.ts similarity index 70% rename from src/lib/programs/web-analytics-doctor/steps.ts rename to src/programs/web-analytics-doctor/steps.ts index 941b58a9d..a213d7b31 100644 --- a/src/lib/programs/web-analytics-doctor/steps.ts +++ b/src/programs/web-analytics-doctor/steps.ts @@ -1,5 +1,5 @@ -import type { ProgramStep } from '@lib/programs/program-step'; -import { AGENT_SKILL_STEPS } from '@lib/programs/agent-skill/steps'; +import type { ProgramStep } from '@programs/program-step'; +import { AGENT_SKILL_STEPS } from '@programs/agent-skill/steps'; import { detectWebAnalyticsPrerequisites } from './detect.js'; export const WEB_ANALYTICS_DOCTOR_PROGRAM: ProgramStep[] = [ diff --git a/src/shared/README.md b/src/shared/README.md index ae2a39c25..4bbd24aab 100644 --- a/src/shared/README.md +++ b/src/shared/README.md @@ -40,4 +40,4 @@ Shared exists so the agent, programs, TUI, headless and CLI code can use one imp ## Architecture -Shared imports `src/env.ts` and itself. The architecture test classifies `src/shared` as its own surface and lists the remaining upward edges in `src/__tests__/architecture/known-violations.json`; each has an owner in the stack plan. `utils/setup-utils.ts`, `utils/oauth.ts` and `utils/wizard-abort.ts` are TUI and CLI flow code that leave in Release C; `utils/analytics.ts` reads the session until Release B; `claude-settings.ts` and `errors/agent-map.ts` import two agent leaf modules until Release B, because the agent entry would form a module cycle through analytics. +Shared imports `src/env.ts` and itself. The architecture test classifies `src/shared` as its own surface and lists the remaining upward edges in `src/__tests__/architecture/known-violations.json`; each has an owner in the stack plan. `utils/setup-utils.ts`, `utils/oauth.ts` and `utils/wizard-abort.ts` are TUI and CLI flow code that leave in Release C; `utils/analytics.ts` reads the session until C2a. The only agent import left is type-only: `errors/skill-map.ts` takes `InstallSkillResult` from `@agent/types`. `claude-settings.ts` now uses `agent-env-isolation.ts` in shared, and the agent error map lives in `src/agent/error-map.ts`. diff --git a/src/agent/__tests__/agent-env-isolation.test.ts b/src/shared/__tests__/agent-env-isolation.test.ts similarity index 99% rename from src/agent/__tests__/agent-env-isolation.test.ts rename to src/shared/__tests__/agent-env-isolation.test.ts index a615522cd..719e002c1 100644 --- a/src/agent/__tests__/agent-env-isolation.test.ts +++ b/src/shared/__tests__/agent-env-isolation.test.ts @@ -2,7 +2,7 @@ import { sanitizeAgentSubprocessEnv, isBlockedAgentEnvKey, BLOCKED_AGENT_ENV_KEYS, -} from '@agent/agent-env-isolation'; +} from '@shared/agent-env-isolation'; describe('isBlockedAgentEnvKey', () => { it('blocks the direct API key that outranks the gateway auth token', () => { diff --git a/src/agent/agent-env-isolation.ts b/src/shared/agent-env-isolation.ts similarity index 100% rename from src/agent/agent-env-isolation.ts rename to src/shared/agent-env-isolation.ts diff --git a/src/shared/claude-settings.ts b/src/shared/claude-settings.ts index 05d697273..43da0b418 100644 --- a/src/shared/claude-settings.ts +++ b/src/shared/claude-settings.ts @@ -12,13 +12,10 @@ import * as fs from 'fs'; import * as os from 'os'; import { analytics } from '@utils/analytics'; import { registerCleanup } from '@utils/wizard-abort'; -// Leaf module on purpose: shared analytics imports the session, which this -// file feeds, so the agent entry would form a module cycle here. -// eslint-disable-next-line @typescript-eslint/no-restricted-imports -- B1: shared stops feeding the session import { BLOCKED_AGENT_ENV_KEYS, BLOCKED_AGENT_ENV_PATTERNS, -} from '@agent/agent-env-isolation'; +} from './agent-env-isolation'; /** The file names Claude Code accepts for project settings, in priority order. */ const SETTINGS_FILENAMES = ['settings.json', 'settings'] as const; diff --git a/src/shared/errors/index.ts b/src/shared/errors/index.ts index 67178ff72..c617753c7 100644 --- a/src/shared/errors/index.ts +++ b/src/shared/errors/index.ts @@ -8,7 +8,6 @@ export { ERROR_CATALOG } from './catalog'; export { WizardError } from './wizard-error'; export type { ErrorCatalogEntry, ErrorGroup, RetryAdvice } from './types'; export { classifyAuthFailure, type AuthFailureInput } from './auth'; -export { AGENT_ERROR_CODE } from './agent-map'; export { skillErrorCode } from './skill-map'; export { PHW_ERROR_PREFIX, diff --git a/src/shared/utils/__tests__/oauth.test.ts b/src/shared/utils/__tests__/oauth.test.ts index 6466d36b4..a77b35c49 100644 --- a/src/shared/utils/__tests__/oauth.test.ts +++ b/src/shared/utils/__tests__/oauth.test.ts @@ -10,7 +10,7 @@ import { WIZARD_OAUTH_SCOPES, WIZARD_PROVISIONING_SCOPES, } from '@shared/constants'; -import { getOAuthScopesForProgram } from '@lib/oauth/program-scopes'; +import { getOAuthScopesForProgram } from '@programs/oauth/program-scopes'; describe('extractOAuthCode', () => { it('extracts the code from a full callback URL', () => { diff --git a/src/shared/utils/env-scan.ts b/src/shared/utils/env-scan.ts index 866b9826b..0a6741514 100644 --- a/src/shared/utils/env-scan.ts +++ b/src/shared/utils/env-scan.ts @@ -3,7 +3,7 @@ * "which env keys does this project define, and in which file". * * Two surfaces read env keys and they must agree: - * - the warehouse-source detector (`@lib/warehouse-sources/detect`), which + * - the warehouse-source detector (`@programs/warehouse-sources/detect`), which * turns key names into detected sources, and * - the `check_env_keys` wizard tool, which answers the agent's * "is this key already set?" question. diff --git a/src/shared/utils/setup-utils.ts b/src/shared/utils/setup-utils.ts index f8857b555..0b327017d 100644 --- a/src/shared/utils/setup-utils.ts +++ b/src/shared/utils/setup-utils.ts @@ -18,8 +18,8 @@ import { DUMMY_PROJECT_API_KEY, ISSUES_URL } from '@shared/constants'; import { getOAuthScopesForProgram, getProvisioningScopesForProgram, -} from '@lib/oauth/program-scopes'; -import type { ProgramId } from '@lib/programs/program-registry'; +} from '@programs/oauth/program-scopes'; +import type { ProgramId } from '@programs/types'; import { analytics } from './analytics'; import { getUI } from '@ui'; import { HostResolution } from '@shared/host-resolution'; diff --git a/src/ui/__tests__/headless-ui.test.ts b/src/ui/__tests__/headless-ui.test.ts index c147f0569..b28417fd3 100644 --- a/src/ui/__tests__/headless-ui.test.ts +++ b/src/ui/__tests__/headless-ui.test.ts @@ -60,8 +60,12 @@ it.each([ ])('publishes %s tasks through the %s variant', async (mode, variant) => { const { WizardStore } = await import('../tui/store'); const { InkUI } = await import('../tui/ink-ui'); - const { TaskStreamPush } = await import('@lib/task-stream/task-stream-push'); - const { WizardRunSync } = await import('@lib/task-stream/wizard-run-sync'); + const { TaskStreamPush } = await import( + '@programs/task-stream/task-stream-push' + ); + const { WizardRunSync } = await import( + '@programs/task-stream/wizard-run-sync' + ); const { HostResolution } = await import('@shared/host-resolution'); const { RunPhase } = await import('@lib/wizard-session'); const store = new WizardStore(); diff --git a/src/ui/tui/__tests__/audit-counts.test.tsx b/src/ui/tui/__tests__/audit-counts.test.tsx index 318028612..a30042c6e 100644 --- a/src/ui/tui/__tests__/audit-counts.test.tsx +++ b/src/ui/tui/__tests__/audit-counts.test.tsx @@ -1,6 +1,6 @@ import { it, expect, vi, afterEach } from 'vitest'; import { render, cleanup } from 'ink-testing-library'; -import type { AuditCheck, AuditStatus } from '@lib/programs/audit/types'; +import type { AuditCheck, AuditStatus } from '@programs/audit/types'; import { AuditChecksOutroSection } from '../screens/audit/AuditChecksOutroSection'; import { Summary } from '../screens/audit/AuditChecksViewer/Header'; import { WriteReportSlide } from '../screens/audit/slides/writeReport'; diff --git a/src/ui/tui/__tests__/frames.test.tsx b/src/ui/tui/__tests__/frames.test.tsx index 49bfb6062..f8700cf03 100644 --- a/src/ui/tui/__tests__/frames.test.tsx +++ b/src/ui/tui/__tests__/frames.test.tsx @@ -62,22 +62,22 @@ vi.mock('@ui/tui/hooks/useGithubConnection', () => ({ useGithubConnection: () => undefined, fetchLoginUrl: vi.fn().mockResolvedValue(null), })); -vi.mock('@lib/programs/self-driving/detect-agentic', async (actual) => ({ +vi.mock('@programs/self-driving/detect-agentic', async (actual) => ({ ...(await actual>()), detectSelfDrivingIntegrationProjects: vi.fn(pending), })); -vi.mock('@lib/programs/error-tracking/detect-agentic', async (actual) => ({ +vi.mock('@programs/error-tracking/detect-agentic', async (actual) => ({ ...(await actual>()), detectErrorTrackingProjects: vi.fn(pending), })); vi.mock( - '@lib/programs/error-tracking-upload-source-maps/detect-agentic', + '@programs/error-tracking-upload-source-maps/detect-agentic', async (actual) => ({ ...(await actual>()), detectSourceMapsProjects: vi.fn(pending), }), ); -vi.mock('@lib/programs/posthog-doctor/fetch', () => ({ +vi.mock('@programs/posthog-doctor/fetch', () => ({ fetchHealthIssues: vi.fn().mockResolvedValue([ { id: 'issue-1', @@ -113,17 +113,17 @@ import { } from '@lib/wizard-session'; import { HostResolution } from '@shared/host-resolution'; import { Integration } from '@shared/constants'; -import { FRAMEWORK_REGISTRY } from '@lib/registry'; -import type { FrameworkConfig } from '@lib/framework-config'; -import { Program, type ProgramId } from '@lib/programs/program-registry'; +import { FRAMEWORK_REGISTRY } from '@programs/frameworks/registry'; +import type { FrameworkConfig } from '@programs/types'; +import { Program, type ProgramId } from '@programs'; import { WizardReadiness, type WizardReadinessResult, } from '@shared/health-checks/readiness'; import { ServiceHealthStatus } from '@shared/health-checks/types'; -import { SOURCE_MAPS_CONTEXT_KEYS } from '@lib/programs/error-tracking-upload-source-maps/detect'; -import { AUDIT_CHECKS_KEY } from '@lib/programs/audit/types'; -import { AUDIT_SEED_CHECKS } from '@lib/programs/audit/seed'; +import { SOURCE_MAPS_CONTEXT_KEYS } from '@programs/error-tracking-upload-source-maps/detect'; +import { AUDIT_CHECKS_KEY } from '@programs/audit/types'; +import { AUDIT_SEED_CHECKS } from '@programs/audit/seed'; import type { McpInstaller } from '@ui/tui/services/mcp-installer'; import type { McpSuggestedPromptsServices } from '@ui/tui/services/mcp-suggested-prompts-services'; import { diff --git a/src/ui/tui/__tests__/keyboard-equivalence.test.tsx b/src/ui/tui/__tests__/keyboard-equivalence.test.tsx index ac61b3309..413cbca7a 100644 --- a/src/ui/tui/__tests__/keyboard-equivalence.test.tsx +++ b/src/ui/tui/__tests__/keyboard-equivalence.test.tsx @@ -25,11 +25,11 @@ import { type WizardSession, } from '@lib/wizard-session'; import { Integration } from '@shared/constants'; -import { FRAMEWORK_REGISTRY } from '@lib/registry'; +import { FRAMEWORK_REGISTRY } from '@programs/frameworks/registry'; import { HostResolution } from '@shared/host-resolution'; import { WizardReadiness } from '@shared/health-checks/readiness'; -import { SOURCE_MAPS_CONTEXT_KEYS } from '@lib/programs/error-tracking-upload-source-maps/detect'; -import { SELF_DRIVING_INTEGRATE_PATH_KEY } from '@lib/programs/self-driving/detect'; +import { SOURCE_MAPS_CONTEXT_KEYS } from '@programs/error-tracking-upload-source-maps/detect'; +import { SELF_DRIVING_INTEGRATE_PATH_KEY } from '@programs/self-driving/detect'; import { ScreenContainer } from '../primitives/ScreenContainer'; import { createScreens, diff --git a/src/ui/tui/__tests__/programs.test.ts b/src/ui/tui/__tests__/programs.test.ts index 7df542c4a..f09e9fa14 100644 --- a/src/ui/tui/__tests__/programs.test.ts +++ b/src/ui/tui/__tests__/programs.test.ts @@ -1,7 +1,7 @@ import { buildSession, McpOutcome, RunPhase } from '@lib/wizard-session'; import { WizardReadiness } from '@shared/health-checks/readiness'; import { PROGRAM_SEQUENCES, ScreenId } from '@ui/tui/screen-sequences'; -import { Program, type ProgramId } from '@lib/programs/program-registry'; +import { Program, type ProgramId } from '@programs'; function getEntry(program: ProgramId, id: ScreenId) { const entry = PROGRAM_SEQUENCES[program].find( diff --git a/src/ui/tui/__tests__/router.test.ts b/src/ui/tui/__tests__/router.test.ts index 89b94150f..62762bab8 100644 --- a/src/ui/tui/__tests__/router.test.ts +++ b/src/ui/tui/__tests__/router.test.ts @@ -8,8 +8,8 @@ import { HostResolution } from '@shared/host-resolution'; import { WizardReadiness } from '@shared/health-checks/readiness'; import { WizardRouter, ScreenId, Overlay, Program } from '@ui/tui/router'; import { Integration } from '@shared/constants'; -import { FRAMEWORK_REGISTRY } from '@lib/registry'; -import { PROGRAM_REGISTRY } from '@lib/programs/program-registry'; +import { FRAMEWORK_REGISTRY } from '@programs/frameworks/registry'; +import { PROGRAM_REGISTRY } from '@programs'; function baseWizardSession() { return buildSession({}); diff --git a/src/ui/tui/__tests__/store-invariants.test.ts b/src/ui/tui/__tests__/store-invariants.test.ts index 1f22aa244..c002c46e6 100644 --- a/src/ui/tui/__tests__/store-invariants.test.ts +++ b/src/ui/tui/__tests__/store-invariants.test.ts @@ -28,9 +28,9 @@ import { PROGRAM_SEQUENCES } from '@ui/tui/screen-sequences'; import { WizardReadiness } from '@shared/health-checks/readiness'; import { HostResolution } from '@shared/host-resolution'; import { Integration } from '@shared/constants'; -import { FRAMEWORK_REGISTRY } from '@lib/registry'; +import { FRAMEWORK_REGISTRY } from '@programs/frameworks/registry'; import { analytics } from '@utils/analytics'; -import { PROGRAM_REGISTRY } from '@lib/programs/program-registry'; +import { PROGRAM_REGISTRY } from '@programs'; import type { SettingsConflict } from '@shared/claude-settings'; vi.mock('@utils/analytics.js', () => ({ diff --git a/src/ui/tui/__tests__/store.test.ts b/src/ui/tui/__tests__/store.test.ts index c53c49985..eca82cdb5 100644 --- a/src/ui/tui/__tests__/store.test.ts +++ b/src/ui/tui/__tests__/store.test.ts @@ -18,7 +18,7 @@ import { buildSession } from '@lib/wizard-session'; import { HostResolution } from '@shared/host-resolution'; import { Integration } from '@shared/constants'; import { analytics } from '@utils/analytics'; -import { getProgramConfig } from '@lib/programs/program-registry'; +import { getProgramConfig } from '@programs'; vi.mock('@utils/analytics.js', () => ({ analytics: { diff --git a/src/ui/tui/components/LearnCard.tsx b/src/ui/tui/components/LearnCard.tsx index be6dfc65f..8a5b2f265 100644 --- a/src/ui/tui/components/LearnCard.tsx +++ b/src/ui/tui/components/LearnCard.tsx @@ -1,8 +1,8 @@ /** * LearnCard — Generic render shell for an animated content deck. * - * Program-owned. Callers pass the script via `blocks`. The script lives - * under `src/lib/programs//content/`. The shell handles + * Callers pass the script via `blocks`. The script lives under + * `src/ui/tui/decks//`. The shell handles * dimension tracking, status-bar height math, and the `display="none"` * clamp on narrow terminals. */ diff --git a/src/lib/programs/agent-skill/content/index.tsx b/src/ui/tui/decks/agent-skill/index.tsx similarity index 100% rename from src/lib/programs/agent-skill/content/index.tsx rename to src/ui/tui/decks/agent-skill/index.tsx diff --git a/src/lib/programs/error-tracking-upload-source-maps/content/index.tsx b/src/ui/tui/decks/error-tracking-upload-source-maps/index.tsx similarity index 100% rename from src/lib/programs/error-tracking-upload-source-maps/content/index.tsx rename to src/ui/tui/decks/error-tracking-upload-source-maps/index.tsx diff --git a/src/lib/programs/error-tracking/content/index.tsx b/src/ui/tui/decks/error-tracking/index.tsx similarity index 85% rename from src/lib/programs/error-tracking/content/index.tsx rename to src/ui/tui/decks/error-tracking/index.tsx index 815ad34fc..39ebbd83d 100644 --- a/src/lib/programs/error-tracking/content/index.tsx +++ b/src/ui/tui/decks/error-tracking/index.tsx @@ -2,7 +2,7 @@ import type { WizardStore } from '@ui/tui/store'; import type { ContentBlock } from '@ui/tui/primitives/content-types'; -import { buildSourceMapsDeck } from '@lib/programs/error-tracking-upload-source-maps/content/index'; +import { buildSourceMapsDeck } from '@ui/tui/decks/error-tracking-upload-source-maps/index'; export const getContentBlocks = (store?: WizardStore): ContentBlock[] => buildSourceMapsDeck(store, { diff --git a/src/lib/programs/error-tracking/content/tips.ts b/src/ui/tui/decks/error-tracking/tips.ts similarity index 93% rename from src/lib/programs/error-tracking/content/tips.ts rename to src/ui/tui/decks/error-tracking/tips.ts index edf968de4..dba3d8e68 100644 --- a/src/lib/programs/error-tracking/content/tips.ts +++ b/src/ui/tui/decks/error-tracking/tips.ts @@ -1,7 +1,7 @@ /** Sidebar tips for the error-tracking run: product features the learn deck does not cover. */ import type { Tip } from '@ui/tui/components/TipsCard'; -import { REPLAY_VISION_SUPPORTED } from '@lib/programs/replay-vision/index'; +import { REPLAY_VISION_SUPPORTED } from '@programs/replay-vision/index'; export const ERROR_TRACKING_TIPS: Tip[] = [ { diff --git a/src/lib/programs/migration/content/free-tier.tsx b/src/ui/tui/decks/migration/free-tier.tsx similarity index 100% rename from src/lib/programs/migration/content/free-tier.tsx rename to src/ui/tui/decks/migration/free-tier.tsx diff --git a/src/lib/programs/migration/content/index.tsx b/src/ui/tui/decks/migration/index.tsx similarity index 96% rename from src/lib/programs/migration/content/index.tsx rename to src/ui/tui/decks/migration/index.tsx index 152e80e8c..3eaff5927 100644 --- a/src/lib/programs/migration/content/index.tsx +++ b/src/ui/tui/decks/migration/index.tsx @@ -21,9 +21,9 @@ import { Colors } from '@ui/tui/styles'; import { TextRevealMode } from '@ui/tui/primitives/TextBlock'; import type { ContentBlock } from '@ui/tui/primitives/content-types'; import { StatusPeekTrigger } from '@ui/tui/components/StatusPeekTrigger'; -import { PRODUCT_SUITE_BLOCK } from '@lib/programs/posthog-integration/content/product-suite'; -import { LINE_CHART_BLOCK } from '@lib/programs/posthog-integration/content/line-chart'; -import { FUNNEL_BLOCK } from '@lib/programs/posthog-integration/content/funnel'; +import { PRODUCT_SUITE_BLOCK } from '@ui/tui/decks/posthog-integration/product-suite'; +import { LINE_CHART_BLOCK } from '@ui/tui/decks/posthog-integration/line-chart'; +import { FUNNEL_BLOCK } from '@ui/tui/decks/posthog-integration/funnel'; import { VENDOR_STACK_BLOCK } from './vendor-stack.js'; import { FREE_TIER_BLOCK } from './free-tier.js'; import { PRICING_STRUCTURE_BLOCK } from './pricing-structure.js'; diff --git a/src/lib/programs/migration/content/pricing-structure.tsx b/src/ui/tui/decks/migration/pricing-structure.tsx similarity index 100% rename from src/lib/programs/migration/content/pricing-structure.tsx rename to src/ui/tui/decks/migration/pricing-structure.tsx diff --git a/src/lib/programs/migration/content/vendor-stack.tsx b/src/ui/tui/decks/migration/vendor-stack.tsx similarity index 100% rename from src/lib/programs/migration/content/vendor-stack.tsx rename to src/ui/tui/decks/migration/vendor-stack.tsx diff --git a/src/lib/programs/posthog-integration/content/data-flow.tsx b/src/ui/tui/decks/posthog-integration/data-flow.tsx similarity index 100% rename from src/lib/programs/posthog-integration/content/data-flow.tsx rename to src/ui/tui/decks/posthog-integration/data-flow.tsx diff --git a/src/lib/programs/posthog-integration/content/funnel.tsx b/src/ui/tui/decks/posthog-integration/funnel.tsx similarity index 100% rename from src/lib/programs/posthog-integration/content/funnel.tsx rename to src/ui/tui/decks/posthog-integration/funnel.tsx diff --git a/src/lib/programs/posthog-integration/content/index.tsx b/src/ui/tui/decks/posthog-integration/index.tsx similarity index 100% rename from src/lib/programs/posthog-integration/content/index.tsx rename to src/ui/tui/decks/posthog-integration/index.tsx diff --git a/src/lib/programs/posthog-integration/content/line-chart.tsx b/src/ui/tui/decks/posthog-integration/line-chart.tsx similarity index 100% rename from src/lib/programs/posthog-integration/content/line-chart.tsx rename to src/ui/tui/decks/posthog-integration/line-chart.tsx diff --git a/src/lib/programs/posthog-integration/content/product-suite.tsx b/src/ui/tui/decks/posthog-integration/product-suite.tsx similarity index 100% rename from src/lib/programs/posthog-integration/content/product-suite.tsx rename to src/ui/tui/decks/posthog-integration/product-suite.tsx diff --git a/src/lib/programs/revenue-analytics/content/index.tsx b/src/ui/tui/decks/revenue-analytics/index.tsx similarity index 74% rename from src/lib/programs/revenue-analytics/content/index.tsx rename to src/ui/tui/decks/revenue-analytics/index.tsx index 1abb4ce84..974ebc431 100644 --- a/src/lib/programs/revenue-analytics/content/index.tsx +++ b/src/ui/tui/decks/revenue-analytics/index.tsx @@ -4,4 +4,4 @@ * revenue narrative grows its own diagrams or talking points. */ -export { getContentBlocks } from '@lib/programs/agent-skill/content/index'; +export { getContentBlocks } from '@ui/tui/decks/agent-skill/index'; diff --git a/src/lib/programs/self-driving/content/index.tsx b/src/ui/tui/decks/self-driving/index.tsx similarity index 100% rename from src/lib/programs/self-driving/content/index.tsx rename to src/ui/tui/decks/self-driving/index.tsx diff --git a/src/lib/programs/self-driving/content/pipeline-diagram.tsx b/src/ui/tui/decks/self-driving/pipeline-diagram.tsx similarity index 100% rename from src/lib/programs/self-driving/content/pipeline-diagram.tsx rename to src/ui/tui/decks/self-driving/pipeline-diagram.tsx diff --git a/src/lib/programs/self-driving/content/pricing.ts b/src/ui/tui/decks/self-driving/pricing.ts similarity index 100% rename from src/lib/programs/self-driving/content/pricing.ts rename to src/ui/tui/decks/self-driving/pricing.ts diff --git a/src/lib/programs/self-driving/content/tips.ts b/src/ui/tui/decks/self-driving/tips.ts similarity index 100% rename from src/lib/programs/self-driving/content/tips.ts rename to src/ui/tui/decks/self-driving/tips.ts diff --git a/src/lib/programs/warehouse-source/content/index.tsx b/src/ui/tui/decks/warehouse-source/index.tsx similarity index 73% rename from src/lib/programs/warehouse-source/content/index.tsx rename to src/ui/tui/decks/warehouse-source/index.tsx index 4be0eab20..0f364bf00 100644 --- a/src/lib/programs/warehouse-source/content/index.tsx +++ b/src/ui/tui/decks/warehouse-source/index.tsx @@ -4,4 +4,4 @@ * narrative grows its own diagrams or talking points. */ -export { getContentBlocks } from '@lib/programs/agent-skill/content/index'; +export { getContentBlocks } from '@ui/tui/decks/agent-skill/index'; diff --git a/src/ui/tui/playground/demos/AuditChecksDemo.tsx b/src/ui/tui/playground/demos/AuditChecksDemo.tsx index 720498694..fab8e01fb 100644 --- a/src/ui/tui/playground/demos/AuditChecksDemo.tsx +++ b/src/ui/tui/playground/demos/AuditChecksDemo.tsx @@ -5,7 +5,7 @@ */ import { Box } from 'ink'; -import type { AuditCheck } from '@lib/programs/audit/types'; +import type { AuditCheck } from '@programs/audit/types'; import { AuditChecksViewer } from '@ui/tui/screens/audit/AuditChecksViewer/AuditChecksViewer'; const MOCK_CHECKS: AuditCheck[] = [ diff --git a/src/ui/tui/playground/demos/DoctorReportDemo.tsx b/src/ui/tui/playground/demos/DoctorReportDemo.tsx index 3dcf61a77..9a7adc6a0 100644 --- a/src/ui/tui/playground/demos/DoctorReportDemo.tsx +++ b/src/ui/tui/playground/demos/DoctorReportDemo.tsx @@ -1,7 +1,7 @@ import { Box, Text } from 'ink'; import { Colors, Icons } from '@ui/tui/styles'; import { IssueTable } from '@ui/tui/screens/doctor/IssueTable'; -import type { HealthIssue } from '@lib/programs/posthog-doctor/index'; +import type { HealthIssue } from '@programs/posthog-doctor/index'; const NOW = '2026-04-27T15:00:00Z'; diff --git a/src/ui/tui/playground/demos/LearnDeckDemo.tsx b/src/ui/tui/playground/demos/LearnDeckDemo.tsx index a38e3ecf3..b94b38796 100644 --- a/src/ui/tui/playground/demos/LearnDeckDemo.tsx +++ b/src/ui/tui/playground/demos/LearnDeckDemo.tsx @@ -28,7 +28,7 @@ import { import type { ContentBlock, ProgressItem } from '@ui/tui/primitives/index'; import { Colors } from '@ui/tui/styles'; import type { WizardStore } from '@ui/tui/store'; -import { PROGRAM_REGISTRY } from '@lib/programs/program-registry'; +import { PROGRAM_REGISTRY } from '@programs'; import { AUDIT_AREA_SLIDES } from '@ui/tui/screens/audit/slides/index'; import type { AreaSlide } from '@ui/tui/screens/audit/slides/shared'; diff --git a/src/ui/tui/playground/demos/RunScreenDemo.tsx b/src/ui/tui/playground/demos/RunScreenDemo.tsx index d1e34c728..60a92516f 100644 --- a/src/ui/tui/playground/demos/RunScreenDemo.tsx +++ b/src/ui/tui/playground/demos/RunScreenDemo.tsx @@ -35,8 +35,8 @@ import type { ProgressItem, TabDefinition } from '@ui/tui/primitives/index'; import { LearnCard } from '@ui/tui/components/LearnCard'; import { TipsCard } from '@ui/tui/components/TipsCard'; import { VisualizerTab } from '@ui/tui/components/PhaseVisuals'; -import { getProgramConfig } from '@lib/programs/program-registry'; -import { getContentBlocks as getSkillContentBlocks } from '@lib/programs/agent-skill/content/index'; +import { getProgramConfig } from '@programs'; +import { getContentBlocks as getSkillContentBlocks } from '@ui/tui/decks/agent-skill/index'; import { Colors } from '@ui/tui/styles'; import { WIZARD_LOG_FILE } from '@utils/paths'; diff --git a/src/ui/tui/router.ts b/src/ui/tui/router.ts index 8c2dc9836..7bea7c35c 100644 --- a/src/ui/tui/router.ts +++ b/src/ui/tui/router.ts @@ -14,7 +14,7 @@ import { RunPhase, type WizardSession } from '@lib/wizard-session'; import { isRunFailure } from '@ui/mint-failure'; -import { Program, type ProgramId } from '@lib/programs/program-registry'; +import { Program, type ProgramId } from '@programs'; import { PROGRAM_SEQUENCES, MINT_HANDOFF_SEQUENCE, diff --git a/src/ui/tui/screen-registry.tsx b/src/ui/tui/screen-registry.tsx index 93e7dbdd3..c3b7d9e37 100644 --- a/src/ui/tui/screen-registry.tsx +++ b/src/ui/tui/screen-registry.tsx @@ -55,7 +55,7 @@ import { MintFailureScreen } from './screens/MintFailureScreen.js'; import type { MintFailureServices } from './screens/MintFailureScreen.js'; import { openCodingAgent } from './services/coding-agent-launcher.js'; import { writeWizardSpellbook } from '@lib/wizard-spellbook'; -import { getProgramConfig } from '@lib/programs/program-registry'; +import { getProgramConfig } from '@programs'; import { ExitScreen } from './screens/ExitScreen.js'; import { AuthErrorScreen } from './screens/AuthErrorScreen.js'; import { SessionTimeoutScreen } from './screens/SessionTimeoutScreen.js'; diff --git a/src/ui/tui/screen-sequences.ts b/src/ui/tui/screen-sequences.ts index 590468495..1ee869245 100644 --- a/src/ui/tui/screen-sequences.ts +++ b/src/ui/tui/screen-sequences.ts @@ -7,12 +7,9 @@ */ import type { WizardSession } from '@lib/wizard-session'; -import { - PROGRAM_REGISTRY, - type ProgramId, -} from '@lib/programs/program-registry'; -import { createProgramSequence } from '@lib/programs/program-step'; -import { withAiOptInGate } from '@lib/programs/ai-opt-in-gate'; +import { PROGRAM_REGISTRY, type ProgramId } from '@programs'; +import { createProgramSequence } from '@programs/program-step'; +import { withAiOptInGate } from '@programs/ai-opt-in-gate'; /** Screens that participate in linear programs. */ export enum ScreenId { diff --git a/src/ui/tui/screens/ErrorTrackingDetectScreen.tsx b/src/ui/tui/screens/ErrorTrackingDetectScreen.tsx index 9dd79815a..4d2c3eaa9 100644 --- a/src/ui/tui/screens/ErrorTrackingDetectScreen.tsx +++ b/src/ui/tui/screens/ErrorTrackingDetectScreen.tsx @@ -9,13 +9,13 @@ import { useEffect, useRef, useState, useSyncExternalStore } from 'react'; import type { WizardStore } from '@ui/tui/store'; import { LoadingBox, PickerMenu } from '@ui/tui/primitives/index'; import { Colors, Icons } from '@ui/tui/styles'; -import { FRAMEWORK_REGISTRY } from '@lib/registry'; +import { FRAMEWORK_REGISTRY } from '@programs/frameworks/registry'; import { detectErrorTrackingProjects, ERROR_TRACKING_PROJECT_PATH_KEY, type ErrorTrackingDetectionReport, type ErrorTrackingProject, -} from '@lib/programs/error-tracking/detect-agentic'; +} from '@programs/error-tracking/detect-agentic'; interface ErrorTrackingDetectScreenProps { store: WizardStore; diff --git a/src/ui/tui/screens/McpSuggestedPromptsScreen.tsx b/src/ui/tui/screens/McpSuggestedPromptsScreen.tsx index c8d7ff9d7..1ebdddb0f 100644 --- a/src/ui/tui/screens/McpSuggestedPromptsScreen.tsx +++ b/src/ui/tui/screens/McpSuggestedPromptsScreen.tsx @@ -43,7 +43,7 @@ import { useEffect, useMemo, useRef, useState } from 'react'; import { useSyncExternalStore } from 'react'; import type { WizardStore } from '@ui/tui/store'; -import { Program } from '@lib/programs/program-registry'; +import { Program } from '@programs'; import { Colors, Icons } from '@ui/tui/styles'; import { useKeyBindings, KeyMatch } from '@ui/tui/hooks/useKeyBindings'; import { diff --git a/src/ui/tui/screens/PostHogIntegrationIntroScreen.tsx b/src/ui/tui/screens/PostHogIntegrationIntroScreen.tsx index e4331f473..c65cca609 100644 --- a/src/ui/tui/screens/PostHogIntegrationIntroScreen.tsx +++ b/src/ui/tui/screens/PostHogIntegrationIntroScreen.tsx @@ -16,7 +16,7 @@ import { Integration } from '@shared/constants'; import { getCommandPath, getLaunchablePrograms, -} from '@lib/programs/program-registry'; +} from '@programs'; import { PickerMenu, LoadingBox, @@ -102,12 +102,14 @@ const FrameworkPicker = ({ options={options} onSelect={(value) => { const integration = Array.isArray(value) ? value[0] : value; - void import('@lib/registry').then(({ FRAMEWORK_REGISTRY }) => { - const config = FRAMEWORK_REGISTRY[integration]; - store.setFrameworkConfig(integration, config); - store.setDetectedFramework(config.metadata.name); - onComplete?.(); - }); + void import('@programs/frameworks/registry').then( + ({ FRAMEWORK_REGISTRY }) => { + const config = FRAMEWORK_REGISTRY[integration]; + store.setFrameworkConfig(integration, config); + store.setDetectedFramework(config.metadata.name); + onComplete?.(); + }, + ); }} /> ); diff --git a/src/ui/tui/screens/RevenueIntroScreen.tsx b/src/ui/tui/screens/RevenueIntroScreen.tsx index 3d791dd3b..73e4f7ff0 100644 --- a/src/ui/tui/screens/RevenueIntroScreen.tsx +++ b/src/ui/tui/screens/RevenueIntroScreen.tsx @@ -18,7 +18,7 @@ import { POSTHOG_SDKS, STRIPE_SDKS, type RevenueDetectError, -} from '@lib/programs/revenue-analytics/index'; +} from '@programs/revenue-analytics/index'; interface RevenueIntroScreenProps { store: WizardStore; diff --git a/src/ui/tui/screens/RunScreen.tsx b/src/ui/tui/screens/RunScreen.tsx index e5cfe1ce2..d7bcf02bf 100644 --- a/src/ui/tui/screens/RunScreen.tsx +++ b/src/ui/tui/screens/RunScreen.tsx @@ -23,8 +23,8 @@ import { VisualizerTab } from '@ui/tui/components/PhaseVisuals'; import { TipsCard } from '@ui/tui/components/TipsCard'; import { useStdoutDimensions } from '@ui/tui/hooks/useStdoutDimensions'; -import { getProgramConfig } from '@lib/programs/program-registry'; -import { getContentBlocks as getSkillContentBlocks } from '@lib/programs/agent-skill/content/index'; +import { getProgramConfig } from '@programs'; +import { getContentBlocks as getSkillContentBlocks } from '@ui/tui/decks/agent-skill/index'; import { WIZARD_LOG_FILE } from '@utils/paths'; diff --git a/src/ui/tui/screens/SelfDrivingGitHubScreen.tsx b/src/ui/tui/screens/SelfDrivingGitHubScreen.tsx index d038f47e2..7bcc46e6c 100644 --- a/src/ui/tui/screens/SelfDrivingGitHubScreen.tsx +++ b/src/ui/tui/screens/SelfDrivingGitHubScreen.tsx @@ -31,7 +31,7 @@ import { OutroKind } from '@lib/wizard-session'; import { GITHUB_REQUIRED_BODY, GITHUB_REQUIRED_MESSAGE, -} from '@lib/programs/self-driving/detect'; +} from '@programs/self-driving/detect'; import { analytics } from '@utils/analytics'; import { openTrackedLink } from '@utils/links'; import { getIntegrationAuthorizeUrl } from '@utils/urls'; diff --git a/src/ui/tui/screens/SelfDrivingHandoffScreen.tsx b/src/ui/tui/screens/SelfDrivingHandoffScreen.tsx index e3565bee6..06ba2c954 100644 --- a/src/ui/tui/screens/SelfDrivingHandoffScreen.tsx +++ b/src/ui/tui/screens/SelfDrivingHandoffScreen.tsx @@ -12,8 +12,8 @@ import { useSyncExternalStore } from 'react'; import type { WizardStore } from '@ui/tui/store'; import { PickerMenu } from '@ui/tui/primitives/index'; import { Colors } from '@ui/tui/styles'; -import { SETUP_REPORT_FILE } from '@lib/programs/posthog-integration/index'; -import { SELF_DRIVING_INTEGRATE_PATH_KEY } from '@lib/programs/self-driving/detect'; +import { SETUP_REPORT_FILE } from '@programs/posthog-integration/index'; +import { SELF_DRIVING_INTEGRATE_PATH_KEY } from '@programs/self-driving/detect'; interface SelfDrivingHandoffScreenProps { store: WizardStore; diff --git a/src/ui/tui/screens/SelfDrivingIntegrationDetectScreen.tsx b/src/ui/tui/screens/SelfDrivingIntegrationDetectScreen.tsx index 110dbc8f0..7c42ccd5f 100644 --- a/src/ui/tui/screens/SelfDrivingIntegrationDetectScreen.tsx +++ b/src/ui/tui/screens/SelfDrivingIntegrationDetectScreen.tsx @@ -15,13 +15,13 @@ import type { WizardStore } from '@ui/tui/store'; import { LoadingBox, PickerMenu } from '@ui/tui/primitives/index'; import { Colors, Icons } from '@ui/tui/styles'; import { Integration } from '@shared/constants'; -import { FRAMEWORK_REGISTRY } from '@lib/registry'; -import { SELF_DRIVING_INTEGRATE_PATH_KEY } from '@lib/programs/self-driving/detect'; +import { FRAMEWORK_REGISTRY } from '@programs/frameworks/registry'; +import { SELF_DRIVING_INTEGRATE_PATH_KEY } from '@programs/self-driving/detect'; import { detectSelfDrivingIntegrationProjects, type IntegrationProject, type IntegrationDetectionReport, -} from '@lib/programs/self-driving/detect-agentic'; +} from '@programs/self-driving/detect-agentic'; interface SelfDrivingIntegrationDetectScreenProps { store: WizardStore; diff --git a/src/ui/tui/screens/SelfDrivingIntroScreen.tsx b/src/ui/tui/screens/SelfDrivingIntroScreen.tsx index 94169aa01..99ed43f9d 100644 --- a/src/ui/tui/screens/SelfDrivingIntroScreen.tsx +++ b/src/ui/tui/screens/SelfDrivingIntroScreen.tsx @@ -18,8 +18,8 @@ import { NO_DEFAULT_LIMIT, PRICING_LONG, PRICING_SHORT, -} from '@lib/programs/self-driving/content/pricing.js'; -import type { SelfDrivingDetectError } from '@lib/programs/self-driving/index'; +} from '@ui/tui/decks/self-driving/pricing.js'; +import type { SelfDrivingDetectError } from '@programs/self-driving/index'; interface SelfDrivingIntroScreenProps { store: WizardStore; diff --git a/src/ui/tui/screens/SetupScreen.tsx b/src/ui/tui/screens/SetupScreen.tsx index d6cce4502..959f82f91 100644 --- a/src/ui/tui/screens/SetupScreen.tsx +++ b/src/ui/tui/screens/SetupScreen.tsx @@ -12,7 +12,7 @@ import { useSyncExternalStore } from 'react'; import type { WizardStore } from '@ui/tui/store'; import { PickerMenu } from '@ui/tui/primitives/index'; import { Colors } from '@ui/tui/styles'; -import type { SetupQuestion } from '@lib/framework-config'; +import type { SetupQuestion } from '@programs/types'; interface SetupScreenProps { store: WizardStore; diff --git a/src/ui/tui/screens/SlackConnectScreen.tsx b/src/ui/tui/screens/SlackConnectScreen.tsx index ecc1958ba..423e551db 100644 --- a/src/ui/tui/screens/SlackConnectScreen.tsx +++ b/src/ui/tui/screens/SlackConnectScreen.tsx @@ -32,7 +32,7 @@ import { PickerMenu, LoadingBox } from '@ui/tui/primitives/index'; import { useKeyBindings, KeyMatch } from '@ui/tui/hooks/useKeyBindings'; import { getSlackAppCard } from '@lib/mcp-role-prompts'; import { fetchSlackConnected } from '@shared/api'; -import { Program } from '@lib/programs/program-registry'; +import { Program } from '@programs'; import { getOrAskForProjectData } from '@utils/setup-utils'; import { analytics } from '@utils/analytics'; import { logToFile } from '@utils/debug'; diff --git a/src/ui/tui/screens/SourceMapsDetectScreen.tsx b/src/ui/tui/screens/SourceMapsDetectScreen.tsx index 699433e5f..645cd61cd 100644 --- a/src/ui/tui/screens/SourceMapsDetectScreen.tsx +++ b/src/ui/tui/screens/SourceMapsDetectScreen.tsx @@ -16,12 +16,12 @@ import { SOURCE_MAPS_CONTEXT_KEYS, VARIANT_DISPLAY_NAME, MANUAL_SDK_VARIANTS, -} from '@lib/programs/error-tracking-upload-source-maps/index'; +} from '@programs/error-tracking-upload-source-maps/index'; import { detectSourceMapsProjects, type DetectedProject, type DetectionReport, -} from '@lib/programs/error-tracking-upload-source-maps/detect-agentic'; +} from '@programs/error-tracking-upload-source-maps/detect-agentic'; interface SourceMapsDetectScreenProps { store: WizardStore; diff --git a/src/ui/tui/screens/WarehouseIntroScreen.tsx b/src/ui/tui/screens/WarehouseIntroScreen.tsx index 8a507c5c3..94205ef98 100644 --- a/src/ui/tui/screens/WarehouseIntroScreen.tsx +++ b/src/ui/tui/screens/WarehouseIntroScreen.tsx @@ -18,7 +18,7 @@ import { IntroScreenLayout } from './IntroScreenLayout.js'; import { getDetectedWarehouseSources, type WarehouseDetectError, -} from '@lib/programs/warehouse-source/index'; +} from '@programs/warehouse-source/index'; interface WarehouseIntroScreenProps { store: WizardStore; diff --git a/src/ui/tui/screens/audit/AuditAreaPane.tsx b/src/ui/tui/screens/audit/AuditAreaPane.tsx index 2ceb1e512..443d95c1e 100644 --- a/src/ui/tui/screens/audit/AuditAreaPane.tsx +++ b/src/ui/tui/screens/audit/AuditAreaPane.tsx @@ -17,7 +17,7 @@ import { Fragment } from 'react'; import { Box, Text, useInput } from 'ink'; import { spawn } from 'node:child_process'; import { Colors } from '@ui/tui/styles'; -import { type AuditCheck } from '@lib/programs/audit/types'; +import { type AuditCheck } from '@programs/audit/types'; import { AUDIT_AREA_SLIDES, type AreaSlide } from './slides/index.js'; // ── Helpers ────────────────────────────────────────────────────────── diff --git a/src/ui/tui/screens/audit/AuditChecksOutroSection.tsx b/src/ui/tui/screens/audit/AuditChecksOutroSection.tsx index 64013d49b..d9178db01 100644 --- a/src/ui/tui/screens/audit/AuditChecksOutroSection.tsx +++ b/src/ui/tui/screens/audit/AuditChecksOutroSection.tsx @@ -2,7 +2,7 @@ import { Box, Text } from 'ink'; import { AUDIT_SEVERITY_STYLE, type AuditCheck, -} from '@lib/programs/audit/types'; +} from '@programs/audit/types'; import { relativeToInstallDir } from '@utils/paths'; import { countNoun } from '@utils/count-noun'; diff --git a/src/ui/tui/screens/audit/AuditChecksViewer/AuditChecksViewer.tsx b/src/ui/tui/screens/audit/AuditChecksViewer/AuditChecksViewer.tsx index 25e887bd8..8c104eb83 100644 --- a/src/ui/tui/screens/audit/AuditChecksViewer/AuditChecksViewer.tsx +++ b/src/ui/tui/screens/audit/AuditChecksViewer/AuditChecksViewer.tsx @@ -23,7 +23,7 @@ import { useKeyBindings, type KeyBinding, } from '@ui/tui/hooks/useKeyBindings'; -import type { AuditCheck } from '@lib/programs/audit/types'; +import type { AuditCheck } from '@programs/audit/types'; import { AreaHeaderRow } from './AreaHeaderRow.js'; import { CheckRow } from './CheckRow.js'; import { DetailRow } from './DetailRow.js'; diff --git a/src/ui/tui/screens/audit/AuditChecksViewer/CheckRow.tsx b/src/ui/tui/screens/audit/AuditChecksViewer/CheckRow.tsx index cb9b4c408..7506a87df 100644 --- a/src/ui/tui/screens/audit/AuditChecksViewer/CheckRow.tsx +++ b/src/ui/tui/screens/audit/AuditChecksViewer/CheckRow.tsx @@ -2,7 +2,7 @@ import { Box, Text } from 'ink'; import { AUDIT_SEVERITY_STYLE, type AuditCheck, -} from '@lib/programs/audit/types'; +} from '@programs/audit/types'; import { truncate, type ViewerLayout } from './layout.js'; interface CheckRowProps { diff --git a/src/ui/tui/screens/audit/AuditChecksViewer/DetailRow.tsx b/src/ui/tui/screens/audit/AuditChecksViewer/DetailRow.tsx index 4b65b0e5d..84ae4304a 100644 --- a/src/ui/tui/screens/audit/AuditChecksViewer/DetailRow.tsx +++ b/src/ui/tui/screens/audit/AuditChecksViewer/DetailRow.tsx @@ -1,5 +1,5 @@ import { Box, Text } from 'ink'; -import type { AuditCheck } from '@lib/programs/audit/types'; +import type { AuditCheck } from '@programs/audit/types'; import type { ViewerLayout } from './layout.js'; interface DetailRowProps { diff --git a/src/ui/tui/screens/audit/AuditChecksViewer/Footer.tsx b/src/ui/tui/screens/audit/AuditChecksViewer/Footer.tsx index dc01e3748..42b1bd6d3 100644 --- a/src/ui/tui/screens/audit/AuditChecksViewer/Footer.tsx +++ b/src/ui/tui/screens/audit/AuditChecksViewer/Footer.tsx @@ -1,6 +1,6 @@ import { Legend } from './Legend.js'; import { Summary } from './Header.js'; -import type { AuditStatus } from '@lib/programs/audit/types'; +import type { AuditStatus } from '@programs/audit/types'; interface FooterProps { total: number; diff --git a/src/ui/tui/screens/audit/AuditChecksViewer/Header.tsx b/src/ui/tui/screens/audit/AuditChecksViewer/Header.tsx index e44fb8f8b..c170459f0 100644 --- a/src/ui/tui/screens/audit/AuditChecksViewer/Header.tsx +++ b/src/ui/tui/screens/audit/AuditChecksViewer/Header.tsx @@ -1,5 +1,5 @@ import { Box, Text } from 'ink'; -import type { AuditCheck, AuditStatus } from '@lib/programs/audit/types'; +import type { AuditCheck, AuditStatus } from '@programs/audit/types'; import { countNoun } from '@utils/count-noun'; import type { ViewerLayout } from './layout.js'; diff --git a/src/ui/tui/screens/audit/AuditChecksViewer/sort.ts b/src/ui/tui/screens/audit/AuditChecksViewer/sort.ts index 05406bd68..2d33264db 100644 --- a/src/ui/tui/screens/audit/AuditChecksViewer/sort.ts +++ b/src/ui/tui/screens/audit/AuditChecksViewer/sort.ts @@ -1,4 +1,4 @@ -import type { AuditCheck, AuditStatus } from '@lib/programs/audit/types'; +import type { AuditCheck, AuditStatus } from '@programs/audit/types'; const STATUS_ORDER: Record = { error: 0, diff --git a/src/ui/tui/screens/audit/AuditOutroScreen.tsx b/src/ui/tui/screens/audit/AuditOutroScreen.tsx index fd308d9f9..227af7968 100644 --- a/src/ui/tui/screens/audit/AuditOutroScreen.tsx +++ b/src/ui/tui/screens/audit/AuditOutroScreen.tsx @@ -11,7 +11,7 @@ import { useSyncExternalStore } from 'react'; import type { WizardStore } from '@ui/tui/store'; import { OutroKind } from '@lib/wizard-session'; import { Colors } from '@ui/tui/styles'; -import { getAuditChecks } from '@lib/programs/audit/types'; +import { getAuditChecks } from '@programs/audit/types'; import { AuditChecksOutroSection } from './AuditChecksOutroSection.js'; import { useDismissOnAnyKey } from '@ui/tui/hooks/useDismissOnAnyKey'; diff --git a/src/ui/tui/screens/audit/AuditRunScreen.tsx b/src/ui/tui/screens/audit/AuditRunScreen.tsx index b9cbc4f87..1ef1c0a46 100644 --- a/src/ui/tui/screens/audit/AuditRunScreen.tsx +++ b/src/ui/tui/screens/audit/AuditRunScreen.tsx @@ -13,8 +13,8 @@ import { AuditAreaPane } from './AuditAreaPane.js'; import { AUDIT_AREA_SLIDES } from './slides/index.js'; import { EVENTS_AUDIT_AREA_SLIDES } from './slides/events-audit/index.js'; import { PendingChecksList } from './PendingChecksList.js'; -import { AUDIT_REPORT_FILE, getAuditChecks } from '@lib/programs/audit/types'; -import { getProgramConfig } from '@lib/programs/program-registry'; +import { AUDIT_REPORT_FILE, getAuditChecks } from '@programs/audit/types'; +import { getProgramConfig } from '@programs'; import { WIZARD_LOG_FILE } from '@utils/paths'; interface AuditRunScreenProps { diff --git a/src/ui/tui/screens/audit/PendingChecksList.tsx b/src/ui/tui/screens/audit/PendingChecksList.tsx index 530dacafc..c6eb4f6f7 100644 --- a/src/ui/tui/screens/audit/PendingChecksList.tsx +++ b/src/ui/tui/screens/audit/PendingChecksList.tsx @@ -3,7 +3,7 @@ import { Spinner } from '@inkjs/ui'; import { AUDIT_SEVERITY_STYLE, type AuditCheck, -} from '@lib/programs/audit/types'; +} from '@programs/audit/types'; import { Colors, Icons } from '@ui/tui/styles'; import { LoadingBox } from '@ui/tui/primitives/index'; import { useStdoutDimensions } from '@ui/tui/hooks/useStdoutDimensions'; diff --git a/src/ui/tui/screens/doctor/DoctorReportScreen.tsx b/src/ui/tui/screens/doctor/DoctorReportScreen.tsx index 3e44e6d45..e090bd378 100644 --- a/src/ui/tui/screens/doctor/DoctorReportScreen.tsx +++ b/src/ui/tui/screens/doctor/DoctorReportScreen.tsx @@ -6,7 +6,7 @@ import { Colors, Icons } from '@ui/tui/styles'; import { fetchHealthIssues, type HealthIssue, -} from '@lib/programs/posthog-doctor/index'; +} from '@programs/posthog-doctor/index'; import { OutroKind } from '@lib/wizard-session'; import { ApiError } from '@shared/api'; import { POSTHOG_DOCS_URL } from '@shared/constants'; diff --git a/src/ui/tui/screens/doctor/IssueTable.tsx b/src/ui/tui/screens/doctor/IssueTable.tsx index d565f8005..f487a2ef6 100644 --- a/src/ui/tui/screens/doctor/IssueTable.tsx +++ b/src/ui/tui/screens/doctor/IssueTable.tsx @@ -5,7 +5,7 @@ import { getKindMeta, type HealthIssue, type HealthIssueSeverity, -} from '@lib/programs/posthog-doctor/index'; +} from '@programs/posthog-doctor/index'; export const SEVERITY_ORDER: HealthIssueSeverity[] = [ 'critical', diff --git a/src/ui/tui/services/mcp-suggested-prompts-services.ts b/src/ui/tui/services/mcp-suggested-prompts-services.ts index 3a5cbda40..813596516 100644 --- a/src/ui/tui/services/mcp-suggested-prompts-services.ts +++ b/src/ui/tui/services/mcp-suggested-prompts-services.ts @@ -12,7 +12,7 @@ import type { Credentials } from '@lib/wizard-session'; import { getOrAskForProjectData } from '@utils/setup-utils'; -import { Program } from '@lib/programs/program-registry'; +import { Program } from '@programs'; import type { WizardStore } from '@ui/tui/store'; import type { ApiUser } from '@shared/api'; import { @@ -108,7 +108,7 @@ export function createMcpSuggestedPromptsServices( // replays, errors, web analytics, AI Observability, cohorts, persons) plus // annotation read/write. Persistence writes (dashboard, insight, // notebook) come for free from the base set. See - // `src/lib/oauth/program-scopes.ts`. + // `src/programs/oauth/program-scopes.ts`. programId: Program.McpTutorial, }); return { diff --git a/src/ui/tui/store.ts b/src/ui/tui/store.ts index 3318643f3..97573dead 100644 --- a/src/ui/tui/store.ts +++ b/src/ui/tui/store.ts @@ -49,13 +49,10 @@ import { type ProgramId, } from './router.js'; import { analytics, sessionProperties } from '@utils/analytics'; -import type { - StoreInitContext, - ProgramReadyContext, -} from '@lib/programs/program-step'; -import { getProgramConfig } from '@lib/programs/program-registry'; -import { withAiOptInGate } from '@lib/programs/ai-opt-in-gate'; -import { reportWarehouseSourcesDetected } from '@lib/programs/posthog-integration/detect'; +import type { StoreInitContext, ProgramReadyContext } from '@programs/types'; +import { getProgramConfig } from '@programs'; +import { withAiOptInGate } from '@programs/ai-opt-in-gate'; +import { reportWarehouseSourcesDetected } from '@programs/posthog-integration/detect'; import { appendStatus } from '@shared/status-history'; import { IS_DEV } from '@shared/constants'; import { computeTokenCostUsd } from '@shared/token-pricing'; diff --git a/tsconfig.build.json b/tsconfig.build.json index d716e8367..e66f19f33 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -23,14 +23,16 @@ "@agent": ["./src/agent/index.ts"], "@agent/types": ["./src/agent/types.ts"], "@agent/*": ["./src/agent/*"], + "@programs": ["./src/programs/index.ts"], + "@programs/types": ["./src/programs/types.ts"], + "@programs/*": ["./src/programs/*"], "@lib/*": ["./src/lib/*"], "@e2e-harness/*": ["./e2e-harness/*"], "@utils/*": ["./src/shared/utils/*"], "@ui": ["./src/ui/index.ts"], "@ui/*": ["./src/ui/*"], "@steps": ["./src/steps/index.ts"], - "@steps/*": ["./src/steps/*"], - "@frameworks/*": ["./src/frameworks/*"] + "@steps/*": ["./src/steps/*"] } } } diff --git a/vitest.config.ts b/vitest.config.ts index 713b61ac1..16492b363 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -33,6 +33,7 @@ function resolveTsForJs(): Plugin { // alone with `vitest run --project `; `vitest run` runs them all. const TESTS = '__tests__/**/*.{js,jsx,ts,tsx}'; const AGENT_TESTS = [`src/agent/**/${TESTS}`]; +const PROGRAM_TESTS = [`src/programs/**/${TESTS}`]; const TUI_TESTS = [`src/ui/tui/**/${TESTS}`]; const CLI_TESTS = [ `src/commands/**/${TESTS}`, @@ -82,6 +83,9 @@ export default defineConfig({ { find: /^@agent$/, replacement: r('src/agent/index.ts') }, { find: /^@agent\/types$/, replacement: r('src/agent/types.ts') }, { find: /^@agent\/(.*)$/, replacement: `${r('src/agent')}/$1` }, + { find: /^@programs$/, replacement: r('src/programs/index.ts') }, + { find: /^@programs\/types$/, replacement: r('src/programs/types.ts') }, + { find: /^@programs\/(.*)$/, replacement: `${r('src/programs')}/$1` }, // Path aliases — mirror tsconfig `paths`. { find: /^@env$/, replacement: r('src/env.ts') }, { find: /^@lib\/(.*)$/, replacement: `${r('src/lib')}/$1` }, @@ -91,7 +95,6 @@ export default defineConfig({ { find: /^@ui\/(.*)$/, replacement: `${r('src/ui')}/$1` }, { find: /^@steps$/, replacement: r('src/steps/index.ts') }, { find: /^@steps\/(.*)$/, replacement: `${r('src/steps')}/$1` }, - { find: /^@frameworks\/(.*)$/, replacement: `${r('src/frameworks')}/$1` }, ], }, test: { @@ -99,6 +102,7 @@ export default defineConfig({ environment: 'node', projects: [ project('agent', AGENT_TESTS), + project('programs', PROGRAM_TESTS), project('tui', TUI_TESTS), project('cli', CLI_TESTS), project('harness', HARNESS_TESTS), @@ -108,7 +112,13 @@ export default defineConfig({ // The second glob keeps the pre-split behavior: a test file outside // a __tests__ directory still runs, here, rather than nowhere. [`src/**/${TESTS}`, 'src/**/*.{test,spec}.{js,jsx,ts,tsx}'], - [...AGENT_TESTS, ...TUI_TESTS, ...CLI_TESTS, ...ARCH_TESTS], + [ + ...AGENT_TESTS, + ...PROGRAM_TESTS, + ...TUI_TESTS, + ...CLI_TESTS, + ...ARCH_TESTS, + ], ), ], coverage: {