opencode-swarm 7.99.2 → 7.99.4

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.
@@ -91,6 +91,12 @@ export declare function retryCasWithBackoff(directory: string, eventInput: Ledge
91
91
  * Use this when you want to check for structured plans without triggering migration.
92
92
  */
93
93
  export declare function loadPlanJsonOnly(directory: string): Promise<Plan | null>;
94
+ /**
95
+ * Check if plan.md is derived from the given plan by comparing content hashes.
96
+ * Returns true if plan.md exists and matches the plan's content hash.
97
+ * This avoids timestamp comparison issues by using a deterministic hash.
98
+ */
99
+ export declare function isPlanMdInSync(directory: string, plan: Plan, cache?: Map<string, Promise<string | null>>): Promise<boolean>;
94
100
  /**
95
101
  * Regenerate plan.md from valid plan.json (auto-heal case 1).
96
102
  */
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Returns true if `value` is a strictly-valid semver string. Pure; never throws.
3
+ */
4
+ export declare function isStrictSemver(value: unknown): value is string;
1
5
  interface VersionCheckCache {
2
6
  checkedAt: number;
3
7
  npmLatest: string | null;
@@ -8,6 +12,34 @@ export declare function readVersionCache(): VersionCheckCache | null;
8
12
  * 0 if equal. Treats prerelease tags as lower than the release. Pure function.
9
13
  */
10
14
  export declare function compareVersions(a: string, b: string): number;
15
+ /**
16
+ * Fetch the latest published version from the npm registry with strict,
17
+ * fail-safe validation (issue #1270-4):
18
+ * (a) HTTP status must be ok.
19
+ * (b) Content-Type must look like JSON — a mislabeled HTML error page or
20
+ * proxy interstitial is rejected rather than parsed.
21
+ * (c) The body is length-bounded both by the advertised Content-Length and
22
+ * by the actual decoded length, so a hostile endpoint cannot make us
23
+ * buffer an unbounded response.
24
+ * (d) The `version` field must be a STRICT semver string before it is
25
+ * returned (and thus before it is cached, compared, or surfaced).
26
+ *
27
+ * Any validation failure returns null. This function NEVER throws into its
28
+ * caller — staleness checking must never disrupt plugin startup.
29
+ *
30
+ * Exported so tests can exercise the validation directly via the
31
+ * `_internals.fetch` seam (mocking the global `fetch` would leak across files
32
+ * in Bun's shared test process).
33
+ */
34
+ export declare function fetchLatestVersion(signal: AbortSignal): Promise<string | null>;
35
+ /**
36
+ * Test-only dependency-injection seam. Production reads `_internals.fetch(...)`
37
+ * at the call site so tests can replace it without `mock.module` (which leaks
38
+ * across files in Bun's shared test-runner process). Restore in `afterEach`.
39
+ */
40
+ export declare const _internals: {
41
+ fetch: (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
42
+ };
11
43
  /**
12
44
  * Schedule a one-shot, fully detached version check. Returns immediately.
13
45
  * Emits a deferred warning via `emitWarning` when a newer version is found.
package/dist/state.d.ts CHANGED
@@ -380,6 +380,41 @@ export declare function resetSwarmState(): void;
380
380
  * propagate to caller (no try/catch wrapper).
381
381
  */
382
382
  export declare function resetSwarmStatePreservingSingletons(): void;
383
+ /**
384
+ * Evict every agent session whose last tool activity is older than
385
+ * staleDurationMs, and drop the delegation chain keyed by that same sessionID
386
+ * (delegationChains is keyed by sessionID — see delegation-tracker.ts, which
387
+ * does `delegationChains.set(input.sessionID, ...)`). This is the single
388
+ * eviction loop reused by BOTH startAgentSession (eager, on new session start)
389
+ * and maybeSweepStaleSessions (opportunistic, on the hot path) so the logic is
390
+ * never duplicated.
391
+ *
392
+ * @param staleDurationMs - Age threshold in ms (default 2h)
393
+ * @param now - Current time in ms (injectable for deterministic tests)
394
+ * @returns The list of evicted session IDs
395
+ */
396
+ export declare function sweepStaleSessions(staleDurationMs?: number, now?: number): string[];
397
+ /**
398
+ * Opportunistic, cooldown-guarded wrapper around sweepStaleSessions, intended
399
+ * to be called from a frequently-hit code path (per-tool-call accounting in
400
+ * ensureAgentSession). This reclaims accumulated session state even when no
401
+ * new session is ever started — closing the gap where eager eviction only ran
402
+ * inside startAgentSession, so a long-lived host that stopped creating
403
+ * sessions never reclaimed old ones.
404
+ *
405
+ * Bounded work (invariant 8): the O(n) scan runs at most once per
406
+ * IDLE_SWEEP_COOLDOWN_MS. The cooldown timestamp advances whenever the cooldown
407
+ * has elapsed — even when zero sessions are evicted — so an idle/empty map does
408
+ * not re-scan on every call.
409
+ *
410
+ * No timers, no init-path work (invariant 1): this only runs when a hook
411
+ * actively calls it on the hot path; it never schedules background work.
412
+ *
413
+ * @param staleDurationMs - Age threshold in ms (default 2h)
414
+ * @param now - Current time in ms (injectable for deterministic tests)
415
+ * @returns Evicted session IDs ([] when the cooldown blocks this run)
416
+ */
417
+ export declare function maybeSweepStaleSessions(staleDurationMs?: number, now?: number): string[];
383
418
  /**
384
419
  * Start a new agent session with initialized guardrail state.
385
420
  * Also removes any stale sessions older than staleDurationMs.
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import type { ToolContext, ToolDefinition } from '@opencode-ai/plugin/tool';
6
6
  import { tryAcquireLock } from '../parallel/file-locks.js';
7
- import { updateTaskStatus } from '../plan/manager';
7
+ import { loadPlan, updateTaskStatus } from '../plan/manager';
8
8
  import { resolveWorkingDirectory } from './resolve-working-directory';
9
9
  /**
10
10
  * Internal seams for test injection.
@@ -15,6 +15,7 @@ export declare const _internals: {
15
15
  readonly tryAcquireLock: typeof tryAcquireLock;
16
16
  readonly updateTaskStatus: typeof updateTaskStatus;
17
17
  readonly resolveWorkingDirectory: typeof resolveWorkingDirectory;
18
+ readonly loadPlan: typeof loadPlan;
18
19
  };
19
20
  /**
20
21
  * Arguments for the update_task_status tool
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.99.2",
3
+ "version": "7.99.4",
4
4
  "description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",