@kontourai/flow-agents 0.1.1 → 0.2.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.
- package/.github/dependabot.yml +23 -0
- package/.github/workflows/publish-npm.yml +1 -1
- package/.github/workflows/release-please.yml +31 -0
- package/.github/workflows/runtime-compat.yml +118 -0
- package/CHANGELOG.md +38 -0
- package/CONTRIBUTING.md +4 -0
- package/README.md +58 -19
- package/build/src/cli/init.js +215 -5
- package/build/src/cli/utterance-check.js +236 -0
- package/build/src/cli.js +3 -0
- package/build/src/tools/build-universal-bundles.js +268 -0
- package/build/src/tools/filter-installed-packs.js +3 -0
- package/build/src/tools/validate-source-tree.js +6 -1
- package/context/scripts/telemetry/lib/config.sh +5 -1
- package/context/settings/flow-agents-settings.json +7 -0
- package/docs/agent-system-guidebook.md +4 -5
- package/docs/context-map.md +1 -0
- package/docs/index.md +46 -6
- package/docs/integrations/conformance.md +246 -0
- package/docs/integrations/framework-adapter.md +275 -0
- package/docs/integrations/harness-install.md +213 -0
- package/docs/integrations/index.md +54 -0
- package/docs/north-star.md +3 -3
- package/docs/repository-structure.md +1 -1
- package/docs/skills-map.md +10 -4
- package/docs/spec/runtime-hook-surface.md +472 -0
- package/docs/survey-utterance-check.md +308 -0
- package/docs/vision.md +45 -0
- package/docs/workflow-usage-guide.md +1 -1
- package/evals/acceptance/run.sh +4 -2
- package/evals/acceptance/test_opencode_harness.sh +121 -0
- package/evals/acceptance/test_pi_harness.sh +98 -0
- package/evals/integration/test_bundle_install.sh +226 -1
- package/evals/integration/test_bundle_lifecycle.sh +641 -0
- package/evals/integration/test_utterance_check.sh +518 -0
- package/evals/run.sh +2 -0
- package/evals/static/test_universal_bundles.sh +137 -2
- package/integrations/strands/README.md +256 -0
- package/integrations/strands/example.py +74 -0
- package/integrations/strands/flow_agents_strands/__init__.py +27 -0
- package/integrations/strands/flow_agents_strands/hooks.py +194 -0
- package/integrations/strands/flow_agents_strands/policy.py +348 -0
- package/integrations/strands/flow_agents_strands/steering.py +172 -0
- package/integrations/strands/flow_agents_strands/telemetry.py +238 -0
- package/integrations/strands/pyproject.toml +38 -0
- package/integrations/strands/tests/__init__.py +0 -0
- package/integrations/strands/tests/test_hooks.py +304 -0
- package/integrations/strands/tests/test_policy.py +315 -0
- package/integrations/strands/tests/test_telemetry.py +184 -0
- package/integrations/strands-ts/README.md +224 -0
- package/integrations/strands-ts/bin/conformance-shim.mjs +257 -0
- package/integrations/strands-ts/package.json +53 -0
- package/integrations/strands-ts/src/hooks.ts +208 -0
- package/integrations/strands-ts/src/index.ts +22 -0
- package/integrations/strands-ts/src/policy.ts +345 -0
- package/integrations/strands-ts/src/telemetry.ts +251 -0
- package/integrations/strands-ts/test/test-policy.ts +322 -0
- package/integrations/strands-ts/test/test-telemetry.ts +226 -0
- package/integrations/strands-ts/tsconfig.json +20 -0
- package/package.json +7 -2
- package/packaging/conformance/README.md +142 -0
- package/packaging/conformance/fixtures/config-protection--allow-no-path.json +18 -0
- package/packaging/conformance/fixtures/config-protection--allow-safe-file.json +20 -0
- package/packaging/conformance/fixtures/config-protection--block-biome.json +20 -0
- package/packaging/conformance/fixtures/config-protection--block-eslintrc.json +20 -0
- package/packaging/conformance/fixtures/quality-gate--allow-no-path.json +17 -0
- package/packaging/conformance/fixtures/quality-gate--allow-nonexistent-file.json +19 -0
- package/packaging/conformance/fixtures/stop-goal-fit--allow-clean-cwd.json +17 -0
- package/packaging/conformance/fixtures/stop-goal-fit--block-strict-mode.json +23 -0
- package/packaging/conformance/fixtures/stop-goal-fit--warn-active-delivery.json +21 -0
- package/packaging/conformance/fixtures/workflow-steering--allow-no-state.json +16 -0
- package/packaging/conformance/fixtures/workflow-steering--inject-active-state.json +29 -0
- package/packaging/conformance/fixtures/workflow-steering--inject-subagent-steering.json +25 -0
- package/packaging/conformance/package.json +4 -0
- package/packaging/conformance/run-conformance.js +322 -0
- package/packaging/manifest.json +59 -0
- package/schemas/flow-agents-settings.schema.json +48 -0
- package/scripts/README.md +5 -0
- package/scripts/dogfood.js +16 -0
- package/scripts/hooks/opencode-hook-adapter.js +123 -0
- package/scripts/hooks/opencode-telemetry-hook.js +101 -0
- package/scripts/hooks/pi-hook-adapter.js +123 -0
- package/scripts/hooks/pi-telemetry-hook.js +105 -0
- package/scripts/hooks/run-hook.js +8 -0
- package/scripts/hooks/utterance-check.js +327 -0
- package/scripts/telemetry/lib/config.sh +5 -1
- package/skills/idea-to-backlog/SKILL.md +1 -1
- package/src/cli/init.ts +219 -6
- package/src/cli/utterance-check.ts +324 -0
- package/src/cli.ts +3 -0
- package/src/tools/build-universal-bundles.ts +266 -0
- package/src/tools/filter-installed-packs.ts +3 -0
- package/src/tools/validate-source-tree.ts +6 -1
- package/build/src/cli/docs-preview.js +0 -39
- package/build/src/cli/export-bookmarks.js +0 -38
- package/build/src/cli/import-bookmarks.js +0 -50
- package/build/src/cli/instinct-cli.js +0 -93
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Keeps pinned dependencies current; the runtime-compat workflow separately
|
|
2
|
+
# canaries LATEST runtime binaries and framework SDKs on a weekly cron.
|
|
3
|
+
version: 2
|
|
4
|
+
updates:
|
|
5
|
+
- package-ecosystem: npm
|
|
6
|
+
directory: "/"
|
|
7
|
+
schedule:
|
|
8
|
+
interval: weekly
|
|
9
|
+
groups:
|
|
10
|
+
dev-dependencies:
|
|
11
|
+
dependency-type: development
|
|
12
|
+
- package-ecosystem: npm
|
|
13
|
+
directory: "/integrations/strands-ts"
|
|
14
|
+
schedule:
|
|
15
|
+
interval: weekly
|
|
16
|
+
- package-ecosystem: pip
|
|
17
|
+
directory: "/integrations/strands"
|
|
18
|
+
schedule:
|
|
19
|
+
interval: weekly
|
|
20
|
+
- package-ecosystem: github-actions
|
|
21
|
+
directory: "/"
|
|
22
|
+
schedule:
|
|
23
|
+
interval: weekly
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: Release Please
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: write
|
|
11
|
+
pull-requests: write
|
|
12
|
+
actions: write
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
release-please:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- name: Run release-please
|
|
19
|
+
id: release
|
|
20
|
+
uses: googleapis/release-please-action@v4
|
|
21
|
+
with:
|
|
22
|
+
config-file: release-please-config.json
|
|
23
|
+
manifest-file: .release-please-manifest.json
|
|
24
|
+
|
|
25
|
+
# Tags created with GITHUB_TOKEN do not trigger tag-push workflows, so
|
|
26
|
+
# dispatch the existing publish pipeline at the new tag explicitly.
|
|
27
|
+
- name: Dispatch publish workflow
|
|
28
|
+
if: steps.release.outputs.release_created == 'true'
|
|
29
|
+
env:
|
|
30
|
+
GH_TOKEN: ${{ github.token }}
|
|
31
|
+
run: gh workflow run publish-npm.yml --repo "$GITHUB_REPOSITORY" --ref "${{ steps.release.outputs.tag_name }}"
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
name: Runtime Compatibility
|
|
2
|
+
|
|
3
|
+
# Weekly canary against the LATEST released versions of supported host
|
|
4
|
+
# runtimes and framework SDKs. Catches upstream drift (config schema changes,
|
|
5
|
+
# plugin/extension API changes, SDK breaking releases) before users do.
|
|
6
|
+
#
|
|
7
|
+
# Report-only: failures open/refresh a tracking issue; they do not block CI.
|
|
8
|
+
# Live model loops are out of scope here (no provider credentials in CI) —
|
|
9
|
+
# coverage is install + config acceptance + plugin/extension load + the
|
|
10
|
+
# mechanical hook chain, which is where every upstream break found so far
|
|
11
|
+
# (opencode config schema, plugin spawn semantics, pi extension parsing)
|
|
12
|
+
# would have surfaced.
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
schedule:
|
|
16
|
+
- cron: "17 6 * * 1" # Mondays 06:17 UTC
|
|
17
|
+
workflow_dispatch:
|
|
18
|
+
|
|
19
|
+
permissions:
|
|
20
|
+
contents: read
|
|
21
|
+
issues: write
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
harness-canary:
|
|
25
|
+
name: Harness canary (${{ matrix.runtime }})
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
timeout-minutes: 20
|
|
28
|
+
strategy:
|
|
29
|
+
fail-fast: false
|
|
30
|
+
matrix:
|
|
31
|
+
include:
|
|
32
|
+
- runtime: opencode
|
|
33
|
+
install: npm install -g opencode-ai@latest
|
|
34
|
+
version: opencode --version
|
|
35
|
+
- runtime: pi
|
|
36
|
+
install: npm install -g @earendil-works/pi-coding-agent@latest
|
|
37
|
+
version: pi --version
|
|
38
|
+
steps:
|
|
39
|
+
- name: Checkout
|
|
40
|
+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
41
|
+
|
|
42
|
+
- name: Set up Node.js
|
|
43
|
+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
|
44
|
+
with:
|
|
45
|
+
node-version: 24
|
|
46
|
+
|
|
47
|
+
- name: Install latest ${{ matrix.runtime }}
|
|
48
|
+
run: |
|
|
49
|
+
${{ matrix.install }}
|
|
50
|
+
${{ matrix.version }}
|
|
51
|
+
|
|
52
|
+
- name: Build bundles
|
|
53
|
+
run: npm run build:bundles
|
|
54
|
+
|
|
55
|
+
- name: Mechanical hook chain (lifecycle suite)
|
|
56
|
+
run: bash evals/integration/test_bundle_lifecycle.sh
|
|
57
|
+
|
|
58
|
+
- name: Live harness (binary-gated, provider assertions skip)
|
|
59
|
+
run: bash evals/acceptance/test_${{ matrix.runtime }}_harness.sh
|
|
60
|
+
|
|
61
|
+
framework-sdk-canary:
|
|
62
|
+
name: Framework SDK canary
|
|
63
|
+
runs-on: ubuntu-latest
|
|
64
|
+
timeout-minutes: 20
|
|
65
|
+
steps:
|
|
66
|
+
- name: Checkout
|
|
67
|
+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
68
|
+
|
|
69
|
+
- name: Set up Node.js
|
|
70
|
+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
|
71
|
+
with:
|
|
72
|
+
node-version: 24
|
|
73
|
+
|
|
74
|
+
- name: Set up Python
|
|
75
|
+
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
|
76
|
+
with:
|
|
77
|
+
python-version: "3.12"
|
|
78
|
+
|
|
79
|
+
- name: Root install + build
|
|
80
|
+
run: |
|
|
81
|
+
npm ci
|
|
82
|
+
npm run build
|
|
83
|
+
|
|
84
|
+
- name: Strands TS adapter against latest @strands-agents/sdk
|
|
85
|
+
run: |
|
|
86
|
+
cd integrations/strands-ts
|
|
87
|
+
npm view @strands-agents/sdk version
|
|
88
|
+
npm test
|
|
89
|
+
npm run conformance
|
|
90
|
+
|
|
91
|
+
- name: Strands Python adapter against latest strands-agents
|
|
92
|
+
run: |
|
|
93
|
+
python3 -m venv /tmp/sdk-canary
|
|
94
|
+
/tmp/sdk-canary/bin/pip install -q strands-agents
|
|
95
|
+
/tmp/sdk-canary/bin/pip show strands-agents | head -2
|
|
96
|
+
cd integrations/strands
|
|
97
|
+
/tmp/sdk-canary/bin/python -m unittest discover
|
|
98
|
+
|
|
99
|
+
report:
|
|
100
|
+
name: Open tracking issue on failure
|
|
101
|
+
runs-on: ubuntu-latest
|
|
102
|
+
needs: [harness-canary, framework-sdk-canary]
|
|
103
|
+
if: failure()
|
|
104
|
+
steps:
|
|
105
|
+
- name: Create or comment on tracking issue
|
|
106
|
+
env:
|
|
107
|
+
GH_TOKEN: ${{ github.token }}
|
|
108
|
+
run: |
|
|
109
|
+
TITLE="Runtime compatibility canary failed ($(date -u +%Y-%m-%d))"
|
|
110
|
+
BODY="The weekly runtime/SDK canary failed: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
111
|
+
|
|
112
|
+
One or more of: latest opencode, latest pi, latest @strands-agents/sdk, latest strands-agents (Python) broke install, hook-chain, harness, adapter tests, or conformance. Triage the run logs and either fix the adapter or document the gap in the conformance declaration."
|
|
113
|
+
EXISTING=$(gh issue list --repo "${{ github.repository }}" --search "Runtime compatibility canary failed in:title state:open" --json number --jq '.[0].number // empty')
|
|
114
|
+
if [ -n "$EXISTING" ]; then
|
|
115
|
+
gh issue comment "$EXISTING" --repo "${{ github.repository }}" --body "$BODY"
|
|
116
|
+
else
|
|
117
|
+
gh issue create --repo "${{ github.repository }}" --title "$TITLE" --body "$BODY" --label upstream-drift
|
|
118
|
+
fi
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.2.0](https://github.com/kontourai/flow-agents/compare/v0.1.2...v0.2.0) (2026-06-11)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* engine contract 1.0, conformance kit, Strands rebind, integration docs ([fd94f58](https://github.com/kontourai/flow-agents/commit/fd94f583f52c874d901e06da0ee338830b3d469a))
|
|
9
|
+
* install lifecycle tests, dogfood command, collision marker fix ([a0fb2e3](https://github.com/kontourai/flow-agents/commit/a0fb2e31d897426db435801c8a637a9736d99ad1))
|
|
10
|
+
* live acceptance harnesses for opencode and pi ([181382b](https://github.com/kontourai/flow-agents/commit/181382b8dfe05cce41c0471a030e7d795950cd09))
|
|
11
|
+
* Strands TypeScript adapter — first native-import engine consumer ([0f387ab](https://github.com/kontourai/flow-agents/commit/0f387ab8e5a8b7f65e511af2fc33340f51e2d047))
|
|
12
|
+
* weekly runtime/SDK compatibility canary + dependabot ([9a371b1](https://github.com/kontourai/flow-agents/commit/9a371b1af86394fe1f7febebe3a35d3f05321f8e))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Fixes
|
|
16
|
+
|
|
17
|
+
* opencode.json — emit schema-valid config (instructions must be array) ([35a01ec](https://github.com/kontourai/flow-agents/commit/35a01ec508b2f99d4a7bca854e5f09740bac4fb3))
|
|
18
|
+
* opencode/pi hook chain — node resolution, stdin payloads, telemetry escape ([be4e4f8](https://github.com/kontourai/flow-agents/commit/be4e4f8d3b81fc7b67d6e45f4c9c1515407268a7))
|
|
19
|
+
* pi extension template escaping; parse-gate generated hook artifacts ([6fe40c5](https://github.com/kontourai/flow-agents/commit/6fe40c5079b8ee89a58c4dfecd6df2992c46cf59))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Documentation
|
|
23
|
+
|
|
24
|
+
* roadmap rows reflect the shipped utterance evidence-check hook ([#24](https://github.com/kontourai/flow-agents/issues/24)) ([617c755](https://github.com/kontourai/flow-agents/commit/617c75567b692c02564f457577d1ab3c01c1ea8e))
|
|
25
|
+
|
|
26
|
+
## 0.1.2
|
|
27
|
+
|
|
28
|
+
- Source validation resolves the Flow CLI at `dist/cli.js` (with a
|
|
29
|
+
`src/cli.js` fallback), and the source-and-static CI lane installs
|
|
30
|
+
`@kontourai/flow` so kit Flow Definitions are validated by the real
|
|
31
|
+
Flow CLI.
|
|
32
|
+
- The publish workflow builds the bundle explicitly before `npm publish`.
|
|
33
|
+
- Docs routing between the System Guidebook and the Workflow Usage Guide;
|
|
34
|
+
duplicated development walkthrough removed.
|
|
35
|
+
- README and Pages home advertise the npm install with the version badge;
|
|
36
|
+
pre-release caveats removed; Kontour family table links product pages
|
|
37
|
+
and gains a Survey row.
|
|
38
|
+
- Fixes phantom skill references, a stale pack list, and path accuracy in
|
|
39
|
+
the docs.
|
|
40
|
+
|
|
3
41
|
## 0.1.1
|
|
4
42
|
|
|
5
43
|
### Documentation And Site
|
package/CONTRIBUTING.md
CHANGED
|
@@ -34,6 +34,10 @@ gem install --user-install jekyll -v 3.9.5 jekyll-optional-front-matter \
|
|
|
34
34
|
Set `FLOW_CLI_ROOT` to a Flow checkout or installed `@kontourai/flow` package
|
|
35
35
|
root to enable full Flow Definition validation in `npm run validate:source`.
|
|
36
36
|
|
|
37
|
+
## Releases
|
|
38
|
+
|
|
39
|
+
Releases are automated with release-please: merges to main accumulate into a release PR, and merging it tags the version and dispatches the npm publish workflow. Use conventional commit prefixes (feat:, fix:, docs:, chore:) so version inference works.
|
|
40
|
+
|
|
37
41
|
## Validation
|
|
38
42
|
|
|
39
43
|
- `npm run validate:source` — source-tree integrity (paths, packs, manifests)
|
package/README.md
CHANGED
|
@@ -2,53 +2,78 @@
|
|
|
2
2
|
|
|
3
3
|
# Kontour Flow Agents
|
|
4
4
|
|
|
5
|
-
**
|
|
5
|
+
**A portable process-discipline layer for agentic work — canonical policies, evidence, and telemetry that compile to whatever hook surface a host exposes.**
|
|
6
6
|
|
|
7
|
+
[](https://www.npmjs.com/package/@kontourai/flow-agents)
|
|
7
8
|
[](https://github.com/kontourai/flow-agents/actions/workflows/ci.yml)
|
|
8
9
|
[](LICENSE)
|
|
9
10
|
[](package.json)
|
|
10
11
|
|
|
11
|
-
[Documentation](https://kontourai.github.io/flow-agents/) · [Workflow Guide](docs/workflow-usage-guide.md) · [System Guidebook](docs/agent-system-guidebook.md) · [Kontour Flow](https://kontourai.github.io/flow/)
|
|
12
|
+
[Documentation](https://kontourai.github.io/flow-agents/) · [Workflow Guide](docs/workflow-usage-guide.md) · [System Guidebook](docs/agent-system-guidebook.md) · [Runtime Hook Spec](docs/spec/runtime-hook-surface.md) · [Kontour Flow](https://kontourai.github.io/flow/)
|
|
12
13
|
|
|
13
14
|
</div>
|
|
14
15
|
|
|
15
16
|
---
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
Agents are powerful and forgetful. They plan well, then drift. They skip verification when context gets crowded. They call partial work done, and after a compaction nobody — including the agent — can say where the work actually stands.
|
|
18
19
|
|
|
19
|
-
Flow Agents
|
|
20
|
+
Flow Agents addresses this with a process-discipline layer that sits between the user and the agent: four canonical policy classes (workflow steering, quality gate, stop-goal-fit, config protection), durable sidecar state that survives compaction and handoff, evidence gates before release decisions, and telemetry that feeds corrections back into the system. [Kontour Flow](https://kontourai.github.io/flow/) owns the gate semantics underneath; Flow Agents compiles those policies to whatever hook surface a host exposes — coding-agent harnesses today, agent frameworks next.
|
|
20
21
|
|
|
21
22
|
**You ask for outcomes. The system supplies the path, the state, the checks, and the proof.**
|
|
22
23
|
|
|
23
24
|
## What you get
|
|
24
25
|
|
|
25
|
-
- **One workflow across runtimes** — the same `idea → backlog → plan → build → review → verify → evidence → release → learning` path installs into Codex,
|
|
26
|
+
- **One workflow across runtimes** — the same `idea → backlog → plan → build → review → verify → evidence → release → learning` path installs into Claude Code, Codex, Kiro, opencode, and pi without rewriting it per tool.
|
|
26
27
|
- **Workflow skills** — `idea-to-backlog`, `pull-work`, `plan-work`, `execute-plan`, `review-work`, `verify-work`, `evidence-gate`, `release-readiness`, `learning-review`, and orchestrators like `deliver` and `fix-bug` that chain them.
|
|
27
28
|
- **Durable workflow state** — schema-validated sidecars under `.flow-agents/` record acceptance criteria, evidence, critique, handoff, and learning, so any session can resume from recorded state instead of chat memory.
|
|
28
|
-
- **
|
|
29
|
+
- **Four canonical policies** — workflow steering (phase reminders at each turn), quality gate (per-file checks after edits), stop-goal-fit (evidence check before the agent stops), and config protection (veto writes to linter/formatter configs). Each policy class has a canonical script under `scripts/hooks/` and compiles to the host's native hook format.
|
|
29
30
|
- **Evidence over confidence** — important work ends with tests, browser checks, CI results, review findings, governance reports, or an explicit `NOT_VERIFIED` gap. Optional [Veritas](docs/veritas-integration.md) integration attaches repo-governance evidence without making it mandatory.
|
|
30
|
-
- **Evals that keep the bundle honest** —
|
|
31
|
+
- **Evals that keep the bundle honest** — 77 integration and 36 static bundle assertions validate the skills, contracts, fixtures, and hook influence as the bundle evolves.
|
|
32
|
+
|
|
33
|
+
## Flow Agents as a process-discipline layer
|
|
34
|
+
|
|
35
|
+
The four canonical policy classes are defined in the [Runtime Hook Surface spec](docs/spec/runtime-hook-surface.md) using a runtime-neutral vocabulary. Adapters translate them to whatever hook surface a host exposes:
|
|
36
|
+
|
|
37
|
+
| Policy Class | What it does | Hook trigger |
|
|
38
|
+
| --- | --- | --- |
|
|
39
|
+
| Workflow steering | Injects phase-transition reminders so the agent does not lose track of where it is in the delivery pipeline | `userPromptSubmit` |
|
|
40
|
+
| Quality gate | Runs format and lint checks immediately after edit tool calls | `postToolUse` |
|
|
41
|
+
| Stop-goal-fit | Warns (or blocks) when the agent is about to stop but required evidence is missing | `stop` |
|
|
42
|
+
| Config protection | Vetoes writes to linter and formatter configuration files | `preToolUse` |
|
|
43
|
+
|
|
44
|
+
The spec defines three conformance levels: **L0** (telemetry only), **L1** (steering + stop-goal-fit warning), and **L2** (all four policies with blocking). Claude Code and Codex are the current L2 reference implementations.
|
|
45
|
+
|
|
46
|
+
## Runtime and support matrix
|
|
47
|
+
|
|
48
|
+
| Tier | Runtime | Ships | Tested | Conformance |
|
|
49
|
+
| --- | --- | --- | --- | --- |
|
|
50
|
+
| **Core harness** | Claude Code | install + hooks + bundle | 77 integration + 36 static assertions | L2 — reference implementation |
|
|
51
|
+
| **Core harness** | Codex | install + hooks + bundle | 77 integration + 36 static assertions | L2 — reference implementation |
|
|
52
|
+
| **Core harness** | Kiro | install + hooks + bundle | included in bundle assertions | L2 |
|
|
53
|
+
| **Core harness** | opencode | `.opencode/agents/`, `.opencode/skills/`, `.opencode/plugins/flow-agents.js`, `opencode.json` | included in bundle assertions | L1 — no prompt-submit hook; steering wired to `session.created` + `tool.execute.before` |
|
|
54
|
+
| **Core harness** | pi | `.pi/extensions/flow-agents.ts`, `.pi/skills/`, `AGENTS.md` | included in bundle assertions | L1 — no stop hook; stop-goal-fit unavailable |
|
|
55
|
+
| **Official framework adapter** | AWS Strands (Python) | `integrations/strands/` — `flow-agents-strands` PyPI package | 50 unit tests (no Strands SDK required) | Spike/preview — see [integrations/strands/README.md](integrations/strands/README.md) |
|
|
56
|
+
| **Conformance-certified** | Community / third-party | Self-certify using the conformance kit | — | Conformance kit in development; not yet shipped |
|
|
57
|
+
|
|
58
|
+
Honest gaps are documented in the artifacts: opencode has no native `prompt.submit`-equivalent event; Codex live hook influence is limited to installed-command and protocol coverage; pi has no `permissionRequest` equivalent and no stop hook. The [Runtime Hook Surface spec](docs/spec/runtime-hook-surface.md) names every gap explicitly.
|
|
31
59
|
|
|
32
60
|
## Install
|
|
33
61
|
|
|
34
62
|
```bash
|
|
35
|
-
# guided install into your workspace
|
|
63
|
+
# guided install into your workspace (auto-detects runtime)
|
|
36
64
|
npx @kontourai/flow-agents init --dest /path/to/workspace
|
|
37
65
|
|
|
38
66
|
# headless, for CI or scripts
|
|
39
67
|
npx @kontourai/flow-agents init --dest /path/to/workspace --telemetry-sink local-files --yes
|
|
40
68
|
|
|
41
|
-
#
|
|
69
|
+
# runtime-specific wiring
|
|
70
|
+
npx @kontourai/flow-agents init --runtime claude-code --dest /path/to/workspace --yes
|
|
42
71
|
npx @kontourai/flow-agents init --runtime codex --dest /path/to/workspace --activate-kits --yes
|
|
72
|
+
npx @kontourai/flow-agents init --runtime opencode --dest /path/to/workspace --yes
|
|
73
|
+
npx @kontourai/flow-agents init --runtime pi --dest /path/to/workspace --yes
|
|
43
74
|
```
|
|
44
75
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
git clone https://github.com/kontourai/flow-agents.git
|
|
49
|
-
cd flow-agents && npm install && npm run build
|
|
50
|
-
node build/src/cli.js init --dest /path/to/workspace
|
|
51
|
-
```
|
|
76
|
+
Working from a checkout (for contributors): `npm install && npm run build`, then `node build/src/cli.js init --dest /path/to/workspace`.
|
|
52
77
|
|
|
53
78
|
The installer copies the bundled agents, skills, context, scripts, evals, Flow Kit assets, and the Flow Agents-owned `console.telemetry.json` descriptor into the target workspace. Telemetry writes to local files by default; optional sinks mirror it to a local, hosted, or self-hosted Kontour Console (`--telemetry-sink local-kontour-console | kontour-hosted-console | user-hosted-console --console-url …`).
|
|
54
79
|
|
|
@@ -80,15 +105,29 @@ Use fix-bug. Reproduce the issue, diagnose root cause, plan the fix, implement i
|
|
|
80
105
|
|
|
81
106
|
The [Workflow Usage Guide](docs/workflow-usage-guide.md) walks every stage with example prompts and expected behavior; the [Agent System Guidebook](docs/agent-system-guidebook.md) is the plain-language map of how the pieces fit.
|
|
82
107
|
|
|
108
|
+
## Framework adapters
|
|
109
|
+
|
|
110
|
+
The same canonical policies that wire into coding-agent harnesses via file-based hook scripts can also wire into agent frameworks as in-process language-native packages.
|
|
111
|
+
|
|
112
|
+
`integrations/strands/` contains `flow-agents-strands`, a Python package implementing a Strands `HookProvider` that:
|
|
113
|
+
- emits the canonical telemetry taxonomy (`agentSpawn`, `preToolUse`, `postToolUse`, `stop`, etc.) to the same JSONL format as the harness adapters
|
|
114
|
+
- enforces config protection via `BeforeToolCallEvent` cancellation (the Strands equivalent of a blocking `preToolUse` hook)
|
|
115
|
+
- injects workflow steering context at agent construction via `steering_context()`
|
|
116
|
+
|
|
117
|
+
This is a spike/preview — 50 unit tests pass without requiring the Strands SDK, and the README documents 7 limitations honestly. It demonstrates that the policy engine is not harness-specific.
|
|
118
|
+
|
|
119
|
+
The [Runtime Hook Surface spec](docs/spec/runtime-hook-surface.md) documents the full framework adapter mapping, including VoltAgent, LangGraph, and OpenAI Agents SDK hook surfaces, and the minimum viable adapter pseudocode.
|
|
120
|
+
|
|
83
121
|
## Where Flow Agents fits
|
|
84
122
|
|
|
85
123
|
Kontour AI shows the work behind AI. Each product stands alone; together they cohere:
|
|
86
124
|
|
|
87
125
|
| Product | Owns |
|
|
88
126
|
| --- | --- |
|
|
89
|
-
| **[
|
|
90
|
-
| **[
|
|
91
|
-
| **[
|
|
127
|
+
| **[Survey](https://kontourai.io/survey)** | Producer evidence: source → extraction → candidate → review → claim |
|
|
128
|
+
| **[Surface](https://kontourai.io/surface)** | Portable trust state: claims, evidence, policies, trust snapshots |
|
|
129
|
+
| **[Flow](https://kontourai.io/flow)** | Process transparency: steps, gates, transitions, runs, exceptions, reports |
|
|
130
|
+
| **[Veritas](https://kontourai.io/veritas)** | Code/change transparency: repo standards, merge readiness |
|
|
92
131
|
| **Flow Agents** | Agent-facing distribution: skills, kits, runtime adapters, hooks, telemetry |
|
|
93
132
|
|
|
94
133
|
Flow Agents owns the glue — discovery, just-in-time guidance, scoped delegation, Flow-backed state inside harnesses, evidence-backed completion, and feedback loops. It deliberately does not own the model, the runtime, the workflow engine, or repo governance. The [North Star](docs/north-star.md) records the direction and design principles.
|
package/build/src/cli/init.js
CHANGED
|
@@ -13,12 +13,67 @@ const runtimeBundles = {
|
|
|
13
13
|
codex: "codex",
|
|
14
14
|
"claude-code": "claude-code",
|
|
15
15
|
kiro: "kiro",
|
|
16
|
+
opencode: "opencode",
|
|
17
|
+
pi: "pi",
|
|
16
18
|
};
|
|
19
|
+
// Stable marker present in every Flow Agents claude-code hook command.
|
|
20
|
+
// Used by scope-collision detection to identify an existing flow-agents install.
|
|
21
|
+
// Marker must be distinctive to Flow Agents generated settings. Sibling
|
|
22
|
+
// products from the same lineage ship identically named hook scripts such
|
|
23
|
+
// as claude-hook-adapter.js, so script filenames are NOT a safe marker.
|
|
24
|
+
export const COLLISION_MARKER = "Recording Flow Agents telemetry";
|
|
25
|
+
/**
|
|
26
|
+
* Check whether a user-level Claude Code settings file already contains
|
|
27
|
+
* Flow Agents hook commands. If it does, print a WARNING explaining that
|
|
28
|
+
* Claude Code merges user-level and project-level settings and runs ALL
|
|
29
|
+
* matching hooks, so having flow-agents in both places causes duplicate
|
|
30
|
+
* hook execution (double telemetry, double policy enforcement).
|
|
31
|
+
*
|
|
32
|
+
* The check does NOT block the install; it is advisory only.
|
|
33
|
+
*
|
|
34
|
+
* @param userSettingsFile Path to inspect (defaults to $HOME/.claude/settings.json;
|
|
35
|
+
* overridable via FLOW_AGENTS_USER_CLAUDE_SETTINGS env var for testability).
|
|
36
|
+
* @returns true if a collision was detected, false otherwise.
|
|
37
|
+
*/
|
|
38
|
+
export function checkScopeCollision(userSettingsFile) {
|
|
39
|
+
const filePath = userSettingsFile
|
|
40
|
+
?? process.env["FLOW_AGENTS_USER_CLAUDE_SETTINGS"]
|
|
41
|
+
?? path.join(os.homedir(), ".claude", "settings.json");
|
|
42
|
+
if (!fs.existsSync(filePath))
|
|
43
|
+
return false;
|
|
44
|
+
let text;
|
|
45
|
+
try {
|
|
46
|
+
text = fs.readFileSync(filePath, "utf8");
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
if (!text.includes(COLLISION_MARKER))
|
|
52
|
+
return false;
|
|
53
|
+
console.warn(`\nWARNING: Flow Agents scope collision detected.\n` +
|
|
54
|
+
` ${filePath}\n` +
|
|
55
|
+
`already contains Flow Agents hook commands (marker: ${COLLISION_MARKER}).\n` +
|
|
56
|
+
`\n` +
|
|
57
|
+
`Claude Code merges user-level (~/.claude/settings.json) and project-level\n` +
|
|
58
|
+
`(.claude/settings.json) settings, then runs ALL matching hooks from both files.\n` +
|
|
59
|
+
`Installing Flow Agents at the project level while it is also present at the\n` +
|
|
60
|
+
`user level will cause duplicate hook execution: telemetry events are recorded\n` +
|
|
61
|
+
`twice and policy hooks (workflow-steering, config-protection, quality-gate,\n` +
|
|
62
|
+
`stop-goal-fit) run twice per event.\n` +
|
|
63
|
+
`\n` +
|
|
64
|
+
`To resolve:\n` +
|
|
65
|
+
` - Remove the hooks section from ${filePath} and rely solely on the\n` +
|
|
66
|
+
` project-level .claude/settings.json installed by flow-agents init, OR\n` +
|
|
67
|
+
` - Remove the project-level install and keep only the user-level one.\n` +
|
|
68
|
+
`\n` +
|
|
69
|
+
`The install will continue; resolve the collision before running Claude Code.\n`);
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
17
72
|
function usage() {
|
|
18
73
|
console.error(`usage: flow-agents init [options]
|
|
19
74
|
|
|
20
75
|
Options:
|
|
21
|
-
--runtime base|codex|claude-code|kiro
|
|
76
|
+
--runtime base|codex|claude-code|kiro|opencode|pi
|
|
22
77
|
--dest PATH
|
|
23
78
|
--telemetry-sink local-files|local-kontour-console|kontour-hosted-console|user-hosted-console
|
|
24
79
|
--console-url URL
|
|
@@ -35,9 +90,9 @@ function normalizeRuntime(value) {
|
|
|
35
90
|
return undefined;
|
|
36
91
|
if (value === "claude")
|
|
37
92
|
return "claude-code";
|
|
38
|
-
if (value === "base" || value === "codex" || value === "claude-code" || value === "kiro")
|
|
93
|
+
if (value === "base" || value === "codex" || value === "claude-code" || value === "kiro" || value === "opencode" || value === "pi")
|
|
39
94
|
return value;
|
|
40
|
-
throw new Error(`unknown runtime '${value}'; expected base, codex, claude-code, or
|
|
95
|
+
throw new Error(`unknown runtime '${value}'; expected base, codex, claude-code, kiro, opencode, or pi`);
|
|
41
96
|
}
|
|
42
97
|
function normalizeTelemetrySink(value) {
|
|
43
98
|
if (value === "local-files" || value === "local-kontour-console" || value === "kontour-hosted-console" || value === "user-hosted-console" || value === "kontour-cloud" || value === "hosted-kontour-console")
|
|
@@ -67,7 +122,7 @@ async function questionHidden(prompt) {
|
|
|
67
122
|
let value = "";
|
|
68
123
|
const onData = (buffer) => {
|
|
69
124
|
const text = buffer.toString("utf8");
|
|
70
|
-
if (text === "
|
|
125
|
+
if (text === "") {
|
|
71
126
|
stdout.write("\n");
|
|
72
127
|
process.exit(130);
|
|
73
128
|
}
|
|
@@ -78,7 +133,7 @@ async function questionHidden(prompt) {
|
|
|
78
133
|
resolve(value);
|
|
79
134
|
return;
|
|
80
135
|
}
|
|
81
|
-
if (text === "
|
|
136
|
+
if (text === "") {
|
|
82
137
|
value = value.slice(0, -1);
|
|
83
138
|
return;
|
|
84
139
|
}
|
|
@@ -224,6 +279,18 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
224
279
|
const headless = argv.includes("--yes") || argv.includes("--headless") || !process.stdin.isTTY;
|
|
225
280
|
try {
|
|
226
281
|
const options = headless ? headlessOptions(argv) : await interactiveOptions(argv);
|
|
282
|
+
// Scope-collision check for claude-code: Claude Code merges user-level
|
|
283
|
+
// (~/.claude/settings.json) and project-level (.claude/settings.json) settings
|
|
284
|
+
// and runs ALL matching hooks from both files. If a user-level settings file
|
|
285
|
+
// already contains flow-agents hooks, installing at the project level will
|
|
286
|
+
// cause duplicate hook execution. We warn but do not block.
|
|
287
|
+
//
|
|
288
|
+
// Codex note: Codex hooks live in .codex/hooks.json (project-level only).
|
|
289
|
+
// There is no well-known user-level codex hooks file in our install paths,
|
|
290
|
+
// so no collision check is needed for codex.
|
|
291
|
+
if (options.runtime === "claude-code") {
|
|
292
|
+
checkScopeCollision();
|
|
293
|
+
}
|
|
227
294
|
const bundle = ensureBundle(options.runtime);
|
|
228
295
|
const installed = installBundle(bundle, options);
|
|
229
296
|
if (installed !== 0)
|
|
@@ -235,5 +302,148 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
235
302
|
return 2;
|
|
236
303
|
}
|
|
237
304
|
}
|
|
305
|
+
// ---------------------------------------------------------------------------
|
|
306
|
+
// Dogfood subcommand
|
|
307
|
+
//
|
|
308
|
+
// `flow-agents dogfood --runtime claude-code [--dest PATH]`
|
|
309
|
+
//
|
|
310
|
+
// Writes only the hook-wiring artifacts for the specified runtime into the
|
|
311
|
+
// target directory (default: cwd). Unlike a full install, dogfood:
|
|
312
|
+
// - Does NOT rsync the full bundle (no agents/skills duplication).
|
|
313
|
+
// - Reads the generated settings/config from dist/<runtime>/ so the output
|
|
314
|
+
// cannot drift from what the bundle generates (DRY guarantee).
|
|
315
|
+
// - For claude-code: OMITS permissions.defaultMode and
|
|
316
|
+
// skipDangerousModePermissionPrompt (permissive defaults are for installed
|
|
317
|
+
// workspaces, not source repos).
|
|
318
|
+
// - Runs the same scope-collision warning as init.
|
|
319
|
+
// ---------------------------------------------------------------------------
|
|
320
|
+
function dogfoodUsage() {
|
|
321
|
+
console.error(`usage: flow-agents dogfood [options]
|
|
322
|
+
|
|
323
|
+
Options:
|
|
324
|
+
--runtime claude-code|codex|opencode|pi (required)
|
|
325
|
+
--dest PATH (default: cwd)
|
|
326
|
+
--yes, --headless
|
|
327
|
+
`);
|
|
328
|
+
}
|
|
329
|
+
function normalizeDogfoodRuntime(value) {
|
|
330
|
+
if (!value)
|
|
331
|
+
return undefined;
|
|
332
|
+
if (value === "claude" || value === "claude-code")
|
|
333
|
+
return "claude-code";
|
|
334
|
+
if (value === "codex" || value === "opencode" || value === "pi")
|
|
335
|
+
return value;
|
|
336
|
+
throw new Error(`dogfood: unsupported runtime '${value}'; expected claude-code, codex, opencode, or pi`);
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Write the claude-code hook-wiring artifacts into dest.
|
|
340
|
+
* Reads dist/claude-code/.claude/settings.json (generated by build-bundles),
|
|
341
|
+
* strips the permissive-mode permission keys (defaultMode, skipDangerousModePermissionPrompt),
|
|
342
|
+
* and writes .claude/settings.json to dest.
|
|
343
|
+
*/
|
|
344
|
+
function dogfoodClaudeCode(bundleRoot, dest) {
|
|
345
|
+
const sourcePath = path.join(bundleRoot, ".claude", "settings.json");
|
|
346
|
+
if (!fs.existsSync(sourcePath))
|
|
347
|
+
throw new Error(`dogfood: bundle settings missing: ${sourcePath}`);
|
|
348
|
+
const settings = JSON.parse(fs.readFileSync(sourcePath, "utf8"));
|
|
349
|
+
// Remove permissive defaults that are only appropriate for installed workspaces.
|
|
350
|
+
// These keys must not be present in the source repo's .claude/settings.json.
|
|
351
|
+
delete settings["permissions"];
|
|
352
|
+
delete settings["skipDangerousModePermissionPrompt"];
|
|
353
|
+
const outDir = path.join(dest, ".claude");
|
|
354
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
355
|
+
fs.writeFileSync(path.join(outDir, "settings.json"), `${JSON.stringify(settings, null, 2)}\n`, "utf8");
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Write the codex hook-wiring artifacts into dest.
|
|
359
|
+
* Reads dist/codex/.codex/hooks.json and writes .codex/hooks.json to dest.
|
|
360
|
+
* The monolithic .codex/config.toml is not written here because it contains
|
|
361
|
+
* workspace settings (approvals_reviewer, features) that would override the
|
|
362
|
+
* developer's existing codex configuration. Only the hooks file is written.
|
|
363
|
+
*/
|
|
364
|
+
function dogfoodCodex(bundleRoot, dest) {
|
|
365
|
+
const sourcePath = path.join(bundleRoot, ".codex", "hooks.json");
|
|
366
|
+
if (!fs.existsSync(sourcePath))
|
|
367
|
+
throw new Error(`dogfood: bundle hooks.json missing: ${sourcePath}`);
|
|
368
|
+
const hooks = fs.readFileSync(sourcePath, "utf8");
|
|
369
|
+
const outDir = path.join(dest, ".codex");
|
|
370
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
371
|
+
fs.writeFileSync(path.join(outDir, "hooks.json"), hooks, "utf8");
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Write the opencode hook-wiring artifacts into dest.
|
|
375
|
+
* Reads dist/opencode/.opencode/plugins/flow-agents.js and opencode.json,
|
|
376
|
+
* and writes them into dest. These are the minimal hook-wiring files; the
|
|
377
|
+
* full skill/agent tree is not copied.
|
|
378
|
+
*/
|
|
379
|
+
function dogfoodOpencode(bundleRoot, dest) {
|
|
380
|
+
const pluginSource = path.join(bundleRoot, ".opencode", "plugins", "flow-agents.js");
|
|
381
|
+
const configSource = path.join(bundleRoot, "opencode.json");
|
|
382
|
+
if (!fs.existsSync(pluginSource))
|
|
383
|
+
throw new Error(`dogfood: bundle plugin missing: ${pluginSource}`);
|
|
384
|
+
const pluginDir = path.join(dest, ".opencode", "plugins");
|
|
385
|
+
fs.mkdirSync(pluginDir, { recursive: true });
|
|
386
|
+
fs.copyFileSync(pluginSource, path.join(pluginDir, "flow-agents.js"));
|
|
387
|
+
// Write opencode.json only if it does not already exist to avoid clobbering
|
|
388
|
+
// any workspace-specific opencode configuration.
|
|
389
|
+
const destConfig = path.join(dest, "opencode.json");
|
|
390
|
+
if (!fs.existsSync(destConfig) && fs.existsSync(configSource)) {
|
|
391
|
+
fs.copyFileSync(configSource, destConfig);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Write the pi hook-wiring artifacts into dest.
|
|
396
|
+
* Reads dist/pi/.pi/extensions/flow-agents.ts and writes it to dest.
|
|
397
|
+
* The extension is the only hook-wiring file needed for pi.
|
|
398
|
+
*/
|
|
399
|
+
function dogfoodPi(bundleRoot, dest) {
|
|
400
|
+
const extSource = path.join(bundleRoot, ".pi", "extensions", "flow-agents.ts");
|
|
401
|
+
if (!fs.existsSync(extSource))
|
|
402
|
+
throw new Error(`dogfood: bundle extension missing: ${extSource}`);
|
|
403
|
+
const extDir = path.join(dest, ".pi", "extensions");
|
|
404
|
+
fs.mkdirSync(extDir, { recursive: true });
|
|
405
|
+
fs.copyFileSync(extSource, path.join(extDir, "flow-agents.ts"));
|
|
406
|
+
}
|
|
407
|
+
export async function mainDogfood(argv = process.argv.slice(2)) {
|
|
408
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
409
|
+
dogfoodUsage();
|
|
410
|
+
return 0;
|
|
411
|
+
}
|
|
412
|
+
const args = parseArgs(argv);
|
|
413
|
+
try {
|
|
414
|
+
const runtimeRaw = flagString(args.flags, "runtime");
|
|
415
|
+
const runtime = normalizeDogfoodRuntime(runtimeRaw);
|
|
416
|
+
if (!runtime) {
|
|
417
|
+
console.error("dogfood: --runtime is required (claude-code, codex, opencode, or pi)");
|
|
418
|
+
dogfoodUsage();
|
|
419
|
+
return 2;
|
|
420
|
+
}
|
|
421
|
+
const dest = path.resolve(flagString(args.flags, "dest") ?? process.cwd());
|
|
422
|
+
// Ensure the bundle for the requested runtime is built.
|
|
423
|
+
const bundleRuntime = runtime;
|
|
424
|
+
const bundleRoot = ensureBundle(bundleRuntime);
|
|
425
|
+
// Scope-collision check: warn if user-level claude settings already has flow-agents.
|
|
426
|
+
// Codex: no user-level hooks file in our install paths — skip with note above.
|
|
427
|
+
if (runtime === "claude-code") {
|
|
428
|
+
checkScopeCollision();
|
|
429
|
+
}
|
|
430
|
+
// Write only the hook-wiring artifacts, not the full bundle.
|
|
431
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
432
|
+
if (runtime === "claude-code")
|
|
433
|
+
dogfoodClaudeCode(bundleRoot, dest);
|
|
434
|
+
else if (runtime === "codex")
|
|
435
|
+
dogfoodCodex(bundleRoot, dest);
|
|
436
|
+
else if (runtime === "opencode")
|
|
437
|
+
dogfoodOpencode(bundleRoot, dest);
|
|
438
|
+
else if (runtime === "pi")
|
|
439
|
+
dogfoodPi(bundleRoot, dest);
|
|
440
|
+
console.log(`Flow Agents dogfood hooks wired for ${runtime} in ${dest}`);
|
|
441
|
+
return 0;
|
|
442
|
+
}
|
|
443
|
+
catch (error) {
|
|
444
|
+
console.error(`flow-agents dogfood: ${error.message}`);
|
|
445
|
+
return 2;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
238
448
|
if (import.meta.url === `file://${process.argv[1]}`)
|
|
239
449
|
process.exit(await main());
|