From 181ae2ba8539f737c207e5bb616cb6485dccd742 Mon Sep 17 00:00:00 2001 From: Thomas Stang Date: Fri, 26 Jun 2026 14:52:43 -0500 Subject: [PATCH 01/23] chore(oat): scaffold brainstorm-visual-companion-v6 --- .../discovery.md | 142 ++++++++++++ .../implementation.md | 210 ++++++++++++++++++ .../brainstorm-visual-companion-v6/plan.md | 204 +++++++++++++++++ .../brainstorm-visual-companion-v6/state.md | 62 ++++++ 4 files changed, 618 insertions(+) create mode 100644 .oat/projects/shared/brainstorm-visual-companion-v6/discovery.md create mode 100644 .oat/projects/shared/brainstorm-visual-companion-v6/implementation.md create mode 100644 .oat/projects/shared/brainstorm-visual-companion-v6/plan.md create mode 100644 .oat/projects/shared/brainstorm-visual-companion-v6/state.md diff --git a/.oat/projects/shared/brainstorm-visual-companion-v6/discovery.md b/.oat/projects/shared/brainstorm-visual-companion-v6/discovery.md new file mode 100644 index 0000000000..c82555eb24 --- /dev/null +++ b/.oat/projects/shared/brainstorm-visual-companion-v6/discovery.md @@ -0,0 +1,142 @@ +--- +oat_status: in_progress +oat_ready_for: null +oat_blockers: [] +oat_last_updated: 2026-06-26 +oat_generated: false +--- + +# Discovery: brainstorm-visual-companion-v6 + +## Phase Guardrails (Discovery) + +Discovery is for requirements and decisions, not implementation details. + +- Prefer outcomes and constraints over concrete deliverables (no specific scripts, file paths, or function names). +- If an implementation detail comes up, capture it as an **Open Question** for design (or a constraint), not as a deliverable list. + +## Initial Request + +{Copy of user's initial request} + +## Clarifying Questions + +### Question 1: {Topic} + +**Q:** {Question} +**A:** {User's answer} +**Decision:** {What this means for the project} + +## Solution Space + +_Include this section only when the request is exploratory or multiple viable approaches exist. For well-understood requests with an obvious approach, omit or replace with a single sentence stating the chosen direction._ + +{Divergent exploration of the problem space before converging on an approach. Capture genuinely distinct strategies, not minor variations. Include 2-3 approaches as needed.} + +### Approach 1: {Strategy Name} _(Recommended)_ + +**Description:** {What this approach involves} +**When this is the right choice:** {Conditions under which this approach is best} +**Tradeoffs:** {What you give up by choosing this} + +### Approach 2: {Strategy Name} + +**Description:** {What this approach involves} +**When this is the right choice:** {Conditions under which this approach is best} +**Tradeoffs:** {What you give up by choosing this} + +### Chosen Direction + +**Approach:** {Which approach was selected} +**Rationale:** {Why this approach over the alternatives} +**User validated:** {Yes/No — explicit buy-in before proceeding} + +## Options Considered + +{Specific implementation options within the chosen approach. More granular than Solution Space — captures decisions about libraries, patterns, data formats, etc.} + +### Option A: {Option Name} + +**Description:** {What this option involves} + +**Pros:** + +- {Benefit 1} +- {Benefit 2} + +**Cons:** + +- {Drawback 1} +- {Drawback 2} + +**Chosen:** {A/B/Neither} + +**Summary:** {1-2 sentence summary of the chosen option and why} + +## Key Decisions + +1. **{Decision Category}:** {Decision made and why} +2. **{Decision Category}:** {Decision made and why} + +## Constraints + +- {Constraint 1} +- {Constraint 2} + +## Success Criteria + +- {Criterion 1} +- {Criterion 2} + +## Out of Scope + +- {Thing we explicitly decided not to do} +- {Thing we explicitly decided not to include in this phase} + +## Deferred Ideas + +{Ideas that came up during discovery but are intentionally out of scope for now} + +- {Idea 1} - {Why deferred} +- {Idea 2} - {Why deferred} + +## Open Questions + +{Questions that need resolution before or during specification (and later design)} + +- **{Question Category}:** {Question that needs answering} +- **{Question Category}:** {Question that needs answering} + +## Assumptions + +{Assumptions we're making that need validation} + +- {Assumption 1} +- {Assumption 2} + +## Risks + +{Potential risks identified during discovery} + +- **{Risk Name}:** {Description} + - **Likelihood:** Low / Medium / High + - **Impact:** Low / Medium / High + - **Mitigation Ideas:** {How to address} + +## Next Steps + +Use this discovery artifact to drive the next workflow step: + +- **Spec-driven mode:** continue to `oat-project-design` (which confirms + requirements and produces both `spec.md` and `design.md`). +- **Spec-driven mode → formalize-only:** use `oat-project-spec` standalone + if you want a formalized requirements artifact but aren't ready to + design yet. +- **Quick mode → straight to plan:** proceed directly to `plan.md` when + scope is clear and no architecture decisions remain. +- **Quick mode → optional lightweight design:** produce a focused + `design.md` (architecture, components, data flow, testing) before + planning. Choose this when discovery surfaced architecture choices + or component boundaries. +- **Quick mode → promote:** escalate to spec-driven if discovery revealed + the scope is larger or more complex than expected. diff --git a/.oat/projects/shared/brainstorm-visual-companion-v6/implementation.md b/.oat/projects/shared/brainstorm-visual-companion-v6/implementation.md new file mode 100644 index 0000000000..a6b1dc4184 --- /dev/null +++ b/.oat/projects/shared/brainstorm-visual-companion-v6/implementation.md @@ -0,0 +1,210 @@ +--- +oat_status: in_progress +oat_ready_for: null +oat_blockers: [] +oat_last_updated: 2026-06-26 +oat_current_task_id: p01-t01 +oat_generated: false +--- + +# Implementation: brainstorm-visual-companion-v6 + +**Started:** 2026-06-26 +**Last Updated:** 2026-06-26 + +> This document is used to resume interrupted implementation sessions. +> +> Conventions: +> +> - `oat_current_task_id` always points at the **next plan task to do** (not the last completed task). +> - When all plan tasks are complete, set `oat_current_task_id: null`. +> - Reviews are **not** plan tasks. Track review status in `plan.md` under `## Reviews` (e.g., `| final | code | passed | ... |`). +> - Keep phase/task statuses consistent with the Progress Overview table so restarts resume correctly. +> - Before running the `oat-project-pr-final` skill, ensure `## Final Summary (for PR/docs)` is filled with what was actually implemented. + +## Progress Overview + +| Phase | Status | Tasks | Completed | +| ------- | ----------- | ----- | --------- | +| Phase 1 | in_progress | N | 0/N | +| Phase 2 | pending | N | 0/N | + +**Total:** 0/{N} tasks completed + +--- + +## Phase 1: {Phase Name} + +**Status:** in_progress +**Started:** 2026-06-26 + +### Phase Summary (fill when phase is complete) + +**Outcome (what changed):** + +- {2-5 bullets describing user-visible / behavior-level changes delivered in this phase} + +**Key files touched:** + +- `{path}` - {why} + +**Verification:** + +- Run: `{command(s)}` +- Result: {pass/fail + notes} + +**Notes / Decisions:** + +- {trade-offs or deviations discovered during implementation} + +### Task p01-t01: {Task Name} + +**Status:** completed / in_progress / pending / blocked +**Commit:** {sha} (if completed) + +**Outcome (required when completed):** + +- {what materially changed (not “did task”, but “system now does X”)} + +**Files changed:** + +- `{path}` - {why} + +**Verification:** + +- Run: `{command(s)}` +- Result: {pass/fail + notes} + +**Notes / Decisions:** + +- {gotchas, trade-offs, design deltas, important context for future sessions} + +**Issues Encountered:** + +- {Issue and resolution} + +--- + +### Task p01-t02: {Task Name} + +**Status:** pending +**Commit:** - + +**Notes:** + +- {Notes will be added during implementation} + +--- + +## Phase 2: {Phase Name} + +**Status:** pending +**Started:** - + +### Task p02-t01: {Task Name} + +**Status:** pending +**Commit:** - + +--- + +## Orchestration Runs + +_Each run from `oat-project-implement` appends an entry below with:_ +_- Run header (number, timestamp, branch, tier, policy, phase counts)_ +_- Phase Outcomes table_ +_- Parallel Groups list_ +_- Outstanding Items_ + + + +_Orchestration runs from `oat-project-implement` are appended here, most-recent-first within the file but append-only at the bottom of the log._ + + + +--- + +## Implementation Log + +Chronological log of implementation progress. + +### 2026-06-26 + +**Session Start:** {time} + +- [x] p01-t01: {Task name} - {commit sha} +- [ ] p01-t02: {Task name} - in progress + +**What changed (high level):** + +- {short bullets suitable for PR/docs} + +**Decisions:** + +- {Decision made and rationale} + +**Follow-ups / TODO:** + +- {anything discovered during implementation that should be captured for later} + +**Blockers:** + +- {Blocker description} - {status: resolved/pending} + +**Session End:** {time} + +--- + +### 2026-06-26 + +**Session Start:** {time} + +{Continue log...} + +--- + +## Deviations from Plan / Design + +Document any intentional deviations from the original plan, spec, or design. Include accepted review findings where the shipped implementation is source of truth and a lifecycle artifact needs alignment. + +| Task / Review | Source Artifact | Planned / Documented | Actual / Accepted | Reason | Source of Truth | Follow-up | +| ------------- | --------------- | -------------------- | ----------------- | ------ | --------------- | --------- | +| - | - | - | - | - | - | - | + +## Test Results + +Track test execution during implementation. + +| Phase | Tests Run | Passed | Failed | Coverage | +| ----- | --------- | ------ | ------ | -------- | +| 1 | - | - | - | - | +| 2 | - | - | - | - | + +## Final Summary (for PR/docs) + +**What shipped:** + +- {capability 1} +- {capability 2} + +**Behavioral changes (user-facing):** + +- {bullet} + +**Key files / modules:** + +- `{path}` - {purpose} + +**Verification performed:** + +- {tests/lint/typecheck/build/manual steps} + +**Design deltas (if any):** + +- {what changed vs design.md and why} + +## References + +- Plan: `plan.md` +- Design: `design.md` +- Spec: `spec.md` diff --git a/.oat/projects/shared/brainstorm-visual-companion-v6/plan.md b/.oat/projects/shared/brainstorm-visual-companion-v6/plan.md new file mode 100644 index 0000000000..dc8db6d215 --- /dev/null +++ b/.oat/projects/shared/brainstorm-visual-companion-v6/plan.md @@ -0,0 +1,204 @@ +--- +oat_status: in_progress +oat_ready_for: null +oat_blockers: [] +oat_last_updated: 2026-06-26 +oat_phase: plan +oat_phase_status: in_progress +oat_plan_hill_phases: [] # phases to pause AFTER completing (empty = every phase) +oat_plan_parallel_groups: [] # groups of phases that run concurrently in worktrees; [] = fully sequential +oat_plan_source: spec-driven # spec-driven | quick | imported +oat_import_reference: null # e.g., references/imported-plan.md +oat_import_source_path: null # original source path provided by user +oat_import_provider: null # codex | cursor | claude | null +oat_generated: false +--- + +# Implementation Plan: brainstorm-visual-companion-v6 + +> Execute this plan using `oat-project-implement` — sequential by default, parallel when `oat_plan_parallel_groups` is declared. + +**Goal:** {Brief goal statement from spec} + +**Architecture:** {1-2 sentence architecture summary from design} + +**Tech Stack:** {Key technologies from design} + +**Commit Convention:** `{type}({scope}): {description}` - e.g., `feat(p01-t01): add user auth endpoint` + +## Planning Checklist + +- [ ] Confirmed HiLL checkpoints with user +- [ ] Set `oat_plan_hill_phases` in frontmatter +- [ ] Evaluated phases for parallelism opportunities +- [ ] Set `oat_plan_parallel_groups` in frontmatter + +--- + +## Parallelism + +Phases that have no overlapping file modifications may run concurrently. To declare parallelism: + +```yaml +oat_plan_parallel_groups: [['p02', 'p03']] +``` + +Each inner array is a group of phases that execute in parallel (each in its own worktree) and merge back in plan order after all pass. Groups themselves run sequentially. + +Default is `[]` (fully sequential, no worktrees). Only declare parallelism when phases are genuinely file-disjoint — overlap will produce merge conflicts that stop the run. + +--- + +## Dispatch Profile + +_Optional override surface. Use only for explicit user-authored constraints or preferences. Omit this section when runtime selection should choose the lowest confident tier._ + +Blank or `auto` means there is no explicit constraint for that provider. Do not generate rows by default; a missing phase row uses runtime selection. + +| Phase | Claude model | Codex effort | Rationale | +| ----- | ------------------------- | ------------------------------ | ----------------------------- | +| pNN | haiku\|sonnet\|opus\|auto | low\|medium\|high\|xhigh\|auto | why this constraint is needed | + +Codex effort values are preferred controls. `oat-project-implement` caps them against the resolved OAT dispatch ceiling and maps selected efforts to pinned implementer variants. Codex provider default effort is informational for base/unpinned roles and is not an OAT ceiling. + +--- + +## Phase 1: {Phase Name} + +### Task p01-t01: {Task Name} + +**Files:** + +- Create: `{path/to/file.ts}` +- Modify: `{path/to/existing.ts}` + +**Step 1: Write test (RED)** + +```typescript +// {path/to/file.test.ts} +describe('{feature}', () => { + it('{test case}', () => { + // Test implementation + }); +}); +``` + +Run: `pnpm --filter {package-name} exec vitest run {path/to/file.test.ts}` +Expected: Test fails (RED) + +**Step 2: Implement (GREEN)** + +```typescript +// {path/to/file.ts} +// Implementation code or interface signatures +``` + +Run: `pnpm --filter {package-name} exec vitest run {path/to/file.test.ts}` +Expected: Test passes (GREEN) + +Use the actual runner command that scopes to the intended file or test target. Do not write a package-level shortcut unless it truly executes only the scope the task claims. + +**Step 3: Refactor** + +{Any cleanup or improvements while tests stay green} + +**Step 4: Verify** + +Run: `pnpm lint && pnpm type-check` +Expected: No errors + +**Step 5: Commit** + +```bash +git add {files} +git commit -m "feat(p01-t01): {description}" +``` + +--- + +### Task p01-t02: {Task Name} + +**Files:** + +- {File list} + +**Step 1: Write test (RED)** + +{Test code} + +**Step 2: Implement (GREEN)** + +{Implementation code or signatures} + +**Step 3: Refactor** + +{Optional cleanup} + +**Step 4: Verify** + +Run: `{verification command}` +Expected: {output} + +Verification commands should be behaviorally accurate. If the task claims a file-scoped or test-scoped check, use the concrete runner invocation that really scopes to that target. + +**Step 5: Commit** + +```bash +git add {files} +git commit -m "feat(p01-t02): {description}" +``` + +--- + +## Phase 2: {Phase Name} + +### Task p02-t01: {Task Name} + +{Continue TDD pattern...} + +--- + +## Reviews + +{Track reviews here after running the oat-project-review-provide and oat-project-review-receive skills.} + +{Keep both code + artifact rows below. Add additional code rows (p03, p04, etc.) as needed, but do not delete `spec`/`design`.} + +| Scope | Type | Status | Date | Artifact | +| ------ | -------- | ------- | ---- | -------- | +| p01 | code | pending | - | - | +| p02 | code | pending | - | - | +| final | code | pending | - | - | +| spec | artifact | pending | - | - | +| design | artifact | pending | - | - | + +**Status values:** `pending` → `received` → `fixes_added` → `fixes_completed` → `passed` + +**Meaning:** + +- `received`: review artifact exists (not yet converted into fix tasks) +- `fixes_added`: fix tasks were added to the plan (work queued) +- `fixes_completed`: fix tasks implemented, awaiting re-review +- `passed`: re-review run and recorded as passing (no Critical/Important) + +--- + +## Implementation Complete + +**Summary:** + +- Phase 1: {N} tasks - {Description} +- Phase 2: {N} tasks - {Description} + +**Total: {N} tasks** + +Ready for code review and merge. + +--- + +## References + +- Design: `design.md` (required in spec-driven mode; optional in quick/import mode) +- Spec: `spec.md` (required in spec-driven mode; optional in quick/import mode) +- Discovery: `discovery.md` +- Imported Source: `references/imported-plan.md` (when `oat_plan_source: imported`) diff --git a/.oat/projects/shared/brainstorm-visual-companion-v6/state.md b/.oat/projects/shared/brainstorm-visual-companion-v6/state.md new file mode 100644 index 0000000000..ba180ed698 --- /dev/null +++ b/.oat/projects/shared/brainstorm-visual-companion-v6/state.md @@ -0,0 +1,62 @@ +--- +oat_current_task: null +oat_last_commit: null +oat_blockers: [] +associated_issues: [] # [{type: backlog|project|jira|linear, ref: "identifier"}] +oat_kind: implementation # implementation | coordination; coordination parents may use oat_phase: decomposition +oat_parent: null # optional child-only coordination parent slug +oat_siblings: [] # optional child-only sibling slugs +oat_depends_on: [] # optional child-only sibling dependencies +oat_children: [] # optional coordination-parent child slugs +oat_hill_checkpoints: { OAT_HILL_CHECKPOINTS } # Configured: which phases require human-in-the-loop lifecycle approval +oat_hill_completed: [] # Progress: which HiLL checkpoints have been completed +oat_parallel_execution: false +oat_phase: { OAT_PHASE } # Current phase: discovery | spec | design | plan | implement | decomposition +oat_phase_status: in_progress # Status: in_progress | complete | pr_open +# oat_orchestration_retry_limit: 2 # optional; override fix-loop retry limit (range 0-5) +# oat_dispatch_ceiling: # optional project override for provider-aware dispatch ceilings +# provider: codex # codex | claude +# value: high # codex: low|medium|high|xhigh; claude: haiku|sonnet|opus +# source: project-state +oat_workflow_mode: { OAT_WORKFLOW_MODE } # spec-driven | quick | import +oat_workflow_origin: native # native | imported +oat_docs_updated: null # null | skipped | complete — documentation sync status +oat_pr_status: null # null | ready | open | closed | merged — actual PR state for the current project +oat_pr_url: null # null | string — tracked PR URL when a PR exists +oat_project_created: '2026-06-26T19:52:43.792Z' # ISO 8601 UTC timestamp — set once at project creation +oat_project_completed: null # ISO 8601 UTC timestamp — set when project is completed/archived +oat_project_state_updated: '2026-06-26T19:52:43.792Z' # ISO 8601 UTC timestamp — updated on every state.md mutation +oat_generated: false +--- + +# Project State: brainstorm-visual-companion-v6 + +**Status:** Discovery +**Started:** 2026-06-26 +**Last Updated:** 2026-06-26 + +## Current Phase + +Discovery - Gathering requirements for a quick workflow before planning + +## Artifacts + +- **Discovery:** `discovery.md` (in_progress) +- **Spec:** N/A (quick mode) +- **Design:** N/A (quick mode unless lightweight design is needed) +- **Plan:** `plan.md` (scaffolded template — not started) +- **Implementation:** `implementation.md` (scaffolded template — not started) + +## Progress + +- ✓ Discovery started +- ✓ Execution artifacts scaffolded +- ⧗ Awaiting user input + +## Blockers + +None + +## Next Milestone + +Complete discovery and generate a quick implementation plan From 857d4d089d9183fe30ee2dbc0f974682ee271d03 Mon Sep 17 00:00:00 2001 From: Thomas Stang Date: Fri, 26 Jun 2026 14:54:35 -0500 Subject: [PATCH 02/23] chore(oat): quick-start discovery and plan for brainstorm-visual-companion-v6 Capture Superpowers v6.0.3 visual companion parity scope and a 9-task sequential implementation plan for the oat-brainstorm bundled server. Co-authored-by: Cursor --- .../discovery.md | 181 +++++---- .../implementation.md | 191 +--------- .../brainstorm-visual-companion-v6/plan.md | 356 +++++++++++++----- .../brainstorm-visual-companion-v6/state.md | 63 ++-- 4 files changed, 403 insertions(+), 388 deletions(-) diff --git a/.oat/projects/shared/brainstorm-visual-companion-v6/discovery.md b/.oat/projects/shared/brainstorm-visual-companion-v6/discovery.md index c82555eb24..7ad367cf86 100644 --- a/.oat/projects/shared/brainstorm-visual-companion-v6/discovery.md +++ b/.oat/projects/shared/brainstorm-visual-companion-v6/discovery.md @@ -1,6 +1,6 @@ --- -oat_status: in_progress -oat_ready_for: null +oat_status: complete +oat_ready_for: oat-project-quick-start oat_blockers: [] oat_last_updated: 2026-06-26 oat_generated: false @@ -10,133 +10,166 @@ oat_generated: false ## Phase Guardrails (Discovery) -Discovery is for requirements and decisions, not implementation details. - -- Prefer outcomes and constraints over concrete deliverables (no specific scripts, file paths, or function names). -- If an implementation detail comes up, capture it as an **Open Question** for design (or a constraint), not as a deliverable list. +Discovery captures outcomes and constraints. Implementation file names appear only where they clarify scope boundaries agreed in the prior release review. ## Initial Request -{Copy of user's initial request} +Review Superpowers GitHub releases (currently through v6.0.3) for visual brainstorming functionality that OAT has largely ported one-to-one, identify gaps worth incorporating into the OAT brainstorm skillset, and execute the work via quick-start planning (discovery + plan, no full spec-driven workflow). + +Session context: OAT's visual companion bundle was ported from **Superpowers v5.0.7** (see repo `NOTICES.md` and the `independent-brainstorming` project summary). Superpowers v6.0.0 shipped a major visual-companion security and resilience rewrite; v5.0.6 shipped server lifecycle fixes OAT already has; v6.0.3 is SDD-only and out of scope here. ## Clarifying Questions -### Question 1: {Topic} +### Question 1: Workflow shape + +**Q:** Proceed without OAT project tracking, or use quick-start to capture discovery and a plan? + +**A:** Use OAT quick start — capture discovery and write a plan. + +**Decision:** This project (`brainstorm-visual-companion-v6`) tracks the work; implementation follows `plan.md` via `oat-project-implement`. + +### Question 2: Scope boundary + +**Q:** What belongs in this project vs. other OAT skills? -**Q:** {Question} -**A:** {User's answer} -**Decision:** {What this means for the project} +**A:** (Inferred from release review and user focus on visual brainstorming.) + +**Decision:** Primary scope is the **visual companion Node bundle** and its **skill/reference docs** under `oat-brainstorm`. Superpowers SDD, writing-plans, harness bootstraps, and brainstorming→writing-plans terminal flow are out of scope. Optional skill-content improvements (e.g. synthesis self-review) are deferred unless trivial. ## Solution Space -_Include this section only when the request is exploratory or multiple viable approaches exist. For well-understood requests with an obvious approach, omit or replace with a single sentence stating the chosen direction._ +OAT already diverges productively from upstream: Activation Contract, pack-aware destinations, conditional visual offer, and OAT persistence paths (`.oat/brainstorm/`). The gap is **technical parity** with Superpowers v6.0.x for the local web server, not re-adopting Superpowers' single-pipeline brainstorm model. + +### Approach 1: Full v6.0.3 bundle port with OAT path adaptations _(Recommended)_ + +**Description:** Cherry-pick Superpowers v6.0.3 visual-companion scripts (`server.cjs`, `helper.js`, `start-server.sh`, `stop-server.sh`, `frame-template.html`) and adapt persistence/token paths from `.superpowers/brainstorm/` to OAT conventions (`.oat/brainstorm/.last-port`, `.last-token`, repo walk-up, user-scope fallback). Update `references/visual-companion.md` and `SKILL.md` step 3 for session keys, `--open`, restart semantics, and 4h idle default. + +**When this is the right choice:** Security and reconnect behavior are the headline v6 changes; partial ports leave known vulnerabilities and brittle restarts. + +**Tradeoffs:** Breaks byte-for-byte parity with v5.0.7 (document in `NOTICES.md`). Touches publishable bundled assets → lockstep public package version bump and `pnpm release:validate`. + +### Approach 2: Security-only minimal patch + +**Description:** Port only session-key auth, file sandbox, and security headers into existing OAT files without full helper/start-server v6 features. -{Divergent exploration of the problem space before converging on an approach. Capture genuinely distinct strategies, not minor variations. Include 2-3 approaches as needed.} +**When this is the right choice:** If schedule is extremely tight and resilience features can wait. -### Approach 1: {Strategy Name} _(Recommended)_ +**Tradeoffs:** Leaves restart persistence, stop-server instance-ID guard, status pill/tombstone UI, and Windows hardening gaps; higher merge cost later. -**Description:** {What this approach involves} -**When this is the right choice:** {Conditions under which this approach is best} -**Tradeoffs:** {What you give up by choosing this} +### Approach 3: Reimplement from scratch in OAT CLI -### Approach 2: {Strategy Name} +**Description:** Move server into `packages/cli` as `oat brainstorm visual-server` with TypeScript. -**Description:** {What this approach involves} -**When this is the right choice:** {Conditions under which this approach is best} -**Tradeoffs:** {What you give up by choosing this} +**When this is the right choice:** Long-term if the bash/Node bundle becomes unmaintainable. + +**Tradeoffs:** Large scope; contradicts "ported not reimplemented" decision in `independent-brainstorming`; not justified for this increment. ### Chosen Direction -**Approach:** {Which approach was selected} -**Rationale:** {Why this approach over the alternatives} -**User validated:** {Yes/No — explicit buy-in before proceeding} +**Approach:** Full v6.0.3 bundle port with OAT path adaptations (Approach 1). -## Options Considered +**Rationale:** v6 security model closes real local/remote exposure; resilience features match how agents actually use long brainstorm sessions; upstream MIT code is battle-tested. OAT-specific path and offer semantics stay as-is. -{Specific implementation options within the chosen approach. More granular than Solution Space — captures decisions about libraries, patterns, data formats, etc.} +**User validated:** Yes — user chose quick-start to plan this work after the release review. + +## Options Considered -### Option A: {Option Name} +### Option A: Pin upstream at v6.0.3 tag -**Description:** {What this option involves} +**Description:** Copy files from `obra/superpowers` tag `v6.0.3` and apply mechanical `.superpowers` → `.oat` substitutions plus repo/user persistence rules from current OAT `start-server.sh`. **Pros:** -- {Benefit 1} -- {Benefit 2} +- Clear provenance line in `NOTICES.md` +- Matches release notes the review was based on **Cons:** -- {Drawback 1} -- {Drawback 2} +- Must re-apply OAT-only behaviors (repo walk-up, `~/.oat/brainstorm/` fallback, Codex foreground auto-detect) + +**Chosen:** A + +**Summary:** Port from v6.0.3 tag; preserve OAT persistence resolution order from current bundle. + +### Option B: Skip Superpowers telemetry/branding -**Chosen:** {A/B/Neither} +**Description:** Omit upstream telemetry hooks and Superpowers logo URLs when adapting `server.cjs`. -**Summary:** {1-2 sentence summary of the chosen option and why} +**Pros:** Keeps OAT neutral branding (frame template already says "Superpowers Brainstorming" — may rebrand to OAT in same pass) + +**Cons:** Minor diff from upstream + +**Chosen:** B for telemetry; rebrand frame header to OAT in the same implementation phase (cosmetic, low risk). ## Key Decisions -1. **{Decision Category}:** {Decision made and why} -2. **{Decision Category}:** {Decision made and why} +1. **Upstream version target:** Superpowers **v6.0.3** visual-companion scripts and docs (brainstorming skill server bundle only). +2. **OAT persistence:** Keep three-tier resolution (`--project-dir` → repo `.oat/` walk-up → `~/.oat/brainstorm/`); store `.last-port` / `.last-token` under the same prefix as sessions (repo or user scope), not `.superpowers/`. +3. **Skill behavior preserved:** Do not regress Activation Contract, conditional visual offer, or destination dispatcher — only update companion startup/usage prose and flags (`--open`, same `--project-dir` on restart). +4. **Publishable guardrail:** Bundled skill asset changes require lockstep bump of all five public packages and `pnpm release:validate` before merge. +5. **Testing:** Extend existing `visual-companion-smoke.test.ts` for session key, restart reuse, and stop-server instance-ID behavior. +6. **Deferred:** Inline synthesis self-review in `oat-brainstorm` step 8 (Superpowers v5.0.6 brainstorming skill change) — already lives in `oat-project-design`; not required for visual parity. ## Constraints -- {Constraint 1} -- {Constraint 2} +- Minimize scope: visual bundle + references + smoke tests + NOTICES/version/docs touchpoints only. +- Do not reformat upstream script files for oxfmt (existing ignore patterns for bundled scripts). +- Provider-linked skill views sync from `.agents/skills/oat-brainstorm/` via normal OAT sync — canonical edits under `.agents/skills/`. +- Live dogfood (`bl-7d5b`) remains a follow-up; this project delivers the port and automated smoke coverage. ## Success Criteria -- {Criterion 1} -- {Criterion 2} +- Visual companion requires session key on HTTP and WebSocket; file server rejects traversal/symlinks/dotfiles; security headers present. +- Restart with same `--project-dir` (or same repo context) reuses port/key so browser tab reconnects. +- Idle default 4 hours (configurable via `--idle-timeout-minutes`); stop-server verifies server instance ID before kill. +- Client shows connection status and paused overlay after extended disconnect (v6 helper behavior). +- `SKILL.md` and `visual-companion.md` document key URL, `--open`, restart, and idle semantics. +- `pnpm test` visual-companion smoke passes; `pnpm release:validate` passes after version bump. +- `NOTICES.md` updated to reference Superpowers v6.0.3 adapted port (no longer claims byte-for-byte v5.0.7 for all files). ## Out of Scope -- {Thing we explicitly decided not to do} -- {Thing we explicitly decided not to include in this phase} +- Superpowers subagent-driven development, writing-plans, task-reviewer, SDD workspace changes (v6.0.0–v6.0.3 non-visual release notes). +- Harness-specific bootstrap/tool-mapping (Kimi, Pi, Antigravity, Copilot SessionStart). +- Replacing OAT destination model with Superpowers design→spec→writing-plans pipeline. +- `oat brainstorm visual-server` CLI wrapper (deferred in original project; raw scripts remain). +- Live LLM dogfood scenarios (`bl-7d5b`) — separate backlog item. +- Synthesis self-review checklist in `oat-brainstorm` step 8 (deferred). ## Deferred Ideas -{Ideas that came up during discovery but are intentionally out of scope for now} - -- {Idea 1} - {Why deferred} -- {Idea 2} - {Why deferred} +- **Synthesis self-review before handoff** — Superpowers v5.0.6 inline spec self-review adapted for `oat-brainstorm` step 8; low priority once visual parity ships. +- **CLI wrapper for visual server** — convenience command; not needed for parity. +- **Frame template full OAT visual rebrand** — beyond header text if design wants a distinct theme. ## Open Questions -{Questions that need resolution before or during specification (and later design)} - -- **{Question Category}:** {Question that needs answering} -- **{Question Category}:** {Question that needs answering} +- **User-scope token persistence:** When fallback is `~/.oat/brainstorm/`, should `.last-port`/`.last-token` live at `~/.oat/brainstorm/` root (mirroring repo layout)? **Assumption:** yes, for symmetric restart behavior outside a repo. +- **Frame title branding:** Rename "Superpowers Brainstorming" to "OAT Brainstorm" in frame template during port? **Assumption:** yes, cosmetic alignment with OAT product. ## Assumptions -{Assumptions we're making that need validation} - -- {Assumption 1} -- {Assumption 2} +- Superpowers v6.0.3 `skills/brainstorming/scripts/*` is the canonical upstream source set. +- Existing smoke test harness can assert keyed URLs and auth rejection without a full browser. +- No breaking change to agent workflows beyond requiring agents to use the keyed URL from `server-started` JSON (already how v6 upstream works). ## Risks -{Potential risks identified during discovery} +- **Regression in OAT persistence paths** + - **Likelihood:** Medium + - **Impact:** Medium + - **Mitigation:** Preserve current smoke tests for repo/user/`--project-dir` paths; add restart/key tests. + +- **Publishable release validation failure** + - **Likelihood:** Low + - **Impact:** High (blocks merge) + - **Mitigation:** Plan includes lockstep version bump + `pnpm release:validate` task. -- **{Risk Name}:** {Description} - - **Likelihood:** Low / Medium / High - - **Impact:** Low / Medium / High - - **Mitigation Ideas:** {How to address} +- **Provider skill sync drift** + - **Likelihood:** Low + - **Impact:** Low + - **Mitigation:** Bump `oat-brainstorm` skill `version:` in frontmatter; run `oat sync --scope all` before PR if needed. ## Next Steps -Use this discovery artifact to drive the next workflow step: - -- **Spec-driven mode:** continue to `oat-project-design` (which confirms - requirements and produces both `spec.md` and `design.md`). -- **Spec-driven mode → formalize-only:** use `oat-project-spec` standalone - if you want a formalized requirements artifact but aren't ready to - design yet. -- **Quick mode → straight to plan:** proceed directly to `plan.md` when - scope is clear and no architecture decisions remain. -- **Quick mode → optional lightweight design:** produce a focused - `design.md` (architecture, components, data flow, testing) before - planning. Choose this when discovery surfaced architecture choices - or component boundaries. -- **Quick mode → promote:** escalate to spec-driven if discovery revealed - the scope is larger or more complex than expected. +Proceed to quick-start **plan generation** (straight to plan — architecture is understood from release review; lightweight design skipped by user intent). diff --git a/.oat/projects/shared/brainstorm-visual-companion-v6/implementation.md b/.oat/projects/shared/brainstorm-visual-companion-v6/implementation.md index a6b1dc4184..da2580d6a8 100644 --- a/.oat/projects/shared/brainstorm-visual-companion-v6/implementation.md +++ b/.oat/projects/shared/brainstorm-visual-companion-v6/implementation.md @@ -9,202 +9,35 @@ oat_generated: false # Implementation: brainstorm-visual-companion-v6 -**Started:** 2026-06-26 +**Started:** (pending) **Last Updated:** 2026-06-26 -> This document is used to resume interrupted implementation sessions. -> -> Conventions: -> -> - `oat_current_task_id` always points at the **next plan task to do** (not the last completed task). -> - When all plan tasks are complete, set `oat_current_task_id: null`. -> - Reviews are **not** plan tasks. Track review status in `plan.md` under `## Reviews` (e.g., `| final | code | passed | ... |`). -> - Keep phase/task statuses consistent with the Progress Overview table so restarts resume correctly. -> - Before running the `oat-project-pr-final` skill, ensure `## Final Summary (for PR/docs)` is filled with what was actually implemented. +> Resume pointer: `oat_current_task_id: p01-t01` ## Progress Overview -| Phase | Status | Tasks | Completed | -| ------- | ----------- | ----- | --------- | -| Phase 1 | in_progress | N | 0/N | -| Phase 2 | pending | N | 0/N | +| Phase | Status | Tasks | Completed | +| ------- | ------- | ----- | --------- | +| Phase 1 | pending | 4 | 0/4 | +| Phase 2 | pending | 2 | 0/2 | +| Phase 3 | pending | 2 | 0/2 | +| Phase 4 | pending | 1 | 0/1 | -**Total:** 0/{N} tasks completed +**Total:** 0/9 tasks completed --- -## Phase 1: {Phase Name} - -**Status:** in_progress -**Started:** 2026-06-26 - -### Phase Summary (fill when phase is complete) - -**Outcome (what changed):** - -- {2-5 bullets describing user-visible / behavior-level changes delivered in this phase} - -**Key files touched:** - -- `{path}` - {why} - -**Verification:** - -- Run: `{command(s)}` -- Result: {pass/fail + notes} - -**Notes / Decisions:** - -- {trade-offs or deviations discovered during implementation} - -### Task p01-t01: {Task Name} - -**Status:** completed / in_progress / pending / blocked -**Commit:** {sha} (if completed) - -**Outcome (required when completed):** - -- {what materially changed (not “did task”, but “system now does X”)} - -**Files changed:** - -- `{path}` - {why} - -**Verification:** - -- Run: `{command(s)}` -- Result: {pass/fail + notes} - -**Notes / Decisions:** - -- {gotchas, trade-offs, design deltas, important context for future sessions} - -**Issues Encountered:** - -- {Issue and resolution} - ---- - -### Task p01-t02: {Task Name} +## Phase 1: Port Superpowers v6 visual bundle **Status:** pending -**Commit:** - -**Notes:** - -- {Notes will be added during implementation} - ---- - -## Phase 2: {Phase Name} +### Task p01-t01: Import and adapt server.cjs **Status:** pending -**Started:** - - -### Task p02-t01: {Task Name} - -**Status:** pending -**Commit:** - - ---- - -## Orchestration Runs - -_Each run from `oat-project-implement` appends an entry below with:_ -_- Run header (number, timestamp, branch, tier, policy, phase counts)_ -_- Phase Outcomes table_ -_- Parallel Groups list_ -_- Outstanding Items_ - - - -_Orchestration runs from `oat-project-implement` are appended here, most-recent-first within the file but append-only at the bottom of the log._ - - --- -## Implementation Log - -Chronological log of implementation progress. - -### 2026-06-26 - -**Session Start:** {time} - -- [x] p01-t01: {Task name} - {commit sha} -- [ ] p01-t02: {Task name} - in progress - -**What changed (high level):** - -- {short bullets suitable for PR/docs} - -**Decisions:** - -- {Decision made and rationale} - -**Follow-ups / TODO:** - -- {anything discovered during implementation that should be captured for later} - -**Blockers:** - -- {Blocker description} - {status: resolved/pending} - -**Session End:** {time} - ---- - -### 2026-06-26 - -**Session Start:** {time} - -{Continue log...} - ---- - -## Deviations from Plan / Design - -Document any intentional deviations from the original plan, spec, or design. Include accepted review findings where the shipped implementation is source of truth and a lifecycle artifact needs alignment. - -| Task / Review | Source Artifact | Planned / Documented | Actual / Accepted | Reason | Source of Truth | Follow-up | -| ------------- | --------------- | -------------------- | ----------------- | ------ | --------------- | --------- | -| - | - | - | - | - | - | - | - -## Test Results - -Track test execution during implementation. - -| Phase | Tests Run | Passed | Failed | Coverage | -| ----- | --------- | ------ | ------ | -------- | -| 1 | - | - | - | - | -| 2 | - | - | - | - | - -## Final Summary (for PR/docs) - -**What shipped:** - -- {capability 1} -- {capability 2} - -**Behavioral changes (user-facing):** - -- {bullet} - -**Key files / modules:** - -- `{path}` - {purpose} - -**Verification performed:** - -- {tests/lint/typecheck/build/manual steps} - -**Design deltas (if any):** - -- {what changed vs design.md and why} - ## References - Plan: `plan.md` -- Design: `design.md` -- Spec: `spec.md` +- Discovery: `discovery.md` diff --git a/.oat/projects/shared/brainstorm-visual-companion-v6/plan.md b/.oat/projects/shared/brainstorm-visual-companion-v6/plan.md index dc8db6d215..33a24f1f9e 100644 --- a/.oat/projects/shared/brainstorm-visual-companion-v6/plan.md +++ b/.oat/projects/shared/brainstorm-visual-companion-v6/plan.md @@ -1,185 +1,335 @@ --- -oat_status: in_progress -oat_ready_for: null +oat_status: complete +oat_ready_for: oat-project-implement oat_blockers: [] oat_last_updated: 2026-06-26 oat_phase: plan -oat_phase_status: in_progress -oat_plan_hill_phases: [] # phases to pause AFTER completing (empty = every phase) -oat_plan_parallel_groups: [] # groups of phases that run concurrently in worktrees; [] = fully sequential -oat_plan_source: spec-driven # spec-driven | quick | imported -oat_import_reference: null # e.g., references/imported-plan.md -oat_import_source_path: null # original source path provided by user -oat_import_provider: null # codex | cursor | claude | null +oat_phase_status: complete +oat_plan_hill_phases: [] +oat_plan_parallel_groups: [] +oat_plan_source: quick +oat_import_reference: null +oat_import_source_path: null +oat_import_provider: null oat_generated: false --- # Implementation Plan: brainstorm-visual-companion-v6 -> Execute this plan using `oat-project-implement` — sequential by default, parallel when `oat_plan_parallel_groups` is declared. +> Execute this plan using `oat-project-implement`. -**Goal:** {Brief goal statement from spec} +**Goal:** Bring OAT's `oat-brainstorm` visual companion to parity with Superpowers v6.0.3 security, resilience, and lifecycle behavior while preserving OAT persistence paths and conditional-offer skill semantics. -**Architecture:** {1-2 sentence architecture summary from design} +**Architecture:** Replace the v5.0.7 Node/bash bundle under `.agents/skills/oat-brainstorm/scripts/` with an adapted Superpowers v6.0.3 port (session-key auth, sandboxed static serving, port/token persistence, resilient client UI, safe stop-server). Update skill/reference prose and integration smoke tests; bump bundled-asset version metadata and run release validation. -**Tech Stack:** {Key technologies from design} +**Tech Stack:** Node.js (server.cjs), bash (start/stop scripts), HTML/JS (frame + helper), Vitest integration smoke test, OAT skill frontmatter, lockstep npm packages. -**Commit Convention:** `{type}({scope}): {description}` - e.g., `feat(p01-t01): add user auth endpoint` +**Commit Convention:** `feat(pNN-tNN): {description}` for functional port tasks; `chore(pNN-tNN): {description}` for bookkeeping/docs/version tasks. ## Planning Checklist -- [ ] Confirmed HiLL checkpoints with user -- [ ] Set `oat_plan_hill_phases` in frontmatter -- [ ] Evaluated phases for parallelism opportunities -- [ ] Set `oat_plan_parallel_groups` in frontmatter +- [x] Confirmed HiLL checkpoints with user (none — quick mode, empty `oat_plan_hill_phases`) +- [x] Set `oat_plan_hill_phases` in frontmatter +- [x] Evaluated phases for parallelism opportunities +- [x] Set `oat_plan_parallel_groups` in frontmatter (sequential — shared skill directory) --- ## Parallelism -Phases that have no overlapping file modifications may run concurrently. To declare parallelism: +All phases modify the same skill bundle or its tests/docs. Phases run **sequentially** (`oat_plan_parallel_groups: []`). Phase 1 must land before smoke tests in Phase 3 can assert v6 behavior. -```yaml -oat_plan_parallel_groups: [['p02', 'p03']] -``` +--- -Each inner array is a group of phases that execute in parallel (each in its own worktree) and merge back in plan order after all pass. Groups themselves run sequentially. +## Phase 1: Port Superpowers v6 visual bundle -Default is `[]` (fully sequential, no worktrees). Only declare parallelism when phases are genuinely file-disjoint — overlap will produce merge conflicts that stop the run. +### Task p01-t01: Import and adapt server.cjs ---- +**Files:** + +- Modify: `.agents/skills/oat-brainstorm/scripts/server.cjs` + +**Step 1: Baseline check (RED)** -## Dispatch Profile +Run: `pnpm exec vitest run packages/cli/src/integration/visual-companion-smoke.test.ts` +Expected: Current tests pass on v5.0.7 baseline (establishes green before port). -_Optional override surface. Use only for explicit user-authored constraints or preferences. Omit this section when runtime selection should choose the lowest confident tier._ +**Step 2: Port v6 server (GREEN)** -Blank or `auto` means there is no explicit constraint for that provider. Do not generate rows by default; a missing phase row uses runtime selection. +Copy `skills/brainstorming/scripts/server.cjs` from `obra/superpowers` tag `v6.0.3` and adapt: -| Phase | Claude model | Codex effort | Rationale | -| ----- | ------------------------- | ------------------------------ | ----------------------------- | -| pNN | haiku\|sonnet\|opus\|auto | low\|medium\|high\|xhigh\|auto | why this constraint is needed | +- Session-key auth on HTTP + WebSocket (`?key=`, cookie bootstrap) +- Sandboxed `/files/` serving (no symlinks, dotfiles, traversal) +- Security headers (`Cache-Control: no-store`, `X-Frame-Options: DENY`) +- Configurable idle timeout via `BRAINSTORM_IDLE_TIMEOUT_MS` (default 4h) +- Port reuse via `BRAINSTORM_PORT_FILE` +- WebSocket max frame size guard +- Omit Superpowers telemetry/branding hooks -Codex effort values are preferred controls. `oat-project-implement` caps them against the resolved OAT dispatch ceiling and maps selected efforts to pinned implementer variants. Codex provider default effort is informational for base/unpinned roles and is not an OAT ceiling. +Preserve OAT `CONTENT_DIR` / `STATE_DIR` layout and existing JSON log events consumed by agents. + +**Step 3: Verify** + +Run: `node --check .agents/skills/oat-brainstorm/scripts/server.cjs` +Expected: Syntax OK. + +**Step 4: Commit** + +```bash +git add .agents/skills/oat-brainstorm/scripts/server.cjs +git commit -m "feat(p01-t01): port v6 visual companion server with session auth" +``` --- -## Phase 1: {Phase Name} +### Task p01-t02: Port helper.js and frame-template.html -### Task p01-t01: {Task Name} +**Files:** + +- Modify: `.agents/skills/oat-brainstorm/scripts/helper.js` +- Modify: `.agents/skills/oat-brainstorm/scripts/frame-template.html` + +**Step 1: Port client resilience (GREEN)** + +From v6.0.3: + +- Session key in WebSocket URL from `sessionStorage` +- Status pill states (connecting/connected/reconnecting/disconnected) +- Exponential backoff reconnect + paused overlay after disconnect +- Keyed reload after server recovery + +Update frame template header branding to **OAT Brainstorm** (remove Superpowers title); ensure `.status` element matches helper expectations. + +**Step 2: Verify** + +Manual: grep frame for `.status` and helper for `setStatus` — both present. + +**Step 3: Commit** + +```bash +git add .agents/skills/oat-brainstorm/scripts/helper.js .agents/skills/oat-brainstorm/scripts/frame-template.html +git commit -m "feat(p01-t02): port v6 companion client UI and OAT frame branding" +``` + +--- + +### Task p01-t03: Adapt start-server.sh for OAT persistence + v6 flags **Files:** -- Create: `{path/to/file.ts}` -- Modify: `{path/to/existing.ts}` +- Modify: `.agents/skills/oat-brainstorm/scripts/start-server.sh` + +**Step 1: Port v6 launcher behaviors (GREEN)** + +Merge v6.0.3 `start-server.sh` capabilities with OAT persistence resolution: -**Step 1: Write test (RED)** +1. `--project-dir` → `/.oat/brainstorm//` and `/.oat/brainstorm/.last-port` + `.last-token` +2. Repo walk-up → `/.oat/brainstorm/...` +3. Fallback → `~/.oat/brainstorm/...` with token files at `~/.oat/brainstorm/.last-port` / `.last-token` -```typescript -// {path/to/file.test.ts} -describe('{feature}', () => { - it('{test case}', () => { - // Test implementation - }); -}); +Add v6 flags: `--open`, `--idle-timeout-minutes`, `umask 077`, `server-instance-id`, Windows `is_windows_like_shell` + clear `OWNER_PID`, pass `--brainstorm-server-id` to node. + +**Step 2: Verify** + +Run: `bash -n .agents/skills/oat-brainstorm/scripts/start-server.sh` +Expected: No syntax errors. + +**Step 3: Commit** + +```bash +git add .agents/skills/oat-brainstorm/scripts/start-server.sh +git commit -m "feat(p01-t03): adapt v6 start-server for OAT paths and restart reuse" ``` -Run: `pnpm --filter {package-name} exec vitest run {path/to/file.test.ts}` -Expected: Test fails (RED) +--- + +### Task p01-t04: Port stop-server.sh instance-ID guard + +**Files:** + +- Modify: `.agents/skills/oat-brainstorm/scripts/stop-server.sh` + +**Step 1: Port safe shutdown (GREEN)** -**Step 2: Implement (GREEN)** +From v6.0.3: verify PID carries matching `--brainstorm-server-id` before signaling; write `server-stopped` marker; keep OAT behavior of retaining persistent session dirs (not only `/tmp`). -```typescript -// {path/to/file.ts} -// Implementation code or interface signatures +**Step 2: Verify** + +Run: `bash -n .agents/skills/oat-brainstorm/scripts/stop-server.sh` +Expected: No syntax errors. + +**Step 3: Commit** + +```bash +git add .agents/skills/oat-brainstorm/scripts/stop-server.sh +git commit -m "feat(p01-t04): port v6 stop-server instance verification" ``` -Run: `pnpm --filter {package-name} exec vitest run {path/to/file.test.ts}` -Expected: Test passes (GREEN) +--- -Use the actual runner command that scopes to the intended file or test target. Do not write a package-level shortcut unless it truly executes only the scope the task claims. +## Phase 2: Update skill and reference docs -**Step 3: Refactor** +### Task p02-t01: Update visual-companion.md -{Any cleanup or improvements while tests stay green} +**Files:** + +- Modify: `.agents/skills/oat-brainstorm/references/visual-companion.md` + +**Step 1: Align reference with v6 behavior (GREEN)** + +Document: + +- Session key in URL and cookie auth requirement +- `--open` after user accepts companion +- Restart with same `--project-dir`/repo context reuses port/key (no new URL) +- 4h idle default and `--idle-timeout-minutes` +- Paused overlay / reconnect behavior +- Pre-flight alive check before pushing screens + +Keep OAT persistence path examples (`.oat/brainstorm/`, user-scope fallback). -**Step 4: Verify** +**Step 2: Verify** -Run: `pnpm lint && pnpm type-check` -Expected: No errors +Run: `pnpm oat:validate-skills` (or repo equivalent skill validation) +Expected: Skill pack validates. -**Step 5: Commit** +**Step 3: Commit** ```bash -git add {files} -git commit -m "feat(p01-t01): {description}" +git add .agents/skills/oat-brainstorm/references/visual-companion.md +git commit -m "docs(p02-t01): document v6 visual companion behavior in reference" ``` --- -### Task p01-t02: {Task Name} +### Task p02-t02: Update oat-brainstorm SKILL.md step 3 **Files:** -- {File list} +- Modify: `.agents/skills/oat-brainstorm/SKILL.md` + +**Step 1: Update activation/handoff prose (GREEN)** + +In Step 3 (visual companion offer/accept): + +- On accept, pass `--open` when starting server (after user approval) +- Instruct agent to preserve keyed URL from JSON; restart with same path resolution +- Note 4h idle / restart semantics +- Bump skill frontmatter `version:` (required for skill change) + +Do **not** change Activation Contract or destination logic. + +**Step 2: Verify** -**Step 1: Write test (RED)** +Run: `pnpm oat:validate-skills` +Expected: Pass including version/frontmatter checks. -{Test code} +**Step 3: Commit** -**Step 2: Implement (GREEN)** +```bash +git add .agents/skills/oat-brainstorm/SKILL.md +git commit -m "docs(p02-t02): align brainstorm skill with v6 companion startup" +``` + +--- + +## Phase 3: Tests and release validation -{Implementation code or signatures} +### Task p03-t01: Extend visual-companion smoke tests -**Step 3: Refactor** +**Files:** -{Optional cleanup} +- Modify: `packages/cli/src/integration/visual-companion-smoke.test.ts` -**Step 4: Verify** +**Step 1: Add failing assertions (RED)** -Run: `{verification command}` -Expected: {output} +Add cases for: -Verification commands should be behaviorally accurate. If the task claims a file-scoped or test-scoped check, use the concrete runner invocation that really scopes to that target. +- `server-started` JSON includes keyed URL (`?key=`) +- Unauthenticated GET `/` returns 401/403 (per server behavior) +- Restart with same `--project-dir` reuses port (read `.last-port`) +- `stop-server.sh` refuses stale/wrong instance (mock or integration-safe check) -**Step 5: Commit** +**Step 2: Implement until green (GREEN)** + +Run: `pnpm exec vitest run packages/cli/src/integration/visual-companion-smoke.test.ts` +Expected: All tests pass. + +**Step 3: Commit** ```bash -git add {files} -git commit -m "feat(p01-t02): {description}" +git add packages/cli/src/integration/visual-companion-smoke.test.ts +git commit -m "test(p03-t01): cover v6 visual companion auth and restart behavior" ``` --- -## Phase 2: {Phase Name} +### Task p03-t02: NOTICES, lockstep versions, release validate + +**Files:** + +- Modify: `NOTICES.md` +- Modify: `.agents/skills/oat-brainstorm/SKILL.md` (version if not done in p02-t02) +- Modify: `packages/cli/package.json`, `packages/control-plane/package.json`, `packages/docs-config/package.json`, `packages/docs-theme/package.json`, `packages/docs-transforms/package.json` (lockstep bump) -### Task p02-t01: {Task Name} +**Step 1: Update provenance (GREEN)** -{Continue TDD pattern...} +`NOTICES.md`: change referenced Superpowers version to v6.0.3; note adapted port (no longer byte-for-byte v5.0.7 for all script files). + +Bump all five public packages together per repo guardrail. + +**Step 2: Verify** + +Run: `pnpm release:validate` +Expected: Pass. + +Run: `pnpm test --filter visual-companion-smoke` or full `pnpm test` if fast enough +Expected: Pass. + +**Step 3: Commit** + +```bash +git add NOTICES.md packages/cli/package.json packages/control-plane/package.json packages/docs-config/package.json packages/docs-theme/package.json packages/docs-transforms/package.json +git commit -m "chore(p03-t02): record v6 port provenance and bump public packages" +``` --- -## Reviews +## Phase 4: Optional docs touchpoint + +### Task p04-t01: Update tool-packs docs if companion behavior changed materially + +**Files:** + +- Modify: `apps/oat-docs/docs/cli-utilities/tool-packs.md` (only if step 3 / security semantics need user-facing mention) + +**Step 1: Assess diff** -{Track reviews here after running the oat-project-review-provide and oat-project-review-receive skills.} +If brainstorm pack section still accurate after p02 changes, skip with note in implementation log. -{Keep both code + artifact rows below. Add additional code rows (p03, p04, etc.) as needed, but do not delete `spec`/`design`.} +**Step 2: Update if needed (GREEN)** -| Scope | Type | Status | Date | Artifact | -| ------ | -------- | ------- | ---- | -------- | -| p01 | code | pending | - | - | -| p02 | code | pending | - | - | -| final | code | pending | - | - | -| spec | artifact | pending | - | - | -| design | artifact | pending | - | - | +Add brief note: session-key URL, `--open`, restart reuse — only if missing. -**Status values:** `pending` → `received` → `fixes_added` → `fixes_completed` → `passed` +Run: `pnpm build:docs` (if docs changed) +Expected: Build passes. -**Meaning:** +**Step 3: Commit (if changed)** + +```bash +git add apps/oat-docs/docs/cli-utilities/tool-packs.md +git commit -m "docs(p04-t01): note v6 visual companion security and restart behavior" +``` + +If skipped: record "skipped — no user-facing doc delta" in `implementation.md`. + +--- + +## Reviews -- `received`: review artifact exists (not yet converted into fix tasks) -- `fixes_added`: fix tasks were added to the plan (work queued) -- `fixes_completed`: fix tasks implemented, awaiting re-review -- `passed`: re-review run and recorded as passing (no Critical/Important) +| Cycle | Scope | Status | Date | Notes | +| ----- | ----- | ------- | ---------- | -------------------------------------------- | +| plan | plan | pending | 2026-06-26 | Run artifact review before implement handoff | --- @@ -187,18 +337,20 @@ git commit -m "feat(p01-t02): {description}" **Summary:** -- Phase 1: {N} tasks - {Description} -- Phase 2: {N} tasks - {Description} +- Phase 1: 4 tasks — v6 server bundle port with OAT paths +- Phase 2: 2 tasks — skill/reference doc alignment +- Phase 3: 2 tasks — smoke tests + release validation +- Phase 4: 1 task — optional docs touchpoint -**Total: {N} tasks** +**Total: 9 tasks** -Ready for code review and merge. +Ready for `oat-project-implement`. --- ## References -- Design: `design.md` (required in spec-driven mode; optional in quick/import mode) -- Spec: `spec.md` (required in spec-driven mode; optional in quick/import mode) - Discovery: `discovery.md` -- Imported Source: `references/imported-plan.md` (when `oat_plan_source: imported`) +- Upstream: https://github.com/obra/superpowers/releases (v6.0.0 visual companion notes; v6.0.3 tag for file source) +- Prior OAT project: `.oat/repo/reference/project-summaries/20260507-independent-brainstorming.md` +- Live dogfood follow-up: `.oat/repo/reference/backlog/items/live-dogfood-oat-brainstorm.md` (`bl-7d5b`) diff --git a/.oat/projects/shared/brainstorm-visual-companion-v6/state.md b/.oat/projects/shared/brainstorm-visual-companion-v6/state.md index ba180ed698..3e3d20f685 100644 --- a/.oat/projects/shared/brainstorm-visual-companion-v6/state.md +++ b/.oat/projects/shared/brainstorm-visual-companion-v6/state.md @@ -2,56 +2,53 @@ oat_current_task: null oat_last_commit: null oat_blockers: [] -associated_issues: [] # [{type: backlog|project|jira|linear, ref: "identifier"}] -oat_kind: implementation # implementation | coordination; coordination parents may use oat_phase: decomposition -oat_parent: null # optional child-only coordination parent slug -oat_siblings: [] # optional child-only sibling slugs -oat_depends_on: [] # optional child-only sibling dependencies -oat_children: [] # optional coordination-parent child slugs -oat_hill_checkpoints: { OAT_HILL_CHECKPOINTS } # Configured: which phases require human-in-the-loop lifecycle approval -oat_hill_completed: [] # Progress: which HiLL checkpoints have been completed +associated_issues: [] +oat_kind: implementation +oat_parent: null +oat_siblings: [] +oat_depends_on: [] +oat_children: [] +oat_hill_checkpoints: [] +oat_hill_completed: [] oat_parallel_execution: false -oat_phase: { OAT_PHASE } # Current phase: discovery | spec | design | plan | implement | decomposition -oat_phase_status: in_progress # Status: in_progress | complete | pr_open -# oat_orchestration_retry_limit: 2 # optional; override fix-loop retry limit (range 0-5) -# oat_dispatch_ceiling: # optional project override for provider-aware dispatch ceilings -# provider: codex # codex | claude -# value: high # codex: low|medium|high|xhigh; claude: haiku|sonnet|opus -# source: project-state -oat_workflow_mode: { OAT_WORKFLOW_MODE } # spec-driven | quick | import -oat_workflow_origin: native # native | imported -oat_docs_updated: null # null | skipped | complete — documentation sync status -oat_pr_status: null # null | ready | open | closed | merged — actual PR state for the current project -oat_pr_url: null # null | string — tracked PR URL when a PR exists -oat_project_created: '2026-06-26T19:52:43.792Z' # ISO 8601 UTC timestamp — set once at project creation -oat_project_completed: null # ISO 8601 UTC timestamp — set when project is completed/archived -oat_project_state_updated: '2026-06-26T19:52:43.792Z' # ISO 8601 UTC timestamp — updated on every state.md mutation +oat_phase: plan +oat_phase_status: complete +oat_workflow_mode: quick +oat_workflow_origin: native +oat_docs_updated: null +oat_pr_status: null +oat_pr_url: null +oat_project_created: '2026-06-26T19:52:43.792Z' +oat_project_completed: null +oat_project_state_updated: '2026-06-26T20:00:00.000Z' oat_generated: false --- # Project State: brainstorm-visual-companion-v6 -**Status:** Discovery +**Status:** Plan complete — ready for implementation **Started:** 2026-06-26 **Last Updated:** 2026-06-26 ## Current Phase -Discovery - Gathering requirements for a quick workflow before planning +Plan — complete. Hand off to `oat-project-implement`. ## Artifacts -- **Discovery:** `discovery.md` (in_progress) +- **Discovery:** `discovery.md` (complete) - **Spec:** N/A (quick mode) -- **Design:** N/A (quick mode unless lightweight design is needed) -- **Plan:** `plan.md` (scaffolded template — not started) -- **Implementation:** `implementation.md` (scaffolded template — not started) +- **Design:** N/A (skipped — scope clear from release review) +- **Plan:** `plan.md` (complete, `oat_ready_for: oat-project-implement`) +- **Implementation:** `implementation.md` (initialized) ## Progress -- ✓ Discovery started -- ✓ Execution artifacts scaffolded -- ⧗ Awaiting user input +- ✓ Project scaffolded (quick mode) +- ✓ Discovery captured from Superpowers v6 release review +- ✓ Plan generated (9 tasks, 4 phases, sequential) +- ⧗ Plan artifact review pending +- ⧗ Implementation not started ## Blockers @@ -59,4 +56,4 @@ None ## Next Milestone -Complete discovery and generate a quick implementation plan +Run `oat-project-implement` starting at `p01-t01` From 413a713e19c4b41ef7bac27eef4ee30f35da2577 Mon Sep 17 00:00:00 2001 From: Thomas Stang Date: Sun, 28 Jun 2026 11:18:43 -0500 Subject: [PATCH 03/23] chore(oat): record plan review artifact --- .../brainstorm-visual-companion-v6/plan.md | 6 +- .../artifact-plan-review-2026-06-28.md | 165 ++++++++++++++++++ 2 files changed, 168 insertions(+), 3 deletions(-) create mode 100644 .oat/projects/shared/brainstorm-visual-companion-v6/reviews/artifact-plan-review-2026-06-28.md diff --git a/.oat/projects/shared/brainstorm-visual-companion-v6/plan.md b/.oat/projects/shared/brainstorm-visual-companion-v6/plan.md index 33a24f1f9e..a39666dc33 100644 --- a/.oat/projects/shared/brainstorm-visual-companion-v6/plan.md +++ b/.oat/projects/shared/brainstorm-visual-companion-v6/plan.md @@ -327,9 +327,9 @@ If skipped: record "skipped — no user-facing doc delta" in `implementation.md` ## Reviews -| Cycle | Scope | Status | Date | Notes | -| ----- | ----- | ------- | ---------- | -------------------------------------------- | -| plan | plan | pending | 2026-06-26 | Run artifact review before implement handoff | +| Cycle | Scope | Status | Date | Notes | +| ----- | ----- | -------- | ---------- | ------------------------------------------------------------------------- | +| plan | plan | received | 2026-06-28 | artifact review: 0C/1I/2M/3m — reviews/artifact-plan-review-2026-06-28.md | --- diff --git a/.oat/projects/shared/brainstorm-visual-companion-v6/reviews/artifact-plan-review-2026-06-28.md b/.oat/projects/shared/brainstorm-visual-companion-v6/reviews/artifact-plan-review-2026-06-28.md new file mode 100644 index 0000000000..8b0042c5fe --- /dev/null +++ b/.oat/projects/shared/brainstorm-visual-companion-v6/reviews/artifact-plan-review-2026-06-28.md @@ -0,0 +1,165 @@ +--- +oat_generated: true +oat_generated_at: 2026-06-28 +oat_review_scope: plan +oat_review_type: artifact +oat_review_invocation: manual +oat_project: .oat/projects/shared/brainstorm-visual-companion-v6 +--- + +# Artifact Review: plan + +**Reviewed:** 2026-06-28 +**Scope:** `plan.md` (quick-mode plan artifact, pre-implement handoff) +**Files reviewed:** 2 (plan.md, discovery.md) + codebase feasibility spot-checks +**Commits:** n/a (artifact review) + +## Summary + +The plan is well-structured, canonical-format conformant, and maps cleanly onto the discovery +success criteria, key decisions, and out-of-scope boundaries. Task IDs are stable and monotonic, +file scopes are bounded, the sequential parallelism claim is justified, and the referenced files, +packages, and validation scripts all exist. The main gap is that the headline security guarantees +of this parity project (file-server sandbox + security headers) have no automated regression +coverage in the test task; a few verification-command and ownership inconsistencies are also worth +tightening before implementation. + +## Findings + +### Critical + +None + +### Important + +- **Security sandbox and headers (Success Criterion #1) have no automated test coverage** (`plan.md:238-263` / `discovery.md:122`) + - Issue: The whole premise of this project is v6 security parity. Baseline `server.cjs` (v5.0.7) + confirms the sandbox is genuinely new: no `?key=` session auth, no `X-Frame-Options`/ + `Cache-Control: no-store`, and no traversal/symlink/dotfile guards exist today + (`.agents/skills/oat-brainstorm/scripts/server.cjs`). Success Criterion #1 requires the file + server to "reject traversal/symlinks/dotfiles" and emit "security headers present". But the + only security-related assertions in the test task `p03-t01` are a keyed `?key=` URL in + `server-started` JSON and an unauthenticated `GET /` returning 401/403. There is no test that + asserts traversal/dotfile/symlink rejection on `/files/`, and none that asserts the security + headers. These headline deliverables would ship with zero regression protection. + - Note on alignment: the plan is faithful to discovery Key Decision #5 (`discovery.md:110`), + which scoped automated tests to "session key, restart reuse, and stop-server instance-ID + behavior" only — so the gap is partly a discovery scoping choice, not solely a plan defect. + - Fix: Expand `p03-t01` with two cheap assertions (both are low-cost on the harness that already + spawns the server): (1) assert the `Cache-Control: no-store` and `X-Frame-Options: DENY` + headers on the existing authenticated/unauthenticated `fetch` response, and (2) one negative + `GET` against `/files/` with a traversal payload (e.g. `/files/../server.cjs` or a dotfile path) + expecting a 4xx. Alternatively, if these are intentionally left to manual/port inspection, + state that explicitly in the plan and `discovery.md` Key Decision #5 so the success-criteria-vs- + test scope is reconciled rather than silently divergent. + +### Medium + +- **SKILL.md version-bump ownership is split and self-contradictory between p02-t02 and p03-t02** (`plan.md:218`, `plan.md:272`, `plan.md:292`) + - Issue: `p02-t02` instructs "Bump skill frontmatter `version:` (required for skill change)". + `p03-t02` then lists `.agents/skills/oat-brainstorm/SKILL.md (version if not done in p02-t02)` + in its Files block, but its `git add` (`plan.md:292`) omits `SKILL.md` entirely. If the bump + is done in `p02-t02` (as instructed), the `p03-t02` Files entry is a dead/contradictory item; + if it is somehow deferred to `p03-t02`, the change would never be staged by the listed commit. + Either way the release guardrail (one PR-scoped skill version bump) hinges on an ambiguous + owner. Current `SKILL.md` is `version: 1.1.0`. + - Fix: Assign the SKILL.md version bump unambiguously to `p02-t02` and remove the + "(version if not done in p02-t02)" line from `p03-t02`'s Files block, or — if the bump must + co-land with the lockstep package bump in `p03-t02` — move it wholly into `p03-t02` and add + `SKILL.md` to that task's `git add`. + +- **`p03-t02` verification command `pnpm test --filter visual-companion-smoke` is an invalid package filter** (`plan.md:286`) + - Issue: `pnpm test` resolves to `turbo run test`, and Turbo `--filter` matches package names, + not test files. There is no package named `visual-companion-smoke`, so this filter selects no + package (Turbo errors/runs nothing). Only the in-step fallback `pnpm test` is valid. The other + smoke invocations in the plan use `pnpm exec vitest run packages/cli/src/integration/visual-companion-smoke.test.ts`, + so the verification surface is inconsistent. Note the cli vitest config lives only at + `packages/cli/vitest.config.ts` (no root config), so package-scoped invocation is the reliable + form. + - Fix: Replace with a canonical command, e.g. `pnpm --filter @open-agent-toolkit/cli test` + (full cli suite) or `pnpm --filter @open-agent-toolkit/cli exec vitest run src/integration/visual-companion-smoke.test.ts` + for the single file. Align the other smoke-test verification steps to the same form. + +### Minor + +- **`p01-t01` Step 1 is labeled "(RED)" but expects the suite to pass** (`plan.md:52-55`) + - Issue: The step is titled "Baseline check (RED)" yet its Expected is "Current tests pass on + v5.0.7 baseline (establishes green before port)." A RED step by convention expects a failing + assertion; this is a green baseline. The mislabel can confuse an implementer following strict + RED/GREEN discipline. + - Suggestion: Rename to "Baseline check (GREEN baseline)" or just "Baseline check". The port + tasks `p01-t02/t03/t04` correctly use GREEN-only steps; only `p03-t01` is genuinely RED-first. + +- **Success Criterion #4 (client status pill / paused overlay) is verified only by manual grep** (`plan.md:104-105`, `discovery.md:125`) + - Issue: `p01-t02` Step 2 verification is "Manual: grep frame for `.status` and helper for + `setStatus` — both present." This confirms element/handler presence, not reconnect/overlay + behavior, and is not automated. Discovery assumptions (`discovery.md:153`) acknowledge the + smoke harness cannot drive a browser, so leaving UI behavior to manual verification is + defensible — but the plan should make that explicit rather than implying coverage. + - Suggestion: Add a one-line note in `p01-t02` (or `implementation.md` expectation) that the + status-pill/paused-overlay behavior is verified manually in a browser and is intentionally + outside automated smoke scope. + +- **Idle-timeout interface seam (minutes flag vs ms env) is unstated** (`plan.md:64`, `plan.md:130`) + - Issue: `p01-t01` has `server.cjs` read `BRAINSTORM_IDLE_TIMEOUT_MS` (milliseconds, default 4h), + while `p01-t03` adds a `--idle-timeout-minutes` flag to `start-server.sh`. Baseline confirms the + current server hardcodes `IDLE_TIMEOUT_MS = 30 * 60 * 1000`, so this is new wiring. The plan + does not state that `start-server.sh` must convert minutes→ms and export the env var the server + reads, leaving a small seam an implementer could get wrong (units mismatch → wrong idle window). + - Suggestion: Add a sentence to `p01-t03` specifying that `--idle-timeout-minutes` is converted to + milliseconds and passed via `BRAINSTORM_IDLE_TIMEOUT_MS` so the server/launcher agree on units. + +## Requirements/Discovery Alignment + +**Evidence sources used:** `plan.md`, `discovery.md` (quick mode — no `spec.md`/`design.md`, expected and not flagged). Codebase feasibility spot-checks against `.agents/skills/oat-brainstorm/`, `packages/cli/src/integration/visual-companion-smoke.test.ts`, `NOTICES.md`, the five lockstep `package.json` files, root `package.json` scripts, and the referenced project-summary/backlog files. + +### Discovery Coverage + +| Discovery item | Status | Notes | +| ---------------------------------------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------- | +| SC#1 Session-key auth (HTTP+WS), file sandbox (traversal/symlink/dotfile), security headers | partial | Behavior ported in `p01-t01`; auth rejection tested in `p03-t01`; sandbox + headers have no automated test (Important I1) | +| SC#2 Restart reuses port/key with same `--project-dir`/repo | implemented | `p01-t03` persistence + `.last-port`/`.last-token`; `p03-t01` restart-reuse test | +| SC#3 Idle default 4h configurable; stop-server instance-ID guard | implemented | `p01-t01` idle (ms env), `p01-t03` minutes flag (units seam — m3), `p01-t04` instance guard | +| SC#4 Client status pill + paused overlay | partial | `p01-t02` port; verification is manual grep only (Minor) | +| SC#5 SKILL.md + visual-companion.md document key URL/`--open`/restart/idle | implemented | `p02-t01`, `p02-t02` | +| SC#6 Smoke test passes; `release:validate` passes after bump | implemented | `p03-t01`, `p03-t02` (verification cmd issue — M2) | +| SC#7 NOTICES updated to v6.0.3 adapted port | implemented | `p03-t02`; baseline `NOTICES.md` currently says 5.0.7/verbatim | +| KD#1 Upstream target v6.0.3 tag (file source) | implemented | Plan References reconcile "v6.0.0 notes; v6.0.3 tag for file source" — consistent with discovery's SDD-only note | +| KD#2 Three-tier OAT persistence resolution | implemented | `p01-t03` enumerates `--project-dir` / repo walk-up / `~/.oat` | +| KD#3 Preserve Activation Contract / offer / dispatcher | implemented | `p02-t02` explicitly "Do not change Activation Contract or destination logic" | +| KD#4 Lockstep five-package bump + `release:validate` | implemented | `p03-t02`; all five `package.json` files confirmed present | +| KD#5 Tests: session key, restart reuse, stop-server instance | implemented | `p03-t01` (note tension with SC#1 — see I1) | +| KD#6 / Out-of-scope: synthesis self-review, CLI wrapper, SDD, harness bootstraps, live dogfood | respected | No tasks stray into deferred/out-of-scope areas | +| Open Q: user-scope token persistence at `~/.oat/brainstorm/` | implemented | `p01-t03` fallback writes `.last-port`/`.last-token` there | +| Open Q: rebrand frame title to "OAT Brainstorm" | implemented | `p01-t02` header rebrand | + +### Extra Work (not in declared requirements) + +None. Phase 4 (`p04-t01`, optional tool-packs docs touchpoint) falls within the discovery +constraint "NOTICES/version/docs touchpoints only" and includes an explicit skip path with an +`implementation.md` log note, so it is not scope creep. + +## Verification Commands + +```bash +# Confirm the validation/release scripts the plan relies on exist +node -e "const s=require('./package.json').scripts; console.log('oat:validate-skills=',s['oat:validate-skills']); console.log('release:validate=',s['release:validate'])" + +# Confirm the test file and bundle scripts the plan targets exist +ls .agents/skills/oat-brainstorm/scripts/ packages/cli/src/integration/visual-companion-smoke.test.ts + +# Reliable single-file smoke invocation (replaces the invalid --filter form in p03-t02) +pnpm --filter @open-agent-toolkit/cli exec vitest run src/integration/visual-companion-smoke.test.ts + +# Confirm current baseline lacks the new security behaviors (justifies I1) +grep -nE "X-Frame-Options|no-store|brainstorm-server-id|\?key=" .agents/skills/oat-brainstorm/scripts/server.cjs || echo "none present in baseline" + +# Confirm all five lockstep packages exist for the p03-t02 bump +ls packages/cli/package.json packages/control-plane/package.json packages/docs-config/package.json packages/docs-theme/package.json packages/docs-transforms/package.json +``` + +## Recommended Next Step + +Run the `oat-project-review-receive` skill to convert these findings into plan tasks (or to +record explicit deferrals/artifact-alignment edits for the Important security-test gap and the +Medium ownership/verification-command items) before handing off to `oat-project-implement`. From 933acbfdde8875fdb635533acf560a6dfc72837f Mon Sep 17 00:00:00 2001 From: Thomas Stang Date: Sun, 28 Jun 2026 11:37:00 -0500 Subject: [PATCH 04/23] chore(oat): record plan review findings and apply artifact edits (plan) --- .../brainstorm-visual-companion-v6/plan.md | 25 +-- .../artifact-plan-review-2026-06-28.md | 165 ------------------ 2 files changed, 15 insertions(+), 175 deletions(-) delete mode 100644 .oat/projects/shared/brainstorm-visual-companion-v6/reviews/artifact-plan-review-2026-06-28.md diff --git a/.oat/projects/shared/brainstorm-visual-companion-v6/plan.md b/.oat/projects/shared/brainstorm-visual-companion-v6/plan.md index a39666dc33..d3e54ace9b 100644 --- a/.oat/projects/shared/brainstorm-visual-companion-v6/plan.md +++ b/.oat/projects/shared/brainstorm-visual-companion-v6/plan.md @@ -2,7 +2,7 @@ oat_status: complete oat_ready_for: oat-project-implement oat_blockers: [] -oat_last_updated: 2026-06-26 +oat_last_updated: 2026-06-28 oat_phase: plan oat_phase_status: complete oat_plan_hill_phases: [] @@ -49,9 +49,9 @@ All phases modify the same skill bundle or its tests/docs. Phases run **sequenti - Modify: `.agents/skills/oat-brainstorm/scripts/server.cjs` -**Step 1: Baseline check (RED)** +**Step 1: Baseline check (GREEN baseline)** -Run: `pnpm exec vitest run packages/cli/src/integration/visual-companion-smoke.test.ts` +Run: `pnpm --filter @open-agent-toolkit/cli exec vitest run src/integration/visual-companion-smoke.test.ts` Expected: Current tests pass on v5.0.7 baseline (establishes green before port). **Step 2: Port v6 server (GREEN)** @@ -104,6 +104,8 @@ Update frame template header branding to **OAT Brainstorm** (remove Superpowers Manual: grep frame for `.status` and helper for `setStatus` — both present. +Note: reconnect/status-pill/paused-overlay runtime behavior (SC#4) is verified manually in a browser and is intentionally outside automated smoke scope (the smoke harness cannot drive a browser). + **Step 3: Commit** ```bash @@ -129,6 +131,8 @@ Merge v6.0.3 `start-server.sh` capabilities with OAT persistence resolution: Add v6 flags: `--open`, `--idle-timeout-minutes`, `umask 077`, `server-instance-id`, Windows `is_windows_like_shell` + clear `OWNER_PID`, pass `--brainstorm-server-id` to node. +`--idle-timeout-minutes` must be converted to milliseconds and exported as `BRAINSTORM_IDLE_TIMEOUT_MS` so the launcher and `server.cjs` agree on units (server reads ms; default 4h). + **Step 2: Verify** Run: `bash -n .agents/skills/oat-brainstorm/scripts/start-server.sh` @@ -215,7 +219,7 @@ In Step 3 (visual companion offer/accept): - On accept, pass `--open` when starting server (after user approval) - Instruct agent to preserve keyed URL from JSON; restart with same path resolution - Note 4h idle / restart semantics -- Bump skill frontmatter `version:` (required for skill change) +- Bump skill frontmatter `version:` here — this task is the sole owner of the skill version bump (required for the skill change; not repeated in p03-t02) Do **not** change Activation Contract or destination logic. @@ -247,12 +251,14 @@ Add cases for: - `server-started` JSON includes keyed URL (`?key=`) - Unauthenticated GET `/` returns 401/403 (per server behavior) +- Security headers present on responses: `Cache-Control: no-store` and `X-Frame-Options: DENY` (SC#1) +- Sandboxed `/files/` rejects traversal/dotfile payloads: an authenticated `GET /files/../server.cjs?key=` (or a dotfile path) returns 4xx (SC#1) - Restart with same `--project-dir` reuses port (read `.last-port`) - `stop-server.sh` refuses stale/wrong instance (mock or integration-safe check) **Step 2: Implement until green (GREEN)** -Run: `pnpm exec vitest run packages/cli/src/integration/visual-companion-smoke.test.ts` +Run: `pnpm --filter @open-agent-toolkit/cli exec vitest run src/integration/visual-companion-smoke.test.ts` Expected: All tests pass. **Step 3: Commit** @@ -269,7 +275,6 @@ git commit -m "test(p03-t01): cover v6 visual companion auth and restart behavio **Files:** - Modify: `NOTICES.md` -- Modify: `.agents/skills/oat-brainstorm/SKILL.md` (version if not done in p02-t02) - Modify: `packages/cli/package.json`, `packages/control-plane/package.json`, `packages/docs-config/package.json`, `packages/docs-theme/package.json`, `packages/docs-transforms/package.json` (lockstep bump) **Step 1: Update provenance (GREEN)** @@ -283,7 +288,7 @@ Bump all five public packages together per repo guardrail. Run: `pnpm release:validate` Expected: Pass. -Run: `pnpm test --filter visual-companion-smoke` or full `pnpm test` if fast enough +Run: `pnpm --filter @open-agent-toolkit/cli exec vitest run src/integration/visual-companion-smoke.test.ts` (or full `pnpm --filter @open-agent-toolkit/cli test`) Expected: Pass. **Step 3: Commit** @@ -327,9 +332,9 @@ If skipped: record "skipped — no user-facing doc delta" in `implementation.md` ## Reviews -| Cycle | Scope | Status | Date | Notes | -| ----- | ----- | -------- | ---------- | ------------------------------------------------------------------------- | -| plan | plan | received | 2026-06-28 | artifact review: 0C/1I/2M/3m — reviews/artifact-plan-review-2026-06-28.md | +| Cycle | Scope | Status | Date | Notes | +| ----- | ----- | --------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | +| plan | plan | fixes_completed | 2026-06-28 | artifact review 0C/1I/2M/3m — all 6 resolved in-artifact (I1 tests added, M1/M2/m1/m2/m3 fixed) — reviews/archived/artifact-plan-review-2026-06-28.md | --- diff --git a/.oat/projects/shared/brainstorm-visual-companion-v6/reviews/artifact-plan-review-2026-06-28.md b/.oat/projects/shared/brainstorm-visual-companion-v6/reviews/artifact-plan-review-2026-06-28.md deleted file mode 100644 index 8b0042c5fe..0000000000 --- a/.oat/projects/shared/brainstorm-visual-companion-v6/reviews/artifact-plan-review-2026-06-28.md +++ /dev/null @@ -1,165 +0,0 @@ ---- -oat_generated: true -oat_generated_at: 2026-06-28 -oat_review_scope: plan -oat_review_type: artifact -oat_review_invocation: manual -oat_project: .oat/projects/shared/brainstorm-visual-companion-v6 ---- - -# Artifact Review: plan - -**Reviewed:** 2026-06-28 -**Scope:** `plan.md` (quick-mode plan artifact, pre-implement handoff) -**Files reviewed:** 2 (plan.md, discovery.md) + codebase feasibility spot-checks -**Commits:** n/a (artifact review) - -## Summary - -The plan is well-structured, canonical-format conformant, and maps cleanly onto the discovery -success criteria, key decisions, and out-of-scope boundaries. Task IDs are stable and monotonic, -file scopes are bounded, the sequential parallelism claim is justified, and the referenced files, -packages, and validation scripts all exist. The main gap is that the headline security guarantees -of this parity project (file-server sandbox + security headers) have no automated regression -coverage in the test task; a few verification-command and ownership inconsistencies are also worth -tightening before implementation. - -## Findings - -### Critical - -None - -### Important - -- **Security sandbox and headers (Success Criterion #1) have no automated test coverage** (`plan.md:238-263` / `discovery.md:122`) - - Issue: The whole premise of this project is v6 security parity. Baseline `server.cjs` (v5.0.7) - confirms the sandbox is genuinely new: no `?key=` session auth, no `X-Frame-Options`/ - `Cache-Control: no-store`, and no traversal/symlink/dotfile guards exist today - (`.agents/skills/oat-brainstorm/scripts/server.cjs`). Success Criterion #1 requires the file - server to "reject traversal/symlinks/dotfiles" and emit "security headers present". But the - only security-related assertions in the test task `p03-t01` are a keyed `?key=` URL in - `server-started` JSON and an unauthenticated `GET /` returning 401/403. There is no test that - asserts traversal/dotfile/symlink rejection on `/files/`, and none that asserts the security - headers. These headline deliverables would ship with zero regression protection. - - Note on alignment: the plan is faithful to discovery Key Decision #5 (`discovery.md:110`), - which scoped automated tests to "session key, restart reuse, and stop-server instance-ID - behavior" only — so the gap is partly a discovery scoping choice, not solely a plan defect. - - Fix: Expand `p03-t01` with two cheap assertions (both are low-cost on the harness that already - spawns the server): (1) assert the `Cache-Control: no-store` and `X-Frame-Options: DENY` - headers on the existing authenticated/unauthenticated `fetch` response, and (2) one negative - `GET` against `/files/` with a traversal payload (e.g. `/files/../server.cjs` or a dotfile path) - expecting a 4xx. Alternatively, if these are intentionally left to manual/port inspection, - state that explicitly in the plan and `discovery.md` Key Decision #5 so the success-criteria-vs- - test scope is reconciled rather than silently divergent. - -### Medium - -- **SKILL.md version-bump ownership is split and self-contradictory between p02-t02 and p03-t02** (`plan.md:218`, `plan.md:272`, `plan.md:292`) - - Issue: `p02-t02` instructs "Bump skill frontmatter `version:` (required for skill change)". - `p03-t02` then lists `.agents/skills/oat-brainstorm/SKILL.md (version if not done in p02-t02)` - in its Files block, but its `git add` (`plan.md:292`) omits `SKILL.md` entirely. If the bump - is done in `p02-t02` (as instructed), the `p03-t02` Files entry is a dead/contradictory item; - if it is somehow deferred to `p03-t02`, the change would never be staged by the listed commit. - Either way the release guardrail (one PR-scoped skill version bump) hinges on an ambiguous - owner. Current `SKILL.md` is `version: 1.1.0`. - - Fix: Assign the SKILL.md version bump unambiguously to `p02-t02` and remove the - "(version if not done in p02-t02)" line from `p03-t02`'s Files block, or — if the bump must - co-land with the lockstep package bump in `p03-t02` — move it wholly into `p03-t02` and add - `SKILL.md` to that task's `git add`. - -- **`p03-t02` verification command `pnpm test --filter visual-companion-smoke` is an invalid package filter** (`plan.md:286`) - - Issue: `pnpm test` resolves to `turbo run test`, and Turbo `--filter` matches package names, - not test files. There is no package named `visual-companion-smoke`, so this filter selects no - package (Turbo errors/runs nothing). Only the in-step fallback `pnpm test` is valid. The other - smoke invocations in the plan use `pnpm exec vitest run packages/cli/src/integration/visual-companion-smoke.test.ts`, - so the verification surface is inconsistent. Note the cli vitest config lives only at - `packages/cli/vitest.config.ts` (no root config), so package-scoped invocation is the reliable - form. - - Fix: Replace with a canonical command, e.g. `pnpm --filter @open-agent-toolkit/cli test` - (full cli suite) or `pnpm --filter @open-agent-toolkit/cli exec vitest run src/integration/visual-companion-smoke.test.ts` - for the single file. Align the other smoke-test verification steps to the same form. - -### Minor - -- **`p01-t01` Step 1 is labeled "(RED)" but expects the suite to pass** (`plan.md:52-55`) - - Issue: The step is titled "Baseline check (RED)" yet its Expected is "Current tests pass on - v5.0.7 baseline (establishes green before port)." A RED step by convention expects a failing - assertion; this is a green baseline. The mislabel can confuse an implementer following strict - RED/GREEN discipline. - - Suggestion: Rename to "Baseline check (GREEN baseline)" or just "Baseline check". The port - tasks `p01-t02/t03/t04` correctly use GREEN-only steps; only `p03-t01` is genuinely RED-first. - -- **Success Criterion #4 (client status pill / paused overlay) is verified only by manual grep** (`plan.md:104-105`, `discovery.md:125`) - - Issue: `p01-t02` Step 2 verification is "Manual: grep frame for `.status` and helper for - `setStatus` — both present." This confirms element/handler presence, not reconnect/overlay - behavior, and is not automated. Discovery assumptions (`discovery.md:153`) acknowledge the - smoke harness cannot drive a browser, so leaving UI behavior to manual verification is - defensible — but the plan should make that explicit rather than implying coverage. - - Suggestion: Add a one-line note in `p01-t02` (or `implementation.md` expectation) that the - status-pill/paused-overlay behavior is verified manually in a browser and is intentionally - outside automated smoke scope. - -- **Idle-timeout interface seam (minutes flag vs ms env) is unstated** (`plan.md:64`, `plan.md:130`) - - Issue: `p01-t01` has `server.cjs` read `BRAINSTORM_IDLE_TIMEOUT_MS` (milliseconds, default 4h), - while `p01-t03` adds a `--idle-timeout-minutes` flag to `start-server.sh`. Baseline confirms the - current server hardcodes `IDLE_TIMEOUT_MS = 30 * 60 * 1000`, so this is new wiring. The plan - does not state that `start-server.sh` must convert minutes→ms and export the env var the server - reads, leaving a small seam an implementer could get wrong (units mismatch → wrong idle window). - - Suggestion: Add a sentence to `p01-t03` specifying that `--idle-timeout-minutes` is converted to - milliseconds and passed via `BRAINSTORM_IDLE_TIMEOUT_MS` so the server/launcher agree on units. - -## Requirements/Discovery Alignment - -**Evidence sources used:** `plan.md`, `discovery.md` (quick mode — no `spec.md`/`design.md`, expected and not flagged). Codebase feasibility spot-checks against `.agents/skills/oat-brainstorm/`, `packages/cli/src/integration/visual-companion-smoke.test.ts`, `NOTICES.md`, the five lockstep `package.json` files, root `package.json` scripts, and the referenced project-summary/backlog files. - -### Discovery Coverage - -| Discovery item | Status | Notes | -| ---------------------------------------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------- | -| SC#1 Session-key auth (HTTP+WS), file sandbox (traversal/symlink/dotfile), security headers | partial | Behavior ported in `p01-t01`; auth rejection tested in `p03-t01`; sandbox + headers have no automated test (Important I1) | -| SC#2 Restart reuses port/key with same `--project-dir`/repo | implemented | `p01-t03` persistence + `.last-port`/`.last-token`; `p03-t01` restart-reuse test | -| SC#3 Idle default 4h configurable; stop-server instance-ID guard | implemented | `p01-t01` idle (ms env), `p01-t03` minutes flag (units seam — m3), `p01-t04` instance guard | -| SC#4 Client status pill + paused overlay | partial | `p01-t02` port; verification is manual grep only (Minor) | -| SC#5 SKILL.md + visual-companion.md document key URL/`--open`/restart/idle | implemented | `p02-t01`, `p02-t02` | -| SC#6 Smoke test passes; `release:validate` passes after bump | implemented | `p03-t01`, `p03-t02` (verification cmd issue — M2) | -| SC#7 NOTICES updated to v6.0.3 adapted port | implemented | `p03-t02`; baseline `NOTICES.md` currently says 5.0.7/verbatim | -| KD#1 Upstream target v6.0.3 tag (file source) | implemented | Plan References reconcile "v6.0.0 notes; v6.0.3 tag for file source" — consistent with discovery's SDD-only note | -| KD#2 Three-tier OAT persistence resolution | implemented | `p01-t03` enumerates `--project-dir` / repo walk-up / `~/.oat` | -| KD#3 Preserve Activation Contract / offer / dispatcher | implemented | `p02-t02` explicitly "Do not change Activation Contract or destination logic" | -| KD#4 Lockstep five-package bump + `release:validate` | implemented | `p03-t02`; all five `package.json` files confirmed present | -| KD#5 Tests: session key, restart reuse, stop-server instance | implemented | `p03-t01` (note tension with SC#1 — see I1) | -| KD#6 / Out-of-scope: synthesis self-review, CLI wrapper, SDD, harness bootstraps, live dogfood | respected | No tasks stray into deferred/out-of-scope areas | -| Open Q: user-scope token persistence at `~/.oat/brainstorm/` | implemented | `p01-t03` fallback writes `.last-port`/`.last-token` there | -| Open Q: rebrand frame title to "OAT Brainstorm" | implemented | `p01-t02` header rebrand | - -### Extra Work (not in declared requirements) - -None. Phase 4 (`p04-t01`, optional tool-packs docs touchpoint) falls within the discovery -constraint "NOTICES/version/docs touchpoints only" and includes an explicit skip path with an -`implementation.md` log note, so it is not scope creep. - -## Verification Commands - -```bash -# Confirm the validation/release scripts the plan relies on exist -node -e "const s=require('./package.json').scripts; console.log('oat:validate-skills=',s['oat:validate-skills']); console.log('release:validate=',s['release:validate'])" - -# Confirm the test file and bundle scripts the plan targets exist -ls .agents/skills/oat-brainstorm/scripts/ packages/cli/src/integration/visual-companion-smoke.test.ts - -# Reliable single-file smoke invocation (replaces the invalid --filter form in p03-t02) -pnpm --filter @open-agent-toolkit/cli exec vitest run src/integration/visual-companion-smoke.test.ts - -# Confirm current baseline lacks the new security behaviors (justifies I1) -grep -nE "X-Frame-Options|no-store|brainstorm-server-id|\?key=" .agents/skills/oat-brainstorm/scripts/server.cjs || echo "none present in baseline" - -# Confirm all five lockstep packages exist for the p03-t02 bump -ls packages/cli/package.json packages/control-plane/package.json packages/docs-config/package.json packages/docs-theme/package.json packages/docs-transforms/package.json -``` - -## Recommended Next Step - -Run the `oat-project-review-receive` skill to convert these findings into plan tasks (or to -record explicit deferrals/artifact-alignment edits for the Important security-test gap and the -Medium ownership/verification-command items) before handing off to `oat-project-implement`. From f8d992db58a8bae7bf8b39e9485991f52c8bd857 Mon Sep 17 00:00:00 2001 From: Thomas Stang Date: Sun, 28 Jun 2026 11:44:33 -0500 Subject: [PATCH 05/23] chore(oat): record plan review artifact --- .../brainstorm-visual-companion-v6/plan.md | 6 +- .../artifact-plan-review-2026-06-28-v2.md | 81 +++++++++++++++++++ 2 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 .oat/projects/shared/brainstorm-visual-companion-v6/reviews/artifact-plan-review-2026-06-28-v2.md diff --git a/.oat/projects/shared/brainstorm-visual-companion-v6/plan.md b/.oat/projects/shared/brainstorm-visual-companion-v6/plan.md index d3e54ace9b..ee59bb8bbc 100644 --- a/.oat/projects/shared/brainstorm-visual-companion-v6/plan.md +++ b/.oat/projects/shared/brainstorm-visual-companion-v6/plan.md @@ -332,9 +332,9 @@ If skipped: record "skipped — no user-facing doc delta" in `implementation.md` ## Reviews -| Cycle | Scope | Status | Date | Notes | -| ----- | ----- | --------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | -| plan | plan | fixes_completed | 2026-06-28 | artifact review 0C/1I/2M/3m — all 6 resolved in-artifact (I1 tests added, M1/M2/m1/m2/m3 fixed) — reviews/archived/artifact-plan-review-2026-06-28.md | +| Cycle | Scope | Status | Date | Notes | +| ----- | ----- | -------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| plan | plan | received | 2026-06-28 | artifact re-review 0C/1I/1M/0m - reviews/artifact-plan-review-2026-06-28-v2.md; prior fixed review remains archived under reviews/archived/ | --- diff --git a/.oat/projects/shared/brainstorm-visual-companion-v6/reviews/artifact-plan-review-2026-06-28-v2.md b/.oat/projects/shared/brainstorm-visual-companion-v6/reviews/artifact-plan-review-2026-06-28-v2.md new file mode 100644 index 0000000000..f4e29226e9 --- /dev/null +++ b/.oat/projects/shared/brainstorm-visual-companion-v6/reviews/artifact-plan-review-2026-06-28-v2.md @@ -0,0 +1,81 @@ +--- +oat_generated: true +oat_generated_at: 2026-06-28 +oat_review_scope: plan +oat_review_type: artifact +oat_review_invocation: manual +oat_project: .oat/projects/shared/brainstorm-visual-companion-v6 +--- + +# Artifact Review: plan + +**Reviewed:** 2026-06-28 +**Scope:** `plan.md` re-review for quick-mode pre-implementation handoff +**Files reviewed:** 2 primary (`plan.md`, `discovery.md`) plus project-state and repo-guardrail spot checks +**Commits:** n/a (artifact review) + +## Summary + +The current plan is much stronger than the archived first-pass review: the version-bump ownership, smoke command, security-header/traversal coverage, UI manual-verification note, and idle-timeout unit seam have all been addressed. Two gaps remain before implementation handoff: the plan still leaves the symlink branch of the file-sandbox success criterion without regression coverage, and it omits the provider-view sync step required when canonical skills change. + +## Findings + +### Critical + +None + +### Important + +- **SC#1 still lacks symlink regression coverage for `/files/` sandboxing** (`plan.md:61-63`, `plan.md:248-257`, `discovery.md:122`) + - Issue: Discovery requires the file server to reject traversal, symlinks, and dotfiles, and the plan correctly calls out "no symlinks, dotfiles, traversal" in the server port task. The revised smoke-test task now covers security headers plus traversal/dotfile payloads, but it still does not require a symlink case. That leaves one explicitly named security guarantee validated only by code inspection or upstream trust. + - Fix: Extend `p03-t01` with a symlink fixture under the served file area and assert an authenticated `/files/...` request to that symlink returns 4xx. If symlink validation is intentionally manual or platform-limited, say that explicitly in `p03-t01` and reconcile the success criterion. + +### Medium + +- **Provider-view sync is missing from the implementation plan** (`AGENTS.md:7-12`, `plan.md:209-229`, `plan.md:273-299`) + - Issue: This PR will change the canonical `oat-brainstorm` skill and bundled assets. Repo instructions say canonical skills live under `.agents/skills`, provider-linked views are managed by sync tooling, and provider views should be refreshed with `oat sync --scope all`. The plan validates skills and bumps package versions, but it never schedules the sync step or the resulting `.claude`/`.cursor`/manifest changes if they occur. + - Fix: Add a verification/bookkeeping step, likely in `p03-t02`, to run the repo-local equivalent of `oat sync --scope all` (`pnpm run cli -- sync --scope all` in this checkout) after the skill edits. Commit any provider-view or `.oat/sync/manifest.json` updates with the release/version bookkeeping if the command changes them. + +### Minor + +None + +## Requirements/Discovery Alignment + +| Discovery item | Status | Notes | +| ------------------------------------------------------------------- | ----------- | --------------------------------------------------------------------------------------------------------- | +| SC#1 Session-key auth, file sandbox, security headers | partial | Plan covers auth, headers, traversal, and dotfile checks; symlink rejection remains untested (Important). | +| SC#2 Restart reuses port/key with same context | implemented | `p01-t03` plus `p03-t01` restart-reuse test. | +| SC#3 Idle default 4h configurable; stop-server instance guard | implemented | Launcher/server unit handoff is now explicit; stop-server stale instance check is planned. | +| SC#4 Client status pill and paused overlay | implemented | Plan now states browser/manual verification is intentional because smoke cannot drive the UI. | +| SC#5 Skill/reference docs document key URL, `--open`, restart, idle | implemented | `p02-t01` and `p02-t02`. | +| SC#6 Smoke test and `release:validate` pass after bump | implemented | Commands now use package-scoped Vitest and `pnpm release:validate`. | +| SC#7 NOTICES updated for Superpowers v6.0.3 adapted port | implemented | `p03-t02`. | + +### Extra Work + +None. Phase 4 remains an optional docs touchpoint with a skip path and does not expand beyond the discovery constraints. + +## Dispatch Profile Advisory + +No `## Dispatch Profile` section is present. That is normal for this plan and is not a finding. + +## Verification Commands + +```bash +# Re-check the plan/discovery assertions after fixing the review findings. +rg -n "symlink|oat sync|sync --scope" .oat/projects/shared/brainstorm-visual-companion-v6/plan.md + +# Validate the skill pack after the planned skill edits. +pnpm oat:validate-skills + +# Refresh provider views after canonical skill edits, using the repo-local CLI. +pnpm run cli -- sync --scope all + +# Run the targeted smoke test. +pnpm --filter @open-agent-toolkit/cli exec vitest run src/integration/visual-companion-smoke.test.ts +``` + +## Recommended Next Step + +Run the `oat-project-review-receive` skill to convert the Important and Medium findings into plan edits or explicit deferrals before starting `oat-project-implement`. From 59761caff6cfd4337128ca769802881251a5d682 Mon Sep 17 00:00:00 2001 From: Thomas Stang Date: Wed, 1 Jul 2026 19:47:03 -0500 Subject: [PATCH 06/23] chore(oat): initialize implementation run (tier 1, ceiling sonnet, hill p04) --- .../implementation.md | 6 ++--- .../brainstorm-visual-companion-v6/plan.md | 3 ++- .../brainstorm-visual-companion-v6/state.md | 26 ++++++++++++------- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/.oat/projects/shared/brainstorm-visual-companion-v6/implementation.md b/.oat/projects/shared/brainstorm-visual-companion-v6/implementation.md index da2580d6a8..f8622b4aaa 100644 --- a/.oat/projects/shared/brainstorm-visual-companion-v6/implementation.md +++ b/.oat/projects/shared/brainstorm-visual-companion-v6/implementation.md @@ -2,15 +2,15 @@ oat_status: in_progress oat_ready_for: null oat_blockers: [] -oat_last_updated: 2026-06-26 +oat_last_updated: 2026-07-02 oat_current_task_id: p01-t01 oat_generated: false --- # Implementation: brainstorm-visual-companion-v6 -**Started:** (pending) -**Last Updated:** 2026-06-26 +**Started:** 2026-07-02 +**Last Updated:** 2026-07-02 > Resume pointer: `oat_current_task_id: p01-t01` diff --git a/.oat/projects/shared/brainstorm-visual-companion-v6/plan.md b/.oat/projects/shared/brainstorm-visual-companion-v6/plan.md index ee59bb8bbc..f6bac7e5fd 100644 --- a/.oat/projects/shared/brainstorm-visual-companion-v6/plan.md +++ b/.oat/projects/shared/brainstorm-visual-companion-v6/plan.md @@ -5,8 +5,9 @@ oat_blockers: [] oat_last_updated: 2026-06-28 oat_phase: plan oat_phase_status: complete -oat_plan_hill_phases: [] +oat_plan_hill_phases: ['p04'] oat_plan_parallel_groups: [] +oat_auto_review_at_hill_checkpoints: true oat_plan_source: quick oat_import_reference: null oat_import_source_path: null diff --git a/.oat/projects/shared/brainstorm-visual-companion-v6/state.md b/.oat/projects/shared/brainstorm-visual-companion-v6/state.md index 3e3d20f685..898d546360 100644 --- a/.oat/projects/shared/brainstorm-visual-companion-v6/state.md +++ b/.oat/projects/shared/brainstorm-visual-companion-v6/state.md @@ -1,5 +1,5 @@ --- -oat_current_task: null +oat_current_task: p01-t01 oat_last_commit: null oat_blockers: [] associated_issues: [] @@ -11,8 +11,8 @@ oat_children: [] oat_hill_checkpoints: [] oat_hill_completed: [] oat_parallel_execution: false -oat_phase: plan -oat_phase_status: complete +oat_phase: implement +oat_phase_status: in_progress oat_workflow_mode: quick oat_workflow_origin: native oat_docs_updated: null @@ -20,19 +20,25 @@ oat_pr_status: null oat_pr_url: null oat_project_created: '2026-06-26T19:52:43.792Z' oat_project_completed: null -oat_project_state_updated: '2026-06-26T20:00:00.000Z' +oat_project_state_updated: '2026-07-02T00:45:51.000Z' +oat_dispatch_ceiling: + preset: balanced + providers: + codex: high + claude: sonnet + source: project-state oat_generated: false --- # Project State: brainstorm-visual-companion-v6 -**Status:** Plan complete — ready for implementation +**Status:** Implementation in progress **Started:** 2026-06-26 -**Last Updated:** 2026-06-26 +**Last Updated:** 2026-07-02 ## Current Phase -Plan — complete. Hand off to `oat-project-implement`. +Implementation — in progress. Executing plan phases sequentially (Tier 1 subagents, ceiling: sonnet). ## Artifacts @@ -47,8 +53,8 @@ Plan — complete. Hand off to `oat-project-implement`. - ✓ Project scaffolded (quick mode) - ✓ Discovery captured from Superpowers v6 release review - ✓ Plan generated (9 tasks, 4 phases, sequential) -- ⧗ Plan artifact review pending -- ⧗ Implementation not started +- ✓ Plan artifact review (fixes_completed, resolved in-artifact) +- ⧗ Implementation in progress (starting p01) ## Blockers @@ -56,4 +62,4 @@ None ## Next Milestone -Run `oat-project-implement` starting at `p01-t01` +Implement phases p01→p04; final review at p04 checkpoint From a563f83cfcb80f6ca8d1cd8c0293acf30c21f345 Mon Sep 17 00:00:00 2001 From: Thomas Stang Date: Wed, 1 Jul 2026 19:52:04 -0500 Subject: [PATCH 07/23] feat(p01-t01): port v6 visual companion server with session auth --- .../skills/oat-brainstorm/scripts/server.cjs | 351 ++++++++++++++++-- 1 file changed, 327 insertions(+), 24 deletions(-) diff --git a/.agents/skills/oat-brainstorm/scripts/server.cjs b/.agents/skills/oat-brainstorm/scripts/server.cjs index 562c17f893..ad9e734762 100644 --- a/.agents/skills/oat-brainstorm/scripts/server.cjs +++ b/.agents/skills/oat-brainstorm/scripts/server.cjs @@ -7,6 +7,7 @@ const path = require('path'); const OPCODES = { TEXT: 0x01, CLOSE: 0x08, PING: 0x09, PONG: 0x0A }; const WS_MAGIC = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; +const MAX_FRAME_PAYLOAD_BYTES = 10 * 1024 * 1024; function computeAcceptKey(clientKey) { return crypto.createHash('sha1').update(clientKey + WS_MAGIC).digest('base64'); @@ -53,10 +54,18 @@ function decodeFrame(buffer) { offset = 4; } else if (payloadLen === 127) { if (buffer.length < 10) return null; - payloadLen = Number(buffer.readBigUInt64BE(2)); + const extendedLen = buffer.readBigUInt64BE(2); + if (extendedLen > BigInt(MAX_FRAME_PAYLOAD_BYTES)) { + throw new Error('WebSocket frame payload exceeds maximum allowed size'); + } + payloadLen = Number(extendedLen); offset = 10; } + if (payloadLen > MAX_FRAME_PAYLOAD_BYTES) { + throw new Error('WebSocket frame payload exceeds maximum allowed size'); + } + const maskOffset = offset; const dataOffset = offset + 4; const totalLen = dataOffset + payloadLen; @@ -73,7 +82,21 @@ function decodeFrame(buffer) { // ========== Configuration ========== -const PORT = process.env.BRAINSTORM_PORT || (49152 + Math.floor(Math.random() * 16383)); +const PORT_FILE = process.env.BRAINSTORM_PORT_FILE || null; +const randomPort = () => 49152 + Math.floor(Math.random() * 16383); +// Prefer an explicit port, else the port this session last bound (so a restart +// reuses it and an already-open browser tab reconnects), else a random high port. +function preferredPort() { + if (process.env.BRAINSTORM_PORT) return Number(process.env.BRAINSTORM_PORT); + if (PORT_FILE) { + try { + const p = Number(fs.readFileSync(PORT_FILE, 'utf-8').trim()); + if (Number.isInteger(p) && p > 1023 && p < 65536) return p; + } catch (e) { /* no prior port recorded */ } + } + return randomPort(); +} +let PORT = preferredPort(); const HOST = process.env.BRAINSTORM_HOST || '127.0.0.1'; const URL_HOST = process.env.BRAINSTORM_URL_HOST || (HOST === '127.0.0.1' ? 'localhost' : HOST); const SESSION_DIR = process.env.BRAINSTORM_DIR || '/tmp/brainstorm'; @@ -81,6 +104,44 @@ const CONTENT_DIR = path.join(SESSION_DIR, 'content'); const STATE_DIR = path.join(SESSION_DIR, 'state'); let ownerPid = process.env.BRAINSTORM_OWNER_PID ? Number(process.env.BRAINSTORM_OWNER_PID) : null; +// Per-session secret key. The companion is reachable by any local browser tab +// and, when bound to a non-loopback host, by any host that can route to it. +// The key authenticates the real client uniformly across loopback, tunnel, and +// remote binds — and defeats DNS rebinding — where a Host/Origin allowlist +// cannot. It rides the served URL as ?key= and is mirrored into a cookie on +// first load so same-origin subresources and the WebSocket carry it for free. +// Persisted alongside the port (BRAINSTORM_TOKEN_FILE) so a restart keeps the +// same key and an already-open tab's cookie still validates. +const TOKEN_FILE = process.env.BRAINSTORM_TOKEN_FILE || null; +function generateToken() { + return crypto.randomBytes(32).toString('hex'); +} + +function chmodOwnerOnly(file) { + try { fs.chmodSync(file, 0o600); } catch (e) { /* best effort */ } +} + +function initialToken() { + if (process.env.BRAINSTORM_TOKEN) { + return { value: process.env.BRAINSTORM_TOKEN, source: 'env' }; + } + if (TOKEN_FILE) { + try { + const t = fs.readFileSync(TOKEN_FILE, 'utf-8').trim(); + if (/^[0-9a-f]{32,}$/i.test(t)) { + chmodOwnerOnly(TOKEN_FILE); + return { value: t, source: 'file' }; + } + } catch (e) { /* no prior token recorded */ } + } + return { value: generateToken(), source: 'generated' }; +} + +const tokenInfo = initialToken(); +let TOKEN = tokenInfo.value; +let tokenSource = tokenInfo.source; +let COOKIE_NAME = 'brainstorm-key-' + PORT; // refined to the actual bound port in onListen + const MIME_TYPES = { '.html': 'text/html', '.css': 'text/css', '.js': 'application/javascript', '.json': 'application/json', '.png': 'image/png', '.jpg': 'image/jpeg', @@ -98,6 +159,30 @@ h1 { color: #333; } p { color: #666; }

