@wrongstack/core 0.298.3 → 0.300.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chronicle/index.js +4 -1
- package/dist/coordination/agents/index.js +4 -1
- package/dist/coordination/director.d.ts +8 -0
- package/dist/coordination/fleet-manager.d.ts +48 -3
- package/dist/coordination/ifleet-manager.d.ts +2 -0
- package/dist/coordination/index.js +127 -24
- package/dist/coordination/multi-agent-coordinator.d.ts +1 -0
- package/dist/core/fallback-model.d.ts +48 -0
- package/dist/core/index.d.ts +3 -2
- package/dist/core/index.js +288 -34
- package/dist/core/instruction-template.d.ts +80 -0
- package/dist/core/system-prompt-blocks.d.ts +10 -1
- package/dist/core/system-prompt-builder.d.ts +35 -1
- package/dist/defaults/index.js +358 -117
- package/dist/design/index.js +4 -1
- package/dist/execution/autonomy-brain.d.ts +7 -0
- package/dist/execution/council-brain.d.ts +17 -2
- package/dist/execution/council-orchestrator.d.ts +23 -4
- package/dist/execution/council-personas.d.ts +10 -0
- package/dist/execution/council-prompts.d.ts +12 -1
- package/dist/execution/index.d.ts +1 -1
- package/dist/execution/index.js +412 -145
- package/dist/fleet-notifier.d.ts +9 -2
- package/dist/goal/index.js +4 -1
- package/dist/hooks/index.js +140 -10
- package/dist/hq/exposure.d.ts +0 -11
- package/dist/hq/index.js +34 -8
- package/dist/hq/protocol/client.d.ts +14 -1
- package/dist/hq/protocol/fleet.d.ts +22 -0
- package/dist/hq/protocol.js +12 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1718 -753
- package/dist/infrastructure/index.js +50 -2
- package/dist/infrastructure/mcp-servers.d.ts +35 -0
- package/dist/kernel/events/brain-events.d.ts +9 -0
- package/dist/kernel/events/provider-events.d.ts +49 -2
- package/dist/kernel/events/sdd-events.d.ts +2 -0
- package/dist/models/index.js +1 -1
- package/dist/plugin/api.d.ts +6 -0
- package/dist/plugin/config.d.ts +55 -0
- package/dist/plugin/index.d.ts +1 -1
- package/dist/plugin/index.js +138 -22
- package/dist/security/index.d.ts +1 -1
- package/dist/security/index.js +157 -42
- package/dist/security/permission-helpers.d.ts +23 -6
- package/dist/security/permission-policy.d.ts +16 -0
- package/dist/security/totp.d.ts +14 -0
- package/dist/storage/director-state.d.ts +7 -0
- package/dist/storage/index.js +46 -9
- package/dist/tools/council-tool.d.ts +1 -1
- package/dist/tools/fallback-system-config-view-tool.d.ts +1 -1
- package/dist/tools/index.js +449 -112
- package/dist/types/config/skills-fleet-brain.d.ts +4 -2
- package/dist/types/config/tools.d.ts +99 -0
- package/dist/types/council.d.ts +11 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/types/index.js +3 -3
- package/dist/types/multi-agent.d.ts +10 -0
- package/dist/types/one-shot-llm.d.ts +31 -3
- package/dist/types/plugin.d.ts +28 -0
- package/dist/types/session.d.ts +5 -1
- package/dist/utils/index.js +4 -1
- package/dist/utils/wstack-paths.d.ts +2 -0
- package/dist/worktree/index.js +47 -25
- package/dist/worktree/worktree-manager.d.ts +16 -10
- package/instructions/coordination/subagent-baseline.md +8 -0
- package/instructions/system-lite.md +83 -3
- package/instructions/system-pro.md +286 -97
- package/instructions/system.md +236 -85
- package/package.json +3 -3
|
@@ -170,8 +170,10 @@ export interface BrainModelEntry {
|
|
|
170
170
|
export interface BrainCouncilVoterConfig extends BrainModelEntry {
|
|
171
171
|
/**
|
|
172
172
|
* Decision lens for this seat. Built-ins: 'executor' (progress-biased),
|
|
173
|
-
* 'skeptic' (risk-hunting), 'auditor' (cost/waste-focused)
|
|
174
|
-
*
|
|
173
|
+
* 'skeptic' (risk-hunting), 'auditor' (cost/waste-focused), 'security'
|
|
174
|
+
* (trust boundaries, abuse cases), 'maintainer' (complexity, compatibility)
|
|
175
|
+
* and 'user-advocate' (usability, recovery). Any other string is registered
|
|
176
|
+
* as an ad-hoc lens whose instruction is the string itself.
|
|
175
177
|
*/
|
|
176
178
|
persona?: string | undefined;
|
|
177
179
|
/** Vote weight in the tally. Default 1. */
|
|
@@ -50,6 +50,21 @@ export interface ToolsConfig {
|
|
|
50
50
|
* it is honored from any source.
|
|
51
51
|
*/
|
|
52
52
|
exec?: ExecToolConfig | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* Agent-callable `council` tool: which panel profile it runs by default and
|
|
55
|
+
* which extra lenses/profiles are available to it.
|
|
56
|
+
*
|
|
57
|
+
* Distinct from `brain.council`, which is the Brain's own decision tier —
|
|
58
|
+
* that one is convened by the Brain on high-risk questions, this one is
|
|
59
|
+
* invoked by the agent.
|
|
60
|
+
*
|
|
61
|
+
* SECURITY: in the in-project DENY list. A persona's `instruction` is
|
|
62
|
+
* rendered into the voter SYSTEM prompt, and a profile seat may pin a
|
|
63
|
+
* `providerId`/`model` — so a repo-committed config could otherwise inject
|
|
64
|
+
* system-level instructions into every seat and reroute the calls to an
|
|
65
|
+
* attacker-chosen provider. Only honoured from the active-profile config.
|
|
66
|
+
*/
|
|
67
|
+
council?: CouncilToolConfig | undefined;
|
|
53
68
|
/**
|
|
54
69
|
* Agent-loop repetition detector tuning. The detector watches two signals:
|
|
55
70
|
* consecutive effectively-identical iterations (same tool-name set + inputs
|
|
@@ -86,6 +101,90 @@ export interface LoopDetectionConfig {
|
|
|
86
101
|
*/
|
|
87
102
|
callRepeatThreshold?: number | undefined;
|
|
88
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Configuration for the agent-callable `council` tool.
|
|
106
|
+
*
|
|
107
|
+
* The Council orchestrator has always accepted custom persona and profile
|
|
108
|
+
* registries, but no host ever built one — the tool was pinned to the three
|
|
109
|
+
* built-in profiles with no way to add a lens, change the default panel, or
|
|
110
|
+
* tune concurrency. This is that surface.
|
|
111
|
+
*/
|
|
112
|
+
export interface CouncilToolConfig {
|
|
113
|
+
/**
|
|
114
|
+
* Profile the tool runs when a call names none. Must be a built-in id
|
|
115
|
+
* (`balanced`, `fast`, `risk-review`) or one defined in `profiles`.
|
|
116
|
+
* Default `balanced`.
|
|
117
|
+
*/
|
|
118
|
+
defaultProfile?: string | undefined;
|
|
119
|
+
/** Seats polled concurrently, 1..8. Default 3. */
|
|
120
|
+
maxConcurrency?: number | undefined;
|
|
121
|
+
/**
|
|
122
|
+
* Extra decision lenses, registered alongside the six built-ins. Each needs
|
|
123
|
+
* a kebab-case `id`, a `name`, a `description` and the `instruction` that
|
|
124
|
+
* becomes the seat's system prompt.
|
|
125
|
+
*/
|
|
126
|
+
personas?: CouncilPersonaDefinition[] | undefined;
|
|
127
|
+
/**
|
|
128
|
+
* Extra panel profiles, registered alongside the built-ins. A profile whose
|
|
129
|
+
* id matches a built-in replaces it.
|
|
130
|
+
*/
|
|
131
|
+
profiles?: CouncilToolProfileDefinition[] | undefined;
|
|
132
|
+
}
|
|
133
|
+
/** A custom Council decision lens declared in configuration. */
|
|
134
|
+
export interface CouncilPersonaDefinition {
|
|
135
|
+
/** Kebab-case identifier, e.g. "latency-hawk". */
|
|
136
|
+
id: string;
|
|
137
|
+
name: string;
|
|
138
|
+
description: string;
|
|
139
|
+
/** Trusted system-level instruction for this lens. */
|
|
140
|
+
instruction: string;
|
|
141
|
+
defaultWeight?: number | undefined;
|
|
142
|
+
defaultVeto?: boolean | undefined;
|
|
143
|
+
tags?: string[] | undefined;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* A custom Council panel declared in configuration.
|
|
147
|
+
*
|
|
148
|
+
* Structurally the config-facing half of `CouncilProfileConfig`; kept as its
|
|
149
|
+
* own type so the config surface stays JSON-shaped (no readonly arrays) and
|
|
150
|
+
* documents itself where users read it.
|
|
151
|
+
*/
|
|
152
|
+
export interface CouncilToolProfileDefinition {
|
|
153
|
+
id: string;
|
|
154
|
+
name?: string | undefined;
|
|
155
|
+
description?: string | undefined;
|
|
156
|
+
seats: Array<{
|
|
157
|
+
id?: string | undefined;
|
|
158
|
+
label?: string | undefined;
|
|
159
|
+
/** Persona id — a built-in or one declared in `personas`. */
|
|
160
|
+
persona: string;
|
|
161
|
+
target?: {
|
|
162
|
+
providerId?: string | undefined;
|
|
163
|
+
model?: string | undefined;
|
|
164
|
+
/** Model-matrix role, resolved before the explicit target. */
|
|
165
|
+
role?: string | undefined;
|
|
166
|
+
fallbackProfile?: string | undefined;
|
|
167
|
+
fallbackModels?: string[] | undefined;
|
|
168
|
+
} | undefined;
|
|
169
|
+
weight?: number | undefined;
|
|
170
|
+
veto?: boolean | undefined;
|
|
171
|
+
}>;
|
|
172
|
+
/** `false` disables judging; omitted also means no judge. */
|
|
173
|
+
judge?: false | {
|
|
174
|
+
providerId?: string | undefined;
|
|
175
|
+
model?: string | undefined;
|
|
176
|
+
role?: string | undefined;
|
|
177
|
+
fallbackProfile?: string | undefined;
|
|
178
|
+
fallbackModels?: string[] | undefined;
|
|
179
|
+
} | undefined;
|
|
180
|
+
quorumFraction?: number | undefined;
|
|
181
|
+
approvalFraction?: number | undefined;
|
|
182
|
+
distinctness?: 'none' | 'model' | 'provider' | undefined;
|
|
183
|
+
voterMaxTokens?: number | undefined;
|
|
184
|
+
judgeMaxTokens?: number | undefined;
|
|
185
|
+
perCallTimeoutMs?: number | undefined;
|
|
186
|
+
overallTimeoutMs?: number | undefined;
|
|
187
|
+
}
|
|
89
188
|
/** Allow/deny extension of the `exec` tool's built-in command allowlist. */
|
|
90
189
|
export interface ExecToolConfig {
|
|
91
190
|
/**
|
package/dist/types/council.d.ts
CHANGED
|
@@ -28,6 +28,10 @@ export interface CouncilSeatConfig {
|
|
|
28
28
|
label?: string | undefined;
|
|
29
29
|
persona: string;
|
|
30
30
|
target?: CouncilModelTarget | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Vote weight in the tally. Ignored for optionless questions — open
|
|
33
|
+
* stances are not tallied, so every valid stance counts once.
|
|
34
|
+
*/
|
|
31
35
|
weight?: number | undefined;
|
|
32
36
|
veto?: boolean | undefined;
|
|
33
37
|
}
|
|
@@ -37,6 +41,7 @@ export interface ResolvedCouncilSeat {
|
|
|
37
41
|
label: string;
|
|
38
42
|
persona: string;
|
|
39
43
|
target?: CouncilModelTarget | undefined;
|
|
44
|
+
/** Vote weight in the tally. No-op for optionless questions (see above). */
|
|
40
45
|
weight: number;
|
|
41
46
|
veto: boolean;
|
|
42
47
|
}
|
|
@@ -56,6 +61,11 @@ export interface CouncilProfileConfig {
|
|
|
56
61
|
/** False disables judging. Omitted profiles also default to no judge. */
|
|
57
62
|
judge?: CouncilModelTarget | false | undefined;
|
|
58
63
|
quorumFraction?: number | undefined;
|
|
64
|
+
/**
|
|
65
|
+
* Winning option must exceed this fraction of cast vote weight. No-op for
|
|
66
|
+
* optionless questions — open stances are not tallied; divergence is
|
|
67
|
+
* escalated instead (see `resolveOpenQuestion`).
|
|
68
|
+
*/
|
|
59
69
|
approvalFraction?: number | undefined;
|
|
60
70
|
distinctness?: CouncilDistinctness | undefined;
|
|
61
71
|
voterMaxTokens?: number | undefined;
|
|
@@ -71,6 +81,7 @@ export interface ResolvedCouncilProfile {
|
|
|
71
81
|
seats: readonly ResolvedCouncilSeat[];
|
|
72
82
|
judge: CouncilModelTarget | false;
|
|
73
83
|
quorumFraction: number;
|
|
84
|
+
/** No-op for optionless questions (see the config-level doc above). */
|
|
74
85
|
approvalFraction: number;
|
|
75
86
|
distinctness: CouncilDistinctness;
|
|
76
87
|
voterMaxTokens: number;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export type { CacheTtl, Capabilities, JsonSchemaSpec, Provider, ProviderErrorBod
|
|
|
14
14
|
export { StreamHangError } from './provider.js';
|
|
15
15
|
export type { ProviderRunner, RunProviderOptions } from './provider-runner.js';
|
|
16
16
|
export { DEFAULT_TUI_THINKING_WORD, FLEET_CHAT_VERBOSITY_VALUES, MAX_TUI_THINKING_WORD_LENGTH, normalizeTokenSavingTier, normalizeTuiThinkingWord, resolveFleetChatVerbosity, resolveTokenSavingTier } from './config.js';
|
|
17
|
-
export type { AdaptiveConcurrencyConfig, AutonomyConfig, BrainConfig, BrainCouncilConfig, BrainCouncilVoterConfig, BrainModelEntry, CircuitBreakerRuntimeConfig, ConcreteTokenSavingTier, Config, ConfigLoader, ConfigStore, ContextConfig, CustomModelDefinition, ExecDangerConfig, ExecToolConfig, FeaturesConfig, FleetChatVerbosity, FleetConfig, FleetSupervisorConfig, GitBehaviorConfig, HqClientConfig, IndexingConfig, InputHistoryConfig, LaunchConfig, LaunchMenuChoice, LogConfig, LoopDetectionConfig, MCPHealthConfig, MCPHealthThresholds, MCPServerConfig, ModelMatrixEntry, ModelRuntimeCacheConfig, ModelRuntimeConfig, ModelRuntimeParametersConfig, ModelRuntimeReasoningConfig, PluginConfig, PluginManagerConfig, ProviderApiKey, ProviderConfig, SageConfig, SessionLoggingConfig, SkillsConfig, SyncCategory, SyncConfig, TokenSavingTier, ToolDescriptionMode, ToolDescriptionModeConfig, ToolResultRenderMode, ToolResultRenderModeConfig, ToolsConfig } from './config.js';
|
|
17
|
+
export type { AdaptiveConcurrencyConfig, AutonomyConfig, BrainConfig, BrainCouncilConfig, BrainCouncilVoterConfig, BrainModelEntry, CircuitBreakerRuntimeConfig, ConcreteTokenSavingTier, Config, ConfigLoader, ConfigStore, ContextConfig, CouncilPersonaDefinition, CouncilToolConfig, CouncilToolProfileDefinition, CustomModelDefinition, ExecDangerConfig, ExecToolConfig, FeaturesConfig, FleetChatVerbosity, FleetConfig, FleetSupervisorConfig, GitBehaviorConfig, HqClientConfig, IndexingConfig, InputHistoryConfig, LaunchConfig, LaunchMenuChoice, LogConfig, LoopDetectionConfig, MCPHealthConfig, MCPHealthThresholds, MCPServerConfig, ModelMatrixEntry, ModelRuntimeCacheConfig, ModelRuntimeConfig, ModelRuntimeParametersConfig, ModelRuntimeReasoningConfig, PluginConfig, PluginManagerConfig, ProviderApiKey, ProviderConfig, SageConfig, SessionLoggingConfig, SkillsConfig, SyncCategory, SyncConfig, TokenSavingTier, ToolDescriptionMode, ToolDescriptionModeConfig, ToolResultRenderMode, ToolResultRenderModeConfig, ToolsConfig } from './config.js';
|
|
18
18
|
export type { AnyHookOutcome, ConfiguredHook, HookEntry, HookEvent, HookFailurePolicy, HookInput, HookInvocationContext, HookMatcher, HookOutcome, HookRegistrationOptions, HttpHook, InProcessHook, PreToolUseOutcome, PreToolUseStage, ShellHook } from './hooks.js';
|
|
19
19
|
export type { Compactor, CompactReport } from './compactor.js';
|
|
20
20
|
export type { DirectoryPolicy, DirectoryRule, PermissionDecision, PermissionPolicy, PermissionTrace, PermissionTraceStep, TrustPolicy } from './permission.js';
|
|
@@ -40,7 +40,7 @@ export { flattenSystemPromptRegions } from './system-prompt.js';
|
|
|
40
40
|
export type { BuildContext, ModelCapabilities, SystemPromptBuilder, SystemPromptRegions } from './system-prompt.js';
|
|
41
41
|
export type { Renderer } from './renderer.js';
|
|
42
42
|
export type { InputReader, PromptOption } from './input-reader.js';
|
|
43
|
-
export type { MCPRegistryView, MetricsSinkView, Notifier, Plugin, PluginAPI, PluginCapabilities, PluginConfigFieldLifecycle, PluginConfigFieldMetadata, PluginConfigFields, PluginDependency, PluginLLM, PluginLLMOptions, PluginLLMResult, PluginPipelines, PluginRuntime, ProviderFactory, ProviderRegistryView, SessionWriterView, SlashCommandRegistryView, ToolRegistryView } from './plugin.js';
|
|
43
|
+
export type { MCPRegistryView, MetricsSinkView, Notifier, Plugin, PluginAPI, PluginCapabilities, PluginConfigFieldLifecycle, PluginConfigFieldMetadata, PluginConfigFields, PluginCouncilOptions, PluginDependency, PluginLLM, PluginLLMOptions, PluginLLMResult, PluginPipelines, PluginRuntime, ProviderFactory, ProviderRegistryView, SessionWriterView, SlashCommandRegistryView, ToolRegistryView } from './plugin.js';
|
|
44
44
|
export { AgentError, ConfigError, ERROR_CODES, FetchError, FsError, ParseError, PluginError, SddError, SessionError, ToolError, ToolValidationError, WrongStackError, isAgentError, isConfigError, isFetchError, isFsError, isParseError, isPluginError, isSddError, isSessionError, isToolError, isToolValidationError, isWrongStackError, toWrongStackError } from './errors.js';
|
|
45
45
|
export type { ErrorCode, ErrorSeverity, ErrorSubsystem } from './errors.js';
|
|
46
46
|
export type { ModelsDevModel, ModelsDevPayload, ModelsDevProvider, ModelsDevReasoningOption, ModelsRegistry, ResolvedModel, ResolvedProvider, WireFamily } from './models-registry.js';
|
|
@@ -50,6 +50,7 @@ export { CONTEXT_WINDOW_MODES, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEPRECATED_CONTEX
|
|
|
50
50
|
export type { ContextSnapshot, ContextWindowAggressiveOn, ContextWindowConfigLike, ContextWindowMode, ContextWindowModeId, ContextWindowModeSelectionId, ContextWindowPolicy, ContextWindowThresholds, DeprecatedContextWindowModeId } from './context-window.js';
|
|
51
51
|
export type { CompletedWorkEvidence, CompletedWorkSource, ContextEvidenceState, ContextFileEvidence, ContextIntentEvidence, ContextRepeatedReadEvidence, ToolEvidenceStatus, ToolOutputMetadata } from './context-evidence.js';
|
|
52
52
|
export type { CouncilDistinctness, CouncilLLMCaller, CouncilModelTarget, CouncilOption, CouncilPersona, CouncilProfileConfig, CouncilQuestion, CouncilResolutionMethod, CouncilResult, CouncilSeatConfig, CouncilUsage, CouncilVoteResult, CouncilVoteStatus, ResolvedCouncilProfile, ResolvedCouncilSeat } from './council.js';
|
|
53
|
+
export type { OneShotLLMInput, OneShotLLMResult, OneShotModelPick, OneShotModelRouter, OneShotOrchestratorOptions } from './one-shot-llm.js';
|
|
53
54
|
export type { AwaitAnyResult, CoordinatorEvents, CoordinatorStatus, DoneCondition, MultiAgentConfig, MultiAgentCoordinator, SpawnResult, SubagentConfig, SubagentContext, SubagentError, SubagentErrorKind, SubagentPartialResult, SubagentRunContext, SubagentRunOutcome, SubagentRunner, SubagentSpawnLineage, SubagentStructuredReport, TaskDelegation, TaskResult, TaskSpec } from './multi-agent.js';
|
|
54
55
|
export { DEFAULT_SPEC_TEMPLATE } from './spec.js';
|
|
55
56
|
export type { SpecAnalysis, SpecApiEndpoint, SpecRequirement, SpecSection, SpecSectionType, SpecStatus, SpecTemplate, SpecValidationResult, Specification } from './spec.js';
|
package/dist/types/index.js
CHANGED
|
@@ -324,7 +324,7 @@ var QUOTA_EXHAUSTED_RE = /(?:insufficient|exhausted|depleted|exceeded|no|not eno
|
|
|
324
324
|
function effectiveInputTokens(usage) {
|
|
325
325
|
return usage.input + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
|
|
326
326
|
}
|
|
327
|
-
var CONTEXT_OVERFLOW_RE = /context.length|context.window|maximum context|max.*tokens?.*exceeded|prompt
|
|
327
|
+
var CONTEXT_OVERFLOW_RE = /context.length|context.window|maximum context|max.*tokens?.*exceeded|(?:prompt|request|input|messages?).{0,12}too (?:large|long)|exceeds the context|\btokens\b.*exceed|too many tokens|reduce the length|resulted in \d+ tokens|context_length_exceeded/i;
|
|
328
328
|
var CONTENT_FILTER_RE = /content.(filter|policy|moderation)|safety (system|filter)/i;
|
|
329
329
|
var RATE_LIMIT_EXCEEDED_RE = /rate[-_\s]*limit[-_\s]*exceeded/i;
|
|
330
330
|
function classifyProviderError(status, body, message) {
|
|
@@ -334,7 +334,7 @@ function classifyProviderError(status, body, message) {
|
|
|
334
334
|
if (status === 408) return "timeout";
|
|
335
335
|
if (status === 599) return "stream_hang";
|
|
336
336
|
if (status === 402 || QUOTA_EXHAUSTED_RE.test(text)) return "quota_exhausted";
|
|
337
|
-
if (status === 429 && body?.message && RATE_LIMIT_EXCEEDED_RE.test(body.message)) {
|
|
337
|
+
if (status === 429 && body?.message && body.type !== "rate_limit_exceeded" && RATE_LIMIT_EXCEEDED_RE.test(body.message)) {
|
|
338
338
|
return "quota_exhausted";
|
|
339
339
|
}
|
|
340
340
|
if (type === "rate_limit_error" || status === 429) return "rate_limit";
|
|
@@ -411,7 +411,7 @@ var ProviderError = class extends WrongStackError {
|
|
|
411
411
|
const e = err;
|
|
412
412
|
const name = e.name;
|
|
413
413
|
if (typeof name !== "string" || !name.endsWith("Error")) return false;
|
|
414
|
-
return typeof e.status === "number" && typeof e.retryable === "boolean" && typeof e.kind === "string";
|
|
414
|
+
return typeof e.status === "number" && typeof e.retryable === "boolean" && typeof e.kind === "string" && typeof e.describe === "function";
|
|
415
415
|
}
|
|
416
416
|
constructor(message, status, retryable, providerId, opts = {}) {
|
|
417
417
|
const kind = opts.kind ?? classifyProviderError(status, opts.body, message);
|
|
@@ -65,6 +65,16 @@ export interface SubagentConfig {
|
|
|
65
65
|
allowedCapabilities?: readonly string[] | undefined;
|
|
66
66
|
model?: string | undefined;
|
|
67
67
|
priority?: number | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* Exempt this spawn from the director's lifetime `maxSpawns` budget.
|
|
70
|
+
* Ephemeral infrastructure agents (Chimera reviewers, cascade agents) set
|
|
71
|
+
* this so background review traffic cannot exhaust the leader's
|
|
72
|
+
* deliberate-delegation budget: the `max_spawns` admission check is skipped
|
|
73
|
+
* and the lifetime spawn counter is NOT incremented. All other caps
|
|
74
|
+
* (spawn depth, fleet cost/tokens, leader context load) still apply.
|
|
75
|
+
* Deliberate leader spawns must leave this unset.
|
|
76
|
+
*/
|
|
77
|
+
spawnBudgetExempt?: boolean | undefined;
|
|
68
78
|
/**
|
|
69
79
|
* Director-authored recursion/budget inheritance. Director.spawn overwrites
|
|
70
80
|
* caller input so a model cannot forge a shallower depth or larger budget.
|
|
@@ -92,6 +92,15 @@ export interface OneShotLLMResult {
|
|
|
92
92
|
durationMs: number;
|
|
93
93
|
/** Whether the response came from a fallback model. */
|
|
94
94
|
fromFallback: boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Number of provider invocations behind this result (primary attempt +
|
|
97
|
+
* every fallback entry actually tried). Absent for callers without
|
|
98
|
+
* fallback machinery (Brain seats, test doubles) — consumers treat
|
|
99
|
+
* absence as one call. Producers report explicit 0 only for pre-call
|
|
100
|
+
* failures where no provider was invoked (e.g. unresolved target), so
|
|
101
|
+
* consumers should clamp to at least 1 when a seat ran at all.
|
|
102
|
+
*/
|
|
103
|
+
attempts?: number | undefined;
|
|
95
104
|
/** Provider-level stop reason, if available. */
|
|
96
105
|
stopReason?: string | undefined;
|
|
97
106
|
/**
|
|
@@ -100,6 +109,21 @@ export interface OneShotLLMResult {
|
|
|
100
109
|
*/
|
|
101
110
|
error?: string | undefined;
|
|
102
111
|
}
|
|
112
|
+
/** One role→model resolution. Mirrors `ModelPick` from the ModelRouter. */
|
|
113
|
+
export interface OneShotModelPick {
|
|
114
|
+
provider: string;
|
|
115
|
+
model: string;
|
|
116
|
+
/**
|
|
117
|
+
* True when the pick came from the user's `/setmodel` matrix (explicit
|
|
118
|
+
* intent) rather than from capability heuristics. Only a matrix pick may
|
|
119
|
+
* override a caller's explicit `providerId`/`model`.
|
|
120
|
+
*/
|
|
121
|
+
fromMatrix?: boolean | undefined;
|
|
122
|
+
}
|
|
123
|
+
/** Minimal router contract consumed by role-based routing. */
|
|
124
|
+
export interface OneShotModelRouter {
|
|
125
|
+
pickForTask(role: string, description: string): OneShotModelPick | undefined;
|
|
126
|
+
}
|
|
103
127
|
/**
|
|
104
128
|
* Dependencies for OneShotOrchestrator.
|
|
105
129
|
*/
|
|
@@ -119,10 +143,14 @@ export interface OneShotOrchestratorOptions {
|
|
|
119
143
|
*/
|
|
120
144
|
fallbackProfileManager: import('../core/fallback-profile-manager.js').FallbackProfileManager;
|
|
121
145
|
/**
|
|
122
|
-
* Optional
|
|
123
|
-
*
|
|
146
|
+
* Optional role→model router. When absent, role-based routing is skipped
|
|
147
|
+
* and `role` on an input is inert.
|
|
148
|
+
*
|
|
149
|
+
* Structurally typed rather than pinned to the concrete `ModelRouter` class
|
|
150
|
+
* so a host can supply a router rebuilt from the LIVE config on every call
|
|
151
|
+
* (the `/setmodel` matrix changes mid-session). `ModelRouter` satisfies it.
|
|
124
152
|
*/
|
|
125
|
-
modelRouter?:
|
|
153
|
+
modelRouter?: OneShotModelRouter | undefined;
|
|
126
154
|
/**
|
|
127
155
|
* Optional logger for fallback warnings.
|
|
128
156
|
*/
|
package/dist/types/plugin.d.ts
CHANGED
|
@@ -103,6 +103,12 @@ export interface PluginLLMOptions {
|
|
|
103
103
|
responseFormat?: 'text' | 'json' | undefined;
|
|
104
104
|
/** Abort signal — plugins should pass one for cancellable work. */
|
|
105
105
|
signal?: AbortSignal | undefined;
|
|
106
|
+
/** Model-matrix role hint used by the host One Shot router. */
|
|
107
|
+
role?: string | undefined;
|
|
108
|
+
/** Explicit fallback model references for this call. */
|
|
109
|
+
fallbackModels?: string[] | undefined;
|
|
110
|
+
/** Hard timeout in milliseconds. Defaults to the host One Shot timeout. */
|
|
111
|
+
timeoutMs?: number | undefined;
|
|
106
112
|
}
|
|
107
113
|
export interface PluginLLMResult {
|
|
108
114
|
/** Concatenated text blocks of the response. */
|
|
@@ -116,6 +122,23 @@ export interface PluginLLMResult {
|
|
|
116
122
|
output: number;
|
|
117
123
|
};
|
|
118
124
|
stopReason: string;
|
|
125
|
+
/** True when the host served the completion through a fallback target. */
|
|
126
|
+
fromFallback?: boolean | undefined;
|
|
127
|
+
/** Provider invocations made by the One Shot fallback ladder. */
|
|
128
|
+
attempts?: number | undefined;
|
|
129
|
+
/** End-to-end completion duration when reported by the host. */
|
|
130
|
+
durationMs?: number | undefined;
|
|
131
|
+
}
|
|
132
|
+
/** Options for a bounded, read-only plugin Council request. */
|
|
133
|
+
export interface PluginCouncilOptions {
|
|
134
|
+
/** Evidence and constraints supplied separately from the question. */
|
|
135
|
+
context?: string | undefined;
|
|
136
|
+
/** Registered Council profile or an ad-hoc profile. */
|
|
137
|
+
profile?: string | import('./council.js').CouncilProfileConfig | undefined;
|
|
138
|
+
/** Optional closed set of choices. Omit for an open synthesis. */
|
|
139
|
+
options?: readonly import('./council.js').CouncilOption[] | undefined;
|
|
140
|
+
/** Abort signal propagated to every Council seat and judge. */
|
|
141
|
+
signal?: AbortSignal | undefined;
|
|
119
142
|
}
|
|
120
143
|
/**
|
|
121
144
|
* LLM access for plugins, routed through the host's provider layer —
|
|
@@ -138,6 +161,11 @@ export interface PluginLLM {
|
|
|
138
161
|
};
|
|
139
162
|
/** One-shot completion. Throws on provider errors. */
|
|
140
163
|
complete(prompt: string, opts?: PluginLLMOptions): Promise<PluginLLMResult>;
|
|
164
|
+
/**
|
|
165
|
+
* Multi-model Council deliberation. Present only when the host wires the
|
|
166
|
+
* Council runtime; plugins must retain a One Shot or deterministic fallback.
|
|
167
|
+
*/
|
|
168
|
+
council?(question: string, opts?: PluginCouncilOptions): Promise<import('./council.js').CouncilResult>;
|
|
141
169
|
}
|
|
142
170
|
export interface PluginPipelines {
|
|
143
171
|
request: ReadonlyPipeline<Request>;
|
package/dist/types/session.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ContentBlock } from './blocks.js';
|
|
2
2
|
import type { Message } from './messages.js';
|
|
3
|
-
import type { Usage } from './provider.js';
|
|
3
|
+
import type { ProviderErrorBody, Usage } from './provider.js';
|
|
4
4
|
export interface SessionMetadata {
|
|
5
5
|
id: string;
|
|
6
6
|
title?: string | undefined;
|
|
@@ -295,6 +295,8 @@ export type SessionEvent = {
|
|
|
295
295
|
delayMs: number;
|
|
296
296
|
status?: number | undefined;
|
|
297
297
|
description: string;
|
|
298
|
+
/** Scrubbed raw provider error envelope/body for post-run diagnosis. */
|
|
299
|
+
errorBody?: ProviderErrorBody | undefined;
|
|
298
300
|
} | {
|
|
299
301
|
type: 'provider_error';
|
|
300
302
|
ts: string;
|
|
@@ -302,6 +304,8 @@ export type SessionEvent = {
|
|
|
302
304
|
status?: number | undefined;
|
|
303
305
|
description: string;
|
|
304
306
|
retryable: boolean;
|
|
307
|
+
/** Scrubbed raw provider error envelope/body for post-run diagnosis. */
|
|
308
|
+
errorBody?: ProviderErrorBody | undefined;
|
|
305
309
|
} | {
|
|
306
310
|
type: 'checkpoint';
|
|
307
311
|
ts: string;
|
package/dist/utils/index.js
CHANGED
|
@@ -2478,7 +2478,9 @@ function safeProfileName(name) {
|
|
|
2478
2478
|
function activeProfileName(globalRoot) {
|
|
2479
2479
|
try {
|
|
2480
2480
|
const parsed = JSON.parse(fs3.readFileSync(path3.join(globalRoot, "config.json"), "utf8"));
|
|
2481
|
-
return safeProfileName(
|
|
2481
|
+
return safeProfileName(
|
|
2482
|
+
typeof parsed.activeProfile === "string" ? parsed.activeProfile : void 0
|
|
2483
|
+
);
|
|
2482
2484
|
} catch {
|
|
2483
2485
|
return "default";
|
|
2484
2486
|
}
|
|
@@ -2558,6 +2560,7 @@ function resolveWstackPaths(opts) {
|
|
|
2558
2560
|
projectPlan: path3.join(projectDir, "plan.json"),
|
|
2559
2561
|
projectAutophase: path3.join(projectDir, "autophase"),
|
|
2560
2562
|
projectSddBoards: path3.join(projectDir, "sdd-boards"),
|
|
2563
|
+
projectRequirementIntakes: path3.join(projectDir, "requirement-intakes"),
|
|
2561
2564
|
syncConfig: path3.join(profileDir, "sync.json"),
|
|
2562
2565
|
configHistoryDir: path3.join(globalRoot, "config-history"),
|
|
2563
2566
|
projectStatus: (projectHash2) => path3.join(globalRoot, "projects", projectHash2, "status.json")
|
|
@@ -124,6 +124,8 @@ export interface WstackPaths {
|
|
|
124
124
|
projectAutophase: string;
|
|
125
125
|
/** ~/.wrongstack/projects/<hash>/sdd-boards — live SDD board snapshots + JSONL event logs */
|
|
126
126
|
projectSddBoards: string;
|
|
127
|
+
/** ~/.wrongstack/projects/<hash>/requirement-intakes — requirement intake records */
|
|
128
|
+
projectRequirementIntakes: string;
|
|
127
129
|
/** ~/.wrongstack/profiles/<activeProfile>/sync.json — CloudSync configuration */
|
|
128
130
|
syncConfig: string;
|
|
129
131
|
/** ~/.wrongstack/config-history — timestamped backups on every config write */
|
package/dist/worktree/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/worktree/worktree-manager.ts
|
|
2
|
-
import { mkdir } from "node:fs/promises";
|
|
2
|
+
import { mkdir, readFile } from "node:fs/promises";
|
|
3
3
|
import { join, resolve as resolve3, sep as sep3 } from "node:path";
|
|
4
4
|
|
|
5
5
|
// src/utils/error.ts
|
|
@@ -466,11 +466,11 @@ var WorktreeManager = class {
|
|
|
466
466
|
}
|
|
467
467
|
const mergeArgs = squash ? ["merge", "--squash", handle.branch] : ["merge", "--no-ff", handle.branch];
|
|
468
468
|
const merged = await this.runGit(mergeArgs, this.projectRoot);
|
|
469
|
-
|
|
470
|
-
const fromOutput = parseConflictPaths(`${merged.stdout}
|
|
469
|
+
const fromOutput = parseConflictPaths(`${merged.stdout}
|
|
471
470
|
${merged.stderr}`);
|
|
472
|
-
|
|
473
|
-
|
|
471
|
+
const fromIndex = await this.unmergedFiles();
|
|
472
|
+
const conflictFiles = [.../* @__PURE__ */ new Set([...fromOutput, ...fromIndex])];
|
|
473
|
+
if (merged.code !== 0 || conflictFiles.length > 0) {
|
|
474
474
|
if (opts.resolve) {
|
|
475
475
|
const finalized = await this.tryResolveConflict(handle, conflictFiles, opts);
|
|
476
476
|
if (finalized) return finalized;
|
|
@@ -523,6 +523,10 @@ ${merged.stderr}`);
|
|
|
523
523
|
* Safe because SDD merges are serialized — no other commit lands in between.
|
|
524
524
|
*/
|
|
525
525
|
async revertBaseTo(handle, sha) {
|
|
526
|
+
const status = await this.runGit(["status", "--porcelain"], this.projectRoot);
|
|
527
|
+
if (status.code !== 0) return false;
|
|
528
|
+
const hasTrackedDirt = status.stdout.split("\n").some((line) => line.trim().length > 0 && !line.startsWith("??"));
|
|
529
|
+
if (hasTrackedDirt) return false;
|
|
526
530
|
const co = await this.runGit(["checkout", handle.baseBranch], this.projectRoot);
|
|
527
531
|
if (co.code !== 0) return false;
|
|
528
532
|
const reset = await this.runGit(["reset", "--hard", sha], this.projectRoot);
|
|
@@ -737,29 +741,47 @@ ${merged.stderr}`);
|
|
|
737
741
|
/**
|
|
738
742
|
* True when staged content still carries conflict markers.
|
|
739
743
|
*
|
|
740
|
-
*
|
|
741
|
-
*
|
|
742
|
-
*
|
|
743
|
-
*
|
|
744
|
-
*
|
|
745
|
-
*
|
|
744
|
+
* Reads the working-tree files directly and matches a full marker line
|
|
745
|
+
* (`<<<<<<< `, `=======`, `>>>>>>> `, `||||||| `) with a lenient regex
|
|
746
|
+
* (`{7,}`) that stays platform- and config-independent — unlike the old
|
|
747
|
+
* `git diff --check` (only fires when `core.whitespace` opts in) and
|
|
748
|
+
* `git grep` (assumes the default 7-char markers).
|
|
749
|
+
*
|
|
750
|
+
* Scan set: when the caller supplies the conflicted paths (the normal
|
|
751
|
+
* path from {@link tryResolveConflict}), ONLY those files are scanned so
|
|
752
|
+
* an unrelated `=======` setext-heading underline in a staged document
|
|
753
|
+
* can't false-positive and discard valid resolution work. The staged-file
|
|
754
|
+
* listing (`git diff --cached --name-only`) is used only as a fallback
|
|
755
|
+
* when no paths are given.
|
|
746
756
|
*
|
|
747
|
-
*
|
|
748
|
-
*
|
|
749
|
-
*
|
|
750
|
-
*
|
|
757
|
+
* CRLF caveat: conflicted files checked out with CRLF (`core.autocrlf=true`,
|
|
758
|
+
* `.gitattributes eol=crlf`) carry bare markers as `=======\r\n`. Because
|
|
759
|
+
* `$` in multiline mode matches only before `\n`, carriage returns are
|
|
760
|
+
* stripped before matching so `\r` never defeats the end-of-line anchor.
|
|
751
761
|
*/
|
|
752
762
|
async hasConflictMarkers(files) {
|
|
753
|
-
const
|
|
754
|
-
const
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
)
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
+
const listed = files ?? [];
|
|
764
|
+
const paths = listed.length > 0 ? listed : (await this.runGit(["diff", "--cached", "--name-only", "-z"], this.projectRoot)).stdout.split("\0").filter(Boolean);
|
|
765
|
+
const marker = /^(?:<{7,}(?: |$)|={7,}$|>{7,}(?: |$)|\|{7,}(?: |$))/m;
|
|
766
|
+
const startMarker = /^(?:<{7,}(?: |$)|\|{7,}(?: |$))/m;
|
|
767
|
+
for (const rel of paths) {
|
|
768
|
+
try {
|
|
769
|
+
const content = (await readFile(join(this.projectRoot, rel), "utf8")).replace(/\r/g, "");
|
|
770
|
+
const lines = content.split("\n");
|
|
771
|
+
let seenStart = false;
|
|
772
|
+
for (const line of lines) {
|
|
773
|
+
if (!marker.test(line)) continue;
|
|
774
|
+
if (line.startsWith("=====")) {
|
|
775
|
+
if (!seenStart) continue;
|
|
776
|
+
} else if (startMarker.test(line)) {
|
|
777
|
+
seenStart = true;
|
|
778
|
+
}
|
|
779
|
+
return true;
|
|
780
|
+
}
|
|
781
|
+
} catch {
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
return false;
|
|
763
785
|
}
|
|
764
786
|
/**
|
|
765
787
|
* Remove the worktree + branch. Conflicted/failed handles (or `keep:true`)
|
|
@@ -153,17 +153,23 @@ export declare class WorktreeManager {
|
|
|
153
153
|
/**
|
|
154
154
|
* True when staged content still carries conflict markers.
|
|
155
155
|
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
* some document can't false-positive.
|
|
156
|
+
* Reads the working-tree files directly and matches a full marker line
|
|
157
|
+
* (`<<<<<<< `, `=======`, `>>>>>>> `, `||||||| `) with a lenient regex
|
|
158
|
+
* (`{7,}`) that stays platform- and config-independent — unlike the old
|
|
159
|
+
* `git diff --check` (only fires when `core.whitespace` opts in) and
|
|
160
|
+
* `git grep` (assumes the default 7-char markers).
|
|
162
161
|
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
162
|
+
* Scan set: when the caller supplies the conflicted paths (the normal
|
|
163
|
+
* path from {@link tryResolveConflict}), ONLY those files are scanned so
|
|
164
|
+
* an unrelated `=======` setext-heading underline in a staged document
|
|
165
|
+
* can't false-positive and discard valid resolution work. The staged-file
|
|
166
|
+
* listing (`git diff --cached --name-only`) is used only as a fallback
|
|
167
|
+
* when no paths are given.
|
|
168
|
+
*
|
|
169
|
+
* CRLF caveat: conflicted files checked out with CRLF (`core.autocrlf=true`,
|
|
170
|
+
* `.gitattributes eol=crlf`) carry bare markers as `=======\r\n`. Because
|
|
171
|
+
* `$` in multiline mode matches only before `\n`, carriage returns are
|
|
172
|
+
* stripped before matching so `\r` never defeats the end-of-line anchor.
|
|
167
173
|
*/
|
|
168
174
|
private hasConflictMarkers;
|
|
169
175
|
/**
|
|
@@ -40,6 +40,14 @@ deletion, history rewriting, force-push, or database destruction unless the
|
|
|
40
40
|
task explicitly requires the action and identifies the exact target. Recheck
|
|
41
41
|
the target before any destructive step.
|
|
42
42
|
|
|
43
|
+
## Codebase discovery
|
|
44
|
+
|
|
45
|
+
When the index is available, use it before broad `grep`/`glob` exploration:
|
|
46
|
+
- `codebase-search` to locate symbols, definitions, and candidate modules.
|
|
47
|
+
- `codebase-incoming-calls` to find all callers of a symbol before refactoring.
|
|
48
|
+
- `codebase-outgoing-calls` to understand a symbol's dependencies.
|
|
49
|
+
Read source files returned by search before relying on them.
|
|
50
|
+
|
|
43
51
|
## No further delegation
|
|
44
52
|
|
|
45
53
|
You MUST NOT call `delegate`, `spawn_subagent`, `assign_task`, or any equivalent.
|