openhermes 4.12.1 → 4.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/CONTEXT.md +6 -6
  2. package/ETHOS.md +2 -2
  3. package/README.md +11 -17
  4. package/bootstrap.ts +118 -126
  5. package/docs/HOW-IT-WORKS.md +162 -0
  6. package/docs/adr/ADR-0001-rebuild-vs-increment.md +30 -0
  7. package/docs/adr/ADR-0002-routing-graph-vs-linear-chain.md +36 -0
  8. package/docs/adr/ADR-0003-per-directory-plan-storage.md +34 -0
  9. package/docs/adr/ADR-0004-composer-fragment-architecture.md +42 -0
  10. package/docs/adr/ADR-0005-hook-system-design.md +42 -0
  11. package/docs/adr/README.md +9 -0
  12. package/harness/codex/AUTOPILOT.md +35 -40
  13. package/harness/codex/CHARTER.md +3 -3
  14. package/harness/lib/composer/compose.test.ts +29 -29
  15. package/harness/lib/composer/fragments/02-delegation.md +5 -5
  16. package/harness/lib/composer/fragments/04-task-flow.md +13 -13
  17. package/harness/lib/composer/fragments/08-routing.md +1 -1
  18. package/harness/lib/composer/fragments/09-guardrails.md +25 -25
  19. package/harness/lib/composer/index.ts +1 -1
  20. package/harness/lib/guards/guard-config.ts +72 -72
  21. package/harness/lib/hooks/builtins/confidence-gate-hook.ts +9 -9
  22. package/harness/lib/hooks/builtins/delegation-depth-hook.ts +1 -1
  23. package/harness/lib/hooks/builtins/dynamic-route-hook.ts +99 -99
  24. package/harness/lib/hooks/builtins/next-route-hook.ts +24 -24
  25. package/harness/lib/hooks/builtins/plan-check-hook.ts +5 -5
  26. package/harness/lib/hooks/builtins/route-tracking-hook.ts +1 -1
  27. package/harness/lib/hooks/hooks.test.ts +160 -324
  28. package/harness/lib/hooks/index.ts +38 -42
  29. package/harness/lib/hooks/registry.ts +309 -416
  30. package/harness/lib/hooks/types.ts +116 -119
  31. package/harness/lib/plans/plan-location.ts +134 -134
  32. package/harness/lib/routing/index.ts +21 -21
  33. package/harness/lib/routing/route-guidance.ts +147 -147
  34. package/harness/lib/routing/route-resolver.ts +58 -58
  35. package/harness/lib/routing/routing.test.ts +195 -195
  36. package/harness/lib/routing/skill-frontmatter.ts +125 -125
  37. package/harness/lib/routing/types.ts +52 -52
  38. package/harness/skills/oh-ascii/SKILL.md +1 -1
  39. package/harness/skills/oh-fusion/DEEP.md +109 -109
  40. package/harness/skills/oh-fusion/SKILL.md +47 -47
  41. package/harness/skills/oh-init/DEEP.md +2 -2
  42. package/harness/skills/oh-plan-review/DEEP.md +1 -1
  43. package/harness/skills/oh-planner/DEEP.md +3 -3
  44. package/harness/skills/oh-review/DEEP.md +5 -5
  45. package/package.json +56 -53
  46. package/harness/lib/background/background.test.ts +0 -216
  47. package/harness/lib/background/index.ts +0 -7
  48. package/harness/lib/background/interfaces.ts +0 -31
  49. package/harness/lib/background/manager.ts +0 -320
  50. package/harness/lib/hooks/builtins/error-recovery-hook.ts +0 -107
  51. package/harness/lib/hooks/builtins/memory-sync-hook.ts +0 -73
  52. package/harness/lib/hooks/builtins/sanity-check-hook.ts +0 -52
  53. package/harness/lib/hooks/builtins/subagent-failure-hook.ts +0 -93
  54. package/harness/lib/memory/index.ts +0 -18
  55. package/harness/lib/memory/interfaces.ts +0 -53
  56. package/harness/lib/memory/memory-manager.ts +0 -205
  57. package/harness/lib/memory/memory.test.ts +0 -485
  58. package/harness/lib/memory/plan-store.ts +0 -346
  59. package/harness/lib/recovery/handler.ts +0 -243
  60. package/harness/lib/recovery/index.ts +0 -14
  61. package/harness/lib/recovery/interfaces.ts +0 -48
  62. package/harness/lib/recovery/patterns.ts +0 -149
  63. package/harness/lib/recovery/recovery.test.ts +0 -312
  64. package/harness/lib/sanity/anomaly-tracker.ts +0 -127
  65. package/harness/lib/sanity/checker.ts +0 -189
  66. package/harness/lib/sanity/index.ts +0 -13
  67. package/harness/lib/sanity/interfaces.ts +0 -24
  68. package/harness/lib/sanity/sanity.test.ts +0 -472
  69. package/harness/lib/sync/file-watcher.ts +0 -175
  70. package/harness/lib/sync/index.ts +0 -11
  71. package/harness/lib/sync/interfaces.ts +0 -27
  72. package/harness/lib/sync/plan-sync.ts +0 -533
  73. package/harness/lib/sync/sync.test.ts +0 -858
