Skip to content
Merged

Dev #21

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
165 commits
Select commit Hold shift + click to select a range
fd0d387
Add MCP memory search guidance
May 16, 2026
dd2ae21
Thread originServerId through memory recall pipeline
May 16, 2026
69d1318
Cap preview ChatView events + render slice so SubSessionCard doesn't …
May 16, 2026
fa313b5
Route MCP get_memory_sources to the owning daemon across servers
May 16, 2026
c2ad1e3
Document ?serverId= query-string as the preferred pod-sticky convention
May 16, 2026
6b55d85
Close test gaps for memory-source-server-routing
May 16, 2026
f69e197
Pin search→cache side effect for memory-source-server-routing
May 16, 2026
536da5d
Use shared error-code constants in memory-source routing path
May 16, 2026
94f5d6d
Suppress \"no events\" placeholder while history is still bootstrapping
May 16, 2026
78da3a4
Lift mobile file-preview above the sub-session window on the z-stack
May 16, 2026
e4b097e
Seed useTimeline events synchronously at mount to eliminate cache flash
May 16, 2026
9ea9aa6
Fix IndexedDB open-race data loss + raise local-history snapshot cap
May 16, 2026
90cd30e
Prioritize IDB load for the active session; defer inactive cards to idle
May 16, 2026
055e051
Improve startup memory bootstrap context
May 16, 2026
da09b8d
Document managed MCP tools
May 16, 2026
c44407e
Fix non-active chat windows showing empty history
May 16, 2026
f4a52d3
Surface user preferences in memory-context timeline card
May 16, 2026
36682b6
Allow cold-cache inactive sessions one daemon-history fetch
May 17, 2026
a9aec3c
Fix scope-drift orphan reads in IDB and localStorage
May 17, 2026
02c97e4
Preserve personal local startup memory under remote-processed authority
May 17, 2026
93629e7
Speed up mobile sub-session toggles
May 17, 2026
5ea28f1
Fix mobile sub-session touch toggle
May 17, 2026
76bd517
Reduce sub-session timeline startup fanout
May 18, 2026
070a6cb
Stabilize timeline cache unit tests
May 18, 2026
4db8c7a
Fix long-running web timeline freezes
May 18, 2026
05329c8
Defer sub-session startup rendering
May 18, 2026
6c4fd97
Harden legacy file upload validation
May 18, 2026
77f1cb7
Use shared upload error code
May 18, 2026
0c358be
Improve streaming chat render performance
May 18, 2026
fe7230d
Handle Blob websocket binary messages
May 18, 2026
25d5dd7
Fix timeline rendering stalls
May 19, 2026
860ef24
Fix systemd linger setup for bound daemons
May 19, 2026
3f88c94
Show full file change updates
May 19, 2026
310efe9
Hide worker sessions from main windows
May 19, 2026
822b0a4
Improve file browser create controls
May 19, 2026
d1b5ff8
fix p2p discussion progress sync
May 19, 2026
6fddcfc
Fix large upload relay handling
May 20, 2026
b0ca2fb
Fix transport subscription stale status
May 20, 2026
5659151
Fix daemon startup blocking sync work
May 20, 2026
f36a572
Fix qwen compatible API thinking resume
May 21, 2026
23019d6
Fix web build for qwen thinking controls
May 21, 2026
1f33e2c
Fix qwen queue terminal handling
May 21, 2026
f404c24
fix(web): add mobile tab long-press menu
May 22, 2026
243e689
feat(upload): stream daemon fetch progress
May 22, 2026
18ea751
feat(web): add openspec folder browsing shortcut
May 22, 2026
3dff3f6
fix(web): open openspec change folders in files view
May 22, 2026
83fcf5c
fix(web): hide openspec archive from change picker
May 22, 2026
0577a47
feat(web): copy current file browser path
May 22, 2026
dc9af1f
fix(web): move file browser path to footer
May 22, 2026
4302a13
fix(web): split file browser nav and breadcrumb rows
May 22, 2026
001e5d5
fix(web): restore mobile sub-session touch actions
May 22, 2026
f4d9790
fix(web): cover expanded sub-session touch opens
May 22, 2026
bd41efd
fix(web): make mobile sub-session buttons open reliably
May 22, 2026
1552ee0
fix(web): restore mobile sub-session button toggle
May 22, 2026
014da22
Use created folder for new session path
May 22, 2026
b823596
feat: strengthen managed MCP guidance
May 23, 2026
6cd7514
fix: keep relay uploads compatible with older daemons
May 23, 2026
96b3b41
test: update daemon hello capability expectations
May 23, 2026
2f08c54
ci: retry e2e checkout
May 23, 2026
0588bb5
ci: handle npm provenance duplicate entries
May 23, 2026
c6b6431
fix: close quick file picker after insert
May 23, 2026
d00e9b9
fix: raise repo panel from sub-session branch
May 23, 2026
addc5aa
ci: retry flaky checkout jobs
May 23, 2026
754f8b4
fix: keep managed windows above sub-session fallback
May 23, 2026
13e2367
fix: layer sub-session repo panels via stack
May 23, 2026
7162ff3
docs: update why narrative for multi-model review
May 23, 2026
a4150cb
feat: add safe html file previews
May 23, 2026
3e9d84f
test: make html preview check cwd independent
May 23, 2026
c7ab47f
Add Kimi SDK provider support
May 24, 2026
2b60272
Rename P2P UI copy to Team
May 24, 2026
96f0ccd
Fix CI after Team copy rename
May 24, 2026
c24ea3c
Remove shallow default Team combos
May 24, 2026
ddfa5c7
Count final chat messages for scroll badge
May 24, 2026
68d1a2f
Keep supervision audit combos supported
May 24, 2026
a75a2bb
Stabilize timeline cache churn test
May 24, 2026
45ce47b
Polish Team workflow dropdown
May 24, 2026
ad77cbe
Fix Team dropdown style contract
May 24, 2026
494817a
Mark advanced Team workflows alpha
May 24, 2026
5687823
Fix manual memory save validation
May 24, 2026
6c7fba1
Add lexical fallback to memory recall
May 24, 2026
362df2f
Improve MCP memory search provenance
May 24, 2026
949b77f
Persist memory short refs for MCP source lookup
May 24, 2026
0d26bf1
Fix memory source expansion fallback
May 25, 2026
a22ed4d
Fix memory fallback source type
May 25, 2026
6812855
Polish memory management UI
May 25, 2026
87796fc
Fix Qwen transient retry close race
May 25, 2026
8fe132b
Add memory summary sync MCP tool
May 25, 2026
4ef194b
Collapse long sent messages
May 25, 2026
941f89d
Include memory refs in summary sync
May 25, 2026
fd4ab80
Polish sub-session toolbar shortcuts
May 25, 2026
be68cb5
Refine sub-session toolbar labels
May 25, 2026
df2350e
Fit HTML previews to viewport width
May 25, 2026
f6c7c87
Fix PDF preview worker loading
May 25, 2026
8bb8712
Open HTML previews fullscreen
May 25, 2026
83962d3
Speed up startup splash
May 25, 2026
dc0ebb8
Fix HTML preview file-too-large error code
May 25, 2026
e40fe79
Clamp fullscreen HTML previews to viewport
May 25, 2026
d5ce21d
Open file browser HTML previews fullscreen
May 25, 2026
3327b75
Scope memory summaries to current project
May 25, 2026
337266f
Add desktop labels to sub-session toolbar actions
May 25, 2026
09e8426
Update built-in quick phrases
May 25, 2026
1a5fa83
Derive MCP memory project id from session path
May 25, 2026
fc426db
Bridge private memory projections for project MCP scope
May 25, 2026
7b94539
fix: keep cloud server picker populated
May 25, 2026
8cc25d3
fix: refresh codex sdk auth on app-server reuse
May 25, 2026
650aba9
Harden cloud memory source authorization
May 25, 2026
dcd6f23
Stabilize Codex SDK provider tests
May 25, 2026
6de57b7
Use retry install for server DB CI
May 25, 2026
20e7344
Add shared agent progress guidance
May 25, 2026
63edc41
Fix chat path downloads and memory defaults
May 25, 2026
128a14c
fix: prioritize stop cancellation
May 25, 2026
7bdc171
feat: add pull quick phrase
May 25, 2026
13ad051
style: refresh app chrome visuals
May 25, 2026
e48ac26
fix: cancel sdk turns after tool activity
May 25, 2026
e2a0c7e
fix: preserve active brain tab contract
May 25, 2026
09dce66
test: stabilize codex model list pagination
May 25, 2026
5021d0c
style: refresh chat composer chrome
May 26, 2026
a6d7c98
feat: preview local chat images inline
May 26, 2026
125c639
fix: remove unused local image preview imports
May 26, 2026
ac1a392
fix: portal mobile shortcut dropdowns
May 26, 2026
afc583c
style: enhance context meter visuals
May 26, 2026
be1b31d
feat: require image path reporting
May 26, 2026
d8de4b3
fix: keep image lightbox controls below safe area
May 26, 2026
6cd60aa
fix(mobile): SessionControls stop button visibility and spacing compr…
May 26, 2026
b26b104
test: cover mobile model menu touch dismissal
May 26, 2026
5bb58db
fix(ui): ctx bar cached tokens purple color + SessionControls layout …
May 26, 2026
4585a1a
feat: refine session creation controls
May 26, 2026
1888452
Support drag file upload in composer
May 26, 2026
06c74aa
Fix chat path downloads and md ingest scheduling
May 26, 2026
42a2dc6
Expand session drag upload target
May 26, 2026
8ce8d8f
Add ctx usage burn animation
May 26, 2026
e882503
Handle frontend build drift gracefully
May 26, 2026
234d6f7
Limit ctx burn effect to used tokens
May 26, 2026
0c32427
Fix repo panel focus sync
May 26, 2026
9ce6ed0
fix: keep server rail status dots visible
May 26, 2026
cd563b8
fix: localize app update prompts
May 26, 2026
0a9bed0
feat: polish sub-session chrome controls
May 26, 2026
5bab4f6
fix: refine daemon stats clock display
May 26, 2026
7970d10
fix: cache inline chat image previews
May 26, 2026
c4454b4
chore: raise chat image preview cache limit
May 26, 2026
97f8271
style: enlarge mobile server switcher
May 26, 2026
33e091a
style: polish shared context management panel
May 26, 2026
ae87325
Make NewSessionDialog responsive + fix custom-provider checkbox layout
May 26, 2026
98cf7fc
Cap dialog width to maxWidth on narrow screens, not fixed width
May 26, 2026
33007dc
fix: harden mobile session dialog width
May 26, 2026
66f88ce
fix: cap memory summary sync payload
May 26, 2026
714e5d1
fix: slim automatic memory summaries
May 26, 2026
ef62c63
Drop nested flex layout for custom-provider help text — block flow
May 26, 2026
14890b2
fix: satisfy dialog overflowWrap contract for narrow viewports
May 26, 2026
3994f50
fix: override .form-group input width on custom-provider checkbox
May 26, 2026
b862de0
fix: route stable system context efficiently
May 26, 2026
c34aab5
fix: tighten system context routing
May 26, 2026
4e8c650
Cap user-authored session text fields at 300 chars
May 26, 2026
943025b
fix(transport): inject identity + image-reporting outside user 300-ch…
May 26, 2026
47c6c62
refactor(transport): move image-reporting to Codex baseInstructions tail
May 27, 2026
03f84cf
Scope memory recall to current project
May 27, 2026
194468d
Harden memory project scoping
May 27, 2026
d920b37
Stabilize preview read smoke timing
May 27, 2026
7838094
Report exact Codex image output paths
May 27, 2026
aebdb09
Fix Codex image path completion race
May 27, 2026
a170aae
Tighten agent progress guidance
May 27, 2026
a668f37
Increase memory summary sync limit
May 27, 2026
b5acd7e
Fix session tab pointer activation race
May 27, 2026
d174df2
Fix desktop session tab mouse activation
May 27, 2026
954f27d
Restore compact command timeline feedback
May 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 164 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,44 @@ jobs:
matrix:
node: ['22', '24']
steps:
- uses: actions/checkout@v4
- name: Checkout
id: checkout_1
continue-on-error: true
uses: actions/checkout@v4

