@wrongstack/core 0.260.0 → 0.265.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/dist/{agent-bridge-BbskZ7HH.d.ts → agent-bridge-DrkBxszZ.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-BNIGZx18.d.ts → agent-subagent-runner-DM2pP-B6.d.ts} +116 -12
  3. package/dist/{brain-C2yDd7Lw.d.ts → brain-BXd_61kQ.d.ts} +32 -3
  4. package/dist/{compactor-t0R_AIt_.d.ts → compactor-B8pOf45Y.d.ts} +1 -1
  5. package/dist/{config-FG6As4H5.d.ts → config-BMCj_XDs.d.ts} +86 -12
  6. package/dist/{context-JFOVvu6z.d.ts → context-MRk5PhNv.d.ts} +26 -1
  7. package/dist/coordination/index.d.ts +1737 -15
  8. package/dist/coordination/index.js +3152 -494
  9. package/dist/coordination/index.js.map +1 -1
  10. package/dist/{default-config-CXsDvOmP.d.ts → default-config-B0cj-Hry.d.ts} +11 -1
  11. package/dist/defaults/index.d.ts +28 -28
  12. package/dist/defaults/index.js +1804 -1363
  13. package/dist/defaults/index.js.map +1 -1
  14. package/dist/dispatcher-types.d-BBeXBQgS.d.ts +66 -0
  15. package/dist/execution/index.d.ts +16 -16
  16. package/dist/execution/index.js +933 -672
  17. package/dist/execution/index.js.map +1 -1
  18. package/dist/execution/prompt-enhancer.d.ts +1 -1
  19. package/dist/execution/prompt-enhancer.js +7 -1
  20. package/dist/execution/prompt-enhancer.js.map +1 -1
  21. package/dist/extension/index.d.ts +6 -6
  22. package/dist/extension/index.js.map +1 -1
  23. package/dist/{goal-preamble-B1IXJtLX.d.ts → goal-preamble-DvHDSKSe.d.ts} +26 -10
  24. package/dist/{goal-store-CPXz6Mml.d.ts → goal-store-DtLMySNb.d.ts} +1 -1
  25. package/dist/{index-CebbJB94.d.ts → index-B-ch8K9C.d.ts} +8 -8
  26. package/dist/{index-BPcg4N3M.d.ts → index-CEDeNodM.d.ts} +5 -5
  27. package/dist/index.d.ts +189 -104
  28. package/dist/index.js +24693 -21162
  29. package/dist/index.js.map +1 -1
  30. package/dist/infrastructure/index.d.ts +6 -6
  31. package/dist/infrastructure/index.js +12 -8
  32. package/dist/infrastructure/index.js.map +1 -1
  33. package/dist/kernel/index.d.ts +9 -9
  34. package/dist/kernel/index.js +7 -2
  35. package/dist/kernel/index.js.map +1 -1
  36. package/dist/{llm-selector-DXxI2tlu.d.ts → llm-selector-C0tfTCUe.d.ts} +14 -2
  37. package/dist/{mcp-servers-OwNHo43-.d.ts → mcp-servers-2x4w6Jn9.d.ts} +3 -3
  38. package/dist/models/index.d.ts +5 -5
  39. package/dist/models/index.js +80 -31
  40. package/dist/models/index.js.map +1 -1
  41. package/dist/{models-registry-Djlmq4uB.d.ts → models-registry-DmJlKuNp.d.ts} +1 -1
  42. package/dist/{multi-agent-coordinator-CEmrSCMJ.d.ts → multi-agent-coordinator-DyCkCZnU.d.ts} +2 -2
  43. package/dist/{null-fleet-bus-DT92xqgJ.d.ts → null-fleet-bus-CG9QY2aP.d.ts} +6 -6
  44. package/dist/observability/index.d.ts +2 -2
  45. package/dist/observability/index.js +8 -3
  46. package/dist/observability/index.js.map +1 -1
  47. package/dist/{parallel-eternal-engine-0SItuq5r.d.ts → parallel-eternal-engine-Jw9uhEoT.d.ts} +9 -9
  48. package/dist/{path-resolver-DKBh6Jlo.d.ts → path-resolver-Dy2ej-gE.d.ts} +3 -3
  49. package/dist/{permission-BJ7eO9Vl.d.ts → permission-B9SB45lp.d.ts} +1 -1
  50. package/dist/{permission-policy-DEXOfnpm.d.ts → permission-policy-CkjSXabK.d.ts} +2 -2
  51. package/dist/{pipeline-zflkI2dp.d.ts → pipeline-DPDxH_7m.d.ts} +59 -4
  52. package/dist/{plan-templates-BFXyRkEK.d.ts → plan-templates-CzD9GnAU.d.ts} +32 -8
  53. package/dist/{provider-runner-BC-uywtT.d.ts → provider-runner-DMa70ODu.d.ts} +3 -3
  54. package/dist/{retry-policy-Cavrzmtk.d.ts → retry-policy-CN0khdlj.d.ts} +1 -1
  55. package/dist/sdd/index.d.ts +8 -8
  56. package/dist/sdd/index.js +313 -122
  57. package/dist/sdd/index.js.map +1 -1
  58. package/dist/{secret-vault-CDvDYXWX.d.ts → secret-vault-B2yw84VT.d.ts} +43 -4
  59. package/dist/secret-vault-BAKpgFw_.d.ts +57 -0
  60. package/dist/security/index.d.ts +5 -5
  61. package/dist/security/index.js +411 -225
  62. package/dist/security/index.js.map +1 -1
  63. package/dist/{selector-B7AivHsu.d.ts → selector-CzHh_igB.d.ts} +1 -1
  64. package/dist/{session-event-bridge-BmIDxdJd.d.ts → session-event-bridge-BUI6Jf-4.d.ts} +8 -2
  65. package/dist/{session-reader-DtofsB-2.d.ts → session-reader-CMgdMSRP.d.ts} +1 -1
  66. package/dist/skills/index.js +67 -64
  67. package/dist/skills/index.js.map +1 -1
  68. package/dist/storage/index.d.ts +132 -16
  69. package/dist/storage/index.js +851 -432
  70. package/dist/storage/index.js.map +1 -1
  71. package/dist/tools/index.d.ts +57 -0
  72. package/dist/tools/index.js +411 -0
  73. package/dist/tools/index.js.map +1 -0
  74. package/dist/types/index.d.ts +21 -21
  75. package/dist/types/index.js +928 -711
  76. package/dist/types/index.js.map +1 -1
  77. package/dist/utils/error.d.ts +7 -0
  78. package/dist/utils/error.js +8 -0
  79. package/dist/utils/error.js.map +1 -0
  80. package/dist/utils/index.d.ts +8 -68
  81. package/dist/utils/index.js +20 -10
  82. package/dist/utils/index.js.map +1 -1
  83. package/dist/{wstack-paths-CJjEwPXn.d.ts → wstack-paths-hOpNLmvf.d.ts} +2 -0
  84. package/package.json +5 -1
  85. package/skills/api-design/SKILL.md +1 -1
  86. package/skills/audit-log/SKILL.md +6 -6
  87. package/skills/bug-hunter/SKILL.md +5 -5
  88. package/skills/chimera/SKILL.md +4 -4
  89. package/skills/docker-deploy/SKILL.md +1 -1
  90. package/skills/git-flow/SKILL.md +3 -3
  91. package/skills/multi-agent/SKILL.md +3 -3
  92. package/skills/node-modern/SKILL.md +1 -0
  93. package/skills/observability/SKILL.md +2 -2
  94. package/skills/output-standards/SKILL.md +51 -28
  95. package/skills/refactor-planner/SKILL.md +3 -3
  96. package/skills/security-scanner/SKILL.md +4 -3
  97. package/skills/tech-stack/SKILL.md +1 -2
  98. package/dist/package-outdated-watcher-C70ag2G9.d.ts +0 -581
  99. package/dist/secret-vault-BJDY28ev.d.ts +0 -25
