Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
6f51dc8
feat: add face analysis, MuScriptor, and MatAnyone workflows
Sportinger Jul 24, 2026
684b8dd
feat: expand AI analysis transcription and agent tooling
Sportinger Jul 26, 2026
cb69a8b
feat: canonical timeline occupancy selector (agent-kernel WP2-A)
Sportinger Jul 26, 2026
2c3d45e
feat: central timelineRevision via store middleware (agent-kernel WP2-B)
Sportinger Jul 26, 2026
4615ca4
feat: AgentMutationTransaction - one agent task, one undo group (WP2-C)
Sportinger Jul 27, 2026
478cf71
feat: unify agent timeline analysis workspace
Sportinger Jul 27, 2026
5e444d1
feat: expose canonical occupancy + stateRevision via getTimelineState…
Sportinger Jul 27, 2026
c651e60
refactor: migrate aiTools append-points to canonical occupancy (WP2-E)
Sportinger Jul 27, 2026
4ca4f88
feat: expose inPoint/outPoint/linkedClipId in track clip listings (ke…
Sportinger Jul 27, 2026
6bd0076
feat: segment-family handlers return entity ids + revisions (WP4-A)
Sportinger Jul 27, 2026
34dd83e
fix: WP2 review findings - batch timing, atomic groups, revision cove…
Sportinger Jul 27, 2026
05c1556
fix: unique batch ids, flush-adoption ownership, truthful rollback au…
Sportinger Jul 27, 2026
7bde38b
fix: startBatch reports ownership; rolled-back audits complete as fai…
Sportinger Jul 27, 2026
ec21f0c
feat: shared validation core extracted from guided actions (agent-ker…
Sportinger Jul 27, 2026
980f5ef
feat: entity/revision reporting wave 2 - markers, tracks, transitions…
Sportinger Jul 27, 2026
41c8929
test: tool registry parity gate - definitions/policy/handlers/modifyi…
Sportinger Jul 27, 2026
80554d6
feat: kernel service client - the app side of the split (agent-kernel…
Sportinger Jul 27, 2026
423d583
feat: kernel-first chat routing with legacy fallback (agent-kernel WP…
Sportinger Jul 27, 2026
5d9c01b
feat: editable tempo map + tempo-driven timeline grid (#299)
kfxs Jul 27, 2026
70c8473
fix: export getRegisteredToolPolicyNames for registry parity gate (WP3)
Sportinger Jul 27, 2026
e9155b6
feat: MIDI content follows tempo changes (#299)
kfxs Jul 27, 2026
8ec8847
feat: mutation entity/revision envelopes for clip/effect/mask/keyfram…
Sportinger Jul 27, 2026
38f8e34
feat: mutation envelopes for track-state/media/batch/face tools with …
Sportinger Jul 27, 2026
f0c7c25
refactor: agent-facing duration sites use canonical timeline occupanc…
Sportinger Jul 27, 2026
1f769cb
feat: split results expose runtime segment binding payload; clip list…
Sportinger Jul 27, 2026
a166dd5
test+docs: kernel client isolation guard and Kernel-Client feature do…
Sportinger Jul 27, 2026
da7574e
feat: verifyTimelineInvariants read-only tool over the shared validat…
Sportinger Jul 27, 2026
610f2d0
fix: use checkToolAccess in verifyTimelineInvariants registry test
Sportinger Jul 27, 2026
bcabd92
feat: tempo lane with editable marks, ramps and musical anchoring (#299)
kfxs Jul 27, 2026
5401bc1
fix: align stale tests with committed contracts; cancelled warm bench…
Sportinger Jul 27, 2026
cddf7e5
feat: show the tempo lane in the piano roll (#299)
kfxs Jul 27, 2026
4d3c820
feat: open MIDI tracks on the Track instrument tab
kfxs Jul 27, 2026
e62fe4d
refactor: retire flashBoardChatEditOptions experiment (agent-kernel W…
Sportinger Jul 27, 2026
c6fc36f
feat: kernel-first cutover transport - snapshot compile, one-transact…
Sportinger Jul 27, 2026
ee929e1
Merge branch 'agent-kernel-w3-public' into staging
Sportinger Jul 27, 2026
c153e64
feat: metronome click engine and toolbar control (#299)
kfxs Jul 27, 2026
e36a859
feat: kernel-handled chat turns record a durable run trace (agent-ker…
Sportinger Jul 27, 2026
6dde1b1
fix: kernel gateway maps simulated segment ids to real store ids per …
Sportinger Jul 27, 2026
f773275
docs: tempo and metronome feature documentation (#299)
kfxs Jul 27, 2026
0834a41
fix: keep getState policy registry under the file budget
kfxs Jul 27, 2026
ba0f23b
Merge origin/staging into 299-add-bpm-management
kfxs Jul 27, 2026
9ccf0fe
Merge pull request #349 from Sportinger/299-add-bpm-management
kfxs Jul 27, 2026
c1a425c
Merge remote-tracking branch 'origin/staging' into merge-staging
Sportinger Jul 27, 2026
d8b10e4
fix: CI gates after staging merge - snapshot via semantic gateway, pr…
Sportinger Jul 27, 2026
511dcbb
docs: kernel-first routing cross-references; parity-gated tool regist…
Sportinger Jul 27, 2026
7d2cc62
feat: local transcript moment handles + story compile flow in the ker…
Sportinger Jul 27, 2026
accdd6f
fix: kernel gateway calibration - real moment-handle schema, 180s com…
Sportinger Jul 27, 2026
e7b9156
fix: media-anchored transcript resolution for agent tool reads
Sportinger Jul 27, 2026
3cb51b7
refactor: neutral storySummary wire field in kernel client
Sportinger Jul 27, 2026
84e63db
fix: restore transcript words media-anchored after history restores; …
Sportinger Jul 28, 2026
77bf7b3
test: transcriptMoments expectations follow the calibrated kernel mom…
Sportinger Jul 28, 2026
63b7e93
test: classify clipTranscriptResolver in getState policy; cutover fix…
Sportinger Jul 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .dev.vars.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ STRIPE_PRICE_STARTER=price_starter_replace_me
STRIPE_PRICE_PRO=price_pro_replace_me
STRIPE_PRICE_STUDIO=price_studio_replace_me
OPENAI_API_KEY=replace-me
ANTHROPIC_API_KEY=replace-me
DEEPGRAM_API_KEY=replace-me
PIAPI_API_KEY=replace-me
KIEAI_API_KEY=replace-me
ELEVENLABS_API_KEY=replace-me
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ tools/native-helper/ffmpeg/

# AI Bridge session token (generated per dev session)
.ai-bridge-token
.ai-bridge-tool-history.jsonl

# Native helper release/package artifacts
tools/native-helper/MasterSelects-NativeHelper-v*-windows-x64.msi
Expand All @@ -91,6 +92,10 @@ tools/native-helper/icon.ico
Wonder/
_fremd/

# Private planning docs (proprietary kernel/orchestration design — never publish
# to the public MIT repo; lives in docs/private/, future home: private repo)
docs/private/

# Python virtual environments
**/venv/

Expand Down
14 changes: 14 additions & 0 deletions .mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"mcpServers": {
"masterselects": {
"command": "node",
"args": [
"scripts/masterselects-mcp.mjs"
],
"env": {
"MASTERSELECTS_BRIDGE_URL": "http://localhost:5173",
"MASTERSELECTS_BRIDGE_SURFACE": "chat"
}
}
}
}
49 changes: 49 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,55 @@ Bridge automation gotchas:
- For long diagnostics, print compact summaries. Full `getStats`/trace payloads
are huge and easy to truncate, which can hide the real result.

#### End-to-end chat-agent testing

When changing the FlashBoard system prompt, playbooks, tool schemas, history
construction, approval policy, or provider loop, test the complete in-app agent
through the bridge. Calling an editor tool directly proves only that tool; it
does not validate model planning, tool selection, result handling, follow-up
rounds, or the final answer.

Use this workflow:

1. Start Vite, open the app in a browser, and wait at least 5 seconds after
every reload before reading bridge state.
2. Discover the connected sessions with `bridge_list_sessions`, identify the
intended project/timeline, and select it explicitly with
`bridge_select_session`. Never let a multi-tab test choose a tab implicitly.
3. Inspect the exact rendered prompt first with
`bridge_get_chat_system_prompt` (or `GET /api/agent-chat/prompt`), including
its prompt version, live context, and selected playbooks.
4. Run `bridge_send_chat_message` with `dryRun: true` before making a provider
request. Provider calls can consume paid credits, so do not set
`confirm: true` without explicit user approval. A prompt comparison makes
two provider rounds.
5. For diagnosis, default to `toolExecutionMode: "read-only"` and
`persistToChat: false`. Enable normal/mutating execution or visible chat
persistence only when that behavior is itself under test.
6. For an A/B test, use `bridge_compare_chat_prompts` with the same prompt,
session, provider/model, and context settings for `legacy-v1` and `v2`.
Default to `includeHistory: false` for a controlled comparison.
7. Read each completed run by ID with `bridge_get_chat_run`. Review the exact
resolved system prompt, provider/model, final response, ordered tool calls,
arguments, results, denied/failed/truncated output, status, and timing.
Cross-check `bridge_get_history` or `/api/agent-control/history` when the
browser-side tool audit is relevant.
8. Classify the failure before editing code: prompt/playbook, missing
conversation or tool-result continuity, tool schema/result
size/pagination, policy/approval, or provider-loop/dispatcher
orchestration. Do not patch the system prompt to mask a non-prompt defect.
9. Keep large transcript and analysis reads bounded. Follow
`hasMore`/`nextOffset` and use source ranges, `offset`, `limit`, and
`includeFrames` only as needed.
10. Capture the failing request as a regression case before changing the
default prompt. Keep `legacy-v1` available until the controlled v2
comparison demonstrates the improvement.

The durable chat-run audit is authoritative for this debugging workflow: it
survives clearing the visible chat store and records the resolved prompt plus
the full model/tool loop. Never copy bridge tokens, API keys, or unredacted
secret fields into logs, fixtures, or reports.

| Tool | Purpose |
|---|---|
| `getStats` / `getStatsHistory` | engine snapshot(s): FPS, timing, decoder, drops, audio, GPU |
Expand Down
49 changes: 49 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,55 @@ Bridge automation gotchas:
- For long diagnostics, print compact summaries. Full `getStats`/trace payloads
are huge and easy to truncate, which can hide the real result.

#### End-to-end chat-agent testing

When changing the FlashBoard system prompt, playbooks, tool schemas, history
construction, approval policy, or provider loop, test the complete in-app agent
through the bridge. Calling an editor tool directly proves only that tool; it
does not validate model planning, tool selection, result handling, follow-up
rounds, or the final answer.

Use this workflow:

1. Start Vite, open the app in a browser, and wait at least 5 seconds after
every reload before reading bridge state.
2. Discover the connected sessions with `bridge_list_sessions`, identify the
intended project/timeline, and select it explicitly with
`bridge_select_session`. Never let a multi-tab test choose a tab implicitly.
3. Inspect the exact rendered prompt first with
`bridge_get_chat_system_prompt` (or `GET /api/agent-chat/prompt`), including
its prompt version, live context, and selected playbooks.
4. Run `bridge_send_chat_message` with `dryRun: true` before making a provider
request. Provider calls can consume paid credits, so do not set
`confirm: true` without explicit user approval. A prompt comparison makes
two provider rounds.
5. For diagnosis, default to `toolExecutionMode: "read-only"` and
`persistToChat: false`. Enable normal/mutating execution or visible chat
persistence only when that behavior is itself under test.
6. For an A/B test, use `bridge_compare_chat_prompts` with the same prompt,
session, provider/model, and context settings for `legacy-v1` and `v2`.
Default to `includeHistory: false` for a controlled comparison.
7. Read each completed run by ID with `bridge_get_chat_run`. Review the exact
resolved system prompt, provider/model, final response, ordered tool calls,
arguments, results, denied/failed/truncated output, status, and timing.
Cross-check `bridge_get_history` or `/api/agent-control/history` when the
browser-side tool audit is relevant.
8. Classify the failure before editing code: prompt/playbook, missing
conversation or tool-result continuity, tool schema/result
size/pagination, policy/approval, or provider-loop/dispatcher
orchestration. Do not patch the system prompt to mask a non-prompt defect.
9. Keep large transcript and analysis reads bounded. Follow
`hasMore`/`nextOffset` and use source ranges, `offset`, `limit`, and
`includeFrames` only as needed.
10. Capture the failing request as a regression case before changing the
default prompt. Keep `legacy-v1` available until the controlled v2
comparison demonstrates the improvement.

The durable chat-run audit is authoritative for this debugging workflow: it
survives clearing the visible chat store and records the resolved prompt plus
the full model/tool loop. Never copy bridge tokens, API keys, or unredacted
secret fields into logs, fixtures, or reports.

| Tool | Purpose |
|---|---|
| `getStats` / `getStatsHistory` | engine snapshot(s): FPS, timing, decoder, drops, audio, GPU |
Expand Down
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
156 changes: 156 additions & 0 deletions docs/Features/AI-Bridge-Control.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
[Back to Documentation Index](./README.md)

# AI Bridge Control

MasterSelects exposes its live in-app AI tool surface to local external agents through an authenticated development bridge. The bridge is intended for debugging, parity checks, and controlled automation: an external client can inspect the same tool schemas offered to FlashBoard Chat, execute those tools through the same dispatcher and policy layer, and inspect the resulting history.

## Architecture

```text
Codex or another MCP client
|
| stdio MCP
v
scripts/masterselects-mcp.mjs
|
| authenticated HTTP
v
Vite /api/agent-control
|
| targeted Vite HMR request
v
Selected MasterSelects browser tab
|
+-- FlashBoard Chat dispatcher and approval policy
+-- project chat history
+-- browser-wide AI tool audit
```

The browser is the execution authority. The HTTP server does not reproduce editor state or tool behavior, so bridge calls observe the same currently loaded project and state as an in-app AI call.

## Requirements

- Run the MasterSelects Vite development server at `http://localhost:5173`.
- Keep at least one editor tab open. After a page reload, allow about five seconds for bridge presence to register.
- Keep `.ai-bridge-token` private. The MCP adapter reads it directly and does not expose it as a tool result.
- Restart Codex after adding or changing the MCP registration so it reloads the server configuration.

The checked-in `.mcp.json` registers the adapter for clients that support project-local MCP configuration. A matching personal Codex registration can run:

```text
node scripts/masterselects-mcp.mjs
```

Environment variables:

| Variable | Default | Purpose |
|---|---|---|
| `MASTERSELECTS_BRIDGE_URL` | `http://localhost:5173` | Vite bridge base URL |
| `MASTERSELECTS_BRIDGE_SURFACE` | `chat` | Default execution surface: `chat` or `devBridge` |
| `MASTERSELECTS_BRIDGE_SESSION_ID` | none | Initial target session |
| `MASTERSELECTS_BRIDGE_TOKEN_FILE` | project `.ai-bridge-token` | Alternate token file |
| `MASTERSELECTS_BRIDGE_TIMEOUT_MS` | `60000` | Default request timeout |

## MCP Tools

The MCP server publishes the current FlashBoard Chat tools with their exact live JSON schemas. It also provides these control tools:

| Tool | Purpose |
|---|---|
| `bridge_list_sessions` | List connected browser tabs and their project/chat metadata |
| `bridge_select_session` | Select the tab used by subsequent direct calls |
| `bridge_list_tools` | Read the live tool registry for either surface |
| `bridge_get_tool_schema` | Inspect one live schema and policy |
| `bridge_call_tool` | Execute a named tool, optionally as a dry run |
| `bridge_get_history` | Merge saved project chat calls, browser audit calls, and bridge traces |
| `bridge_get_tool_result` | Read the stored details of one call |
| `bridge_replay_tool_call` | Replay a stored call with optional replacement arguments |
| `bridge_send_chat_message` | Run a complete turn through the real in-app chat agent |
| `bridge_compare_chat_prompts` | Compare legacy-v1 and v2 with identical read-only tasks |
| `bridge_list_chat_runs` | List durable UI, bridge, MCP, and test chat runs |
| `bridge_get_chat_run` | Read a run’s exact system prompt, response, tool calls, results, and timing |
| `bridge_get_chat_system_prompt` | Render v1 or v2 plus live context/playbook without calling a model |

Direct MCP calls to a published editor tool use the `chat` surface by default. That route goes through the FlashBoard Chat execution layer and therefore uses the current in-app approval mode and tool policy.

Chat turns require explicit `confirm: true` because they can incur provider cost; normal mode may also mutate the editor. `dryRun: true` validates routing and reports the expected provider-round count without sending a model request. Prompt comparison always runs with technically enforced read-only tool execution and makes two provider calls.

## HTTP API

All routes are under `/api/agent-control` and require the same bridge token accepted by `/api/ai-tools`.

| Method | Route | Purpose |
|---|---|---|
| `GET` | `/sessions` | Connected browser sessions |
| `GET` | `/tools?surface=chat` | Live tool list |
| `GET` | `/tools/:name?surface=chat` | One tool schema |
| `GET` | `/history?sessionId=...&limit=500` | Merged history |
| `GET` | `/calls/:callId?sessionId=...` | One stored result |
| `POST` | `/call` | Execute or dry-run a tool |
| `POST` | `/replay` | Replay a stored call |

Example request body:

```json
{
"sessionId": "opaque-tab-id",
"surface": "chat",
"tool": "getTimelineState",
"args": {},
"dryRun": false,
"idempotencyKey": "debug-read-001"
}
```

Explicit unknown or stale session IDs fail instead of silently targeting another tab.

Complete chat-agent runs use the separate authenticated `/api/agent-chat` control plane:

| Method | Route | Purpose |
|---|---|---|
| `GET` | `/prompt` | Render v2 or legacy-v1, optional task playbook, and live context |
| `GET` | `/runs` | List durable chat runs |
| `GET` | `/runs/:runId` | Read one complete run |
| `POST` | `/turn` | Execute one full model/tool loop |
| `POST` | `/compare` | Run the same read-only task through legacy-v1 and v2 |

`POST /turn` supports provider/model selection, history inclusion, chat-store persistence, prompt version or complete override, context/playbook toggles, reasoning effort, temperature, read-only enforcement, timeout, and idempotency keys. The response contains the final model answer and every executed tool call; the durable run additionally stores the exact resolved system prompt.

## Chat Agent v2

The built-in v2 prompt replaces the recipe-heavy default with a compact operating loop:

```text
Inspect -> Plan -> Act -> Verify -> Report
```

The previous prompt remains available as `legacy-v1` for regression comparisons. Specialized instructions are selected from the user’s current task and injected only when relevant, including montage, transcript, face/person, silence, quality-analysis, and visual-verification playbooks. Call budgets, approval policy, and diagnostic read-only execution are enforced in code instead of relying on prompt compliance.

Conversation context now includes bounded summaries of prior successful tool calls and their results. This allows a later turn to know what was actually executed rather than seeing only assistant prose.

Long inspection tools are also bounded:

- `getClipAnalysis` returns a summary by default; use `includeFrames`, a source-time range, `offset`, and `limit` for details.
- `getClipTranscript` returns a bounded word page and `hasMore`/`nextOffset` continuation metadata.

## History And Safety

The history response keeps three sources distinct:

- `project`: tool calls already stored in the open project’s FlashBoard chat messages;
- `audit`: central browser-side records for in-app and bridge-triggered AI tool execution;
- `bridgeCalls`: durable JSONL traces created by HTTP/MCP bridge requests.

Chat-agent runs are stored separately in browser IndexedDB (`masterselects-ai-chat-runs`). They survive UI chat clearing and contain source, session/project, provider/model, prompt version, exact resolved system prompt, full request prompt, response, tool calls/results, execution mode, status, and timing. API keys are never included.

Audit and bridge records include source, caller context, session, timing, policy snapshot, arguments, status, result, replay origin, and idempotency key where applicable. Secret-like fields are redacted, and embedded base64 images are omitted from durable traces. MCP returns a discovered image as image content instead of duplicating its data in structured output.

`dryRun` resolves the target and policy without performing the tool. An `idempotencyKey` prevents accidental duplicate bridge execution. Replays keep a link to the original call. On the broader `devBridge` surface, mutating or sensitive calls require explicit `confirm: true`; the default `chat` surface delegates approval to the same in-app policy used by FlashBoard Chat.

## Current Scope

- This control plane is attached to the local Vite development bridge; it is not a hosted production API.
- A browser tab must remain connected because the real editor state and dispatcher live in the browser.
- Hosted Cloudflare/D1 chat logs are a separate data source and are not silently merged into local project history.
- A timeout stops waiting on the HTTP side but cannot forcibly cancel browser work that has already started. Use idempotency keys for safe retries.
- Native Helper parity and multi-editor routing outside the Vite bridge are not part of this implementation.
Loading
Loading