feat: scrum4me-copilot host-side integration (in-app drawer) #54

Merged
janpeter merged 14 commits from claude/epic-wiles-b9e081 into main 2026-06-18 19:57:59 +02:00
Owner

Summary

Embed the scrum4me-copilot as an in-app drawer (Chat/Docs/Ideas/Jobs), mirroring the DigiPlein integration. Host-side wiring only; authorization is enforced server-side by the central copilot service via Scrum4Me product membership. Design reviewed by codex (OORDEEL: GO, 2 rounds); implemented via subagent-driven TDD with per-task spec + code-quality review and a final whole-implementation review.

  • Vendored kit git submodule + webpack build plumbing (--webpack, @s4m-kit/* alias, extensionAlias)
  • /api/s4m/[...path] catch-all proxy route via createS4MRoutes (empty ToolRegistry, force-dynamic)
  • copilotRequireSession iron-session adapter (single-user identity)
  • /api/s4m CSRF carve-out in the active root proxy.ts + removal of the dead src/proxy.ts
  • <S4MCopilotDrawer> mounted app-wide behind the session + Tailwind v4 styling token contract
  • Host env (S4M_COPILOT_URL/S4M_COPILOT_APP_KEY) + web joins the external compose_default network
  • CI checks out submodules (SUBMODULE_TOKEN); npm test scoped away from vendored tests

Test plan

  • npm run build green (project DoD); route ƒ /api/s4m/[...path] present
  • npm test: copilot-session (2) + proxy CSRF (2) + existing unit tests pass (231). The 20 failures are pre-existing Immich/library/slideshow integration tests that require a live Postgres (Can't reach database server) — unrelated to this change; CI runs docker build only
  • Browser e2e (deferred until the ops binding is live): drawer opens → not_linked before linking → chat streams + Docs/Ideas/Jobs after

Ops prerequisites (before the copilot answers)

  • JP mints the COPILOT-scoped MCP token + links the copilot user in Scrum4Me-web (product cmpecvxh70002vh7r2b5pye3m)
  • App-key agreed out-of-band → host media-organizer.env.sops + service copilot.env (154 adds COPILOT_APP_MEDIAORGANIZER_*, DISPATCH_JOBS=true)
  • Deploy flow must git submodule update --init before build; SUBMODULE_TOKEN configured; external compose_default network must exist

Spec: docs/superpowers/specs/2026-06-18-media-organizer-copilot-integration-design.md
Plan: docs/superpowers/plans/2026-06-18-copilot-host-integration.md
Scrum4Me: PBI-11 / ST-015 / T-73…T-79

🤖 Generated with Claude Code

## Summary Embed the `scrum4me-copilot` as an in-app drawer (Chat/Docs/Ideas/Jobs), mirroring the DigiPlein integration. Host-side wiring only; authorization is enforced server-side by the central copilot service via Scrum4Me product membership. Design reviewed by codex (OORDEEL: GO, 2 rounds); implemented via subagent-driven TDD with per-task spec + code-quality review and a final whole-implementation review. - Vendored kit git submodule + webpack build plumbing (`--webpack`, `@s4m-kit/*` alias, `extensionAlias`) - `/api/s4m/[...path]` catch-all proxy route via `createS4MRoutes` (empty `ToolRegistry`, `force-dynamic`) - `copilotRequireSession` iron-session adapter (single-user identity) - `/api/s4m` CSRF carve-out in the active root `proxy.ts` + removal of the dead `src/proxy.ts` - `<S4MCopilotDrawer>` mounted app-wide behind the session + Tailwind v4 styling token contract - Host env (`S4M_COPILOT_URL`/`S4M_COPILOT_APP_KEY`) + `web` joins the external `compose_default` network - CI checks out submodules (`SUBMODULE_TOKEN`); `npm test` scoped away from vendored tests ## Test plan - [x] `npm run build` green (project DoD); route `ƒ /api/s4m/[...path]` present - [x] `npm test`: copilot-session (2) + proxy CSRF (2) + existing unit tests pass (231). The 20 failures are pre-existing Immich/library/slideshow integration tests that require a live Postgres (`Can't reach database server`) — unrelated to this change; CI runs `docker build` only - [ ] Browser e2e (deferred until the ops binding is live): drawer opens → `not_linked` before linking → chat streams + Docs/Ideas/Jobs after ## Ops prerequisites (before the copilot answers) - JP mints the COPILOT-scoped MCP token + links the copilot user in Scrum4Me-web (product `cmpecvxh70002vh7r2b5pye3m`) - App-key agreed out-of-band → host `media-organizer.env.sops` + service `copilot.env` (154 adds `COPILOT_APP_MEDIAORGANIZER_*`, `DISPATCH_JOBS=true`) - Deploy flow must `git submodule update --init` before build; `SUBMODULE_TOKEN` configured; external `compose_default` network must exist Spec: `docs/superpowers/specs/2026-06-18-media-organizer-copilot-integration-design.md` Plan: `docs/superpowers/plans/2026-06-18-copilot-host-integration.md` Scrum4Me: PBI-11 / ST-015 / T-73…T-79 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Host-side wiring mirroring DigiPlein: submodule vendoring, /api/s4m proxy route,
empty ToolRegistry full drawer, CSRF carve-out, styling token contract, and the
docker compose_default network join. Ops track (binding/token/linking) split out.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Blocker (proxy ambiguity): prove root proxy.ts is the active compiled proxy
  via build-artifact inspection; add deletion of the dead src/proxy.ts to remove
  the ambiguity (narrow IDEA-132 half); note presence-only-auth hardening as
  out of scope.
- Major (@source path): fix to ../../vendor/scrum4me-copilot/kit (globals.css is
  at src/app/, two levels above repo-root vendor/).
- Note baseline build verified green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Spread existing config.resolve.extensionAlias first so the required .js->[.ts,.tsx,.js]
  mapping always wins (codex round-2 minor).
- Status: reviewed by codex (GO); awaiting user sign-off.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bite-sized TDD plan (8 tasks) derived from the codex-GO'd design spec, mapping to
Scrum4Me PBI-11 / ST-015 / T-73..T-79.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
tsx --test auto-discovered vendor/scrum4me-copilot's vitest-based tests; scope
discovery to src/ + repo-root host tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ci: use submodules: true (non-recursive) for checkout
Some checks failed
CI / docker-build (pull_request) Failing after 2s
e109dbe562
The host build only needs vendor/scrum4me-copilot (kit + protocol); the kit's
nested scrum4me-shared submodule is service-only. 'true' (one level) suffices and
avoids requiring SUBMODULE_TOKEN access to scrum4me-shared. Matches DigiPlein.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Merge origin/main into copilot integration
Some checks failed
CI / docker-build (pull_request) Failing after 2s
b2cf12375c
Resolve the proxy collision with #53 (proxy consolidation): main made
src/proxy.ts the single canonical proxy (CSRF + CSP) and removed the root
proxy.ts. Re-apply the /api/s4m CSRF prefix carve-out (+ tests) onto the
consolidated src/proxy.ts; drop our root-proxy edits and our src/proxy.ts
deletion. Keep both SessionHeartbeat (#52) and S4MCopilotDrawer in (app)/layout.
Build green; proxy + copilot-session tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
janpeter/Media-Organizer!54
No description provided.