@opengsd/gsd-pi 1.9.0-dev.e10b60d4 → 1.10.0-dev.a5e42e99

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/README.md +10 -9
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/extensions/gsd/auto/loop.js +24 -4
  4. package/dist/resources/extensions/gsd/auto/run-unit.js +19 -1
  5. package/dist/resources/extensions/gsd/auto-model-selection.js +1 -0
  6. package/dist/resources/extensions/gsd/auto-start.js +30 -10
  7. package/dist/resources/extensions/gsd/auto-verification.js +25 -12
  8. package/dist/resources/extensions/gsd/auto-worktree-sync.js +7 -3
  9. package/dist/resources/extensions/gsd/auto.js +12 -1
  10. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +4 -3
  11. package/dist/resources/extensions/gsd/docs/preferences-reference.md +12 -3
  12. package/dist/resources/extensions/gsd/doctor-engine-checks.js +37 -6
  13. package/dist/resources/extensions/gsd/flat-phase-migration.js +12 -0
  14. package/dist/resources/extensions/gsd/gsd-db.js +75 -31
  15. package/dist/resources/extensions/gsd/model-cost-table.js +6 -3
  16. package/dist/resources/extensions/gsd/model-router.js +10 -5
  17. package/dist/resources/extensions/gsd/planning-subagent-registry.js +12 -4
  18. package/dist/resources/extensions/gsd/preferences-models.js +50 -10
  19. package/dist/resources/extensions/gsd/preferences-types.js +1 -0
  20. package/dist/resources/extensions/gsd/preferences-validation.js +41 -6
  21. package/dist/resources/extensions/gsd/preferences.js +7 -0
  22. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +3 -0
  23. package/dist/resources/extensions/gsd/tools/plan-slice.js +5 -1
  24. package/dist/resources/extensions/gsd/verification-evidence.js +5 -3
  25. package/dist/resources/extensions/gsd/worktree-state-projection.js +20 -18
  26. package/dist/resources/extensions/ollama/ollama-chat-provider.js +2 -2
  27. package/dist/resources/extensions/subagent/index.js +1 -1
  28. package/dist/startup-model-validation.d.ts +1 -1
  29. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  30. package/dist/web/standalone/.next/BUILD_ID +1 -1
  31. package/dist/web/standalone/.next/app-path-routes-manifest.json +6 -6
  32. package/dist/web/standalone/.next/build-manifest.json +2 -2
  33. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  34. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  35. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  36. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  37. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  38. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  39. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  40. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  41. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  42. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  43. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  44. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  45. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  46. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  47. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  48. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  49. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  50. package/dist/web/standalone/.next/server/app/index.html +1 -1
  51. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  52. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  53. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  54. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  55. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  56. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  57. package/dist/web/standalone/.next/server/app-paths-manifest.json +6 -6
  58. package/dist/web/standalone/.next/server/chunks/1991.js +2 -2
  59. package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
  60. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  61. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  62. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  63. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  64. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  65. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  66. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  67. package/integrations/hermes/open_gsd_hermes/gsd_client.py +1 -1
  68. package/integrations/hermes/pyproject.toml +1 -1
  69. package/package.json +7 -6
  70. package/packages/cloud-mcp-gateway/package.json +2 -2
  71. package/packages/contracts/dist/rpc.d.ts +1 -1
  72. package/packages/contracts/dist/rpc.d.ts.map +1 -1
  73. package/packages/contracts/dist/rpc.js +1 -1
  74. package/packages/contracts/dist/rpc.js.map +1 -1
  75. package/packages/contracts/dist/rpc.test.js +1 -1
  76. package/packages/contracts/dist/rpc.test.js.map +1 -1
  77. package/packages/contracts/package.json +1 -1
  78. package/packages/daemon/package.json +4 -4
  79. package/packages/gsd-agent-core/package.json +5 -5
  80. package/packages/gsd-agent-modes/dist/cli/args.js +2 -2
  81. package/packages/gsd-agent-modes/dist/cli/args.js.map +1 -1
  82. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  83. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +1 -0
  84. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
  85. package/packages/gsd-agent-modes/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  86. package/packages/gsd-agent-modes/dist/modes/interactive/components/thinking-selector.js +1 -0
  87. package/packages/gsd-agent-modes/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  88. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-autocomplete.d.ts.map +1 -1
  89. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-autocomplete.js +1 -0
  90. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
  91. package/packages/gsd-agent-modes/package.json +7 -7
  92. package/packages/gsd-cloud/README.md +21 -5
  93. package/packages/gsd-cloud/dist/background-cli.test.d.ts +2 -0
  94. package/packages/gsd-cloud/dist/background-cli.test.d.ts.map +1 -0
  95. package/packages/gsd-cloud/dist/background-cli.test.js +325 -0
  96. package/packages/gsd-cloud/dist/background-cli.test.js.map +1 -0
  97. package/packages/gsd-cloud/dist/cli.d.ts.map +1 -1
  98. package/packages/gsd-cloud/dist/cli.js +146 -16
  99. package/packages/gsd-cloud/dist/cli.js.map +1 -1
  100. package/packages/gsd-cloud/dist/cloud-config.d.ts +1 -1
  101. package/packages/gsd-cloud/dist/cloud-config.d.ts.map +1 -1
  102. package/packages/gsd-cloud/dist/cloud-config.js +7 -1
  103. package/packages/gsd-cloud/dist/cloud-config.js.map +1 -1
  104. package/packages/gsd-cloud/dist/cloud-runtime.d.ts +7 -4
  105. package/packages/gsd-cloud/dist/cloud-runtime.d.ts.map +1 -1
  106. package/packages/gsd-cloud/dist/cloud-runtime.js +115 -31
  107. package/packages/gsd-cloud/dist/cloud-runtime.js.map +1 -1
  108. package/packages/gsd-cloud/dist/cloud-runtime.test.js +224 -59
  109. package/packages/gsd-cloud/dist/cloud-runtime.test.js.map +1 -1
  110. package/packages/gsd-cloud/dist/runtime-artifacts.d.ts +3 -0
  111. package/packages/gsd-cloud/dist/runtime-artifacts.d.ts.map +1 -0
  112. package/packages/gsd-cloud/dist/runtime-artifacts.js +36 -0
  113. package/packages/gsd-cloud/dist/runtime-artifacts.js.map +1 -0
  114. package/packages/gsd-cloud/dist/runtime-process.d.ts +32 -0
  115. package/packages/gsd-cloud/dist/runtime-process.d.ts.map +1 -0
  116. package/packages/gsd-cloud/dist/runtime-process.js +640 -0
  117. package/packages/gsd-cloud/dist/runtime-process.js.map +1 -0
  118. package/packages/gsd-cloud/dist/runtime-process.test.d.ts +2 -0
  119. package/packages/gsd-cloud/dist/runtime-process.test.d.ts.map +1 -0
  120. package/packages/gsd-cloud/dist/runtime-process.test.js +543 -0
  121. package/packages/gsd-cloud/dist/runtime-process.test.js.map +1 -0
  122. package/packages/gsd-cloud/dist/runtime-telemetry.d.ts +117 -0
  123. package/packages/gsd-cloud/dist/runtime-telemetry.d.ts.map +1 -0
  124. package/packages/gsd-cloud/dist/runtime-telemetry.js +291 -0
  125. package/packages/gsd-cloud/dist/runtime-telemetry.js.map +1 -0
  126. package/packages/gsd-cloud/dist/runtime-telemetry.test.d.ts +2 -0
  127. package/packages/gsd-cloud/dist/runtime-telemetry.test.d.ts.map +1 -0
  128. package/packages/gsd-cloud/dist/runtime-telemetry.test.js +434 -0
  129. package/packages/gsd-cloud/dist/runtime-telemetry.test.js.map +1 -0
  130. package/packages/gsd-cloud/package.json +2 -2
  131. package/packages/mcp-server/dist/cli-runner.d.ts +3 -0
  132. package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -1
  133. package/packages/mcp-server/dist/cli-runner.js +119 -33
  134. package/packages/mcp-server/dist/cli-runner.js.map +1 -1
  135. package/packages/mcp-server/package.json +4 -4
  136. package/packages/native/package.json +1 -1
  137. package/packages/pi-agent-core/dist/types.d.ts +2 -2
  138. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  139. package/packages/pi-agent-core/dist/types.js.map +1 -1
  140. package/packages/pi-agent-core/package.json +1 -1
  141. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  142. package/packages/pi-ai/dist/models.generated.d.ts +130 -2
  143. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  144. package/packages/pi-ai/dist/models.generated.js +101 -9
  145. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  146. package/packages/pi-ai/dist/models.js +18 -6
  147. package/packages/pi-ai/dist/models.js.map +1 -1
  148. package/packages/pi-ai/dist/providers/amazon-bedrock.js +3 -2
  149. package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  150. package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts +1 -1
  151. package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
  152. package/packages/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
  153. package/packages/pi-ai/dist/providers/google-vertex.js.map +1 -1
  154. package/packages/pi-ai/dist/providers/google.js.map +1 -1
  155. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts +1 -1
  156. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  157. package/packages/pi-ai/dist/providers/openai-codex-responses.js +1 -1
  158. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  159. package/packages/pi-ai/dist/providers/openai-completions.d.ts +1 -1
  160. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  161. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  162. package/packages/pi-ai/dist/providers/openai-responses.d.ts +1 -1
  163. package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
  164. package/packages/pi-ai/dist/providers/openai-responses.js +1 -1
  165. package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
  166. package/packages/pi-ai/dist/providers/simple-options.d.ts +1 -1
  167. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  168. package/packages/pi-ai/dist/providers/simple-options.js +1 -1
  169. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  170. package/packages/pi-ai/dist/types.d.ts +9 -1
  171. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  172. package/packages/pi-ai/dist/types.js.map +1 -1
  173. package/packages/pi-ai/package.json +1 -1
  174. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  175. package/packages/pi-coding-agent/dist/core/model-registry.js +1 -0
  176. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  177. package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -1
  178. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  179. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -3
  180. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  181. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  182. package/packages/pi-coding-agent/dist/core/skills.d.ts +5 -0
  183. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  184. package/packages/pi-coding-agent/dist/core/skills.js +54 -0
  185. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  186. package/packages/pi-coding-agent/dist/theme/theme.d.ts +1 -1
  187. package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
  188. package/packages/pi-coding-agent/dist/theme/theme.js +1 -0
  189. package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
  190. package/packages/pi-coding-agent/package.json +7 -7
  191. package/packages/pi-tui/package.json +2 -2
  192. package/packages/rpc-client/package.json +2 -2
  193. package/pkg/dist/theme/theme.d.ts +1 -1
  194. package/pkg/dist/theme/theme.d.ts.map +1 -1
  195. package/pkg/dist/theme/theme.js +1 -0
  196. package/pkg/dist/theme/theme.js.map +1 -1
  197. package/pkg/package.json +1 -1
  198. package/src/resources/extensions/gsd/auto/loop.ts +48 -4
  199. package/src/resources/extensions/gsd/auto/run-unit.ts +20 -1
  200. package/src/resources/extensions/gsd/auto-model-selection.ts +1 -0
  201. package/src/resources/extensions/gsd/auto-start.ts +32 -9
  202. package/src/resources/extensions/gsd/auto-verification.ts +46 -12
  203. package/src/resources/extensions/gsd/auto-worktree-sync.ts +10 -3
  204. package/src/resources/extensions/gsd/auto.ts +13 -1
  205. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +4 -3
  206. package/src/resources/extensions/gsd/docs/preferences-reference.md +12 -3
  207. package/src/resources/extensions/gsd/doctor-engine-checks.ts +42 -6
  208. package/src/resources/extensions/gsd/flat-phase-migration.ts +14 -0
  209. package/src/resources/extensions/gsd/gsd-db.ts +85 -33
  210. package/src/resources/extensions/gsd/model-cost-table.ts +14 -3
  211. package/src/resources/extensions/gsd/model-router.ts +10 -5
  212. package/src/resources/extensions/gsd/planning-subagent-registry.ts +18 -4
  213. package/src/resources/extensions/gsd/preferences-models.ts +54 -10
  214. package/src/resources/extensions/gsd/preferences-types.ts +10 -2
  215. package/src/resources/extensions/gsd/preferences-validation.ts +49 -6
  216. package/src/resources/extensions/gsd/preferences.ts +13 -0
  217. package/src/resources/extensions/gsd/templates/PREFERENCES.md +3 -0
  218. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +156 -0
  219. package/src/resources/extensions/gsd/tests/auto-start-index-lock.test.ts +21 -1
  220. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +74 -1
  221. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +147 -0
  222. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +8 -9
  223. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +32 -0
  224. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +13 -0
  225. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +22 -7
  226. package/src/resources/extensions/gsd/tests/model-isolation.test.ts +55 -0
  227. package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
  228. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +24 -0
  229. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +38 -1
  230. package/src/resources/extensions/gsd/tests/preferences.test.ts +71 -4
  231. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +3 -0
  232. package/src/resources/extensions/gsd/tests/service-tier.test.ts +2 -2
  233. package/src/resources/extensions/gsd/tests/thinking-level-resolution.test.ts +1 -1
  234. package/src/resources/extensions/gsd/tests/verification-evidence.test.ts +12 -0
  235. package/src/resources/extensions/gsd/tests/workflow-authority-faults.test.ts +238 -0
  236. package/src/resources/extensions/gsd/tests/workflow-authority-fixture.test.ts +48 -0
  237. package/src/resources/extensions/gsd/tests/workflow-authority-fixture.ts +141 -0
  238. package/src/resources/extensions/gsd/tests/workflow-authority-projection-conflict.test.ts +177 -0
  239. package/src/resources/extensions/gsd/tests/workflow-fault-harness.test.ts +39 -0
  240. package/src/resources/extensions/gsd/tests/workflow-fault-harness.ts +72 -0
  241. package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +2 -2
  242. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +60 -0
  243. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +40 -0
  244. package/src/resources/extensions/gsd/tools/plan-slice.ts +5 -1
  245. package/src/resources/extensions/gsd/verification-evidence.ts +5 -2
  246. package/src/resources/extensions/gsd/worktree-state-projection.ts +21 -24
  247. package/src/resources/extensions/ollama/ollama-chat-provider.ts +2 -2
  248. package/src/resources/extensions/ollama/tests/ollama-chat-provider-think.test.ts +4 -0
  249. package/src/resources/extensions/subagent/index.ts +1 -1
  250. /package/dist/web/standalone/.next/static/{V9MAVyYVPboQUB9KTTAMi → xwUaOqui04jIIFVsIBLiL}/_buildManifest.js +0 -0
  251. /package/dist/web/standalone/.next/static/{V9MAVyYVPboQUB9KTTAMi → xwUaOqui04jIIFVsIBLiL}/_ssgManifest.js +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-process.test.js","sourceRoot":"","sources":["../src/runtime-process.test.ts"],"names":[],"mappings":"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","sourcesContent":["// Project/App: Open GSD\n// File Purpose: Regression coverage for detached cloud runtime process timing and shutdown.\nimport { spawn } from \"node:child_process\";\nimport { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, statSync, utimesSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { test } from \"node:test\";\nimport assert from \"node:assert/strict\";\nimport { CLOUD_RUNTIME_INITIAL_CONNECT_WINDOW_MS } from \"./cloud-runtime.js\";\nimport {\n BACKGROUND_RUNTIME_READY_TIMEOUT_MS,\n acquireRuntimeStartLock,\n backgroundRuntimeStatus,\n commandLineMatchesRuntimeConfig,\n runtimeLogPath,\n runtimeStatePath,\n startBackgroundRuntime,\n stopBackgroundRuntime,\n writeRuntimeState,\n} from \"./runtime-process.js\";\nimport { runtimeArtifactPath } from \"./runtime-artifacts.js\";\nimport { runtimeTelemetryPath } from \"./runtime-telemetry.js\";\n\ntest(\"background startup allows the cloud runtime's full initial reconnect window\", () => {\n assert.ok(BACKGROUND_RUNTIME_READY_TIMEOUT_MS > CLOUD_RUNTIME_INITIAL_CONNECT_WINDOW_MS);\n});\n\ntest(\"runtime artifacts are namespaced by config path while daemon.yaml stays legacy-compatible\", (t) => {\n const root = mkdtempSync(join(tmpdir(), \"gsd-cloud-artifacts-\"));\n t.after(() => rmSync(root, { recursive: true, force: true }));\n const defaultConfig = join(root, \"daemon.yaml\");\n const firstConfig = join(root, \"first.yaml\");\n const secondConfig = join(root, \"second.yaml\");\n\n assert.equal(runtimeStatePath(defaultConfig), join(root, \"cloud-runtime.json\"));\n assert.equal(runtimeLogPath(defaultConfig), join(root, \"cloud-runtime.log\"));\n assert.equal(runtimeTelemetryPath(defaultConfig), join(root, \"cloud-runtime-status.json\"));\n assert.notEqual(runtimeStatePath(firstConfig), runtimeStatePath(secondConfig));\n assert.notEqual(runtimeLogPath(firstConfig), runtimeLogPath(secondConfig));\n assert.notEqual(runtimeTelemetryPath(firstConfig), runtimeTelemetryPath(secondConfig));\n});\n\ntest(\"runtime artifact namespace is stable across monitor implementations\", () => {\n assert.equal(\n runtimeStatePath(\"/work/state/first.yaml\"),\n \"/work/state/cloud-runtime-58cb3ff924131c6e.json\",\n );\n});\n\ntest(\"stop refuses to signal a process whose identity does not match state\", async (t) => {\n const root = mkdtempSync(join(tmpdir(), \"gsd-cloud-reused-pid-\"));\n const configPath = join(root, \"daemon.yaml\");\n const statePath = join(root, \"cloud-runtime.json\");\n const child = spawn(process.execPath, [\"-e\", \"setInterval(()=>{},1000)\"]);\n t.after(() => {\n child.kill(\"SIGKILL\");\n rmSync(root, { recursive: true, force: true });\n });\n\n assert.ok(child.pid);\n writeFileSync(statePath, `${JSON.stringify({\n pid: child.pid,\n projects: [root],\n process_start_identity: \"not-this-process\",\n })}\\n`);\n\n assert.equal(await stopBackgroundRuntime(configPath), false);\n assert.equal(processIsRunning(child.pid), true);\n assert.equal(existsSync(statePath), true);\n});\n\ntest(\"custom configs migrate matching live legacy runtime state\", (t) => {\n const root = mkdtempSync(join(tmpdir(), \"gsd-cloud-legacy-state-\"));\n const configPath = join(root, \"custom.yaml\");\n const legacyStatePath = join(root, \"cloud-runtime.json\");\n const child = spawn(process.execPath, [\n writeLegacyRuntime(root, \"gsd-cloud.js\"),\n \"_run\",\n \"--config\",\n configPath,\n ]);\n t.after(() => {\n child.kill(\"SIGKILL\");\n rmSync(root, { recursive: true, force: true });\n });\n\n assert.ok(child.pid);\n writeFileSync(legacyStatePath, `${JSON.stringify({ pid: child.pid, projects: [root] })}\\n`);\n\n const status = backgroundRuntimeStatus(configPath);\n\n assert.equal(status.running, true);\n assert.equal(status.pid, child.pid);\n assert.equal(existsSync(runtimeStatePath(configPath)), true);\n assert.equal(existsSync(legacyStatePath), false);\n});\n\nfor (const runtimeArgs of [\n [\"connect\"],\n [\"login\", \"--foreground\"],\n]) {\n test(`custom configs migrate legacy ${runtimeArgs.join(\" \")} runtime state`, async (t) => {\n const root = mkdtempSync(join(tmpdir(), \"gsd-cloud-foreground-legacy-\"));\n const configPath = join(root, \"custom runtime.yaml\");\n const legacyStatePath = join(root, \"cloud-runtime.json\");\n const binaryPath = writeLegacyRuntime(root, \"gsd-cloud.js\");\n const child = spawn(process.execPath, [\n binaryPath,\n ...runtimeArgs,\n \"--config\",\n configPath,\n ]);\n t.after(() => {\n child.kill(\"SIGKILL\");\n rmSync(root, { recursive: true, force: true });\n });\n\n assert.ok(child.pid);\n await waitForCondition(() => processIsRunning(child.pid!));\n writeFileSync(legacyStatePath, `${JSON.stringify({ pid: child.pid, projects: [root] })}\\n`);\n\n const status = backgroundRuntimeStatus(configPath);\n\n assert.equal(status.running, true);\n assert.equal(status.pid, child.pid);\n assert.equal(existsSync(runtimeStatePath(configPath)), true);\n assert.equal(existsSync(legacyStatePath), false);\n });\n}\n\ntest(\"legacy runtime state for another config is not migrated or signalled\", async (t) => {\n const root = mkdtempSync(join(tmpdir(), \"gsd-cloud-foreign-legacy-state-\"));\n const requestedConfig = join(root, \"requested.yaml\");\n const actualConfig = join(root, \"actual.yaml\");\n const legacyStatePath = join(root, \"cloud-runtime.json\");\n const child = spawn(process.execPath, [\n \"-e\",\n \"setInterval(()=>{},1000)\",\n \"_run\",\n \"--config\",\n actualConfig,\n ]);\n t.after(() => {\n child.kill(\"SIGKILL\");\n rmSync(root, { recursive: true, force: true });\n });\n\n assert.ok(child.pid);\n writeFileSync(legacyStatePath, `${JSON.stringify({ pid: child.pid, projects: [root] })}\\n`);\n\n assert.equal(await stopBackgroundRuntime(requestedConfig), false);\n assert.equal(processIsRunning(child.pid), true);\n assert.equal(existsSync(legacyStatePath), true);\n});\n\ntest(\"default config preserves shared legacy state owned by a custom config\", async (t) => {\n const root = mkdtempSync(join(tmpdir(), \"gsd-cloud-shared-legacy-state-\"));\n const requestedConfig = join(root, \"daemon.yaml\");\n const actualConfig = join(root, \"custom.yaml\");\n const legacyStatePath = join(root, \"cloud-runtime.json\");\n const binaryPath = writeLegacyRuntime(root, \"gsd-cloud.js\");\n const child = spawn(process.execPath, [binaryPath, \"connect\", \"--config\", actualConfig]);\n t.after(() => {\n child.kill(\"SIGKILL\");\n rmSync(root, { recursive: true, force: true });\n });\n\n assert.ok(child.pid);\n writeFileSync(legacyStatePath, `${JSON.stringify({ pid: child.pid, projects: [root] })}\\n`);\n\n assert.equal(await stopBackgroundRuntime(requestedConfig), false);\n assert.equal(processIsRunning(child.pid), true);\n assert.equal(existsSync(legacyStatePath), true);\n});\n\ntest(\"legacy migration rejects unrelated executables\", async (t) => {\n const root = mkdtempSync(join(tmpdir(), \"gsd-cloud-unrelated-legacy-state-\"));\n const configPath = join(root, \"daemon.yaml\");\n const legacyStatePath = join(root, \"cloud-runtime.json\");\n const binaryPath = writeLegacyRuntime(root, \"other-tool.js\");\n const child = spawn(process.execPath, [binaryPath, \"connect\", \"--config\", configPath]);\n t.after(() => {\n child.kill(\"SIGKILL\");\n rmSync(root, { recursive: true, force: true });\n });\n\n assert.ok(child.pid);\n writeFileSync(legacyStatePath, `${JSON.stringify({ pid: child.pid, projects: [root] })}\\n`);\n\n assert.equal(await stopBackgroundRuntime(configPath), false);\n assert.equal(processIsRunning(child.pid), true);\n assert.equal(existsSync(legacyStatePath), true);\n});\n\ntest(\"legacy migration preserves config paths with spaces before short options\", async (t) => {\n const root = mkdtempSync(join(tmpdir(), \"gsd-cloud-argv-legacy-\"));\n const configPath = join(root, \"custom runtime.yaml\");\n const legacyStatePath = join(root, \"cloud-runtime.json\");\n const binaryPath = writeLegacyRuntime(root, \"gsd-cloud.js\");\n const child = spawn(process.execPath, [\n binaryPath,\n \"connect\",\n \"--config\",\n configPath,\n \"-v\",\n \"--foreground\",\n ]);\n t.after(() => {\n child.kill(\"SIGKILL\");\n rmSync(root, { recursive: true, force: true });\n });\n\n assert.ok(child.pid);\n await waitForCondition(() => processIsRunning(child.pid!));\n writeFileSync(legacyStatePath, `${JSON.stringify({ pid: child.pid, projects: [root] })}\\n`);\n\n const status = backgroundRuntimeStatus(configPath);\n\n assert.equal(status.running, true);\n assert.equal(status.pid, child.pid);\n assert.equal(existsSync(runtimeStatePath(configPath)), true);\n assert.equal(existsSync(legacyStatePath), false);\n});\n\ntest(\"Windows command matching accepts quoted gsd-cloud.js paths\", () => {\n const configPath = \"/work/runtime/daemon.yaml\";\n const command = [\n '\"C:\\\\Program Files\\\\nodejs\\\\node.exe\"',\n '\"C:\\\\Program Files\\\\gsd-cloud\\\\gsd-cloud.js\"',\n \"connect\",\n \"--config\",\n `\"${configPath}\"`,\n ].join(\" \");\n\n assert.equal(commandLineMatchesRuntimeConfig(command, configPath, \"win32\"), true);\n});\n\ntest(\"command matching rejects gsd-cloud decoys before another launcher\", () => {\n const configPath = \"/work/runtime/daemon.yaml\";\n\n assert.equal(commandLineMatchesRuntimeConfig(\n `other-tool /tmp/gsd-cloud.js connect --config ${configPath}`,\n configPath,\n \"linux\",\n ), false);\n assert.equal(commandLineMatchesRuntimeConfig(\n `\"C:\\\\Tools\\\\other-tool.exe\" \"C:\\\\tmp\\\\gsd-cloud.js\" connect --config \"${configPath}\"`,\n configPath,\n \"win32\",\n ), false);\n assert.equal(commandLineMatchesRuntimeConfig(\n `/usr/bin/node /tmp/gsd-cloud.js --config ${configPath} connect --config /other.yaml`,\n configPath,\n \"linux\",\n ), false);\n assert.equal(commandLineMatchesRuntimeConfig(\n `/usr/bin/other /tmp/gsd-cloud.js connect --config ${configPath}`,\n configPath,\n \"darwin\",\n ), false);\n assert.equal(commandLineMatchesRuntimeConfig(\n `/usr/bin/node /usr/bin/other /tmp/gsd-cloud.js connect --config ${configPath}`,\n configPath,\n \"darwin\",\n ), false);\n});\n\ntest(\"command matching accepts a directly launched bare gsd-cloud executable\", () => {\n const configPath = \"/work/runtime/daemon.yaml\";\n\n assert.equal(commandLineMatchesRuntimeConfig(\n `gsd-cloud connect --config ${configPath}`,\n configPath,\n \"darwin\",\n ), true);\n assert.equal(commandLineMatchesRuntimeConfig(\n `\"/Applications/GSD Cloud/gsd-cloud\" connect --config ${configPath}`,\n configPath,\n \"darwin\",\n ), true);\n});\n\ntest(\"start lock atomically records PID and process identity\", { timeout: 5_000 }, async (t) => {\n const root = mkdtempSync(join(tmpdir(), \"gsd-cloud-lock-owner-\"));\n const configPath = join(root, \"daemon.yaml\");\n const binaryPath = writeReadyRuntime(root, 500);\n const lockPath = runtimeArtifactPath(configPath, \"start.lock\");\n t.after(async () => {\n await stopBackgroundRuntime(configPath).catch(() => undefined);\n rmSync(root, { recursive: true, force: true });\n });\n\n const starting = startBackgroundRuntime({ binaryPath, configPath, projectDirs: [root] });\n await waitForCondition(() => existsSync(lockPath));\n\n const owner = JSON.parse(readFileSync(lockPath, \"utf8\")) as {\n pid?: number;\n process_start_identity?: string;\n };\n assert.equal(owner.pid, process.pid);\n assert.equal(typeof owner.process_start_identity, \"string\");\n assert.ok(owner.process_start_identity);\n\n await starting;\n});\n\ntest(\"start lock recovers immediately when its PID identity is stale\", { timeout: 5_000 }, async (t) => {\n const root = mkdtempSync(join(tmpdir(), \"gsd-cloud-stale-lock-\"));\n const configPath = join(root, \"daemon.yaml\");\n const binaryPath = writeReadyRuntime(root);\n const lockPath = runtimeArtifactPath(configPath, \"start.lock\");\n writeFileSync(lockPath, `${JSON.stringify({\n pid: process.pid,\n process_start_identity: \"reused-process\",\n })}\\n`);\n t.after(async () => {\n await stopBackgroundRuntime(configPath).catch(() => undefined);\n rmSync(root, { recursive: true, force: true });\n });\n\n const starting = startBackgroundRuntime({ binaryPath, configPath, projectDirs: [root] });\n await new Promise<void>((resolveImmediate) => setImmediate(resolveImmediate));\n const owner = JSON.parse(readFileSync(lockPath, \"utf8\")) as {\n process_start_identity?: string;\n };\n\n assert.notEqual(owner.process_start_identity, \"reused-process\");\n await starting;\n});\n\ntest(\"start lock recovery never removes a replacement owner\", { timeout: 5_000 }, async (t) => {\n const root = mkdtempSync(join(tmpdir(), \"gsd-cloud-replaced-lock-\"));\n const ownerConfigPath = join(root, \"owner.yaml\");\n const configPath = join(root, \"daemon.yaml\");\n const ownerLockPath = runtimeArtifactPath(ownerConfigPath, \"start.lock\");\n const lockPath = runtimeArtifactPath(configPath, \"start.lock\");\n const releaseOwner = await acquireRuntimeStartLock(ownerConfigPath);\n const replacementOwner = readFileSync(ownerLockPath, \"utf8\");\n releaseOwner();\n writeFileSync(lockPath, \"stale\");\n const old = new Date(0);\n utimesSync(lockPath, old, old);\n let release: (() => void) | undefined;\n t.after(async () => {\n rmSync(lockPath, { force: true });\n release ??= await acquiring.catch(() => undefined);\n release?.();\n rmSync(root, { recursive: true, force: true });\n });\n\n let replacementInstalled!: () => void;\n let replacementInode: bigint | undefined;\n const installed = new Promise<void>((resolve) => {\n replacementInstalled = resolve;\n });\n const acquiring = acquireRuntimeStartLock(configPath, () => {\n rmSync(lockPath);\n writeFileSync(lockPath, replacementOwner);\n replacementInode = statSync(lockPath, { bigint: true }).ino;\n replacementInstalled();\n });\n\n await installed;\n assert.equal(readFileSync(lockPath, \"utf8\"), replacementOwner);\n assert.equal(statSync(lockPath, { bigint: true }).ino, replacementInode);\n rmSync(lockPath);\n release = await acquiring;\n release();\n});\n\ntest(\"start lock recovery ignores an abandoned recovery claim\", { timeout: 5_000 }, async (t) => {\n const root = mkdtempSync(join(tmpdir(), \"gsd-cloud-abandoned-recovery-\"));\n const configPath = join(root, \"daemon.yaml\");\n const lockPath = runtimeArtifactPath(configPath, \"start.lock\");\n const recoveryPath = `${lockPath}.recovery`;\n writeFileSync(lockPath, \"stale\");\n writeFileSync(recoveryPath, \"abandoned\");\n const old = new Date(0);\n utimesSync(lockPath, old, old);\n utimesSync(recoveryPath, old, old);\n let release: (() => void) | undefined;\n const acquiring = acquireRuntimeStartLock(configPath);\n t.after(async () => {\n rmSync(lockPath, { force: true });\n rmSync(recoveryPath, { force: true });\n release ??= await acquiring.catch(() => undefined);\n release?.();\n rmSync(root, { recursive: true, force: true });\n });\n\n release = await Promise.race([\n acquiring,\n new Promise<never>((_resolve, reject) => {\n setTimeout(() => reject(new Error(\"abandoned recovery claim blocked start\")), 500);\n }),\n ]);\n release();\n\n assert.equal(existsSync(lockPath), false);\n assert.equal(readFileSync(recoveryPath, \"utf8\"), \"abandoned\");\n});\n\ntest(\"start lock does not reclaim a live legacy owner by age\", { timeout: 5_000 }, async (t) => {\n const root = mkdtempSync(join(tmpdir(), \"gsd-cloud-live-legacy-lock-\"));\n const configPath = join(root, \"daemon.yaml\");\n const binaryPath = writeReadyRuntime(root);\n const lockPath = runtimeArtifactPath(configPath, \"start.lock\");\n writeFileSync(lockPath, `${process.pid}\\n`);\n t.after(async () => {\n await stopBackgroundRuntime(configPath).catch(() => undefined);\n rmSync(root, { recursive: true, force: true });\n });\n\n const starting = startBackgroundRuntime({ binaryPath, configPath, projectDirs: [root] });\n await new Promise((resolveDelay) => setTimeout(resolveDelay, 1_200));\n\n assert.equal(readFileSync(lockPath, \"utf8\"), `${process.pid}\\n`);\n rmSync(lockPath);\n await starting;\n});\n\ntest(\"start lock preserves an aged legacy owner running the same config\", { timeout: 5_000 }, async (t) => {\n const root = mkdtempSync(join(tmpdir(), \"gsd-cloud-live-runtime-lock-\"));\n const configPath = join(root, \"daemon.yaml\");\n const binaryPath = writeReadyRuntime(root);\n const legacyBinaryPath = writeLegacyRuntime(root, \"gsd-cloud\");\n const lockPath = runtimeArtifactPath(configPath, \"start.lock\");\n const owner = spawn(process.execPath, [legacyBinaryPath, \"connect\", \"--config\", configPath]);\n t.after(async () => {\n owner.kill(\"SIGKILL\");\n await stopBackgroundRuntime(configPath).catch(() => undefined);\n rmSync(root, { recursive: true, force: true });\n });\n\n assert.ok(owner.pid);\n await waitForCondition(() => processIsRunning(owner.pid!));\n writeFileSync(lockPath, `${owner.pid}\\n`);\n const old = new Date(0);\n utimesSync(lockPath, old, old);\n\n const starting = startBackgroundRuntime({ binaryPath, configPath, projectDirs: [root] });\n await new Promise((resolveDelay) => setTimeout(resolveDelay, 200));\n\n assert.equal(readFileSync(lockPath, \"utf8\"), `${owner.pid}\\n`);\n rmSync(lockPath);\n await starting;\n});\n\nfor (const staleOwner of [\"\", \"not-json\", `${process.pid}\\n`]) {\n test(`start lock recovers stale legacy owner ${JSON.stringify(staleOwner)}`, { timeout: 2_000 }, async (t) => {\n const root = mkdtempSync(join(tmpdir(), \"gsd-cloud-stale-legacy-lock-\"));\n const configPath = join(root, \"daemon.yaml\");\n const lockPath = runtimeArtifactPath(configPath, \"start.lock\");\n writeFileSync(lockPath, staleOwner);\n const old = new Date(0);\n utimesSync(lockPath, old, old);\n let release: (() => void) | undefined;\n const acquiring = acquireRuntimeStartLock(configPath);\n t.after(async () => {\n if (!release) {\n rmSync(lockPath, { force: true });\n release = await acquiring.catch(() => undefined);\n }\n release?.();\n rmSync(root, { recursive: true, force: true });\n });\n\n release = await Promise.race([\n acquiring,\n new Promise<never>((_resolve, reject) => {\n setTimeout(() => reject(new Error(\"stale start lock was not recovered promptly\")), 500);\n }),\n ]);\n release();\n\n assert.equal(existsSync(lockPath), false);\n });\n}\n\ntest(\"stop waits for the detached runtime to exit before removing its state\", { timeout: 5_000 }, async (t) => {\n const root = mkdtempSync(join(tmpdir(), \"gsd-cloud-stop-\"));\n const configPath = join(root, \"daemon.yaml\");\n const statePath = join(root, \"cloud-runtime.json\");\n const binaryPath = join(root, \"gsd-cloud.js\");\n writeFileSync(binaryPath, [\n \"process.on('SIGTERM',()=>setTimeout(()=>process.exit(0),200));\",\n \"process.send?.('ready');\",\n \"setInterval(()=>{},1000);\",\n ].join(\"\\n\"));\n const child = spawn(process.execPath, [\n binaryPath,\n \"_run\",\n \"--config\",\n configPath,\n ], { stdio: [\"ignore\", \"ignore\", \"ignore\", \"ipc\"] });\n t.after(() => {\n child.kill(\"SIGKILL\");\n rmSync(root, { recursive: true, force: true });\n });\n\n await new Promise<void>((resolve, reject) => {\n child.once(\"error\", reject);\n child.once(\"message\", () => resolve());\n });\n assert.ok(child.pid);\n writeRuntimeState(configPath, child.pid, [root]);\n\n const startedAt = Date.now();\n assert.equal(await stopBackgroundRuntime(configPath), true);\n\n assert.ok(Date.now() - startedAt >= 150);\n assert.equal(existsSync(statePath), false);\n});\n\ntest(\"background startup terminates its child when state registration fails\", { timeout: 5_000 }, async (t) => {\n const root = mkdtempSync(join(tmpdir(), \"gsd-cloud-registration-failure-\"));\n const configPath = join(root, \"daemon.yaml\");\n const pidPath = join(root, \"runtime-pid.txt\");\n const binaryPath = join(root, \"runtime.mjs\");\n writeFileSync(binaryPath, [\n 'import { writeFileSync } from \"node:fs\";',\n `writeFileSync(${JSON.stringify(pidPath)}, String(process.pid));`,\n 'process.on(\"SIGTERM\", () => process.exit(0));',\n 'setInterval(() => undefined, 1_000);',\n ].join(\"\\n\"));\n mkdirSync(runtimeStatePath(configPath));\n t.after(() => {\n if (existsSync(pidPath)) {\n const pid = Number.parseInt(readFileSync(pidPath, \"utf8\"), 10);\n if (processIsRunning(pid)) process.kill(pid, \"SIGKILL\");\n }\n rmSync(root, { recursive: true, force: true });\n });\n\n await assert.rejects(\n startBackgroundRuntime({ binaryPath, configPath, projectDirs: [root] }),\n );\n await new Promise((resolve) => setTimeout(resolve, 250));\n if (existsSync(pidPath)) {\n const pid = Number.parseInt(readFileSync(pidPath, \"utf8\"), 10);\n await waitForCondition(() => !processIsRunning(pid));\n assert.equal(processIsRunning(pid), false);\n }\n});\n\ntest(\"background startup force-stops its child when identity registration fails\", { timeout: 8_000 }, async (t) => {\n const root = mkdtempSync(join(tmpdir(), \"gsd-cloud-registration-force-stop-\"));\n const configPath = join(root, \"daemon.yaml\");\n const pidPath = join(root, \"runtime-pid.txt\");\n const binaryPath = join(root, \"runtime.mjs\");\n writeFileSync(binaryPath, [\n 'import { writeFileSync } from \"node:fs\";',\n 'process.on(\"SIGTERM\", () => undefined);',\n `writeFileSync(${JSON.stringify(pidPath)}, String(process.pid));`,\n 'setInterval(() => undefined, 1_000);',\n ].join(\"\\n\"));\n mkdirSync(runtimeStatePath(configPath));\n t.after(() => {\n if (existsSync(pidPath)) {\n const pid = Number.parseInt(readFileSync(pidPath, \"utf8\"), 10);\n if (processIsRunning(pid)) process.kill(pid, \"SIGKILL\");\n }\n rmSync(root, { recursive: true, force: true });\n });\n\n await assert.rejects(\n startBackgroundRuntime({\n binaryPath,\n configPath,\n projectDirs: [root],\n processIdentityReader: () => {\n const deadline = Date.now() + 1_000;\n while (!existsSync(pidPath) && Date.now() < deadline) {\n Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 10);\n }\n return null;\n },\n }),\n );\n if (existsSync(pidPath)) {\n const pid = Number.parseInt(readFileSync(pidPath, \"utf8\"), 10);\n await waitForCondition(() => !processIsRunning(pid), 7_000);\n assert.equal(processIsRunning(pid), false);\n }\n});\n\ntest(\"concurrent starts serialize and leave only the newest runtime running\", { timeout: 15_000 }, async (t) => {\n const root = mkdtempSync(join(tmpdir(), \"gsd-cloud-concurrent-start-\"));\n const configPath = join(root, \"daemon.yaml\");\n const binaryPath = writeReadyRuntime(root);\n t.after(async () => {\n await stopBackgroundRuntime(configPath).catch(() => undefined);\n rmSync(root, { recursive: true, force: true });\n });\n\n const [first, second] = await Promise.all([\n startBackgroundRuntime({ binaryPath, configPath, projectDirs: [root] }),\n startBackgroundRuntime({ binaryPath, configPath, projectDirs: [root] }),\n ]);\n\n assert.notEqual(first.pid, second.pid);\n assert.ok(first.pid);\n assert.equal(processIsRunning(first.pid), false);\n assert.equal(backgroundRuntimeStatus(configPath).pid, second.pid);\n});\n\ntest(\"verbose background starts forward the flag to the runtime child\", { timeout: 10_000 }, async (t) => {\n const root = mkdtempSync(join(tmpdir(), \"gsd-cloud-verbose-start-\"));\n const configPath = join(root, \"daemon.yaml\");\n const binaryPath = writeReadyRuntime(root);\n t.after(async () => {\n await stopBackgroundRuntime(configPath).catch(() => undefined);\n rmSync(root, { recursive: true, force: true });\n });\n\n await startBackgroundRuntime({\n binaryPath,\n configPath,\n projectDirs: [root],\n verbose: true,\n });\n\n const args = JSON.parse(readFileSync(join(root, \"runtime-args.json\"), \"utf8\")) as string[];\n assert.ok(args.includes(\"--verbose\"));\n});\n\nfunction writeReadyRuntime(root: string, readyDelayMs = 0): string {\n const binaryPath = join(root, \"gsd-cloud.js\");\n writeFileSync(binaryPath, [\n 'import { writeFileSync } from \"node:fs\";',\n `writeFileSync(${JSON.stringify(join(root, \"runtime-args.json\"))}, JSON.stringify(process.argv.slice(2)));`,\n 'process.on(\"SIGTERM\", () => process.exit(0));',\n `setTimeout(() => process.send?.({ type: \"ready\" }), ${readyDelayMs});`,\n 'setInterval(() => undefined, 1_000);',\n ].join(\"\\n\"));\n return binaryPath;\n}\n\nfunction writeLegacyRuntime(root: string, name: string): string {\n const binaryPath = join(root, name);\n writeFileSync(binaryPath, [\n \"process.on('SIGTERM', () => process.exit(0));\",\n \"setInterval(() => undefined, 1_000);\",\n ].join(\"\\n\"));\n return binaryPath;\n}\n\nfunction processIsRunning(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function waitForCondition(condition: () => boolean, timeoutMs = 2_000): Promise<void> {\n const deadline = Date.now() + timeoutMs;\n while (!condition()) {\n if (Date.now() >= deadline) throw new Error(\"timed out waiting for test condition\");\n await new Promise((resolve) => setTimeout(resolve, 25));\n }\n}\n"]}
