opencode-matrixx 2.6.3 → 2.6.4

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 (84) hide show
  1. package/dist/agents/dynamic-agent-prompt-builder.d.ts +5 -3
  2. package/dist/agents/mouse/agent.d.ts +1 -1
  3. package/dist/agents/oracle/behavioral-summary.d.ts +1 -1
  4. package/dist/agents/oracle/identity-constraints.d.ts +1 -1
  5. package/dist/agents/oracle/plan-generation.d.ts +1 -1
  6. package/dist/agents/oracle/plan-template.d.ts +1 -1
  7. package/dist/agents/oracle/system-prompt.d.ts +4 -3
  8. package/dist/agents/smith.d.ts +1 -1
  9. package/dist/agents/types.d.ts +1 -1
  10. package/dist/cli.js +115 -10
  11. package/dist/config/migrations/index.d.ts +1 -0
  12. package/dist/config/migrations/model-migration.d.ts +18 -0
  13. package/dist/config/resolve-tiers.d.ts +1 -1
  14. package/dist/config/schema/failure-counter.d.ts +7 -0
  15. package/dist/config/schema/hooks.d.ts +1 -0
  16. package/dist/config/schema/matrixx-config.d.ts +43 -0
  17. package/dist/config/schema/model-config.d.ts +81 -0
  18. package/dist/config/schema/morpheus.d.ts +4 -0
  19. package/dist/config/schema.d.ts +2 -0
  20. package/dist/create-hooks.d.ts +1 -0
  21. package/dist/features/background-agent/manager.d.ts +8 -0
  22. package/dist/features/builtin-commands/templates/start-work.d.ts +1 -1
  23. package/dist/features/mission-state/plan-storage.d.ts +1 -0
  24. package/dist/features/mission-state/plan-storage.test.d.ts +1 -0
  25. package/dist/features/session-state/state.d.ts +26 -0
  26. package/dist/features/session-state/state.test.d.ts +1 -0
  27. package/dist/features/task-storage/types.d.ts +1 -0
  28. package/dist/hooks/context-mode-enforcer/constants.d.ts +1 -1
  29. package/dist/hooks/failure-counter/counter.d.ts +7 -0
  30. package/dist/hooks/failure-counter/counter.test.d.ts +1 -0
  31. package/dist/hooks/failure-counter/hook.d.ts +18 -0
  32. package/dist/hooks/failure-counter/index.d.ts +3 -0
  33. package/dist/hooks/failure-counter/patterns.d.ts +6 -0
  34. package/dist/hooks/failure-counter/patterns.test.d.ts +1 -0
  35. package/dist/hooks/index.d.ts +1 -0
  36. package/dist/hooks/interactive-bash-session/hook.test.d.ts +1 -0
  37. package/dist/hooks/keyword-detector/analyze/default.d.ts +1 -1
  38. package/dist/hooks/keyword-detector/search/default.d.ts +1 -1
  39. package/dist/hooks/keyword-detector/ultrawork/deepseek.d.ts +1 -1
  40. package/dist/hooks/keyword-detector/ultrawork/default.d.ts +1 -1
  41. package/dist/hooks/keyword-detector/ultrawork/gemini.d.ts +1 -1
  42. package/dist/hooks/keyword-detector/ultrawork/glm.d.ts +1 -1
  43. package/dist/hooks/keyword-detector/ultrawork/mimo.d.ts +1 -1
  44. package/dist/hooks/stop-continuation-guard/hook.d.ts +3 -2
  45. package/dist/hooks/stop-continuation-guard/repro.test.d.ts +1 -0
  46. package/dist/hooks/task-continuation-enforcer/awaiting-user.test.d.ts +1 -0
  47. package/dist/hooks/task-continuation-enforcer/continuation-injection.d.ts +2 -0
  48. package/dist/hooks/task-continuation-enforcer/countdown.d.ts +2 -0
  49. package/dist/hooks/task-continuation-enforcer/handler.d.ts +2 -0
  50. package/dist/hooks/task-continuation-enforcer/idle-event.d.ts +2 -0
  51. package/dist/hooks/task-continuation-enforcer/staleness.d.ts +16 -0
  52. package/dist/hooks/task-continuation-enforcer/staleness.test.d.ts +1 -0
  53. package/dist/hooks/task-continuation-enforcer/todo.d.ts +15 -0
  54. package/dist/hooks/task-continuation-enforcer/types.d.ts +6 -0
  55. package/dist/hooks/task-edit-guard/constants.d.ts +2 -0
  56. package/dist/hooks/todo-continuation-enforcer/awaiting-user.test.d.ts +1 -0
  57. package/dist/hooks/todo-continuation-enforcer/types.d.ts +3 -0
  58. package/dist/index.js +28049 -26859
  59. package/dist/matrixx.schema.json +228 -1
  60. package/dist/plugin/hooks/create-core-hooks.d.ts +1 -0
  61. package/dist/plugin/hooks/create-session-hooks.d.ts +2 -1
  62. package/dist/plugin-handlers/oracle-agent-config-builder.d.ts +2 -1
  63. package/dist/shared/awaiting-user.d.ts +12 -0
  64. package/dist/shared/merge-categories.d.ts +12 -1
  65. package/dist/shared/model-requirements.d.ts +9 -0
  66. package/dist/shared/model-tiers.d.ts +28 -15
  67. package/dist/shared/tier-resolver.d.ts +9 -9
  68. package/dist/tools/delegate-task/categories.d.ts +12 -1
  69. package/dist/tools/delegate-task/complexity-constants.d.ts +15 -11
  70. package/dist/tools/delegate-task/executor-types.d.ts +4 -1
  71. package/dist/tools/delegate-task/index.d.ts +1 -1
  72. package/dist/tools/delegate-task/types.d.ts +4 -1
  73. package/dist/tools/index.d.ts +5 -0
  74. package/dist/tools/plan/constants.d.ts +10 -0
  75. package/dist/tools/plan/index.d.ts +6 -0
  76. package/dist/tools/plan/plan-create.d.ts +3 -0
  77. package/dist/tools/plan/plan-delete.d.ts +3 -0
  78. package/dist/tools/plan/plan-list.d.ts +3 -0
  79. package/dist/tools/plan/plan-read.d.ts +3 -0
  80. package/dist/tools/plan/plan-update.d.ts +3 -0
  81. package/dist/tools/plan/types.d.ts +28 -0
  82. package/dist/tools/task/constants.d.ts +5 -0
  83. package/dist/tools/task/types.d.ts +2 -0
  84. package/package.json +1 -1
