opencode-matrixx-v2 1.2.0 → 1.2.1

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.
@@ -0,0 +1,13 @@
1
+ export interface NudgeInput {
2
+ tool: string;
3
+ sessionID: string;
4
+ agent?: string;
5
+ toolCallCount: number;
6
+ delegationUsed: boolean;
7
+ reminderShown: boolean;
8
+ }
9
+ export interface NudgeEvent {
10
+ skill: string;
11
+ reason: string;
12
+ }
13
+ export declare function detectNudge(input: NudgeInput): NudgeEvent | null;
@@ -1,2 +1,7 @@
1
1
  import type { AvailableSkill } from "../../agents/dynamic-agent-prompt-builder";
2
2
  export declare function buildReminderMessage(availableSkills: AvailableSkill[]): string;
3
+ export interface NudgeMessageEvent {
4
+ skill: string;
5
+ reason: string;
6
+ }
7
+ export declare function buildNudgeMessage(event: NudgeMessageEvent): string;
@@ -1,5 +1,7 @@
1
1
  import type { AvailableSkill } from "../../agents/dynamic-agent-prompt-builder";
2
2
  import type { MatrixxContext } from "../../plugin/context";
3
+ export type { NudgeEvent, NudgeInput } from "./detector";
4
+ export { detectNudge } from "./detector";
3
5
  interface ToolExecuteInput {
4
6
  tool: string;
5
7
  sessionID: string;
@@ -11,9 +13,11 @@ interface ToolExecuteOutput {
11
13
  output: string;
12
14
  metadata: unknown;
13
15
  }
16
+ export interface CategorySkillReminderOptions {
17
+ now?: () => number;
18
+ }
14
19
  import type { V2Event } from "../../plugin/context";
15
- export declare function createCategorySkillReminderHook(ctx: MatrixxContext, availableSkills?: AvailableSkill[]): {
20
+ export declare function createCategorySkillReminderHook(ctx: MatrixxContext, availableSkills?: AvailableSkill[], options?: CategorySkillReminderOptions): {
16
21
  "tool.execute.after": (input: ToolExecuteInput, output: ToolExecuteOutput) => Promise<void>;
17
22
  event: (event: V2Event) => Promise<void>;
18
23
  };
19
- export {};
package/dist/index.js CHANGED
@@ -26192,7 +26192,7 @@ function buildInlineConfig(profile, options) {
26192
26192
  const commands = merged.commands ?? {};
26193
26193
  const manualMode = merged.manualMode ?? {};
26194
26194
  return {
26195
- $schema: "https://raw.githubusercontent.com/Opencode-DCP/opencode-dynamic-context-pruning/v3.1.14/dcp.schema.json",
26195
+ $schema: "https://raw.githubusercontent.com/Opencode-DCP/opencode-dynamic-context-pruning/v3.2.0/dcp.schema.json",
26196
26196
  enabled: true,
26197
26197
  autoUpdate: merged.autoUpdate ?? false,
26198
26198
  debug: merged.debug ?? false,
@@ -76209,6 +76209,51 @@ function createBashFileReadGuardHook() {
76209
76209
  }
76210
76210
  };
76211
76211
  }
76212
+ // src/hooks/category-skill-reminder/detector.ts
76213
+ var TARGET_AGENTS = new Set([
76214
+ "morpheus",
76215
+ "mouse",
76216
+ "niobe"
76217
+ ]);
76218
+ var DELEGATABLE_WORK_TOOLS = new Set([
76219
+ "edit",
76220
+ "write",
76221
+ "bash",
76222
+ "shell",
76223
+ "read",
76224
+ "grep",
76225
+ "glob"
76226
+ ]);
76227
+ var NUDGE_THRESHOLD = 3;
76228
+ var NUDGE_SKILL = "construct";
76229
+ function isTargetAgent(sessionID, inputAgent) {
76230
+ const agent = getSessionAgent(sessionID) ?? inputAgent;
76231
+ if (!agent)
76232
+ return false;
76233
+ const agentKey = getAgentConfigKey(agent);
76234
+ return TARGET_AGENTS.has(agentKey) || agentKey.includes("morpheus") || agentKey.includes("niobe");
76235
+ }
76236
+ function detectNudge(input) {
76237
+ try {
76238
+ if (subagentSessions.has(input.sessionID))
76239
+ return null;
76240
+ if (!isTargetAgent(input.sessionID, input.agent))
76241
+ return null;
76242
+ if (!DELEGATABLE_WORK_TOOLS.has(input.tool.toLowerCase()))
76243
+ return null;
76244
+ if (input.delegationUsed || input.reminderShown)
76245
+ return null;
76246
+ if (input.toolCallCount < NUDGE_THRESHOLD)
76247
+ return null;
76248
+ return {
76249
+ skill: NUDGE_SKILL,
76250
+ reason: `delegatable work without delegation (${input.toolCallCount} ${input.tool} calls)`
76251
+ };
76252
+ } catch {
76253
+ return null;
76254
+ }
76255
+ }
76256
+
76212
76257
  // src/hooks/category-skill-reminder/formatter.ts
76213
76258
  function formatSkillNames(skills, limit) {
76214
76259
  if (skills.length === 0)
@@ -76244,12 +76289,12 @@ function buildReminderMessage(availableSkills) {
76244
76289
  }
76245
76290
 
76246
76291
  // src/hooks/category-skill-reminder/hook.ts
76247
- var TARGET_AGENTS = new Set([
76292
+ var TARGET_AGENTS2 = new Set([
76248
76293
  "morpheus",
76249
76294
  "mouse",
76250
76295
  "niobe"
76251
76296
  ]);
76252
- var DELEGATABLE_WORK_TOOLS = new Set([
76297
+ var DELEGATABLE_WORK_TOOLS2 = new Set([
76253
76298
  "edit",
76254
76299
  "write",
76255
76300
  "bash",
@@ -76262,6 +76307,7 @@ var DELEGATION_TOOLS = new Set([
76262
76307
  "task",
76263
76308
  "subagent"
76264
76309
  ]);
76310
+ var DEDUP_WINDOW_MS2 = 60000;
76265
76311
  function hashSnippet(value) {
76266
76312
  let hash = 5381;
76267
76313
  for (let i = 0;i < value.length; i++) {
@@ -76269,9 +76315,11 @@ function hashSnippet(value) {
76269
76315
  }
76270
76316
  return (hash >>> 0).toString(16);
76271
76317
  }
76272
- function createCategorySkillReminderHook(ctx, availableSkills = []) {
76318
+ function createCategorySkillReminderHook(ctx, availableSkills = [], options = {}) {
76273
76319
  const sessionStates = new Map;
76320
+ const lastNudgeAt = new Map;
76274
76321
  const reminderMessage = buildReminderMessage(availableSkills);
76322
+ const now = options.now ?? Date.now;
76275
76323
  function getOrCreateState(sessionID) {
76276
76324
  if (!sessionStates.has(sessionID)) {
76277
76325
  sessionStates.set(sessionID, {
@@ -76282,58 +76330,103 @@ function createCategorySkillReminderHook(ctx, availableSkills = []) {
76282
76330
  }
76283
76331
  return sessionStates.get(sessionID);
76284
76332
  }
76333
+ function clearSessionState(sessionID) {
76334
+ sessionStates.delete(sessionID);
76335
+ }
76336
+ function clearSessionDedup(sessionID) {
76337
+ const prefix = `${sessionID}:`;
76338
+ for (const key of lastNudgeAt.keys()) {
76339
+ if (key.startsWith(prefix))
76340
+ lastNudgeAt.delete(key);
76341
+ }
76342
+ }
76285
76343
  function isTargetAgent(sessionID, inputAgent) {
76286
76344
  const agent = getSessionAgent(sessionID) ?? inputAgent;
76287
76345
  if (!agent)
76288
76346
  return false;
76289
76347
  const agentKey = getAgentConfigKey(agent);
76290
- return TARGET_AGENTS.has(agentKey) || agentKey.includes("morpheus") || agentKey.includes("niobe");
76348
+ return TARGET_AGENTS2.has(agentKey) || agentKey.includes("morpheus") || agentKey.includes("niobe");
76291
76349
  }
76292
76350
  const toolExecuteAfter = async (input, output) => {
76293
- const { tool, sessionID } = input;
76294
- const toolLower = tool.toLowerCase();
76295
- if (!isTargetAgent(sessionID, input.agent)) {
76296
- return;
76297
- }
76298
- const state = getOrCreateState(sessionID);
76299
- if (DELEGATION_TOOLS.has(toolLower)) {
76300
- state.delegationUsed = true;
76301
- log("[category-skill-reminder] Delegation tool used", { sessionID, tool });
76302
- return;
76303
- }
76304
- if (!DELEGATABLE_WORK_TOOLS.has(toolLower)) {
76351
+ try {
76352
+ const { tool, sessionID } = input;
76353
+ const toolLower = tool.toLowerCase();
76354
+ if (subagentSessions.has(sessionID))
76355
+ return;
76356
+ if (!isTargetAgent(sessionID, input.agent)) {
76357
+ return;
76358
+ }
76359
+ const state = getOrCreateState(sessionID);
76360
+ if (DELEGATION_TOOLS.has(toolLower)) {
76361
+ state.delegationUsed = true;
76362
+ log("[category-skill-reminder] Delegation tool used", { sessionID, tool });
76363
+ return;
76364
+ }
76365
+ if (!DELEGATABLE_WORK_TOOLS2.has(toolLower)) {
76366
+ return;
76367
+ }
76368
+ state.toolCallCount++;
76369
+ let nudge = null;
76370
+ try {
76371
+ nudge = detectNudge({
76372
+ tool,
76373
+ sessionID,
76374
+ agent: input.agent,
76375
+ toolCallCount: state.toolCallCount,
76376
+ delegationUsed: state.delegationUsed,
76377
+ reminderShown: state.reminderShown
76378
+ });
76379
+ } catch {
76380
+ nudge = null;
76381
+ }
76382
+ if (nudge) {
76383
+ const dedupKey = `${sessionID}:${toolLower}:${nudge.skill}`;
76384
+ const lastAt = lastNudgeAt.get(dedupKey);
76385
+ const current = now();
76386
+ if (lastAt !== undefined && current - lastAt < DEDUP_WINDOW_MS2) {
76387
+ return;
76388
+ }
76389
+ lastNudgeAt.set(dedupKey, current);
76390
+ output.output += reminderMessage;
76391
+ state.reminderShown = true;
76392
+ log("[category-skill-reminder] Reminder injected", {
76393
+ sessionID,
76394
+ toolCallCount: state.toolCallCount
76395
+ });
76396
+ try {
76397
+ await notifyInjection(ctx, {
76398
+ sessionID,
76399
+ injector: "category-skill-reminder",
76400
+ hash: hashSnippet(reminderMessage),
76401
+ title: "Context injection",
76402
+ message: "Delegation guidance applied"
76403
+ });
76404
+ } catch {
76405
+ return;
76406
+ }
76407
+ }
76408
+ } catch {
76305
76409
  return;
76306
76410
  }
76307
- state.toolCallCount++;
76308
- if (state.toolCallCount >= 3 && !state.delegationUsed && !state.reminderShown) {
76309
- output.output += reminderMessage;
76310
- state.reminderShown = true;
76311
- log("[category-skill-reminder] Reminder injected", {
76312
- sessionID,
76313
- toolCallCount: state.toolCallCount
76314
- });
76315
- await notifyInjection(ctx, {
76316
- sessionID,
76317
- injector: "category-skill-reminder",
76318
- hash: hashSnippet(reminderMessage),
76319
- title: "Context injection",
76320
- message: "Delegation guidance applied"
76321
- });
76322
- }
76323
76411
  };
76324
76412
  const eventHandler = async (event) => {
76325
- const props = event.data;
76326
- if (event.type === "session.deleted") {
76327
- const sessionInfo = props?.info;
76328
- if (sessionInfo?.id) {
76329
- sessionStates.delete(sessionInfo.id);
76413
+ try {
76414
+ const props = event.data;
76415
+ if (event.type === "session.deleted") {
76416
+ const sessionInfo = props?.info;
76417
+ if (sessionInfo?.id) {
76418
+ clearSessionState(sessionInfo.id);
76419
+ clearSessionDedup(sessionInfo.id);
76420
+ }
76330
76421
  }
76331
- }
76332
- if (event.type === "session.compacted") {
76333
- const sessionID = props?.sessionID ?? props?.info?.id;
76334
- if (sessionID) {
76335
- sessionStates.delete(sessionID);
76422
+ if (event.type === "session.compacted") {
76423
+ const sessionID = props?.sessionID ?? props?.info?.id;
76424
+ if (sessionID) {
76425
+ clearSessionState(sessionID);
76426
+ }
76336
76427
  }
76428
+ } catch {
76429
+ return;
76337
76430
  }
76338
76431
  };
76339
76432
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-matrixx-v2",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
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",