@@ -1,72 +1,72 @@
1
- // ---------------------------------------------------------------------------
2
- // GuardConfig — centralized configuration for all loop/safety guards
3
- // ---------------------------------------------------------------------------
4
-
5
- export interface GuardConfig {
6
- /** Max times the same skill can repeat in one chain before STOP */
7
- maxSkillRepeats: number
8
- /** Max consecutive unproductive hops before STOP (0 = disabled) */
9
- maxUnproductiveHops: number
10
- /** Max delegation (sub-agent) depth before STOP */
11
- maxDelegationDepth: number
12
- /** Consecutive anomalies before recovery escalation */
13
- maxConsecutiveAnomalies: number
14
- /** Max subagent failures on same task before BLOCKER */
15
- maxSubagentFailures: number
16
- /** Enable progressive warning at thresholds before hard stop */
17
- progressiveGuards: boolean
18
- /** Ratio of limit at which to warn (e.g. 0.6 = 60%) */
19
- progressiveWarnThreshold: number
20
- /** Ratio of limit at which to escalate (e.g. 0.8 = 80%) */
21
- progressiveEscalateThreshold: number
22
- }
23
-
24
- export const DEFAULT_GUARD_CONFIG: GuardConfig = {
25
- maxSkillRepeats: 5,
26
- maxUnproductiveHops: 8,
27
- maxDelegationDepth: 25,
28
- maxConsecutiveAnomalies: 2,
29
- maxSubagentFailures: 5,
30
- progressiveGuards: true,
31
- progressiveWarnThreshold: 0.6,
32
- progressiveEscalateThreshold: 0.8,
33
- }
34
-
35
- export type GuardLevel = "ok" | "warn" | "escalate" | "stop"
36
-
37
- export interface GuardProgression {
38
- level: GuardLevel
39
- current: number
40
- limit: number
41
- /**
42
- * If progressive guards are disabled: stop at limit, ok otherwise.
43
- * If enabled: ok < warn% < escalate% < stop.
44
- */
45
- }
46
-
47
- export function checkGuardProgression(
48
- current: number,
49
- limit: number,
50
- config: GuardConfig,
51
- ): GuardProgression {
52
- if (!config.progressiveGuards || limit <= 0) {
53
- return {
54
- level: current >= limit ? "stop" as GuardLevel : "ok" as GuardLevel,
55
- current,
56
- limit,
57
- }
58
- }
59
- if (current >= limit) return { level: "stop", current, limit }
60
- if (current / limit >= config.progressiveEscalateThreshold) return { level: "escalate" as GuardLevel, current, limit }
61
- if (current / limit >= config.progressiveWarnThreshold) return { level: "warn" as GuardLevel, current, limit }
62
- return { level: "ok" as GuardLevel, current, limit }
63
- }
64
-
65
- /**
66
- * Merge partial user config(s) with defaults.
67
- * Priority: defaults → earlier args → later args (last wins).
68
- * Supports single-arg calls and multi-override chains.
69
- */
70
- export function mergeGuardConfig(...overrides: Array<Partial<GuardConfig> | undefined>): GuardConfig {
71
- return Object.assign({}, DEFAULT_GUARD_CONFIG, ...overrides.filter(Boolean));
72
- }
1
+ // ---------------------------------------------------------------------------
2
+ // GuardConfig — centralized configuration for all loop/safety guards
3
+ // ---------------------------------------------------------------------------
4
+
5
+ export interface GuardConfig {
6
+ /** Max times the same skill can repeat in one chain before STOP */
7
+ maxSkillRepeats: number
8
+ /** Max consecutive unproductive hops before STOP (0 = disabled) */
9
+ maxUnproductiveHops: number
10
+ /** Max delegation (sub-agent) depth before STOP */
11
+ maxDelegationDepth: number
12
+ /** Consecutive anomalies before guard escalation */
13
+ maxConsecutiveAnomalies: number
14
+ /** Max subagent failures on same task before BLOCKER */
15
+ maxSubagentFailures: number
16
+ /** Enable progressive warning at thresholds before hard stop */
17
+ progressiveGuards: boolean
18
+ /** Ratio of limit at which to warn (e.g. 0.6 = 60%) */
19
+ progressiveWarnThreshold: number
20
+ /** Ratio of limit at which to escalate (e.g. 0.8 = 80%) */
21
+ progressiveEscalateThreshold: number
22
+ }
23
+
24
+ export const DEFAULT_GUARD_CONFIG: GuardConfig = {
25
+ maxSkillRepeats: 5,
26
+ maxUnproductiveHops: 8,
27
+ maxDelegationDepth: 25,
28
+ maxConsecutiveAnomalies: 2,
29
+ maxSubagentFailures: 5,
30
+ progressiveGuards: true,
31
+ progressiveWarnThreshold: 0.6,
32
+ progressiveEscalateThreshold: 0.8,
33
+ }
34
+
35
+ export type GuardLevel = "ok" | "warn" | "escalate" | "stop"
36
+
37
+ export interface GuardProgression {
38
+ level: GuardLevel
39
+ current: number
40
+ limit: number
41
+ /**
42
+ * If progressive guards are disabled: stop at limit, ok otherwise.
43
+ * If enabled: ok < warn% < escalate% < stop.
44
+ */
45
+ }
46
+
47
+ export function checkGuardProgression(
48
+ current: number,
49
+ limit: number,
50
+ config: GuardConfig,
51
+ ): GuardProgression {
52
+ if (!config.progressiveGuards || limit <= 0) {
53
+ return {
54
+ level: current >= limit ? "stop" as GuardLevel : "ok" as GuardLevel,
55
+ current,
56
+ limit,
57
+ }
58
+ }
59
+ if (current >= limit) return { level: "stop", current, limit }
60
+ if (current / limit >= config.progressiveEscalateThreshold) return { level: "escalate" as GuardLevel, current, limit }
61
+ if (current / limit >= config.progressiveWarnThreshold) return { level: "warn" as GuardLevel, current, limit }
62
+ return { level: "ok" as GuardLevel, current, limit }
63
+ }
64
+
65
+ /**
66
+ * Merge partial user config(s) with defaults.
67
+ * Priority: defaults → earlier args → later args (last wins).
68
+ * Supports single-arg calls and multi-override chains.
69
+ */
70
+ export function mergeGuardConfig(...overrides: Array<Partial<GuardConfig> | undefined>): GuardConfig {
71
+ return Object.assign({}, DEFAULT_GUARD_CONFIG, ...overrides.filter(Boolean));
72
+ }
@@ -23,21 +23,21 @@ export const confidenceGateHook: RouteHook = {
23
23
  errorHandling: "isolate",
24
24
  },
