noterai 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/README.md +368 -0
  2. package/bin/noter.js +218 -0
  3. package/bin/noter.js.map +1 -0
  4. package/package.json +73 -0
  5. package/packages/client/dist/assets/geist-mono-latin-400-normal-CoULgQGM.woff +0 -0
  6. package/packages/client/dist/assets/geist-mono-latin-400-normal-LC9RFr9I.woff2 +0 -0
  7. package/packages/client/dist/assets/index-CBiNAMaA.js +264 -0
  8. package/packages/client/dist/assets/index-u7i5Fle2.css +1 -0
  9. package/packages/client/dist/assets/space-grotesk-latin-500-normal-CNSSEhBt.woff +0 -0
  10. package/packages/client/dist/assets/space-grotesk-latin-500-normal-lFbtlQH6.woff2 +0 -0
  11. package/packages/client/dist/assets/space-grotesk-latin-600-normal-BflQw4A9.woff +0 -0
  12. package/packages/client/dist/assets/space-grotesk-latin-600-normal-DjKNqYRj.woff2 +0 -0
  13. package/packages/client/dist/assets/vendor-react-DHeZC_T5.js +17 -0
  14. package/packages/client/dist/index.html +14 -0
  15. package/packages/server/dist/adapters/claudeAdapter.d.ts +34 -0
  16. package/packages/server/dist/adapters/claudeAdapter.d.ts.map +1 -0
  17. package/packages/server/dist/adapters/claudeAdapter.js +281 -0
  18. package/packages/server/dist/adapters/claudeAdapter.js.map +1 -0
  19. package/packages/server/dist/adapters/codexAdapter.d.ts +39 -0
  20. package/packages/server/dist/adapters/codexAdapter.d.ts.map +1 -0
  21. package/packages/server/dist/adapters/codexAdapter.js +347 -0
  22. package/packages/server/dist/adapters/codexAdapter.js.map +1 -0
  23. package/packages/server/dist/adapters/droidAdapter.d.ts +34 -0
  24. package/packages/server/dist/adapters/droidAdapter.d.ts.map +1 -0
  25. package/packages/server/dist/adapters/droidAdapter.js +109 -0
  26. package/packages/server/dist/adapters/droidAdapter.js.map +1 -0
  27. package/packages/server/dist/adapters/genericAdapter.d.ts +50 -0
  28. package/packages/server/dist/adapters/genericAdapter.d.ts.map +1 -0
  29. package/packages/server/dist/adapters/genericAdapter.js +203 -0
  30. package/packages/server/dist/adapters/genericAdapter.js.map +1 -0
  31. package/packages/server/dist/adapters/index.d.ts +7 -0
  32. package/packages/server/dist/adapters/index.d.ts.map +1 -0
  33. package/packages/server/dist/adapters/index.js +7 -0
  34. package/packages/server/dist/adapters/index.js.map +1 -0
  35. package/packages/server/dist/adapters/opencodeAdapter.d.ts +28 -0
  36. package/packages/server/dist/adapters/opencodeAdapter.d.ts.map +1 -0
  37. package/packages/server/dist/adapters/opencodeAdapter.js +265 -0
  38. package/packages/server/dist/adapters/opencodeAdapter.js.map +1 -0
  39. package/packages/server/dist/adapters/opencodeSessionManager.d.ts +13 -0
  40. package/packages/server/dist/adapters/opencodeSessionManager.d.ts.map +1 -0
  41. package/packages/server/dist/adapters/opencodeSessionManager.js +230 -0
  42. package/packages/server/dist/adapters/opencodeSessionManager.js.map +1 -0
  43. package/packages/server/dist/adapters/pathUtils.d.ts +54 -0
  44. package/packages/server/dist/adapters/pathUtils.d.ts.map +1 -0
  45. package/packages/server/dist/adapters/pathUtils.js +86 -0
  46. package/packages/server/dist/adapters/pathUtils.js.map +1 -0
  47. package/packages/server/dist/adapters/piAdapter.d.ts +34 -0
  48. package/packages/server/dist/adapters/piAdapter.d.ts.map +1 -0
  49. package/packages/server/dist/adapters/piAdapter.js +307 -0
  50. package/packages/server/dist/adapters/piAdapter.js.map +1 -0
  51. package/packages/server/dist/autoDetect.d.ts +15 -0
  52. package/packages/server/dist/autoDetect.d.ts.map +1 -0
  53. package/packages/server/dist/autoDetect.js +102 -0
  54. package/packages/server/dist/autoDetect.js.map +1 -0
  55. package/packages/server/dist/config.d.ts +29 -0
  56. package/packages/server/dist/config.d.ts.map +1 -0
  57. package/packages/server/dist/config.js +96 -0
  58. package/packages/server/dist/config.js.map +1 -0
  59. package/packages/server/dist/eventStore.d.ts +14 -0
  60. package/packages/server/dist/eventStore.d.ts.map +1 -0
  61. package/packages/server/dist/eventStore.js +35 -0
  62. package/packages/server/dist/eventStore.js.map +1 -0
  63. package/packages/server/dist/hookWatcher.d.ts +24 -0
  64. package/packages/server/dist/hookWatcher.d.ts.map +1 -0
  65. package/packages/server/dist/hookWatcher.js +152 -0
  66. package/packages/server/dist/hookWatcher.js.map +1 -0
  67. package/packages/server/dist/index.d.ts +58 -0
  68. package/packages/server/dist/index.d.ts.map +1 -0
  69. package/packages/server/dist/index.js +527 -0
  70. package/packages/server/dist/index.js.map +1 -0
  71. package/packages/server/dist/llm/jsonExtractor.d.ts +39 -0
  72. package/packages/server/dist/llm/jsonExtractor.d.ts.map +1 -0
  73. package/packages/server/dist/llm/jsonExtractor.js +83 -0
  74. package/packages/server/dist/llm/jsonExtractor.js.map +1 -0
  75. package/packages/server/dist/llm/ollamaCache.d.ts +19 -0
  76. package/packages/server/dist/llm/ollamaCache.d.ts.map +1 -0
  77. package/packages/server/dist/llm/ollamaCache.js +31 -0
  78. package/packages/server/dist/llm/ollamaCache.js.map +1 -0
  79. package/packages/server/dist/llm/ollamaClient.d.ts +29 -0
  80. package/packages/server/dist/llm/ollamaClient.d.ts.map +1 -0
  81. package/packages/server/dist/llm/ollamaClient.js +117 -0
  82. package/packages/server/dist/llm/ollamaClient.js.map +1 -0
  83. package/packages/server/dist/llm/ollamaQueue.d.ts +7 -0
  84. package/packages/server/dist/llm/ollamaQueue.d.ts.map +1 -0
  85. package/packages/server/dist/llm/ollamaQueue.js +28 -0
  86. package/packages/server/dist/llm/ollamaQueue.js.map +1 -0
  87. package/packages/server/dist/llm/promptBuilder.d.ts +8 -0
  88. package/packages/server/dist/llm/promptBuilder.d.ts.map +1 -0
  89. package/packages/server/dist/llm/promptBuilder.js +85 -0
  90. package/packages/server/dist/llm/promptBuilder.js.map +1 -0
  91. package/packages/server/dist/llm/promptSections.d.ts +64 -0
  92. package/packages/server/dist/llm/promptSections.d.ts.map +1 -0
  93. package/packages/server/dist/llm/promptSections.js +128 -0
  94. package/packages/server/dist/llm/promptSections.js.map +1 -0
  95. package/packages/server/dist/llm/providerModels.d.ts +14 -0
  96. package/packages/server/dist/llm/providerModels.d.ts.map +1 -0
  97. package/packages/server/dist/llm/providerModels.js +67 -0
  98. package/packages/server/dist/llm/providerModels.js.map +1 -0
  99. package/packages/server/dist/llm/suggester.d.ts +12 -0
  100. package/packages/server/dist/llm/suggester.d.ts.map +1 -0
  101. package/packages/server/dist/llm/suggester.js +263 -0
  102. package/packages/server/dist/llm/suggester.js.map +1 -0
  103. package/packages/server/dist/llm/summarizer.d.ts +53 -0
  104. package/packages/server/dist/llm/summarizer.d.ts.map +1 -0
  105. package/packages/server/dist/llm/summarizer.js +174 -0
  106. package/packages/server/dist/llm/summarizer.js.map +1 -0
  107. package/packages/server/dist/persistence.d.ts +42 -0
  108. package/packages/server/dist/persistence.d.ts.map +1 -0
  109. package/packages/server/dist/persistence.js +103 -0
  110. package/packages/server/dist/persistence.js.map +1 -0
  111. package/packages/server/dist/repoContext.d.ts +60 -0
  112. package/packages/server/dist/repoContext.d.ts.map +1 -0
  113. package/packages/server/dist/repoContext.js +197 -0
  114. package/packages/server/dist/repoContext.js.map +1 -0
  115. package/packages/server/dist/routes/blueprint.d.ts +7 -0
  116. package/packages/server/dist/routes/blueprint.d.ts.map +1 -0
  117. package/packages/server/dist/routes/blueprint.js +529 -0
  118. package/packages/server/dist/routes/blueprint.js.map +1 -0
  119. package/packages/server/dist/routes/config.d.ts +17 -0
  120. package/packages/server/dist/routes/config.d.ts.map +1 -0
  121. package/packages/server/dist/routes/config.js +282 -0
  122. package/packages/server/dist/routes/config.js.map +1 -0
  123. package/packages/server/dist/routes/lmstudio.d.ts +4 -0
  124. package/packages/server/dist/routes/lmstudio.d.ts.map +1 -0
  125. package/packages/server/dist/routes/lmstudio.js +67 -0
  126. package/packages/server/dist/routes/lmstudio.js.map +1 -0
  127. package/packages/server/dist/routes/notes.d.ts +5 -0
  128. package/packages/server/dist/routes/notes.d.ts.map +1 -0
  129. package/packages/server/dist/routes/notes.js +60 -0
  130. package/packages/server/dist/routes/notes.js.map +1 -0
  131. package/packages/server/dist/routes/ollama.d.ts +4 -0
  132. package/packages/server/dist/routes/ollama.d.ts.map +1 -0
  133. package/packages/server/dist/routes/ollama.js +207 -0
  134. package/packages/server/dist/routes/ollama.js.map +1 -0
  135. package/packages/server/dist/routes/prompt.d.ts +4 -0
  136. package/packages/server/dist/routes/prompt.d.ts.map +1 -0
  137. package/packages/server/dist/routes/prompt.js +75 -0
  138. package/packages/server/dist/routes/prompt.js.map +1 -0
  139. package/packages/server/dist/routes/refineNotes.d.ts +4 -0
  140. package/packages/server/dist/routes/refineNotes.d.ts.map +1 -0
  141. package/packages/server/dist/routes/refineNotes.js +87 -0
  142. package/packages/server/dist/routes/refineNotes.js.map +1 -0
  143. package/packages/server/dist/routes/repoContext.d.ts +3 -0
  144. package/packages/server/dist/routes/repoContext.d.ts.map +1 -0
  145. package/packages/server/dist/routes/repoContext.js +15 -0
  146. package/packages/server/dist/routes/repoContext.js.map +1 -0
  147. package/packages/server/dist/routes/sessions.d.ts +15 -0
  148. package/packages/server/dist/routes/sessions.d.ts.map +1 -0
  149. package/packages/server/dist/routes/sessions.js +420 -0
  150. package/packages/server/dist/routes/sessions.js.map +1 -0
  151. package/packages/server/dist/routes/summarize.d.ts +6 -0
  152. package/packages/server/dist/routes/summarize.d.ts.map +1 -0
  153. package/packages/server/dist/routes/summarize.js +85 -0
  154. package/packages/server/dist/routes/summarize.js.map +1 -0
  155. package/packages/server/dist/server.d.ts +2 -0
  156. package/packages/server/dist/server.d.ts.map +1 -0
  157. package/packages/server/dist/server.js +6 -0
  158. package/packages/server/dist/server.js.map +1 -0
  159. package/packages/server/dist/sessionManager.d.ts +41 -0
  160. package/packages/server/dist/sessionManager.d.ts.map +1 -0
  161. package/packages/server/dist/sessionManager.js +493 -0
  162. package/packages/server/dist/sessionManager.js.map +1 -0
  163. package/packages/server/dist/sessionScanner.d.ts +22 -0
  164. package/packages/server/dist/sessionScanner.d.ts.map +1 -0
  165. package/packages/server/dist/sessionScanner.js +165 -0
  166. package/packages/server/dist/sessionScanner.js.map +1 -0
  167. package/packages/server/dist/sessionTitle.d.ts +17 -0
  168. package/packages/server/dist/sessionTitle.d.ts.map +1 -0
  169. package/packages/server/dist/sessionTitle.js +321 -0
  170. package/packages/server/dist/sessionTitle.js.map +1 -0
  171. package/packages/server/dist/stateManager.d.ts +38 -0
  172. package/packages/server/dist/stateManager.d.ts.map +1 -0
  173. package/packages/server/dist/stateManager.js +83 -0
  174. package/packages/server/dist/stateManager.js.map +1 -0
  175. package/packages/server/dist/wsServer.d.ts +27 -0
  176. package/packages/server/dist/wsServer.d.ts.map +1 -0
  177. package/packages/server/dist/wsServer.js +144 -0
  178. package/packages/server/dist/wsServer.js.map +1 -0
  179. package/packages/shared/dist/index.d.ts +3 -0
  180. package/packages/shared/dist/index.d.ts.map +1 -0
  181. package/packages/shared/dist/index.js +3 -0
  182. package/packages/shared/dist/index.js.map +1 -0
  183. package/packages/shared/dist/llm/mambaDetect.d.ts +84 -0
  184. package/packages/shared/dist/llm/mambaDetect.d.ts.map +1 -0
  185. package/packages/shared/dist/llm/mambaDetect.js +205 -0
  186. package/packages/shared/dist/llm/mambaDetect.js.map +1 -0
  187. package/packages/shared/dist/types.d.ts +184 -0
  188. package/packages/shared/dist/types.d.ts.map +1 -0
  189. package/packages/shared/dist/types.js +2 -0
  190. package/packages/shared/dist/types.js.map +1 -0
  191. package/scripts/postbuild.js +70 -0
