opencode-matrixx 2.6.10 → 2.6.12

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 (132) hide show
  1. package/README.md +6 -5
  2. package/dist/agents/architect/default.d.ts +1 -1
  3. package/dist/agents/architect/gpt.d.ts +1 -1
  4. package/dist/agents/dynamic-agent-prompt-builder.d.ts +6 -5
  5. package/dist/agents/oracle/plan-template.d.ts +1 -7
  6. package/dist/agents/oracle/system-prompt.d.ts +1 -1
  7. package/dist/cli.js +29 -86
  8. package/dist/config/schema/agent-overrides.d.ts +126 -126
  9. package/dist/config/schema/commands.d.ts +0 -5
  10. package/dist/config/schema/dcp.d.ts +3 -3
  11. package/dist/config/schema/hooks.d.ts +3 -2
  12. package/dist/config/schema/internal/permission.d.ts +8 -8
  13. package/dist/config/schema/knowledge.d.ts +34 -0
  14. package/dist/config/schema/matrixx-config.d.ts +145 -132
  15. package/dist/config/schema/tool-gating.d.ts +9 -0
  16. package/dist/config/schema.d.ts +2 -1
  17. package/dist/create-hooks.d.ts +3 -2
  18. package/dist/features/background-agent/manager.d.ts +19 -0
  19. package/dist/features/bdd/schema.d.ts +5 -5
  20. package/dist/features/builtin-commands/templates/evolution.d.ts +1 -1
  21. package/dist/features/builtin-commands/templates/start-work.d.ts +1 -1
  22. package/dist/features/builtin-commands/types.d.ts +1 -1
  23. package/dist/features/evolution/compressor/index.d.ts +2 -2
  24. package/dist/features/evolution/compressor/interface.d.ts +9 -4
  25. package/dist/features/evolution/compressor/llm.d.ts +14 -4
  26. package/dist/features/evolution/evaluator.d.ts +10 -0
  27. package/dist/features/evolution/pipeline.d.ts +3 -1
  28. package/dist/features/evolution/schema.d.ts +46 -0
  29. package/dist/features/evolution/store/budget-ledger.d.ts +46 -0
  30. package/dist/features/evolution/store/index.d.ts +5 -0
  31. package/dist/features/evolution/store/lifecycle.d.ts +52 -0
  32. package/dist/features/evolution/store/project-identity.d.ts +27 -0
  33. package/dist/features/evolution/store/query.d.ts +23 -0
  34. package/dist/features/evolution/{store.d.ts → store/trace-store.d.ts} +1 -1
  35. package/dist/features/evolution/types.d.ts +34 -1
  36. package/dist/features/evolution/writer-emit.d.ts +17 -0
  37. package/dist/features/evolution/writer-frontmatter.d.ts +23 -0
  38. package/dist/features/evolution/writer-supersede.d.ts +20 -0
  39. package/dist/features/evolution/writer.d.ts +4 -0
  40. package/dist/features/knowledge-hub/index.d.ts +3 -0
  41. package/dist/features/knowledge-hub/loader.d.ts +11 -0
  42. package/dist/features/knowledge-hub/resolver.d.ts +2 -0
  43. package/dist/features/mission-state/constants.d.ts +20 -0
  44. package/dist/features/mission-state/index.d.ts +1 -0
  45. package/dist/features/mission-state/plan-storage.d.ts +32 -6
  46. package/dist/features/mission-state/reconcile.d.ts +75 -0
  47. package/dist/features/mission-state/reconcile.test.d.ts +1 -0
  48. package/dist/features/mission-state/storage.d.ts +26 -0
  49. package/dist/features/mission-state/types.d.ts +6 -0
  50. package/dist/features/plan-contract/appendix.d.ts +14 -0
  51. package/dist/features/plan-contract/constants.d.ts +16 -0
  52. package/dist/features/plan-contract/front-matter.d.ts +34 -0
  53. package/dist/features/plan-contract/index.d.ts +14 -0
  54. package/dist/features/plan-contract/migration.d.ts +36 -0
  55. package/dist/features/plan-contract/schema.d.ts +32 -0
  56. package/dist/features/plan-contract/skeleton.d.ts +5 -0
  57. package/dist/features/plan-contract/types.d.ts +56 -0
  58. package/dist/features/plan-contract/validate.d.ts +9 -0
  59. package/dist/features/session-state/state.d.ts +0 -11
  60. package/dist/hooks/auto-slash-command/executor.d.ts +11 -3
  61. package/dist/hooks/auto-slash-command/hook.d.ts +0 -2
  62. package/dist/hooks/evolution-compressor/host-llm-call.d.ts +17 -0
  63. package/dist/hooks/index.d.ts +3 -2
  64. package/dist/hooks/knowledge-hub-guard/approvals.d.ts +5 -0
  65. package/dist/hooks/knowledge-hub-guard/hook.d.ts +15 -0
  66. package/dist/hooks/knowledge-hub-guard/hook.test.d.ts +1 -0
  67. package/dist/hooks/knowledge-hub-guard/index.d.ts +3 -0
  68. package/dist/hooks/knowledge-hub-injector/hook.d.ts +26 -0
  69. package/dist/hooks/knowledge-hub-injector/hook.test.d.ts +1 -0
  70. package/dist/hooks/knowledge-hub-injector/index.d.ts +2 -0
  71. package/dist/hooks/knowledge-hub-search-nudge/hook.d.ts +16 -0
  72. package/dist/hooks/knowledge-hub-search-nudge/hook.test.d.ts +1 -0
  73. package/dist/hooks/knowledge-hub-search-nudge/index.d.ts +2 -0
  74. package/dist/hooks/plan-persister/index.d.ts +4 -0
  75. package/dist/hooks/plan-persister/task-link.d.ts +31 -0
  76. package/dist/hooks/plan-persister/task-sync.d.ts +39 -0
  77. package/dist/hooks/plan-persister/task-sync.test.d.ts +1 -0
  78. package/dist/hooks/start-work/index.d.ts +1 -0
  79. package/dist/hooks/start-work/plan-filter.d.ts +48 -0
  80. package/dist/hooks/task-continuation-enforcer/constants.d.ts +0 -5
  81. package/dist/index.js +6247 -4111
  82. package/dist/matrixx.schema.json +88 -145
  83. package/dist/plugin/hooks/create-core-hooks.d.ts +3 -2
  84. package/dist/plugin/hooks/create-session-hooks.d.ts +1 -2
  85. package/dist/plugin/hooks/create-tool-guard-hooks.d.ts +3 -2
  86. package/dist/plugin/hooks/create-transform-hooks.d.ts +2 -1
  87. package/dist/plugin/tool-gating.d.ts +35 -0
  88. package/dist/shared/dcp-guidance.d.ts +16 -0
  89. package/dist/{tools/dcp-switch-profile/tools.d.ts → shared/dcp-switch-profile.d.ts} +1 -3
  90. package/dist/shared/index.d.ts +1 -0
  91. package/dist/tools/background-task/constants.d.ts +1 -0
  92. package/dist/tools/background-task/create-background-wait-all.d.ts +3 -0
  93. package/dist/tools/background-task/index.d.ts +1 -1
  94. package/dist/tools/background-task/tools.d.ts +1 -0
  95. package/dist/tools/background-task/types.d.ts +3 -0
  96. package/dist/tools/delegate-task/constants.d.ts +6 -0
  97. package/dist/tools/delegate-task/prompt-builder.d.ts +1 -0
  98. package/dist/tools/delegate-task/prompt-builder.tdd.test.d.ts +1 -0
  99. package/dist/tools/delegate-task/tdd-enforcement.test.d.ts +1 -0
  100. package/dist/tools/delegate-task/tools.d.ts +6 -0
  101. package/dist/tools/delegate-task/types.d.ts +1 -0
  102. package/dist/tools/evolution/constants.d.ts +24 -0
  103. package/dist/tools/evolution/index.d.ts +3 -0
  104. package/dist/tools/evolution/query-actions.d.ts +3 -0
  105. package/dist/tools/evolution/query-actions.test.d.ts +1 -0
  106. package/dist/tools/evolution/tools.d.ts +16 -0
  107. package/dist/tools/evolution/tools.test.d.ts +1 -0
  108. package/dist/tools/evolution/types.d.ts +20 -0
  109. package/dist/tools/index.d.ts +2 -1
  110. package/dist/tools/knowledge-hub-confirm/index.d.ts +1 -0
  111. package/dist/tools/knowledge-hub-confirm/tools.d.ts +12 -0
  112. package/dist/tools/knowledge-hub-confirm/tools.test.d.ts +1 -0
  113. package/dist/tools/plan/constants.d.ts +1 -0
  114. package/dist/tools/plan/index.d.ts +1 -0
  115. package/dist/tools/plan/plan-tasks.d.ts +3 -0
  116. package/dist/tools/plan/types.d.ts +10 -0
  117. package/package.json +1 -1
  118. package/dist/config/schema/failure-counter.d.ts +0 -7
  119. package/dist/features/builtin-commands/templates/bdd-backend.d.ts +0 -1
  120. package/dist/features/builtin-commands/templates/bdd-contract.d.ts +0 -1
  121. package/dist/features/builtin-commands/templates/bdd-frontend.d.ts +0 -1
  122. package/dist/features/builtin-commands/templates/bdd-tests.d.ts +0 -1
  123. package/dist/features/builtin-commands/templates/dcp-profile.d.ts +0 -1
  124. package/dist/hooks/failure-counter/counter.d.ts +0 -7
  125. package/dist/hooks/failure-counter/hook.d.ts +0 -18
  126. package/dist/hooks/failure-counter/index.d.ts +0 -3
  127. package/dist/hooks/failure-counter/patterns.d.ts +0 -6
  128. package/dist/hooks/hashline-edit-diff-enhancer/hook.d.ts +0 -28
  129. package/dist/hooks/hashline-edit-diff-enhancer/index.d.ts +0 -1
  130. package/dist/tools/dcp-switch-profile/index.d.ts +0 -1
  131. /package/dist/{hooks/failure-counter/counter.test.d.ts → features/knowledge-hub/loader.test.d.ts} +0 -0
  132. /package/dist/{hooks/failure-counter/patterns.test.d.ts → features/knowledge-hub/resolver.test.d.ts} +0 -0
