@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,58 @@
1
+ // delete KEY — remove a secret and re-encrypt.
2
+
3
+ import {
4
+ defaultPaths,
5
+ checkDeps,
6
+ depInstallMessage,
7
+ checkVault,
8
+ getPublicKey,
9
+ secretsFileExists,
10
+ decryptStoreForWrite,
11
+ sopsEncrypt,
12
+ sopsEncryptScoped,
13
+ VaultError,
14
+ } from '../vault.mjs';
15
+
16
+ export async function runDelete(args, overrides = {}) {
17
+ const paths = overrides.paths || defaultPaths(overrides);
18
+ const key = args[0];
19
+
20
+ if (!key) {
21
+ console.error('Usage: secrets delete KEY');
22
+ throw new VaultError('usage', 1);
23
+ }
24
+
25
+ const missing = await checkDeps();
26
+ if (missing.length > 0) {
27
+ console.error(depInstallMessage(missing[0]));
28
+ throw new VaultError('missing dependencies', 1);
29
+ }
30
+
31
+ const vaultState = checkVault(paths);
32
+ if (!vaultState.ok) {
33
+ console.error(vaultState.message);
34
+ throw new VaultError(vaultState.reason || 'vault not initialised', vaultState.exitCode ?? 1);
35
+ }
36
+
37
+ if (!secretsFileExists(paths)) {
38
+ console.error(paths.scoped ? `Error: No secrets file found at ${paths.secretsFile}.` : 'Error: No secrets file found.');
39
+ throw new VaultError('no secrets file', 1);
40
+ }
41
+
42
+ const pubKey = paths.scoped ? null : getPublicKey(paths);
43
+ const data = await decryptStoreForWrite(paths);
44
+
45
+ if (!(key in data)) {
46
+ console.error(`Error: Key "${key}" not found.`);
47
+ throw new VaultError('key not found', 1);
48
+ }
49
+
50
+ delete data[key];
51
+ if (paths.scoped) {
52
+ await sopsEncryptScoped(paths, data);
53
+ } else {
54
+ await sopsEncrypt(paths, pubKey, data);
55
+ }
56
+ console.log(`Secret '${key}' deleted.`);
57
+ return 0;
58
+ }
@@ -0,0 +1,36 @@
1
+ // find KEY (alias: which) — report every vault whose plaintext key-name
2
+ // structure contains KEY. Names and paths only — values are NEVER read;
3
+ // no decryption happens anywhere in this command (sops JSON keeps key
4
+ // names in plaintext, values encrypted).
5
+
6
+ import { VaultError, readVaultKeyNames } from '../vault.mjs';
7
+ import { vaultEntriesFor } from './vaults.mjs';
8
+
9
+ // Estate key-name discipline — validated before the name is used anywhere.
10
+ const KEY_NAME_RE = /^[A-Z0-9_]+$/;
11
+
12
+ export async function runFind(args, overrides = {}) {
13
+ const key = args[0];
14
+
15
+ if (!key) {
16
+ console.error('Usage: secrets find KEY');
17
+ throw new VaultError('usage', 1);
18
+ }
19
+ if (!KEY_NAME_RE.test(key)) {
20
+ console.error(`Error: Invalid key name "${key}". Key names must match ${KEY_NAME_RE}.`);
21
+ throw new VaultError('invalid key name', 1);
22
+ }
23
+
24
+ const entries = vaultEntriesFor(overrides);
25
+ const hits = entries.filter((e) => (readVaultKeyNames(e.path) ?? []).includes(key));
26
+
27
+ if (hits.length === 0) {
28
+ console.error(`Key "${key}" not found in any of ${entries.length} vault(s).`);
29
+ return 1;
30
+ }
31
+
32
+ for (const h of hits) {
33
+ console.log(`${h.scope}\t${h.layout}\t${h.path}`);
34
+ }
35
+ return 0;
36
+ }
@@ -0,0 +1,49 @@
1
+ // get KEY — print the value of a single secret to stdout.
2
+
3
+ import {
4
+ resolveCommandPaths,
5
+ checkDeps,
6
+ depInstallMessage,
7
+ checkVault,
8
+ secretsFileExists,
9
+ sopsDecrypt,
10
+ VaultError,
11
+ } from '../vault.mjs';
12
+
13
+ export async function runGet(args, overrides = {}) {
14
+ // resolveCommandPaths prints the interim stderr notice (naming the
15
+ // target vault) whenever --scope/--file wasn't given upstream in
16
+ // cli.mjs — see vault.mjs's default-scope resolution section.
17
+ const paths = resolveCommandPaths(overrides);
18
+ const key = args[0];
19
+
20
+ if (!key) {
21
+ console.error('Usage: secrets get KEY');
22
+ throw new VaultError('usage', 1);
23
+ }
24
+
25
+ const missing = await checkDeps();
26
+ if (missing.length > 0) {
27
+ console.error(depInstallMessage(missing[0]));
28
+ throw new VaultError('missing dependencies', 1);
29
+ }
30
+
31
+ const vaultState = checkVault(paths);
32
+ if (!vaultState.ok) {
33
+ console.error(vaultState.message);
34
+ throw new VaultError(vaultState.reason || 'vault not initialised', vaultState.exitCode ?? 1);
35
+ }
36
+
37
+ if (!secretsFileExists(paths)) {
38
+ console.error(paths.scoped ? `Error: No secrets file found at ${paths.secretsFile}.` : "Error: No secrets file found. Run 'secrets init' first.");
39
+ throw new VaultError('no secrets file', 1);
40
+ }
41
+
42
+ const data = await sopsDecrypt(paths, paths.secretsFile);
43
+ if (!(key in data)) {
44
+ console.error(`Error: Key "${key}" not found.`);
45
+ throw new VaultError('key not found', 1);
46
+ }
47
+ console.log(data[key]);
48
+ return 0;
49
+ }
@@ -0,0 +1,69 @@
1
+ // init — generate age keypair, write recipients, write SOPS config,
2
+ // create an empty encrypted secrets file if none exists.
3
+
4
+ import {
5
+ defaultPaths,
6
+ checkDeps,
7
+ depInstallMessage,
8
+ ageKeygen,
9
+ publicKeyFromKeyFile,
10
+ ensureKeyDir,
11
+ ensureVaultDir,
12
+ chmodKeyFile,
13
+ writeRecipients,
14
+ writeSopsConfig,
15
+ keyFileExists,
16
+ secretsFileExists,
17
+ sopsEncrypt,
18
+ VaultError,
19
+ } from '../vault.mjs';
20
+
21
+ export async function runInit(overrides = {}) {
22
+ const paths = overrides.paths || defaultPaths({ ...overrides, allowGitRootWithoutVault: true });
23
+
24
+ const missing = await checkDeps();
25
+ if (missing.length > 0) {
26
+ console.error(depInstallMessage(missing[0]));
27
+ if (missing.length > 1) console.error(depInstallMessage(missing[1]));
28
+ throw new VaultError('missing dependencies', 1);
29
+ }
30
+
31
+ console.log('Initialising vault...');
32
+
33
+ ensureKeyDir(paths);
34
+
35
+ if (keyFileExists(paths)) {
36
+ console.log(`Age private key already exists at ${paths.keyFile}`);
37
+ } else {
38
+ await ageKeygen(paths);
39
+ chmodKeyFile(paths);
40
+ console.log(`Generated age private key: ${paths.keyFile}`);
41
+ }
42
+
43
+ const pubKey = publicKeyFromKeyFile(paths.keyFile);
44
+ if (!pubKey) {
45
+ throw new VaultError(`Could not extract public key from ${paths.keyFile}`, 2);
46
+ }
47
+
48
+ ensureVaultDir(paths);
49
+ writeRecipients(paths, pubKey);
50
+ console.log(`Public key written to ${paths.recipientsFile}`);
51
+
52
+ writeSopsConfig(paths, pubKey);
53
+ console.log(`SOPS config written to ${paths.sopsConfig}`);
54
+
55
+ if (!secretsFileExists(paths)) {
56
+ await sopsEncrypt(paths, pubKey, {});
57
+ console.log('Created empty encrypted secrets file.');
58
+ } else {
59
+ console.log('Encrypted secrets file already exists.');
60
+ }
61
+
62
+ console.log('');
63
+ console.log('Vault initialised.');
64
+ console.log(` Private key: ${paths.keyFile} (NEVER commit this)`);
65
+ console.log(` Public key: ${paths.recipientsFile} (safe to commit)`);
66
+ console.log(` Secrets: ${paths.secretsFile} (safe to commit)`);
67
+
68
+ return 0;
69
+ }
@@ -0,0 +1,37 @@
1
+ // list — print all secret key names (not values), one per line, sorted.
2
+
3
+ import {
4
+ defaultPaths,
5
+ checkDeps,
6
+ depInstallMessage,
7
+ checkVault,
8
+ secretsFileExists,
9
+ sopsDecrypt,
10
+ VaultError,
11
+ } from '../vault.mjs';
12
+
13
+ export async function runList(overrides = {}) {
14
+ const paths = overrides.paths || defaultPaths(overrides);
15
+
16
+ const missing = await checkDeps();
17
+ if (missing.length > 0) {
18
+ console.error(depInstallMessage(missing[0]));
19
+ throw new VaultError('missing dependencies', 1);
20
+ }
21
+
22
+ const vaultState = checkVault(paths);
23
+ if (!vaultState.ok) {
24
+ console.error(vaultState.message);
25
+ throw new VaultError(vaultState.reason || 'vault not initialised', vaultState.exitCode ?? 1);
26
+ }
27
+
28
+ if (!secretsFileExists(paths)) {
29
+ console.log('No secrets stored.');
30
+ return 0;
31
+ }
32
+
33
+ const data = await sopsDecrypt(paths, paths.secretsFile);
34
+ const keys = Object.keys(data).sort();
35
+ for (const key of keys) console.log(key);
36
+ return 0;
37
+ }
@@ -0,0 +1,46 @@
1
+ // rotate — decrypt-and-re-encrypt in place using the current recipients.
2
+ // Used after a key change so existing payloads carry the updated recipient.
3
+
4
+ import {
5
+ defaultPaths,
6
+ checkDeps,
7
+ depInstallMessage,
8
+ checkVault,
9
+ getPublicKey,
10
+ secretsFileExists,
11
+ decryptStoreForWrite,
12
+ sopsEncrypt,
13
+ sopsEncryptScoped,
14
+ VaultError,
15
+ } from '../vault.mjs';
16
+
17
+ export async function runRotate(overrides = {}) {
18
+ const paths = overrides.paths || defaultPaths(overrides);
19
+
20
+ const missing = await checkDeps();
21
+ if (missing.length > 0) {
22
+ console.error(depInstallMessage(missing[0]));
23
+ throw new VaultError('missing dependencies', 1);
24
+ }
25
+
26
+ const vaultState = checkVault(paths);
27
+ if (!vaultState.ok) {
28
+ console.error(vaultState.message);
29
+ throw new VaultError(vaultState.reason || 'vault not initialised', vaultState.exitCode ?? 1);
30
+ }
31
+
32
+ if (!secretsFileExists(paths)) {
33
+ console.log('No secrets file to rotate.');
34
+ return 0;
35
+ }
36
+
37
+ const pubKey = paths.scoped ? null : getPublicKey(paths);
38
+ const data = await decryptStoreForWrite(paths);
39
+ if (paths.scoped) {
40
+ await sopsEncryptScoped(paths, data);
41
+ } else {
42
+ await sopsEncrypt(paths, pubKey, data);
43
+ }
44
+ console.log('Secrets re-encrypted with current recipients.');
45
+ return 0;
46
+ }
@@ -0,0 +1,123 @@
1
+ // set KEY VALUE — upsert a secret and re-encrypt.
2
+ // Passing `-` as VALUE reads the secret from stdin (trailing newline stripped),
3
+ // which keeps the value out of argv / process listings / shell history.
4
+ //
5
+ // --canonical-clone PATH: write the canonical clone's vault file FIRST,
6
+ // then this workspace copy SECOND. If the canonical write fails for any
7
+ // reason, the command aborts (exit 2) BEFORE touching the workspace copy
8
+ // at all — a device-side vault mutation never round-trips only halfway
9
+ // (see up-path-single-writer-ownership's vault follow-up: "device-side
10
+ // vault mutations must round-trip to canonical immediately"). Without the
11
+ // flag, behaviour is exactly as before (workspace copy only).
12
+
13
+ import { readFileSync } from 'node:fs';
14
+ import {
15
+ resolveCommandPaths,
16
+ resolveScopePaths,
17
+ checkDeps,
18
+ depInstallMessage,
19
+ checkVault,
20
+ getPublicKey,
21
+ secretsFileExists,
22
+ decryptStoreForWrite,
23
+ sopsEncrypt,
24
+ sopsEncryptScoped,
25
+ VaultError,
26
+ } from '../vault.mjs';
27
+
28
+ // --canonical-clone may appear anywhere in argv, matching the --scope/
29
+ // --file convention in cli.mjs. Local to `set` (not a global flag) since
30
+ // no other command writes to a second target.
31
+ function extractCanonicalCloneFlag(argv) {
32
+ const rest = [];
33
+ let canonicalClone;
34
+ for (let i = 0; i < argv.length; i += 1) {
35
+ const a = argv[i];
36
+ if (a === '--canonical-clone') { canonicalClone = argv[i + 1]; i += 1; continue; }
37
+ if (a.startsWith('--canonical-clone=')) { canonicalClone = a.slice('--canonical-clone='.length); continue; }
38
+ rest.push(a);
39
+ }
40
+ return { canonicalClone, rest };
41
+ }
42
+
43
+ export async function runSet(args, overrides = {}) {
44
+ // resolveCommandPaths prints the interim stderr notice (naming the
45
+ // target vault) whenever --scope/--file wasn't given upstream in
46
+ // cli.mjs — see vault.mjs's default-scope resolution section.
47
+ const paths = resolveCommandPaths(overrides);
48
+ const { canonicalClone, rest } = extractCanonicalCloneFlag(args);
49
+ const key = rest[0];
50
+ let value = rest[1];
51
+
52
+ if (!key || value == null || value === '') {
53
+ console.error('Usage: secrets set KEY VALUE [--canonical-clone PATH] (use `-` as VALUE to read from stdin)');
54
+ throw new VaultError('usage', 1);
55
+ }
56
+
57
+ if (value === '-') {
58
+ const readStdin = overrides.readStdin ?? (() => readFileSync(0, 'utf-8'));
59
+ const raw = readStdin();
60
+ // Strip a single trailing newline (\r\n or \n) — common when piping from
61
+ // `echo` or heredocs. Preserve all other whitespace in case the secret
62
+ // legitimately contains it.
63
+ value = raw.replace(/\r?\n$/, '');
64
+ if (value === '') {
65
+ console.error('Empty value on stdin — refusing to store an empty secret.');
66
+ throw new VaultError('empty stdin', 1);
67
+ }
68
+ }
69
+
70
+ const missing = await checkDeps();
71
+ if (missing.length > 0) {
72
+ console.error(depInstallMessage(missing[0]));
73
+ throw new VaultError('missing dependencies', 1);
74
+ }
75
+
76
+ const vaultState = checkVault(paths);
77
+ if (!vaultState.ok) {
78
+ console.error(vaultState.message);
79
+ throw new VaultError(vaultState.reason || 'vault not initialised', vaultState.exitCode ?? 1);
80
+ }
81
+
82
+ // Canonical FIRST. Resolved the same way `--file` already works for
83
+ // every other scope-aware command — an arbitrary path, its own
84
+ // .sops.yaml expected alongside it, reusing THIS host's key material
85
+ // (same recipients in practice for a workspace/canonical-clone pair).
86
+ // Any failure here (existing canonical store undecryptable, sops
87
+ // encrypt failure) throws and propagates straight out of runSet —
88
+ // the workspace write below is never reached.
89
+ if (canonicalClone) {
90
+ const canonicalPaths = overrides.canonicalPaths || resolveScopePaths({
91
+ file: canonicalClone,
92
+ keyDir: paths.keyDir,
93
+ keyFile: paths.keyFile,
94
+ });
95
+
96
+ let canonicalData = {};
97
+ if (secretsFileExists(canonicalPaths)) {
98
+ canonicalData = await decryptStoreForWrite(canonicalPaths);
99
+ }
100
+ canonicalData[key] = value;
101
+ await sopsEncryptScoped(canonicalPaths, canonicalData);
102
+ console.log(`Secret '${key}' stored in canonical clone (${canonicalPaths.secretsFile}).`);
103
+ }
104
+
105
+ const pubKey = paths.scoped ? null : getPublicKey(paths);
106
+
107
+ // A store that exists but cannot be decrypted REFUSES the write — the old
108
+ // `catch { data = {} }` fallback meant a host without the right age key
109
+ // would silently replace the vault's entire contents with this one key.
110
+ let data = {};
111
+ if (secretsFileExists(paths)) {
112
+ data = await decryptStoreForWrite(paths);
113
+ }
114
+
115
+ data[key] = value;
116
+ if (paths.scoped) {
117
+ await sopsEncryptScoped(paths, data);
118
+ } else {
119
+ await sopsEncrypt(paths, pubKey, data);
120
+ }
121
+ console.log(`Secret '${key}' stored.`);
122
+ return 0;
123
+ }
@@ -0,0 +1,146 @@
1
+ // status — report vault health.
2
+ // Returns 0 when every core artefact is present, 1 otherwise, so callers
3
+ // can gate operations on initialisation state.
4
+
5
+ import { readFileSync } from 'node:fs';
6
+ import {
7
+ defaultPaths,
8
+ runCmd,
9
+ hasBinary,
10
+ keyFileExists,
11
+ secretsFileExists,
12
+ recipientsFileExists,
13
+ sopsConfigExists,
14
+ sopsDecrypt,
15
+ } from '../vault.mjs';
16
+
17
+ async function printDepVersions() {
18
+ console.log('');
19
+ if (await hasBinary('sops')) {
20
+ const { stdout, stderr } = await runCmd('sops', ['--version']);
21
+ const line = ((stdout || stderr).split('\n')[0] || '').trim();
22
+ console.log(`sops: ${line}`);
23
+ } else {
24
+ console.log('sops: NOT INSTALLED');
25
+ }
26
+ if (await hasBinary('age')) {
27
+ const { stdout, stderr } = await runCmd('age', ['--version']);
28
+ const line = ((stdout || stderr).split('\n')[0] || '').trim();
29
+ console.log(`age: ${line}`);
30
+ } else {
31
+ console.log('age: NOT INSTALLED');
32
+ }
33
+ }
34
+
35
+ export async function runStatus(overrides = {}) {
36
+ const paths = overrides.paths || defaultPaths(overrides);
37
+ if (paths.scoped) return runStatusScoped(paths);
38
+
39
+ let ok = true;
40
+
41
+ console.log('Vault status');
42
+ console.log('============');
43
+ console.log('');
44
+
45
+ // Private key
46
+ if (keyFileExists(paths)) {
47
+ console.log(`Private key: ${paths.keyFile} (present)`);
48
+ } else {
49
+ console.log(`Private key: ${paths.keyFile} (MISSING)`);
50
+ ok = false;
51
+ }
52
+
53
+ // Recipients
54
+ if (recipientsFileExists(paths)) {
55
+ const pub = readFileSync(paths.recipientsFile, 'utf-8').split('\n')[0];
56
+ console.log(`Public key: ${pub}`);
57
+ } else {
58
+ console.log(`Public key: ${paths.recipientsFile} (MISSING)`);
59
+ ok = false;
60
+ }
61
+
62
+ // Secrets file + count
63
+ if (secretsFileExists(paths)) {
64
+ if (keyFileExists(paths)) {
65
+ let count = '?';
66
+ try {
67
+ const data = await sopsDecrypt(paths, paths.secretsFile);
68
+ count = String(Object.keys(data).length);
69
+ } catch {
70
+ count = '?';
71
+ }
72
+ console.log(`Secrets: ${paths.secretsFile} (${count} keys)`);
73
+ } else {
74
+ console.log(`Secrets: ${paths.secretsFile} (present, cannot count without private key)`);
75
+ }
76
+ } else {
77
+ console.log(`Secrets: ${paths.secretsFile} (not created)`);
78
+ ok = false;
79
+ }
80
+
81
+ // SOPS config
82
+ if (sopsConfigExists(paths)) {
83
+ console.log(`SOPS config: ${paths.sopsConfig} (present)`);
84
+ } else {
85
+ console.log(`SOPS config: ${paths.sopsConfig} (MISSING)`);
86
+ ok = false;
87
+ }
88
+
89
+ // Dependency versions
90
+ await printDepVersions();
91
+
92
+ return ok ? 0 : 1;
93
+ }
94
+
95
+ // Scoped vaults have no recipients.txt — a scope's recipients live in
96
+ // per-file creation_rules inside the shared .sops.yaml, so the "public
97
+ // key" line has no single-value equivalent. Rather than hand-roll a YAML
98
+ // parser to enumerate them for a cosmetic status line (real recipient
99
+ // resolution stays entirely sops's job at encrypt/decrypt time), this
100
+ // points at the config file instead of guessing.
101
+ async function runStatusScoped(paths) {
102
+ let ok = true;
103
+ const heading = paths.scope ? `Vault status (scope: ${paths.scope})` : 'Vault status (scoped)';
104
+
105
+ console.log(heading);
106
+ console.log('='.repeat(heading.length));
107
+ console.log('');
108
+
109
+ if (keyFileExists(paths)) {
110
+ console.log(`Private key: ${paths.keyFile} (present)`);
111
+ } else {
112
+ console.log(`Private key: ${paths.keyFile} (MISSING)`);
113
+ ok = false;
114
+ }
115
+
116
+ if (sopsConfigExists(paths)) {
117
+ console.log(`SOPS config: ${paths.sopsConfig} (present)`);
118
+ } else {
119
+ console.log(`SOPS config: ${paths.sopsConfig} (MISSING)`);
120
+ ok = false;
121
+ }
122
+
123
+ if (secretsFileExists(paths)) {
124
+ if (keyFileExists(paths)) {
125
+ let count = '?';
126
+ try {
127
+ const data = await sopsDecrypt(paths, paths.secretsFile);
128
+ count = String(Object.keys(data).length);
129
+ } catch {
130
+ count = '?';
131
+ }
132
+ console.log(`Secrets: ${paths.secretsFile} (${count} keys)`);
133
+ } else {
134
+ console.log(`Secrets: ${paths.secretsFile} (present, cannot count without private key)`);
135
+ }
136
+ } else {
137
+ console.log(`Secrets: ${paths.secretsFile} (not created)`);
138
+ ok = false;
139
+ }
140
+
141
+ console.log(`Recipients: see ${paths.sopsConfig} (per-scope creation_rules; not enumerated in scoped mode)`);
142
+
143
+ await printDepVersions();
144
+
145
+ return ok ? 0 : 1;
146
+ }
@@ -0,0 +1,57 @@
1
+ // vaults — enumerate every vault visible from the resolved workspace:
2
+ // legacy .vault/secrets.enc.json, workspace scopes .vault/scopes/*.enc.json,
3
+ // and canonical vault/*.enc.json. Key counts come from the plaintext
4
+ // structure of the sops JSON (key names are not encrypted; values are) —
5
+ // no decryption, no private key required, no secret material touched.
6
+ //
7
+ // --scope / --file narrow to a single vault (paths arrive pre-resolved
8
+ // from the CLI layer).
9
+
10
+ import {
11
+ resolveWorkspaceRoot,
12
+ enumerateVaults,
13
+ readVaultKeyNames,
14
+ } from '../vault.mjs';
15
+
16
+ /** Shared with `find`: turn overrides into the list of vault entries in play. */
17
+ export function vaultEntriesFor(overrides = {}) {
18
+ const paths = overrides.paths;
19
+ if (paths && paths.scoped) {
20
+ return [{
21
+ scope: paths.scope ?? '(file)',
22
+ layout: paths.layout === 'workspace' ? 'workspace-scoped' : paths.layout,
23
+ path: paths.secretsFile,
24
+ }];
25
+ }
26
+ const root = paths?.root
27
+ ?? resolveWorkspaceRoot({ cwd: overrides.cwd, env: overrides.env, home: overrides.home }).root;
28
+ return enumerateVaults(root);
29
+ }
30
+
31
+ export async function runVaults(overrides = {}) {
32
+ const entries = vaultEntriesFor(overrides);
33
+
34
+ if (entries.length === 0) {
35
+ console.log('No vaults found.');
36
+ return 1;
37
+ }
38
+
39
+ const rows = entries.map((e) => {
40
+ const names = readVaultKeyNames(e.path);
41
+ return { ...e, keys: names == null ? '?' : String(names.length) };
42
+ });
43
+
44
+ const w = (sel, heading) => Math.max(heading.length, ...rows.map((r) => sel(r).length));
45
+ const cols = [
46
+ ['SCOPE', (r) => r.scope],
47
+ ['LAYOUT', (r) => r.layout],
48
+ ['KEYS', (r) => r.keys],
49
+ ['PATH', (r) => r.path],
50
+ ];
51
+ const widths = cols.map(([h, sel]) => w(sel, h));
52
+ console.log(cols.map(([h], i) => h.padEnd(widths[i])).join(' ').trimEnd());
53
+ for (const r of rows) {
54
+ console.log(cols.map(([, sel], i) => sel(r).padEnd(widths[i])).join(' ').trimEnd());
55
+ }
56
+ return 0;
57
+ }