opencode-swarm 7.165.0 → 7.166.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.
Files changed (95) hide show
  1. package/binaries/win32-arm64/swarm-sandbox-runner.exe +0 -0
  2. package/binaries/win32-x64/swarm-sandbox-runner.exe +0 -0
  3. package/dist/background/delegation-cost-identity.d.ts +41 -0
  4. package/dist/background/delegation-lifecycle.d.ts +24 -5
  5. package/dist/background/pending-delegations.d.ts +2 -0
  6. package/dist/background/pr-monitor-worker.d.ts +60 -6
  7. package/dist/background/pr-subscriptions.d.ts +13 -0
  8. package/dist/cli/{capability-probe-5wa7mcp6.js → capability-probe-faqefhah.js} +2 -1
  9. package/dist/cli/{coder-settlement-89nt4j7g.js → coder-settlement-ydg2jfrk.js} +8 -8
  10. package/dist/cli/{config-doctor-gm6f5chm.js → config-doctor-drqx6tzc.js} +2 -2
  11. package/dist/cli/{core-91p43zwj.js → core-x6sftfwt.js} +1 -1
  12. package/dist/cli/{curation-policy-bqpmry2n.js → curation-policy-jtzwz6bc.js} +4 -4
  13. package/dist/cli/{curator-drift-hbc3w5zj.js → curator-drift-2vwtkegg.js} +2 -2
  14. package/dist/cli/{curator-4bs2hmy9.js → curator-kg2h8jjf.js} +34 -34
  15. package/dist/cli/curator-llm-factory-7znajprp.js +70 -0
  16. package/dist/cli/{evidence-summary-service-g1xd8egd.js → evidence-summary-service-ry5ebnmq.js} +15 -15
  17. package/dist/cli/{gate-evidence-gdmgsz7c.js → gate-evidence-qgeceqy8.js} +5 -5
  18. package/dist/cli/guardrail-explain-jdv4n2j3.js +71 -0
  19. package/dist/cli/{guardrail-log-nyggdv04.js → guardrail-log-s7c3rpde.js} +7 -7
  20. package/dist/cli/{guardrail-reset-rp9jq0gj.js → guardrail-reset-4nmy7xas.js} +34 -34
  21. package/dist/cli/{hive-promoter-39xb4tx2.js → hive-promoter-w5tsgttc.js} +34 -34
  22. package/dist/cli/{index-tqw8w2n5.js → index-17yszqs5.js} +1 -1
  23. package/dist/cli/{index-qzvry1n1.js → index-289epdpc.js} +36 -36
  24. package/dist/cli/{index-7h94rfem.js → index-2dvk153d.js} +14 -12
  25. package/dist/cli/{index-p7hdp3rp.js → index-2rm5x9ps.js} +1 -1
  26. package/dist/cli/{index-xwbn7c8m.js → index-2v17wb75.js} +2 -2
  27. package/dist/cli/{index-y1zhpfk8.js → index-30f4fe30.js} +4 -4
  28. package/dist/cli/{index-n3pjcks8.js → index-359djbj1.js} +5 -5
  29. package/dist/cli/{index-4gmt79q9.js → index-4mpdy32j.js} +1 -1
  30. package/dist/cli/{index-afpkqsdb.js → index-52jfm5s0.js} +13 -6
  31. package/dist/cli/{index-6m24v15v.js → index-79sr3fd1.js} +2 -2
  32. package/dist/cli/{index-dh5th4jn.js → index-8hqkrd2j.js} +1 -1
  33. package/dist/cli/{index-3xyjvx24.js → index-8m12y79g.js} +11 -9
  34. package/dist/cli/{index-e6n7cemz.js → index-8n62bphd.js} +11 -7
  35. package/dist/cli/{index-hdakb4n9.js → index-9hy5q7gp.js} +15 -12
  36. package/dist/cli/{index-2k53pfnc.js → index-a5w71m8f.js} +4 -4
  37. package/dist/cli/{index-6rx1rdaq.js → index-a7rw4g4s.js} +1 -1
  38. package/dist/cli/{index-w6988bbc.js → index-aftapk6j.js} +75 -1
  39. package/dist/cli/{index-hwz46jj7.js → index-an89qzd9.js} +2074 -545
  40. package/dist/cli/{index-58be2gtd.js → index-apxaa755.js} +2 -2
  41. package/dist/cli/{index-j2svfhzk.js → index-axf65x87.js} +1 -1
  42. package/dist/cli/{index-g8wdekzz.js → index-bw7r2b2m.js} +2 -2
  43. package/dist/cli/{index-ajknebrc.js → index-c20gf089.js} +1 -1
  44. package/dist/cli/{index-ptsqnxwd.js → index-czr3jcg6.js} +20 -10
  45. package/dist/cli/{index-jre6tm3v.js → index-edm41q4j.js} +1 -1
  46. package/dist/cli/{index-r5hj3nfe.js → index-ejf6w8vw.js} +2 -2
  47. package/dist/cli/{index-c4ddtrqg.js → index-fywshabz.js} +6 -6
  48. package/dist/cli/{index-6be5caj8.js → index-hrkamw9q.js} +3 -3
  49. package/dist/cli/{index-f36hy1x4.js → index-hvk3zs62.js} +1 -1
  50. package/dist/cli/{index-5ebgzb5a.js → index-hwj25q9r.js} +78 -53
  51. package/dist/cli/{index-gn6ybsc4.js → index-jc9cxh90.js} +7 -7
  52. package/dist/cli/{index-e45htt92.js → index-jx9f4ke1.js} +1 -1
  53. package/dist/cli/{index-zycp24b9.js → index-mg43w8p2.js} +1 -1
  54. package/dist/cli/{index-0e9jh9c7.js → index-nb924ar6.js} +2 -2
  55. package/dist/cli/{index-k1ntjzmf.js → index-p04pa9c9.js} +1 -1
  56. package/dist/cli/{index-4fwbbad3.js → index-q1r1cfww.js} +46 -17
  57. package/dist/cli/{index-5ythtd9t.js → index-qkq56zyr.js} +11 -11
  58. package/dist/cli/{index-1v6vc90w.js → index-rkn17q5e.js} +3 -3
  59. package/dist/cli/{index-556ja8an.js → index-yzjaj53h.js} +9 -2
  60. package/dist/cli/index.js +34 -34
  61. package/dist/cli/{knowledge-escalator-eq07pcj3.js → knowledge-escalator-xdzmr31d.js} +10 -10
  62. package/dist/cli/{knowledge-events-rv9q9mkm.js → knowledge-events-1t1t0bv7.js} +8 -8
  63. package/dist/cli/{knowledge-link-dgvbqjqg.js → knowledge-link-1zykfk1p.js} +3 -3
  64. package/dist/cli/{knowledge-store-cxcr0ttk.js → knowledge-store-m2snb0xg.js} +4 -4
  65. package/dist/cli/{knowledge-validator-8qtd9ys0.js → knowledge-validator-tf7yq2pd.js} +6 -6
  66. package/dist/cli/{pending-delegations-dp3g8e7k.js → pending-delegations-jr8hwxrz.js} +11 -9
  67. package/dist/cli/{pr-subscriptions-3vx06rar.js → pr-subscriptions-ca1xmf9r.js} +13 -9
  68. package/dist/cli/{pr-workflow-gate-bbet0apk.js → pr-workflow-gate-fb1dj0zx.js} +34 -34
  69. package/dist/cli/{runner-0e3bjeev.js → runner-j3acybhs.js} +4 -4
  70. package/dist/cli/{scan-cursor-zwm0xng7.js → scan-cursor-3gdvy0ym.js} +5 -5
  71. package/dist/cli/{schema-ebfxgya0.js → schema-mzb1354k.js} +1 -1
  72. package/dist/cli/{scope-persistence-6c55akfz.js → scope-persistence-c4n21b5n.js} +14 -14
  73. package/dist/cli/{skill-generator-mv5jxzsh.js → skill-generator-dvpvwt8k.js} +12 -12
  74. package/dist/cli/{snapshot-coordination-init-n556wa18.js → snapshot-coordination-init-g7v63zcm.js} +34 -34
  75. package/dist/cli/{telemetry-a1yvjerj.js → telemetry-9h1z2w9d.js} +1 -1
  76. package/dist/cli/{worktree-collision-ownership-pp4z4z8p.js → worktree-collision-ownership-k15qrpy9.js} +9 -9
  77. package/dist/cli/{worktree-isolation-69hz9dgg.js → worktree-isolation-y7ec1pm5.js} +34 -34
  78. package/dist/commands/pr-monitor-status.d.ts +2 -0
  79. package/dist/commands/registry.d.ts +8 -0
  80. package/dist/commands/report.d.ts +36 -0
  81. package/dist/db/observability-event-store.d.ts +162 -0
  82. package/dist/git/pr.d.ts +23 -25
  83. package/dist/hooks/context-capsule-inject.d.ts +3 -0
  84. package/dist/index.d.ts +6 -1
  85. package/dist/index.js +522 -429
  86. package/dist/observability/catalog.d.ts +8 -4
  87. package/dist/sandbox/executor.d.ts +10 -0
  88. package/dist/sandbox/win32/runner-client.d.ts +7 -0
  89. package/dist/services/context-attribution.d.ts +69 -0
  90. package/dist/services/cost-accounting.d.ts +2 -0
  91. package/dist/telemetry.d.ts +10 -2
  92. package/opencode-swarm.schema.json +1 -1
  93. package/package.json +1 -1
  94. package/dist/cli/curator-llm-factory-fhbjwar0.js +0 -70
  95. package/dist/cli/guardrail-explain-1nfbtpgg.js +0 -71
