@khoavu882/doflow 2.0.0-beta.4 → 2.0.0-beta.5

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 (101) hide show
  1. package/core/.antigravity-plugin/plugin.json +0 -1
  2. package/core/.claude-plugin/plugin.json +1 -1
  3. package/core/.codex-plugin/plugin.json +1 -1
  4. package/core/.plugin/plugin.json +1 -1
  5. package/core/harnesses/claude/hooks/mcp-tool-guard.sh +7 -17
  6. package/core/harnesses/claude/hooks/pre-bash-guard.sh +7 -17
  7. package/core/harnesses/claude/hooks/pre-implement-gate.sh +7 -18
  8. package/core/harnesses/claude/hooks/session-start.sh +5 -3
  9. package/core/harnesses/claude/hooks/stop-check.sh +5 -3
  10. package/core/harnesses/claude/hooks/subagent-audit.sh +5 -5
  11. package/core/harnesses/claude/hooks/user-prompt-submit.sh +5 -3
  12. package/core/harnesses/codex/hooks/mcp-tool-guard.sh +7 -15
  13. package/core/harnesses/codex/hooks/pre-bash-guard.sh +7 -15
  14. package/core/harnesses/codex/hooks/pre-implement-gate.sh +7 -16
  15. package/core/harnesses/codex/hooks/session-start.sh +5 -3
  16. package/core/harnesses/codex/hooks/stop-check.sh +6 -5
  17. package/core/harnesses/codex/hooks/subagent-audit.sh +17 -6
  18. package/core/harnesses/codex/hooks/user-prompt-submit.sh +5 -4
  19. package/core/harnesses/gemini/hooks/mcp-tool-guard.sh +7 -18
  20. package/core/harnesses/gemini/hooks/pre-bash-guard.sh +7 -18
  21. package/core/harnesses/gemini/hooks/pre-implement-gate.sh +7 -19
  22. package/core/harnesses/gemini/hooks/session-start.sh +5 -3
  23. package/core/harnesses/kiro/hooks/mcp-tool-guard.sh +20 -5
  24. package/core/harnesses/kiro/hooks/pre-bash-guard.sh +20 -5
  25. package/core/harnesses/kiro/hooks/pre-implement-gate.sh +20 -5
  26. package/core/harnesses/kiro/hooks/session-start.sh +11 -5
  27. package/core/harnesses/kiro/hooks/stop-check.sh +21 -30
  28. package/core/harnesses/pi/extensions/doflow-guard.js +159 -0
  29. package/core/harnesses/shared/hooks/ENVELOPE_MIGRATION.md +27 -11
  30. package/core/harnesses/shared/hooks/adapters/antigravity.js +14 -57
  31. package/core/harnesses/shared/hooks/bridge/bridge.sh +184 -0
  32. package/core/harnesses/shared/hooks/bridge/envelope.jq +60 -0
  33. package/core/harnesses/shared/hooks/bridge/respond.sh +62 -0
  34. package/core/harnesses/shared/hooks/policies/capture-failure.sh +4 -2
  35. package/core/harnesses/shared/hooks/policies/contract.sh +75 -0
  36. package/core/harnesses/shared/hooks/policies/deny-json.sh +39 -4
  37. package/core/harnesses/shared/hooks/policies/lib.sh +4 -2
  38. package/core/harnesses/shared/hooks/policies/mcp-tool-guard.sh +46 -34
  39. package/core/harnesses/shared/hooks/policies/pre-bash-guard.sh +75 -25
  40. package/core/harnesses/shared/hooks/policies/pre-implementation-gate.sh +67 -73
  41. package/core/harnesses/shared/hooks/policies/session-context.sh +37 -7
  42. package/core/harnesses/shared/hooks/policies/stop-check.sh +42 -15
  43. package/core/harnesses/shared/hooks/policies/subagent-audit.sh +35 -5
  44. package/core/harnesses/shared/hooks/policies/user-prompt-submit.sh +40 -7
  45. package/core/harnesses/shared/hooks/stream-hook-runner.js +69 -181
  46. package/core/registry/assets.json +19 -0
  47. package/core/registry/contracts.json +2 -2
  48. package/core/registry/harnesses.json +196 -10
  49. package/core/registry/lifecycle.json +2626 -7
  50. package/core/registry/storage.json +24 -1
  51. package/core/shared/scripts/doflow/bin/doflow-run +10 -6
  52. package/core/shared/skills/do-design/SKILL.md +6 -6
  53. package/core/shared/skills/do-execute-plan/SKILL.md +11 -10
  54. package/core/shared/skills/do-execute-plan/references/readiness_gate.md +2 -0
  55. package/core/shared/skills/do-implement/SKILL.md +3 -2
  56. package/core/shared/skills/do-plan/SKILL.md +7 -8
  57. package/package.json +1 -1
  58. package/src/adapters/antigravity/index.js +83 -47
  59. package/src/adapters/claude/index.js +15 -1
  60. package/src/adapters/codex/hooks.js +40 -5
  61. package/src/adapters/codex/index.js +52 -9
  62. package/src/adapters/copy-tree.js +4 -4
  63. package/src/adapters/gemini/hooks.js +57 -16
  64. package/src/adapters/gemini/index.js +57 -18
  65. package/src/adapters/kiro/index.js +15 -1
  66. package/src/adapters/pi/hooks.js +119 -0
  67. package/src/adapters/pi/index.js +34 -9
  68. package/src/cli/commands/install.js +1 -1
  69. package/src/cli/commands/update.js +1 -1
  70. package/src/cli/index.js +17 -5
  71. package/src/cli/runtime-commands.js +51 -12
  72. package/src/lifecycle/coverage.js +57 -0
  73. package/src/lifecycle/hook-step.js +61 -0
  74. package/src/lifecycle/index.js +28 -14
  75. package/src/registry/index.js +136 -7
  76. package/src/runtime/candidate.js +505 -0
  77. package/src/runtime/claims.js +14 -5
  78. package/src/runtime/cli-result.js +11 -4
  79. package/src/runtime/cli.js +35 -268
  80. package/src/runtime/context/budget.js +203 -0
  81. package/src/runtime/context/compose.js +1367 -0
  82. package/src/runtime/context/delivery-store.js +102 -0
  83. package/src/runtime/context/mandatory.js +594 -0
  84. package/src/runtime/context/pointer.js +142 -0
  85. package/src/runtime/context-pack.js +1029 -244
  86. package/src/runtime/evidence-fields.js +39 -0
  87. package/src/runtime/evidence-ledger.js +7 -0
  88. package/src/runtime/freshness.js +44 -7
  89. package/src/runtime/outcome.js +1 -1
  90. package/src/runtime/readiness.js +83 -13
  91. package/src/runtime/retrieval-plan.js +422 -73
  92. package/src/runtime/retrieval-record.js +223 -0
  93. package/src/runtime/scaffold/artifacts.js +3 -0
  94. package/src/runtime/source-version.js +289 -0
  95. package/src/runtime/task-attempts.js +1 -1
  96. package/src/runtime/task-scope.js +28 -3
  97. package/src/runtime/task-state.js +72 -7
  98. package/core/.antigravity-plugin/hooks.json +0 -39
  99. package/core/harnesses/shared/hooks/adapters/arg-fields.js +0 -19
  100. package/core/harnesses/shared/hooks/adapters/gemini.js +0 -114
  101. package/core/harnesses/shared/hooks/hooks.json +0 -47