- name: Wait before checkout retry 2
if: steps.checkout_1.outcome == 'failure'
run: |
echo "::warning::actions/checkout failed on attempt 1; retrying in 15s"
sleep 15

- name: Checkout (retry 2)
id: checkout_2
if: steps.checkout_1.outcome == 'failure'
continue-on-error: true
uses: actions/checkout@v4

- name: Wait before checkout retry 3
if: steps.checkout_1.outcome == 'failure' && steps.checkout_2.outcome == 'failure'
run: |
echo "::warning::actions/checkout failed on attempt 2; retrying in 30s"
sleep 30

- name: Checkout (retry 3)
id: checkout_3
if: steps.checkout_1.outcome == 'failure' && steps.checkout_2.outcome == 'failure'
continue-on-error: true
uses: actions/checkout@v4

- name: Wait before checkout retry 4
if: steps.checkout_1.outcome == 'failure' && steps.checkout_2.outcome == 'failure' && steps.checkout_3.outcome == 'failure'
run: |
echo "::warning::actions/checkout failed on attempt 3; retrying in 60s"
sleep 60

- name: Checkout (retry 4)
if: steps.checkout_1.outcome == 'failure' && steps.checkout_2.outcome == 'failure' && steps.checkout_3.outcome == 'failure'
uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
Expand Down Expand Up @@ -164,7 +201,47 @@ jobs:
name: Unit Tests (Windows ConPTY)
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Checkout
id: checkout_1
continue-on-error: true
uses: actions/checkout@v4

