opencode-matrixx 2.6.6 → 2.6.8
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/dist/agents/seraph.d.ts +1 -1
- package/dist/cli.js +51 -4
- package/dist/config/schema/background-task.d.ts +37 -0
- package/dist/config/schema/dcp.d.ts +46 -0
- package/dist/config/schema/matrixx-config.d.ts +32 -0
- package/dist/features/background-agent/admission.d.ts +24 -0
- package/dist/features/background-agent/concurrency.d.ts +9 -0
- package/dist/features/background-agent/constants.d.ts +13 -0
- package/dist/features/background-agent/handle-index.d.ts +12 -0
- package/dist/features/background-agent/manager.d.ts +59 -4
- package/dist/features/background-agent/notification-builder.d.ts +1 -0
- package/dist/features/background-agent/reconcile.d.ts +33 -0
- package/dist/features/background-agent/revive.d.ts +39 -0
- package/dist/features/background-agent/session-output.d.ts +40 -0
- package/dist/features/background-agent/task-history.d.ts +20 -0
- package/dist/features/background-agent/types.d.ts +21 -1
- package/dist/features/background-agent/wake-scheduler.d.ts +47 -0
- package/dist/features/background-agent/wallclock.d.ts +37 -0
- package/dist/features/bdd/schema.d.ts +5 -5
- package/dist/features/builtin-commands/templates/refactor.d.ts +1 -1
- package/dist/features/context-injector/collector.d.ts +2 -0
- package/dist/features/context-injector/index.d.ts +1 -1
- package/dist/hooks/agent-usage-reminder/constants.d.ts +1 -0
- package/dist/hooks/compaction-context-injector/hook.d.ts +1 -0
- package/dist/hooks/context-mode-enforcer/constants.d.ts +1 -1
- package/dist/hooks/task-continuation-enforcer/constants.d.ts +4 -0
- package/dist/index.js +2172 -1276
- package/dist/matrixx.schema.json +165 -3
- package/dist/plugin-handlers/agent-config-handler.d.ts +2 -1
- package/dist/shared/context-mode-enforcement.d.ts +35 -0
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/poll-timeout-outcome.d.ts +21 -0
- package/dist/shared/revive-outcome.d.ts +15 -0
- package/dist/shared/saturated-outcome.d.ts +18 -0
- package/dist/shared/wallclock-outcome.d.ts +18 -0
- package/dist/tools/background-task/constants.d.ts +1 -0
- package/dist/tools/background-task/create-background-revive.d.ts +3 -0
- package/dist/tools/background-task/index.d.ts +1 -1
- package/dist/tools/background-task/tools.d.ts +1 -0
- package/dist/tools/background-task/types.d.ts +9 -0
- package/dist/tools/dcp-switch-profile/tools.d.ts +7 -0
- package/dist/tools/delegate-task/constants.d.ts +1 -0
- package/dist/tools/index.d.ts +1 -2
- package/package.json +1 -1
- package/dist/shared/context-mode-prompt.d.ts +0 -12
- package/dist/tools/delegate-agent/background-executor.d.ts +0 -13
- package/dist/tools/delegate-agent/completion-poller.d.ts +0 -11
- package/dist/tools/delegate-agent/constants.d.ts +0 -2
- package/dist/tools/delegate-agent/index.d.ts +0 -3
- package/dist/tools/delegate-agent/message-dir.d.ts +0 -1
- package/dist/tools/delegate-agent/message-processor.d.ts +0 -2
- package/dist/tools/delegate-agent/session-creator.d.ts +0 -15
- package/dist/tools/delegate-agent/sync-executor.d.ts +0 -21
- package/dist/tools/delegate-agent/tools.d.ts +0 -3
- package/dist/tools/delegate-agent/types.d.ts +0 -19
- /package/dist/{shared/context-mode-prompt.test.d.ts → tools/delegate-task/poll-timeout-outcome.test.d.ts} +0 -0
package/dist/agents/seraph.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ import type { AgentPromptMetadata } from "./types";
|
|
|
13
13
|
* - Generate clarifying questions for the user
|
|
14
14
|
* - Prepare directives for the planner agent
|
|
15
15
|
*/
|
|
16
|
-
export declare const SERAPH_SYSTEM_PROMPT = "# Seraph - Pre-Planning Consultant\n\n## CONSTRAINTS\n\n- **READ-ONLY**: You analyze, question, advise. You do NOT implement or modify files.\n- **OUTPUT**: Your analysis feeds into Oracle (planner). Be actionable.\n\n---\n\n## PHASE 0: INTENT CLASSIFICATION (MANDATORY FIRST STEP)\n\nBefore ANY analysis, classify the work intent. This determines your entire strategy.\n\n### Step 1: Identify Intent Type\n\n| Intent | Signals | Your Primary Focus |\n|--------|---------|-------------------|\n| **Refactoring** | \"refactor\", \"restructure\", \"clean up\", changes to existing code | SAFETY: regression prevention, behavior preservation |\n| **Build from Scratch** | \"create new\", \"add feature\", greenfield, new module | DISCOVERY: explore patterns first, informed questions |\n| **Mid-sized Task** | Scoped feature, specific deliverable, bounded work | GUARDRAILS: exact deliverables, explicit exclusions |\n| **Collaborative** | \"help me plan\", \"let's figure out\", wants dialogue | INTERACTIVE: incremental clarity through dialogue |\n| **Architecture** | \"how should we structure\", system design, infrastructure | STRATEGIC: long-term impact, Oracle recommendation |\n| **Research** | Investigation needed, goal exists but path unclear | INVESTIGATION: exit criteria, parallel probes |\n\n### Step 2: Validate Classification\n\nConfirm:\n- [ ] Intent type is clear from request\n- [ ] If ambiguous, ASK before proceeding\n\n---\n\n## PHASE 1: INTENT-SPECIFIC ANALYSIS\n\n### IF REFACTORING\n\n**Your Mission**: Ensure zero regressions, behavior preservation.\n\n**Tool Guidance** (recommend to Oracle):\n- `lsp_find_references`: Map all usages before changes\n- `lsp_rename` / `lsp_prepare_rename`: Safe symbol renames\n- `ast_grep_search`: Find structural patterns to preserve\n- `ast_grep_replace(dryRun=true)`: Preview transformations\n\n**Questions to Ask**:\n1. What specific behavior must be preserved? (test commands to verify)\n2. What's the rollback strategy if something breaks?\n3. Should this change propagate to related code, or stay isolated?\n\n**Directives for Oracle**:\n- MUST: Define pre-refactor verification (exact test commands + expected outputs)\n- MUST: Verify after EACH change, not just at the end\n- MUST NOT: Change behavior while restructuring\n- MUST NOT: Refactor adjacent code not in scope\n\n---\n\n### IF BUILD FROM SCRATCH\n\n**Your Mission**: Discover patterns before asking, then surface hidden requirements.\n\n**Pre-Analysis Actions** (YOU should do before questioning):\n```\n// Launch these explore agents FIRST\n// Prompt structure: CONTEXT + GOAL + QUESTION + REQUEST\ndelegate_agent(subagent_type=\"trinity\", prompt=\"I'm analyzing a new feature request and need to understand existing patterns before asking clarifying questions. Find similar implementations in this codebase - their structure and conventions.\")\ndelegate_agent(subagent_type=\"trinity\", prompt=\"I'm planning to build [feature type] and want to ensure consistency with the project. Find how similar features are organized - file structure, naming patterns, and architectural approach.\")\ndelegate_agent(subagent_type=\"operator\", prompt=\"I'm implementing [technology] and need to understand best practices before making recommendations. Find official documentation, common patterns, and known pitfalls to avoid.\")\n```\n\n**Questions to Ask** (AFTER exploration):\n1. Found pattern X in codebase. Should new code follow this, or deviate? Why?\n2. What should explicitly NOT be built? (scope boundaries)\n3. What's the minimum viable version vs full vision?\n\n**Directives for Oracle**:\n- MUST: Follow patterns from `[discovered file:lines]`\n- MUST: Define \"Must NOT Have\" section (AI over-engineering prevention)\n- MUST NOT: Invent new patterns when existing ones work\n- MUST NOT: Add features not explicitly requested\n\n---\n\n### IF MID-SIZED TASK\n\n**Your Mission**: Define exact boundaries. AI slop prevention is critical.\n\n**Questions to Ask**:\n1. What are the EXACT outputs? (files, endpoints, UI elements)\n2. What must NOT be included? (explicit exclusions)\n3. What are the hard boundaries? (no touching X, no changing Y)\n4. Acceptance criteria: how do we know it's done?\n\n**AI-Slop Patterns to Flag**:\n| Pattern | Example | Ask |\n|---------|---------|-----|\n| Scope inflation | \"Also tests for adjacent modules\" | \"Should I add tests beyond [TARGET]?\" |\n| Premature abstraction | \"Extracted to utility\" | \"Do you want abstraction, or inline?\" |\n| Over-validation | \"15 error checks for 3 inputs\" | \"Error handling: minimal or comprehensive?\" |\n| Documentation bloat | \"Added JSDoc everywhere\" | \"Documentation: none, minimal, or full?\" |\n\n**Directives for Oracle**:\n- MUST: \"Must Have\" section with exact deliverables\n- MUST: \"Must NOT Have\" section with explicit exclusions\n- MUST: Per-task guardrails (what each task should NOT do)\n- MUST NOT: Exceed defined scope\n\n---\n\n### IF COLLABORATIVE\n\n**Your Mission**: Build understanding through dialogue. No rush.\n\n**Behavior**:\n1. Start with open-ended exploration questions\n2. Use explore/librarian to gather context as user provides direction\n3. Incrementally refine understanding\n4. Don't finalize until user confirms direction\n\n**Questions to Ask**:\n1. What problem are you trying to solve? (not what solution you want)\n2. What constraints exist? (time, tech stack, team skills)\n3. What trade-offs are acceptable? (speed vs quality vs cost)\n\n**Directives for Oracle**:\n- MUST: Record all user decisions in \"Key Decisions\" section\n- MUST: Flag assumptions explicitly\n- MUST NOT: Proceed without user confirmation on major decisions\n\n---\n\n### IF ARCHITECTURE\n\n**Your Mission**: Strategic analysis. Long-term impact assessment.\n\n**Oracle Consultation** (RECOMMEND to Oracle):\n```\nTask(\n subagent_type=\"oracle\",\n prompt=\"Architecture consultation:\n Request: [user's request]\n Current state: [gathered context]\n \n Analyze: options, trade-offs, long-term implications, risks\"\n)\n```\n\n**Questions to Ask**:\n1. What's the expected lifespan of this design?\n2. What scale/load should it handle?\n3. What are the non-negotiable constraints?\n4. What existing systems must this integrate with?\n\n**AI-Slop Guardrails for Architecture**:\n- MUST NOT: Over-engineer for hypothetical future requirements\n- MUST NOT: Add unnecessary abstraction layers\n- MUST NOT: Ignore existing patterns for \"better\" design\n- MUST: Document decisions and rationale\n\n**Directives for Oracle**:\n- MUST: Consult Oracle before finalizing plan\n- MUST: Document architectural decisions with rationale\n- MUST: Define \"minimum viable architecture\"\n- MUST NOT: Introduce complexity without justification\n\n---\n\n### IF RESEARCH\n\n**Your Mission**: Define investigation boundaries and exit criteria.\n\n**Questions to Ask**:\n1. What's the goal of this research? (what decision will it inform?)\n2. How do we know research is complete? (exit criteria)\n3. What's the time box? (when to stop and synthesize)\n4. What outputs are expected? (report, recommendations, prototype?)\n\n**Investigation Structure**:\n```\n// Parallel probes - Prompt structure: CONTEXT + GOAL + QUESTION + REQUEST\ndelegate_agent(subagent_type=\"trinity\", prompt=\"I'm researching how to implement [feature] and need to understand the current approach. Find how X is currently handled - implementation details, edge cases, and any known issues.\")\ndelegate_agent(subagent_type=\"operator\", prompt=\"I'm implementing Y and need authoritative guidance. Find official documentation - API reference, configuration options, and recommended patterns.\")\ndelegate_agent(subagent_type=\"operator\", prompt=\"I'm looking for proven implementations of Z. Find open source projects that solve this - focus on production-quality code and lessons learned.\")\n```\n\n**Directives for Oracle**:\n- MUST: Define clear exit criteria\n- MUST: Specify parallel investigation tracks\n- MUST: Define synthesis format (how to present findings)\n- MUST NOT: Research indefinitely without convergence\n\n---\n\n## OUTPUT FORMAT\n\n```markdown\n## Intent Classification\n**Type**: [Refactoring | Build | Mid-sized | Collaborative | Architecture | Research]\n**Confidence**: [High | Medium | Low]\n**Rationale**: [Why this classification]\n\n## Pre-Analysis Findings\n[Results from explore/librarian agents if launched]\n[Relevant codebase patterns discovered]\n\n## Questions for User\n1. [Most critical question first]\n2. [Second priority]\n3. [Third priority]\n\n## Identified Risks\n- [Risk 1]: [Mitigation]\n- [Risk 2]: [Mitigation]\n\n## Directives for Oracle\n\n### Core Directives\n- MUST: [Required action]\n- MUST: [Required action]\n- MUST NOT: [Forbidden action]\n- MUST NOT: [Forbidden action]\n- PATTERN: Follow `[file:lines]`\n- TOOL: Use `[specific tool]` for [purpose]\n\n### QA/Acceptance Criteria Directives (MANDATORY)\n> **ZERO USER INTERVENTION PRINCIPLE**: All acceptance criteria MUST be executable by agents.\n\n- MUST: Write acceptance criteria as executable commands (curl, bun test, playwright actions)\n- MUST: Include exact expected outputs, not vague descriptions\n- MUST: Specify verification tool for each deliverable type (playwright for UI, curl for API, etc.)\n- MUST NOT: Create criteria requiring \"user manually tests...\"\n- MUST NOT: Create criteria requiring \"user visually confirms...\"\n- MUST NOT: Create criteria requiring \"user clicks/interacts...\"\n- MUST NOT: Use placeholders without concrete examples (bad: \"[endpoint]\", good: \"/api/users\")\n\nExample of GOOD acceptance criteria:\n```\ncurl -s http://localhost:3000/api/health | jq '.status'\n# Assert: Output is \"ok\"\n```\n\nExample of BAD acceptance criteria (FORBIDDEN):\n```\nUser opens browser and checks if the page loads correctly.\nUser confirms the button works as expected.\n```\n\n## Recommended Approach\n[1-2 sentence summary of how to proceed]\n```\n\n---\n\n## TOOL REFERENCE\n\n| Tool | When to Use | Intent |\n|------|-------------|--------|\n| `lsp_find_references` | Map impact before changes | Refactoring |\n| `lsp_rename` | Safe symbol renames | Refactoring |\n| `ast_grep_search` | Find structural patterns | Refactoring, Build |\n| `explore` agent | Codebase pattern discovery | Build, Research |\n| `librarian` agent | External docs, best practices | Build, Architecture, Research |\n| `oracle` agent | Read-only consultation. High-IQ debugging, architecture | Architecture |\n\n---\n\n## CRITICAL RULES\n\n**NEVER**:\n- Skip intent classification\n- Ask generic questions (\"What's the scope?\")\n- Proceed without addressing ambiguity\n- Make assumptions about user's codebase\n- Suggest acceptance criteria requiring user intervention (\"user manually tests\", \"user confirms\", \"user clicks\")\n- Leave QA/acceptance criteria vague or placeholder-heavy\n\n**ALWAYS**:\n- Classify intent FIRST\n- Be specific (\"Should this change UserService only, or also AuthService?\")\n- Explore before asking (for Build/Research intents)\n- Provide actionable directives for Oracle\n- Include QA automation directives in every output\n- Ensure acceptance criteria are agent-executable (commands, not human actions)\n";
|
|
16
|
+
export declare const SERAPH_SYSTEM_PROMPT = "# Seraph - Pre-Planning Consultant\n\n## CONSTRAINTS\n\n- **READ-ONLY**: You analyze, question, advise. You do NOT implement or modify files.\n- **OUTPUT**: Your analysis feeds into Oracle (planner). Be actionable.\n\n---\n\n## PHASE 0: INTENT CLASSIFICATION (MANDATORY FIRST STEP)\n\nBefore ANY analysis, classify the work intent. This determines your entire strategy.\n\n### Step 1: Identify Intent Type\n\n| Intent | Signals | Your Primary Focus |\n|--------|---------|-------------------|\n| **Refactoring** | \"refactor\", \"restructure\", \"clean up\", changes to existing code | SAFETY: regression prevention, behavior preservation |\n| **Build from Scratch** | \"create new\", \"add feature\", greenfield, new module | DISCOVERY: explore patterns first, informed questions |\n| **Mid-sized Task** | Scoped feature, specific deliverable, bounded work | GUARDRAILS: exact deliverables, explicit exclusions |\n| **Collaborative** | \"help me plan\", \"let's figure out\", wants dialogue | INTERACTIVE: incremental clarity through dialogue |\n| **Architecture** | \"how should we structure\", system design, infrastructure | STRATEGIC: long-term impact, Oracle recommendation |\n| **Research** | Investigation needed, goal exists but path unclear | INVESTIGATION: exit criteria, parallel probes |\n\n### Step 2: Validate Classification\n\nConfirm:\n- [ ] Intent type is clear from request\n- [ ] If ambiguous, ASK before proceeding\n\n---\n\n## PHASE 1: INTENT-SPECIFIC ANALYSIS\n\n### IF REFACTORING\n\n**Your Mission**: Ensure zero regressions, behavior preservation.\n\n**Tool Guidance** (recommend to Oracle):\n- `lsp_find_references`: Map all usages before changes\n- `lsp_rename` / `lsp_prepare_rename`: Safe symbol renames\n- `ast_grep_search`: Find structural patterns to preserve\n- `ast_grep_replace(dryRun=true)`: Preview transformations\n\n**Questions to Ask**:\n1. What specific behavior must be preserved? (test commands to verify)\n2. What's the rollback strategy if something breaks?\n3. Should this change propagate to related code, or stay isolated?\n\n**Directives for Oracle**:\n- MUST: Define pre-refactor verification (exact test commands + expected outputs)\n- MUST: Verify after EACH change, not just at the end\n- MUST NOT: Change behavior while restructuring\n- MUST NOT: Refactor adjacent code not in scope\n\n---\n\n### IF BUILD FROM SCRATCH\n\n**Your Mission**: Discover patterns before asking, then surface hidden requirements.\n\n**Pre-Analysis Actions** (YOU should do before questioning):\n```\n// Launch these explore agents FIRST\n// Prompt structure: CONTEXT + GOAL + QUESTION + REQUEST\ntask(subagent_type=\"trinity\", run_in_background=true, prompt=\"I'm analyzing a new feature request and need to understand existing patterns before asking clarifying questions. Find similar implementations in this codebase - their structure and conventions.\")\ntask(subagent_type=\"trinity\", run_in_background=true, prompt=\"I'm planning to build [feature type] and want to ensure consistency with the project. Find how similar features are organized - file structure, naming patterns, and architectural approach.\")\ntask(subagent_type=\"operator\", run_in_background=true, prompt=\"I'm implementing [technology] and need to understand best practices before making recommendations. Find official documentation, common patterns, and known pitfalls to avoid.\")\n```\n\n**Questions to Ask** (AFTER exploration):\n1. Found pattern X in codebase. Should new code follow this, or deviate? Why?\n2. What should explicitly NOT be built? (scope boundaries)\n3. What's the minimum viable version vs full vision?\n\n**Directives for Oracle**:\n- MUST: Follow patterns from `[discovered file:lines]`\n- MUST: Define \"Must NOT Have\" section (AI over-engineering prevention)\n- MUST NOT: Invent new patterns when existing ones work\n- MUST NOT: Add features not explicitly requested\n\n---\n\n### IF MID-SIZED TASK\n\n**Your Mission**: Define exact boundaries. AI slop prevention is critical.\n\n**Questions to Ask**:\n1. What are the EXACT outputs? (files, endpoints, UI elements)\n2. What must NOT be included? (explicit exclusions)\n3. What are the hard boundaries? (no touching X, no changing Y)\n4. Acceptance criteria: how do we know it's done?\n\n**AI-Slop Patterns to Flag**:\n| Pattern | Example | Ask |\n|---------|---------|-----|\n| Scope inflation | \"Also tests for adjacent modules\" | \"Should I add tests beyond [TARGET]?\" |\n| Premature abstraction | \"Extracted to utility\" | \"Do you want abstraction, or inline?\" |\n| Over-validation | \"15 error checks for 3 inputs\" | \"Error handling: minimal or comprehensive?\" |\n| Documentation bloat | \"Added JSDoc everywhere\" | \"Documentation: none, minimal, or full?\" |\n\n**Directives for Oracle**:\n- MUST: \"Must Have\" section with exact deliverables\n- MUST: \"Must NOT Have\" section with explicit exclusions\n- MUST: Per-task guardrails (what each task should NOT do)\n- MUST NOT: Exceed defined scope\n\n---\n\n### IF COLLABORATIVE\n\n**Your Mission**: Build understanding through dialogue. No rush.\n\n**Behavior**:\n1. Start with open-ended exploration questions\n2. Use explore/librarian to gather context as user provides direction\n3. Incrementally refine understanding\n4. Don't finalize until user confirms direction\n\n**Questions to Ask**:\n1. What problem are you trying to solve? (not what solution you want)\n2. What constraints exist? (time, tech stack, team skills)\n3. What trade-offs are acceptable? (speed vs quality vs cost)\n\n**Directives for Oracle**:\n- MUST: Record all user decisions in \"Key Decisions\" section\n- MUST: Flag assumptions explicitly\n- MUST NOT: Proceed without user confirmation on major decisions\n\n---\n\n### IF ARCHITECTURE\n\n**Your Mission**: Strategic analysis. Long-term impact assessment.\n\n**Oracle Consultation** (RECOMMEND to Oracle):\n```\nTask(\n subagent_type=\"oracle\",\n prompt=\"Architecture consultation:\n Request: [user's request]\n Current state: [gathered context]\n \n Analyze: options, trade-offs, long-term implications, risks\"\n)\n```\n\n**Questions to Ask**:\n1. What's the expected lifespan of this design?\n2. What scale/load should it handle?\n3. What are the non-negotiable constraints?\n4. What existing systems must this integrate with?\n\n**AI-Slop Guardrails for Architecture**:\n- MUST NOT: Over-engineer for hypothetical future requirements\n- MUST NOT: Add unnecessary abstraction layers\n- MUST NOT: Ignore existing patterns for \"better\" design\n- MUST: Document decisions and rationale\n\n**Directives for Oracle**:\n- MUST: Consult Oracle before finalizing plan\n- MUST: Document architectural decisions with rationale\n- MUST: Define \"minimum viable architecture\"\n- MUST NOT: Introduce complexity without justification\n\n---\n\n### IF RESEARCH\n\n**Your Mission**: Define investigation boundaries and exit criteria.\n\n**Questions to Ask**:\n1. What's the goal of this research? (what decision will it inform?)\n2. How do we know research is complete? (exit criteria)\n3. What's the time box? (when to stop and synthesize)\n4. What outputs are expected? (report, recommendations, prototype?)\n\n**Investigation Structure**:\n```\n// Parallel probes - Prompt structure: CONTEXT + GOAL + QUESTION + REQUEST\ntask(subagent_type=\"trinity\", run_in_background=true, prompt=\"I'm researching how to implement [feature] and need to understand the current approach. Find how X is currently handled - implementation details, edge cases, and any known issues.\")\ntask(subagent_type=\"operator\", run_in_background=true, prompt=\"I'm implementing Y and need authoritative guidance. Find official documentation - API reference, configuration options, and recommended patterns.\")\ntask(subagent_type=\"operator\", run_in_background=true, prompt=\"I'm looking for proven implementations of Z. Find open source projects that solve this - focus on production-quality code and lessons learned.\")\n```\n\n**Directives for Oracle**:\n- MUST: Define clear exit criteria\n- MUST: Specify parallel investigation tracks\n- MUST: Define synthesis format (how to present findings)\n- MUST NOT: Research indefinitely without convergence\n\n---\n\n## OUTPUT FORMAT\n\n```markdown\n## Intent Classification\n**Type**: [Refactoring | Build | Mid-sized | Collaborative | Architecture | Research]\n**Confidence**: [High | Medium | Low]\n**Rationale**: [Why this classification]\n\n## Pre-Analysis Findings\n[Results from explore/librarian agents if launched]\n[Relevant codebase patterns discovered]\n\n## Questions for User\n1. [Most critical question first]\n2. [Second priority]\n3. [Third priority]\n\n## Identified Risks\n- [Risk 1]: [Mitigation]\n- [Risk 2]: [Mitigation]\n\n## Directives for Oracle\n\n### Core Directives\n- MUST: [Required action]\n- MUST: [Required action]\n- MUST NOT: [Forbidden action]\n- MUST NOT: [Forbidden action]\n- PATTERN: Follow `[file:lines]`\n- TOOL: Use `[specific tool]` for [purpose]\n\n### QA/Acceptance Criteria Directives (MANDATORY)\n> **ZERO USER INTERVENTION PRINCIPLE**: All acceptance criteria MUST be executable by agents.\n\n- MUST: Write acceptance criteria as executable commands (curl, bun test, playwright actions)\n- MUST: Include exact expected outputs, not vague descriptions\n- MUST: Specify verification tool for each deliverable type (playwright for UI, curl for API, etc.)\n- MUST NOT: Create criteria requiring \"user manually tests...\"\n- MUST NOT: Create criteria requiring \"user visually confirms...\"\n- MUST NOT: Create criteria requiring \"user clicks/interacts...\"\n- MUST NOT: Use placeholders without concrete examples (bad: \"[endpoint]\", good: \"/api/users\")\n\nExample of GOOD acceptance criteria:\n```\ncurl -s http://localhost:3000/api/health | jq '.status'\n# Assert: Output is \"ok\"\n```\n\nExample of BAD acceptance criteria (FORBIDDEN):\n```\nUser opens browser and checks if the page loads correctly.\nUser confirms the button works as expected.\n```\n\n## Recommended Approach\n[1-2 sentence summary of how to proceed]\n```\n\n---\n\n## TOOL REFERENCE\n\n| Tool | When to Use | Intent |\n|------|-------------|--------|\n| `lsp_find_references` | Map impact before changes | Refactoring |\n| `lsp_rename` | Safe symbol renames | Refactoring |\n| `ast_grep_search` | Find structural patterns | Refactoring, Build |\n| `explore` agent | Codebase pattern discovery | Build, Research |\n| `librarian` agent | External docs, best practices | Build, Architecture, Research |\n| `oracle` agent | Read-only consultation. High-IQ debugging, architecture | Architecture |\n\n---\n\n## CRITICAL RULES\n\n**NEVER**:\n- Skip intent classification\n- Ask generic questions (\"What's the scope?\")\n- Proceed without addressing ambiguity\n- Make assumptions about user's codebase\n- Suggest acceptance criteria requiring user intervention (\"user manually tests\", \"user confirms\", \"user clicks\")\n- Leave QA/acceptance criteria vague or placeholder-heavy\n\n**ALWAYS**:\n- Classify intent FIRST\n- Be specific (\"Should this change UserService only, or also AuthService?\")\n- Explore before asking (for Build/Research intents)\n- Provide actionable directives for Oracle\n- Include QA automation directives in every output\n- Ensure acceptance criteria are agent-executable (commands, not human actions)\n";
|
|
17
17
|
export declare function createSeraphAgent(model: string): AgentConfig;
|
|
18
18
|
export declare namespace createSeraphAgent {
|
|
19
19
|
var mode: "subagent";
|
package/dist/cli.js
CHANGED
|
@@ -15787,6 +15787,20 @@ var CircuitBreakerConfigSchema = exports_external.object({
|
|
|
15787
15787
|
maxToolCalls: exports_external.number().int().min(10).optional(),
|
|
15788
15788
|
consecutiveThreshold: exports_external.number().int().min(5).optional()
|
|
15789
15789
|
});
|
|
15790
|
+
var NestedAdmissionConfigSchema = exports_external.object({
|
|
15791
|
+
enabled: exports_external.boolean().optional(),
|
|
15792
|
+
mode: exports_external.enum(["bypass", "reserve"]).optional(),
|
|
15793
|
+
maxDepth: exports_external.number().int().min(1).max(5).optional()
|
|
15794
|
+
});
|
|
15795
|
+
var WakeSchedulerConfigSchema = exports_external.object({
|
|
15796
|
+
enabled: exports_external.boolean().optional(),
|
|
15797
|
+
intervalMs: exports_external.number().min(60000).optional()
|
|
15798
|
+
});
|
|
15799
|
+
var JobBoardConfigSchema = exports_external.object({
|
|
15800
|
+
enabled: exports_external.boolean().optional(),
|
|
15801
|
+
strategy: exports_external.enum(["latest", "checkpoint-compatible"]).optional(),
|
|
15802
|
+
maxRetainedSnapshots: exports_external.number().int().min(1).max(100).optional()
|
|
15803
|
+
});
|
|
15790
15804
|
var BackgroundTaskConfigSchema = exports_external.object({
|
|
15791
15805
|
defaultConcurrency: exports_external.number().min(1).optional(),
|
|
15792
15806
|
providerConcurrency: exports_external.record(exports_external.string(), exports_external.number().min(0)).optional(),
|
|
@@ -15794,7 +15808,13 @@ var BackgroundTaskConfigSchema = exports_external.object({
|
|
|
15794
15808
|
staleTimeoutMs: exports_external.number().min(60000).optional(),
|
|
15795
15809
|
messageStalenessTimeoutMs: exports_external.number().min(60000).optional(),
|
|
15796
15810
|
maxToolCalls: exports_external.number().int().min(10).optional(),
|
|
15797
|
-
circuitBreaker: CircuitBreakerConfigSchema.optional()
|
|
15811
|
+
circuitBreaker: CircuitBreakerConfigSchema.optional(),
|
|
15812
|
+
admissionTimeoutMs: exports_external.union([exports_external.literal(0), exports_external.number().min(60000)]).optional(),
|
|
15813
|
+
nestedAdmission: NestedAdmissionConfigSchema.optional(),
|
|
15814
|
+
wakeScheduler: WakeSchedulerConfigSchema.optional(),
|
|
15815
|
+
jobBoard: JobBoardConfigSchema.optional(),
|
|
15816
|
+
wallClockTimeoutMs: exports_external.union([exports_external.literal(0), exports_external.number().int().min(60000).max(2147483647)]).optional(),
|
|
15817
|
+
wallClockAbortGraceMs: exports_external.number().int().min(1000).max(60000).optional()
|
|
15798
15818
|
});
|
|
15799
15819
|
|
|
15800
15820
|
// src/config/schema/browser-automation.ts
|
|
@@ -15873,7 +15893,7 @@ var CommentCheckerConfigSchema = exports_external.object({
|
|
|
15873
15893
|
var ContextModeConfigSchema = exports_external.object({
|
|
15874
15894
|
enabled: exports_external.boolean().default(true),
|
|
15875
15895
|
enforce: exports_external.boolean().default(false),
|
|
15876
|
-
blocked_tools: exports_external.array(exports_external.string()).default(["
|
|
15896
|
+
blocked_tools: exports_external.array(exports_external.string()).default(["grep", "glob"])
|
|
15877
15897
|
});
|
|
15878
15898
|
|
|
15879
15899
|
// src/config/schema/dcp.ts
|
|
@@ -15959,12 +15979,37 @@ var BUILTIN_DCP_PROFILES = {
|
|
|
15959
15979
|
turnProtection: { enabled: true, turns: 5 },
|
|
15960
15980
|
experimental: { allowSubAgents: true },
|
|
15961
15981
|
strategies: { purgeErrors: { turns: 4 } }
|
|
15982
|
+
},
|
|
15983
|
+
brutal: {
|
|
15984
|
+
pruneNotification: "off",
|
|
15985
|
+
compress: {
|
|
15986
|
+
maxContextLimit: "20%",
|
|
15987
|
+
minContextLimit: "10%",
|
|
15988
|
+
nudgeFrequency: 1,
|
|
15989
|
+
nudgeForce: "strong",
|
|
15990
|
+
iterationNudgeThreshold: 1
|
|
15991
|
+
},
|
|
15992
|
+
turnProtection: { enabled: false },
|
|
15993
|
+
experimental: { allowSubAgents: false },
|
|
15994
|
+
strategies: { purgeErrors: { turns: 1 } }
|
|
15962
15995
|
}
|
|
15963
15996
|
};
|
|
15997
|
+
var DcpHandoffCompressionSchema = exports_external.object({
|
|
15998
|
+
enabled: exports_external.boolean().default(true),
|
|
15999
|
+
maxMessages: exports_external.number().int().min(1).default(6),
|
|
16000
|
+
keepFirst: exports_external.number().int().min(0).default(2),
|
|
16001
|
+
keepLast: exports_external.number().int().min(0).default(3)
|
|
16002
|
+
});
|
|
15964
16003
|
var DcpConfigSchema = exports_external.object({
|
|
15965
16004
|
enabled: exports_external.boolean().default(true),
|
|
15966
16005
|
profiles: exports_external.record(exports_external.string(), DcpProfileDefinitionSchema).default(BUILTIN_DCP_PROFILES),
|
|
15967
16006
|
default_profile: exports_external.string().optional(),
|
|
16007
|
+
handoffCompression: DcpHandoffCompressionSchema.default({
|
|
16008
|
+
enabled: true,
|
|
16009
|
+
maxMessages: 6,
|
|
16010
|
+
keepFirst: 2,
|
|
16011
|
+
keepLast: 3
|
|
16012
|
+
}),
|
|
15968
16013
|
base: exports_external.object({
|
|
15969
16014
|
autoUpdate: exports_external.boolean().default(false),
|
|
15970
16015
|
debug: exports_external.boolean().default(false),
|
|
@@ -16021,7 +16066,8 @@ var DcpConfigSchema = exports_external.object({
|
|
|
16021
16066
|
enabled: false,
|
|
16022
16067
|
automaticStrategies: true
|
|
16023
16068
|
}),
|
|
16024
|
-
protectedFilePatterns: exports_external.array(exports_external.string()).default([])
|
|
16069
|
+
protectedFilePatterns: exports_external.array(exports_external.string()).default([]),
|
|
16070
|
+
experimental: DcpExperimentalSchema.default({ allowSubAgents: true })
|
|
16025
16071
|
}).default({
|
|
16026
16072
|
autoUpdate: false,
|
|
16027
16073
|
debug: false,
|
|
@@ -16042,7 +16088,8 @@ var DcpConfigSchema = exports_external.object({
|
|
|
16042
16088
|
},
|
|
16043
16089
|
commands: { enabled: true, protectedTools: [] },
|
|
16044
16090
|
manualMode: { enabled: false, automaticStrategies: true },
|
|
16045
|
-
protectedFilePatterns: []
|
|
16091
|
+
protectedFilePatterns: [],
|
|
16092
|
+
experimental: { allowSubAgents: true }
|
|
16046
16093
|
})
|
|
16047
16094
|
});
|
|
16048
16095
|
|
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
/** Idle-parent wake scheduler settings (default ON, default interval 300000ms, minimum 60000ms) */
|
|
3
|
+
export declare const WakeSchedulerConfigSchema: z.ZodObject<{
|
|
4
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
5
|
+
intervalMs: z.ZodOptional<z.ZodNumber>;
|
|
6
|
+
}, z.core.$strip>;
|
|
7
|
+
/** Job-board snapshot settings (defaults: enabled true, strategy "latest", maxRetainedSnapshots 20) */
|
|
8
|
+
export declare const JobBoardConfigSchema: z.ZodObject<{
|
|
9
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
10
|
+
strategy: z.ZodOptional<z.ZodEnum<{
|
|
11
|
+
latest: "latest";
|
|
12
|
+
"checkpoint-compatible": "checkpoint-compatible";
|
|
13
|
+
}>>;
|
|
14
|
+
maxRetainedSnapshots: z.ZodOptional<z.ZodNumber>;
|
|
15
|
+
}, z.core.$strip>;
|
|
2
16
|
export declare const BackgroundTaskConfigSchema: z.ZodObject<{
|
|
3
17
|
defaultConcurrency: z.ZodOptional<z.ZodNumber>;
|
|
4
18
|
providerConcurrency: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
|
|
@@ -11,5 +25,28 @@ export declare const BackgroundTaskConfigSchema: z.ZodObject<{
|
|
|
11
25
|
maxToolCalls: z.ZodOptional<z.ZodNumber>;
|
|
12
26
|
consecutiveThreshold: z.ZodOptional<z.ZodNumber>;
|
|
13
27
|
}, z.core.$strip>>;
|
|
28
|
+
admissionTimeoutMs: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<0>, z.ZodNumber]>>;
|
|
29
|
+
nestedAdmission: z.ZodOptional<z.ZodObject<{
|
|
30
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
31
|
+
mode: z.ZodOptional<z.ZodEnum<{
|
|
32
|
+
bypass: "bypass";
|
|
33
|
+
reserve: "reserve";
|
|
34
|
+
}>>;
|
|
35
|
+
maxDepth: z.ZodOptional<z.ZodNumber>;
|
|
36
|
+
}, z.core.$strip>>;
|
|
37
|
+
wakeScheduler: z.ZodOptional<z.ZodObject<{
|
|
38
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
39
|
+
intervalMs: z.ZodOptional<z.ZodNumber>;
|
|
40
|
+
}, z.core.$strip>>;
|
|
41
|
+
jobBoard: z.ZodOptional<z.ZodObject<{
|
|
42
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
43
|
+
strategy: z.ZodOptional<z.ZodEnum<{
|
|
44
|
+
latest: "latest";
|
|
45
|
+
"checkpoint-compatible": "checkpoint-compatible";
|
|
46
|
+
}>>;
|
|
47
|
+
maxRetainedSnapshots: z.ZodOptional<z.ZodNumber>;
|
|
48
|
+
}, z.core.$strip>>;
|
|
49
|
+
wallClockTimeoutMs: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<0>, z.ZodNumber]>>;
|
|
50
|
+
wallClockAbortGraceMs: z.ZodOptional<z.ZodNumber>;
|
|
14
51
|
}, z.core.$strip>;
|
|
15
52
|
export type BackgroundTaskConfig = z.infer<typeof BackgroundTaskConfigSchema>;
|
|
@@ -158,7 +158,44 @@ export declare const BUILTIN_DCP_PROFILES: {
|
|
|
158
158
|
};
|
|
159
159
|
};
|
|
160
160
|
};
|
|
161
|
+
readonly brutal: {
|
|
162
|
+
readonly pruneNotification: "off";
|
|
163
|
+
readonly compress: {
|
|
164
|
+
readonly maxContextLimit: "20%";
|
|
165
|
+
readonly minContextLimit: "10%";
|
|
166
|
+
readonly nudgeFrequency: 1;
|
|
167
|
+
readonly nudgeForce: "strong";
|
|
168
|
+
readonly iterationNudgeThreshold: 1;
|
|
169
|
+
};
|
|
170
|
+
readonly turnProtection: {
|
|
171
|
+
readonly enabled: false;
|
|
172
|
+
};
|
|
173
|
+
readonly experimental: {
|
|
174
|
+
readonly allowSubAgents: false;
|
|
175
|
+
};
|
|
176
|
+
readonly strategies: {
|
|
177
|
+
readonly purgeErrors: {
|
|
178
|
+
readonly turns: 1;
|
|
179
|
+
};
|
|
180
|
+
};
|
|
181
|
+
};
|
|
161
182
|
};
|
|
183
|
+
/**
|
|
184
|
+
* Configuration for compressing background task results when sending
|
|
185
|
+
* completion notifications to the parent session (handoff boundary).
|
|
186
|
+
*
|
|
187
|
+
* When enabled, assistant messages beyond `maxMessages` are truncated:
|
|
188
|
+
* the first `keepFirst` and last `keepLast` messages are preserved,
|
|
189
|
+
* with a "[... N messages truncated]" marker inserted between them.
|
|
190
|
+
* This reduces the context cost of notifying the parent session.
|
|
191
|
+
*/
|
|
192
|
+
export declare const DcpHandoffCompressionSchema: z.ZodObject<{
|
|
193
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
194
|
+
maxMessages: z.ZodDefault<z.ZodNumber>;
|
|
195
|
+
keepFirst: z.ZodDefault<z.ZodNumber>;
|
|
196
|
+
keepLast: z.ZodDefault<z.ZodNumber>;
|
|
197
|
+
}, z.core.$strip>;
|
|
198
|
+
export type DcpHandoffCompression = z.infer<typeof DcpHandoffCompressionSchema>;
|
|
162
199
|
export declare const DcpConfigSchema: z.ZodObject<{
|
|
163
200
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
164
201
|
profiles: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
@@ -194,6 +231,12 @@ export declare const DcpConfigSchema: z.ZodObject<{
|
|
|
194
231
|
}, z.core.$strip>>;
|
|
195
232
|
}, z.core.$strip>>>;
|
|
196
233
|
default_profile: z.ZodOptional<z.ZodString>;
|
|
234
|
+
handoffCompression: z.ZodDefault<z.ZodObject<{
|
|
235
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
236
|
+
maxMessages: z.ZodDefault<z.ZodNumber>;
|
|
237
|
+
keepFirst: z.ZodDefault<z.ZodNumber>;
|
|
238
|
+
keepLast: z.ZodDefault<z.ZodNumber>;
|
|
239
|
+
}, z.core.$strip>>;
|
|
197
240
|
base: z.ZodDefault<z.ZodObject<{
|
|
198
241
|
autoUpdate: z.ZodDefault<z.ZodBoolean>;
|
|
199
242
|
debug: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -240,6 +283,9 @@ export declare const DcpConfigSchema: z.ZodObject<{
|
|
|
240
283
|
automaticStrategies: z.ZodDefault<z.ZodBoolean>;
|
|
241
284
|
}, z.core.$strip>>;
|
|
242
285
|
protectedFilePatterns: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
286
|
+
experimental: z.ZodDefault<z.ZodObject<{
|
|
287
|
+
allowSubAgents: z.ZodOptional<z.ZodBoolean>;
|
|
288
|
+
}, z.core.$strip>>;
|
|
243
289
|
}, z.core.$strip>>;
|
|
244
290
|
}, z.core.$strip>;
|
|
245
291
|
export type DcpConfig = z.infer<typeof DcpConfigSchema>;
|
|
@@ -1608,6 +1608,12 @@ export declare const MatrixxConfigSchema: z.ZodObject<{
|
|
|
1608
1608
|
}, z.core.$strip>>;
|
|
1609
1609
|
}, z.core.$strip>>>;
|
|
1610
1610
|
default_profile: z.ZodOptional<z.ZodString>;
|
|
1611
|
+
handoffCompression: z.ZodDefault<z.ZodObject<{
|
|
1612
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
1613
|
+
maxMessages: z.ZodDefault<z.ZodNumber>;
|
|
1614
|
+
keepFirst: z.ZodDefault<z.ZodNumber>;
|
|
1615
|
+
keepLast: z.ZodDefault<z.ZodNumber>;
|
|
1616
|
+
}, z.core.$strip>>;
|
|
1611
1617
|
base: z.ZodDefault<z.ZodObject<{
|
|
1612
1618
|
autoUpdate: z.ZodDefault<z.ZodBoolean>;
|
|
1613
1619
|
debug: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -1654,6 +1660,9 @@ export declare const MatrixxConfigSchema: z.ZodObject<{
|
|
|
1654
1660
|
automaticStrategies: z.ZodDefault<z.ZodBoolean>;
|
|
1655
1661
|
}, z.core.$strip>>;
|
|
1656
1662
|
protectedFilePatterns: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
1663
|
+
experimental: z.ZodDefault<z.ZodObject<{
|
|
1664
|
+
allowSubAgents: z.ZodOptional<z.ZodBoolean>;
|
|
1665
|
+
}, z.core.$strip>>;
|
|
1657
1666
|
}, z.core.$strip>>;
|
|
1658
1667
|
}, z.core.$strip>>;
|
|
1659
1668
|
auto_update: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -1701,6 +1710,29 @@ export declare const MatrixxConfigSchema: z.ZodObject<{
|
|
|
1701
1710
|
maxToolCalls: z.ZodOptional<z.ZodNumber>;
|
|
1702
1711
|
consecutiveThreshold: z.ZodOptional<z.ZodNumber>;
|
|
1703
1712
|
}, z.core.$strip>>;
|
|
1713
|
+
admissionTimeoutMs: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<0>, z.ZodNumber]>>;
|
|
1714
|
+
nestedAdmission: z.ZodOptional<z.ZodObject<{
|
|
1715
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
1716
|
+
mode: z.ZodOptional<z.ZodEnum<{
|
|
1717
|
+
bypass: "bypass";
|
|
1718
|
+
reserve: "reserve";
|
|
1719
|
+
}>>;
|
|
1720
|
+
maxDepth: z.ZodOptional<z.ZodNumber>;
|
|
1721
|
+
}, z.core.$strip>>;
|
|
1722
|
+
wakeScheduler: z.ZodOptional<z.ZodObject<{
|
|
1723
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
1724
|
+
intervalMs: z.ZodOptional<z.ZodNumber>;
|
|
1725
|
+
}, z.core.$strip>>;
|
|
1726
|
+
jobBoard: z.ZodOptional<z.ZodObject<{
|
|
1727
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
1728
|
+
strategy: z.ZodOptional<z.ZodEnum<{
|
|
1729
|
+
latest: "latest";
|
|
1730
|
+
"checkpoint-compatible": "checkpoint-compatible";
|
|
1731
|
+
}>>;
|
|
1732
|
+
maxRetainedSnapshots: z.ZodOptional<z.ZodNumber>;
|
|
1733
|
+
}, z.core.$strip>>;
|
|
1734
|
+
wallClockTimeoutMs: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<0>, z.ZodNumber]>>;
|
|
1735
|
+
wallClockAbortGraceMs: z.ZodOptional<z.ZodNumber>;
|
|
1704
1736
|
}, z.core.$strip>>;
|
|
1705
1737
|
notification: z.ZodOptional<z.ZodObject<{
|
|
1706
1738
|
force_enable: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a background launch originates from the root session or from a
|
|
3
|
+
* managed (subagent) session descended from it. Nested launches are exempt
|
|
4
|
+
* from the concurrency semaphore so a saturated managed child cannot deadlock
|
|
5
|
+
* by waiting on its own background work.
|
|
6
|
+
*/
|
|
7
|
+
export type AdmissionClass = {
|
|
8
|
+
kind: "root";
|
|
9
|
+
} | {
|
|
10
|
+
kind: "nested";
|
|
11
|
+
depth: number;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Classify a launch whose requesting session is `parentSessionID`.
|
|
15
|
+
*
|
|
16
|
+
* Walks the child→parent session registry using `getParentSessionID`, treating
|
|
17
|
+
* each registered ancestor hop as one level of nesting. Depth is capped at
|
|
18
|
+
* `maxDepth` and reported as actually reached.
|
|
19
|
+
*
|
|
20
|
+
* Fails open to `root` when the requester is absent from the process-local
|
|
21
|
+
* registry (undefined, empty, or unregistered), so a cold start can never
|
|
22
|
+
* misclassify a root launch as nested.
|
|
23
|
+
*/
|
|
24
|
+
export declare function classifyAdmission(parentSessionID: string | undefined, maxDepth: number): AdmissionClass;
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import type { BackgroundTaskConfig } from "../../config/schema";
|
|
2
|
+
export type AcquireOutcome = {
|
|
3
|
+
granted: true;
|
|
4
|
+
} | {
|
|
5
|
+
granted: false;
|
|
6
|
+
reason: "timeout" | "cancelled";
|
|
7
|
+
waitedMs: number;
|
|
8
|
+
};
|
|
2
9
|
export declare class ConcurrencyManager {
|
|
3
10
|
private config?;
|
|
4
11
|
private counts;
|
|
5
12
|
private queues;
|
|
6
13
|
constructor(config?: BackgroundTaskConfig);
|
|
7
14
|
getConcurrencyLimit(model: string): number;
|
|
15
|
+
private tryAcquireSlot;
|
|
8
16
|
acquire(model: string): Promise<void>;
|
|
17
|
+
acquireWithDeadline(model: string, timeoutMs?: number): Promise<AcquireOutcome>;
|
|
9
18
|
release(model: string): void;
|
|
10
19
|
/**
|
|
11
20
|
* Cancel all waiting acquires for a model. Used during cleanup.
|
|
@@ -12,6 +12,19 @@ export declare const MIN_IDLE_TIME_MS = 5000;
|
|
|
12
12
|
export declare const POLLING_INTERVAL_MS = 3000;
|
|
13
13
|
export declare const PRUNE_THROTTLE_MS = 30000;
|
|
14
14
|
export declare const TASK_CLEANUP_DELAY_MS: number;
|
|
15
|
+
export declare const DEFAULT_ADMISSION_TIMEOUT_MS = 0;
|
|
16
|
+
export declare const DEFAULT_WALL_CLOCK_TIMEOUT_MS = 0;
|
|
17
|
+
export declare const DEFAULT_WALL_CLOCK_ABORT_GRACE_MS = 5000;
|
|
18
|
+
export declare const DEFAULT_NESTED_ADMISSION_ENABLED = true;
|
|
19
|
+
export declare const DEFAULT_NESTED_ADMISSION_MODE: "bypass";
|
|
20
|
+
export declare const DEFAULT_NESTED_MAX_DEPTH = 2;
|
|
21
|
+
export declare const DEFAULT_WAKE_SCHEDULER_ENABLED = false;
|
|
22
|
+
export declare const DEFAULT_WAKE_INTERVAL_MS = 300000;
|
|
23
|
+
export declare const MIN_WAKE_INTERVAL_MS = 60000;
|
|
24
|
+
export declare const DEFAULT_JOB_BOARD_ENABLED = true;
|
|
25
|
+
export declare const DEFAULT_JOB_BOARD_STRATEGY: "latest";
|
|
26
|
+
export declare const DEFAULT_MAX_RETAINED_SNAPSHOTS = 10;
|
|
27
|
+
export declare const RECONCILE_CONFIRMATION_GRACE_MS = 5000;
|
|
15
28
|
export type ProcessCleanupEvent = NodeJS.Signals | "beforeExit" | "exit";
|
|
16
29
|
export type OpencodeClient = PluginInput["client"];
|
|
17
30
|
export interface MessagePartInfo {
|
|
@@ -26,7 +26,19 @@ export declare const BgHandleSchema: z.ZodObject<{
|
|
|
26
26
|
pending: "pending";
|
|
27
27
|
running: "running";
|
|
28
28
|
completed: "completed";
|
|
29
|
+
stopped: "stopped";
|
|
30
|
+
statusUncertain: "statusUncertain";
|
|
29
31
|
}>;
|
|
32
|
+
sessionID: z.ZodOptional<z.ZodString>;
|
|
33
|
+
terminalReason: z.ZodOptional<z.ZodEnum<{
|
|
34
|
+
aborted: "aborted";
|
|
35
|
+
"queue-saturated": "queue-saturated";
|
|
36
|
+
"no-output": "no-output";
|
|
37
|
+
uncertain: "uncertain";
|
|
38
|
+
stale: "stale";
|
|
39
|
+
"nested-depth-exceeded": "nested-depth-exceeded";
|
|
40
|
+
"wall-clock-timeout": "wall-clock-timeout";
|
|
41
|
+
}>>;
|
|
30
42
|
model: z.ZodOptional<z.ZodObject<{
|
|
31
43
|
providerID: z.ZodString;
|
|
32
44
|
modelID: z.ZodString;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { PluginInput } from "@opencode-ai/plugin";
|
|
2
|
-
import type { BackgroundTaskConfig, TmuxConfig } from "../../config/schema";
|
|
2
|
+
import type { BackgroundTaskConfig, DcpHandoffCompression, TmuxConfig } from "../../config/schema";
|
|
3
3
|
import { TaskHistory } from "./task-history";
|
|
4
|
-
import type { BackgroundTask, LaunchInput, ResumeInput } from "./types";
|
|
4
|
+
import type { BackgroundTask, LaunchInput, ResumeInput, ReviveInput } from "./types";
|
|
5
5
|
export interface EventProperties {
|
|
6
6
|
sessionID?: string;
|
|
7
7
|
info?: {
|
|
@@ -41,15 +41,26 @@ export declare class BackgroundManager {
|
|
|
41
41
|
private processingKeys;
|
|
42
42
|
private completionTimers;
|
|
43
43
|
private idleDeferralTimers;
|
|
44
|
+
private wakeScheduler;
|
|
44
45
|
private notificationQueueByParent;
|
|
45
46
|
private enableParentSessionNotifications;
|
|
46
47
|
private cachedCircuitBreakerSettings?;
|
|
48
|
+
private handoffCompression?;
|
|
49
|
+
/** Active nested bypass admits per concurrency key (maxDepth cap). */
|
|
50
|
+
private nestedActive;
|
|
51
|
+
/** Task IDs admitted via nested bypass — used to decrement `nestedActive` exactly once. */
|
|
52
|
+
private nestedBypassTaskIds;
|
|
53
|
+
/** Elapsed-time bound supervisor (U7 wall-clock). OFF by default — arms nothing when disabled. */
|
|
54
|
+
private wallclock;
|
|
55
|
+
/** Grace timers pending a terminal wall-clock mark, keyed by task id. */
|
|
56
|
+
private wallclockGraceTimers;
|
|
47
57
|
readonly taskHistory: TaskHistory;
|
|
48
58
|
constructor(ctx: PluginInput, config?: BackgroundTaskConfig, options?: {
|
|
49
59
|
tmuxConfig?: TmuxConfig;
|
|
50
60
|
onSubagentSessionCreated?: OnSubagentSessionCreated;
|
|
51
61
|
onShutdown?: () => void;
|
|
52
62
|
enableParentSessionNotifications?: boolean;
|
|
63
|
+
handoffCompression?: DcpHandoffCompression;
|
|
53
64
|
});
|
|
54
65
|
/**
|
|
55
66
|
* Persist a lightweight handle for the given task. Called on running and
|
|
@@ -57,14 +68,45 @@ export declare class BackgroundManager {
|
|
|
57
68
|
* Best-effort: write failures are logged and never break task lifecycle.
|
|
58
69
|
*/
|
|
59
70
|
private persistHandle;
|
|
71
|
+
private armWallclock;
|
|
72
|
+
private disarmWallclock;
|
|
73
|
+
private onWallclockFire;
|
|
74
|
+
private completeWallclockTimeout;
|
|
60
75
|
/**
|
|
61
76
|
* Recover handles persisted by a previous manager/process. Sweeps stale
|
|
62
|
-
* handles first, then loads the remainder into memory.
|
|
63
|
-
*
|
|
77
|
+
* handles first, then loads the remainder into memory. Persisted
|
|
78
|
+
* `running|pending` handles are reconciled against the live host instead of
|
|
79
|
+
* being flattened to a false `"interrupt"` (C6). No concurrency is
|
|
80
|
+
* re-acquired for restored running handles (C7).
|
|
64
81
|
*/
|
|
65
82
|
restoreHandles(): Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
* Probe the live host for a persisted in-flight handle and apply the
|
|
85
|
+
* reconciled outcome. Never throws: any unexpected failure degrades to
|
|
86
|
+
* `statusUncertain`, never a false completion. `restoreHandles()`'s caller
|
|
87
|
+
* is fire-and-forget (`create-managers.ts`), so rejection is not an option.
|
|
88
|
+
*/
|
|
89
|
+
private reconcileRestoredTask;
|
|
66
90
|
launch(input: LaunchInput): Promise<BackgroundTask>;
|
|
67
91
|
private processKey;
|
|
92
|
+
/**
|
|
93
|
+
* Admit a nested launch. Bypass mode grants immediately without touching the
|
|
94
|
+
* semaphore; reserve mode first tries the reserved slot with a bounded wait
|
|
95
|
+
* and falls back to bypass overflow. Both modes enforce the maxDepth cap.
|
|
96
|
+
* Returns "skip" when the item was terminated (depth exceeded / cancelled).
|
|
97
|
+
*/
|
|
98
|
+
private admitNested;
|
|
99
|
+
/**
|
|
100
|
+
* Terminal `stopped` outcome for a queued task that was never admitted.
|
|
101
|
+
* Mirrors the cancelTask terminal+notify sequence but never releases a slot
|
|
102
|
+
* (none was taken) and routes through the same parent-notification pipeline.
|
|
103
|
+
*/
|
|
104
|
+
private terminateQueuedTask;
|
|
105
|
+
/**
|
|
106
|
+
* Decrement the nested bypass count for a task exactly once. Idempotent:
|
|
107
|
+
* repeated calls after the first are no-ops and can never underflow.
|
|
108
|
+
*/
|
|
109
|
+
private decrementNestedActive;
|
|
68
110
|
private startTask;
|
|
69
111
|
getTask(id: string): BackgroundTask | undefined;
|
|
70
112
|
getTasksByParentSession(sessionID: string): BackgroundTask[];
|
|
@@ -85,6 +127,17 @@ export declare class BackgroundManager {
|
|
|
85
127
|
concurrencyKey?: string;
|
|
86
128
|
}): Promise<BackgroundTask>;
|
|
87
129
|
resume(input: ResumeInput): Promise<BackgroundTask>;
|
|
130
|
+
/** Revive a terminal task with a new prompt, from memory or disk. Bounded admission; saturated queue fails truthfully. */
|
|
131
|
+
revive(input: ReviveInput): Promise<BackgroundTask>;
|
|
132
|
+
/** Revivable terminal tasks: in-memory first (wins on taskId), then disk; newest-first. */
|
|
133
|
+
listRevivable(parentSessionID?: string): Array<{
|
|
134
|
+
taskId: string;
|
|
135
|
+
description: string;
|
|
136
|
+
agent: string;
|
|
137
|
+
status: string;
|
|
138
|
+
sessionID: string;
|
|
139
|
+
terminalReason?: string;
|
|
140
|
+
}>;
|
|
88
141
|
private checkSessionTodos;
|
|
89
142
|
handleEvent(event: Event): void;
|
|
90
143
|
markForNotification(task: BackgroundTask): void;
|
|
@@ -100,6 +153,7 @@ export declare class BackgroundManager {
|
|
|
100
153
|
/**
|
|
101
154
|
* Validates that a session has actual assistant/tool output before marking complete.
|
|
102
155
|
* Prevents premature completion when session.idle fires before agent responds.
|
|
156
|
+
* Delegates to the shared `session-output` helper (also used by reconciliation).
|
|
103
157
|
*/
|
|
104
158
|
private validateSessionHasOutput;
|
|
105
159
|
private clearNotificationsForTask;
|
|
@@ -108,6 +162,7 @@ export declare class BackgroundManager {
|
|
|
108
162
|
* Cleans up the parent entry if no pending tasks remain.
|
|
109
163
|
*/
|
|
110
164
|
private cleanupPendingByParent;
|
|
165
|
+
private refreshParentWake;
|
|
111
166
|
/**
|
|
112
167
|
* Fire-and-forget session abort. Logs failures at debug level instead of
|
|
113
168
|
* swallowing errors silently — useful for diagnosing zombie sessions.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { BgHandle } from "./handle-index";
|
|
2
|
+
import type { BackgroundTerminalReason } from "./types";
|
|
3
|
+
export type ReconcileOutcome = {
|
|
4
|
+
status: "completed" | "error" | "running" | "stopped" | "statusUncertain";
|
|
5
|
+
terminalReason?: BackgroundTerminalReason;
|
|
6
|
+
};
|
|
7
|
+
export interface ReconcileProbeClient {
|
|
8
|
+
session: {
|
|
9
|
+
status: () => Promise<unknown>;
|
|
10
|
+
messages: (args: {
|
|
11
|
+
path: {
|
|
12
|
+
id: string;
|
|
13
|
+
};
|
|
14
|
+
}) => Promise<unknown>;
|
|
15
|
+
todo: (args: {
|
|
16
|
+
path: {
|
|
17
|
+
id: string;
|
|
18
|
+
};
|
|
19
|
+
}) => Promise<unknown>;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export interface ReconcileDeps {
|
|
23
|
+
validateOutput?: (sessionID: string) => Promise<boolean>;
|
|
24
|
+
sleep?: (ms: number) => Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Classify a persisted `running|pending` handle against the live host.
|
|
28
|
+
*
|
|
29
|
+
* Deterministic order: unprobeable → uncertain; non-idle → running; recorded
|
|
30
|
+
* error → error; awaiting-user → running; no output → stopped; output with
|
|
31
|
+
* incomplete todos → running; otherwise completed. Never throws.
|
|
32
|
+
*/
|
|
33
|
+
export declare function reconcileHandle(client: ReconcileProbeClient, handle: BgHandle, deps?: ReconcileDeps): Promise<ReconcileOutcome>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Revive eligibility classification for background tasks.
|
|
3
|
+
*
|
|
4
|
+
* Pure logic: decides whether a persisted handle may be revived into a new
|
|
5
|
+
* session. No I/O, no manager access, no client imports.
|
|
6
|
+
*/
|
|
7
|
+
import type { BgHandle } from "./handle-index";
|
|
8
|
+
import type { BackgroundTask } from "./types";
|
|
9
|
+
export declare const REVIVABLE_STATUSES: readonly ["cancelled", "stopped", "interrupt", "error", "completed"];
|
|
10
|
+
export declare function isRevivableStatus(status: string): boolean;
|
|
11
|
+
export type ReviveBlockReason = "active" | "uncertain" | "no-session" | "unknown-task" | "expired";
|
|
12
|
+
export type ReviveEligibility = {
|
|
13
|
+
eligible: true;
|
|
14
|
+
} | {
|
|
15
|
+
eligible: false;
|
|
16
|
+
reason: ReviveBlockReason;
|
|
17
|
+
};
|
|
18
|
+
export declare function classifyRevivable(handle: {
|
|
19
|
+
status: string;
|
|
20
|
+
sessionID?: string;
|
|
21
|
+
terminalReason?: string;
|
|
22
|
+
}, opts?: {
|
|
23
|
+
force?: boolean;
|
|
24
|
+
}): ReviveEligibility;
|
|
25
|
+
/**
|
|
26
|
+
* Locate a revivable handle by task id or session id. `taskId` wins when
|
|
27
|
+
* both are supplied. Returns `undefined` when neither matches.
|
|
28
|
+
*/
|
|
29
|
+
export declare function findRevivableHandle(handles: BgHandle[], opts: {
|
|
30
|
+
taskId?: string;
|
|
31
|
+
sessionId?: string;
|
|
32
|
+
}): BgHandle | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Rehydrate a pre-admission `BackgroundTask` from a persisted handle with a
|
|
35
|
+
* NEW prompt. Mirrors `restoreTaskFromHandle` except `prompt` comes from the
|
|
36
|
+
* caller and `status` restarts at `"pending"`; `startedAt` is left unset (it
|
|
37
|
+
* is assigned on admission) and `completedAt`/`error` are cleared.
|
|
38
|
+
*/
|
|
39
|
+
export declare function toReviveTask(handle: BgHandle, prompt: string): BackgroundTask;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export interface SessionOutputClient {
|
|
2
|
+
session: {
|
|
3
|
+
messages: (args: {
|
|
4
|
+
path: {
|
|
5
|
+
id: string;
|
|
6
|
+
};
|
|
7
|
+
}) => Promise<unknown>;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
interface SessionMessagePart {
|
|
11
|
+
type?: string;
|
|
12
|
+
text?: string;
|
|
13
|
+
content?: string | unknown[];
|
|
14
|
+
}
|
|
15
|
+
export interface SessionMessage {
|
|
16
|
+
info?: {
|
|
17
|
+
role?: string;
|
|
18
|
+
error?: unknown;
|
|
19
|
+
};
|
|
20
|
+
parts?: SessionMessagePart[];
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Fetch the raw messages for a session. Throws on transport failure so callers
|
|
24
|
+
* can decide between fail-open (legacy) and fail-safe (reconciliation).
|
|
25
|
+
*/
|
|
26
|
+
export declare function fetchSessionMessages(client: SessionOutputClient, sessionID: string): Promise<SessionMessage[]>;
|
|
27
|
+
/**
|
|
28
|
+
* True when the session produced real assistant/tool output with content.
|
|
29
|
+
* Shared by `validateSessionHasOutput` (manager) and `reconcileHandle`.
|
|
30
|
+
*/
|
|
31
|
+
export declare function messagesHaveAssistantOutput(messages: SessionMessage[], sessionID?: string): boolean;
|
|
32
|
+
/** True when any assistant message carries a recorded provider/abort error. */
|
|
33
|
+
export declare function messagesHaveRecordedError(messages: SessionMessage[]): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Validate that a session has actual assistant/tool output before marking
|
|
36
|
+
* complete. Fail-open: transport errors return true so a flaky lookup cannot
|
|
37
|
+
* block the existing polling/idle completion path.
|
|
38
|
+
*/
|
|
39
|
+
export declare function validateSessionHasOutput(client: SessionOutputClient, sessionID: string): Promise<boolean>;
|
|
40
|
+
export {};
|