@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,66 @@
1
+ {
2
+ "$schema": "https://stravica.ai/schemas/runbook/1.0",
3
+ "id": "dex-template-v1-to-v2",
4
+ "target": "dex",
5
+ "description": "Template runbook for Dex cutover. Parameterise {{daveRoot}} from inspection output before executing.",
6
+ "version": "1.0.0",
7
+ "inspectionRef": "inspection-dex.json",
8
+ "steps": [
9
+ {
10
+ "id": "step-1",
11
+ "intent": "snapshot-v1-fork",
12
+ "description": "Preserve v1 fork.",
13
+ "params": { "snapshotSuffix": "pre-v2-{{inspectedAt|date}}" },
14
+ "preconditions": [
15
+ { "assert": "workingTreeClean" },
16
+ { "assert": "onBranch", "value": "main" }
17
+ ],
18
+ "expect": { "produces": ["{{daveRoot}}-pre-v2-{{inspectedAt|date}}/"] },
19
+ "rollback": { "trigger": "v2 instance fails 24h soak", "action": "restore-from-snapshot" }
20
+ },
21
+ {
22
+ "id": "step-2",
23
+ "intent": "run-migrate-to-v2",
24
+ "description": "Run migrate-to-v2 CLI.",
25
+ "params": {
26
+ "source": "{{daveRoot}}",
27
+ "target": "{{daveRoot}}-v2",
28
+ "dryRun": false
29
+ },
30
+ "preconditions": [
31
+ { "assert": "snapshotExists" },
32
+ { "assert": "nodeVersion", "value": ">=24" },
33
+ { "assert": "pnpmOnPath" }
34
+ ],
35
+ "expect": { "produces": ["{{daveRoot}}-v2/package.json", "{{daveRoot}}-v2/operator/"] },
36
+ "rollback": { "trigger": "migrate-to-v2 exits non-zero", "action": "restore-from-snapshot" }
37
+ },
38
+ {
39
+ "id": "step-3",
40
+ "intent": "update-host-service",
41
+ "description": "Update the workspace launchd plist to point to the v2 instance.",
42
+ "params": {
43
+ "label": "com.dave.workspace",
44
+ "workingDirectory": "{{daveRoot}}-v2"
45
+ },
46
+ "preconditions": [
47
+ { "assert": "hostService", "value": "com.dave.workspace" }
48
+ ],
49
+ "expect": { "produces": ["~/Library/LaunchAgents/com.dave.workspace.plist"] },
50
+ "rollback": { "trigger": "workspace fails to start", "action": "restore-previous-plist" }
51
+ },
52
+ {
53
+ "id": "step-4",
54
+ "intent": "verify-boot-health",
55
+ "description": "Verify pa status exits 0.",
56
+ "params": { "daveRoot": "{{daveRoot}}-v2" },
57
+ "expect": { "exitCode": 0 }
58
+ },
59
+ {
60
+ "id": "step-5",
61
+ "intent": "define-roster-entry",
62
+ "description": "Register Dex in operator roster.",
63
+ "params": { "hostId": "dex", "layoutVersion": "v2", "daveRoot": "{{daveRoot}}-v2" }
64
+ }
65
+ ]
66
+ }
@@ -0,0 +1,69 @@
1
+ {
2
+ "$schema": "https://stravica.ai/schemas/runbook/1.0",
3
+ "id": "hq-dave-v1-to-v2",
4
+ "target": "hq-dave",
5
+ "description": "Migrate HQ Dave instance from v1 fork to v2 operator-repo.",
6
+ "version": "1.0.0",
7
+ "inspectionRef": "inspection-hq-dave.json",
8
+ "steps": [
9
+ {
10
+ "id": "step-1",
11
+ "intent": "snapshot-v1-fork",
12
+ "description": "Preserve the v1 fork as rollback point.",
13
+ "params": { "snapshotSuffix": "pre-v2-{{inspectedAt|date}}" },
14
+ "preconditions": [
15
+ { "assert": "workingTreeClean" },
16
+ { "assert": "onBranch", "value": "main" }
17
+ ],
18
+ "expect": { "produces": ["{{daveRoot}}-pre-v2-{{inspectedAt|date}}/"] },
19
+ "rollback": { "trigger": "v2 instance fails 24h soak", "action": "restore-from-snapshot" }
20
+ },
21
+ {
22
+ "id": "step-2",
23
+ "intent": "run-migrate-to-v2",
24
+ "description": "Run migrate-to-v2 CLI against the v1 fork.",
25
+ "params": {
26
+ "source": "{{daveRoot}}",
27
+ "target": "{{daveRoot}}-v2",
28
+ "dryRun": false
29
+ },
30
+ "preconditions": [
31
+ { "assert": "snapshotExists" },
32
+ { "assert": "nodeVersion", "value": ">=24" },
33
+ { "assert": "pnpmOnPath" }
34
+ ],
35
+ "expect": { "produces": ["{{daveRoot}}-v2/package.json", "{{daveRoot}}-v2/operator/"] },
36
+ "rollback": { "trigger": "migrate-to-v2 exits non-zero", "action": "restore-from-snapshot" }
37
+ },
38
+ {
39
+ "id": "step-3",
40
+ "intent": "update-host-service",
41
+ "description": "Update the workspace launchd plist to point to the v2 instance.",
42
+ "params": {
43
+ "label": "com.dave.workspace",
44
+ "workingDirectory": "{{daveRoot}}-v2"
45
+ },
46
+ "preconditions": [
47
+ { "assert": "hostService", "value": "com.dave.workspace" }
48
+ ],
49
+ "expect": { "produces": ["~/Library/LaunchAgents/com.dave.workspace.plist"] },
50
+ "rollback": { "trigger": "workspace fails to start", "action": "restore-previous-plist" }
51
+ },
52
+ {
53
+ "id": "step-4",
54
+ "intent": "verify-boot-health",
55
+ "description": "Verify pa status exits 0 in the v2 instance.",
56
+ "params": { "daveRoot": "{{daveRoot}}-v2" },
57
+ "preconditions": [
58
+ { "assert": "directoryExists", "value": "{{daveRoot}}-v2" }
59
+ ],
60
+ "expect": { "exitCode": 0 }
61
+ },
62
+ {
63
+ "id": "step-5",
64
+ "intent": "define-roster-entry",
65
+ "description": "Register hq-dave in the operator roster as a v2 instance.",
66
+ "params": { "hostId": "hq-dave", "layoutVersion": "v2", "daveRoot": "{{daveRoot}}-v2" }
67
+ }
68
+ ]
69
+ }
@@ -0,0 +1,92 @@
1
+ {
2
+ "$schema": "https://stravica.ai/schemas/runbook/1.0",
3
+ "id": "smarthome01-v1-to-v2",
4
+ "target": "smarthome01",
5
+ "description": "Migrate smarthome01 from v1 fork to v2. upstream-triage cron entry is deliberately dropped (operator decision 2026-05-17).",
6
+ "version": "1.0.0",
7
+ "inspectionRef": "inspection-smarthome01.json",
8
+ "steps": [
9
+ {
10
+ "id": "step-1",
11
+ "intent": "snapshot-v1-fork",
12
+ "description": "Preserve v1 fork.",
13
+ "params": { "snapshotSuffix": "pre-v2-{{inspectedAt|date}}" },
14
+ "preconditions": [
15
+ { "assert": "workingTreeClean" },
16
+ { "assert": "onBranch", "value": "main" }
17
+ ],
18
+ "expect": { "produces": ["{{daveRoot}}-pre-v2-{{inspectedAt|date}}/"] },
19
+ "rollback": { "trigger": "v2 instance fails 24h soak", "action": "restore-from-snapshot" }
20
+ },
21
+ {
22
+ "id": "step-2",
23
+ "intent": "drop-cron-entry",
24
+ "description": "Remove upstream-triage cron entry (operator decision: not carried forward to v2).",
25
+ "params": { "matchCommand": "upstream-triage" },
26
+ "preconditions": [
27
+ { "assert": "cronEntryExists", "value": "upstream-triage" }
28
+ ],
29
+ "expect": { "cronEntryAbsent": "upstream-triage" },
30
+ "rollback": { "trigger": "upstream-triage still required", "action": "restore-cron-entry" },
31
+ "notes": "Operator confirmed drop on 2026-05-17. upstream-triage is superseded by Dex-side processing."
32
+ },
33
+ {
34
+ "id": "step-3",
35
+ "intent": "run-migrate-to-v2",
36
+ "description": "Run migrate-to-v2 CLI.",
37
+ "params": {
38
+ "source": "{{daveRoot}}",
39
+ "target": "{{daveRoot}}-v2",
40
+ "dryRun": false
41
+ },
42
+ "preconditions": [
43
+ { "assert": "snapshotExists" },
44
+ { "assert": "nodeVersion", "value": ">=24" },
45
+ { "assert": "pnpmOnPath" }
46
+ ],
47
+ "expect": { "produces": ["{{daveRoot}}-v2/package.json", "{{daveRoot}}-v2/operator/"] },
48
+ "rollback": { "trigger": "migrate-to-v2 exits non-zero", "action": "restore-from-snapshot" }
49
+ },
50
+ {
51
+ "id": "step-4",
52
+ "intent": "rewrite-crontab",
53
+ "description": "Update the 3 remaining cron entries (distill, wsd-ingest, sync) to use the v2 instance path.",
54
+ "params": {
55
+ "entries": [
56
+ { "matchCommand": "distill", "newWorkingDirectory": "{{daveRoot}}-v2" },
57
+ { "matchCommand": "wsd-ingest", "newWorkingDirectory": "{{daveRoot}}-v2" },
58
+ { "matchCommand": "sync", "newWorkingDirectory": "{{daveRoot}}-v2" }
59
+ ]
60
+ },
61
+ "preconditions": [
62
+ { "assert": "cronEntryExists", "value": "distill" },
63
+ { "assert": "cronEntryExists", "value": "wsd-ingest" },
64
+ { "assert": "cronEntryExists", "value": "sync" }
65
+ ],
66
+ "expect": { "cronEntriesUpdated": 3 }
67
+ },
68
+ {
69
+ "id": "step-5",
70
+ "intent": "verify-sync-continuity",
71
+ "description": "Verify sync reaches the dropbox share from the v2 instance.",
72
+ "params": { "daveRoot": "{{daveRoot}}-v2" },
73
+ "preconditions": [
74
+ { "assert": "mountExists", "value": "/mnt/share/dropbox" }
75
+ ],
76
+ "expect": { "syncExitCode": 0 }
77
+ },
78
+ {
79
+ "id": "step-6",
80
+ "intent": "verify-boot-health",
81
+ "description": "Verify pa status exits 0.",
82
+ "params": { "daveRoot": "{{daveRoot}}-v2" },
83
+ "expect": { "exitCode": 0 }
84
+ },
85
+ {
86
+ "id": "step-7",
87
+ "intent": "define-roster-entry",
88
+ "description": "Register smarthome01 in operator roster.",
89
+ "params": { "hostId": "smarthome01", "layoutVersion": "v2", "daveRoot": "{{daveRoot}}-v2" }
90
+ }
91
+ ]
92
+ }
@@ -0,0 +1,113 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://stravica.ai/schemas/inspection/1.0",
4
+ "title": "MigrateInspectionResult",
5
+ "type": "object",
6
+ "required": ["host", "runtimes", "scheduled", "mounts", "daveEnv", "paths", "extensions", "inspectedAt"],
7
+ "properties": {
8
+ "host": {
9
+ "type": "object",
10
+ "required": ["hostname", "os", "osVersion", "arch"],
11
+ "properties": {
12
+ "hostname": { "type": "string" },
13
+ "os": { "type": "string" },
14
+ "osVersion": { "type": "string" },
15
+ "arch": { "type": "string" },
16
+ "chip": { "type": "string" },
17
+ "memory": { "type": "number" }
18
+ }
19
+ },
20
+ "runtimes": {
21
+ "type": "object",
22
+ "required": ["nodeVersion", "pnpmVersion", "gitVersion"],
23
+ "properties": {
24
+ "nodeVersion": { "type": ["string", "null"] },
25
+ "pnpmVersion": { "type": ["string", "null"] },
26
+ "gitVersion": { "type": ["string", "null"] }
27
+ }
28
+ },
29
+ "scheduled": {
30
+ "type": "object",
31
+ "required": ["crontab", "launchdPlists"],
32
+ "properties": {
33
+ "crontab": {
34
+ "type": "array",
35
+ "items": {
36
+ "type": "object",
37
+ "required": ["schedule", "command"],
38
+ "properties": {
39
+ "schedule": { "type": "string" },
40
+ "command": { "type": "string" }
41
+ }
42
+ }
43
+ },
44
+ "launchdPlists": {
45
+ "type": "array",
46
+ "items": {
47
+ "type": "object",
48
+ "properties": {
49
+ "label": { "type": ["string", "null"] },
50
+ "program": { "type": ["string", "null"] },
51
+ "args": {
52
+ "oneOf": [
53
+ { "type": "array", "items": { "type": "string" } },
54
+ { "type": "null" }
55
+ ]
56
+ },
57
+ "workingDirectory": { "type": ["string", "null"] },
58
+ "runAtLoad": { "type": "boolean" },
59
+ "keepAlive": { "type": "boolean" }
60
+ }
61
+ }
62
+ }
63
+ }
64
+ },
65
+ "mounts": {
66
+ "type": "array",
67
+ "items": {
68
+ "type": "object",
69
+ "required": ["source", "target", "fsType"],
70
+ "properties": {
71
+ "source": { "type": "string" },
72
+ "target": { "type": "string" },
73
+ "fsType": { "type": "string" }
74
+ }
75
+ }
76
+ },
77
+ "daveEnv": {
78
+ "type": "object",
79
+ "required": ["daveRoot", "daveRelevantEnvVars", "pathSegments"],
80
+ "properties": {
81
+ "daveRoot": { "type": ["string", "null"] },
82
+ "daveRelevantEnvVars": { "type": "object" },
83
+ "pathSegments": { "type": "array", "items": { "type": "string" } }
84
+ }
85
+ },
86
+ "paths": {
87
+ "type": "object",
88
+ "required": ["daveRoot", "coreToolsPath", "operatorPath", "layoutVersion"],
89
+ "properties": {
90
+ "daveRoot": { "type": ["string", "null"] },
91
+ "coreToolsPath": { "type": ["string", "null"] },
92
+ "operatorPath": { "type": ["string", "null"] },
93
+ "layoutVersion": {
94
+ "type": "string",
95
+ "enum": ["v1", "v2", "unknown"]
96
+ }
97
+ }
98
+ },
99
+ "extensions": {
100
+ "type": "array",
101
+ "items": {
102
+ "type": "object",
103
+ "required": ["name", "path", "hasManifestEntry"],
104
+ "properties": {
105
+ "name": { "type": "string" },
106
+ "path": { "type": "string" },
107
+ "hasManifestEntry": { "type": "boolean" }
108
+ }
109
+ }
110
+ },
111
+ "inspectedAt": { "type": "string" }
112
+ }
113
+ }
@@ -0,0 +1,67 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://stravica.ai/schemas/runbook/1.0",
4
+ "title": "MigrationRunbook",
5
+ "type": "object",
6
+ "required": ["$schema", "id", "target", "version", "steps"],
7
+ "properties": {
8
+ "$schema": { "type": "string" },
9
+ "id": { "type": "string" },
10
+ "target": { "type": "string" },
11
+ "description": { "type": "string" },
12
+ "version": { "type": "string" },
13
+ "inspectionRef": { "type": "string" },
14
+ "steps": {
15
+ "type": "array",
16
+ "minItems": 1,
17
+ "items": { "$ref": "#/$defs/Step" }
18
+ }
19
+ },
20
+ "$defs": {
21
+ "Step": {
22
+ "type": "object",
23
+ "required": ["id", "intent"],
24
+ "properties": {
25
+ "id": { "type": "string" },
26
+ "intent": {
27
+ "type": "string",
28
+ "enum": [
29
+ "snapshot-v1-fork",
30
+ "run-migrate-to-v2",
31
+ "rewrite-crontab",
32
+ "drop-cron-entry",
33
+ "update-host-service",
34
+ "verify-sync-continuity",
35
+ "verify-boot-health",
36
+ "define-roster-entry"
37
+ ]
38
+ },
39
+ "description": { "type": "string" },
40
+ "params": { "type": "object" },
41
+ "preconditions": {
42
+ "type": "array",
43
+ "items": { "$ref": "#/$defs/Condition" }
44
+ },
45
+ "expect": { "type": "object" },
46
+ "rollback": { "$ref": "#/$defs/Rollback" },
47
+ "notes": { "type": "string" }
48
+ }
49
+ },
50
+ "Condition": {
51
+ "type": "object",
52
+ "required": ["assert"],
53
+ "properties": {
54
+ "assert": { "type": "string" },
55
+ "value": {}
56
+ }
57
+ },
58
+ "Rollback": {
59
+ "type": "object",
60
+ "required": ["trigger", "action"],
61
+ "properties": {
62
+ "trigger": { "type": "string" },
63
+ "action": { "type": "string" }
64
+ }
65
+ }
66
+ }
67
+ }
@@ -0,0 +1,167 @@
1
+ // validator.mjs — minimal structural validator for runbook.schema.json and
2
+ // inspection.schema.json. Handles the subset of JSON Schema 2020-12 that
3
+ // the two schemas actually use. No external deps.
4
+
5
+ const PRIMITIVE_TYPES = new Set(['string', 'number', 'integer', 'boolean', 'null', 'array', 'object']);
6
+
7
+ /**
8
+ * Validate data against a JSON Schema (subset).
9
+ * @param {object} schema - the schema to validate against
10
+ * @param {unknown} data - the data to validate
11
+ * @param {object} [rootSchema] - root schema for $ref resolution (defaults to schema)
12
+ * @returns {{ valid: boolean, errors: string[] }}
13
+ */
14
+ export function validate(schema, data, rootSchema = schema) {
15
+ const errors = [];
16
+ _validate(schema, data, rootSchema, '', errors);
17
+ return { valid: errors.length === 0, errors };
18
+ }
19
+
20
+ function _validate(schema, data, rootSchema, path, errors) {
21
+ if (schema === true) return;
22
+ if (schema === false) {
23
+ errors.push(`${path || '(root)'}: schema is false`);
24
+ return;
25
+ }
26
+
27
+ // $ref resolution
28
+ if (schema.$ref) {
29
+ const resolved = _resolveRef(schema.$ref, rootSchema);
30
+ if (!resolved) {
31
+ errors.push(`${path || '(root)'}: unresolvable $ref ${schema.$ref}`);
32
+ return;
33
+ }
34
+ _validate(resolved, data, rootSchema, path, errors);
35
+ return;
36
+ }
37
+
38
+ // type check
39
+ if (schema.type !== undefined) {
40
+ const types = Array.isArray(schema.type) ? schema.type : [schema.type];
41
+ if (!types.some(t => _checkType(t, data))) {
42
+ errors.push(`${path || '(root)'}: expected type ${types.join('|')}, got ${_typeOf(data)}`);
43
+ return; // no point continuing if type is wrong
44
+ }
45
+ }
46
+
47
+ // enum
48
+ if (schema.enum !== undefined) {
49
+ if (!schema.enum.some(v => _deepEqual(v, data))) {
50
+ errors.push(`${path || '(root)'}: value ${JSON.stringify(data)} not in enum [${schema.enum.map(v => JSON.stringify(v)).join(', ')}]`);
51
+ }
52
+ }
53
+
54
+ // object-specific
55
+ if (_typeOf(data) === 'object' && data !== null) {
56
+ // required
57
+ if (Array.isArray(schema.required)) {
58
+ for (const key of schema.required) {
59
+ if (!Object.prototype.hasOwnProperty.call(data, key)) {
60
+ errors.push(`${path || '(root)'}: missing required property "${key}"`);
61
+ }
62
+ }
63
+ }
64
+
65
+ // properties
66
+ if (schema.properties) {
67
+ for (const [key, subSchema] of Object.entries(schema.properties)) {
68
+ if (Object.prototype.hasOwnProperty.call(data, key)) {
69
+ _validate(subSchema, data[key], rootSchema, path ? `${path}.${key}` : key, errors);
70
+ }
71
+ }
72
+ }
73
+
74
+ // additionalProperties
75
+ if (schema.additionalProperties !== undefined && schema.properties) {
76
+ const knownKeys = new Set(Object.keys(schema.properties));
77
+ for (const key of Object.keys(data)) {
78
+ if (!knownKeys.has(key)) {
79
+ if (schema.additionalProperties === false) {
80
+ errors.push(`${path || '(root)'}: additional property "${key}" not allowed`);
81
+ } else if (typeof schema.additionalProperties === 'object') {
82
+ _validate(schema.additionalProperties, data[key], rootSchema, path ? `${path}.${key}` : key, errors);
83
+ }
84
+ }
85
+ }
86
+ }
87
+ }
88
+
89
+ // array-specific
90
+ if (Array.isArray(data)) {
91
+ // minItems
92
+ if (typeof schema.minItems === 'number' && data.length < schema.minItems) {
93
+ errors.push(`${path || '(root)'}: array has ${data.length} items, minItems is ${schema.minItems}`);
94
+ }
95
+
96
+ // items
97
+ if (schema.items !== undefined) {
98
+ for (let i = 0; i < data.length; i++) {
99
+ _validate(schema.items, data[i], rootSchema, `${path}[${i}]`, errors);
100
+ }
101
+ }
102
+ }
103
+
104
+ // oneOf
105
+ if (schema.oneOf !== undefined) {
106
+ const matchCount = schema.oneOf.filter(subSchema => {
107
+ const sub = [];
108
+ _validate(subSchema, data, rootSchema, path, sub);
109
+ return sub.length === 0;
110
+ }).length;
111
+ if (matchCount !== 1) {
112
+ errors.push(`${path || '(root)'}: expected exactly one of oneOf schemas to match, got ${matchCount}`);
113
+ }
114
+ }
115
+
116
+ // anyOf
117
+ if (schema.anyOf !== undefined) {
118
+ const anyMatch = schema.anyOf.some(subSchema => {
119
+ const sub = [];
120
+ _validate(subSchema, data, rootSchema, path, sub);
121
+ return sub.length === 0;
122
+ });
123
+ if (!anyMatch) {
124
+ errors.push(`${path || '(root)'}: value does not match any of anyOf schemas`);
125
+ }
126
+ }
127
+ }
128
+
129
+ function _resolveRef(ref, rootSchema) {
130
+ // Only handles #/$defs/<name>
131
+ const match = ref.match(/^#\/\$defs\/(.+)$/);
132
+ if (!match) return null;
133
+ const name = match[1];
134
+ return rootSchema.$defs && rootSchema.$defs[name] ? rootSchema.$defs[name] : null;
135
+ }
136
+
137
+ function _checkType(type, data) {
138
+ switch (type) {
139
+ case 'string': return typeof data === 'string';
140
+ case 'number': return typeof data === 'number' && !Number.isNaN(data);
141
+ case 'integer': return typeof data === 'number' && Number.isInteger(data);
142
+ case 'boolean': return typeof data === 'boolean';
143
+ case 'null': return data === null;
144
+ case 'array': return Array.isArray(data);
145
+ case 'object': return typeof data === 'object' && data !== null && !Array.isArray(data);
146
+ default: return false;
147
+ }
148
+ }
149
+
150
+ function _typeOf(data) {
151
+ if (data === null) return 'null';
152
+ if (Array.isArray(data)) return 'array';
153
+ return typeof data;
154
+ }
155
+
156
+ function _deepEqual(a, b) {
157
+ if (a === b) return true;
158
+ if (a === null || b === null) return false;
159
+ if (typeof a !== typeof b) return false;
160
+ if (typeof a === 'object') {
161
+ const aKeys = Object.keys(a);
162
+ const bKeys = Object.keys(b);
163
+ if (aKeys.length !== bKeys.length) return false;
164
+ return aKeys.every(k => _deepEqual(a[k], b[k]));
165
+ }
166
+ return false;
167
+ }