@@ -0,0 +1,162 @@
1
+ /**
2
+ * swarm.db store for the canonical observability event envelope (issue #2482,
3
+ * Workstream D PR 3).
4
+ *
5
+ * The durable local query authority for observability events:
6
+ *
7
+ * - Table `observability_event` — one row per emitted canonical
8
+ * `ObservabilityEvent`, appended through the group-commit writer (queue ->
9
+ * one txn per flush). Durability class `normal` (rebuildable telemetry
10
+ * sink; the bounded `.swarm/telemetry.jsonl` stream remains the
11
+ * operational legacy record — this store does NOT replace it).
12
+ * - The sink registers as a TELEMETRY LISTENER (`registerObservabilityEventSink`),
13
+ * not as an `emit()` call site: the retention-registry writer-coverage
14
+ * ratchet requires every writer module to appear in exactly one registry
15
+ * row, and `src/telemetry.ts` is already owned by the `telemetry-jsonl`
16
+ * row. The listener receives the canonical envelope as its third
17
+ * parameter.
18
+ * - Zero top-level executable side effects; no DB work at plugin init. The
19
+ * DB handle opens lazily on the first sink append (`getProjectDb` /
20
+ * `getGroupCommitWriter` are invoked inside the listener closure, matching
21
+ * the `insight-candidate-store.ts` precedent). Processes that never
22
+ * register the sink (direct CLI / test scripts) simply get no SQLite sink —
23
+ * fail-open, never an error.
24
+ * - Fail-open everywhere: sink failures are counted (bounded in-memory
25
+ * counters persisted opportunistically into `observability_sink_health`)
26
+ * and never propagate. The sink is non-authoritative for every decision;
27
+ * observability health is surfaced through `/swarm report`.
28
+ * - Malformed events are QUARANTINED, not dropped: rows that cannot carry a
29
+ * faithful envelope (fallback observations, oversize payloads, unparseable
30
+ * legacy import lines) are stored with `quarantined = 1` plus a reason and
31
+ * excluded from report timelines while remaining countable.
32
+ * - Rebuildable: `syncObservabilityImport` (report path only — never per
33
+ * emit, never at init) incrementally imports the bounded legacy
34
+ * `telemetry.jsonl(.1)` stream using deterministic per-line synthetic ids,
35
+ * so deleting the imported rows and re-syncing reproduces byte-identical
36
+ * content (proven by test).
37
+ */
38
+ import type { ObservabilityEvent } from '../observability/envelope.js';
39
+ import { extractWorkflowIds } from '../observability/legacy.js';
40
+ import { getGroupCommitWriter } from './group-commit-writer.js';
41
+ import { getProjectDb } from './project-db.js';
42
+ /** Hard cap on retained observability rows (DELETE-based retention). */
43
+ export declare const MAX_OBSERVABILITY_EVENT_ROWS = 50000;
44
+ /** Rows past this many accepted events get a retention check appended. */
45
+ export declare const RETENTION_CHECK_INTERVAL = 512;
46
+ /** Health-counter deltas are persisted at most this often (events). */
47
+ export declare const HEALTH_UPSERT_INTERVAL = 256;
48
+ /** Hard cap on a single serialized payload (oversize → quarantined stub). */
49
+ export declare const MAX_EVENT_PAYLOAD_BYTES: number;
50
+ export type IngestedVia = 'live' | 'import';
51
+ export interface ObservabilityEventRow {
52
+ rowid: number;
53
+ event_id: string;
54
+ kind: string;
55
+ category: string | null;
56
+ severity: string | null;
57
+ occurred_at: string;
58
+ writer_sequence: number | null;
59
+ trace_id: string | null;
60
+ span_id: string | null;
61
+ host_session_id: string | null;
62
+ task_id: string | null;
63
+ lane_id: string | null;
64
+ batch_id: string | null;
65
+ phase_id: string | null;
66
+ council_round_id: string | null;
67
+ project_ref: string | null;
68
+ outcome_status: string | null;
69
+ retry_index: number | null;
70
+ privacy_class: string | null;
71
+ sampled: number | null;
72
+ payload_json: string;
73
+ relationship_violations: string | null;
74
+ quarantined: number;
75
+ quarantine_reason: string | null;
76
+ ingested_via: string;
77
+ }
78
+ export interface ObservabilitySinkHealth {
79
+ accepted: number;
80
+ quarantined: number;
81
+ dropped: number;
82
+ last_error_category: string | null;
83
+ last_error_at: string | null;
84
+ last_flush_at: string | null;
85
+ updated_at: string | null;
86
+ }
87
+ /** Filter set for bounded report queries. Every field optional. */
88
+ export interface ObservabilityEventFilter {
89
+ taskId?: string;
90
+ sessionId?: string;
91
+ traceId?: string;
92
+ batchId?: string;
93
+ /** Inclusive lower bound on `occurred_at` (ISO-8601 string compare). */
94
+ since?: string;
95
+ }
96
+ /**
97
+ * Register the SQLite observability sink as a telemetry listener for this
98
+ * project root. O(1), idempotent, never opens the DB, never throws — safe to
99
+ * call immediately before `initTelemetry` on the plugin init path. Registering
100
+ * with a DIFFERENT directory evicts the previous listener first, so exactly
101
+ * one sink listener is ever on the telemetry bus (per-directory counters live
102
+ * in their own maps and simply resume under the new binding).
103
+ */
104
+ export declare function registerObservabilityEventSink(directory: string): void;
105
+ /** Test/reset hook: drops the listener and forgets the binding. */
106
+ export declare function resetObservabilityEventSinkForTesting(): void;
107
+ /**
108
+ * Append one canonical event to the SQLite query authority via the
109
+ * group-commit writer (durability `normal`). Fail-open contract: throws are
110
+ * the CALLER's to swallow (the sink listener does). In-memory health counters
111
+ * track accepted/quarantined; retention + health persistence are appended to
112
+ * the same batch on their throttle intervals so they can never race a live
113
+ * append.
114
+ */
115
+ export declare function appendObservabilityEventDb(directory: string, canonical: ObservabilityEvent): void;
116
+ export interface ObservabilityImportResult {
117
+ imported: number;
118
+ quarantined: number;
119
+ skippedUnchanged: boolean;
120
+ }
121
+ /**
122
+ * Incrementally import the bounded legacy `telemetry.jsonl(.1)` stream into
123
+ * the query authority. Deterministic and idempotent: per-file markers record
124
+ * (size, mtime, lines_seen); append-only growth imports just the delta;
125
+ * rotation/shrink (or a deleted/recreated file) triggers a full rescan whose
126
+ * content-derived synthetic ids make every re-insert a no-op (`INSERT OR
127
+ * IGNORE`). Runs only from the report path — never per emit, never at init.
128
+ * Files are read oldest-generation first so rowid order tracks event order.
129
+ */
130
+ export declare function syncObservabilityImport(directory: string): ObservabilityImportResult;
131
+ /** Row cap for a single report query (#2048 bounded output budget). */
132
+ export declare const MAX_REPORT_ROWS = 5000;
133
+ export interface ObservabilityQueryResult {
134
+ rows: ObservabilityEventRow[];
135
+ truncated: boolean;
136
+ totalMatching: number;
137
+ }
138
+ /**
139
+ * Bounded, deterministic query over the query authority. Filters are exact
140
+ * bound parameters (node:sqlite strictness — counts are exact per branch);
141
+ * ordering is code-unit string compare on ISO timestamps plus rowid — no
142
+ * locale-dependent collation. Quarantined rows are excluded from timelines.
143
+ */
144
+ export declare function queryObservabilityEvents(directory: string, filter: ObservabilityEventFilter): ObservabilityQueryResult;
145
+ /** Cumulative persisted sink health (never opens a DB when absent). */
146
+ export declare function readObservabilitySinkHealth(directory: string): ObservabilitySinkHealth | null;
147
+ /** Coverage snapshot for report disclosure (live/imported/quarantined). */
148
+ export interface ObservabilityCoverage {
149
+ liveRows: number;
150
+ importedRows: number;
151
+ quarantinedRows: number;
152
+ totalRows: number;
153
+ earliestOccurredAt: string | null;
154
+ latestOccurredAt: string | null;
155
+ }
156
+ export declare function readObservabilityCoverage(directory: string): ObservabilityCoverage | null;
157
+ /** DI seam (repo `_internals` convention). */
158
+ export declare const _internals: {
159
+ getProjectDb: typeof getProjectDb;
160
+ getGroupCommitWriter: typeof getGroupCommitWriter;
161
+ extractWorkflowIds: typeof extractWorkflowIds;
162
+ };
package/dist/git/pr.d.ts CHANGED
@@ -113,13 +113,6 @@ export interface PRStatusResult {
113
113
  detailsUrl?: string;
114
114
  }>;
