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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion e2e-harness/__tests__/e2e-flow-snapshot.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { InkUI } from '@ui/tui/ink-ui';
import { setUI } from '@ui/index';
import { buildSession, RunPhase } from '@lib/wizard-session';
import { Integration } from '@lib/constants';
import { HostResolution } from '@lib/host-resolution';
import { FRAMEWORK_REGISTRY } from '@lib/registry';
import { WizardReadiness } from '@lib/health-checks/readiness';
import {
Expand Down Expand Up @@ -89,7 +90,7 @@ function traceFlow(
store.setCredentials({
accessToken: 'phx_x',
projectApiKey: 'phc_x',
host: 'https://us.posthog.com',
host: HostResolution.fromApiHost('https://us.posthog.com'),
projectId: 1,
});
} else if (screen === ScreenId.SelfDrivingGithub) {
Expand Down
2 changes: 1 addition & 1 deletion e2e-harness/__tests__/wizard-ci-driver.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ describe('WizardCiDriver — source-maps project pick', () => {
store.setCredentials({
accessToken: 'phx_x',
projectApiKey: 'phc_x',
host: 'https://us.posthog.com',
host: HostResolution.fromApiHost('https://us.posthog.com'),
projectId: 1,
});
}
Expand Down
7 changes: 7 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,13 @@
"fix:prettier": "prettier --write \"{lib,src,test}/**/*.ts\"",
"fix:eslint": "eslint . --cache --format stylish --fix",
"test": "pnpm build && vitest run",
"test:legacy": "vitest run --project legacy",
"test:agent": "vitest run --project agent",
"test:tui": "vitest run --project tui",
"test:cli": "vitest run --project cli",
"test:harness": "vitest run --project harness",
"test:arch": "vitest run --project architecture",
"test:goldens:update": "vitest run -u",
"test:coverage": "pnpm build && vitest run --coverage",
"test:e2e": "pnpm build && ./e2e-tests/run.sh",
"test:e2e-record": "export RECORD_FIXTURES=true && pnpm build && ./e2e-tests/run.sh",
Expand Down
31 changes: 16 additions & 15 deletions scripts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,18 @@ real ink render) and is driven purely by store state manipulation; a PTY parent
([`e2e-harness/tui-capture.ts`](../e2e-harness/tui-capture.ts), node-pty +
`@xterm/headless`) captures the real rendered screen.

| Script | What it does | Needs |
| ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| **`tui-host.no-jest.ts`** | Real TUI host: `MODE=fixed` follows a profile; `MODE=serve` accepts socket commands. | `APP_DIR`, `PROJECT_ID`, key for a full run, `SNAP_CTRL`; run under a PTY, with `CONTROL_SOCK` in serve mode |
| **`tui-snapshots.no-jest.ts`** | Runs the fixed host and saves colored `SNAP_OUT/NN-<screen>.ans` frames, including within-screen progress. | `SNAP_OUT`, `APP_DIR`, `PROJECT_ID`, `POSTHOG_KEY_FILE` or `POSTHOG_PERSONAL_API_KEY` |
| **`wizard-ci-mcp.no-jest.ts`** | Stdio MCP server: `open_app`, `read_state`, `perform_action`, `render_screen`, `run_agent`. Screen output is plain text. | Spawns the host; `open_app` requires `appDir` and `projectId`, with optional `keyFile`, `apiKey`, `region` |
| **`wizard-ci-explore.no-jest.ts`** | `pnpm wizard-ci-explore`: opens an app, confirms setup, reads state, prints one frame, and exits. It does not run the agent. | `APP_DIR`, `PROJECT_ID`; optional `POSTHOG_KEY_FILE` |
| Script | What it does | Needs |
| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| **`tui-host.no-jest.ts`** | Real TUI host: `MODE=fixed` follows a profile; `MODE=serve` accepts socket commands. | `APP_DIR`, `PROJECT_ID`, key for a full run, `SNAP_CTRL`; run under a PTY, with `CONTROL_SOCK` in serve mode |
| **`tui-snapshots.no-jest.ts`** | Runs the fixed host and saves colored `SNAP_OUT/NN-<screen>.ans` frames, including within-screen progress. | `SNAP_OUT`, `APP_DIR`, `PROJECT_ID`, `POSTHOG_KEY_FILE` or `POSTHOG_PERSONAL_API_KEY` |
| **`wizard-ci-mcp.no-jest.ts`** | Stdio MCP server: `open_app`, `read_state`, `perform_action`, `render_screen`, `run_agent`. Screen output is plain text. | Spawns the host; `open_app` requires `appDir` and `projectId`, with optional `keyFile`, `apiKey`, `region` |
| **`chunk-manifest.no-jest.ts`** | Prints a structural manifest of `dist/`: per chunk, the source files it contains and the chunks it imports, hash suffixes stripped. `--summary` prints chunk names plus the sorted source set. A reading tool, nothing diffs its output. | A built `dist/` |
| **`wizard-ci-explore.no-jest.ts`** | `pnpm wizard-ci-explore`: opens an app, confirms setup, reads state, prints one frame, and exits. It does not run the agent. | `APP_DIR`, `PROJECT_ID`; optional `POSTHOG_KEY_FILE` |

> You usually don't call these directly — `pnpm wizard-ci-snapshots` (in
> [wizard-workbench](https://github.com/PostHog/wizard-workbench)) orchestrates
> the snapshot route; the MCP server is registered in this repo's `.mcp.json` and
> used via the `exploring-the-wizard` skill.
> the snapshot route; the MCP server is registered in this repo's `.mcp.json`
> and used via the `exploring-the-wizard` skill.

`PROGRAM`, `SNAP_HARNESS`, `SNAP_SEQUENCE`, `SNAP_MODEL`, and `E2E_ASK` are host
environment inputs, inherited from the launcher; they are not MCP tool
Expand All @@ -34,17 +35,17 @@ before choosing credentials or an EU project.
## Credentials for full agent runs

Full TUI host and snapshot runs require both the personal API key (or
`POSTHOG_KEY_FILE`) and `WIZARD_CI_GATEWAY_TOKEN_FILE`, plus `PROJECT_ID`.
For MCP runs, pass the personal key through `open_app` and set the gateway
token file path in the server environment before launch. Restart the server
after changing it; the gateway path is not an MCP tool argument.
Detection-only exploration does not need either secret. See
`POSTHOG_KEY_FILE`) and `WIZARD_CI_GATEWAY_TOKEN_FILE`, plus `PROJECT_ID`. For
MCP runs, pass the personal key through `open_app` and set the gateway token
file path in the server environment before launch. Restart the server after
changing it; the gateway path is not an MCP tool argument. Detection-only
exploration does not need either secret. See
[local credential setup](../docs/local-dev.md#credentials-for-local-ci-and-headless-runs).

## Background

The control plane lives in [`e2e-harness/`](../e2e-harness/) — out of `src/`, so
none of it ships in prod. `WizardCiDriver` (read/act over the store), the
screen→action registry, the e2e profiles, and `tui-capture` (real-TUI PTY
capture). See [`ARCHITECTURE.md`](../e2e-harness/ARCHITECTURE.md) for how the two
routes drive these (env strip, scoped project id, gotchas).
capture). See [`ARCHITECTURE.md`](../e2e-harness/ARCHITECTURE.md) for how the
two routes drive these (env strip, scoped project id, gotchas).
55 changes: 55 additions & 0 deletions scripts/chunk-manifest.no-jest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* Structural manifest of the built bundle: for every chunk in dist/, the
* source files it contains (from its sourcemap) and the chunks it imports.
* Hash suffixes are stripped so the output is stable across builds.
*
* tsx scripts/chunk-manifest.no-jest.ts [distDir] > manifest.json
* tsx scripts/chunk-manifest.no-jest.ts [distDir] --summary > summary.json
*
* `--summary` prints the chunk names and the sorted set of every bundled
* source. Output differs between macOS and Linux (chunk assignment and
* sourcemap sources), so this is a reading tool, not a golden.
*/
import fs from 'fs';
import path from 'path';

const args = process.argv.slice(2);
const summary = args.includes('--summary');
const dist = path.resolve(args.find((a) => !a.startsWith('--')) ?? 'dist');
const root = path.resolve(dist, '..');

const stripHash = (file: string): string =>
file.replace(/-[A-Za-z0-9_-]{8}\.js$/, '.js');

const importRe = /(?:from\s*|import\s*\(\s*)["']\.\/([^"']+\.js)["']/g;

const manifest: Record<string, { sources: string[]; imports: string[] }> = {};

for (const file of fs
.readdirSync(dist)
.filter((f) => f.endsWith('.js'))
.sort()) {
const code = fs.readFileSync(path.join(dist, file), 'utf8');
const mapPath = path.join(dist, `${file}.map`);
const sources = fs.existsSync(mapPath)
? (
JSON.parse(fs.readFileSync(mapPath, 'utf8')) as { sources: string[] }
).sources
.map((s) => path.relative(root, path.resolve(dist, s)))
.filter((s) => !s.includes('node_modules'))
.sort()
: [];
const imports = new Set<string>();
for (const m of code.matchAll(importRe)) imports.add(stripHash(m[1]));
manifest[stripHash(file)] = { sources, imports: [...imports].sort() };
}

const output = summary
? {
chunks: Object.keys(manifest).sort(),
sources: [
...new Set(Object.values(manifest).flatMap((c) => c.sources)),
].sort(),
}
: manifest;
process.stdout.write(JSON.stringify(output, null, 2) + '\n');
Loading
Loading