@@ -0,0 +1,117 @@
1
+ import type { AdvertisedProject } from "./executors/executor.js";
2
+ export type RuntimeConnectionState = "connecting" | "connected" | "reconnecting" | "error" | "stopped";
3
+ export type RuntimeProjectState = "idle" | "active" | "error";
4
+ export type RuntimeRequestOutcome = "success" | "error" | "cancelled";
5
+ export interface RuntimeProjectTelemetry {
6
+ alias: string;
7
+ path: string;
8
+ repo_identity: string;
9
+ remote_label?: string;
10
+ state: RuntimeProjectState;
11
+ active_requests: number;
12
+ active_tools: string[];
13
+ request_count: number;
14
+ error_count: number;
15
+ received_bytes: number;
16
+ sent_bytes: number;
17
+ last_tool: string | null;
18
+ last_activity_at: string | null;
19
+ }
20
+ export interface RuntimeActivityTelemetry {
21
+ request_id: string;
22
+ project_alias?: string;
23
+ project_path?: string;
24
+ tool_name: string;
25
+ outcome: RuntimeRequestOutcome;
26
+ duration_ms: number;
27
+ at: string;
28
+ error?: string;
29
+ }
30
+ export interface RuntimeTelemetryStatus {
31
+ version: 1;
32
+ pid: number;
33
+ state: RuntimeConnectionState;
34
+ gateway_url: string;
35
+ runtime_id?: string;
36
+ runtime_name?: string;
37
+ started_at: string;
38
+ connected_at: string | null;
39
+ updated_at: string;
40
+ last_error: string | null;
41
+ connection_attempts: number;
42
+ reconnects: number;
43
+ received_messages: number;
44
+ sent_messages: number;
45
+ received_bytes: number;
46
+ sent_bytes: number;
47
+ active_requests: number;
48
+ projects: RuntimeProjectTelemetry[];
49
+ recent_activity: RuntimeActivityTelemetry[];
50
+ }
51
+ export interface RuntimeRequestStarted {
52
+ requestId: string;
53
+ projectAlias?: string;
54
+ projectPath?: string;
55
+ toolName: string;
56
+ receivedBytes: number;
57
+ }
58
+ export interface RuntimeRequestFinished {
59
+ requestId: string;
60
+ projectAlias?: string;
61
+ projectPath?: string;
62
+ toolName: string;
63
+ durationMs: number;
64
+ outcome: RuntimeRequestOutcome;
65
+ error?: string;
66
+ }
67
+ export interface RuntimeTelemetryReporter {
68
+ connecting(): void;
69
+ connected(): void;
70
+ disconnected(error?: string): void;
71
+ socketError(error: string): void;
72
+ received(text: string): void;
73
+ sent(text: string, projectPath?: string): void;
74
+ projectsAdvertised(projects: AdvertisedProject[]): void;
75
+ requestStarted(request: RuntimeRequestStarted): void;
76
+ requestFinished(request: RuntimeRequestFinished): void;
77
+ stopped(): void;
78
+ failed?(): void;
79
+ flush?(): Promise<void>;
80
+ }
81
+ interface RuntimeTelemetryMetadata {
82
+ gatewayUrl: string;
83
+ runtimeId?: string;
84
+ runtimeName?: string;
85
+ }
86
+ export declare const noopRuntimeTelemetry: RuntimeTelemetryReporter;
87
+ export declare class RuntimeTelemetryStore implements RuntimeTelemetryReporter {
88
+ private readonly path;
89
+ private readonly activeRequests;
90
+ private status;
91
+ private livenessTimer;
92
+ private persistTimer;
93
+ private persistPromise;
94
+ constructor(configPath: string, metadata: RuntimeTelemetryMetadata);
95
+ connecting(): void;
96
+ connected(): void;
97
+ disconnected(error?: string): void;
98
+ socketError(error: string): void;
99
+ received(text: string): void;
100
+ sent(text: string, projectPath?: string): void;
101
+ projectsAdvertised(projects: AdvertisedProject[]): void;
102
+ requestStarted(request: RuntimeRequestStarted): void;
103
+ requestFinished(request: RuntimeRequestFinished): void;
104
+ stopped(): void;
105
+ failed(): void;
106
+ flush(): Promise<void>;
107
+ private findProject;
108
+ private activeToolsForProject;
109
+ private persist;
110
+ private enqueuePersist;
111
+ private writeSnapshot;
112
+ }
113
+ export declare function readRuntimeTelemetry(configPath: string): RuntimeTelemetryStatus | null;
114
+ export declare function runtimeTelemetryPath(configPath: string): string;
115
+ export declare function clearRuntimeTelemetry(configPath: string): void;
116
+ export {};
117
+ //# sourceMappingURL=runtime-telemetry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-telemetry.d.ts","sourceRoot":"","sources":["../src/runtime-telemetry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,291 @@
1
+ // Project/App: Open GSD
2
+ // File Purpose: Persist token-free cloud runtime status and traffic counters for local monitors.
3
+ import { readFileSync, unlinkSync } from "node:fs";
4
+ import { chmod, mkdir, rename, rm, writeFile } from "node:fs/promises";
5
+ import { dirname } from "node:path";
6
+ import { runtimeArtifactPath } from "./runtime-artifacts.js";
7
+ export const noopRuntimeTelemetry = {
8
+ connecting() { },
9
+ connected() { },
10
+ disconnected() { },
11
+ socketError() { },
12
+ received() { },
13
+ sent() { },
14
+ projectsAdvertised() { },
15
+ requestStarted() { },
16
+ requestFinished() { },
17
+ stopped() { },
18
+ failed() { },
19
+ };
20
+ export class RuntimeTelemetryStore {
21
+ path;
22
+ activeRequests = new Map();
23
+ status;
24
+ livenessTimer;
25
+ persistTimer;
26
+ persistPromise = Promise.resolve();
27
+ constructor(configPath, metadata) {
28
+ const now = new Date().toISOString();
29
+ this.path = runtimeTelemetryPath(configPath);
30
+ this.status = {
31
+ version: 1,
32
+ pid: process.pid,
33
+ state: "connecting",
34
+ gateway_url: credentialFreeGatewayLabel(metadata.gatewayUrl),
35
+ ...(metadata.runtimeId ? { runtime_id: metadata.runtimeId } : {}),
36
+ ...(metadata.runtimeName ? { runtime_name: metadata.runtimeName } : {}),
37
+ started_at: now,
38
+ connected_at: null,
39
+ updated_at: now,
40
+ last_error: null,
41
+ connection_attempts: 0,
42
+ reconnects: 0,
43
+ received_messages: 0,
44
+ sent_messages: 0,
45
+ received_bytes: 0,
46
+ sent_bytes: 0,
47
+ active_requests: 0,
48
+ projects: [],
49
+ recent_activity: [],
50
+ };
51
+ }
52
+ connecting() {
53
+ if (!this.livenessTimer) {
54
+ this.livenessTimer = setInterval(() => this.persist(), 1_000);
55
+ this.livenessTimer.unref();
56
+ }
57
+ this.status.state = this.status.connection_attempts === 0 ? "connecting" : "reconnecting";
58
+ this.status.connection_attempts += 1;
59
+ this.persist();
60
+ }
61
+ connected() {
62
+ this.status.state = "connected";
63
+ this.status.connected_at = new Date().toISOString();
64
+ this.status.last_error = null;
65
+ this.persist();
66
+ }
67
+ disconnected(error) {
68
+ if (this.status.connected_at && this.status.state !== "reconnecting") {
69
+ this.status.reconnects += 1;
70
+ }
71
+ this.status.state = "reconnecting";
72
+ this.status.last_error = error ?? this.status.last_error ?? "connection closed";
73
+ this.persist();
74
+ }
75
+ socketError(error) {
76
+ this.status.state = "error";
77
+ this.status.last_error = error;
78
+ this.persist();
79
+ }
80
+ received(text) {
81
+ this.status.received_messages += 1;
82
+ this.status.received_bytes += Buffer.byteLength(text);
83
+ this.persist();
84
+ }
85
+ sent(text, projectPath) {
86
+ this.status.sent_messages += 1;
87
+ const bytes = Buffer.byteLength(text);
88
+ this.status.sent_bytes += bytes;
89
+ const project = projectPath ? this.findProject(projectPath) : undefined;
90
+ if (project)
91
+ project.sent_bytes += bytes;
92
+ this.persist();
93
+ }
94
+ projectsAdvertised(projects) {
95
+ const existingProjects = new Map(this.status.projects.map((project) => [project.path, project]));
96
+ this.status.projects = projects.map((project) => {
97
+ const existing = existingProjects.get(project.path);
98
+ const remoteLabel = project.remoteLabel
99
+ ? credentialFreeRemoteLabel(project.remoteLabel)
100
+ : undefined;
101
+ return {
102
+ alias: project.alias,
103
+ path: project.path,
104
+ repo_identity: project.repoIdentity,
105
+ ...(remoteLabel ? { remote_label: remoteLabel } : {}),
106
+ state: existing?.state ?? "idle",
107
+ active_requests: existing?.active_requests ?? 0,
108
+ active_tools: existing?.active_tools ?? [],
109
+ request_count: existing?.request_count ?? 0,
110
+ error_count: existing?.error_count ?? 0,
111
+ received_bytes: existing?.received_bytes ?? 0,
112
+ sent_bytes: existing?.sent_bytes ?? 0,
113
+ last_tool: existing?.last_tool ?? null,
114
+ last_activity_at: existing?.last_activity_at ?? null,
115
+ };
116
+ });
117
+ this.persist();
118
+ }
119
+ requestStarted(request) {
120
+ this.status.active_requests += 1;
121
+ const project = this.findProject(request.projectPath, request.projectAlias);
122
+ if (project) {
123
+ this.activeRequests.set(request.requestId, {
124
+ projectPath: project.path,
125
+ toolName: request.toolName,
126
+ });
127
+ project.state = "active";
128
+ project.active_requests += 1;
129
+ project.active_tools = this.activeToolsForProject(project.path);
130
+ project.received_bytes += request.receivedBytes;
131
+ project.last_tool = request.toolName;
132
+ project.last_activity_at = new Date().toISOString();
133
+ }
134
+ this.persist();
135
+ }
136
+ requestFinished(request) {
137
+ this.status.active_requests = Math.max(0, this.status.active_requests - 1);
138
+ const now = new Date().toISOString();
139
+ const project = this.findProject(request.projectPath, request.projectAlias);
140
+ this.activeRequests.delete(request.requestId);
141
+ if (project) {
142
+ project.active_requests = Math.max(0, project.active_requests - 1);
143
+ project.active_tools = this.activeToolsForProject(project.path);
144
+ project.request_count += 1;
145
+ project.last_tool = request.toolName;
146
+ project.last_activity_at = now;
147
+ if (request.outcome === "error")
148
+ project.error_count += 1;
149
+ if (request.outcome === "error") {
150
+ project.state = "error";
151
+ }
152
+ else if (project.active_requests > 0) {
153
+ project.state = "active";
154
+ }
155
+ else {
156
+ project.state = "idle";
157
+ }
158
+ }
159
+ this.status.recent_activity.push({
160
+ request_id: request.requestId,
161
+ ...(request.projectAlias ? { project_alias: request.projectAlias } : {}),
162
+ ...(request.projectPath ? { project_path: request.projectPath } : {}),
163
+ tool_name: request.toolName,
164
+ outcome: request.outcome,
165
+ duration_ms: request.durationMs,
166
+ at: now,
167
+ ...(request.error ? { error: request.error } : {}),
168
+ });
169
+ if (this.status.recent_activity.length > 50) {
170
+ this.status.recent_activity.splice(0, this.status.recent_activity.length - 50);
171
+ }
172
+ this.persist();
173
+ }
174
+ stopped() {
175
+ if (this.livenessTimer)
176
+ clearInterval(this.livenessTimer);
177
+ this.livenessTimer = undefined;
178
+ this.status.state = "stopped";
179
+ this.status.active_requests = 0;
180
+ this.activeRequests.clear();
181
+ for (const project of this.status.projects) {
182
+ project.active_requests = 0;
183
+ project.active_tools = [];
184
+ project.state = "idle";
185
+ }
186
+ void this.flush();
187
+ }
188
+ failed() {
189
+ if (this.livenessTimer)
190
+ clearInterval(this.livenessTimer);
191
+ this.livenessTimer = undefined;
192
+ }
193
+ async flush() {
194
+ if (this.persistTimer) {
195
+ clearTimeout(this.persistTimer);
196
+ this.persistTimer = undefined;
197
+ }
198
+ this.enqueuePersist();
199
+ await this.persistPromise;
200
+ }
201
+ findProject(path, alias) {
202
+ if (path)
203
+ return this.status.projects.find((project) => project.path === path);
204
+ if (alias)
205
+ return this.status.projects.find((project) => project.alias === alias);
206
+ if (this.status.projects.length === 1)
207
+ return this.status.projects[0];
208
+ return undefined;
209
+ }
210
+ activeToolsForProject(projectPath) {
211
+ return [...this.activeRequests.values()]
212
+ .filter((request) => request.projectPath === projectPath)
213
+ .map((request) => request.toolName);
214
+ }
215
+ persist() {
216
+ this.status.updated_at = new Date().toISOString();
217
+ if (this.persistTimer)
218
+ return;
219
+ this.persistTimer = setTimeout(() => {
220
+ this.persistTimer = undefined;
221
+ this.enqueuePersist();
222
+ }, 25);
223
+ this.persistTimer.unref();
224
+ }
225
+ enqueuePersist() {
226
+ this.status.updated_at = new Date().toISOString();
227
+ const snapshot = `${JSON.stringify(this.status, null, 2)}\n`;
228
+ this.persistPromise = this.persistPromise.then(() => this.writeSnapshot(snapshot));
229
+ }
230
+ async writeSnapshot(snapshot) {
231
+ const temporaryPath = `${this.path}.${process.pid}.tmp`;
232
+ try {
233
+ await mkdir(dirname(this.path), { recursive: true });
234
+ await writeFile(temporaryPath, snapshot, { encoding: "utf8", mode: 0o600 });
235
+ await chmod(temporaryPath, 0o600);
236
+ await rename(temporaryPath, this.path);
237
+ }
238
+ catch {
239
+ await rm(temporaryPath, { force: true }).catch(() => undefined);
240
+ }
241
+ }
242
+ }
243
+ export function readRuntimeTelemetry(configPath) {
244
+ try {
245
+ const value = JSON.parse(readFileSync(runtimeTelemetryPath(configPath), "utf8"));
246
+ return value.version === 1 ? value : null;
247
+ }
248
+ catch {
249
+ return null;
250
+ }
251
+ }
252
+ export function runtimeTelemetryPath(configPath) {
253
+ return runtimeArtifactPath(configPath, "status");
254
+ }
255
+ export function clearRuntimeTelemetry(configPath) {
256
+ try {
257
+ unlinkSync(runtimeTelemetryPath(configPath));
258
+ }
259
+ catch (error) {
260
+ if (error.code !== "ENOENT")
261
+ throw error;
262
+ }
263
+ }
264
+ function credentialFreeRemoteLabel(remoteLabel) {
265
+ try {
266
+ const url = new URL(remoteLabel);
267
+ url.username = "";
268
+ url.password = "";
269
+ url.search = "";
270
+ url.hash = "";
271
+ return url.toString();
272
+ }
273
+ catch {
274
+ return remoteLabel
275
+ .replace(/^[^/@]+@([^:]+):/, "$1:")
276
+ .replace(/[?#].*$/, "");
277
+ }
278
+ }
279
+ function credentialFreeGatewayLabel(gatewayUrl) {
280
+ try {
281
+ const url = new URL(gatewayUrl);
282
+ if (url.protocol !== "http:" && url.protocol !== "https:")
283
+ return "invalid gateway";
284
+ const path = url.pathname === "/" ? "" : url.pathname;
285
+ return `${url.protocol}//${url.host}${path}`;
286
+ }
287
+ catch {
288
+ return "invalid gateway";
289
+ }
290
+ }
291
+ //# sourceMappingURL=runtime-telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-telemetry.js","sourceRoot":"","sources":["../src/runtime-telemetry.ts"],"names":[],"mappings":"AAAA,wBAAwB;AACxB,iGAAiG;AACjG,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AA8F7D,MAAM,CAAC,MAAM,oBAAoB,GAA6B;IAC5D,UAAU,KAAU,CAAC;IACrB,SAAS,KAAU,CAAC;IACpB,YAAY,KAAU,CAAC;IACvB,WAAW,KAAU,CAAC;IACtB,QAAQ,KAAU,CAAC;IACnB,IAAI,KAAU,CAAC;IACf,kBAAkB,KAAU,CAAC;IAC7B,cAAc,KAAU,CAAC;IACzB,eAAe,KAAU,CAAC;IAC1B,OAAO,KAAU,CAAC;IAClB,MAAM,KAAU,CAAC;CAClB,CAAC;AAEF,MAAM,OAAO,qBAAqB;IACf,IAAI,CAAS;IACb,cAAc,GAAG,IAAI,GAAG,EAAqD,CAAC;IACvF,MAAM,CAAyB;IAC/B,aAAa,CAA6C;IAC1D,YAAY,CAA4C;IACxD,cAAc,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAE3C,YAAY,UAAkB,EAAE,QAAkC;QAChE,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,GAAG;YACZ,OAAO,EAAE,CAAC;YACV,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,KAAK,EAAE,YAAY;YACnB,WAAW,EAAE,0BAA0B,CAAC,QAAQ,CAAC,UAAU,CAAC;YAC5D,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjE,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvE,UAAU,EAAE,GAAG;YACf,YAAY,EAAE,IAAI;YAClB,UAAU,EAAE,GAAG;YACf,UAAU,EAAE,IAAI;YAChB,mBAAmB,EAAE,CAAC;YACtB,UAAU,EAAE,CAAC;YACb,iBAAiB,EAAE,CAAC;YACpB,aAAa,EAAE,CAAC;YAChB,cAAc,EAAE,CAAC;YACjB,UAAU,EAAE,CAAC;YACb,eAAe,EAAE,CAAC;YAClB,QAAQ,EAAE,EAAE;YACZ,eAAe,EAAE,EAAE;SACpB,CAAC;IACJ,CAAC;IAED,UAAU;QACR,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,IAAI,CAAC,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;YAC9D,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;QAC7B,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,mBAAmB,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,cAAc,CAAC;QAC1F,IAAI,CAAC,MAAM,CAAC,mBAAmB,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAED,SAAS;QACP,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,WAAW,CAAC;QAChC,IAAI,CAAC,MAAM,CAAC,YAAY,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACpD,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;QAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAED,YAAY,CAAC,KAAc;QACzB,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,cAAc,EAAE,CAAC;YACrE,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,CAAC,CAAC;QAC9B,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,cAAc,CAAC;QACnC,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,mBAAmB,CAAC;QAChF,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAED,WAAW,CAAC,KAAa;QACvB,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC;QAC5B,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,KAAK,CAAC;QAC/B,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAED,QAAQ,CAAC,IAAY;QACnB,IAAI,CAAC,MAAM,CAAC,iBAAiB,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtD,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAED,IAAI,CAAC,IAAY,EAAE,WAAoB;QACrC,IAAI,CAAC,MAAM,CAAC,aAAa,IAAI,CAAC,CAAC;QAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,KAAK,CAAC;QAChC,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACxE,IAAI,OAAO;YAAE,OAAO,CAAC,UAAU,IAAI,KAAK,CAAC;QACzC,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAED,kBAAkB,CAAC,QAA6B;QAC9C,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAC9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAC/D,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;YAC9C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACpD,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW;gBACrC,CAAC,CAAC,yBAAyB,CAAC,OAAO,CAAC,WAAW,CAAC;gBAChD,CAAC,CAAC,SAAS,CAAC;YACd,OAAO;gBACL,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,aAAa,EAAE,OAAO,CAAC,YAAY;gBACnC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrD,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,MAAM;gBAChC,eAAe,EAAE,QAAQ,EAAE,eAAe,IAAI,CAAC;gBAC/C,YAAY,EAAE,QAAQ,EAAE,YAAY,IAAI,EAAE;gBAC1C,aAAa,EAAE,QAAQ,EAAE,aAAa,IAAI,CAAC;gBAC3C,WAAW,EAAE,QAAQ,EAAE,WAAW,IAAI,CAAC;gBACvC,cAAc,EAAE,QAAQ,EAAE,cAAc,IAAI,CAAC;gBAC7C,UAAU,EAAE,QAAQ,EAAE,UAAU,IAAI,CAAC;gBACrC,SAAS,EAAE,QAAQ,EAAE,SAAS,IAAI,IAAI;gBACtC,gBAAgB,EAAE,QAAQ,EAAE,gBAAgB,IAAI,IAAI;aACrD,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAED,cAAc,CAAC,OAA8B;QAC3C,IAAI,CAAC,MAAM,CAAC,eAAe,IAAI,CAAC,CAAC;QACjC,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;QAC5E,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE;gBACzC,WAAW,EAAE,OAAO,CAAC,IAAI;gBACzB,QAAQ,EAAE,OAAO,CAAC,QAAQ;aAC3B,CAAC,CAAC;YACH,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC;YACzB,OAAO,CAAC,eAAe,IAAI,CAAC,CAAC;YAC7B,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAChE,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,aAAa,CAAC;YAChD,OAAO,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC;YACrC,OAAO,CAAC,gBAAgB,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACtD,CAAC;QACD,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAED,eAAe,CAAC,OAA+B;QAC7C,IAAI,CAAC,MAAM,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC;QAC3E,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;QAC5E,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC9C,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC;YACnE,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAChE,OAAO,CAAC,aAAa,IAAI,CAAC,CAAC;YAC3B,OAAO,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC;YACrC,OAAO,CAAC,gBAAgB,GAAG,GAAG,CAAC;YAC/B,IAAI,OAAO,CAAC,OAAO,KAAK,OAAO;gBAAE,OAAO,CAAC,WAAW,IAAI,CAAC,CAAC;YAC1D,IAAI,OAAO,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;gBAChC,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC;YAC1B,CAAC;iBAAM,IAAI,OAAO,CAAC,eAAe,GAAG,CAAC,EAAE,CAAC;gBACvC,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC;YAC3B,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,GAAG,MAAM,CAAC;YACzB,CAAC;QACH,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC;YAC/B,UAAU,EAAE,OAAO,CAAC,SAAS;YAC7B,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxE,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrE,SAAS,EAAE,OAAO,CAAC,QAAQ;YAC3B,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,WAAW,EAAE,OAAO,CAAC,UAAU;YAC/B,EAAE,EAAE,GAAG;YACP,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACnD,CAAC,CAAC;QACH,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YAC5C,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;QACjF,CAAC;QACD,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAED,OAAO;QACL,IAAI,IAAI,CAAC,aAAa;YAAE,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC1D,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,SAAS,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,eAAe,GAAG,CAAC,CAAC;QAChC,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAC5B,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YAC3C,OAAO,CAAC,eAAe,GAAG,CAAC,CAAC;YAC5B,OAAO,CAAC,YAAY,GAAG,EAAE,CAAC;YAC1B,OAAO,CAAC,KAAK,GAAG,MAAM,CAAC;QACzB,CAAC;QACD,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;IAED,MAAM;QACJ,IAAI,IAAI,CAAC,aAAa;YAAE,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC1D,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAChC,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;QAChC,CAAC;QACD,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,MAAM,IAAI,CAAC,cAAc,CAAC;IAC5B,CAAC;IAEO,WAAW,CAAC,IAAa,EAAE,KAAc;QAC/C,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QAC/E,IAAI,KAAK;YAAE,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;QAClF,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACtE,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,qBAAqB,CAAC,WAAmB;QAC/C,OAAO,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC;aACrC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,KAAK,WAAW,CAAC;aACxD,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC;IAEO,OAAO;QACb,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAClD,IAAI,IAAI,CAAC,YAAY;YAAE,OAAO;QAC9B,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC,GAAG,EAAE;YAClC,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;YAC9B,IAAI,CAAC,cAAc,EAAE,CAAC;QACxB,CAAC,EAAE,EAAE,CAAC,CAAC;QACP,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC;IAEO,cAAc;QACpB,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAClD,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;QAC7D,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC;IACrF,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,QAAgB;QAC1C,MAAM,aAAa,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,MAAM,CAAC;QACxD,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACrD,MAAM,SAAS,CAAC,aAAa,EAAE,QAAQ,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YAC5E,MAAM,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;YAClC,MAAM,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,EAAE,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;CACF;AAED,MAAM,UAAU,oBAAoB,CAAC,UAAkB;IACrD,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,oBAAoB,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,CAA2B,CAAC;QAC3G,OAAO,KAAK,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,UAAkB;IACrD,OAAO,mBAAmB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,UAAkB;IACtD,IAAI,CAAC;QACH,UAAU,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,KAAK,CAAC;IACtE,CAAC;AACH,CAAC;AAED,SAAS,yBAAyB,CAAC,WAAmB;IACpD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;QACjC,GAAG,CAAC,QAAQ,GAAG,EAAE,CAAC;QAClB,GAAG,CAAC,QAAQ,GAAG,EAAE,CAAC;QAClB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC;QAChB,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC;QACd,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,WAAW;aACf,OAAO,CAAC,kBAAkB,EAAE,KAAK,CAAC;aAClC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC;AAED,SAAS,0BAA0B,CAAC,UAAkB;IACpD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;QAChC,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ;YAAE,OAAO,iBAAiB,CAAC;QACpF,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC;QACtD,OAAO,GAAG,GAAG,CAAC,QAAQ,KAAK,GAAG,CAAC,IAAI,GAAG,IAAI,EAAE,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,iBAAiB,CAAC;IAC3B,CAAC;AACH,CAAC","sourcesContent":["// Project/App: Open GSD\n// File Purpose: Persist token-free cloud runtime status and traffic counters for local monitors.\nimport { readFileSync, unlinkSync } from \"node:fs\";\nimport { chmod, mkdir, rename, rm, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport type { AdvertisedProject } from \"./executors/executor.js\";\nimport { runtimeArtifactPath } from \"./runtime-artifacts.js\";\n\nexport type RuntimeConnectionState = \"connecting\" | \"connected\" | \"reconnecting\" | \"error\" | \"stopped\";\nexport type RuntimeProjectState = \"idle\" | \"active\" | \"error\";\nexport type RuntimeRequestOutcome = \"success\" | \"error\" | \"cancelled\";\n\nexport interface RuntimeProjectTelemetry {\n alias: string;\n path: string;\n repo_identity: string;\n remote_label?: string;\n state: RuntimeProjectState;\n active_requests: number;\n active_tools: string[];\n request_count: number;\n error_count: number;\n received_bytes: number;\n sent_bytes: number;\n last_tool: string | null;\n last_activity_at: string | null;\n}\n\nexport interface RuntimeActivityTelemetry {\n request_id: string;\n project_alias?: string;\n project_path?: string;\n tool_name: string;\n outcome: RuntimeRequestOutcome;\n duration_ms: number;\n at: string;\n error?: string;\n}\n\nexport interface RuntimeTelemetryStatus {\n version: 1;\n pid: number;\n state: RuntimeConnectionState;\n gateway_url: string;\n runtime_id?: string;\n runtime_name?: string;\n started_at: string;\n connected_at: string | null;\n updated_at: string;\n last_error: string | null;\n connection_attempts: number;\n reconnects: number;\n received_messages: number;\n sent_messages: number;\n received_bytes: number;\n sent_bytes: number;\n active_requests: number;\n projects: RuntimeProjectTelemetry[];\n recent_activity: RuntimeActivityTelemetry[];\n}\n\nexport interface RuntimeRequestStarted {\n requestId: string;\n projectAlias?: string;\n projectPath?: string;\n toolName: string;\n receivedBytes: number;\n}\n\nexport interface RuntimeRequestFinished {\n requestId: string;\n projectAlias?: string;\n projectPath?: string;\n toolName: string;\n durationMs: number;\n outcome: RuntimeRequestOutcome;\n error?: string;\n}\n\nexport interface RuntimeTelemetryReporter {\n connecting(): void;\n connected(): void;\n disconnected(error?: string): void;\n socketError(error: string): void;\n received(text: string): void;\n sent(text: string, projectPath?: string): void;\n projectsAdvertised(projects: AdvertisedProject[]): void;\n requestStarted(request: RuntimeRequestStarted): void;\n requestFinished(request: RuntimeRequestFinished): void;\n stopped(): void;\n failed?(): void;\n flush?(): Promise<void>;\n}\n\ninterface RuntimeTelemetryMetadata {\n gatewayUrl: string;\n runtimeId?: string;\n runtimeName?: string;\n}\n\nexport const noopRuntimeTelemetry: RuntimeTelemetryReporter = {\n connecting(): void {},\n connected(): void {},\n disconnected(): void {},\n socketError(): void {},\n received(): void {},\n sent(): void {},\n projectsAdvertised(): void {},\n requestStarted(): void {},\n requestFinished(): void {},\n stopped(): void {},\n failed(): void {},\n};\n\nexport class RuntimeTelemetryStore implements RuntimeTelemetryReporter {\n private readonly path: string;\n private readonly activeRequests = new Map<string, { projectPath: string; toolName: string }>();\n private status: RuntimeTelemetryStatus;\n private livenessTimer: ReturnType<typeof setInterval> | undefined;\n private persistTimer: ReturnType<typeof setTimeout> | undefined;\n private persistPromise = Promise.resolve();\n\n constructor(configPath: string, metadata: RuntimeTelemetryMetadata) {\n const now = new Date().toISOString();\n this.path = runtimeTelemetryPath(configPath);\n this.status = {\n version: 1,\n pid: process.pid,\n state: \"connecting\",\n gateway_url: credentialFreeGatewayLabel(metadata.gatewayUrl),\n ...(metadata.runtimeId ? { runtime_id: metadata.runtimeId } : {}),\n ...(metadata.runtimeName ? { runtime_name: metadata.runtimeName } : {}),\n started_at: now,\n connected_at: null,\n updated_at: now,\n last_error: null,\n connection_attempts: 0,\n reconnects: 0,\n received_messages: 0,\n sent_messages: 0,\n received_bytes: 0,\n sent_bytes: 0,\n active_requests: 0,\n projects: [],\n recent_activity: [],\n };\n }\n\n connecting(): void {\n if (!this.livenessTimer) {\n this.livenessTimer = setInterval(() => this.persist(), 1_000);\n this.livenessTimer.unref();\n }\n this.status.state = this.status.connection_attempts === 0 ? \"connecting\" : \"reconnecting\";\n this.status.connection_attempts += 1;\n this.persist();\n }\n\n connected(): void {\n this.status.state = \"connected\";\n this.status.connected_at = new Date().toISOString();\n this.status.last_error = null;\n this.persist();\n }\n\n disconnected(error?: string): void {\n if (this.status.connected_at && this.status.state !== \"reconnecting\") {\n this.status.reconnects += 1;\n }\n this.status.state = \"reconnecting\";\n this.status.last_error = error ?? this.status.last_error ?? \"connection closed\";\n this.persist();\n }\n\n socketError(error: string): void {\n this.status.state = \"error\";\n this.status.last_error = error;\n this.persist();\n }\n\n received(text: string): void {\n this.status.received_messages += 1;\n this.status.received_bytes += Buffer.byteLength(text);\n this.persist();\n }\n\n sent(text: string, projectPath?: string): void {\n this.status.sent_messages += 1;\n const bytes = Buffer.byteLength(text);\n this.status.sent_bytes += bytes;\n const project = projectPath ? this.findProject(projectPath) : undefined;\n if (project) project.sent_bytes += bytes;\n this.persist();\n }\n\n projectsAdvertised(projects: AdvertisedProject[]): void {\n const existingProjects = new Map(\n this.status.projects.map((project) => [project.path, project]),\n );\n this.status.projects = projects.map((project) => {\n const existing = existingProjects.get(project.path);\n const remoteLabel = project.remoteLabel\n ? credentialFreeRemoteLabel(project.remoteLabel)\n : undefined;\n return {\n alias: project.alias,\n path: project.path,\n repo_identity: project.repoIdentity,\n ...(remoteLabel ? { remote_label: remoteLabel } : {}),\n state: existing?.state ?? \"idle\",\n active_requests: existing?.active_requests ?? 0,\n active_tools: existing?.active_tools ?? [],\n request_count: existing?.request_count ?? 0,\n error_count: existing?.error_count ?? 0,\n received_bytes: existing?.received_bytes ?? 0,\n sent_bytes: existing?.sent_bytes ?? 0,\n last_tool: existing?.last_tool ?? null,\n last_activity_at: existing?.last_activity_at ?? null,\n };\n });\n this.persist();\n }\n\n requestStarted(request: RuntimeRequestStarted): void {\n this.status.active_requests += 1;\n const project = this.findProject(request.projectPath, request.projectAlias);\n if (project) {\n this.activeRequests.set(request.requestId, {\n projectPath: project.path,\n toolName: request.toolName,\n });\n project.state = \"active\";\n project.active_requests += 1;\n project.active_tools = this.activeToolsForProject(project.path);\n project.received_bytes += request.receivedBytes;\n project.last_tool = request.toolName;\n project.last_activity_at = new Date().toISOString();\n }\n this.persist();\n }\n\n requestFinished(request: RuntimeRequestFinished): void {\n this.status.active_requests = Math.max(0, this.status.active_requests - 1);\n const now = new Date().toISOString();\n const project = this.findProject(request.projectPath, request.projectAlias);\n this.activeRequests.delete(request.requestId);\n if (project) {\n project.active_requests = Math.max(0, project.active_requests - 1);\n project.active_tools = this.activeToolsForProject(project.path);\n project.request_count += 1;\n project.last_tool = request.toolName;\n project.last_activity_at = now;\n if (request.outcome === \"error\") project.error_count += 1;\n if (request.outcome === \"error\") {\n project.state = \"error\";\n } else if (project.active_requests > 0) {\n project.state = \"active\";\n } else {\n project.state = \"idle\";\n }\n }\n this.status.recent_activity.push({\n request_id: request.requestId,\n ...(request.projectAlias ? { project_alias: request.projectAlias } : {}),\n ...(request.projectPath ? { project_path: request.projectPath } : {}),\n tool_name: request.toolName,\n outcome: request.outcome,\n duration_ms: request.durationMs,\n at: now,\n ...(request.error ? { error: request.error } : {}),\n });\n if (this.status.recent_activity.length > 50) {\n this.status.recent_activity.splice(0, this.status.recent_activity.length - 50);\n }\n this.persist();\n }\n\n stopped(): void {\n if (this.livenessTimer) clearInterval(this.livenessTimer);\n this.livenessTimer = undefined;\n this.status.state = \"stopped\";\n this.status.active_requests = 0;\n this.activeRequests.clear();\n for (const project of this.status.projects) {\n project.active_requests = 0;\n project.active_tools = [];\n project.state = \"idle\";\n }\n void this.flush();\n }\n\n failed(): void {\n if (this.livenessTimer) clearInterval(this.livenessTimer);\n this.livenessTimer = undefined;\n }\n\n async flush(): Promise<void> {\n if (this.persistTimer) {\n clearTimeout(this.persistTimer);\n this.persistTimer = undefined;\n }\n this.enqueuePersist();\n await this.persistPromise;\n }\n\n private findProject(path?: string, alias?: string): RuntimeProjectTelemetry | undefined {\n if (path) return this.status.projects.find((project) => project.path === path);\n if (alias) return this.status.projects.find((project) => project.alias === alias);\n if (this.status.projects.length === 1) return this.status.projects[0];\n return undefined;\n }\n\n private activeToolsForProject(projectPath: string): string[] {\n return [...this.activeRequests.values()]\n .filter((request) => request.projectPath === projectPath)\n .map((request) => request.toolName);\n }\n\n private persist(): void {\n this.status.updated_at = new Date().toISOString();\n if (this.persistTimer) return;\n this.persistTimer = setTimeout(() => {\n this.persistTimer = undefined;\n this.enqueuePersist();\n }, 25);\n this.persistTimer.unref();\n }\n\n private enqueuePersist(): void {\n this.status.updated_at = new Date().toISOString();\n const snapshot = `${JSON.stringify(this.status, null, 2)}\\n`;\n this.persistPromise = this.persistPromise.then(() => this.writeSnapshot(snapshot));\n }\n\n private async writeSnapshot(snapshot: string): Promise<void> {\n const temporaryPath = `${this.path}.${process.pid}.tmp`;\n try {\n await mkdir(dirname(this.path), { recursive: true });\n await writeFile(temporaryPath, snapshot, { encoding: \"utf8\", mode: 0o600 });\n await chmod(temporaryPath, 0o600);\n await rename(temporaryPath, this.path);\n } catch {\n await rm(temporaryPath, { force: true }).catch(() => undefined);\n }\n }\n}\n\nexport function readRuntimeTelemetry(configPath: string): RuntimeTelemetryStatus | null {\n try {\n const value = JSON.parse(readFileSync(runtimeTelemetryPath(configPath), \"utf8\")) as RuntimeTelemetryStatus;\n return value.version === 1 ? value : null;\n } catch {\n return null;\n }\n}\n\nexport function runtimeTelemetryPath(configPath: string): string {\n return runtimeArtifactPath(configPath, \"status\");\n}\n\nexport function clearRuntimeTelemetry(configPath: string): void {\n try {\n unlinkSync(runtimeTelemetryPath(configPath));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n }\n}\n\nfunction credentialFreeRemoteLabel(remoteLabel: string): string {\n try {\n const url = new URL(remoteLabel);\n url.username = \"\";\n url.password = \"\";\n url.search = \"\";\n url.hash = \"\";\n return url.toString();\n } catch {\n return remoteLabel\n .replace(/^[^/@]+@([^:]+):/, \"$1:\")\n .replace(/[?#].*$/, \"\");\n }\n}\n\nfunction credentialFreeGatewayLabel(gatewayUrl: string): string {\n try {\n const url = new URL(gatewayUrl);\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") return \"invalid gateway\";\n const path = url.pathname === \"/\" ? \"\" : url.pathname;\n return `${url.protocol}//${url.host}${path}`;\n } catch {\n return \"invalid gateway\";\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=runtime-telemetry.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-telemetry.test.d.ts","sourceRoot":"","sources":["../src/runtime-telemetry.test.ts"],"names":[],"mappings":""}