@@ -55,7 +55,7 @@ export interface AgentPromptMetadata {
55
55
  export declare function isGptModel(model: string): boolean;
56
56
  /**
57
57
  * Detect Anthropic/Claude models by provider or model name.
58
- * Matches: "anthropic/claude-*", "google-vertex-anthropic/claude-*", etc.
58
+ * Matches: "<provider>/<model>" e.g., provider/model strings containing relevant indicators — replace with live model from provider.list
59
59
  */
60
60
  export declare function isAnthropicModel(model: string): boolean;
61
61
  export declare function isQwenModel(model: string): boolean;
package/dist/cli.js CHANGED
@@ -46,6 +46,7 @@ var __export = (target, all) => {
46
46
  set: __exportSetter.bind(all, name)
47
47
  });
48
48
  };
49
+ var __require = import.meta.require;
49
50
 
50
51
  // node_modules/sisteransi/src/index.js
51
52
  var require_src = __commonJS(function(exports, module) {
@@ -128,6 +129,9 @@ function getCacheDir() {
128
129
  function getOmoOpenCodeCacheDir() {
129
130
  return path.join(getCacheDir(), "matrixx");
130
131
  }
132
+ function getOpenCodeCacheDir() {
133
+ return path.join(getCacheDir(), "opencode");
134
+ }
131
135
 
132
136
  // src/shared/logger.ts
133
137
  import * as fs from "fs";
@@ -16127,6 +16131,13 @@ var ExperimentalConfigSchema = exports_external.object({
16127
16131
  hashline_edit: exports_external.boolean().optional()
16128
16132
  });
16129
16133
 
16134
+ // src/config/schema/failure-counter.ts
16135
+ var FailureCounterConfigSchema = exports_external.object({
16136
+ enabled: exports_external.boolean().default(true),
16137
+ threshold: exports_external.number().min(1).max(10).default(2),
16138
+ resetOnSuccess: exports_external.boolean().default(true)
16139
+ });
16140
+
16130
16141
  // src/config/schema/headroom.ts
16131
16142
  var HeadroomConfigSchema = exports_external.object({
16132
16143
  enabled: exports_external.boolean().default(false),
@@ -16196,7 +16207,9 @@ var HookNameEnum = exports_external.enum([
16196
16207
  "evolution-compressor",
16197
16208
  "evolution-hitl",
16198
16209
  "context-mode-enforcer",
16199
- "task-edit-guard"
16210
+ "context-mode-enforcer",
16211
+ "task-edit-guard",
16212
+ "failure-counter"
16200
16213
  ]);
16201
16214
  var HookNameSchema = exports_external.union([
16202
16215
  HookNameEnum,
@@ -16216,11 +16229,64 @@ var MatrixxSelfConfigSkillConfigSchema = exports_external.object({
16216
16229
  proactive: exports_external.boolean().default(false)
16217
16230
  });
16218
16231
 
16232
+ // src/config/schema/model-config.ts
16233
+ var ModelFallbackEntrySchema = exports_external.object({
16234
+ providers: exports_external.array(exports_external.string().min(1)),
16235
+ model: exports_external.string().min(1),
16236
+ variant: exports_external.string().optional()
16237
+ });
16238
+ var TierSpecSchema = exports_external.object({
16239
+ providerPriority: exports_external.array(exports_external.string()),
16240
+ modelPattern: exports_external.string().refine((s) => {
16241
+ try {
16242
+ new RegExp(s);
16243
+ return true;
16244
+ } catch {
16245
+ return false;
16246
+ }
16247
+ }, { message: "Invalid regex pattern" }),
16248
+ fallbackTier: exports_external.string().optional(),
16249
+ fallback: exports_external.array(ModelFallbackEntrySchema).optional()
16250
+ });
16251
+ var TiersSchema = exports_external.record(exports_external.string(), TierSpecSchema);
16252
+ var complexityDowngradeValueSchema = exports_external.string().refine((s) => {
16253
+ if (s.startsWith("tier:")) {
16254
+ const name = s.slice(5);
16255
+ return name.length > 0;
16256
+ }
16257
+ if (s.includes("/")) {
16258
+ const parts = s.split("/");
16259
+ return parts.length === 2 && parts[0].length > 0 && parts[1].length > 0;
16260
+ }
16261
+ return false;
16262
+ }, { message: "Must be tier:<name> or <provider>/<model>" });
16263
+ var ComplexityDowngradesSchema = exports_external.record(exports_external.string(), exports_external.record(exports_external.string(), complexityDowngradeValueSchema));
16264
+ var AgentModelRequirementsSchema = exports_external.object({
16265
+ fallbackChain: exports_external.array(ModelFallbackEntrySchema),
16266
+ requiresModel: exports_external.string().optional(),
16267
+ requiresAnyModel: exports_external.boolean().optional(),
16268
+ requiresProvider: exports_external.array(exports_external.string()).optional(),
16269
+ variant: exports_external.string().optional()
16270
+ });
16271
+ var CategoryModelRequirementsSchema = exports_external.object({
16272
+ fallbackChain: exports_external.array(ModelFallbackEntrySchema),
16273
+ requiresModel: exports_external.string().optional(),
16274
+ requiresAnyModel: exports_external.boolean().optional(),
16275
+ requiresProvider: exports_external.array(exports_external.string()).optional(),
16276
+ variant: exports_external.string().optional()
16277
+ });
16278
+ var ModelRequirementsSchema = exports_external.object({
16279
+ agents: exports_external.record(exports_external.string(), AgentModelRequirementsSchema).optional(),
16280
+ categories: exports_external.record(exports_external.string(), CategoryModelRequirementsSchema).optional()
16281
+ });
16282
+
16219
16283
  // src/config/schema/morpheus.ts
16220
16284
  var MorpheusTasksConfigSchema = exports_external.object({
16221
16285
  storage_path: exports_external.string().optional(),
16222
16286
  task_list_id: exports_external.string().optional(),
16223
- scope: exports_external.enum(["global", "project"]).default("project").optional().describe("Task storage scope: project \u2192 .matrixx/tasks per project (default), global \u2192 ~/.config/opencode/tasks/{listId}")
16287
+ scope: exports_external.enum(["global", "project"]).default("project").optional().describe("Task storage scope: project \u2192 .matrixx/tasks per project (default), global \u2192 ~/.config/opencode/tasks/{listId}"),
16288
+ stale_after_hours: exports_external.number().int().min(1).optional().describe("Pending tasks with no file activity for this many hours are considered stale (default: 24). Stale tasks are excluded from task-continuation directives."),
16289
+ session_scoped: exports_external.boolean().default(true).optional().describe("When true, the task-continuation-enforcer only considers tasks created by the current session (or its subagent sessions). When false, all project tasks are considered regardless of session origin.")
16224
16290
  });
16225
16291
  var MorpheusConfigSchema = exports_external.object({
16226
16292
  tasks: MorpheusTasksConfigSchema.optional()
@@ -16389,6 +16455,7 @@ var MatrixxConfigSchema = exports_external.object({
16389
16455
  auto_update: exports_external.boolean().optional(),
16390
16456
  skills: SkillsConfigSchema.optional(),
16391
16457
  matrix_loop: MatrixLoopConfigSchema.optional(),
16458
+ failure_counter: FailureCounterConfigSchema.optional(),
16392
16459
  background_task: BackgroundTaskConfigSchema.optional(),
16393
16460
  notification: NotificationConfigSchema.optional(),
16394
16461
  babysitting: BabysittingConfigSchema.optional(),
@@ -16406,7 +16473,10 @@ var MatrixxConfigSchema = exports_external.object({
16406
16473
  context_mode: ContextModeConfigSchema.optional(),
16407
16474
  rtk: RtkConfigSchema.optional(),
16408
16475
  evolution: EvolutionConfigSchema.optional(),
16409
- _migrations: exports_external.array(exports_external.string()).optional()
16476
+ _migrations: exports_external.array(exports_external.string()).optional(),
16477
+ tiers: TiersSchema.optional(),
16478
+ modelRequirements: ModelRequirementsSchema.optional(),
16479
+ complexityDowngrades: ComplexityDowngradesSchema.optional()
16410
16480
  });
16411
16481
 
16412
16482
  // src/cli/doctor/checks/config.ts
@@ -16483,7 +16553,38 @@ var configValidationCheck = {
16483
16553
 
16484
16554
  // src/cli/doctor/checks/context-mode.ts
16485
16555
  import { existsSync as existsSync6, readFileSync as readFileSync5 } from "fs";
16556
+ import { homedir as homedir4 } from "os";
16486
16557
  import { join as join7 } from "path";
16558
+ function resolveDisciplineInfo() {
16559
+ const candidates = [];
16560
+ try {
16561
+ const resolved = __require.resolve("context-mode/configs/opencode/AGENTS.md");
16562
+ candidates.push(resolved);
16563
+ } catch {}
16564
+ try {
16565
+ candidates.push(join7(getOpenCodeCacheDir(), "packages/context-mode@latest/node_modules/context-mode/configs/opencode/AGENTS.md"));
16566
+ } catch {}
16567
+ try {
16568
+ const base = process.env.XDG_CACHE_HOME ?? join7(homedir4(), ".cache");
16569
+ candidates.push(join7(base, "opencode/packages/context-mode@latest/node_modules/context-mode/configs/opencode/AGENTS.md"));
16570
+ } catch {}
16571
+ for (const p of candidates) {
16572
+ try {
16573
+ if (existsSync6(p)) {
16574
+ let version2 = null;
16575
+ try {
16576
+ const pkgPath = join7(p.replace(/configs\/opencode\/AGENTS\.md$/, ""), "package.json");
16577
+ const pkgRaw = readFileSync5(pkgPath, "utf-8");
16578
+ const pkg = JSON.parse(pkgRaw);
16579
+ if (typeof pkg.version === "string")
16580
+ version2 = pkg.version;
16581
+ } catch {}
16582
+ return { path: p, version: version2 };
16583
+ }
16584
+ } catch {}
16585
+ }
16586
+ return { path: null, version: null };
16587
+ }
16487
16588
  function loadContextModeConfig() {
16488
16589
  const dir = getOpenCodeConfigDir({ binary: "opencode" });
16489
16590
  const bases = [join7(dir, "matrixx"), join7(process.cwd(), ".opencode", "matrixx"), join7(process.cwd(), "matrixx")];
@@ -16554,11 +16655,15 @@ var contextModeCheck = {
16554
16655
  Cache dir: ${cacheDir} ${hasCache ? "(exists)" : "(not found \u2014 will be created on first use)"}`
16555
16656
  };
16556
16657
  }
16658
+ const discipline = resolveDisciplineInfo();
16659
+ const disciplineLine = discipline.path ? `Discipline: ${discipline.path}${discipline.version ? ` (v${discipline.version})` : ""}` : "Discipline: not found \u2014 fallback table in use";
16557
16660
  return {
16558
16661
  name: "context-mode-integration",
16559
16662
  status: "pass",
16560
- message: `context-mode plugin registered${hasCache ? ", cache present" : " (cache not yet created)"}`,
16561
- detail: `Cache: ${cacheDir}`
16663
+ message: `context-mode plugin registered${hasCache ? ", cache present" : " (cache not yet created)"}${discipline.version ? `, discipline v${discipline.version}` : ""}`,
16664
+ detail: `Cache: ${cacheDir}
16665
+ ${disciplineLine}
16666
+ Plan tools: plan_create/read/update/list/delete (unconditional)`
16562
16667
  };
16563
16668
  }
16564
16669
  };
@@ -16810,7 +16915,7 @@ Then warm cache: uvx --from markitdown-mcp markitdown-mcp --help` };
16810
16915
 
16811
16916
  // src/cli/doctor/checks/optional.ts
16812
16917
  import { existsSync as existsSync9 } from "fs";
16813
- import { homedir as homedir4 } from "os";
16918
+ import { homedir as homedir5 } from "os";
16814
16919
  import { join as join10 } from "path";
16815
16920
  function spawnVersion(cmd, args) {
16816
16921
  try {
@@ -16823,7 +16928,7 @@ function spawnVersion(cmd, args) {
16823
16928
  }
16824
16929
  function cachedCommentChecker() {
16825
16930
  try {
16826
- const cacheDir = process.env.XDG_CACHE_HOME ? join10(process.env.XDG_CACHE_HOME, "matrixx", "bin") : join10(homedir4(), ".cache", "matrixx", "bin");
16931
+ const cacheDir = process.env.XDG_CACHE_HOME ? join10(process.env.XDG_CACHE_HOME, "matrixx", "bin") : join10(homedir5(), ".cache", "matrixx", "bin");
16827
16932
  const bin = process.platform === "win32" ? "comment-checker.exe" : "comment-checker";
16828
16933
  const p = join10(cacheDir, bin);
16829
16934
  if (existsSync9(p)) {
@@ -17333,10 +17438,10 @@ async function executeDoctor(options = {}) {
17333
17438
 
17334
17439
  // src/cli/install/index.ts
17335
17440
  import { existsSync as existsSync13, mkdirSync as mkdirSync2, readFileSync as readFileSync11, writeFileSync as writeFileSync2 } from "fs";
17336
- import { homedir as homedir5 } from "os";
17441
+ import { homedir as homedir6 } from "os";
17337
17442
  import { join as join14 } from "path";
17338
17443
  function getOpenCodeConfigPath() {
17339
- const configDir = join14(homedir5(), ".config", "opencode");
17444
+ const configDir = join14(homedir6(), ".config", "opencode");
17340
17445
  const jsonPath = join14(configDir, "opencode.json");
17341
17446
  const jsoncPath = join14(configDir, "opencode.jsonc");
17342
17447
  if (existsSync13(jsoncPath))
@@ -17379,7 +17484,7 @@ function generatePluginEntry(absolutePath, forceLocal) {
17379
17484
  return "opencode-matrixx";
17380
17485
  }
17381
17486
  async function executeInstall(options) {
17382
- const configDir = join14(homedir5(), ".config", "opencode");
17487
+ const configDir = join14(homedir6(), ".config", "opencode");
17383
17488
  const configPath = getOpenCodeConfigPath();
17384
17489
  if (!existsSync13(configDir)) {
17385
17490
  mkdirSync2(configDir, { recursive: true });
@@ -0,0 +1 @@
1
+ export { migrateMatrixxConfig, normalizeModelInput } from "./model-migration";
@@ -0,0 +1,18 @@
1
+ import type { MatrixxConfig } from "../schema/matrixx-config";
2
+ /**
3
+ * Normalize a single model string input.
4
+ * - tier:<name> → unchanged, no warning
5
+ * - contains "/" (prefixed provider/model) → emit deprecation warning, keep value
6
+ * - bare model → unchanged, no warning
7
+ *
8
+ * Provider names are opaque strings — no hardcoded allow-list.
9
+ */
10
+ export declare function normalizeModelInput(value: string): string;
11
+ /**
12
+ * In-memory migration for MatrixxConfig model fields.
13
+ * Iterates global_model, tiers fallback models, modelRequirements fallbackChain models,
14
+ * and complexityDowngrades values. Normalizes each via normalizeModelInput.
15
+ * Only mutates in memory — never rewrites the user's config file on disk.
16
+ * Idempotent via _migrations guard.
17
+ */
18
+ export declare function migrateMatrixxConfig(raw: MatrixxConfig): MatrixxConfig;
@@ -28,5 +28,5 @@ export declare function resolveTiersInConfig(config: MatrixxConfig, ctx: TierRes
28
28
  * downstream code (createBuiltinAgents, buildAgent) only ever sees model
29
29
  * strings.
30
30
  */
31
- export declare function resolveTiersInCategoryRegistry(registry: Record<string, WithTier | undefined>, ctx: TierResolverContext): Record<string, WithTier>;
31
+ export declare function resolveTiersInCategoryRegistry(registry: Record<string, WithTier | undefined>, ctx: TierResolverContext, config?: MatrixxConfig): Record<string, WithTier>;
32
32
  export {};
@@ -0,0 +1,7 @@
1
+ import { z } from "zod";
2
+ export declare const FailureCounterConfigSchema: z.ZodObject<{
3
+ enabled: z.ZodDefault<z.ZodBoolean>;
4
+ threshold: z.ZodDefault<z.ZodNumber>;
5
+ resetOnSuccess: z.ZodDefault<z.ZodBoolean>;
6
+ }, z.core.$strip>;
7
+ export type FailureCounterConfig = z.infer<typeof FailureCounterConfigSchema>;
@@ -60,5 +60,6 @@ export declare const HookNameSchema: z.ZodUnion<readonly [z.ZodEnum<{
60
60
  "evolution-hitl": "evolution-hitl";
61
61
  "context-mode-enforcer": "context-mode-enforcer";
62
62
  "task-edit-guard": "task-edit-guard";
63
+ "failure-counter": "failure-counter";
63
64
  }>, z.ZodPipe<z.ZodLiteral<"anthropic-context-window-limit-recovery">, z.ZodTransform<"context-window-limit-recovery", "anthropic-context-window-limit-recovery">>]>;
64
65
  export type HookName = z.infer<typeof HookNameSchema>;
@@ -128,6 +128,7 @@ export declare const MatrixxConfigSchema: z.ZodObject<{
128
128
  "evolution-hitl": "evolution-hitl";
129
129
  "context-mode-enforcer": "context-mode-enforcer";
130
130
  "task-edit-guard": "task-edit-guard";
131
+ "failure-counter": "failure-counter";
131
132
  }>, z.ZodPipe<z.ZodLiteral<"anthropic-context-window-limit-recovery">, z.ZodTransform<"context-window-limit-recovery", "anthropic-context-window-limit-recovery">>]>>>;
132
133
  disabled_commands: z.ZodOptional<z.ZodArray<z.ZodEnum<{
133
134
  "bdd-contract": "bdd-contract";
@@ -1803,6 +1804,11 @@ export declare const MatrixxConfigSchema: z.ZodObject<{
1803
1804
  default_max_iterations: z.ZodDefault<z.ZodNumber>;
1804
1805
  state_dir: z.ZodOptional<z.ZodString>;
1805
1806
  }, z.core.$strip>>;
1807
+ failure_counter: z.ZodOptional<z.ZodObject<{
1808
+ enabled: z.ZodDefault<z.ZodBoolean>;
1809
+ threshold: z.ZodDefault<z.ZodNumber>;
1810
+ resetOnSuccess: z.ZodDefault<z.ZodBoolean>;
1811
+ }, z.core.$strip>>;
1806
1812
  background_task: z.ZodOptional<z.ZodObject<{
1807
1813
  defaultConcurrency: z.ZodOptional<z.ZodNumber>;
1808
1814
  providerConcurrency: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
@@ -1860,6 +1866,8 @@ export declare const MatrixxConfigSchema: z.ZodObject<{
1860
1866
  project: "project";
1861
1867
  global: "global";
1862
1868
  }>>>;
1869
+ stale_after_hours: z.ZodOptional<z.ZodNumber>;
1870
+ session_scoped: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
1863
1871
  }, z.core.$strip>>;
1864
1872
  }, z.core.$strip>>;
1865
1873
  assembly: z.ZodOptional<z.ZodObject<{
@@ -1984,5 +1992,40 @@ export declare const MatrixxConfigSchema: z.ZodObject<{
1984
1992
  }, z.core.$strip>>;
1985
1993
  }, z.core.$strip>>;
1986
1994
  _migrations: z.ZodOptional<z.ZodArray<z.ZodString>>;
1995
+ tiers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
1996
+ providerPriority: z.ZodArray<z.ZodString>;
1997
+ modelPattern: z.ZodString;
1998
+ fallbackTier: z.ZodOptional<z.ZodString>;
1999
+ fallback: z.ZodOptional<z.ZodArray<z.ZodObject<{
2000
+ providers: z.ZodArray<z.ZodString>;
2001
+ model: z.ZodString;
2002
+ variant: z.ZodOptional<z.ZodString>;
2003
+ }, z.core.$strip>>>;
2004
+ }, z.core.$strip>>>;
2005
+ modelRequirements: z.ZodOptional<z.ZodObject<{
2006
+ agents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
2007
+ fallbackChain: z.ZodArray<z.ZodObject<{
2008
+ providers: z.ZodArray<z.ZodString>;
2009
+ model: z.ZodString;
2010
+ variant: z.ZodOptional<z.ZodString>;
2011
+ }, z.core.$strip>>;
2012
+ requiresModel: z.ZodOptional<z.ZodString>;
2013
+ requiresAnyModel: z.ZodOptional<z.ZodBoolean>;
2014
+ requiresProvider: z.ZodOptional<z.ZodArray<z.ZodString>>;
2015
+ variant: z.ZodOptional<z.ZodString>;
2016
+ }, z.core.$strip>>>;
2017
+ categories: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
2018
+ fallbackChain: z.ZodArray<z.ZodObject<{
2019
+ providers: z.ZodArray<z.ZodString>;
2020
+ model: z.ZodString;
2021
+ variant: z.ZodOptional<z.ZodString>;
2022
+ }, z.core.$strip>>;
2023
+ requiresModel: z.ZodOptional<z.ZodString>;
2024
+ requiresAnyModel: z.ZodOptional<z.ZodBoolean>;
2025
+ requiresProvider: z.ZodOptional<z.ZodArray<z.ZodString>>;
2026
+ variant: z.ZodOptional<z.ZodString>;
2027
+ }, z.core.$strip>>>;
2028
+ }, z.core.$strip>>;
2029
+ complexityDowngrades: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>>>;
1987
2030
  }, z.core.$strip>;
1988
2031
  export type MatrixxConfig = z.infer<typeof MatrixxConfigSchema>;
@@ -0,0 +1,81 @@
1
+ import { z } from "zod";
2
+ export declare const ModelFallbackEntrySchema: z.ZodObject<{
3
+ providers: z.ZodArray<z.ZodString>;
4
+ model: z.ZodString;
5
+ variant: z.ZodOptional<z.ZodString>;
6
+ }, z.core.$strip>;
7
+ export type ModelFallbackEntry = z.infer<typeof ModelFallbackEntrySchema>;
8
+ export declare const TierSpecSchema: z.ZodObject<{
9
+ providerPriority: z.ZodArray<z.ZodString>;
10
+ modelPattern: z.ZodString;
11
+ fallbackTier: z.ZodOptional<z.ZodString>;
12
+ fallback: z.ZodOptional<z.ZodArray<z.ZodObject<{
13
+ providers: z.ZodArray<z.ZodString>;
14
+ model: z.ZodString;
15
+ variant: z.ZodOptional<z.ZodString>;
16
+ }, z.core.$strip>>>;
17
+ }, z.core.$strip>;
18
+ export type TierSpec = z.infer<typeof TierSpecSchema>;
19
+ export declare const TiersSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
20
+ providerPriority: z.ZodArray<z.ZodString>;
21
+ modelPattern: z.ZodString;
22
+ fallbackTier: z.ZodOptional<z.ZodString>;
23
+ fallback: z.ZodOptional<z.ZodArray<z.ZodObject<{
24
+ providers: z.ZodArray<z.ZodString>;
25
+ model: z.ZodString;
26
+ variant: z.ZodOptional<z.ZodString>;
27
+ }, z.core.$strip>>>;
28
+ }, z.core.$strip>>;
29
+ export type Tiers = z.infer<typeof TiersSchema>;
30
+ export declare const ComplexityDowngradesSchema: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>>;
31
+ export type ComplexityDowngrades = z.infer<typeof ComplexityDowngradesSchema>;
32
+ export declare const AgentModelRequirementsSchema: z.ZodObject<{
33
+ fallbackChain: z.ZodArray<z.ZodObject<{
34
+ providers: z.ZodArray<z.ZodString>;
35
+ model: z.ZodString;
36
+ variant: z.ZodOptional<z.ZodString>;
37
+ }, z.core.$strip>>;
38
+ requiresModel: z.ZodOptional<z.ZodString>;
39
+ requiresAnyModel: z.ZodOptional<z.ZodBoolean>;
40
+ requiresProvider: z.ZodOptional<z.ZodArray<z.ZodString>>;
41
+ variant: z.ZodOptional<z.ZodString>;
42
+ }, z.core.$strip>;
43
+ export type AgentModelRequirements = z.infer<typeof AgentModelRequirementsSchema>;
44
+ export declare const CategoryModelRequirementsSchema: z.ZodObject<{
45
+ fallbackChain: z.ZodArray<z.ZodObject<{
46
+ providers: z.ZodArray<z.ZodString>;
47
+ model: z.ZodString;
48
+ variant: z.ZodOptional<z.ZodString>;
49
+ }, z.core.$strip>>;
50
+ requiresModel: z.ZodOptional<z.ZodString>;
51
+ requiresAnyModel: z.ZodOptional<z.ZodBoolean>;
52
+ requiresProvider: z.ZodOptional<z.ZodArray<z.ZodString>>;
53
+ variant: z.ZodOptional<z.ZodString>;
54
+ }, z.core.$strip>;
55
+ export type CategoryModelRequirements = z.infer<typeof CategoryModelRequirementsSchema>;
56
+ export declare const ModelRequirementsSchema: z.ZodObject<{
57
+ agents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
58
+ fallbackChain: z.ZodArray<z.ZodObject<{
59
+ providers: z.ZodArray<z.ZodString>;
60
+ model: z.ZodString;
61
+ variant: z.ZodOptional<z.ZodString>;
62
+ }, z.core.$strip>>;
63
+ requiresModel: z.ZodOptional<z.ZodString>;
64
+ requiresAnyModel: z.ZodOptional<z.ZodBoolean>;
65
+ requiresProvider: z.ZodOptional<z.ZodArray<z.ZodString>>;
66
+ variant: z.ZodOptional<z.ZodString>;
67
+ }, z.core.$strip>>>;
68
+ categories: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
69
+ fallbackChain: z.ZodArray<z.ZodObject<{
70
+ providers: z.ZodArray<z.ZodString>;
71
+ model: z.ZodString;
72
+ variant: z.ZodOptional<z.ZodString>;
73
+ }, z.core.$strip>>;
74
+ requiresModel: z.ZodOptional<z.ZodString>;
75
+ requiresAnyModel: z.ZodOptional<z.ZodBoolean>;
76
+ requiresProvider: z.ZodOptional<z.ZodArray<z.ZodString>>;
77
+ variant: z.ZodOptional<z.ZodString>;
78
+ }, z.core.$strip>>>;
79
+ }, z.core.$strip>;
80
+ export type ModelRequirements = z.infer<typeof ModelRequirementsSchema>;
81
+ export declare const DEFAULT_MODEL_CONFIG: {};
@@ -6,6 +6,8 @@ declare const MorpheusTasksConfigSchema: z.ZodObject<{
6
6
  project: "project";
7
7
  global: "global";
8
8
  }>>>;
9
+ stale_after_hours: z.ZodOptional<z.ZodNumber>;
10
+ session_scoped: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
9
11
  }, z.core.$strip>;
10
12
  export declare const MorpheusConfigSchema: z.ZodObject<{
11
13
  tasks: z.ZodOptional<z.ZodObject<{
@@ -15,6 +17,8 @@ export declare const MorpheusConfigSchema: z.ZodObject<{
15
17
  project: "project";
16
18
  global: "global";
17
19
  }>>>;
20
+ stale_after_hours: z.ZodOptional<z.ZodNumber>;
21
+ session_scoped: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
18
22
  }, z.core.$strip>>;
19
23
  }, z.core.$strip>;
20
24
  export type MorpheusTasksConfig = z.infer<typeof MorpheusTasksConfigSchema>;
@@ -13,11 +13,13 @@ export * from "./schema/context-mode";
13
13
  export * from "./schema/dcp";
14
14
  export * from "./schema/evolution";
15
15
  export * from "./schema/experimental";
16
+ export * from "./schema/failure-counter";
16
17
  export * from "./schema/headroom";
17
18
  export * from "./schema/hooks";
18
19
  export * from "./schema/matrix-loop";
19
20
  export * from "./schema/matrixx-config";
20
21
  export * from "./schema/matrixx-self-config";
22
+ export * from "./schema/model-config";
21
23
  export * from "./schema/morpheus";
22
24
  export * from "./schema/morpheus-agent";
23
25
  export * from "./schema/notification";
@@ -66,6 +66,7 @@ export declare function createHooks(args: {
66
66
  matrixLoop: ReturnType<typeof import("./hooks").createMatrixLoopHook> | null;
67
67
  editErrorRecovery: ReturnType<typeof import("./hooks").createEditErrorRecoveryHook> | null;
68
68
  delegateTaskRetry: ReturnType<typeof import("./hooks").createDelegateTaskRetryHook> | null;
69
+ failureCounter: ReturnType<typeof import("./hooks").createFailureCounterHook> | null;
69
70
  startWork: ReturnType<typeof import("./hooks").createStartWorkHook> | null;
70
71
  oracleMdOnly: ReturnType<typeof import("./hooks").createOracleMdOnlyHook> | null;
71
72
  mouseNotepad: ReturnType<typeof import("./hooks").createMouseNotepadHook> | null;
@@ -137,6 +137,14 @@ export declare class BackgroundManager {
137
137
  private notifyParentSession;
138
138
  private hasRunningTasks;
139
139
  private pruneStaleTasksAndNotifications;
140
+ /**
141
+ * True when the subagent session is awaiting user input (unanswered question).
142
+ * The reaper must not kill a task that is legitimately waiting for an answer:
143
+ * its session reports idle and it stops posting progress, but it is not stuck.
144
+ * Ground truth comes from the session message history (hasPendingQuestionMessage);
145
+ * on fetch failure we fail open (return false) so reaping behavior is unchanged.
146
+ */
147
+ private isSessionAwaitingUser;
140
148
  private checkAndInterruptStaleTasks;
141
149
  private pollRunningTasks;
142
150
  /**
@@ -1 +1 @@
1
- export declare const START_WORK_TEMPLATE = "You are starting a Morpheus work session.\n\n## WHAT TO DO\n\n1. **Find available plans**: Search for Oracle-generated plan files at `.matrixx/plans/`\n\n2. **Check for active mission state**: Read `.matrixx/mission.json` if it exists\n\n3. **Decision logic**:\n - If `.matrixx/mission.json` exists AND plan is NOT complete (has unchecked boxes):\n - **APPEND** current session to session_ids\n - Continue work on existing plan\n - If no active plan OR plan is complete:\n - List available plan files\n - If ONE plan: auto-select it\n - If MULTIPLE plans: show list with timestamps, ask user to select\n\n4. **Create/Update mission.json**:\n ```json\n {\n \"active_plan\": \"/absolute/path/to/plan.md\",\n \"started_at\": \"ISO_TIMESTAMP\",\n \"session_ids\": [\"session_id_1\", \"session_id_2\"],\n \"plan_name\": \"plan-name\"\n }\n ```\n\n5. **Read the plan file** and start executing tasks according to architect workflow\n\n## OUTPUT FORMAT\n\nWhen listing plans for selection:\n```\nAvailable Work Plans\n\nCurrent Time: {ISO timestamp}\nSession ID: {current session id}\n\n1. [plan-name-1.md] - Modified: {date} - Progress: 3/10 tasks\n2. [plan-name-2.md] - Modified: {date} - Progress: 0/5 tasks\n\nWhich plan would you like to work on? (Enter number or plan name)\n```\n\nWhen resuming existing work:\n```\nResuming Work Session\n\nActive Plan: {plan-name}\nProgress: {completed}/{total} tasks\nSessions: {count} (appending current session)\n\nReading plan and continuing from last incomplete task...\n```\n\nWhen auto-selecting single plan:\n```\nStarting Work Session\n\nPlan: {plan-name}\nSession ID: {session_id}\nStarted: {timestamp}\n\nReading plan and beginning execution...\n```\n\n## CRITICAL\n\n- The session_id is injected by the hook - use it directly\n- Always update mission.json BEFORE starting work\n- Read the FULL plan file before delegating any tasks\n- Follow architect delegation protocols (7-section format)";
1
+ export declare const START_WORK_TEMPLATE = "You are starting a Morpheus work session.\n\n## WHAT TO DO\n\n1. **Find available plans**: List Oracle-generated plan files via plan_list at `.matrixx/plans/`\n\n2. **Check for active mission state**: Read `.matrixx/mission.json` if it exists\n\n3. **Decision logic**:\n - If `.matrixx/mission.json` exists AND plan is NOT complete (has unchecked boxes):\n - **APPEND** current session to session_ids\n - Continue work on existing plan\n - If no active plan OR plan is complete:\n - List available plan files via plan_list\n - If ONE plan: auto-select it\n - If MULTIPLE plans: show list with timestamps, ask user to select\n\n4. **Create/Update mission.json**:\n ```json\n {\n \"active_plan\": \"/absolute/path/to/plan.md\",\n \"started_at\": \"ISO_TIMESTAMP\",\n \"session_ids\": [\"session_id_1\", \"session_id_2\"],\n \"plan_name\": \"plan-name\"\n }\n ```\n\n5. **Read the plan file via plan_read** and start executing tasks according to architect workflow\n\n## OUTPUT FORMAT\n\nWhen listing plans for selection:\n```\nAvailable Work Plans\n\nCurrent Time: {ISO timestamp}\nSession ID: {current session id}\n\n1. [plan-name-1.md] - Modified: {date} - Progress: 3/10 tasks\n2. [plan-name-2.md] - Modified: {date} - Progress: 0/5 tasks\n\nWhich plan would you like to work on? (Enter number or plan name)\n```\n\nWhen resuming existing work:\n```\nResuming Work Session\n\nActive Plan: {plan-name}\nProgress: {completed}/{total} tasks\nSessions: {count} (appending current session)\n\nReading plan and continuing from last incomplete task...\n```\n\nWhen auto-selecting single plan:\n```\nStarting Work Session\n\nPlan: {plan-name}\nSession ID: {session_id}\nStarted: {timestamp}\n\nReading plan and beginning execution...\n```\n\n## CRITICAL\n\n- The session_id is injected by the hook - use it directly\n- Always update mission.json BEFORE starting work\n- Read the FULL plan file via plan_read before delegating any tasks\n- Follow architect delegation protocols (7-section format)";
@@ -30,6 +30,7 @@ export declare function writePlanFile(directory: string, planPath: string, conte
30
30
  * For each `- [ ]` or `- [x]` line, finds the matching todo by content
31
31
  * and marks it completed if the todo status is completed/cancelled.
32
32
  * Lines without a matching todo keep their current state.
33
+ * Checked boxes are never unchecked — sync only transitions [ ] → [x].
33
34
  */
34
35
  export declare function syncCheckboxes(content: string, todos: Array<{
35
36
  content: string;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,9 +1,35 @@
1
1
  export declare const subagentSessions: Set<string>;
2
+ export declare function registerSubagentSession(sessionID: string, parentSessionID: string): void;
3
+ export declare function getParentSessionID(subagentSessionID: string): string | undefined;
4
+ export declare function getSubagentSessionIDs(parentSessionID: string): string[];
2
5
  export declare function setMainSession(id: string | undefined): void;
3
6
  export declare function getMainSessionID(): string | undefined;
7
+ /**
8
+ * Whether a session.created payload should be tracked as the plugin's main
9
+ * session. Top-level sessions (no parentID) qualify UNLESS they are internal
10
+ * sessions of another plugin (e.g. opencode-mem structured-output capture
11
+ * sessions are top-level with metadata["opencode-mem"].internal === true).
12
+ * Foreign top-level sessions must not hijack main-session tracking.
13
+ */
14
+ export declare function isMainSessionCandidate(sessionInfo: {
15
+ id?: string;
16
+ parentID?: string;
17
+ metadata?: Record<string, unknown>;
18
+ } | undefined): boolean;
4
19
  /** @internal For testing only */
5
20
  export declare function _resetForTesting(): void;
6
21
  export declare function setSessionAgent(sessionID: string, agent: string): void;
7
22
  export declare function updateSessionAgent(sessionID: string, agent: string): void;
8
23
  export declare function getSessionAgent(sessionID: string): string | undefined;
9
24
  export declare function clearSessionAgent(sessionID: string): void;
25
+ export declare function incFailureCounter(sessionID: string): number;
26
+ export declare function resetFailureCounter(sessionID: string): void;
27
+ export declare function getFailureCount(sessionID: string): number;
28
+ export declare function getFailureState(sessionID: string): {
29
+ count: number;
30
+ lastFailedAt: number;
31
+ } | undefined;
32
+ export declare function clearFailureCounter(sessionID: string): void;
33
+ /** @internal For testing only */
34
+ export declare function _resetFailureCountersForTesting(): void;
35
+ export declare function isThresholdReached(sessionID: string, threshold: number): boolean;
@@ -0,0 +1 @@
1
+ export {};
@@ -21,6 +21,7 @@ export declare const TaskSchema: z.ZodObject<{
21
21
  blockedBy: z.ZodArray<z.ZodString>;
22
22
  owner: z.ZodOptional<z.ZodString>;
23
23
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
24
+ threadID: z.ZodOptional<z.ZodString>;
24
25
  projectRoot: z.ZodOptional<z.ZodString>;
25
26
  }, z.core.$strict>;
26
27
  export type Task = z.infer<typeof TaskSchema>;
@@ -1,5 +1,5 @@
1
1
  export declare const HOOK_NAME = "context-mode-enforcer";
2
- export declare const WARN_MESSAGE_READ = "Use ctx_search / ctx_batch_execute / ctx_execute for analysis \u2014 raw read/grep/glob bypasses FTS5 sandbox and pollutes context. Use Read only with hashline IDs for Edit.";
2
+ export declare const WARN_MESSAGE_READ = "Use ctx_search / ctx_batch_execute / ctx_execute for analysis \u2014 raw read/grep/glob bypasses FTS5 sandbox and pollutes context. Use Read only with hashline IDs for Edit (non-plan paths; .matrixx/plans/*.md must use plan_read/plan_update).";
3
3
  export declare const BLOCK_MESSAGE_GREP_GLOB = "Blocked: raw grep/glob is forbidden when context-mode is enforced. Use ctx_search (indexed) \u2192 grep/glob fallback only when ctx_* unavailable, or ctx_batch_execute / ctx_execute for multi-file analysis.";
4
4
  export declare const WARN_MESSAGE_BASH_READ = "Use ctx_* / Read tool instead of `cat`/`head`/`tail`/`grep` via bash for analysis. Raw bash file reads bypass sandbox.";
5
5
  export declare const DEFAULT_BLOCKED_TOOLS: readonly ["grep", "glob"];
@@ -0,0 +1,7 @@
1
+ import { clearFailureCounter, getFailureCount, resetFailureCounter } from "../../features/session-state/state";
2
+ export declare const CONTINUATION_COOLDOWN_MS = 30000;
3
+ export interface HandleToolAfterOptions {
4
+ parentSessionID?: string;
5
+ }
6
+ export declare function handleToolAfter(sessionID: string, output: string, isSuccess: boolean, options?: HandleToolAfterOptions): void;
7
+ export { clearFailureCounter, getFailureCount, resetFailureCounter };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,18 @@
1
+ import type { PluginInput } from "@opencode-ai/plugin";
2
+ export declare function createFailureCounterHook(_ctx: PluginInput): {
3
+ "tool.execute.after": (input: {
4
+ tool: string;
5
+ sessionID: string;
6
+ callID: string;
7
+ }, output: {
8
+ title: string;
9
+ output: string;
10
+ metadata: unknown;
11
+ }) => Promise<void>;
12
+ event: (input: {
13
+ event: {
14
+ type: string;
15
+ properties: Record<string, unknown>;
16
+ };
17
+ }) => Promise<void>;
18
+ };
@@ -0,0 +1,3 @@
1
+ export * from "./counter";
2
+ export { createFailureCounterHook } from "./hook";
3
+ export * from "./patterns";
@@ -0,0 +1,6 @@
1
+ export interface FailureSignature {
2
+ pattern: string | RegExp;
3
+ kind: "task_error" | "timeout" | "abort_excluded";
4
+ }
5
+ export declare const FAILURE_COUNTER_PATTERNS: FailureSignature[];
6
+ export declare function isCountableFailure(output: string): boolean;
@@ -0,0 +1 @@
1
+ export {};
@@ -22,6 +22,7 @@ export { createEvolutionCompressorHook } from "./evolution-compressor";
22
22
  export { createEvolutionHitlHook } from "./evolution-hitl";
23
23
  export { passesQualityGate } from "./evolution-quality-gate";
24
24
  export { createEvolutionWatcherHook } from "./evolution-watcher";
25
+ export { createFailureCounterHook } from "./failure-counter";
25
26
  export { createHashlineEditDiffEnhancerHook } from "./hashline-edit-diff-enhancer";
26
27
  export { createHashlineReadEnhancerHook } from "./hashline-read-enhancer";
27
28
  export { createInputSecretGuardHook } from "./input-secret-guard";
@@ -0,0 +1 @@
1
+ export {};