- name: Wait before checkout retry 2
if: steps.checkout_1.outcome == 'failure'
shell: bash
run: |
echo "::warning::actions/checkout failed on attempt 1; retrying in 15s"
sleep 15

- name: Checkout (retry 2)
id: checkout_2
if: steps.checkout_1.outcome == 'failure'
continue-on-error: true
uses: actions/checkout@v4

- name: Wait before checkout retry 3
if: steps.checkout_1.outcome == 'failure' && steps.checkout_2.outcome == 'failure'
shell: bash
run: |
echo "::warning::actions/checkout failed on attempt 2; retrying in 30s"
sleep 30

- name: Checkout (retry 3)
id: checkout_3
if: steps.checkout_1.outcome == 'failure' && steps.checkout_2.outcome == 'failure'
continue-on-error: true
uses: actions/checkout@v4

- name: Wait before checkout retry 4
if: steps.checkout_1.outcome == 'failure' && steps.checkout_2.outcome == 'failure' && steps.checkout_3.outcome == 'failure'
shell: bash
run: |
echo "::warning::actions/checkout failed on attempt 3; retrying in 60s"
sleep 60

- name: Checkout (retry 4)
if: steps.checkout_1.outcome == 'failure' && steps.checkout_2.outcome == 'failure' && steps.checkout_3.outcome == 'failure'
uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION_PRIMARY }}
Expand Down Expand Up @@ -243,8 +320,7 @@ jobs:
node-version: ${{ env.NODE_VERSION_PRIMARY }}
cache: 'npm'
cache-dependency-path: server/package-lock.json
- run: npm ci
working-directory: server
- run: ./scripts/ci-npm-ci.sh server
- name: Run DB integration tests
run: npm run test:integration
working-directory: server
Expand All @@ -258,7 +334,61 @@ jobs:
runs-on: ubuntu-latest
needs: [unit-tests]
steps:
- uses: actions/checkout@v4
- name: Checkout
id: checkout_1
continue-on-error: true
uses: actions/checkout@v4