Brainstorm Companion

Waiting for the agent to push a screen...

`; +const FORBIDDEN_PAGE = ` + +Session key required + + +

Session key required

+

This page needs the full URL your coding agent gave you, including the +?key=… part. Copy the complete URL and open it again.

`; + +function bootstrapPage(key) { + const jsonKey = JSON.stringify(String(key)); + return ` + +Opening Brainstorm Companion + + + +`; +} + const frameTemplate = fs.readFileSync(path.join(__dirname, 'frame-template.html'), 'utf-8'); const helperScript = fs.readFileSync(path.join(__dirname, 'helper.js'), 'utf-8'); const helperInjection = ''; @@ -115,20 +200,144 @@ function wrapInFrame(content) { function getNewestScreen() { const files = fs.readdirSync(CONTENT_DIR) - .filter(f => f.endsWith('.html')) + .filter(f => !f.startsWith('.') && f.endsWith('.html')) .map(f => { const fp = path.join(CONTENT_DIR, f); + if (!isRegularFileInsideContentDir(fp)) return null; return { path: fp, mtime: fs.statSync(fp).mtime.getTime() }; }) + .filter(Boolean) .sort((a, b) => b.mtime - a.mtime); return files.length > 0 ? files[0].path : null; } +function urlHostForHttp(host) { + const h = String(host); + if (h.startsWith('[') && h.endsWith(']')) return h; + return h.includes(':') ? '[' + h + ']' : h; +} + +function companionUrl() { + return 'http://' + urlHostForHttp(URL_HOST) + ':' + PORT + '/?key=' + TOKEN; +} + +function browserLauncherForPlatform(url, { + platform = process.platform, + osRelease = require('os').release(), + env = process.env +} = {}) { + const isWSL = platform === 'linux' && /microsoft/i.test(osRelease); + if (platform === 'darwin') return { bin: 'open', args: [url] }; + if (platform === 'win32' || isWSL) { + return { bin: 'rundll32.exe', args: ['url.dll,FileProtocolHandler', url] }; + } + if (env.DISPLAY || env.WAYLAND_DISPLAY) return { bin: 'xdg-open', args: [url] }; + return null; +} + +function isRegularFileInsideContentDir(filePath) { + let stat, realContentDir, realFilePath; + try { + stat = fs.lstatSync(filePath); + if (stat.isSymbolicLink()) return false; + if (!stat.isFile()) return false; + if (stat.nlink !== 1) return false; + realContentDir = fs.realpathSync(CONTENT_DIR); + realFilePath = fs.realpathSync(filePath); + } catch (e) { + return false; + } + return realFilePath.startsWith(realContentDir + path.sep); +} + +// ========== Authentication ========== + +function timingSafeEqualStr(a, b) { + const ab = Buffer.from(String(a)); + const bb = Buffer.from(String(b)); + if (ab.length !== bb.length) return false; + return crypto.timingSafeEqual(ab, bb); +} + +function parseCookies(header) { + const out = {}; + if (!header) return out; + for (const part of header.split(';')) { + const eq = part.indexOf('='); + if (eq < 0) continue; + out[part.slice(0, eq).trim()] = part.slice(eq + 1).trim(); + } + return out; +} + +// A request is authorized if it carries the session key as ?key= or as the +// session cookie. Both are compared in constant time. +function isAuthorized(req) { + const q = req.url.indexOf('?'); + if (q >= 0) { + const params = new URLSearchParams(req.url.slice(q + 1)); + if (params.has('key')) { + const key = params.get('key'); + return Boolean(key && timingSafeEqualStr(key, TOKEN)); + } + } + const cookie = parseCookies(req.headers['cookie'])[COOKIE_NAME]; + if (cookie && timingSafeEqualStr(cookie, TOKEN)) return true; + return false; +} + +function pathnameOf(url) { + const q = url.indexOf('?'); + return q >= 0 ? url.slice(0, q) : url; +} + +function queryKey(url) { + const q = url.indexOf('?'); + if (q < 0) return null; + return new URLSearchParams(url.slice(q + 1)).get('key'); +} + +function securityHeaders(headers = {}) { + return { + 'Referrer-Policy': 'no-referrer', + 'Cache-Control': 'no-store', + 'X-Frame-Options': 'DENY', + 'Content-Security-Policy': "frame-ancestors 'none'", + 'Cross-Origin-Resource-Policy': 'same-origin', + ...headers + }; +} + +function isAllowedWebSocketOrigin(req) { + const origin = req.headers.origin; + if (!origin) return true; + const host = req.headers.host; + if (!host) return false; + return origin === 'http://' + host; +} + // ========== HTTP Request Handler ========== function handleRequest(req, res) { - touchActivity(); - if (req.method === 'GET' && req.url === '/') { + if (!isAuthorized(req)) { + res.writeHead(403, securityHeaders({ 'Content-Type': 'text/html; charset=utf-8' })); + res.end(FORBIDDEN_PAGE); + return; + } + touchActivity(); // only authorized requests count as activity + + // Mirror the key into a cookie so same-origin subresources (/files/*) can + // authenticate after bootstrap. HttpOnly keeps it away from page scripts; the + // WebSocket Origin check below is what blocks cross-origin localhost injection. + res.setHeader('Set-Cookie', + COOKIE_NAME + '=' + TOKEN + '; HttpOnly; SameSite=Strict; Path=/'); + + const pathname = pathnameOf(req.url); + const keyFromQuery = queryKey(req.url); + if (req.method === 'GET' && pathname === '/' && keyFromQuery && timingSafeEqualStr(keyFromQuery, TOKEN)) { + res.writeHead(200, securityHeaders({ 'Content-Type': 'text/html; charset=utf-8' })); + res.end(bootstrapPage(keyFromQuery)); + } else if (req.method === 'GET' && pathname === '/') { const screenFile = getNewestScreen(); let html = screenFile ? (raw => isFullDocument(raw) ? raw : wrapInFrame(raw))(fs.readFileSync(screenFile, 'utf-8')) @@ -140,22 +349,24 @@ function handleRequest(req, res) { html += helperInjection; } - res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); + res.writeHead(200, securityHeaders({ 'Content-Type': 'text/html; charset=utf-8' })); res.end(html); - } else if (req.method === 'GET' && req.url.startsWith('/files/')) { - const fileName = req.url.slice(7); - const filePath = path.join(CONTENT_DIR, path.basename(fileName)); - if (!fs.existsSync(filePath)) { - res.writeHead(404); + } else if (req.method === 'GET' && pathname.startsWith('/files/')) { + const fileName = path.basename(pathname.slice(7)); + const filePath = path.join(CONTENT_DIR, fileName); + // Reject empty/dotfile names and anything that isn't a regular file — + // `/files/` would otherwise resolve to CONTENT_DIR and crash readFileSync (EISDIR). + if (!fileName || fileName.startsWith('.') || !isRegularFileInsideContentDir(filePath)) { + res.writeHead(404, securityHeaders()); res.end('Not found'); return; } const ext = path.extname(filePath).toLowerCase(); const contentType = MIME_TYPES[ext] || 'application/octet-stream'; - res.writeHead(200, { 'Content-Type': contentType }); + res.writeHead(200, securityHeaders({ 'Content-Type': contentType })); res.end(fs.readFileSync(filePath)); } else { - res.writeHead(404); + res.writeHead(404, securityHeaders()); res.end('Not found'); } } @@ -165,6 +376,8 @@ function handleRequest(req, res) { const clients = new Set(); function handleUpgrade(req, socket) { + if (!isAuthorized(req) || !isAllowedWebSocketOrigin(req)) { socket.destroy(); return; } + const key = req.headers['sec-websocket-key']; if (!key) { socket.destroy(); return; } @@ -231,7 +444,7 @@ function handleMessage(text) { } touchActivity(); console.log(JSON.stringify({ source: 'user-event', ...event })); - if (event.choice) { + if (event && event.choice) { const eventsFile = path.join(STATE_DIR, 'events'); fs.appendFileSync(eventsFile, JSON.stringify(event) + '\n'); } @@ -244,9 +457,44 @@ function broadcast(msg) { } } +// Best-effort: open the user's browser the first time a screen is actually ready +// to show. Skips when disabled, on a non-loopback (remote) bind, or when a +// browser is already connected. Override the launcher with BRAINSTORM_OPEN_CMD. +let browserOpened = false; +function maybeOpenBrowser() { + if (browserOpened) return; + browserOpened = true; + if (!process.env.BRAINSTORM_OPEN) return; // opt-in: only after the user approves the companion + if (HOST !== '127.0.0.1' && HOST !== 'localhost') return; + if (clients.size > 0) return; // the user already opened it + const url = companionUrl(); // must carry the key or the gate 403s it + const cp = require('child_process'); + // Operator-provided launcher: run as given (this env var is trusted operator input). + if (process.env.BRAINSTORM_OPEN_CMD) { + try { cp.exec(process.env.BRAINSTORM_OPEN_CMD + ' ' + JSON.stringify(url), () => {}); } catch (e) { /* best effort */ } + return; + } + // Platform launchers: pass the URL as an argv element via execFile (no shell), + // so a url-host containing shell metacharacters can't inject a command. + const launcher = browserLauncherForPlatform(url); + if (!launcher) return; // headless: nothing to open + try { cp.execFile(launcher.bin, launcher.args, () => {}); } catch (e) { /* best effort */ } +} + // ========== Activity Tracking ========== -const IDLE_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes +// Idle timeout: shut down after this long with no activity. Default 4 hours; +// override with BRAINSTORM_IDLE_TIMEOUT_MS (start-server.sh: --idle-timeout-minutes). +const IDLE_TIMEOUT_MS = (() => { + const ms = Number(process.env.BRAINSTORM_IDLE_TIMEOUT_MS); + return Number.isFinite(ms) && ms > 0 ? ms : 4 * 60 * 60 * 1000; +})(); +// How often the watchdog checks for owner-death / idleness. Configurable mainly +// so tests can run fast; production default is 60s. +const LIFECYCLE_CHECK_MS = (() => { + const ms = Number(process.env.BRAINSTORM_LIFECYCLE_CHECK_MS); + return Number.isFinite(ms) && ms > 0 ? ms : 60 * 1000; +})(); let lastActivity = Date.now(); function touchActivity() { @@ -267,14 +515,14 @@ function startServer() { // macOS fs.watch reports 'rename' for both new files and overwrites, // so we can't rely on eventType alone. const knownFiles = new Set( - fs.readdirSync(CONTENT_DIR).filter(f => f.endsWith('.html')) + fs.readdirSync(CONTENT_DIR).filter(f => !f.startsWith('.') && f.endsWith('.html')) ); const server = http.createServer(handleRequest); server.on('upgrade', handleUpgrade); const watcher = fs.watch(CONTENT_DIR, (eventType, filename) => { - if (!filename || !filename.endsWith('.html')) return; + if (!filename || filename.startsWith('.') || !filename.endsWith('.html')) return; if (debounceTimers.has(filename)) clearTimeout(debounceTimers.get(filename)); debounceTimers.set(filename, setTimeout(() => { @@ -289,6 +537,7 @@ function startServer() { const eventsFile = path.join(STATE_DIR, 'events'); if (fs.existsSync(eventsFile)) fs.unlinkSync(eventsFile); console.log(JSON.stringify({ type: 'screen-added', file: filePath })); + maybeOpenBrowser(); } else { console.log(JSON.stringify({ type: 'screen-updated', file: filePath })); } @@ -308,6 +557,11 @@ function startServer() { ); watcher.close(); clearInterval(lifecycleCheck); + // Close any upgraded WebSocket sockets so server.close() can complete and + // the process actually exits instead of lingering on an open connection. + for (const socket of clients) { + try { socket.destroy(); } catch (e) { /* already gone */ } + } server.close(() => process.exit(0)); } @@ -316,11 +570,11 @@ function startServer() { try { process.kill(ownerPid, 0); return true; } catch (e) { return e.code === 'EPERM'; } } - // Check every 60s: exit if owner process died or idle for 30 minutes + // Periodically exit if the owner process died or we've been idle too long. const lifecycleCheck = setInterval(() => { if (!ownerAlive()) shutdown('owner process exited'); else if (Date.now() - lastActivity > IDLE_TIMEOUT_MS) shutdown('idle timeout'); - }, 60 * 1000); + }, LIFECYCLE_CHECK_MS); lifecycleCheck.unref(); // Validate owner PID at startup. If it's already dead, the PID resolution @@ -336,19 +590,68 @@ function startServer() { } } - server.listen(PORT, HOST, () => { + // If the preferred port is already taken (e.g. a previous server is still + // alive), fall back to a random port once instead of failing. + let triedFallback = false; + + function onListen() { + // Cookie name keys on the ACTUAL bound port (may differ from the preferred + // one after an EADDRINUSE fallback) so it can't collide with another server's + // cookie in the shared localhost jar. + COOKIE_NAME = 'brainstorm-key-' + PORT; + // Record the bound port AND token so the next restart of this session reuses + // them — but ONLY when we got our preferred port. On a fallback we bound a + // *different* port because someone else holds the preferred one; persisting + // would overwrite the shared files and strand that other session's open tab. + if (PORT_FILE && !triedFallback) { + try { fs.writeFileSync(PORT_FILE, String(PORT)); } catch (e) { /* best effort */ } + if (TOKEN_FILE) { + try { + fs.writeFileSync(TOKEN_FILE, TOKEN, { mode: 0o600 }); + chmodOwnerOnly(TOKEN_FILE); + } catch (e) { /* best effort */ } + } + } const info = JSON.stringify({ type: 'server-started', port: Number(PORT), host: HOST, - url_host: URL_HOST, url: 'http://' + URL_HOST + ':' + PORT, - screen_dir: CONTENT_DIR, state_dir: STATE_DIR + url_host: URL_HOST, url: companionUrl(), + screen_dir: CONTENT_DIR, state_dir: STATE_DIR, idle_timeout_ms: IDLE_TIMEOUT_MS }); console.log(info); - fs.writeFileSync(path.join(STATE_DIR, 'server-info'), info + '\n'); + // server-info embeds the key — keep it owner-only. + fs.writeFileSync(path.join(STATE_DIR, 'server-info'), info + '\n', { mode: 0o600 }); + } + + server.on('error', (err) => { + if (err.code === 'EADDRINUSE' && !triedFallback) { + if (tokenSource === 'env') { + console.error('Server failed to bind: preferred port is in use and BRAINSTORM_TOKEN is set; refusing fallback with explicit token'); + process.exit(1); + } + triedFallback = true; + PORT = randomPort(); + if (tokenSource === 'file') { + TOKEN = generateToken(); + tokenSource = 'generated-fallback'; + } + server.listen(PORT, HOST, onListen); + } else { + console.error('Server failed to bind:', err.message); + process.exit(1); + } }); + server.listen(PORT, HOST, onListen); } if (require.main === module) { startServer(); } -module.exports = { computeAcceptKey, encodeFrame, decodeFrame, OPCODES }; +module.exports = { + computeAcceptKey, + encodeFrame, + decodeFrame, + browserLauncherForPlatform, + OPCODES, + MAX_FRAME_PAYLOAD_BYTES +}; From 7b43b76d833f17fc647e54436212f5384858914a Mon Sep 17 00:00:00 2001 From: Thomas Stang Date: Wed, 1 Jul 2026 19:53:49 -0500 Subject: [PATCH 08/23] feat(p01-t02): port v6 companion client UI and OAT frame branding --- .../scripts/frame-template.html | 32 +++--- .../skills/oat-brainstorm/scripts/helper.js | 108 ++++++++++++++++-- 2 files changed, 119 insertions(+), 21 deletions(-) diff --git a/.agents/skills/oat-brainstorm/scripts/frame-template.html b/.agents/skills/oat-brainstorm/scripts/frame-template.html index dcfe01817e..f0087cce2f 100644 --- a/.agents/skills/oat-brainstorm/scripts/frame-template.html +++ b/.agents/skills/oat-brainstorm/scripts/frame-template.html @@ -2,14 +2,14 @@ - Superpowers Brainstorming + OAT Brainstorm