@kontourai/flow-agents 0.1.1

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 (418) hide show
  1. package/.githooks/pre-push +11 -0
  2. package/.github/workflows/ci.yml +210 -0
  3. package/.github/workflows/docs-pages.yml +52 -0
  4. package/.github/workflows/publish-npm.yml +104 -0
  5. package/AGENTS.md +26 -0
  6. package/CHANGELOG.md +66 -0
  7. package/CODE_OF_CONDUCT.md +25 -0
  8. package/CONTEXT.md +300 -0
  9. package/CONTRIBUTING.md +44 -0
  10. package/LICENSE +201 -0
  11. package/README.md +129 -0
  12. package/SECURITY.md +33 -0
  13. package/agent-cards/dev.json +19 -0
  14. package/agents/dev.json +127 -0
  15. package/agents/tool-code-reviewer.json +61 -0
  16. package/agents/tool-dependencies-updater.json +118 -0
  17. package/agents/tool-explore-config.json +92 -0
  18. package/agents/tool-explore-deps.json +92 -0
  19. package/agents/tool-explore-entry.json +92 -0
  20. package/agents/tool-explore-patterns.json +92 -0
  21. package/agents/tool-explore-structure.json +92 -0
  22. package/agents/tool-explore-tests.json +92 -0
  23. package/agents/tool-planner.json +57 -0
  24. package/agents/tool-playwright.json +145 -0
  25. package/agents/tool-security-reviewer.json +56 -0
  26. package/agents/tool-verifier.json +61 -0
  27. package/agents/tool-worker.json +58 -0
  28. package/build/src/cli/console-learning-projection.js +123 -0
  29. package/build/src/cli/docs-preview.js +39 -0
  30. package/build/src/cli/effective-backlog-settings.js +102 -0
  31. package/build/src/cli/export-bookmarks.js +38 -0
  32. package/build/src/cli/fixture-retirement-audit.js +140 -0
  33. package/build/src/cli/flow-kit.js +138 -0
  34. package/build/src/cli/import-bookmarks.js +50 -0
  35. package/build/src/cli/init.js +239 -0
  36. package/build/src/cli/instinct-cli.js +93 -0
  37. package/build/src/cli/promote-workflow-artifact.js +63 -0
  38. package/build/src/cli/publish-change-helper.js +154 -0
  39. package/build/src/cli/pull-work-provider.js +469 -0
  40. package/build/src/cli/runtime-adapter.js +23 -0
  41. package/build/src/cli/telemetry-doctor.js +221 -0
  42. package/build/src/cli/usage-feedback.js +443 -0
  43. package/build/src/cli/validate-hook-influence.js +152 -0
  44. package/build/src/cli/validate-source-tree.js +31 -0
  45. package/build/src/cli/validate-workflow-artifacts.js +486 -0
  46. package/build/src/cli/veritas-governance.js +262 -0
  47. package/build/src/cli/workflow-artifact-cleanup-audit.js +272 -0
  48. package/build/src/cli/workflow-sidecar.js +816 -0
  49. package/build/src/cli.js +89 -0
  50. package/build/src/flow-kit/validate.js +75 -0
  51. package/build/src/lib/args.js +45 -0
  52. package/build/src/lib/fs.js +62 -0
  53. package/build/src/lib/workflow-learning-projection.js +334 -0
  54. package/build/src/runtime-adapters.js +146 -0
  55. package/build/src/tools/build-universal-bundles.js +397 -0
  56. package/build/src/tools/common.js +56 -0
  57. package/build/src/tools/filter-installed-packs.js +132 -0
  58. package/build/src/tools/generate-context-map.js +198 -0
  59. package/build/src/tools/validate-package.js +64 -0
  60. package/build/src/tools/validate-source-tree.js +622 -0
  61. package/console.telemetry.json +176 -0
  62. package/context/base-rules.md +17 -0
  63. package/context/code-review-standards.md +62 -0
  64. package/context/coding-standards.md +42 -0
  65. package/context/common/orchestrators.md +12 -0
  66. package/context/common/subagents.md +28 -0
  67. package/context/contracts/artifact-contract.md +182 -0
  68. package/context/contracts/builder-kit-workflow-state-contract.md +319 -0
  69. package/context/contracts/delivery-contract.md +69 -0
  70. package/context/contracts/execution-contract.md +53 -0
  71. package/context/contracts/governance-adapter-contract.md +67 -0
  72. package/context/contracts/planning-contract.md +85 -0
  73. package/context/contracts/review-contract.md +104 -0
  74. package/context/contracts/sandbox-policy.md +52 -0
  75. package/context/contracts/verification-contract.md +134 -0
  76. package/context/contracts/work-item-contract.md +215 -0
  77. package/context/deferred/demo-mode.md +33 -0
  78. package/context/deferred/languages/go.md +31 -0
  79. package/context/deferred/languages/python.md +31 -0
  80. package/context/deferred/languages/typescript.md +34 -0
  81. package/context/deferred/parallelization.md +35 -0
  82. package/context/deferred/worktree-isolation.md +24 -0
  83. package/context/development-workflow.md +50 -0
  84. package/context/scripts/context-budget/budget-scan.sh +166 -0
  85. package/context/scripts/detect-tools.sh +3 -0
  86. package/context/scripts/discover-agents.sh +28 -0
  87. package/context/scripts/git-status.sh +49 -0
  88. package/context/scripts/hooks/config-protection.js +79 -0
  89. package/context/scripts/hooks/desktop-notify.sh +39 -0
  90. package/context/scripts/hooks/governance-audit.sh +135 -0
  91. package/context/scripts/hooks/lib/audit-transport.sh +40 -0
  92. package/context/scripts/hooks/lib/hook-flags.js +49 -0
  93. package/context/scripts/hooks/lib/patterns.sh +57 -0
  94. package/context/scripts/hooks/lib/resolve-formatter.js +80 -0
  95. package/context/scripts/hooks/post-edit-accumulator.js +66 -0
  96. package/context/scripts/hooks/pre-commit-quality.js +194 -0
  97. package/context/scripts/hooks/quality-gate.js +93 -0
  98. package/context/scripts/hooks/report-only-guard.js +21 -0
  99. package/context/scripts/hooks/run-hook.js +136 -0
  100. package/context/scripts/hooks/stop-format-typecheck.js +141 -0
  101. package/context/scripts/hooks/stop-goal-fit.js +337 -0
  102. package/context/scripts/hooks/workflow-steering.js +250 -0
  103. package/context/scripts/telemetry/console-presets.sh +14 -0
  104. package/context/scripts/telemetry/install-console-config.sh +214 -0
  105. package/context/scripts/telemetry/lib/config.sh +85 -0
  106. package/context/scripts/telemetry/lib/enrich.sh +115 -0
  107. package/context/scripts/telemetry/lib/redact.sh +22 -0
  108. package/context/scripts/telemetry/lib/session.sh +63 -0
  109. package/context/scripts/telemetry/lib/transport.sh +183 -0
  110. package/context/scripts/telemetry/lib/usage.sh +29 -0
  111. package/context/scripts/telemetry/sync-agents.sh +173 -0
  112. package/context/scripts/telemetry/telemetry.conf +23 -0
  113. package/context/scripts/telemetry/telemetry.sh +387 -0
  114. package/context/scripts/validate-package.sh +89 -0
  115. package/context/settings/backlog-provider-settings.json +54 -0
  116. package/context/templates/core/identity.md +26 -0
  117. package/context/templates/core/user.md +15 -0
  118. package/docs/_config.yml +15 -0
  119. package/docs/_layouts/default.html +87 -0
  120. package/docs/adr/0001-flow-agents-consumes-flow.md +77 -0
  121. package/docs/adr/0002-flow-kits-as-extension-unit.md +13 -0
  122. package/docs/adr/0003-flow-agents-coordinates-kits-and-adapters.md +13 -0
  123. package/docs/adr/0004-gates-expect-surface-claims.md +15 -0
  124. package/docs/adr/0005-kubernetes-inspired-resource-contracts.md +48 -0
  125. package/docs/adr/0006-typescript-first-source-policy.md +98 -0
  126. package/docs/agent-system-guidebook.md +391 -0
  127. package/docs/agent-usage-feedback-loop.md +351 -0
  128. package/docs/assets/favicon.svg +13 -0
  129. package/docs/assets/og-image.png +0 -0
  130. package/docs/assets/site.css +774 -0
  131. package/docs/assets/site.js +139 -0
  132. package/docs/configurable-workflow-routing.md +174 -0
  133. package/docs/context-map.md +145 -0
  134. package/docs/developer-architecture.md +145 -0
  135. package/docs/developer-hook-setup.md +61 -0
  136. package/docs/fixture-ownership.md +44 -0
  137. package/docs/flow-kit-repository-contract.md +180 -0
  138. package/docs/index.md +129 -0
  139. package/docs/kontour-resource-contract.md +358 -0
  140. package/docs/migrations.md +64 -0
  141. package/docs/north-star.md +322 -0
  142. package/docs/operating-layers.md +110 -0
  143. package/docs/repository-structure.md +132 -0
  144. package/docs/sandbox-policy.md +56 -0
  145. package/docs/skills-map.md +203 -0
  146. package/docs/standards-register.md +96 -0
  147. package/docs/veritas-integration.md +165 -0
  148. package/docs/work-item-adapters.md +72 -0
  149. package/docs/workflow-artifact-lifecycle.md +141 -0
  150. package/docs/workflow-eval-strategy.md +295 -0
  151. package/docs/workflow-shared-contracts.md +51 -0
  152. package/docs/workflow-usage-guide.md +443 -0
  153. package/evals/ARCHITECTURE.md +143 -0
  154. package/evals/CONVENTIONS.md +58 -0
  155. package/evals/README.md +128 -0
  156. package/evals/acceptance/run.sh +29 -0
  157. package/evals/acceptance/test_claude_harness.sh +242 -0
  158. package/evals/acceptance/test_codex_harness.sh +108 -0
  159. package/evals/acceptance/test_kiro_harness.sh +128 -0
  160. package/evals/cases/dev/404.html +97 -0
  161. package/evals/cases/dev/code-review.yaml +44 -0
  162. package/evals/cases/dev/dashboard.html +300 -0
  163. package/evals/cases/dev/deliver.yaml +66 -0
  164. package/evals/cases/dev/dependency-update.yaml +16 -0
  165. package/evals/cases/dev/explore.yaml +20 -0
  166. package/evals/cases/dev/index.html +370 -0
  167. package/evals/cases/dev/package-lock.json +28 -0
  168. package/evals/cases/dev/package.json +16 -0
  169. package/evals/cases/dev/plan-work.yaml +20 -0
  170. package/evals/cases/dev/promptfooconfig.yaml +666 -0
  171. package/evals/cases/dev/search-first.yaml +20 -0
  172. package/evals/cases/dev/tdd-workflow.yaml +48 -0
  173. package/evals/cases/dev/verify-work.yaml +44 -0
  174. package/evals/cases/dev/workflow.yaml +34 -0
  175. package/evals/ci/run-baseline.sh +283 -0
  176. package/evals/fixtures/backlog-provider-settings/global-default.json +44 -0
  177. package/evals/fixtures/backlog-provider-settings/project-override.json +53 -0
  178. package/evals/fixtures/builder-kit-workflow-state/baseline-freshness-resolution-hint.json +139 -0
  179. package/evals/fixtures/builder-kit-workflow-state/direct-primitive-stop.json +59 -0
  180. package/evals/fixtures/builder-kit-workflow-state/empty-board-route-shape.json +55 -0
  181. package/evals/fixtures/builder-kit-workflow-state/happy-path.json +71 -0
  182. package/evals/fixtures/builder-kit-workflow-state/mid-work-resume.json +80 -0
  183. package/evals/fixtures/builder-kit-workflow-state/missing-prestep-recovery.json +65 -0
  184. package/evals/fixtures/builder-kit-workflow-state/product-build-chaining.json +60 -0
  185. package/evals/fixtures/builder-kit-workflow-state/stale-continuation-requires-new-probe.json +57 -0
  186. package/evals/fixtures/console-learning-projection/artifacts/console-learning-correction/learning.json +50 -0
  187. package/evals/fixtures/console-learning-projection/artifacts/console-learning-open-route/learning.json +41 -0
  188. package/evals/fixtures/flow-kit-repository/invalid-absolute-path/kit.json +8 -0
  189. package/evals/fixtures/flow-kit-repository/invalid-asset-section/flows/review.flow.json +6 -0
  190. package/evals/fixtures/flow-kit-repository/invalid-asset-section/kit.json +11 -0
  191. package/evals/fixtures/flow-kit-repository/invalid-duplicate-flow/flows/review.flow.json +6 -0
  192. package/evals/fixtures/flow-kit-repository/invalid-duplicate-flow/kit.json +9 -0
  193. package/evals/fixtures/flow-kit-repository/invalid-id/flows/review.flow.json +6 -0
  194. package/evals/fixtures/flow-kit-repository/invalid-id/kit.json +8 -0
  195. package/evals/fixtures/flow-kit-repository/invalid-malformed-json/kit.json +8 -0
  196. package/evals/fixtures/flow-kit-repository/invalid-missing-flow/kit.json +8 -0
  197. package/evals/fixtures/flow-kit-repository/invalid-missing-id/flows/review.flow.json +6 -0
  198. package/evals/fixtures/flow-kit-repository/invalid-missing-id/kit.json +7 -0
  199. package/evals/fixtures/flow-kit-repository/invalid-missing-schema-version/flows/review.flow.json +6 -0
  200. package/evals/fixtures/flow-kit-repository/invalid-missing-schema-version/kit.json +7 -0
  201. package/evals/fixtures/flow-kit-repository/invalid-name/flows/review.flow.json +6 -0
  202. package/evals/fixtures/flow-kit-repository/invalid-name/kit.json +8 -0
  203. package/evals/fixtures/flow-kit-repository/invalid-schema-version/flows/review.flow.json +6 -0
  204. package/evals/fixtures/flow-kit-repository/invalid-schema-version/kit.json +8 -0
  205. package/evals/fixtures/flow-kit-repository/invalid-traversal/kit.json +8 -0
  206. package/evals/fixtures/flow-kit-repository/mixed-runtime-kit/adapters/example.json +3 -0
  207. package/evals/fixtures/flow-kit-repository/mixed-runtime-kit/assets/example.txt +1 -0
  208. package/evals/fixtures/flow-kit-repository/mixed-runtime-kit/docs/README.md +3 -0
  209. package/evals/fixtures/flow-kit-repository/mixed-runtime-kit/flows/runtime.flow.json +26 -0
  210. package/evals/fixtures/flow-kit-repository/mixed-runtime-kit/kit-evals/example.json +3 -0
  211. package/evals/fixtures/flow-kit-repository/mixed-runtime-kit/kit-skills/mixed/SKILL.md +3 -0
  212. package/evals/fixtures/flow-kit-repository/mixed-runtime-kit/kit.json +44 -0
  213. package/evals/fixtures/flow-kit-repository/valid-local-kit/docs/README.md +3 -0
  214. package/evals/fixtures/flow-kit-repository/valid-local-kit/flows/review.flow.json +26 -0
  215. package/evals/fixtures/flow-kit-repository/valid-local-kit/kit.json +20 -0
  216. package/evals/fixtures/hook-influence/cases.json +336 -0
  217. package/evals/fixtures/pull-work-provider/github-issues.json +170 -0
  218. package/evals/fixtures/pull-work-wip-shepherding/global-wip-informs.json +43 -0
  219. package/evals/fixtures/pull-work-wip-shepherding/personal-wip-blocks.json +42 -0
  220. package/evals/fixtures/surface-trust/accepted-claim-trust-report.json +31 -0
  221. package/evals/fixtures/surface-trust/artifact-absent.json +19 -0
  222. package/evals/fixtures/surface-trust/integrity-mismatch-trust-report.json +32 -0
  223. package/evals/fixtures/surface-trust/missing-authority-trust-report.json +27 -0
  224. package/evals/fixtures/surface-trust/provider-absent.json +19 -0
  225. package/evals/fixtures/surface-trust/rejected-claim-trust-report.json +30 -0
  226. package/evals/fixtures/surface-trust/stale-claim-trust-snapshot.json +31 -0
  227. package/evals/fixtures/usage-feedback/sample-full.jsonl +11 -0
  228. package/evals/fixtures/usage-feedback/sample-outcomes.jsonl +1 -0
  229. package/evals/fixtures/veritas-governance-adapter/fake-veritas-pass.sh +18 -0
  230. package/evals/fixtures/veritas-governance-adapter/fake-veritas-secret-fail.sh +10 -0
  231. package/evals/fixtures/veritas-governance-adapter/fake-veritas-unconfigured.sh +4 -0
  232. package/evals/integration/test_bundle_install.sh +541 -0
  233. package/evals/integration/test_console_learning_projection.sh +192 -0
  234. package/evals/integration/test_context_map.sh +65 -0
  235. package/evals/integration/test_effective_backlog_settings.sh +58 -0
  236. package/evals/integration/test_fixture_retirement_audit.sh +58 -0
  237. package/evals/integration/test_flow_agents_statusline.sh +93 -0
  238. package/evals/integration/test_flow_kit_repository.sh +90 -0
  239. package/evals/integration/test_goal_fit_hook.sh +482 -0
  240. package/evals/integration/test_hook_category_behaviors.sh +190 -0
  241. package/evals/integration/test_hook_influence_cases.sh +69 -0
  242. package/evals/integration/test_local_flow_kit_install.sh +145 -0
  243. package/evals/integration/test_publish_change_helper.sh +176 -0
  244. package/evals/integration/test_pull_work_provider.sh +140 -0
  245. package/evals/integration/test_runtime_adapter_activation.sh +106 -0
  246. package/evals/integration/test_telemetry.sh +485 -0
  247. package/evals/integration/test_telemetry_doctor.sh +193 -0
  248. package/evals/integration/test_usage_feedback_dashboard.sh +169 -0
  249. package/evals/integration/test_usage_feedback_global.sh +117 -0
  250. package/evals/integration/test_usage_feedback_import.sh +227 -0
  251. package/evals/integration/test_usage_feedback_outcomes.sh +165 -0
  252. package/evals/integration/test_usage_feedback_report.sh +263 -0
  253. package/evals/integration/test_veritas_governance_adapter.sh +235 -0
  254. package/evals/integration/test_workflow_artifact_cleanup_audit.sh +287 -0
  255. package/evals/integration/test_workflow_artifacts.sh +1247 -0
  256. package/evals/integration/test_workflow_sidecar_writer.sh +2112 -0
  257. package/evals/integration/test_workflow_steering_hook.sh +337 -0
  258. package/evals/lib/assertions/delegated-to.js +40 -0
  259. package/evals/lib/assertions/max-tool-calls.js +15 -0
  260. package/evals/lib/assertions/no-write-tools.js +27 -0
  261. package/evals/lib/assertions/pass-at-k.js +39 -0
  262. package/evals/lib/assertions/telemetry-utils.js +105 -0
  263. package/evals/lib/assertions/tool-called.js +39 -0
  264. package/evals/lib/assertions/verify-after-fix.js +61 -0
  265. package/evals/lib/claude-judge.sh +40 -0
  266. package/evals/lib/claude-provider.sh +74 -0
  267. package/evals/lib/codex-judge.sh +39 -0
  268. package/evals/lib/codex-provider.sh +81 -0
  269. package/evals/lib/eval-dev.sh +5 -0
  270. package/evals/lib/eval-judge.sh +22 -0
  271. package/evals/lib/eval-provider.sh +26 -0
  272. package/evals/lib/eval-report.sh +73 -0
  273. package/evals/lib/kiro-dev.sh +4 -0
  274. package/evals/lib/kiro-judge.sh +17 -0
  275. package/evals/lib/kiro-provider.sh +62 -0
  276. package/evals/lib/node.sh +111 -0
  277. package/evals/promptfooconfig.yaml +70 -0
  278. package/evals/run.sh +309 -0
  279. package/evals/static/test_evidence_refs.sh +141 -0
  280. package/evals/static/test_package.sh +407 -0
  281. package/evals/static/test_repo_hooks.sh +68 -0
  282. package/evals/static/test_universal_bundles.sh +274 -0
  283. package/evals/static/test_workflow_skills.sh +1207 -0
  284. package/install.sh +64 -0
  285. package/integrations/veritas/flow-agents.adapter.json +138 -0
  286. package/integrations/veritas/flow-agents.authority-settings.json +26 -0
  287. package/integrations/veritas/flow-agents.repo-standards.json +82 -0
  288. package/kits/builder/flows/build.flow.json +218 -0
  289. package/kits/builder/flows/shape.flow.json +127 -0
  290. package/kits/builder/kit.json +19 -0
  291. package/kits/catalog.json +11 -0
  292. package/package.json +130 -0
  293. package/packaging/README.md +60 -0
  294. package/packaging/manifest.json +173 -0
  295. package/packaging/packs.json +69 -0
  296. package/powers/dependency-checker/POWER.md +20 -0
  297. package/powers/dependency-checker/mcp.json +20 -0
  298. package/powers/playwright/POWER.md +25 -0
  299. package/powers/playwright/mcp.json +12 -0
  300. package/prompts/code-audit.md +123 -0
  301. package/prompts/kcommit.md +88 -0
  302. package/schemas/backlog-provider-settings.schema.json +138 -0
  303. package/schemas/workflow-acceptance.schema.json +216 -0
  304. package/schemas/workflow-critique.schema.json +113 -0
  305. package/schemas/workflow-evidence.schema.json +357 -0
  306. package/schemas/workflow-handoff.schema.json +52 -0
  307. package/schemas/workflow-learning.schema.json +223 -0
  308. package/schemas/workflow-release.schema.json +172 -0
  309. package/schemas/workflow-state.schema.json +80 -0
  310. package/scripts/README.md +111 -0
  311. package/scripts/build-universal-bundles.js +3 -0
  312. package/scripts/check-content-boundary.cjs +99 -0
  313. package/scripts/context-budget/budget-scan.sh +166 -0
  314. package/scripts/detect-tools.sh +3 -0
  315. package/scripts/discover-agents.sh +28 -0
  316. package/scripts/effective-backlog-settings.js +2 -0
  317. package/scripts/filter-installed-packs.js +2 -0
  318. package/scripts/flow-kit.js +2 -0
  319. package/scripts/generate-context-map.js +2 -0
  320. package/scripts/git-status.sh +49 -0
  321. package/scripts/hooks/claude-hook-adapter.js +174 -0
  322. package/scripts/hooks/claude-telemetry-hook.js +115 -0
  323. package/scripts/hooks/codex-hook-adapter.js +176 -0
  324. package/scripts/hooks/codex-telemetry-hook.js +95 -0
  325. package/scripts/hooks/config-protection.js +79 -0
  326. package/scripts/hooks/desktop-notify.sh +39 -0
  327. package/scripts/hooks/governance-audit.sh +135 -0
  328. package/scripts/hooks/lib/audit-transport.sh +40 -0
  329. package/scripts/hooks/lib/hook-flags.js +49 -0
  330. package/scripts/hooks/lib/patterns.sh +57 -0
  331. package/scripts/hooks/lib/resolve-formatter.js +80 -0
  332. package/scripts/hooks/post-edit-accumulator.js +66 -0
  333. package/scripts/hooks/pre-commit-quality.js +194 -0
  334. package/scripts/hooks/quality-gate.js +93 -0
  335. package/scripts/hooks/report-only-guard.js +21 -0
  336. package/scripts/hooks/run-hook.js +136 -0
  337. package/scripts/hooks/stop-format-typecheck.js +141 -0
  338. package/scripts/hooks/stop-goal-fit.js +337 -0
  339. package/scripts/hooks/workflow-steering.js +250 -0
  340. package/scripts/install-codex-home.sh +106 -0
  341. package/scripts/package.json +3 -0
  342. package/scripts/promote-workflow-artifact.js +2 -0
  343. package/scripts/publish-change-helper.js +2 -0
  344. package/scripts/pull-work-provider.js +2 -0
  345. package/scripts/setup-repo-hooks.sh +8 -0
  346. package/scripts/statusline/flow-agents-statusline.js +157 -0
  347. package/scripts/telemetry/console-presets.sh +14 -0
  348. package/scripts/telemetry/install-console-config.sh +214 -0
  349. package/scripts/telemetry/lib/config.sh +85 -0
  350. package/scripts/telemetry/lib/enrich.sh +115 -0
  351. package/scripts/telemetry/lib/redact.sh +22 -0
  352. package/scripts/telemetry/lib/session.sh +63 -0
  353. package/scripts/telemetry/lib/transport.sh +183 -0
  354. package/scripts/telemetry/lib/usage.sh +29 -0
  355. package/scripts/telemetry/sync-agents.sh +173 -0
  356. package/scripts/telemetry/telemetry.conf +23 -0
  357. package/scripts/telemetry/telemetry.sh +387 -0
  358. package/scripts/usage-feedback.js +2 -0
  359. package/scripts/validate-hook-influence-cases.js +2 -0
  360. package/scripts/validate-package.sh +89 -0
  361. package/scripts/validate-source-tree.js +9 -0
  362. package/skills/agentic-engineering/SKILL.md +62 -0
  363. package/skills/browser-test/SKILL.md +51 -0
  364. package/skills/builder-shape/SKILL.md +76 -0
  365. package/skills/context-budget/SKILL.md +40 -0
  366. package/skills/deliver/SKILL.md +241 -0
  367. package/skills/dependency-update/SKILL.md +68 -0
  368. package/skills/design-probe/SKILL.md +107 -0
  369. package/skills/eval-rebuild/SKILL.md +39 -0
  370. package/skills/evidence-gate/SKILL.md +186 -0
  371. package/skills/execute-plan/SKILL.md +110 -0
  372. package/skills/explore/SKILL.md +137 -0
  373. package/skills/feedback-loop/SKILL.md +87 -0
  374. package/skills/fix-bug/SKILL.md +133 -0
  375. package/skills/frontend-design/SKILL.md +80 -0
  376. package/skills/github-cli/SKILL.md +63 -0
  377. package/skills/idea-to-backlog/SKILL.md +267 -0
  378. package/skills/knowledge-capture/SKILL.md +55 -0
  379. package/skills/learning-review/SKILL.md +115 -0
  380. package/skills/pickup-probe/SKILL.md +114 -0
  381. package/skills/plan-work/SKILL.md +176 -0
  382. package/skills/pull-work/SKILL.md +309 -0
  383. package/skills/release-readiness/SKILL.md +121 -0
  384. package/skills/review-work/SKILL.md +161 -0
  385. package/skills/search-first/SKILL.md +66 -0
  386. package/skills/tdd-workflow/SKILL.md +140 -0
  387. package/skills/verify-work/SKILL.md +109 -0
  388. package/src/cli/console-learning-projection.ts +140 -0
  389. package/src/cli/effective-backlog-settings.ts +99 -0
  390. package/src/cli/fixture-retirement-audit.ts +154 -0
  391. package/src/cli/flow-kit.ts +139 -0
  392. package/src/cli/init.ts +248 -0
  393. package/src/cli/promote-workflow-artifact.ts +64 -0
  394. package/src/cli/publish-change-helper.ts +143 -0
  395. package/src/cli/pull-work-provider.ts +481 -0
  396. package/src/cli/runtime-adapter.ts +24 -0
  397. package/src/cli/telemetry-doctor.ts +243 -0
  398. package/src/cli/usage-feedback.ts +418 -0
  399. package/src/cli/validate-hook-influence.ts +119 -0
  400. package/src/cli/validate-source-tree.ts +30 -0
  401. package/src/cli/validate-workflow-artifacts.ts +411 -0
  402. package/src/cli/veritas-governance.ts +322 -0
  403. package/src/cli/workflow-artifact-cleanup-audit.ts +281 -0
  404. package/src/cli/workflow-sidecar.ts +676 -0
  405. package/src/cli.ts +95 -0
  406. package/src/flow-kit/validate.ts +74 -0
  407. package/src/lib/args.ts +43 -0
  408. package/src/lib/fs.ts +62 -0
  409. package/src/lib/workflow-learning-projection.ts +491 -0
  410. package/src/runtime-adapters.ts +154 -0
  411. package/src/tools/build-universal-bundles.ts +366 -0
  412. package/src/tools/common.ts +61 -0
  413. package/src/tools/filter-installed-packs.ts +129 -0
  414. package/src/tools/generate-context-map.ts +199 -0
  415. package/src/tools/validate-package.ts +57 -0
  416. package/src/tools/validate-source-tree.ts +488 -0
  417. package/tsconfig.json +19 -0
  418. package/veritas.claims.json +6 -0
