@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,186 @@
1
+ #!/usr/bin/env node
2
+ // graph-builder.mjs — Builds a knowledge graph from forward links and backlinks.
3
+ //
4
+ // Reads forward links from markdown files + backlinks from .backlinks.json.
5
+ // Output: operator/knowledge/.graph.json
6
+ //
7
+ // CLI: node graph-builder.mjs [--root /path/to/repo]
8
+
9
+ import { readdir, readFile, writeFile } from 'node:fs/promises';
10
+ import { join, resolve, dirname, relative, normalize } from 'node:path';
11
+ import { fileURLToPath } from 'node:url';
12
+
13
+ const __dirname = dirname(fileURLToPath(import.meta.url));
14
+ const DEFAULT_ROOT = resolve(__dirname, '../../../..');
15
+
16
+ const USAGE = `
17
+ graph-builder — Build a knowledge graph from markdown links and backlinks
18
+
19
+ Usage:
20
+ node graph-builder.mjs [options]
21
+
22
+ Options:
23
+ --root <path> Repository root (default: 4 levels up from this script)
24
+ --help, -h Show this help
25
+
26
+ Reads forward links from .md files in operator/knowledge/ and core/knowledge/.
27
+ Reads backlinks from operator/knowledge/.backlinks.json.
28
+
29
+ Output: operator/knowledge/.graph.json
30
+ `.trim();
31
+
32
+ // ── Helpers ─────────────────────────────────────────────────────────
33
+
34
+ async function walkDir(dir) {
35
+ const results = [];
36
+ let entries;
37
+ try {
38
+ entries = await readdir(dir, { withFileTypes: true });
39
+ } catch (err) {
40
+ if (err.code === 'ENOENT') return results;
41
+ throw err;
42
+ }
43
+ for (const entry of entries) {
44
+ const full = join(dir, entry.name);
45
+ if (entry.isDirectory()) {
46
+ if (entry.name.startsWith('.')) continue;
47
+ results.push(...await walkDir(full));
48
+ } else if (entry.isFile() && entry.name.endsWith('.md')) {
49
+ results.push(full);
50
+ }
51
+ }
52
+ return results;
53
+ }
54
+
55
+ function extractTitle(content) {
56
+ const match = content.match(/^#\s+(.+)$/m);
57
+ return match ? match[1].trim() : null;
58
+ }
59
+
60
+ function extractForwardLinks(content, sourcePath, repoRoot) {
61
+ const links = [];
62
+ const sourceDir = dirname(sourcePath);
63
+
64
+ // Wiki-style: [[target]]
65
+ const wikiRe = /\[\[([^\]]+)\]\]/g;
66
+ let m;
67
+ while ((m = wikiRe.exec(content)) !== null) {
68
+ let target = m[1].trim();
69
+ if (!target.endsWith('.md')) target += '.md';
70
+ links.push(normalize(target));
71
+ }
72
+
73
+ // Markdown-style: [text](relative/path.md)
74
+ const mdRe = /\[([^\]]*)\]\(([^)]+)\)/g;
75
+ while ((m = mdRe.exec(content)) !== null) {
76
+ const href = m[2].trim();
77
+ if (href.startsWith('http://') || href.startsWith('https://') || href.startsWith('#') || href.startsWith('mailto:')) continue;
78
+ const path = href.split('#')[0];
79
+ if (!path || !path.endsWith('.md')) continue;
80
+ const abs = resolve(sourceDir, path);
81
+ const rel = relative(repoRoot, abs);
82
+ links.push(normalize(rel));
83
+ }
84
+
85
+ return [...new Set(links)];
86
+ }
87
+
88
+ function deriveDomain(relPath) {
89
+ const parts = relPath.split('/');
90
+ if (parts.length >= 3 && (parts[0] === 'operator' || parts[0] === 'core') && parts[1] === 'knowledge') {
91
+ return parts[2];
92
+ }
93
+ return null;
94
+ }
95
+
96
+ // ── Main ────────────────────────────────────────────────────────────
97
+
98
+ async function main(args) {
99
+ let root = DEFAULT_ROOT;
100
+
101
+ for (let i = 0; i < args.length; i++) {
102
+ const a = args[i];
103
+ if (a === '--help' || a === '-h') {
104
+ console.log(USAGE);
105
+ return 0;
106
+ }
107
+ if (a === '--root') {
108
+ root = resolve(args[++i]);
109
+ }
110
+ }
111
+
112
+ const scanDirs = [
113
+ join(root, 'operator', 'knowledge'),
114
+ join(root, 'core', 'knowledge'),
115
+ ];
116
+
117
+ const allFiles = [];
118
+ for (const dir of scanDirs) {
119
+ allFiles.push(...await walkDir(dir));
120
+ }
121
+
122
+ const nodesMap = new Map();
123
+ const edges = [];
124
+ const edgeSet = new Set();
125
+
126
+ for (const filePath of allFiles) {
127
+ const content = await readFile(filePath, 'utf8');
128
+ const relPath = relative(root, filePath);
129
+ const title = extractTitle(content) || relPath.split('/').pop().replace('.md', '');
130
+ const domain = deriveDomain(relPath);
131
+
132
+ nodesMap.set(relPath, { id: relPath, title, domain });
133
+
134
+ const forwardLinks = extractForwardLinks(content, filePath, root);
135
+ for (const target of forwardLinks) {
136
+ const edgeKey = `link:${relPath}->${target}`;
137
+ if (!edgeSet.has(edgeKey)) {
138
+ edgeSet.add(edgeKey);
139
+ edges.push({ from: relPath, to: target, type: 'link' });
140
+ }
141
+ }
142
+ }
143
+
144
+ // Read backlinks and add backlink edges
145
+ const backlinksPath = join(root, 'operator', 'knowledge', '.backlinks.json');
146
+ try {
147
+ const raw = await readFile(backlinksPath, 'utf8');
148
+ const backlinksData = JSON.parse(raw);
149
+ const bl = backlinksData.backlinks || {};
150
+ for (const [target, sources] of Object.entries(bl)) {
151
+ for (const source of sources) {
152
+ const edgeKey = `backlink:${target}->${source}`;
153
+ if (!edgeSet.has(edgeKey)) {
154
+ edgeSet.add(edgeKey);
155
+ edges.push({ from: target, to: source, type: 'backlink' });
156
+ }
157
+ if (!nodesMap.has(target)) {
158
+ nodesMap.set(target, { id: target, title: target.split('/').pop().replace('.md', ''), domain: deriveDomain(target) });
159
+ }
160
+ if (!nodesMap.has(source)) {
161
+ nodesMap.set(source, { id: source, title: source.split('/').pop().replace('.md', ''), domain: deriveDomain(source) });
162
+ }
163
+ }
164
+ }
165
+ } catch (err) {
166
+ if (err.code !== 'ENOENT') throw err;
167
+ console.warn('No .backlinks.json found — run backlink-indexer.mjs first. Building graph from forward links only.');
168
+ }
169
+
170
+ const nodes = [...nodesMap.values()].sort((a, b) => a.id.localeCompare(b.id));
171
+
172
+ const output = {
173
+ version: '1.0',
174
+ generatedAt: new Date().toISOString(),
175
+ nodes,
176
+ edges,
177
+ };
178
+
179
+ const outPath = join(root, 'operator', 'knowledge', '.graph.json');
180
+ await writeFile(outPath, JSON.stringify(output, null, 2) + '\n', 'utf8');
181
+ console.log(`Wrote ${outPath} (${nodes.length} nodes, ${edges.length} edges)`);
182
+ return 0;
183
+ }
184
+
185
+ const exitCode = await main(process.argv.slice(2));
186
+ process.exit(exitCode ?? 0);
@@ -0,0 +1,225 @@
1
+ #!/usr/bin/env node
2
+ // index-builder.mjs — Builds a domain index from operator/knowledge/ directories.
3
+ //
4
+ // Walks top-level directories under operator/knowledge/, extracts metadata
5
+ // from each domain's README.md, and outputs operator/knowledge/domains.json.
6
+ //
7
+ // CLI: node index-builder.mjs [--root /path/to/repo]
8
+
9
+ import { readdir, readFile, writeFile, stat } from 'node:fs/promises';
10
+ import { join, resolve, dirname } from 'node:path';
11
+ import { fileURLToPath } from 'node:url';
12
+
13
+ const __dirname = dirname(fileURLToPath(import.meta.url));
14
+ const DEFAULT_ROOT = process.env.DAVE_ROOT
15
+ ? resolve(process.env.DAVE_ROOT)
16
+ : resolve(__dirname, '../../../..');
17
+
18
+ const USAGE = `
19
+ index-builder — Build a domain index from operator knowledge directories
20
+
21
+ Usage:
22
+ node index-builder.mjs [options]
23
+
24
+ Options:
25
+ --root <path> Repository root (default: $DAVE_ROOT if set, else 4 levels up from this script)
26
+ --help, -h Show this help
27
+
28
+ Walks top-level directories under operator/knowledge/.
29
+ Extracts domain metadata from each directory's README.md (first paragraph).
30
+
31
+ Output: operator/knowledge/domains.json
32
+ `.trim();
33
+
34
+ // ── Helpers ─────────────────────────────────────────────────────────
35
+
36
+ function slugToName(slug) {
37
+ return slug
38
+ .split('-')
39
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
40
+ .join(' ');
41
+ }
42
+
43
+ function extractFirstParagraph(content) {
44
+ const lines = stripFrontMatter(content).split('\n');
45
+ let collecting = false;
46
+ const para = [];
47
+ for (const line of lines) {
48
+ const trimmed = line.trim();
49
+ if (trimmed.startsWith('#')) {
50
+ if (collecting) break;
51
+ continue;
52
+ }
53
+ if (trimmed === '') {
54
+ if (collecting) break;
55
+ continue;
56
+ }
57
+ collecting = true;
58
+ para.push(trimmed);
59
+ }
60
+ return para.join(' ') || null;
61
+ }
62
+
63
+ // Parses a leading `---`-delimited YAML front-matter block. Only supports
64
+ // the flat `key: value` pairs we need (displayName primarily). Returns an
65
+ // object of parsed keys (string values) or {} when no front-matter is
66
+ // present or parsing fails.
67
+ //
68
+ // We deliberately DO NOT pull in a YAML dependency — the platform is
69
+ // zero-dep by policy, and domain READMEs only need a handful of scalar
70
+ // fields. A strict line-based parser is both sufficient and auditable.
71
+ export function parseFrontMatter(content) {
72
+ if (typeof content !== 'string') return {};
73
+ if (!content.startsWith('---')) return {};
74
+ const lines = content.split(/\r?\n/);
75
+ if (lines[0].trim() !== '---') return {};
76
+ const out = {};
77
+ for (let i = 1; i < lines.length; i++) {
78
+ const line = lines[i];
79
+ if (line.trim() === '---') return out;
80
+ const m = /^([A-Za-z_][\w-]*)\s*:\s*(.*)$/.exec(line);
81
+ if (!m) continue;
82
+ let value = m[2].trim();
83
+ // Strip matching quotes.
84
+ if ((value.startsWith('"') && value.endsWith('"')) ||
85
+ (value.startsWith("'") && value.endsWith("'"))) {
86
+ value = value.slice(1, -1);
87
+ }
88
+ out[m[1]] = value;
89
+ }
90
+ // Unterminated front-matter — treat as no front-matter so the body
91
+ // parses as written.
92
+ return {};
93
+ }
94
+
95
+ // Returns `content` with the leading `---`-delimited front-matter block
96
+ // removed. If there's no front-matter, returns the content unchanged.
97
+ export function stripFrontMatter(content) {
98
+ if (typeof content !== 'string') return '';
99
+ if (!content.startsWith('---')) return content;
100
+ const lines = content.split(/\r?\n/);
101
+ if (lines[0].trim() !== '---') return content;
102
+ for (let i = 1; i < lines.length; i++) {
103
+ if (lines[i].trim() === '---') {
104
+ return lines.slice(i + 1).join('\n');
105
+ }
106
+ }
107
+ return content;
108
+ }
109
+
110
+ async function countMdFiles(dir) {
111
+ let count = 0;
112
+ const entries = await readdir(dir, { withFileTypes: true });
113
+ for (const entry of entries) {
114
+ const full = join(dir, entry.name);
115
+ if (entry.isDirectory() && !entry.name.startsWith('.')) {
116
+ count += await countMdFiles(full);
117
+ } else if (entry.isFile() && entry.name.endsWith('.md')) {
118
+ count++;
119
+ }
120
+ }
121
+ return count;
122
+ }
123
+
124
+ async function getLatestMtime(dir) {
125
+ let latest = new Date(0);
126
+ const entries = await readdir(dir, { withFileTypes: true });
127
+ for (const entry of entries) {
128
+ const full = join(dir, entry.name);
129
+ if (entry.isDirectory() && !entry.name.startsWith('.')) {
130
+ const sub = await getLatestMtime(full);
131
+ if (sub > latest) latest = sub;
132
+ } else if (entry.isFile()) {
133
+ const s = await stat(full);
134
+ if (s.mtime > latest) latest = s.mtime;
135
+ }
136
+ }
137
+ return latest;
138
+ }
139
+
140
+ // ── Main ────────────────────────────────────────────────────────────
141
+
142
+ async function main(args) {
143
+ let root = DEFAULT_ROOT;
144
+
145
+ for (let i = 0; i < args.length; i++) {
146
+ const a = args[i];
147
+ if (a === '--help' || a === '-h') {
148
+ console.log(USAGE);
149
+ return 0;
150
+ }
151
+ if (a === '--root') {
152
+ root = resolve(args[++i]);
153
+ }
154
+ }
155
+
156
+ const knowledgeDir = join(root, 'operator', 'knowledge');
157
+ let entries;
158
+ try {
159
+ entries = await readdir(knowledgeDir, { withFileTypes: true });
160
+ } catch (err) {
161
+ if (err.code === 'ENOENT') {
162
+ console.error(`Knowledge directory not found: ${knowledgeDir}`);
163
+ return 1;
164
+ }
165
+ throw err;
166
+ }
167
+
168
+ const domains = [];
169
+
170
+ for (const entry of entries) {
171
+ if (!entry.isDirectory()) continue;
172
+ if (entry.name.startsWith('.')) continue;
173
+
174
+ const domainPath = join(knowledgeDir, entry.name);
175
+ const id = entry.name;
176
+ const name = slugToName(id);
177
+ const relPath = `operator/knowledge/${id}`;
178
+
179
+ let description = null;
180
+ let displayName = null;
181
+ try {
182
+ const readme = await readFile(join(domainPath, 'README.md'), 'utf8');
183
+ const fm = parseFrontMatter(readme);
184
+ if (fm && typeof fm.displayName === 'string' && fm.displayName.length) {
185
+ displayName = fm.displayName;
186
+ }
187
+ description = extractFirstParagraph(readme);
188
+ } catch (err) {
189
+ if (err.code !== 'ENOENT') throw err;
190
+ }
191
+
192
+ const fileCount = await countMdFiles(domainPath);
193
+ const lastUpdated = await getLatestMtime(domainPath);
194
+
195
+ // displayName is emitted only when explicitly set in front-matter.
196
+ // Consumers fall back to `name` (capitalised id) when absent — this
197
+ // keeps the field optional and the downstream schema additive.
198
+ const record = {
199
+ id,
200
+ name,
201
+ path: relPath,
202
+ description,
203
+ fileCount,
204
+ lastUpdated: lastUpdated.toISOString(),
205
+ };
206
+ if (displayName) record.displayName = displayName;
207
+ domains.push(record);
208
+ }
209
+
210
+ domains.sort((a, b) => a.id.localeCompare(b.id));
211
+
212
+ const output = {
213
+ version: '1.0',
214
+ generatedAt: new Date().toISOString(),
215
+ domains,
216
+ };
217
+
218
+ const outPath = join(knowledgeDir, 'domains.json');
219
+ await writeFile(outPath, JSON.stringify(output, null, 2) + '\n', 'utf8');
220
+ console.log(`Wrote ${outPath} (${domains.length} domains indexed)`);
221
+ return 0;
222
+ }
223
+
224
+ const exitCode = await main(process.argv.slice(2));
225
+ process.exit(exitCode ?? 0);
@@ -0,0 +1,263 @@
1
+ #!/usr/bin/env node
2
+ // query.mjs — Knowledge graph query functions and CLI.
3
+ //
4
+ // Exports:
5
+ // findRelated(path, root) — files linked to/from the given path
6
+ // getBacklinks(path, root) — files that link TO the given path
7
+ // traverseFrom(path, depth, root) — BFS traversal, reachable nodes within depth
8
+ // searchByDomain(domain, root) — all files in a domain
9
+ //
10
+ // CLI:
11
+ // node query.mjs backlinks <path>
12
+ // node query.mjs related <path>
13
+ // node query.mjs traverse <path> [depth]
14
+ // node query.mjs domain <name>
15
+
16
+ import { readFile } from 'node:fs/promises';
17
+ import { realpathSync } from 'node:fs';
18
+ import { join, resolve, dirname, normalize } from 'node:path';
19
+ import { fileURLToPath } from 'node:url';
20
+
21
+ const __dirname = dirname(fileURLToPath(import.meta.url));
22
+ const DEFAULT_ROOT = resolve(__dirname, '../../../..');
23
+
24
+ const USAGE = `
25
+ query — Query the knowledge graph
26
+
27
+ Usage:
28
+ node query.mjs <command> [args]
29
+
30
+ Commands:
31
+ backlinks <path> Files that link TO the given path
32
+ related <path> Files linked to/from the given path (forward + back)
33
+ traverse <path> [depth] BFS traversal from a node (default depth: 2)
34
+ domain <name> All files in a domain
35
+
36
+ Options:
37
+ --root <path> Repository root (default: 4 levels up from this script)
38
+ --help, -h Show this help
39
+
40
+ Reads from:
41
+ operator/knowledge/.backlinks.json
42
+ operator/knowledge/.graph.json
43
+ operator/knowledge/domains.json
44
+ `.trim();
45
+
46
+ // ── Index readers ───────────────────────────────────────────────────
47
+
48
+ async function readBacklinks(root) {
49
+ const path = join(root, 'operator', 'knowledge', '.backlinks.json');
50
+ try {
51
+ const raw = await readFile(path, 'utf8');
52
+ return JSON.parse(raw);
53
+ } catch (err) {
54
+ if (err.code === 'ENOENT') return { backlinks: {} };
55
+ throw err;
56
+ }
57
+ }
58
+
59
+ async function readGraph(root) {
60
+ const path = join(root, 'operator', 'knowledge', '.graph.json');
61
+ try {
62
+ const raw = await readFile(path, 'utf8');
63
+ return JSON.parse(raw);
64
+ } catch (err) {
65
+ if (err.code === 'ENOENT') return { nodes: [], edges: [] };
66
+ throw err;
67
+ }
68
+ }
69
+
70
+ async function readDomains(root) {
71
+ const path = join(root, 'operator', 'knowledge', 'domains.json');
72
+ try {
73
+ const raw = await readFile(path, 'utf8');
74
+ return JSON.parse(raw);
75
+ } catch (err) {
76
+ if (err.code === 'ENOENT') return { domains: [] };
77
+ throw err;
78
+ }
79
+ }
80
+
81
+ // ── Exported query functions ────────────────────────────────────────
82
+
83
+ export async function findRelated(path, root = DEFAULT_ROOT) {
84
+ const normPath = normalize(path);
85
+ const graph = await readGraph(root);
86
+ const related = new Set();
87
+
88
+ for (const edge of graph.edges) {
89
+ if (normalize(edge.from) === normPath) related.add(edge.to);
90
+ if (normalize(edge.to) === normPath) related.add(edge.from);
91
+ }
92
+
93
+ return [...related].sort();
94
+ }
95
+
96
+ export async function getBacklinks(path, root = DEFAULT_ROOT) {
97
+ const normPath = normalize(path);
98
+ const data = await readBacklinks(root);
99
+ const bl = data.backlinks || {};
100
+
101
+ for (const [target, sources] of Object.entries(bl)) {
102
+ if (normalize(target) === normPath) {
103
+ return [...sources].sort();
104
+ }
105
+ }
106
+
107
+ return [];
108
+ }
109
+
110
+ export async function traverseFrom(path, depth = 2, root = DEFAULT_ROOT) {
111
+ const normPath = normalize(path);
112
+ const graph = await readGraph(root);
113
+
114
+ // Build adjacency list from all edges (undirected traversal)
115
+ const adj = new Map();
116
+ for (const edge of graph.edges) {
117
+ const from = normalize(edge.from);
118
+ const to = normalize(edge.to);
119
+ if (!adj.has(from)) adj.set(from, new Set());
120
+ if (!adj.has(to)) adj.set(to, new Set());
121
+ adj.get(from).add(to);
122
+ adj.get(to).add(from);
123
+ }
124
+
125
+ // BFS
126
+ const visited = new Set([normPath]);
127
+ let frontier = [normPath];
128
+
129
+ for (let d = 0; d < depth && frontier.length > 0; d++) {
130
+ const nextFrontier = [];
131
+ for (const node of frontier) {
132
+ const neighbours = adj.get(node) || new Set();
133
+ for (const n of neighbours) {
134
+ if (!visited.has(n)) {
135
+ visited.add(n);
136
+ nextFrontier.push(n);
137
+ }
138
+ }
139
+ }
140
+ frontier = nextFrontier;
141
+ }
142
+
143
+ visited.delete(normPath);
144
+ return [...visited].sort();
145
+ }
146
+
147
+ export async function searchByDomain(domain, root = DEFAULT_ROOT) {
148
+ const graph = await readGraph(root);
149
+ return graph.nodes
150
+ .filter((n) => n.domain === domain)
151
+ .map((n) => n.id)
152
+ .sort();
153
+ }
154
+
155
+ // ── CLI ─────────────────────────────────────────────────────────────
156
+
157
+ async function main(args) {
158
+ let root = DEFAULT_ROOT;
159
+
160
+ const filtered = [];
161
+ for (let i = 0; i < args.length; i++) {
162
+ if (args[i] === '--root') {
163
+ root = resolve(args[++i]);
164
+ } else {
165
+ filtered.push(args[i]);
166
+ }
167
+ }
168
+
169
+ if (!filtered.length || filtered[0] === '--help' || filtered[0] === '-h') {
170
+ console.log(USAGE);
171
+ return 0;
172
+ }
173
+
174
+ const cmd = filtered[0];
175
+
176
+ if (cmd === 'backlinks') {
177
+ const target = filtered[1];
178
+ if (!target) {
179
+ console.error('Usage: query.mjs backlinks <path>');
180
+ return 1;
181
+ }
182
+ const results = await getBacklinks(target, root);
183
+ if (!results.length) {
184
+ console.log('No backlinks found.');
185
+ } else {
186
+ for (const r of results) console.log(r);
187
+ }
188
+ return 0;
189
+ }
190
+
191
+ if (cmd === 'related') {
192
+ const target = filtered[1];
193
+ if (!target) {
194
+ console.error('Usage: query.mjs related <path>');
195
+ return 1;
196
+ }
197
+ const results = await findRelated(target, root);
198
+ if (!results.length) {
199
+ console.log('No related files found.');
200
+ } else {
201
+ for (const r of results) console.log(r);
202
+ }
203
+ return 0;
204
+ }
205
+
206
+ if (cmd === 'traverse') {
207
+ const target = filtered[1];
208
+ if (!target) {
209
+ console.error('Usage: query.mjs traverse <path> [depth]');
210
+ return 1;
211
+ }
212
+ const depth = parseInt(filtered[2], 10) || 2;
213
+ const results = await traverseFrom(target, depth, root);
214
+ if (!results.length) {
215
+ console.log('No reachable nodes found.');
216
+ } else {
217
+ for (const r of results) console.log(r);
218
+ }
219
+ return 0;
220
+ }
221
+
222
+ if (cmd === 'domain') {
223
+ const name = filtered[1];
224
+ if (!name) {
225
+ console.error('Usage: query.mjs domain <name>');
226
+ return 1;
227
+ }
228
+ const results = await searchByDomain(name, root);
229
+ if (!results.length) {
230
+ console.log('No files found in domain.');
231
+ } else {
232
+ for (const r of results) console.log(r);
233
+ }
234
+ return 0;
235
+ }
236
+
237
+ console.error(`Unknown command: ${cmd}`);
238
+ console.error('Run `node query.mjs --help` for usage.');
239
+ return 1;
240
+ }
241
+
242
+ // ISMAIN-AUDIT (bug-3 sweep): path.resolve() normalises path segments but
243
+ // does not dereference symlinks, so this had the same class of fragility
244
+ // as the endsWith idiom fixed elsewhere in the scheduler — an argv[1]
245
+ // reached via a symlinked path (pnpm .bin shim, workspace link) would not
246
+ // equal the realpath-resolved import.meta.url. This file is not currently
247
+ // registered as a package `bin` (only invoked directly via `node
248
+ // .../query.mjs` per its own usage docs), so it is not proven to fire in
249
+ // production, but is fixed defensively to match the robust pattern used
250
+ // across the repo.
251
+ function isDirectlyInvoked() {
252
+ if (!process.argv[1]) return false;
253
+ try {
254
+ return fileURLToPath(import.meta.url) === realpathSync(resolve(process.argv[1]));
255
+ } catch {
256
+ return false;
257
+ }
258
+ }
259
+
260
+ if (isDirectlyInvoked()) {
261
+ const exitCode = await main(process.argv.slice(2));
262
+ process.exit(exitCode ?? 0);
263
+ }