Skip to content

Commit 67047fb

Browse files
msitarzewskiclaude
andcommitted
feat: v0.2.0 — single-server architecture, multi-track recording, deployment
Single process serves static files, API, WebSocket signaling, and Icecast listener proxy on one port (6736). `git clone && npm install && npm start` gets a working studio. - Static file serving with directory traversal prevention - Icecast listener proxy at /stream/* (keeps everything on one port) - Dynamic client URLs (works at any deployment, no hardcoded localhost) - Auto-copy station-manifest.sample.json on first run - Client-side multi-track recording (per-participant + program mix) - WAV export via OfflineAudioContext - Room TTL for demo servers (ROOM_TTL_MS env var) - Deployment config (Caddy, systemd, Docker Compose, setup script) - README repositioned for conversion (584 → 122 lines) - GitHub Codespaces, CI matrix (Node 18/20/22), issue/PR templates - Host microphone included in recordings - Fixed process.env reference in browser (icecast-streamer.js) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 2da4ddc commit 67047fb

43 files changed

Lines changed: 2636 additions & 2746 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.devcontainer/devcontainer.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "OpenStudio",
3+
"image": "mcr.microsoft.com/devcontainers/javascript-node:18",
4+
"features": {
5+
"ghcr.io/devcontainers/features/docker-in-docker:2": {}
6+
},
7+
"forwardPorts": [6736, 6737, 3478],
8+
"postCreateCommand": "cd server && npm install",
9+
"customizations": {
10+
"vscode": {
11+
"extensions": [
12+
"dbaeumer.vscode-eslint"
13+
]
14+
}
15+
}
16+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: Bug Report
2+
description: Report a bug in OpenStudio
3+
title: "[Bug]: "
4+
labels: ["bug"]
5+
body:
6+
- type: markdown
7+
attributes:
8+
value: Thanks for reporting a bug! Please fill out the sections below.
9+
- type: input
10+
id: version
11+
attributes:
12+
label: OpenStudio Version
13+
description: What version are you running?
14+
placeholder: "0.2.0"
15+
validations:
16+
required: true
17+
- type: dropdown
18+
id: browser
19+
attributes:
20+
label: Browser
21+
options:
22+
- Chrome
23+
- Firefox
24+
- Safari
25+
- Brave
26+
- Edge
27+
- Other
28+
validations:
29+
required: true
30+
- type: textarea
31+
id: description
32+
attributes:
33+
label: What happened?
34+
description: A clear description of the bug.
35+
validations:
36+
required: true
37+
- type: textarea
38+
id: expected
39+
attributes:
40+
label: Expected behavior
41+
description: What did you expect to happen?
42+
validations:
43+
required: true
44+
- type: textarea
45+
id: reproduce
46+
attributes:
47+
label: Steps to reproduce
48+
description: How can we reproduce this?
49+
placeholder: |
50+
1. Start server with `npm start`
51+
2. Open browser to localhost:6736
52+
3. Click 'Start Session'
53+
4. See error in console
54+
validations:
55+
required: true
56+
- type: textarea
57+
id: logs
58+
attributes:
59+
label: Console output / logs
60+
description: Any relevant console output (browser or server)
61+
render: shell
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: Feature Request
2+
description: Suggest a new feature for OpenStudio
3+
title: "[Feature]: "
4+
labels: ["enhancement"]
5+
body:
6+
- type: markdown
7+
attributes:
8+
value: Thanks for suggesting a feature! Please describe what you'd like.
9+
- type: textarea
10+
id: problem
11+
attributes:
12+
label: Problem
13+
description: What problem does this solve?
14+
validations:
15+
required: true
16+
- type: textarea
17+
id: solution
18+
attributes:
19+
label: Proposed solution
20+
description: How would you like this to work?
21+
validations:
22+
required: true
23+
- type: textarea
24+
id: alternatives
25+
attributes:
26+
label: Alternatives considered
27+
description: Any alternative solutions you've thought about?
28+
- type: dropdown
29+
id: category
30+
attributes:
31+
label: Category
32+
options:
33+
- Audio / WebRTC
34+
- UI / UX
35+
- Server / Signaling
36+
- Streaming / Icecast
37+
- Recording
38+
- Deployment
39+
- Documentation
40+
- Other

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
## Summary
2+
3+
<!-- What does this PR do? Keep it to 1-3 bullet points. -->
4+
5+
-
6+
7+
## Changes
8+
9+
<!-- List the key files changed and why. -->
10+
11+
## Test Plan
12+
13+
- [ ] Server tests pass (`npm test`)
14+
- [ ] Manual test: start session, verify audio
15+
- [ ] Tested in Chrome
16+
- [ ] Tested in Firefox
17+
18+
## Screenshots
19+
20+
<!-- If UI changes, add before/after screenshots. -->

.github/workflows/ci.yml

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
13+
strategy:
14+
matrix:
15+
node-version: [18, 20, 22]
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Use Node.js ${{ matrix.node-version }}
21+
uses: actions/setup-node@v4
22+
with:
23+
node-version: ${{ matrix.node-version }}
24+
cache: npm
25+
cache-dependency-path: |
26+
package-lock.json
27+
server/package-lock.json
28+
29+
- name: Install root dependencies
30+
run: npm ci
31+
32+
- name: Install server dependencies
33+
run: cd server && npm ci
34+
35+
- name: Install Playwright browsers
36+
run: npx playwright install --with-deps chromium
37+
38+
- name: Run server tests
39+
run: |
40+
# Start signaling server in background
41+
node server/server.js &
42+
SERVER_PID=$!
43+
44+
# Wait for server to be ready
45+
for i in $(seq 1 30); do
46+
if curl -s http://localhost:6736/health > /dev/null 2>&1; then
47+
echo "Server is ready"
48+
break
49+
fi
50+
sleep 1
51+
done
52+
53+
# Run server tests
54+
node server/test-signaling.js
55+
node server/test-rooms.js
56+
57+
# Keep server running for Playwright tests
58+
59+
- name: Run Playwright tests
60+
run: |
61+
node tests/test-webrtc.mjs
62+
node tests/test-audio-graph.mjs
63+
node tests/test-gain-controls.mjs
64+
node tests/test-program-bus.mjs
65+
node tests/test-mix-minus.mjs
66+
node tests/test-return-feed.mjs

AGENTS.md

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# AGENTS.md
22

3-
**Version**: 2.1 (2025-10-25) | **Compatibility**: Claude, Cursor, Copilot, Cline, Aider, all AGENTS.md-compatible tools
3+
**Version**: 2.2 (2025-03-04) | **Compatibility**: Claude, Cursor, Copilot, Cline, Aider, all AGENTS.md-compatible tools
44
**Status**: Canonical single-file guide for AI-assisted development
55

66
---
@@ -9,6 +9,7 @@
99

1010
1. [Compliance & Core Rules](#1-compliance--core-rules)
1111
2. [Session Startup](#2-session-startup)
12+
- [Compaction Protocol](#compaction-protocol-mid-session-context-preservation)
1213
3. [Memory Bank](#3-memory-bank)
1314
4. [State Machine](#4-state-machine)
1415
5. [Task Contract & Budgets](#5-task-contract--budgets)
@@ -106,6 +107,45 @@ Append-only JSONL format:
106107
{"timestamp":"2025-10-25T11:00:00Z","session_id":"uuid","event":"approval_requested","state":"APPROVAL"}
107108
```
108109

110+
### Compaction Protocol (Mid-Session Context Preservation)
111+
112+
Compaction (context compression) can happen at any time — triggered by the system automatically, by the user via `/compact`, or by platform-level context management. **The agent does not control compaction timing and may not get advance notice.** Therefore, state persistence must be continuous, not deferred to a pre-compaction moment.
113+
114+
#### Continuous State Persistence (At Every State Transition)
115+
116+
At each state transition (`PLAN → BUILD → DIFF → QA → APPROVAL → APPLY → DOCS`), persist the following to the Memory Bank:
117+
118+
1. **State machine position**: Update `activeContext.md` with current state, substate, and working context
119+
2. **Task progress**: Append current status to `tasks/YYYY-MM/README.md` with `[IN-PROGRESS]` tag
120+
3. **Decisions**: Append any new architectural decisions to `decisions.md`
121+
4. **Log transition** to operational log:
122+
```json
123+
{"timestamp":"...","session_id":"uuid","event":"state_transition","from":"PLAN","to":"BUILD"}
124+
```
125+
5. **Loose context**: Capture any information that exists only in conversation (user preferences, verbal requirements, pending questions) into `activeContext.md`
126+
127+
This ensures that when compaction occurs — without warning — the Memory Bank already reflects the latest state.
128+
129+
#### After Compaction (Recovery)
130+
131+
When context has been compressed (detected by loss of earlier conversation detail, or after `/compact`):
132+
133+
1. Re-enter **Session Startup** (Section 2) using **Fast Track** mode — the Memory Bank was just updated via continuous persistence, so full discovery is unnecessary
134+
2. Confirm state machine position from `activeContext.md`
135+
3. Resume from saved state — do not restart the current task from scratch
136+
4. Output recovery confirmation:
137+
```
138+
COMPACTION RECOVERY: Resumed [STATE] for [task name]
139+
Context restored from: activeContext.md, tasks/YYYY-MM/README.md
140+
```
141+
142+
#### Rules
143+
144+
- State persistence happens at every transition, not "before compaction" — you cannot rely on advance notice
145+
- After detecting compaction, always re-read Memory Bank before taking any action
146+
- If the current state is `APPROVAL` or `DIFF`, the diff summary should already be in `activeContext.md` from the transition save
147+
- Compaction does not reset budgets — carry forward cycle/token/minute counts from the operational log
148+
109149
---
110150

111151
## 3. Memory Bank
@@ -577,7 +617,7 @@ Create outline for approval. After approval, do work. Do not document until I ap
577617
2. **Task** (current task): Files being modified, direct dependencies, related tests
578618
3. **Reference** (on-demand): Arch patterns, similar implementations, historical decisions
579619

580-
**Context Rotation**: After each state transition, drop Task Context, reload only what's needed for next state. Keep Core Context persistent.
620+
**Context Rotation**: After each state transition, drop Task Context, reload only what's needed for next state. Keep Core Context persistent. State is persisted to Memory Bank at every transition per **Compaction Protocol** (Section 2), so compaction recovery is automatic.
581621

582622
**Parallel Execution**:
583623
```
@@ -896,7 +936,7 @@ Stuck? → Cycles ≥3?
896936
| Issue | Symptoms | Resolution |
897937
|-------|----------|------------|
898938
| **Loop** | Same diff multiple times, QA fails repeatedly, no progress after 3+ cycles | Check budgets → Load more MB → Clarify requirements → Check environment → Agent swap |
899-
| **Context Exceeded** | Token limit approaching, slow/truncated responses, forgetting earlier info | Rotate context (drop Task, reload essentials) → Focused mode (MB summaries only) → Break into subtasks → Agent swap |
939+
| **Context Exceeded** | Token limit approaching, slow/truncated responses, forgetting earlier info | State already persisted via **Compaction Protocol** (Section 2) → Rotate context (drop Task, reload essentials) → Focused mode (MB summaries only) → Break into subtasks → Agent swap |
900940
| **CI ≠ Local** | QA passes, CI fails | Compare environments → Verify dependency versions → Check timing/concurrency → Check state cleanup → Document waiver if CI issue |
901941
| **Security Fail** | Security checklist incomplete, sensitive data exposed, auth/authz bypassed | Never bypass → Return to BUILD → Fix all issues → Re-test → Document pattern if new |
902942

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ All notable changes to OpenStudio will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8-
## [0.1.0] - 2025-10-26
8+
## [0.1.0] - 2026-03-12
99

1010
### Added
1111

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 OpenStudio Contributors
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

0 commit comments

Comments
 (0)