You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .claude/learnings.md
+10Lines changed: 10 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,6 +8,16 @@
8
8
-`@vercel/sandbox` git clones can be shallow by default, causing "no history in common with main" on PR creation when force-pushing from the sandbox. Always unshallow before pushing (`git fetch --unshallow origin`).
9
9
-`GitHubAdapter.createBranch` must force-reset existing branches to the base SHA on 422, not silently return. Stale branches from previous failed runs can retain orphan history.
10
10
11
+
## Jira adapter
12
+
- Jira REST v3 comments require ADF, and **ADF text nodes cannot contain `\n`**. Multi-line content must be modeled as multiple paragraph nodes (or use `hardBreak` inline nodes between text nodes). Stuffing newline-joined text into a single text node returns 400 Bad Request on `/rest/api/3/issue/{id}/comment`. Adapter helper `toAdfParagraphs` splits on `\n` and emits one paragraph per line.
13
+
14
+
## Codex agent in Vercel Sandbox
15
+
- The `using-git-worktrees` superpowers skill is the dominant root cause of empty-PR / `.gitignore`-only commits, NOT `.codex/` pollution. The skill's contract: "If the worktree directory is not in .gitignore, add it and commit before proceeding." The `executing-plans` skill REQUIRES `using-git-worktrees`, so any prompt that tells the agent to use `executing-plans` chains into "modify .gitignore + commit" before any real implementation work. Confirmed on AWT-641 / AWT-642. Mitigation: prompts (research + implement) explicitly forbid invoking `using-git-worktrees`/`executing-plans` and forbid any `git worktree` command or `.gitignore` change. The block is in the prompt body and must override conflicting skill text.
16
+
- Codex CLI also creates `.codex/` in cwd at runtime (per-session state). Without intervention, the agent sees it as untracked pollution in `git status`, "fixes" it by adding `.codex/` to `.gitignore`, commits only that. Mitigation: `CodexAgentAdapter.configure` writes `.codex/` to `.git/info/exclude` so it's hidden from the agent's git status. The post-phase cleanup `rm -rf .codex/` exists for the same reason but only runs after the agent exits.
17
+
-`extractUsage` cannot derive duration from Codex NDJSON event timestamps (the events do not carry `timestamp`/`ts`/`time` keys). The wrapper script appends a synthetic `{"type":"phase.duration","duration_ms":N}` line to stdout as a fallback so Slack reports show real wall-clock minutes instead of `0m`.
18
+
- Codex Stop-hook protocol accepts BOTH `{"decision":"block","reason":"..."}` (legacy) and `{"continue":true,"stopReason":"..."}` (new) on stdout with exit 0 to force the agent to take another turn — confirmed against developers.openai.com/codex/hooks. Either format works; the codebase uses the legacy one for parity with the Claude commit-guard.
19
+
-`fixAndRetryPush` must dispatch the configured agent's CLI, not hardcode `claude`. When AGENT_KIND=codex the claude binary isn't installed and `|| true` swallows the failure, leaving the same broken HEAD to be force-pushed.
20
+
11
21
## E2E in GitHub Actions
12
22
-`@vercel/sandbox` reads credentials from `process.env` — a GH secret is not enough; it must be mapped via the job's `env:` block (e.g. `VERCEL_OIDC_TOKEN: ${{ secrets.VERCEL_OIDC_TOKEN }}`). Prefer long-lived `VERCEL_TOKEN` + `VERCEL_TEAM_ID` + `VERCEL_PROJECT_ID` over OIDC — OIDC tokens expire in ~12h and the SDK's refresh path requires `.vercel/project.json`, which CI doesn't have.
13
23
- Reconcile (`src/lib/reconcile.ts`) has a 30s `ORPHAN_GRACE_MS` window that skips entries younger than 30s. Any e2e test seeding a registry entry via `setEntry` and expecting reconcile to cancel it on the next cron tick must backdate the timestamp past the grace window (`setEntry(key, runId, { ageMs: 60_000 })`). Without backdating the test is racy — it only passes if Vercel's 1-min scheduled cron happens to fire at T>30s during the test's wait window.
**Switching agents** — Blazebot supports two CLI runtimes. Set `AGENT_KIND` once per deployment:
146
+
147
+
```bash
148
+
AGENT_KIND=claude # default — Anthropic Claude Code
149
+
# or
150
+
AGENT_KIND=codex # OpenAI Codex CLI
151
+
```
152
+
153
+
When `AGENT_KIND=codex`:
154
+
155
+
```bash
156
+
CODEX_API_KEY=sk-codex-xxxxxxxxxxxx # or CODEX_CHATGPT_OAUTH_TOKEN
157
+
CODEX_MODEL=gpt-5-codex # default
158
+
```
159
+
160
+
Pricing is fetched from [LiteLLM's community-maintained JSON](https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json) on each cold start (1h TTL by default). Override `CODEX_PRICING_URL` in air-gapped environments. When pricing is unavailable, Slack reports show tokens-only with `cost unknown`.
161
+
145
162
**Sandbox** — Concurrency and timeout limits:
146
163
```bash
147
164
MAX_CONCURRENT_AGENTS=3 # Max parallel sandboxes (default: 3)
0 commit comments