25
25
 
26
- async execute(context: HookContext, route: string) {
27
- // Read confidence state from context if available
28
- const confidenceLevel = context._confidenceLevel;
26
+ async execute(context: HookContext, route: string) {
27
+ // Read confidence state from context if available
28
+ const confidenceLevel = context._confidenceLevel;
29
29
 
30
30
  if (!confidenceLevel) {
31
31
  // No confidence gate info — pass through unchanged
32
32
  return { result: HookResult.CONTINUE, modifiedRoute: route };
33
33
  }
34
34
 
35
- // Store the confidence assessment for routing decisions
36
- const state: ConfidenceGateState = {
37
- level: confidenceLevel as ConfidenceGateState["level"],
38
- exchanges: context._confidenceExchanges ?? 0,
39
- lastAction: "assessed",
40
- };
35
+ // Store the confidence assessment for routing decisions
36
+ const state: ConfidenceGateState = {
37
+ level: confidenceLevel as ConfidenceGateState["level"],
38
+ exchanges: context._confidenceExchanges ?? 0,
39
+ lastAction: "assessed",
40
+ };
41
41
 
42
42
  // HIGH confidence: proceed without modification
43
43
  if (state.level === "HIGH") {
@@ -75,4 +75,4 @@ export const delegationDepthHook: PreToolUseHook = {
75
75
  },
76
76
  };
77
77
  },
78
- };
78
+ };
@@ -1,99 +1,99 @@
1
- import path from "node:path";
2
- import { HookPhase, HookResult } from "../types.ts";
3
- import type { HookContext, PostToolUseHook } from "../types.ts";
4
- import { readSkillFrontmatter, resolveRoute } from "../../routing/index.ts";
5
- import type { RouteEvidence } from "../../routing/index.ts";
6
- import { ROUTE_GUIDANCE_PREFIX } from "../../routing/index.ts";
7
- import {
8
- ROUTE_ACTIONS,
9
- ROUTE_OUTCOMES,
10
- ROUTE_VERIFICATIONS,
11
- ROUTE_WORK_TYPES,
12
- } from "../../routing/types.ts";
13
-
14
- const ROUTE_EVIDENCE_PREFIX = "ROUTE_EVIDENCE:";
15
-
16
- function isRouteOutcome(value: unknown): value is RouteEvidence["outcome"] {
17
- return typeof value === "string" && ROUTE_OUTCOMES.includes(value as RouteEvidence["outcome"]);
18
- }
19
-
20
- function isRouteVerification(value: unknown): value is NonNullable<RouteEvidence["verification"]> {
21
- return typeof value === "string" && ROUTE_VERIFICATIONS.includes(value as NonNullable<RouteEvidence["verification"]>);
22
- }
23
-
24
- function isRouteAction(value: unknown): value is NonNullable<RouteEvidence["action"]> {
25
- return typeof value === "string" && ROUTE_ACTIONS.includes(value as NonNullable<RouteEvidence["action"]>);
26
- }
27
-
28
- function isRouteWork(value: unknown): value is NonNullable<RouteEvidence["work"]> {
29
- return typeof value === "string" && ROUTE_WORK_TYPES.includes(value as NonNullable<RouteEvidence["work"]>);
30
- }
31
-
32
- function parseRouteEvidence(output: string): RouteEvidence | null {
33
- const evidenceLine = output
34
- .split(/\r?\n/)
35
- .map((line) => line.trim())
36
- .find((line) => line.startsWith(ROUTE_EVIDENCE_PREFIX));
37
-
38
- if (!evidenceLine) return null;
39
-
40
- const raw = evidenceLine.slice(ROUTE_EVIDENCE_PREFIX.length).trim();
41
- if (!raw) return null;
42
-
43
- try {
44
- const parsed = JSON.parse(raw) as Partial<RouteEvidence>;
45
- if (!isRouteOutcome(parsed.outcome)) return null;
46
- if (parsed.verification !== undefined && !isRouteVerification(parsed.verification)) return null;
47
- if (parsed.action !== undefined && !isRouteAction(parsed.action)) return null;
48
- if (parsed.work !== undefined && !isRouteWork(parsed.work)) return null;
49
- if (parsed.target !== undefined && typeof parsed.target !== "string") return null;
50
- if (parsed.reason !== undefined && typeof parsed.reason !== "string") return null;
51
-
52
- return {
53
- outcome: parsed.outcome,
54
- ...(parsed.verification ? { verification: parsed.verification } : {}),
55
- ...(parsed.action ? { action: parsed.action } : {}),
56
- ...(parsed.work ? { work: parsed.work } : {}),
57
- ...(parsed.target ? { target: parsed.target } : {}),
58
- ...(parsed.reason ? { reason: parsed.reason } : {}),
59
- };
60
- } catch {
61
- return null;
62
- }
63
- }
64
-
65
- export const dynamicRouteHook: PostToolUseHook = {
66
- metadata: {
67
- name: "dynamic-route",
68
- priority: 20,
69
- phase: HookPhase.LATE,
70
- dependencies: [],
71
- errorHandling: "isolate",
72
- },
73
-
74
- async execute(context: HookContext, output: string) {
75
- const evidence = parseRouteEvidence(output);
76
- const skillsDir = typeof context._routingSkillsDir === "string" ? context._routingSkillsDir : undefined;
77
-
78
- if (!evidence || !skillsDir || !context.agent) {
79
- return { result: HookResult.CONTINUE };
80
- }
81
-
82
- const skillFilePath = path.join(skillsDir, context.agent, "SKILL.md");
83
- const frontmatter = readSkillFrontmatter(skillFilePath);
84
- if (!frontmatter) {
85
- return { result: HookResult.CONTINUE };
86
- }
87
-
88
- const resolution = resolveRoute(frontmatter.route, evidence);
89
- const guidance = `${ROUTE_GUIDANCE_PREFIX} ${JSON.stringify(resolution)}`;
90
- const modifiedOutput = output.includes(ROUTE_GUIDANCE_PREFIX)
91
- ? output
92
- : `${output.trimEnd()}\n${guidance}`.trim();
93
-
94
- return {
95
- result: HookResult.INJECT,
96
- modifiedOutput,
97
- };
98
- },
99
- };
1
+ import path from "node:path";
2
+ import { HookPhase, HookResult } from "../types.ts";
3
+ import type { HookContext, PostToolUseHook } from "../types.ts";
4
+ import { readSkillFrontmatter, resolveRoute } from "../../routing/index.ts";
5
+ import type { RouteEvidence } from "../../routing/index.ts";
6
+ import { ROUTE_GUIDANCE_PREFIX } from "../../routing/index.ts";
7
+ import {
8
+ ROUTE_ACTIONS,
9
+ ROUTE_OUTCOMES,
10
+ ROUTE_VERIFICATIONS,
11
+ ROUTE_WORK_TYPES,
12
+ } from "../../routing/types.ts";
13
+
14
+ const ROUTE_EVIDENCE_PREFIX = "ROUTE_EVIDENCE:";
15
+
16
+ function isRouteOutcome(value: unknown): value is RouteEvidence["outcome"] {
17
+ return typeof value === "string" && ROUTE_OUTCOMES.includes(value as RouteEvidence["outcome"]);
18
+ }
19
+
20
+ function isRouteVerification(value: unknown): value is NonNullable<RouteEvidence["verification"]> {
21
+ return typeof value === "string" && ROUTE_VERIFICATIONS.includes(value as NonNullable<RouteEvidence["verification"]>);
22
+ }
23
+
24
+ function isRouteAction(value: unknown): value is NonNullable<RouteEvidence["action"]> {
25
+ return typeof value === "string" && ROUTE_ACTIONS.includes(value as NonNullable<RouteEvidence["action"]>);
26
+ }
27
+
28
+ function isRouteWork(value: unknown): value is NonNullable<RouteEvidence["work"]> {
29
+ return typeof value === "string" && ROUTE_WORK_TYPES.includes(value as NonNullable<RouteEvidence["work"]>);
30
+ }
31
+
32
+ function parseRouteEvidence(output: string): RouteEvidence | null {
33
+ const evidenceLine = output
34
+ .split(/\r?\n/)
35
+ .map((line) => line.trim())
36
+ .find((line) => line.startsWith(ROUTE_EVIDENCE_PREFIX));
37
+
38
+ if (!evidenceLine) return null;
39
+
40
+ const raw = evidenceLine.slice(ROUTE_EVIDENCE_PREFIX.length).trim();
41
+ if (!raw) return null;
42
+
43
+ try {
44
+ const parsed = JSON.parse(raw) as Partial<RouteEvidence>;
45
+ if (!isRouteOutcome(parsed.outcome)) return null;
46
+ if (parsed.verification !== undefined && !isRouteVerification(parsed.verification)) return null;
47
+ if (parsed.action !== undefined && !isRouteAction(parsed.action)) return null;
48
+ if (parsed.work !== undefined && !isRouteWork(parsed.work)) return null;
49
+ if (parsed.target !== undefined && typeof parsed.target !== "string") return null;
50
+ if (parsed.reason !== undefined && typeof parsed.reason !== "string") return null;
51
+
52
+ return {
53
+ outcome: parsed.outcome,
54
+ ...(parsed.verification ? { verification: parsed.verification } : {}),
55
+ ...(parsed.action ? { action: parsed.action } : {}),
56
+ ...(parsed.work ? { work: parsed.work } : {}),
57
+ ...(parsed.target ? { target: parsed.target } : {}),
58
+ ...(parsed.reason ? { reason: parsed.reason } : {}),
59
+ };
60
+ } catch {
61
+ return null;
62
+ }
63
+ }
64
+
65
+ export const dynamicRouteHook: PostToolUseHook = {
66
+ metadata: {
67
+ name: "dynamic-route",
68
+ priority: 20,
69
+ phase: HookPhase.LATE,
70
+ dependencies: [],
71
+ errorHandling: "isolate",
72
+ },
73
+
74
+ async execute(context: HookContext, output: string) {
75
+ const evidence = parseRouteEvidence(output);
76
+ const skillsDir = typeof context._routingSkillsDir === "string" ? context._routingSkillsDir : undefined;
77
+
78
+ if (!evidence || !skillsDir || !context.agent) {
79
+ return { result: HookResult.CONTINUE };
80
+ }
81
+
82
+ const skillFilePath = path.join(skillsDir, context.agent, "SKILL.md");
83
+ const frontmatter = readSkillFrontmatter(skillFilePath);
84
+ if (!frontmatter) {
85
+ return { result: HookResult.CONTINUE };
86
+ }
87
+
88
+ const resolution = resolveRoute(frontmatter.route, evidence);
89
+ const guidance = `${ROUTE_GUIDANCE_PREFIX} ${JSON.stringify(resolution)}`;
90
+ const modifiedOutput = output.includes(ROUTE_GUIDANCE_PREFIX)
91
+ ? output
92
+ : `${output.trimEnd()}\n${guidance}`.trim();
93
+
94
+ return {
95
+ result: HookResult.INJECT,
96
+ modifiedOutput,
97
+ };
98
+ },
99
+ };
@@ -1,24 +1,24 @@
1
- import { HookPhase, HookResult } from "../types.ts";
2
- import type { HookContext, RouteHook } from "../types.ts";
3
-
4
- export const nextRouteHook: RouteHook = {
5
- metadata: {
6
- name: "next-route",
7
- priority: 90,
8
- phase: HookPhase.EARLY,
9
- dependencies: [],
10
- errorHandling: "isolate",
11
- },
12
-
13
- async execute(context: HookContext, route: string) {
14
- const nextRoute = context._nextRoute?.selected;
15
- if (!nextRoute || nextRoute === route) {
16
- return { result: HookResult.CONTINUE, modifiedRoute: route };
17
- }
18
-
19
- return {
20
- result: HookResult.CONTINUE,
21
- modifiedRoute: nextRoute,
22
- };
23
- },
24
- };
1
+ import { HookPhase, HookResult } from "../types.ts";
2
+ import type { HookContext, RouteHook } from "../types.ts";
3
+
4
+ export const nextRouteHook: RouteHook = {
5
+ metadata: {
6
+ name: "next-route",
7
+ priority: 90,
8
+ phase: HookPhase.EARLY,
9
+ dependencies: [],
10
+ errorHandling: "isolate",
11
+ },
12
+
13
+ async execute(context: HookContext, route: string) {
14
+ const nextRoute = context._nextRoute?.selected;
15
+ if (!nextRoute || nextRoute === route) {
16
+ return { result: HookResult.CONTINUE, modifiedRoute: route };
17
+ }
18
+
19
+ return {
20
+ result: HookResult.CONTINUE,
21
+ modifiedRoute: nextRoute,
22
+ };
23
+ },
24
+ };
@@ -5,9 +5,9 @@
5
5
  // If missing, inject "create plan first" instruction.
