opencode-swarm 7.177.0 → 7.178.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 (118) 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/agents/architect.d.ts +9 -1
  4. package/dist/cli/{capability-probe-pdwwz8gs.js → capability-probe-8k8ebeyp.js} +2 -2
  5. package/dist/cli/{coder-settlement-pm07553t.js → coder-settlement-d2bfb25j.js} +13 -13
  6. package/dist/cli/{config-doctor-3mwx2rwq.js → config-doctor-905x2s1c.js} +4 -4
  7. package/dist/cli/{core-ty985ae1.js → core-k7wfx1wx.js} +4 -4
  8. package/dist/cli/{curation-policy-d8s9w1z8.js → curation-policy-n4hd2wsa.js} +5 -5
  9. package/dist/cli/{curator-drift-4m984tvy.js → curator-drift-smqmej5v.js} +4 -4
  10. package/dist/cli/curator-llm-factory-qhhxev17.js +72 -0
  11. package/dist/cli/{curator-pch7ww87.js → curator-wyadq69k.js} +40 -40
  12. package/dist/cli/{evidence-summary-service-cxed89n3.js → evidence-summary-service-r3wcprfk.js} +19 -19
  13. package/dist/cli/{gate-evidence-ymye7yew.js → gate-evidence-tq9rb2aj.js} +8 -8
  14. package/dist/cli/guardrail-explain-kvgejh24.js +73 -0
  15. package/dist/cli/{guardrail-log-pgggycf9.js → guardrail-log-m6twga6x.js} +9 -9
  16. package/dist/cli/{guardrail-reset-aghymhr5.js → guardrail-reset-86esv8cr.js} +40 -40
  17. package/dist/cli/hive-promoter-s87hkb40.js +87 -0
  18. package/dist/cli/{index-zzr7f594.js → index-18hjycr1.js} +1 -1
  19. package/dist/cli/{index-w7aedfce.js → index-29begjkp.js} +8 -8
  20. package/dist/cli/{index-7nsvszwn.js → index-2b1whj28.js} +2 -2
  21. package/dist/cli/{index-7bvzssz0.js → index-2bmhe2jn.js} +4 -4
  22. package/dist/cli/{index-hxdswvtv.js → index-2mdk6nt9.js} +7 -7
  23. package/dist/cli/{index-rz4gpt3n.js → index-2vhkwy6v.js} +3 -3
  24. package/dist/cli/{index-fpbcxykc.js → index-6b295cas.js} +87 -1
  25. package/dist/cli/{index-yzjaj53h.js → index-9rwhas09.js} +1 -1
  26. package/dist/cli/{index-8dy3qf4q.js → index-at0ygwwp.js} +5 -5
  27. package/dist/cli/{index-q1jterxw.js → index-azy3tw6c.js} +2 -2
  28. package/dist/cli/{index-eefz8ghz.js → index-bfz1jvcn.js} +1 -1
  29. package/dist/cli/{index-gwnbprzk.js → index-d5dexrv1.js} +4 -4
  30. package/dist/cli/{index-wemtrnch.js → index-ffqy30e5.js} +2 -2
  31. package/dist/cli/{index-5w51tawb.js → index-gg44hytk.js} +9 -9
  32. package/dist/cli/{index-ebmep9me.js → index-heg4em8j.js} +591 -261
  33. package/dist/cli/{index-z8j7jqxt.js → index-j1v54ahd.js} +4 -3
  34. package/dist/cli/{index-tj0sdxg9.js → index-j3rkh9mp.js} +2 -2
  35. package/dist/cli/{index-zbq9091c.js → index-jzxeymr0.js} +13 -13
  36. package/dist/cli/{index-zwam9stk.js → index-ke3m026z.js} +6 -6
  37. package/dist/cli/{index-r18n5f17.js → index-kfk403mc.js} +5 -5
  38. package/dist/cli/{index-5frh43fj.js → index-m2n1rhgv.js} +12 -0
  39. package/dist/cli/{index-k6bjkqw8.js → index-mpcp6rmj.js} +1 -1
  40. package/dist/cli/{index-fnmt1ema.js → index-p27az2hc.js} +4 -4
  41. package/dist/cli/{index-5d2avnj9.js → index-pm7c6f66.js} +2 -2
  42. package/dist/cli/{index-vfp9hjgv.js → index-q9vb5e7n.js} +1 -1
  43. package/dist/cli/{index-0z5s71kn.js → index-qk29b7s4.js} +42 -42
  44. package/dist/cli/{index-by7xpk8f.js → index-qs8eth8h.js} +37 -6
  45. package/dist/cli/{index-ef2fa774.js → index-rp0jk48x.js} +7 -7
  46. package/dist/cli/{index-9ftc8saz.js → index-sqngtwyq.js} +1 -1
  47. package/dist/cli/{index-tzxk6ct7.js → index-swxaa0zs.js} +40 -40
  48. package/dist/cli/{index-xnednxvm.js → index-tnjmn0dn.js} +1 -1
  49. package/dist/cli/{index-rgapg88w.js → index-vfc7d22n.js} +7 -3
  50. package/dist/cli/{index-1bq6hkw5.js → index-w4yjy3vp.js} +1 -1
  51. package/dist/cli/{index-73arkdgf.js → index-wbkxbgk8.js} +9 -5
  52. package/dist/cli/{index-2jtmevrr.js → index-wfbh1bx8.js} +3 -3
  53. package/dist/cli/{index-4chr4gbq.js → index-wkde35ej.js} +9 -9
  54. package/dist/cli/{index-76qm2c2y.js → index-wvghb3x6.js} +4 -4
  55. package/dist/cli/{index-v2he8xfj.js → index-y6a2bkp1.js} +2 -2
  56. package/dist/cli/{index-eya03h5m.js → index-y74n1sy8.js} +7 -7
  57. package/dist/cli/{index-tbswvz8s.js → index-yeh78c1g.js} +2 -2
  58. package/dist/cli/{index-en0p0hqp.js → index-yj1kr0ft.js} +1 -1
  59. package/dist/cli/{index-nzz58tbs.js → index-zex7644g.js} +2 -2
  60. package/dist/cli/{index-exhm2ztr.js → index-zmb8fjp5.js} +1 -1
  61. package/dist/cli/{index-mcq6xs4k.js → index-zsm8h8y1.js} +4 -4
  62. package/dist/cli/{index-yhaxn5r7.js → index-zsp9de3k.js} +2 -2
  63. package/dist/cli/index.js +41 -41
  64. package/dist/cli/{knowledge-escalator-praedffr.js → knowledge-escalator-rgz471df.js} +13 -13
  65. package/dist/cli/{knowledge-events-sn5gs5q9.js → knowledge-events-4mq0ypx9.js} +11 -11
  66. package/dist/cli/{knowledge-link-9z3fha35.js → knowledge-link-npk50523.js} +4 -4
  67. package/dist/cli/{knowledge-store-838sgd97.js → knowledge-store-gft25s5t.js} +5 -5
  68. package/dist/cli/{knowledge-validator-bsxgarqv.js → knowledge-validator-ejqacbx4.js} +7 -7
  69. package/dist/cli/{mcp-skh29erk.js → mcp-emaeeq4s.js} +48 -7
  70. package/dist/cli/mcp.d.ts +9 -0
  71. package/dist/cli/{model-preflight-gk1jysa8.js → model-preflight-kh9dwts2.js} +1 -1
  72. package/dist/cli/{pending-delegations-6zr5es4b.js → pending-delegations-4bhkcykk.js} +11 -11
  73. package/dist/cli/{pr-subscriptions-x2rr3gva.js → pr-subscriptions-h1n6dbds.js} +11 -11
  74. package/dist/cli/{pr-workflow-gate-jx30c9vz.js → pr-workflow-gate-wn6v5za8.js} +40 -40
  75. package/dist/cli/{runner-yhfmejzb.js → runner-ffy5ahhz.js} +5 -5
  76. package/dist/cli/{scan-cursor-6h85e2g0.js → scan-cursor-e63t0g5b.js} +6 -6
  77. package/dist/cli/{schema-8h1b602y.js → schema-4k4hr33y.js} +4 -2
  78. package/dist/cli/{scope-persistence-rb99xjr0.js → scope-persistence-qcw3rtxq.js} +16 -16
  79. package/dist/cli/{server-kdjc5aw8.js → server-58s1wwap.js} +2055 -736
  80. package/dist/cli/{skill-generator-nz7wjabh.js → skill-generator-fhj13jmq.js} +15 -15
  81. package/dist/cli/{snapshot-coordination-init-hexx2msp.js → snapshot-coordination-init-5fawrj35.js} +40 -40
  82. package/dist/cli/{telemetry-w774xb8g.js → telemetry-ca8dmn26.js} +1 -1
  83. package/dist/cli/{workspace-snapshot-9gqna7gq.js → workspace-snapshot-v5qyjxg0.js} +3 -3
  84. package/dist/cli/{worktree-collision-ownership-ecwj3ehp.js → worktree-collision-ownership-hjk0jx19.js} +12 -12
  85. package/dist/cli/{worktree-isolation-0x9fx30v.js → worktree-isolation-aj20bs6q.js} +40 -40
  86. package/dist/commands/dashboard.d.ts +15 -0
  87. package/dist/commands/registry.d.ts +7 -0
  88. package/dist/config/schema.d.ts +16 -0
  89. package/dist/dashboard/assets.d.ts +12 -0
  90. package/dist/dashboard/index.d.ts +74 -0
  91. package/dist/dashboard/server.d.ts +94 -0
  92. package/dist/dashboard/views.d.ts +131 -0
  93. package/dist/events/core-events.d.ts +1 -1
  94. package/dist/hooks/delegation-gate.d.ts +26 -0
  95. package/dist/hooks/index.d.ts +1 -1
  96. package/dist/hooks/tool-summarizer.d.ts +7 -2
  97. package/dist/index.js +437 -276
  98. package/dist/mcp/adapters/knowledge-add.d.ts +19 -0
  99. package/dist/mcp/adapters/receipt-status.d.ts +3 -0
  100. package/dist/mcp/adapters/scope-validation.d.ts +3 -0
  101. package/dist/mcp/registry.d.ts +26 -14
  102. package/dist/mcp/server.d.ts +5 -0
  103. package/dist/mcp/write-receipts.d.ts +168 -0
  104. package/dist/summaries/index.d.ts +1 -1
  105. package/dist/summaries/manager.d.ts +27 -1
  106. package/dist/tools/approve-retry-sounding-board.d.ts +5 -0
  107. package/dist/tools/index.d.ts +3 -0
  108. package/dist/tools/knowledge-receipt-status.d.ts +8 -0
  109. package/dist/tools/manifest.d.ts +3 -0
  110. package/dist/tools/scope-validate.d.ts +55 -0
  111. package/dist/tools/tool-metadata.d.ts +12 -0
  112. package/dist/types/events.d.ts +5 -1
  113. package/dist/utils/path-security.d.ts +21 -0
  114. package/opencode-swarm.schema.json +14 -0
  115. package/package.json +1 -1
  116. package/dist/cli/curator-llm-factory-zbs6hm60.js +0 -72
  117. package/dist/cli/guardrail-explain-1zy8c3vn.js +0 -73
  118. package/dist/cli/hive-promoter-3dp8qbqc.js +0 -87
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Explicitly-authorized MCP knowledge_add adapter (#2500).
3
+ *
4
+ * This adapter owns only the MCP idempotency boundary. Validation,
5
+ * actionability, deduplication, reinforcement, quarantine, and the atomic
6
+ * knowledge transaction remain in the registered production knowledge_add
7
+ * tool. The adapter passes a fixed server root and never accepts a
8
+ * working-directory override.
9
+ */
10
+ import { type KnowledgeAddAdapterRuntime, knowledgeAddInput } from '../write-receipts.js';
11
+ export interface McpKnowledgeAddWriteAdapter {
12
+ name: 'knowledge_add';
13
+ kind: 'write';
14
+ pathFields: string[];
15
+ inputSchema: typeof knowledgeAddInput;
16
+ execute(rawArgs: unknown, root: string, runtime?: KnowledgeAddAdapterRuntime): Promise<unknown>;
17
+ }
18
+ export declare function executeKnowledgeAdd(rawArgs: unknown, root: string, runtime?: KnowledgeAddAdapterRuntime): Promise<unknown>;
19
+ export declare const knowledgeAddAdapter: McpKnowledgeAddWriteAdapter;
@@ -0,0 +1,3 @@
1
+ /** Read-only MCP status probe for explicitly-authorized knowledge writes. */
2
+ import type { McpReadTool } from '../registry.js';
3
+ export declare const receiptStatusAdapter: McpReadTool;
@@ -0,0 +1,3 @@
1
+ /** Read-only MCP adapter for the inline shell-write scope advisory (#2500). */
2
+ import type { McpReadTool } from '../registry.js';
3
+ export declare const scopeValidationAdapter: McpReadTool;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Tool registry for the read-only MCP verification surface (#2499).
2
+ * Tool registry for the MCP verification surface (#2499, #2500).
3
3
  *
4
4
  * `buildMcpToolRegistry` composes the read-only tool set for ONE configured
5
5
  * project root. Descriptions are sourced from `TOOL_METADATA` — the same
@@ -7,21 +7,20 @@
7
7
  * registered tool names with exact description parity (frozen by
8
8
  * repro/check-mcp-registry-capability-coverage.sh, C2).
9
9
  *
10
- * The write boundary is fail-closed (frozen by
11
- * repro/check-mcp-readonly-default-no-writes.sh, C6): every tool name is
12
- * validated against a write-capable denylist and a match THROWS with or
13
- * without `allowWrite`. Phase 1 ships zero write tools; `allowWrite` is the
14
- * documented forward-compat seam for the #2500 write surface and adds
15
- * nothing today.
10
+ * The write boundary is fail-closed: a write is present only when the caller
11
+ * supplies both the startup capability flag and an exact reviewed tool name.
12
+ * The positive allowlist below is checked again here (rather than trusting the
13
+ * CLI) so direct programmatic callers cannot widen the MCP surface.
16
14
  */
17
15
  import type { z } from 'zod';
16
+ import type { KnowledgeAddAdapterRuntime } from './write-receipts.js';
18
17
  /** Write-capable tool-name shapes. Mirrors the frozen C6 denylist. */
19
18
  export declare const WRITE_TOOL_NAME_PATTERN: RegExp;
20
19
  export interface McpReadTool {
21
20
  /** Registered plugin tool name (a TOOL_METADATA key). */
22
21
  name: string;
23
22
  /** Exact TOOL_METADATA description (parity assigned at build time). */
24
- description: string;
23
+ description?: string;
25
24
  kind: 'read';
26
25
  /** Argument field names carrying file-path values (containment-checked). */
27
26
  pathFields: string[];
@@ -29,19 +28,32 @@ export interface McpReadTool {
29
28
  inputSchema: z.ZodObject<z.ZodRawShape>;
30
29
  execute(args: Record<string, unknown>, root: string): Promise<unknown>;
31
30
  }
31
+ export interface McpWriteTool {
32
+ /** Registered plugin tool name (a TOOL_METADATA key). */
33
+ name: string;
34
+ /** Exact TOOL_METADATA description (parity assigned at build time). */
35
+ description?: string;
36
+ kind: 'write';
37
+ /** Argument field names carrying file-path values (containment-checked). */
38
+ pathFields: string[];
39
+ /** MCP input schema (mirrors the reviewed tool's zod args). */
40
+ inputSchema: z.ZodObject<z.ZodRawShape>;
41
+ execute(args: Record<string, unknown>, root: string, runtime?: KnowledgeAddAdapterRuntime): Promise<unknown>;
42
+ }
43
+ export type McpTool = McpReadTool | McpWriteTool;
32
44
  export interface McpToolRegistry {
33
- tools: McpReadTool[];
45
+ tools: McpTool[];
34
46
  }
35
47
  export interface BuildMcpToolRegistryOptions {
36
48
  /** The single configured project root (one server = one root). */
37
49
  root: string;
38
50
  /** Alias for `root` (accepted for harness compatibility). */
39
51
  directory?: string;
40
- /**
41
- * Forward-compat seam for the #2500 explicitly-authorized write surface.
42
- * Phase 1 has no write tools, so this flag never adds anything; the
43
- * write-name denylist stays fail-closed either way.
44
- */
52
+ /** Startup capability gate. This flag alone never registers a write. */
45
53
  allowWrite?: boolean;
54
+ /** Exact reviewed write names authorized for this server instance. */
55
+ writeTools?: string[];
46
56
  }
57
+ /** The only MCP write adapter reviewed and shipped by #2500. */
58
+ export declare const REVIEWED_MCP_WRITE_TOOLS: readonly ["knowledge_add"];
47
59
  export declare function buildMcpToolRegistry(options: BuildMcpToolRegistryOptions): McpToolRegistry;
@@ -8,6 +8,7 @@
8
8
  * the response pipeline before it leaves the server.
9
9
  */
10
10
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
11
+ import type { KnowledgeAddAdapterRuntime } from './write-receipts.js';
11
12
  /** Containment rejection carried as a tool-level error result. */
12
13
  export declare class McpContainmentError extends Error {
13
14
  readonly field: string;
@@ -20,6 +21,10 @@ export declare function validatePathField(field: string, value: unknown, root: s
20
21
  export interface RunMcpServerOptions {
21
22
  root: string;
22
23
  allowWrite?: boolean;
24
+ /** Exact reviewed write names authorized for this server instance. */
25
+ writeTools?: string[];
26
+ /** Test-only receipt fault and clock hooks. */
27
+ writeHooks?: KnowledgeAddAdapterRuntime['hooks'];
23
28
  /** Test seam: inject transports instead of stdio (InMemoryTransport pair). */
24
29
  transport?: {
25
30
  connect(server: unknown): Promise<void>;
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Durable settlement receipts for explicitly-authorized MCP writes (#2500).
3
+ *
4
+ * The receipt journal is deliberately a separate durability domain from the
5
+ * knowledge store. Its lock is held only while looking up or appending a
6
+ * receipt. A production mutation is always made after PREPARED is durable and
7
+ * outside that lock, so the journal cannot be nested with the knowledge-store
8
+ * transaction lock.
9
+ */
10
+ import { z } from 'zod';
11
+ export declare const MCP_WRITE_RECEIPTS_RELATIVE_PATH: string;
12
+ /**
13
+ * Terminal receipt history is moved here when the active journal reaches its
14
+ * bounded record count. Unresolved records remain active; if an active rewrite
15
+ * fails after archive rotation, a best-effort recovery shadow is written so a
16
+ * newly prepared attempt cannot disappear before mutation.
17
+ */
18
+ export declare const MCP_WRITE_RECEIPTS_ARCHIVE_RELATIVE_PATH: string;
19
+ export declare const PREPARED_LEASE_MS = 30000;
20
+ export declare const MAX_RECEIPT_RECORDS = 500;
21
+ export declare const MAX_RECEIPT_ARCHIVE_RECORDS = 10000;
22
+ export declare const MAX_RECEIPT_LINE_BYTES = 16384;
23
+ export declare const MAX_RECEIPT_JOURNAL_BYTES: number;
24
+ export declare const MAX_RECEIPT_ARCHIVE_BYTES: number;
25
+ export declare const MAX_RECEIPT_RESPONSE_BYTES: number;
26
+ /** Immutable receipt identity version for the reviewed knowledge_add policy. */
27
+ export declare const KNOWLEDGE_ADD_POLICY_VERSION = "knowledge_add:v1";
28
+ export declare const writeReceiptStatusInput: z.ZodObject<{
29
+ idempotency_key: z.ZodString;
30
+ }, z.core.$strip>;
31
+ export declare const WRITE_RECEIPT_STATES: readonly ["PREPARED", "COMMITTED", "FAILED_NO_EFFECT", "IN_DOUBT"];
32
+ export type WriteReceiptState = (typeof WRITE_RECEIPT_STATES)[number];
33
+ export interface WriteReceiptRecord {
34
+ version: 1;
35
+ receipt_id: string;
36
+ attempt_id: string;
37
+ tool: string;
38
+ root_hash: string;
39
+ idempotency_hash: string;
40
+ arguments_digest: string;
41
+ policy_digest: string;
42
+ state: WriteReceiptState;
43
+ prepared_at: number;
44
+ updated_at: number;
45
+ lease_expires_at: number;
46
+ response?: string;
47
+ error?: string;
48
+ }
49
+ export interface WriteReceiptHooks {
50
+ /**
51
+ * Test-only fault seam. It is invoked before each durable transition. The
52
+ * supplied record is already sanitized and contains no raw request fields.
53
+ */
54
+ persistReceipt?: (receipt: WriteReceiptRecord) => Promise<void>;
55
+ /**
56
+ * Test-only fault/order seam. It is invoked immediately before each
57
+ * physical archive or active-journal rewrite. The records are sanitized
58
+ * receipt records and the callback may throw to model an I/O failure.
59
+ */
60
+ persistStorage?: (kind: 'archive' | 'active', records: readonly WriteReceiptRecord[]) => Promise<void>;
61
+ /** Test-only interruption seam after PREPARED is durable. */
62
+ afterPrepare?: (receipt: WriteReceiptRecord) => Promise<void>;
63
+ /** Test-only interruption seam after the production call returns. */
64
+ afterMutation?: (receipt: WriteReceiptRecord) => Promise<void>;
65
+ /** Test-only clock seam. Production uses Date.now. */
66
+ now?: () => number;
67
+ }
68
+ export interface WriteReceiptRequest {
69
+ root: string;
70
+ tool: string;
71
+ idempotencyKey: string;
72
+ arguments: unknown;
73
+ policy?: string;
74
+ }
75
+ export type PrepareReceiptResult = {
76
+ kind: 'prepared';
77
+ receipt: WriteReceiptRecord;
78
+ } | {
79
+ kind: 'replay';
80
+ receipt: WriteReceiptRecord;
81
+ response: unknown;
82
+ } | {
83
+ kind: 'in_progress' | 'in_doubt';
84
+ receipt: WriteReceiptRecord;
85
+ } | {
86
+ kind: 'conflict';
87
+ receipt: WriteReceiptRecord;
88
+ response: unknown;
89
+ };
90
+ export declare class WriteReceiptError extends Error {
91
+ readonly code: 'INVALID_REQUEST' | 'JOURNAL_UNAVAILABLE' | 'JOURNAL_CORRUPT' | 'JOURNAL_CAPACITY' | 'TRANSITION_REJECTED';
92
+ constructor(code: WriteReceiptError['code'], message: string);
93
+ }
94
+ export declare function getWriteReceiptPath(root: string): string;
95
+ export declare function getWriteReceiptArchivePath(root: string): string;
96
+ export declare function canonicalArguments(value: unknown): string;
97
+ export declare function computeWriteReceiptIdentity(request: WriteReceiptRequest): Pick<WriteReceiptRecord, 'root_hash' | 'idempotency_hash' | 'arguments_digest' | 'policy_digest'>;
98
+ export interface WriteReceiptStatus {
99
+ found: boolean;
100
+ status: WriteReceiptState | 'NOT_FOUND';
101
+ tool?: string;
102
+ receipt_id?: string;
103
+ attempt_id?: string;
104
+ updated_at?: number;
105
+ lease_expires_at?: number;
106
+ archived?: boolean;
107
+ /** A missing receipt is safe to submit; every recorded state is not. */
108
+ retryable: boolean;
109
+ }
110
+ export declare function sanitizeReceiptResponse(value: unknown, request?: Pick<WriteReceiptRequest, 'root' | 'idempotencyKey' | 'arguments'>): string;
111
+ export declare function parseReceiptResponse(response: string): unknown;
112
+ /**
113
+ * Read the latest status for one knowledge_add idempotency key without
114
+ * creating a lock or any other project state. Response/error payloads are
115
+ * intentionally omitted: this surface is only an uncertainty/replay probe.
116
+ */
117
+ export declare function readWriteReceiptStatus(root: string, idempotencyKey: string): Promise<WriteReceiptStatus>;
118
+ /**
119
+ * Add fixed receipt metadata to a bounded stored response. The production
120
+ * result remains intact, including success:false; no receipt IDs or request
121
+ * fields are exposed to the MCP client.
122
+ */
123
+ export declare function addReplayMarker(value: unknown): unknown;
124
+ /**
125
+ * Look up or durably prepare one write attempt. The returned PREPARED record
126
+ * owns the attempt. Callers MUST release the receipt transition lock before
127
+ * invoking production code, then call commitReceipt or markInDoubt.
128
+ */
129
+ export declare function prepareReceipt(request: WriteReceiptRequest, hooks?: WriteReceiptHooks): Promise<PrepareReceiptResult>;
130
+ export declare function commitReceipt(request: WriteReceiptRequest, attempt: WriteReceiptRecord, response: unknown, hooks?: WriteReceiptHooks): Promise<WriteReceiptRecord>;
131
+ export declare function markInDoubt(request: WriteReceiptRequest, attempt: WriteReceiptRecord, error: string, hooks?: WriteReceiptHooks): Promise<WriteReceiptRecord>;
132
+ /**
133
+ * Adapter-facing execution helper. It owns the prepare/call/settle sequence
134
+ * but accepts the production operation as a callback so the registry can
135
+ * provide knowledge_add without duplicating its logic.
136
+ */
137
+ export declare function executeWithReceipt<T>(request: WriteReceiptRequest, operation: () => Promise<T>, hooks?: WriteReceiptHooks): Promise<unknown>;
138
+ export declare const knowledgeAddInput: z.ZodObject<{
139
+ idempotency_key: z.ZodString;
140
+ lesson: z.ZodString;
141
+ category: z.ZodEnum<{
142
+ security: "security";
143
+ other: "other";
144
+ process: "process";
145
+ architecture: "architecture";
146
+ tooling: "tooling";
147
+ testing: "testing";
148
+ debugging: "debugging";
149
+ performance: "performance";
150
+ integration: "integration";
151
+ todo: "todo";
152
+ }>;
153
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
154
+ scope: z.ZodOptional<z.ZodString>;
155
+ applies_to_agents: z.ZodOptional<z.ZodArray<z.ZodString>>;
156
+ applies_to_tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
157
+ required_actions: z.ZodOptional<z.ZodArray<z.ZodString>>;
158
+ forbidden_actions: z.ZodOptional<z.ZodArray<z.ZodString>>;
159
+ verification_checks: z.ZodOptional<z.ZodArray<z.ZodString>>;
160
+ }, z.core.$strict>;
161
+ export interface KnowledgeAddAdapterRuntime {
162
+ hooks?: WriteReceiptHooks;
163
+ policy?: string;
164
+ }
165
+ export declare function buildKnowledgeAddRequest(root: string, rawArgs: unknown, runtime?: KnowledgeAddAdapterRuntime): {
166
+ request: WriteReceiptRequest;
167
+ productionArgs: Record<string, unknown>;
168
+ };
@@ -1,2 +1,2 @@
1
- export { cleanupSummaries, listSummaries, loadFullOutput, storeSummary, } from './manager';
1
+ export { allocateSummaryId, cleanupSummaries, listSummaries, loadFullOutput, SummaryIdCollisionError, storeSummary, } from './manager';
2
2
  export { createSummary, detectContentType, HYSTERESIS_FACTOR, shouldSummarize, } from './summarizer';
@@ -5,9 +5,20 @@
5
5
  * @throws Error with descriptive message on failure
6
6
  */
7
7
  export declare function sanitizeSummaryId(id: string): string;
8
+ /**
9
+ * Typed collision signal for the no-overwrite store contract (issue #2576):
10
+ * the destination summary entry already exists and must never be replaced.
11
+ * Callers distinguish this from storage errors by `instanceof` (or `name`).
12
+ */
13
+ export declare class SummaryIdCollisionError extends Error {
14
+ readonly summaryId: string;
15
+ constructor(summaryId: string);
16
+ }
8
17
  /**
9
18
  * Store a summary entry to .swarm/summaries/{id}.json.
10
- * Performs atomic write via temp file + rename.
19
+ * Performs an atomic, no-overwrite install: temp file + exclusive
20
+ * hard-link install. Throws {@link SummaryIdCollisionError} if an entry
21
+ * with this ID already exists (it is never replaced — issue #2576).
11
22
  * @throws Error if summary ID is invalid or size limit would be exceeded
12
23
  */
13
24
  export declare function storeSummary(directory: string, id: string, fullOutput: string, summaryText: string, maxStoredBytes: number): Promise<void>;
@@ -26,6 +37,21 @@ export declare function loadFullOutput(directory: string, id: string): Promise<s
26
37
  * directory directly so stale files beyond the newest N are still pruned.
27
38
  */
28
39
  export declare const MAX_SUMMARIES_LISTED = 500;
40
+ /**
41
+ * Durable summary ID allocation (issue #2576): returns the next free numeric
42
+ * ID (`S<max+1>`) derived from the entries that actually exist on disk, so a
43
+ * restarted process continues after persisted IDs instead of reusing `S1`.
44
+ *
45
+ * The scan uses the strict write-side grammar (`^S\d+`) via
46
+ * {@link enumerateSummaryIds} — large timestamp-suffixed IDs (e.g. Stage A's
47
+ * `S<ms><random>`) match and are included; filenames outside the grammar are
48
+ * ignored. The max is computed with BigInt so 16-digit IDs stay exact past
49
+ * 2^53 (a float max could alias two distinct large IDs and hand the retry
50
+ * loop an already-occupied slot); `max + 1n` always stringifies back to a
51
+ * valid `^S\d+$` ID, and leading-zero legacy entries (`S007`) normalize
52
+ * numerically so allocation never regresses.
53
+ */
54
+ export declare function allocateSummaryId(directory: string): string;
29
55
  /**
30
56
  * List summary IDs that have summary entries, newest-first (mtime
31
57
  * descending, code-unit filename tie-break), capped at
@@ -0,0 +1,5 @@
1
+ import { createSwarmTool } from './create-tool.js';
2
+ export declare function executeApproveRetrySoundingBoard(args: unknown, directory: string, context?: {
3
+ sessionID?: string;
4
+ }): Promise<string>;
5
+ export declare const approve_retry_sounding_board: ReturnType<typeof createSwarmTool>;
@@ -42,6 +42,7 @@ export { knowledge_archive } from './knowledge-archive';
42
42
  export { knowledge_query } from './knowledge-query';
43
43
  export { knowledge_recall } from './knowledge-recall';
44
44
  export { knowledge_receipt } from './knowledge-receipt';
45
+ export { knowledge_receipt_status } from './knowledge-receipt-status';
45
46
  export { knowledge_remove } from './knowledge-remove';
46
47
  export { lint } from './lint';
47
48
  export { osv_scan } from './osv-scan';
@@ -68,6 +69,7 @@ export type { SavePlanArgs, SavePlanResult } from './save-plan';
68
69
  export { save_plan } from './save-plan';
69
70
  export { type SbomGenerateInput, type SbomGenerateResult, sbom_generate, } from './sbom-generate';
70
71
  export { schema_drift } from './schema-drift';
72
+ export { evaluateScopeValidate, type ScopeValidateArgs, type ScopeValidateResult, ScopeValidationError, scope_validate, } from './scope-validate';
71
73
  export { search } from './search';
72
74
  export { type SecretFinding, type SecretscanResult, secretscan, } from './secretscan';
73
75
  export { set_qa_gates } from './set-qa-gates';
@@ -98,6 +100,7 @@ export type { FlakyTestEntry } from '../test-impact/flaky-detector.js';
98
100
  export { computeFlakyScore, detectFlakyTests, isTestQuarantined, } from '../test-impact/flaky-detector.js';
99
101
  export { abort_pr_workflow, executeAbortPrWorkflow, } from './abort-pr-workflow';
100
102
  export { approve_plan_critic, executeApprovePlanCritic, } from './approve-plan-critic';
103
+ export { approve_retry_sounding_board, executeApproveRetrySoundingBoard, } from './approve-retry-sounding-board';
101
104
  export { authorize_pr_review_reentry } from './authorize-pr-review-reentry';
102
105
  export { complete_pr_workflow, executeCompletePrWorkflow, } from './complete-pr-workflow';
103
106
  export { epic_plan_waves } from './epic-plan-waves';
@@ -0,0 +1,8 @@
1
+ /** Read-only status for an explicitly-authorized MCP knowledge write receipt. */
2
+ import { createSwarmTool } from './create-tool.js';
3
+ export declare const knowledge_receipt_status: ReturnType<typeof createSwarmTool>;
4
+ export declare const _test_exports: {
5
+ writeReceiptStatusInput: import("zod").ZodObject<{
6
+ idempotency_key: import("zod").ZodString;
7
+ }, import("zod/v4/core").$strip>;
8
+ };
@@ -47,6 +47,7 @@ export declare const TOOL_MANIFEST: {
47
47
  authorize_pr_review_reentry: () => ToolDefinition;
48
48
  submit_pr_review_result: () => ToolDefinition;
49
49
  approve_plan_critic: () => ToolDefinition;
50
+ approve_retry_sounding_board: () => ToolDefinition;
50
51
  prepare_pr_workflow_checkout: () => ToolDefinition;
51
52
  record_implementation_review: () => ToolDefinition;
52
53
  record_issue_publication: () => ToolDefinition;
@@ -89,6 +90,7 @@ export declare const TOOL_MANIFEST: {
89
90
  write_hallucination_evidence: () => ToolDefinition;
90
91
  write_mutation_evidence: () => ToolDefinition;
91
92
  declare_scope: () => ToolDefinition;
93
+ scope_validate: () => ToolDefinition;
92
94
  knowledge_query: () => ToolDefinition;
93
95
  doc_scan: () => ToolDefinition;
94
96
  doc_extract: () => ToolDefinition;
@@ -126,6 +128,7 @@ export declare const TOOL_MANIFEST: {
126
128
  skill_improve: () => ToolDefinition;
127
129
  spec_write: () => ToolDefinition;
128
130
  knowledge_receipt: () => ToolDefinition;
131
+ knowledge_receipt_status: () => ToolDefinition;
129
132
  knowledge_archive: () => ToolDefinition;
130
133
  swarm_memory_recall: () => ToolDefinition;
131
134
  swarm_memory_propose: () => ToolDefinition;
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Read-only shell-write scope advisory for the MCP surface (#2500).
3
+ *
4
+ * This tool is deliberately an evaluator only. It never executes a command,
5
+ * publishes an OpenCode scope binding, or persists any state. The decision is
6
+ * composed from the same classifier, write detector, containment, and file
7
+ * authority helpers used by the live guardrails.
8
+ */
9
+ import { z } from 'zod';
10
+ import { createSwarmTool } from './create-tool';
11
+ export declare const scopeValidateArgs: {
12
+ command: z.ZodString;
13
+ shell: z.ZodEnum<{
14
+ powershell: "powershell";
15
+ cmd: "cmd";
16
+ posix: "posix";
17
+ }>;
18
+ scope_files: z.ZodArray<z.ZodString>;
19
+ };
20
+ export declare const scopeValidateSchema: z.ZodObject<{
21
+ command: z.ZodString;
22
+ shell: z.ZodEnum<{
23
+ powershell: "powershell";
24
+ cmd: "cmd";
25
+ posix: "posix";
26
+ }>;
27
+ scope_files: z.ZodArray<z.ZodString>;
28
+ }, z.core.$strip>;
29
+ export type ScopeValidateArgs = {
30
+ command: string;
31
+ shell: 'posix' | 'powershell' | 'cmd';
32
+ scope_files: string[];
33
+ };
34
+ export interface ScopeValidateTarget {
35
+ category: string;
36
+ operator: string;
37
+ path: string;
38
+ }
39
+ export interface ScopeValidateResult {
40
+ allowed: true;
41
+ shell: ScopeValidateArgs['shell'];
42
+ command_digest: string;
43
+ targets: ScopeValidateTarget[];
44
+ }
45
+ export declare class ScopeValidationError extends Error {
46
+ readonly code: string;
47
+ constructor(code: string, message: string);
48
+ }
49
+ /**
50
+ * Evaluate a shell command against an inline scope without executing it.
51
+ * Every filesystem path is checked against the supplied root and scope before
52
+ * a successful result is returned.
53
+ */
54
+ export declare function evaluateScopeValidate(args: ScopeValidateArgs, directory: string): ScopeValidateResult;
55
+ export declare const scope_validate: ReturnType<typeof createSwarmTool>;
@@ -173,6 +173,10 @@ export declare const TOOL_METADATA: {
173
173
  description: string;
174
174
  agents: "architect"[];
175
175
  };
176
+ approve_retry_sounding_board: {
177
+ description: string;
178
+ agents: "architect"[];
179
+ };
176
180
  prepare_pr_workflow_checkout: {
177
181
  description: string;
178
182
  agents: "architect"[];
@@ -369,6 +373,10 @@ export declare const TOOL_METADATA: {
369
373
  description: string;
370
374
  agents: "architect"[];
371
375
  };
376
+ scope_validate: {
377
+ description: string;
378
+ agents: "architect"[];
379
+ };
372
380
  knowledge_query: {
373
381
  description: string;
374
382
  agents: ("architect" | "skill_improver" | "spec_writer")[];
@@ -537,6 +545,10 @@ export declare const TOOL_METADATA: {
537
545
  description: string;
538
546
  agents: ("reviewer" | "test_engineer" | "coder" | "critic" | "critic_finding_validator" | "architect" | "sme" | "docs" | "docs_design" | "designer" | "critic_sounding_board" | "critic_drift_verifier" | "critic_hallucination_verifier" | "critic_architecture_supervisor" | "curator_init" | "curator_phase" | "skill_improver" | "spec_writer")[];
539
547
  };
548
+ knowledge_receipt_status: {
549
+ description: string;
550
+ agents: "architect"[];
551
+ };
540
552
  knowledge_archive: {
541
553
  description: string;
542
554
  agents: "architect"[];
@@ -52,7 +52,11 @@ export interface CoderRetryCircuitBreakerEvent {
52
52
  rejectionCount: number;
53
53
  rejectionHistory: string[];
54
54
  phase: number;
55
- action: 'sounding_board_consultation' | 'simplification' | 'user_escalation';
55
+ action: 'sounding_board_consultation' | 'simplification' | 'user_escalation' | 'sounding_board_manual_approval';
56
+ /** Present only on sounding_board_manual_approval (issue #2703): the
57
+ * architect-stated justification for the manual override, bounded to 500
58
+ * chars by the recorder. */
59
+ reason?: string;
56
60
  }
57
61
  export interface AgentConflictDetectedEvent {
58
62
  type: 'agent_conflict_detected';
@@ -175,6 +175,27 @@ export declare function validateSymlinkBoundary(targetPath: string, rootPath: st
175
175
  * @returns true if the canonical target is within the canonical root
176
176
  */
177
177
  export declare function isCanonicalPathWithinRoot(targetPath: string, rootPath: string): boolean;
178
+ /**
179
+ * Build a canonical containment checker for a single root.
180
+ *
181
+ * Scope validation may check thousands of entries against one workspace root.
182
+ * Calling `isCanonicalPathWithinRoot` for every entry re-resolves the same root
183
+ * and the same existing ancestors, which turns an otherwise linear validation
184
+ * into a synchronous filesystem bottleneck. This checker keeps the root and
185
+ * observed ancestors local to one evaluation, and only canonicalizes entries
186
+ * that are actually links. A regular entry beneath a non-link ancestor is
187
+ * already lexically inside the validated root; canonicalizing it adds no
188
+ * security signal. Missing entries still walk to the nearest existing
189
+ * ancestor, so a symlinked directory cannot be used to escape the root.
190
+ *
191
+ * The cache is deliberately per-checker (never module-global) and bounded.
192
+ */
193
+ export declare function createCanonicalPathWithinRootChecker(rootPath: string): (targetPath: string) => boolean;
194
+ /**
195
+ * Build a relative-target validator that reuses one canonical root and its
196
+ * observed ancestor cache across a batch of paths.
197
+ */
198
+ export declare function createTargetWithinRootValidator(root: string): (filePath: string) => string | null;
178
199
  /**
179
200
  * Validate that a caller-supplied path stays within an allowed root directory.
180
201
  * Rejects empty paths, absolute paths (POSIX + Windows drive), traversal,
@@ -5400,6 +5400,20 @@
5400
5400
  }
5401
5401
  },
5402
5402
  "additionalProperties": false
5403
+ },
5404
+ "dashboard": {
5405
+ "description": "Opt-in local mission-control dashboard over durable swarm state (issue #2509). Disabled by default; set port > 0 to enable the loopback-only read-only view.",
5406
+ "type": "object",
5407
+ "properties": {
5408
+ "port": {
5409
+ "default": 0,
5410
+ "description": "Loopback port for the opt-in local dashboard (issue #2509). 0 or absent = disabled (default).",
5411
+ "type": "integer",
5412
+ "minimum": 0,
5413
+ "maximum": 65535
5414
+ }
5415
+ },
5416
+ "additionalProperties": false
5403
5417
  }
5404
5418
  },
5405
5419
  "additionalProperties": false
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.177.0",
3
+ "version": "7.178.0",
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",
@@ -1,72 +0,0 @@
1
- // @bun
2
- import {
3
- createCuratorLLMDelegate
4
- } from "./index-ebmep9me.js";
5
- import"./index-hnvmj9wx.js";
6
- import"./index-vfp9hjgv.js";
7
- import"./index-by7xpk8f.js";
8
- import"./index-eefz8ghz.js";
9
- import"./index-rgapg88w.js";
10
- import"./index-zbq9091c.js";
11
- import"./index-k6bjkqw8.js";
12
- import"./index-txdagbh7.js";
13
- import"./index-n1tcj1q7.js";
14
- import"./index-fpbcxykc.js";
15
- import"./index-mcq6xs4k.js";
16
- import"./index-8dy3qf4q.js";
17
- import"./index-nzz58tbs.js";
18
- import"./index-fyfbpz4f.js";
19
- import"./index-eya03h5m.js";
20
- import"./index-549wxbe1.js";
21
- import"./index-zsrtt42s.js";
22
- import"./index-4chr4gbq.js";
23
- import"./index-5d2avnj9.js";
24
- import"./index-7nsvszwn.js";
25
- import"./index-pt7h91zc.js";
26
- import"./index-q7sjgr1y.js";
27
- import"./index-r18n5f17.js";
28
- import"./index-fnmt1ema.js";
29
- import"./index-ef2fa774.js";
30
- import"./index-w7aedfce.js";
31
- import"./index-exhm2ztr.js";
32
- import"./index-2s7dvzff.js";
33
- import"./index-gwnbprzk.js";
34
- import"./index-wemtrnch.js";
35
- import"./index-rtry5xyf.js";
36
- import"./index-rz4gpt3n.js";
37
- import"./index-frcemc0b.js";
38
- import"./index-wrt875kh.js";
39
- import"./index-5w51tawb.js";
40
- import"./index-zwam9stk.js";
41
- import"./index-z8j7jqxt.js";
42
- import"./index-v2he8xfj.js";
43
- import"./index-1bq6hkw5.js";
44
- import"./index-xnednxvm.js";
45
- import"./index-rdm3px0g.js";
46
- import"./index-ry16d01s.js";
47
- import"./index-tbswvz8s.js";
48
- import"./index-hxdswvtv.js";
49
- import"./index-vzm6zre7.js";
50
- import"./index-ae75rja9.js";
51
- import"./index-en0p0hqp.js";
52
- import"./index-tj0sdxg9.js";
53
- import"./index-7g4c7s5r.js";
54
- import"./index-2jtmevrr.js";
55
- import"./index-yhaxn5r7.js";
56
- import"./index-1xnse449.js";
57
- import"./index-c1ggtmpm.js";
58
- import"./index-zzr7f594.js";
59
- import"./index-zz7gzw57.js";
60
- import"./index-4ddpvd5c.js";
61
- import"./index-73arkdgf.js";
62
- import"./index-5frh43fj.js";
63
- import"./index-bk5tah7q.js";
64
- import"./index-gknz3bv1.js";
65
- import"./index-zpsr8rpc.js";
66
- import"./index-76qm2c2y.js";
67
- import"./index-yzjaj53h.js";
68
- import"./index-zgwm4ryv.js";
69
- import"./index-a76rekgs.js";
70
- export {
71
- createCuratorLLMDelegate
72
- };