Skip to content
Open
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,6 @@
[submodule "packages/workflow-mcp"]
path = packages/workflow-mcp
url = https://github.com/Juliusolsson05/workflow-mcp.git
[submodule "packages/grok-code-headless"]
path = packages/grok-code-headless
url = https://github.com/Juliusolsson05/grok-code-headless.git
100 changes: 100 additions & 0 deletions docs/superpowers/plans/2026-09-07-grok-package-wiring.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Grok package wiring — Task 1 of the grok provider plan

(Verbatim extract of the master plan task; master plan: `docs/superpowers/plans/2026-09-07-grok-code-provider.md` on `feat/grok-code-provider`.)

### Task 1: Bootstrap grok-code-headless repo + agent-code wiring

**Files:**
- Create: the new repo `Juliusolsson05/grok-code-headless` (skeleton below)
- Modify: `.gitmodules`, `package.json`, `tsconfig.node.json`, `tsconfig.web.json`, `electron.vite.config.ts`, `vitest.config.ts`
- Test: `src/providers/importBoundaries.test.ts` (auto-covers), `scripts/verify-submodule-checkouts.mjs` (auto-covers)

**Interfaces:** Produces: empty-but-green package compiled from source by the app's four resolvers, tracking-issue-linked PR.

- [ ] **Step 1: Worktree + plan-first commit**

```bash
cd /Users/juliusolsson/Desktop/Development/agent-code
git worktree add .worktrees/grok-package-wiring -b feat/grok-package-wiring origin/main
cd .worktrees/grok-package-wiring && git submodule update --init && ln -s ../../node_modules node_modules
mkdir -p docs/superpowers/plans
# copy Task 1 section verbatim → docs/superpowers/plans/2026-09-07-grok-package-wiring.md
git add docs/superpowers/plans/2026-09-07-grok-package-wiring.md && git commit -m "docs(grok): plan the grok-code-headless package wiring"
```

- [ ] **Step 2: Create the repo with the standard skeleton**

```bash
mkdir -p grok-code-headless && cd grok-code-headless && git init -b main
```
Author `package.json` with the exact script contract from `packages/claude-code-headless/package.json` (`build`, `typecheck`, `test`, `test:core`, `test:system`, `test:live`, `test:coverage`, `test:package`, `test:contract`, `check`, `upstream:check`), name `grok-code-headless`, deps `@xterm/headless ^5.5.0` + `chokidar ^5.0.0`, peerDep `node-pty ^1.0.0`, devDeps matching the sibling (vitest `^4.1.10` — the contract check pins major 4). `tsconfig.json` copied from `packages/codex-headless/tsconfig.json` (module ESNext, strict, outDir dist). `vitest.config.ts` with `core` (node) and `system` projects following the sibling's tier excludes. `LICENSE` (MIT, copyright Julius Olsson), `.gitignore` (node_modules/dist/coverage), `README.md` stating: drives the real Grok Build TUI in a PTY; session layout (`~/.grok/sessions/<encoded resolved cwd>/<uuid>/{summary.json,chat_history.jsonl,updates.jsonl}`); vendor source of truth `xai-org/grok-build`; vendored-shape fixtures policy. `src/index.ts` exporting nothing yet except a version constant; `src/grokVersion.ts`:

```ts
// WHY a version module before any real code: `test:package` in the standard
// contract needs a public entry point to verify, and the app's wiring PR needs
// something importable in all four resolvers. This is replaced by the real
// surface in Task 4.
export const GROK_HEADLESS_VERSION = '0.0.1'
```
One smoke test `src/grokVersion.test.ts` (`expect(GROK_HEADLESS_VERSION).toMatch(/^\d+\.\d+\.\d+$/)`). Commit `feat: bootstrap grok-code-headless package skeleton`. Then:

```bash
gh repo create Juliusolsson05/grok-code-headless --public --source . --push
```
Add `.github/workflows/ci.yml` calling the org's reusable package workflow exactly as `packages/codex-headless/.github/workflows/ci.yml` does (read it and mirror; branch protection on `package / quality-gate` per testing standard).

- [ ] **Step 3: Submodule + dependency wiring in agent-code**

```bash
cd .worktrees/grok-package-wiring
git submodule add https://github.com/Juliusolsson05/grok-code-headless.git packages/grok-code-headless
```
`package.json` dependencies (alphabetical, beside the other file: deps): `"grok-code-headless": "file:./packages/grok-code-headless"`.
`.gitmodules` gains the entry (git writes it).
`tsconfig.node.json`: add to `paths` —
```json
"grok-code-headless": ["./packages/grok-code-headless/src/index.ts"],
"grok-code-headless/*": ["./packages/grok-code-headless/src/*"],
```
and add `"packages/grok-code-headless/src/**/*"` to `include`. Mirror nothing in `tsconfig.web.json` paths (renderer must not import headless packages — same as siblings; web include list stays untouched).
`electron.vite.config.ts`: add to `headlessAlias`:
```ts
{ find: /^grok-code-headless\/(.+)$/, replacement: `${resolve(__dirname, 'packages/grok-code-headless/src')}/$1` },
{ find: 'grok-code-headless', replacement: resolve(__dirname, 'packages/grok-code-headless/src/index.ts') },
```
and add `'grok-code-headless'` to `headlessExclude`.
`vitest.config.ts`: add the same two entries to `alias` (this map is hand-duplicated on purpose — see its header comment).

- [ ] **Step 4: Verify the four resolvers agree**