@@ -10,8 +10,28 @@ export declare const ORACLE_PLANS_DIR = ".matrixx/plans";
10
10
  */
11
11
  /** Relative path from project root to plans directory */
12
12
  export declare const PLANS_DIR = ".matrixx/plans";
13
+ /** Subdir of PLANS_DIR holding archived stale plans; excluded from listings. */
14
+ export declare const PLANS_ARCHIVE_DIR_NAME = "_archive";
15
+ /** Default staleness window (hours) shared by task + plan archival. */
16
+ export declare const DEFAULT_STALE_AFTER_HOURS = 24;
13
17
  /** HTML comment marker for machine metadata at the end of a plan file */
14
18
  export declare const META_TAG_PREFIX = "<!-- plan-persister:";
15
19
  export declare const META_TAG_SUFFIX = "-->";
16
20
  /** Safety cap: max bytes for a single plan file read */
17
21
  export declare const MAX_PLAN_FILE_BYTES = 102400;
22
+ /**
23
+ * Plan Checkbox Patterns
24
+ *
25
+ * Single source of truth for plan progress counting (see getPlanProgress).
26
+ * All patterns are anchored to column 0: indented sub-checkboxes
27
+ * (acceptance criteria, Definition-of-Done nests) never count.
28
+ * Do NOT inline checkbox regexes elsewhere — import these instead.
29
+ */
30
+ /** Top-level unchecked box: `- [ ]` or `* [ ]` */
31
+ export declare const TOP_UNCHECKED_RE: RegExp;
32
+ /** Top-level checked box: `- [x]` / `- [X]` (case-insensitive) */
33
+ export declare const TOP_CHECKED_RE: RegExp;
34
+ /** Numbered unchecked task (Oracle format): `- [ ] 1. Task` */
35
+ export declare const NUMBERED_UNCHECKED_RE: RegExp;
36
+ /** Numbered checked task (Oracle format): `- [x] 2. Task` */
37
+ export declare const NUMBERED_CHECKED_RE: RegExp;
@@ -1,5 +1,6 @@
1
1
  export * from "./constants";