6
6
  // ---------------------------------------------------------------------------
7
7
 
8
- import { HookPhase, HookResult } from "../types.ts";
9
- import type { HookContext, PreToolUseHook } from "../types.ts";
10
- import { resolvePlanAccess } from "../../plans/plan-location.ts";
8
+ import { HookPhase, HookResult } from "../types.ts";
9
+ import type { HookContext, PreToolUseHook } from "../types.ts";
10
+ import { resolvePlanAccess } from "../../plans/plan-location.ts";
11
11
 
12
12
  export const planCheckHook: PreToolUseHook = {
13
13
  metadata: {
@@ -18,8 +18,8 @@ export const planCheckHook: PreToolUseHook = {
18
18
  errorHandling: "propagate",
19
19
  },
20
20
 
21
- async execute(context: HookContext) {
22
- const planFile = resolvePlanAccess(context.directory)?.path ?? null;
21
+ async execute(context: HookContext) {
22
+ const planFile = resolvePlanAccess(context.directory)?.path ?? null;
23
23
 
24
24
  if (!planFile) {
25
25
  return {
@@ -198,4 +198,4 @@ export const routeTrackingHook: RouteHook = {
198
198
 
199
199
  return { result: HookResult.CONTINUE, modifiedRoute: route };
200
200
  },
201
- };
201
+ };