@wrongstack/core 0.250.0 → 0.255.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/{agent-bridge-4gc0vfW2.d.ts → agent-bridge-l_DsFEbr.d.ts} +1 -1
- package/dist/{agent-subagent-runner-Dz-9kiE6.d.ts → agent-subagent-runner-DhYLgAJo.d.ts} +3 -3
- package/dist/{brain-sCZ3lCjq.d.ts → brain-BaQsRNka.d.ts} +17 -0
- package/dist/coordination/index.d.ts +10 -10
- package/dist/coordination/index.js +132 -0
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +11 -11
- package/dist/execution/index.d.ts +7 -7
- package/dist/extension/index.d.ts +3 -3
- package/dist/{goal-preamble-BjJpnLW4.d.ts → goal-preamble-BgoPmZ8l.d.ts} +4 -4
- package/dist/{index-Dy8OwfBD.d.ts → index-BilZMsOK.d.ts} +3 -3
- package/dist/{index-IehiNryU.d.ts → index-Csoc_bKs.d.ts} +2 -2
- package/dist/index.d.ts +21 -21
- package/dist/index.js +150 -3
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +2 -2
- package/dist/infrastructure/index.js +12 -0
- package/dist/infrastructure/index.js.map +1 -1
- package/dist/kernel/index.d.ts +4 -4
- package/dist/kernel/index.js.map +1 -1
- package/dist/{multi-agent-coordinator-CnbEqpv0.d.ts → multi-agent-coordinator-Bs-M0Mo6.d.ts} +1 -1
- package/dist/{null-fleet-bus-Do1OLYpj.d.ts → null-fleet-bus-CWdU1_cO.d.ts} +4 -4
- package/dist/observability/index.d.ts +1 -1
- package/dist/{package-outdated-watcher-CA5GGB4C.d.ts → package-outdated-watcher-Dz-eNZlQ.d.ts} +23 -2
- package/dist/{parallel-eternal-engine-UZg1xOzE.d.ts → parallel-eternal-engine-CAMabk-X.d.ts} +4 -4
- package/dist/{path-resolver-BaP06Owy.d.ts → path-resolver-B7VjhUHq.d.ts} +1 -1
- package/dist/{pipeline-D1n-gQI-.d.ts → pipeline-Bxa3wDcy.d.ts} +41 -1
- package/dist/{plan-templates-BUVRY0pU.d.ts → plan-templates-D3guWwTi.d.ts} +1 -1
- package/dist/{provider-runner-D0HgUqwV.d.ts → provider-runner-C8_e4Lo1.d.ts} +1 -1
- package/dist/sdd/index.d.ts +4 -4
- package/dist/storage/index.d.ts +5 -5
- package/dist/types/index.d.ts +10 -10
- package/dist/types/index.js +12 -0
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as BridgeTransport, a as BridgeMessage, A as AgentBridge, b as AgentBridgeConfig } from './agent-subagent-runner-
|
|
1
|
+
import { B as BridgeTransport, a as BridgeMessage, A as AgentBridge, b as AgentBridgeConfig } from './agent-subagent-runner-DhYLgAJo.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* In-memory pub/sub transport for agent-to-agent messaging.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { c as ToolCallPipelinePayload, d as ToolWrapper, E as ExtensionRegistry, S as SystemPromptContributor, e as ToolRegistry, P as ProviderRegistry, A as AgentPipelines, f as ToolExecutorLike, g as AgentInit, h as AgentInput, R as RunResult } from './index-
|
|
2
|
-
import { C as Container, R as ReadonlyPipeline, a as Renderer } from './pipeline-
|
|
3
|
-
import { E as EventBus, a as EventName, L as Listener } from './brain-
|
|
1
|
+
import { c as ToolCallPipelinePayload, d as ToolWrapper, E as ExtensionRegistry, S as SystemPromptContributor, e as ToolRegistry, P as ProviderRegistry, A as AgentPipelines, f as ToolExecutorLike, g as AgentInit, h as AgentInput, R as RunResult } from './index-Csoc_bKs.js';
|
|
2
|
+
import { C as Container, R as ReadonlyPipeline, a as Renderer } from './pipeline-Bxa3wDcy.js';
|
|
3
|
+
import { E as EventBus, a as EventName, L as Listener } from './brain-BaQsRNka.js';
|
|
4
4
|
import { R as RetryPolicy, E as ErrorHandler } from './retry-policy-BVnkbMET.js';
|
|
5
5
|
import { L as Logger } from './logger-B63L5bTg.js';
|
|
6
6
|
import { T as Tracer } from './observability-D-HZN_mF.js';
|
|
@@ -374,6 +374,23 @@ interface EventMap {
|
|
|
374
374
|
used: number;
|
|
375
375
|
limit: number;
|
|
376
376
|
};
|
|
377
|
+
/**
|
|
378
|
+
* Fired by `DefaultTokenCounter` after each call to `account()` /
|
|
379
|
+
* `accountWithModel()` updates its internal state. The payload carries
|
|
380
|
+
* the live snapshot so subscribers (notably the TUI's `StatusBar`) can
|
|
381
|
+
* re-render fresh token/cost/cache data immediately instead of waiting
|
|
382
|
+
* for a slow polling interval. Cost fields may be zero when the model
|
|
383
|
+
* is unknown to the ModelsRegistry — that is already signalled separately
|
|
384
|
+
* by `token.cost_estimate_unavailable`.
|
|
385
|
+
*/
|
|
386
|
+
'token.accounted': {
|
|
387
|
+
usage: Usage;
|
|
388
|
+
cost: {
|
|
389
|
+
input: number;
|
|
390
|
+
output: number;
|
|
391
|
+
total: number;
|
|
392
|
+
};
|
|
393
|
+
};
|
|
377
394
|
/**
|
|
378
395
|
* Fired when the subagent budget hits a soft limit and the coordinator
|
|
379
396
|
* is being asked for an extension. The coordinator should call `extend()`
|
|
@@ -1,17 +1,17 @@
|
|
|
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-
|
|
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-
|
|
3
|
-
import { A as AgentDefinition } from '../multi-agent-coordinator-
|
|
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-
|
|
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 } from '../agent-subagent-runner-
|
|
6
|
-
export { I as InMemoryAgentBridge, a as InMemoryBridgeTransport, c as createMessage } from '../agent-bridge-
|
|
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-
|
|
8
|
-
import { b as Mailbox } from '../pipeline-
|
|
9
|
-
export { h as AgentHeartbeatInput, A as AgentRegistrationInput, f as MailboxAckInput, g as MailboxAgentStatus, d as MailboxMessage,
|
|
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-BaQsRNka.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-CWdU1_cO.js';
|
|
3
|
+
import { A as AgentDefinition } from '../multi-agent-coordinator-Bs-M0Mo6.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-Bs-M0Mo6.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 } from '../agent-subagent-runner-DhYLgAJo.js';
|
|
6
|
+
export { I as InMemoryAgentBridge, a as InMemoryBridgeTransport, c as createMessage } from '../agent-bridge-l_DsFEbr.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-Dz-eNZlQ.js';
|
|
8
|
+
import { b as Mailbox } from '../pipeline-Bxa3wDcy.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-Bxa3wDcy.js';
|
|
10
10
|
import '../context-CLz3z_E8.js';
|
|
11
11
|
import 'node:events';
|
|
12
12
|
import '../director-state-BfeCUbmk.js';
|
|
13
13
|
import '../config-eSsrto5d.js';
|
|
14
|
-
import '../index-
|
|
14
|
+
import '../index-Csoc_bKs.js';
|
|
15
15
|
import '../logger-B63L5bTg.js';
|
|
16
16
|
import '../observability-D-HZN_mF.js';
|
|
17
17
|
import '../permission-DbWPbuoA.js';
|
|
@@ -10041,6 +10041,14 @@ var DefaultMailbox = class {
|
|
|
10041
10041
|
await fsp6.writeFile(this.filePath, "", "utf8");
|
|
10042
10042
|
});
|
|
10043
10043
|
}
|
|
10044
|
+
// ── Client registry stubs (not applicable per-session) ─────────────────
|
|
10045
|
+
async registerClient(_input) {
|
|
10046
|
+
}
|
|
10047
|
+
async clientHeartbeat(_input) {
|
|
10048
|
+
}
|
|
10049
|
+
async getClientStatuses() {
|
|
10050
|
+
return [];
|
|
10051
|
+
}
|
|
10044
10052
|
// ── Internal ──────────────────────────────────────────────────────────
|
|
10045
10053
|
async _readAll() {
|
|
10046
10054
|
try {
|
|
@@ -10217,7 +10225,9 @@ function wstackGlobalRoot() {
|
|
|
10217
10225
|
|
|
10218
10226
|
// src/coordination/global-mailbox.ts
|
|
10219
10227
|
var MAILBOX_FILE2 = "_mailbox.jsonl";
|
|
10228
|
+
var CLIENT_REGISTRY_FILE = "_mailbox.clients.json";
|
|
10220
10229
|
var AGENT_STALE_MS = 6e4;
|
|
10230
|
+
var CLIENT_STALE_MS = 6e4;
|
|
10221
10231
|
var HEARTBEAT_THROTTLE_MS = 5e3;
|
|
10222
10232
|
var REGISTRY_CACHE_TTL_MS = 2e3;
|
|
10223
10233
|
var LINE_SEPARATOR2 = "\n";
|
|
@@ -10229,6 +10239,8 @@ var GlobalMailbox = class {
|
|
|
10229
10239
|
messagePath;
|
|
10230
10240
|
/** Path to the JSON agent registry file. */
|
|
10231
10241
|
registryPath;
|
|
10242
|
+
/** Path to the JSON client registry file. */
|
|
10243
|
+
clientRegistryPath;
|
|
10232
10244
|
/** Optional event bus for emitting agent registration/heartbeat events. */
|
|
10233
10245
|
_events;
|
|
10234
10246
|
/**
|
|
@@ -10240,8 +10252,17 @@ var GlobalMailbox = class {
|
|
|
10240
10252
|
_registryCache = null;
|
|
10241
10253
|
/** When the registry cache was last refreshed from disk (epoch ms). */
|
|
10242
10254
|
_registryCacheAt = 0;
|
|
10255
|
+
/**
|
|
10256
|
+
* Local cache of the client registry to avoid re-reading on every call.
|
|
10257
|
+
* Same reasoning as agent registry cache.
|
|
10258
|
+
*/
|
|
10259
|
+
_clientRegistryCache = null;
|
|
10260
|
+
/** When the client registry cache was last refreshed from disk (epoch ms). */
|
|
10261
|
+
_clientRegistryCacheAt = 0;
|
|
10243
10262
|
/** Last time each local agent sent a heartbeat (throttle). */
|
|
10244
10263
|
_lastHeartbeat = /* @__PURE__ */ new Map();
|
|
10264
|
+
/** Last time each local client sent a heartbeat (throttle). */
|
|
10265
|
+
_lastClientHeartbeat = /* @__PURE__ */ new Map();
|
|
10245
10266
|
/**
|
|
10246
10267
|
* @param projectDir — `~/.wrongstack/projects/<slug>/`
|
|
10247
10268
|
* @param events — optional EventBus for real-time TUI/WebUI notifications
|
|
@@ -10249,6 +10270,7 @@ var GlobalMailbox = class {
|
|
|
10249
10270
|
constructor(projectDir, events) {
|
|
10250
10271
|
this.messagePath = path4.join(projectDir, MAILBOX_FILE2);
|
|
10251
10272
|
this.registryPath = path4.join(projectDir, "_mailbox.registry.json");
|
|
10273
|
+
this.clientRegistryPath = path4.join(projectDir, CLIENT_REGISTRY_FILE);
|
|
10252
10274
|
this._events = events;
|
|
10253
10275
|
}
|
|
10254
10276
|
// ── Messages ────────────────────────────────────────────────────────────
|
|
@@ -10430,9 +10452,74 @@ var GlobalMailbox = class {
|
|
|
10430
10452
|
const all = await this.getAgentStatuses();
|
|
10431
10453
|
return all.filter((a) => a.online);
|
|
10432
10454
|
}
|
|
10455
|
+
// ── Client registry ─────────────────────────────────────────────────────
|
|
10456
|
+
async registerClient(input) {
|
|
10457
|
+
await this._ensureClientRegistry();
|
|
10458
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
10459
|
+
const client = {
|
|
10460
|
+
clientId: input.clientId,
|
|
10461
|
+
sessionId: input.sessionId,
|
|
10462
|
+
name: input.name,
|
|
10463
|
+
source: input.source,
|
|
10464
|
+
registeredAt: now,
|
|
10465
|
+
lastSeenAt: now,
|
|
10466
|
+
pid: input.pid
|
|
10467
|
+
};
|
|
10468
|
+
await withFileLock(this.clientRegistryPath, async () => {
|
|
10469
|
+
const registry = await this._readClientRegistry({ fresh: true });
|
|
10470
|
+
this._pruneStaleClientsInPlace(registry);
|
|
10471
|
+
registry.set(input.clientId, client);
|
|
10472
|
+
this._clientRegistryCache = registry;
|
|
10473
|
+
this._clientRegistryCacheAt = Date.now();
|
|
10474
|
+
await this._writeClientRegistry(registry);
|
|
10475
|
+
});
|
|
10476
|
+
this._events?.emitCustom("mailbox.client_registered", {
|
|
10477
|
+
clientId: input.clientId,
|
|
10478
|
+
sessionId: input.sessionId,
|
|
10479
|
+
name: input.name,
|
|
10480
|
+
source: input.source
|
|
10481
|
+
});
|
|
10482
|
+
}
|
|
10483
|
+
async clientHeartbeat(input) {
|
|
10484
|
+
const last = this._lastClientHeartbeat.get(input.clientId) ?? 0;
|
|
10485
|
+
const now = Date.now();
|
|
10486
|
+
if (now - last < HEARTBEAT_THROTTLE_MS) return;
|
|
10487
|
+
this._lastClientHeartbeat.set(input.clientId, now);
|
|
10488
|
+
await this._ensureClientRegistry();
|
|
10489
|
+
await withFileLock(this.clientRegistryPath, async () => {
|
|
10490
|
+
const registry = await this._readClientRegistry({ fresh: true });
|
|
10491
|
+
this._pruneStaleClientsInPlace(registry);
|
|
10492
|
+
const client = registry.get(input.clientId);
|
|
10493
|
+
if (client) {
|
|
10494
|
+
client.lastSeenAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
10495
|
+
}
|
|
10496
|
+
this._clientRegistryCache = registry;
|
|
10497
|
+
this._clientRegistryCacheAt = Date.now();
|
|
10498
|
+
await this._writeClientRegistry(registry);
|
|
10499
|
+
});
|
|
10500
|
+
this._events?.emitCustom("mailbox.client_heartbeat", {
|
|
10501
|
+
clientId: input.clientId
|
|
10502
|
+
});
|
|
10503
|
+
}
|
|
10504
|
+
async getClientStatuses() {
|
|
10505
|
+
await this._ensureClientRegistry();
|
|
10506
|
+
const registry = await this._readClientRegistry();
|
|
10507
|
+
this._pruneStaleClientsInPlace(registry);
|
|
10508
|
+
const now = Date.now();
|
|
10509
|
+
return Array.from(registry.values()).map((c) => ({
|
|
10510
|
+
clientId: c.clientId,
|
|
10511
|
+
name: c.name,
|
|
10512
|
+
source: c.source,
|
|
10513
|
+
sessionId: c.sessionId,
|
|
10514
|
+
lastSeenAt: c.lastSeenAt,
|
|
10515
|
+
online: now - new Date(c.lastSeenAt).getTime() < CLIENT_STALE_MS,
|
|
10516
|
+
pid: c.pid
|
|
10517
|
+
})).sort((a, b) => b.lastSeenAt.localeCompare(a.lastSeenAt));
|
|
10518
|
+
}
|
|
10433
10519
|
// ── Lifecycle ───────────────────────────────────────────────────────────
|
|
10434
10520
|
async close() {
|
|
10435
10521
|
this._registryCache = null;
|
|
10522
|
+
this._clientRegistryCache = null;
|
|
10436
10523
|
}
|
|
10437
10524
|
async clearAll() {
|
|
10438
10525
|
await withFileLock(this.messagePath, async () => {
|
|
@@ -10511,6 +10598,51 @@ var GlobalMailbox = class {
|
|
|
10511
10598
|
await fsp6.writeFile(tmp, JSON.stringify(obj, null, 2), "utf8");
|
|
10512
10599
|
await fsp6.rename(tmp, this.registryPath);
|
|
10513
10600
|
}
|
|
10601
|
+
// ── Client registry internals ───────────────────────────────────────────
|
|
10602
|
+
async _ensureClientRegistry() {
|
|
10603
|
+
await fsp6.mkdir(path4.dirname(this.clientRegistryPath), { recursive: true });
|
|
10604
|
+
}
|
|
10605
|
+
async _readClientRegistry(opts) {
|
|
10606
|
+
if (!opts?.fresh && this._clientRegistryCache && Date.now() - this._clientRegistryCacheAt < REGISTRY_CACHE_TTL_MS) {
|
|
10607
|
+
return new Map(this._clientRegistryCache);
|
|
10608
|
+
}
|
|
10609
|
+
try {
|
|
10610
|
+
const raw = await fsp6.readFile(this.clientRegistryPath, "utf8");
|
|
10611
|
+
const data = JSON.parse(raw);
|
|
10612
|
+
const map = /* @__PURE__ */ new Map();
|
|
10613
|
+
for (const [id, client] of Object.entries(data)) {
|
|
10614
|
+
map.set(id, client);
|
|
10615
|
+
}
|
|
10616
|
+
this._clientRegistryCache = map;
|
|
10617
|
+
this._clientRegistryCacheAt = Date.now();
|
|
10618
|
+
return new Map(map);
|
|
10619
|
+
} catch (err) {
|
|
10620
|
+
if (err.code === "ENOENT") {
|
|
10621
|
+
const empty = /* @__PURE__ */ new Map();
|
|
10622
|
+
this._clientRegistryCache = empty;
|
|
10623
|
+
this._clientRegistryCacheAt = Date.now();
|
|
10624
|
+
return empty;
|
|
10625
|
+
}
|
|
10626
|
+
throw err;
|
|
10627
|
+
}
|
|
10628
|
+
}
|
|
10629
|
+
_pruneStaleClientsInPlace(registry) {
|
|
10630
|
+
const cutoff = Date.now() - CLIENT_STALE_MS;
|
|
10631
|
+
for (const client of registry.values()) {
|
|
10632
|
+
if (new Date(client.lastSeenAt).getTime() < cutoff) {
|
|
10633
|
+
client.lastSeenAt = new Date(cutoff).toISOString();
|
|
10634
|
+
}
|
|
10635
|
+
}
|
|
10636
|
+
}
|
|
10637
|
+
async _writeClientRegistry(registry) {
|
|
10638
|
+
const obj = {};
|
|
10639
|
+
for (const [id, client] of registry) {
|
|
10640
|
+
obj[id] = client;
|
|
10641
|
+
}
|
|
10642
|
+
const tmp = `${this.clientRegistryPath}.${randomUUID().slice(0, 8)}.tmp`;
|
|
10643
|
+
await fsp6.writeFile(tmp, JSON.stringify(obj, null, 2), "utf8");
|
|
10644
|
+
await fsp6.rename(tmp, this.clientRegistryPath);
|
|
10645
|
+
}
|
|
10514
10646
|
};
|
|
10515
10647
|
function defaultResolveProjectDir(ctx) {
|
|
10516
10648
|
return resolveProjectDir(ctx.projectRoot, wstackGlobalRoot());
|