@@ -26,6 +26,5 @@
26
26
  "agents": [
27
27
  "../../core/shared/agent-specs/"
28
28
  ],
29
- "hooks": "./hooks.json",
30
29
  "mcp": "./mcp_config.json"
31
30
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "doflow",
3
- "version": "2.0.0-beta.4",
3
+ "version": "2.0.0-beta.5",
4
4
  "description": "Reusable engineering workflows, quality gates, and specialist guidance for Claude Code.",
5
5
  "author": {
6
6
  "name": "DoFlow"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "doflow",
3
- "version": "2.0.0-beta.4",
3
+ "version": "2.0.0-beta.5",
4
4
  "description": "Reusable engineering workflows, quality gates, and specialist guidance for Codex.",
5
5
  "author": {
6
6
  "name": "DoFlow",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "doflow",
3
- "version": "2.0.0-beta.4",
3
+ "version": "2.0.0-beta.5",
4
4
  "description": "Reusable engineering workflows, quality gates, and specialist guidance for GitHub Copilot CLI.",
5
5
  "author": {
6
6
  "name": "DoFlow",
@@ -1,20 +1,10 @@
1
1
  #!/usr/bin/env bash
2
- # Claude front door: delegates the mcp-tool-guard decision to the Canonical Policy
3
- # Library, then translates it into Claude Code's verified deny contract.
4
- #
5
- # Schema verified (Phase 8.3, 2026-04-17): hookSpecificOutput.permissionDecision
6
- # "deny" is correctly recognized by Claude Code and blocks execution — exit code
7
- # alone is not sufficient here, so this front door is a translator, not a bare
8
- # exec (unlike session-context/stop-check, which never need this translation).
2
+ # Claude front door: mcp-tool-guard through the shared lifecycle bridge.
9
3
  set -uo pipefail
10
4
  export DOFLOW_AGENT="${DOFLOW_AGENT:-claude}"
11
-
12
- command -v jq >/dev/null 2>&1 || exit 0
13
- source "$(dirname "$0")/../../.doflow/shared/hooks/policies/deny-json.sh"
14
-
15
- POLICY="$(dirname "$0")/../../.doflow/shared/hooks/policies/mcp-tool-guard.sh"
16
- REASON=$(bash "$POLICY" 2>&1 >/dev/null)
17
- CODE=$?
18
-
19
- [ "$CODE" -ne 0 ] && emit_pretooluse_deny_nested "${REASON:-MCP tool call blocked by mcp-tool-guard}"
20
- exit 0
5
+ if ! . "$(dirname "$0")/../../.doflow/shared/hooks/bridge/bridge.sh" 2>/dev/null; then
6
+ printf '%s\n' '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"[doflow] shared hooks lack the bridge; run: doflow update -t claude"}}'
7
+ exit 0
8
+ fi
9
+ doflow_bridge claude PreToolUse mcp-tool-guard
10
+ exit $?
@@ -1,20 +1,10 @@
1
1
  #!/usr/bin/env bash
2
- # Claude front door: delegates the pre-bash-guard decision to the Canonical Policy
3
- # Library, then translates it into Claude Code's verified deny contract.
4
- #
5
- # Schema verified (Phase 8.3, 2026-04-17): hookSpecificOutput.permissionDecision
6
- # "deny" is correctly recognized by Claude Code and blocks execution — exit code
7
- # alone is not sufficient here, so this front door is a translator, not a bare
8
- # exec (unlike session-context/stop-check, which never need this translation).
2
+ # Claude front door: pre-bash-guard through the shared lifecycle bridge.
9
3
  set -uo pipefail
10
4
  export DOFLOW_AGENT="${DOFLOW_AGENT:-claude}"
11
-
12
- command -v jq >/dev/null 2>&1 || exit 0
13
- source "$(dirname "$0")/../../.doflow/shared/hooks/policies/deny-json.sh"
14
-
15
- POLICY="$(dirname "$0")/../../.doflow/shared/hooks/policies/pre-bash-guard.sh"
16
- REASON=$(bash "$POLICY" 2>&1 >/dev/null)
17
- CODE=$?
18
-
19
- [ "$CODE" -ne 0 ] && emit_pretooluse_deny_nested "${REASON:-Command blocked by pre-bash-guard}"
20
- exit 0
5
+ if ! . "$(dirname "$0")/../../.doflow/shared/hooks/bridge/bridge.sh" 2>/dev/null; then
6
+ printf '%s\n' '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"[doflow] shared hooks lack the bridge; run: doflow update -t claude"}}'
7
+ exit 0
8
+ fi
9
+ doflow_bridge claude PreToolUse pre-bash-guard
10
+ exit $?
@@ -1,21 +1,10 @@
1
1
  #!/usr/bin/env bash
2
- # Claude front door: delegates the pre-implementation-gate decision to the
3
- # Canonical Policy Library, then translates it into Claude Code's verified deny
4
- # contract.
5
- #
6
- # Schema verified (Phase 8.3, 2026-04-17): hookSpecificOutput.permissionDecision
7
- # "deny" is correctly recognized by Claude Code and blocks execution — exit code
8
- # alone is not sufficient here, so this front door is a translator, not a bare
9
- # exec (unlike session-context/stop-check, which never need this translation).
2
+ # Claude front door: pre-implementation-gate through the shared lifecycle bridge.
10
3
  set -uo pipefail
11
4
  export DOFLOW_AGENT="${DOFLOW_AGENT:-claude}"
12
-
13
- command -v jq >/dev/null 2>&1 || exit 0
14
- source "$(dirname "$0")/../../.doflow/shared/hooks/policies/deny-json.sh"
15
-
16
- POLICY="$(dirname "$0")/../../.doflow/shared/hooks/policies/pre-implementation-gate.sh"
17
- REASON=$(bash "$POLICY" 2>&1 >/dev/null)
18
- CODE=$?
19
-
20
- [ "$CODE" -ne 0 ] && emit_pretooluse_deny_nested "${REASON:-Implementation requires an approved plan.md}"
21
- exit 0
5
+ if ! . "$(dirname "$0")/../../.doflow/shared/hooks/bridge/bridge.sh" 2>/dev/null; then
6
+ printf '%s\n' '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"[doflow] shared hooks lack the bridge; run: doflow update -t claude"}}'
7
+ exit 0
8
+ fi
9
+ doflow_bridge claude PreToolUse pre-implementation-gate
10
+ exit $?
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env bash
2
- # Claude adapter: reuse the shared session initializer with Claude attribution.
3
- set -euo pipefail
2
+ # Claude front door: session-context through the shared lifecycle bridge.
3
+ set -uo pipefail
4
4
  export DOFLOW_AGENT="${DOFLOW_AGENT:-claude}"
5
- exec bash "$(dirname "$0")/../../.doflow/shared/hooks/policies/session-context.sh"
5
+ if ! . "$(dirname "$0")/../../.doflow/shared/hooks/bridge/bridge.sh" 2>/dev/null; then exit 0; fi
6
+ doflow_bridge claude SessionStart session-context
7
+ exit $?
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env bash
2
- # Claude adapter: reuse the shared stop-completion check with Claude attribution.
3
- set -euo pipefail
2
+ # Claude front door: stop-check through the shared lifecycle bridge.
3
+ set -uo pipefail
4
4
  export DOFLOW_AGENT="${DOFLOW_AGENT:-claude}"
5
- exec bash "$(dirname "$0")/../../.doflow/shared/hooks/policies/stop-check.sh"
5
+ if ! . "$(dirname "$0")/../../.doflow/shared/hooks/bridge/bridge.sh" 2>/dev/null; then exit 0; fi
6
+ doflow_bridge claude Stop stop-check
7
+ exit $?
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bash
2
- # Claude front door: reuse the canonical subagent-audit policy with Claude attribution.
3
- # No JSON-shape translation needed — claude/codex's copies were byte-identical
4
- # (022-hooks-remaining-duplication).
5
- set -euo pipefail
2
+ # Claude front door: subagent-audit through the shared lifecycle bridge.
3
+ set -uo pipefail
6
4
  export DOFLOW_AGENT="${DOFLOW_AGENT:-claude}"
7
- exec bash "$(dirname "$0")/../../.doflow/shared/hooks/policies/subagent-audit.sh"
5
+ if ! . "$(dirname "$0")/../../.doflow/shared/hooks/bridge/bridge.sh" 2>/dev/null; then exit 0; fi
6
+ doflow_bridge claude SubagentStart subagent-audit
7
+ exit $?
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env bash
2
- # Claude front door: reuse the canonical context policy with Claude's output envelope.
3
- set -euo pipefail
2
+ # Claude front door: user-prompt-submit through the shared lifecycle bridge.
3
+ set -uo pipefail
4
4
  export DOFLOW_AGENT="${DOFLOW_AGENT:-claude}"
5
- exec bash "$(dirname "$0")/../../.doflow/shared/hooks/policies/user-prompt-submit.sh"
5
+ if ! . "$(dirname "$0")/../../.doflow/shared/hooks/bridge/bridge.sh" 2>/dev/null; then exit 0; fi
6
+ doflow_bridge claude UserPromptSubmit user-prompt-submit
7
+ exit $?
@@ -1,18 +1,10 @@
1
1
  #!/usr/bin/env bash
2
- # Codex front door: delegates the mcp-tool-guard decision to the Canonical Policy
3
- # Library, then translates it into the hookSpecificOutput.permissionDecision deny
4
- # contract this script's Codex/Claude originals both used — exit code alone is
5
- # not sufficient here, so this front door is a translator, not a bare exec
6
- # (unlike session-context/stop-check, which never need this translation).
2
+ # Codex front door: mcp-tool-guard through the shared lifecycle bridge.
7
3
  set -uo pipefail
8
4
  export DOFLOW_AGENT="${DOFLOW_AGENT:-codex}"
9
-
10
- command -v jq >/dev/null 2>&1 || exit 0
11
- source "$(dirname "$0")/../../.doflow/shared/hooks/policies/deny-json.sh"
12
-
13
- POLICY="$(dirname "$0")/../../.doflow/shared/hooks/policies/mcp-tool-guard.sh"
14
- REASON=$(bash "$POLICY" 2>&1 >/dev/null)
15
- CODE=$?
16
-
17
- [ "$CODE" -ne 0 ] && emit_pretooluse_deny_nested "${REASON:-MCP tool call blocked by mcp-tool-guard}"
18
- exit 0
5
+ if ! . "$(dirname "$0")/../../.doflow/shared/hooks/bridge/bridge.sh" 2>/dev/null; then
6
+ printf '%s\n' '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"[doflow] shared hooks lack the bridge; run: doflow update -t codex"}}'
7
+ exit 0
8
+ fi
9
+ doflow_bridge codex PreToolUse mcp-tool-guard
10
+ exit $?
@@ -1,18 +1,10 @@
1
1
  #!/usr/bin/env bash
2
- # Codex front door: delegates the pre-bash-guard decision to the Canonical Policy
3
- # Library, then translates it into the hookSpecificOutput.permissionDecision deny
4
- # contract this script's Codex/Claude originals both used — exit code alone is
5
- # not sufficient here, so this front door is a translator, not a bare exec
6
- # (unlike session-context/stop-check, which never need this translation).
2
+ # Codex front door: pre-bash-guard through the shared lifecycle bridge.
7
3
  set -uo pipefail
8
4
  export DOFLOW_AGENT="${DOFLOW_AGENT:-codex}"
9
-
10
- command -v jq >/dev/null 2>&1 || exit 0
11
- source "$(dirname "$0")/../../.doflow/shared/hooks/policies/deny-json.sh"
12
-
13
- POLICY="$(dirname "$0")/../../.doflow/shared/hooks/policies/pre-bash-guard.sh"
14
- REASON=$(bash "$POLICY" 2>&1 >/dev/null)
15
- CODE=$?
16
-
17
- [ "$CODE" -ne 0 ] && emit_pretooluse_deny_nested "${REASON:-Command blocked by pre-bash-guard}"
18
- exit 0
5
+ if ! . "$(dirname "$0")/../../.doflow/shared/hooks/bridge/bridge.sh" 2>/dev/null; then
6
+ printf '%s\n' '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"[doflow] shared hooks lack the bridge; run: doflow update -t codex"}}'
7
+ exit 0
8
+ fi
9
+ doflow_bridge codex PreToolUse pre-bash-guard
10
+ exit $?
@@ -1,19 +1,10 @@
1
1
  #!/usr/bin/env bash
2
- # Codex front door: delegates the pre-implementation-gate decision to the
3
- # Canonical Policy Library, then translates it into the
4
- # hookSpecificOutput.permissionDecision deny contract this script's Codex/Claude
5
- # originals both used — exit code alone is not sufficient here, so this front
6
- # door is a translator, not a bare exec (unlike session-context/stop-check,
7
- # which never need this translation).
2
+ # Codex front door: pre-implementation-gate through the shared lifecycle bridge.
8
3
  set -uo pipefail
9
4
  export DOFLOW_AGENT="${DOFLOW_AGENT:-codex}"
10
-
11
- command -v jq >/dev/null 2>&1 || exit 0
12
- source "$(dirname "$0")/../../.doflow/shared/hooks/policies/deny-json.sh"
13
-
14
- POLICY="$(dirname "$0")/../../.doflow/shared/hooks/policies/pre-implementation-gate.sh"
15
- REASON=$(bash "$POLICY" 2>&1 >/dev/null)
16
- CODE=$?
17
-
18
- [ "$CODE" -ne 0 ] && emit_pretooluse_deny_nested "${REASON:-Implementation requires an approved plan.md}"
19
- exit 0
5
+ if ! . "$(dirname "$0")/../../.doflow/shared/hooks/bridge/bridge.sh" 2>/dev/null; then
6
+ printf '%s\n' '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"[doflow] shared hooks lack the bridge; run: doflow update -t codex"}}'
7
+ exit 0
8
+ fi
9
+ doflow_bridge codex PreToolUse pre-implementation-gate
10
+ exit $?
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env bash
2
- # Codex adapter: reuse the canonical session-context policy with Codex attribution.
3
- set -euo pipefail
2
+ # Codex front door: session-context through the shared lifecycle bridge.
3
+ set -uo pipefail
4
4
  export DOFLOW_AGENT="${DOFLOW_AGENT:-codex}"
5
- exec bash "$(dirname "$0")/../../.doflow/shared/hooks/policies/session-context.sh"
5
+ if ! . "$(dirname "$0")/../../.doflow/shared/hooks/bridge/bridge.sh" 2>/dev/null; then exit 0; fi
6
+ doflow_bridge codex SessionStart session-context
7
+ exit $?
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env bash
2
- # Codex adapter: preserve a blocking exit while returning valid Stop JSON on success.
3
- set -euo pipefail
2
+ # Codex front door: stop-check through the shared lifecycle bridge.
3
+ set -uo pipefail
4
4
  export DOFLOW_AGENT="${DOFLOW_AGENT:-codex}"
5
+ if ! . "$(dirname "$0")/../../.doflow/shared/hooks/bridge/bridge.sh" 2>/dev/null; then printf '{}\n'; exit 0; fi
5
6
  rc=0
6
- bash "$(dirname "$0")/../../.doflow/shared/hooks/policies/stop-check.sh" || rc=$?
7
- [ "$rc" -eq 2 ] && exit 2
8
- printf '{}\n'
7
+ output="$(doflow_bridge codex Stop stop-check)" || rc=$?
8
+ if [ "$rc" -eq 0 ]; then printf '%s\n' "$output"; fi
9
+ exit "$rc"
@@ -1,8 +1,19 @@
1
1
  #!/usr/bin/env bash
2
- # Codex front door: reuse the canonical subagent-audit policy with Codex attribution, then emit
3
- # the empty-JSON SubagentStop requires on success (022-hooks-remaining-duplication: claude/codex's
4
- # copies were byte-identical; only this trailing JSON requirement is Codex-specific).
5
- set -euo pipefail
2
+ # Codex front door: subagent-audit through the shared lifecycle bridge.
3
+ set -uo pipefail
6
4
  export DOFLOW_AGENT="${DOFLOW_AGENT:-codex}"
7
- bash "$(dirname "$0")/../../.doflow/shared/hooks/policies/subagent-audit.sh"
8
- printf '{}\n'
5
+ if ! . "$(dirname "$0")/../../.doflow/shared/hooks/bridge/bridge.sh" 2>/dev/null; then exit 0; fi
6
+ payload=$(cat)
7
+ event=$(printf '%s' "$payload" | jq -r '.hook_event_name // "SubagentStart"' 2>/dev/null || printf 'SubagentStart')
8
+ has_jq=1
9
+ command -v jq >/dev/null 2>&1 || has_jq=0
10
+ rc=0
11
+ doflow_bridge codex "$event" subagent-audit <<<"$payload" || rc=$?
12
+ if [ "$has_jq" -eq 0 ]; then
13
+ printf '{}\n'
14
+ exit 0
15
+ fi
16
+ if [ "$rc" -eq 0 ]; then
17
+ case "$DF_BRIDGE_OUTCOME" in allow|advisory) printf '{}\n' ;; esac
18
+ fi
19
+ exit "$rc"
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env bash
2
- # Codex front door: reuse the canonical context policy with the Codex output envelope.
3
- # The shared policy selects Codex's hookSpecificOutput shape from this attribution.
4
- set -euo pipefail
2
+ # Codex front door: user-prompt-submit through the shared lifecycle bridge.
3
+ set -uo pipefail
5
4
  export DOFLOW_AGENT="${DOFLOW_AGENT:-codex}"
6
- exec bash "$(dirname "$0")/../../.doflow/shared/hooks/policies/user-prompt-submit.sh"
5
+ if ! . "$(dirname "$0")/../../.doflow/shared/hooks/bridge/bridge.sh" 2>/dev/null; then exit 0; fi
6
+ doflow_bridge codex UserPromptSubmit user-prompt-submit
7
+ exit $?
@@ -1,21 +1,10 @@
1
1
  #!/usr/bin/env bash
2
- # Gemini front door: delegates the mcp-tool-guard decision to the Canonical
3
- # Policy Library, then translates it into Gemini's verified deny contract.
4
- #
5
- # Gemini's hook output schema (packages/core/src/hooks/types.ts, confirmed this
6
- # session) is a top-level {"decision": "deny", "reason": "..."} — NOT nested
7
- # under hookSpecificOutput.permissionDecision like Claude/Codex. Exit code alone
8
- # is not sufficient here, so this front door is a translator, not a bare exec
9
- # (unlike session-context, which never needs this translation).
2
+ # Gemini front door: mcp-tool-guard through the shared lifecycle bridge.
10
3
  set -uo pipefail
11
4
  export DOFLOW_AGENT="${DOFLOW_AGENT:-gemini}"
12
-
13
- command -v jq >/dev/null 2>&1 || exit 0
14
- source "$(dirname "$0")/../../.doflow/shared/hooks/policies/deny-json.sh"
15
-
16
- POLICY="$(dirname "$0")/../../.doflow/shared/hooks/policies/mcp-tool-guard.sh"
17
- REASON=$(bash "$POLICY" 2>&1 >/dev/null)
18
- CODE=$?
19
-
20
- [ "$CODE" -ne 0 ] && emit_pretooluse_deny_flat "${REASON:-MCP tool call blocked by mcp-tool-guard}"
21
- exit 0
5
+ if ! . "$(dirname "$0")/../../.doflow/shared/hooks/bridge/bridge.sh" 2>/dev/null; then
6
+ printf '%s\n' '{"decision":"deny","reason":"[doflow] shared hooks lack the bridge; run: doflow update -t gemini"}'
7
+ exit 0
8
+ fi
9
+ doflow_bridge gemini BeforeTool mcp-tool-guard
10
+ exit $?
@@ -1,21 +1,10 @@
1
1
  #!/usr/bin/env bash
2
- # Gemini front door: delegates the pre-bash-guard decision to the Canonical
3
- # Policy Library, then translates it into Gemini's verified deny contract.
4
- #
5
- # Gemini's hook output schema (packages/core/src/hooks/types.ts, confirmed this
6
- # session) is a top-level {"decision": "deny", "reason": "..."} — NOT nested
7
- # under hookSpecificOutput.permissionDecision like Claude/Codex. Exit code alone
8
- # is not sufficient here, so this front door is a translator, not a bare exec
9
- # (unlike session-context, which never needs this translation).
2
+ # Gemini front door: pre-bash-guard through the shared lifecycle bridge.
10
3
  set -uo pipefail
11
4
  export DOFLOW_AGENT="${DOFLOW_AGENT:-gemini}"
12
-
13
- command -v jq >/dev/null 2>&1 || exit 0
14
- source "$(dirname "$0")/../../.doflow/shared/hooks/policies/deny-json.sh"
15
-
16
- POLICY="$(dirname "$0")/../../.doflow/shared/hooks/policies/pre-bash-guard.sh"
17
- REASON=$(bash "$POLICY" 2>&1 >/dev/null)
18
- CODE=$?
19
-
20
- [ "$CODE" -ne 0 ] && emit_pretooluse_deny_flat "${REASON:-Command blocked by pre-bash-guard}"
21
- exit 0
5
+ if ! . "$(dirname "$0")/../../.doflow/shared/hooks/bridge/bridge.sh" 2>/dev/null; then
6
+ printf '%s\n' '{"decision":"deny","reason":"[doflow] shared hooks lack the bridge; run: doflow update -t gemini"}'
7
+ exit 0
8
+ fi
9
+ doflow_bridge gemini BeforeTool pre-bash-guard
10
+ exit $?
@@ -1,22 +1,10 @@
1
1
  #!/usr/bin/env bash
2
- # Gemini front door: delegates the pre-implementation-gate decision to the
3
- # Canonical Policy Library, then translates it into Gemini's verified deny
4
- # contract.
5
- #
6
- # Gemini's hook output schema (packages/core/src/hooks/types.ts, confirmed this
7
- # session) is a top-level {"decision": "deny", "reason": "..."} — NOT nested
8
- # under hookSpecificOutput.permissionDecision like Claude/Codex. Exit code alone
9
- # is not sufficient here, so this front door is a translator, not a bare exec
10
- # (unlike session-context, which never needs this translation).
2
+ # Gemini front door: pre-implementation-gate through the shared lifecycle bridge.
11
3
  set -uo pipefail
12
4
  export DOFLOW_AGENT="${DOFLOW_AGENT:-gemini}"
13
-
14
- command -v jq >/dev/null 2>&1 || exit 0
15
- source "$(dirname "$0")/../../.doflow/shared/hooks/policies/deny-json.sh"
16
-
17
- POLICY="$(dirname "$0")/../../.doflow/shared/hooks/policies/pre-implementation-gate.sh"
18
- REASON=$(bash "$POLICY" 2>&1 >/dev/null)
19
- CODE=$?
20
-
21
- [ "$CODE" -ne 0 ] && emit_pretooluse_deny_flat "${REASON:-Implementation requires an approved plan.md}"
22
- exit 0
5
+ if ! . "$(dirname "$0")/../../.doflow/shared/hooks/bridge/bridge.sh" 2>/dev/null; then
6
+ printf '%s\n' '{"decision":"deny","reason":"[doflow] shared hooks lack the bridge; run: doflow update -t gemini"}'
7
+ exit 0
8
+ fi
9
+ doflow_bridge gemini BeforeTool pre-implementation-gate
10
+ exit $?
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env bash
2
- # Gemini adapter: reuse the Canonical Policy Library's session-context policy.
3
- set -euo pipefail
2
+ # Gemini front door: session-context through the shared lifecycle bridge.
3
+ set -uo pipefail
4
4
  export DOFLOW_AGENT="${DOFLOW_AGENT:-gemini}"
5
- exec bash "$(dirname "$0")/../../.doflow/shared/hooks/policies/session-context.sh"
5
+ if ! . "$(dirname "$0")/../../.doflow/shared/hooks/bridge/bridge.sh" 2>/dev/null; then exit 0; fi
6
+ doflow_bridge gemini SessionStart session-context
7
+ exit $?
@@ -1,9 +1,24 @@
1
1
  #!/usr/bin/env bash
2
- # Kiro adapter: reuse the canonical mcp-tool-guard policy with Kiro attribution.
2
+ # Kiro front door: mcp-tool-guard through the shared lifecycle bridge.
3
3
  set -euo pipefail
4
4
  export DOFLOW_AGENT="${DOFLOW_AGENT:-kiro}"
5
+ here="$(dirname "$0")"
5
6
  # shellcheck source=lib.sh
6
- source "$(dirname "$0")/lib.sh"
7
- # Translate Kiro's payload (tool names, KIRO_SESSION_ID, assistant_response) to the canonical one.
8
- payload=$(kiro_bridge_payload)
9
- exec bash "$(dirname "$0")/../../.doflow/shared/hooks/policies/mcp-tool-guard.sh" <<<"$payload"
7
+ source "$here/lib.sh"
8
+ raw=$(cat)
9
+ payload=$(kiro_bridge_payload <<<"$raw")
10
+ event="PreToolUse"
11
+ if command -v jq >/dev/null 2>&1; then event=$(printf '%s' "$raw" | jq -r '.hook_event_name // "PreToolUse"' 2>/dev/null) || event="PreToolUse"; fi
12
+ bridge="$here/../../.doflow/shared/hooks/bridge/bridge.sh"
13
+ if [ ! -f "$bridge" ]; then
14
+ printf '%s\n' '[doflow] shared hooks lack the bridge; run: doflow update -t kiro' >&2
15
+ exit 2
16
+ fi
17
+ . "$bridge" 2>/dev/null || { printf '%s\n' '[doflow] shared hooks lack the bridge; run: doflow update -t kiro' >&2; exit 2; }
18
+ if doflow_bridge kiro "$event" mcp-tool-guard <<<"$payload"; then
19
+ status=0
20
+ else
21
+ status=$?
22
+ fi
23
+ if [ "$status" -eq 2 ]; then printf '\n' >&2; fi
24
+ exit "$status"
@@ -1,9 +1,24 @@
1
1
  #!/usr/bin/env bash
2
- # Kiro adapter: reuse the canonical pre-bash-guard policy with Kiro attribution.
2
+ # Kiro front door: pre-bash-guard through the shared lifecycle bridge.
3
3
  set -euo pipefail
4
4
  export DOFLOW_AGENT="${DOFLOW_AGENT:-kiro}"
5
+ here="$(dirname "$0")"
5
6
  # shellcheck source=lib.sh
6
- source "$(dirname "$0")/lib.sh"
7
- # Translate Kiro's payload (tool names, KIRO_SESSION_ID, assistant_response) to the canonical one.
8
- payload=$(kiro_bridge_payload)
9
- exec bash "$(dirname "$0")/../../.doflow/shared/hooks/policies/pre-bash-guard.sh" <<<"$payload"
7
+ source "$here/lib.sh"
8
+ raw=$(cat)
9
+ payload=$(kiro_bridge_payload <<<"$raw")
10
+ event="PreToolUse"
11
+ if command -v jq >/dev/null 2>&1; then event=$(printf '%s' "$raw" | jq -r '.hook_event_name // "PreToolUse"' 2>/dev/null) || event="PreToolUse"; fi
12
+ bridge="$here/../../.doflow/shared/hooks/bridge/bridge.sh"
13
+ if [ ! -f "$bridge" ]; then
14
+ printf '%s\n' '[doflow] shared hooks lack the bridge; run: doflow update -t kiro' >&2
15
+ exit 2
16
+ fi
17
+ . "$bridge" 2>/dev/null || { printf '%s\n' '[doflow] shared hooks lack the bridge; run: doflow update -t kiro' >&2; exit 2; }
18
+ if doflow_bridge kiro "$event" pre-bash-guard <<<"$payload"; then
19
+ status=0
20
+ else
21
+ status=$?
22
+ fi
23
+ if [ "$status" -eq 2 ]; then printf '\n' >&2; fi
24
+ exit "$status"
@@ -1,9 +1,24 @@
1
1
  #!/usr/bin/env bash
2
- # Kiro adapter: reuse the canonical pre-implementation-gate policy with Kiro attribution.
2
+ # Kiro front door: pre-implementation-gate through the shared lifecycle bridge.
3
3
  set -euo pipefail
4
4
  export DOFLOW_AGENT="${DOFLOW_AGENT:-kiro}"
5
+ here="$(dirname "$0")"
5
6
  # shellcheck source=lib.sh
6
- source "$(dirname "$0")/lib.sh"
7
- # Translate Kiro's payload (tool names, KIRO_SESSION_ID, assistant_response) to the canonical one.
8
- payload=$(kiro_bridge_payload)
9
- exec bash "$(dirname "$0")/../../.doflow/shared/hooks/policies/pre-implementation-gate.sh" <<<"$payload"
7
+ source "$here/lib.sh"
8
+ raw=$(cat)
9
+ payload=$(kiro_bridge_payload <<<"$raw")
10
+ event="PreToolUse"
11
+ if command -v jq >/dev/null 2>&1; then event=$(printf '%s' "$raw" | jq -r '.hook_event_name // "PreToolUse"' 2>/dev/null) || event="PreToolUse"; fi
12
+ bridge="$here/../../.doflow/shared/hooks/bridge/bridge.sh"
13
+ if [ ! -f "$bridge" ]; then
14
+ printf '%s\n' '[doflow] shared hooks lack the bridge; run: doflow update -t kiro' >&2
15
+ exit 2
16
+ fi
17
+ . "$bridge" 2>/dev/null || { printf '%s\n' '[doflow] shared hooks lack the bridge; run: doflow update -t kiro' >&2; exit 2; }
18
+ if doflow_bridge kiro "$event" pre-implementation-gate <<<"$payload"; then
19
+ status=0
20
+ else
21
+ status=$?
22
+ fi
23
+ if [ "$status" -eq 2 ]; then printf '\n' >&2; fi
24
+ exit "$status"
@@ -1,9 +1,15 @@
1
1
  #!/usr/bin/env bash
2
- # Kiro adapter: reuse the canonical session-context policy with Kiro attribution.
2
+ # Kiro front door: session-context through the shared lifecycle bridge.
3
3
  set -euo pipefail
4
4
  export DOFLOW_AGENT="${DOFLOW_AGENT:-kiro}"
5
+ here="$(dirname "$0")"
5
6
  # shellcheck source=lib.sh
6
- source "$(dirname "$0")/lib.sh"
7
- # Translate Kiro's payload (tool names, KIRO_SESSION_ID, assistant_response) to the canonical one.
8
- payload=$(kiro_bridge_payload)
9
- exec bash "$(dirname "$0")/../../.doflow/shared/hooks/policies/session-context.sh" <<<"$payload"
7
+ source "$here/lib.sh"
8
+ raw=$(cat)
9
+ payload=$(kiro_bridge_payload <<<"$raw")
10
+ event="SessionStart"
11
+ if command -v jq >/dev/null 2>&1; then event=$(printf '%s' "$raw" | jq -r '.hook_event_name // "SessionStart"' 2>/dev/null) || event="SessionStart"; fi
12
+ bridge="$here/../../.doflow/shared/hooks/bridge/bridge.sh"
13
+ if [ ! -f "$bridge" ]; then exit 0; fi
14
+ . "$bridge" 2>/dev/null || exit 0
15
+ doflow_bridge kiro "$event" session-context <<<"$payload"
@@ -1,43 +1,34 @@
1
1
  #!/usr/bin/env bash
2
- # Kiro adapter: run the canonical stop-check policy and translate its verdict to the Kiro engine.
3
- #
4
- # The policy exits 2 to deny the stop. Kiro engines read a Stop hook differently:
5
- # - Kiro CLI V3 / IDE (payload carries session_id): exit 0 finishes the turn; exit 0 with stdout
6
- # JSON {"decision":"block","reason":"..."} starts another turn with that reason; exit 1 also
7
- # starts another turn; other codes finish without forwarding output. Exit 2 does NOT block.
8
- # So a policy deny becomes the JSON block on stdout with exit 0.
9
- # - Kiro CLI 2.x (payload has no session_id): exit 0 succeeded, any other code shows stderr to the
10
- # user as a warning. A policy deny is passed through as stderr with exit 2.
11
- # Every other policy outcome exits 0, never 1: V3 treats exit 1 as "continue another turn".
12
- # The policy blocks a given message once, so the continuation turn is not blocked again.
13
- # Docs: https://kiro.dev/docs/hooks/types/ , https://kiro.dev/docs/cli/v3/hooks-migration/
2
+ # Kiro Stop front door: translate the native payload, then render the bridge verdict for its engine.
14
3
  set -uo pipefail
15
4
  export DOFLOW_AGENT="${DOFLOW_AGENT:-kiro}"
16
5
  here="$(dirname "$0")"
17
6
  # shellcheck source=lib.sh
18
7
  source "$here/lib.sh"
19
- set +e # lib.sh enables errexit; the policy exit code is handled explicitly below
20
-
21
8
  raw=$(cat)
22
- # Translate Kiro's payload (tool names, KIRO_SESSION_ID, assistant_response) to the canonical one.
23
9
  payload=$(kiro_bridge_payload <<<"$raw")
24
-
25
- # V3 and the IDE send session_id in the payload; 2.x does not (the bridge injects it from the env).
26
10
  raw_sid=""
11
+ event="Stop"
27
12
  if command -v jq >/dev/null 2>&1; then
28
13
  raw_sid=$(printf '%s' "$raw" | jq -r '.session_id // empty' 2>/dev/null) || raw_sid=""
14
+ event=$(printf '%s' "$raw" | jq -r '.hook_event_name // "Stop"' 2>/dev/null) || event="Stop"
29
15
  fi
30
-
31
- # Capture the policy's stderr (stdout discarded) and its exit code without a temp file.
32
- errtext=$(bash "$here/../../.doflow/shared/hooks/policies/stop-check.sh" <<<"$payload" 2>&1 >/dev/null)
33
- rc=$?
34
-
35
- if [ "$rc" -eq 2 ]; then
36
- if [ -n "$raw_sid" ] && command -v jq >/dev/null 2>&1; then
37
- jq -n --arg reason "$errtext" '{decision: "block", reason: $reason}'
38
- exit 0
39
- fi
40
- printf '%s\n' "$errtext" >&2
41
- exit 2
16
+ if [ -n "$raw_sid" ]; then
17
+ export DOFLOW_KIRO_ENGINE=v3
18
+ else
19
+ export DOFLOW_KIRO_ENGINE=2x
42
20
  fi
43
- exit 0
21
+ bridge="$here/../../.doflow/shared/hooks/bridge/bridge.sh"
22
+ if [ ! -f "$bridge" ]; then exit 0; fi
23
+ . "$bridge" 2>/dev/null || exit 0
24
+ exec 4>&1
25
+ if bridge_stderr=$(doflow_bridge kiro "$event" stop-check <<<"$payload" 2>&1 1>&4); then
26
+ status=0
27
+ else
28
+ status=$?
29
+ fi
30
+ exec 4>&-
31
+ if [ "$status" -eq 2 ] && [ "$DOFLOW_KIRO_ENGINE" = 2x ]; then
32
+ printf '%s\n' "$bridge_stderr" >&2
33
+ fi
34
+ exit "$status"