@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
|
@@ -40,6 +40,10 @@ CODEX_LEGACY_CONSOLE_DEST="$TMPDIR_EVAL/codex-legacy-console-workspace"
|
|
|
40
40
|
CODEX_BAD_CONSOLE_DEST="$TMPDIR_EVAL/codex-bad-console-workspace"
|
|
41
41
|
BASE_INIT_DEST="$TMPDIR_EVAL/base-init-workspace"
|
|
42
42
|
CODEX_INIT_DEST="$TMPDIR_EVAL/codex-init-workspace"
|
|
43
|
+
OPENCODE_DEST="$TMPDIR_EVAL/opencode-workspace"
|
|
44
|
+
OPENCODE_CONSOLE_DEST="$TMPDIR_EVAL/opencode-console-workspace"
|
|
45
|
+
OPENCODE_CORE_DEST="$TMPDIR_EVAL/opencode-core-workspace"
|
|
46
|
+
PI_DEST="$TMPDIR_EVAL/pi-workspace"
|
|
43
47
|
CONSOLE_TOKEN_FILE="$TMPDIR_EVAL/console-token"
|
|
44
48
|
printf 'test-token\n' > "$CONSOLE_TOKEN_FILE"
|
|
45
49
|
chmod 600 "$CONSOLE_TOKEN_FILE" 2>/dev/null || true
|
|
@@ -112,6 +116,30 @@ else
|
|
|
112
116
|
_fail "flow-agents init headless Codex install failed"
|
|
113
117
|
fi
|
|
114
118
|
|
|
119
|
+
if (cd "$ROOT_DIR/dist/opencode" && bash install.sh "$OPENCODE_DEST" >/dev/null); then
|
|
120
|
+
_pass "opencode install succeeded"
|
|
121
|
+
else
|
|
122
|
+
_fail "opencode install failed"
|
|
123
|
+
fi
|
|
124
|
+
|
|
125
|
+
if (cd "$ROOT_DIR/dist/opencode" && bash install.sh "$OPENCODE_CONSOLE_DEST" --telemetry-sink local-kontour-console --console-token-file "$CONSOLE_TOKEN_FILE" --console-tenant tenant-oc >/dev/null); then
|
|
126
|
+
_pass "opencode install with Console telemetry config succeeded"
|
|
127
|
+
else
|
|
128
|
+
_fail "opencode install with Console telemetry config failed"
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
if node "$ROOT_DIR/build/src/cli.js" init --runtime opencode --dest "$OPENCODE_CORE_DEST" --yes >/dev/null; then
|
|
132
|
+
_pass "flow-agents init headless opencode install succeeded"
|
|
133
|
+
else
|
|
134
|
+
_fail "flow-agents init headless opencode install failed"
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
if (cd "$ROOT_DIR/dist/pi" && bash install.sh "$PI_DEST" >/dev/null); then
|
|
138
|
+
_pass "pi install succeeded"
|
|
139
|
+
else
|
|
140
|
+
_fail "pi install failed"
|
|
141
|
+
fi
|
|
142
|
+
|
|
115
143
|
USER_SKILLS_DIR="$CODEX_CORE_DEST/.codex/sk""ills/user-skill"
|
|
116
144
|
mkdir -p "$CODEX_CORE_DEST/.codex/ag""ents" "$USER_SKILLS_DIR"
|
|
117
145
|
printf 'name = "user-agent"\n' > "$CODEX_CORE_DEST/.codex/ag""ents/user-agent.toml"
|
|
@@ -219,6 +247,14 @@ else
|
|
|
219
247
|
_fail "flow-agents init default did not install base AGENTS.md workspace contract"
|
|
220
248
|
fi
|
|
221
249
|
|
|
250
|
+
if rg -F -q "console_telemetry_url=$LOCAL_KONTOUR_CONSOLE_URL" "$OPENCODE_CONSOLE_DEST/scripts/telemetry/telemetry.conf" \
|
|
251
|
+
&& rg -q '^console_telemetry_token=test-token$' "$OPENCODE_CONSOLE_DEST/scripts/telemetry/telemetry.conf" \
|
|
252
|
+
&& rg -q '^console_tenant_id=tenant-oc$' "$OPENCODE_CONSOLE_DEST/scripts/telemetry/telemetry.conf"; then
|
|
253
|
+
_pass "opencode install persists Console telemetry config"
|
|
254
|
+
else
|
|
255
|
+
_fail "opencode install did not persist Console telemetry config"
|
|
256
|
+
fi
|
|
257
|
+
|
|
222
258
|
for dir in "$KIRO_DEST" "$BASE_DEST" "$CLAUDE_DEST" "$CODEX_DEST"; do
|
|
223
259
|
if [[ -f "$dir/console.telemetry.json" ]] \
|
|
224
260
|
&& node - "$dir/console.telemetry.json" <<'NODE'
|
|
@@ -341,7 +377,7 @@ else
|
|
|
341
377
|
_fail "installed Kiro agent JSON parse failed"
|
|
342
378
|
fi
|
|
343
379
|
|
|
344
|
-
if rg -n '/Users/[^/]+/\.flow-agents|~/\.flow-agents' "$KIRO_DEST" "$BASE_DEST" "$CLAUDE_DEST" "$CODEX_DEST" --glob '!**/evals/**' >/tmp/installed-bundle-leaks.txt 2>/dev/null; then
|
|
380
|
+
if rg -n '/Users/[^/]+/\.flow-agents|~/\.flow-agents' "$KIRO_DEST" "$BASE_DEST" "$CLAUDE_DEST" "$CODEX_DEST" "$OPENCODE_DEST" "$PI_DEST" --glob '!**/evals/**' >/tmp/installed-bundle-leaks.txt 2>/dev/null; then
|
|
345
381
|
_fail "installed bundles contain machine-local absolute paths (see /tmp/installed-bundle-leaks.txt)"
|
|
346
382
|
else
|
|
347
383
|
_pass "installed bundles are free of machine-local absolute paths"
|
|
@@ -359,6 +395,18 @@ else
|
|
|
359
395
|
_fail "Codex task dir scaffold missing"
|
|
360
396
|
fi
|
|
361
397
|
|
|
398
|
+
if [[ -f "$OPENCODE_DEST/.flow-agents/.gitkeep" ]]; then
|
|
399
|
+
_pass "opencode task dir scaffold installed"
|
|
400
|
+
else
|
|
401
|
+
_fail "opencode task dir scaffold missing"
|
|
402
|
+
fi
|
|
403
|
+
|
|
404
|
+
if [[ -f "$PI_DEST/.flow-agents/.gitkeep" ]]; then
|
|
405
|
+
_pass "pi task dir scaffold installed"
|
|
406
|
+
else
|
|
407
|
+
_fail "pi task dir scaffold missing"
|
|
408
|
+
fi
|
|
409
|
+
|
|
362
410
|
if rg -q 'claude-hook-adapter\.js.*stop-goal-fit\.js' "$CLAUDE_DEST/.claude/settings.json" \
|
|
363
411
|
&& rg -q 'claude-hook-adapter\.js.*workflow-steering\.js' "$CLAUDE_DEST/.claude/settings.json" \
|
|
364
412
|
&& rg -q 'claude-hook-adapter\.js.*quality-gate\.js' "$CLAUDE_DEST/.claude/settings.json" \
|
|
@@ -418,6 +466,38 @@ else
|
|
|
418
466
|
_fail "installed bundles do not wire prompt-submit workflow steering consistently"
|
|
419
467
|
fi
|
|
420
468
|
|
|
469
|
+
if [[ -f "$OPENCODE_DEST/.opencode/plugins/flow-agents.js" ]] && node - "$OPENCODE_DEST/.opencode/plugins/flow-agents.js" <<'NODE'
|
|
470
|
+
const fs = require("node:fs");
|
|
471
|
+
const text = fs.readFileSync(process.argv[2], "utf8");
|
|
472
|
+
if (!text.includes("opencode-hook-adapter.js")) throw new Error("opencode plugin missing opencode-hook-adapter.js");
|
|
473
|
+
if (!text.includes("opencode-telemetry-hook.js")) throw new Error("opencode plugin missing opencode-telemetry-hook.js");
|
|
474
|
+
if (!text.includes("workflow-steering.js")) throw new Error("opencode plugin missing workflow-steering.js");
|
|
475
|
+
if (!text.includes("stop-goal-fit.js")) throw new Error("opencode plugin missing stop-goal-fit.js");
|
|
476
|
+
if (!text.includes("config-protection.js")) throw new Error("opencode plugin missing config-protection.js");
|
|
477
|
+
console.log("ok");
|
|
478
|
+
NODE
|
|
479
|
+
then
|
|
480
|
+
_pass "opencode install wires Flow Agents plugin with policy hooks"
|
|
481
|
+
else
|
|
482
|
+
_fail "opencode install missing or mis-wired Flow Agents plugin"
|
|
483
|
+
fi
|
|
484
|
+
|
|
485
|
+
if [[ -f "$PI_DEST/.pi/extensions/flow-agents.ts" ]] && node - "$PI_DEST/.pi/extensions/flow-agents.ts" <<'NODE'
|
|
486
|
+
const fs = require("node:fs");
|
|
487
|
+
const text = fs.readFileSync(process.argv[2], "utf8");
|
|
488
|
+
if (!text.includes("pi-hook-adapter.js")) throw new Error("pi extension missing pi-hook-adapter.js");
|
|
489
|
+
if (!text.includes("pi-telemetry-hook.js")) throw new Error("pi extension missing pi-telemetry-hook.js");
|
|
490
|
+
if (!text.includes("workflow-steering.js")) throw new Error("pi extension missing workflow-steering.js");
|
|
491
|
+
if (!text.includes("stop-goal-fit.js")) throw new Error("pi extension missing stop-goal-fit.js");
|
|
492
|
+
if (!text.includes("config-protection.js")) throw new Error("pi extension missing config-protection.js");
|
|
493
|
+
console.log("ok");
|
|
494
|
+
NODE
|
|
495
|
+
then
|
|
496
|
+
_pass "pi install wires Flow Agents extension with policy hooks"
|
|
497
|
+
else
|
|
498
|
+
_fail "pi install missing or mis-wired Flow Agents extension"
|
|
499
|
+
fi
|
|
500
|
+
|
|
421
501
|
KIRO_WORKSPACE="$TMPDIR_EVAL/kiro-workspace"
|
|
422
502
|
mkdir -p "$KIRO_WORKSPACE"
|
|
423
503
|
if node - "$CLAUDE_DEST" "$CODEX_DEST" "$KIRO_DEST" "$KIRO_WORKSPACE" <<'NODE'
|
|
@@ -504,6 +584,125 @@ else
|
|
|
504
584
|
_fail "installed prompt-submit workflow-steering commands did not execute consistently"
|
|
505
585
|
fi
|
|
506
586
|
|
|
587
|
+
# Execute the opencode plugin's workflow-steering command path directly
|
|
588
|
+
OPENCODE_WORKSPACE="$TMPDIR_EVAL/opencode-exec-workspace"
|
|
589
|
+
mkdir -p "$OPENCODE_WORKSPACE"
|
|
590
|
+
if node - "$OPENCODE_DEST" "$OPENCODE_WORKSPACE" <<'NODE'
|
|
591
|
+
const fs = require("node:fs");
|
|
592
|
+
const path = require("node:path");
|
|
593
|
+
const { spawnSync } = require("node:child_process");
|
|
594
|
+
const [opencodeDest, opencodeWorkspace] = process.argv.slice(2);
|
|
595
|
+
const state = {
|
|
596
|
+
schema_version: "1.0",
|
|
597
|
+
task_slug: "opencode-hook-demo",
|
|
598
|
+
status: "not_verified",
|
|
599
|
+
phase: "verification",
|
|
600
|
+
updated_at: "2026-06-01T00:00:00Z",
|
|
601
|
+
next_action: { status: "needs_user", summary: "Opencode hook test.", target_phase: "goal_fit" },
|
|
602
|
+
};
|
|
603
|
+
const critique = {
|
|
604
|
+
schema_version: "1.0",
|
|
605
|
+
task_slug: "opencode-hook-demo",
|
|
606
|
+
status: "fail",
|
|
607
|
+
required: true,
|
|
608
|
+
updated_at: "2026-06-01T00:01:00Z",
|
|
609
|
+
critiques: [{ id: "oc-review", reviewer: "tool-code-reviewer", reviewed_at: "2026-06-01T00:01:00Z", verdict: "fail", summary: "Blocking.", findings: [{ id: "oc-open", severity: "high", status: "open", description: "Open finding." }] }],
|
|
610
|
+
};
|
|
611
|
+
function writeFixture(root) {
|
|
612
|
+
const taskDir = path.join(root, ".flow-agents/opencode-hook-demo");
|
|
613
|
+
fs.mkdirSync(taskDir, { recursive: true });
|
|
614
|
+
fs.writeFileSync(path.join(taskDir, "state.json"), JSON.stringify(state), "utf8");
|
|
615
|
+
fs.writeFileSync(path.join(taskDir, "critique.json"), JSON.stringify(critique), "utf8");
|
|
616
|
+
fs.mkdirSync(path.join(root, "docs"), { recursive: true });
|
|
617
|
+
fs.writeFileSync(path.join(root, "docs/context-map.md"), "# Context Map\n", "utf8");
|
|
618
|
+
}
|
|
619
|
+
function runOpencodeAdapter(bundleDest, cwd) {
|
|
620
|
+
const adapterPath = path.join(bundleDest, "scripts", "hooks", "opencode-hook-adapter.js");
|
|
621
|
+
const payload = JSON.stringify({ hook_event_name: "UserPromptSubmit", cwd });
|
|
622
|
+
const result = spawnSync(process.execPath, [adapterPath, "UserPromptSubmit", "workflow-steering", "workflow-steering.js", "default"], {
|
|
623
|
+
input: payload,
|
|
624
|
+
cwd,
|
|
625
|
+
env: { ...process.env, SA_HOOK_PROFILE: "standard", FLOW_AGENTS_HOOK_RUNTIME: "opencode" },
|
|
626
|
+
encoding: "utf8",
|
|
627
|
+
timeout: 30000,
|
|
628
|
+
});
|
|
629
|
+
if (result.status !== 0) throw new Error("opencode adapter failed: rc=" + result.status + " stderr=" + result.stderr);
|
|
630
|
+
const out = JSON.parse(result.stdout || "{}");
|
|
631
|
+
const ctx = out.context || "";
|
|
632
|
+
if (!ctx.includes("WORKFLOW STATE ATTENTION")) throw new Error("opencode adapter did not emit workflow attention: stdout=" + result.stdout + " stderr=" + result.stderr);
|
|
633
|
+
if (!ctx.includes("STATE: opencode-hook-demo is status:not_verified phase:verification")) throw new Error("opencode adapter missed state guidance: " + ctx);
|
|
634
|
+
if (!ctx.includes("CRITIQUE: required critique is status:fail")) throw new Error("opencode adapter missed critique guidance: " + ctx);
|
|
635
|
+
}
|
|
636
|
+
writeFixture(opencodeWorkspace);
|
|
637
|
+
runOpencodeAdapter(opencodeDest, opencodeWorkspace);
|
|
638
|
+
console.log("ok");
|
|
639
|
+
NODE
|
|
640
|
+
then
|
|
641
|
+
_pass "opencode installed hook adapter executes workflow-steering commands correctly"
|
|
642
|
+
else
|
|
643
|
+
_fail "opencode installed hook adapter did not execute workflow-steering commands correctly"
|
|
644
|
+
fi
|
|
645
|
+
|
|
646
|
+
# Execute the pi extension's hook adapter command path directly
|
|
647
|
+
PI_WORKSPACE="$TMPDIR_EVAL/pi-exec-workspace"
|
|
648
|
+
mkdir -p "$PI_WORKSPACE"
|
|
649
|
+
if node - "$PI_DEST" "$PI_WORKSPACE" <<'NODE'
|
|
650
|
+
const fs = require("node:fs");
|
|
651
|
+
const path = require("node:path");
|
|
652
|
+
const { spawnSync } = require("node:child_process");
|
|
653
|
+
const [piDest, piWorkspace] = process.argv.slice(2);
|
|
654
|
+
const state = {
|
|
655
|
+
schema_version: "1.0",
|
|
656
|
+
task_slug: "pi-hook-demo",
|
|
657
|
+
status: "not_verified",
|
|
658
|
+
phase: "verification",
|
|
659
|
+
updated_at: "2026-06-01T00:00:00Z",
|
|
660
|
+
next_action: { status: "needs_user", summary: "Pi hook test.", target_phase: "goal_fit" },
|
|
661
|
+
};
|
|
662
|
+
const critique = {
|
|
663
|
+
schema_version: "1.0",
|
|
664
|
+
task_slug: "pi-hook-demo",
|
|
665
|
+
status: "fail",
|
|
666
|
+
required: true,
|
|
667
|
+
updated_at: "2026-06-01T00:01:00Z",
|
|
668
|
+
critiques: [{ id: "pi-review", reviewer: "tool-code-reviewer", reviewed_at: "2026-06-01T00:01:00Z", verdict: "fail", summary: "Blocking.", findings: [{ id: "pi-open", severity: "high", status: "open", description: "Open finding." }] }],
|
|
669
|
+
};
|
|
670
|
+
function writeFixture(root) {
|
|
671
|
+
const taskDir = path.join(root, ".flow-agents/pi-hook-demo");
|
|
672
|
+
fs.mkdirSync(taskDir, { recursive: true });
|
|
673
|
+
fs.writeFileSync(path.join(taskDir, "state.json"), JSON.stringify(state), "utf8");
|
|
674
|
+
fs.writeFileSync(path.join(taskDir, "critique.json"), JSON.stringify(critique), "utf8");
|
|
675
|
+
fs.mkdirSync(path.join(root, "docs"), { recursive: true });
|
|
676
|
+
fs.writeFileSync(path.join(root, "docs/context-map.md"), "# Context Map\n", "utf8");
|
|
677
|
+
}
|
|
678
|
+
function runPiAdapter(bundleDest, cwd) {
|
|
679
|
+
const adapterPath = path.join(bundleDest, "scripts", "hooks", "pi-hook-adapter.js");
|
|
680
|
+
const payload = JSON.stringify({ hook_event_name: "UserPromptSubmit", cwd });
|
|
681
|
+
const result = spawnSync(process.execPath, [adapterPath, "UserPromptSubmit", "workflow-steering", "workflow-steering.js", "default"], {
|
|
682
|
+
input: payload,
|
|
683
|
+
cwd,
|
|
684
|
+
env: { ...process.env, SA_HOOK_PROFILE: "standard", FLOW_AGENTS_HOOK_RUNTIME: "pi" },
|
|
685
|
+
encoding: "utf8",
|
|
686
|
+
timeout: 30000,
|
|
687
|
+
});
|
|
688
|
+
if (result.status !== 0) throw new Error("pi adapter failed: rc=" + result.status + " stderr=" + result.stderr);
|
|
689
|
+
const out = JSON.parse(result.stdout || "{}");
|
|
690
|
+
const ctx = out.context || "";
|
|
691
|
+
if (!ctx.includes("WORKFLOW STATE ATTENTION")) throw new Error("pi adapter did not emit workflow attention: stdout=" + result.stdout + " stderr=" + result.stderr);
|
|
692
|
+
if (!ctx.includes("STATE: pi-hook-demo is status:not_verified phase:verification")) throw new Error("pi adapter missed state guidance: " + ctx);
|
|
693
|
+
if (!ctx.includes("CRITIQUE: required critique is status:fail")) throw new Error("pi adapter missed critique guidance: " + ctx);
|
|
694
|
+
}
|
|
695
|
+
writeFixture(piWorkspace);
|
|
696
|
+
runPiAdapter(piDest, piWorkspace);
|
|
697
|
+
console.log("ok");
|
|
698
|
+
NODE
|
|
699
|
+
then
|
|
700
|
+
_pass "pi installed hook adapter executes workflow-steering commands correctly"
|
|
701
|
+
else
|
|
702
|
+
_fail "pi installed hook adapter did not execute workflow-steering commands correctly"
|
|
703
|
+
fi
|
|
704
|
+
|
|
705
|
+
|
|
507
706
|
echo ""
|
|
508
707
|
echo "--- Pack Filtering ---"
|
|
509
708
|
CODEX_AGENTS_DIR="$CODEX_CORE_DEST/.codex/ag""ents"
|
|
@@ -533,6 +732,32 @@ else
|
|
|
533
732
|
_fail "Codex core-pack install removed unknown user files"
|
|
534
733
|
fi
|
|
535
734
|
|
|
735
|
+
# Pack filtering for opencode
|
|
736
|
+
OPENCODE_AGENTS_DIR="$OPENCODE_CORE_DEST/.opencode/agents"
|
|
737
|
+
if (cd "$ROOT_DIR/dist/opencode" && FLOW_AGENTS_PACKS=core bash install.sh "$OPENCODE_CORE_DEST" >/dev/null); then
|
|
738
|
+
_pass "opencode core-pack filtered install succeeded"
|
|
739
|
+
else
|
|
740
|
+
_fail "opencode core-pack filtered install failed"
|
|
741
|
+
fi
|
|
742
|
+
|
|
743
|
+
if [[ -d "$OPENCODE_AGENTS_DIR/tool-planner.md" ]] || [[ -f "$OPENCODE_AGENTS_DIR/tool-planner.md" ]]; then
|
|
744
|
+
_pass "opencode core-pack install keeps core agents"
|
|
745
|
+
else
|
|
746
|
+
_fail "opencode core-pack agent filtering failed (tool-planner.md missing)"
|
|
747
|
+
fi
|
|
748
|
+
|
|
749
|
+
if [[ -d "$OPENCODE_CORE_DEST/.opencode/skills/plan-work" && ! -d "$OPENCODE_CORE_DEST/.opencode/skills/deliver" ]]; then
|
|
750
|
+
_pass "opencode core-pack install keeps core skills and prunes optional skills"
|
|
751
|
+
else
|
|
752
|
+
_fail "opencode core-pack skill filtering failed"
|
|
753
|
+
fi
|
|
754
|
+
|
|
755
|
+
if [[ -f "$OPENCODE_CORE_DEST/.flow-agents/installed-packs.json" ]]; then
|
|
756
|
+
_pass "opencode core-pack install records selected packs"
|
|
757
|
+
else
|
|
758
|
+
_fail "opencode core-pack install did not record selected packs"
|
|
759
|
+
fi
|
|
760
|
+
|
|
536
761
|
echo ""
|
|
537
762
|
echo "==========================="
|
|
538
763
|
total=$((pass + fail))
|