@@ -1,21 +1,23 @@
1
- export { B as BrainArbiter, b as BrainDecision, c as BrainDecisionOption, d as BrainDecisionQueue, e as BrainDecisionRequest, f as BrainDecisionSource, g as BrainFallback, h as BrainRisk, D as DefaultBrainArbiter, i as DefaultBrainArbiterOptions, H as HumanEscalatingBrainArbiter, O as ObservableBrainArbiter, j as formatHumanPrompt } from '../brain-C2yDd7Lw.js';
2
- export { A as ACP_AGENTS, a as AGENTS_BY_PHASE, b as AGENT_CATALOG, c as ALL_AGENT_DEFINITIONS, d as ALL_FLEET_AGENTS, e as AUDIT_LOG_AGENT, f as AutoExtendCeiling, g as AutoExtendPolicy, B as BUG_HUNTER_AGENT, h as BugFinding, C as CollabBudgetConfig, i as CollabBudgetOverrides, j as CollabBudgetWarningPayload, k as CollabDebugReport, l as CollabSession, m as CollabSessionOptions, n as CreateDelegateToolOptions, o as CriticConcern, p as CriticEvaluation, D as DEFAULT_DIRECTOR_PREAMBLE, q as DEFAULT_SUBAGENT_BASELINE, r as DelegateHost, s as Director, t as DirectorAlert, u as DirectorAlertLevel, v as DirectorCancelCollabPayload, w as DirectorPromptParts, x as DirectorSessionFactory, y as DirectorSessionFactoryOptions, F as FLEET_ROSTER, z as FLEET_ROSTER_BUDGETS, E as FLEET_ROSTER_WITHACP, G as FleetCostCapError, H as FleetManager, I as FleetManagerOptions, J as FleetRosterBudget, K as FleetSpawnBudgetError, L as ICoordinator, M as IFleetManager, N as LargeAnswerStore, O as NULL_FLEET_BUS, R as REFACTOR_PLANNER_AGENT, P as RefactorPhase, Q as RefactorPlan, S as SECURITY_SCANNER_AGENT, T as SharedFileEntry, U as SharedFileSnapshot, V as SubagentPromptParts, W as applyRosterBudget, X as attachAutoExtend, Y as composeDirectorPrompt, Z as composeSubagentPrompt, _ as createDelegateTool, $ as getAgentDefinition, a0 as makeAskResultTool, a1 as makeAskTool, a2 as makeAssignTool, a3 as makeAwaitTasksTool, a4 as makeCollabDebugTool, a5 as makeDirectorSessionFactory, a6 as makeFleetEmitTool, a7 as makeFleetHealthTool, a8 as makeFleetSessionTool, a9 as makeFleetStatusTool, aa as makeFleetUsageTool, ab as makeRollUpTool, ac as makeSpawnTool, ad as makeTerminateTool, ae as makeWorkCompleteTool, af as rosterSummaryFromConfigs } from '../null-fleet-bus-DT92xqgJ.js';
3
- import { A as AgentDefinition } from '../multi-agent-coordinator-CEmrSCMJ.js';
4
- export { T as AGENT_TOOL_PRESETS, b as AgentBudgetTier, c as AgentCapability, d as AgentPhase, e as DEFAULT_DISPATCH_ROLE, a as DefaultMultiAgentCoordinator, f as DispatchCandidate, D as DispatchClassifier, g as DispatchMethod, h as DispatchOptions, i as DispatchResult, H as HEAVY_BUDGET, L as LIGHT_BUDGET, M as MEDIUM_BUDGET, j as MultiAgentCoordinatorOptions, k as dispatchAgent, m as makeLLMClassifier, s as scoreAgents } from '../multi-agent-coordinator-CEmrSCMJ.js';
5
- export { h as AgentFactory, i as AgentFactoryResult, j as AgentRunnerOptions, k as BudgetExceededError, l as BudgetKind, m as BudgetLimits, n as BudgetNegotiationMode, o as BudgetThresholdDecision, p as BudgetThresholdHandler, q as BudgetThresholdSignal, r as BudgetUsage, F as FleetBus, s as FleetEvent, t as FleetHandler, u as FleetUsage, v as FleetUsageAggregator, w as SubagentBudget, x as SubagentUsageSnapshot, y as makeAgentSubagentRunner, z as withDisabledToolFiltering } from '../agent-subagent-runner-BNIGZx18.js';
6
- export { I as InMemoryAgentBridge, a as InMemoryBridgeTransport, c as createMessage } from '../agent-bridge-BbskZ7HH.js';
7
- export { B as BrainInterventionInput, a as BrainMonitor, b as BrainMonitorOptions, D as DEPENDENCY_FILE_PATTERNS, c as DefaultMailbox, d as DepWatchEntry, e as DepWatcherBridgeOptions, f as DependencyWatcherConfig, G as GlobalMailbox, M as MailToolsOptions, g as MailboxResolver, h as MailboxToolOptions, O as OutdatedNotifyMessage, P as PackageAuthorEntry, i as PackageAuthorLog, j as PackageAuthorTrackerOptions, k as PackageOutdatedEntry, l as PackageOutdatedResult, m as PackageOutdatedWatcherOptions, n as attachDepWatcherBridge, o as detectEcosystem, p as getFullPackageLog, q as getManifestPackages, r as getPackageAuthor, s as getPackagesByAgent, t as mailboxSessionTag, u as makeDependencyWatcherConfig, v as makeMailInboxTool, w as makeMailSendTool, x as makeMailboxTool, y as recordPackageAction, z as resolveMailboxIdentity, A as resolveProjectDir, C as startPackageOutdatedWatcher, E as updatePackageOutdatedStatus } from '../package-outdated-watcher-C70ag2G9.js';
8
- import { b as Mailbox } from '../pipeline-zflkI2dp.js';
9
- export { h as AgentHeartbeatInput, A as AgentRegistrationInput, f as MailboxAckInput, g as MailboxAgentStatus, d as MailboxMessage, l as MailboxMessageType, e as MailboxQuery, c as MailboxSendInput, m as MailboxTaskContext, n as ReadReceipts, o as RegisteredAgent, p as normalizeRecipient } from '../pipeline-zflkI2dp.js';
10
- import '../context-JFOVvu6z.js';
1
+ import { E as EventBus, B as BrainArbiter, f as BrainDecisionOption, k as BrainRisk, h as BrainDecisionRequest, e as BrainDecision, i as BrainDecisionSource } from '../brain-BXd_61kQ.js';
2
+ export { g as BrainDecisionQueue, j as BrainFallback, D as DefaultBrainArbiter, l as DefaultBrainArbiterOptions, H as HumanEscalatingBrainArbiter, O as ObservableBrainArbiter, w as formatHumanPrompt } from '../brain-BXd_61kQ.js';
3
+ import { H as FleetManager, s as Director } from '../null-fleet-bus-CG9QY2aP.js';
4
+ export { A as ACP_AGENTS, a as AGENTS_BY_PHASE, b as AGENT_CATALOG, c as ALL_AGENT_DEFINITIONS, d as ALL_FLEET_AGENTS, e as AUDIT_LOG_AGENT, f as AutoExtendCeiling, g as AutoExtendPolicy, B as BUG_HUNTER_AGENT, h as BugFinding, C as CollabBudgetConfig, i as CollabBudgetOverrides, j as CollabBudgetWarningPayload, k as CollabDebugReport, l as CollabSession, m as CollabSessionOptions, n as CreateDelegateToolOptions, o as CriticConcern, p as CriticEvaluation, D as DEFAULT_DIRECTOR_PREAMBLE, q as DEFAULT_SUBAGENT_BASELINE, r as DelegateHost, t as DirectorAlert, u as DirectorAlertLevel, v as DirectorCancelCollabPayload, w as DirectorPromptParts, x as DirectorSessionFactory, y as DirectorSessionFactoryOptions, F as FLEET_ROSTER, z as FLEET_ROSTER_BUDGETS, E as FLEET_ROSTER_WITHACP, G as FleetCostCapError, I as FleetManagerOptions, J as FleetRosterBudget, K as FleetSpawnBudgetError, L as ICoordinator, M as IFleetManager, N as LargeAnswerStore, O as NULL_FLEET_BUS, R as REFACTOR_PLANNER_AGENT, P as RefactorPhase, Q as RefactorPlan, S as SECURITY_SCANNER_AGENT, T as SharedFileEntry, U as SharedFileSnapshot, V as SubagentPromptParts, W as applyRosterBudget, X as attachAutoExtend, Y as composeDirectorPrompt, Z as composeSubagentPrompt, _ as createDelegateTool, $ as getAgentDefinition, a0 as makeAskResultTool, a1 as makeAskTool, a2 as makeAssignTool, a3 as makeAwaitTasksTool, a4 as makeCollabDebugTool, a5 as makeDirectorSessionFactory, a6 as makeFleetEmitTool, a7 as makeFleetHealthTool, a8 as makeFleetSessionTool, a9 as makeFleetStatusTool, aa as makeFleetUsageTool, ab as makeRollUpTool, ac as makeSpawnTool, ad as makeTerminateTool, ae as makeWorkCompleteTool, af as rosterSummaryFromConfigs } from '../null-fleet-bus-CG9QY2aP.js';
5
+ import { b as AgentDefinition } from '../multi-agent-coordinator-DyCkCZnU.js';
6
+ export { T as AGENT_TOOL_PRESETS, c as AgentBudgetTier, d as AgentCapability, A as AgentPhase, e as DEFAULT_DISPATCH_ROLE, a as DefaultMultiAgentCoordinator, f as DispatchCandidate, D as DispatchClassifier, g as DispatchMethod, h as DispatchOptions, i as DispatchResult, H as HEAVY_BUDGET, L as LIGHT_BUDGET, M as MEDIUM_BUDGET, j as MultiAgentCoordinatorOptions, k as dispatchAgent, m as makeLLMClassifier, s as scoreAgents } from '../multi-agent-coordinator-DyCkCZnU.js';
7
+ import { F as FleetBus } from '../agent-subagent-runner-DM2pP-B6.js';
8
+ export { h as AgentFactory, v as AgentFactoryResult, w as AgentRunnerOptions, x as BudgetExceededError, y as BudgetKind, z as BudgetLimits, E as BudgetNegotiationMode, G as BudgetThresholdDecision, H as BudgetThresholdHandler, I as BudgetThresholdSignal, J as BudgetUsage, L as DECISION_TIMEOUT_MS, N as FleetEvent, O as FleetHandler, i as FleetUsage, j as FleetUsageAggregator, Q as SubagentBudget, Y as SubagentUsageSnapshot, Z as TIMEOUT_PREEMPT_FRACTION, $ as makeAgentSubagentRunner, a0 as withDisabledToolFiltering } from '../agent-subagent-runner-DM2pP-B6.js';
9
+ export { I as InMemoryAgentBridge, a as InMemoryBridgeTransport, c as createMessage } from '../agent-bridge-DrkBxszZ.js';
10
+ import { c as Mailbox, k as MailboxSendInput, d as MailboxMessage, j as MailboxQuery, g as MailboxAckInput, s as MailboxAckBatchInput, h as MailboxAgentStatus, e as AgentRegistrationInput, A as AgentHeartbeatInput, t as PurgeOptions, u as PurgeResult, v as ClientRegistrationInput, w as ClientHeartbeatInput, x as ClientStatus } from '../pipeline-DPDxH_7m.js';
11
+ export { i as MailboxMessageType, l as MailboxTaskContext, o as ReadReceipts, p as RegisteredAgent, r as normalizeRecipient } from '../pipeline-DPDxH_7m.js';
12
+ import { C as Context, T as Tool } from '../context-MRk5PhNv.js';
11
13
  import 'node:events';
12
14
  import '../director-state-BfeCUbmk.js';
13
- import '../config-FG6As4H5.js';
14
- import '../index-BPcg4N3M.js';
15
+ import '../config-BMCj_XDs.js';
16
+ import '../index-CEDeNodM.js';
15
17
  import '../logger-B63L5bTg.js';
16
18
  import '../observability-D-HZN_mF.js';
17
- import '../permission-BJ7eO9Vl.js';
18
- import '../retry-policy-Cavrzmtk.js';
19
+ import '../permission-B9SB45lp.js';
20
+ import '../retry-policy-CN0khdlj.js';
19
21
 
20
22
  /** Phase 1 · Discovery — map the territory before any work begins. */
21
23
  declare const DISCOVERY_AGENTS: AgentDefinition[];
@@ -44,6 +46,471 @@ declare const DELIVERY_AGENTS: AgentDefinition[];
44
46
  /** Phase 9 · Meta — agents that improve the agent system itself. */
45
47
  declare const META_AGENTS: AgentDefinition[];
46
48
 
