@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,199 @@
1
+ // checks.mjs — domain definitions for the smoke suite.
2
+ import { PA_PACKAGE_NAME } from '../../../engineering-pa-core/src/config/pa-package-name.mjs';
3
+
4
+ //
5
+ // v2: the smoke suite validates a v2 operator-instance layout. There are
6
+ // two distinct shapes the operator repo can be in, each with different
7
+ // expectations:
8
+ //
9
+ // • fresh-scaffold — the post-`pa-init --mode=solo` shape. Operator
10
+ // content is empty except for `.gitkeep` markers; node_modules is
11
+ // present from `pnpm install`. This mode is exercised when an
12
+ // operator first stands up the platform on a new host.
13
+ //
14
+ // • live-repo — a populated operator repo with real work items,
15
+ // projects, profile content, etc. The `.gitkeep` markers may have
16
+ // been removed once real files exist in each directory. This is
17
+ // the day-to-day operator-machine shape.
18
+ //
19
+ // Mode selection is plumbed in cli.mjs (`--mode=fresh-scaffold|live-repo`,
20
+ // default `live-repo`). Each mode builds its own check plan via
21
+ // `buildCheckPlan(mode)`.
22
+ //
23
+ // Check classes:
24
+ //
25
+ // path — path exists (file or dir)
26
+ // dirExists — directory exists (alias of path for clarity)
27
+ // dirNotEmpty — directory exists AND contains at least one entry
28
+ // pkgInstalled — node_modules/@stravica-ai/digital-operator-pa* present
29
+ // serverReady — workspace server started on port N
30
+ // httpStatus — GET url returns a specific status code
31
+ // jsonValid — GET url returns parseable JSON
32
+ // cliExit — running `<bin> --help` exits 0
33
+ // vaultExit — `secrets` exits 0 or 1 (no vault yet is fine)
34
+
35
+ /**
36
+ * Fresh-scaffold paths verified on disk. These are the v2 operator-instance
37
+ * shape produced by `pa-init --mode=solo`, with `.gitkeep` markers in every
38
+ * directory before the operator has populated them. Paths are
39
+ * operator-tree-relative.
40
+ */
41
+ export const EXPECTED_PATHS_FRESH_SCAFFOLD = [
42
+ // Operator content scaffold.
43
+ 'operator/.gitkeep',
44
+ 'operator/profile/.gitkeep',
45
+ 'operator/knowledge/.gitkeep',
46
+ 'operator/notes/.gitkeep',
47
+ 'operator/extensions/.gitkeep',
48
+ // Work and projects.
49
+ 'work/.gitkeep',
50
+ 'projects/.gitkeep',
51
+ // Schedules (gitkept folder, individual schedules created on demand).
52
+ 'schedules/.gitkeep',
53
+ // Root files an operator repo always carries.
54
+ 'CLAUDE.md',
55
+ 'package.json',
56
+ '.gitignore',
57
+ ];
58
+
59
+ /**
60
+ * Backwards-compat alias — pre-v0.1.3 callers and tests reference
61
+ * EXPECTED_PATHS. Keep the alias pointing at the fresh-scaffold list since
62
+ * that's the shape the existing tests exercise.
63
+ */
64
+ export const EXPECTED_PATHS = EXPECTED_PATHS_FRESH_SCAFFOLD;
65
+
66
+ /**
67
+ * Live-repo paths verified on disk. Same operator scaffold but expressed as
68
+ * directories (not `.gitkeep` markers) — operator activity may have removed
69
+ * the markers once real files arrived. The root files are unchanged.
70
+ */
71
+ export const EXPECTED_PATHS_LIVE_REPO_DIRS = [
72
+ 'operator',
73
+ 'operator/profile',
74
+ 'operator/knowledge',
75
+ 'operator/notes',
76
+ 'operator/extensions',
77
+ 'work',
78
+ 'projects',
79
+ 'schedules',
80
+ ];
81
+
82
+ export const EXPECTED_PATHS_LIVE_REPO_FILES = [
83
+ 'CLAUDE.md',
84
+ 'package.json',
85
+ '.gitignore',
86
+ ];
87
+
88
+ /**
89
+ * Bundled package install paths verified on disk. These point inside
90
+ * node_modules — the package is read-only on the operator's machine.
91
+ */
92
+ export const EXPECTED_PACKAGE_PATHS = [
93
+ `node_modules/${PA_PACKAGE_NAME}/package.json`,
94
+ ];
95
+
96
+ /** HTML pages verified over HTTP. Labels mirror the operator UX. */
97
+ export const HTML_PAGES = [
98
+ { label: '/ (shell)', path: '/' },
99
+ { label: '/home.html', path: '/home.html' },
100
+ { label: '/onboarding.html', path: '/onboarding.html' },
101
+ { label: '/tasks.html', path: '/tasks.html' },
102
+ { label: '/knowledge.html', path: '/knowledge.html' },
103
+ { label: '/secrets.html', path: '/secrets.html' },
104
+ { label: '/viewer.html', path: '/viewer.html' },
105
+ ];
106
+
107
+ /** JSON API endpoints exercised by the smoke suite. */
108
+ export const API_ENDPOINTS = [
109
+ '/__api/overview',
110
+ '/__api/projects',
111
+ '/__api/work',
112
+ ];
113
+
114
+ /**
115
+ * CLI --help invocations. In v2 these are installed bin shims; the smoke
116
+ * runner resolves them via `node_modules/.bin/<name>` rather than absolute
117
+ * repo paths.
118
+ */
119
+ export const CLI_HELP_TOOLS = [
120
+ { name: 'desk --help', binName: 'desk' },
121
+ { name: 'distill --help', binName: 'distill' },
122
+ { name: 'memory-sync --help', binName: 'memory-sync' },
123
+ { name: 'sync --help', binName: 'sync' },
124
+ { name: 'scheduler --help', binName: 'scheduler' },
125
+ { name: 'pa --help', binName: 'pa' },
126
+ { name: 'slice --help', binName: 'slice' },
127
+ ];
128
+
129
+ /** Test port for the workspace server. */
130
+ export const TEST_PORT = 4201;
131
+
132
+ /**
133
+ * Build the complete check plan. Returns an array of check descriptors in
134
+ * a stable order:
135
+ *
136
+ * 1. Operator-content paths
137
+ * 2. Package install paths
138
+ * 3. Server boot
139
+ * 4. HTML pages (gated on server)
140
+ * 5. JSON endpoints (gated on server)
141
+ * 6. CLI --help (one per bin shim)
142
+ * 7. Secrets exit-code probe
143
+ *
144
+ * @param {object} [opts]
145
+ * @param {'fresh-scaffold'|'live-repo'} [opts.mode] — defaults to fresh-scaffold
146
+ * for backwards compatibility with v0.1.2-era callers and tests. The
147
+ * CLI defaults to 'live-repo' for operator-machine usage.
148
+ */
149
+ export function buildCheckPlan(opts = {}) {
150
+ const mode = opts.mode ?? 'fresh-scaffold';
151
+ const plan = [];
152
+
153
+ if (mode === 'live-repo') {
154
+ // In live-repo mode, directories must exist (any contents OK) and root
155
+ // files must exist. We never assert on `.gitkeep` markers because real
156
+ // operator content may have evicted them.
157
+ for (const p of EXPECTED_PATHS_LIVE_REPO_DIRS) {
158
+ plan.push({ id: `path-${p}`, class: 'path', path: p, label: `directory exists: ${p}` });
159
+ }
160
+ for (const p of EXPECTED_PATHS_LIVE_REPO_FILES) {
161
+ plan.push({ id: `path-${p}`, class: 'path', path: p, label: `path exists: ${p}` });
162
+ }
163
+ } else {
164
+ // fresh-scaffold (default for backwards compat).
165
+ for (const p of EXPECTED_PATHS_FRESH_SCAFFOLD) {
166
+ plan.push({ id: `path-${p}`, class: 'path', path: p, label: `path exists: ${p}` });
167
+ }
168
+ }
169
+
170
+ for (const p of EXPECTED_PACKAGE_PATHS) {
171
+ plan.push({ id: `pkg-${p}`, class: 'pkgInstalled', path: p, label: `package installed: ${p}` });
172
+ }
173
+
174
+ plan.push({ id: 'server-ready', class: 'serverReady', port: TEST_PORT, label: `workspace server started on port ${TEST_PORT}` });
175
+
176
+ for (const page of HTML_PAGES) {
177
+ plan.push({ id: `http-${page.path}`, class: 'httpStatus', path: page.path, expect: 200, label: `HTTP 200: ${page.label}`, requires: 'server' });
178
+ }
179
+
180
+ for (const ep of API_ENDPOINTS) {
181
+ plan.push({ id: `json-${ep}`, class: 'jsonValid', path: ep, label: `valid JSON: ${ep}`, requires: 'server' });
182
+ }
183
+
184
+ for (const tool of CLI_HELP_TOOLS) {
185
+ plan.push({ id: `cli-${tool.binName}`, class: 'cliExit', binName: tool.binName, label: `CLI exits 0: ${tool.name}` });
186
+ }
187
+
188
+ plan.push({ id: 'vault', class: 'vaultExit', binName: 'secrets', label: 'secrets runs' });
189
+
190
+ return plan;
191
+ }
192
+
193
+ /**
194
+ * Render the full JSON-endpoint URL for a given port and path.
195
+ * Centralised here so checks and tests see the same construction.
196
+ */
197
+ export function apiUrl(port, path) {
198
+ return `http://localhost:${port}${path}`;
199
+ }
@@ -0,0 +1,108 @@
1
+ // cli.mjs — arg parsing, exit-code translation, usage.
2
+ //
3
+ // The smoke tool has a single default verb: run. It is invoked via
4
+ // `npm run test:smoke` which resolves to `node core/tools/smoke/bin/smoke`.
5
+ //
6
+ // Exit codes (see README §Exit codes):
7
+ // 0 all checks passed
8
+ // 1 one or more checks failed
9
+ // 2 internal error (uncaught exception)
10
+ // 3 IO / transport failure during setup (tempdir, copy, server spawn)
11
+
12
+ import { parseArgs } from 'node:util';
13
+ import { fileURLToPath } from 'node:url';
14
+ import { dirname, resolve } from 'node:path';
15
+ import { PA_PACKAGE_NAME } from '../../../engineering-pa-core/src/config/pa-package-name.mjs';
16
+ import { runSmoke } from './commands/run.mjs';
17
+
18
+ const USAGE = `
19
+ smoke — operator-instance smoke suite for the v2 platform
20
+
21
+ Usage:
22
+ smoke Run the live-repo suite against the auto-detected root
23
+ smoke --mode <mode> 'live-repo' (default) or 'fresh-scaffold'
24
+ smoke --root <path> Repo root (default: auto-detect)
25
+ smoke --port <n> HTTP port for the workspace server (default: 4201)
26
+ smoke -h, --help Show this help
27
+
28
+ Modes:
29
+ live-repo Probe a populated operator repo in-place — no tempdir copy.
30
+ Asserts that operator/ subdirs exist (any contents), required
31
+ root files are present, the installed ${PA_PACKAGE_NAME}
32
+ package is reachable, the workspace server starts, the API
33
+ responds, and every published bin shim returns exit 0 on --help.
34
+
35
+ fresh-scaffold Verify the layout produced by 'pa-init --mode=solo' on a
36
+ freshly-scaffolded operator repo. Asserts the .gitkeep
37
+ markers, root files, the installed package, and the same
38
+ HTTP/CLI surfaces. Copies the source tree into a tempdir
39
+ to keep the original untouched.
40
+
41
+ Exit codes:
42
+ 0 all checks passed
43
+ 1 one or more checks failed
44
+ 2 internal error
45
+ 3 IO / transport failure (tempdir, copy, server launch)
46
+ `;
47
+
48
+ const VALID_MODES = new Set(['live-repo', 'fresh-scaffold']);
49
+
50
+ export async function run(argv) {
51
+ let parsed;
52
+ try {
53
+ parsed = parseArgs({
54
+ args: argv,
55
+ options: {
56
+ help: { type: 'boolean', short: 'h' },
57
+ root: { type: 'string' },
58
+ port: { type: 'string' },
59
+ mode: { type: 'string' },
60
+ },
61
+ strict: true,
62
+ allowPositionals: false,
63
+ });
64
+ } catch (err) {
65
+ console.error(`smoke: ${err.message}`);
66
+ console.error('Run `smoke --help` for usage.');
67
+ return 1;
68
+ }
69
+
70
+ if (parsed.values.help) {
71
+ console.log(USAGE.trim());
72
+ return 0;
73
+ }
74
+
75
+ const mode = parsed.values.mode ?? 'live-repo';
76
+ if (!VALID_MODES.has(mode)) {
77
+ console.error(`smoke: invalid --mode value: ${mode}. Must be one of: ${[...VALID_MODES].join(', ')}`);
78
+ return 1;
79
+ }
80
+
81
+ const repoRoot = parsed.values.root
82
+ ? resolve(parsed.values.root)
83
+ : autoDetectRepoRoot();
84
+
85
+ const port = parsed.values.port ? Number(parsed.values.port) : undefined;
86
+ if (port != null && (!Number.isInteger(port) || port <= 0 || port > 65535)) {
87
+ console.error(`smoke: invalid port: ${parsed.values.port}`);
88
+ return 1;
89
+ }
90
+
91
+ try {
92
+ const result = await runSmoke(repoRoot, { port, mode });
93
+ return result.exitCode;
94
+ } catch (err) {
95
+ console.error(`smoke: ${err.message || err}`);
96
+ return 3;
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Auto-detect the repo root. The binary lives at
102
+ * `<root>/core/tools/smoke/bin/smoke`, so the root is four levels up
103
+ * from this module.
104
+ */
105
+ function autoDetectRepoRoot() {
106
+ const here = dirname(fileURLToPath(import.meta.url));
107
+ return resolve(here, '..', '..', '..', '..');
108
+ }
@@ -0,0 +1,237 @@
1
+ // commands/run.mjs — orchestrate the full smoke suite.
2
+ //
3
+ // Flow (mirrors test/smoke.sh):
4
+ // 1. mktemp and copy the repo (excluding .git, node_modules)
5
+ // 2. cd (conceptually) into the temp dir
6
+ // 3. Run path checks
7
+ // 4. Launch the workspace server, wait for ready
8
+ // 5. Run HTTP / JSON checks (gated on ready)
9
+ // 6. Run CLI --help checks
10
+ // 7. Run secrets check
11
+ // 8. Run dave.sh --help check
12
+ // 9. Cleanup (kill server, remove temp dir)
13
+ // 10. Print PASS/FAIL lines and summary, return exit code
14
+
15
+ import { resolve as pathResolve } from 'node:path';
16
+ import { existsSync } from 'node:fs';
17
+ import {
18
+ spawnProcess,
19
+ launchProcess,
20
+ killProcess,
21
+ makeTempDir,
22
+ removeDir,
23
+ copyTree,
24
+ pathExists,
25
+ pathExecutable,
26
+ waitForHttp,
27
+ httpGet,
28
+ } from '../runner.mjs';
29
+ import { PA_PACKAGE_NAME } from '../../../../engineering-pa-core/src/config/pa-package-name.mjs';
30
+ import { buildCheckPlan, apiUrl, TEST_PORT } from '../checks.mjs';
31
+
32
+ /**
33
+ * Run the full smoke suite against `repoRoot`.
34
+ * Returns { pass, fail, results, exitCode }.
35
+ *
36
+ * `opts.runner` (optional) injects a fake for unit tests.
37
+ * `opts.mode` ('live-repo' | 'fresh-scaffold') — default 'fresh-scaffold'
38
+ * to preserve the pre-v0.1.3 calling convention (the CLI overrides to
39
+ * 'live-repo'). Live-repo mode runs against the source root in-place
40
+ * (no tempdir copy) because copying excludes node_modules and breaks
41
+ * every CLI/cliExit probe against the destination.
42
+ */
43
+ export async function runSmoke(repoRoot, opts = {}) {
44
+ const log = opts.log ?? ((line) => console.log(line));
45
+ const io = opts.runner ?? defaultRunner();
46
+ const port = opts.port ?? TEST_PORT;
47
+ const mode = opts.mode ?? 'fresh-scaffold';
48
+
49
+ const absRoot = pathResolve(repoRoot);
50
+ // Live-repo runs in-place; fresh-scaffold copies into a tempdir.
51
+ const useTempDir = mode !== 'live-repo';
52
+ const tempDir = useTempDir ? await io.makeTempDir() : null;
53
+ const workRoot = useTempDir ? tempDir : absRoot;
54
+ let serverChild = null;
55
+ const results = [];
56
+
57
+ try {
58
+ if (useTempDir) {
59
+ await io.copyTree(absRoot, tempDir);
60
+ }
61
+
62
+ const plan = buildCheckPlan({ mode });
63
+ let serverReady = false;
64
+
65
+ for (const check of plan) {
66
+ // Lazy-launch the server the first time we hit a server-ready check.
67
+ if (check.class === 'serverReady') {
68
+ serverChild = io.launchWorkspace(workRoot, port);
69
+ const url = apiUrl(port, '/');
70
+ serverReady = await io.waitForHttp(url);
71
+ results.push(record(check, serverReady));
72
+ log(line(check, serverReady));
73
+ continue;
74
+ }
75
+
76
+ // HTTP / JSON checks are skipped if the server never came up.
77
+ if (check.requires === 'server' && !serverReady) {
78
+ continue;
79
+ }
80
+
81
+ const ok = await runCheck(check, workRoot, port, io);
82
+ results.push(record(check, ok));
83
+ log(line(check, ok));
84
+ }
85
+
86
+ const pass = results.filter((r) => r.ok).length;
87
+ const fail = results.filter((r) => !r.ok).length;
88
+ const total = pass + fail;
89
+
90
+ log('');
91
+ log('========================================');
92
+ log(`${pass}/${total} passed`);
93
+ if (fail > 0) {
94
+ log(`${fail} test(s) failed`);
95
+ return { pass, fail, results, exitCode: 1 };
96
+ }
97
+ log('All tests passed');
98
+ return { pass, fail, results, exitCode: 0 };
99
+ } finally {
100
+ if (serverChild) await io.killProcess(serverChild);
101
+ if (useTempDir) await io.removeDir(tempDir);
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Execute a single check. Returns a boolean pass/fail.
107
+ */
108
+ async function runCheck(check, root, port, io) {
109
+ switch (check.class) {
110
+ case 'execFile':
111
+ return io.pathExecutable(pathJoin(root, check.path));
112
+
113
+ case 'file':
114
+ case 'path':
115
+ return io.pathExists(pathJoin(root, check.path));
116
+
117
+ case 'httpStatus': {
118
+ const res = await io.httpGet(apiUrl(port, check.path));
119
+ return res.status === check.expect;
120
+ }
121
+
122
+ case 'jsonValid': {
123
+ const res = await io.httpGet(apiUrl(port, check.path));
124
+ try { JSON.parse(res.body); return true; } catch { return false; }
125
+ }
126
+
127
+ case 'cliExit': {
128
+ // v2: invoke via the installed bin shim. Under pnpm's hoisted layout
129
+ // there is no `node_modules/.bin/<name>` symlink adjacent to the
130
+ // operator-repo root (the .bin lives off the @stravica-ai/digital-operator-pa
131
+ // package's own node_modules, not the operator repo's). Resolve to the
132
+ // package's `bin/<name>` shim instead — that is the canonical entry
133
+ // point for published commands.
134
+ const bin = await resolveBin(root, check.binName, io);
135
+ if (!bin) return false;
136
+ const res = await io.spawnProcess(bin, ['--help'], { cwd: root, timeoutMs: 15000 });
137
+ return res.code === 0;
138
+ }
139
+
140
+ case 'vaultExit': {
141
+ const bin = await resolveBin(root, check.binName ?? 'secrets', io);
142
+ if (!bin) return false;
143
+ const res = await io.spawnProcess(bin, [], { cwd: root, timeoutMs: 15000 });
144
+ return res.code === 0 || res.code === 1;
145
+ }
146
+
147
+ case 'pkgInstalled':
148
+ return io.pathExists(pathJoin(root, check.path));
149
+
150
+ case 'cliShell': {
151
+ // v1-compat — no v2 check uses this class but the runner remains
152
+ // backwards-compatible for operator-extension smoke suites that
153
+ // drop in their own check sets.
154
+ const res = await io.spawnProcess('bash', [check.path, '--help'], { cwd: root, timeoutMs: 15000 });
155
+ return res.code === 0;
156
+ }
157
+
158
+ default:
159
+ throw new Error(`smoke: unknown check class: ${check.class}`);
160
+ }
161
+ }
162
+
163
+ function record(check, ok) {
164
+ return { id: check.id, class: check.class, label: check.label, ok };
165
+ }
166
+
167
+ function line(check, ok) {
168
+ return `${ok ? 'PASS' : 'FAIL'}: ${check.label}`;
169
+ }
170
+
171
+ function pathJoin(root, p) {
172
+ return `${root}/${p}`;
173
+ }
174
+
175
+ /**
176
+ * Resolve a published bin shim for a given command. We try, in order:
177
+ *
178
+ * 1. node_modules/@stravica-ai/digital-operator-pa/bin/<name> — canonical v2 path
179
+ * 2. node_modules/.bin/<name> — pnpm-symlinked
180
+ *
181
+ * Returns the first absolute path that exists, or null if neither does.
182
+ * The lookup uses the injected runner so tests can fake it without
183
+ * touching disk.
184
+ */
185
+ async function resolveBin(root, name, io) {
186
+ const candidates = [
187
+ pathJoin(root, `node_modules/${PA_PACKAGE_NAME}/bin/${name}`),
188
+ pathJoin(root, `node_modules/.bin/${name}`),
189
+ ];
190
+ for (const candidate of candidates) {
191
+ // eslint-disable-next-line no-await-in-loop
192
+ if (await io.pathExists(candidate)) return candidate;
193
+ }
194
+ return null;
195
+ }
196
+
197
+ /**
198
+ * Default runner — the production chokepoint bindings. Tests pass their
199
+ * own object matching this shape to avoid touching the filesystem / network.
200
+ */
201
+ function defaultRunner() {
202
+ return {
203
+ makeTempDir,
204
+ removeDir,
205
+ copyTree,
206
+ pathExists,
207
+ pathExecutable,
208
+ waitForHttp,
209
+ httpGet,
210
+ spawnProcess,
211
+ killProcess,
212
+ launchWorkspace(cwd, port) {
213
+ // The workspace server lives in different places depending on
214
+ // install layout. In the published @stravica-ai/digital-operator-pa bundle
215
+ // it lives under `node_modules/@stravica-ai/digital-operator-pa/dist/
216
+ // engineering-pa-workspace/src/server.mjs`. In the dev monorepo
217
+ // (or any layout where workspace is installed as a separate
218
+ // package), it's at `node_modules/@stravica-ai/engineering-pa-workspace/
219
+ // src/server.mjs`. Try the bundled path first because that's the
220
+ // canonical operator-machine layout.
221
+ //
222
+ // Operators don't run server.mjs directly — the `pa workspace start`
223
+ // bin shim handles supervision in production — but the smoke suite
224
+ // bypasses that to keep the child PID easy to reap.
225
+ const candidates = [
226
+ `node_modules/${PA_PACKAGE_NAME}/dist/engineering-pa-workspace/src/server.mjs`,
227
+ 'node_modules/@stravica-ai/engineering-pa-workspace/src/server.mjs',
228
+ ];
229
+ const serverScript = candidates.find((rel) => existsSync(`${cwd}/${rel}`)) ?? candidates[0];
230
+ return launchProcess(
231
+ 'node',
232
+ [serverScript, '--port', String(port), '--no-open', '--no-timeout'],
233
+ { cwd, stdio: ['ignore', 'ignore', 'pipe'] },
234
+ );
235
+ },
236
+ };
237
+ }