@opengsd/gsd-pi 1.0.2-dev.50223bc → 1.0.2-dev.5961fbf

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 (251) hide show
  1. package/dist/resource-loader.d.ts +5 -0
  2. package/dist/resource-loader.js +24 -8
  3. package/dist/resources/.managed-resources-content-hash +1 -1
  4. package/dist/resources/extensions/gsd/auto/loop.js +19 -0
  5. package/dist/resources/extensions/gsd/auto/phases.js +1 -1
  6. package/dist/resources/extensions/gsd/auto-worktree.js +2 -54
  7. package/dist/resources/extensions/gsd/worktree-post-create-hook.js +117 -0
  8. package/dist/web/standalone/.next/BUILD_ID +1 -1
  9. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  10. package/dist/web/standalone/.next/build-manifest.json +2 -2
  11. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  12. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  13. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  14. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  15. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  16. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  17. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  18. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  19. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  20. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  21. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  22. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  23. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  24. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  25. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  26. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  27. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  28. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  29. package/dist/web/standalone/.next/server/app/api/session/events/route.js +1 -1
  30. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  31. package/dist/web/standalone/.next/server/app/index.html +1 -1
  32. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  33. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  34. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  35. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  36. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  37. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  38. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  39. package/dist/web/standalone/.next/server/chunks/1834.js +1 -1
  40. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  41. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  42. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  43. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  44. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  45. package/dist/web/standalone/package.json +0 -1
  46. package/dist/worktree-cli.d.ts +0 -2
  47. package/dist/worktree-cli.js +21 -9
  48. package/package.json +9 -4
  49. package/packages/cloud-mcp-gateway/bin/gsd-cloud-mcp-gateway.js +14 -0
  50. package/packages/cloud-mcp-gateway/package.json +5 -4
  51. package/packages/contracts/package.json +2 -2
  52. package/packages/daemon/bin/gsd-daemon.js +14 -0
  53. package/packages/daemon/bin/gsd-mcp-runtime.js +14 -0
  54. package/packages/daemon/bin/gsd-mcp.js +14 -0
  55. package/packages/daemon/dist/channel-manager.d.ts +53 -0
  56. package/packages/daemon/dist/channel-manager.d.ts.map +1 -0
  57. package/packages/daemon/dist/channel-manager.js +167 -0
  58. package/packages/daemon/dist/channel-manager.js.map +1 -0
  59. package/packages/daemon/dist/cli.d.ts +3 -0
  60. package/packages/daemon/dist/cli.d.ts.map +1 -0
  61. package/packages/daemon/dist/cli.js +94 -0
  62. package/packages/daemon/dist/cli.js.map +1 -0
  63. package/packages/daemon/dist/cloud-cli.d.ts +7 -0
  64. package/packages/daemon/dist/cloud-cli.d.ts.map +1 -0
  65. package/packages/daemon/dist/cloud-cli.js +96 -0
  66. package/packages/daemon/dist/cloud-cli.js.map +1 -0
  67. package/packages/daemon/dist/cloud-config.d.ts +18 -0
  68. package/packages/daemon/dist/cloud-config.d.ts.map +1 -0
  69. package/packages/daemon/dist/cloud-config.js +209 -0
  70. package/packages/daemon/dist/cloud-config.js.map +1 -0
  71. package/packages/daemon/dist/cloud-config.test.d.ts +2 -0
  72. package/packages/daemon/dist/cloud-config.test.d.ts.map +1 -0
  73. package/packages/daemon/dist/cloud-config.test.js +132 -0
  74. package/packages/daemon/dist/cloud-config.test.js.map +1 -0
  75. package/packages/daemon/dist/cloud-runtime.d.ts +26 -0
  76. package/packages/daemon/dist/cloud-runtime.d.ts.map +1 -0
  77. package/packages/daemon/dist/cloud-runtime.js +180 -0
  78. package/packages/daemon/dist/cloud-runtime.js.map +1 -0
  79. package/packages/daemon/dist/cloud-runtime.test.d.ts +2 -0
  80. package/packages/daemon/dist/cloud-runtime.test.d.ts.map +1 -0
  81. package/packages/daemon/dist/cloud-runtime.test.js +28 -0
  82. package/packages/daemon/dist/cloud-runtime.test.js.map +1 -0
  83. package/packages/daemon/dist/cloud-token.d.ts +3 -0
  84. package/packages/daemon/dist/cloud-token.d.ts.map +1 -0
  85. package/packages/daemon/dist/cloud-token.js +37 -0
  86. package/packages/daemon/dist/cloud-token.js.map +1 -0
  87. package/packages/daemon/dist/commands.d.ts +25 -0
  88. package/packages/daemon/dist/commands.d.ts.map +1 -0
  89. package/packages/daemon/dist/commands.js +81 -0
  90. package/packages/daemon/dist/commands.js.map +1 -0
  91. package/packages/daemon/dist/config.d.ts +17 -0
  92. package/packages/daemon/dist/config.d.ts.map +1 -0
  93. package/packages/daemon/dist/config.js +146 -0
  94. package/packages/daemon/dist/config.js.map +1 -0
  95. package/packages/daemon/dist/daemon.d.ts +38 -0
  96. package/packages/daemon/dist/daemon.d.ts.map +1 -0
  97. package/packages/daemon/dist/daemon.js +194 -0
  98. package/packages/daemon/dist/daemon.js.map +1 -0
  99. package/packages/daemon/dist/daemon.test.d.ts +2 -0
  100. package/packages/daemon/dist/daemon.test.d.ts.map +1 -0
  101. package/packages/daemon/dist/daemon.test.js +692 -0
  102. package/packages/daemon/dist/daemon.test.js.map +1 -0
  103. package/packages/daemon/dist/discord-bot.d.ts +70 -0
  104. package/packages/daemon/dist/discord-bot.d.ts.map +1 -0
  105. package/packages/daemon/dist/discord-bot.js +433 -0
  106. package/packages/daemon/dist/discord-bot.js.map +1 -0
  107. package/packages/daemon/dist/discord-bot.test.d.ts +2 -0
  108. package/packages/daemon/dist/discord-bot.test.d.ts.map +1 -0
  109. package/packages/daemon/dist/discord-bot.test.js +667 -0
  110. package/packages/daemon/dist/discord-bot.test.js.map +1 -0
  111. package/packages/daemon/dist/event-bridge.d.ts +72 -0
  112. package/packages/daemon/dist/event-bridge.d.ts.map +1 -0
  113. package/packages/daemon/dist/event-bridge.js +366 -0
  114. package/packages/daemon/dist/event-bridge.js.map +1 -0
  115. package/packages/daemon/dist/event-bridge.test.d.ts +9 -0
  116. package/packages/daemon/dist/event-bridge.test.d.ts.map +1 -0
  117. package/packages/daemon/dist/event-bridge.test.js +528 -0
  118. package/packages/daemon/dist/event-bridge.test.js.map +1 -0
  119. package/packages/daemon/dist/event-formatter.d.ts +34 -0
  120. package/packages/daemon/dist/event-formatter.d.ts.map +1 -0
  121. package/packages/daemon/dist/event-formatter.js +355 -0
  122. package/packages/daemon/dist/event-formatter.js.map +1 -0
  123. package/packages/daemon/dist/event-formatter.test.d.ts +2 -0
  124. package/packages/daemon/dist/event-formatter.test.d.ts.map +1 -0
  125. package/packages/daemon/dist/event-formatter.test.js +333 -0
  126. package/packages/daemon/dist/event-formatter.test.js.map +1 -0
  127. package/packages/daemon/dist/index.d.ts +25 -0
  128. package/packages/daemon/dist/index.d.ts.map +1 -0
  129. package/packages/daemon/dist/index.js +17 -0
  130. package/packages/daemon/dist/index.js.map +1 -0
  131. package/packages/daemon/dist/launchd.d.ts +49 -0
  132. package/packages/daemon/dist/launchd.d.ts.map +1 -0
  133. package/packages/daemon/dist/launchd.js +188 -0
  134. package/packages/daemon/dist/launchd.js.map +1 -0
  135. package/packages/daemon/dist/launchd.test.d.ts +2 -0
  136. package/packages/daemon/dist/launchd.test.d.ts.map +1 -0
  137. package/packages/daemon/dist/launchd.test.js +296 -0
  138. package/packages/daemon/dist/launchd.test.js.map +1 -0
  139. package/packages/daemon/dist/local-tool-executor.d.ts +22 -0
  140. package/packages/daemon/dist/local-tool-executor.d.ts.map +1 -0
  141. package/packages/daemon/dist/local-tool-executor.js +307 -0
  142. package/packages/daemon/dist/local-tool-executor.js.map +1 -0
  143. package/packages/daemon/dist/local-tool-executor.test.d.ts +2 -0
  144. package/packages/daemon/dist/local-tool-executor.test.d.ts.map +1 -0
  145. package/packages/daemon/dist/local-tool-executor.test.js +111 -0
  146. package/packages/daemon/dist/local-tool-executor.test.js.map +1 -0
  147. package/packages/daemon/dist/logger.d.ts +25 -0
  148. package/packages/daemon/dist/logger.d.ts.map +1 -0
  149. package/packages/daemon/dist/logger.js +72 -0
  150. package/packages/daemon/dist/logger.js.map +1 -0
  151. package/packages/daemon/dist/mcp-cli.d.ts +3 -0
  152. package/packages/daemon/dist/mcp-cli.d.ts.map +1 -0
  153. package/packages/daemon/dist/mcp-cli.js +8 -0
  154. package/packages/daemon/dist/mcp-cli.js.map +1 -0
  155. package/packages/daemon/dist/mcp-cli.test.d.ts +2 -0
  156. package/packages/daemon/dist/mcp-cli.test.d.ts.map +1 -0
  157. package/packages/daemon/dist/mcp-cli.test.js +13 -0
  158. package/packages/daemon/dist/mcp-cli.test.js.map +1 -0
  159. package/packages/daemon/dist/mcp-runtime-cli.d.ts +3 -0
  160. package/packages/daemon/dist/mcp-runtime-cli.d.ts.map +1 -0
  161. package/packages/daemon/dist/mcp-runtime-cli.js +8 -0
  162. package/packages/daemon/dist/mcp-runtime-cli.js.map +1 -0
  163. package/packages/daemon/dist/message-batcher.d.ts +78 -0
  164. package/packages/daemon/dist/message-batcher.d.ts.map +1 -0
  165. package/packages/daemon/dist/message-batcher.js +173 -0
  166. package/packages/daemon/dist/message-batcher.js.map +1 -0
  167. package/packages/daemon/dist/message-batcher.test.d.ts +2 -0
  168. package/packages/daemon/dist/message-batcher.test.d.ts.map +1 -0
  169. package/packages/daemon/dist/message-batcher.test.js +242 -0
  170. package/packages/daemon/dist/message-batcher.test.js.map +1 -0
  171. package/packages/daemon/dist/orchestrator.d.ts +98 -0
  172. package/packages/daemon/dist/orchestrator.d.ts.map +1 -0
  173. package/packages/daemon/dist/orchestrator.js +359 -0
  174. package/packages/daemon/dist/orchestrator.js.map +1 -0
  175. package/packages/daemon/dist/orchestrator.test.d.ts +8 -0
  176. package/packages/daemon/dist/orchestrator.test.d.ts.map +1 -0
  177. package/packages/daemon/dist/orchestrator.test.js +425 -0
  178. package/packages/daemon/dist/orchestrator.test.js.map +1 -0
  179. package/packages/daemon/dist/project-scanner.d.ts +18 -0
  180. package/packages/daemon/dist/project-scanner.d.ts.map +1 -0
  181. package/packages/daemon/dist/project-scanner.js +90 -0
  182. package/packages/daemon/dist/project-scanner.js.map +1 -0
  183. package/packages/daemon/dist/project-scanner.test.d.ts +5 -0
  184. package/packages/daemon/dist/project-scanner.test.d.ts.map +1 -0
  185. package/packages/daemon/dist/project-scanner.test.js +183 -0
  186. package/packages/daemon/dist/project-scanner.test.js.map +1 -0
  187. package/packages/daemon/dist/session-manager.d.ts +70 -0
  188. package/packages/daemon/dist/session-manager.d.ts.map +1 -0
  189. package/packages/daemon/dist/session-manager.js +358 -0
  190. package/packages/daemon/dist/session-manager.js.map +1 -0
  191. package/packages/daemon/dist/session-manager.test.d.ts +9 -0
  192. package/packages/daemon/dist/session-manager.test.d.ts.map +1 -0
  193. package/packages/daemon/dist/session-manager.test.js +616 -0
  194. package/packages/daemon/dist/session-manager.test.js.map +1 -0
  195. package/packages/daemon/dist/types.d.ts +133 -0
  196. package/packages/daemon/dist/types.d.ts.map +1 -0
  197. package/packages/daemon/dist/types.js +8 -0
  198. package/packages/daemon/dist/types.js.map +1 -0
  199. package/packages/daemon/dist/verbosity.d.ts +27 -0
  200. package/packages/daemon/dist/verbosity.d.ts.map +1 -0
  201. package/packages/daemon/dist/verbosity.js +86 -0
  202. package/packages/daemon/dist/verbosity.js.map +1 -0
  203. package/packages/daemon/dist/verbosity.test.d.ts +2 -0
  204. package/packages/daemon/dist/verbosity.test.d.ts.map +1 -0
  205. package/packages/daemon/dist/verbosity.test.js +136 -0
  206. package/packages/daemon/dist/verbosity.test.js.map +1 -0
  207. package/packages/daemon/package.json +9 -8
  208. package/packages/gsd-agent-core/package.json +6 -6
  209. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  210. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +3 -1
  211. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  212. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
  213. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +0 -1
  214. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
  215. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts +1 -0
  216. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts.map +1 -1
  217. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js +1 -0
  218. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js.map +1 -1
  219. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  220. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +2 -1
  221. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  222. package/packages/gsd-agent-modes/package.json +8 -8
  223. package/packages/mcp-server/bin/gsd-mcp-server.js +14 -0
  224. package/packages/mcp-server/package.json +6 -5
  225. package/packages/native/package.json +3 -3
  226. package/packages/pi-agent-core/package.json +4 -4
  227. package/packages/pi-ai/bin/pi-ai.js +14 -0
  228. package/packages/pi-ai/dist/models.generated.d.ts +0 -17
  229. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  230. package/packages/pi-ai/dist/models.generated.js +18 -35
  231. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  232. package/packages/pi-ai/package.json +5 -4
  233. package/packages/pi-coding-agent/dist/core/tools/read.d.ts +2 -2
  234. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  235. package/packages/pi-coding-agent/dist/core/tools/read.js +5 -3
  236. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  237. package/packages/pi-coding-agent/package.json +9 -9
  238. package/packages/pi-tui/package.json +2 -2
  239. package/packages/rpc-client/package.json +3 -3
  240. package/pkg/package.json +1 -1
  241. package/scripts/ensure-workspace-builds.cjs +4 -4
  242. package/scripts/install/deps.js +10 -0
  243. package/src/resources/extensions/gsd/auto/loop.ts +22 -0
  244. package/src/resources/extensions/gsd/auto/phases.ts +1 -1
  245. package/src/resources/extensions/gsd/auto-worktree.ts +2 -56
  246. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +64 -0
  247. package/src/resources/extensions/gsd/tests/worktree-post-create-hook.test.ts +141 -1
  248. package/src/resources/extensions/gsd/worktree-post-create-hook.ts +127 -0
  249. package/dist/tsconfig.extensions.tsbuildinfo +0 -1
  250. /package/dist/web/standalone/.next/static/{JP7xjsa5zSaO76XhE-mFJ → spUYLkQXoHJyxYOMH9VQy}/_buildManifest.js +0 -0
  251. /package/dist/web/standalone/.next/static/{JP7xjsa5zSaO76XhE-mFJ → spUYLkQXoHJyxYOMH9VQy}/_ssgManifest.js +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-manager.test.js","sourceRoot":"","sources":["../src/session-manager.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * SessionManager unit tests.\n *\n * Uses the MockRpcClient + TestableSessionManager pattern (K008) to test\n * session lifecycle, event handling, cost tracking, blocker detection,\n * and cleanup without spawning real GSD processes.\n */\n\nimport { describe, it, beforeEach, afterEach } from 'node:test';\nimport assert from 'node:assert/strict';\nimport { resolve, basename } from 'node:path';\nimport { mkdtempSync, writeFileSync, mkdirSync, rmSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\n\nimport { SessionManager } from './session-manager.js';\nimport { MAX_EVENTS } from './types.js';\nimport type { ManagedSession, PendingBlocker } from './types.js';\nimport { Logger } from './logger.js';\n\n// ---------------------------------------------------------------------------\n// Mock RpcClient (duck-typed to match RpcClient interface)\n// ---------------------------------------------------------------------------\n\nclass MockRpcClient {\n started = false;\n stopped = false;\n aborted = false;\n prompted: string[] = [];\n private eventListeners: Array<(event: Record<string, unknown>) => void> = [];\n uiResponses: Array<{ requestId: string; response: Record<string, unknown> }> = [];\n\n /** Control — set to make start() reject */\n startError: Error | null = null;\n /** Control — set to make init() reject */\n initError: Error | null = null;\n /** Control — override sessionId from init */\n initSessionId = 'mock-session-001';\n\n cwd: string;\n args: string[];\n\n constructor(options?: Record<string, unknown>) {\n this.cwd = (options?.cwd as string) ?? '';\n this.args = (options?.args as string[]) ?? [];\n }\n\n async start(): Promise<void> {\n if (this.startError) throw this.startError;\n this.started = true;\n }\n\n async stop(): Promise<void> {\n this.stopped = true;\n }\n\n async init(): Promise<{ sessionId: string; version: string }> {\n if (this.initError) throw this.initError;\n return { sessionId: this.initSessionId, version: '2.51.0' };\n }\n\n onEvent(listener: (event: Record<string, unknown>) => void): () => void {\n this.eventListeners.push(listener);\n return () => {\n const idx = this.eventListeners.indexOf(listener);\n if (idx >= 0) this.eventListeners.splice(idx, 1);\n };\n }\n\n async prompt(message: string): Promise<void> {\n this.prompted.push(message);\n }\n\n async abort(): Promise<void> {\n this.aborted = true;\n }\n\n sendUIResponse(requestId: string, response: Record<string, unknown>): void {\n this.uiResponses.push({ requestId, response });\n }\n\n /** Test helper — emit an event to all listeners */\n emitEvent(event: Record<string, unknown>): void {\n for (const listener of this.eventListeners) {\n listener(event);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// TestableSessionManager — injects mock clients without module mocking (K008)\n// ---------------------------------------------------------------------------\n\nclass TestableSessionManager extends SessionManager {\n lastClient: MockRpcClient | null = null;\n allClients: MockRpcClient[] = [];\n private sessionCounter = 0;\n nextInitError: Error | null = null;\n nextStartError: Error | null = null;\n\n override async startSession(options: { projectDir: string; command?: string; model?: string; bare?: boolean; cliPath?: string }): Promise<string> {\n const { projectDir } = options;\n\n if (!projectDir || projectDir.trim() === '') {\n throw new Error('projectDir is required and cannot be empty');\n }\n\n const resolvedDir = resolve(projectDir);\n const projectName = basename(resolvedDir);\n\n // Check duplicate via getSessionByDir\n const existing = this.getSessionByDir(resolvedDir);\n if (existing) {\n throw new Error(\n `Session already active for ${resolvedDir} (sessionId: ${existing.sessionId}, status: ${existing.status})`\n );\n }\n\n const client = new MockRpcClient({ cwd: resolvedDir, args: [] });\n if (this.nextStartError) {\n client.startError = this.nextStartError;\n this.nextStartError = null;\n }\n if (this.nextInitError) {\n client.initError = this.nextInitError;\n this.nextInitError = null;\n }\n\n this.sessionCounter++;\n client.initSessionId = `mock-session-${String(this.sessionCounter).padStart(3, '0')}`;\n this.lastClient = client;\n this.allClients.push(client);\n\n // Build session shell\n const session: ManagedSession = {\n sessionId: '',\n projectDir: resolvedDir,\n projectName,\n status: 'starting',\n client: client as any, // duck-typed mock\n events: [],\n pendingBlocker: null,\n cost: { totalCost: 0, tokens: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 } },\n startTime: Date.now(),\n };\n\n // Insert into internal sessions map\n (this as any).sessions.set(resolvedDir, session);\n\n try {\n await client.start();\n\n const initResult = await client.init();\n session.sessionId = initResult.sessionId;\n session.status = 'running';\n\n // Wire event tracking using parent's handleEvent\n session.unsubscribe = client.onEvent((event: Record<string, unknown>) => {\n (this as any).handleEvent(session, event);\n });\n\n // Kick off auto-mode\n const command = options.command ?? '/gsd auto';\n await client.prompt(command);\n\n // Emit lifecycle events (matching parent behavior)\n (this as any).logger.info('session started', { sessionId: session.sessionId, projectDir: resolvedDir });\n this.emit('session:started', { sessionId: session.sessionId, projectDir: resolvedDir, projectName });\n\n return session.sessionId;\n } catch (err) {\n session.status = 'error';\n session.error = err instanceof Error ? err.message : String(err);\n try { await client.stop(); } catch { /* swallow */ }\n\n (this as any).logger.error('session error', { sessionId: session.sessionId, projectDir: resolvedDir, error: session.error });\n this.emit('session:error', { sessionId: session.sessionId, projectDir: resolvedDir, projectName, error: session.error });\n\n throw new Error(`Failed to start session for ${resolvedDir}: ${session.error}`);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Logger spy helper\n// ---------------------------------------------------------------------------\n\ninterface LogCall {\n level: string;\n msg: string;\n data?: Record<string, unknown>;\n}\n\nclass SpyLogger {\n calls: LogCall[] = [];\n private tmpDir: string;\n logger: Logger;\n\n constructor() {\n this.tmpDir = mkdtempSync(join(tmpdir(), 'sm-test-'));\n this.logger = new Logger({\n filePath: join(this.tmpDir, 'test.log'),\n level: 'debug',\n });\n\n // Intercept write calls by wrapping the logger methods\n const original = {\n debug: this.logger.debug.bind(this.logger),\n info: this.logger.info.bind(this.logger),\n warn: this.logger.warn.bind(this.logger),\n error: this.logger.error.bind(this.logger),\n };\n\n this.logger.debug = (msg: string, data?: Record<string, unknown>) => {\n this.calls.push({ level: 'debug', msg, data });\n original.debug(msg, data);\n };\n this.logger.info = (msg: string, data?: Record<string, unknown>) => {\n this.calls.push({ level: 'info', msg, data });\n original.info(msg, data);\n };\n this.logger.warn = (msg: string, data?: Record<string, unknown>) => {\n this.calls.push({ level: 'warn', msg, data });\n original.warn(msg, data);\n };\n this.logger.error = (msg: string, data?: Record<string, unknown>) => {\n this.calls.push({ level: 'error', msg, data });\n original.error(msg, data);\n };\n }\n\n async cleanup(): Promise<void> {\n await this.logger.close();\n try { rmSync(this.tmpDir, { recursive: true, force: true }); } catch { /* ignore */ }\n }\n\n findCalls(level: string, msgSubstring: string): LogCall[] {\n return this.calls.filter(c => c.level === level && c.msg.includes(msgSubstring));\n }\n}\n\n// ---------------------------------------------------------------------------\n// Test Helpers\n// ---------------------------------------------------------------------------\n\nlet allManagers: TestableSessionManager[] = [];\nlet allSpyLoggers: SpyLogger[] = [];\n\nfunction createManager(): { manager: TestableSessionManager; spy: SpyLogger } {\n const spy = new SpyLogger();\n const manager = new TestableSessionManager(spy.logger);\n allManagers.push(manager);\n allSpyLoggers.push(spy);\n return { manager, spy };\n}\n\n// ---------------------------------------------------------------------------\n// Tests\n// ---------------------------------------------------------------------------\n\ndescribe('SessionManager', () => {\n afterEach(async () => {\n for (const m of allManagers) {\n try { await m.cleanup(); } catch { /* swallow */ }\n }\n allManagers = [];\n for (const s of allSpyLoggers) {\n await s.cleanup();\n }\n allSpyLoggers = [];\n });\n\n // ---- Lifecycle: start → running → completed ----\n\n it('start → running → completed lifecycle', async () => {\n const { manager, spy } = createManager();\n\n const sessionId = await manager.startSession({ projectDir: '/tmp/test-project' });\n assert.ok(sessionId);\n\n const session = manager.getSession(sessionId);\n assert.ok(session);\n assert.equal(session.status, 'running');\n assert.equal(session.projectName, 'test-project');\n\n // Simulate terminal notification\n manager.lastClient!.emitEvent({\n type: 'extension_ui_request',\n id: 'n1',\n method: 'notify',\n message: 'Auto-mode stopped: completed all tasks',\n });\n\n assert.equal(session.status, 'completed');\n\n // Verify logger calls\n const startedLogs = spy.findCalls('info', 'session started');\n assert.equal(startedLogs.length, 1);\n const completedLogs = spy.findCalls('info', 'session completed');\n assert.equal(completedLogs.length, 1);\n });\n\n // ---- Lifecycle: start → running → blocked → resolve → running → completed ----\n\n it('start → blocked → resolve → running → completed lifecycle', async () => {\n const { manager } = createManager();\n\n const sessionId = await manager.startSession({ projectDir: '/tmp/test-project-2' });\n const session = manager.getSession(sessionId)!;\n\n // Simulate blocking UI request (non-fire-and-forget method)\n manager.lastClient!.emitEvent({\n type: 'extension_ui_request',\n id: 'blocker-1',\n method: 'confirm',\n title: 'Merge PR?',\n message: 'Should I merge this PR?',\n });\n\n assert.equal(session.status, 'blocked');\n assert.ok(session.pendingBlocker);\n assert.equal(session.pendingBlocker!.id, 'blocker-1');\n assert.equal(session.pendingBlocker!.method, 'confirm');\n\n // Resolve the blocker\n await manager.resolveBlocker(sessionId, 'yes');\n\n assert.equal(session.status, 'running');\n assert.equal(session.pendingBlocker, null);\n\n // Verify UI response was sent\n const client = manager.lastClient!;\n assert.equal(client.uiResponses.length, 1);\n assert.equal(client.uiResponses[0].requestId, 'blocker-1');\n\n // Complete the session\n manager.lastClient!.emitEvent({\n type: 'extension_ui_request',\n id: 'n2',\n method: 'notify',\n message: 'Auto-mode stopped: all done',\n });\n\n assert.equal(session.status, 'completed');\n });\n\n // ---- Lifecycle: start → error (init failure) ----\n\n it('start → error when init fails', async () => {\n const { manager, spy } = createManager();\n\n manager.nextInitError = new Error('Connection refused');\n\n await assert.rejects(\n () => manager.startSession({ projectDir: '/tmp/test-error-project' }),\n (err: Error) => {\n assert.ok(err.message.includes('Connection refused'));\n return true;\n }\n );\n\n // Session should still exist in map with error status\n const session = manager.getSessionByDir('/tmp/test-error-project');\n assert.ok(session);\n assert.equal(session.status, 'error');\n assert.ok(session.error?.includes('Connection refused'));\n\n // Logger should have error call\n const errorLogs = spy.findCalls('error', 'session error');\n assert.equal(errorLogs.length, 1);\n });\n\n // ---- Duplicate session prevention ----\n\n it('rejects duplicate session for same projectDir', async () => {\n const { manager } = createManager();\n\n await manager.startSession({ projectDir: '/tmp/dup-test' });\n\n await assert.rejects(\n () => manager.startSession({ projectDir: '/tmp/dup-test' }),\n (err: Error) => {\n assert.ok(err.message.includes('Session already active'));\n return true;\n }\n );\n });\n\n // ---- Cancel session ----\n\n it('cancels a running session', async () => {\n const { manager, spy } = createManager();\n\n const sessionId = await manager.startSession({ projectDir: '/tmp/cancel-test' });\n const session = manager.getSession(sessionId)!;\n const client = manager.lastClient!;\n\n await manager.cancelSession(sessionId);\n\n assert.equal(session.status, 'cancelled');\n assert.ok(client.aborted);\n assert.ok(client.stopped);\n\n const cancelLogs = spy.findCalls('info', 'session cancelled');\n assert.equal(cancelLogs.length, 1);\n });\n\n // ---- Cost accumulation (K004 cumulative-max) ----\n\n it('accumulates cost using cumulative-max pattern (K004)', async () => {\n const { manager } = createManager();\n\n const sessionId = await manager.startSession({ projectDir: '/tmp/cost-test' });\n const session = manager.getSession(sessionId)!;\n const client = manager.lastClient!;\n\n // First cost update\n client.emitEvent({\n type: 'cost_update',\n runId: 'run-1',\n turnCost: 0.01,\n cumulativeCost: 0.01,\n tokens: { input: 100, output: 50, cacheRead: 20, cacheWrite: 10 },\n });\n\n assert.equal(session.cost.totalCost, 0.01);\n assert.equal(session.cost.tokens.input, 100);\n\n // Second cost update — cumulative values should increase\n client.emitEvent({\n type: 'cost_update',\n runId: 'run-1',\n turnCost: 0.02,\n cumulativeCost: 0.03,\n tokens: { input: 250, output: 120, cacheRead: 40, cacheWrite: 20 },\n });\n\n assert.equal(session.cost.totalCost, 0.03);\n assert.equal(session.cost.tokens.input, 250);\n assert.equal(session.cost.tokens.output, 120);\n\n // Third update with lower values — max should hold\n client.emitEvent({\n type: 'cost_update',\n runId: 'run-2',\n turnCost: 0.005,\n cumulativeCost: 0.02, // lower than 0.03 — should NOT replace\n tokens: { input: 50, output: 30, cacheRead: 5, cacheWrite: 2 },\n });\n\n assert.equal(session.cost.totalCost, 0.03); // max held\n assert.equal(session.cost.tokens.input, 250); // max held\n });\n\n // ---- Ring buffer event trimming ----\n\n it('trims events when exceeding MAX_EVENTS', async () => {\n const { manager } = createManager();\n\n const sessionId = await manager.startSession({ projectDir: '/tmp/ringbuf-test' });\n const session = manager.getSession(sessionId)!;\n const client = manager.lastClient!;\n\n // Push MAX_EVENTS + 20 events\n for (let i = 0; i < MAX_EVENTS + 20; i++) {\n client.emitEvent({\n type: 'assistant_message',\n id: `msg-${i}`,\n content: `Event ${i}`,\n });\n }\n\n assert.equal(session.events.length, MAX_EVENTS);\n // Oldest events should be trimmed — first event should be #20\n const firstEvent = session.events[0] as Record<string, unknown>;\n assert.equal(firstEvent.id, 'msg-20');\n });\n\n // ---- Blocker detection (non-fire-and-forget extension_ui_request) ----\n\n it('detects blocker from non-fire-and-forget extension_ui_request', async () => {\n const { manager, spy } = createManager();\n\n const sessionId = await manager.startSession({ projectDir: '/tmp/blocker-test' });\n const session = manager.getSession(sessionId)!;\n\n manager.lastClient!.emitEvent({\n type: 'extension_ui_request',\n id: 'sel-1',\n method: 'select',\n title: 'Choose deployment target',\n options: ['staging', 'production'],\n });\n\n assert.equal(session.status, 'blocked');\n assert.ok(session.pendingBlocker);\n assert.equal(session.pendingBlocker!.method, 'select');\n\n const blockedLogs = spy.findCalls('info', 'session blocked');\n assert.equal(blockedLogs.length, 1);\n });\n\n // ---- Fire-and-forget methods do NOT block ----\n\n it('fire-and-forget methods do not trigger blocker', async () => {\n const { manager } = createManager();\n\n const sessionId = await manager.startSession({ projectDir: '/tmp/faf-test' });\n const session = manager.getSession(sessionId)!;\n\n // setStatus is fire-and-forget\n manager.lastClient!.emitEvent({\n type: 'extension_ui_request',\n id: 'st-1',\n method: 'setStatus',\n statusKey: 'build',\n statusText: 'Building...',\n });\n\n assert.equal(session.status, 'running');\n assert.equal(session.pendingBlocker, null);\n });\n\n // ---- Terminal detection (auto-mode stopped notification) ----\n\n it('detects terminal from auto-mode stopped notification', async () => {\n const { manager } = createManager();\n\n const sessionId = await manager.startSession({ projectDir: '/tmp/terminal-test' });\n const session = manager.getSession(sessionId)!;\n\n manager.lastClient!.emitEvent({\n type: 'extension_ui_request',\n id: 'n1',\n method: 'notify',\n message: 'Step-mode stopped: user requested',\n });\n\n assert.equal(session.status, 'completed');\n });\n\n // ---- getAllSessions returns all tracked sessions ----\n\n it('getAllSessions returns all tracked sessions', async () => {\n const { manager } = createManager();\n\n await manager.startSession({ projectDir: '/tmp/proj-a' });\n await manager.startSession({ projectDir: '/tmp/proj-b' });\n await manager.startSession({ projectDir: '/tmp/proj-c' });\n\n const all = manager.getAllSessions();\n assert.equal(all.length, 3);\n\n const dirs = all.map(s => s.projectDir).sort();\n assert.ok(dirs[0].endsWith('proj-a'));\n assert.ok(dirs[1].endsWith('proj-b'));\n assert.ok(dirs[2].endsWith('proj-c'));\n });\n\n // ---- cleanup stops all active sessions ----\n\n it('cleanup stops all active sessions', async () => {\n const { manager } = createManager();\n\n await manager.startSession({ projectDir: '/tmp/cleanup-a' });\n await manager.startSession({ projectDir: '/tmp/cleanup-b' });\n\n const clients = [...manager.allClients];\n assert.equal(clients.length, 2);\n\n await manager.cleanup();\n\n const all = manager.getAllSessions();\n for (const s of all) {\n assert.equal(s.status, 'cancelled');\n }\n // Both clients should have been stopped\n for (const c of clients) {\n assert.ok(c.stopped);\n }\n });\n\n // ---- EventEmitter: session:started ----\n\n it('emits session:started event', async () => {\n const { manager } = createManager();\n\n let emittedData: Record<string, unknown> | undefined;\n manager.on('session:started', (data: Record<string, unknown>) => { emittedData = data; });\n\n const sessionId = await manager.startSession({ projectDir: '/tmp/emit-start' });\n\n assert.ok(emittedData);\n assert.equal(emittedData.sessionId, sessionId);\n assert.equal(emittedData.projectName, 'emit-start');\n });\n\n // ---- EventEmitter: session:blocked ----\n\n it('emits session:blocked event', async () => {\n const { manager } = createManager();\n\n let emittedData: Record<string, unknown> | undefined;\n manager.on('session:blocked', (data: Record<string, unknown>) => { emittedData = data; });\n\n await manager.startSession({ projectDir: '/tmp/emit-blocked' });\n\n manager.lastClient!.emitEvent({\n type: 'extension_ui_request',\n id: 'b-1',\n method: 'input',\n title: 'Enter API key',\n });\n\n assert.ok(emittedData);\n assert.equal((emittedData.blocker as PendingBlocker).id, 'b-1');\n });\n\n // ---- EventEmitter: session:completed ----\n\n it('emits session:completed event', async () => {\n const { manager } = createManager();\n\n let emittedData: Record<string, unknown> | undefined;\n manager.on('session:completed', (data: Record<string, unknown>) => { emittedData = data; });\n\n await manager.startSession({ projectDir: '/tmp/emit-completed' });\n\n manager.lastClient!.emitEvent({\n type: 'extension_ui_request',\n id: 'n1',\n method: 'notify',\n message: 'Auto-mode stopped: success',\n });\n\n assert.ok(emittedData);\n assert.equal(emittedData.projectName, 'emit-completed');\n });\n\n // ---- EventEmitter: session:error ----\n\n it('emits session:error event on init failure', async () => {\n const { manager } = createManager();\n\n let emittedData: Record<string, unknown> | undefined;\n manager.on('session:error', (data: Record<string, unknown>) => { emittedData = data; });\n\n manager.nextInitError = new Error('Process crashed');\n\n try {\n await manager.startSession({ projectDir: '/tmp/emit-error' });\n } catch { /* expected */ }\n\n assert.ok(emittedData);\n assert.ok((emittedData.error as string).includes('Process crashed'));\n });\n\n // ---- EventEmitter: session:event ----\n\n it('emits session:event for every forwarded event', async () => {\n const { manager } = createManager();\n\n const events: Record<string, unknown>[] = [];\n manager.on('session:event', (data) => { events.push(data); });\n\n await manager.startSession({ projectDir: '/tmp/emit-event' });\n\n manager.lastClient!.emitEvent({ type: 'assistant_message', id: 'a1', content: 'Hello' });\n manager.lastClient!.emitEvent({ type: 'tool_use', id: 't1', name: 'read' });\n\n assert.equal(events.length, 2);\n });\n\n // ---- Empty projectDir rejection ----\n\n it('rejects empty projectDir', async () => {\n const { manager } = createManager();\n\n await assert.rejects(\n () => manager.startSession({ projectDir: '' }),\n (err: Error) => {\n assert.ok(err.message.includes('projectDir is required'));\n return true;\n }\n );\n\n await assert.rejects(\n () => manager.startSession({ projectDir: ' ' }),\n (err: Error) => {\n assert.ok(err.message.includes('projectDir is required'));\n return true;\n }\n );\n });\n\n // ---- Logger receives structured calls ----\n\n it('logger receives structured calls during lifecycle', async () => {\n const { manager, spy } = createManager();\n\n const sessionId = await manager.startSession({ projectDir: '/tmp/log-test' });\n\n // Should have 'session started' info log\n const started = spy.findCalls('info', 'session started');\n assert.equal(started.length, 1);\n assert.ok(started[0].data?.sessionId);\n assert.ok(started[0].data?.projectDir);\n\n // Emit an event — should produce debug log\n manager.lastClient!.emitEvent({ type: 'assistant_message', id: 'a1', content: 'hi' });\n const debugLogs = spy.findCalls('debug', 'session event');\n assert.ok(debugLogs.length >= 1);\n assert.ok(debugLogs[0].data?.type);\n });\n\n // ---- getResult returns structured status ----\n\n it('getResult returns structured status', async () => {\n const { manager } = createManager();\n\n const sessionId = await manager.startSession({ projectDir: '/tmp/result-test' });\n const result = manager.getResult(sessionId);\n\n assert.equal(result.sessionId, sessionId);\n assert.equal(result.status, 'running');\n assert.equal(result.projectName, 'result-test');\n assert.equal(result.error, null);\n assert.equal(result.pendingBlocker, null);\n assert.ok(typeof result.durationMs === 'number');\n assert.ok(result.cost);\n assert.ok(Array.isArray(result.recentEvents));\n });\n\n // ---- getResult throws for unknown session ----\n\n it('getResult throws for unknown sessionId', () => {\n const { manager } = createManager();\n\n assert.throws(\n () => manager.getResult('nonexistent'),\n (err: Error) => err.message.includes('Session not found')\n );\n });\n\n // ---- resolveBlocker throws when no blocker pending ----\n\n it('resolveBlocker throws when no blocker pending', async () => {\n const { manager } = createManager();\n\n const sessionId = await manager.startSession({ projectDir: '/tmp/no-blocker' });\n\n await assert.rejects(\n () => manager.resolveBlocker(sessionId, 'yes'),\n (err: Error) => err.message.includes('No pending blocker')\n );\n });\n\n // ---- cancelSession throws for unknown session ----\n\n it('cancelSession throws for unknown sessionId', async () => {\n const { manager } = createManager();\n\n await assert.rejects(\n () => manager.cancelSession('nonexistent'),\n (err: Error) => err.message.includes('Session not found')\n );\n });\n\n // ---- Blocked notification detected as blocker, not terminal ----\n\n it('blocked notification sets status to blocked, not completed', async () => {\n const { manager } = createManager();\n\n const sessionId = await manager.startSession({ projectDir: '/tmp/blocked-notify' });\n const session = manager.getSession(sessionId)!;\n\n manager.lastClient!.emitEvent({\n type: 'extension_ui_request',\n id: 'bn-1',\n method: 'notify',\n message: 'Auto-mode stopped: Blocked: waiting for approval',\n });\n\n assert.equal(session.status, 'blocked');\n assert.ok(session.pendingBlocker);\n });\n\n // ---- projectName is basename of resolved projectDir ----\n\n it('projectName is basename of projectDir', async () => {\n const { manager } = createManager();\n\n const sessionId = await manager.startSession({ projectDir: '/home/user/projects/my-app' });\n const session = manager.getSession(sessionId)!;\n\n assert.equal(session.projectName, 'my-app');\n });\n\n // ---- Custom command is sent instead of default ----\n\n it('sends custom command when provided', async () => {\n const { manager } = createManager();\n\n await manager.startSession({ projectDir: '/tmp/custom-cmd', command: '/gsd quick fix-typo' });\n const client = manager.lastClient!;\n\n assert.ok(client.prompted.includes('/gsd quick fix-typo'));\n assert.ok(!client.prompted.includes('/gsd auto'));\n });\n\n // ---- getSessionByDir returns session by directory lookup ----\n\n it('getSessionByDir returns session by directory', async () => {\n const { manager } = createManager();\n\n await manager.startSession({ projectDir: '/tmp/dir-lookup' });\n const session = manager.getSessionByDir('/tmp/dir-lookup');\n\n assert.ok(session);\n assert.equal(session.projectName, 'dir-lookup');\n });\n});\n"]}
@@ -0,0 +1,133 @@
1
+ import type { RpcClient } from '@opengsd/rpc-client';
2
+ import type { McpPendingBlocker as PendingBlocker, SdkAgentEvent } from '@opengsd/contracts';
3
+ /**
4
+ * Log severity levels, ordered from most to least verbose.
5
+ */
6
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
7
+ /**
8
+ * Per-channel verbosity for Discord event streaming.
9
+ * - 'default': tool calls, messages, transitions, blockers, errors, completions
10
+ * - 'verbose': everything including cost_update and status events
11
+ * - 'quiet': only blockers, errors, completions
12
+ */
13
+ export type VerbosityLevel = 'default' | 'verbose' | 'quiet';
14
+ /**
15
+ * A single structured log entry written as JSON-lines.
16
+ */
17
+ export interface LogEntry {
18
+ /** ISO-8601 timestamp */
19
+ ts: string;
20
+ level: LogLevel;
21
+ msg: string;
22
+ data?: Record<string, unknown>;
23
+ }
24
+ /**
25
+ * Top-level daemon configuration, loaded from YAML.
26
+ */
27
+ export interface DaemonConfig {
28
+ cloud?: {
29
+ gateway_url: string;
30
+ device_token?: string;
31
+ runtime_id?: string;
32
+ runtime_name?: string;
33
+ enabled?: boolean;
34
+ };
35
+ discord?: {
36
+ token: string;
37
+ guild_id: string;
38
+ owner_id: string;
39
+ /** When true, DM the owner on blocker events in addition to channel messages */
40
+ dm_on_blocker?: boolean;
41
+ /** Discord channel ID where the orchestrator listens for natural language commands */
42
+ control_channel_id?: string;
43
+ /** LLM orchestrator settings */
44
+ orchestrator?: {
45
+ model?: string;
46
+ max_tokens?: number;
47
+ };
48
+ };
49
+ projects: {
50
+ scan_roots: string[];
51
+ };
52
+ log: {
53
+ file: string;
54
+ level: LogLevel;
55
+ max_size_mb: number;
56
+ };
57
+ }
58
+ export type SessionStatus = 'starting' | 'running' | 'blocked' | 'completed' | 'error' | 'cancelled';
59
+ /**
60
+ * A daemon-managed GSD headless session.
61
+ */
62
+ export interface ManagedSession {
63
+ /** Unique session ID returned from RpcClient.init() */
64
+ sessionId: string;
65
+ /** Absolute path to the project directory */
66
+ projectDir: string;
67
+ /** Human-readable project name (basename of projectDir) */
68
+ projectName: string;
69
+ /** Current lifecycle status */
70
+ status: SessionStatus;
71
+ /** The RpcClient instance managing the agent process */
72
+ client: RpcClient;
73
+ /** Ring buffer of recent events (capped at MAX_EVENTS) */
74
+ events: SdkAgentEvent[];
75
+ /** Pending blocker requiring user response, if any */
76
+ pendingBlocker: PendingBlocker | null;
77
+ /** Cumulative cost tracking (max pattern per K004) */
78
+ cost: CostAccumulator;
79
+ /** Session start timestamp */
80
+ startTime: number;
81
+ /** Error message if status is 'error' */
82
+ error?: string;
83
+ /** Cleanup function to unsubscribe from events */
84
+ unsubscribe?: () => void;
85
+ }
86
+ export type { PendingBlocker };
87
+ export interface CostAccumulator {
88
+ totalCost: number;
89
+ tokens: {
90
+ input: number;
91
+ output: number;
92
+ cacheRead: number;
93
+ cacheWrite: number;
94
+ };
95
+ }
96
+ /** Marker types detectable by the project scanner */
97
+ export type ProjectMarker = 'git' | 'node' | 'gsd' | 'rust' | 'python' | 'go';
98
+ export interface ProjectInfo {
99
+ /** Directory name (basename) */
100
+ name: string;
101
+ /** Absolute path to the project directory */
102
+ path: string;
103
+ /** Detected marker types */
104
+ markers: ProjectMarker[];
105
+ /** Most recent mtime of detected marker files/dirs (epoch ms) */
106
+ lastModified: number;
107
+ }
108
+ export interface StartSessionOptions {
109
+ /** Absolute path to the project directory */
110
+ projectDir: string;
111
+ /** Command to send after '/gsd auto' (default: none) */
112
+ command?: string;
113
+ /** Model ID override */
114
+ model?: string;
115
+ /** Run in bare mode (skip user config) */
116
+ bare?: boolean;
117
+ /** Path to CLI binary (overrides GSD_CLI_PATH and which resolution) */
118
+ cliPath?: string;
119
+ }
120
+ /**
121
+ * Formatted Discord message payload for a GSD event.
122
+ * content is the plain-text fallback; embeds and components are optional.
123
+ */
124
+ export interface FormattedEvent {
125
+ content: string;
126
+ embed?: import('discord.js').EmbedBuilder;
127
+ components?: import('discord.js').ActionRowBuilder<import('discord.js').ButtonBuilder>[];
128
+ }
129
+ /** Maximum number of events kept in the ring buffer (larger than mcp-server's 50 — daemon forwards events to Discord) */
130
+ export declare const MAX_EVENTS = 100;
131
+ /** Timeout for RpcClient initialization (ms) */
132
+ export declare const INIT_TIMEOUT_MS = 30000;
133
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Constants
3
+ // ---------------------------------------------------------------------------
4
+ /** Maximum number of events kept in the ring buffer (larger than mcp-server's 50 — daemon forwards events to Discord) */
5
+ export const MAX_EVENTS = 100;
6
+ /** Timeout for RpcClient initialization (ms) */
7
+ export const INIT_TIMEOUT_MS = 30_000;
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAsLA,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,yHAAyH;AACzH,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAC;AAE9B,gDAAgD;AAChD,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC","sourcesContent":["import type { RpcClient } from '@opengsd/rpc-client';\nimport type { McpPendingBlocker as PendingBlocker, SdkAgentEvent } from '@opengsd/contracts';\n\n/**\n * Log severity levels, ordered from most to least verbose.\n */\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\n/**\n * Per-channel verbosity for Discord event streaming.\n * - 'default': tool calls, messages, transitions, blockers, errors, completions\n * - 'verbose': everything including cost_update and status events\n * - 'quiet': only blockers, errors, completions\n */\nexport type VerbosityLevel = 'default' | 'verbose' | 'quiet';\n\n/**\n * A single structured log entry written as JSON-lines.\n */\nexport interface LogEntry {\n /** ISO-8601 timestamp */\n ts: string;\n level: LogLevel;\n msg: string;\n data?: Record<string, unknown>;\n}\n\n/**\n * Top-level daemon configuration, loaded from YAML.\n */\nexport interface DaemonConfig {\n cloud?: {\n gateway_url: string;\n device_token?: string;\n runtime_id?: string;\n runtime_name?: string;\n enabled?: boolean;\n };\n discord?: {\n token: string;\n guild_id: string;\n owner_id: string;\n /** When true, DM the owner on blocker events in addition to channel messages */\n dm_on_blocker?: boolean;\n /** Discord channel ID where the orchestrator listens for natural language commands */\n control_channel_id?: string;\n /** LLM orchestrator settings */\n orchestrator?: {\n model?: string;\n max_tokens?: number;\n };\n };\n projects: {\n scan_roots: string[];\n };\n log: {\n file: string;\n level: LogLevel;\n max_size_mb: number;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Session Status\n// ---------------------------------------------------------------------------\n\nexport type SessionStatus = 'starting' | 'running' | 'blocked' | 'completed' | 'error' | 'cancelled';\n\n// ---------------------------------------------------------------------------\n// Managed Session\n// ---------------------------------------------------------------------------\n\n/**\n * A daemon-managed GSD headless session.\n */\nexport interface ManagedSession {\n /** Unique session ID returned from RpcClient.init() */\n sessionId: string;\n\n /** Absolute path to the project directory */\n projectDir: string;\n\n /** Human-readable project name (basename of projectDir) */\n projectName: string;\n\n /** Current lifecycle status */\n status: SessionStatus;\n\n /** The RpcClient instance managing the agent process */\n client: RpcClient;\n\n /** Ring buffer of recent events (capped at MAX_EVENTS) */\n events: SdkAgentEvent[];\n\n /** Pending blocker requiring user response, if any */\n pendingBlocker: PendingBlocker | null;\n\n /** Cumulative cost tracking (max pattern per K004) */\n cost: CostAccumulator;\n\n /** Session start timestamp */\n startTime: number;\n\n /** Error message if status is 'error' */\n error?: string;\n\n /** Cleanup function to unsubscribe from events */\n unsubscribe?: () => void;\n}\n\nexport type { PendingBlocker };\n\n// ---------------------------------------------------------------------------\n// Cost Accumulator (K004 — cumulative-max)\n// ---------------------------------------------------------------------------\n\nexport interface CostAccumulator {\n totalCost: number;\n tokens: {\n input: number;\n output: number;\n cacheRead: number;\n cacheWrite: number;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Project Info — scanner output\n// ---------------------------------------------------------------------------\n\n/** Marker types detectable by the project scanner */\nexport type ProjectMarker = 'git' | 'node' | 'gsd' | 'rust' | 'python' | 'go';\n\nexport interface ProjectInfo {\n /** Directory name (basename) */\n name: string;\n\n /** Absolute path to the project directory */\n path: string;\n\n /** Detected marker types */\n markers: ProjectMarker[];\n\n /** Most recent mtime of detected marker files/dirs (epoch ms) */\n lastModified: number;\n}\n\n// ---------------------------------------------------------------------------\n// Start Session Options\n// ---------------------------------------------------------------------------\n\nexport interface StartSessionOptions {\n /** Absolute path to the project directory */\n projectDir: string;\n\n /** Command to send after '/gsd auto' (default: none) */\n command?: string;\n\n /** Model ID override */\n model?: string;\n\n /** Run in bare mode (skip user config) */\n bare?: boolean;\n\n /** Path to CLI binary (overrides GSD_CLI_PATH and which resolution) */\n cliPath?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Formatted Event — output of event-formatter.ts\n// ---------------------------------------------------------------------------\n\n/**\n * Formatted Discord message payload for a GSD event.\n * content is the plain-text fallback; embeds and components are optional.\n */\nexport interface FormattedEvent {\n content: string;\n embed?: import('discord.js').EmbedBuilder;\n components?: import('discord.js').ActionRowBuilder<import('discord.js').ButtonBuilder>[];\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Maximum number of events kept in the ring buffer (larger than mcp-server's 50 — daemon forwards events to Discord) */\nexport const MAX_EVENTS = 100;\n\n/** Timeout for RpcClient initialization (ms) */\nexport const INIT_TIMEOUT_MS = 30_000;\n"]}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * verbosity.ts — Per-channel verbosity filter for Discord event streaming.
3
+ *
4
+ * Controls which RPC event types reach each Discord channel.
5
+ * Three levels:
6
+ * - 'quiet': blockers, errors, completions only
7
+ * - 'default': tool calls, messages, transitions, blockers, errors, completions
8
+ * - 'verbose': everything (adds cost_update, status, generic events)
9
+ */
10
+ import type { VerbosityLevel } from './types.js';
11
+ export declare class VerbosityManager {
12
+ private levels;
13
+ /** Get the verbosity level for a channel. Defaults to 'default'. */
14
+ getLevel(channelId: string): VerbosityLevel;
15
+ /** Set the verbosity level for a channel. */
16
+ setLevel(channelId: string, level: VerbosityLevel): void;
17
+ /**
18
+ * Determine whether an event of the given type should be shown
19
+ * in the specified channel.
20
+ */
21
+ shouldShow(channelId: string, eventType: string): boolean;
22
+ }
23
+ /**
24
+ * Pure predicate: should an event of this type be shown at the given verbosity level?
25
+ */
26
+ export declare function shouldShowAtLevel(level: VerbosityLevel, eventType: string): boolean;
27
+ //# sourceMappingURL=verbosity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verbosity.d.ts","sourceRoot":"","sources":["../src/verbosity.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAuCjD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAA0C;IAExD,oEAAoE;IACpE,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc;IAI3C,6CAA6C;IAC7C,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI;IAIxD;;;OAGG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;CAI1D;AAMD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAqBnF"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * verbosity.ts — Per-channel verbosity filter for Discord event streaming.
3
+ *
4
+ * Controls which RPC event types reach each Discord channel.
5
+ * Three levels:
6
+ * - 'quiet': blockers, errors, completions only
7
+ * - 'default': tool calls, messages, transitions, blockers, errors, completions
8
+ * - 'verbose': everything (adds cost_update, status, generic events)
9
+ */
10
+ // ---------------------------------------------------------------------------
11
+ // Event classification
12
+ // ---------------------------------------------------------------------------
13
+ /** Event types that are always shown (even in quiet mode). */
14
+ const ALWAYS_SHOWN = new Set([
15
+ 'extension_ui_request', // blockers
16
+ 'execution_complete',
17
+ 'error',
18
+ 'session_error',
19
+ ]);
20
+ /** Event types shown at default level and above. */
21
+ const DEFAULT_SHOWN = new Set([
22
+ 'tool_execution_start',
23
+ 'tool_execution_end',
24
+ 'message_start',
25
+ 'message_end',
26
+ 'message',
27
+ 'task_transition',
28
+ 'session_started',
29
+ ]);
30
+ /** Event types shown only at verbose level. */
31
+ const VERBOSE_ONLY = new Set([
32
+ 'cost_update',
33
+ 'state_update',
34
+ 'status',
35
+ 'set_status',
36
+ 'set_widget',
37
+ 'set_title',
38
+ ]);
39
+ // ---------------------------------------------------------------------------
40
+ // VerbosityManager
41
+ // ---------------------------------------------------------------------------
42
+ export class VerbosityManager {
43
+ levels = new Map();
44
+ /** Get the verbosity level for a channel. Defaults to 'default'. */
45
+ getLevel(channelId) {
46
+ return this.levels.get(channelId) ?? 'default';
47
+ }
48
+ /** Set the verbosity level for a channel. */
49
+ setLevel(channelId, level) {
50
+ this.levels.set(channelId, level);
51
+ }
52
+ /**
53
+ * Determine whether an event of the given type should be shown
54
+ * in the specified channel.
55
+ */
56
+ shouldShow(channelId, eventType) {
57
+ const level = this.getLevel(channelId);
58
+ return shouldShowAtLevel(level, eventType);
59
+ }
60
+ }
61
+ // ---------------------------------------------------------------------------
62
+ // Pure filter — exported for direct use and testability
63
+ // ---------------------------------------------------------------------------
64
+ /**
65
+ * Pure predicate: should an event of this type be shown at the given verbosity level?
66
+ */
67
+ export function shouldShowAtLevel(level, eventType) {
68
+ // Always-shown events pass through regardless of level
69
+ if (ALWAYS_SHOWN.has(eventType))
70
+ return true;
71
+ switch (level) {
72
+ case 'quiet':
73
+ // Quiet only shows ALWAYS_SHOWN events
74
+ return false;
75
+ case 'default':
76
+ // Default shows ALWAYS_SHOWN + DEFAULT_SHOWN
77
+ return DEFAULT_SHOWN.has(eventType);
78
+ case 'verbose':
79
+ // Verbose shows everything
80
+ return true;
81
+ default:
82
+ // Unknown level → treat as default
83
+ return DEFAULT_SHOWN.has(eventType);
84
+ }
85
+ }
86
+ //# sourceMappingURL=verbosity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verbosity.js","sourceRoot":"","sources":["../src/verbosity.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,8EAA8E;AAC9E,uBAAuB;AACvB,8EAA8E;AAE9E,8DAA8D;AAC9D,MAAM,YAAY,GAAwB,IAAI,GAAG,CAAC;IAChD,sBAAsB,EAAG,WAAW;IACpC,oBAAoB;IACpB,OAAO;IACP,eAAe;CAChB,CAAC,CAAC;AAEH,oDAAoD;AACpD,MAAM,aAAa,GAAwB,IAAI,GAAG,CAAC;IACjD,sBAAsB;IACtB,oBAAoB;IACpB,eAAe;IACf,aAAa;IACb,SAAS;IACT,iBAAiB;IACjB,iBAAiB;CAClB,CAAC,CAAC;AAEH,+CAA+C;AAC/C,MAAM,YAAY,GAAwB,IAAI,GAAG,CAAC;IAChD,aAAa;IACb,cAAc;IACd,QAAQ;IACR,YAAY;IACZ,YAAY;IACZ,WAAW;CACZ,CAAC,CAAC;AAEH,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,MAAM,OAAO,gBAAgB;IACnB,MAAM,GAAgC,IAAI,GAAG,EAAE,CAAC;IAExD,oEAAoE;IACpE,QAAQ,CAAC,SAAiB;QACxB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC;IACjD,CAAC;IAED,6CAA6C;IAC7C,QAAQ,CAAC,SAAiB,EAAE,KAAqB;QAC/C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IACpC,CAAC;IAED;;;OAGG;IACH,UAAU,CAAC,SAAiB,EAAE,SAAiB;QAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QACvC,OAAO,iBAAiB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAC7C,CAAC;CACF;AAED,8EAA8E;AAC9E,wDAAwD;AACxD,8EAA8E;AAE9E;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAqB,EAAE,SAAiB;IACxE,uDAAuD;IACvD,IAAI,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IAE7C,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,OAAO;YACV,uCAAuC;YACvC,OAAO,KAAK,CAAC;QAEf,KAAK,SAAS;YACZ,6CAA6C;YAC7C,OAAO,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAEtC,KAAK,SAAS;YACZ,2BAA2B;YAC3B,OAAO,IAAI,CAAC;QAEd;YACE,mCAAmC;YACnC,OAAO,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;AACH,CAAC","sourcesContent":["/**\n * verbosity.ts — Per-channel verbosity filter for Discord event streaming.\n *\n * Controls which RPC event types reach each Discord channel.\n * Three levels:\n * - 'quiet': blockers, errors, completions only\n * - 'default': tool calls, messages, transitions, blockers, errors, completions\n * - 'verbose': everything (adds cost_update, status, generic events)\n */\n\nimport type { VerbosityLevel } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Event classification\n// ---------------------------------------------------------------------------\n\n/** Event types that are always shown (even in quiet mode). */\nconst ALWAYS_SHOWN: ReadonlySet<string> = new Set([\n 'extension_ui_request', // blockers\n 'execution_complete',\n 'error',\n 'session_error',\n]);\n\n/** Event types shown at default level and above. */\nconst DEFAULT_SHOWN: ReadonlySet<string> = new Set([\n 'tool_execution_start',\n 'tool_execution_end',\n 'message_start',\n 'message_end',\n 'message',\n 'task_transition',\n 'session_started',\n]);\n\n/** Event types shown only at verbose level. */\nconst VERBOSE_ONLY: ReadonlySet<string> = new Set([\n 'cost_update',\n 'state_update',\n 'status',\n 'set_status',\n 'set_widget',\n 'set_title',\n]);\n\n// ---------------------------------------------------------------------------\n// VerbosityManager\n// ---------------------------------------------------------------------------\n\nexport class VerbosityManager {\n private levels: Map<string, VerbosityLevel> = new Map();\n\n /** Get the verbosity level for a channel. Defaults to 'default'. */\n getLevel(channelId: string): VerbosityLevel {\n return this.levels.get(channelId) ?? 'default';\n }\n\n /** Set the verbosity level for a channel. */\n setLevel(channelId: string, level: VerbosityLevel): void {\n this.levels.set(channelId, level);\n }\n\n /**\n * Determine whether an event of the given type should be shown\n * in the specified channel.\n */\n shouldShow(channelId: string, eventType: string): boolean {\n const level = this.getLevel(channelId);\n return shouldShowAtLevel(level, eventType);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Pure filter — exported for direct use and testability\n// ---------------------------------------------------------------------------\n\n/**\n * Pure predicate: should an event of this type be shown at the given verbosity level?\n */\nexport function shouldShowAtLevel(level: VerbosityLevel, eventType: string): boolean {\n // Always-shown events pass through regardless of level\n if (ALWAYS_SHOWN.has(eventType)) return true;\n\n switch (level) {\n case 'quiet':\n // Quiet only shows ALWAYS_SHOWN events\n return false;\n\n case 'default':\n // Default shows ALWAYS_SHOWN + DEFAULT_SHOWN\n return DEFAULT_SHOWN.has(eventType);\n\n case 'verbose':\n // Verbose shows everything\n return true;\n\n default:\n // Unknown level → treat as default\n return DEFAULT_SHOWN.has(eventType);\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=verbosity.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verbosity.test.d.ts","sourceRoot":"","sources":["../src/verbosity.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,136 @@
1
+ import { describe, it, beforeEach } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { VerbosityManager, shouldShowAtLevel } from './verbosity.js';
4
+ // ---------------------------------------------------------------------------
5
+ // VerbosityManager
6
+ // ---------------------------------------------------------------------------
7
+ describe('VerbosityManager', () => {
8
+ let vm;
9
+ beforeEach(() => {
10
+ vm = new VerbosityManager();
11
+ });
12
+ it('returns default level for unknown channel', () => {
13
+ assert.equal(vm.getLevel('chan-1'), 'default');
14
+ });
15
+ it('set/get round-trips', () => {
16
+ vm.setLevel('chan-1', 'quiet');
17
+ assert.equal(vm.getLevel('chan-1'), 'quiet');
18
+ vm.setLevel('chan-1', 'verbose');
19
+ assert.equal(vm.getLevel('chan-1'), 'verbose');
20
+ });
21
+ it('different channels are independent', () => {
22
+ vm.setLevel('chan-a', 'quiet');
23
+ vm.setLevel('chan-b', 'verbose');
24
+ assert.equal(vm.getLevel('chan-a'), 'quiet');
25
+ assert.equal(vm.getLevel('chan-b'), 'verbose');
26
+ assert.equal(vm.getLevel('chan-c'), 'default');
27
+ });
28
+ it('shouldShow delegates to the level-based filter', () => {
29
+ vm.setLevel('chan-q', 'quiet');
30
+ assert.equal(vm.shouldShow('chan-q', 'tool_execution_start'), false);
31
+ assert.equal(vm.shouldShow('chan-q', 'extension_ui_request'), true);
32
+ });
33
+ });
34
+ // ---------------------------------------------------------------------------
35
+ // shouldShowAtLevel — quiet
36
+ // ---------------------------------------------------------------------------
37
+ describe('shouldShowAtLevel — quiet', () => {
38
+ const level = 'quiet';
39
+ it('shows blockers', () => {
40
+ assert.equal(shouldShowAtLevel(level, 'extension_ui_request'), true);
41
+ });
42
+ it('shows execution_complete', () => {
43
+ assert.equal(shouldShowAtLevel(level, 'execution_complete'), true);
44
+ });
45
+ it('shows error', () => {
46
+ assert.equal(shouldShowAtLevel(level, 'error'), true);
47
+ });
48
+ it('shows session_error', () => {
49
+ assert.equal(shouldShowAtLevel(level, 'session_error'), true);
50
+ });
51
+ it('hides tool calls', () => {
52
+ assert.equal(shouldShowAtLevel(level, 'tool_execution_start'), false);
53
+ assert.equal(shouldShowAtLevel(level, 'tool_execution_end'), false);
54
+ });
55
+ it('hides messages', () => {
56
+ assert.equal(shouldShowAtLevel(level, 'message_start'), false);
57
+ assert.equal(shouldShowAtLevel(level, 'message'), false);
58
+ });
59
+ it('hides cost_update', () => {
60
+ assert.equal(shouldShowAtLevel(level, 'cost_update'), false);
61
+ });
62
+ it('hides task_transition', () => {
63
+ assert.equal(shouldShowAtLevel(level, 'task_transition'), false);
64
+ });
65
+ it('hides unknown events', () => {
66
+ assert.equal(shouldShowAtLevel(level, 'totally_random'), false);
67
+ });
68
+ });
69
+ // ---------------------------------------------------------------------------
70
+ // shouldShowAtLevel — default
71
+ // ---------------------------------------------------------------------------
72
+ describe('shouldShowAtLevel — default', () => {
73
+ const level = 'default';
74
+ it('shows blockers', () => {
75
+ assert.equal(shouldShowAtLevel(level, 'extension_ui_request'), true);
76
+ });
77
+ it('shows execution_complete', () => {
78
+ assert.equal(shouldShowAtLevel(level, 'execution_complete'), true);
79
+ });
80
+ it('shows error', () => {
81
+ assert.equal(shouldShowAtLevel(level, 'error'), true);
82
+ });
83
+ it('shows tool calls', () => {
84
+ assert.equal(shouldShowAtLevel(level, 'tool_execution_start'), true);
85
+ assert.equal(shouldShowAtLevel(level, 'tool_execution_end'), true);
86
+ });
87
+ it('shows messages', () => {
88
+ assert.equal(shouldShowAtLevel(level, 'message_start'), true);
89
+ assert.equal(shouldShowAtLevel(level, 'message_end'), true);
90
+ assert.equal(shouldShowAtLevel(level, 'message'), true);
91
+ });
92
+ it('shows task_transition', () => {
93
+ assert.equal(shouldShowAtLevel(level, 'task_transition'), true);
94
+ });
95
+ it('shows session_started', () => {
96
+ assert.equal(shouldShowAtLevel(level, 'session_started'), true);
97
+ });
98
+ it('hides cost_update', () => {
99
+ assert.equal(shouldShowAtLevel(level, 'cost_update'), false);
100
+ });
101
+ it('hides status events', () => {
102
+ assert.equal(shouldShowAtLevel(level, 'state_update'), false);
103
+ assert.equal(shouldShowAtLevel(level, 'status'), false);
104
+ });
105
+ it('hides unknown events', () => {
106
+ assert.equal(shouldShowAtLevel(level, 'something_weird'), false);
107
+ });
108
+ });
109
+ // ---------------------------------------------------------------------------
110
+ // shouldShowAtLevel — verbose
111
+ // ---------------------------------------------------------------------------
112
+ describe('shouldShowAtLevel — verbose', () => {
113
+ const level = 'verbose';
114
+ it('shows everything that quiet/default show', () => {
115
+ const events = [
116
+ 'extension_ui_request', 'execution_complete', 'error', 'session_error',
117
+ 'tool_execution_start', 'tool_execution_end', 'message_start', 'message_end',
118
+ 'message', 'task_transition', 'session_started',
119
+ ];
120
+ for (const e of events) {
121
+ assert.equal(shouldShowAtLevel(level, e), true, `Expected verbose to show ${e}`);
122
+ }
123
+ });
124
+ it('shows cost_update', () => {
125
+ assert.equal(shouldShowAtLevel(level, 'cost_update'), true);
126
+ });
127
+ it('shows status events', () => {
128
+ assert.equal(shouldShowAtLevel(level, 'state_update'), true);
129
+ assert.equal(shouldShowAtLevel(level, 'status'), true);
130
+ assert.equal(shouldShowAtLevel(level, 'set_status'), true);
131
+ });
132
+ it('shows unknown/arbitrary events', () => {
133
+ assert.equal(shouldShowAtLevel(level, 'something_arbitrary'), true);
134
+ });
135
+ });
136
+ //# sourceMappingURL=verbosity.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verbosity.test.js","sourceRoot":"","sources":["../src/verbosity.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, it, beforeEach } from 'node:test';\nimport assert from 'node:assert/strict';\nimport { VerbosityManager, shouldShowAtLevel } from './verbosity.js';\n\n// ---------------------------------------------------------------------------\n// VerbosityManager\n// ---------------------------------------------------------------------------\n\ndescribe('VerbosityManager', () => {\n let vm: VerbosityManager;\n\n beforeEach(() => {\n vm = new VerbosityManager();\n });\n\n it('returns default level for unknown channel', () => {\n assert.equal(vm.getLevel('chan-1'), 'default');\n });\n\n it('set/get round-trips', () => {\n vm.setLevel('chan-1', 'quiet');\n assert.equal(vm.getLevel('chan-1'), 'quiet');\n vm.setLevel('chan-1', 'verbose');\n assert.equal(vm.getLevel('chan-1'), 'verbose');\n });\n\n it('different channels are independent', () => {\n vm.setLevel('chan-a', 'quiet');\n vm.setLevel('chan-b', 'verbose');\n assert.equal(vm.getLevel('chan-a'), 'quiet');\n assert.equal(vm.getLevel('chan-b'), 'verbose');\n assert.equal(vm.getLevel('chan-c'), 'default');\n });\n\n it('shouldShow delegates to the level-based filter', () => {\n vm.setLevel('chan-q', 'quiet');\n assert.equal(vm.shouldShow('chan-q', 'tool_execution_start'), false);\n assert.equal(vm.shouldShow('chan-q', 'extension_ui_request'), true);\n });\n});\n\n// ---------------------------------------------------------------------------\n// shouldShowAtLevel — quiet\n// ---------------------------------------------------------------------------\n\ndescribe('shouldShowAtLevel — quiet', () => {\n const level = 'quiet' as const;\n\n it('shows blockers', () => {\n assert.equal(shouldShowAtLevel(level, 'extension_ui_request'), true);\n });\n\n it('shows execution_complete', () => {\n assert.equal(shouldShowAtLevel(level, 'execution_complete'), true);\n });\n\n it('shows error', () => {\n assert.equal(shouldShowAtLevel(level, 'error'), true);\n });\n\n it('shows session_error', () => {\n assert.equal(shouldShowAtLevel(level, 'session_error'), true);\n });\n\n it('hides tool calls', () => {\n assert.equal(shouldShowAtLevel(level, 'tool_execution_start'), false);\n assert.equal(shouldShowAtLevel(level, 'tool_execution_end'), false);\n });\n\n it('hides messages', () => {\n assert.equal(shouldShowAtLevel(level, 'message_start'), false);\n assert.equal(shouldShowAtLevel(level, 'message'), false);\n });\n\n it('hides cost_update', () => {\n assert.equal(shouldShowAtLevel(level, 'cost_update'), false);\n });\n\n it('hides task_transition', () => {\n assert.equal(shouldShowAtLevel(level, 'task_transition'), false);\n });\n\n it('hides unknown events', () => {\n assert.equal(shouldShowAtLevel(level, 'totally_random'), false);\n });\n});\n\n// ---------------------------------------------------------------------------\n// shouldShowAtLevel — default\n// ---------------------------------------------------------------------------\n\ndescribe('shouldShowAtLevel — default', () => {\n const level = 'default' as const;\n\n it('shows blockers', () => {\n assert.equal(shouldShowAtLevel(level, 'extension_ui_request'), true);\n });\n\n it('shows execution_complete', () => {\n assert.equal(shouldShowAtLevel(level, 'execution_complete'), true);\n });\n\n it('shows error', () => {\n assert.equal(shouldShowAtLevel(level, 'error'), true);\n });\n\n it('shows tool calls', () => {\n assert.equal(shouldShowAtLevel(level, 'tool_execution_start'), true);\n assert.equal(shouldShowAtLevel(level, 'tool_execution_end'), true);\n });\n\n it('shows messages', () => {\n assert.equal(shouldShowAtLevel(level, 'message_start'), true);\n assert.equal(shouldShowAtLevel(level, 'message_end'), true);\n assert.equal(shouldShowAtLevel(level, 'message'), true);\n });\n\n it('shows task_transition', () => {\n assert.equal(shouldShowAtLevel(level, 'task_transition'), true);\n });\n\n it('shows session_started', () => {\n assert.equal(shouldShowAtLevel(level, 'session_started'), true);\n });\n\n it('hides cost_update', () => {\n assert.equal(shouldShowAtLevel(level, 'cost_update'), false);\n });\n\n it('hides status events', () => {\n assert.equal(shouldShowAtLevel(level, 'state_update'), false);\n assert.equal(shouldShowAtLevel(level, 'status'), false);\n });\n\n it('hides unknown events', () => {\n assert.equal(shouldShowAtLevel(level, 'something_weird'), false);\n });\n});\n\n// ---------------------------------------------------------------------------\n// shouldShowAtLevel — verbose\n// ---------------------------------------------------------------------------\n\ndescribe('shouldShowAtLevel — verbose', () => {\n const level = 'verbose' as const;\n\n it('shows everything that quiet/default show', () => {\n const events = [\n 'extension_ui_request', 'execution_complete', 'error', 'session_error',\n 'tool_execution_start', 'tool_execution_end', 'message_start', 'message_end',\n 'message', 'task_transition', 'session_started',\n ];\n for (const e of events) {\n assert.equal(shouldShowAtLevel(level, e), true, `Expected verbose to show ${e}`);\n }\n });\n\n it('shows cost_update', () => {\n assert.equal(shouldShowAtLevel(level, 'cost_update'), true);\n });\n\n it('shows status events', () => {\n assert.equal(shouldShowAtLevel(level, 'state_update'), true);\n assert.equal(shouldShowAtLevel(level, 'status'), true);\n assert.equal(shouldShowAtLevel(level, 'set_status'), true);\n });\n\n it('shows unknown/arbitrary events', () => {\n assert.equal(shouldShowAtLevel(level, 'something_arbitrary'), true);\n });\n});\n"]}