```bash
source /opt/homebrew/opt/nvm/nvm.sh && nvm use 24
npm install
npm run submodules:check && npm run typecheck
NODE_ENV=test npx vitest run --project unit src/providers/importBoundaries.test.ts
```
Expected: typecheck exit 0; boundary test green (it scans `src/`, unaffected, but run it as the guard it is).

- [ ] **Step 5: Commit, push, PR**

```bash
git add .gitmodules package.json package-lock.json tsconfig.node.json electron.vite.config.ts vitest.config.ts
git commit -m "feat(grok): add grok-code-headless submodule and resolver wiring"
git push -u origin feat/grok-package-wiring
gh pr create --title "feat(grok): add grok-code-headless submodule and resolver wiring" --body "Task 1 of the grok provider plan. Skeleton package compiled from source in all resolvers. Refs #<issue>."
```
CHECKPOINT: merge on explicit confirmation only.

---


## Amendment (2026-09-07, post-review)

- `package.json` / `package-lock.json` are NOT modified after all: the sibling
headless packages are compiled from submodule source only (no `file:` dep),
and a first attempt adding one broke `npm ci` — the subpackage's
devDependencies entered npm's ideal tree and demanded a different vitest
patch than the root lock pins. Wiring = .gitmodules + tsconfig.node paths/
include + electron-vite headlessAlias/headlessExclude + vitest alias map +
**tsconfig.web.json paths** (both projects must declare the same alias map —
review caught the initial omission).
3 changes: 3 additions & 0 deletions electron.vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ const headlessAlias = [
{ find: 'claude-code-headless', replacement: resolve(__dirname, 'packages/claude-code-headless/src/index.ts') },
{ find: /^codex-headless\/(.+)$/, replacement: `${resolve(__dirname, 'packages/codex-headless/src')}/$1` },
{ find: 'codex-headless', replacement: resolve(__dirname, 'packages/codex-headless/src/index.ts') },
{ find: /^grok-code-headless\/(.+)$/, replacement: `${resolve(__dirname, 'packages/grok-code-headless/src')}/$1` },
{ find: 'grok-code-headless', replacement: resolve(__dirname, 'packages/grok-code-headless/src/index.ts') },
{ find: /^opencode-headless\/(.+)$/, replacement: `${resolve(__dirname, 'packages/opencode-headless/src')}/$1` },
{ find: 'opencode-headless', replacement: resolve(__dirname, 'packages/opencode-headless/src/index.ts') },
{ find: /^agent-transcript-parser\/(.+)$/, replacement: `${resolve(__dirname, 'packages/agent-transcript-parser/src')}/$1` },
Expand Down Expand Up @@ -55,6 +57,7 @@ const projectAlias = {
const headlessExclude = [
'claude-code-headless',
'codex-headless',
'grok-code-headless',
'opencode-headless',
'agent-transcript-parser',
'agent-voice-dictation',
Expand Down
1 change: 1 addition & 0 deletions packages/grok-code-headless
Submodule grok-code-headless added at 1be2fc
3 changes: 3 additions & 0 deletions tsconfig.node.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
"claude-code-headless/*": ["./packages/claude-code-headless/src/*"],
"codex-headless": ["./packages/codex-headless/src/index.ts"],
"codex-headless/*": ["./packages/codex-headless/src/*"],
"grok-code-headless": ["./packages/grok-code-headless/src/index.ts"],
"grok-code-headless/*": ["./packages/grok-code-headless/src/*"],
"opencode-headless": ["./packages/opencode-headless/src/index.ts"],
"opencode-headless/*": ["./packages/opencode-headless/src/*"],
"agent-transcript-parser": ["./packages/agent-transcript-parser/src/index.ts"],
Expand Down Expand Up @@ -74,6 +76,7 @@
"packages/agent-voice-dictation/src/speech/**/*",
"packages/claude-code-headless/src/**/*",
"packages/codex-headless/src/**/*",
"packages/grok-code-headless/src/**/*",
"packages/opencode-headless/src/**/*",
"packages/workflow-mcp/src/**/*"
],
Expand Down
2 changes: 2 additions & 0 deletions tsconfig.web.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
"claude-code-headless/*": ["./packages/claude-code-headless/src/*"],
"codex-headless": ["./packages/codex-headless/src/index.ts"],
"codex-headless/*": ["./packages/codex-headless/src/*"],
"grok-code-headless": ["./packages/grok-code-headless/src/index.ts"],
"grok-code-headless/*": ["./packages/grok-code-headless/src/*"],
"opencode-headless": ["./packages/opencode-headless/src/index.ts"],
"opencode-headless/*": ["./packages/opencode-headless/src/*"],
"agent-transcript-parser": ["./packages/agent-transcript-parser/src/index.ts"],
Expand Down
2 changes: 2 additions & 0 deletions vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export const alias = [
{ find: 'claude-code-headless', replacement: resolve(root, 'packages/claude-code-headless/src/index.ts') },
{ find: /^codex-headless\/(.+)$/, replacement: `${resolve(root, 'packages/codex-headless/src')}/$1` },
{ find: 'codex-headless', replacement: resolve(root, 'packages/codex-headless/src/index.ts') },
{ find: /^grok-code-headless\/(.+)$/, replacement: `${resolve(root, 'packages/grok-code-headless/src')}/$1` },
{ find: 'grok-code-headless', replacement: resolve(root, 'packages/grok-code-headless/src/index.ts') },
// Drift fix: electron.vite.config.ts gained opencode-headless when the
// third provider landed; this map (deliberately duplicated — see the WHY
// above) did not. Any test whose import graph reaches
Expand Down