Skip to content

refactor(agent): WIP move agent and shared source trees (A2b) - #1299

Merged
gewenyu99 merged 10 commits into
posthog/functional-a2a-edgesfrom
workbench/wizard-functional-a2b
Sep 23, 2026
Merged

gewenyu99 merged 10 commits into
posthog/functional-a2a-edgesfrom
workbench/wizard-functional-a2b

Conversation

@gewenyu99

@gewenyu99 gewenyu99 commented Sep 22, 2026 •

Copy link
Copy Markdown
Collaborator

Stacked on #1297 (A2a). Second of the two PRs that replace the plan's A2′: A2a cut the agent's outside edges and fenced them, this one moves the files so the fence is a directory. No logic in it, review with git diff -M.

Intent

Isolates the agent behind a defined boundary. The agent runs a program's prompt against a harness and reports back through progress events and asks, so nothing under src/agent/ may reach the UI, the session, detection, the runners or the CLI.

Two things that buys:

  • Code splits into areas. src/agent/ is the agent, src/shared/ is what every area may import, src/lib/ is what's left to sort in B and C. A file's directory says which rules apply to it.
  • True detachment. UI from program, program from agent. Each boundary is one glob in ESLint, the architecture test, CODEOWNERS and the vitest project, so a new import across it fails lint rather than waiting for a reviewer to notice.

Impact

People running the wizard. Nothing changes. No command, flag, prompt or network call moved. The bundle differs only in module paths.

