From 53c3565874f02d18f3faf4ce1ead9fc70798b980 Mon Sep 17 00:00:00 2001 From: saravanakumardb1 Date: Thu, 2 Apr 2026 23:02:38 -0700 Subject: [PATCH] fix(cowork-service): audit flush field name mismatch + server test mock gap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: flush-scheduler.ts flushAudit() read 'events' from IPC response but Rust handle_flush_audit() returns { count, entries }. Audit events were silently lost (always empty array). Fixed to read 'entries'. Also fixed: - server.test.ts: added missing flush-scheduler.js mock (new import in server.ts) - feature-flags.ts: doc comment '12 flags' → '13 flags' - flush-scheduler.test.ts: mock data aligned to Rust response shape 49 tests passing, 8 test files, typecheck clean. --- .windsurf/workflows/repos.txt | 20 +++- .../WINDSURF/.last-refresh.log | 10 +- .../learning_ai_common_plat/repos.txt | 20 +++- scripts/update-agent-docs.sh | 105 ++++++++++++++++++ .../cowork-service/src/lib/feature-flags.ts | 2 +- .../src/lib/flush-scheduler.test.ts | 4 +- .../cowork-service/src/lib/flush-scheduler.ts | 3 +- services/cowork-service/src/server.test.ts | 8 ++ 8 files changed, 157 insertions(+), 15 deletions(-) diff --git a/.windsurf/workflows/repos.txt b/.windsurf/workflows/repos.txt index a7546012..6f0530b6 100644 --- a/.windsurf/workflows/repos.txt +++ b/.windsurf/workflows/repos.txt @@ -1,8 +1,12 @@ -# All workspace repositories -# Single source of truth for repo-management workflows -# Reference this file in scripts instead of hardcoding repo lists +# All workspace repositories — SINGLE SOURCE OF TRUTH +# Used by all /repo_* workflows and scripts (backup, commit, push, sync, agent-docs) +# Paths are relative to ~/code/mygh/ (the workspace root) +# To add a new repo: append its path here and all workflows will pick it up automatically +# --- Platform & shared --- learning_ai_common_plat + +# --- Product repos --- learning_voice_ai_agent learning_multimodal_memory_agents learning_ai_clock @@ -13,6 +17,16 @@ learning_ai_notes learning_ai_flowmonk learning_ai_trails learning_ai_local_memory_gpt +learning_ai_efforise +learning_ai_local_llms + +# --- Auth & identity --- learning_ai_smart_auth learning_ai_auth_app + +# --- Web & misc --- learning_ai_productivity_web + +# --- OSS (subdirectory repos under oss/) --- +oss/learning_ai_claw-code-oss +oss/learning_ai_claw-cowork diff --git a/__LOCAL_LLMs/AI_IDE_CHAT_HISTORY/WINDSURF/.last-refresh.log b/__LOCAL_LLMs/AI_IDE_CHAT_HISTORY/WINDSURF/.last-refresh.log index bb58a7c5..5f187673 100644 --- a/__LOCAL_LLMs/AI_IDE_CHAT_HISTORY/WINDSURF/.last-refresh.log +++ b/__LOCAL_LLMs/AI_IDE_CHAT_HISTORY/WINDSURF/.last-refresh.log @@ -1,9 +1,9 @@ -Last refresh: 2026-04-02T17:27:25Z (2026-04-02 10:27:25 PDT) -Cascade conversations: 50 (330M) -Memories: 119 +Last refresh: 2026-04-03T06:00:06Z (2026-04-02 23:00:06 PDT) +Cascade conversations: 50 (297M) +Memories: 121 Implicit context: 20 -Code tracker dirs: 102 -File edit history: 4201 entries +Code tracker dirs: 106 +File edit history: 4222 entries Workspace storage: 37 workspaces Repo docs: 7 files across 2 repos Repo workflows: 54 files across 12 repos diff --git a/__LOCAL_LLMs/AI_IDE_CHAT_HISTORY/WINDSURF/repo_workflows/learning_ai_common_plat/repos.txt b/__LOCAL_LLMs/AI_IDE_CHAT_HISTORY/WINDSURF/repo_workflows/learning_ai_common_plat/repos.txt index a7546012..6f0530b6 100644 --- a/__LOCAL_LLMs/AI_IDE_CHAT_HISTORY/WINDSURF/repo_workflows/learning_ai_common_plat/repos.txt +++ b/__LOCAL_LLMs/AI_IDE_CHAT_HISTORY/WINDSURF/repo_workflows/learning_ai_common_plat/repos.txt @@ -1,8 +1,12 @@ -# All workspace repositories -# Single source of truth for repo-management workflows -# Reference this file in scripts instead of hardcoding repo lists +# All workspace repositories — SINGLE SOURCE OF TRUTH +# Used by all /repo_* workflows and scripts (backup, commit, push, sync, agent-docs) +# Paths are relative to ~/code/mygh/ (the workspace root) +# To add a new repo: append its path here and all workflows will pick it up automatically +# --- Platform & shared --- learning_ai_common_plat + +# --- Product repos --- learning_voice_ai_agent learning_multimodal_memory_agents learning_ai_clock @@ -13,6 +17,16 @@ learning_ai_notes learning_ai_flowmonk learning_ai_trails learning_ai_local_memory_gpt +learning_ai_efforise +learning_ai_local_llms + +# --- Auth & identity --- learning_ai_smart_auth learning_ai_auth_app + +# --- Web & misc --- learning_ai_productivity_web + +# --- OSS (subdirectory repos under oss/) --- +oss/learning_ai_claw-code-oss +oss/learning_ai_claw-cowork diff --git a/scripts/update-agent-docs.sh b/scripts/update-agent-docs.sh index 0bf2fa9a..1e090113 100755 --- a/scripts/update-agent-docs.sh +++ b/scripts/update-agent-docs.sh @@ -174,6 +174,28 @@ set_meta() { LINT2="cd android && ./gradlew :app:assembleDebug 2>&1 | tail -20" AIDER_READ2="README.md" ;; + learning_ai_efforise) + NAME="EffoRise" + ID="efforise" + TAGLINE="Identity-based habit tracker" + STACK="Vite + React 19 SPA (client/) + Fastify 5 backend (backend/) + React Native/Expo (mobile/) + @bytelyst/* shared packages" + BUILD_VFY="cd backend && pnpm test && pnpm run typecheck && pnpm run build" + LINT1="cd backend && pnpm test 2>&1 | tail -10" + LINT2="cd backend && pnpm run typecheck 2>&1 | tail -10" + LINT3="cd backend && pnpm run build 2>&1 | tail -10" + AIDER_READ2="README.md" + ;; + learning_ai_local_llms) + NAME="Local LLM Lab" + ID="localllmlab" + TAGLINE="Personal local AI inference toolkit" + STACK="Next.js 16 (dashboard) + Ollama + @bytelyst/llm-router + Python (TTS)" + BUILD_VFY="cd dashboard && pnpm test && pnpm typecheck && pnpm build" + LINT1="cd dashboard && pnpm test 2>&1 | tail -10" + LINT2="cd dashboard && pnpm typecheck 2>&1 | tail -10" + LINT3="cd dashboard && pnpm build 2>&1 | tail -10" + AIDER_READ2="README.md" + ;; learning_ai_productivity_web) NAME="Productivity Web" ID="(internal)" @@ -184,6 +206,28 @@ set_meta() { LINT2="npm run build 2>&1 | tail -10" AIDER_READ2="README.md" ;; + oss/learning_ai_claw-code-oss) + NAME="Claw Code OSS" + ID="(upstream)" + TAGLINE="Upstream Claude Code OSS fork — runtime, API, and tools crates" + STACK="Rust (workspace) + Python + TypeScript" + BUILD_VFY="cargo build --workspace && cargo test --workspace" + LINT1="cargo fmt --check 2>&1 | tail -10" + LINT2="cargo clippy --workspace --all-targets -- -D warnings 2>&1 | tail -10" + LINT3="cargo test --workspace 2>&1 | tail -10" + AIDER_READ2="README.md" + ;; + oss/learning_ai_claw-cowork) + NAME="Claw Cowork" + ID="clawcowork" + TAGLINE="Desktop agent for complex multi-step knowledge work with Docker sandboxing" + STACK="Rust (workspace) + React/TypeScript (Tauri frontend) + Python (skills server)" + BUILD_VFY="cargo build --workspace && cargo test --workspace" + LINT1="cargo fmt --check 2>&1 | tail -10" + LINT2="cargo clippy --workspace --all-targets -- -D warnings 2>&1 | tail -10" + LINT3="cargo test --workspace 2>&1 | tail -10" + AIDER_READ2="COWORK.md" + ;; *) warn "Unknown repo: $1 — skipping" return 1 @@ -299,6 +343,22 @@ repo_rules() { echo "- Theme via BLAuthUIConfig (iOS) / MaterialTheme (Android)" echo "- Never create a separate backend — app talks to platform-service" ;; + learning_ai_efforise) + echo "- Backend follows the ByteLyst product-backend pattern with Fastify 5 + TypeScript ESM" + echo "- Use @bytelyst/* shared packages instead of reimplementing common infrastructure" + echo "- Fastify modules follow types.ts → repository.ts → routes.ts" + echo "- Use req.log / app.log — never console.log" + echo "- Every Cosmos document MUST include productId: \"efforise\"" + echo "- Theme tokens use --er-* CSS custom properties — never hardcode colors" + ;; + learning_ai_local_llms) + echo "- Dashboard uses server-side routing — keep UI as thin client" + echo "- @bytelyst/llm-router from Gitea npm registry (not file: ref)" + echo "- Never commit model weights (.gguf, .bin, .safetensors)" + echo "- Never hardcode Ollama URLs — use OLLAMA_HOST env var" + echo "- Corporate proxy: use hf-mirror.com instead of huggingface.co" + echo "- CSS tokens use --llm-* prefix" + ;; learning_ai_productivity_web) echo "- App Router pages live in src/app/" echo "- Reusable UI lives in src/components/" @@ -306,6 +366,21 @@ repo_rules() { echo "- Keep UI changes thin and tool-registry-driven where possible" echo "- Avoid inventing APIs or hidden backend contracts" ;; + oss/learning_ai_claw-code-oss) + echo "- Upstream claw-code fork — do NOT add custom features here" + echo "- Periodically pull from upstream and merge" + echo "- Rust crates: runtime, api, tools (consumed by claw-cowork)" + echo "- Python client: tests/, scripts/" + echo "- TypeScript SDK: ts-sdk/" + ;; + oss/learning_ai_claw-cowork) + echo "- Docker-first sandbox — native VM backends are stubs" + echo "- Python skills inside sandbox for document processing" + echo "- Tauri v2 for desktop GUI — Rust backend + React frontend" + echo "- Async architecture — bollard (Docker API) is async" + echo "- Base64 encoding for file content passed to sandbox" + echo "- Use conventional commit prefixes: feat(), fix(), docs:, test:, refactor:" + ;; esac } @@ -405,12 +480,42 @@ repo_paths() { echo "- shared/product.json — canonical product identity" echo "- ios/project.yml and android/ build files — native project wiring" ;; + learning_ai_efforise) + echo "- client/ — Vite + React 19 SPA" + echo "- backend/ — Fastify 5 + TypeScript ESM backend (port 4020)" + echo "- backend/src/modules/ — identities, efforts, habits, streaks, insights" + echo "- mobile/ — React Native + Expo (SDK 55) companion app" + echo "- mobile/src/app/(tabs)/ — 5-tab navigator (Home, Identity, Log, Insights, Settings)" + ;; + learning_ai_local_llms) + echo "- dashboard/ — Mission Control Next.js 16 app" + echo "- dashboard/src/app/api/ — Ollama proxy, Whisper, TTS, system info" + echo "- dashboard/src/app/(mission-control)/ — System overview, model management" + echo "- tts/ — TTS setup scripts + experiments" + echo "- scripts/ — start-dashboard.sh + windows setup" + echo "- experiments/ — oss-llm, open-claw, voicebox" + ;; learning_ai_productivity_web) echo "- src/app/ — App Router pages and routes" echo "- src/components/ — Navbar and tool cards" echo "- src/lib/ — utility and tool registry helpers" echo "- next.config.ts, tailwind.config.ts — web app configuration" ;; + oss/learning_ai_claw-code-oss) + echo "- rust/crates/runtime/ — ConversationRuntime, Session, PermissionPolicy" + echo "- rust/crates/api/ — AnthropicClient, AuthSource, SSE streaming" + echo "- rust/crates/tools/ — ToolSpec, tool dispatch" + echo "- python/ — Python client SDK" + echo "- ts-sdk/ — TypeScript SDK" + ;; + oss/learning_ai_claw-cowork) + echo "- crates/cowork-vm/ — Sandbox lifecycle (Docker, VZ abstraction)" + echo "- crates/cowork-orchestrator/ — Task coordination, LLM planner, plugins, MCP" + echo "- crates/cowork-skills/ — Rust↔Python bridge for document processing" + echo "- crates/cowork-desktop/ — Tauri v2 desktop app (Rust + React)" + echo "- docker/ — Dockerfile + Python skills server" + echo "- connectors/ — MCP connector servers (Google Drive, Gmail, GCal, Slack)" + ;; esac } diff --git a/services/cowork-service/src/lib/feature-flags.ts b/services/cowork-service/src/lib/feature-flags.ts index 002b9d7b..2a5c969d 100644 --- a/services/cowork-service/src/lib/feature-flags.ts +++ b/services/cowork-service/src/lib/feature-flags.ts @@ -1,7 +1,7 @@ /** * Feature flag registry for cowork-service. * - * Defaults match the 12 platform flags seeded in H.1 + * Defaults match the 13 platform flags seeded in H.1 * (platform-service/src/modules/flags/seed.ts clawcowork entry). */ import { createFlagRegistry } from '@bytelyst/backend-flags'; diff --git a/services/cowork-service/src/lib/flush-scheduler.test.ts b/services/cowork-service/src/lib/flush-scheduler.test.ts index 25363432..f373efd4 100644 --- a/services/cowork-service/src/lib/flush-scheduler.test.ts +++ b/services/cowork-service/src/lib/flush-scheduler.test.ts @@ -45,7 +45,7 @@ const mockLog = { function createMockBridge(running = true) { return { isRunning: running, - flushAudit: vi.fn().mockResolvedValue({ result: { count: 2, events: [ + flushAudit: vi.fn().mockResolvedValue({ result: { count: 2, entries: [ { userId: 'u1', action: 'task.submit', category: 'task', details: {} }, { userId: 'u2', action: 'task.cancel', category: 'task', details: {} }, ] } }), @@ -133,7 +133,7 @@ describe('FlushScheduler', () => { it('handles empty IPC responses', async () => { const bridge = createMockBridge(true); - bridge.flushAudit.mockResolvedValue({ result: { count: 0, events: [] } }); + bridge.flushAudit.mockResolvedValue({ result: { count: 0, entries: [] } }); bridge.flushTelemetry.mockResolvedValue({ result: { count: 0, events: [] } }); bridge.flushBudget.mockResolvedValue({ result: { count: 0, records: [] } }); vi.mocked(getIpcBridge).mockReturnValue(bridge as unknown as ReturnType); diff --git a/services/cowork-service/src/lib/flush-scheduler.ts b/services/cowork-service/src/lib/flush-scheduler.ts index eb23dfea..3893d446 100644 --- a/services/cowork-service/src/lib/flush-scheduler.ts +++ b/services/cowork-service/src/lib/flush-scheduler.ts @@ -115,7 +115,8 @@ export class FlushScheduler { return null; } const r = resp.result as Record | undefined; - const entries: AuditEntry[] = (r?.events as AuditEntry[]) ?? []; + // Rust flush_audit returns { count, entries } — NOT "events" + const entries: AuditEntry[] = (r?.entries as AuditEntry[]) ?? []; if (entries.length === 0) return { drained: 0, posted: 0, errors: 0 }; const { posted, errors } = await postAuditEvents(entries); diff --git a/services/cowork-service/src/server.test.ts b/services/cowork-service/src/server.test.ts index 5eb2bce7..48ee2c04 100644 --- a/services/cowork-service/src/server.test.ts +++ b/services/cowork-service/src/server.test.ts @@ -54,6 +54,14 @@ vi.mock('./lib/ipc-bridge.js', () => ({ shutdown: vi.fn(async () => undefined), })), })); +vi.mock('./lib/flush-scheduler.js', () => ({ + getFlushScheduler: vi.fn(() => ({ + isRunning: false, + start: vi.fn(), + stop: vi.fn(), + finalFlush: vi.fn(async () => undefined), + })), +})); describe('cowork-service bootstrap', () => { beforeEach(() => {