2
2
  export * from "./plan-storage";
3
+ export * from "./reconcile";
3
4
  export * from "./rehydrate";
4
5
  export * from "./storage";
5
6
  export * from "./types";
@@ -25,13 +25,39 @@ export declare function atomicWrite(filePath: string, content: string): boolean;
25
25
  */
26
26
  export declare function writePlanFile(directory: string, planPath: string, content: string): boolean;
27
27
  /**
28
- * Sync markdown checkbox status to match todos.
29
- *
30
- * For each `- [ ]` or `- [x]` line, finds the matching todo by content
31
- * and marks it completed if the todo status is completed/cancelled.
32
- * Lines without a matching todo keep their current state.
33
- * Checked boxes are never unchecked — sync only transitions [ ] → [x].
28
+ * Verification-style guard: boxes matching verify/verification/checklist/
29
+ * definition-of-done/final check with zero task overlap are never
30
+ * force-completed — state kept, line reported via `flaggedVerification`.
31
+ */
32
+ export declare const VERIFICATION_STYLE_RE: RegExp;
33
+ /** Lowercase, strip punctuation/numbers, split tokens, drop stop-words. */
34
+ export declare function normalizeCheckboxText(text: string): string[];
35
+ export declare const isVerificationStyle: (text: string) => boolean;
36
+ /**
37
+ * Token overlap: match on >= 2 shared content tokens, or on shorter-side
38
+ * ratio >= 0.5 with normalized-set equality (equality keeps exact matches
39
+ * like "Task A"; without it one generic word cross-matches every sibling,
40
+ * e.g. "Task D" would flip on completed "Task A").
41
+ */
42
+ export declare function checkboxOverlap(a: string, b: string): {
43
+ shared: number;
44
+ score: number;
45
+ matched: boolean;
46
+ };
47
+ export interface SyncCheckboxesResult {
48
+ content: string;
49
+ flaggedVerification: string[];
50
+ }
51
+ /**
52
+ * Sync checkboxes to todos by token overlap (indented lines sync too, though
53
+ * Task 2 counting ignores them). Best overlap wins, ties go first. Checked
54
+ * boxes never uncheck ([ ] → [x] only); unmatched lines keep state.
34
55
  */