- name: Wait before checkout retry 2
if: steps.checkout_1.outcome == 'failure'
shell: bash
run: |
echo "::warning::actions/checkout failed on attempt 1; retrying in 15s"
sleep 15

- name: Checkout (retry 2)
id: checkout_2
if: steps.checkout_1.outcome == 'failure'
continue-on-error: true
uses: actions/checkout@v4

- name: Wait before checkout retry 3
if: steps.checkout_1.outcome == 'failure' && steps.checkout_2.outcome == 'failure'
shell: bash
run: |
echo "::warning::actions/checkout failed on attempt 2; retrying in 30s"
sleep 30

- name: Checkout (retry 3)
id: checkout_3
if: steps.checkout_1.outcome == 'failure' && steps.checkout_2.outcome == 'failure'
continue-on-error: true
uses: actions/checkout@v4

- name: Wait before checkout retry 4
if: steps.checkout_1.outcome == 'failure' && steps.checkout_2.outcome == 'failure' && steps.checkout_3.outcome == 'failure'
shell: bash
run: |
echo "::warning::actions/checkout failed on attempt 3; retrying in 60s"
sleep 60

- name: Checkout (retry 4)
id: checkout_4
if: steps.checkout_1.outcome == 'failure' && steps.checkout_2.outcome == 'failure' && steps.checkout_3.outcome == 'failure'
continue-on-error: true
uses: actions/checkout@v4

