opencode-matrixx 2.2.0 → 2.3.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 (134) hide show
  1. package/README.md +21 -25
  2. package/dist/agents/bdd-contract.d.ts +7 -0
  3. package/dist/agents/builtin-agents/architect-agent.d.ts +1 -0
  4. package/dist/agents/builtin-agents/general-agents.d.ts +1 -0
  5. package/dist/agents/builtin-agents/{hephaestus-agent.d.ts → keymaker-agent.d.ts} +2 -0
  6. package/dist/agents/builtin-agents/model-resolution.d.ts +1 -0
  7. package/dist/agents/builtin-agents/morpheus-agent.d.ts +2 -0
  8. package/dist/agents/builtin-agents.d.ts +1 -1
  9. package/dist/agents/dynamic-agent-prompt-builder.d.ts +2 -1
  10. package/dist/agents/env-context.d.ts +1 -1
  11. package/dist/agents/mouse/agent.d.ts +5 -2
  12. package/dist/agents/mouse/deepseek.d.ts +16 -0
  13. package/dist/agents/mouse/index.d.ts +3 -0
  14. package/dist/agents/mouse/mimo.d.ts +15 -0
  15. package/dist/agents/mouse/qwen.d.ts +16 -0
  16. package/dist/agents/mouse/shared.d.ts +7 -0
  17. package/dist/agents/types.d.ts +4 -1
  18. package/dist/config/index.d.ts +1 -2
  19. package/dist/config/presets.d.ts +4 -0
  20. package/dist/config/resolve-tiers.d.ts +32 -0
  21. package/dist/config/schema/agent-names.d.ts +6 -0
  22. package/dist/config/schema/agent-overrides.d.ts +133 -0
  23. package/dist/config/schema/categories.d.ts +16 -0
  24. package/dist/config/schema/commands.d.ts +6 -0
  25. package/dist/config/schema/dcp.d.ts +16 -0
  26. package/dist/config/schema/hooks.d.ts +2 -0
  27. package/dist/config/schema/matrixx-config.d.ts +153 -18
  28. package/dist/config/schema.d.ts +3 -1
  29. package/dist/create-hooks.d.ts +2 -0
  30. package/dist/features/bdd/schema.d.ts +434 -0
  31. package/dist/features/bdd/types.d.ts +2 -0
  32. package/dist/features/builtin-commands/templates/bdd-backend.d.ts +1 -0
  33. package/dist/features/builtin-commands/templates/bdd-contract.d.ts +1 -0
  34. package/dist/features/builtin-commands/templates/bdd-frontend.d.ts +1 -0
  35. package/dist/features/builtin-commands/templates/bdd-pipeline.d.ts +1 -0
  36. package/dist/features/builtin-commands/templates/bdd-tests.d.ts +1 -0
  37. package/dist/features/builtin-commands/templates/dcp-profile.d.ts +1 -0
  38. package/dist/features/builtin-commands/types.d.ts +2 -2
  39. package/dist/features/builtin-skills/lazy-skill-helper.d.ts +17 -0
  40. package/dist/features/builtin-skills/skills/bdd-backend.d.ts +3 -0
  41. package/dist/features/builtin-skills/skills/bdd-contract.d.ts +3 -0
  42. package/dist/features/builtin-skills/skills/bdd-frontend.d.ts +3 -0
  43. package/dist/features/builtin-skills/skills/bdd-tests.d.ts +3 -0
  44. package/dist/features/builtin-skills/skills/docker-master.d.ts +2 -0
  45. package/dist/features/builtin-skills/skills/index.d.ts +5 -0
  46. package/dist/features/{claude-code-command-loader → command-loader}/loader.d.ts +0 -2
  47. package/dist/features/mission-state/constants.d.ts +10 -0
  48. package/dist/features/mission-state/index.d.ts +2 -0
  49. package/dist/features/mission-state/plan-storage.d.ts +48 -0
  50. package/dist/features/mission-state/rehydrate.d.ts +21 -0
  51. package/dist/features/mission-state/types.d.ts +46 -0
  52. package/dist/features/opencode-skill-loader/loader.d.ts +1 -3
  53. package/dist/features/opencode-skill-loader/skill-definition-record.d.ts +1 -1
  54. package/dist/features/opencode-skill-loader/types.d.ts +1 -1
  55. package/dist/features/skill-mcp-manager/connection-type.d.ts +2 -3
  56. package/dist/features/skill-mcp-manager/connection.d.ts +3 -4
  57. package/dist/features/skill-mcp-manager/manager.d.ts +2 -3
  58. package/dist/features/skill-mcp-manager/oauth-handler.d.ts +3 -3
  59. package/dist/features/skill-mcp-manager/types.d.ts +16 -4
  60. package/dist/hooks/env-context-injector/index.d.ts +23 -0
  61. package/dist/hooks/index.d.ts +2 -0
  62. package/dist/hooks/plan-persister/hook.d.ts +20 -0
  63. package/dist/hooks/plan-persister/index.d.ts +2 -0
  64. package/dist/index.js +44907 -28359
  65. package/dist/plugin/hooks/create-continuation-hooks.d.ts +2 -1
  66. package/dist/plugin/hooks/create-core-hooks.d.ts +1 -0
  67. package/dist/plugin/hooks/create-transform-hooks.d.ts +2 -1
  68. package/dist/plugin-config.d.ts +1 -1
  69. package/dist/plugin-handlers/agent-config-handler.d.ts +2 -0
  70. package/dist/plugin-handlers/plugin-components-loader.d.ts +1 -1
  71. package/dist/plugin-handlers/prometheus-agent-config-builder.d.ts +1 -0
  72. package/dist/shared/index.d.ts +1 -1
  73. package/dist/shared/merge-categories.d.ts +4 -0
  74. package/dist/shared/model-resolution-types.d.ts +3 -0
  75. package/dist/shared/model-tiers.d.ts +31 -0
  76. package/dist/shared/tier-resolver.d.ts +26 -0
  77. package/dist/tools/bdd-create-contract/constants.d.ts +1 -0
  78. package/dist/tools/bdd-create-contract/index.d.ts +3 -0
  79. package/dist/tools/bdd-create-contract/tools.d.ts +3 -0
  80. package/dist/tools/bdd-create-contract/types.d.ts +12 -0
  81. package/dist/tools/bdd-parse-gherkin/constants.d.ts +1 -0
  82. package/dist/tools/bdd-parse-gherkin/index.d.ts +3 -0
  83. package/dist/tools/bdd-parse-gherkin/tools.d.ts +5 -0
  84. package/dist/tools/bdd-parse-gherkin/types.d.ts +9 -0
  85. package/dist/tools/bdd-pipeline/analysis-report-sections.d.ts +10 -0
  86. package/dist/tools/bdd-pipeline/analysis-report.d.ts +9 -0
  87. package/dist/tools/bdd-pipeline/constants.d.ts +4 -0
  88. package/dist/tools/bdd-pipeline/feature-resolver.d.ts +5 -0
  89. package/dist/tools/bdd-pipeline/index.d.ts +3 -0
  90. package/dist/tools/bdd-pipeline/pipeline-runner.d.ts +6 -0
  91. package/dist/tools/bdd-pipeline/subagent-runner.d.ts +14 -0
  92. package/dist/tools/bdd-pipeline/tools.d.ts +5 -0
  93. package/dist/tools/bdd-pipeline/types.d.ts +74 -0
  94. package/dist/tools/bdd-validate-contract/index.d.ts +1 -0
  95. package/dist/tools/bdd-validate-contract/tools.d.ts +21 -0
  96. package/dist/tools/delegate-task/categories.d.ts +7 -0
  97. package/dist/tools/delegate-task/category-resolver.d.ts +6 -0
  98. package/dist/tools/delegate-task/complexity-constants.d.ts +24 -0
  99. package/dist/tools/delegate-task/complexity-scorer.d.ts +31 -0
  100. package/dist/tools/delegate-task/complexity-types.d.ts +10 -0
  101. package/dist/tools/delegate-task/executor-types.d.ts +1 -0
  102. package/dist/tools/delegate-task/index.d.ts +3 -0
  103. package/dist/tools/delegate-task/types.d.ts +8 -0
  104. package/dist/tools/index.d.ts +4 -0
  105. package/dist/tools/task/todo-sync.d.ts +1 -1
  106. package/package.json +19 -4
  107. package/dist/agents/builtin-agents/environment-context.d.ts +0 -2
  108. package/dist/config/profiles.d.ts +0 -4
  109. package/dist/config/schema/claude-code.d.ts +0 -10
  110. package/dist/features/claude-code-mcp-loader/index.d.ts +0 -10
  111. package/dist/features/claude-code-mcp-loader/loader.d.ts +0 -3
  112. package/dist/features/claude-code-mcp-loader/transformer.d.ts +0 -2
  113. package/dist/features/claude-code-mcp-loader/types.d.ts +0 -39
  114. package/dist/features/claude-code-plugin-loader/agent-loader.d.ts +0 -3
  115. package/dist/features/claude-code-plugin-loader/command-loader.d.ts +0 -3
  116. package/dist/features/claude-code-plugin-loader/discovery.d.ts +0 -2
  117. package/dist/features/claude-code-plugin-loader/hook-loader.d.ts +0 -2
  118. package/dist/features/claude-code-plugin-loader/index.d.ts +0 -10
  119. package/dist/features/claude-code-plugin-loader/loader.d.ts +0 -20
  120. package/dist/features/claude-code-plugin-loader/mcp-server-loader.d.ts +0 -3
  121. package/dist/features/claude-code-plugin-loader/plugin-path-resolver.d.ts +0 -1
  122. package/dist/features/claude-code-plugin-loader/skill-loader.d.ts +0 -3
  123. package/dist/features/claude-code-plugin-loader/types.d.ts +0 -187
  124. package/dist/shared/claude-config-dir.d.ts +0 -1
  125. /package/dist/features/{claude-code-agent-loader → agent-loader}/index.d.ts +0 -0
  126. /package/dist/features/{claude-code-agent-loader → agent-loader}/loader.d.ts +0 -0
  127. /package/dist/features/{claude-code-agent-loader → agent-loader}/types.d.ts +0 -0
  128. /package/dist/features/{claude-code-command-loader → command-loader}/index.d.ts +0 -0
  129. /package/dist/features/{claude-code-command-loader → command-loader}/types.d.ts +0 -0
  130. /package/dist/features/{claude-code-session-state → session-state}/index.d.ts +0 -0
  131. /package/dist/features/{claude-code-session-state → session-state}/state.d.ts +0 -0
  132. /package/dist/features/{claude-code-mcp-loader → skill-mcp-manager}/env-expander.d.ts +0 -0
  133. /package/dist/features/{claude-tasks → task-storage}/storage.d.ts +0 -0
  134. /package/dist/features/{claude-tasks → task-storage}/types.d.ts +0 -0