49
+ /**
50
+ * DefaultMailbox — append-only JSONL inter-agent mailbox (per-session).
51
+ *
52
+ * Stores messages under `<sessionDir>/_mailbox.jsonl`. Every send appends
53
+ * one line. Query reads and filters all lines. Ack rewrites changed
54
+ * messages in-place via atomic write.
55
+ *
56
+ * For cross-session communication, use GlobalMailbox instead.
57
+ *
58
+ * @module DefaultMailbox
59
+ */
60
+
61
+ declare class DefaultMailbox implements Mailbox {
62
+ private readonly filePath;
63
+ constructor(sessionDir: string);
64
+ get mailboxPath(): string;
65
+ send(input: MailboxSendInput): Promise<MailboxMessage>;
66
+ query(q: MailboxQuery): Promise<MailboxMessage[]>;
67
+ ack(input: MailboxAckInput): Promise<MailboxMessage | null>;
68
+ ackMany(input: MailboxAckBatchInput): Promise<MailboxMessage[]>;
69
+ getAgentStatuses(): Promise<MailboxAgentStatus[]>;
70
+ getOnlineAgents(): Promise<MailboxAgentStatus[]>;
71
+ registerAgent(_input: AgentRegistrationInput): Promise<void>;
72
+ heartbeat(_input: AgentHeartbeatInput): Promise<void>;
73
+ unreadCount(forAgentId: string): Promise<number>;
74
+ close(): Promise<void>;
75
+ clearAll(): Promise<void>;
76
+ purgeStale(opts?: PurgeOptions): Promise<PurgeResult>;
77
+ registerClient(_input: ClientRegistrationInput): Promise<void>;
78
+ clientHeartbeat(_input: ClientHeartbeatInput): Promise<void>;
79
+ getClientStatuses(): Promise<ClientStatus[]>;
80
+ private _readAll;
81
+ }
82
+
83
+ /**
84
+ * BrainMonitor — the Brain's SELF-ACTIVATION layer.
85
+ *
86
+ * The BrainArbiter alone is reactive: subsystems (director, autophase,
87
+ * eternal engine) ask it questions. The monitor closes the loop the other
88
+ * way — it WATCHES the live EventBus for distress signals, consults the
89
+ * Brain proactively, and when the decision calls for it, INTERVENES in the
90
+ * running work by delivering a corrective steer to the working agent
91
+ * (steers are folded into the agent's conversation before its next step
92
+ * via the mailbox loop, so no new plumbing is needed).
93
+ *
94
+ * Watched signals (v1):
95
+ * - tool-failure streak — the same tool failing N times consecutively
96
+ * (default 3). Classic stuck-loop: the agent keeps retrying an
97
+ * approach that does not work.
98
+ * - error storm — N `error` events within a sliding window (default
99
+ * 4 in 60s). Something is systematically wrong.
100
+ *
101
+ * Decision contract: every consultation offers [steer | continue] with
102
+ * fallback `continue`, at `medium` risk. Degradation is safe by design:
103
+ * - tiered brain with an LLM layer → a real judgement call, with the
104
+ * LLM's rationale becoming the steer text;
105
+ * - policy-only brain → fallback `continue` → observe, never interfere.
106
+ *
107
+ * Every engagement (whether or not it intervened) emits
108
+ * `brain.intervention` for the TUI/WebUI surfaces, and is rate-limited by
109
+ * a per-signal cooldown so the Brain never spams the agent.
110
+ *
111
+ * @module brain-monitor
112
+ */
113
+
114
+ interface BrainInterventionInput {
115
+ subject: string;
116
+ body: string;
117
+ }
118
+ interface BrainMonitorOptions {
119
+ events: EventBus;
120
+ brain: BrainArbiter;
121
+ /**
122
+ * Deliver a corrective steer to the working agent(s). Hosts typically
123
+ * send a `steer` mail to this session's leader via the project
124
+ * GlobalMailbox — the agent loop injects it before the next LLM call.
125
+ */
126
+ intervene: (input: BrainInterventionInput) => Promise<void>;
127
+ /** Consecutive failures of the SAME tool before engaging. Default 3. */
128
+ toolFailureStreak?: number | undefined;
129
+ /** Number of `error` events within the window before engaging. Default 4. */
130
+ errorStormCount?: number | undefined;
131
+ /** Sliding window for the error storm signal (ms). Default 60_000. */
132
+ errorStormWindowMs?: number | undefined;
133
+ /** Minimum gap between engagements of the same signal kind (ms). Default 120_000. */
134
+ cooldownMs?: number | undefined;
135
+ }
136
+ declare class BrainMonitor {
137
+ private readonly opts;
138
+ private readonly failStreaks;
139
+ private errorTimestamps;
140
+ private readonly lastEngagedAt;
141
+ private readonly unsubscribers;
142
+ private engaging;
143
+ private readonly toolFailureStreak;
144
+ private readonly errorStormCount;
145
+ private readonly errorStormWindowMs;
146
+ private readonly cooldownMs;
147
+ constructor(opts: BrainMonitorOptions);
148
+ start(): void;
149
+ stop(): void;
150
+ private engage;
151
+ private maybeIntervene;
152
+ }
153
+
154
+ /**
155
+ * GlobalMailbox — project-level inter-agent mailbox with cross-session support.
156
+ *
157
+ * Stores messages at `~/.wrongstack/projects/<slug>/_mailbox.jsonl` so all
158
+ * sessions (terminals, WebUIs) working on the same project share one inbox.
159
+ *
160
+ * Features:
161
+ * - Agent registration + heartbeat (agents go stale after 60s without heartbeat)
162
+ * - Per-recipient read receipts (readBy[agentId] = ISO8601)
163
+ * - Atomic file-locking for concurrent multi-process writes
164
+ * - Unread count for new-mail notifications
165
+ * - Online agent list
166
+ *
167
+ * @module GlobalMailbox
168
+ */
169
+
170
+ /**
171
+ * Derive the project-level mailbox directory path.
172
+ *
173
+ * Delegates to the CANONICAL `projectSlug()` from wstack-paths so every
174
+ * surface (CLI, TUI, WebUI, mailbox tool, loop checker) lands in the exact
175
+ * same `~/.wrongstack/projects/<slug>/` directory. A previous inline copy
176
+ * skipped the leading/trailing-hyphen strip, which silently split agents
177
+ * working on projects with non-alphanumeric name edges into TWO mailboxes.
178
+ *
179
+ * @param projectRoot — absolute path to the project root
180
+ * @param globalRoot — `~/.wrongstack` (or custom global root)
181
+ */
182
+ declare function resolveProjectDir(projectRoot: string, globalRoot: string): string;
183
+ declare class GlobalMailbox implements Mailbox {
184
+ /** Path to the JSONL message file. */
185
+ readonly messagePath: string;
186
+ /** Path to the JSON agent registry file. */
187
+ readonly registryPath: string;
188
+ /** Path to the JSON client registry file. */
189
+ readonly clientRegistryPath: string;
190
+ /** Optional event bus for emitting agent registration/heartbeat events. */
191
+ private readonly _events?;
192
+ /**
193
+ * Local cache of the agent registry to avoid re-reading on every call.
194
+ * Time-bounded: the registry file is shared ACROSS PROCESSES (that's the
195
+ * whole point of GlobalMailbox), so a cache served forever would never see
196
+ * agents registered by other sessions. Writers always bypass it.
197
+ */
198
+ private _registryCache;
199
+ /** When the registry cache was last refreshed from disk (epoch ms). */
200
+ private _registryCacheAt;
201
+ /**
202
+ * Local cache of the client registry to avoid re-reading on every call.
203
+ * Same reasoning as agent registry cache.
204
+ */
205
+ private _clientRegistryCache;
206
+ /** When the client registry cache was last refreshed from disk (epoch ms). */
207
+ private _clientRegistryCacheAt;
208
+ /** Last time each local agent sent a heartbeat (throttle). */
209
+ private _lastHeartbeat;
210
+ /** Last time each local client sent a heartbeat (throttle). */
211
+ private _lastClientHeartbeat;
212
+ /**
213
+ * In-memory mirror of the JSONL message file. The mailbox is shared
214
+ * ACROSS PROCESSES, so reads cannot trust the cache blindly — we pair it
215
+ * with an mtime check. The file lock serializes every write, so a
216
+ * changed mtimeMs is a definitive signal that another process (or this
217
+ * one) wrote; an unchanged mtimeMs guarantees no write happened and the
218
+ * cache is current. This collapses the per-iteration `query()` cost from
219
+ * O(file_size) disk + parse to O(messages) in memory.
220
+ */
221
+ private _messageCache;
222
+ /** mtimeMs of the file when `_messageCache` was populated. */
223
+ private _messageCacheMtime;
224
+ /** Size of the file when `_messageCache` was populated (extra guard). */
225
+ private _messageCacheSize;
226
+ /**
227
+ * @param projectDir — `~/.wrongstack/projects/<slug>/`
228
+ * @param events — optional EventBus for real-time TUI/WebUI notifications
229
+ */
230
+ constructor(projectDir: string, events?: EventBus);
231
+ send(input: MailboxSendInput): Promise<MailboxMessage>;
232
+ query(q: MailboxQuery): Promise<MailboxMessage[]>;
233
+ ack(input: MailboxAckInput): Promise<MailboxMessage | null>;
234
+ ackMany(input: MailboxAckBatchInput): Promise<MailboxMessage[]>;
235
+ unreadCount(forAgentId: string): Promise<number>;
236
+ registerAgent(input: AgentRegistrationInput): Promise<void>;
237
+ heartbeat(input: AgentHeartbeatInput): Promise<void>;
238
+ getAgentStatuses(): Promise<MailboxAgentStatus[]>;
239
+ getOnlineAgents(): Promise<MailboxAgentStatus[]>;
240
+ registerClient(input: ClientRegistrationInput): Promise<void>;
241
+ clientHeartbeat(input: ClientHeartbeatInput): Promise<void>;
242
+ getClientStatuses(): Promise<ClientStatus[]>;
243
+ close(): Promise<void>;
244
+ clearAll(): Promise<void>;
245
+ purgeStale(opts?: PurgeOptions): Promise<PurgeResult>;
246
+ /**
247
+ * Read all messages from the JSONL file. Always reads + parses the file.
248
+ * Callers that can tolerate a stale-by-mtime view should use
249
+ * {@link _readMessagesCached}; writers that need the post-lock truth
250
+ * should call this directly (it's what {@link _readMessagesFresh} aliases).
251
+ */
252
+ private _readMessages;
253
+ /**
254
+ * Read messages, then adopt the result as the in-memory cache. Use this
255
+ * from writers that just took the file lock — the read reflects the
256
+ * authoritative post-lock state and should be served to subsequent
257
+ * queries without re-reading.
258
+ */
259
+ private _readMessagesFresh;
260
+ /**
261
+ * Read messages, consulting the mtime-bounded in-memory cache first.
262
+ * The mailbox file is shared across processes; every `send`/`ack`/
263
+ * `clearAll`/`purgeStale` takes the file lock, so writes are serialized
264
+ * and a changed mtimeMs is a definitive freshness signal. When the
265
+ * stat matches the cached mtime+size we return the cached array — no
266
+ * file read and no JSON.parse — collapsing the per-iteration query
267
+ * cost on the mailbox-loop hot path.
268
+ */
269
+ private _readMessagesCached;
270
+ /**
271
+ * Replace the in-memory cache. Caller is responsible for guaranteeing
272
+ * that `messages` reflects the current on-disk state (e.g. they just
273
+ * read or wrote it under the file lock).
274
+ */
275
+ private _setMessageCache;
276
+ /**
277
+ * Append a single just-sent message to the in-memory cache without
278
+ * re-reading the file. The caller must hold the file lock (or have
279
+ * just released it after a successful append) so the cache stays
280
+ * consistent with on-disk state.
281
+ */
282
+ private _pushToCache;
283
+ private _ensureRegistry;
284
+ private _readRegistry;
285
+ private _pruneStaleInPlace;
286
+ private _writeRegistry;
287
+ private _ensureClientRegistry;
288
+ private _readClientRegistry;
289
+ private _pruneStaleClientsInPlace;
290
+ private _writeClientRegistry;
291
+ }
292
+
293
+ /**
294
+ * mailbox-tool — Tool that exposes the inter-agent mailbox to agents.
295
+ *
296
+ * Sub-commands: check, send, ack, query, status, online, unread
297
+ *
298
+ * Uses the project-level GlobalMailbox for cross-session communication.
299
+ * Agents are auto-registered on first use with heartbeat tracking.
300
+ * Read receipts track who read each message and when.
301
+ *
302
+ * @module mailbox-tool
303
+ */
304
+
305
+ type MailboxResolver = (ctx: Context) => Mailbox;
306
+ interface MailboxToolOptions {
307
+ /**
308
+ * How to obtain a Mailbox instance given the execution Context.
309
+ * Default: derives project dir from ctx and creates a GlobalMailbox.
310
+ */
311
+ resolveMailbox?: MailboxResolver | undefined;
312
+ /**
313
+ * Agent id of the caller — used as default "from" on send.
314
+ * Default: 'leader' for the main agent, or derived from ctx.meta.
315
+ */
316
+ agentId?: string | undefined;
317
+ /** Session id for cross-session communication. Default: derived from ctx. */
318
+ sessionId?: string | undefined;
319
+ /**
320
+ * Project directory where the mailbox is stored.
321
+ * Default: derived from ctx.projectRoot (may differ from wpaths.projectDir).
322
+ * For correct cross-session sharing, pass `wpaths.projectDir` from the caller.
323
+ */
324
+ projectDir?: string | undefined;
325
+ /**
326
+ * EventBus for emitting mailbox.agent_registered and mailbox.agent_heartbeat
327
+ * events so the TUI/WebUI can update the online agent count in the status bar.
328
+ * When omitted, events are not emitted and the status bar count stays at 0.
329
+ */
330
+ events?: EventBus | undefined;
331
+ }
332
+ /**
333
+ * Compact, deterministic tag for a session id — 8 hex chars of its sha256.
334
+ * Session ids are date-sharded paths ("2026-06-11/10-48-34Z_model_e66c");
335
+ * the tag keeps mailbox identities short, filesystem-safe, and stable for
336
+ * the lifetime of the session (including across process restarts/resumes).
337
+ */
338
+ declare function mailboxSessionTag(sessionId: string): string;
339
+ /**
340
+ * Resolve the caller's mailbox identity from the execution Context.
341
+ *
342
+ * Shared by the `mailbox` power-tool, the thin `mail_send`/`mail_inbox`
343
+ * tools, the agent-loop checker, and the /mailbox slash command so every
344
+ * surface agrees on who is talking:
345
+ * - base id: ctx.meta.agentId → ctx.agentId field (subagents) → fallback
346
+ * - unique id: `<base>@<sessionTag>` — SESSION-bound, not pid-bound. Every
347
+ * session has its own id, so two leader sessions on the same project
348
+ * never collide (pids can be recycled by the OS), and a resumed session
349
+ * keeps its identity: read state survives a restart instead of
350
+ * re-flooding old broadcasts. Derived LIVE from ctx.session.id so an
351
+ * in-process session swap (resume / session.new / project switch) moves
352
+ * the identity with it. `ctx.meta.globalAgentId` remains an explicit
353
+ * override for hosts that manage identity themselves.
354
+ */
355
+ declare function resolveMailboxIdentity(ctx: Context, fallbackBase?: string): {
356
+ baseId: string;
357
+ callerId: string;
358
+ name: string;
359
+ role?: string | undefined;
360
+ sessionId: string;
361
+ };
362
+ declare function makeMailboxTool(opts?: MailboxToolOptions): Tool;
363
+
364
+ /**
365
+ * mail-tools — thin, high-affordance wrappers over the project mailbox.
366
+ *
367
+ * The multi-action `mailbox` tool is the power surface; these two exist
368
+ * because explicit verbs ("send a mail", "read my inbox") are what makes
369
+ * agents USE the mailbox autonomously — a model reaches for `mail_send`
370
+ * mid-task far more readily than for `mailbox action=send ...`.
371
+ *
372
+ * mail_send — message one agent (`to: "leader@a1b2c3d4"`), every leader
373
+ * (`to: "leader"`), or everyone (`to: "*"`)
374
+ * mail_inbox — read unread mail (unique id + base alias + broadcasts),
375
+ * marking it read so it isn't re-injected next iteration
376
+ *
377
+ * Both share the identity convention with the agent-loop checker
378
+ * (`<base>@<sessionTag>`, see mailbox-attach) via `resolveMailboxIdentity`.
379
+ *
380
+ * @module mail-tools
381
+ */
382
+
383
+ interface MailToolsOptions {
384
+ /** How to obtain a Mailbox given the execution Context (tests). */
385
+ resolveMailbox?: MailboxResolver | undefined;
386
+ /** Project dir for the shared mailbox. Prefer wpaths.projectDir. */
387
+ projectDir?: string | undefined;
388
+ /** EventBus for mailbox.agent_registered / heartbeat surface events. */
389
+ events?: EventBus | undefined;
390
+ }
391
+ declare function makeMailSendTool(opts?: MailToolsOptions): Tool;
392
+ declare function makeMailInboxTool(opts?: MailToolsOptions): Tool;
393
+
394
+ /**
395
+ * dep-watcher — File-change → Mailbox bridge for dependency monitoring.
396
+ *
397
+ * Watches dependency manifest files (package.json, go.mod, Cargo.toml, etc.)
398
+ * and when they change (create/update), posts a message to the inter-agent
399
+ * mailbox. A tech-stack analysis agent can then pick up the message and
400
+ * run a full tech-stack validation, feeding results back to the coding LLM.
401
+ *
402
+ * This module is a *config factory*, not a watcher itself. It produces
403
+ * configuration that the file-watcher plugin (`watch_start`) can consume,
404
+ * plus a callback that posts to a Mailbox instance.
405
+ *
406
+ * Usage:
407
+ * const cfg = makeDependencyWatcherConfig({
408
+ * projectRoot: '/path/to/project',
409
+ * mailbox,
410
+ * targetAgent: 'tech-stack-agent',
411
+ * });
412
+ * // cfg.watchPaths → pass to watch_start
413
+ * // cfg.onChange → call on file-watcher:changed events
414
+ *
415
+ * @module dep-watcher
416
+ */
417
+
418
+ /**
419
+ * Files that declare project dependencies. When any of these change
420
+ * (create/update), a mailbox message triggers a tech-stack audit.
421
+ */
422
+ declare const DEPENDENCY_FILE_PATTERNS: ReadonlyArray<string>;
423
+ interface DepWatchEntry {
424
+ /** Relative path from project root that changed. */
425
+ path: string;
426
+ /** Event type from the file watcher: 'change', 'add', 'delete' (rare). */
427
+ event: string;
428
+ /** ISO8601 timestamp of when the change was detected. */
429
+ timestamp: string;
430
+ }
431
+ interface DependencyWatcherConfig {
432
+ /** Paths to pass to `watch_start` — the project-root-relative dependency files. */
433
+ watchPaths: string[];
434
+ /** Callback to invoke when a dependency file changes. Posts to mailbox. */
435
+ onChange: (entry: DepWatchEntry) => Promise<void>;
436
+ /** Debounce window in ms — multiple changes to the same file within this window are collapsed. */
437
+ debounceMs: number;
438
+ /** Cancel all in-flight debounce timers. Call when the file watcher is
439
+ * stopped (session end / project switch) so pending setTimeouts — each
440
+ * holding a closure over the mailbox + entry — don't leak. */
441
+ dispose: () => void;
442
+ }
443
+ interface DependencyWatcherOptions {
444
+ /** Absolute path to the project root. */
445
+ projectRoot: string;
446
+ /** The mailbox instance where messages will be posted. */
447
+ mailbox: Mailbox;
448
+ /** Agent id that should receive the tech-stack audit task. */
449
+ targetAgent?: string | undefined;
450
+ /** Agent id of the watcher (sender). */
451
+ watcherAgentId?: string | undefined;
452
+ /** Debounce window in ms. Default: 3000 (3 seconds). */
453
+ debounceMs?: number | undefined;
454
+ /** Only watch these specific patterns. Defaults to DEPENDENCY_FILE_PATTERNS. */
455
+ patterns?: string[] | undefined;
456
+ }
457
+ /**
458
+ * Build a dependency watcher configuration. The returned `watchPaths` can be
459
+ * passed directly to the `watch_start` tool, and `onChange` should be wired
460
+ * to the `file-watcher:changed` custom event.
461
+ *
462
+ * When a dependency file changes, `onChange` posts a high-priority `assign`
463
+ * message to the mailbox targeting the tech-stack agent, with the changed
464
+ * file path and event type in the body.
465
+ */
466
+ declare function makeDependencyWatcherConfig(opts: DependencyWatcherOptions): DependencyWatcherConfig;
467
+
468
+ /**
469
+ * dep-watcher-bridge — Bridges the file-watcher plugin's custom events
470
+ * to the dependency watcher → mailbox pipeline.
471
+ *
472
+ * The file-watcher plugin emits `file-watcher:changed` custom events
473
+ * when files change. This module subscribes to those events, filters
474
+ * for dependency manifests (package.json, go.mod, etc.), and posts
475
+ * assign messages to the inter-agent mailbox for tech-stack audit.
476
+ *
477
+ * Returns a dispose function that unsubscribes from the event bus.
478
+ *
479
+ * @module dep-watcher-bridge
480
+ */
481
+
482
+ interface DepWatcherBridgeOptions {
483
+ /** The event bus to subscribe to (same bus the file-watcher plugin emits on). */
484
+ events: EventBus;
485
+ /** The mailbox instance where dep-change notifications will be posted. */
486
+ mailbox: Mailbox;
487
+ /** Absolute project root — used to build watch paths and match file patterns. */
488
+ projectRoot: string;
489
+ /** Agent id the tech-stack audit tasks should target. Default: 'tech-stack'. */
490
+ targetAgent?: string | undefined;
491
+ /** Agent id of the watcher/sender. Default: 'dep-watcher'. */
492
+ watcherAgentId?: string | undefined;
493
+ /** Debounce window in ms. Default: 3000 (3 seconds). */
494
+ debounceMs?: number | undefined;
495
+ }
496
+ /**
497
+ * Wire the file-watcher's `file-watcher:changed` events into the
498
+ * dependency watcher → mailbox pipeline.
499
+ *
500
+ * Returns a dispose function. Call it to unsubscribe when the
501
+ * session ends or the watcher is no longer needed.
502
+ *
503
+ * Usage:
504
+ * const dispose = attachDepWatcherBridge({
505
+ * events: ctx.events,
506
+ * mailbox: new DefaultMailbox(sessionDir),
507
+ * projectRoot: ctx.projectRoot,
508
+ * });
509
+ * // ... session runs ...
510
+ * dispose(); // clean up on exit
511
+ */
512
+ declare function attachDepWatcherBridge(opts: DepWatcherBridgeOptions): () => void;
513
+
47
514
  /**
48
515
  * mailbox-hooks — Tool-execution hooks for mailbox integration.
49
516
  *
@@ -99,4 +566,1259 @@ declare function createMailboxHooks(opts: MailboxHooksOptions): {
99
566
  reset(): void;
100
567
  };
101
568
 
102
- export { AgentDefinition, BUILD_AGENTS, DELIVERY_AGENTS, DISCOVERY_AGENTS, DOMAIN_AGENTS, KNOWLEDGE_AGENTS, META_AGENTS, Mailbox, type MailboxHooksOptions, PLANNING_AGENTS, REVIEW_AGENTS, VERIFY_AGENTS, createMailboxHooks };
569
+ /**
570
+ * package-author-tracker — Tracks which agent added which package to which manifest.
571
+ *
572
+ * Stores a per-project JSON log in the global project directory:
573
+ * ~/.wrongstack/projects/<slug-hash>/package-authors.json
574
+ *
575
+ * Each entry records: manifest path, package name, version range at time of add,
576
+ * agent id/name, timestamp, and session id.
577
+ *
578
+ * Used by the tech-stack agent and outdated-watcher to route outdated-package
579
+ * notifications back to the agent that originally added the package.
580
+ *
581
+ * @module package-author-tracker
582
+ */
583
+ interface PackageAuthorEntry {
584
+ /** Absolute or relative path to the manifest (package.json, go.mod, etc.). */
585
+ manifestPath: string;
586
+ /** Exact package name as it appears in the manifest. */
587
+ packageName: string;
588
+ /** Version specifier at time of install (e.g. "^1.2.0", "latest", "file:..."). */
589
+ versionSpec: string;
590
+ /** Ecosystem: 'npm', 'cargo', 'go', 'pip', 'gem', 'composer', 'nuget', etc. */
591
+ ecosystem: string;
592
+ /** Agent id that performed the install (e.g. 'leader', 'executor', 'tech-stack'). */
593
+ agentId: string;
594
+ /** Human-readable agent name. */
595
+ agentName?: string | undefined;
596
+ /** Session that performed the install. */
597
+ sessionId?: string | undefined;
598
+ /** ISO8601 timestamp. */
599
+ timestamp: string;
600
+ /** Whether this package is currently flagged as outdated. */
601
+ outdated?: boolean | undefined;
602
+ /** Latest version available (set by outdated checker). */
603
+ latestVersion?: string | undefined;
604
+ }
605
+ interface PackageAuthorLog {
606
+ /** Project root this log belongs to. */
607
+ projectRoot: string;
608
+ /** All entries, newest last. */
609
+ entries: PackageAuthorEntry[];
610
+ /** Last time the log was compacted. */
611
+ lastCompactedAt?: string | undefined;
612
+ }
613
+ interface PackageAuthorTrackerOptions {
614
+ /** Directory where the JSON log is stored. Usually the global project dir. */
615
+ storageDir: string;
616
+ /** Project root for reference. */
617
+ projectRoot: string;
618
+ /** Max entries before auto-compaction. Default: 10000. */
619
+ maxEntries?: number | undefined;
620
+ }
621
+ /**
622
+ * Detect the ecosystem from a manifest filename.
623
+ */
624
+ declare function detectEcosystem(manifestPath: string): string;
625
+ /**
626
+ * Record that an agent added (or updated) a package to a manifest file.
627
+ *
628
+ * If the same (manifestPath, packageName) entry already exists, the previous
629
+ * entry is kept (for audit trail) and a new entry is appended.
630
+ */
631
+ declare function recordPackageAction(opts: PackageAuthorTrackerOptions, entry: Omit<PackageAuthorEntry, 'timestamp'>): Promise<void>;
632
+ /**
633
+ * Get the most recent author entry for a given (manifest, package) pair.
634
+ * Returns undefined if no entry exists.
635
+ */
636
+ declare function getPackageAuthor(opts: Pick<PackageAuthorTrackerOptions, 'storageDir' | 'projectRoot'>, manifestPath: string, packageName: string): Promise<PackageAuthorEntry | undefined>;
637
+ /**
638
+ * Get all packages in a manifest that have an author on record.
639
+ */
640
+ declare function getManifestPackages(opts: Pick<PackageAuthorTrackerOptions, 'storageDir' | 'projectRoot'>, manifestPath: string): Promise<PackageAuthorEntry[]>;
641
+ /**
642
+ * Get all packages last tracked by a specific agent.
643
+ * Returns a Map from (manifestPath, packageName) → entry.
644
+ */
645
+ declare function getPackagesByAgent(opts: Pick<PackageAuthorTrackerOptions, 'storageDir' | 'projectRoot'>, agentId: string): Promise<Map<string, PackageAuthorEntry>>;
646
+ /**
647
+ * Update the outdated status of a package entry (adds or replaces the entry
648
+ * for the given manifest+package, appending to the log for audit).
649
+ */
650
+ declare function updatePackageOutdatedStatus(opts: PackageAuthorTrackerOptions, manifestPath: string, packageName: string, outdated: boolean, latestVersion?: string | undefined): Promise<void>;
651
+ /**
652
+ * Return the full log (for debugging/auditing).
653
+ */
654
+ declare function getFullPackageLog(opts: Pick<PackageAuthorTrackerOptions, 'storageDir' | 'projectRoot'>): Promise<PackageAuthorLog>;
655
+
656
+ /**
657
+ * package-outdated-watcher — Periodically checks installed packages for outdated
658
+ * versions and notifies the agent that originally added each package.
659
+ *
660
+ * Architecture:
661
+ * 1. Polls the mailbox for `assign` messages from the tech-stack agent
662
+ * containing outdated package results.
663
+ * 2. For each outdated package, looks up the original author via
664
+ * `package-author-tracker`.
665
+ * 3. Sends a high-priority `note` message to the original author (or
666
+ * broadcasts to `*` if the author is unknown or no longer online).
667
+ *
668
+ * The watcher can also be triggered directly via `checkOutdated` for
669
+ * on-demand checks (e.g. on a timer, or when the user requests it).
670
+ *
671
+ * Usage:
672
+ * const dispose = startPackageOutdatedWatcher({
673
+ * mailbox,
674
+ * storageDir: wpaths.globalDir,
675
+ * projectRoot,
676
+ * pollIntervalMs: 60 * 60 * 1000, // 1 hour
677
+ * onNotify: async (msg) => mailbox.send(msg),
678
+ * onLog: (m) => console.log(`[pkg-outdated-watcher] ${m}`),
679
+ * });
680
+ *
681
+ * @module package-outdated-watcher
682
+ */
683
+
684
+ interface PackageOutdatedEntry {
685
+ /** Package name. */
686
+ name: string;
687
+ /** Currently installed version. */
688
+ currentVersion: string;
689
+ /** Latest stable version available. */
690
+ latestVersion: string;
691
+ /** semver major.minor.patch wanted range (from lockfile). */
692
+ wantedVersion: string;
693
+ /** Manifest file this package belongs to. */
694
+ manifestPath: string;
695
+ /** Ecosystem: 'npm', 'cargo', 'go', etc. */
696
+ ecosystem: string;
697
+ }
698
+ interface PackageOutdatedResult {
699
+ /** All outdated entries. */
700
+ outdated: PackageOutdatedEntry[];
701
+ /** Packages that are up-to-date. */
702
+ upToDate: string[];
703
+ /** Whether the check failed. */
704
+ checkFailed: boolean;
705
+ }
706
+ interface PackageOutdatedWatcherOptions {
707
+ /** The mailbox for sending notifications and receiving tech-stack results. */
708
+ mailbox: Mailbox;
709
+ /** Package-author-tracker options. */
710
+ packageTrackerOpts: Pick<PackageAuthorTrackerOptions, 'storageDir' | 'projectRoot'>;
711
+ /** Polling interval in ms. Default: 60 * 60 * 1000 (1 hour). */
712
+ pollIntervalMs?: number | undefined;
713
+ /** Agent id that runs this watcher. Default: 'pkg-outdated-watcher'. */
714
+ watcherAgentId?: string | undefined;
715
+ /** Agent id of the tech-stack agent to watch for results. Default: 'tech-stack'. */
716
+ techStackAgentId?: string | undefined;
717
+ /** Called to send a notification to an agent. */
718
+ onNotify: (msg: OutdatedNotifyMessage) => Promise<void>;
719
+ /** Called for log output. */
720
+ onLog?: ((msg: string) => void) | undefined;
721
+ /** Called on errors. */
722
+ onError?: ((err: unknown) => void) | undefined;
723
+ }
724
+ interface OutdatedNotifyMessage {
725
+ from: string;
726
+ to: string;
727
+ subject: string;
728
+ body: string;
729
+ priority: 'high' | 'normal' | 'low';
730
+ }
731
+ /**
732
+ * Start the package outdated watcher.
733
+ *
734
+ * Returns a dispose function that stops polling and cleans up.
735
+ */
736
+ declare function startPackageOutdatedWatcher(opts: PackageOutdatedWatcherOptions): () => void;
737
+
738
+ type NodeType = 'fact' | 'goal' | 'decision' | 'change' | 'vote';
739
+ type FactCategory = 'bug' | 'refactor' | 'security' | 'test' | 'perf' | 'deps' | 'architecture' | 'quality';
740
+ type GoalStatus = 'pending' | 'in_progress' | 'blocked' | 'done' | 'failed';
741
+ type GoalPriority = 'critical' | 'high' | 'medium' | 'low';
742
+ type ChangeStatus = 'proposed' | 'approved' | 'rejected' | 'applied' | 'rolled_back';
743
+ type VoteValue = 'approve' | 'reject' | 'abstain';
744
+ type DecisionType = 'spawn' | 'assign' | 'approve_change' | 'reject_change' | 'escalate' | 'rollback' | 'merge_results';
745
+ interface FactNode {
746
+ id: string;
747
+ type: 'fact';
748
+ category: FactCategory;
749
+ subject: string;
750
+ detail: string;
751
+ file?: string;
752
+ line?: number;
753
+ severity?: 'critical' | 'high' | 'medium' | 'low';
754
+ discoveredBy: string;
755
+ discoveredAt: string;
756
+ tags: string[];
757
+ /** Stable key — dedup facts about the same subject */
758
+ key: string;
759
+ /** References to other nodes this fact relates to */
760
+ related: string[];
761
+ }
762
+ interface GoalNode {
763
+ id: string;
764
+ type: 'goal';
765
+ title: string;
766
+ description: string;
767
+ status: GoalStatus;
768
+ priority: GoalPriority;
769
+ assignee?: string;
770
+ blockedBy: string[];
771
+ dependsOn: string[];
772
+ createdBy: string;
773
+ createdAt: string;
774
+ updatedAt: string;
775
+ tags: string[];
776
+ /** Sub-goals spawned from this goal */
777
+ children: string[];
778
+ /** The top-level goal this belongs to (for hierarchy) */
779
+ parentGoal?: string;
780
+ result?: string;
781
+ }
782
+ interface DecisionNode {
783
+ id: string;
784
+ type: 'decision';
785
+ decisionType: DecisionType;
786
+ question: string;
787
+ options: {
788
+ id: string;
789
+ label: string;
790
+ risk?: string;
791
+ }[];
792
+ chosen: string;
793
+ rationale: string;
794
+ madeBy: string;
795
+ madeAt: string;
796
+ context?: string;
797
+ }
798
+ interface ChangeNode {
799
+ id: string;
800
+ type: 'change';
801
+ title: string;
802
+ description: string;
803
+ files: {
804
+ path: string;
805
+ action: 'create' | 'modify' | 'delete';
806
+ }[];
807
+ status: ChangeStatus;
808
+ proposedBy: string;
809
+ proposedAt: string;
810
+ approvedBy: string[];
811
+ rejectedBy: string[];
812
+ appliedAt?: string;
813
+ rolledBackAt?: string;
814
+ rollbackReason?: string;
815
+ votes: VoteRecord[];
816
+ qualityGate: QualityGateResult;
817
+ /** Goals satisfied by this change */
818
+ satisfiesGoals: string[];
819
+ }
820
+ interface VoteRecord {
821
+ agentId: string;
822
+ agentName: string;
823
+ value: VoteValue;
824
+ rationale?: string | undefined;
825
+ votedAt: string;
826
+ }
827
+ interface QualityGateResult {
828
+ passed: boolean;
829
+ checks: QualityCheck[];
830
+ }
831
+ interface QualityCheck {
832
+ name: string;
833
+ passed: boolean;
834
+ detail?: string;
835
+ }
836
+ interface VoteNode {
837
+ id: string;
838
+ type: 'vote';
839
+ changeId: string;
840
+ voterId: string;
841
+ voterName: string;
842
+ value: VoteValue;
843
+ rationale?: string;
844
+ votedAt: string;
845
+ }
846
+ type GraphNode = FactNode | GoalNode | DecisionNode | ChangeNode | VoteNode;
847
+ interface GraphSubscription {
848
+ id: string;
849
+ agentId: string;
850
+ /** JSONPath-like filter */
851
+ filter: NodeFilter;
852
+ /** Channel for this specific subscription */
853
+ channel: string;
854
+ }
855
+ interface NodeFilter {
856
+ type?: NodeType;
857
+ category?: FactCategory;
858
+ status?: GoalStatus | ChangeStatus;
859
+ tags?: string[];
860
+ assignee?: string;
861
+ discoveredBy?: string;
862
+ proposedBy?: string;
863
+ /** Only nodes added after this timestamp */
864
+ since?: string;
865
+ }
866
+ declare class KnowledgeGraph {
867
+ private readonly nodes;
868
+ private readonly index;
869
+ private readonly subs;
870
+ private readonly pendingDeliveries;
871
+ private readonly filePath;
872
+ private readonly graphFilePath;
873
+ /** Exposed for unit-testing only: read current index contents. */
874
+ getIndex(): ReadonlyMap<string, ReadonlySet<string>>;
875
+ constructor(sessionDir: string);
876
+ /**
877
+ * Add a node. Fires to all matching subscriptions synchronously.
878
+ * Returns the node with its assigned id.
879
+ */
880
+ add(node: Omit<GraphNode, 'id'>): Promise<GraphNode>;
881
+ /** Update an existing node by id. Returns updated node or null if not found. */
882
+ update(id: string, patch: Partial<GraphNode>): Promise<GraphNode | null>;
883
+ get(id: string): GraphNode | undefined;
884
+ getAll(filter?: NodeFilter): GraphNode[];
885
+ getGoals(filter?: Partial<{
886
+ status: GoalStatus;
887
+ assignee: string;
888
+ priority: GoalPriority;
889
+ }>): GoalNode[];
890
+ getFacts(filter?: Partial<{
891
+ category: FactCategory;
892
+ severity: string;
893
+ }>): FactNode[];
894
+ getChanges(filter?: Partial<{
895
+ status: ChangeStatus;
896
+ }>): ChangeNode[];
897
+ getOpenGoals(): GoalNode[];
898
+ getTopLevelGoals(): GoalNode[];
899
+ getBlockedGoals(): GoalNode[];
900
+ getPendingChanges(): ChangeNode[];
901
+ getDecisions(since?: string): DecisionNode[];
902
+ searchFacts(query: string): FactNode[];
903
+ getRelatedFacts(factId: string): FactNode[];
904
+ /**
905
+ * Subscribe to nodes matching a filter. Returns a channel id that can be
906
+ * used to poll for new nodes since the last check.
907
+ */
908
+ subscribe(agentId: string, filter: NodeFilter): string;
909
+ /**
910
+ * Poll for new nodes delivered to a channel since last check.
911
+ * Clears the delivery buffer after reading.
912
+ */
913
+ poll(channel: string): GraphNode[];
914
+ unsubscribe(channel: string): void;
915
+ /**
916
+ * Create a quality gate result. Call this when a change is being proposed
917
+ * so the change node carries the gate result.
918
+ */
919
+ static makeQualityGate(checks: {
920
+ name: string;
921
+ passed: boolean;
922
+ detail?: string;
923
+ }[]): QualityGateResult;
924
+ /** Pure: compute the set of index keys a node would belong to. */
925
+ private _indexKeys;
926
+ /** Mutate the index: add a node's id to every set for the given keys. */
927
+ private _addToIndex;
928
+ /** Remove a node's id from all index sets for the given keys. */
929
+ private _removeFromIndex;
930
+ private _matches;
931
+ private _deliver;
932
+ private _persist;
933
+ private _append;
934
+ /** Rebuild in-memory state from the log file. Call on startup. */
935
+ load(): Promise<void>;
936
+ /** Snapshot for serialization. */
937
+ snapshot(): {
938
+ nodes: GraphNode[];
939
+ subs: number;
940
+ };
941
+ }
942
+
943
+ /**
944
+ * TaskDAG — Directed Acyclic Graph of tasks with fork/join semantics.
945
+ *
946
+ * Replaces the Director's flat `awaitTasks()` with a proper dependency graph.
947
+ * Each task has explicit dependencies; the DAG resolves which tasks are
948
+ * runnable at any moment and manages blocking/unblocking as tasks complete.
949
+ *
950
+ * Key features:
951
+ * - Fork: one parent spawns multiple children that run in parallel
952
+ * - Join: a task can wait for multiple children before continuing
953
+ * - Dynamic: tasks can be added dynamically; the graph re-evaluates runnable set
954
+ * - Cycle detection: inserting a dependency that would create a cycle throws
955
+ * - Priority queue: within a "runnable" set, tasks are ordered by priority
956
+ * - Deadlock detection: if no tasks are runnable and no tasks are complete,
957
+ * the DAG is in deadlock — agents are notified
958
+ *
959
+ * @module task-dag
960
+ */
961
+ /** Represents a node in the DAG. */
962
+ interface DAGNode {
963
+ id: string;
964
+ description: string;
965
+ role?: string;
966
+ priority: number;
967
+ status: DAGNodeStatus;
968
+ deps: string[];
969
+ dependents: string[];
970
+ result?: unknown;
971
+ error?: string;
972
+ spawnedAt?: string;
973
+ completedAt?: string;
974
+ assignedTo?: string;
975
+ tags: string[];
976
+ }
977
+ type DAGNodeStatus = 'pending' | 'ready' | 'running' | 'done' | 'failed' | 'skipped';
978
+ /** Event emitted by the DAG on state changes. */
979
+ type DAGEdgeEvent = {
980
+ type: 'node:ready';
981
+ nodeId: string;
982
+ deps: string[];
983
+ } | {
984
+ type: 'node:started';
985
+ nodeId: string;
986
+ assignedTo: string;
987
+ } | {
988
+ type: 'node:completed';
989
+ nodeId: string;
990
+ result: unknown;
991
+ blockers: string[];
992
+ } | {
993
+ type: 'node:failed';
994
+ nodeId: string;
995
+ error: string;
996
+ blockers: string[];
997
+ } | {
998
+ type: 'node:skipped';
999
+ nodeId: string;
1000
+ reason: string;
1001
+ } | {
1002
+ type: 'deadlock';
1003
+ blocked: string[];
1004
+ } | {
1005
+ type: 'graph:done';
1006
+ allDone: boolean;
1007
+ };
1008
+ type DAGEdgeHandler = (event: DAGEdgeEvent) => void;
1009
+ /** Callback invoked when the DAG produces a set of runnable tasks. */
1010
+ type RunnablesHandler = (nodes: DAGNode[]) => void;
1011
+ declare class TaskDAG {
1012
+ private readonly nodes;
1013
+ private readonly handlers;
1014
+ private readonly runnablesHandlers;
1015
+ private runnableCache;
1016
+ /**
1017
+ * Add a task node. Dependencies are validated for cycles.
1018
+ * Throws if adding a dep would create a cycle.
1019
+ */
1020
+ addNode(id: string, description: string, deps?: string[], opts?: {
1021
+ role?: string;
1022
+ priority?: number;
1023
+ tags?: string[];
1024
+ }): void;
1025
+ /**
1026
+ * Remove a node and all edges to/from it.
1027
+ * Skips any dependents that would become dangling.
1028
+ */
1029
+ removeNode(id: string): void;
1030
+ /**
1031
+ * Mark a task as running. Returns true if the transition was valid
1032
+ * (task was in 'ready' state), false otherwise.
1033
+ */
1034
+ start(id: string, assignedTo: string): boolean;
1035
+ /**
1036
+ * Mark a task as completed. Unblocks all dependents; they become 'ready'
1037
+ * if all their deps are done.
1038
+ */
1039
+ complete(id: string, result: unknown): void;
1040
+ /**
1041
+ * Mark a task as failed. Unblocks dependents but they remain 'pending'
1042
+ * (they may still be runnable if other deps succeeded).
1043
+ */
1044
+ fail(id: string, error: string): void;
1045
+ /**
1046
+ * Skip a task (e.g., it was deemed unnecessary by an earlier step).
1047
+ * Treats it as done for dependency purposes.
1048
+ */
1049
+ skip(id: string, reason: string): void;
1050
+ getNode(id: string): DAGNode | undefined;
1051
+ getAll(): DAGNode[];
1052
+ getReady(): DAGNode[];
1053
+ getRunning(): DAGNode[];
1054
+ getPending(): DAGNode[];
1055
+ getDone(): DAGNode[];
1056
+ getFailed(): DAGNode[];
1057
+ getCompleted(): DAGNode[];
1058
+ isDone(): boolean;
1059
+ isFailed(): boolean;
1060
+ /** All tasks that are currently blocked (pending but not ready). */
1061
+ getBlocked(): DAGNode[];
1062
+ /** Topological sort — tasks in dependency order. */
1063
+ getTopologicalOrder(): DAGNode[];
1064
+ /** Check for deadlock: no runnable tasks but not done. */
1065
+ hasDeadlock(): boolean;
1066
+ /** Stats snapshot for reporting. */
1067
+ stats(): {
1068
+ total: number;
1069
+ pending: number;
1070
+ ready: number;
1071
+ running: number;
1072
+ done: number;
1073
+ failed: number;
1074
+ skipped: number;
1075
+ progress: number;
1076
+ };
1077
+ onEvent(handler: DAGEdgeHandler): () => void;
1078
+ onRunnable(handler: RunnablesHandler): () => void;
1079
+ private _transition;
1080
+ private _emit;
1081
+ private _emitReady;
1082
+ private invalidateCache;
1083
+ /**
1084
+ * DFS cycle detection. Adding edge (id → dep) creates a cycle if
1085
+ * there already exists a path from dep to id.
1086
+ */
1087
+ private _wouldCycle;
1088
+ }
1089
+
1090
+ /**
1091
+ * ConsensusProtocol — agent voting on proposed changes.
1092
+ *
1093
+ * Enables autonomous approval of code changes without a human. Agents register
1094
+ * as voters with a role weight; changes gather votes; the protocol resolves
1095
+ * the outcome based on configured quorum rules.
1096
+ *
1097
+ * Voting rules (configurable):
1098
+ * - Quorum: minimum fraction of eligible voters required (default: 0.5)
1099
+ * - Approval threshold: minimum fraction of cast votes that must be approve (default: 0.6)
1100
+ * - Veto roles: roles whose 'reject' vote is fatal regardless of count
1101
+ * - Auto-approve: changes with severity=critical bypass voting if the proposer is trusted
1102
+ *
1103
+ * The protocol is stateless — it reads from the KnowledgeGraph and writes results
1104
+ * back to it. This makes it naturally consistent with the shared knowledge model.
1105
+ *
1106
+ * @module consensus-protocol
1107
+ */
1108
+
1109
+ interface VoterConfig {
1110
+ agentId: string;
1111
+ agentName: string;
1112
+ role: string;
1113
+ /** Weight multiplier for this voter's vote. Default: 1. */
1114
+ weight: number;
1115
+ /** If true, a 'reject' vote from this role is a hard veto. Default: false. */
1116
+ veto?: boolean;
1117
+ /**
1118
+ * @deprecated Not yet implemented. Auto-approve of low-risk changes is planned
1119
+ * but not wired up in the vote resolution logic.
1120
+ */
1121
+ autoApprovesLowRisk?: boolean;
1122
+ }
1123
+ interface QuorumRule {
1124
+ /** Fraction of eligible voters required (0-1). Default: 0.5. */
1125
+ quorumFraction: number;
1126
+ /** Fraction of cast votes that must be approve (0-1). Default: 0.6. */
1127
+ approvalFraction: number;
1128
+ /** Roles whose reject vote is a hard veto regardless of count. */
1129
+ vetoRoles: string[];
1130
+ /** Minimum total weight of approve votes to pass (0-1 of total eligible weight). */
1131
+ approvalWeightFraction?: number | undefined;
1132
+ }
1133
+ interface ConsensusResult {
1134
+ changeId: string;
1135
+ outcome: 'approved' | 'rejected' | 'pending' | 'vetoed' | 'quorum_not_met';
1136
+ votes: VoteRecord[];
1137
+ approveCount: number;
1138
+ rejectCount: number;
1139
+ abstainCount: number;
1140
+ totalWeightApprove: number;
1141
+ totalWeightReject: number;
1142
+ eligibleVoters: string[];
1143
+ quorumMet: boolean;
1144
+ approvalMet: boolean;
1145
+ vetoedBy?: string;
1146
+ rationale: string;
1147
+ }
1148
+ interface ConsensusOptions {
1149
+ rules?: Partial<QuorumRule>;
1150
+ voters: VoterConfig[];
1151
+ graph: KnowledgeGraph;
1152
+ fleet?: FleetBus | undefined;
1153
+ }
1154
+ /**
1155
+ * ConsensusProtocol manages voting on ChangeNodes in the KnowledgeGraph.
1156
+ * It is instantiated once per autonomous session and used to initiate votes,
1157
+ * cast votes, and resolve outcomes.
1158
+ */
1159
+ declare class ConsensusProtocol {
1160
+ private readonly graph;
1161
+ private readonly fleet?;
1162
+ private readonly rules;
1163
+ private readonly voters;
1164
+ constructor(opts: ConsensusOptions);
1165
+ /**
1166
+ * Initiate a vote on a proposed change. Updates the change node's status
1167
+ * to 'proposed' and notifies eligible voters via FleetBus.
1168
+ */
1169
+ initiateVote(changeId: string): void;
1170
+ /**
1171
+ * Cast a vote. Updates the change node in the graph and re-evaluates
1172
+ * consensus. If the vote triggers a resolution, updates the change status.
1173
+ */
1174
+ castVote(changeId: string, voterId: string, value: VoteValue, rationale?: string): ConsensusResult;
1175
+ /**
1176
+ * Resolve the current vote without waiting for all eligible voters.
1177
+ * Useful when a timeout fires or an agent decides to finalize early.
1178
+ */
1179
+ resolveNow(changeId: string): ConsensusResult;
1180
+ /**
1181
+ * Register or update a voter's configuration.
1182
+ */
1183
+ registerVoter(config: VoterConfig): void;
1184
+ /**
1185
+ * Get the current vote status for a change.
1186
+ */
1187
+ getStatus(changeId: string): ConsensusResult | null;
1188
+ private _eligibleVoters;
1189
+ private _resolve;
1190
+ private _toChangeStatus;
1191
+ private _notifyVoters;
1192
+ }
1193
+
1194
+ /**
1195
+ * ChangeManager — autonomous code change lifecycle management.
1196
+ *
1197
+ * Manages the full lifecycle of proposed code changes:
1198
+ * PROPOSE → REVIEW (consensus) → APPLY → VERIFY → (ROLLBACK on failure)
1199
+ *
1200
+ * The manager does NOT write files directly — it publishes change nodes to the
1201
+ * KnowledgeGraph and uses the ConsensusProtocol for approvals. File mutations
1202
+ * are performed by agents acting on approved change nodes.
1203
+ *
1204
+ * Quality gates run automatically before approval:
1205
+ * - Tests must pass (or be explicitly waived)
1206
+ * - TypeScript must compile
1207
+ * - No new critical/high security findings
1208
+ * - Lint must pass (or be explicitly ignored)
1209
+ *
1210
+ * Rollback: on failure detection, the manager can propose a rollback change
1211
+ * that reverses the applied change. Rollback changes also go through consensus.
1212
+ *
1213
+ * @module change-manager
1214
+ */
1215
+
1216
+ interface ChangeFile {
1217
+ path: string;
1218
+ action: 'create' | 'modify' | 'delete';
1219
+ /** For modify: unified diff string */
1220
+ diff?: string;
1221
+ /** For create/modify: full file content */
1222
+ content?: string;
1223
+ }
1224
+ interface ChangeProposal {
1225
+ title: string;
1226
+ description: string;
1227
+ files: ChangeFile[];
1228
+ proposedBy: string;
1229
+ satisfiesGoals: string[];
1230
+ tags: string[];
1231
+ /** Quality gate waivers (e.g., ['no-tests', 'lint-errors']) */
1232
+ waivers?: string[];
1233
+ /** Skip consensus vote (for automated/internal refactors only) */
1234
+ skipVote?: boolean;
1235
+ }
1236
+ interface ApplyResult {
1237
+ changeId: string;
1238
+ success: boolean;
1239
+ appliedAt: string;
1240
+ filesTouched: string[];
1241
+ verificationResult?: QualityGateResult;
1242
+ rollbackChangeId?: string | undefined;
1243
+ error?: string | undefined;
1244
+ }
1245
+ interface RollbackResult {
1246
+ originalChangeId: string;
1247
+ rollbackChangeId: string;
1248
+ success: boolean;
1249
+ rolledBackAt: string;
1250
+ error?: string;
1251
+ }
1252
+ /** Quality checks performed before applying a change. */
1253
+ interface QualityGateChecks {
1254
+ runTests: boolean;
1255
+ runTypecheck: boolean;
1256
+ runLint: boolean;
1257
+ runSecurityScan: boolean;
1258
+ checkTestCoverage: boolean;
1259
+ minCoveragePercent?: number;
1260
+ }
1261
+ interface ChangeManagerOptions {
1262
+ graph: KnowledgeGraph;
1263
+ consensus: ConsensusProtocol;
1264
+ fleet?: FleetBus | undefined;
1265
+ checks?: Partial<QualityGateChecks> | undefined;
1266
+ }
1267
+ /**
1268
+ * Default quality gate: tests + typecheck + security scan.
1269
+ * Lint and coverage are informational warnings, not blockers.
1270
+ */
1271
+ declare const DEFAULT_QUALITY_CHECKS: QualityGateChecks;
1272
+ /**
1273
+ * ChangeManager orchestrates the full change lifecycle.
1274
+ *
1275
+ * ## Workflow
1276
+ * ```
1277
+ * propose() → knowledge graph (proposed)
1278
+ * → consensus.vote() (approved/rejected)
1279
+ * → apply() → knowledge graph (applied)
1280
+ * → verify() → on failure: proposeRollback()
1281
+ * ```
1282
+ */
1283
+ declare class ChangeManager {
1284
+ private readonly graph;
1285
+ private readonly consensus;
1286
+ private readonly fleet?;
1287
+ private readonly checks;
1288
+ /** Track applied changes for rollback lookup. */
1289
+ private readonly appliedChanges;
1290
+ constructor(opts: ChangeManagerOptions);
1291
+ /**
1292
+ * Propose a new code change. Creates a ChangeNode in the knowledge graph.
1293
+ * Does NOT automatically initiate voting — call `submitForReview()` for that.
1294
+ */
1295
+ propose(input: ChangeProposal): Promise<ChangeNode>;
1296
+ /**
1297
+ * Submit an approved change for application.
1298
+ * Returns the change node — actual file mutations are performed by agents
1299
+ * acting on this node's data from the knowledge graph.
1300
+ */
1301
+ submitForReview(changeId: string): Promise<void>;
1302
+ /**
1303
+ * Apply an approved change. Updates the change node to 'applied'.
1304
+ * Agents should watch for 'applied' status and perform the actual file mutations.
1305
+ */
1306
+ markApplied(changeId: string, appliedAt: string): Promise<ChangeNode | null>;
1307
+ /**
1308
+ * Mark a change as applied and trigger rollback for any satisfied goal
1309
+ * that turns out to be broken.
1310
+ */
1311
+ markAppliedWithVerification(changeId: string, verify: () => Promise<QualityGateResult>): Promise<ApplyResult>;
1312
+ /**
1313
+ * Propose a rollback for an applied change. Creates a new change that
1314
+ * reverses the original. Goes through full consensus.
1315
+ */
1316
+ proposeRollback(appliedChangeId: string, reason: string): Promise<ChangeNode | null>;
1317
+ /**
1318
+ * Mark a change as rolled back.
1319
+ */
1320
+ markRolledBack(changeId: string, rolledBackAt: string): Promise<ChangeNode | null>;
1321
+ getPendingReviews(): ChangeNode[];
1322
+ getAppliedChanges(): ChangeNode[];
1323
+ getChange(id: string): ChangeNode | undefined;
1324
+ getChangesForGoal(goalId: string): ChangeNode[];
1325
+ /**
1326
+ * Run quality gate checks. This is informational — actual test/lint/typecheck
1327
+ * execution is done by agents spawned for this purpose. This method stores
1328
+ * the result in the change node.
1329
+ */
1330
+ private _runQualityGate;
1331
+ /**
1332
+ * Update quality gate result for a change. Called by verify agents
1333
+ * after running their checks.
1334
+ */
1335
+ updateQualityGate(changeId: string, checkName: string, result: {
1336
+ passed: boolean;
1337
+ detail?: string;
1338
+ }): Promise<void>;
1339
+ private _emit;
1340
+ }
1341
+
1342
+ type AutonomousDecisionType = 'spawn' | 'approve_change' | 'reject_change' | 'prioritize_goals' | 'escalate_task' | 'rollback_change' | 'retry_task' | 'merge_results' | 'decompose_goal' | 'assign_task';
1343
+ interface AutonomousDecisionRequest {
1344
+ id: string;
1345
+ source: BrainDecisionSource;
1346
+ decisionType: AutonomousDecisionType;
1347
+ question: string;
1348
+ context: {
1349
+ /** Relevant facts from the knowledge graph */
1350
+ facts?: FactNode[];
1351
+ /** Goals relevant to this decision */
1352
+ goals?: GoalNode[];
1353
+ /** Change being reviewed (for approval decisions) */
1354
+ change?: ChangeNode;
1355
+ /** Current fleet status */
1356
+ fleetStatus?: {
1357
+ running: number;
1358
+ idle: number;
1359
+ total: number;
1360
+ costSoFar: number;
1361
+ };
1362
+ /** Task that triggered this decision */
1363
+ taskDescription?: string;
1364
+ /** Error that triggered escalation, if any */
1365
+ error?: string;
1366
+ /** Number of times this task has been attempted */
1367
+ attempts?: number;
1368
+ };
1369
+ options: BrainDecisionOption[];
1370
+ risk: BrainRisk;
1371
+ /** Whether this decision requires consensus */
1372
+ requiresConsensus: boolean;
1373
+ }
1374
+ interface SpawnDecision {
1375
+ role: string;
1376
+ budget: {
1377
+ timeoutMs?: number;
1378
+ maxIterations?: number;
1379
+ maxToolCalls?: number;
1380
+ maxCostUsd?: number;
1381
+ };
1382
+ rationale: string;
1383
+ }
1384
+ interface ApprovalDecision {
1385
+ approved: boolean;
1386
+ rationale: string;
1387
+ waivers?: string[];
1388
+ conditions?: string[];
1389
+ }
1390
+ interface PrioritizationDecision {
1391
+ orderedGoals: string[];
1392
+ rationale: string;
1393
+ }
1394
+ interface EscalationDecision {
1395
+ action: 'retry' | 'delegate' | 'mark_failed' | 'ask_for_help';
1396
+ rationale: string;
1397
+ budgetAdjustment?: {
1398
+ increaseFactor?: number;
1399
+ newTimeoutMs?: number;
1400
+ addModel?: string;
1401
+ };
1402
+ }
1403
+ interface AutonomousBrainOptions {
1404
+ /** The LLM provider for making decisions */
1405
+ llmProvider: LLMProvider;
1406
+ graph: KnowledgeGraph;
1407
+ fleet?: FleetBus | undefined;
1408
+ /** Maximum retries before a task is marked failed. Default: 3. */
1409
+ maxRetries?: number | undefined;
1410
+ /** Risk threshold above which consensus is required. Default: 'high'. */
1411
+ consensusRiskThreshold?: BrainRisk | undefined;
1412
+ /** Self-improve: track decision history for learning. Default: true. */
1413
+ selfImprove?: boolean | undefined;
1414
+ }
1415
+ interface LLMProvider {
1416
+ /**
1417
+ * Generate a decision. Receives the full context as a structured prompt.
1418
+ * Returns the chosen option id and rationale.
1419
+ */
1420
+ decide(prompt: DecisionPrompt): Promise<{
1421
+ optionId: string;
1422
+ rationale: string;
1423
+ }>;
1424
+ }
1425
+ interface DecisionPrompt {
1426
+ decisionType: AutonomousDecisionType;
1427
+ question: string;
1428
+ context: string;
1429
+ options: BrainDecisionOption[];
1430
+ risk: BrainRisk;
1431
+ decisionHistory: DecisionNode[];
1432
+ /** Hints derived from self-improvement data */
1433
+ selfImproveHints?: string[];
1434
+ }
1435
+ declare class AutonomousBrain implements BrainArbiter {
1436
+ private readonly graph;
1437
+ private readonly fleetBus?;
1438
+ private readonly llmProvider;
1439
+ private readonly maxRetries;
1440
+ private readonly consensusRiskThreshold;
1441
+ private readonly selfImprove;
1442
+ /** Decision history for self-improvement and audit. */
1443
+ private decisionHistory;
1444
+ /** Tracks failure patterns for self-improvement. */
1445
+ private failurePatterns;
1446
+ private readonly RISK_ORDER;
1447
+ private _emit;
1448
+ constructor(opts: AutonomousBrainOptions);
1449
+ /** Implements BrainArbiter — bridges standard brain.ts interface to autonomous engine. */
1450
+ decide(request: BrainDecisionRequest): Promise<BrainDecision>;
1451
+ /**
1452
+ * Primary autonomous decision engine — receives AutonomousDecisionRequest,
1453
+ * queries the LLM, records the decision, and returns a BrainDecision.
1454
+ *
1455
+ * Specialized methods (decideSpawn, decideApproval, etc.) should call this
1456
+ * directly with a pre-built AutonomousDecisionRequest.
1457
+ */
1458
+ decideAuto(request: AutonomousDecisionRequest): Promise<BrainDecision>;
1459
+ /**
1460
+ * Decide whether to spawn a subagent, which role to use, and what budget.
1461
+ */
1462
+ decideSpawn(source: BrainDecisionSource, taskDescription: string, availableFacts: FactNode[], fleetStatus: {
1463
+ running: number;
1464
+ idle: number;
1465
+ total: number;
1466
+ costSoFar: number;
1467
+ }): Promise<BrainDecision>;
1468
+ /**
1469
+ * Decide whether to approve a proposed change.
1470
+ */
1471
+ decideApproval(source: BrainDecisionSource, change: ChangeNode, relevantFacts: FactNode[]): Promise<BrainDecision>;
1472
+ /**
1473
+ * Decide how to handle a failed task.
1474
+ */
1475
+ decideEscalation(source: BrainDecisionSource, taskId: string, error: string, attempts: number): Promise<BrainDecision>;
1476
+ /**
1477
+ * Record the outcome of a decision for self-improvement.
1478
+ * Call this after a spawned agent completes or a change is applied.
1479
+ */
1480
+ recordOutcome(decisionId: string, outcome: 'success' | 'failure', _detail?: string): void;
1481
+ private _getSelfImproveHints;
1482
+ private _toAutonomous;
1483
+ private _inferDecisionType;
1484
+ private _serializeContext;
1485
+ private _loadHistory;
1486
+ private _recordDecision;
1487
+ private _inferRoles;
1488
+ private _changeRisk;
1489
+ }
1490
+
1491
+ interface TaskBid {
1492
+ id: string;
1493
+ taskId: string;
1494
+ agentId: string;
1495
+ agentName: string;
1496
+ agentRole: string;
1497
+ /** Dispatcher score for this task */
1498
+ score: number;
1499
+ /** Why this agent is a good fit */
1500
+ rationale: string;
1501
+ submittedAt: string;
1502
+ }
1503
+ interface TaskAuctionOptions {
1504
+ graph: KnowledgeGraph;
1505
+ fleet?: FleetBus | undefined;
1506
+ mailbox?: Mailbox | undefined;
1507
+ selfAgentId?: string | undefined;
1508
+ /** How long a bid window stays open before auto-awarding. Default: 30s */
1509
+ bidWindowMs?: number | undefined;
1510
+ /** Maximum concurrent tasks per agent. Default: 3 */
1511
+ maxTasksPerAgent?: number | undefined;
1512
+ /** Minimum confidence threshold for dispatcher scoring. Default: 0.3 */
1513
+ minConfidence?: number | undefined;
1514
+ /**
1515
+ * Maximum times a task can be republished when no bids are received.
1516
+ * After this, the task is marked as 'failed' with reason 'no_bids'.
1517
+ * Default: 3.
1518
+ */
1519
+ maxBidRetries?: number | undefined;
1520
+ }
1521
+ declare class TaskAuctioneer {
1522
+ private readonly graph;
1523
+ private readonly fleet?;
1524
+ private readonly mailbox?;
1525
+ private readonly selfAgentId;
1526
+ private readonly bidWindowMs;
1527
+ private readonly maxTasksPerAgent;
1528
+ private readonly minConfidence;
1529
+ private readonly maxBidRetries;
1530
+ /** Pending bids keyed by taskId. */
1531
+ private readonly pendingBids;
1532
+ /** Active bid windows keyed by taskId. */
1533
+ private readonly bidTimers;
1534
+ /** FleetBus subscription disposers, detached in dispose(). */
1535
+ private readonly unsubs;
1536
+ /** How many times a task has been republished with no bids received. */
1537
+ private readonly bidRetryCounts;
1538
+ /** Agent → current task count (from graph + in-flight). */
1539
+ private readonly agentTaskCounts;
1540
+ constructor(opts: TaskAuctionOptions);
1541
+ /**
1542
+ * Detach all FleetBus subscriptions and cancel any open bid-window timers.
1543
+ * Call when the owning coordinator stops/restarts so handlers and timers
1544
+ * don't accumulate across cycles.
1545
+ */
1546
+ dispose(): void;
1547
+ /**
1548
+ * Publish a new task to the auction. Creates a GoalNode and broadcasts
1549
+ * it to all online agents. Returns the goal id.
1550
+ *
1551
+ * If `targetAgent` is specified, the task is assigned directly without auction.
1552
+ */
1553
+ publishTask(input: {
1554
+ title: string;
1555
+ description: string;
1556
+ priority?: GoalPriority;
1557
+ tags?: string[];
1558
+ targetAgent?: string;
1559
+ parentGoal?: string;
1560
+ satisfiesGoals?: string[];
1561
+ /** Goal ids that must reach 'done' before this goal becomes workable. */
1562
+ blockedBy?: string[];
1563
+ deadline?: string;
1564
+ reward?: string;
1565
+ }): Promise<string>;
1566
+ /**
1567
+ * Submit a bid for a task. Called by agents who want to work on it.
1568
+ * Returns true if the bid was accepted, false if the task was already claimed.
1569
+ */
1570
+ bid(taskId: string, agent: {
1571
+ agentId: string;
1572
+ agentName: string;
1573
+ agentRole: string;
1574
+ }, rationale: string): Promise<boolean>;
1575
+ /**
1576
+ * Award a task to a specific agent. Called internally by the bid window
1577
+ * expiry, or can be called directly to force an award.
1578
+ */
1579
+ claim(taskId: string, agentId: string, agentName: string): Promise<boolean>;
1580
+ /**
1581
+ * Mark a task as done. Called by the agent when it finishes.
1582
+ */
1583
+ complete(taskId: string, _result?: string): Promise<void>;
1584
+ /**
1585
+ * Mark a task as failed. Optionally spawn a retry.
1586
+ */
1587
+ fail(taskId: string, error: string): Promise<void>;
1588
+ /**
1589
+ * Find the best available tasks for an agent based on its capabilities.
1590
+ * Returns tasks sorted by match score (best first).
1591
+ */
1592
+ findWork(_agentId: string, agentRole: string, limit?: number): Promise<{
1593
+ task: GoalNode;
1594
+ score: number;
1595
+ bids: number;
1596
+ }[]>;
1597
+ /** Get all pending tasks (available for bidding). */
1598
+ getPendingTasks(): GoalNode[];
1599
+ /** Get tasks assigned to a specific agent. */
1600
+ getTasksForAgent(agentId: string): GoalNode[];
1601
+ /** Get the current bid count for a task. */
1602
+ getBidCount(taskId: string): number;
1603
+ /** Get bids for a task. */
1604
+ getBids(taskId: string): TaskBid[];
1605
+ /** Get task stats for a project-wide dashboard. */
1606
+ getStats(): {
1607
+ total: number;
1608
+ pending: number;
1609
+ in_progress: number;
1610
+ done: number;
1611
+ failed: number;
1612
+ totalBids: number;
1613
+ avgBidsPerTask: number;
1614
+ };
1615
+ private _emit;
1616
+ private _broadcastTask;
1617
+ private _mailboxPublish;
1618
+ private _notifyAgent;
1619
+ private _startBidWindow;
1620
+ private _cancelBidWindow;
1621
+ private _evaluateBids;
1622
+ private _assignDirect;
1623
+ private _onBidEvent;
1624
+ private _onClaimedEvent;
1625
+ private _getAgentTaskCount;
1626
+ private agentTaskCount;
1627
+ }
1628
+
1629
+ /**
1630
+ * CoordinatorEvent — union of all event types emitted by the AutonomousCoordinator.
1631
+ * Consumed by the TUI to drive coordinator panel state and the reducer.
1632
+ */
1633
+ type CoordinatorEvent = {
1634
+ type: 'goal:added';
1635
+ goalId: string;
1636
+ title?: string;
1637
+ text?: string;
1638
+ participants?: string[];
1639
+ } | {
1640
+ type: 'goal:completed';
1641
+ goalId: string;
1642
+ text?: string;
1643
+ participants?: string[];
1644
+ } | {
1645
+ type: 'goal:failed';
1646
+ goalId: string;
1647
+ text?: string;
1648
+ } | {
1649
+ type: 'task:ready';
1650
+ goalId: string;
1651
+ taskId: string;
1652
+ title?: string;
1653
+ assignedTo?: string;
1654
+ text?: string;
1655
+ } | {
1656
+ type: 'task:completed';
1657
+ goalId: string;
1658
+ taskId: string;
1659
+ text?: string;
1660
+ } | {
1661
+ type: 'knowledge:added';
1662
+ knowledgeId: string;
1663
+ title?: string;
1664
+ text?: string;
1665
+ } | {
1666
+ type: 'consensus:reached';
1667
+ goalId: string;
1668
+ text?: string;
1669
+ participants?: string[];
1670
+ } | {
1671
+ type: 'deadlock:detected';
1672
+ goalId: string;
1673
+ text?: string;
1674
+ } | {
1675
+ type: 'coordinator:mode';
1676
+ mode: 'standalone' | 'fleet';
1677
+ };
1678
+
1679
+ interface AutonomousCoordinatorOptions {
1680
+ sessionDir: string;
1681
+ selfAgentId: string;
1682
+ selfAgentName: string;
1683
+ fleet?: FleetBus | undefined;
1684
+ fleetManager?: FleetManager | undefined;
1685
+ director?: Director | undefined;
1686
+ mailbox?: Mailbox | undefined;
1687
+ events?: EventBus | undefined;
1688
+ llmProvider: LLMProvider;
1689
+ /** Disable self-improvement. Default: false. */
1690
+ disableSelfImprove?: boolean;
1691
+ /** Max concurrent subagents. Default: 5. */
1692
+ maxConcurrentAgents?: number;
1693
+ /**
1694
+ * Called with every CoordinatorEvent so the caller (e.g. execution.ts)
1695
+ * can forward it to the TUI coordinator panel timeline.
1696
+ */
1697
+ onCoordinatorEvent?: (event: CoordinatorEvent) => void;
1698
+ }
1699
+ interface RunOptions {
1700
+ /** Top-level goal description. Default: "Improve the codebase". */
1701
+ goal?: string;
1702
+ /** If true, the loop runs until all goals are done (no timeout). Default: false. */
1703
+ runUntilComplete?: boolean;
1704
+ /** Max iterations. Default: 100. */
1705
+ maxIterations?: number;
1706
+ /** Stop if cost exceeds this. Default: no limit. */
1707
+ maxCostUsd?: number;
1708
+ }
1709
+ interface CoordinatorStats {
1710
+ goals: {
1711
+ total: number;
1712
+ done: number;
1713
+ pending: number;
1714
+ failed: number;
1715
+ progress: number;
1716
+ };
1717
+ dag: ReturnType<TaskDAG['stats']>;
1718
+ auction: ReturnType<TaskAuctioneer['getStats']>;
1719
+ changes: {
1720
+ proposed: number;
1721
+ approved: number;
1722
+ applied: number;
1723
+ rejected: number;
1724
+ };
1725
+ decisions: number;
1726
+ costSoFar?: number | undefined;
1727
+ }
1728
+ /**
1729
+ * AutonomousCoordinator — wires all coordination components into one engine.
1730
+ *
1731
+ * ## Quick start
1732
+ *
1733
+ * ```typescript
1734
+ * const coord = new AutonomousCoordinator({
1735
+ * sessionDir: '/tmp/session',
1736
+ * selfAgentId: 'director-1',
1737
+ * selfAgentName: 'Director',
1738
+ * llmProvider: myLLMProvider,
1739
+ * fleet: myFleetBus,
1740
+ * mailbox: myMailbox,
1741
+ * });
1742
+ *
1743
+ * // Run a self-directing session
1744
+ * await coord.run({ goal: 'Audit and fix all security issues in the auth module' });
1745
+ * ```
1746
+ */
1747
+ declare class AutonomousCoordinator {
1748
+ readonly graph: KnowledgeGraph;
1749
+ readonly dag: TaskDAG;
1750
+ readonly auction: TaskAuctioneer;
1751
+ readonly consensus: ConsensusProtocol;
1752
+ readonly changes: ChangeManager;
1753
+ readonly brain: AutonomousBrain;
1754
+ private readonly selfAgentId;
1755
+ private readonly fleet?;
1756
+ private readonly fleetManager?;
1757
+ private readonly director?;
1758
+ private readonly mailbox?;
1759
+ private readonly events?;
1760
+ private readonly onCoordinatorEvent?;
1761
+ private running;
1762
+ private iterationCount;
1763
+ /** Tasks already handled by _onSubagentTerminated (to avoid double goal:failed on fleet event). */
1764
+ private readonly _handledBySubagent;
1765
+ /** FleetBus subscription disposers, detached in dispose(). */
1766
+ private readonly unsubs;
1767
+ constructor(opts: AutonomousCoordinatorOptions);
1768
+ /**
1769
+ * Run the autonomous loop until the goal is satisfied or max iterations reached.
1770
+ * This is the main entry point for a fully autonomous session.
1771
+ */
1772
+ run(opts?: RunOptions): Promise<CoordinatorStats>;
1773
+ /** Stop the autonomous loop. */
1774
+ stop(): void;
1775
+ /**
1776
+ * Tear down the coordinator for good: stop the loop and detach all FleetBus
1777
+ * subscriptions (this coordinator's + the auctioneer's) plus any open bid
1778
+ * timers. Call this when discarding the instance (e.g. `/coordinator stop`
1779
+ * that recreates a fresh coordinator on the next start) so handlers and
1780
+ * timers don't accumulate across cycles. `stop()` only pauses the loop.
1781
+ */
1782
+ dispose(): void;
1783
+ /** Get a stats snapshot. */
1784
+ getStats(): CoordinatorStats;
1785
+ /**
1786
+ * Publish a fact discovered by an agent. Facts are immutable and form
1787
+ * the basis for other agents' decisions.
1788
+ */
1789
+ publishFact(input: {
1790
+ category: FactCategory;
1791
+ subject: string;
1792
+ detail: string;
1793
+ file?: string;
1794
+ line?: number;
1795
+ severity?: 'critical' | 'high' | 'medium' | 'low';
1796
+ tags?: string[];
1797
+ }): Promise<FactNode>;
1798
+ /**
1799
+ * Publish a goal and add it to the DAG.
1800
+ */
1801
+ createGoal(input: {
1802
+ title: string;
1803
+ description: string;
1804
+ priority?: 'critical' | 'high' | 'medium' | 'low';
1805
+ deps?: string[];
1806
+ tags?: string[];
1807
+ }): Promise<GoalNode>;
1808
+ private _decomposeGoal;
1809
+ private _inferCategory;
1810
+ private _processGoal;
1811
+ private _handlePendingChange;
1812
+ private _onDagEvent;
1813
+ private _onSubagentTerminated;
1814
+ private _fleetStatus;
1815
+ private _buildVoters;
1816
+ private _goalToOptions;
1817
+ private _optionToGoal;
1818
+ private _dagPriorityToGoal;
1819
+ private _mailboxBroadcast;
1820
+ /** Emit a CoordinatorEvent to the subscriber (e.g. TUI panel timeline). */
1821
+ private _emit;
1822
+ }
1823
+
1824
+ export { AgentDefinition, AgentHeartbeatInput, AgentRegistrationInput, type ApplyResult, type ApprovalDecision, AutonomousBrain, type AutonomousBrainOptions, AutonomousCoordinator, type AutonomousCoordinatorOptions, type AutonomousDecisionRequest, type AutonomousDecisionType, BUILD_AGENTS, BrainArbiter, BrainDecision, BrainDecisionOption, BrainDecisionRequest, BrainDecisionSource, type BrainInterventionInput, BrainMonitor, type BrainMonitorOptions, BrainRisk, type ChangeFile, ChangeManager, type ChangeManagerOptions, type ChangeNode, type ChangeProposal, type ChangeStatus, type ConsensusOptions, ConsensusProtocol, type ConsensusResult, type CoordinatorEvent, type CoordinatorStats, type DAGEdgeEvent, type DAGEdgeHandler, type DAGNode, type DAGNodeStatus, DEFAULT_QUALITY_CHECKS, DELIVERY_AGENTS, DEPENDENCY_FILE_PATTERNS, DISCOVERY_AGENTS, DOMAIN_AGENTS, type DecisionNode, type DecisionPrompt, DefaultMailbox, type DepWatchEntry, type DepWatcherBridgeOptions, type DependencyWatcherConfig, Director, type EscalationDecision, type FactCategory, type FactNode, FleetBus, FleetManager, GlobalMailbox, type GoalNode, type GoalPriority, type GoalStatus, type GraphSubscription, KNOWLEDGE_AGENTS, KnowledgeGraph, type LLMProvider, META_AGENTS, type MailToolsOptions, Mailbox, MailboxAckInput, MailboxAgentStatus, type MailboxHooksOptions, MailboxMessage, MailboxQuery, type MailboxResolver, MailboxSendInput, type MailboxToolOptions, type NodeFilter, type NodeType, type OutdatedNotifyMessage, PLANNING_AGENTS, type PackageAuthorEntry, type PackageAuthorLog, type PackageAuthorTrackerOptions, type PackageOutdatedEntry, type PackageOutdatedResult, type PackageOutdatedWatcherOptions, type PrioritizationDecision, type QualityCheck, type QualityGateChecks, type QualityGateResult, type QuorumRule, REVIEW_AGENTS, type RollbackResult, type RunOptions, type RunnablesHandler, type SpawnDecision, type TaskAuctionOptions, TaskAuctioneer, type TaskBid, TaskDAG, VERIFY_AGENTS, type VoteNode, type VoteRecord, type VoteValue, type VoterConfig, attachDepWatcherBridge, createMailboxHooks, detectEcosystem, getFullPackageLog, getManifestPackages, getPackageAuthor, getPackagesByAgent, mailboxSessionTag, makeDependencyWatcherConfig, makeMailInboxTool, makeMailSendTool, makeMailboxTool, recordPackageAction, resolveMailboxIdentity, resolveProjectDir, startPackageOutdatedWatcher, updatePackageOutdatedStatus };