- name: Wait before checkout retry 5
if: steps.checkout_1.outcome == 'failure' && steps.checkout_2.outcome == 'failure' && steps.checkout_3.outcome == 'failure' && steps.checkout_4.outcome == 'failure'
shell: bash
run: |
echo "::warning::actions/checkout failed on attempt 4; retrying in 90s"
sleep 90

- name: Checkout (retry 5)
if: steps.checkout_1.outcome == 'failure' && steps.checkout_2.outcome == 'failure' && steps.checkout_3.outcome == 'failure' && steps.checkout_4.outcome == 'failure'
uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION_PRIMARY }}
Expand Down Expand Up @@ -390,15 +520,40 @@ jobs:
run: npm version ${{ needs.docker.outputs.npm_version }} --no-git-tag-version
- name: Publish (skip if version already on npm)
run: |
set -euo pipefail
VERSION=${{ needs.docker.outputs.npm_version }}
PUBLISH_ARGS=(--access public)
if [ "${{ github.ref }}" = "refs/heads/dev" ]; then
PUBLISH_ARGS=(--tag dev "${PUBLISH_ARGS[@]}")
fi

if npm view "imcodes@${VERSION}" version >/dev/null 2>&1; then
echo "::warning::Version ${VERSION} already published — skipping"
elif [ "${{ github.ref }}" = "refs/heads/dev" ]; then
npm publish --tag dev --provenance --access public
else
npm publish --provenance --access public
exit 0
fi

set +e
npm publish "${PUBLISH_ARGS[@]}" --provenance 2>&1 | tee npm-publish.log
publish_status=${PIPESTATUS[0]}
set -e

if [ "${publish_status}" -eq 0 ]; then
exit 0
fi

if npm view "imcodes@${VERSION}" version >/dev/null 2>&1; then
echo "::warning::Version ${VERSION} was published despite npm publish exiting ${publish_status}; treating as success"
exit 0
fi