56
+ export declare function syncCheckboxesDetailed(content: string, todos: Array<{
57
+ content: string;
58
+ status: string;
59
+ }>): SyncCheckboxesResult;
60
+ /** String-only wrapper (backward compatible with plan-persister hook). */
35
61
  export declare function syncCheckboxes(content: string, todos: Array<{
36
62
  content: string;
37
63
  status: string;
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Plan reconciliation + stale-plan archival policy.
3
+ *
4
+ * The reconciler re-runs the Tasks 3-4 linkage pass (checkboxOverlap +
5
+ * verification guard from plan-storage) with a confidence gate: only
6
+ * high-confidence token overlap auto-checks, the rest is reported for
7
+ * manual plan_update. Runs are idempotent — a converged plan yields no writes.
8
+ *
9
+ * Archival moves stale orphans to .matrixx/plans/_archive/ (never deletes).
10
+ */
11
+ import type { MatrixxConfig } from "../../config/schema";
12
+ export interface ReconcileTodo {
13
+ content: string;
14
+ status: string;
15
+ }
16
+ export interface ReconcileResult {
17
+ content: string;
18
+ checked: string[];
19
+ lowConfidence: string[];
20
+ flaggedVerification: string[];
21
+ changed: boolean;
22
+ }
23
+ export interface ReconcileFileResult extends ReconcileResult {
24
+ wrote: boolean;
25
+ }
26
+ /**
27
+ * High-confidence gate: token overlap matched (Task 3 thresholds) AND the
28
+ * box is not verification-flagged. Verification-style boxes with genuine
29
+ * overlap still flip (overlap wins); zero-overlap verification boxes land
30
+ * in flaggedVerification and never auto-check.
31
+ */
32
+ export declare function isHighConfidence(boxText: string, todoContent: string, flaggedVerification?: string[]): boolean;
33
+ /** Reconcile plan content against runtime todos; pure, no disk writes. */
34
+ export declare function reconcilePlanContent(content: string, todos: ReconcileTodo[]): ReconcileResult;
35
+ /** Reconcile one plan file; writes only when content changed (idempotent). */
36
+ export declare function reconcilePlanFile(planPath: string, todos: ReconcileTodo[]): ReconcileFileResult;
37
+ /** Invocation point for start-work: reconcile only when plans compete (>1). */
38
+ export declare function shouldReconcileOnStartWork(incompleteCount: number): boolean;
39
+ export interface ActiveTaskSubjects {
40
+ subjects: string[];
41
+ unknownTaskFiles: string[];
42
+ }
43
+ /**
44
+ * Subjects of active (pending/in_progress) tasks. Strict-schema drops
45
+ * (readJsonSafe -> null) are counted + logged as unknown — never treated
46
+ * as completed, never silently ignored.
47
+ */
48
+ export declare function readActiveTaskSubjects(directory: string, config?: Partial<MatrixxConfig>): ActiveTaskSubjects;
49
+ /** A plan whose file cannot be stat'ed is treated as fresh (not stale). */
50
+ export declare function isStaleByMtime(planPath: string, staleAfterHours?: number): boolean;
51
+ export type ArchiveDecision = "active-plan" | "linked-active-tasks" | "fresh" | "unreadable" | "stale-orphan";
52
+ /** Archive candidacy: stale mtime AND zero linked active tasks AND not active. */
53
+ export declare function isArchiveCandidate(planPath: string, content: string | null, subjects: string[], staleAfterHours: number, activePlan?: string | null): {
54
+ candidate: boolean;
55
+ reason: ArchiveDecision;
56
+ };
57
+ export interface ArchiveScanOptions {
58
+ staleAfterHours?: number;
59
+ activePlan?: string | null;
60
+ activeTaskSubjects?: string[];
61
+ config?: Partial<MatrixxConfig>;
62
+ dryRun?: boolean;
63
+ }
64
+ export interface ArchiveResult {
65
+ candidates: string[];
66
+ moved: string[];
67
+ unknownTaskFiles: string[];
68
+ before: number;
69
+ after: number;
70
+ }
71
+ /**
72
+ * Move stale orphans to _archive/ preserving bytes (incl. plan-persister
73
+ * meta). Dry-run reports candidates with zero moves. Never deletes.
74
+ */
75
+ export declare function archiveStalePlans(directory: string, opts?: ArchiveScanOptions): ArchiveResult;
@@ -0,0 +1 @@
1
+ export {};
@@ -5,6 +5,23 @@
5
5
  */
6
6
  import type { MissionState, PlanProgress } from "./types";
7
7
  export declare function readMissionState(directory: string): MissionState | null;
8
+ /**
9
+ * Normalize a parsed mission.json value in memory (no disk rewrite).
10
+ * Legacy files used a singular `session_id` string; modern files use
11
+ * `session_ids[]`. Missing or non-array values become `[]` unless a
12
+ * legacy `session_id` string is present, which becomes `[session_id]`.
13
+ */
14
+ export declare function normalizeMissionState(parsed: unknown): MissionState | null;
15
+ /**
16
+ * Rotate the mission when its active plan is complete: clear mission.json
17
+ * so the next start-work run auto-selects instead of zombie-resuming.
18
+ * Returns `{ rotated: true, state: null }` after clearing, otherwise the
19
+ * preserved state. Never rewrites an incomplete or missing mission.
20
+ */
21
+ export declare function rotateMissionIfComplete(directory: string): {
22
+ rotated: boolean;
23
+ state: MissionState | null;
24
+ };
8
25
  export declare function writeMissionState(directory: string, state: MissionState): boolean;
9
26
  export declare function appendSessionId(directory: string, sessionId: string): MissionState | null;
10
27
  export declare function clearMissionState(directory: string): boolean;
@@ -13,6 +30,15 @@ export declare function clearMissionState(directory: string): boolean;
13
30
  * Oracle stores plans at: {project}/.matrixx/plans/{name}.md
14
31
  */
15
32
  export declare function findOraclePlans(directory: string): string[];
33
+ /**
34
+ * Count checkbox progress from plan content.
35
+ *
36
+ * Single content-level implementation behind getPlanProgress: numbered
37
+ * task lines (Oracle format) win when present, otherwise all top-level
38
+ * checkboxes count. Indented boxes never count. Do NOT inline checkbox
39
+ * regexes elsewhere — import the Task 2 constants instead.
40
+ */
41
+ export declare function countPlanProgressFromContent(content: string): PlanProgress;
16
42
  /**
17
43
  * Parse a plan file and count checkbox progress.
18
44
  */
@@ -23,6 +23,12 @@ export interface PlanProgress {
23
23
  completed: number;
24
24
  /** Whether all tasks are done */
25
25
  isComplete: boolean;
26
+ /**
27
+ * True when total is 0 (empty, prose-only, or missing plan).
28
+ * isComplete stays true by vacuity; callers should log/warn and
29
+ * route these plans to human triage instead of treating them as done.
30
+ */
31
+ needsTriage?: boolean;
26
32
  }
27
33
  /**
28
34
  * Plan Persistence Types
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Plan Contract — Appendix Boundary
3
+ *
4
+ * Locates the designated appendix region of a plan. The region begins at the
5
+ * first H2 whose normalized text is exactly `Appendix` and extends to EOF.
6
+ * H2s at/after it are exempt from canonical-section and ordering checks.
7
+ *
8
+ * Pure content-level helper — accepts a string only, never touches the file system.
9
+ */
10
+ /**
11
+ * Return the ZERO-BASED line index of the first `## Appendix` H2, or `-1` when
12
+ * the plan has no appendix. "Normalized" means the heading text is trimmed.
13
+ */
14
+ export declare function findAppendixStart(content: string): number;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Plan Contract Constants
3
+ *
4
+ * Canonical structure of an Oracle work plan: the ordered H2 sections and the
5
+ * required per-task grammar. Checkbox regexes are the single source of truth in
6
+ * mission-state — re-exported here, never re-declared.
7
+ */
8
+ export { NUMBERED_CHECKED_RE, NUMBERED_UNCHECKED_RE, TOP_CHECKED_RE, TOP_UNCHECKED_RE, } from "../../features/mission-state/constants";
9
+ /** Ordered H2 section titles, exactly as emitted by the Oracle plan template. */
10
+ export declare const CANONICAL_SECTIONS: readonly ["TL;DR", "Context", "Work Objectives", "Verification Strategy (MANDATORY)", "Execution Strategy", "TODOs", "Commit Strategy", "Success Criteria"];
11
+ /** Ordered labels that every TODO task block must declare. */
12
+ export declare const REQUIRED_TASK_SUBFIELDS: readonly ["What to do", "Must NOT do", "Recommended Agent Profile", "Parallelization", "References", "Acceptance Criteria", "Agent-Executed QA Scenarios"];
13
+ /** Canonical section title union derived from {@link CANONICAL_SECTIONS}. */
14
+ export type PlanSection = (typeof CANONICAL_SECTIONS)[number];
15
+ /** Canonical task subfield label union derived from {@link REQUIRED_TASK_SUBFIELDS}. */
16
+ export type PlanTaskSubfield = (typeof REQUIRED_TASK_SUBFIELDS)[number];
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Plan Front-Matter
3
+ *
4
+ * Structured YAML front-matter (a leading `---` fenced block) for Oracle plan
5
+ * files, parsed with `js-yaml`.
6
+ *
7
+ * PRECEDENCE: when a front-matter block is present it is authoritative for
8
+ * `status` and `revision`. The legacy `<!-- plan-persister: {...} -->` comment
9
+ * (see mission-state `plan-storage.ts`) remains authoritative for `todoTotal`,
10
+ * `todoCompleted`, `updatedAt` and `sessionId`, and is NEVER removed. Front-matter
11
+ * is ADDITIVE over that comment, not a replacement.
12
+ *
13
+ * Serialization is IDEMPOTENT: `parse(serialize(parse(content)))` equals
14
+ * `parse(content)`, and `serialize(parse(serialize(fm)))` equals
15
+ * `serialize(fm)`. On disagreement `status` comes from the front-matter while
16
+ * the legacy comment is left untouched.
17
+ */
18
+ import type { PlanFrontMatter } from "./types";
19
+ /**
20
+ * Parse the leading YAML front-matter block.
21
+ *
22
+ * Returns `null` when the block is absent, malformed, or fails the
23
+ * {@link PlanFrontMatter} shape (e.g. missing `status`/`revision` or an
24
+ * out-of-vocabulary status).
25
+ */
26
+ export declare function parsePlanFrontMatter(content: string): PlanFrontMatter | null;
27
+ /**
28
+ * Serialize front-matter to a `---` fenced YAML block.
29
+ *
30
+ * Optional fields are omitted when `undefined`; array fields are emitted even
31
+ * when empty. The returned block ends with a trailing newline so it can be
32
+ * prepended to plan content additively.
33
+ */
34
+ export declare function serializePlanFrontMatter(fm: PlanFrontMatter): string;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Plan Contract — barrel
3
+ *
4
+ * Foundation module for the plan contract: canonical sections, task grammar,
5
+ * and the Zod schema for the structured plan view.
6
+ */
7
+ export { findAppendixStart } from "./appendix";
8
+ export { CANONICAL_SECTIONS, NUMBERED_CHECKED_RE, NUMBERED_UNCHECKED_RE, type PlanSection, type PlanTaskSubfield, REQUIRED_TASK_SUBFIELDS, TOP_CHECKED_RE, TOP_UNCHECKED_RE, } from "./constants";
9
+ export { parsePlanFrontMatter, serializePlanFrontMatter } from "./front-matter";
10
+ export { isGrandfathered, shouldMigrate } from "./migration";
11
+ export { type PlanContract, PlanContractSchema } from "./schema";
12
+ export { renderPlanSkeleton } from "./skeleton";
13
+ export type { PlanContractResult, PlanContractWarning, PlanFrontMatter, PlanStatus, PlanTask, } from "./types";
14
+ export { parsePlanContract, parsePlanTasks, validatePlanContract } from "./validate";
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Plan Front-Matter Migration & Grandfathering
3
+ *
4
+ * Front-matter is ADDITIVE over the legacy `<!-- plan-persister: {...} -->`
5
+ * comment (`mission-state/plan-storage.ts`) — it does not replace it. Migration
6
+ * is apply-on-next-edit ONLY: no `plan_migrate` tool is shipped and no plan is
7
+ * rewritten automatically.
8
+ *
9
+ * Grandfathering protects the pre-existing plan corpus from retro-breaking: a
10
+ * plan that lacks front-matter is only exempt when its id is on the frozen
11
+ * {@link GRANDFATHER_ALLOWLIST}. A brand-new plan lacking front-matter is NOT
12
+ * grandfathered.
13
+ */
14
+ /**
15
+ * Frozen allowlist of plan ids (filename without `.md`) that predate the
16
+ * front-matter requirement — captured from the live `.matrixx/plans` corpus
17
+ * (23 files) at planning time.
18
+ *
19
+ * Grandfathered plans never emit a front-matter warning and are exempt from any
20
+ * future FAIL-mode front-matter requirement. The exemption clears as soon as
21
+ * the plan gains a front-matter block.
22
+ */
23
+ export declare const GRANDFATHER_ALLOWLIST: readonly string[];
24
+ /**
25
+ * True IFF the plan has no front-matter AND its id is on the frozen allowlist.
26
+ *
27
+ * This is deliberately narrower than "any plan lacking front-matter": a new
28
+ * non-allowlisted plan returns `false`.
29
+ */
30
+ export declare function isGrandfathered(filePath: string, content: string): boolean;
31
+ /**
32
+ * True IFF front-matter is absent, for ANY plan (grandfathered included),
33
+ * because injection is additive. Idempotent: once front-matter is present this
34
+ * returns `false`.
35
+ */
36
+ export declare function shouldMigrate(content: string): boolean;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Plan Contract Schema
3
+ *
4
+ * Zod v4 schema for the STRUCTURED view of an Oracle plan. The Markdown grammar
5
+ * itself is parsed elsewhere; this validates the parsed shape.
6
+ */
7
+ import { z } from "zod";
8
+ export declare const PlanContractSchema: z.ZodObject<{
9
+ frontMatter: z.ZodOptional<z.ZodObject<{
10
+ status: z.ZodEnum<{
11
+ pending: "pending";
12
+ completed: "completed";
13
+ in_progress: "in_progress";
14
+ }>;
15
+ revision: z.ZodNumber;
16
+ phase: z.ZodOptional<z.ZodString>;
17
+ wave: z.ZodOptional<z.ZodString>;
18
+ deps: z.ZodOptional<z.ZodArray<z.ZodString>>;
19
+ blockedBy: z.ZodOptional<z.ZodArray<z.ZodString>>;
20
+ }, z.core.$strip>>;
21
+ sections: z.ZodArray<z.ZodString>;
22
+ tasks: z.ZodArray<z.ZodObject<{
23
+ n: z.ZodNumber;
24
+ title: z.ZodString;
25
+ checked: z.ZodBoolean;
26
+ line: z.ZodNumber;
27
+ anchor: z.ZodString;
28
+ }, z.core.$strip>>;
29
+ dod: z.ZodArray<z.ZodString>;
30
+ }, z.core.$strip>;
31
+ /** Parsed, validated structured view of a plan. */
32
+ export type PlanContract = z.infer<typeof PlanContractSchema>;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Render the full canonical Oracle plan markdown skeleton — the content between
3
+ * the `\`\`\`markdown` fences of {@link ORACLE_PLAN_TEMPLATE}.
4
+ */
5
+ export declare function renderPlanSkeleton(): string;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Plan Contract Types
3
+ *
4
+ * Structured view of an Oracle work plan: parsed sections, numbered tasks,
5
+ * definition-of-done lines, and optional YAML front-matter.
6
+ */
7
+ import type { PlanSection } from "./constants";
8
+ export type { PlanSection };
9
+ /** A single numbered TODO task parsed from a plan. */
10
+ export interface PlanTask {
11
+ /** Task number as written in the plan (e.g. `1` in `- [ ] 1. ...`). */
12
+ n: number;
13
+ /** Task title text following the number. */
14
+ title: string;
15
+ /** Whether the task checkbox is checked. */
16
+ checked: boolean;
17
+ /** 1-based line number of the task within the plan file. */
18
+ line: number;
19
+ /** Stable LINE#ID anchor for hashline-scoped edits. */
20
+ anchor: string;
21
+ }
22
+ /** Severity-neutral diagnostic emitted while validating a plan contract. */
23
+ export interface PlanContractWarning {
24
+ /** Machine-readable warning code. */
25
+ code: string;
26
+ /** Human-readable explanation. */
27
+ message: string;
28
+ /** 1-based line the warning refers to, when known. */
29
+ line?: number;
30
+ }
31
+ /** Outcome of validating a plan against the contract. */
32
+ export interface PlanContractResult {
33
+ /** True when no errors were produced (warnings may still be present). */
34
+ ok: boolean;
35
+ /** Non-fatal contract deviations. */
36
+ warnings: PlanContractWarning[];
37
+ /** Fatal contract violations. */
38
+ errors: string[];
39
+ }
40
+ /** Lifecycle status carried by a plan's YAML front-matter. */
41
+ export type PlanStatus = "pending" | "in_progress" | "completed";
42
+ /** Structured YAML front-matter block parsed from a plan file. */
43
+ export interface PlanFrontMatter {
44
+ /** Current plan lifecycle status. */
45
+ status: PlanStatus;
46
+ /** Monotonic revision counter. */
47
+ revision: number;
48
+ /** Execution phase label, when present. */
49
+ phase?: string;
50
+ /** Execution wave label, when present. */
51
+ wave?: string;
52
+ /** Task ids this plan depends on. */
53
+ deps?: string[];
54
+ /** Task ids blocked by this plan. */
55
+ blockedBy?: string[];
56
+ }
@@ -0,0 +1,9 @@
1
+ import type { PlanContract } from "./schema";
2
+ import type { PlanContractResult, PlanTask } from "./types";
3
+ /** Optional caller-supplied LINE#ID anchors keyed by 1-based line number. */
4
+ export type HashlineAnchors = ReadonlyMap<number, string> | Readonly<Record<number, string>>;
5
+ export declare function parsePlanTasks(content: string, hashlineAnchors?: HashlineAnchors): PlanTask[];
6
+ export declare function parsePlanContract(content: string): PlanContract;
7
+ export declare function validatePlanContract(content: string, options?: {
8
+ mode?: "warn" | "fail";
9
+ }): PlanContractResult;
@@ -28,14 +28,3 @@ export declare function setSessionAgent(sessionID: string, agent: string): void;
28
28
  export declare function updateSessionAgent(sessionID: string, agent: string): void;
29
29
  export declare function getSessionAgent(sessionID: string): string | undefined;
30
30
  export declare function clearSessionAgent(sessionID: string): void;
31
- export declare function incFailureCounter(sessionID: string): number;
32
- export declare function resetFailureCounter(sessionID: string): void;
33
- export declare function getFailureCount(sessionID: string): number;
34
- export declare function getFailureState(sessionID: string): {
35
- count: number;
36
- lastFailedAt: number;
37
- } | undefined;
38
- export declare function clearFailureCounter(sessionID: string): void;
39
- /** @internal For testing only */
40
- export declare function _resetFailureCountersForTesting(): void;
41
- export declare function isThresholdReached(sessionID: string, threshold: number): boolean;
@@ -1,11 +1,19 @@
1
- import type { createOpencodeClient } from "@opencode-ai/sdk";
2
1
  import type { BuiltinSkill } from "../../features/builtin-skills";
3
2
  import type { ParsedSlashCommand } from "./types";
4
3
  export interface ExecutorOptions {
5
4
  skills?: BuiltinSkill[];
6
- /** OpenCode SDK client for discovering plugin-registered commands */
7
- client?: ReturnType<typeof createOpencodeClient>;
8
5
  }
6
+ /**
7
+ * Ownership rule: the hook expands only matrixx-owned scopes (builtin,
8
+ * markdown command dirs, skills). Plugin-scope commands belong to other
9
+ * plugins and must fall through so the owning plugin handles them natively —
10
+ * claiming them renders instruction-less blocks (e.g. /dcp-compress). Empty
11
+ * templates are declined in every scope for the same reason.
12
+ */
13
+ export declare function isHookOwnedCommand(cmd: {
14
+ scope: string;
15
+ content?: string;
16
+ }): boolean;
9
17
  interface ExecuteResult {
10
18
  success: boolean;
11
19
  replacementText?: string;
@@ -2,8 +2,6 @@ import type { BuiltinSkill } from "../../features/builtin-skills";
2
2
  import type { AutoSlashCommandHookInput, AutoSlashCommandHookOutput, CommandExecuteBeforeInput, CommandExecuteBeforeOutput } from "./types";
3
3
  export interface AutoSlashCommandHookOptions {
4
4
  skills?: BuiltinSkill[];
5
- /** OpenCode SDK client for discovering plugin-registered commands */
6
- client?: ReturnType<typeof import("@opencode-ai/sdk").createOpencodeClient>;
7
5
  }
8
6
  export declare function createAutoSlashCommandHook(options?: AutoSlashCommandHookOptions): {
9
7
  "chat.message": (input: AutoSlashCommandHookInput, output: AutoSlashCommandHookOutput) => Promise<void>;
@@ -0,0 +1,17 @@
1
+ import type { createOpencodeClient } from "@opencode-ai/sdk";
2
+ import type { LlmUsage } from "../../features/evolution/compressor/interface";
3
+ type Client = ReturnType<typeof createOpencodeClient>;
4
+ export declare function parseModelOverride(model: string | undefined): {
5
+ providerID: string;
6
+ modelID: string;
7
+ } | undefined;
8
+ export declare function createHostLlmCall(options: {
9
+ client: Client;
10
+ directory: string;
11
+ agent?: string;
12
+ model?: string;
13
+ }): (prompt: string, model?: string) => Promise<{
14
+ text: string;
15
+ usage?: LlmUsage;
16
+ }>;
17
+ export {};
@@ -24,13 +24,14 @@ export { createEvolutionCompressorHook } from "./evolution-compressor";
24
24
  export { createEvolutionHitlHook } from "./evolution-hitl";
25
25
  export { passesQualityGate } from "./evolution-quality-gate";
26
26
  export { createEvolutionWatcherHook } from "./evolution-watcher";
27
- export { createFailureCounterHook } from "./failure-counter";
28
- export { createHashlineEditDiffEnhancerHook } from "./hashline-edit-diff-enhancer";
29
27
  export { createHashlineReadEnhancerHook } from "./hashline-read-enhancer";
30
28
  export { createInputSecretGuardHook } from "./input-secret-guard";
31
29
  export { createInteractiveBashSessionHook } from "./interactive-bash-session";
32
30
  export { createJsonErrorRecoveryHook } from "./json-error-recovery";
33
31
  export { createKeywordDetectorHook } from "./keyword-detector";
32
+ export { createKnowledgeHubGuardHook } from "./knowledge-hub-guard";
33
+ export { createKnowledgeHubInjectorHook } from "./knowledge-hub-injector";
34
+ export { createKnowledgeHubSearchNudgeHook } from "./knowledge-hub-search-nudge";
34
35
  export { createMatrixLoopHook, type MatrixLoopHook } from "./matrix-loop";
35
36
  export { createMouseNotepadHook } from "./mouse-notepad";
36
37
  export { createNonInteractiveEnvHook } from "./non-interactive-env";
@@ -0,0 +1,5 @@
1
+ export declare const HUB_WRITE_APPROVAL_TTL_MS: number;
2
+ export declare function normalizeApprovedPath(absPath: string): string;
3
+ export declare function approveHubWrite(sessionID: string, absPath: string, ttlMs?: number): string;
4
+ export declare function isHubWriteApproved(sessionID: string, absPath: string): boolean;
5
+ export declare function clearHubWriteApprovals(): void;
@@ -0,0 +1,15 @@
1
+ import type { PluginInput } from "@opencode-ai/plugin";
2
+ import type { LoadedHub } from "../../features/knowledge-hub/loader";
3
+ export interface KnowledgeHubGuardOptions {
4
+ hubs?: LoadedHub[];
5
+ getHubs?: () => LoadedHub[];
6
+ }
7
+ export declare function createKnowledgeHubGuardHook(ctx: PluginInput, options?: KnowledgeHubGuardOptions): {
8
+ "tool.execute.before": (input: {
9
+ tool: string;
10
+ sessionID: string;
11
+ callID: string;
12
+ }, output: {
13
+ args: Record<string, unknown>;
14
+ }) => Promise<void>;
15
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ export { approveHubWrite, clearHubWriteApprovals, HUB_WRITE_APPROVAL_TTL_MS, isHubWriteApproved } from "./approvals";
2
+ export type { KnowledgeHubGuardOptions } from "./hook";
3
+ export { createKnowledgeHubGuardHook } from "./hook";
@@ -0,0 +1,26 @@
1
+ import type { PluginInput } from "@opencode-ai/plugin";
2
+ import type { Message, Part } from "@opencode-ai/sdk";
3
+ import type { KnowledgeHub } from "../../config/schema/knowledge";
4
+ import { type ContextCollector } from "../../features/context-injector";
5
+ export interface KnowledgeHubInjectorOptions {
6
+ hubs?: KnowledgeHub[];
7
+ getHubs?: () => KnowledgeHub[];
8
+ pinnedFiles?: string[];
9
+ collector?: ContextCollector;
10
+ }
11
+ interface MessageWithParts {
12
+ info: Message;
13
+ parts: Part[];
14
+ }
15
+ export declare function createKnowledgeHubInjectorHook(ctx: PluginInput, options?: KnowledgeHubInjectorOptions): {
16
+ "experimental.chat.messages.transform": (_input: Record<string, never>, output: {
17
+ messages: MessageWithParts[];
18
+ }) => Promise<void>;
19
+ event: ({ event }: {
20
+ event: {
21
+ type: string;
22
+ properties?: unknown;
23
+ };
24
+ }) => Promise<void>;
25
+ };
26
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export type { KnowledgeHubInjectorOptions } from "./hook";
2
+ export { createKnowledgeHubInjectorHook } from "./hook";
@@ -0,0 +1,16 @@
1
+ import type { PluginInput } from "@opencode-ai/plugin";
2
+ import type { LoadedHub } from "../../features/knowledge-hub/loader";
3
+ export interface KnowledgeHubSearchNudgeOptions {
4
+ hubs?: LoadedHub[];
5
+ getHubs?: () => LoadedHub[];
6
+ }
7
+ export declare function createKnowledgeHubSearchNudgeHook(ctx: PluginInput, options?: KnowledgeHubSearchNudgeOptions): {
8
+ "tool.execute.before": (input: {
9
+ tool: string;
10
+ sessionID: string;
11
+ callID: string;
12
+ }, output: {
13
+ args: Record<string, unknown>;
14
+ message?: string;
15
+ }) => Promise<void>;
16
+ };
@@ -0,0 +1,2 @@
1
+ export type { KnowledgeHubSearchNudgeOptions } from "./hook";
2
+ export { createKnowledgeHubSearchNudgeHook } from "./hook";
@@ -1,2 +1,6 @@
1
1
  export type { PlanPersister } from "./hook";
2
2
  export { createPlanPersister } from "./hook";
3
+ export type { LinkageDecision, LinkageOptions, LinkedTodos } from "./task-link";
4
+ export { collectLinkedTodos, isTaskLinkedToMission, isTerminalTaskStatus } from "./task-link";
5
+ export type { FilteredSyncInput, FilteredSyncResult, MatchedBox, SyncTriggerInput, SyncTriggerResult, } from "./task-sync";
6
+ export { applyFilteredSync, maybeSyncTaskToPlans } from "./task-sync";