package/README.md ADDED
@@ -0,0 +1,368 @@
1
+ # Noter
2
+
3
+ A locally-run, browser-based AI agent dashboard that monitors AI agent activity, summarizes context using a local or cloud LLM, and generates next-step task suggestions and implementation prompts.
4
+
5
+ > **npm package:** [`noterai`](https://www.npmjs.com/package/noterai) — install with `npx noterai` or `npm install -g noterai`. The CLI command is `noter`.
6
+
7
+ ## Architecture
8
+
9
+ ```
10
+ ┌─────────────────────────────────┐ ┌─────────────────────────────────┐
11
+ │ OpenCode (SSE port 4096) │ │ Claude Code (MCP stdio) │
12
+ └────────────┬────────────────────┘ └────────────┬────────────────────┘
13
+ │ SSE │ MCP
14
+ └────────────────┬──────────────────────┘
15
+
16
+ ┌─────────▼──────────┐
17
+ │ Express Backend │ port 3000
18
+ │ (packages/server) │
19
+ │ │
20
+ │ • EventStore │ 200 events, FIFO ring buffer
21
+ │ • StateManager │ summary, suggestions, notes, prompts
22
+ │ • Summarizer │ Ollama + ai-sdk generateObject
23
+ │ • Suggester │ Ollama + ai-sdk generateObject
24
+ │ • PromptBuilder │ Ollama / Anthropic / OpenAI / Gemini
25
+ │ • OllamaQueue │ serialized inference queue
26
+ │ • OllamaCache │ memoized provider instances
27
+ │ • wsServer │ ping/pong heartbeat, 1MB msg limit
28
+ │ • MCP Server │ stdio transport, send_event + get_state
29
+ └─────────┬────────┘
30
+ │ WebSocket + HTTP
31
+ ┌─────────▼──────────┐
32
+ │ React Frontend │ port 5173 (dev) / served static
33
+ │ (packages/client) │
34
+ │ │
35
+ │ • 2x2 grid layout│ Editorial Brutalism design system
36
+ │ • wsClient │ auto-reconnect, exponential backoff
37
+ │ • 4 panels │ Notes, Tasks, Context, Prompts
38
+ └──────────────────┘
39
+ ```
40
+
41
+ ## Quick Start
42
+
43
+ ### From npm (no clone needed)
44
+
45
+ ```bash
46
+ npx noterai # Run without installing (opens browser automatically)
47
+ npx noterai serve # Production server without auto-opening browser
48
+ npx noterai serve --open # Production server + auto-open browser
49
+ npx noterai help # Show all commands
50
+ npx noterai version # Print version
51
+
52
+ # Or install globally:
53
+ npm install -g noterai
54
+ noter # Then run directly
55
+ ```
56
+
57
+ ### From source (development)
58
+
59
+ ```bash
60
+ git clone https://github.com/oniwakaa/noter.git && cd noter
61
+ pnpm install
62
+ pnpm run dev
63
+ ```
64
+
65
+ The dashboard opens at `http://localhost:5173`. The backend runs on `http://localhost:3000`.
66
+
67
+ > **Note:** `pnpm run dev` starts both the backend server (`:3000`) and the Vite dev client (`:5173`) concurrently.
68
+
69
+ ## Prerequisites
70
+
71
+ - **Node.js** >= 20 (tested on v24.4.1)
72
+ - **pnpm** >= 10 (tested on v10.30.3)
73
+ - **Ollama** running locally with at least one model pulled (check `ollama list`)
74
+ - Default model in `.env.example` is `falcon-h1r:7b-q4_K_M` — **update `.env` to a model you have installed** (e.g. `deepseek-v4-flash:cloud` or `gemma4:e4b`)
75
+ - *(Optional)* **OpenCode** CLI for OpenCode SSE event ingestion
76
+ - *(Optional)* API keys if using cloud LLM providers for prompt generation (Anthropic, OpenAI, Gemini)
77
+
78
+ ## Environment Variables
79
+
80
+ Copy `.env.example` to `.env` and adjust values:
81
+
82
+ ```bash
83
+ cp .env.example .env
84
+ ```
85
+
86
+ | Variable | Default | Description |
87
+ |----------|---------|-------------|
88
+ | `PORT` | `3000` | Backend HTTP/WebSocket server port |
89
+ | `VITE_SERVER_PORT` | `3000` | **Must match `PORT`** — used by Vite proxy and WebSocket client |
90
+ | `OLLAMA_BASE_URL` | `http://localhost:11434` | Ollama API endpoint |
91
+ | `OLLAMA_MODEL` | `falcon-h1r:7b-q4_K_M` | Model for summarization & suggestions. **Must be a model you have pulled locally.** |
92
+ | `CONTEXT_OFFLOAD_THRESHOLD` | `0.8` | Auto-offload model when accumulated context exceeds this % of context window (0.0–1.0) |
93
+ | `VRAM_LIMIT_GB` | `6` | VRAM display limit for the Ollama status memory bar |
94
+ | `OPENCODE_PORT` | `4096` | OpenCode SSE stream port (only when `ACTIVE_SOURCE` includes `opencode`) |
95
+ | `ACTIVE_SOURCE` | `generic` | Event source: `opencode`, `claude-code`, `codex`, `factory-droid`, `pi`, `generic`, `auto`, `both`, or `all` |
96
+ | `NOTER_EVENT_LOG` | `/tmp/noter-events.jsonl` | Path to JSONL event log for file-based adapters (Droid, Pi) |
97
+ | `GENERIC_LOG_PATH` | `/tmp/noter-generic-events.jsonl` | Path to JSONL event log for the generic adapter |
98
+ | `LLM_PROVIDER` | `ollama` | Prompt generation provider: `ollama`, `anthropic`, `openai`, `gemini` |
99
+ | `ANTHROPIC_API_KEY` | *(empty)* | Required when `LLM_PROVIDER=anthropic` |
100
+ | `OPENAI_API_KEY` | *(empty)* | Required when `LLM_PROVIDER=openai` |
101
+ | `GEMINI_API_KEY` | *(empty)* | Required when `LLM_PROVIDER=gemini` |
102
+
103
+ ## Scripts
104
+
105
+ ### Root (`package.json`)
106
+
107
+ | Script | Description |
108
+ |--------|-------------|
109
+ | `pnpm run dev` | Start both server and client concurrently |
110
+ | `pnpm run dev:server` | Start backend only (Express + WebSocket on port 3000) |
111
+ | `pnpm run dev:client` | Start frontend only (Vite dev server on port 5173) |
112
+ | `pnpm run build` | Build shared + server + client + bin for production |
113
+ | `pnpm run typecheck` | TypeScript strict mode check (both packages) |
114
+ | `pnpm run test` | Run full Vitest suite (server + client workspaces) |
115
+
116
+ ### Sub-package scripts
117
+
118
+ ```bash
119
+ # Client build
120
+ cd packages/client && pnpm run build # tsc && vite build
121
+ cd packages/client && pnpm run preview # preview production build
122
+
123
+ # Server build
124
+ cd packages/server && pnpm run build # tsc
125
+ cd packages/server && pnpm run build:mcp # tsc, outputs dist/mcp-server.js
126
+ ```
127
+
128
+ ### CLI (`bin/noter.ts` / `bin/noter.js`)
129
+
130
+ The package exposes a `noter` CLI via the `bin` field:
131
+
132
+ ```bash
133
+ noter --help # Show all commands
134
+ noter version # Print version
135
+ noter serve # Production server (serves static frontend + API)
136
+ noter serve --open # Production server + auto-open browser
137
+ noter dev # Development mode (hot-reload)
138
+ noter build # Build client & server for production
139
+ PORT=8080 noter serve # Custom port
140
+ ```
141
+
142
+ ## Project Structure
143
+
144
+ ```
145
+ noter/
146
+ ├── bin/
147
+ │ ├── noter.ts # CLI source (compiled to noter.js for publish)
148
+ │ ├── noter.js # Compiled CLI entry point (gitignored, built on publish)
149
+ │ └── tsconfig.json # Bin-specific tsconfig (node16 module resolution)
150
+ ├── packages/
151
+ │ ├── server/ # Express + WebSocket backend
152
+ │ │ ├── src/
153
+ │ │ │ ├── adapters/
154
+ │ │ │ │ ├── opencodeAdapter.ts # OpenCode SSE → AgentEvent
155
+ │ │ │ │ ├── claudeAdapter.ts # Claude Code MCP → AgentEvent
156
+ │ │ │ │ ├── codexAdapter.ts # OpenAI Codex CLI MCP → AgentEvent
157
+ │ │ │ │ ├── droidAdapter.ts # Factory Droid hooks → AgentEvent
158
+ │ │ │ │ ├── piAdapter.ts # Pi (pi.dev) hooks → AgentEvent
159
+ │ │ │ │ └── genericAdapter.ts # Generic JSONL/webhook → AgentEvent
160
+ │ │ │ ├── llm/
161
+ │ │ │ │ ├── ollamaClient.ts # Low-level Ollama client (60s timeout, AbortController)
162
+ │ │ │ │ ├── ollamaCache.ts # Memoized createOllama() provider instances
163
+ │ │ │ │ ├── ollamaQueue.ts # Serialized inference queues (suggester + inference)
164
+ │ │ │ │ ├── summarizer.ts # ContextSummary generation from events
165
+ │ │ │ │ ├── suggester.ts # TaskSuggestion[] generation from context + notes
166
+ │ │ │ │ └── promptBuilder.ts # GeneratedPrompt from task + context + notes
167
+ │ │ │ ├── routes/
168
+ │ │ │ │ ├── notes.ts # POST /api/notes → save + fire-and-forget suggest
169
+ │ │ │ │ ├── prompt.ts # POST /api/prompt (by taskId) + GET /:taskId
170
+ │ │ │ │ ├── summarize.ts # POST /api/summarize (mutex-guarded)
171
+ │ │ │ │ └── ollama.ts # GET /api/ollama/status + POST /api/ollama/offload
172
+ │ │ │ ├── config.ts # AppConfig, types, loadConfig(), Zod-like validation
173
+ │ │ │ ├── eventStore.ts # In-memory FIFO ring buffer (200 max)
174
+ │ │ │ ├── stateManager.ts # Shared state + task→prompt map
175
+ │ │ │ ├── wsServer.ts # WebSocketServer wrapper (heartbeat, 1MB limit)
176
+ │ │ │ ├── mcp-server.ts # MCP stdio server (send_event, get_state tools)
177
+ │ │ │ └── index.ts # createApp() factory + listenServer() + startServer()
178
+ │ │ └── package.json
179
+ │ └── client/ # React + Vite frontend
180
+ │ ├── src/
181
+ │ │ ├── components/
182
+ │ │ │ ├── NotesPanel.tsx # Debounced textarea, drag-to-delete
183
+ │ │ │ ├── SuggestionsPanel.tsx # Task cards, priority badges, conflict warnings
184
+ │ │ │ ├── ContextPanel.tsx # Summary fields, Ollama status, activity log
185
+ │ │ │ ├── PromptsPanel.tsx # Build → expand prompt, copy to clipboard
186
+ │ │ │ └── OllamaStatus.tsx # Model name, connection, VRAM bar, offload
187
+ │ │ ├── styles/
188
+ │ │ │ └── tokens.css # DESIGN.md tokens: monochrome, zero-radius, no shadows
189
+ │ │ ├── App.tsx # 2x2 grid, top nav, dark/light toggle
190
+ │ │ ├── wsClient.ts # Singleton WebSocket client (reconnect backoff)
191
+ │ │ ├── localDeletions.ts # Drag-delete tracking set
192
+ │ │ ├── types.ts # Shared TypeScript interfaces
193
+ │ │ └── test/ # Component tests (RTL + jsdom)
194
+ │ └── package.json
195
+ ├── .env.example # All environment variables with comments
196
+ ├── vitest.workspace.ts # Server (node) + Client (jsdom) test workspaces
197
+ ├── tsconfig.base.json # Shared TypeScript strict config
198
+ ├── pnpm-workspace.yaml # Monorepo workspace definition
199
+ └── README.md # This file
200
+ ```
201
+
202
+ ## Frontend Panels
203
+
204
+ The UI is a fixed 2x2 viewport grid separated by 1px solid dividers (`outline_variant`).
205
+
206
+ | Panel | Grid Position | Description |
207
+ |-------|--------------|-------------|
208
+ | **Notes** | Top-left | Borderless textarea with debounced save (500ms POST to `/api/notes`). Supports drag-to-delete: drop a task card here to remove it. |
209
+ | **Suggested Tasks** | Top-right | Task cards (`TaskSuggestion[]`) with priority badges (high/medium/low), conflict warnings, and a **"Build →"** action to generate a prompt. |
210
+ | **Agent Context** | Bottom-left | `ContextSummary` fields: what's happening, files changed, current goal, blockers. Includes Ollama status (model, VRAM bar, offload button). Terminal-style activity log. |
211
+ | **Suggested Prompts** | Bottom-right | List of generated prompts. Click **"Build →"** to expand a prompt row (animated from `0fr` to `1fr`). Each prompt has a copy-to-clipboard button. |
212
+
213
+ **Design System:** High-End Editorial Brutalism — zero `border-radius`, no `box-shadow`, monochrome palette (`#131313` surface), Space Grotesk for labels, Geist Mono for data/code. See [`DESIGN.md`](./DESIGN.md) for full spec.
214
+
215
+ ## WebSocket Message Types
216
+
217
+ All messages are typed as `WsMessage` union. The client auto-reconnects with exponential backoff (500ms → 30s max).
218
+
219
+ ```typescript
220
+ type WsMessage =
221
+ | { type: 'sync'; payload: { events: AgentEvent[]; summary: ContextSummary | null; suggestions: TaskSuggestion[]; notes: HumanNotes | null } }
222
+ | { type: 'event'; payload: AgentEvent }
223
+ | { type: 'summary'; payload: ContextSummary }
224
+ | { type: 'suggestions'; payload: TaskSuggestion[] }
225
+ | { type: 'notes'; payload: HumanNotes };
226
+ ```
227
+
228
+ - **`sync`** — sent to every new WebSocket connection to hydrate frontend state.
229
+ - **`event`** — broadcast when a new agent event is ingested.
230
+ - **`summary`** — broadcast when the summarizer generates a new context summary.
231
+ - **`suggestions`** — broadcast when new task suggestions are generated.
232
+ - **`notes`** — broadcast when notes are updated.
233
+
234
+ **Server-side protections:** ping/pong heartbeat every 30s (stale connections terminated), maximum message size 1MB.
235
+
236
+ ## API Endpoints
237
+
238
+ ### `GET /health`
239
+ Returns `{"status":"ok"}` — used by services.yaml healthcheck and CLI startup verification.
240
+
241
+ ### `POST /api/notes`
242
+ **Body:** `{ content: string, updatedAt: number }` (Zod-validated)
243
+
244
+ Saves notes, returns `{ saved: true }` immediately, then **fire-and-forget** generates `TaskSuggestion[]` via the suggester queue. Suggestions are broadcast via WebSocket.
245
+
246
+ ### `POST /api/prompt`
247
+ **Body:** `{ taskId: string }` (Zod-validated)
248
+
249
+ Generates a `GeneratedPrompt` for the given task using the configured `LLM_PROVIDER`. Uses shared `INFERENCE_QUEUE` to serialize with summarization. Returns `404` if taskId not found, `500` if API key missing or generation fails.
250
+
251
+ **Also:** `GET /api/prompt/:taskId` — retrieve a previously generated prompt for a task.
252
+
253
+ ### `POST /api/summarize`
254
+ **Body:** none required.
255
+
256
+ Triggers context summarization manually. Mutex-guarded: concurrent requests return `202` without duplicate Ollama calls. Returns `ContextSummary` with fields: `whatIsHappening`, `filesChanged`, `currentGoal`, `blockers`, `rawEventCount`.
257
+
258
+ ### `GET /api/ollama/status`
259
+ Returns Ollama `/api/ps` response formatted with `models[]` and `memory{}` (totalSize, totalVram, usedPercent).
260
+
261
+ ### `POST /api/ollama/offload`
262
+ Offloads all loaded Ollama models (sends `keep_alive: 0`).
263
+
264
+ ## MCP Integration
265
+
266
+ Noter exposes an MCP server via stdio transport for use with Claude Code, Cursor, VS Code Copilot, Continue.dev, Windsurf, and OpenAI Codex CLI.
267
+
268
+ **Tools:**
269
+ - **`send_event`** — Push an agent event into the pipeline. Zod-validated against `AgentEvent` schema. Stored in `eventStore`, broadcast via WebSocket, and processed by the summarizer.
270
+ - **`get_state`** — Returns current application state (summary, suggestions, notes) as JSON.
271
+
272
+ **Configuration** — add to your agent's MCP settings (e.g. `~/.claude/mcp.json`, `.cursor/mcp.json`, or equivalent):
273
+
274
+ ```json
275
+ {
276
+ "mcpServers": {
277
+ "noter": {
278
+ "command": "node",
279
+ "args": ["packages/server/dist/mcp-server.js"]
280
+ }
281
+ }
282
+ }
283
+ ```
284
+
285
+ ### Per-Harness Setup
286
+
287
+ **Claude Code & OpenAI Codex CLI:**
288
+ Both use the same MCP protocol. Add the MCP server config above to your agent's settings, then set `ACTIVE_SOURCE=claude-code` (or `codex`, or `all`).
289
+
290
+ **Factory Droid:**
291
+ Droid writes events to `/tmp/noter-events.jsonl` via its hooks system. The `droidAdapter.ts` watches this file automatically when `ACTIVE_SOURCE` includes `factory-droid`.
292
+
293
+ **Pi (pi.dev):**
294
+ Pi extensions can emit events to the same JSONL file. Install a `noter-bridge.ts` extension in Pi that writes `{ type, sessionId, payload, timestamp }` lines to `NOTER_EVENT_LOG`.
295
+
296
+ **OpenCode:**
297
+ Run `opencode` with the `--events` flag pointing to `http://localhost:${OPENCODE_PORT}`. The `opencodeAdapter.ts` connects via SSE.
298
+
299
+ **Generic (any harness):**
300
+ The generic adapter watches a JSONL file (default: `/tmp/noter-generic-events.jsonl`) for events from any agent harness. Zero-config — just write JSON events to the default path, or set `GENERIC_LOG_PATH` for a custom path. Set `ACTIVE_SOURCE=generic` (the default).
301
+
302
+ ## Ollama Integration
303
+
304
+ - **Provider caching:** `ollamaCache.ts` memoizes `createOllama()` instances by `baseURL` so the same provider config is reused across summarizer, suggester, and prompt builder.
305
+ - **Queue serialization:** `ollamaQueue.ts` provides two queues:
306
+ - `INFERENCE_QUEUE` — shared between summarizer and prompt builder (prevents concurrent calls).
307
+ - `SUGGESTER_QUEUE` — dedicated queue for suggestion generation (runs independently).
308
+ - **Timeout:** `ollamaClient.ts` uses `AbortController` with a 60-second default timeout. Configurable via `OllamaClientOptions.timeout`.
309
+ - **Context auto-offload:** Tracks accumulated token usage and automatically offloads models when the context window threshold (`CONTEXT_OFFLOAD_THRESHOLD`) is exceeded.
310
+
311
+ ## LLM Providers for Prompt Generation
312
+
313
+ | Provider | Model ID | Requires Key |
314
+ |----------|---------|-------------|
315
+ | `ollama` | Configured `OLLAMA_MODEL` | No |
316
+ | `anthropic` | `claude-sonnet-4-20250514` | `ANTHROPIC_API_KEY` |
317
+ | `openai` | `gpt-4o` | `OPENAI_API_KEY` |
318
+ | `gemini` | `gemini-2.5-flash` | `GEMINI_API_KEY` |
319
+
320
+ ## Event Sources
321
+
322
+ | Source | Adapter | Transport | Trigger |
323
+ |--------|---------|-----------|---------|
324
+ | **OpenCode** | `opencodeAdapter.ts` | SSE (`http://localhost:${OPENCODE_PORT}`) | `session.idle`, `tool.before/after`, `message.updated` |
325
+ | **Claude Code** | `claudeAdapter.ts` | MCP stdio | `send_event` tool calls |
326
+ | **OpenAI Codex CLI** | `codexAdapter.ts` | MCP stdio | `send_event` tool calls |
327
+ | **Factory Droid** | `droidAdapter.ts` | File hooks (`AGENTDESK_EVENT_LOG`) | `tool.before/after`, `session.start/end` |
328
+ | **Pi (pi.dev)** | `piAdapter.ts` | File hooks (`AGENTDESK_EVENT_LOG`) | `tool_call`, `tool_result`, `agent_start/end` |
329
+ | **Generic** | `genericAdapter.ts` | JSONL file watcher + webhook | Any harness writing JSON events |
330
+
331
+ Set `ACTIVE_SOURCE=all` to ingest from all supported harnesses simultaneously.
332
+
333
+ ## Testing
334
+
335
+ ```bash
336
+ # Full suite (server + client)
337
+ pnpm run test
338
+
339
+ # Server only (node environment)
340
+ pnpm vitest run --project server
341
+
342
+ # Client only (jsdom environment)
343
+ pnpm vitest run --project client
344
+
345
+ # With coverage
346
+ pnpm vitest run --coverage
347
+ ```
348
+
349
+ - **Server tests:** 30+ test files covering routes, adapters (5 harnesses), LLM pipeline, config validation, WebSocket server, MCP server, session management, and CLI.
350
+ - **Client tests:** 10+ component test files using React Testing Library + jsdom.
351
+
352
+ ## TypeScript
353
+
354
+ Strict mode enabled across both packages. Root `tsconfig.base.json` provides shared compiler options.
355
+
356
+ ```bash
357
+ pnpm run typecheck # Both packages
358
+ ```
359
+
360
+ ## Security
361
+
362
+ - No hardcoded secrets in source files.
363
+ - `.env` is in `.gitignore`.
364
+ - API keys are read exclusively via `loadConfig()` in `config.ts`.
365
+
366
+ ## License
367
+
368
+ MIT
package/bin/noter.js ADDED
@@ -0,0 +1,218 @@
1
+ #!/usr/bin/env node
2
+ // noter — CLI-first repo-aware startup
3
+ //
4
+ // When launched inside a git repository, automatically:
5
+ // 1. Detects the repository root
6
+ // 2. Loads AGENTS.md / AGENT.md as repo instructions
7
+ // 3. Matches active harness sessions for this repo
8
+ // 4. Injects all context into the running server
9
+ import { createApp, listenServer } from '../packages/server/dist/index.js';
10
+ import { loadConfig } from '../packages/server/dist/config.js';
11
+ import { resolveRepoContext, formatStartupLog } from '../packages/server/dist/repoContext.js';
12
+ import { stateManager } from '../packages/server/dist/stateManager.js';
13
+ import { execSync } from 'child_process';
14
+ import { resolve, dirname } from 'path';
15
+ import { fileURLToPath } from 'url';
16
+ import { existsSync, readFileSync } from 'fs';
17
+ const __filename = fileURLToPath(import.meta.url);
18
+ const __dirname = dirname(__filename);
19
+ const ROOT = resolve(__dirname, '..');
20
+ const CLIENT_DIST = resolve(ROOT, 'packages/client/dist');
21
+ const PACKAGE_JSON = resolve(ROOT, 'package.json');
22
+ function log(msg) {
23
+ console.log(`[noter] ${msg}`);
24
+ }
25
+ function logError(msg) {
26
+ console.error(`[noter] ${msg}`);
27
+ }
28
+ function getVersion() {
29
+ const raw = readFileSync(PACKAGE_JSON, 'utf-8');
30
+ const pkg = JSON.parse(raw);
31
+ return pkg.version ?? '0.0.1';
32
+ }
33
+ function showHelp() {
34
+ const version = getVersion();
35
+ const help = `
36
+ noter v${version} — CLI-first repo-aware AI agent dashboard
37
+
38
+ Usage:
39
+ noter [command] [options]
40
+
41
+ Commands:
42
+ (default) Start with repo-aware context (auto-detect repo, load AGENTS.md)
43
+ serve Start the production server (serves frontend + API)
44
+ dev Start development mode (hot-reload client & server)
45
+ build Build client and server for production
46
+ help Show this help message
47
+ version Print the version number
48
+
49
+ Options:
50
+ serve --open Open the browser after starting the server
51
+ serve --no-open Do not open the browser (default for 'serve')
52
+
53
+ Repo-Aware Behavior:
54
+ When launched inside a git repository, noter automatically:
55
+ - Detects the repository root (walks up from CWD to find .git)
56
+ - Loads AGENTS.md or AGENT.md from the repo root (AGENTS.md takes precedence)
57
+ - Matches active harness sessions (Pi, Factory Droid) by repo path
58
+ - Injects repo instructions into summarization, suggestions, and prompts
59
+ When launched from a non-repo directory, all repo-specific features are skipped.
60
+
61
+ Environment Variables:
62
+ PORT Server port (default: 3000)
63
+ OLLAMA_BASE_URL Ollama API URL (default: http://localhost:11434)
64
+ OLLAMA_MODEL Ollama model name (default: falcon-h1r:7b-q4_K_M)
65
+ ACTIVE_SOURCE Event source: opencode | claude-code | codex | factory-droid | pi | generic | auto
66
+ LLM_PROVIDER LLM provider: ollama | anthropic | openai | gemini
67
+ OPENCODE_PORT OpenCode SSE port (default: 4096)
68
+ ANTHROPIC_API_KEY API key for Anthropic
69
+ OPENAI_API_KEY API key for OpenAI
70
+ GEMINI_API_KEY API key for Google Gemini
71
+
72
+ Examples:
73
+ noter Repo-aware startup + open browser
74
+ noter serve Start server without opening browser
75
+ noter serve --open Start server and open browser
76
+ noter dev Start development mode
77
+ noter build Build for production
78
+ PORT=8080 noter serve Start server on port 8080
79
+ `.trim();
80
+ console.log(help);
81
+ }
82
+ async function build() {
83
+ log('Building client...');
84
+ execSync('pnpm run build', { cwd: resolve(ROOT, 'packages/client'), stdio: 'inherit' });
85
+ log('Building server...');
86
+ execSync('pnpm run build', { cwd: resolve(ROOT, 'packages/server'), stdio: 'inherit' });
87
+ log('Build complete.');
88
+ }
89
+ async function serve(openBrowser) {
90
+ // Auto-build if client dist is missing
91
+ if (!existsSync(CLIENT_DIST)) {
92
+ log('Client build not found. Building...');
93
+ await build();
94
+ }
95
+ // Resolve repo context BEFORE starting the server
96
+ const cwd = process.cwd();
97
+ const repoCtx = resolveRepoContext(cwd);
98
+ // Log startup context
99
+ for (const line of formatStartupLog(repoCtx)) {
100
+ log(line);
101
+ }
102
+ // Store repo context in state manager so it's available to all routes/LLM prompts
103
+ stateManager.setRepoContext(repoCtx);
104
+ // Lazy-load config to pick up env vars (including PORT)
105
+ const cfg = loadConfig();
106
+ const { default: express } = await import('express');
107
+ const appServer = await createApp();
108
+ // Serve static frontend in production
109
+ appServer.app.use(express.static(CLIENT_DIST));
110
+ // Express v5 SPA fallback — catch-all route using {*path} parameter
111
+ appServer.app.get('{*path}', (_req, res) => {
112
+ res.sendFile(resolve(CLIENT_DIST, 'index.html'));
113
+ });
114
+ const port = cfg.port;
115
+ try {
116
+ await listenServer(appServer, port);
117
+ }
118
+ catch (err) {
119
+ logError(err.message);
120
+ process.exit(1);
121
+ }
122
+ log(`Noter running at http://localhost:${port}`);
123
+ if (openBrowser) {
124
+ const url = `http://localhost:${port}`;
125
+ log(`Opening browser at ${url}`);
126
+ const opener = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';
127
+ try {
128
+ execSync(`${opener} ${url}`);
129
+ }
130
+ catch {
131
+ log(`Could not open browser. Visit ${url} manually.`);
132
+ }
133
+ }
134
+ log('Press Ctrl+C to stop.');
135
+ // Graceful shutdown handlers
136
+ const shutdown = async (signal) => {
137
+ log(`Received ${signal}, shutting down gracefully...`);
138
+ try {
139
+ await appServer.close();
140
+ }
141
+ catch {
142
+ // Ignore errors during shutdown
143
+ }
144
+ process.exit(0);
145
+ };
146
+ process.on('SIGINT', () => shutdown('SIGINT'));
147
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
148
+ }
149
+ async function main() {
150
+ const args = process.argv.slice(2);
151
+ const command = args[0];
152
+ switch (command) {
153
+ case 'help':
154
+ case '--help':
155
+ case '-h':
156
+ showHelp();
157
+ process.exit(0);
158
+ break;
159
+ case 'version':
160
+ case '--version':
161
+ case '-v':
162
+ console.log(`noter v${getVersion()}`);
163
+ process.exit(0);
164
+ break;
165
+ case 'build':
166
+ try {
167
+ await build();
168
+ }
169
+ catch (err) {
170
+ logError(`Build failed: ${err.message}`);
171
+ process.exit(1);
172
+ }
173
+ break;
174
+ case 'serve': {
175
+ const openBrowser = args.includes('--open');
176
+ try {
177
+ await serve(openBrowser);
178
+ }
179
+ catch (err) {
180
+ logError(`Server error: ${err.message}`);
181
+ process.exit(1);
182
+ }
183
+ break;
184
+ }
185
+ case 'dev':
186
+ log('Starting development mode...');
187
+ try {
188
+ execSync('pnpm run dev', { cwd: ROOT, stdio: 'inherit' });
189
+ }
190
+ catch (err) {
191
+ logError(`Dev server error: ${err.message}`);
192
+ process.exit(1);
193
+ }
194
+ break;
195
+ case undefined:
196
+ // Default: repo-aware serve with browser open
197
+ try {
198
+ await serve(true);
199
+ }
200
+ catch (err) {
201
+ logError(`Server error: ${err.message}`);
202
+ process.exit(1);
203
+ }
204
+ break;
205
+ default:
206
+ // Unknown command — show help and exit 1
207
+ logError(`Unknown command: ${command}`);
208
+ console.log();
209
+ showHelp();
210
+ process.exit(1);
211
+ break;
212
+ }
213
+ }
214
+ main().catch((err) => {
215
+ logError(`Fatal error: ${err instanceof Error ? err.message : String(err)}`);
216
+ process.exit(1);
217
+ });
218
+ //# sourceMappingURL=noter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"noter.js","sourceRoot":"","sources":["noter.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "noterai",
3
+ "version": "0.1.0",
4
+ "description": "Locally-run, browser-based AI agent dashboard for developers using LLM coding assistants",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "keywords": [
8
+ "ai",
9
+ "agent",
10
+ "dashboard",
11
+ "llm",
12
+ "claude",
13
+ "codex",
14
+ "opencode",
15
+ "developer-tools",
16
+ "cli"
17
+ ],
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/oniwakaa/noter.git"
21
+ },
22
+ "homepage": "https://github.com/oniwakaa/noter#readme",
23
+ "engines": {
24
+ "node": ">=20.0.0"
25
+ },
26
+ "bin": {
27
+ "noter": "./bin/noter.js"
28
+ },
29
+ "files": [
30
+ "bin/noter.js",
31
+ "bin/noter.js.map",
32
+ "packages/client/dist",
33
+ "packages/server/dist",
34
+ "packages/shared/dist",
35
+ "scripts/postbuild.js"
36
+ ],
37
+ "scripts": {
38
+ "dev:server": "pnpm --filter @noter/server run dev",
39
+ "dev:client": "pnpm --filter @noter/client run dev",
40
+ "dev": "concurrently \"pnpm run dev:server\" \"pnpm run dev:client\"",
41
+ "build:shared": "pnpm --filter @noter/shared run build",
42
+ "build:server": "pnpm --filter @noter/server run build",
43
+ "build:client": "pnpm --filter @noter/client run build",
44
+ "build:bin": "tsc -p bin/tsconfig.json",
45
+ "postbuild": "node scripts/postbuild.js",
46
+ "build": "pnpm run build:shared && pnpm run build:server && pnpm run build:client && pnpm run build:bin && pnpm run postbuild",
47
+ "typecheck": "pnpm --filter @noter/server run typecheck && pnpm --filter @noter/client run typecheck",
48
+ "test": "vitest run",
49
+ "prepublishOnly": "pnpm run build && pnpm run typecheck && pnpm run test"
50
+ },
51
+ "dependencies": {
52
+ "@ai-sdk/anthropic": "^3.0.74",
53
+ "@ai-sdk/google": "^3.0.67",
54
+ "@ai-sdk/openai": "^3.0.58",
55
+ "@opencode-ai/sdk": "^1.3.3",
56
+ "ai": "^6.0.174",
57
+ "ai-sdk-ollama": "^3.8.3",
58
+ "better-sqlite3": "^12.3.1",
59
+ "dotenv": "^17.3.1",
60
+ "express": "^5.0.1",
61
+ "ws": "^8.18.0",
62
+ "zod": "^3.25.76"
63
+ },
64
+ "devDependencies": {
65
+ "@playwright/test": "^1.60.0",
66
+ "@vitest/coverage-v8": "^4.1.5",
67
+ "concurrently": "^9.1.2",
68
+ "typescript": "^5.8.2",
69
+ "vite": "^6.4.2",
70
+ "vitest": "^4.1.5"
71
+ },
72
+ "packageManager": "pnpm@10.30.3"
73
+ }