@@ -1,6 +1,6 @@
1
1
  import type { HookName, MatrixxConfig } from "../../config";
2
2
  import type { BackgroundManager } from "../../features/background-agent";
3
- import { createArchitectHook, createBackgroundNotificationHook, createCompactionContextInjector, createCompactionTodoPreserverHook, createStopContinuationGuardHook, createTodoContinuationEnforcer } from "../../hooks";
3
+ import { createArchitectHook, createBackgroundNotificationHook, createCompactionContextInjector, createCompactionTodoPreserverHook, createPlanPersister, createStopContinuationGuardHook, createTodoContinuationEnforcer } from "../../hooks";
4
4
  import type { PluginContext } from "../types";
5
5
  import { createUnstableAgentBabysitter } from "../unstable-agent-babysitter";
6
6
  export type ContinuationHooks = {
@@ -11,6 +11,7 @@ export type ContinuationHooks = {
11
11
  unstableAgentBabysitter: ReturnType<typeof createUnstableAgentBabysitter> | null;
12
12
  backgroundNotificationHook: ReturnType<typeof createBackgroundNotificationHook> | null;
13
13
  architectHook: ReturnType<typeof createArchitectHook> | null;
14
+ planPersister: ReturnType<typeof createPlanPersister> | null;
14
15
  };
15
16
  type SessionRecovery = {
16
17
  setOnAbortCallback: (callback: (sessionID: string) => void) => void;
@@ -8,6 +8,7 @@ export declare function createCoreHooks(args: {
8
8
  }): {
9
9
  keywordDetector: ReturnType<typeof import("../../hooks").createKeywordDetectorHook> | null;
10
10
  contextInjectorMessagesTransform: ReturnType<typeof import("../../features/context-injector").createContextInjectorMessagesTransformHook>;
11
+ envContextInjector: ReturnType<typeof import("../../hooks").createEnvContextInjectorHook> | null;
11
12
  thinkingBlockValidator: ReturnType<typeof import("../../hooks").createThinkingBlockValidatorHook> | null;
12
13
  toolPairValidator: ReturnType<typeof import("../../hooks").createToolPairValidatorHook> | null;
13
14
  designIntentPreserver: ReturnType<typeof import("../../hooks").createDesignIntentPreserverHook> | null;
@@ -1,10 +1,11 @@
1
1
  import type { MatrixxConfig } from "../../config";
2
2
  import { createContextInjectorMessagesTransformHook } from "../../features/context-injector";
3
- import { createDesignIntentPreserverHook, createKeywordDetectorHook, createThinkingBlockValidatorHook, createToolPairValidatorHook } from "../../hooks";
3
+ import { createDesignIntentPreserverHook, createEnvContextInjectorHook, createKeywordDetectorHook, createThinkingBlockValidatorHook, createToolPairValidatorHook } from "../../hooks";
4
4
  import type { PluginContext } from "../types";
5
5
  export type TransformHooks = {
6
6
  keywordDetector: ReturnType<typeof createKeywordDetectorHook> | null;
7
7
  contextInjectorMessagesTransform: ReturnType<typeof createContextInjectorMessagesTransformHook>;
8
+ envContextInjector: ReturnType<typeof createEnvContextInjectorHook> | null;
8
9
  thinkingBlockValidator: ReturnType<typeof createThinkingBlockValidatorHook> | null;
9
10
  toolPairValidator: ReturnType<typeof createToolPairValidatorHook> | null;
10
11
  designIntentPreserver: ReturnType<typeof createDesignIntentPreserverHook> | null;
@@ -24,5 +24,5 @@ export declare function getDisabledSets(config: MatrixxConfig): DisabledSets;
24
24
  */
25
25
  export declare function _resetDisabledSetsCacheForTesting(): void;
26
26
  export declare function mergeConfigs(base: MatrixxConfig, override: MatrixxConfig): MatrixxConfig;
27
- export declare function loadPluginConfig(directory: string, ctx: unknown): MatrixxConfig;
27
+ export declare function loadPluginConfig(directory: string, ctx: unknown): Promise<MatrixxConfig>;
28
28
  export {};
@@ -1,5 +1,7 @@
1
1
  import type { MatrixxConfig } from "../config";
2
2
  import type { PluginComponents } from "./plugin-components-loader";
3
+ export declare function setAvailableToolNames(names: string[]): void;
4
+ export declare function getAvailableToolNames(): string[];
3
5
  export declare function applyAgentConfig(params: {
4
6
  config: Record<string, unknown>;
5
7
  pluginConfig: MatrixxConfig;
@@ -17,6 +17,6 @@ export type PluginComponents = {
17
17
  error: string;
18
18
  }>;
19
19
  };
20
- export declare function loadPluginComponents(params: {
20
+ export declare function loadPluginComponents(_params: {
21
21
  pluginConfig: MatrixxConfig;
22
22
  }): Promise<PluginComponents>;
@@ -19,5 +19,6 @@ export declare function buildOracleAgentConfig(params: {
19
19
  pluginOracleOverride: OracleOverride | undefined;
20
20
  userCategories: Record<string, CategoryConfig> | undefined;
21
21
  currentModel: string | undefined;
22
+ globalOverrideModel?: string;
22
23
  }): Promise<Record<string, unknown>>;
23
24
  export {};
@@ -1,7 +1,7 @@
1
1
  export * from "./agent-tool-restrictions";
2
2
  export * from "./agent-variant";
3
3
  export * from "./binary-downloader";
4
- export * from "./claude-config-dir";
4
+ export * from "./code-patterns";
5
5
  export * from "./code-patterns";
6
6
  export * from "./command-executor";
7
7
  export * from "./config-errors";
@@ -2,5 +2,9 @@ import type { CategoriesConfig, CategoryConfig } from "../config/schema";
2
2
  /**
3
3
  * Merge default and user categories, filtering out disabled ones.
4
4
  * Single source of truth for category merging across the codebase.
5
+ *
6
+ * The built-in `DEFAULT_CATEGORIES` registry is now tier-based. Before
7
+ * returning, the tier fields are resolved against the live provider cache
8
+ * (or the static fallback) so callers always see concrete `model:` strings.
5
9
  */
6
10
  export declare function mergeCategories(userCategories?: CategoriesConfig): Record<string, CategoryConfig>;
@@ -1,6 +1,9 @@
1
1
  import type { FallbackEntry } from "./model-requirements";
2
2
  export type ModelResolutionRequest = {
3
3
  intent?: {
4
+ /** Global override for all agents and categories — set via the global_model config.
5
+ * Highest priority; checked before everything else. */
6
+ globalOverrideModel?: string;
4
7
  uiSelectedModel?: string;
5
8
  userModel?: string;
6
9
  categoryDefaultModel?: string;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Tier registry — abstract model classifications resolved against the live provider list.
3
+ *
4
+ * Tiers are matched by regex against "provider/model" strings, with a `providerPriority`
5
+ * list to choose between providers when multiple match. A `staticFallback` is used at
6
+ * first run when the live provider list is not yet available.
7
+ *
8
+ * Adding a new model does NOT require code changes — the regex patterns intentionally
9
+ * match model families (e.g. `claude-opus`) so a new opus-4-7 model is picked up
10
+ * automatically.
11
+ */
12
+ export type TierName = "free" | "fast" | "standard" | "premium" | "frontier";
13
+ export interface TierSpec {
14
+ name: TierName;
15
+ /** Provider priority — first provider with a matching model wins. */
16
+ providerPriority: string[];
17
+ /** Regex tested against each "provider/model" string in the live provider list. */
18
+ modelPattern: RegExp;
19
+ /** Tier to recurse into if this tier cannot be satisfied. */
20
+ fallbackTier?: TierName;
21
+ /** Static fallbacks used at first run when the live provider list is empty
22
+ * but the connected providers cache already lists which providers are reachable. */
23
+ staticFallback: {
24
+ providers: string[];
25
+ model: string;
26
+ variant?: string;
27
+ }[];
28
+ }
29
+ export declare const TIER_SPECS: Record<TierName, TierSpec>;
30
+ export declare const TIER_NAMES: TierName[];
31
+ export declare function parseTierReference(value: string | undefined | null): TierName | null;
@@ -0,0 +1,26 @@
1
+ import { parseTierReference, type TierName } from "./model-tiers";
2
+ export interface TierResolverContext {
3
+ availableModels: Set<string>;
4
+ connectedProviders: string[] | null;
5
+ }
6
+ export type TierProvenance = "tier-resolved" | "tier-static-fallback";
7
+ export interface TierResolutionResult {
8
+ model: string;
9
+ provenance: TierProvenance;
10
+ tier: TierName;
11
+ }
12
+ /**
13
+ * Resolve a tier alias to a concrete "provider/model" string.
14
+ *
15
+ * Strategy:
16
+ * 1. Live resolution: walk `providerPriority`, test `modelPattern` against
17
+ * each `provider/model` in the available set.
18
+ * 2. Static fallback: pick the first static fallback whose provider is
19
+ * connected (used at first run when the live cache is cold).
20
+ * 3. Recurse into `fallbackTier` if defined.
21
+ *
22
+ * Returns null when no match is possible (no live models, no static fallback
23
+ * available, no fallback tier).
24
+ */
25
+ export declare function resolveTier(tier: TierName, ctx: TierResolverContext): TierResolutionResult | null;
26
+ export { parseTierReference };
@@ -0,0 +1 @@
1
+ export declare const BDD_CREATE_CONTRACT_TOOL_NAME = "bdd_create_contract";
@@ -0,0 +1,3 @@
1
+ export * from "./constants";
2
+ export { createBddCreateContractTool } from "./tools";
3
+ export * from "./types";
@@ -0,0 +1,3 @@
1
+ import { type ToolDefinition } from "@opencode-ai/plugin";
2
+ /** Create a tool that produces a Contract JSON from a parsed Gherkin AST. */
3
+ export declare function createBddCreateContractTool(): ToolDefinition;
@@ -0,0 +1,12 @@
1
+ export interface BddCreateContractArgs {
2
+ parsedAst: string;
3
+ sourceFile: string;
4
+ sourceText: string;
5
+ force?: boolean;
6
+ outputPath?: string;
7
+ }
8
+ export interface BddCreateContractResult {
9
+ success: boolean;
10
+ outputPath?: string;
11
+ error?: string;
12
+ }
@@ -0,0 +1 @@
1
+ export declare const BDD_PARSE_GHERKIN_TOOL_NAME = "bdd_parse_gherkin";
@@ -0,0 +1,3 @@
1
+ export * from "./constants";
2
+ export { createBddParseGherkinTool } from "./tools";
3
+ export * from "./types";
@@ -0,0 +1,5 @@
1
+ import { type ToolDefinition } from "@opencode-ai/plugin";
2
+ /**
3
+ * Create a tool that parses Gherkin .feature files into structured JSON AST.
4
+ */
5
+ export declare function createBddParseGherkinTool(): ToolDefinition;
@@ -0,0 +1,9 @@
1
+ export interface BddParseGherkinArgs {
2
+ filePath: string;
3
+ includeSourceMap?: boolean;
4
+ }
5
+ export interface BddParseGherkinResult {
6
+ success: boolean;
7
+ data?: Record<string, unknown>;
8
+ error?: string;
9
+ }
@@ -0,0 +1,10 @@
1
+ import type { Contract } from "../../features/bdd/schema";
2
+ import type { BddPipelineResult, BddPipelineStageName, BddPipelineStageResult } from "./types";
3
+ export declare function stageStatusBadge(stage: BddPipelineStageResult): string;
4
+ export declare function buildAnnotationsSection(contract: Contract): string;
5
+ export declare function buildFrontendMappingSection(contract: Contract, stage: BddPipelineStageResult): string;
6
+ export declare function buildBackendMappingSection(contract: Contract, stage: BddPipelineStageResult): string;
7
+ export declare function buildTestCoverageSection(result: BddPipelineResult): string;
8
+ export declare function buildAssumptionsSection(contract: Contract): string;
9
+ export declare function buildAmbiguitiesSection(result: BddPipelineResult): string;
10
+ export declare function buildFilesGeneratedSection(result: BddPipelineResult, featureDir: string, order: readonly BddPipelineStageName[]): string;
@@ -0,0 +1,9 @@
1
+ import type { Contract } from "../../features/bdd/schema";
2
+ import type { BddPipelineResult } from "./types";
3
+ export { stageStatusBadge } from "./analysis-report-sections";
4
+ export interface AnalysisReportInput {
5
+ result: BddPipelineResult;
6
+ contract: Contract;
7
+ featureDir: string;
8
+ }
9
+ export declare function buildAnalysisReport(input: AnalysisReportInput): string;
@@ -0,0 +1,4 @@
1
+ export declare const BDD_PIPELINE_TOOL_NAME = "bdd_pipeline_run";
2
+ export declare const BDD_PIPELINE_DESCRIPTION: string;
3
+ export declare const PIPELINE_REQUIRED_OUTPUTS: readonly ["ANALYSIS.md", "cucumber.cjs", "run-tests.sh"];
4
+ export declare const PIPELINE_STAGES: readonly ["tests", "frontend", "backend"];
@@ -0,0 +1,5 @@
1
+ export declare function isFeaturePath(input: string): boolean;
2
+ export declare function looksLikeGlob(input: string): boolean;
3
+ export declare function listFeatureFilesInDir(input: string): string[];
4
+ export declare function expandGlob(input: string): string[];
5
+ export declare function resolveFeaturePaths(inputs: string[]): string[];
@@ -0,0 +1,3 @@
1
+ export * from "./constants";
2
+ export { createBddPipelineTool } from "./tools";
3
+ export * from "./types";
@@ -0,0 +1,6 @@
1
+ import type { BddPipelineContext, BddPipelineDeps, BddPipelineResult } from "./types";
2
+ export declare function runBddPipeline(args: {
3
+ featurePaths: string[];
4
+ outDir: string;
5
+ force?: boolean;
6
+ }, ctxIn: Omit<BddPipelineContext, "outDir" | "force" | "featureName">, deps: BddPipelineDeps): Promise<BddPipelineResult>;
@@ -0,0 +1,14 @@
1
+ import type { BackgroundManager } from "../../features/background-agent/manager";
2
+ import type { BddPipelineStageName, BddPipelineStageResult } from "./types";
3
+ export interface SpawnSubagentOptions {
4
+ manager: BackgroundManager;
5
+ stage: BddPipelineStageName;
6
+ prompt: string;
7
+ contractPath: string;
8
+ parentSessionID: string;
9
+ parentMessageID: string;
10
+ parentAgent?: string;
11
+ abort?: AbortSignal;
12
+ outDir: string;
13
+ }
14
+ export declare function spawnStageSubagent(opts: SpawnSubagentOptions): Promise<BddPipelineStageResult>;
@@ -0,0 +1,5 @@
1
+ import { type ToolDefinition } from "@opencode-ai/plugin";
2
+ import type { BackgroundManager } from "../../features/background-agent/manager";
3
+ export declare function createBddPipelineTool(opts: {
4
+ manager: BackgroundManager;
5
+ }): ToolDefinition;
@@ -0,0 +1,74 @@
1
+ import type { Contract } from "../../features/bdd/schema";
2
+ export interface BddPipelineArgs {
3
+ featurePaths: string[];
4
+ outDir: string;
5
+ force?: boolean;
6
+ }
7
+ export type BddPipelineStageName = "tests" | "frontend" | "backend";
8
+ export type BddPipelineStageStatus = "completed" | "failed" | "timeout";
9
+ export interface BddPipelineStageResult {
10
+ stage: BddPipelineStageName;
11
+ status: BddPipelineStageStatus;
12
+ filesCreated: string[];
13
+ testsRun: number;
14
+ testsPassed: number;
15
+ testsFailed: number;
16
+ testOutput: string;
17
+ error?: string;
18
+ }
19
+ export type BddPipelineStatus = "PASS" | "FAIL";
20
+ export interface BddPipelineResult {
21
+ feature: string;
22
+ sourceFile: string;
23
+ contractPath: string;
24
+ status: BddPipelineStatus;
25
+ stages: Record<BddPipelineStageName, BddPipelineStageResult>;
26
+ missingOutputs: string[];
27
+ ambiguities: string[];
28
+ startedAt: string;
29
+ finishedAt: string;
30
+ error?: string;
31
+ }
32
+ export interface BddPipelineContext {
33
+ parentSessionID: string;
34
+ parentMessageID: string;
35
+ parentAgent?: string;
36
+ abort?: AbortSignal;
37
+ outDir: string;
38
+ force: boolean;
39
+ featureName: string;
40
+ }
41
+ export interface ParseFeatureResult {
42
+ success: boolean;
43
+ data?: unknown;
44
+ error?: string;
45
+ }
46
+ export interface CreateContractResult {
47
+ success: boolean;
48
+ outputPath?: string;
49
+ error?: string;
50
+ }
51
+ export interface EnrichContractResult {
52
+ success: boolean;
53
+ contract?: Contract;
54
+ error?: string;
55
+ }
56
+ export interface GateResult {
57
+ ok: boolean;
58
+ missing: string[];
59
+ }
60
+ export interface BddPipelineDeps {
61
+ parseFeature: (path: string) => Promise<ParseFeatureResult>;
62
+ createContract: (args: {
63
+ parsedAst: string;
64
+ sourceFile: string;
65
+ sourceText: string;
66
+ force?: boolean;
67
+ outputPath?: string;
68
+ }) => Promise<CreateContractResult>;
69
+ enrichContract: (contractPath: string) => Promise<EnrichContractResult>;
70
+ spawnSubagent: (stage: BddPipelineStageName, prompt: string, contract: Contract, ctx: BddPipelineContext) => Promise<BddPipelineStageResult>;
71
+ gateRequiredOutputs: (featureDir: string) => Promise<GateResult>;
72
+ writeAnalysis: (featureDir: string, report: BddPipelineResult) => Promise<void>;
73
+ readFeatureSource: (path: string) => Promise<string>;
74
+ }
@@ -0,0 +1 @@
1
+ export { createBddValidateContractTool } from "./tools";
@@ -0,0 +1,21 @@
1
+ import { type ToolDefinition } from "@opencode-ai/plugin";
2
+ /**
3
+ * The bdd_validate_contract tool reads a contract JSON from disk and
4
+ * validates it against the strict ContractSchema. It is the single source
5
+ * of truth for what a valid contract looks like.
6
+ *
7
+ * Use this tool:
8
+ * - After the bdd-contract agent edits a contract file in any way
9
+ * (read-back-then-validate is the only way to be sure the on-disk
10
+ * bytes conform to the schema).
11
+ * - In a CI gate that re-validates every contract in the repo.
12
+ * - Whenever the bdd-pipeline runs as a pre-flight check before
13
+ * bdd-frontend / bdd-backend / bdd-tests phase starts.
14
+ *
15
+ * Returns:
16
+ * { success: true, contract } -- when validation passes
17
+ * { success: false, errors: <ZodFlatten> } -- when validation fails
18
+ * { success: false, error: <string> } -- when the file is missing,
19
+ * unreadable, or not JSON
20
+ */
21
+ export declare function createBddValidateContractTool(): ToolDefinition;
@@ -1,9 +1,11 @@
1
1
  import type { CategoriesConfig, CategoryConfig } from "../../config/schema";
2
+ import type { TierResolverContext } from "../../shared/tier-resolver";
2
3
  interface ResolveCategoryConfigOptions {
3
4
  userCategories?: CategoriesConfig;
4
5
  inheritedModel?: string;
5
6
  systemDefaultModel?: string;
6
7
  availableModels?: Set<string>;
8
+ tierContext?: TierResolverContext;
7
9
  }
8
10
  interface ResolveCategoryConfigResult {
9
11
  config: CategoryConfig;
@@ -14,6 +16,11 @@ interface ResolveCategoryConfigResult {
14
16
  /**
15
17
  * Resolve the configuration for a given category name.
16
18
  * Merges default and user configurations, handles model resolution.
19
+ *
20
+ * Tier resolution: both `userConfig.tier` and `defaultConfig.tier` are
21
+ * resolved against the live provider list (`tierContext`). An explicit
22
+ * `userConfig.model` always wins; an explicit `userConfig.tier` wins
23
+ * over the default tier; otherwise the default tier is used.
17
24
  */
18
25
  export declare function resolveCategoryConfig(categoryName: string, options: ResolveCategoryConfigOptions): ResolveCategoryConfigResult | null;
19
26
  export {};
@@ -13,6 +13,12 @@ export interface CategoryResolutionResult {
13
13
  modelInfo: ModelFallbackInfo | undefined;
14
14
  actualModel: string | undefined;
15
15
  isUnstableAgent: boolean;
16
+ /** The complexity level that was applied (auto-scored or caller-provided) */
17
+ complexityApplied?: import("./complexity-types").ComplexityLevel;
18
+ /** If true, model was downgraded due to low complexity */
19
+ complexityDowngraded?: boolean;
20
+ /** Human-readable note about complexity-based model selection */
21
+ _complexityNote?: string;
16
22
  error?: string;
17
23
  }
18
24
  export declare function resolveCategoryExecution(args: DelegateTaskArgs, executorCtx: ExecutorContext, inheritedModel: string | undefined, systemDefaultModel: string | undefined): Promise<CategoryResolutionResult>;
@@ -0,0 +1,24 @@
1
+ import type { ComplexityLevel } from "./complexity-types";
2
+ /**
3
+ * Built-in complexity-to-model downgrade targets per category.
4
+ * Key: category name, Value: map of complexity level → model string.
5
+ * Only levels 1-2 are downgradable; levels 3+ use the category's resolved model.
6
+ */
7
+ export declare const BUILTIN_COMPLEXITY_DOWNGRADES: Record<string, Partial<Record<ComplexityLevel, string>>>;
8
+ /**
9
+ * Resolve the model for a given category and complexity level.
10
+ *
11
+ * Returns the original model unchanged if:
12
+ * - Complexity is 3+ (not eligible for downgrade)
13
+ * - No downgrade target exists for this category/level combination
14
+ *
15
+ * @param category - The task category name
16
+ * @param complexity - The complexity level (1-5)
17
+ * @param originalModel - The currently resolved model string
18
+ * @param userDowngrades - Optional per-category user override from CategoryConfig
19
+ * @returns The model to use and whether a downgrade was applied
20
+ */
21
+ export declare function resolveComplexityModel(category: string, complexity: ComplexityLevel, originalModel: string, userDowngrades?: Record<string, string>): {
22
+ model: string;
23
+ downgraded: boolean;
24
+ };
@@ -0,0 +1,31 @@
1
+ import type { ComplexityLevel } from "./complexity-types";
2
+ export interface ComplexityScorerInput {
3
+ /** Short task description (3-5 words) */
4
+ description?: string;
5
+ /** Full task prompt content */
6
+ prompt?: string;
7
+ /** Skill names requested */
8
+ loadSkills?: string[];
9
+ /** Task category name */
10
+ category?: string;
11
+ }
12
+ /**
13
+ * Category baseline complexity levels.
14
+ * Used when no keyword signal is present to provide a sensible default.
15
+ */
16
+ export declare const CATEGORY_BASELINE: Partial<Record<string, ComplexityLevel>>;
17
+ /**
18
+ * Auto-score complexity from task context.
19
+ *
20
+ * Heuristic:
21
+ * 1. Start with category baseline (defaults to 3 for unknown categories)
22
+ * 2. Keyword detection in description/prompt can override:
23
+ * - Trivial keywords → level 1 (unless complex keywords also present)
24
+ * - Simple keywords → level 2 (unless complex keywords also present)
25
+ * - Architectural keywords → level 5
26
+ * - Complex keywords → level 4
27
+ * 3. Skills signal: many skills bump minimum score
28
+ *
29
+ * Returns a ComplexityLevel (1-5).
30
+ */
31
+ export declare function autoScoreComplexity(input: ComplexityScorerInput): ComplexityLevel;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Complexity level for per-task model routing.
3
+ * 1 = trivial, 2 = simple, 3 = standard, 4 = complex, 5 = architectural
4
+ */
5
+ export type ComplexityLevel = 1 | 2 | 3 | 4 | 5;
6
+ export declare const COMPLEXITY_LEVELS: readonly [1, 2, 3, 4, 5];
7
+ export type ComplexityInput = ComplexityLevel | "auto";
8
+ export declare const COMPLEXITY_DESCRIPTIONS: Record<ComplexityLevel, string>;
9
+ /** Returns true if this complexity level is eligible for model downgrade. */
10
+ export declare function isDowngradable(level: ComplexityLevel): boolean;
@@ -7,6 +7,7 @@ export interface ExecutorContext {
7
7
  directory: string;
8
8
  userCategories?: CategoriesConfig;
9
9
  mouseModel?: string;
10
+ globalModel?: string;
10
11
  browserProvider?: BrowserAutomationProvider;
11
12
  agentOverrides?: AgentOverrides;
12
13
  onSyncSessionCreated?: (event: {
@@ -1,3 +1,6 @@
1
+ export { BUILTIN_COMPLEXITY_DOWNGRADES, resolveComplexityModel } from "./complexity-constants";
2
+ export { autoScoreComplexity } from "./complexity-scorer";
3
+ export type { ComplexityInput, ComplexityLevel } from "./complexity-types";
1
4
  export * from "./constants";
2
5
  export type { BuildSystemContentInput, DelegateTaskToolOptions, SyncSessionCreatedEvent } from "./tools";
3
6
  export { buildSystemContent, createDelegateTask, resolveCategoryConfig } from "./tools";
@@ -16,6 +16,12 @@ export interface DelegateTaskArgs {
16
16
  task_id: string;
17
17
  task_dir?: string;
18
18
  };
19
+ /**
20
+ * Task complexity level (1-5) or "auto" for automatic scoring.
21
+ * When < 3, model may be downgraded to a cheaper tier.
22
+ * Default: "auto" (scored from prompt/description heuristics)
23
+ */
24
+ complexity?: import("./complexity-types").ComplexityLevel | "auto";
19
25
  }
20
26
  export interface ToolContextWithMetadata {
21
27
  sessionID: string;
@@ -55,6 +61,8 @@ export interface DelegateTaskToolOptions {
55
61
  */
56
62
  availableModelsOverride?: Set<string>;
57
63
  userCategories?: CategoriesConfig;
64
+ /** Global provider/model override for ALL tasks (overrides all category models) */
65
+ globalModel?: string;
58
66
  mouseModel?: string;
59
67
  browserProvider?: BrowserAutomationProvider;
60
68
  disabledSkills?: Set<string>;
@@ -1,5 +1,9 @@
1
1
  import { lspManager } from "./lsp";
2
2
  export { createAstGrepTools } from "./ast-grep";
3
+ export { createBddCreateContractTool } from "./bdd-create-contract";
4
+ export { createBddParseGherkinTool } from "./bdd-parse-gherkin";
5
+ export { createBddPipelineTool } from "./bdd-pipeline";
6
+ export { createBddValidateContractTool } from "./bdd-validate-contract";
3
7
  export { createGlobTools } from "./glob";
4
8
  export { createGrepTools } from "./grep";
5
9
  export { createHandoffTools } from "./handoff";
@@ -1,5 +1,5 @@
1
1
  import type { PluginInput } from "@opencode-ai/plugin";
2
- import type { Task } from "../../features/claude-tasks/types.ts";
2
+ import type { Task } from "../../features/task-storage/types.ts";
3
3
  export interface TodoInfo {
4
4
  id?: string;
5
5
  content: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-matrixx",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -49,16 +49,17 @@
49
49
  "license": "SUL-1.0",
50
50
  "repository": {
51
51
  "type": "git",
52
- "url": "git+https://github.com/klpanagi/matrixx.git"
52
+ "url": "git+https://github.com/klpanagi/opencode-matrixx.git"
53
53
  },
54
54
  "bugs": {
55
- "url": "https://github.com/klpanagi/matrixx/issues"
55
+ "url": "https://github.com/klpanagi/opencode-matrixx/issues"
56
56
  },
57
- "homepage": "https://github.com/klpanagi/matrixx#readme",
57
+ "homepage": "https://github.com/klpanagi/opencode-matrixx#readme",
58
58
  "dependencies": {
59
59
  "@ast-grep/cli": "^0.40.0",
60
60
  "@ast-grep/napi": "^0.40.0",
61
61
  "@code-yeongyu/comment-checker": "^0.6.1",
62
+ "@cucumber/gherkin": "^34.0.0",
62
63
  "@modelcontextprotocol/sdk": "^1.25.1",
63
64
  "@opencode-ai/plugin": "1.3.15",
64
65
  "@opencode-ai/sdk": "1.3.15",
@@ -70,9 +71,23 @@
70
71
  },
71
72
  "devDependencies": {
72
73
  "@biomejs/biome": "^2.5.0",
74
+ "@cucumber/cucumber": "^13.0.0",
75
+ "@playwright/test": "^1.61.1",
76
+ "@testing-library/jest-dom": "^6.6.3",
77
+ "@testing-library/react": "^16.3.0",
78
+ "@testing-library/user-event": "^14.6.1",
79
+ "@types/chai": "^5.2.3",
73
80
  "@types/js-yaml": "^4.0.9",
74
81
  "@types/picomatch": "^3.0.2",
82
+ "@types/react": "^19.0.0",
83
+ "@types/react-dom": "^19.0.0",
75
84
  "bun-types": "1.3.6",
85
+ "chai": "^6.2.2",
86
+ "happy-dom": "^15.11.7",
87
+ "jsdom": "^29.1.1",
88
+ "react": "^19.0.0",
89
+ "react-dom": "^19.0.0",
90
+ "tsx": "^4.23.0",
76
91
  "typescript": "^5.7.3"
77
92
  },
78
93
  "trustedDependencies": [
@@ -1,2 +0,0 @@
1
- import type { AgentConfig } from "@opencode-ai/sdk";
2
- export declare function applyEnvironmentContext(config: AgentConfig, directory?: string): AgentConfig;
@@ -1,4 +0,0 @@
1
- import type { MatrixxConfig } from "./schema/matrixx-config";
2
- export declare const PROFILE_NAMES: readonly ["free", "budget", "economy", "balanced", "performance", "go", "xiaomi-ultimate", "go-ultimate", "go-trio", "go-duo"];
3
- export type ProfileName = (typeof PROFILE_NAMES)[number];
4
- export declare function expandProfile(profile: ProfileName): Partial<MatrixxConfig>;
@@ -1,10 +0,0 @@
1
- import { z } from "zod";
2
- export declare const ClaudeCodeConfigSchema: z.ZodObject<{
3
- mcp: z.ZodOptional<z.ZodBoolean>;
4
- commands: z.ZodOptional<z.ZodBoolean>;
5
- skills: z.ZodOptional<z.ZodBoolean>;
6
- agents: z.ZodOptional<z.ZodBoolean>;
7
- plugins: z.ZodOptional<z.ZodBoolean>;
8
- plugins_override: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
9
- }, z.core.$strip>;
10
- export type ClaudeCodeConfig = z.infer<typeof ClaudeCodeConfigSchema>;