opencode-orchestrator 1.3.5 → 1.3.7
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.
- package/README.md +3 -1
- package/dist/agents/prompts/02_discovery/agents/discovery_commander.d.ts +1 -5
- package/dist/agents/prompts/02_discovery/agents/discovery_planner.d.ts +1 -5
- package/dist/agents/prompts/03_planning/agents/planning_commander.d.ts +1 -5
- package/dist/agents/prompts/04_execution/agents/execution_commander.d.ts +1 -5
- package/dist/agents/prompts/04_execution/agents/execution_worker.d.ts +1 -5
- package/dist/agents/prompts/04_execution/execution_error_handling.d.ts +1 -5
- package/dist/agents/prompts/05_verification/agents/verification_commander.d.ts +1 -5
- package/dist/agents/prompts/05_verification/verification_build.d.ts +1 -5
- package/dist/agents/prompts/05_verification/verification_test.d.ts +1 -5
- package/dist/agents/prompts/06_mission/agents/mission_commander.d.ts +1 -5
- package/dist/agents/prompts/06_mission/mission_lifecycle.d.ts +1 -5
- package/dist/agents/prompts/07_agents/commander/commander_mandate.d.ts +1 -5
- package/dist/agents/prompts/07_agents/planner/planner_mandate.d.ts +1 -5
- package/dist/agents/prompts/07_agents/reviewer/reviewer_mandate.d.ts +1 -5
- package/dist/agents/prompts/07_agents/worker/worker_mandate.d.ts +1 -5
- package/dist/agents/prompts/08_tools/tools_code_editing.d.ts +1 -5
- package/dist/agents/prompts/08_tools/tools_testing.d.ts +1 -5
- package/dist/core/memory/interfaces.d.ts +1 -1
- package/dist/core/memory/memory-manager.d.ts +1 -1
- package/dist/core/orchestrator/session-manager.d.ts +19 -2
- package/dist/core/queue/async-utils.d.ts +1 -1
- package/dist/hooks/compatibility/external-plugin.d.ts +3 -3
- package/dist/hooks/custom/agent-ui.d.ts +2 -10
- package/dist/hooks/custom/memory-gate.d.ts +3 -6
- package/dist/hooks/custom/metrics.d.ts +4 -6
- package/dist/hooks/custom/resource-control.d.ts +3 -2
- package/dist/hooks/custom/secret-scanner.d.ts +2 -10
- package/dist/hooks/custom/strict-role-guard.d.ts +2 -11
- package/dist/hooks/custom/user-activity.d.ts +2 -2
- package/dist/hooks/features/mission-loop.d.ts +3 -2
- package/dist/hooks/features/sanity-check.d.ts +3 -6
- package/dist/hooks/registry.d.ts +4 -16
- package/dist/hooks/types.d.ts +21 -16
- package/dist/index.js +116 -59
- package/dist/tools/lsp/diagnostics-cache.d.ts +3 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
[](https://www.npmjs.com/package/opencode-orchestrator)
|
|
8
8
|
<!-- VERSION:START -->
|
|
9
|
-
**Version:** `1.3.
|
|
9
|
+
**Version:** `1.3.7`
|
|
10
10
|
<!-- VERSION:END -->
|
|
11
11
|
</div>
|
|
12
12
|
|
|
@@ -139,6 +139,8 @@ Useful references:
|
|
|
139
139
|
3. OpenCode keybinds: https://opencode.ai/docs/keybinds/
|
|
140
140
|
4. Project issues: https://github.com/agnusdei1207/opencode-orchestrator/issues
|
|
141
141
|
|
|
142
|
+
Contributions are welcome: open an issue or pull request when you find a bug, compatibility gap, or focused improvement.
|
|
143
|
+
|
|
142
144
|
Config logs:
|
|
143
145
|
|
|
144
146
|
| Platform | Path |
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Placeholder for commander in discovery category.
|
|
3
|
-
* Generated to match PROMPT_ARCHITECTURE_PROPOSAL.md
|
|
4
|
-
*/
|
|
5
|
-
export declare const DISCOVERY_COMMANDER = "\n# TODO: Implement commander specific prompt\n";
|
|
1
|
+
export declare const DISCOVERY_COMMANDER = "\n# Discovery: Commander\n\n- Confirm repository root, active branch, package manager, and configured OpenCode runtime before delegating.\n- Identify entry points, public exports, generated artifacts, and dynamic plugin hooks that can affect the mission.\n- Turn unknowns into explicit questions or Planner tasks instead of treating assumptions as facts.\n";
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Placeholder for planner in discovery category.
|
|
3
|
-
* Generated to match PROMPT_ARCHITECTURE_PROPOSAL.md
|
|
4
|
-
*/
|
|
5
|
-
export declare const DISCOVERY_PLANNER = "\n# TODO: Implement planner specific prompt\n";
|
|
1
|
+
export declare const DISCOVERY_PLANNER = "\n# Discovery: Planner\n\n- Map inputs, outputs, dependencies, and dynamic registration points for the assigned area.\n- Read the files that define the behavior before proposing a plan.\n- Report confirmed facts separately from risks, gaps, and assumptions that still need verification.\n";
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Placeholder for commander in planning category.
|
|
3
|
-
* Generated to match PROMPT_ARCHITECTURE_PROPOSAL.md
|
|
4
|
-
*/
|
|
5
|
-
export declare const PLANNING_COMMANDER = "\n# TODO: Implement commander specific prompt\n";
|
|
1
|
+
export declare const PLANNING_COMMANDER = "\n# Planning: Commander\n\n- Convert the mission into ordered work with clear owners, dependencies, and verification gates.\n- Keep parallel work file-disjoint unless the dependency graph proves it is safe.\n- Prefer the smallest plan that satisfies the request and leaves documentation, tests, and release state synchronized.\n";
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Placeholder for commander in execution category.
|
|
3
|
-
* Generated to match PROMPT_ARCHITECTURE_PROPOSAL.md
|
|
4
|
-
*/
|
|
5
|
-
export declare const EXECUTION_COMMANDER = "\n# TODO: Implement commander specific prompt\n";
|
|
1
|
+
export declare const EXECUTION_COMMANDER = "\n# Execution: Commander\n\n- Delegate scoped implementation tasks only after discovery and planning evidence exists.\n- Monitor each task for progress, conflicts, and missing validation instead of assuming completion.\n- Re-plan when verification exposes a real mismatch between intended and observed behavior.\n";
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Placeholder for worker in execution category.
|
|
3
|
-
* Generated to match PROMPT_ARCHITECTURE_PROPOSAL.md
|
|
4
|
-
*/
|
|
5
|
-
export declare const EXECUTION_WORKER = "\n# TODO: Implement worker specific prompt\n";
|
|
1
|
+
export declare const EXECUTION_WORKER = "\n# Execution: Worker\n\n- Modify only the files assigned by Commander unless new evidence shows the scope is incomplete.\n- Keep changes focused, preserve existing behavior outside the assignment, and remove obsolete code after migration.\n- Return exact files changed, commands run, observed results, and remaining risks.\n";
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Placeholder for error handling in execution category.
|
|
3
|
-
* Generated to match PROMPT_ARCHITECTURE_PROPOSAL.md
|
|
4
|
-
*/
|
|
5
|
-
export declare const EXECUTION_ERROR_HANDLING = "\n# TODO: Implement error handling specific prompt\n";
|
|
1
|
+
export declare const EXECUTION_ERROR_HANDLING = "\n# Execution Error Handling\n\n- Treat failing commands as evidence, not noise; capture the command, exit state, and relevant output.\n- Classify failures as environmental, dependency, test, type, runtime, or design before retrying.\n- Retry only transient failures with a changed condition; otherwise inspect the affected path and adapt the plan.\n";
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Placeholder for commander in verification category.
|
|
3
|
-
* Generated to match PROMPT_ARCHITECTURE_PROPOSAL.md
|
|
4
|
-
*/
|
|
5
|
-
export declare const VERIFICATION_COMMANDER = "\n# TODO: Implement commander specific prompt\n";
|
|
1
|
+
export declare const VERIFICATION_COMMANDER = "\n# Verification: Commander\n\n- Require evidence for every completed task: file reads, command output, tests, or direct runtime observation.\n- Ask Reviewer for final integration verification before declaring the mission complete.\n- Keep unresolved failures visible in the mission summary with owner, cause, and next step.\n";
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Placeholder for build in verification category.
|
|
3
|
-
* Generated to match PROMPT_ARCHITECTURE_PROPOSAL.md
|
|
4
|
-
*/
|
|
5
|
-
export declare const VERIFICATION_BUILD = "\n# TODO: Implement build specific prompt\n";
|
|
1
|
+
export declare const VERIFICATION_BUILD = "\n# Build Verification\n\n- Run the repository build or the narrowest build command that covers the changed surface.\n- Treat generated artifacts, package metadata, and exported types as part of the build contract.\n- If a build cannot run in the current environment, state the exact blocker and run the closest lower-level checks.\n";
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Placeholder for test in verification category.
|
|
3
|
-
* Generated to match PROMPT_ARCHITECTURE_PROPOSAL.md
|
|
4
|
-
*/
|
|
5
|
-
export declare const VERIFICATION_TEST = "\n# TODO: Implement test specific prompt\n";
|
|
1
|
+
export declare const VERIFICATION_TEST = "\n# Test Verification\n\n- Run targeted tests for changed behavior before broader suites.\n- Add or update regression tests when the change fixes a bug or guards a public contract.\n- Report pass, fail, or skipped status with exact command evidence.\n";
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Placeholder for commander in mission category.
|
|
3
|
-
* Generated to match PROMPT_ARCHITECTURE_PROPOSAL.md
|
|
4
|
-
*/
|
|
5
|
-
export declare const MISSION_COMMANDER = "\n# TODO: Implement commander specific prompt\n";
|
|
1
|
+
export declare const MISSION_COMMANDER = "\n# Mission: Commander\n\n- Preserve the user objective, active plan, evidence, and verification state across continuation turns.\n- Continue only while the mission is active, incomplete, and below the configured iteration ceiling.\n- Finish with a concise outcome, validation evidence, known risks, and follow-up state.\n";
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Placeholder for lifecycle in mission category.
|
|
3
|
-
* Generated to match PROMPT_ARCHITECTURE_PROPOSAL.md
|
|
4
|
-
*/
|
|
5
|
-
export declare const MISSION_LIFECYCLE = "\n# TODO: Implement lifecycle specific prompt\n";
|
|
1
|
+
export declare const MISSION_LIFECYCLE = "\n# Mission Lifecycle\n\n- /task starts a persisted mission with objective, iteration budget, evidence trail, and active session state.\n- Idle continuation may proceed only after a completed assistant turn for the current user message.\n- /cancel, /stop, or an interrupt without current completion evidence deactivates continuation until a new mission starts.\n";
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Placeholder for mandate in agents category.
|
|
3
|
-
* Generated to match PROMPT_ARCHITECTURE_PROPOSAL.md
|
|
4
|
-
*/
|
|
5
|
-
export declare const COMMANDER_MANDATE = "\n# TODO: Implement mandate specific prompt\n";
|
|
1
|
+
export declare const COMMANDER_MANDATE = "\n# Commander Mandate\n\n- Own mission interpretation, task decomposition, delegation, progress monitoring, and final completion.\n- Keep subagents context-isolated while preserving shared truth through the mission state and evidence trail.\n- Do not mark completion until implementation, documentation, and verification evidence all agree.\n";
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Placeholder for mandate in agents category.
|
|
3
|
-
* Generated to match PROMPT_ARCHITECTURE_PROPOSAL.md
|
|
4
|
-
*/
|
|
5
|
-
export declare const PLANNER_MANDATE = "\n# TODO: Implement mandate specific prompt\n";
|
|
1
|
+
export declare const PLANNER_MANDATE = "\n# Planner Mandate\n\n- Produce evidence-backed plans with affected files, dependency order, risks, and validation commands.\n- Keep TODO state aligned with the latest verified scope.\n- Prefer incremental migration paths that avoid overlapping file ownership.\n";
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Placeholder for mandate in agents category.
|
|
3
|
-
* Generated to match PROMPT_ARCHITECTURE_PROPOSAL.md
|
|
4
|
-
*/
|
|
5
|
-
export declare const REVIEWER_MANDATE = "\n# TODO: Implement mandate specific prompt\n";
|
|
1
|
+
export declare const REVIEWER_MANDATE = "\n# Reviewer Mandate\n\n- Verify claimed completion against source files, tests, build output, and integration paths.\n- Mark TODO items complete only after direct evidence confirms the requested behavior.\n- Report residual risk clearly when the environment prevents full validation.\n";
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Placeholder for mandate in agents category.
|
|
3
|
-
* Generated to match PROMPT_ARCHITECTURE_PROPOSAL.md
|
|
4
|
-
*/
|
|
5
|
-
export declare const WORKER_MANDATE = "\n# TODO: Implement mandate specific prompt\n";
|
|
1
|
+
export declare const WORKER_MANDATE = "\n# Worker Mandate\n\n- Implement the assigned scope with minimal, tested edits.\n- Preserve public contracts unless Commander explicitly assigns a behavior change.\n- Return enough evidence for Reviewer to reproduce the validation path.\n";
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Placeholder for code editing in tools category.
|
|
3
|
-
* Generated to match PROMPT_ARCHITECTURE_PROPOSAL.md
|
|
4
|
-
*/
|
|
5
|
-
export declare const TOOLS_CODE_EDITING = "\n# TODO: Implement code editing specific prompt\n";
|
|
1
|
+
export declare const TOOLS_CODE_EDITING = "\n# Code Editing Tools\n\n- Read the surrounding file before editing so imports, exports, formatting, and local conventions stay coherent.\n- Use structured parsers or existing helpers when they are available for the file type.\n- After editing, re-open the changed file and verify the connected import/export and configuration paths.\n";
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Placeholder for testing in tools category.
|
|
3
|
-
* Generated to match PROMPT_ARCHITECTURE_PROPOSAL.md
|
|
4
|
-
*/
|
|
5
|
-
export declare const TOOLS_TESTING = "\n# TODO: Implement testing specific prompt\n";
|
|
1
|
+
export declare const TOOLS_TESTING = "\n# Testing Tools\n\n- Run the narrowest meaningful test first, then broaden when shared behavior or release artifacts are affected.\n- Prefer deterministic fixtures, isolated temporary directories, and explicit assertions over timing assumptions.\n- Record the exact command and observed result in the mission evidence.\n";
|
|
@@ -12,7 +12,7 @@ export declare class MemoryManager {
|
|
|
12
12
|
/**
|
|
13
13
|
* Add a memory entry
|
|
14
14
|
*/
|
|
15
|
-
add(level: MemoryLevel, content: string, importance?: number, metadata?: Record<string,
|
|
15
|
+
add(level: MemoryLevel, content: string, importance?: number, metadata?: Record<string, unknown>): string;
|
|
16
16
|
/**
|
|
17
17
|
* Retrieve memory for prompt construction
|
|
18
18
|
*/
|
|
@@ -1,8 +1,24 @@
|
|
|
1
|
+
interface ManagedSessionState {
|
|
2
|
+
active: boolean;
|
|
3
|
+
step: number;
|
|
4
|
+
timestamp: number;
|
|
5
|
+
startTime: number;
|
|
6
|
+
lastStepTime: number;
|
|
7
|
+
lastCompletedMessageID?: string;
|
|
8
|
+
lastUserMessageAt?: number;
|
|
9
|
+
lastAssistantCompletedAt?: number;
|
|
10
|
+
lastAbortAt?: number;
|
|
11
|
+
tokens: {
|
|
12
|
+
totalInput: number;
|
|
13
|
+
totalOutput: number;
|
|
14
|
+
estimatedCost: number;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
1
17
|
/**
|
|
2
18
|
* Ensures a local session object exists in the plugin context map.
|
|
3
19
|
* Now WITH disk-based rehydration for robustness.
|
|
4
20
|
*/
|
|
5
|
-
export declare function ensureSessionInitialized(sessions: Map<string,
|
|
21
|
+
export declare function ensureSessionInitialized(sessions: Map<string, unknown>, sessionID: string, directory?: string): ManagedSessionState;
|
|
6
22
|
/**
|
|
7
23
|
* Activates the global mission state for a specific session.
|
|
8
24
|
*/
|
|
@@ -19,7 +35,7 @@ export declare function deactivateMissionState(sessionID: string): void;
|
|
|
19
35
|
/**
|
|
20
36
|
* Updates token usage and estimated cost for a session.
|
|
21
37
|
*/
|
|
22
|
-
export declare function updateSessionTokens(sessions: Map<string,
|
|
38
|
+
export declare function updateSessionTokens(sessions: Map<string, unknown>, sessionID: string, inputLen: number, outputLen: number): void;
|
|
23
39
|
/**
|
|
24
40
|
* Anomaly Management
|
|
25
41
|
*/
|
|
@@ -29,3 +45,4 @@ export declare function resetAnomaly(sessionID: string): void;
|
|
|
29
45
|
* Task Tracking
|
|
30
46
|
*/
|
|
31
47
|
export declare function updateCurrentTask(sessionID: string, taskID: string): void;
|
|
48
|
+
export {};
|
|
@@ -17,4 +17,4 @@ export declare function withTimeout<T>(promise: Promise<T>, timeoutMs: number, e
|
|
|
17
17
|
/**
|
|
18
18
|
* Debounce async function
|
|
19
19
|
*/
|
|
20
|
-
export declare function debounceAsync<
|
|
20
|
+
export declare function debounceAsync<TArgs extends unknown[], TResult>(fn: (...args: TArgs) => Promise<TResult>, delayMs: number): (...args: TArgs) => Promise<TResult>;
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Detects if other major plugins are present and ensures orchestrator plays nicely.
|
|
5
5
|
*/
|
|
6
|
-
import type { ChatMessageHook,
|
|
7
|
-
export declare class ExternalPluginCompatHook implements ChatMessageHook
|
|
6
|
+
import type { ChatMessageHook, ChatMessageResult, HookContext } from "../types.js";
|
|
7
|
+
export declare class ExternalPluginCompatHook implements ChatMessageHook {
|
|
8
8
|
name: string;
|
|
9
|
-
execute(ctx: HookContext, input:
|
|
9
|
+
execute(ctx: HookContext, input: string): Promise<ChatMessageResult>;
|
|
10
10
|
}
|
|
@@ -5,16 +5,8 @@
|
|
|
5
5
|
* - Agent headers (e.g. [P] PLANNER Working...)
|
|
6
6
|
* - Task ID tracking
|
|
7
7
|
*/
|
|
8
|
-
import type { PostToolUseHook, HookContext } from "../types.js";
|
|
8
|
+
import type { PostToolUseHook, HookContext, PostToolResult, ToolInput, ToolOutput } from "../types.js";
|
|
9
9
|
export declare class AgentUIHook implements PostToolUseHook {
|
|
10
10
|
name: "AgentUI";
|
|
11
|
-
execute(ctx: HookContext, tool: string, input:
|
|
12
|
-
title: string;
|
|
13
|
-
output: string;
|
|
14
|
-
metadata: any;
|
|
15
|
-
}): Promise<{
|
|
16
|
-
output?: undefined;
|
|
17
|
-
} | {
|
|
18
|
-
output: string;
|
|
19
|
-
}>;
|
|
11
|
+
execute(ctx: HookContext, tool: string, input: ToolInput, output: ToolOutput): Promise<PostToolResult>;
|
|
20
12
|
}
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MemoryGate Hook - Intercepts tool usage and turn completion to maintain memory.
|
|
3
3
|
*/
|
|
4
|
-
import { PostToolUseHook, AssistantDoneHook, HookContext } from "../types.js";
|
|
4
|
+
import type { PostToolUseHook, AssistantDoneHook, HookContext, HookResult, PostToolResult, ToolInput, ToolOutput } from "../types.js";
|
|
5
5
|
export declare class MemoryGateHook implements PostToolUseHook, AssistantDoneHook {
|
|
6
6
|
name: "MemoryGate";
|
|
7
7
|
private memoryManager;
|
|
8
|
-
execute(context: HookContext,
|
|
9
|
-
|
|
10
|
-
output: string;
|
|
11
|
-
metadata: any;
|
|
12
|
-
}): Promise<any>;
|
|
8
|
+
execute(context: HookContext, tool: string, input: ToolInput, output: ToolOutput): Promise<PostToolResult>;
|
|
9
|
+
execute(context: HookContext, finalText: string): Promise<HookResult>;
|
|
13
10
|
/**
|
|
14
11
|
* Post-Tool: Capture tool outputs to TASK memory
|
|
15
12
|
*/
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MetricsHook - Collects telemetry during mission execution
|
|
3
3
|
*/
|
|
4
|
-
import { PreToolUseHook, PostToolUseHook, AssistantDoneHook, HookContext } from "../types.js";
|
|
4
|
+
import type { PreToolUseHook, PostToolUseHook, AssistantDoneHook, HookContext, HookResult, PostToolResult, PreToolResult, ToolInput, ToolOutput } from "../types.js";
|
|
5
5
|
export declare class MetricsHook implements PreToolUseHook, PostToolUseHook, AssistantDoneHook {
|
|
6
6
|
name: "MetricsTelemetry";
|
|
7
7
|
private startTimes;
|
|
8
8
|
private metrics;
|
|
9
|
-
execute(context: HookContext,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
metadata: any;
|
|
13
|
-
}): Promise<any>;
|
|
9
|
+
execute(context: HookContext, tool: string, input: ToolInput): Promise<PreToolResult>;
|
|
10
|
+
execute(context: HookContext, tool: string, input: ToolInput, output: ToolOutput): Promise<PostToolResult>;
|
|
11
|
+
execute(context: HookContext, finalText: string): Promise<HookResult>;
|
|
14
12
|
}
|
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
* Unifies resource tracking, monitoring, and active memory compaction.
|
|
5
5
|
* Replaces separate ResourceUsageHook and MemoryCompactionHook.
|
|
6
6
|
*/
|
|
7
|
-
import type { PostToolUseHook, AssistantDoneHook, HookContext } from "../types.js";
|
|
7
|
+
import type { PostToolUseHook, AssistantDoneHook, HookContext, HookResult, PostToolResult, ToolInput, ToolOutput } from "../types.js";
|
|
8
8
|
export declare class ResourceControlHook implements PostToolUseHook, AssistantDoneHook {
|
|
9
9
|
name: "ResourceControl";
|
|
10
10
|
private lastCompactionTime;
|
|
11
|
-
execute(ctx: HookContext,
|
|
11
|
+
execute(ctx: HookContext, tool: string, input: ToolInput, output: ToolOutput): Promise<PostToolResult>;
|
|
12
|
+
execute(ctx: HookContext, finalText: string): Promise<HookResult>;
|
|
12
13
|
private checkMemoryHealth;
|
|
13
14
|
}
|
|
@@ -4,16 +4,8 @@
|
|
|
4
4
|
* Scans tool outputs for potential secrets (API Keys, etc) and masks them.
|
|
5
5
|
* This prevents leaking secrets into the context window or logs.
|
|
6
6
|
*/
|
|
7
|
-
import type { PostToolUseHook, HookContext } from "../types.js";
|
|
7
|
+
import type { PostToolUseHook, HookContext, PostToolResult, ToolInput, ToolOutput } from "../types.js";
|
|
8
8
|
export declare class SecretScannerHook implements PostToolUseHook {
|
|
9
9
|
name: "SecretScanner";
|
|
10
|
-
execute(ctx: HookContext, tool: string, input:
|
|
11
|
-
title: string;
|
|
12
|
-
output: string;
|
|
13
|
-
metadata: any;
|
|
14
|
-
}): Promise<{
|
|
15
|
-
output: string;
|
|
16
|
-
} | {
|
|
17
|
-
output?: undefined;
|
|
18
|
-
}>;
|
|
10
|
+
execute(ctx: HookContext, tool: string, input: ToolInput, output: ToolOutput): Promise<PostToolResult>;
|
|
19
11
|
}
|
|
@@ -5,17 +5,8 @@
|
|
|
5
5
|
* - Planner: Cannot write code or run commands.
|
|
6
6
|
* - Reviewer: Cannot write code (only review).
|
|
7
7
|
*/
|
|
8
|
-
import type { PreToolUseHook, HookContext } from "../types.js";
|
|
8
|
+
import type { PreToolUseHook, HookContext, PreToolResult, ToolInput } from "../types.js";
|
|
9
9
|
export declare class StrictRoleGuardHook implements PreToolUseHook {
|
|
10
10
|
name: "StrictRoleGuard";
|
|
11
|
-
execute(ctx: HookContext, tool: string, args:
|
|
12
|
-
action: "block";
|
|
13
|
-
reason: "Fork bomb detected.";
|
|
14
|
-
} | {
|
|
15
|
-
action: "block";
|
|
16
|
-
reason: "Root deletion blocked.";
|
|
17
|
-
} | {
|
|
18
|
-
action: "allow";
|
|
19
|
-
reason?: undefined;
|
|
20
|
-
}>;
|
|
11
|
+
execute(ctx: HookContext, tool: string, args: ToolInput): Promise<PreToolResult>;
|
|
21
12
|
}
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Tracks user interaction (chat messages) to pause auto-continuation/loops
|
|
5
5
|
* and update activity timestamps.
|
|
6
6
|
*/
|
|
7
|
-
import type { ChatMessageHook, HookContext } from "../types.js";
|
|
7
|
+
import type { ChatMessageHook, ChatMessageResult, HookContext } from "../types.js";
|
|
8
8
|
export declare class UserActivityHook implements ChatMessageHook {
|
|
9
9
|
name: "UserActivity";
|
|
10
|
-
execute(ctx: HookContext, message: string): Promise<
|
|
10
|
+
execute(ctx: HookContext, message: string): Promise<ChatMessageResult>;
|
|
11
11
|
}
|
|
@@ -6,10 +6,11 @@
|
|
|
6
6
|
* - Auto-continuation injection (Loop)
|
|
7
7
|
* - User cancellation detection
|
|
8
8
|
*/
|
|
9
|
-
import type { AssistantDoneHook, ChatMessageHook, HookContext } from "../types.js";
|
|
9
|
+
import type { AssistantDoneHook, ChatMessageHook, ChatMessageResult, HookContext, HookResult } from "../types.js";
|
|
10
10
|
export declare class MissionControlHook implements AssistantDoneHook, ChatMessageHook {
|
|
11
11
|
name: "MissionLoop";
|
|
12
|
-
execute(ctx: HookContext, text: string): Promise<
|
|
12
|
+
execute(ctx: HookContext, text: string): Promise<ChatMessageResult>;
|
|
13
|
+
execute(ctx: HookContext, text: string): Promise<HookResult>;
|
|
13
14
|
private handleChatCommand;
|
|
14
15
|
private cancelMission;
|
|
15
16
|
private handleMissionProgress;
|
|
@@ -2,14 +2,11 @@
|
|
|
2
2
|
* Sanity Check Hook
|
|
3
3
|
* Implements output anomaly detection.
|
|
4
4
|
*/
|
|
5
|
-
import type { PostToolUseHook, AssistantDoneHook, HookContext } from "../types.js";
|
|
5
|
+
import type { PostToolUseHook, AssistantDoneHook, HookContext, HookResult, PostToolResult, ToolInput, ToolOutput } from "../types.js";
|
|
6
6
|
export declare class SanityCheckHook implements PostToolUseHook, AssistantDoneHook {
|
|
7
7
|
name: "SanityCheck";
|
|
8
|
-
execute(ctx: HookContext,
|
|
9
|
-
|
|
10
|
-
output: string;
|
|
11
|
-
metadata: any;
|
|
12
|
-
}): Promise<any>;
|
|
8
|
+
execute(ctx: HookContext, tool: string, input: ToolInput, output: ToolOutput): Promise<PostToolResult>;
|
|
9
|
+
execute(ctx: HookContext, finalText: string): Promise<HookResult>;
|
|
13
10
|
private checkToolOutput;
|
|
14
11
|
private checkFinalText;
|
|
15
12
|
}
|
package/dist/hooks/registry.d.ts
CHANGED
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
* Hook Registry
|
|
3
3
|
* Manages registration and execution of hooks with priority and dependency support.
|
|
4
4
|
*/
|
|
5
|
-
import type { PreToolUseHook, PostToolUseHook, ChatMessageHook, AssistantDoneHook, HookContext, HookResult, HookMetadata } from "./types.js";
|
|
6
|
-
import { HOOK_ACTIONS } from "./constants.js";
|
|
5
|
+
import type { PreToolUseHook, PostToolUseHook, ChatMessageHook, AssistantDoneHook, HookContext, HookResult, HookMetadata, ChatMessageResult, PreToolResult, ToolInput, ToolOutput } from "./types.js";
|
|
7
6
|
export declare class HookRegistry {
|
|
8
7
|
private static instance;
|
|
9
8
|
private preToolHooks;
|
|
@@ -19,19 +18,8 @@ export declare class HookRegistry {
|
|
|
19
18
|
private prepareMetadata;
|
|
20
19
|
private sortHooks;
|
|
21
20
|
private topologicalSort;
|
|
22
|
-
executePreTool(ctx: HookContext, tool: string, args:
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
reason?: string;
|
|
26
|
-
}>;
|
|
27
|
-
executePostTool(ctx: HookContext, tool: string, input: Record<string, unknown>, output: {
|
|
28
|
-
title: string;
|
|
29
|
-
output: string;
|
|
30
|
-
metadata: Record<string, unknown>;
|
|
31
|
-
}): Promise<void>;
|
|
32
|
-
executeChat(ctx: HookContext, message: string): Promise<{
|
|
33
|
-
action: typeof HOOK_ACTIONS.PROCESS | typeof HOOK_ACTIONS.INTERCEPT;
|
|
34
|
-
modifiedMessage?: string;
|
|
35
|
-
}>;
|
|
21
|
+
executePreTool(ctx: HookContext, tool: string, args: ToolInput): Promise<PreToolResult>;
|
|
22
|
+
executePostTool(ctx: HookContext, tool: string, input: ToolInput, output: ToolOutput): Promise<void>;
|
|
23
|
+
executeChat(ctx: HookContext, message: string): Promise<ChatMessageResult>;
|
|
36
24
|
executeDone(ctx: HookContext, finalText: string): Promise<HookResult>;
|
|
37
25
|
}
|
package/dist/hooks/types.d.ts
CHANGED
|
@@ -25,17 +25,31 @@ export type HookResult = {
|
|
|
25
25
|
action: typeof HOOK_ACTIONS.INJECT;
|
|
26
26
|
prompts: string[];
|
|
27
27
|
};
|
|
28
|
+
export type ToolInput = Record<string, unknown>;
|
|
29
|
+
export interface ToolOutput {
|
|
30
|
+
title: string;
|
|
31
|
+
output: string;
|
|
32
|
+
metadata: Record<string, unknown>;
|
|
33
|
+
}
|
|
34
|
+
export type PreToolResult = {
|
|
35
|
+
action: typeof HOOK_ACTIONS.ALLOW | typeof HOOK_ACTIONS.BLOCK | typeof HOOK_ACTIONS.MODIFY;
|
|
36
|
+
modifiedArgs?: ToolInput;
|
|
37
|
+
reason?: string;
|
|
38
|
+
};
|
|
39
|
+
export type PostToolResult = {
|
|
40
|
+
output?: string;
|
|
41
|
+
};
|
|
42
|
+
export type ChatMessageResult = {
|
|
43
|
+
action: typeof HOOK_ACTIONS.PROCESS | typeof HOOK_ACTIONS.INTERCEPT;
|
|
44
|
+
modifiedMessage?: string;
|
|
45
|
+
};
|
|
28
46
|
/**
|
|
29
47
|
* Pre-Tool Execution Hook
|
|
30
48
|
* Runs before a tool is executed. Can block execution or modify arguments.
|
|
31
49
|
*/
|
|
32
50
|
export interface PreToolUseHook {
|
|
33
51
|
name: string;
|
|
34
|
-
execute(context: HookContext, tool: string, args:
|
|
35
|
-
action: typeof HOOK_ACTIONS.ALLOW | typeof HOOK_ACTIONS.BLOCK | typeof HOOK_ACTIONS.MODIFY;
|
|
36
|
-
modifiedArgs?: Record<string, unknown>;
|
|
37
|
-
reason?: string;
|
|
38
|
-
}>;
|
|
52
|
+
execute(context: HookContext, tool: string, args: ToolInput): Promise<PreToolResult>;
|
|
39
53
|
}
|
|
40
54
|
/**
|
|
41
55
|
* Post-Tool Execution Hook
|
|
@@ -43,13 +57,7 @@ export interface PreToolUseHook {
|
|
|
43
57
|
*/
|
|
44
58
|
export interface PostToolUseHook {
|
|
45
59
|
name: string;
|
|
46
|
-
execute(context: HookContext, tool: string, input:
|
|
47
|
-
title: string;
|
|
48
|
-
output: string;
|
|
49
|
-
metadata: Record<string, unknown>;
|
|
50
|
-
}): Promise<{
|
|
51
|
-
output?: string;
|
|
52
|
-
}>;
|
|
60
|
+
execute(context: HookContext, tool: string, input: ToolInput, output: ToolOutput): Promise<PostToolResult>;
|
|
53
61
|
}
|
|
54
62
|
/**
|
|
55
63
|
* Chat Message Hook
|
|
@@ -57,10 +65,7 @@ export interface PostToolUseHook {
|
|
|
57
65
|
*/
|
|
58
66
|
export interface ChatMessageHook {
|
|
59
67
|
name: string;
|
|
60
|
-
execute(context: HookContext, message: string): Promise<
|
|
61
|
-
action: typeof HOOK_ACTIONS.PROCESS | typeof HOOK_ACTIONS.INTERCEPT;
|
|
62
|
-
modifiedMessage?: string;
|
|
63
|
-
}>;
|
|
68
|
+
execute(context: HookContext, message: string): Promise<ChatMessageResult>;
|
|
64
69
|
}
|
|
65
70
|
/**
|
|
66
71
|
* Assistant Done Hook
|
package/dist/index.js
CHANGED
|
@@ -1037,7 +1037,7 @@ function show(options) {
|
|
|
1037
1037
|
} catch {
|
|
1038
1038
|
}
|
|
1039
1039
|
}, timeoutMs);
|
|
1040
|
-
const
|
|
1040
|
+
const payload = {
|
|
1041
1041
|
body: {
|
|
1042
1042
|
title: toast.title,
|
|
1043
1043
|
message: toast.message,
|
|
@@ -1045,15 +1045,11 @@ function show(options) {
|
|
|
1045
1045
|
duration: toast.duration
|
|
1046
1046
|
},
|
|
1047
1047
|
signal: ac.signal
|
|
1048
|
+
};
|
|
1049
|
+
Promise.resolve(client.tui.showToast(payload)).finally(() => {
|
|
1050
|
+
clearTimeout(timer);
|
|
1051
|
+
}).catch(() => {
|
|
1048
1052
|
});
|
|
1049
|
-
if (promise3 && typeof promise3.then === "function") {
|
|
1050
|
-
Promise.resolve(promise3).finally(() => {
|
|
1051
|
-
if (timer) {
|
|
1052
|
-
clearTimeout(timer);
|
|
1053
|
-
}
|
|
1054
|
-
}).catch(() => {
|
|
1055
|
-
});
|
|
1056
|
-
}
|
|
1057
1053
|
} catch {
|
|
1058
1054
|
}
|
|
1059
1055
|
}
|
|
@@ -36891,30 +36887,26 @@ function normalizeContinuationContext(state2, input) {
|
|
|
36891
36887
|
// src/core/orchestrator/session-manager.ts
|
|
36892
36888
|
function ensureSessionInitialized(sessions, sessionID, directory) {
|
|
36893
36889
|
if (!sessions.has(sessionID)) {
|
|
36894
|
-
const
|
|
36895
|
-
const newSession = {
|
|
36896
|
-
active: true,
|
|
36897
|
-
step: 0,
|
|
36898
|
-
timestamp: now,
|
|
36899
|
-
startTime: now,
|
|
36900
|
-
lastStepTime: now,
|
|
36901
|
-
lastCompletedMessageID: void 0,
|
|
36902
|
-
lastUserMessageAt: void 0,
|
|
36903
|
-
lastAssistantCompletedAt: void 0,
|
|
36904
|
-
lastAbortAt: void 0,
|
|
36905
|
-
tokens: { totalInput: 0, totalOutput: 0, estimatedCost: 0 }
|
|
36906
|
-
};
|
|
36890
|
+
const newSession2 = createManagedSession();
|
|
36907
36891
|
if (directory) {
|
|
36908
36892
|
const diskState = readLoopState(directory);
|
|
36909
36893
|
if (diskState && diskState.sessionID === sessionID) {
|
|
36910
|
-
|
|
36911
|
-
|
|
36894
|
+
newSession2.step = diskState.iteration;
|
|
36895
|
+
newSession2.startTime = new Date(diskState.startedAt).getTime();
|
|
36912
36896
|
log(`[SessionManager] Rehydrated session from disk: ${sessionID}`);
|
|
36913
36897
|
}
|
|
36914
36898
|
}
|
|
36915
|
-
sessions.set(sessionID,
|
|
36899
|
+
sessions.set(sessionID, newSession2);
|
|
36900
|
+
return newSession2;
|
|
36916
36901
|
}
|
|
36917
|
-
|
|
36902
|
+
const session = sessions.get(sessionID);
|
|
36903
|
+
if (isManagedSessionState(session)) return session;
|
|
36904
|
+
if (isRecord(session)) {
|
|
36905
|
+
return normalizeManagedSession(session);
|
|
36906
|
+
}
|
|
36907
|
+
const newSession = createManagedSession();
|
|
36908
|
+
sessions.set(sessionID, newSession);
|
|
36909
|
+
return newSession;
|
|
36918
36910
|
}
|
|
36919
36911
|
function ensureGlobalState(sessionID, directory) {
|
|
36920
36912
|
let stateSession = state.sessions.get(sessionID);
|
|
@@ -36978,6 +36970,43 @@ function updateSessionTokens(sessions, sessionID, inputLen, outputLen) {
|
|
|
36978
36970
|
const cost = session.tokens.totalInput / 1e3 * COST_PER_1K_INPUT + session.tokens.totalOutput / 1e3 * COST_PER_1K_OUTPUT;
|
|
36979
36971
|
session.tokens.estimatedCost = Number(cost.toFixed(4));
|
|
36980
36972
|
}
|
|
36973
|
+
function createManagedSession() {
|
|
36974
|
+
const now = Date.now();
|
|
36975
|
+
return {
|
|
36976
|
+
active: true,
|
|
36977
|
+
step: 0,
|
|
36978
|
+
timestamp: now,
|
|
36979
|
+
startTime: now,
|
|
36980
|
+
lastStepTime: now,
|
|
36981
|
+
lastCompletedMessageID: void 0,
|
|
36982
|
+
lastUserMessageAt: void 0,
|
|
36983
|
+
lastAssistantCompletedAt: void 0,
|
|
36984
|
+
lastAbortAt: void 0,
|
|
36985
|
+
tokens: { totalInput: 0, totalOutput: 0, estimatedCost: 0 }
|
|
36986
|
+
};
|
|
36987
|
+
}
|
|
36988
|
+
function normalizeManagedSession(session) {
|
|
36989
|
+
const now = Date.now();
|
|
36990
|
+
if (typeof session.active !== "boolean") session.active = true;
|
|
36991
|
+
if (typeof session.step !== "number") session.step = 0;
|
|
36992
|
+
if (typeof session.timestamp !== "number") session.timestamp = now;
|
|
36993
|
+
if (typeof session.startTime !== "number") session.startTime = now;
|
|
36994
|
+
if (typeof session.lastStepTime !== "number") session.lastStepTime = now;
|
|
36995
|
+
if (!isTokenUsage(session.tokens)) {
|
|
36996
|
+
session.tokens = { totalInput: 0, totalOutput: 0, estimatedCost: 0 };
|
|
36997
|
+
}
|
|
36998
|
+
return session;
|
|
36999
|
+
}
|
|
37000
|
+
function isManagedSessionState(value) {
|
|
37001
|
+
return isRecord(value) && typeof value.active === "boolean" && typeof value.step === "number" && typeof value.timestamp === "number" && typeof value.startTime === "number" && typeof value.lastStepTime === "number" && isTokenUsage(value.tokens);
|
|
37002
|
+
}
|
|
37003
|
+
function isRecord(value) {
|
|
37004
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
37005
|
+
}
|
|
37006
|
+
function isTokenUsage(value) {
|
|
37007
|
+
if (!isRecord(value)) return false;
|
|
37008
|
+
return typeof value.totalInput === "number" && typeof value.totalOutput === "number" && typeof value.estimatedCost === "number";
|
|
37009
|
+
}
|
|
36981
37010
|
function recordAnomaly(sessionID) {
|
|
36982
37011
|
const session = ensureGlobalState(sessionID);
|
|
36983
37012
|
session.anomalyCount = (session.anomalyCount || 0) + 1;
|
|
@@ -37000,6 +37029,7 @@ var SanityCheckHook = class {
|
|
|
37000
37029
|
if (toolOrText === TOOL_NAMES.CALL_AGENT) {
|
|
37001
37030
|
return this.checkToolOutput(ctx, input, output);
|
|
37002
37031
|
}
|
|
37032
|
+
return {};
|
|
37003
37033
|
} else {
|
|
37004
37034
|
return this.checkFinalText(ctx, toolOrText);
|
|
37005
37035
|
}
|
|
@@ -37008,7 +37038,7 @@ var SanityCheckHook = class {
|
|
|
37008
37038
|
const sanityResult = checkOutputSanity(toolOutput.output);
|
|
37009
37039
|
if (!sanityResult.isHealthy) {
|
|
37010
37040
|
const count = recordAnomaly(ctx.sessionID);
|
|
37011
|
-
const agentName = toolInput?.agent
|
|
37041
|
+
const agentName = typeof toolInput?.agent === "string" ? toolInput.agent : "unknown";
|
|
37012
37042
|
const recoveryText = count >= 2 ? ESCALATION_PROMPT : RECOVERY_PROMPT;
|
|
37013
37043
|
const errorMsg = MISSION_MESSAGES.ANOMALY_DETECTED_TITLE(agentName.toUpperCase()) + "\n\n" + MISSION_MESSAGES.ANOMALY_DETECTED_BODY(sanityResult.reason || "Unknown anomaly", count, recoveryText);
|
|
37014
37044
|
return { output: errorMsg };
|
|
@@ -37756,7 +37786,7 @@ var MissionControlHook = class {
|
|
|
37756
37786
|
deactivateMissionState(sessionID);
|
|
37757
37787
|
clearSession2(sessionID);
|
|
37758
37788
|
const session = sessions.get(sessionID);
|
|
37759
|
-
if (
|
|
37789
|
+
if (isRecord2(session)) {
|
|
37760
37790
|
session.active = false;
|
|
37761
37791
|
}
|
|
37762
37792
|
}
|
|
@@ -37872,11 +37902,11 @@ var MissionControlHook = class {
|
|
|
37872
37902
|
}
|
|
37873
37903
|
}
|
|
37874
37904
|
};
|
|
37875
|
-
function
|
|
37905
|
+
function isRecord2(value) {
|
|
37876
37906
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
37877
37907
|
}
|
|
37878
37908
|
function isMissionSessionState(value) {
|
|
37879
|
-
return
|
|
37909
|
+
return isRecord2(value) && typeof value.step === "number" && typeof value.startTime === "number" && typeof value.lastStepTime === "number";
|
|
37880
37910
|
}
|
|
37881
37911
|
|
|
37882
37912
|
// src/hooks/custom/strict-role-guard.ts
|
|
@@ -37909,7 +37939,7 @@ var StrictRoleGuardHook = class {
|
|
|
37909
37939
|
name = HOOK_NAMES2.STRICT_ROLE_GUARD;
|
|
37910
37940
|
async execute(ctx, tool2, args) {
|
|
37911
37941
|
if (tool2 === TOOL_NAMES.RUN_COMMAND || tool2 === TOOL_NAMES.RUN_BACKGROUND) {
|
|
37912
|
-
const cmd = args
|
|
37942
|
+
const cmd = typeof args.command === "string" ? args.command : void 0;
|
|
37913
37943
|
if (cmd) {
|
|
37914
37944
|
if (cmd.includes(SECURITY_PATTERNS.FORK_BOMB)) {
|
|
37915
37945
|
return { action: HOOK_ACTIONS.BLOCK, reason: MISSION_MESSAGES.BLOCK_REASON_FORK_BOMB };
|
|
@@ -37948,14 +37978,15 @@ var AgentUIHook = class {
|
|
|
37948
37978
|
name = HOOK_NAMES2.AGENT_UI;
|
|
37949
37979
|
async execute(ctx, tool2, input, output) {
|
|
37950
37980
|
if (tool2 !== TOOL_NAMES.CALL_AGENT) return {};
|
|
37951
|
-
|
|
37952
|
-
|
|
37981
|
+
const task = typeof input.task === "string" ? input.task : void 0;
|
|
37982
|
+
if (task) {
|
|
37983
|
+
const taskIdMatch = task.match(UI_PATTERNS.TASK_ID);
|
|
37953
37984
|
if (taskIdMatch) {
|
|
37954
37985
|
updateCurrentTask(ctx.sessionID, taskIdMatch[1].toUpperCase());
|
|
37955
37986
|
}
|
|
37956
37987
|
}
|
|
37957
|
-
|
|
37958
|
-
|
|
37988
|
+
const agentName = typeof input.agent === "string" ? input.agent : void 0;
|
|
37989
|
+
if (agentName) {
|
|
37959
37990
|
const indicator = agentName[0].toUpperCase();
|
|
37960
37991
|
const header = MISSION_MESSAGES.AGENT_HEADER_FORMAT(indicator, agentName.toUpperCase());
|
|
37961
37992
|
if (!output.output.startsWith("[" + indicator + "]")) {
|
|
@@ -38072,25 +38103,21 @@ var ResourceControlHook = class {
|
|
|
38072
38103
|
name = HOOK_NAMES2.RESOURCE_CONTROL;
|
|
38073
38104
|
lastCompactionTime = /* @__PURE__ */ new Map();
|
|
38074
38105
|
async execute(ctx, toolOrText, input, output) {
|
|
38075
|
-
|
|
38076
|
-
|
|
38077
|
-
|
|
38078
|
-
|
|
38079
|
-
inputLen = inputStr.length;
|
|
38080
|
-
}
|
|
38081
|
-
if (output) {
|
|
38082
|
-
const outputStr = typeof output === "string" ? output : JSON.stringify(output);
|
|
38083
|
-
outputLen = outputStr.length;
|
|
38084
|
-
}
|
|
38085
|
-
if (arguments.length === 2 && typeof toolOrText === "string") {
|
|
38106
|
+
const isAssistantDone = input === void 0 && output === void 0;
|
|
38107
|
+
const inputLen = isAssistantDone ? 0 : getSerializedLength(input);
|
|
38108
|
+
let outputLen = getSerializedLength(output);
|
|
38109
|
+
if (isAssistantDone) {
|
|
38086
38110
|
outputLen = toolOrText.length;
|
|
38087
38111
|
}
|
|
38088
38112
|
updateSessionTokens(ctx.sessions, ctx.sessionID, inputLen, outputLen);
|
|
38113
|
+
if (!isAssistantDone) {
|
|
38114
|
+
return {};
|
|
38115
|
+
}
|
|
38089
38116
|
const session = ctx.sessions.get(ctx.sessionID);
|
|
38090
38117
|
return this.checkMemoryHealth(ctx, session);
|
|
38091
38118
|
}
|
|
38092
38119
|
async checkMemoryHealth(ctx, session) {
|
|
38093
|
-
if (!session
|
|
38120
|
+
if (!hasTokenUsage(session)) return { action: HOOK_ACTIONS.CONTINUE };
|
|
38094
38121
|
const totalUsed = session.tokens.totalInput + session.tokens.totalOutput;
|
|
38095
38122
|
const maxTokens = CONTEXT_MONITOR_CONFIG.DEFAULT_MAX_TOKENS;
|
|
38096
38123
|
const usage = calculateUsage(totalUsed, maxTokens);
|
|
@@ -38112,6 +38139,22 @@ var ResourceControlHook = class {
|
|
|
38112
38139
|
};
|
|
38113
38140
|
}
|
|
38114
38141
|
};
|
|
38142
|
+
function getSerializedLength(value) {
|
|
38143
|
+
if (value === void 0 || value === null) return 0;
|
|
38144
|
+
if (typeof value === "string") return value.length;
|
|
38145
|
+
try {
|
|
38146
|
+
return JSON.stringify(value)?.length ?? 0;
|
|
38147
|
+
} catch {
|
|
38148
|
+
return String(value).length;
|
|
38149
|
+
}
|
|
38150
|
+
}
|
|
38151
|
+
function hasTokenUsage(session) {
|
|
38152
|
+
if (typeof session !== "object" || session === null || Array.isArray(session)) return false;
|
|
38153
|
+
const tokens = session.tokens;
|
|
38154
|
+
if (typeof tokens !== "object" || tokens === null || Array.isArray(tokens)) return false;
|
|
38155
|
+
const candidate = tokens;
|
|
38156
|
+
return typeof candidate.totalInput === "number" && typeof candidate.totalOutput === "number";
|
|
38157
|
+
}
|
|
38115
38158
|
|
|
38116
38159
|
// src/core/loop/todo-continuation.ts
|
|
38117
38160
|
init_shared();
|
|
@@ -41183,11 +41226,11 @@ var CONCURRENCY_KEYS = [
|
|
|
41183
41226
|
"providerConcurrency",
|
|
41184
41227
|
"modelConcurrency"
|
|
41185
41228
|
];
|
|
41186
|
-
function
|
|
41229
|
+
function isRecord3(value) {
|
|
41187
41230
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
41188
41231
|
}
|
|
41189
41232
|
function readLimitMap(value) {
|
|
41190
|
-
if (!
|
|
41233
|
+
if (!isRecord3(value)) return void 0;
|
|
41191
41234
|
const result = {};
|
|
41192
41235
|
for (const [key, limit] of Object.entries(value)) {
|
|
41193
41236
|
if (typeof limit === "number" && Number.isFinite(limit) && limit >= 0) {
|
|
@@ -41197,7 +41240,7 @@ function readLimitMap(value) {
|
|
|
41197
41240
|
return Object.keys(result).length > 0 ? result : void 0;
|
|
41198
41241
|
}
|
|
41199
41242
|
function extractConcurrencyConfig(source) {
|
|
41200
|
-
if (!
|
|
41243
|
+
if (!isRecord3(source)) return {};
|
|
41201
41244
|
const config3 = {};
|
|
41202
41245
|
if (typeof source.defaultConcurrency === "number" && source.defaultConcurrency >= 0) {
|
|
41203
41246
|
config3.defaultConcurrency = source.defaultConcurrency;
|
|
@@ -41211,7 +41254,7 @@ function extractConcurrencyConfig(source) {
|
|
|
41211
41254
|
return config3;
|
|
41212
41255
|
}
|
|
41213
41256
|
function hasConcurrencyConfig(source) {
|
|
41214
|
-
if (!
|
|
41257
|
+
if (!isRecord3(source)) return false;
|
|
41215
41258
|
return CONCURRENCY_KEYS.some((key) => source[key] !== void 0);
|
|
41216
41259
|
}
|
|
41217
41260
|
function mergeConcurrencyConfig(base, override) {
|
|
@@ -41235,14 +41278,14 @@ function mergeConcurrencyConfig(base, override) {
|
|
|
41235
41278
|
|
|
41236
41279
|
// src/core/config/plugin-options.ts
|
|
41237
41280
|
function parseOrchestratorPluginOptions(options) {
|
|
41238
|
-
const source =
|
|
41281
|
+
const source = isRecord4(options) ? options : {};
|
|
41239
41282
|
return {
|
|
41240
41283
|
concurrency: extractConcurrencyConfig(source),
|
|
41241
41284
|
missionLoop: readMissionLoopOptions(source.missionLoop)
|
|
41242
41285
|
};
|
|
41243
41286
|
}
|
|
41244
41287
|
function readMissionLoopOptions(value) {
|
|
41245
|
-
if (!
|
|
41288
|
+
if (!isRecord4(value)) return DEFAULT_MISSION_RUNTIME_OPTIONS;
|
|
41246
41289
|
return {
|
|
41247
41290
|
ledger: readBoolean(value.ledger, DEFAULT_MISSION_RUNTIME_OPTIONS.ledger),
|
|
41248
41291
|
markdownMemory: readBoolean(value.markdownMemory, DEFAULT_MISSION_RUNTIME_OPTIONS.markdownMemory),
|
|
@@ -41258,7 +41301,7 @@ function readBoolean(value, fallback) {
|
|
|
41258
41301
|
function readPositiveInteger(value, fallback) {
|
|
41259
41302
|
return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : fallback;
|
|
41260
41303
|
}
|
|
41261
|
-
function
|
|
41304
|
+
function isRecord4(value) {
|
|
41262
41305
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
41263
41306
|
}
|
|
41264
41307
|
|
|
@@ -41380,7 +41423,7 @@ This plugin runs in "Claude Code Compatibility Mode".
|
|
|
41380
41423
|
}
|
|
41381
41424
|
|
|
41382
41425
|
// src/plugin-handlers/config-handler.ts
|
|
41383
|
-
function
|
|
41426
|
+
function isRecord5(value) {
|
|
41384
41427
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
41385
41428
|
}
|
|
41386
41429
|
function isPermissionAction(value) {
|
|
@@ -41390,10 +41433,10 @@ function mergePermission(globalPermission, agentPermission) {
|
|
|
41390
41433
|
if (agentPermission === void 0) {
|
|
41391
41434
|
return globalPermission;
|
|
41392
41435
|
}
|
|
41393
|
-
if (
|
|
41436
|
+
if (isRecord5(globalPermission) && isRecord5(agentPermission)) {
|
|
41394
41437
|
return { ...globalPermission, ...agentPermission };
|
|
41395
41438
|
}
|
|
41396
|
-
if (isPermissionAction(globalPermission) &&
|
|
41439
|
+
if (isPermissionAction(globalPermission) && isRecord5(agentPermission)) {
|
|
41397
41440
|
return { "*": globalPermission, ...agentPermission };
|
|
41398
41441
|
}
|
|
41399
41442
|
return agentPermission;
|
|
@@ -43081,6 +43124,20 @@ Use \`delegate_task\` with background=true for parallel work.
|
|
|
43081
43124
|
// src/index.ts
|
|
43082
43125
|
var require2 = createRequire(import.meta.url);
|
|
43083
43126
|
var { version: PLUGIN_VERSION } = require2("../package.json");
|
|
43127
|
+
function isRecord6(value) {
|
|
43128
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
43129
|
+
}
|
|
43130
|
+
function readStringField(source, key) {
|
|
43131
|
+
const value = source[key];
|
|
43132
|
+
return typeof value === "string" ? value : void 0;
|
|
43133
|
+
}
|
|
43134
|
+
function readCreatedSessionID(properties) {
|
|
43135
|
+
if (!isRecord6(properties)) return void 0;
|
|
43136
|
+
const directID = readStringField(properties, "sessionID") ?? readStringField(properties, "id");
|
|
43137
|
+
if (directID) return directID;
|
|
43138
|
+
const info = properties.info;
|
|
43139
|
+
return isRecord6(info) ? readStringField(info, "sessionID") : void 0;
|
|
43140
|
+
}
|
|
43084
43141
|
var OrchestratorPlugin = async (input, options) => {
|
|
43085
43142
|
const { directory, client } = input;
|
|
43086
43143
|
const orchestratorOptions = parseOrchestratorPluginOptions(options);
|
|
@@ -43140,8 +43197,8 @@ var OrchestratorPlugin = async (input, options) => {
|
|
|
43140
43197
|
event: async (payload) => {
|
|
43141
43198
|
const result = await createEventHandler(handlerContext)(payload);
|
|
43142
43199
|
const { event } = payload;
|
|
43143
|
-
if (event.type === SESSION_EVENTS.CREATED
|
|
43144
|
-
const sessionID = event.properties
|
|
43200
|
+
if (event.type === SESSION_EVENTS.CREATED) {
|
|
43201
|
+
const sessionID = readCreatedSessionID(event.properties);
|
|
43145
43202
|
if (sessionID) {
|
|
43146
43203
|
todoSync.registerSession(sessionID);
|
|
43147
43204
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
export interface CachedDiagnostics {
|
|
2
|
-
diagnostics:
|
|
2
|
+
diagnostics: string;
|
|
3
3
|
timestamp: number;
|
|
4
4
|
filesMtime: number;
|
|
5
5
|
}
|
|
6
6
|
export declare class DiagnosticsCache {
|
|
7
7
|
private cache;
|
|
8
8
|
private defaultTTL;
|
|
9
|
-
get(directory: string, file?: string): Promise<
|
|
10
|
-
set(directory: string, file: string | undefined, diagnostics:
|
|
9
|
+
get(directory: string, file?: string): Promise<string | null>;
|
|
10
|
+
set(directory: string, file: string | undefined, diagnostics: string): Promise<void>;
|
|
11
11
|
private getCacheKey;
|
|
12
12
|
private getFilesMtime;
|
|
13
13
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-orchestrator",
|
|
3
3
|
"displayName": "OpenCode Orchestrator",
|
|
4
|
-
"description": "
|
|
5
|
-
"version": "1.3.
|
|
4
|
+
"description": "Multi-agent mission control for OpenCode with Commander, Planner, Worker, and Reviewer workflows.",
|
|
5
|
+
"version": "1.3.7",
|
|
6
6
|
"author": "agnusdei1207",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"repository": {
|