@@ -0,0 +1,146 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import { readJson, relPath, writeJson } from "./lib/fs.js";
4
+ const ASSET_CLASSES = ["flows", "skills", "docs", "adapters", "evals", "assets"];
5
+ function assetPath(root, value) {
6
+ if (path.isAbsolute(value))
7
+ return null;
8
+ const resolved = path.resolve(root, value);
9
+ const absRoot = path.resolve(root);
10
+ return resolved === absRoot || resolved.startsWith(`${absRoot}${path.sep}`) ? resolved : null;
11
+ }
12
+ function loadKitAssets(kitRoot, sourceKind, warnings, errors) {
13
+ const manifestPath = path.join(kitRoot, "kit.json");
14
+ if (!fs.existsSync(manifestPath)) {
15
+ errors.push(`${kitRoot}: missing kit.json`);
16
+ return [];
17
+ }
18
+ let manifest;
19
+ try {
20
+ manifest = readJson(manifestPath);
21
+ }
22
+ catch (error) {
23
+ errors.push(`${manifestPath}: ${error.message}`);
24
+ return [];
25
+ }
26
+ const kitId = typeof manifest.id === "string" ? manifest.id : "";
27
+ const kitName = typeof manifest.name === "string" ? manifest.name : kitId;
28
+ if (!kitId) {
29
+ errors.push(`${manifestPath}: missing kit id`);
30
+ return [];
31
+ }
32
+ const assets = [];
33
+ for (const assetClass of ASSET_CLASSES) {
34
+ const entries = manifest[assetClass];
35
+ if (entries === undefined)
36
+ continue;
37
+ if (!Array.isArray(entries)) {
38
+ warnings.push(`${kitId}: ${assetClass} must be a list; skipping section`);
39
+ continue;
40
+ }
41
+ for (const entry of entries) {
42
+ let rel;
43
+ let assetId = null;
44
+ let description;
45
+ if (typeof entry === "string")
46
+ rel = entry;
47
+ else if (typeof entry === "object" && entry !== null) {
48
+ const record = entry;
49
+ rel = typeof record.path === "string" ? record.path : undefined;
50
+ assetId = typeof record.id === "string" ? record.id : null;
51
+ description = typeof record.description === "string" ? record.description : undefined;
52
+ }
53
+ if (!rel) {
54
+ warnings.push(`${kitId}: ${assetClass} entry missing string path`);
55
+ continue;
56
+ }
57
+ const source = assetPath(kitRoot, rel);
58
+ if (!source) {
59
+ warnings.push(`${kitId}: ${assetClass} asset path is not local: ${rel}`);
60
+ continue;
61
+ }
62
+ if (!fs.existsSync(source)) {
63
+ warnings.push(`${kitId}: ${assetClass} asset path is missing: ${rel}`);
64
+ continue;
65
+ }
66
+ assets.push({ kit_id: kitId, kit_name: kitName, asset_class: assetClass, asset_id: assetId, relative_path: rel, source_path: source, source_kind: sourceKind, description });
67
+ }
68
+ }
69
+ return assets;
70
+ }
71
+ export function readKitInventory(sourceRoot, dest) {
72
+ const warnings = [];
73
+ const errors = [];
74
+ const assets = [];
75
+ const catalogPath = path.join(sourceRoot, "kits", "catalog.json");
76
+ if (!fs.existsSync(catalogPath))
77
+ errors.push(`${catalogPath}: missing Kit Catalog`);
78
+ else {
79
+ const catalog = readJson(catalogPath);
80
+ const kits = catalog.kits;
81
+ if (Array.isArray(kits)) {
82
+ kits.forEach((entry, index) => {
83
+ const rel = typeof entry === "object" && entry !== null ? entry.path : undefined;
84
+ if (typeof rel !== "string") {
85
+ warnings.push(`${catalogPath}: kits[${index}].path missing; skipping`);
86
+ return;
87
+ }
88
+ const kitRoot = assetPath(sourceRoot, rel);
89
+ if (!kitRoot || !fs.existsSync(kitRoot))
90
+ warnings.push(`${catalogPath}: kits[${index}].path unavailable: ${rel}`);
91
+ else
92
+ assets.push(...loadKitAssets(kitRoot, "builtin", warnings, errors));
93
+ });
94
+ }
95
+ }
96
+ const registryPath = path.join(dest, "kits", "local", "installed-kits.json");
97
+ if (fs.existsSync(registryPath)) {
98
+ const registry = readJson(registryPath);
99
+ const kits = registry.kits;
100
+ if (Array.isArray(kits)) {
101
+ kits.forEach((entry) => {
102
+ if (typeof entry !== "object" || entry === null)
103
+ return;
104
+ const record = entry;
105
+ const id = record.id;
106
+ if (typeof id !== "string")
107
+ return;
108
+ const kitRoot = path.join(dest, "kits", "local", "repositories", id);
109
+ if (!fs.existsSync(kitRoot))
110
+ warnings.push(`${id}: installed kit copy missing at ${kitRoot}; skipping`);
111
+ else
112
+ assets.push(...loadKitAssets(kitRoot, "local", warnings, errors));
113
+ });
114
+ }
115
+ }
116
+ return { assets, warnings, errors };
117
+ }
118
+ function safeSegment(value) {
119
+ return value.replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^[.-]+|[.-]+$/g, "") || "asset";
120
+ }
121
+ export function activateCodexLocal(sourceRoot, dest) {
122
+ const inventory = readKitInventory(sourceRoot, dest);
123
+ const runtimeDir = path.join(dest, ".flow-agents", "runtime", "codex");
124
+ const generated = [];
125
+ const skipped = [];
126
+ for (const asset of inventory.assets) {
127
+ if (asset.asset_class !== "flows") {
128
+ skipped.push({ asset_class: asset.asset_class, path: asset.relative_path, kit_id: asset.kit_id, asset_id: asset.asset_id, reason: "asset class is diagnostic-only for codex-local" });
129
+ continue;
130
+ }
131
+ if (!asset.asset_id) {
132
+ skipped.push({ asset_class: asset.asset_class, path: asset.relative_path, kit_id: asset.kit_id, asset_id: null, reason: "flow asset is missing an id" });
133
+ continue;
134
+ }
135
+ const output = path.join(runtimeDir, "flows", safeSegment(asset.kit_id), `${safeSegment(asset.asset_id)}.flow.json`);
136
+ fs.mkdirSync(path.dirname(output), { recursive: true });
137
+ fs.copyFileSync(asset.source_path, output);
138
+ generated.push({ asset_class: asset.asset_class, path: relPath(dest, output), kit_id: asset.kit_id, asset_id: asset.asset_id, source_path: asset.source_path.split(path.sep).join("/") });
139
+ }
140
+ fs.mkdirSync(runtimeDir, { recursive: true });
141
+ const manifest = { schema_version: "1.0", adapter: "codex-local", supported_asset_classes: ["flows"], generated_runtime_files: generated, skipped_assets: skipped, warnings: inventory.warnings, errors: inventory.errors };
142
+ const manifestPath = path.join(runtimeDir, "activation.json");
143
+ writeJson(manifestPath, manifest);
144
+ generated.push({ asset_class: "activation-manifest", path: relPath(dest, manifestPath), kit_id: "runtime", asset_id: "codex-local.activation", source_path: manifestPath.split(path.sep).join("/") });
145
+ return { selected_adapter: "codex-local", supported_asset_classes: ["flows"], generated_runtime_files: generated, skipped_assets: skipped, warnings: inventory.warnings, errors: inventory.errors };
146
+ }
@@ -0,0 +1,397 @@
1
+ #!/usr/bin/env node
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { loadJson, readText, root, walkFiles, writeText } from "./common.js";
5
+ const dist = process.env.FLOW_AGENTS_DIST_DIR ? path.resolve(process.env.FLOW_AGENTS_DIST_DIR) : path.join(root, "dist");
6
+ const manifest = loadJson(path.join(root, "packaging/manifest.json"));
7
+ const packs = loadJson(path.join(root, "packaging/packs.json"));
8
+ const textExtensions = new Set([".css", ".html", ".js", ".json", ".md", ".sh", ".toml", ".txt", ".yaml", ".yml", ".ts"]);
9
+ const dropDiagnostics = [];
10
+ const printDiagnostics = !["0", "false", "no"].includes(String(process.env.FLOW_AGENTS_EXPORT_DIAGNOSTICS ?? "1").toLowerCase());
11
+ function resetDir(dir) {
12
+ fs.rmSync(dir, { recursive: true, force: true });
13
+ fs.mkdirSync(dir, { recursive: true });
14
+ }
15
+ function sourceRootPatterns() {
16
+ return manifest.source_root_aliases.map((alias) => new RegExp(alias.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"));
17
+ }
18
+ function applySubstitutions(text, substitutions) {
19
+ let result = text;
20
+ for (const item of substitutions ?? [])
21
+ result = result.split(item.from).join(item.to);
22
+ return result;
23
+ }
24
+ function sanitizeText(text, target, rootReplacement, proseSubstitutions = true) {
25
+ let result = text;
26
+ for (const pattern of sourceRootPatterns())
27
+ result = result.replace(pattern, rootReplacement);
28
+ if (target === "claude-code" || target === "codex")
29
+ result = applySubstitutions(result, manifest.target_substitutions.common);
30
+ if (!proseSubstitutions)
31
+ return result;
32
+ if (target === "claude-code")
33
+ result = applySubstitutions(result, manifest.target_substitutions.claude_code);
34
+ if (target === "codex")
35
+ result = applySubstitutions(result, manifest.target_substitutions.codex);
36
+ return result;
37
+ }
38
+ function isCodeAsset(src, relPath) {
39
+ return path.basename(src) === "scripts" || relPath.split(path.sep).includes("scripts");
40
+ }
41
+ function copyTree(src, dest, target, rootReplacement) {
42
+ if (!fs.existsSync(src))
43
+ return;
44
+ for (const file of walkFiles(src)) {
45
+ const relPath = path.relative(src, file);
46
+ if (path.basename(src) === "evals" && relPath.split(path.sep)[0] === "results")
47
+ continue;
48
+ const out = path.join(dest, relPath);
49
+ if (textExtensions.has(path.extname(file).toLowerCase())) {
50
+ writeText(out, sanitizeText(readText(file), target, rootReplacement, !isCodeAsset(src, relPath)));
51
+ }
52
+ else {
53
+ fs.mkdirSync(path.dirname(out), { recursive: true });
54
+ fs.copyFileSync(file, out);
55
+ }
56
+ }
57
+ }
58
+ function resolveSourcePath(pathText) {
59
+ let normalized = pathText;
60
+ for (const alias of manifest.source_root_aliases)
61
+ normalized = normalized.split(alias).join(root);
62
+ normalized = normalized.replace(/^~/, process.env.HOME ?? "");
63
+ return path.isAbsolute(normalized) ? normalized : path.join(root, normalized);
64
+ }
65
+ function candidatePaths(value) {
66
+ return value.split(/\s+/).flatMap((raw) => {
67
+ const part = raw.replace(/^["']|["']$/g, "");
68
+ if (part.includes("=")) {
69
+ const maybePath = part.split("=", 2)[1];
70
+ return maybePath.startsWith("/") ? [maybePath] : [];
71
+ }
72
+ return part.startsWith("/") ? [part] : [];
73
+ });
74
+ }
75
+ function portableAbsolutePath(value) {
76
+ const candidate = resolveSourcePath(value);
77
+ if (manifest.source_root_aliases.some((alias) => value.startsWith(alias)))
78
+ return fs.existsSync(candidate);
79
+ return fs.existsSync(candidate) && candidate.startsWith(root);
80
+ }
81
+ function sanitizeAgentJson(spec) {
82
+ const cleaned = JSON.parse(JSON.stringify(spec));
83
+ const agentName = String(cleaned.name ?? "unknown");
84
+ const resources = Array.isArray(cleaned.resources) ? cleaned.resources : [];
85
+ cleaned.resources = resources.filter((resource) => {
86
+ const source = typeof resource === "object" ? resource.source : resource;
87
+ if (typeof source !== "string" || !source.startsWith("file://") || source.includes("*"))
88
+ return true;
89
+ const keep = fs.existsSync(resolveSourcePath(source.slice("file://".length)));
90
+ if (!keep)
91
+ dropDiagnostics.push(`${agentName}: dropped missing resource ${source}`);
92
+ return keep;
93
+ });
94
+ if (cleaned.hooks && typeof cleaned.hooks === "object") {
95
+ const hooks = {};
96
+ for (const [hookName, entries] of Object.entries(cleaned.hooks)) {
97
+ const kept = (Array.isArray(entries) ? entries : []).filter((entry) => candidatePaths(String(entry.command ?? "")).every(portableAbsolutePath));
98
+ if (kept.length)
99
+ hooks[hookName] = kept;
100
+ else if (Array.isArray(entries) && entries.length)
101
+ dropDiagnostics.push(`${agentName}: no portable entries remain for hook ${hookName}`);
102
+ }
103
+ cleaned.hooks = hooks;
104
+ }
105
+ return cleaned;
106
+ }
107
+ function modelPrefix(value) {
108
+ if (value.startsWith("claude-opus"))
109
+ return "claude-opus";
110
+ if (value.startsWith("claude-sonnet"))
111
+ return "claude-sonnet";
112
+ return value;
113
+ }
114
+ function mapped(mapName, value) {
115
+ const map = manifest[mapName];
116
+ return map[modelPrefix(String(value ?? ""))] ?? map.default;
117
+ }
118
+ function resolveCodexModel(spec) {
119
+ return ["tool-agent-delegate", "tool-agent-handoff"].includes(spec.name) ? "gpt-5.4-mini" : mapped("codex_model_map", spec.model);
120
+ }
121
+ function normalizeCodexText(text) {
122
+ const replacements = { "—": "-", "–": "-", "→": "->", "←": "<-", "’": "'", "“": '"', "”": '"', "⚡": "[quick]", "🖥️": "[interactive]" };
123
+ let normalized = text;
124
+ for (const [from, to] of Object.entries(replacements))
125
+ normalized = normalized.split(from).join(to);
126
+ return normalized.normalize("NFKD").replace(/[^\x00-\x7F]/g, "");
127
+ }
128
+ function appendExportNote(body, note) {
129
+ return `${body.trimEnd()}\n\n## Export Notes\n\n${note}\n`;
130
+ }
131
+ function generatedAgentsSummary(agents) {
132
+ return agents.slice().sort((a, b) => a.name.localeCompare(b.name)).map((spec) => `- \`${spec.name}\` — ${String(spec.description ?? "").trim()}`).join("\n");
133
+ }
134
+ function exportRootAgentsMd(label, agents, taskDir) {
135
+ return `# Universal Agent Bundle (${label})\n\nThis bundle was generated from the canonical source in this repo. Treat the repo root as the source of truth and regenerate the bundle instead of editing exported agent files by hand.\n\n## Shared Conventions\n\n- \`skills/\`, \`context/\`, \`powers/\`, \`prompts/\`, \`scripts/\`, and \`evals/\` were copied from the canonical source.\n- Cross-session task artifacts should live under \`${taskDir}\`.\n- Kiro-only hook wiring was stripped from exported non-Kiro agents to keep the package portable.\n\n## Exported Agents\n\n${generatedAgentsSummary(agents)}\n`;
136
+ }
137
+ function exportTargetReadme(label, installHint) {
138
+ return `# ${label} Bundle\n\nGenerated from the canonical source in this repository.\n\n## Install\n\n\`\`\`bash\n${installHint}\n\`\`\`\n\nOptional pack filtering is available at install time with \`FLOW_AGENTS_PACKS\`.\nThe default pack is always included:\n\n\`\`\`bash\nFLOW_AGENTS_PACKS=development,knowledge ${installHint}\n\`\`\`\n\n## Contents\n\n- Harness-specific agents\n- Shared skills\n- Shared context, powers, prompts, scripts, and evals\n`;
139
+ }
140
+ function mapClaudeTools(allowedTools) {
141
+ const ordered = [];
142
+ for (const tool of Array.isArray(allowedTools) ? allowedTools : []) {
143
+ const mappedTool = manifest.tool_name_map[String(tool)];
144
+ if (mappedTool && !ordered.includes(mappedTool))
145
+ ordered.push(mappedTool);
146
+ }
147
+ return ordered.length ? ordered : ["Read", "Bash"];
148
+ }
149
+ function exportClaudeAgent(spec) {
150
+ const prompt = appendExportNote(sanitizeText(spec.prompt, "claude-code", "<bundle-root>"), "Kiro hook wiring and JSON-only runtime fields were omitted. If this agent mentions Kiro-specific scheduler or hook behavior, treat that as optional operational guidance rather than a hard dependency.");
151
+ return `---\nname: ${spec.name}\ndescription: ${String(spec.description ?? "").trim()}\ntools: ${JSON.stringify(mapClaudeTools(spec.allowedTools))}\nmodel: ${mapped("claude_model_map", spec.model)}\n---\n\n${prompt}`;
152
+ }
153
+ function codexNicknames(agentName) {
154
+ const base = agentName.replace(/^tool-/, "");
155
+ return [...new Set([agentName, base, base.replace(/[-_]/g, " ")].map((item) => item.trim()).filter(Boolean))];
156
+ }
157
+ function exportCodexAgent(spec) {
158
+ const prompt = appendExportNote(normalizeCodexText(sanitizeText(spec.prompt, "codex", "<bundle-root>")), "Exported from a Kiro agent spec. Hooks, resource auto-loading, and tool allowlists were converted into prompt guidance only. Any explicit Kiro scheduler commands are preserved as optional shell workflows.");
159
+ const description = normalizeCodexText(String(spec.description ?? "")).replace(/"/g, "'");
160
+ return `# exported from agents/${spec.name}.json\nname = "${spec.name}"\nnickname_candidates = ${JSON.stringify(codexNicknames(spec.name))}\ndescription = "${description}"\nmodel = "${resolveCodexModel(spec)}"\nmodel_reasoning_effort = "${mapped("codex_reasoning_map", spec.model)}"\ndeveloper_instructions = ${JSON.stringify(prompt)}\n`;
161
+ }
162
+ function tomlValue(value) {
163
+ if (typeof value === "boolean")
164
+ return value ? "true" : "false";
165
+ if (typeof value === "number")
166
+ return String(value);
167
+ if (Array.isArray(value))
168
+ return `[${value.map((item) => tomlValue(item)).join(", ")}]`;
169
+ return JSON.stringify(value);
170
+ }
171
+ function exportCodexConfig() {
172
+ const lines = ["# Generated from packaging/manifest.json. Edit the manifest, not this file.", ""];
173
+ const settings = manifest.codex.settings ?? {};
174
+ for (const [key, value] of Object.entries(settings))
175
+ lines.push(`${key} = ${tomlValue(value)}`);
176
+ if (Object.keys(settings).length)
177
+ lines.push("");
178
+ if (manifest.codex.tui) {
179
+ lines.push("[tui]");
180
+ for (const [key, value] of Object.entries(manifest.codex.tui))
181
+ lines.push(`${key} = ${tomlValue(value)}`);
182
+ lines.push("");
183
+ }
184
+ lines.push("[features]");
185
+ for (const [key, value] of Object.entries(manifest.codex.features ?? {}))
186
+ lines.push(`${key} = ${tomlValue(value)}`);
187
+ lines.push("");
188
+ for (const [providerName, providerRaw] of Object.entries(manifest.codex.model_providers ?? {})) {
189
+ const provider = providerRaw;
190
+ const scalars = Object.entries(provider).filter(([, value]) => typeof value !== "object" || value === null);
191
+ if (scalars.length) {
192
+ lines.push(`[model_providers.${providerName}]`);
193
+ for (const [key, value] of scalars)
194
+ lines.push(`${key} = ${tomlValue(value)}`);
195
+ lines.push("");
196
+ }
197
+ for (const [childName, childRaw] of Object.entries(provider).filter(([, value]) => typeof value === "object" && value !== null)) {
198
+ lines.push(`[model_providers.${providerName}.${childName}]`);
199
+ for (const [key, value] of Object.entries(childRaw))
200
+ lines.push(`${key} = ${tomlValue(value)}`);
201
+ lines.push("");
202
+ }
203
+ }
204
+ return `${lines.join("\n").trimEnd()}\n`;
205
+ }
206
+ function exportCodexProfileConfig(profile, settings) {
207
+ const lines = ["# Generated from packaging/manifest.json. Edit the manifest, not this file.", ""];
208
+ if ("approvals_reviewer" in settings && !("approvals_reviewer" in profile))
209
+ lines.push(`approvals_reviewer = ${tomlValue(settings.approvals_reviewer)}`);
210
+ for (const [key, value] of Object.entries(profile))
211
+ if (typeof value !== "object" || value === null)
212
+ lines.push(`${key} = ${tomlValue(value)}`);
213
+ return `${lines.join("\n").trimEnd()}\n`;
214
+ }
215
+ function shellHook(command, timeout = 10, statusMessage) {
216
+ const hook = { type: "command", command, timeout };
217
+ if (statusMessage)
218
+ hook.statusMessage = statusMessage;
219
+ return hook;
220
+ }
221
+ function claudeTelemetry(event) {
222
+ return `bash -lc 'root="\${CLAUDE_PROJECT_DIR:-$(pwd)}"; node "$root/scripts/hooks/claude-telemetry-hook.js" ${event} dev'`;
223
+ }
224
+ function claudePolicy(event, script) {
225
+ return `bash -lc 'root="\${CLAUDE_PROJECT_DIR:-$(pwd)}"; node "$root/scripts/hooks/claude-hook-adapter.js" ${event} ${script.replace(/\.js$/, "")} ${script} default'`;
226
+ }
227
+ function codexRoot(scriptPath) {
228
+ return `root="\${CODEX_HOME:-}"; if [ -z "$root" ] || [ ! -f "$root/${scriptPath}" ]; then root=$(git rev-parse --show-toplevel 2>/dev/null || pwd); fi`;
229
+ }
230
+ function codexTelemetry(event) {
231
+ if (event === "PermissionRequest")
232
+ return `bash -lc '${codexRoot("scripts/telemetry/telemetry.sh")}; bash "$root/scripts/telemetry/telemetry.sh" permissionRequest dev'`;
233
+ return `bash -lc '${codexRoot("scripts/hooks/codex-telemetry-hook.js")}; node "$root/scripts/hooks/codex-telemetry-hook.js" ${event} dev'`;
234
+ }
235
+ function codexPolicy(script) {
236
+ return `bash -lc '${codexRoot("scripts/hooks/codex-hook-adapter.js")}; node "$root/scripts/hooks/codex-hook-adapter.js" ${script.replace(/\.js$/, "")} ${script} default'`;
237
+ }
238
+ function exportClaudeSettings() {
239
+ const hooks = {};
240
+ for (const event of ["SessionStart", "UserPromptSubmit", "PreToolUse", "PermissionRequest", "PostToolUse", "Stop", "SessionEnd"]) {
241
+ hooks[event] = [{ hooks: [shellHook(claudeTelemetry(event), 10, "Recording Flow Agents telemetry")] }];
242
+ }
243
+ hooks.Stop.push({ hooks: [shellHook(claudePolicy("Stop", "stop-goal-fit.js"), 30, "Running Flow Agents hook policy")] });
244
+ hooks.UserPromptSubmit.push({ hooks: [shellHook(claudePolicy("UserPromptSubmit", "workflow-steering.js"), 30, "Running Flow Agents hook policy")] });
245
+ hooks.PostToolUse.push({ hooks: [shellHook(claudePolicy("PostToolUse", "quality-gate.js"), 30, "Running Flow Agents hook policy")] });
246
+ hooks.PreToolUse.push({ hooks: [shellHook(claudePolicy("PreToolUse", "config-protection.js"), 30, "Running Flow Agents hook policy")] });
247
+ return `${JSON.stringify({
248
+ statusLine: { type: "command", command: 'bash -lc \'root="${CLAUDE_PROJECT_DIR:-$(pwd)}"; node "$root/scripts/statusline/flow-agents-statusline.js"\'' },
249
+ permissions: manifest.claude_code.permissions ?? {},
250
+ skipDangerousModePermissionPrompt: manifest.claude_code.skipDangerousModePermissionPrompt ?? true,
251
+ hooks,
252
+ }, null, 2)}\n`;
253
+ }
254
+ function exportCodexHooks() {
255
+ const hooks = {};
256
+ for (const event of ["SessionStart", "UserPromptSubmit", "PreToolUse", "PermissionRequest", "PostToolUse", "Stop"]) {
257
+ hooks[event] = [{ hooks: [shellHook(codexTelemetry(event), 10, "Recording Flow Agents telemetry")] }];
258
+ }
259
+ hooks.Stop.push({ hooks: [shellHook(codexPolicy("stop-goal-fit.js"), 30, "Running Flow Agents hook policy")] });
260
+ hooks.UserPromptSubmit.push({ hooks: [shellHook(codexPolicy("workflow-steering.js"), 30, "Running Flow Agents hook policy")] });
261
+ return `${JSON.stringify({ hooks }, null, 2)}\n`;
262
+ }
263
+ function copySharedContent(targetRoot, targetName, token) {
264
+ const dirs = [...manifest.canonical_copy_dirs];
265
+ if (fs.existsSync(path.join(root, "kits")) && !dirs.includes("kits"))
266
+ dirs.push("kits");
267
+ for (const dir of dirs)
268
+ copyTree(path.join(root, dir), path.join(targetRoot, dir), targetName, token);
269
+ for (const file of manifest.root_copy_files ?? []) {
270
+ const source = path.join(root, file);
271
+ if (!fs.existsSync(source))
272
+ throw new Error(`manifest root_copy_files entry missing: ${file}`);
273
+ const target = path.join(targetRoot, file);
274
+ if (textExtensions.has(path.extname(source).toLowerCase()))
275
+ writeText(target, sanitizeText(readText(source), targetName, token));
276
+ else {
277
+ fs.mkdirSync(path.dirname(target), { recursive: true });
278
+ fs.copyFileSync(source, target);
279
+ }
280
+ }
281
+ for (const dir of manifest.optional_copy_dirs ?? [])
282
+ copyTree(path.join(root, dir), path.join(targetRoot, dir), targetName, token);
283
+ writeText(path.join(targetRoot, "build/package.json"), `${JSON.stringify({ type: "module" }, null, 2)}\n`);
284
+ const filterBuilt = path.join(root, "build/src/tools/filter-installed-packs.js");
285
+ const commonBuilt = path.join(root, "build/src/tools/common.js");
286
+ if (fs.existsSync(filterBuilt))
287
+ writeText(path.join(targetRoot, "scripts/filter-installed-packs.mjs"), readText(filterBuilt).replace("./common.js", "./common.mjs"));
288
+ if (fs.existsSync(commonBuilt))
289
+ writeText(path.join(targetRoot, "scripts/common.mjs"), readText(commonBuilt));
290
+ copyTree(path.join(root, "build/src"), path.join(targetRoot, "build/src"), targetName, token);
291
+ }
292
+ function installScript(label, defaultDestDisplay, token, destFallbackShell) {
293
+ const replaceBlock = token ? `\nexport DEST\nfind "$DEST" -type f \\( -name '*.json' -o -name '*.md' -o -name '*.sh' -o -name '*.js' -o -name '*.ts' -o -name '*.yaml' -o -name '*.yml' \\) -print0 | xargs -0 perl -0pi -e 's#${token.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}#$ENV{DEST}#g'` : "";
294
+ const destFallback = destFallbackShell ? `\nif [[ -z "$DEST" ]]; then\n DEST="${destFallbackShell}"\nfi` : "";
295
+ const destRequired = !destFallbackShell;
296
+ const requiredCheck = destRequired ? `if [[ -z "$DEST" ]]; then\n usage\n exit 2\nfi\n` : "";
297
+ const usageDest = destRequired ? "/path/to/workspace" : defaultDestDisplay;
298
+ return `#!/usr/bin/env bash\nset -euo pipefail\n\nusage() {\n cat >&2 <<'EOF'\nusage: bash install.sh ${usageDest} [options]\n\nOptions:\n --telemetry-sink NAME local-files, local-kontour-console,\n kontour-hosted-console, user-hosted-console,\n or legacy aliases. May be repeated.\n --console-url URL Persist Console telemetry base URL.\n --console-endpoint URL Persist full Console telemetry records endpoint URL.\n --console-token-file PATH\n Read Console telemetry bearer token from a file.\n --console-tenant ID Persist Console tenant identifier.\nEOF\n}\n\nDEST=""\nDEST_SET=0\nCONSOLE_CONFIG_ARGS=()\nwhile [[ $# -gt 0 ]]; do\n case "$1" in\n --telemetry-sink|--telemetry-sinks|--console-url|--console-endpoint|--console-endpoint-url|--console-token-file|--console-tenant|--console-tenant-id)\n [[ $# -ge 2 ]] || { echo "install.sh: $1 requires a value" >&2; exit 2; }\n CONSOLE_CONFIG_ARGS+=("$1" "$2")\n shift 2\n ;;\n --help|-h)\n usage\n exit 0\n ;;\n -*)\n echo "install.sh: unknown option: $1" >&2\n usage\n exit 2\n ;;\n *)\n if [[ "$DEST_SET" -eq 1 ]]; then\n echo "install.sh: unexpected argument: $1" >&2\n usage\n exit 2\n fi\n DEST="$1"\n DEST_SET=1\n shift\n ;;\n esac\ndone${destFallback}\n${requiredCheck}SRC="$(cd "$(dirname "\${BASH_SOURCE[0]}")" && pwd)"\n\nmkdir -p "$DEST"\nrsync -a ${token ? "--delete " : ""}"$SRC"/ "$DEST"/\nif [[ -n "\${FLOW_AGENTS_PACKS:-}" ]]; then\n node "$DEST/scripts/filter-installed-packs.mjs" "$DEST" --packs "$FLOW_AGENTS_PACKS"\nfi${replaceBlock}\nif [[ \${#CONSOLE_CONFIG_ARGS[@]} -gt 0 || -n "\${FLOW_AGENTS_TELEMETRY_SINK:-}" || -n "\${FLOW_AGENTS_TELEMETRY_SINKS:-}" || -n "\${FLOW_AGENTS_CONSOLE_URL:-}" || -n "\${CONSOLE_TELEMETRY_URL:-}" || -n "\${CONSOLE_URL:-}" || -n "\${FLOW_AGENTS_CONSOLE_TOKEN_FILE:-}" || -n "\${CONSOLE_TELEMETRY_TOKEN_FILE:-}" ]]; then\n bash "$DEST/scripts/telemetry/install-console-config.sh" "$DEST/scripts/telemetry/telemetry.conf" "\${CONSOLE_CONFIG_ARGS[@]}"\nfi\necho "Installed ${label} bundle ${token ? "to" : "into"} $DEST"\n`;
299
+ }
300
+ function buildBase(agents) {
301
+ const bundle = path.join(dist, "base");
302
+ resetDir(bundle);
303
+ copySharedContent(bundle, "base", "<bundle-root>");
304
+ writeText(path.join(bundle, ".flow-agents", ".gitkeep"), "");
305
+ writeText(path.join(bundle, "AGENTS.md"), exportRootAgentsMd("Base", agents, ".flow-agents"));
306
+ writeText(path.join(bundle, "README.md"), exportTargetReadme("Base", "bash install.sh /path/to/workspace"));
307
+ writeText(path.join(bundle, "install.sh"), installScript("Base", "/path/to/workspace"));
308
+ fs.chmodSync(path.join(bundle, "install.sh"), 0o755);
309
+ }
310
+ function buildKiro(agents) {
311
+ const bundle = path.join(dist, "kiro");
312
+ const token = manifest.kiro.path_token;
313
+ resetDir(bundle);
314
+ copySharedContent(bundle, "kiro", token);
315
+ for (const spec of agents)
316
+ writeText(path.join(bundle, "agents", `${spec.name}.json`), sanitizeText(`${JSON.stringify(sanitizeAgentJson(spec), null, 2)}\n`, "kiro", token));
317
+ writeText(path.join(bundle, "AGENTS.md"), exportRootAgentsMd("Kiro", agents, ".flow-agents"));
318
+ writeText(path.join(bundle, "README.md"), exportTargetReadme("Kiro", "bash install.sh $HOME/.flow-agents"));
319
+ writeText(path.join(bundle, "install.sh"), installScript("Kiro", "$HOME/.flow-agents", token, '${FLOW_AGENTS_DEST:-$HOME/.flow-agents}'));
320
+ fs.chmodSync(path.join(bundle, "install.sh"), 0o755);
321
+ }
322
+ function buildClaudeCode(agents) {
323
+ const bundle = path.join(dist, "claude-code");
324
+ resetDir(bundle);
325
+ copySharedContent(bundle, "claude-code", "<bundle-root>");
326
+ writeText(path.join(bundle, manifest.claude_code.task_dir, ".gitkeep"), "");
327
+ for (const spec of agents)
328
+ writeText(path.join(bundle, ".claude/agents", `${spec.name}.md`), exportClaudeAgent(spec));
329
+ for (const skill of fs.readdirSync(path.join(root, "skills"))) {
330
+ const skillPath = path.join(root, "skills", skill, "SKILL.md");
331
+ if (fs.existsSync(skillPath))
332
+ writeText(path.join(bundle, ".claude/skills", skill, "SKILL.md"), sanitizeText(readText(skillPath), "claude-code", "<bundle-root>"));
333
+ }
334
+ writeText(path.join(bundle, ".claude/settings.json"), exportClaudeSettings());
335
+ writeText(path.join(bundle, "AGENTS.md"), exportRootAgentsMd("Claude Code", agents, manifest.claude_code.task_dir));
336
+ writeText(path.join(bundle, "README.md"), exportTargetReadme("Claude Code", "bash install.sh /path/to/workspace"));
337
+ writeText(path.join(bundle, "install.sh"), installScript("Claude Code", "/path/to/workspace"));
338
+ fs.chmodSync(path.join(bundle, "install.sh"), 0o755);
339
+ }
340
+ function buildCodex(agents) {
341
+ const bundle = path.join(dist, "codex");
342
+ const excluded = new Set(manifest.codex.excluded_agents ?? []);
343
+ const targetAgents = agents.filter((spec) => !excluded.has(spec.name));
344
+ resetDir(bundle);
345
+ copySharedContent(bundle, "codex", "<bundle-root>");
346
+ writeText(path.join(bundle, manifest.codex.task_dir, ".gitkeep"), "");
347
+ writeText(path.join(bundle, ".codex/config.toml"), exportCodexConfig());
348
+ const settings = manifest.codex.settings ?? {};
349
+ for (const [profileName, profile] of Object.entries(manifest.codex.profiles ?? {}))
350
+ writeText(path.join(bundle, ".codex", `${profileName}.config.toml`), exportCodexProfileConfig(profile, settings));
351
+ writeText(path.join(bundle, ".codex/hooks.json"), exportCodexHooks());
352
+ for (const spec of targetAgents)
353
+ writeText(path.join(bundle, ".codex/agents", `${spec.name}.toml`), exportCodexAgent(spec));
354
+ for (const skill of fs.readdirSync(path.join(root, "skills"))) {
355
+ const skillPath = path.join(root, "skills", skill, "SKILL.md");
356
+ if (fs.existsSync(skillPath))
357
+ writeText(path.join(bundle, ".codex/skills", skill, "SKILL.md"), sanitizeText(readText(skillPath), "codex", "<bundle-root>"));
358
+ }
359
+ writeText(path.join(bundle, "AGENTS.md"), exportRootAgentsMd("Codex", targetAgents, manifest.codex.task_dir));
360
+ writeText(path.join(bundle, "README.md"), exportTargetReadme("Codex", "bash install.sh /path/to/workspace"));
361
+ writeText(path.join(bundle, "install.sh"), installScript("Codex", "/path/to/workspace"));
362
+ fs.chmodSync(path.join(bundle, "install.sh"), 0o755);
363
+ }
364
+ function buildCatalog(agents) {
365
+ const kitsCatalog = path.join(root, "kits/catalog.json");
366
+ return {
367
+ source_root: ".",
368
+ agents: agents.slice().sort((a, b) => a.name.localeCompare(b.name)).map((spec) => spec.name),
369
+ skills: fs.readdirSync(path.join(root, "skills")).filter((name) => fs.existsSync(path.join(root, "skills", name, "SKILL.md"))).sort(),
370
+ powers: fs.readdirSync(path.join(root, "powers")).filter((name) => fs.existsSync(path.join(root, "powers", name, "mcp.json"))).sort(),
371
+ packs: packs.packs ?? [],
372
+ kits: fs.existsSync(kitsCatalog) ? loadJson(kitsCatalog).kits ?? [] : [],
373
+ };
374
+ }
375
+ export function main() {
376
+ fs.mkdirSync(dist, { recursive: true });
377
+ const agents = fs.readdirSync(path.join(root, "agents")).filter((name) => name.endsWith(".json")).sort().map((name) => loadJson(path.join(root, "agents", name)));
378
+ buildBase(agents);
379
+ buildKiro(agents);
380
+ buildClaudeCode(agents);
381
+ buildCodex(agents);
382
+ writeText(path.join(dist, "catalog.json"), `${JSON.stringify(buildCatalog(agents), null, 2)}\n`);
383
+ writeText(path.join(dist, "README.md"), "# Universal Bundles\n\nRun `npm run build:bundles` from the repo root to regenerate these bundles.\n");
384
+ console.log("Built bundles:");
385
+ console.log(" - dist/base");
386
+ console.log(" - dist/kiro");
387
+ console.log(" - dist/claude-code");
388
+ console.log(" - dist/codex");
389
+ if (printDiagnostics && dropDiagnostics.length) {
390
+ console.error("Export sanitization diagnostics:");
391
+ for (const item of dropDiagnostics)
392
+ console.error(` - ${item}`);
393
+ }
394
+ return 0;
395
+ }
396
+ if (import.meta.url === `file://${process.argv[1]}`)
397
+ process.exit(main());
@@ -0,0 +1,56 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ function findRoot(start) {
5
+ let current = start;
6
+ for (;;) {
7
+ if (fs.existsSync(path.join(current, "package.json")) && fs.existsSync(path.join(current, "packaging")))
8
+ return current;
9
+ const parent = path.dirname(current);
10
+ if (parent === current)
11
+ return start;
12
+ current = parent;
13
+ }
14
+ }
15
+ export const root = findRoot(path.dirname(fileURLToPath(import.meta.url)));
16
+ export function rel(file) {
17
+ const relative = path.relative(root, file).split(path.sep).join("/");
18
+ return relative.startsWith("..") ? file.split(path.sep).join("/") : relative || ".";
19
+ }
20
+ export function readText(file) {
21
+ return fs.readFileSync(file, "utf8");
22
+ }
23
+ export function writeText(file, text) {
24
+ fs.mkdirSync(path.dirname(file), { recursive: true });
25
+ fs.writeFileSync(file, text, "utf8");
26
+ }
27
+ export function loadJson(file) {
28
+ return JSON.parse(readText(file));
29
+ }
30
+ export function exists(file) {
31
+ return fs.existsSync(file);
32
+ }
33
+ export function walkFiles(dir) {
34
+ if (!exists(dir))
35
+ return [];
36
+ const out = [];
37
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
38
+ const full = path.join(dir, entry.name);
39
+ if (entry.isDirectory())
40
+ out.push(...walkFiles(full));
41
+ else if (entry.isFile())
42
+ out.push(full);
43
+ }
44
+ return out;
45
+ }
46
+ export function oneLine(value, limit = 240) {
47
+ const compact = value.replace(/\s+/g, " ").trim();
48
+ return compact.length <= limit ? compact : `${compact.slice(0, limit - 3).trimEnd()}...`;
49
+ }
50
+ export function markdownTable(headers, rows) {
51
+ return [
52
+ `| ${headers.join(" | ")} |`,
53
+ `| ${headers.map(() => "---").join(" | ")} |`,
54
+ ...rows.map((row) => `| ${row.map((cell) => cell.replace(/\n/g, " ")).join(" | ")} |`),
55
+ ];
56
+ }