if grep -q 'TLOG_CREATE_ENTRY_ERROR' npm-publish.log; then
echo "::warning::npm provenance transparency-log entry already exists, but ${VERSION} is not published; retrying once without --provenance"
npm publish "${PUBLISH_ARGS[@]}"
exit 0
fi

exit "${publish_status}"

# ── Build & push Docker image ─────────────────────────────────────────────

docker:
Expand Down
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ The web project uses `i18next` with `react-i18next` for internationalization.
- Session names follow the pattern `deck_{project}_{role}` (e.g., `deck_myapp_brain`, `deck_myapp_w1`).
- Main sessions and sub-sessions are the same session model. Treat them as equally important in behavior, queueing, timeline semantics, edit/undo, and lifecycle handling. Differences should come only from parent/attachment relationship and presentation constraints, not from weaker semantics for sub-sessions.
- Agent types: Process = `'claude-code' | 'codex' | 'gemini' | 'opencode' | 'shell' | 'script'`, Transport = `'openclaw' | 'qwen'` — the `AgentType` union in `src/agent/detect.ts`.
- **Pod-sticky routing (MANDATORY for daemon-dependent requests)**: The server runs multiple replicas. Each daemon connects to ONE pod via WebSocket. The ingress uses `:serverId` in the URL path to route requests to the pod holding that daemon's WS. Any endpoint that depends on the daemon (file transfer, session commands, Watch API) **MUST** include `:serverId` in the URL path (e.g., `/api/server/:serverId/...`). In-memory state (download tokens, WsBridge instances, terminal streams) is per-pod — requests without serverId routing will hit a random pod and fail.
- **Pod-sticky routing (MANDATORY for daemon-dependent requests)**: The server runs multiple replicas. Each daemon connects to ONE pod via WebSocket. The ingress routes any request that carries `serverId` (as a `?serverId=` query string OR as a `:serverId` URL-path parameter) to the pod holding that daemon's WS. Any endpoint that depends on the daemon (file transfer, session commands, Watch API, memory source resolution) **MUST** carry `serverId`. In-memory state (download tokens, WsBridge instances, terminal streams, pending RPCs) is per-pod — requests without serverId routing will hit a random pod and fail.
- **Convention going forward — prefer `?serverId=` query string** for new routes. The ingress handles this generically: any route under `/api/...` that carries `?serverId=` is pod-sticky-routed without needing a dedicated path-style mount. Use `c.req.query('serverId')` server-side and treat its presence as the routing key. Path-style `/api/server/:serverId/...` mounts still work for existing routes (file-transfer, watch, cron, session-mgmt, etc.) — don't break them — but new routes should follow the query-string convention. Example: `GET /api/memory/sources?serverId=...&projectionId=...` lives under a flat `/api` mount and is automatically routed to the pod holding that daemon's WS.
- **MANDATORY — Transport command liveness contract:** Daemon command receipt and urgent-control delivery MUST preserve current dev behavior. The daemon MUST NOT intercept `/compact`; `/compact` is an ordinary SDK-native message and is forwarded unchanged to the transport provider. Provider adapters that expose a native compact RPC (for example Codex app-server `thread/compact/start`) MUST translate the raw `/compact` command at the SDK boundary instead of sending it as model text. Ordinary `session.send` ack is a daemon-receipt ack and MUST NOT wait for recall, live context bootstrap, memory lookup/enrichment, embedding, transport lock, pending relaunch, provider send-start, provider settlement, telemetry, or any background memory work. `/stop` and approval/feedback/control responses MUST use the priority path and MUST NOT be routed through or blocked by the ordinary send queue/locks.
- Server secrets (`JWT_SIGNING_KEY`) are set via environment variables, never committed.
- E2E tests require tmux. They are auto-skipped when `SKIP_TMUX_TESTS=1` or inside a Claude Code session (`CLAUDECODE` env var set).
Expand Down
Loading
Loading