People maintaining it. Two roots are now load bearing.

  • Anything under src/agent/ is fenced the moment it exists. ESLint refuses @ui, every @lib path except @lib/programs/** types, detection, runners, commands, steps, frameworks, setup-utils, oauth and wizardAbort. Its tests run under vitest run --project agent. Team wizard-docs owns it.
  • Anything under src/shared/ is the floor the agent may stand on. A file both the TUI and the agent need goes there, which is why claude-settings.ts, agent-phase.ts and token-pricing.ts left the agent in this PR.
  • @utils/* still resolves, now to src/shared/utils/*. The three alias lines live twice, in tsconfig.build.json and vitest.config.ts, and must match.
  • A new import from src/agent into src/lib needs a known-violations.json entry or a move into src/shared. The custom scanner stays the enforcement mechanism here; standard tooling is deferred to C2, see Enforcement below.

Map

%%{init: {"block": {"padding": 20}}}%%
block-beta
  columns 11
  hostBand["src/lib/runners and src/ui   old, moves in C1"]:11
  runWizard["runWizard / runNonInteractive"]:3 space:1 InkUI["WizardUI"]:7
  adapterBand["src/lib/programs run-agent-legacy   temporary until B1"]:11
  runProgramAgent["runProgramAgent"]:3 space:1 createUiReducer["createUiReducer"]:3 space:1 uiInteraction["uiInteraction"]:3
  agentBand["src/agent   new root, ESLint fenced"]:11
  runAgent["runAgent"]:3 space:8
  runLinearProgram["runLinearProgram"]:3 space:5 askBridge["createAskBridge"]:3
  anthropicBackend["anthropicBackend"]:3 space:1 collector["createProgressCollector"]:3 space:1 wizard_ask["wizard_ask"]:3
  sharedBand["src/shared   new root, imported by every row above"]:11
  sdk["Claude Agent SDK query loop"]:11

  runWizard --> runProgramAgent
  runProgramAgent -- "RunConfig, RunInput, options" --> runAgent
  runAgent --> runLinearProgram
  runLinearProgram --> anthropicBackend
  runLinearProgram --> askBridge
  anthropicBackend --> sdk
  anthropicBackend -- "emit" --> collector
  sdk --> wizard_ask
  wizard_ask --> askBridge
  askBridge --> uiInteraction
  collector -- "onProgress" --> createUiReducer
  createUiReducer --> InkUI
  uiInteraction --> InkUI

  classDef old fill:#f3f4f6,stroke:#6b7280,color:#111827
  classDef temp fill:#fef3c7,stroke:#b45309,color:#78350f
  classDef new fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
  classDef ext fill:#ffffff,stroke:#6b7280,color:#111827,stroke-dasharray:4 3
  classDef oldBand fill:#e5e7eb,stroke:#e5e7eb,color:#374151
  classDef tempBand fill:#fde68a,stroke:#fde68a,color:#78350f
  classDef newBand fill:#bfdbfe,stroke:#bfdbfe,color:#1e3a8a
  class runWizard,InkUI old
  class runProgramAgent,createUiReducer,uiInteraction temp
  class runAgent,runLinearProgram,anthropicBackend,collector,askBridge,wizard_ask new
  class sdk ext
  class hostBand oldBand
  class adapterBand tempBand
  class agentBand,sharedBand newBand
Loading

Left lane is the call down, middle lane is progress back up, right lane is questions back up. Blue is the two new roots this PR creates, grey is untouched, amber is the legacy adapter that dies in B1, dashed is outside the repo. No arrow changed direction. Every node kept its name and lost its src/lib/ prefix.

Blocks

  • runWizard, runNonInteractive (run-wizard.ts, run-non-interactive.ts). Hosts. Own the session and the TUI, call the adapter. Untouched except import lines.
  • runProgramAgent (run-agent-legacy.ts:66). Legacy adapter. Builds RunConfig and RunInput from the session, wires createUiReducer as onProgress and uiInteraction as the answerer, calls runAgent. Only file that imports both @ui and @agent. Dies in B1.
  • createUiReducer, uiInteraction (agent-progress.ts:12, :67). Map progress events to WizardUI calls and asks to the TUI overlay. Untouched.
  • runAgent (runner/index.ts:74). The agent's one public entry. Takes config, input, options, returns RunResult. Never exits the process. Was src/lib/agent/runner/index.ts.
  • runLinearProgram (sequence/linear.ts:30). Picks the harness, builds the ask bridge, runs the prompt once. Was under src/lib/agent.
  • anthropicBackend (harness/anthropic/index.ts:20). Drives the SDK, mounts the MCP tools, emits every message. pi harness sits beside it, same shape.
  • createProgressCollector (progress-collector.ts:25). Folds emit calls into a RunSnapshot and forwards to onProgress.
  • createAskBridge, wizard_ask (ask.ts:18, tools/mcp.ts:117). The model calls the tool, the bridge parks a promise, the answerer resolves it. src/lib/wizard-tools is now src/agent/tools.
  • src/shared. Constants, errors, health checks, utils/*, claude-settings, token-pricing, agent-phase, generated version.ts. Counting @shared/* and @utils/* import lines at head: 176 from the agent, 113 from the UI, 88 from programs. Classified legacy by the architecture test until A3 zeroes its outward edges — 8 of them across 7 files, 3 into src/agent (claude-settings.ts, errors/agent-map.ts, errors/skill-map.ts) and 5 into src/ui (utils/debug.ts, utils/oauth.ts, utils/setup-utils.ts, utils/wizard-abort.ts).

Code

Every renamed file's non-import content is byte-identical to the A2a head, except three comment-only path updates in the last commit: src/shared/constants.ts, src/lib/wizard-session.ts and src/lib/programs/__tests__/mcp-analytics.test.ts. git grep under src/ at head finds no old spelling outside known-violations.json.

Moves.

  • src/lib/agent/** → src/agent/**, minus claude-settings.ts, token-pricing.ts, agent-phase.ts and their tests, which go to src/shared
  • src/lib/middleware/** → src/agent/middleware/**
  • src/lib/wizard-tools/** → src/agent/tools/**
  • yara-hooks, yara-policy, gateway-session, wizard-ask-bridge, safe-tools → src/agent/*.ts
  • src/utils/** → src/shared/utils/** whole. setup-utils.ts and oauth.ts ride along and leave for tui in C1
  • src/lib/errors/**, src/lib/health-checks/** → same names under src/shared
  • constants, api, host-resolution, skill-install, secret-vault, local-dev, version, fetch-retry, auth-session-state, status-history, audit-ledger → src/shared/*.ts
  • Tests follow their subjects into src/agent/__tests__ and src/shared/__tests__

Stays in src/lib until B/C: programs, detection, runners, registry, task-stream, warehouse-sources, framework-config, wizard-session, wizard-spellbook, mcp-*, headless-mode, file-watcher, cloudflare-detection, oauth/program-scopes.ts.

Config, read these.

Everything else in the diff is an import line following a move, or a doc path.

Review by commit. Five commits, move only. Each leaves typecheck, lint and the full suite green.

  • 2b8c672d src/utils → src/shared/utils, @utils/* retargeted. 50 renames, 23 files touched.
  • 8210a647 errors, health-checks and the shared singles → src/shared, @shared/* alias, version script, .gitignore. 38 renames, 205 files of import lines.
  • 0de7b0b1 claude-settings, token-pricing, agent-phase and tests → src/shared. 5 renames, 20 files of import lines.
  • 719737a0 agent tree, middleware, tools, 5 singles, 9 tests → src/agent, @agent/* alias, vitest globs, fence, arch rules, known-violations.json. 132 renames, 59 files of import lines.
  • 273cd0ea docs and comment paths, 20 files, no prose change.

Enforcement

A sixth commit was written on this branch and has been reverted: it swapped the repo's custom import scanner for eslint-plugin-import boundary configuration, added src/agent/index.ts and types.ts entry modules, and banned deep agent imports outside tests.

The boundary matrix cannot be configured once while four of its seven layers do not exist yet. B1 and C1 would each rewrite it, so the tooling choice is deferred to C2, where it is made once against the final tree.

What that means for this PR:

  • The custom scanner stays: import-boundaries.test.ts, 394 lines, and known-violations.json, 70 tracked violations. Both pass.
  • No new dependency. A stale node_modules/eslint-plugin-import symlink into a temp directory was removed; package.json is unchanged.
  • The reverted work is preserved at workbench/wizard-functional-evidence/a2b-commit6-eslint-enforcement.patch — 84 files, +1253/−613, verified to reapply.

Evidence on the head, re-run at 273cd0ea after the revert.

  • pnpm typecheck clean.
  • pnpm test:arch 4 tests pass.
  • pnpm lint 0 errors, 482 pre-existing warnings.

Next: A3 zeroes the 8 src/shared edges and reclassifies it. B1 removes the amber row.


Created with PostHog Desktop

Generated-By: PostHog Desktop
Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
Generated-By: PostHog Desktop
Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
Generated-By: PostHog Desktop
Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
Generated-By: PostHog Desktop
Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
Generated-By: PostHog Desktop
Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
@github-actions

Copy link
Copy Markdown

🧙 Wizard CI

Run the Wizard CI and test your changes against wizard-workbench example apps by replying with a GitHub comment using one of the following commands:

Test all apps:

  • /wizard-ci all

Test all apps in a directory:

  • /wizard-ci ai-observability
  • /wizard-ci basic-integration
  • /wizard-ci mcp-analytics
  • /wizard-ci replay-vision
  • /wizard-ci revenue
  • /wizard-ci self-driving
  • /wizard-ci warehouse
  • /wizard-ci warehouse-seeded

Test an individual app:

  • /wizard-ci ai-observability/anthropic
  • /wizard-ci ai-observability/google-adk
  • /wizard-ci ai-observability/groq
Show more apps
  • /wizard-ci ai-observability/manual-capture
  • /wizard-ci ai-observability/openai
  • /wizard-ci ai-observability/openai-agents
  • /wizard-ci ai-observability/opentelemetry
  • /wizard-ci ai-observability/vercel-ai
  • /wizard-ci basic-integration/android
  • /wizard-ci basic-integration/angular
  • /wizard-ci basic-integration/astro
  • /wizard-ci basic-integration/django
  • /wizard-ci basic-integration/fastapi
  • /wizard-ci basic-integration/flask
  • /wizard-ci basic-integration/flutter
  • /wizard-ci basic-integration/javascript-node
  • /wizard-ci basic-integration/javascript-web
  • /wizard-ci basic-integration/laravel
  • /wizard-ci basic-integration/next-js
  • /wizard-ci basic-integration/nuxt
  • /wizard-ci basic-integration/python
  • /wizard-ci basic-integration/rails
  • /wizard-ci basic-integration/react-native
  • /wizard-ci basic-integration/react-router
  • /wizard-ci basic-integration/sveltekit
  • /wizard-ci basic-integration/swift
  • /wizard-ci basic-integration/tanstack-router
  • /wizard-ci basic-integration/tanstack-start
  • /wizard-ci basic-integration/vue
  • /wizard-ci mcp-analytics/custom-dispatcher
  • /wizard-ci mcp-analytics/typescript-sdk
  • /wizard-ci replay-vision/javascript-node
  • /wizard-ci replay-vision/next-js
  • /wizard-ci replay-vision/react-vite
  • /wizard-ci revenue/stripe
  • /wizard-ci self-driving/astro
  • /wizard-ci self-driving/fastapi
  • /wizard-ci self-driving/nuxt
  • /wizard-ci self-driving/react-router
  • /wizard-ci self-driving/sveltekit
  • /wizard-ci warehouse/monorepo-env
  • /wizard-ci warehouse/multi-source-next
  • /wizard-ci warehouse/stripe-node
  • /wizard-ci warehouse/zero-source
  • /wizard-ci warehouse-seeded/next-stripe
  • /wizard-ci warehouse-seeded/next-stripe-declined

Test against a Context Mill branch:

  • /wizard-ci all context-mill:my-branch

Add context-mill:<branch> to any command above to pin the Context Mill branch. It defaults to main.

Results will be posted here when complete.

@gewenyu99

Copy link
Copy Markdown
Collaborator Author

/wizard-ci basic-integration/tanstack-start

@wizard-ci-bot

wizard-ci-bot Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

🧙 Wizard CI Results

Trigger ID: 30d5de1
Workflow: View run

App Confidence PR YARA
basic-integration/tanstack-start/tanstack-start-saas 5/5 #4083 (logs) ✓

Configuration

Setting Value
Wizard ref workbench/wizard-functional-a2b
Context Mill ref main
PostHog ref master

Search for trigger ID 30d5de1 in wizard-workbench PRs.

Carries main's eight fixes and A1's per-request ask signal and host-owned
analytics shutdown onto the moved tree. Seven conflicts, all import lines,
resolved to the incoming side with this PR's aliases. main's new
detection retry test moves from @lib/agent and @lib/host-resolution to
@agent and @shared.

Generated-By: PostHog Desktop
Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
Carries the guard that keeps a successful run successful when its
terminal analytics flush fails.

Generated-By: PostHog Desktop
Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
Carries the fence's directory-import patterns and the handoff, benchmark
and scan-summary wiring tests. One conflict, in .eslintrc.cjs: the new
patterns and comment land on A2b's collapsed src/agent/** fence, where
@lib/** already covers the alias forms. The handoff tools test moves to
src/agent/tools with its aliases rewritten.

Generated-By: PostHog Desktop
Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
Brings in main (#1235, 2.77.0) through A2a. Conflicts come from A2b's moves:
main's excluded-task-types test lands under src/agent, and #1235's imports
point at @shared/constants, @shared/errors and @agent instead of @lib.

Generated-By: PostHog Desktop
Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
Brings in main (#1319). No conflicts.

Generated-By: PostHog Desktop
Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
@gewenyu99
gewenyu99 marked this pull request as ready for review September 23, 2026 21:15
@gewenyu99
gewenyu99 requested review from a team as code owners September 23, 2026 21:15
@gewenyu99
gewenyu99 requested review from TueHaulund, arnohillen, fasyy612, hpouillot and ksvat and removed request for a team September 23, 2026 21:15
@gewenyu99
gewenyu99 merged commit 8af055b into main Sep 23, 2026
32 of 33 checks passed
@gewenyu99
gewenyu99 deleted the workbench/wizard-functional-a2b branch September 23, 2026 21:21
gewenyu99 added a commit that referenced this pull request Sep 24, 2026
Release A landed on main as squash commits (#1293, #1297, #1299, #1303).
B1 already carries that content through the A3 branch, so the merge
keeps B1's tree and adds #1334, the one change main has beyond A3, with
B1 import paths.

Generated-By: PostHog Desktop
Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants