@stravica-ai/digital-operator-pa 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (372) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +170 -0
  3. package/bin/desk +9 -0
  4. package/bin/distill +2 -0
  5. package/bin/estate-sync +2 -0
  6. package/bin/launch +2 -0
  7. package/bin/memory-sync +2 -0
  8. package/bin/migrate-inspect +2 -0
  9. package/bin/pa +2 -0
  10. package/bin/pa-coordinator-hook +2 -0
  11. package/bin/pa-init +2 -0
  12. package/bin/research +2 -0
  13. package/bin/scheduler +2 -0
  14. package/bin/secrets +2 -0
  15. package/bin/slice +2 -0
  16. package/bin/smoke +9 -0
  17. package/bin/sync +2 -0
  18. package/dist/engineering-pa-cli/README.md +205 -0
  19. package/dist/engineering-pa-cli/bin/estate-sync +2 -0
  20. package/dist/engineering-pa-cli/bin/launch +2 -0
  21. package/dist/engineering-pa-cli/bin/pa +2 -0
  22. package/dist/engineering-pa-cli/bin/pa-coordinator-hook +12 -0
  23. package/dist/engineering-pa-cli/bin/research +2 -0
  24. package/dist/engineering-pa-cli/bin/scheduler +2 -0
  25. package/dist/engineering-pa-cli/bin/secrets +2 -0
  26. package/dist/engineering-pa-cli/bin/smoke +9 -0
  27. package/dist/engineering-pa-cli/bin/sync +2 -0
  28. package/dist/engineering-pa-cli/config/coordinator-allowlist.json +118 -0
  29. package/dist/engineering-pa-cli/docs/coordinator-hook.md +211 -0
  30. package/dist/engineering-pa-cli/docs/estate-sync.md +412 -0
  31. package/dist/engineering-pa-cli/docs/gsc.md +175 -0
  32. package/dist/engineering-pa-cli/docs/lint-linkedin.md +139 -0
  33. package/dist/engineering-pa-cli/docs/secrets.md +221 -0
  34. package/dist/engineering-pa-cli/docs/smoke.md +113 -0
  35. package/dist/engineering-pa-cli/docs/staging-alias.md +114 -0
  36. package/dist/engineering-pa-cli/index.mjs +17 -0
  37. package/dist/engineering-pa-cli/package.json +37 -0
  38. package/dist/engineering-pa-cli/src/autonomy/cli.mjs +329 -0
  39. package/dist/engineering-pa-cli/src/autonomy/envelope.mjs +301 -0
  40. package/dist/engineering-pa-cli/src/coordinator-hook/cli.mjs +140 -0
  41. package/dist/engineering-pa-cli/src/coordinator-hook/config.mjs +134 -0
  42. package/dist/engineering-pa-cli/src/coordinator-hook/message.mjs +47 -0
  43. package/dist/engineering-pa-cli/src/coordinator-hook/policy.mjs +211 -0
  44. package/dist/engineering-pa-cli/src/coordinator-hook/repo-root.mjs +44 -0
  45. package/dist/engineering-pa-cli/src/coordinator-hook/self.mjs +30 -0
  46. package/dist/engineering-pa-cli/src/environment/cli.mjs +287 -0
  47. package/dist/engineering-pa-cli/src/environment/probes.mjs +302 -0
  48. package/dist/engineering-pa-cli/src/gsc/auth.mjs +148 -0
  49. package/dist/engineering-pa-cli/src/gsc/cli.mjs +93 -0
  50. package/dist/engineering-pa-cli/src/gsc/cloudflare.mjs +318 -0
  51. package/dist/engineering-pa-cli/src/gsc/commands/add-property.mjs +70 -0
  52. package/dist/engineering-pa-cli/src/gsc/commands/list-properties.mjs +33 -0
  53. package/dist/engineering-pa-cli/src/gsc/commands/pull-analytics.mjs +130 -0
  54. package/dist/engineering-pa-cli/src/gsc/commands/submit-sitemap.mjs +41 -0
  55. package/dist/engineering-pa-cli/src/gsc/commands/verify-via-cf-dns.mjs +189 -0
  56. package/dist/engineering-pa-cli/src/knowledge/call-log.mjs +59 -0
  57. package/dist/engineering-pa-cli/src/knowledge/cli.mjs +242 -0
  58. package/dist/engineering-pa-cli/src/knowledge/eval.mjs +446 -0
  59. package/dist/engineering-pa-cli/src/knowledge/formatters.mjs +331 -0
  60. package/dist/engineering-pa-cli/src/knowledge/graph.mjs +710 -0
  61. package/dist/engineering-pa-cli/src/launch/README.md +214 -0
  62. package/dist/engineering-pa-cli/src/launch/cli.mjs +51 -0
  63. package/dist/engineering-pa-cli/src/launch/commands/launch.mjs +106 -0
  64. package/dist/engineering-pa-cli/src/launch/identity.mjs +43 -0
  65. package/dist/engineering-pa-cli/src/launch/planner.mjs +44 -0
  66. package/dist/engineering-pa-cli/src/launch/repo-root.mjs +53 -0
  67. package/dist/engineering-pa-cli/src/launch/runner.mjs +147 -0
  68. package/dist/engineering-pa-cli/src/launch/task-loader.mjs +85 -0
  69. package/dist/engineering-pa-cli/src/lint/cli.mjs +61 -0
  70. package/dist/engineering-pa-cli/src/lint/commands/linkedin.mjs +133 -0
  71. package/dist/engineering-pa-cli/src/lint/detectors.mjs +90 -0
  72. package/dist/engineering-pa-cli/src/lint/linter.mjs +69 -0
  73. package/dist/engineering-pa-cli/src/lint/reporter.mjs +32 -0
  74. package/dist/engineering-pa-cli/src/lint/rules.mjs +132 -0
  75. package/dist/engineering-pa-cli/src/pa/cli.mjs +369 -0
  76. package/dist/engineering-pa-cli/src/pa/doc-groups.mjs +164 -0
  77. package/dist/engineering-pa-cli/src/pa/io.mjs +80 -0
  78. package/dist/engineering-pa-cli/src/pa/project-cli.mjs +385 -0
  79. package/dist/engineering-pa-cli/src/pa/projects.mjs +352 -0
  80. package/dist/engineering-pa-cli/src/pa/repo-root.mjs +64 -0
  81. package/dist/engineering-pa-cli/src/pa/session.mjs +254 -0
  82. package/dist/engineering-pa-cli/src/pa/work-cli.mjs +164 -0
  83. package/dist/engineering-pa-cli/src/pa/work.mjs +196 -0
  84. package/dist/engineering-pa-cli/src/pa/workstreams.mjs +201 -0
  85. package/dist/engineering-pa-cli/src/research/README.md +360 -0
  86. package/dist/engineering-pa-cli/src/research/briefs/extractor.md +103 -0
  87. package/dist/engineering-pa-cli/src/research/briefs/searcher.md +113 -0
  88. package/dist/engineering-pa-cli/src/research/briefs/synthesizer.md +124 -0
  89. package/dist/engineering-pa-cli/src/research/briefs/verifier.md +86 -0
  90. package/dist/engineering-pa-cli/src/research/cli.mjs +141 -0
  91. package/dist/engineering-pa-cli/src/research/commands/gates.mjs +176 -0
  92. package/dist/engineering-pa-cli/src/research/commands/list.mjs +56 -0
  93. package/dist/engineering-pa-cli/src/research/commands/mark.mjs +97 -0
  94. package/dist/engineering-pa-cli/src/research/commands/paths.mjs +69 -0
  95. package/dist/engineering-pa-cli/src/research/commands/prune.mjs +86 -0
  96. package/dist/engineering-pa-cli/src/research/commands/run.mjs +94 -0
  97. package/dist/engineering-pa-cli/src/research/commands/show.mjs +43 -0
  98. package/dist/engineering-pa-cli/src/research/docs/operator-present-flow.md +120 -0
  99. package/dist/engineering-pa-cli/src/research/format.mjs +59 -0
  100. package/dist/engineering-pa-cli/src/research/promote.mjs +260 -0
  101. package/dist/engineering-pa-cli/src/research/schema/finding.schema.json +55 -0
  102. package/dist/engineering-pa-cli/src/research/schema/gates.schema.json +34 -0
  103. package/dist/engineering-pa-cli/src/research/schema/manifest.schema.json +59 -0
  104. package/dist/engineering-pa-cli/src/research/schema/plan.schema.json +41 -0
  105. package/dist/engineering-pa-cli/src/research/schema/sources.schema.json +31 -0
  106. package/dist/engineering-pa-cli/src/research/store/findings.mjs +61 -0
  107. package/dist/engineering-pa-cli/src/research/store/gates.mjs +73 -0
  108. package/dist/engineering-pa-cli/src/research/store/index.mjs +312 -0
  109. package/dist/engineering-pa-cli/src/research/store/manifest.mjs +56 -0
  110. package/dist/engineering-pa-cli/src/research/store/plan.mjs +59 -0
  111. package/dist/engineering-pa-cli/src/research/store/sources.mjs +44 -0
  112. package/dist/engineering-pa-cli/src/research/store/validate.mjs +92 -0
  113. package/dist/engineering-pa-cli/src/research/workflows/research-normal.js +573 -0
  114. package/dist/engineering-pa-cli/src/scheduler/cli.mjs +197 -0
  115. package/dist/engineering-pa-cli/src/secrets/cli.mjs +254 -0
  116. package/dist/engineering-pa-cli/src/secrets/commands/backup-template.mjs +67 -0
  117. package/dist/engineering-pa-cli/src/secrets/commands/backup.mjs +85 -0
  118. package/dist/engineering-pa-cli/src/secrets/commands/delete.mjs +58 -0
  119. package/dist/engineering-pa-cli/src/secrets/commands/find.mjs +36 -0
  120. package/dist/engineering-pa-cli/src/secrets/commands/get.mjs +49 -0
  121. package/dist/engineering-pa-cli/src/secrets/commands/init.mjs +69 -0
  122. package/dist/engineering-pa-cli/src/secrets/commands/list.mjs +37 -0
  123. package/dist/engineering-pa-cli/src/secrets/commands/rotate.mjs +46 -0
  124. package/dist/engineering-pa-cli/src/secrets/commands/set.mjs +123 -0
  125. package/dist/engineering-pa-cli/src/secrets/commands/status.mjs +146 -0
  126. package/dist/engineering-pa-cli/src/secrets/commands/vaults.mjs +57 -0
  127. package/dist/engineering-pa-cli/src/secrets/commands/verify.mjs +143 -0
  128. package/dist/engineering-pa-cli/src/secrets/vault.mjs +766 -0
  129. package/dist/engineering-pa-cli/src/smoke/checks.mjs +199 -0
  130. package/dist/engineering-pa-cli/src/smoke/cli.mjs +108 -0
  131. package/dist/engineering-pa-cli/src/smoke/commands/run.mjs +237 -0
  132. package/dist/engineering-pa-cli/src/smoke/runner.mjs +191 -0
  133. package/dist/engineering-pa-cli/src/staging-alias/cli.mjs +91 -0
  134. package/dist/engineering-pa-cli/src/staging-alias/cloudflare.mjs +380 -0
  135. package/dist/engineering-pa-cli/src/staging-alias/commands/list.mjs +36 -0
  136. package/dist/engineering-pa-cli/src/staging-alias/commands/set.mjs +188 -0
  137. package/dist/engineering-pa-cli/src/staging-alias/commands/status.mjs +113 -0
  138. package/dist/engineering-pa-cli/src/staging-alias/commands/unset.mjs +95 -0
  139. package/dist/engineering-pa-cli/src/staging-alias/sites.mjs +105 -0
  140. package/dist/engineering-pa-cli/src/sync/cli.mjs +151 -0
  141. package/dist/engineering-pa-cli/src/sync/git.mjs +149 -0
  142. package/dist/engineering-pa-cli/src/sync/lock.mjs +30 -0
  143. package/dist/engineering-pa-cli/src/sync/regenerated-artifacts.mjs +114 -0
  144. package/dist/engineering-pa-cli/src/sync/registry-scope.mjs +260 -0
  145. package/dist/engineering-pa-cli/src/sync/run.mjs +531 -0
  146. package/dist/engineering-pa-cli/src/sync/runner.mjs +62 -0
  147. package/dist/engineering-pa-cli/src/sync/runs-digest.mjs +138 -0
  148. package/dist/engineering-pa-core/README.md +60 -0
  149. package/dist/engineering-pa-core/bin/desk +9 -0
  150. package/dist/engineering-pa-core/bin/distill +2 -0
  151. package/dist/engineering-pa-core/bin/memory-sync +2 -0
  152. package/dist/engineering-pa-core/bin/slice +2 -0
  153. package/dist/engineering-pa-core/docs/autonomy-envelope-tracker.md +111 -0
  154. package/dist/engineering-pa-core/docs/blueprints/README.md +45 -0
  155. package/dist/engineering-pa-core/docs/blueprints/docker-services/blueprint.md +168 -0
  156. package/dist/engineering-pa-core/docs/blueprints/git-identity/blueprint.md +116 -0
  157. package/dist/engineering-pa-core/docs/blueprints/ideas/custom-workspace-views.md +9 -0
  158. package/dist/engineering-pa-core/docs/blueprints/ideas/knowledge-domain-patterns.md +15 -0
  159. package/dist/engineering-pa-core/docs/blueprints/ideas/office-integration.md +11 -0
  160. package/dist/engineering-pa-core/docs/blueprints/ideas/team-scaling.md +9 -0
  161. package/dist/engineering-pa-core/docs/blueprints/ideas/work-personal-separation.md +9 -0
  162. package/dist/engineering-pa-core/docs/blueprints/scheduled-distillation/blueprint.md +129 -0
  163. package/dist/engineering-pa-core/docs/blueprints/tool-integration/blueprint.md +110 -0
  164. package/dist/engineering-pa-core/docs/commands/init.md +159 -0
  165. package/dist/engineering-pa-core/docs/commands/schedule.md +98 -0
  166. package/dist/engineering-pa-core/docs/commands/upgrade.md +67 -0
  167. package/dist/engineering-pa-core/docs/entity-location-map.md +93 -0
  168. package/dist/engineering-pa-core/docs/knowledge-scaffold.md +121 -0
  169. package/dist/engineering-pa-core/docs/lock.md +155 -0
  170. package/dist/engineering-pa-core/docs/memory-sync.md +28 -0
  171. package/dist/engineering-pa-core/docs/pa-operating-model.md +457 -0
  172. package/dist/engineering-pa-core/docs/scheduling.md +35 -0
  173. package/dist/engineering-pa-core/docs/standards/README.md +24 -0
  174. package/dist/engineering-pa-core/docs/standards/briefing-contract.md +161 -0
  175. package/dist/engineering-pa-core/docs/standards/tooling.md +240 -0
  176. package/dist/engineering-pa-core/docs/tools/distill.md +230 -0
  177. package/dist/engineering-pa-core/docs/tools/memory-sync.md +98 -0
  178. package/dist/engineering-pa-core/docs/tools/scheduler.md +243 -0
  179. package/dist/engineering-pa-core/docs/tools/slice.md +150 -0
  180. package/dist/engineering-pa-core/docs/upstream-issue-filing.md +88 -0
  181. package/dist/engineering-pa-core/docs/working-directory.md +29 -0
  182. package/dist/engineering-pa-core/docs/workspace-operations.md +46 -0
  183. package/dist/engineering-pa-core/index.mjs +21 -0
  184. package/dist/engineering-pa-core/knowledge/README.md +53 -0
  185. package/dist/engineering-pa-core/knowledge/canonical/.gitkeep +0 -0
  186. package/dist/engineering-pa-core/knowledge/content-voice/README.md +64 -0
  187. package/dist/engineering-pa-core/knowledge/content-voice/banned-ai-tells-baseline.md +133 -0
  188. package/dist/engineering-pa-core/knowledge/content-voice/banned-ai-tells-shape.md +58 -0
  189. package/dist/engineering-pa-core/knowledge/content-voice/banned-ai-tells-taxonomy.md +33 -0
  190. package/dist/engineering-pa-core/knowledge/content-voice/content-pipeline-routing.md +58 -0
  191. package/dist/engineering-pa-core/knowledge/content-voice/new-tell-capture-procedure.md +40 -0
  192. package/dist/engineering-pa-core/knowledge/content-voice/voice-guide-shape.md +43 -0
  193. package/dist/engineering-pa-core/knowledge/delegation-dispatch/README.md +34 -0
  194. package/dist/engineering-pa-core/knowledge/delegation-dispatch/briefing-contract.md +77 -0
  195. package/dist/engineering-pa-core/knowledge/delegation-dispatch/delegation-modes.md +84 -0
  196. package/dist/engineering-pa-core/knowledge/delegation-dispatch/dispatch-envelope.md +238 -0
  197. package/dist/engineering-pa-core/knowledge/delegation-dispatch/task-groups-and-orchestrators.md +62 -0
  198. package/dist/engineering-pa-core/knowledge/delegation-dispatch/team-improvement-loop.md +48 -0
  199. package/dist/engineering-pa-core/knowledge/delegation-dispatch/tool-development-policy.md +48 -0
  200. package/dist/engineering-pa-core/knowledge/engineering-discipline/README.md +33 -0
  201. package/dist/engineering-pa-core/knowledge/engineering-discipline/blast-radius-and-safety.md +50 -0
  202. package/dist/engineering-pa-core/knowledge/engineering-discipline/investigate-root-causes.md +48 -0
  203. package/dist/engineering-pa-core/knowledge/engineering-discipline/role-ladder.md +57 -0
  204. package/dist/engineering-pa-core/knowledge/engineering-discipline/verify-runtime-behaviour.md +53 -0
  205. package/dist/engineering-pa-core/knowledge/engineering-discipline/worktree-isolation.md +50 -0
  206. package/dist/engineering-pa-core/knowledge/knowledge-memory/README.md +33 -0
  207. package/dist/engineering-pa-core/knowledge/knowledge-memory/claude-md-hygiene.md +47 -0
  208. package/dist/engineering-pa-core/knowledge/knowledge-memory/journal-and-self-improvement.md +53 -0
  209. package/dist/engineering-pa-core/knowledge/knowledge-memory/knowledge-retrieval-discipline.md +62 -0
  210. package/dist/engineering-pa-core/knowledge/knowledge-memory/librarian-synthesis-mandate.md +56 -0
  211. package/dist/engineering-pa-core/knowledge/knowledge-memory/staging-and-observations.md +58 -0
  212. package/dist/engineering-pa-core/knowledge/operator-interface/README.md +32 -0
  213. package/dist/engineering-pa-core/knowledge/operator-interface/communication-style.md +33 -0
  214. package/dist/engineering-pa-core/knowledge/operator-interface/escalation-and-correction.md +45 -0
  215. package/dist/engineering-pa-core/knowledge/operator-interface/push-back-discipline.md +42 -0
  216. package/dist/engineering-pa-core/knowledge/operator-interface/session-boot-and-end.md +56 -0
  217. package/dist/engineering-pa-core/knowledge/platform-tooling/README.md +37 -0
  218. package/dist/engineering-pa-core/knowledge/platform-tooling/desk-cli-reference.md +52 -0
  219. package/dist/engineering-pa-core/knowledge/platform-tooling/environment-awareness.md +91 -0
  220. package/dist/engineering-pa-core/knowledge/platform-tooling/mcp-servers-catalogue.md +52 -0
  221. package/dist/engineering-pa-core/knowledge/platform-tooling/pa-cli-reference.md +55 -0
  222. package/dist/engineering-pa-core/knowledge/platform-tooling/scheduling-and-launchd.md +56 -0
  223. package/dist/engineering-pa-core/knowledge/platform-tooling/tool-discovery-discipline.md +49 -0
  224. package/dist/engineering-pa-core/knowledge/platform-tooling/working-directory-vs-project-root.md +43 -0
  225. package/dist/engineering-pa-core/knowledge/platform-tooling/workspace-server.md +51 -0
  226. package/dist/engineering-pa-core/knowledge/raw/.gitkeep +0 -0
  227. package/dist/engineering-pa-core/knowledge/scaffold/domains.json +5 -0
  228. package/dist/engineering-pa-core/knowledge/schema/.gitkeep +0 -0
  229. package/dist/engineering-pa-core/knowledge/work-management/README.md +33 -0
  230. package/dist/engineering-pa-core/knowledge/work-management/desk-cli.md +84 -0
  231. package/dist/engineering-pa-core/knowledge/work-management/progress-md.md +48 -0
  232. package/dist/engineering-pa-core/knowledge/work-management/projects.md +64 -0
  233. package/dist/engineering-pa-core/knowledge/work-management/spawn-log.md +48 -0
  234. package/dist/engineering-pa-core/knowledge/work-management/work-items.md +67 -0
  235. package/dist/engineering-pa-core/package.json +26 -0
  236. package/dist/engineering-pa-core/roles/agent-ops/definition.md +79 -0
  237. package/dist/engineering-pa-core/roles/dispatch-briefer/definition.md +195 -0
  238. package/dist/engineering-pa-core/roles/librarian/definition.md +176 -0
  239. package/dist/engineering-pa-core/roles/pa/definition.md +93 -0
  240. package/dist/engineering-pa-core/roles/system-admin/definition.md +106 -0
  241. package/dist/engineering-pa-core/roles/tool-developer/definition.md +116 -0
  242. package/dist/engineering-pa-core/roles/writer/definition.md +130 -0
  243. package/dist/engineering-pa-core/schema/autonomy-envelope.schema.json +61 -0
  244. package/dist/engineering-pa-core/schema/project.json +114 -0
  245. package/dist/engineering-pa-core/schema/schedule.json +63 -0
  246. package/dist/engineering-pa-core/schema/work-item.json +92 -0
  247. package/dist/engineering-pa-core/src/config/pa-package-name.mjs +30 -0
  248. package/dist/engineering-pa-core/src/desk/cli.mjs +95 -0
  249. package/dist/engineering-pa-core/src/desk/commands.mjs +398 -0
  250. package/dist/engineering-pa-core/src/desk/format.mjs +84 -0
  251. package/dist/engineering-pa-core/src/desk/repo.mjs +172 -0
  252. package/dist/engineering-pa-core/src/desk/team-scope.mjs +142 -0
  253. package/dist/engineering-pa-core/src/distill/cli.mjs +112 -0
  254. package/dist/engineering-pa-core/src/distill/prereqs.mjs +171 -0
  255. package/dist/engineering-pa-core/src/distill/prompt.mjs +74 -0
  256. package/dist/engineering-pa-core/src/distill/run.mjs +230 -0
  257. package/dist/engineering-pa-core/src/distill/runner.mjs +86 -0
  258. package/dist/engineering-pa-core/src/distill/staging.mjs +59 -0
  259. package/dist/engineering-pa-core/src/knowledge/retrieval/backlink-indexer.mjs +154 -0
  260. package/dist/engineering-pa-core/src/knowledge/retrieval/graph-builder.mjs +186 -0
  261. package/dist/engineering-pa-core/src/knowledge/retrieval/index-builder.mjs +225 -0
  262. package/dist/engineering-pa-core/src/knowledge/retrieval/query.mjs +263 -0
  263. package/dist/engineering-pa-core/src/lock/lock.mjs +202 -0
  264. package/dist/engineering-pa-core/src/memory-sync/cli-support.mjs +12 -0
  265. package/dist/engineering-pa-core/src/memory-sync/cli.mjs +56 -0
  266. package/dist/engineering-pa-core/src/memory-sync/commands/pull.mjs +44 -0
  267. package/dist/engineering-pa-core/src/memory-sync/commands/push.mjs +46 -0
  268. package/dist/engineering-pa-core/src/memory-sync/mirror.mjs +114 -0
  269. package/dist/engineering-pa-core/src/memory-sync/repo.mjs +65 -0
  270. package/dist/engineering-pa-core/src/scheduler/detect.mjs +111 -0
  271. package/dist/engineering-pa-core/src/scheduler/host.mjs +38 -0
  272. package/dist/engineering-pa-core/src/scheduler/index.mjs +13 -0
  273. package/dist/engineering-pa-core/src/scheduler/install.mjs +854 -0
  274. package/dist/engineering-pa-core/src/scheduler/list.mjs +168 -0
  275. package/dist/engineering-pa-core/src/scheduler/remove.mjs +176 -0
  276. package/dist/engineering-pa-core/src/scheduler/verify.mjs +435 -0
  277. package/dist/engineering-pa-core/src/session-boot/autonomy-injection.mjs +84 -0
  278. package/dist/engineering-pa-core/src/slice/cli.mjs +139 -0
  279. package/dist/engineering-pa-core/src/slice/inputs.mjs +174 -0
  280. package/dist/engineering-pa-core/src/slice/prompt.mjs +94 -0
  281. package/dist/engineering-pa-core/src/slice/prompts/dave-boot.md +91 -0
  282. package/dist/engineering-pa-core/src/slice/run.mjs +334 -0
  283. package/dist/engineering-pa-core-extensions-atlassian/README.md +31 -0
  284. package/dist/engineering-pa-core-extensions-atlassian/index.mjs +9 -0
  285. package/dist/engineering-pa-core-extensions-atlassian/package.json +19 -0
  286. package/dist/engineering-pa-core-extensions-n8n/README.md +29 -0
  287. package/dist/engineering-pa-core-extensions-n8n/index.mjs +8 -0
  288. package/dist/engineering-pa-core-extensions-n8n/package.json +19 -0
  289. package/dist/engineering-pa-librarian/README.md +38 -0
  290. package/dist/engineering-pa-librarian/index.mjs +12 -0
  291. package/dist/engineering-pa-librarian/package.json +19 -0
  292. package/dist/engineering-pa-migrate-inspect/README.md +131 -0
  293. package/dist/engineering-pa-migrate-inspect/bin/migrate-inspect +2 -0
  294. package/dist/engineering-pa-migrate-inspect/package.json +21 -0
  295. package/dist/engineering-pa-migrate-inspect/src/age-key-migrate.mjs +83 -0
  296. package/dist/engineering-pa-migrate-inspect/src/cli.mjs +97 -0
  297. package/dist/engineering-pa-migrate-inspect/src/inspector.mjs +237 -0
  298. package/dist/engineering-pa-migrate-inspect/src/platforms/linux.mjs +87 -0
  299. package/dist/engineering-pa-migrate-inspect/src/platforms/macos.mjs +105 -0
  300. package/dist/engineering-pa-migrate-inspect/src/runner.mjs +87 -0
  301. package/dist/engineering-pa-runbook/README.md +103 -0
  302. package/dist/engineering-pa-runbook/package.json +18 -0
  303. package/dist/engineering-pa-runbook/reference/dex-template.runbook.json +66 -0
  304. package/dist/engineering-pa-runbook/reference/hq-dave.runbook.json +69 -0
  305. package/dist/engineering-pa-runbook/reference/smarthome01.runbook.json +92 -0
  306. package/dist/engineering-pa-runbook/schema/inspection.schema.json +113 -0
  307. package/dist/engineering-pa-runbook/schema/runbook.schema.json +67 -0
  308. package/dist/engineering-pa-runbook/src/validator.mjs +167 -0
  309. package/dist/engineering-pa-scaffold/README.md +164 -0
  310. package/dist/engineering-pa-scaffold/bin/pa-init +2 -0
  311. package/dist/engineering-pa-scaffold/index.mjs +42 -0
  312. package/dist/engineering-pa-scaffold/package.json +22 -0
  313. package/dist/engineering-pa-scaffold/src/cli.mjs +115 -0
  314. package/dist/engineering-pa-scaffold/src/commands/init.mjs +169 -0
  315. package/dist/engineering-pa-scaffold/src/generator.mjs +354 -0
  316. package/dist/engineering-pa-scaffold/src/prompts.mjs +125 -0
  317. package/dist/engineering-pa-scaffold/src/runner.mjs +142 -0
  318. package/dist/engineering-pa-scaffold/templates/CLAUDE.md.template +196 -0
  319. package/dist/engineering-pa-scaffold/templates/operator-README.md.template +44 -0
  320. package/dist/engineering-pa-types-engineering/README.md +35 -0
  321. package/dist/engineering-pa-types-engineering/docs/commands/product-build.md +120 -0
  322. package/dist/engineering-pa-types-engineering/index.mjs +9 -0
  323. package/dist/engineering-pa-types-engineering/package.json +19 -0
  324. package/dist/engineering-pa-types-engineering/roles/product-engineer/definition.md +650 -0
  325. package/dist/engineering-pa-types-engineering/roles/product-engineer/templates/build-spec.md +82 -0
  326. package/dist/engineering-pa-types-engineering/roles/product-engineer/templates/preflight-checklist.md +158 -0
  327. package/dist/engineering-pa-types-engineering/roles/product-engineer/templates/worker-brief.md +130 -0
  328. package/dist/engineering-pa-workspace/README.md +197 -0
  329. package/dist/engineering-pa-workspace/app/assets/md.js +187 -0
  330. package/dist/engineering-pa-workspace/app/assets/modal.js +120 -0
  331. package/dist/engineering-pa-workspace/app/assets/theme.css +132 -0
  332. package/dist/engineering-pa-workspace/app/assets/theme.js +159 -0
  333. package/dist/engineering-pa-workspace/app/banner.js +320 -0
  334. package/dist/engineering-pa-workspace/app/delegations.html +345 -0
  335. package/dist/engineering-pa-workspace/app/home.html +1060 -0
  336. package/dist/engineering-pa-workspace/app/index.html +361 -0
  337. package/dist/engineering-pa-workspace/app/knowledge-map.html +163 -0
  338. package/dist/engineering-pa-workspace/app/knowledge.html +304 -0
  339. package/dist/engineering-pa-workspace/app/nav.json +75 -0
  340. package/dist/engineering-pa-workspace/app/notes.html +199 -0
  341. package/dist/engineering-pa-workspace/app/onboarding.html +592 -0
  342. package/dist/engineering-pa-workspace/app/profile.html +243 -0
  343. package/dist/engineering-pa-workspace/app/project-detail.html +432 -0
  344. package/dist/engineering-pa-workspace/app/projects.html +297 -0
  345. package/dist/engineering-pa-workspace/app/repos.html +598 -0
  346. package/dist/engineering-pa-workspace/app/schedules.html +486 -0
  347. package/dist/engineering-pa-workspace/app/secrets.html +164 -0
  348. package/dist/engineering-pa-workspace/app/staging.html +319 -0
  349. package/dist/engineering-pa-workspace/app/tasks.html +465 -0
  350. package/dist/engineering-pa-workspace/app/vendor/chart.umd.min.js +21 -0
  351. package/dist/engineering-pa-workspace/app/viewer.html +116 -0
  352. package/dist/engineering-pa-workspace/docs/DAEMON.md +104 -0
  353. package/dist/engineering-pa-workspace/docs/page-blueprint.md +286 -0
  354. package/dist/engineering-pa-workspace/docs/status-mon.md +168 -0
  355. package/dist/engineering-pa-workspace/index.mjs +12 -0
  356. package/dist/engineering-pa-workspace/nav.json.example +8 -0
  357. package/dist/engineering-pa-workspace/package.json +27 -0
  358. package/dist/engineering-pa-workspace/src/api.mjs +2086 -0
  359. package/dist/engineering-pa-workspace/src/install-daemon.mjs +573 -0
  360. package/dist/engineering-pa-workspace/src/nav.mjs +190 -0
  361. package/dist/engineering-pa-workspace/src/secrets-api.mjs +175 -0
  362. package/dist/engineering-pa-workspace/src/server.mjs +516 -0
  363. package/dist/engineering-pa-workspace/src/status-mon/poll.mjs +220 -0
  364. package/dist/engineering-pa-workspace/src/status-mon/poller.mjs +113 -0
  365. package/dist/engineering-pa-workspace/src/status-mon/run.mjs +133 -0
  366. package/dist/engineering-pa-workspace/src/supervisor.mjs +264 -0
  367. package/dist/engineering-pa-workspace/src/ws.mjs +633 -0
  368. package/index.mjs +60 -0
  369. package/package.json +58 -0
  370. package/templates/banned-ai-tells.md +102 -0
  371. package/templates/purpose.md +105 -0
  372. package/templates/voice-guide.md +98 -0
@@ -0,0 +1,220 @@
1
+ /**
2
+ * poll.mjs — Pure polling logic for Statuspage.io-backed service-status sources.
3
+ *
4
+ * No filesystem side effects at import time. All I/O (fetch, read, write)
5
+ * happens inside explicit functions so tests can drive the module with
6
+ * injected fetchers and temp paths.
7
+ *
8
+ * Source shape assumed: Atlassian Statuspage `/api/v2/summary.json`. The
9
+ * adapter only reads fields that are documented + stable across all major
10
+ * Statuspage.io deployments (Anthropic, GitHub, OpenAI, Stripe, etc.).
11
+ *
12
+ * See README.md for the state-file schema and configuration contract.
13
+ */
14
+
15
+ /** Default polling sources. Override via operator/config/preferences.json. */
16
+ export const DEFAULT_SOURCES = [
17
+ { id: 'anthropic', name: 'Anthropic', url: 'https://status.anthropic.com/api/v2/summary.json' },
18
+ { id: 'github', name: 'GitHub', url: 'https://www.githubstatus.com/api/v2/summary.json' },
19
+ ];
20
+
21
+ /**
22
+ * Overall status indicators emitted by Statuspage.io in `status.indicator`.
23
+ * Ordering matters for severity (higher index = more severe). `maintenance`
24
+ * is rendered distinctly on the banner; it's not strictly "more severe"
25
+ * than `minor` in text, but colour-wise it's neutral.
26
+ */
27
+ export const INDICATORS = ['none', 'maintenance', 'minor', 'major', 'critical'];
28
+
29
+ /** Incident statuses that mean "still open". Anything else is considered closed. */
30
+ const OPEN_STATUSES = new Set(['investigating', 'identified', 'monitoring']);
31
+
32
+ /** Default window for "recently resolved" highlighting. */
33
+ const DEFAULT_RESOLVED_WINDOW_MS = 6 * 60 * 60 * 1000; // 6h
34
+
35
+ /**
36
+ * Normalise a raw summary.json payload into the canonical per-source slice
37
+ * used by the state file. Validates required fields loosely — Statuspage.io
38
+ * occasionally ships optional fields absent, so we prefer lenient coercion
39
+ * over schema rejection. Returns null on unusable payload so the caller can
40
+ * skip one bad source without failing the whole poll.
41
+ *
42
+ * @param {object} source { id, name, url }
43
+ * @param {object} payload Raw Statuspage.io summary JSON.
44
+ * @param {number} nowMs Epoch millis at poll time (injected for tests).
45
+ * @param {number} [resolvedWindowMs] Override the recently-resolved window.
46
+ * @returns {object|null}
47
+ */
48
+ export function normaliseSummary(source, payload, nowMs, resolvedWindowMs) {
49
+ if (!payload || typeof payload !== 'object') return null;
50
+ const status = payload.status || {};
51
+ const indicator = typeof status.indicator === 'string' ? status.indicator : 'none';
52
+ const description = typeof status.description === 'string' ? status.description : '';
53
+
54
+ const window = typeof resolvedWindowMs === 'number' ? resolvedWindowMs : DEFAULT_RESOLVED_WINDOW_MS;
55
+ const rawIncidents = Array.isArray(payload.incidents) ? payload.incidents : [];
56
+
57
+ const incidents = [];
58
+ const recentlyResolved = [];
59
+ for (const inc of rawIncidents) {
60
+ if (!inc || typeof inc.id !== 'string') continue;
61
+ const normal = {
62
+ id: inc.id,
63
+ name: typeof inc.name === 'string' ? inc.name : 'Unknown incident',
64
+ status: typeof inc.status === 'string' ? inc.status : 'unknown',
65
+ impact: typeof inc.impact === 'string' ? inc.impact : 'none',
66
+ startedAt: typeof inc.started_at === 'string' ? inc.started_at : null,
67
+ updatedAt: typeof inc.updated_at === 'string' ? inc.updated_at : null,
68
+ resolvedAt: typeof inc.resolved_at === 'string' ? inc.resolved_at : null,
69
+ url: typeof inc.shortlink === 'string' && inc.shortlink
70
+ ? inc.shortlink
71
+ : (typeof inc.url === 'string' ? inc.url : null),
72
+ };
73
+ if (OPEN_STATUSES.has(normal.status)) {
74
+ incidents.push({
75
+ id: normal.id,
76
+ name: normal.name,
77
+ status: normal.status,
78
+ impact: normal.impact,
79
+ startedAt: normal.startedAt,
80
+ updatedAt: normal.updatedAt,
81
+ url: normal.url,
82
+ });
83
+ } else if (normal.status === 'resolved' && normal.resolvedAt) {
84
+ const resolvedMs = Date.parse(normal.resolvedAt);
85
+ if (!Number.isNaN(resolvedMs) && (nowMs - resolvedMs) <= window) {
86
+ recentlyResolved.push({
87
+ id: normal.id,
88
+ name: normal.name,
89
+ resolvedAt: normal.resolvedAt,
90
+ url: normal.url,
91
+ });
92
+ }
93
+ }
94
+ }
95
+
96
+ return {
97
+ id: source.id,
98
+ name: source.name,
99
+ sourceUrl: source.url,
100
+ overall: { indicator, description },
101
+ incidents,
102
+ recentlyResolved,
103
+ };
104
+ }
105
+
106
+ /**
107
+ * Poll all configured sources and build a state payload. Uses the injected
108
+ * fetcher so production code passes `globalThis.fetch` and tests pass a
109
+ * deterministic stub. Never throws — per-source failure is captured in the
110
+ * source slice as `fetchError` and the overall indicator defaults to 'none'
111
+ * so the banner degrades gracefully.
112
+ *
113
+ * @param {object} options
114
+ * @param {Array<{id:string,name:string,url:string}>} options.sources
115
+ * @param {(url:string)=>Promise<Response>} options.fetcher
116
+ * @param {number} options.nowMs
117
+ * @param {number} [options.timeoutMs] Abort fetches after this many ms.
118
+ * @returns {Promise<object>}
119
+ */
120
+ export async function poll({ sources, fetcher, nowMs, timeoutMs }) {
121
+ const effectiveTimeout = typeof timeoutMs === 'number' ? timeoutMs : 10_000;
122
+ const list = Array.isArray(sources) && sources.length > 0 ? sources : DEFAULT_SOURCES;
123
+ const results = await Promise.all(list.map(async (source) => {
124
+ const slice = {
125
+ id: source.id,
126
+ name: source.name,
127
+ sourceUrl: source.url,
128
+ overall: { indicator: 'none', description: '' },
129
+ incidents: [],
130
+ recentlyResolved: [],
131
+ };
132
+ try {
133
+ const controller = new AbortController();
134
+ const timer = setTimeout(() => controller.abort(), effectiveTimeout);
135
+ let res;
136
+ try {
137
+ res = await fetcher(source.url, { signal: controller.signal });
138
+ } finally {
139
+ clearTimeout(timer);
140
+ }
141
+ if (!res || !res.ok) {
142
+ slice.fetchError = res ? `HTTP ${res.status}` : 'no response';
143
+ return slice;
144
+ }
145
+ const payload = await res.json();
146
+ const normalised = normaliseSummary(source, payload, nowMs);
147
+ if (!normalised) {
148
+ slice.fetchError = 'unusable payload';
149
+ return slice;
150
+ }
151
+ return normalised;
152
+ } catch (err) {
153
+ slice.fetchError = err && err.message ? err.message : String(err);
154
+ return slice;
155
+ }
156
+ }));
157
+
158
+ const polledAt = new Date(nowMs).toISOString();
159
+ const anyOk = results.some((r) => !r.fetchError);
160
+ const state = {
161
+ polledAt,
162
+ sources: results,
163
+ };
164
+ if (anyOk) state.lastSuccessfulPollAt = polledAt;
165
+ return state;
166
+ }
167
+
168
+ /**
169
+ * Merge a fresh poll result with the previously-persisted state. The goal is
170
+ * graceful degradation: when a source fetch fails this pass but succeeded
171
+ * last pass, keep showing the last-known-good slice (with its age carried in
172
+ * `lastSuccessfulPollAt` at top level) rather than flipping the banner to
173
+ * 'unknown'. Per-source `fetchError` is preserved on the latest attempt so
174
+ * consumers can distinguish stale-but-known from never-fetched.
175
+ *
176
+ * @param {object|null} previous Previous state file contents, or null.
177
+ * @param {object} fresh Result of poll().
178
+ * @returns {object}
179
+ */
180
+ export function mergeWithPrevious(previous, fresh) {
181
+ if (!previous || !Array.isArray(previous.sources)) return fresh;
182
+ const merged = { ...fresh, sources: [] };
183
+ for (const freshSlice of fresh.sources) {
184
+ if (freshSlice.fetchError) {
185
+ const prev = previous.sources.find((s) => s.id === freshSlice.id);
186
+ if (prev && !prev.fetchError) {
187
+ merged.sources.push({
188
+ ...prev,
189
+ sourceUrl: freshSlice.sourceUrl,
190
+ fetchError: freshSlice.fetchError,
191
+ stale: true,
192
+ });
193
+ continue;
194
+ }
195
+ }
196
+ merged.sources.push(freshSlice);
197
+ }
198
+ // Carry forward lastSuccessfulPollAt when the fresh poll had no successes.
199
+ if (!merged.lastSuccessfulPollAt && previous.lastSuccessfulPollAt) {
200
+ merged.lastSuccessfulPollAt = previous.lastSuccessfulPollAt;
201
+ }
202
+ return merged;
203
+ }
204
+
205
+ /**
206
+ * Load sources from a preferences.json object. Falls back to defaults when
207
+ * the key is missing or malformed. Validates each entry has { id, name, url }.
208
+ *
209
+ * @param {object|null} prefs Parsed preferences.json, or null.
210
+ * @returns {Array<{id:string,name:string,url:string}>}
211
+ */
212
+ export function resolveSources(prefs) {
213
+ if (!prefs || typeof prefs !== 'object') return DEFAULT_SOURCES;
214
+ const configured = prefs.statusMonSources;
215
+ if (!Array.isArray(configured) || configured.length === 0) return DEFAULT_SOURCES;
216
+ const valid = configured.filter((s) =>
217
+ s && typeof s.id === 'string' && typeof s.name === 'string' && typeof s.url === 'string',
218
+ );
219
+ return valid.length > 0 ? valid : DEFAULT_SOURCES;
220
+ }
@@ -0,0 +1,113 @@
1
+ /**
2
+ * poller.mjs — Server-side poller lifecycle for the workspace.
3
+ *
4
+ * The workspace server imports `startPoller({ repoRoot })` on boot. The
5
+ * returned handle exposes `stop()` for graceful shutdown. The poller writes
6
+ * the shared state file every `intervalMs` (default 60s); the banner client
7
+ * reads it via the /__api/status-mon endpoint.
8
+ *
9
+ * This module lives alongside poll.mjs so the (A) server-side integration
10
+ * and the (B) CLI path share the exact same polling + normalisation logic.
11
+ */
12
+
13
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
14
+ import { dirname, join } from 'node:path';
15
+ import { poll, resolveSources, mergeWithPrevious } from './poll.mjs';
16
+
17
+ const DEFAULT_INTERVAL_MS = 60_000;
18
+
19
+ function readPreferences(repoRoot) {
20
+ try {
21
+ const prefsPath = join(repoRoot, 'operator', 'config', 'preferences.json');
22
+ if (!existsSync(prefsPath)) return null;
23
+ return JSON.parse(readFileSync(prefsPath, 'utf-8'));
24
+ } catch {
25
+ return null;
26
+ }
27
+ }
28
+
29
+ function readState(statePath) {
30
+ try {
31
+ if (!existsSync(statePath)) return null;
32
+ return JSON.parse(readFileSync(statePath, 'utf-8'));
33
+ } catch {
34
+ return null;
35
+ }
36
+ }
37
+
38
+ function writeState(statePath, state) {
39
+ mkdirSync(dirname(statePath), { recursive: true });
40
+ writeFileSync(statePath, JSON.stringify(state, null, 2) + '\n', 'utf-8');
41
+ }
42
+
43
+ /**
44
+ * Start the poller loop.
45
+ *
46
+ * @param {object} options
47
+ * @param {string} options.repoRoot Absolute path to project root.
48
+ * @param {number} [options.intervalMs] Poll cadence (default 60s).
49
+ * @param {string} [options.statePath] Override state file location.
50
+ * @param {Function} [options.fetcher] Injected fetcher (default globalThis.fetch).
51
+ * @param {Function} [options.onError] Called on unexpected poll errors.
52
+ * @param {boolean} [options.runImmediately] If true, runs the first poll now (default true).
53
+ * @returns {{ stop: () => void, triggerNow: () => Promise<object> }}
54
+ */
55
+ export function startPoller(options) {
56
+ const repoRoot = options.repoRoot;
57
+ if (!repoRoot) throw new Error('startPoller: repoRoot is required');
58
+ const intervalMs = options.intervalMs || DEFAULT_INTERVAL_MS;
59
+ const statePath = options.statePath || join(repoRoot, '.state', 'status-mon.json');
60
+ const fetcher = options.fetcher || globalThis.fetch;
61
+ const onError = options.onError || function () {};
62
+ const runImmediately = options.runImmediately !== false;
63
+
64
+ let stopped = false;
65
+ let timer = null;
66
+ let inflight = null;
67
+
68
+ async function runOnce() {
69
+ if (stopped) return null;
70
+ try {
71
+ const prefs = readPreferences(repoRoot);
72
+ const sources = resolveSources(prefs);
73
+ const previous = readState(statePath);
74
+ const fresh = await poll({ sources, fetcher, nowMs: Date.now() });
75
+ const state = mergeWithPrevious(previous, fresh);
76
+ writeState(statePath, state);
77
+ return state;
78
+ } catch (err) {
79
+ try { onError(err); } catch { /* user hook must not crash the loop */ }
80
+ return null;
81
+ }
82
+ }
83
+
84
+ function schedule() {
85
+ if (stopped) return;
86
+ timer = setTimeout(async function tick() {
87
+ inflight = runOnce();
88
+ try { await inflight; } finally { inflight = null; schedule(); }
89
+ }, intervalMs);
90
+ if (timer && typeof timer.unref === 'function') timer.unref();
91
+ }
92
+
93
+ function triggerNow() {
94
+ inflight = runOnce();
95
+ return inflight;
96
+ }
97
+
98
+ if (runImmediately) {
99
+ // Kick off a first poll out-of-band so the banner has data before the
100
+ // first interval elapses. We don't await — boot shouldn't block on
101
+ // network. The result lands in the state file when it's ready.
102
+ triggerNow();
103
+ }
104
+ schedule();
105
+
106
+ return {
107
+ stop() {
108
+ stopped = true;
109
+ if (timer) { clearTimeout(timer); timer = null; }
110
+ },
111
+ triggerNow,
112
+ };
113
+ }
@@ -0,0 +1,133 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * run.mjs — One-shot CLI wrapper for the status-mon poller.
4
+ *
5
+ * Writes the state file to $DAVE_ROOT/.state/status-mon.json by default.
6
+ * Intended to be invoked either:
7
+ * - directly on a schedule (schedules/status-mon.json) via the OS scheduler
8
+ * - by tests (via `--out <path>` to redirect the write target)
9
+ *
10
+ * The workspace server's server-side integration (see server.mjs / poller.mjs)
11
+ * imports poll.mjs directly rather than spawning this script, because it
12
+ * already has the repo root resolved and the in-memory state is cheaper than
13
+ * a subprocess round-trip.
14
+ *
15
+ * run.mjs Run a live poll against configured sources.
16
+ * run.mjs --dry-run Fetch, write to stdout as JSON, don't touch fs.
17
+ * run.mjs --out PATH Write state to PATH (overrides default).
18
+ * run.mjs --help Show this help.
19
+ *
20
+ * Environment:
21
+ * DAVE_ROOT Override the project root (default: derived by walking up to .git).
22
+ *
23
+ * Exit codes: 0 ok | 1 usage | 2 fetch failure (all sources) | 3 write failure
24
+ */
25
+
26
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
27
+ import { dirname, join, resolve } from 'node:path';
28
+ import { fileURLToPath } from 'node:url';
29
+
30
+ import { poll, resolveSources, mergeWithPrevious } from './poll.mjs';
31
+
32
+ const __filename = fileURLToPath(import.meta.url);
33
+ const __dirname = dirname(__filename);
34
+
35
+ function printHelp() {
36
+ const help = [
37
+ 'Usage: run.mjs [--dry-run] [--out PATH] [--help]',
38
+ '',
39
+ 'Polls configured Statuspage.io sources and writes a state file.',
40
+ '',
41
+ 'Default output path: $DAVE_ROOT/.state/status-mon.json',
42
+ 'Override sources via operator/config/preferences.json (statusMonSources).',
43
+ ].join('\n');
44
+ process.stdout.write(help + '\n');
45
+ }
46
+
47
+ function parseArgs(argv) {
48
+ const out = { dryRun: false, help: false, outPath: null };
49
+ for (let i = 0; i < argv.length; i++) {
50
+ const arg = argv[i];
51
+ if (arg === '--help' || arg === '-h') out.help = true;
52
+ else if (arg === '--dry-run') out.dryRun = true;
53
+ else if (arg === '--out') { out.outPath = argv[++i]; }
54
+ else {
55
+ process.stderr.write(`unknown argument: ${arg}\n`);
56
+ return null;
57
+ }
58
+ }
59
+ return out;
60
+ }
61
+
62
+ function findRepoRoot() {
63
+ if (process.env.DAVE_ROOT) return process.env.DAVE_ROOT;
64
+ let dir = __dirname;
65
+ while (dir !== '/' && dir !== '.') {
66
+ if (existsSync(join(dir, '.git'))) return dir;
67
+ const parent = dirname(dir);
68
+ if (parent === dir) break;
69
+ dir = parent;
70
+ }
71
+ return resolve(__dirname, '..', '..', '..');
72
+ }
73
+
74
+ function readPreviousState(statePath) {
75
+ try {
76
+ if (!existsSync(statePath)) return null;
77
+ const raw = readFileSync(statePath, 'utf-8');
78
+ return JSON.parse(raw);
79
+ } catch {
80
+ return null;
81
+ }
82
+ }
83
+
84
+ function readPreferences(repoRoot) {
85
+ try {
86
+ const prefsPath = join(repoRoot, 'operator', 'config', 'preferences.json');
87
+ if (!existsSync(prefsPath)) return null;
88
+ return JSON.parse(readFileSync(prefsPath, 'utf-8'));
89
+ } catch {
90
+ return null;
91
+ }
92
+ }
93
+
94
+ async function main() {
95
+ const parsed = parseArgs(process.argv.slice(2));
96
+ if (!parsed) { printHelp(); process.exit(1); }
97
+ if (parsed.help) { printHelp(); process.exit(0); }
98
+
99
+ const repoRoot = findRepoRoot();
100
+ const prefs = readPreferences(repoRoot);
101
+ const sources = resolveSources(prefs);
102
+ const outPath = parsed.outPath || join(repoRoot, '.state', 'status-mon.json');
103
+
104
+ const previous = parsed.dryRun ? null : readPreviousState(outPath);
105
+ const fresh = await poll({
106
+ sources,
107
+ fetcher: globalThis.fetch,
108
+ nowMs: Date.now(),
109
+ });
110
+ const state = mergeWithPrevious(previous, fresh);
111
+
112
+ const allFailed = state.sources.every((s) => s.fetchError);
113
+
114
+ if (parsed.dryRun) {
115
+ process.stdout.write(JSON.stringify(state, null, 2) + '\n');
116
+ process.exit(allFailed && !state.lastSuccessfulPollAt ? 2 : 0);
117
+ }
118
+
119
+ try {
120
+ mkdirSync(dirname(outPath), { recursive: true });
121
+ writeFileSync(outPath, JSON.stringify(state, null, 2) + '\n', 'utf-8');
122
+ } catch (err) {
123
+ process.stderr.write(`write failed: ${err.message}\n`);
124
+ process.exit(3);
125
+ }
126
+
127
+ process.exit(allFailed && !state.lastSuccessfulPollAt ? 2 : 0);
128
+ }
129
+
130
+ main().catch((err) => {
131
+ process.stderr.write(`unexpected: ${err && err.stack ? err.stack : err}\n`);
132
+ process.exit(1);
133
+ });