115
115
  }
116
- export interface PRCheckResult {
117
- name: string;
118
- bucket: string;
119
- state: string;
120
- startedAt: string | null;
121
- completedAt: string | null;
122
- }
123
116
  export interface PRCommentResult {
124
117
  id: string;
125
118
  author: string;
@@ -138,28 +131,33 @@ export interface ReviewStateResult {
138
131
  /** Number of requesting reviewers (non-zero means reviews are still pending). */
139
132
  reviewRequestCount: number;
140
133
  }
134
+ /** All per-PR data one poll cycle needs, in two gh spawns. */
135
+ export interface PRPollSnapshot {
136
+ status: PRStatusResult;
137
+ comments: PRCommentResult[];
138
+ merge: MergeStateResult;
139
+ review: ReviewStateResult;
140
+ }
141
141
  /**
142
- * Fetch PR status via gh pr view --json
143
- */
144
- export declare function getPRStatus(prNumber: number, repoFullName: string, cwd: string): Promise<PRStatusResult>;
145
- /**
146
- * Fetch CI check results via gh pr checks --json
147
- */
148
- export declare function getPRChecks(prNumber: number, repoFullName: string, cwd: string): Promise<PRCheckResult[]>;
149
- /**
150
- * Fetch PR comments since a given timestamp via gh api
151
- * Returns both issue comments and pull request review comments, merged together
152
- */
153
- export declare function getPRComments(prNumber: number, repoFullName: string, cwd: string, since?: string): Promise<PRCommentResult[]>;
154
- /**
155
- * Fetch merge state (mergeable + mergeStateStatus) via gh pr view --json
142
+ * Fetch status, merge state, review state and conversation (issue) comments
143
+ * with ONE `gh pr view --json` call. Previously this was three near-duplicate
144
+ * pr-view spawns (status/merge/review) plus two gh api spawns per PR per poll.
145
+ *
146
+ * `comments[].id` from pr-view is the GraphQL node id, NOT the numeric
147
+ * database id the REST endpoints return. The numeric id is recovered from the
148
+ * comment permalink (`#issuecomment-<id>` suffix, verified equal to the REST
149
+ * id on gh >= 2.92) so `lastCommentId` markers written by earlier versions
150
+ * keep matching; the node id remains the defensive fallback (a warn is
151
+ * logged if it ever fires fallback ids change the marker space).
156
152
  */
157
- export declare function getMergeState(prNumber: number, repoFullName: string, cwd: string): Promise<MergeStateResult>;
153
+ export declare function getPRPollSnapshot(prNumber: number, repoFullName: string, cwd: string): Promise<PRPollSnapshot>;
158
154
  /**
159
- * Fetch the current review state for a PR using `gh pr view --json reviewDecision,reviewRequests`.
160
- * Uses async ghExecAsync to avoid blocking the event loop.
155
+ * Fetch inline pull-request review comments via gh api the review half of
156
+ * the old two-endpoint getPRComments (the issue-comment half now rides the
157
+ * pr-view snapshot). Inline review comments have no `gh pr view --json`
158
+ * equivalent, so this stays the second spawn of the poll cycle.
161
159
  */
162
- export declare function getPRReviewState(prNumber: number, repoFullName: string, cwd: string): Promise<ReviewStateResult>;
160
+ export declare function getPRReviewComments(prNumber: number, repoFullName: string, cwd: string): Promise<PRCommentResult[]>;
163
161
  /**
164
162
  * Result of fetching a GitHub Actions run for a PR's merge group.
165
163
  */
@@ -23,6 +23,7 @@ import type { PluginConfig } from '../config/index.js';
23
23
  import { buildCapsule } from '../context-map/capsule-builder.js';
24
24
  import { saveCapsule } from '../context-map/capsule-persistence.js';
25
25
  import { recordTelemetry } from '../context-map/telemetry.js';
26
+ import { measureCitedFileTokens, recordContextSourceAttribution } from '../services/context-attribution.js';
26
27
  import type { AgentSessionState } from '../state.js';
27
28
  import type { CapsuleDelegationReason } from '../types/context-capsule.js';
28
29
  /**
@@ -58,6 +59,8 @@ export declare const _internals: {
58
59
  buildCapsule: typeof buildCapsule;
59
60
  recordTelemetry: typeof recordTelemetry;
60
61
  saveCapsule: typeof saveCapsule;
62
+ measureCitedFileTokens: typeof measureCitedFileTokens;
63
+ recordContextSourceAttribution: typeof recordContextSourceAttribution;
61
64
  getActiveAgent: (sessionID: string) => string | undefined;
62
65
  getSession: (sessionID: string) => AgentSessionState | undefined;
63
66
  getCurrentTaskId: (sessionID: string) => string | null;
package/dist/index.d.ts CHANGED
@@ -12,7 +12,12 @@ import { ensureSwarmGitExcluded } from './utils/gitignore-warning';
12
12
  * unit testing of the cap invariant; used by the heartbeat throttle and
13
13
  * delegation-telemetry pairing paths below.
14
14
  */
15
- export declare function capSessionMap<K, V>(map: Map<K, V>, max: number): void;
15
+ export declare function capSessionMap<K, V>(map: Map<K, V>, max: number,
16
+ /** #2482 / #2244: the just-inserted key must never evict itself (a re-set
17
+ * entry keeps its ORIGINAL insertion position, so without this guard the
18
+ * fresh entry can be the oldest and evict itself at the cap — mirroring
19
+ * the stored-input-args guard). */
20
+ justInserted?: K): void;
16
21
  /** @internal — test-only: clears delegation-telemetry pairing state so one
17
22
  * test's unconsumed entries (e.g. a before with no matching after) cannot
18
23
  * leak into the next. Mirrors resetTelemetryForTesting / resetSwarmState. */