@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,189 @@
1
+ // verify-via-cf-dns — End-to-end GSC verification via Cloudflare DNS.
2
+ //
3
+ // Steps:
4
+ // 1. Get the TXT verification token from Site Verification API.
5
+ // 2. Resolve the Cloudflare zone id for the domain.
6
+ // 3. Plant a TXT record at the apex (idempotent — see plantTxtRecord).
7
+ // 4. Wait for DNS propagation (default 60s, --wait N overrides).
8
+ // 5. Call siteVerification.webResource.insert to confirm ownership.
9
+ // 6. Call webmasters.sites.add to register the domain-property in
10
+ // Search Console.
11
+ //
12
+ // On any failure the command returns the underlying exit code and prints
13
+ // what it managed to do so the operator can resume from the failure point.
14
+
15
+ import { buildGscClient, toDomainProperty, bareDomain } from '../auth.mjs';
16
+ import { loadCloudflareCreds, resolveZoneId, plantTxtRecord, sleep } from '../cloudflare.mjs';
17
+
18
+ const DEFAULT_WAIT_SECONDS = 60;
19
+
20
+ function parseFlags(args) {
21
+ const out = { positional: [], wait: DEFAULT_WAIT_SECONDS, account: null };
22
+ for (let i = 0; i < args.length; i++) {
23
+ const a = args[i];
24
+ if (a === '--wait') {
25
+ const n = Number(args[++i]);
26
+ if (!Number.isFinite(n) || n < 0) {
27
+ throw Object.assign(new Error(`--wait expects a non-negative number, got "${args[i]}"`), { exitCode: 1 });
28
+ }
29
+ out.wait = n;
30
+ } else if (a.startsWith('--wait=')) {
31
+ const n = Number(a.slice('--wait='.length));
32
+ if (!Number.isFinite(n) || n < 0) {
33
+ throw Object.assign(new Error(`--wait expects a non-negative number, got "${a}"`), { exitCode: 1 });
34
+ }
35
+ out.wait = n;
36
+ } else if (a === '--account') {
37
+ const v = args[++i];
38
+ if (!v || v.startsWith('--')) {
39
+ throw Object.assign(new Error('--account expects a value (e.g. --account stravica)'), { exitCode: 1 });
40
+ }
41
+ out.account = v;
42
+ } else if (a.startsWith('--account=')) {
43
+ const v = a.slice('--account='.length);
44
+ if (!v) {
45
+ throw Object.assign(new Error('--account expects a value (e.g. --account=stravica)'), { exitCode: 1 });
46
+ }
47
+ out.account = v;
48
+ } else {
49
+ out.positional.push(a);
50
+ }
51
+ }
52
+ return out;
53
+ }
54
+
55
+ export async function runVerifyViaCfDns(args, overrides = {}) {
56
+ let flags;
57
+ try { flags = parseFlags(args); } catch (e) {
58
+ process.stderr.write(`[gsc verify-via-cf-dns] ${e.message}\n`);
59
+ return e.exitCode || 1;
60
+ }
61
+
62
+ const domain = flags.positional[0];
63
+ if (!domain) {
64
+ process.stderr.write('Usage: pa gsc verify-via-cf-dns <domain> [--wait SECONDS] [--account NAME]\n');
65
+ return 1;
66
+ }
67
+
68
+ const siteUrl = toDomainProperty(domain);
69
+ const bare = bareDomain(siteUrl);
70
+ const out = overrides.stdout || process.stdout;
71
+ const log = (msg) => out.write(`[gsc verify] ${msg}\n`);
72
+
73
+ const trace = {
74
+ domain: bare,
75
+ siteUrl,
76
+ account: flags.account || null,
77
+ steps: [],
78
+ };
79
+
80
+ // ── Step 1: get the verification token. ──
81
+ let client;
82
+ try {
83
+ client = await buildGscClient(overrides);
84
+ } catch (e) {
85
+ process.stderr.write(`[gsc verify-via-cf-dns] auth failed: ${e.message}\n`);
86
+ return e.exitCode || 2;
87
+ }
88
+
89
+ let token;
90
+ try {
91
+ log('fetching verification token...');
92
+ const res = await client.siteVerification.webResource.getToken({
93
+ requestBody: {
94
+ verificationMethod: 'DNS_TXT',
95
+ site: { type: 'INET_DOMAIN', identifier: bare },
96
+ },
97
+ });
98
+ token = res?.data?.token;
99
+ if (!token) throw new Error('no token returned');
100
+ trace.steps.push({ step: 'getToken', ok: true });
101
+ log(`token obtained (${token.length} chars)`);
102
+ } catch (e) {
103
+ trace.steps.push({ step: 'getToken', ok: false, error: e.message });
104
+ process.stderr.write(`[gsc verify-via-cf-dns] getToken failed: ${e.message}\n`);
105
+ return 2;
106
+ }
107
+
108
+ // ── Step 2: resolve zone id. ──
109
+ // The `account` flag is plumbed through `overrides.account` so the vault
110
+ // lookup resolves the right suffixed key pair. An explicit override here
111
+ // wins over anything the dispatcher might set in `overrides`.
112
+ const credOverrides = flags.account ? { ...overrides, account: flags.account } : overrides;
113
+ let creds;
114
+ let zone;
115
+ try {
116
+ creds = await loadCloudflareCreds(credOverrides);
117
+ if (creds.account) {
118
+ log(`using CF account "${creds.account}" (vault keys: ${creds.vaultKeys.tokenKey}, ${creds.vaultKeys.accountIdKey})`);
119
+ }
120
+ zone = await resolveZoneId(creds, bare, overrides.fetchImpl);
121
+ trace.steps.push({ step: 'resolveZone', ok: true, zoneId: zone.zoneId, zoneName: zone.zoneName });
122
+ log(`zone: ${zone.zoneName} (${zone.zoneId})`);
123
+ } catch (e) {
124
+ trace.steps.push({ step: 'resolveZone', ok: false, error: e.message });
125
+ process.stderr.write(`[gsc verify-via-cf-dns] CF zone lookup failed: ${e.message}\n`);
126
+ return e.exitCode || 2;
127
+ }
128
+
129
+ // ── Step 3: plant TXT at apex. ──
130
+ let plantResult;
131
+ try {
132
+ plantResult = await plantTxtRecord(creds, zone.zoneId, bare, token, overrides.fetchImpl);
133
+ trace.steps.push({ step: 'plantTxt', ok: true, action: plantResult.action });
134
+ log(`TXT record ${plantResult.action} at apex (${bare})`);
135
+ } catch (e) {
136
+ trace.steps.push({ step: 'plantTxt', ok: false, error: e.message });
137
+ process.stderr.write(`[gsc verify-via-cf-dns] DNS planting failed: ${e.message}\n`);
138
+ return e.exitCode || 2;
139
+ }
140
+
141
+ // ── Step 4: wait for propagation. ──
142
+ if (flags.wait > 0) {
143
+ log(`waiting ${flags.wait}s for DNS propagation...`);
144
+ await sleep(flags.wait * 1000, overrides.sleepImpl);
145
+ }
146
+
147
+ // ── Step 5: verify ownership. ──
148
+ try {
149
+ log('calling siteVerification.webResource.insert...');
150
+ await client.siteVerification.webResource.insert({
151
+ verificationMethod: 'DNS_TXT',
152
+ requestBody: {
153
+ site: { type: 'INET_DOMAIN', identifier: bare },
154
+ },
155
+ });
156
+ trace.steps.push({ step: 'verify', ok: true });
157
+ log('verification succeeded');
158
+ } catch (e) {
159
+ trace.steps.push({ step: 'verify', ok: false, error: e.message });
160
+ process.stderr.write(
161
+ `[gsc verify-via-cf-dns] verification failed: ${e.message}\n` +
162
+ ` The TXT record may not have propagated yet. Retry with: pa gsc verify-via-cf-dns ${bare} --wait 120\n`,
163
+ );
164
+ return 2;
165
+ }
166
+
167
+ // ── Step 6: register property in Search Console. ──
168
+ try {
169
+ log(`registering ${siteUrl} in Search Console...`);
170
+ await client.webmasters.sites.add({ siteUrl });
171
+ trace.steps.push({ step: 'sitesAdd', ok: true });
172
+ log('property registered');
173
+ } catch (e) {
174
+ // 409 already-exists is benign; surface it as ok.
175
+ const code = e?.code || e?.response?.status;
176
+ if (code === 409 || /already exists/i.test(e.message || '')) {
177
+ trace.steps.push({ step: 'sitesAdd', ok: true, note: 'already exists' });
178
+ log('property already registered (idempotent)');
179
+ } else {
180
+ trace.steps.push({ step: 'sitesAdd', ok: false, error: e.message });
181
+ process.stderr.write(`[gsc verify-via-cf-dns] sites.add failed: ${e.message}\n`);
182
+ return 2;
183
+ }
184
+ }
185
+
186
+ trace.verified = true;
187
+ out.write(JSON.stringify(trace, null, 2) + '\n');
188
+ return 0;
189
+ }
@@ -0,0 +1,59 @@
1
+ // call-log.mjs — best-effort JSONL logger for `pa knowledge` invocations.
2
+ //
3
+ // Purpose (Deliverable B, w-2026-07-06-020): the eval set proves the
4
+ // system CAN retrieve; this log shows whether sessions DO retrieve.
5
+ // Written to `<repoRoot>/.session/knowledge-calls.jsonl` — per-host,
6
+ // gitignored. The Librarian periodically scans the tail to spot queries
7
+ // that repeatedly miss; those become new eval cases.
8
+ //
9
+ // Line schema (camelCase per estate convention):
10
+ // { timestamp, query, verb, resultCount, sessionId }
11
+ //
12
+ // Discipline: this file MUST NOT throw or reject. A broken .session dir,
13
+ // permission error, or missing repo root are all silent no-ops — the log
14
+ // is an observability aid, not a critical path.
15
+
16
+ import { appendFile, mkdir } from 'node:fs/promises';
17
+ import { join } from 'node:path';
18
+
19
+ import { getRepoRoot } from '../pa/repo-root.mjs';
20
+
21
+ const LOG_RELATIVE_PATH = '.session/knowledge-calls.jsonl';
22
+
23
+ // Session id: a short random tag captured once per process. The intent
24
+ // is grouping — the Librarian wants to see "which queries came from the
25
+ // same shell / same task", not to correlate across restarts.
26
+ let sessionId = null;
27
+ function ensureSessionId() {
28
+ if (sessionId) return sessionId;
29
+ if (process.env.CLAUDE_SESSION_ID) {
30
+ sessionId = process.env.CLAUDE_SESSION_ID.slice(0, 32);
31
+ return sessionId;
32
+ }
33
+ if (process.env.PA_SESSION_ID) {
34
+ sessionId = process.env.PA_SESSION_ID.slice(0, 32);
35
+ return sessionId;
36
+ }
37
+ sessionId = Math.random().toString(36).slice(2, 10) + '-' + process.pid;
38
+ return sessionId;
39
+ }
40
+
41
+ export async function appendCallLog({ verb, query, resultCount, timestamp } = {}) {
42
+ const repoRoot = await getRepoRoot().catch(() => null);
43
+ if (!repoRoot) return;
44
+ const target = join(repoRoot, LOG_RELATIVE_PATH);
45
+ const line = JSON.stringify({
46
+ timestamp: timestamp ?? new Date().toISOString(),
47
+ query: query ?? null,
48
+ verb,
49
+ resultCount,
50
+ sessionId: ensureSessionId(),
51
+ }) + '\n';
52
+ try {
53
+ await mkdir(join(repoRoot, '.session'), { recursive: true });
54
+ await appendFile(target, line, 'utf8');
55
+ } catch { /* no-op — see file header */ }
56
+ }
57
+
58
+ // Test seams.
59
+ export const _internals = { LOG_RELATIVE_PATH, ensureSessionId };
@@ -0,0 +1,242 @@
1
+ // cli.mjs — argv router for `pa knowledge <verb>`.
2
+ //
3
+ // Verbs (6):
4
+ // pa knowledge related <slug> [--in|--out]
5
+ // pa knowledge search <term> [--full] [--strict]
6
+ // pa knowledge domain <name>
7
+ // pa knowledge orphans [--exclude-stubs]
8
+ // pa knowledge path <a> <b>
9
+ // pa knowledge eval [--fixture PATH] [--out DIR] [--full] [--format ...]
10
+ //
11
+ // Global flag:
12
+ // --format <table|json|mermaid> default: table
13
+ //
14
+ // Repo-root resolution: DAVE_REPO_ROOT / PA_REPO_ROOT env var, else walk
15
+ // upward from cwd until a `.git` ancestor is found (same as `pa work` /
16
+ // `pa project` via `pa/repo-root.mjs`).
17
+ //
18
+ // Exit codes (tooling standard §6):
19
+ // 0 ok | 1 usage | 2 unknown-slug / ambiguous / unknown-domain
20
+ // 3 IO (graph missing or unreadable)
21
+
22
+ import { getRepoRoot, loadGraph, related, search, searchCascade, domain, orphans, path } from './graph.mjs';
23
+ import { formatRelated, formatSearch, formatDomain, formatOrphans, formatPath } from './formatters.mjs';
24
+ import { appendCallLog } from './call-log.mjs';
25
+
26
+ const USAGE = `pa knowledge — query the operator's knowledge graph
27
+
28
+ Usage:
29
+ pa knowledge related <slug> 1-hop neighbourhood for a doc
30
+ [--in|--out] limit to inbound / outbound edges
31
+ pa knowledge search <term> Find docs matching a term. Multi-word
32
+ terms AND-match: every word must appear
33
+ in the doc's id or title (or body with
34
+ --full) — e.g. search "barry voice".
35
+ On a zero-result AND-match, the default
36
+ cascade retries with body (--full) and
37
+ then as OR-match ranked by hits, then
38
+ prints a guided miss with nearest
39
+ domains — never a bare "(no matches)".
40
+ [--full] Include doc body (default: title only)
41
+ [--strict] Disable the cascade — restores the
42
+ AND-only behaviour for scripted callers
43
+ pa knowledge domain <name> All docs in a domain + internal edges
44
+ pa knowledge orphans Docs with no inbound edges
45
+ [--exclude-stubs] Skip null-domain nodes
46
+ pa knowledge path <a> <b> Shortest path between two docs
47
+ pa knowledge eval [--fixture P] Score the retrieval eval set (hit@1/5,
48
+ [--out D] orphan gauge, delta vs last run);
49
+ [--full] persists to
50
+ [--format ...] operator/knowledge/_meta/retrieval-eval-runs/
51
+ pa knowledge -h, --help Show this help
52
+
53
+ Global flags:
54
+ --format <table|json|mermaid> Output format (default: table)
55
+
56
+ Slug resolution: <slug> matches against node id (exact, or path-suffix)
57
+ and node title (case-insensitive substring). Ambiguous matches exit 2.
58
+
59
+ Domains (from the current operator graph):
60
+ claude-code-learnings, clients, engineering, hr, principles.md, systems, writing
61
+
62
+ Graph location: <repo-root>/operator/knowledge/.graph.json.
63
+ Repo-root resolution: \$DAVE_REPO_ROOT / \$PA_REPO_ROOT, else walk upward
64
+ from cwd looking for a .git entry.
65
+
66
+ JSON output shape (stable-by-convention — consumed by dispatch-briefer):
67
+ { "verb": "<name>", ...verb-specific fields }
68
+
69
+ Exit codes (tooling standard §6):
70
+ 0 ok | 1 usage error | 2 unknown/ambiguous slug or domain | 3 IO failure
71
+ `;
72
+
73
+ export async function run(argv) {
74
+ if (!argv.length || argv[0] === '-h' || argv[0] === '--help') {
75
+ process.stdout.write(USAGE);
76
+ return 0;
77
+ }
78
+ const verb = argv[0];
79
+ const rest = argv.slice(1);
80
+ try {
81
+ switch (verb) {
82
+ case 'related': return await doRelated(rest);
83
+ case 'search': return await doSearch(rest);
84
+ case 'domain': return await doDomain(rest);
85
+ case 'orphans': return await doOrphans(rest);
86
+ case 'path': return await doPath(rest);
87
+ case 'eval': {
88
+ const { run: runEval } = await import('./eval.mjs');
89
+ return await runEval(rest);
90
+ }
91
+ default:
92
+ process.stderr.write(`[pa knowledge] unknown verb: ${verb}\n`);
93
+ process.stderr.write(USAGE);
94
+ return 1;
95
+ }
96
+ } catch (err) {
97
+ process.stderr.write(`[pa knowledge] ${err.message || err}\n`);
98
+ return err.exitCode || 2;
99
+ }
100
+ }
101
+
102
+ // Best-effort call-log append. Failures are swallowed — a broken .session
103
+ // dir must never break `pa knowledge`. Awaited (not fire-and-forget) so
104
+ // the append lands before the CLI process exits; the underlying write is
105
+ // on the order of 1-2 ms so this is not a user-perceptible delay.
106
+ async function logCall(entry) {
107
+ try { await appendCallLog(entry); } catch { /* see file header */ }
108
+ }
109
+
110
+ // --- flag parser (bespoke to keep zero-dep) -------------------------------
111
+
112
+ function parseFlags(args) {
113
+ const positional = [];
114
+ const flags = {};
115
+ for (let i = 0; i < args.length; i++) {
116
+ const a = args[i];
117
+ if (a.startsWith('--')) {
118
+ const key = a.slice(2);
119
+ const peek = args[i + 1];
120
+ if (peek == null || peek.startsWith('--')) {
121
+ flags[key] = true;
122
+ } else {
123
+ flags[key] = peek;
124
+ i += 1;
125
+ }
126
+ } else {
127
+ positional.push(a);
128
+ }
129
+ }
130
+ return { positional, flags };
131
+ }
132
+
133
+ function resolveFormat(flags) {
134
+ const raw = flags.format;
135
+ if (raw == null || raw === true) return 'table';
136
+ if (raw !== 'table' && raw !== 'json' && raw !== 'mermaid') {
137
+ const err = new Error(`unknown --format: ${raw} (expected table | json | mermaid)`);
138
+ err.exitCode = 1;
139
+ throw err;
140
+ }
141
+ return raw;
142
+ }
143
+
144
+ async function loadGraphOrExplain() {
145
+ const repoRoot = await getRepoRoot();
146
+ const graph = await loadGraph({ repoRoot });
147
+ return { repoRoot, graph };
148
+ }
149
+
150
+ // --- verbs ----------------------------------------------------------------
151
+
152
+ async function doRelated(args) {
153
+ const { positional, flags } = parseFlags(args);
154
+ const format = resolveFormat(flags);
155
+ if (positional.length === 0) {
156
+ process.stderr.write('usage: pa knowledge related <slug> [--in|--out] [--format ...]\n');
157
+ return 1;
158
+ }
159
+ if (flags.in && flags.out) {
160
+ process.stderr.write('usage: pa knowledge related — --in and --out are mutually exclusive\n');
161
+ return 1;
162
+ }
163
+ const direction = flags.in ? 'in' : flags.out ? 'out' : 'both';
164
+ const { graph } = await loadGraphOrExplain();
165
+ const result = related(graph, positional[0], { direction });
166
+ process.stdout.write(formatRelated(result, format));
167
+ await logCall({ verb: 'related', query: positional[0], resultCount: result.neighbours.length });
168
+ return 0;
169
+ }
170
+
171
+ async function doSearch(args) {
172
+ const { positional, flags } = parseFlags(args);
173
+ const format = resolveFormat(flags);
174
+ if (positional.length === 0) {
175
+ process.stderr.write('usage: pa knowledge search <term> [--full] [--strict] [--format ...]\n');
176
+ return 1;
177
+ }
178
+ const full = flags.full === true;
179
+ const strict = flags.strict === true;
180
+ // Accept both `search "barry voice"` and unquoted `search barry voice` —
181
+ // all positionals form the query; tokenisation happens in search().
182
+ const term = positional.join(' ');
183
+ const { repoRoot, graph } = await loadGraphOrExplain();
184
+ if (strict) {
185
+ // Scripted-caller escape hatch. Preserves the pre-cascade shape —
186
+ // results-only, table renders "(no matches)" on empty, JSON envelope
187
+ // omits `mode` and `hint`. Byte-identical to the pre-Deliverable-A world.
188
+ const results = await search(graph, term, { full, repoRoot });
189
+ process.stdout.write(formatSearch(results, format, { term }));
190
+ await logCall({ verb: 'search', query: term, resultCount: results.length });
191
+ return 0;
192
+ }
193
+ const envelope = await searchCascade(graph, term, { full, repoRoot });
194
+ process.stdout.write(formatSearch(envelope.results, format, { term, envelope }));
195
+ await logCall({ verb: 'search', query: term, resultCount: envelope.results.length });
196
+ return 0;
197
+ }
198
+
199
+ async function doDomain(args) {
200
+ const { positional, flags } = parseFlags(args);
201
+ const format = resolveFormat(flags);
202
+ if (positional.length === 0) {
203
+ process.stderr.write('usage: pa knowledge domain <name> [--format ...]\n');
204
+ return 1;
205
+ }
206
+ const { graph } = await loadGraphOrExplain();
207
+ const result = domain(graph, positional[0]);
208
+ process.stdout.write(formatDomain(result, format));
209
+ await logCall({ verb: 'domain', query: positional[0], resultCount: result.nodes.length });
210
+ return 0;
211
+ }
212
+
213
+ async function doOrphans(args) {
214
+ const { flags } = parseFlags(args);
215
+ const format = resolveFormat(flags);
216
+ const includeStubs = !(flags['exclude-stubs'] === true);
217
+ const { graph } = await loadGraphOrExplain();
218
+ const results = orphans(graph, { includeStubs });
219
+ process.stdout.write(formatOrphans(results, format));
220
+ await logCall({ verb: 'orphans', query: null, resultCount: results.length });
221
+ return 0;
222
+ }
223
+
224
+ async function doPath(args) {
225
+ const { positional, flags } = parseFlags(args);
226
+ const format = resolveFormat(flags);
227
+ if (positional.length < 2) {
228
+ process.stderr.write('usage: pa knowledge path <a> <b> [--format ...]\n');
229
+ return 1;
230
+ }
231
+ const { graph } = await loadGraphOrExplain();
232
+ const result = path(graph, positional[0], positional[1]);
233
+ process.stdout.write(formatPath(result, format));
234
+ await logCall({
235
+ verb: 'path',
236
+ query: `${positional[0]} → ${positional[1]}`,
237
+ resultCount: result.path ? result.path.length : 0,
238
+ });
239
+ return 0;
240
+ }
241
+
242
+ export { USAGE };