@sw4rm/js-sdk 0.3.0 → 0.5.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 (37) hide show
  1. package/README.md +13 -0
  2. package/dist/cjs/index.cjs +3576 -342
  3. package/dist/esm/index.js +3497 -336
  4. package/dist/types/agentConfig.d.ts +245 -0
  5. package/dist/types/audit.d.ts +214 -0
  6. package/dist/types/clients/handoff.d.ts +188 -0
  7. package/dist/types/clients/negotiationRoom.d.ts +423 -0
  8. package/dist/types/clients/negotiationRoomStore.d.ts +155 -0
  9. package/dist/types/clients/workflow.d.ts +316 -0
  10. package/dist/types/constants/index.d.ts +100 -0
  11. package/dist/types/index.d.ts +15 -4
  12. package/dist/types/internal/baseClient.d.ts +7 -1
  13. package/dist/types/internal/envelope.d.ts +16 -0
  14. package/dist/types/internal/errorMapping.d.ts +114 -0
  15. package/dist/types/internal/worktreeState.d.ts +60 -0
  16. package/dist/types/persistentActivityBuffer.d.ts +94 -0
  17. package/dist/types/runtime/agentState.d.ts +205 -0
  18. package/dist/types/runtime/policyStore.d.ts +391 -0
  19. package/dist/types/runtime/voting.d.ts +208 -0
  20. package/package.json +4 -2
  21. package/protos/activity.proto +24 -0
  22. package/protos/common.proto +134 -0
  23. package/protos/connector.proto +29 -0
  24. package/protos/handoff.proto +63 -0
  25. package/protos/hitl.proto +23 -0
  26. package/protos/logging.proto +20 -0
  27. package/protos/negotiation.proto +57 -0
  28. package/protos/negotiation_room.proto +220 -0
  29. package/protos/policy.proto +55 -0
  30. package/protos/reasoning.proto +41 -0
  31. package/protos/registry.proto +36 -0
  32. package/protos/router.proto +16 -0
  33. package/protos/scheduler.proto +52 -0
  34. package/protos/scheduler_policy.proto +36 -0
  35. package/protos/tool.proto +47 -0
  36. package/protos/workflow.proto +116 -0
  37. package/protos/worktree.proto +33 -0
@@ -1859,7 +1859,7 @@ var require_fetch = __commonJS({
1859
1859
  module2.exports = fetch;
1860
1860
  var asPromise = require_aspromise();
1861
1861
  var inquire2 = require_inquire();
1862
- var fs = inquire2("fs");
1862
+ var fs3 = inquire2("fs");
1863
1863
  function fetch(filename, options, callback) {
1864
1864
  if (typeof options === "function") {
1865
1865
  callback = options;
@@ -1868,8 +1868,8 @@ var require_fetch = __commonJS({
1868
1868
  options = {};
1869
1869
  if (!callback)
1870
1870
  return asPromise(fetch, this, filename, options);
1871
- if (!options.xhr && fs && fs.readFile)
1872
- return fs.readFile(filename, function fetchReadFileCallback(err, contents) {
1871
+ if (!options.xhr && fs3 && fs3.readFile)
1872
+ return fs3.readFile(filename, function fetchReadFileCallback(err, contents) {
1873
1873
  return err && typeof XMLHttpRequest !== "undefined" ? fetch.xhr(filename, options, callback) : err ? callback(err) : callback(null, options.binary ? contents : contents.toString("utf8"));
1874
1874
  });
1875
1875
  return fetch.xhr(filename, options, callback);
@@ -1907,15 +1907,15 @@ var require_fetch = __commonJS({
1907
1907
  var require_path = __commonJS({
1908
1908
  "node_modules/@protobufjs/path/index.js"(exports2) {
1909
1909
  "use strict";
1910
- var path3 = exports2;
1910
+ var path5 = exports2;
1911
1911
  var isAbsolute = (
1912
1912
  /**
1913
1913
  * Tests if the specified path is absolute.
1914
1914
  * @param {string} path Path to test
1915
1915
  * @returns {boolean} `true` if path is absolute
1916
1916
  */
1917
- path3.isAbsolute = function isAbsolute2(path4) {
1918
- return /^(?:\/|\w+:)/.test(path4);
1917
+ path5.isAbsolute = function isAbsolute2(path6) {
1918
+ return /^(?:\/|\w+:)/.test(path6);
1919
1919
  }
1920
1920
  );
1921
1921
  var normalize = (
@@ -1924,9 +1924,9 @@ var require_path = __commonJS({
1924
1924
  * @param {string} path Path to normalize
1925
1925
  * @returns {string} Normalized path
1926
1926
  */
1927
- path3.normalize = function normalize2(path4) {
1928
- path4 = path4.replace(/\\/g, "/").replace(/\/{2,}/g, "/");
1929
- var parts = path4.split("/"), absolute = isAbsolute(path4), prefix = "";
1927
+ path5.normalize = function normalize2(path6) {
1928
+ path6 = path6.replace(/\\/g, "/").replace(/\/{2,}/g, "/");
1929
+ var parts = path6.split("/"), absolute = isAbsolute(path6), prefix = "";
1930
1930
  if (absolute)
1931
1931
  prefix = parts.shift() + "/";
1932
1932
  for (var i = 0; i < parts.length; ) {
@@ -1945,7 +1945,7 @@ var require_path = __commonJS({
1945
1945
  return prefix + parts.join("/");
1946
1946
  }
1947
1947
  );
1948
- path3.resolve = function resolve(originPath, includePath, alreadyNormalized) {
1948
+ path5.resolve = function resolve(originPath, includePath, alreadyNormalized) {
1949
1949
  if (!alreadyNormalized)
1950
1950
  includePath = normalize(includePath);
1951
1951
  if (isAbsolute(includePath))
@@ -2096,16 +2096,16 @@ var require_namespace = __commonJS({
2096
2096
  object.onRemove(this);
2097
2097
  return clearCache(this);
2098
2098
  };
2099
- Namespace.prototype.define = function define2(path3, json) {
2100
- if (util.isString(path3))
2101
- path3 = path3.split(".");
2102
- else if (!Array.isArray(path3))
2099
+ Namespace.prototype.define = function define2(path5, json) {
2100
+ if (util.isString(path5))
2101
+ path5 = path5.split(".");
2102
+ else if (!Array.isArray(path5))
2103
2103
  throw TypeError("illegal path");
2104
- if (path3 && path3.length && path3[0] === "")
2104
+ if (path5 && path5.length && path5[0] === "")
2105
2105
  throw Error("path must be relative");
2106
2106
  var ptr = this;
2107
- while (path3.length > 0) {
2108
- var part = path3.shift();
2107
+ while (path5.length > 0) {
2108
+ var part = path5.shift();
2109
2109
  if (ptr.nested && ptr.nested[part]) {
2110
2110
  ptr = ptr.nested[part];
2111
2111
  if (!(ptr instanceof Namespace))
@@ -2142,26 +2142,26 @@ var require_namespace = __commonJS({
2142
2142
  });
2143
2143
  return this;
2144
2144
  };
2145
- Namespace.prototype.lookup = function lookup(path3, filterTypes, parentAlreadyChecked) {
2145
+ Namespace.prototype.lookup = function lookup(path5, filterTypes, parentAlreadyChecked) {
2146
2146
  if (typeof filterTypes === "boolean") {
2147
2147
  parentAlreadyChecked = filterTypes;
2148
2148
  filterTypes = void 0;
2149
2149
  } else if (filterTypes && !Array.isArray(filterTypes))
2150
2150
  filterTypes = [filterTypes];
2151
- if (util.isString(path3) && path3.length) {
2152
- if (path3 === ".")
2151
+ if (util.isString(path5) && path5.length) {
2152
+ if (path5 === ".")
2153
2153
  return this.root;
2154
- path3 = path3.split(".");
2155
- } else if (!path3.length)
2154
+ path5 = path5.split(".");
2155
+ } else if (!path5.length)
2156
2156
  return this;
2157
- var flatPath = path3.join(".");
2158
- if (path3[0] === "")
2159
- return this.root.lookup(path3.slice(1), filterTypes);
2157
+ var flatPath = path5.join(".");
2158
+ if (path5[0] === "")
2159
+ return this.root.lookup(path5.slice(1), filterTypes);
2160
2160
  var found = this.root._fullyQualifiedObjects && this.root._fullyQualifiedObjects["." + flatPath];
2161
2161
  if (found && (!filterTypes || filterTypes.indexOf(found.constructor) > -1)) {
2162
2162
  return found;
2163
2163
  }
2164
- found = this._lookupImpl(path3, flatPath);
2164
+ found = this._lookupImpl(path5, flatPath);
2165
2165
  if (found && (!filterTypes || filterTypes.indexOf(found.constructor) > -1)) {
2166
2166
  return found;
2167
2167
  }
@@ -2169,7 +2169,7 @@ var require_namespace = __commonJS({
2169
2169
  return null;
2170
2170
  var current = this;
2171
2171
  while (current.parent) {
2172
- found = current.parent._lookupImpl(path3, flatPath);
2172
+ found = current.parent._lookupImpl(path5, flatPath);
2173
2173
  if (found && (!filterTypes || filterTypes.indexOf(found.constructor) > -1)) {
2174
2174
  return found;
2175
2175
  }
@@ -2177,49 +2177,49 @@ var require_namespace = __commonJS({
2177
2177
  }
2178
2178
  return null;
2179
2179
  };
2180
- Namespace.prototype._lookupImpl = function lookup(path3, flatPath) {
2180
+ Namespace.prototype._lookupImpl = function lookup(path5, flatPath) {
2181
2181
  if (Object.prototype.hasOwnProperty.call(this._lookupCache, flatPath)) {
2182
2182
  return this._lookupCache[flatPath];
2183
2183
  }
2184
- var found = this.get(path3[0]);
2184
+ var found = this.get(path5[0]);
2185
2185
  var exact = null;
2186
2186
  if (found) {
2187
- if (path3.length === 1) {
2187
+ if (path5.length === 1) {
2188
2188
  exact = found;
2189
2189
  } else if (found instanceof Namespace) {
2190
- path3 = path3.slice(1);
2191
- exact = found._lookupImpl(path3, path3.join("."));
2190
+ path5 = path5.slice(1);
2191
+ exact = found._lookupImpl(path5, path5.join("."));
2192
2192
  }
2193
2193
  } else {
2194
2194
  for (var i = 0; i < this.nestedArray.length; ++i)
2195
- if (this._nestedArray[i] instanceof Namespace && (found = this._nestedArray[i]._lookupImpl(path3, flatPath)))
2195
+ if (this._nestedArray[i] instanceof Namespace && (found = this._nestedArray[i]._lookupImpl(path5, flatPath)))
2196
2196
  exact = found;
2197
2197
  }
2198
2198
  this._lookupCache[flatPath] = exact;
2199
2199
  return exact;
2200
2200
  };
2201
- Namespace.prototype.lookupType = function lookupType(path3) {
2202
- var found = this.lookup(path3, [Type]);
2201
+ Namespace.prototype.lookupType = function lookupType(path5) {
2202
+ var found = this.lookup(path5, [Type]);
2203
2203
  if (!found)
2204
- throw Error("no such type: " + path3);
2204
+ throw Error("no such type: " + path5);
2205
2205
  return found;
2206
2206
  };
2207
- Namespace.prototype.lookupEnum = function lookupEnum(path3) {
2208
- var found = this.lookup(path3, [Enum]);
2207
+ Namespace.prototype.lookupEnum = function lookupEnum(path5) {
2208
+ var found = this.lookup(path5, [Enum]);
2209
2209
  if (!found)
2210
- throw Error("no such Enum '" + path3 + "' in " + this);
2210
+ throw Error("no such Enum '" + path5 + "' in " + this);
2211
2211
  return found;
2212
2212
  };
2213
- Namespace.prototype.lookupTypeOrEnum = function lookupTypeOrEnum(path3) {
2214
- var found = this.lookup(path3, [Type, Enum]);
2213
+ Namespace.prototype.lookupTypeOrEnum = function lookupTypeOrEnum(path5) {
2214
+ var found = this.lookup(path5, [Type, Enum]);
2215
2215
  if (!found)
2216
- throw Error("no such Type or Enum '" + path3 + "' in " + this);
2216
+ throw Error("no such Type or Enum '" + path5 + "' in " + this);
2217
2217
  return found;
2218
2218
  };
2219
- Namespace.prototype.lookupService = function lookupService(path3) {
2220
- var found = this.lookup(path3, [Service]);
2219
+ Namespace.prototype.lookupService = function lookupService(path5) {
2220
+ var found = this.lookup(path5, [Service]);
2221
2221
  if (!found)
2222
- throw Error("no such Service '" + path3 + "' in " + this);
2222
+ throw Error("no such Service '" + path5 + "' in " + this);
2223
2223
  return found;
2224
2224
  };
2225
2225
  Namespace._configure = function(Type_, Service_, Enum_) {
@@ -3620,14 +3620,14 @@ var require_util = __commonJS({
3620
3620
  Object.defineProperty(object, "$type", { value: enm, enumerable: false });
3621
3621
  return enm;
3622
3622
  };
3623
- util.setProperty = function setProperty(dst, path3, value, ifNotSet) {
3624
- function setProp(dst2, path4, value2) {
3625
- var part = path4.shift();
3623
+ util.setProperty = function setProperty(dst, path5, value, ifNotSet) {
3624
+ function setProp(dst2, path6, value2) {
3625
+ var part = path6.shift();
3626
3626
  if (part === "__proto__" || part === "prototype") {
3627
3627
  return dst2;
3628
3628
  }
3629
- if (path4.length > 0) {
3630
- dst2[part] = setProp(dst2[part] || {}, path4, value2);
3629
+ if (path6.length > 0) {
3630
+ dst2[part] = setProp(dst2[part] || {}, path6, value2);
3631
3631
  } else {
3632
3632
  var prevValue = dst2[part];
3633
3633
  if (prevValue && ifNotSet)
@@ -3640,10 +3640,10 @@ var require_util = __commonJS({
3640
3640
  }
3641
3641
  if (typeof dst !== "object")
3642
3642
  throw TypeError("dst must be an object");
3643
- if (!path3)
3643
+ if (!path5)
3644
3644
  throw TypeError("path must be specified");
3645
- path3 = path3.split(".");
3646
- return setProp(dst, path3, value);
3645
+ path5 = path5.split(".");
3646
+ return setProp(dst, path5, value);
3647
3647
  };
3648
3648
  Object.defineProperty(util, "decorateRoot", {
3649
3649
  get: function() {
@@ -4190,12 +4190,12 @@ var require_object = __commonJS({
4190
4190
  */
4191
4191
  fullName: {
4192
4192
  get: function() {
4193
- var path3 = [this.name], ptr = this.parent;
4193
+ var path5 = [this.name], ptr = this.parent;
4194
4194
  while (ptr) {
4195
- path3.unshift(ptr.name);
4195
+ path5.unshift(ptr.name);
4196
4196
  ptr = ptr.parent;
4197
4197
  }
4198
- return path3.join(".");
4198
+ return path5.join(".");
4199
4199
  }
4200
4200
  }
4201
4201
  });
@@ -8177,19 +8177,19 @@ var require_util2 = __commonJS({
8177
8177
  "use strict";
8178
8178
  Object.defineProperty(exports2, "__esModule", { value: true });
8179
8179
  exports2.addCommonProtos = exports2.loadProtosWithOptionsSync = exports2.loadProtosWithOptions = void 0;
8180
- var fs = require("fs");
8181
- var path3 = require("path");
8180
+ var fs3 = require("fs");
8181
+ var path5 = require("path");
8182
8182
  var Protobuf = require_protobufjs();
8183
8183
  function addIncludePathResolver(root, includePaths) {
8184
8184
  const originalResolvePath = root.resolvePath;
8185
8185
  root.resolvePath = (origin, target) => {
8186
- if (path3.isAbsolute(target)) {
8186
+ if (path5.isAbsolute(target)) {
8187
8187
  return target;
8188
8188
  }
8189
8189
  for (const directory of includePaths) {
8190
- const fullPath = path3.join(directory, target);
8190
+ const fullPath = path5.join(directory, target);
8191
8191
  try {
8192
- fs.accessSync(fullPath, fs.constants.R_OK);
8192
+ fs3.accessSync(fullPath, fs3.constants.R_OK);
8193
8193
  return fullPath;
8194
8194
  } catch (err) {
8195
8195
  continue;
@@ -9483,31 +9483,71 @@ var require_src2 = __commonJS({
9483
9483
  var src_exports = {};
9484
9484
  __export(src_exports, {
9485
9485
  ACKLifecycleManager: () => ACKLifecycleManager,
9486
- AckStage: () => AckStage,
9486
+ AckStage: () => AckStage2,
9487
9487
  ActivityBuffer: () => ActivityBuffer,
9488
9488
  ActivityBufferSync: () => ActivityBufferSync,
9489
9489
  ActivityClient: () => ActivityClient,
9490
+ AgentState: () => AgentState,
9491
+ AgentStateMachine: () => AgentStateMachine,
9492
+ ArtifactType: () => ArtifactType,
9490
9493
  BaseClient: () => BaseClient,
9494
+ BordaCountAggregator: () => BordaCountAggregator,
9495
+ BufferFullError: () => BufferFullError,
9491
9496
  CT_AGENT_REPORT_V1: () => CT_AGENT_REPORT_V1,
9492
9497
  CT_SCHEDULER_COMMAND_V1: () => CT_SCHEDULER_COMMAND_V1,
9498
+ CommunicationClass: () => CommunicationClass,
9499
+ ConfidenceWeightedAggregator: () => ConfidenceWeightedAggregator,
9493
9500
  ConnectorClient: () => ConnectorClient,
9501
+ DEDUP_WINDOW_S: () => DEDUP_WINDOW_S,
9502
+ DEFAULT_ACK_TIMEOUT_MS: () => DEFAULT_ACK_TIMEOUT_MS,
9503
+ DEFAULT_ESCALATION_POLICY: () => DEFAULT_ESCALATION_POLICY,
9504
+ DEFAULT_EXECUTION_POLICY: () => DEFAULT_EXECUTION_POLICY,
9505
+ DEFAULT_NEGOTIATION_POLICY: () => DEFAULT_NEGOTIATION_POLICY,
9506
+ DebateIntensity: () => DebateIntensity,
9507
+ DecisionOutcome: () => DecisionOutcome,
9494
9508
  DefaultWorktreePolicy: () => DefaultWorktreePolicy,
9509
+ DuplicateDetectedError: () => DuplicateDetectedError,
9510
+ EnvelopeState: () => EnvelopeState,
9495
9511
  ErrorCode: () => ErrorCode,
9496
9512
  ErrorCodeMapper: () => ErrorCodeMapper,
9497
9513
  FileBackend: () => FileBackend,
9498
9514
  HITLClient: () => HITLClient,
9515
+ HandoffClient: () => HandoffClient,
9516
+ HandoffStatus: () => HandoffStatus,
9517
+ HandoffTimeoutError: () => HandoffTimeoutError,
9518
+ HandoffValidationError: () => HandoffValidationError,
9519
+ HitlMode: () => HitlMode,
9520
+ HitlReasonType: () => HitlReasonType,
9521
+ InMemoryAuditor: () => InMemoryAuditor,
9522
+ InMemoryNegotiationRoomStore: () => InMemoryNegotiationRoomStore,
9523
+ InMemoryPolicyStore: () => InMemoryPolicyStore,
9499
9524
  InterceptorChain: () => InterceptorChain,
9500
9525
  JSONFilePersistence: () => JSONFilePersistence,
9526
+ JsonFilePolicyStore: () => JsonFilePolicyStore,
9501
9527
  KeyringBackend: () => KeyringBackend,
9502
9528
  LoggingClient: () => LoggingClient,
9529
+ MajorityVoteAggregator: () => MajorityVoteAggregator,
9503
9530
  MaxEntriesStrategy: () => MaxEntriesStrategy,
9504
9531
  MessageProcessor: () => MessageProcessor,
9505
9532
  MessageType: () => MessageType,
9506
9533
  NegotiationClient: () => NegotiationClient,
9534
+ NegotiationError: () => NegotiationError,
9535
+ NegotiationRoomClient: () => NegotiationRoomClient,
9536
+ NegotiationRoomStoreError: () => NegotiationRoomStoreError,
9537
+ NegotiationTimeoutError: () => NegotiationTimeoutError,
9538
+ NegotiationValidationError: () => NegotiationValidationError,
9539
+ NoOpAuditor: () => NoOpAuditor,
9540
+ NodeStatus: () => NodeStatus,
9541
+ PermissionError: () => PermissionError,
9542
+ PersistentActivityBuffer: () => PersistentActivityBuffer,
9507
9543
  PersistentWorktreeState: () => PersistentWorktreeState,
9544
+ PolicyStoreError: () => PolicyStoreError,
9545
+ PolicyViolationError: () => PolicyViolationError,
9546
+ PreemptionError: () => PreemptionError,
9508
9547
  ReasoningClient: () => ReasoningClient,
9509
9548
  RegistryClient: () => RegistryClient,
9510
9549
  Resolver: () => Resolver,
9550
+ RouteError: () => RouteError,
9511
9551
  RouterClient: () => RouterClient,
9512
9552
  RuntimePersistence: () => RuntimePersistence,
9513
9553
  SchedulerClient: () => SchedulerClient,
@@ -9522,32 +9562,66 @@ __export(src_exports, {
9522
9562
  SecretValidationError: () => SecretValidationError,
9523
9563
  SecretValue: () => SecretValue,
9524
9564
  Secrets: () => Secrets,
9565
+ SimpleAverageAggregator: () => SimpleAverageAggregator,
9566
+ StateTransitionError: () => StateTransitionError,
9525
9567
  Sw4rmError: () => Sw4rmError,
9568
+ TimeoutError: () => TimeoutError,
9526
9569
  ToolClient: () => ToolClient,
9570
+ TriggerType: () => TriggerType,
9571
+ ValidationError: () => ValidationError,
9572
+ VotingAnalyzer: () => VotingAnalyzer,
9573
+ WorkflowClient: () => WorkflowClient,
9574
+ WorkflowCycleError: () => WorkflowCycleError,
9575
+ WorkflowStatus: () => WorkflowStatus,
9576
+ WorkflowValidationError: () => WorkflowValidationError,
9527
9577
  WorktreeClient: () => WorktreeClient,
9578
+ WorktreeError: () => WorktreeError,
9579
+ WorktreeStateEnum: () => WorktreeStateEnum,
9580
+ WorktreeTransitionError: () => WorktreeTransitionError,
9581
+ aggregateVotes: () => aggregateVotes,
9528
9582
  buildAckEnvelope: () => buildAckEnvelope,
9529
9583
  buildEnvelope: () => buildEnvelope,
9584
+ computeEnvelopeHash: () => computeEnvelopeHash,
9530
9585
  computeIdempotencyToken: () => computeIdempotencyToken,
9531
9586
  createResilientIncomingStream: () => createResilientIncomingStream,
9587
+ createSimpleProof: () => createSimpleProof,
9532
9588
  decodeAgentReportV1: () => decodeAgentReportV1,
9533
9589
  decodeBase64: () => decodeBase64,
9590
+ defaultAgentConfig: () => defaultAgentConfig,
9591
+ defaultEndpoints: () => defaultEndpoints,
9592
+ defaultRetryPolicy: () => defaultRetryPolicy,
9593
+ defaultSW4RMConfig: () => defaultSW4RMConfig,
9534
9594
  durationToMs: () => durationToMs,
9535
9595
  encodeSchedulerCommandV1: () => encodeSchedulerCommandV1,
9596
+ getConfig: () => getConfig,
9597
+ getDefaultStore: () => getDefaultStore,
9598
+ getValidTransitions: () => getValidTransitions,
9599
+ isTerminalEnvelopeState: () => isTerminalEnvelopeState,
9600
+ isValidTransition: () => isValidTransition,
9601
+ isValidWorktreeTransition: () => isValidWorktreeTransition,
9602
+ loadConfig: () => loadConfig,
9603
+ loadConfigFromEnv: () => loadConfigFromEnv,
9536
9604
  loggingInterceptor: () => loggingInterceptor,
9537
9605
  mapGrpcStatusToErrorCode: () => mapGrpcStatusToErrorCode,
9538
9606
  msToDuration: () => msToDuration,
9539
9607
  normalizeReportPaths: () => normalizeReportPaths,
9540
9608
  nowTimestamp: () => nowTimestamp,
9541
9609
  parseNegotiationEvent: () => parseNegotiationEvent,
9610
+ resetConfig: () => resetConfig,
9611
+ resetDefaultStore: () => resetDefaultStore,
9542
9612
  selectBackend: () => selectBackend,
9543
9613
  sendMessageWithAck: () => sendMessageWithAck,
9614
+ setConfig: () => setConfig,
9544
9615
  timingInterceptor: () => timingInterceptor,
9616
+ updateEnvelopeState: () => updateEnvelopeState,
9545
9617
  uuidv4: () => uuidv4,
9618
+ verifyAuditProof: () => verifyAuditProof,
9546
9619
  version: () => version
9547
9620
  });
9548
9621
  module.exports = __toCommonJS(src_exports);
9549
9622
 
9550
9623
  // src/internal/baseClient.ts
9624
+ var import_node_fs = __toESM(require("node:fs"), 1);
9551
9625
  var import_node_path = __toESM(require("node:path"), 1);
9552
9626
  var import_node_url = require("node:url");
9553
9627
  var grpc = __toESM(require("@grpc/grpc-js"), 1);
@@ -9569,6 +9643,8 @@ var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
9569
9643
  ErrorCode2[ErrorCode2["PARTIAL_DELIVERY"] = 11] = "PARTIAL_DELIVERY";
9570
9644
  ErrorCode2[ErrorCode2["FORCED_PREEMPTION"] = 12] = "FORCED_PREEMPTION";
9571
9645
  ErrorCode2[ErrorCode2["TTL_EXPIRED"] = 13] = "TTL_EXPIRED";
9646
+ ErrorCode2[ErrorCode2["DUPLICATE_DETECTED"] = 14] = "DUPLICATE_DETECTED";
9647
+ ErrorCode2[ErrorCode2["ALREADY_IN_PROGRESS"] = 15] = "ALREADY_IN_PROGRESS";
9572
9648
  ErrorCode2[ErrorCode2["INTERNAL_ERROR"] = 99] = "INTERNAL_ERROR";
9573
9649
  return ErrorCode2;
9574
9650
  })(ErrorCode || {});
@@ -9584,6 +9660,54 @@ var Sw4rmError = class extends Error {
9584
9660
  this.details = opts?.details;
9585
9661
  }
9586
9662
  };
9663
+ var ValidationError = class extends Sw4rmError {
9664
+ constructor(message, code = 6 /* VALIDATION_ERROR */, opts) {
9665
+ super(message, code, opts);
9666
+ this.name = "ValidationError";
9667
+ }
9668
+ };
9669
+ var TimeoutError = class extends Sw4rmError {
9670
+ constructor(message, code = 3 /* ACK_TIMEOUT */, opts) {
9671
+ super(message, code, opts);
9672
+ this.name = "TimeoutError";
9673
+ }
9674
+ };
9675
+ var StateTransitionError = class extends Sw4rmError {
9676
+ constructor(message, code = 99 /* INTERNAL_ERROR */, opts) {
9677
+ super(message, code, opts);
9678
+ this.name = "StateTransitionError";
9679
+ }
9680
+ };
9681
+ var NegotiationError = class extends Sw4rmError {
9682
+ constructor(message, code = 99 /* INTERNAL_ERROR */, opts) {
9683
+ super(message, code, opts);
9684
+ this.name = "NegotiationError";
9685
+ }
9686
+ };
9687
+ var BufferFullError = class extends Sw4rmError {
9688
+ constructor(message, code = 1 /* BUFFER_FULL */, opts) {
9689
+ super(message, code, opts);
9690
+ this.name = "BufferFullError";
9691
+ }
9692
+ };
9693
+ var RouteError = class extends Sw4rmError {
9694
+ constructor(message, code = 2 /* NO_ROUTE */, opts) {
9695
+ super(message, code, opts);
9696
+ this.name = "RouteError";
9697
+ }
9698
+ };
9699
+ var PermissionError = class extends Sw4rmError {
9700
+ constructor(message, code = 7 /* PERMISSION_DENIED */, opts) {
9701
+ super(message, code, opts);
9702
+ this.name = "PermissionError";
9703
+ }
9704
+ };
9705
+ var DuplicateDetectedError = class extends Sw4rmError {
9706
+ constructor(message, code = 14 /* DUPLICATE_DETECTED */, opts) {
9707
+ super(message, code, opts);
9708
+ this.name = "DuplicateDetectedError";
9709
+ }
9710
+ };
9587
9711
  var GrpcStatus = {
9588
9712
  OK: 0,
9589
9713
  CANCELLED: 1,
@@ -9603,6 +9727,28 @@ var GrpcStatus = {
9603
9727
  DATA_LOSS: 15,
9604
9728
  UNAUTHENTICATED: 16
9605
9729
  };
9730
+ var PreemptionError = class extends Sw4rmError {
9731
+ agentId;
9732
+ reason;
9733
+ constructor(agentId, reason, code = 12 /* FORCED_PREEMPTION */, opts) {
9734
+ super(`Agent ${agentId} preempted: ${reason}`, code, opts);
9735
+ this.name = "PreemptionError";
9736
+ this.agentId = agentId;
9737
+ this.reason = reason;
9738
+ }
9739
+ };
9740
+ var WorktreeError = class extends Sw4rmError {
9741
+ constructor(message, code = 99 /* INTERNAL_ERROR */, opts) {
9742
+ super(message, code, opts);
9743
+ this.name = "WorktreeError";
9744
+ }
9745
+ };
9746
+ var PolicyViolationError = class extends Sw4rmError {
9747
+ constructor(message, code = 7 /* PERMISSION_DENIED */, opts) {
9748
+ super(message, code, opts);
9749
+ this.name = "PolicyViolationError";
9750
+ }
9751
+ };
9606
9752
  function mapGrpcStatusToErrorCode(status) {
9607
9753
  switch (status) {
9608
9754
  case GrpcStatus.OK:
@@ -9672,7 +9818,7 @@ var InterceptorChain = class {
9672
9818
  };
9673
9819
  function timingInterceptor() {
9674
9820
  return {
9675
- onRequest(ctx) {
9821
+ onRequest(_ctx) {
9676
9822
  },
9677
9823
  onResponse(ctx, status) {
9678
9824
  if (typeof console !== "undefined" && console.debug) {
@@ -9717,12 +9863,12 @@ var BaseClient = class {
9717
9863
  errorMapper = new ErrorCodeMapper();
9718
9864
  constructor(opts) {
9719
9865
  this.address = opts.address;
9720
- this.deadlineMs = opts.deadlineMs ?? 1e4;
9866
+ this.deadlineMs = opts.deadlineMs ?? 3e4;
9721
9867
  this.retry = opts.retry ?? { maxAttempts: 3, initialBackoffMs: 200, maxBackoffMs: 2e3, multiplier: 2 };
9722
9868
  this.userAgent = opts.userAgent ?? "sw4rm-js-sdk/0.1";
9723
9869
  const __filename = (0, import_node_url.fileURLToPath)(import_meta.url);
9724
9870
  const __dirname = import_node_path.default.dirname(__filename);
9725
- const protosDir = import_node_path.default.resolve(__dirname, "../../../../protos");
9871
+ const protosDir = this.resolveProtosDir(__dirname);
9726
9872
  const loaderOpts = {
9727
9873
  keepCase: true,
9728
9874
  longs: String,
@@ -9742,10 +9888,13 @@ var BaseClient = class {
9742
9888
  "tool.proto",
9743
9889
  "connector.proto",
9744
9890
  "negotiation.proto",
9891
+ "negotiation_room.proto",
9745
9892
  "reasoning.proto",
9746
9893
  "logging.proto",
9747
9894
  "policy.proto",
9748
- "activity.proto"
9895
+ "activity.proto",
9896
+ "handoff.proto",
9897
+ "workflow.proto"
9749
9898
  ], loaderOpts);
9750
9899
  this.root = grpc.loadPackageDefinition(this.pkgDef);
9751
9900
  this.interceptors.use(timingInterceptor());
@@ -9755,6 +9904,27 @@ var BaseClient = class {
9755
9904
  if (opts.errorMapper)
9756
9905
  opts.errorMapper(this.errorMapper);
9757
9906
  }
9907
+ /**
9908
+ * Resolves the protos directory, checking multiple locations:
9909
+ * 1. npm package: ./protos relative to package root
9910
+ * 2. Monorepo dev: ../../../../protos relative to this file
9911
+ */
9912
+ resolveProtosDir(dirname3) {
9913
+ const candidates = [
9914
+ // npm package structure: node_modules/@sw4rm/js-sdk/protos
9915
+ import_node_path.default.resolve(dirname3, "../../protos"),
9916
+ // Alternative npm structure: dist/esm/internal -> protos
9917
+ import_node_path.default.resolve(dirname3, "../../../protos"),
9918
+ // Monorepo development: sdks/js_sdk/src/internal -> protos
9919
+ import_node_path.default.resolve(dirname3, "../../../../protos")
9920
+ ];
9921
+ for (const candidate of candidates) {
9922
+ if (import_node_fs.default.existsSync(candidate) && import_node_fs.default.existsSync(import_node_path.default.join(candidate, "common.proto"))) {
9923
+ return candidate;
9924
+ }
9925
+ }
9926
+ return candidates[candidates.length - 1];
9927
+ }
9758
9928
  channelCredentials() {
9759
9929
  return grpc.credentials.createInsecure();
9760
9930
  }
@@ -10342,214 +10512,1370 @@ var RegistryClient = class extends BaseClient {
10342
10512
  }
10343
10513
  };
10344
10514
 
10345
- // src/internal/envelope.ts
10346
- var import_node_crypto2 = __toESM(require("node:crypto"), 1);
10347
- function nowTimestamp(date = /* @__PURE__ */ new Date()) {
10348
- const ms = date.getTime();
10349
- const seconds = Math.floor(ms / 1e3);
10350
- const nanos = ms % 1e3 * 1e6;
10351
- return { seconds, nanos };
10352
- }
10353
- function nowHlcStub(date = /* @__PURE__ */ new Date()) {
10354
- return String(date.getTime());
10355
- }
10356
- function uuidv42() {
10357
- if (typeof import_node_crypto2.default.randomUUID === "function") {
10358
- return import_node_crypto2.default.randomUUID();
10515
+ // src/clients/negotiationRoomStore.ts
10516
+ var NegotiationRoomStoreError = class extends Error {
10517
+ constructor(message) {
10518
+ super(message);
10519
+ this.name = "NegotiationRoomStoreError";
10359
10520
  }
10360
- const buf = import_node_crypto2.default.randomBytes(16);
10361
- buf[6] = buf[6] & 15 | 64;
10362
- buf[8] = buf[8] & 63 | 128;
10363
- const hex = [...buf].map((b) => b.toString(16).padStart(2, "0"));
10364
- return hex.slice(0, 4).join("") + "-" + hex.slice(4, 6).join("") + "-" + hex.slice(6, 8).join("") + "-" + hex.slice(8, 10).join("") + "-" + hex.slice(10, 16).join("");
10365
- }
10366
- function buildEnvelope(input) {
10367
- const hasPayload = input.payload !== void 0;
10368
- const content_type = input.content_type ?? "application/json";
10369
- const message_id = uuidv42();
10370
- const correlation_id = input.correlation_id ?? uuidv42();
10371
- const sequence_number = input.sequence_number ?? 1;
10372
- const retry_count = input.retry_count ?? 0;
10373
- const ts = nowTimestamp(input.timestamp ?? /* @__PURE__ */ new Date());
10374
- const hlc_timestamp = input.hlc_timestamp ?? nowHlcStub(input.timestamp);
10375
- const built = {
10376
- message_id,
10377
- idempotency_token: input.idempotency_token,
10378
- producer_id: input.producer_id,
10379
- correlation_id,
10380
- sequence_number,
10381
- retry_count,
10382
- message_type: input.message_type,
10383
- content_type,
10384
- // Always set content_type (aligns with Python/Rust)
10385
- repo_id: input.repo_id,
10386
- worktree_id: input.worktree_id,
10387
- hlc_timestamp,
10388
- // Always set hlc_timestamp (aligns with Python/Rust)
10389
- ttl_ms: input.ttl_ms,
10390
- timestamp: ts
10391
- };
10392
- if (hasPayload) {
10393
- const payload = input.payload instanceof Uint8Array ? input.payload : new Uint8Array(input.payload);
10394
- built.payload = payload;
10395
- built.content_length = payload.byteLength;
10396
- if (!input.content_type) {
10397
- built.content_type = "application/octet-stream";
10521
+ };
10522
+ var InMemoryNegotiationRoomStore = class {
10523
+ proposals = /* @__PURE__ */ new Map();
10524
+ votes = /* @__PURE__ */ new Map();
10525
+ decisions = /* @__PURE__ */ new Map();
10526
+ async hasProposal(artifactId) {
10527
+ return this.proposals.has(artifactId);
10528
+ }
10529
+ async getProposal(artifactId) {
10530
+ return this.proposals.get(artifactId) || null;
10531
+ }
10532
+ async saveProposal(proposal) {
10533
+ const artifactId = proposal.artifactId;
10534
+ if (this.proposals.has(artifactId)) {
10535
+ throw new NegotiationRoomStoreError(
10536
+ `Proposal with artifact_id '${artifactId}' already exists`
10537
+ );
10398
10538
  }
10539
+ const proposalWithTimestamp = {
10540
+ ...proposal,
10541
+ createdAt: proposal.createdAt || (/* @__PURE__ */ new Date()).toISOString()
10542
+ };
10543
+ this.proposals.set(artifactId, proposalWithTimestamp);
10544
+ this.votes.set(artifactId, []);
10399
10545
  }
10400
- return built;
10401
- }
10402
-
10403
- // src/internal/worktreeState.ts
10404
- var PersistentWorktreeState = class {
10405
- state = "UNBOUND";
10406
- repoId;
10407
- worktreeId;
10408
- bind(repoId, worktreeId) {
10409
- this.repoId = repoId;
10410
- this.worktreeId = worktreeId;
10411
- this.state = "BOUND_HOME";
10546
+ async listProposals(negotiationRoomId) {
10547
+ const allProposals = Array.from(this.proposals.values());
10548
+ if (negotiationRoomId === void 0) {
10549
+ return allProposals;
10550
+ }
10551
+ return allProposals.filter((p) => p.negotiationRoomId === negotiationRoomId);
10412
10552
  }
10413
- unbind() {
10414
- this.repoId = void 0;
10415
- this.worktreeId = void 0;
10416
- this.state = "UNBOUND";
10553
+ async getVotes(artifactId) {
10554
+ return [...this.votes.get(artifactId) || []];
10417
10555
  }
10418
- setState(state) {
10419
- this.state = state;
10556
+ async addVote(vote) {
10557
+ const artifactId = vote.artifactId;
10558
+ const criticId = vote.criticId;
10559
+ const existingVotes = this.votes.get(artifactId) || [];
10560
+ for (const existingVote of existingVotes) {
10561
+ if (existingVote.criticId === criticId) {
10562
+ throw new NegotiationRoomStoreError(
10563
+ `Critic '${criticId}' has already voted for artifact '${artifactId}'`
10564
+ );
10565
+ }
10566
+ }
10567
+ const voteWithTimestamp = {
10568
+ ...vote,
10569
+ votedAt: vote.votedAt || (/* @__PURE__ */ new Date()).toISOString()
10570
+ };
10571
+ if (!this.votes.has(artifactId)) {
10572
+ this.votes.set(artifactId, []);
10573
+ }
10574
+ this.votes.get(artifactId).push(voteWithTimestamp);
10420
10575
  }
10421
- current() {
10422
- return { state: this.state, repo_id: this.repoId, worktree_id: this.worktreeId };
10576
+ async getDecision(artifactId) {
10577
+ return this.decisions.get(artifactId) || null;
10578
+ }
10579
+ async saveDecision(decision) {
10580
+ const artifactId = decision.artifactId;
10581
+ if (this.decisions.has(artifactId)) {
10582
+ throw new NegotiationRoomStoreError(
10583
+ `Decision already exists for artifact_id '${artifactId}'`
10584
+ );
10585
+ }
10586
+ const decisionWithTimestamp = {
10587
+ ...decision,
10588
+ decidedAt: decision.decidedAt || (/* @__PURE__ */ new Date()).toISOString()
10589
+ };
10590
+ this.decisions.set(artifactId, decisionWithTimestamp);
10423
10591
  }
10424
10592
  };
10593
+ var defaultStore = null;
10594
+ function getDefaultStore() {
10595
+ if (defaultStore === null) {
10596
+ defaultStore = new InMemoryNegotiationRoomStore();
10597
+ }
10598
+ return defaultStore;
10599
+ }
10600
+ function resetDefaultStore() {
10601
+ defaultStore = null;
10602
+ }
10425
10603
 
10426
- // src/internal/runtime/activityBuffer.ts
10427
- var MaxEntriesStrategy = class {
10428
- prune(records, maxEntries) {
10429
- if (records.length <= maxEntries)
10430
- return records;
10431
- const overflow = records.length - maxEntries;
10432
- return records.slice(overflow);
10604
+ // src/clients/negotiationRoom.ts
10605
+ var ArtifactType = /* @__PURE__ */ ((ArtifactType2) => {
10606
+ ArtifactType2[ArtifactType2["ARTIFACT_TYPE_UNSPECIFIED"] = 0] = "ARTIFACT_TYPE_UNSPECIFIED";
10607
+ ArtifactType2[ArtifactType2["REQUIREMENTS"] = 1] = "REQUIREMENTS";
10608
+ ArtifactType2[ArtifactType2["PLAN"] = 2] = "PLAN";
10609
+ ArtifactType2[ArtifactType2["CODE"] = 3] = "CODE";
10610
+ ArtifactType2[ArtifactType2["DEPLOYMENT"] = 4] = "DEPLOYMENT";
10611
+ return ArtifactType2;
10612
+ })(ArtifactType || {});
10613
+ var DecisionOutcome = /* @__PURE__ */ ((DecisionOutcome2) => {
10614
+ DecisionOutcome2[DecisionOutcome2["DECISION_OUTCOME_UNSPECIFIED"] = 0] = "DECISION_OUTCOME_UNSPECIFIED";
10615
+ DecisionOutcome2[DecisionOutcome2["APPROVED"] = 1] = "APPROVED";
10616
+ DecisionOutcome2[DecisionOutcome2["REVISION_REQUESTED"] = 2] = "REVISION_REQUESTED";
10617
+ DecisionOutcome2[DecisionOutcome2["ESCALATED_TO_HITL"] = 3] = "ESCALATED_TO_HITL";
10618
+ return DecisionOutcome2;
10619
+ })(DecisionOutcome || {});
10620
+ var NegotiationTimeoutError = class extends Error {
10621
+ constructor(message) {
10622
+ super(message);
10623
+ this.name = "NegotiationTimeoutError";
10433
10624
  }
10434
10625
  };
10435
- var ActivityBuffer = class {
10436
- records = /* @__PURE__ */ new Map();
10437
- maxEntries;
10438
- strategy;
10439
- constructor(opts) {
10440
- this.maxEntries = opts?.maxEntries ?? 1e3;
10441
- this.strategy = opts?.strategy ?? new MaxEntriesStrategy();
10626
+ var NegotiationValidationError = class extends Error {
10627
+ constructor(message) {
10628
+ super(message);
10629
+ this.name = "NegotiationValidationError";
10442
10630
  }
10443
- upsert(rec) {
10444
- this.records.set(rec.task_id, rec);
10445
- this.prune();
10631
+ };
10632
+ function validateVote(vote) {
10633
+ if (vote.score < 0 || vote.score > 10) {
10634
+ throw new NegotiationValidationError(
10635
+ `score must be in range [0, 10], got ${vote.score}`
10636
+ );
10446
10637
  }
10447
- remove(taskId) {
10448
- this.records.delete(taskId);
10638
+ if (vote.confidence < 0 || vote.confidence > 1) {
10639
+ throw new NegotiationValidationError(
10640
+ `confidence must be in range [0, 1], got ${vote.confidence}`
10641
+ );
10449
10642
  }
10450
- list() {
10451
- return [...this.records.values()].sort((a, b) => a.timestamp.localeCompare(b.timestamp));
10643
+ }
10644
+ var NegotiationRoomClient = class {
10645
+ store;
10646
+ /**
10647
+ * Create a new negotiation room client.
10648
+ *
10649
+ * @param options - Configuration options. If no store is provided,
10650
+ * uses the shared default in-memory store.
10651
+ */
10652
+ constructor(options = {}) {
10653
+ this.store = options.store || getDefaultStore();
10654
+ }
10655
+ /**
10656
+ * Submit an artifact proposal for multi-agent review.
10657
+ *
10658
+ * Stores the proposal and initializes empty vote tracking for the artifact.
10659
+ * This method is typically called by producer agents.
10660
+ *
10661
+ * @param proposal - The negotiation proposal containing artifact details
10662
+ * @returns The artifact_id of the submitted proposal
10663
+ * @throws NegotiationValidationError if a proposal with the same artifact_id already exists
10664
+ *
10665
+ * @example
10666
+ * ```typescript
10667
+ * const client = new NegotiationRoomClient();
10668
+ * const proposal: NegotiationProposal = {
10669
+ * artifactType: ArtifactType.CODE,
10670
+ * artifactId: "code-123",
10671
+ * producerId: "agent-producer",
10672
+ * artifact: new TextEncoder().encode("def hello(): pass"),
10673
+ * artifactContentType: "text/x-python",
10674
+ * requestedCritics: ["critic-1", "critic-2"],
10675
+ * negotiationRoomId: "room-1"
10676
+ * };
10677
+ * const artifactId = await client.submitProposal(proposal);
10678
+ * console.log(artifactId); // "code-123"
10679
+ * ```
10680
+ */
10681
+ async submitProposal(proposal) {
10682
+ await this.store.saveProposal(proposal);
10683
+ return proposal.artifactId;
10684
+ }
10685
+ /**
10686
+ * Submit a critic's vote for an artifact.
10687
+ *
10688
+ * Adds the vote to the collection for the specified artifact.
10689
+ * This method is typically called by critic agents after evaluating
10690
+ * an artifact.
10691
+ *
10692
+ * @param vote - The negotiation vote containing the critic's evaluation
10693
+ * @throws NegotiationValidationError if no proposal exists for the vote's artifact_id
10694
+ * @throws NegotiationValidationError if the critic has already voted for this artifact
10695
+ * @throws NegotiationValidationError if score or confidence are out of range
10696
+ *
10697
+ * @example
10698
+ * ```typescript
10699
+ * const vote: NegotiationVote = {
10700
+ * artifactId: "code-123",
10701
+ * criticId: "critic-1",
10702
+ * score: 8.5,
10703
+ * confidence: 0.9,
10704
+ * passed: true,
10705
+ * strengths: ["Good structure"],
10706
+ * weaknesses: ["Needs tests"],
10707
+ * recommendations: ["Add unit tests"],
10708
+ * negotiationRoomId: "room-1"
10709
+ * };
10710
+ * await client.submitVote(vote);
10711
+ * ```
10712
+ */
10713
+ async submitVote(vote) {
10714
+ const artifactId = vote.artifactId;
10715
+ if (!await this.store.hasProposal(artifactId)) {
10716
+ throw new NegotiationValidationError(
10717
+ `No proposal found for artifact_id '${artifactId}'`
10718
+ );
10719
+ }
10720
+ validateVote(vote);
10721
+ await this.store.addVote(vote);
10452
10722
  }
10453
- recent(limit = 50) {
10454
- const arr = this.list();
10455
- return arr.slice(Math.max(0, arr.length - limit));
10723
+ /**
10724
+ * Retrieve all votes for a specific artifact.
10725
+ *
10726
+ * Returns all critic votes that have been submitted for the artifact.
10727
+ * This method is typically called by coordinator agents to aggregate
10728
+ * votes and make decisions.
10729
+ *
10730
+ * @param artifactId - The identifier of the artifact
10731
+ * @returns List of all votes for the artifact (empty array if no votes yet)
10732
+ * @throws NegotiationValidationError if no proposal exists for the artifact_id
10733
+ *
10734
+ * @example
10735
+ * ```typescript
10736
+ * const votes = await client.getVotes("code-123");
10737
+ * console.log(votes.length); // 1
10738
+ * ```
10739
+ */
10740
+ async getVotes(artifactId) {
10741
+ if (!await this.store.hasProposal(artifactId)) {
10742
+ throw new NegotiationValidationError(
10743
+ `No proposal found for artifact_id '${artifactId}'`
10744
+ );
10745
+ }
10746
+ return this.store.getVotes(artifactId);
10456
10747
  }
10457
- reconcile(knownTaskIds) {
10458
- for (const id of this.records.keys()) {
10459
- if (!knownTaskIds.has(id))
10460
- this.records.delete(id);
10748
+ /**
10749
+ * Retrieve the decision for a specific artifact if available.
10750
+ *
10751
+ * Returns the final decision if one has been made, or null if the
10752
+ * artifact is still under review.
10753
+ *
10754
+ * @param artifactId - The identifier of the artifact
10755
+ * @returns The negotiation decision if available, null otherwise
10756
+ * @throws NegotiationValidationError if no proposal exists for the artifact_id
10757
+ *
10758
+ * @example
10759
+ * ```typescript
10760
+ * const decision = await client.getDecision("code-123");
10761
+ * if (decision === null) {
10762
+ * console.log("Decision pending");
10763
+ * }
10764
+ * ```
10765
+ */
10766
+ async getDecision(artifactId) {
10767
+ if (!await this.store.hasProposal(artifactId)) {
10768
+ throw new NegotiationValidationError(
10769
+ `No proposal found for artifact_id '${artifactId}'`
10770
+ );
10461
10771
  }
10772
+ return this.store.getDecision(artifactId);
10462
10773
  }
10463
- prune() {
10464
- const arr = this.list();
10465
- const pruned = this.strategy.prune(arr, this.maxEntries);
10466
- if (pruned.length === arr.length)
10467
- return;
10468
- this.records.clear();
10469
- for (const r of pruned)
10470
- this.records.set(r.task_id, r);
10774
+ /**
10775
+ * Store a decision for an artifact.
10776
+ *
10777
+ * This is an internal method used by coordinators to record the
10778
+ * final decision after evaluating votes. Once a decision is stored,
10779
+ * it becomes available via getDecision() and waitForDecision().
10780
+ *
10781
+ * @param decision - The negotiation decision to store
10782
+ * @throws NegotiationValidationError if no proposal exists for the decision's artifact_id
10783
+ * @throws NegotiationValidationError if a decision already exists for this artifact
10784
+ *
10785
+ * @example
10786
+ * ```typescript
10787
+ * const votes = await client.getVotes("code-123");
10788
+ * const aggregated = aggregateVotes(votes);
10789
+ * const decision: NegotiationDecision = {
10790
+ * artifactId: "code-123",
10791
+ * outcome: DecisionOutcome.APPROVED,
10792
+ * votes: votes,
10793
+ * aggregatedScore: aggregated,
10794
+ * policyVersion: "1.0",
10795
+ * reason: "Met all criteria",
10796
+ * negotiationRoomId: "room-1"
10797
+ * };
10798
+ * await client.storeDecision(decision);
10799
+ * ```
10800
+ */
10801
+ async storeDecision(decision) {
10802
+ const artifactId = decision.artifactId;
10803
+ if (!await this.store.hasProposal(artifactId)) {
10804
+ throw new NegotiationValidationError(
10805
+ `No proposal found for artifact_id '${artifactId}'`
10806
+ );
10807
+ }
10808
+ await this.store.saveDecision(decision);
10471
10809
  }
10472
- toJSON() {
10473
- return this.list();
10810
+ /**
10811
+ * Wait for a decision to be made on an artifact.
10812
+ *
10813
+ * Polls for a decision until one is available or the timeout is reached.
10814
+ * This method is useful for producer agents waiting for the outcome
10815
+ * of their artifact review.
10816
+ *
10817
+ * @param artifactId - The identifier of the artifact
10818
+ * @param timeoutMs - Maximum time to wait in milliseconds (default: 30000)
10819
+ * @param pollIntervalMs - Time between polling attempts in milliseconds (default: 100)
10820
+ * @returns The negotiation decision once available
10821
+ * @throws NegotiationValidationError if no proposal exists for the artifact_id
10822
+ * @throws NegotiationTimeoutError if no decision is made within the timeout period
10823
+ *
10824
+ * @example
10825
+ * ```typescript
10826
+ * // In a separate thread/process, a coordinator makes a decision
10827
+ * const decision = await client.waitForDecision("code-123", 10000);
10828
+ * console.log(decision.outcome); // DecisionOutcome.APPROVED
10829
+ * ```
10830
+ */
10831
+ async waitForDecision(artifactId, timeoutMs = 3e4, pollIntervalMs = 100) {
10832
+ if (!await this.store.hasProposal(artifactId)) {
10833
+ throw new NegotiationValidationError(
10834
+ `No proposal found for artifact_id '${artifactId}'`
10835
+ );
10836
+ }
10837
+ const startTime = Date.now();
10838
+ while (Date.now() - startTime < timeoutMs) {
10839
+ const decision = await this.store.getDecision(artifactId);
10840
+ if (decision !== null) {
10841
+ return decision;
10842
+ }
10843
+ await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
10844
+ }
10845
+ throw new NegotiationTimeoutError(
10846
+ `No decision made for artifact '${artifactId}' within ${timeoutMs} milliseconds`
10847
+ );
10474
10848
  }
10475
- fromJSON(records) {
10476
- this.records.clear();
10477
- for (const r of records)
10478
- this.records.set(r.task_id, r);
10479
- this.prune();
10849
+ /**
10850
+ * Retrieve the original proposal for an artifact.
10851
+ *
10852
+ * Useful for critics that need to review the original artifact
10853
+ * before submitting a vote.
10854
+ *
10855
+ * @param artifactId - The identifier of the artifact
10856
+ * @returns The negotiation proposal if it exists, null otherwise
10857
+ *
10858
+ * @example
10859
+ * ```typescript
10860
+ * const proposal = await client.getProposal("code-123");
10861
+ * console.log(proposal?.artifactType); // ArtifactType.CODE
10862
+ * ```
10863
+ */
10864
+ async getProposal(artifactId) {
10865
+ return this.store.getProposal(artifactId);
10866
+ }
10867
+ /**
10868
+ * List all proposals, optionally filtered by negotiation room.
10869
+ *
10870
+ * @param negotiationRoomId - If provided, only return proposals for this room
10871
+ * @returns List of proposals matching the filter criteria
10872
+ *
10873
+ * @example
10874
+ * ```typescript
10875
+ * const proposals = await client.listProposals("room-1");
10876
+ * console.log(proposals.length); // 1
10877
+ * ```
10878
+ */
10879
+ async listProposals(negotiationRoomId) {
10880
+ return this.store.listProposals(negotiationRoomId);
10480
10881
  }
10481
10882
  };
10482
-
10483
- // src/internal/runtime/ackLifecycle.ts
10484
- var AckStage = /* @__PURE__ */ ((AckStage2) => {
10485
- AckStage2[AckStage2["ACK_STAGE_UNSPECIFIED"] = 0] = "ACK_STAGE_UNSPECIFIED";
10486
- AckStage2[AckStage2["RECEIVED"] = 1] = "RECEIVED";
10487
- AckStage2[AckStage2["READ"] = 2] = "READ";
10488
- AckStage2[AckStage2["FULFILLED"] = 3] = "FULFILLED";
10489
- AckStage2[AckStage2["REJECTED"] = 4] = "REJECTED";
10490
- AckStage2[AckStage2["FAILED"] = 5] = "FAILED";
10491
- AckStage2[AckStage2["TIMED_OUT"] = 6] = "TIMED_OUT";
10492
- return AckStage2;
10493
- })(AckStage || {});
10494
- var ACKLifecycleManager = class {
10495
- acks = /* @__PURE__ */ new Map();
10496
- mark(messageId, stage, note, errorCode) {
10497
- const st = {
10498
- messageId,
10499
- stage,
10500
- lastUpdateIso: (/* @__PURE__ */ new Date()).toISOString(),
10501
- note,
10502
- errorCode
10503
- };
10504
- this.acks.set(messageId, st);
10505
- }
10506
- get(messageId) {
10507
- return this.acks.get(messageId);
10508
- }
10509
- recent(limit = 100) {
10510
- const arr = [...this.acks.values()].sort((a, b) => a.lastUpdateIso.localeCompare(b.lastUpdateIso));
10511
- return arr.slice(Math.max(0, arr.length - limit));
10883
+ function aggregateVotes(votes) {
10884
+ if (votes.length === 0) {
10885
+ throw new NegotiationValidationError(
10886
+ "Cannot aggregate empty list of votes"
10887
+ );
10512
10888
  }
10513
- reconcileLateAck(messageId, stage) {
10514
- const curr = this.acks.get(messageId);
10515
- if (!curr || curr.stage === stage)
10516
- return;
10517
- this.mark(messageId, stage, "late_ack_reconciled");
10889
+ const scores = votes.map((v) => v.score);
10890
+ const confidences = votes.map((v) => v.confidence);
10891
+ const mean = scores.reduce((a, b) => a + b, 0) / scores.length;
10892
+ const minScore = Math.min(...scores);
10893
+ const maxScore = Math.max(...scores);
10894
+ const variance = scores.reduce((sum, s) => sum + Math.pow(s - mean, 2), 0) / scores.length;
10895
+ const stdDev = Math.sqrt(variance);
10896
+ const totalConfidence = confidences.reduce((a, b) => a + b, 0);
10897
+ let weightedMean;
10898
+ if (totalConfidence > 0) {
10899
+ weightedMean = scores.reduce((sum, s, i) => sum + s * confidences[i], 0) / totalConfidence;
10900
+ } else {
10901
+ weightedMean = mean;
10518
10902
  }
10519
- toJSON() {
10520
- return [...this.acks.values()].sort((a, b) => a.lastUpdateIso.localeCompare(b.lastUpdateIso));
10903
+ return {
10904
+ mean,
10905
+ minScore,
10906
+ maxScore,
10907
+ stdDev,
10908
+ weightedMean,
10909
+ voteCount: votes.length
10910
+ };
10911
+ }
10912
+
10913
+ // src/clients/handoff.ts
10914
+ var HandoffStatus = /* @__PURE__ */ ((HandoffStatus2) => {
10915
+ HandoffStatus2[HandoffStatus2["HANDOFF_STATUS_UNSPECIFIED"] = 0] = "HANDOFF_STATUS_UNSPECIFIED";
10916
+ HandoffStatus2[HandoffStatus2["PENDING"] = 1] = "PENDING";
10917
+ HandoffStatus2[HandoffStatus2["ACCEPTED"] = 2] = "ACCEPTED";
10918
+ HandoffStatus2[HandoffStatus2["REJECTED"] = 3] = "REJECTED";
10919
+ HandoffStatus2[HandoffStatus2["COMPLETED"] = 4] = "COMPLETED";
10920
+ HandoffStatus2[HandoffStatus2["EXPIRED"] = 5] = "EXPIRED";
10921
+ return HandoffStatus2;
10922
+ })(HandoffStatus || {});
10923
+ var HandoffValidationError = class extends Error {
10924
+ constructor(message) {
10925
+ super(message);
10926
+ this.name = "HandoffValidationError";
10521
10927
  }
10522
- fromJSON(states) {
10523
- this.acks.clear();
10524
- for (const s of states)
10525
- this.acks.set(s.messageId, s);
10928
+ };
10929
+ var HandoffTimeoutError = class extends Error {
10930
+ constructor(message) {
10931
+ super(message);
10932
+ this.name = "HandoffTimeoutError";
10526
10933
  }
10527
10934
  };
10528
-
10529
- // src/internal/runtime/messageProcessor.ts
10530
- var MessageType = /* @__PURE__ */ ((MessageType3) => {
10531
- MessageType3[MessageType3["MESSAGE_TYPE_UNSPECIFIED"] = 0] = "MESSAGE_TYPE_UNSPECIFIED";
10532
- MessageType3[MessageType3["CONTROL"] = 1] = "CONTROL";
10533
- MessageType3[MessageType3["DATA"] = 2] = "DATA";
10534
- MessageType3[MessageType3["HEARTBEAT"] = 3] = "HEARTBEAT";
10535
- MessageType3[MessageType3["NOTIFICATION"] = 4] = "NOTIFICATION";
10536
- MessageType3[MessageType3["ACKNOWLEDGEMENT"] = 5] = "ACKNOWLEDGEMENT";
10537
- MessageType3[MessageType3["HITL_INVOCATION"] = 6] = "HITL_INVOCATION";
10538
- MessageType3[MessageType3["WORKTREE_CONTROL"] = 7] = "WORKTREE_CONTROL";
10539
- MessageType3[MessageType3["NEGOTIATION"] = 8] = "NEGOTIATION";
10540
- MessageType3[MessageType3["TOOL_CALL"] = 9] = "TOOL_CALL";
10541
- MessageType3[MessageType3["TOOL_RESULT"] = 10] = "TOOL_RESULT";
10542
- MessageType3[MessageType3["TOOL_ERROR"] = 11] = "TOOL_ERROR";
10543
- return MessageType3;
10544
- })(MessageType || {});
10545
- var MessageProcessor = class {
10546
- handlers = /* @__PURE__ */ new Map();
10547
- defaultHandler;
10548
- ack;
10549
- constructor(ack) {
10550
- this.ack = ack;
10935
+ var HandoffClient = class {
10936
+ requests = /* @__PURE__ */ new Map();
10937
+ responses = /* @__PURE__ */ new Map();
10938
+ pendingByAgent = /* @__PURE__ */ new Map();
10939
+ /**
10940
+ * Request a handoff to another agent.
10941
+ *
10942
+ * Initiates a handoff request that the target agent can accept or reject.
10943
+ * The request is stored and made available to the target agent via
10944
+ * getPendingHandoffs().
10945
+ *
10946
+ * @param request - The handoff request containing context and requirements
10947
+ * @returns The response once the handoff is accepted, rejected, or times out
10948
+ * @throws HandoffValidationError if a request with the same ID already exists
10949
+ *
10950
+ * @example
10951
+ * ```typescript
10952
+ * const client = new HandoffClient();
10953
+ * const request: HandoffRequest = {
10954
+ * requestId: "handoff-123",
10955
+ * fromAgent: "agent-a",
10956
+ * toAgent: "agent-b",
10957
+ * reason: "Capability mismatch",
10958
+ * contextSnapshot: new TextEncoder().encode('{"state": "in_progress"}'),
10959
+ * capabilitiesRequired: ["code_review"],
10960
+ * priority: 5
10961
+ * };
10962
+ * const response = await client.requestHandoff(request);
10963
+ * ```
10964
+ */
10965
+ async requestHandoff(request) {
10966
+ if (this.requests.has(request.requestId)) {
10967
+ throw new HandoffValidationError(
10968
+ `Handoff request with ID '${request.requestId}' already exists`
10969
+ );
10970
+ }
10971
+ const requestWithTimestamp = {
10972
+ ...request,
10973
+ createdAt: request.createdAt || (/* @__PURE__ */ new Date()).toISOString()
10974
+ };
10975
+ this.requests.set(request.requestId, requestWithTimestamp);
10976
+ if (request.toAgent) {
10977
+ if (!this.pendingByAgent.has(request.toAgent)) {
10978
+ this.pendingByAgent.set(request.toAgent, /* @__PURE__ */ new Set());
10979
+ }
10980
+ this.pendingByAgent.get(request.toAgent).add(request.requestId);
10981
+ }
10982
+ const timeoutMs = request.timeoutMs || 3e4;
10983
+ const startTime = Date.now();
10984
+ const pollIntervalMs = 100;
10985
+ while (Date.now() - startTime < timeoutMs) {
10986
+ const response = this.responses.get(request.requestId);
10987
+ if (response) {
10988
+ return response;
10989
+ }
10990
+ await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
10991
+ }
10992
+ const timeoutResponse = {
10993
+ requestId: request.requestId,
10994
+ accepted: false,
10995
+ rejectionReason: `Handoff request timed out after ${timeoutMs}ms`
10996
+ };
10997
+ this.responses.set(request.requestId, timeoutResponse);
10998
+ if (request.toAgent && this.pendingByAgent.has(request.toAgent)) {
10999
+ this.pendingByAgent.get(request.toAgent).delete(request.requestId);
11000
+ }
11001
+ return timeoutResponse;
10551
11002
  }
10552
- registerHandler(type, handler) {
11003
+ /**
11004
+ * Accept a pending handoff request.
11005
+ *
11006
+ * Called by the target agent to accept a handoff. After acceptance,
11007
+ * the agent should process the context snapshot and continue the work.
11008
+ *
11009
+ * @param handoffId - The ID of the handoff request to accept
11010
+ * @throws HandoffValidationError if no request exists with the given ID
11011
+ * @throws HandoffValidationError if the request has already been responded to
11012
+ *
11013
+ * @example
11014
+ * ```typescript
11015
+ * // Get pending handoffs for this agent
11016
+ * const pending = await client.getPendingHandoffs("agent-b");
11017
+ * if (pending.length > 0) {
11018
+ * await client.acceptHandoff(pending[0].requestId);
11019
+ * }
11020
+ * ```
11021
+ */
11022
+ async acceptHandoff(handoffId) {
11023
+ const request = this.requests.get(handoffId);
11024
+ if (!request) {
11025
+ throw new HandoffValidationError(
11026
+ `No handoff request found with ID '${handoffId}'`
11027
+ );
11028
+ }
11029
+ if (this.responses.has(handoffId)) {
11030
+ throw new HandoffValidationError(
11031
+ `Handoff request '${handoffId}' has already been responded to`
11032
+ );
11033
+ }
11034
+ const response = {
11035
+ requestId: handoffId,
11036
+ accepted: true,
11037
+ acceptingAgent: request.toAgent
11038
+ };
11039
+ this.responses.set(handoffId, response);
11040
+ if (request.toAgent && this.pendingByAgent.has(request.toAgent)) {
11041
+ this.pendingByAgent.get(request.toAgent).delete(handoffId);
11042
+ }
11043
+ }
11044
+ /**
11045
+ * Reject a pending handoff request.
11046
+ *
11047
+ * Called by the target agent to reject a handoff. A reason should be
11048
+ * provided to help the originating agent determine next steps.
11049
+ *
11050
+ * @param handoffId - The ID of the handoff request to reject
11051
+ * @param reason - Human-readable reason for the rejection
11052
+ * @throws HandoffValidationError if no request exists with the given ID
11053
+ * @throws HandoffValidationError if the request has already been responded to
11054
+ *
11055
+ * @example
11056
+ * ```typescript
11057
+ * await client.rejectHandoff("handoff-123", "Agent at capacity");
11058
+ * ```
11059
+ */
11060
+ async rejectHandoff(handoffId, reason) {
11061
+ const request = this.requests.get(handoffId);
11062
+ if (!request) {
11063
+ throw new HandoffValidationError(
11064
+ `No handoff request found with ID '${handoffId}'`
11065
+ );
11066
+ }
11067
+ if (this.responses.has(handoffId)) {
11068
+ throw new HandoffValidationError(
11069
+ `Handoff request '${handoffId}' has already been responded to`
11070
+ );
11071
+ }
11072
+ const response = {
11073
+ requestId: handoffId,
11074
+ accepted: false,
11075
+ rejectionReason: reason
11076
+ };
11077
+ this.responses.set(handoffId, response);
11078
+ if (request.toAgent && this.pendingByAgent.has(request.toAgent)) {
11079
+ this.pendingByAgent.get(request.toAgent).delete(handoffId);
11080
+ }
11081
+ }
11082
+ /**
11083
+ * Get all pending handoff requests for an agent.
11084
+ *
11085
+ * Returns handoff requests that have been addressed to the specified
11086
+ * agent and have not yet been accepted or rejected.
11087
+ *
11088
+ * @param agentId - The ID of the agent to get pending handoffs for
11089
+ * @returns List of pending handoff requests for the agent
11090
+ *
11091
+ * @example
11092
+ * ```typescript
11093
+ * const pending = await client.getPendingHandoffs("agent-b");
11094
+ * console.log(`${pending.length} pending handoffs`);
11095
+ * for (const request of pending) {
11096
+ * console.log(`From ${request.fromAgent}: ${request.reason}`);
11097
+ * }
11098
+ * ```
11099
+ */
11100
+ async getPendingHandoffs(agentId) {
11101
+ const pendingIds = this.pendingByAgent.get(agentId);
11102
+ if (!pendingIds) {
11103
+ return [];
11104
+ }
11105
+ const pending = [];
11106
+ for (const requestId of pendingIds) {
11107
+ const request = this.requests.get(requestId);
11108
+ if (request && !this.responses.has(requestId)) {
11109
+ pending.push(request);
11110
+ }
11111
+ }
11112
+ return pending;
11113
+ }
11114
+ /**
11115
+ * Get the response for a handoff request.
11116
+ *
11117
+ * Returns the response if the handoff has been accepted, rejected, or
11118
+ * timed out. Returns null if the handoff is still pending.
11119
+ *
11120
+ * @param handoffId - The ID of the handoff request
11121
+ * @returns The handoff response if available, null otherwise
11122
+ */
11123
+ async getHandoffResponse(handoffId) {
11124
+ return this.responses.get(handoffId) || null;
11125
+ }
11126
+ /**
11127
+ * Get the original handoff request.
11128
+ *
11129
+ * @param handoffId - The ID of the handoff request
11130
+ * @returns The handoff request if it exists, null otherwise
11131
+ */
11132
+ async getHandoffRequest(handoffId) {
11133
+ return this.requests.get(handoffId) || null;
11134
+ }
11135
+ };
11136
+
11137
+ // src/clients/workflow.ts
11138
+ var NodeStatus = /* @__PURE__ */ ((NodeStatus2) => {
11139
+ NodeStatus2[NodeStatus2["NODE_STATUS_UNSPECIFIED"] = 0] = "NODE_STATUS_UNSPECIFIED";
11140
+ NodeStatus2[NodeStatus2["PENDING"] = 1] = "PENDING";
11141
+ NodeStatus2[NodeStatus2["READY"] = 2] = "READY";
11142
+ NodeStatus2[NodeStatus2["RUNNING"] = 3] = "RUNNING";
11143
+ NodeStatus2[NodeStatus2["COMPLETED"] = 4] = "COMPLETED";
11144
+ NodeStatus2[NodeStatus2["FAILED"] = 5] = "FAILED";
11145
+ NodeStatus2[NodeStatus2["SKIPPED"] = 6] = "SKIPPED";
11146
+ return NodeStatus2;
11147
+ })(NodeStatus || {});
11148
+ var TriggerType = /* @__PURE__ */ ((TriggerType2) => {
11149
+ TriggerType2[TriggerType2["TRIGGER_TYPE_UNSPECIFIED"] = 0] = "TRIGGER_TYPE_UNSPECIFIED";
11150
+ TriggerType2[TriggerType2["EVENT"] = 1] = "EVENT";
11151
+ TriggerType2[TriggerType2["SCHEDULE"] = 2] = "SCHEDULE";
11152
+ TriggerType2[TriggerType2["MANUAL"] = 3] = "MANUAL";
11153
+ TriggerType2[TriggerType2["DEPENDENCY"] = 4] = "DEPENDENCY";
11154
+ return TriggerType2;
11155
+ })(TriggerType || {});
11156
+ var WorkflowStatus = /* @__PURE__ */ ((WorkflowStatus2) => {
11157
+ WorkflowStatus2[WorkflowStatus2["WORKFLOW_STATUS_UNSPECIFIED"] = 0] = "WORKFLOW_STATUS_UNSPECIFIED";
11158
+ WorkflowStatus2[WorkflowStatus2["CREATED"] = 1] = "CREATED";
11159
+ WorkflowStatus2[WorkflowStatus2["RUNNING"] = 2] = "RUNNING";
11160
+ WorkflowStatus2[WorkflowStatus2["COMPLETED"] = 3] = "COMPLETED";
11161
+ WorkflowStatus2[WorkflowStatus2["FAILED"] = 4] = "FAILED";
11162
+ WorkflowStatus2[WorkflowStatus2["CANCELLED"] = 5] = "CANCELLED";
11163
+ WorkflowStatus2[WorkflowStatus2["PAUSED"] = 6] = "PAUSED";
11164
+ return WorkflowStatus2;
11165
+ })(WorkflowStatus || {});
11166
+ var WorkflowValidationError = class extends Error {
11167
+ constructor(message) {
11168
+ super(message);
11169
+ this.name = "WorkflowValidationError";
11170
+ }
11171
+ };
11172
+ var WorkflowCycleError = class extends Error {
11173
+ constructor(message) {
11174
+ super(message);
11175
+ this.name = "WorkflowCycleError";
11176
+ }
11177
+ };
11178
+ function validateWorkflowDefinition(definition) {
11179
+ const nodeIds = new Set(Object.keys(definition.nodes));
11180
+ for (const [nodeId, node] of Object.entries(definition.nodes)) {
11181
+ for (const dep of node.dependencies) {
11182
+ if (!nodeIds.has(dep)) {
11183
+ throw new WorkflowValidationError(
11184
+ `Node '${nodeId}' has dependency '${dep}' which does not exist`
11185
+ );
11186
+ }
11187
+ if (dep === nodeId) {
11188
+ throw new WorkflowCycleError(
11189
+ `Node '${nodeId}' has a self-dependency`
11190
+ );
11191
+ }
11192
+ }
11193
+ }
11194
+ const visited = /* @__PURE__ */ new Set();
11195
+ const recursionStack = /* @__PURE__ */ new Set();
11196
+ function hasCycle(nodeId) {
11197
+ if (recursionStack.has(nodeId)) {
11198
+ return true;
11199
+ }
11200
+ if (visited.has(nodeId)) {
11201
+ return false;
11202
+ }
11203
+ visited.add(nodeId);
11204
+ recursionStack.add(nodeId);
11205
+ const node = definition.nodes[nodeId];
11206
+ for (const dep of node.dependencies) {
11207
+ if (hasCycle(dep)) {
11208
+ return true;
11209
+ }
11210
+ }
11211
+ recursionStack.delete(nodeId);
11212
+ return false;
11213
+ }
11214
+ for (const nodeId of nodeIds) {
11215
+ if (hasCycle(nodeId)) {
11216
+ throw new WorkflowCycleError(
11217
+ `Workflow contains a cycle involving node '${nodeId}'`
11218
+ );
11219
+ }
11220
+ }
11221
+ }
11222
+ function generateInstanceId() {
11223
+ return `wf-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
11224
+ }
11225
+ var WorkflowClient = class {
11226
+ definitions = /* @__PURE__ */ new Map();
11227
+ instances = /* @__PURE__ */ new Map();
11228
+ instancesByWorkflow = /* @__PURE__ */ new Map();
11229
+ /**
11230
+ * Create a new workflow from a definition.
11231
+ *
11232
+ * Validates the workflow definition and stores it for later execution.
11233
+ *
11234
+ * @param definition - The workflow definition to create
11235
+ * @returns The workflow_id of the created workflow
11236
+ * @throws WorkflowValidationError if the definition is invalid
11237
+ * @throws WorkflowCycleError if the workflow contains a cycle
11238
+ *
11239
+ * @example
11240
+ * ```typescript
11241
+ * const client = new WorkflowClient();
11242
+ * const definition: WorkflowDefinition = {
11243
+ * workflowId: "review-workflow",
11244
+ * nodes: {
11245
+ * "produce": {
11246
+ * nodeId: "produce",
11247
+ * agentId: "producer-agent",
11248
+ * dependencies: [],
11249
+ * triggerType: TriggerType.MANUAL,
11250
+ * inputMapping: {},
11251
+ * outputMapping: { "artifact": "produced_artifact" },
11252
+ * metadata: {}
11253
+ * },
11254
+ * "review": {
11255
+ * nodeId: "review",
11256
+ * agentId: "critic-agent",
11257
+ * dependencies: ["produce"],
11258
+ * triggerType: TriggerType.DEPENDENCY,
11259
+ * inputMapping: { "artifact": "produced_artifact" },
11260
+ * outputMapping: { "result": "review_result" },
11261
+ * metadata: {}
11262
+ * }
11263
+ * },
11264
+ * metadata: {}
11265
+ * };
11266
+ * const workflowId = await client.createWorkflow(definition);
11267
+ * ```
11268
+ */
11269
+ async createWorkflow(definition) {
11270
+ validateWorkflowDefinition(definition);
11271
+ if (this.definitions.has(definition.workflowId)) {
11272
+ throw new WorkflowValidationError(
11273
+ `Workflow with ID '${definition.workflowId}' already exists`
11274
+ );
11275
+ }
11276
+ const definitionWithTimestamp = {
11277
+ ...definition,
11278
+ createdAt: definition.createdAt || (/* @__PURE__ */ new Date()).toISOString()
11279
+ };
11280
+ this.definitions.set(definition.workflowId, definitionWithTimestamp);
11281
+ this.instancesByWorkflow.set(definition.workflowId, /* @__PURE__ */ new Set());
11282
+ return definition.workflowId;
11283
+ }
11284
+ /**
11285
+ * Start a new instance of a workflow.
11286
+ *
11287
+ * Creates a new workflow instance and initializes all nodes to their
11288
+ * starting states based on dependencies.
11289
+ *
11290
+ * @param workflowId - The ID of the workflow to start
11291
+ * @param initialData - Optional initial workflow data (JSON string)
11292
+ * @param metadata - Optional runtime metadata
11293
+ * @returns The created workflow instance
11294
+ * @throws WorkflowValidationError if the workflow does not exist
11295
+ *
11296
+ * @example
11297
+ * ```typescript
11298
+ * const instance = await client.startWorkflow("review-workflow");
11299
+ * console.log(instance.status); // WorkflowStatus.RUNNING
11300
+ * ```
11301
+ */
11302
+ async startWorkflow(workflowId, initialData, metadata) {
11303
+ const definition = this.definitions.get(workflowId);
11304
+ if (!definition) {
11305
+ throw new WorkflowValidationError(
11306
+ `Workflow with ID '${workflowId}' does not exist`
11307
+ );
11308
+ }
11309
+ const instanceId = generateInstanceId();
11310
+ const now = (/* @__PURE__ */ new Date()).toISOString();
11311
+ const nodeStates = {};
11312
+ for (const [nodeId, node] of Object.entries(definition.nodes)) {
11313
+ const status = node.dependencies.length === 0 ? 2 /* READY */ : 1 /* PENDING */;
11314
+ nodeStates[nodeId] = {
11315
+ nodeId,
11316
+ status
11317
+ };
11318
+ }
11319
+ const instance = {
11320
+ instanceId,
11321
+ workflowId,
11322
+ status: 2 /* RUNNING */,
11323
+ nodeStates,
11324
+ workflowData: initialData || "{}",
11325
+ startedAt: now,
11326
+ metadata: metadata || {}
11327
+ };
11328
+ this.instances.set(instanceId, instance);
11329
+ this.instancesByWorkflow.get(workflowId).add(instanceId);
11330
+ return instance;
11331
+ }
11332
+ /**
11333
+ * Get the current status of a workflow instance.
11334
+ *
11335
+ * @param instanceId - The ID of the workflow instance
11336
+ * @returns The workflow instance with current state
11337
+ * @throws WorkflowValidationError if the instance does not exist
11338
+ *
11339
+ * @example
11340
+ * ```typescript
11341
+ * const instance = await client.getWorkflowStatus("wf-123-abc");
11342
+ * console.log(instance.status);
11343
+ * for (const [nodeId, state] of Object.entries(instance.nodeStates)) {
11344
+ * console.log(`${nodeId}: ${NodeStatus[state.status]}`);
11345
+ * }
11346
+ * ```
11347
+ */
11348
+ async getWorkflowStatus(instanceId) {
11349
+ const instance = this.instances.get(instanceId);
11350
+ if (!instance) {
11351
+ throw new WorkflowValidationError(
11352
+ `Workflow instance with ID '${instanceId}' does not exist`
11353
+ );
11354
+ }
11355
+ return instance;
11356
+ }
11357
+ /**
11358
+ * Cancel a running workflow instance.
11359
+ *
11360
+ * Marks the workflow as cancelled and stops any pending nodes.
11361
+ *
11362
+ * @param instanceId - The ID of the workflow instance to cancel
11363
+ * @throws WorkflowValidationError if the instance does not exist
11364
+ * @throws WorkflowValidationError if the workflow is not in a cancellable state
11365
+ *
11366
+ * @example
11367
+ * ```typescript
11368
+ * await client.cancelWorkflow("wf-123-abc");
11369
+ * const instance = await client.getWorkflowStatus("wf-123-abc");
11370
+ * console.log(instance.status); // WorkflowStatus.CANCELLED
11371
+ * ```
11372
+ */
11373
+ async cancelWorkflow(instanceId) {
11374
+ const instance = this.instances.get(instanceId);
11375
+ if (!instance) {
11376
+ throw new WorkflowValidationError(
11377
+ `Workflow instance with ID '${instanceId}' does not exist`
11378
+ );
11379
+ }
11380
+ if (instance.status === 3 /* COMPLETED */ || instance.status === 4 /* FAILED */ || instance.status === 5 /* CANCELLED */) {
11381
+ throw new WorkflowValidationError(
11382
+ `Workflow instance '${instanceId}' is already in terminal state '${WorkflowStatus[instance.status]}'`
11383
+ );
11384
+ }
11385
+ instance.status = 5 /* CANCELLED */;
11386
+ instance.completedAt = (/* @__PURE__ */ new Date()).toISOString();
11387
+ for (const nodeState of Object.values(instance.nodeStates)) {
11388
+ if (nodeState.status === 1 /* PENDING */ || nodeState.status === 2 /* READY */) {
11389
+ nodeState.status = 6 /* SKIPPED */;
11390
+ }
11391
+ }
11392
+ this.instances.set(instanceId, instance);
11393
+ }
11394
+ /**
11395
+ * Get the workflow definition.
11396
+ *
11397
+ * @param workflowId - The ID of the workflow
11398
+ * @returns The workflow definition if it exists, null otherwise
11399
+ */
11400
+ async getWorkflowDefinition(workflowId) {
11401
+ return this.definitions.get(workflowId) || null;
11402
+ }
11403
+ /**
11404
+ * List all instances of a workflow.
11405
+ *
11406
+ * @param workflowId - The ID of the workflow
11407
+ * @returns List of all instances for the workflow
11408
+ */
11409
+ async listWorkflowInstances(workflowId) {
11410
+ const instanceIds = this.instancesByWorkflow.get(workflowId);
11411
+ if (!instanceIds) {
11412
+ return [];
11413
+ }
11414
+ const instances = [];
11415
+ for (const instanceId of instanceIds) {
11416
+ const instance = this.instances.get(instanceId);
11417
+ if (instance) {
11418
+ instances.push(instance);
11419
+ }
11420
+ }
11421
+ return instances;
11422
+ }
11423
+ /**
11424
+ * Update the state of a node in a workflow instance.
11425
+ *
11426
+ * This is an internal method used by node executors to report progress.
11427
+ *
11428
+ * @param instanceId - The ID of the workflow instance
11429
+ * @param nodeId - The ID of the node to update
11430
+ * @param status - The new status of the node
11431
+ * @param output - Optional output data from the node
11432
+ * @param error - Optional error message if the node failed
11433
+ * @throws WorkflowValidationError if the instance or node does not exist
11434
+ */
11435
+ async updateNodeState(instanceId, nodeId, status, output, error) {
11436
+ const instance = this.instances.get(instanceId);
11437
+ if (!instance) {
11438
+ throw new WorkflowValidationError(
11439
+ `Workflow instance with ID '${instanceId}' does not exist`
11440
+ );
11441
+ }
11442
+ const nodeState = instance.nodeStates[nodeId];
11443
+ if (!nodeState) {
11444
+ throw new WorkflowValidationError(
11445
+ `Node '${nodeId}' does not exist in workflow instance '${instanceId}'`
11446
+ );
11447
+ }
11448
+ const now = (/* @__PURE__ */ new Date()).toISOString();
11449
+ nodeState.status = status;
11450
+ if (status === 3 /* RUNNING */ && !nodeState.startedAt) {
11451
+ nodeState.startedAt = now;
11452
+ }
11453
+ if (status === 4 /* COMPLETED */ || status === 5 /* FAILED */ || status === 6 /* SKIPPED */) {
11454
+ nodeState.completedAt = now;
11455
+ }
11456
+ if (output !== void 0) {
11457
+ nodeState.output = output;
11458
+ }
11459
+ if (error !== void 0) {
11460
+ nodeState.error = error;
11461
+ }
11462
+ if (status === 4 /* COMPLETED */) {
11463
+ const definition = this.definitions.get(instance.workflowId);
11464
+ if (definition) {
11465
+ this.updateDependentNodes(instance, definition, nodeId);
11466
+ }
11467
+ }
11468
+ this.checkWorkflowCompletion(instance);
11469
+ this.instances.set(instanceId, instance);
11470
+ }
11471
+ /**
11472
+ * Update the status of nodes that depend on a completed node.
11473
+ */
11474
+ updateDependentNodes(instance, definition, completedNodeId) {
11475
+ for (const [nodeId, node] of Object.entries(definition.nodes)) {
11476
+ if (node.dependencies.includes(completedNodeId)) {
11477
+ const nodeState = instance.nodeStates[nodeId];
11478
+ if (nodeState.status === 1 /* PENDING */) {
11479
+ const allDepsComplete = node.dependencies.every((dep) => {
11480
+ const depState = instance.nodeStates[dep];
11481
+ return depState && depState.status === 4 /* COMPLETED */;
11482
+ });
11483
+ if (allDepsComplete) {
11484
+ nodeState.status = 2 /* READY */;
11485
+ }
11486
+ }
11487
+ }
11488
+ }
11489
+ }
11490
+ /**
11491
+ * Check if a workflow instance is complete and update its status.
11492
+ */
11493
+ checkWorkflowCompletion(instance) {
11494
+ const nodeStatuses = Object.values(instance.nodeStates).map((s) => s.status);
11495
+ if (nodeStatuses.some((s) => s === 5 /* FAILED */)) {
11496
+ instance.status = 4 /* FAILED */;
11497
+ instance.completedAt = (/* @__PURE__ */ new Date()).toISOString();
11498
+ return;
11499
+ }
11500
+ const allComplete = nodeStatuses.every(
11501
+ (s) => s === 4 /* COMPLETED */ || s === 6 /* SKIPPED */
11502
+ );
11503
+ if (allComplete) {
11504
+ instance.status = 3 /* COMPLETED */;
11505
+ instance.completedAt = (/* @__PURE__ */ new Date()).toISOString();
11506
+ }
11507
+ }
11508
+ /**
11509
+ * Resume a workflow by marking a node as completed and advancing dependents.
11510
+ *
11511
+ * Implements the ResumeWorkflow RPC (spec §17.7 MUST). Marks the specified
11512
+ * node as COMPLETED, updates workflow data if provided, then transitions
11513
+ * dependent nodes from PENDING to READY when all their dependencies are met.
11514
+ *
11515
+ * @param instanceId - The ID of the workflow instance
11516
+ * @param nodeId - The ID of the node to mark as completed
11517
+ * @param workflowData - Optional updated workflow data (JSON string)
11518
+ * @param metadata - Optional metadata for the resume operation
11519
+ * @returns The updated workflow instance
11520
+ * @throws WorkflowValidationError if the instance or node does not exist
11521
+ */
11522
+ async resumeWorkflow(instanceId, nodeId, workflowData, metadata) {
11523
+ await this.updateNodeState(instanceId, nodeId, 4 /* COMPLETED */);
11524
+ if (workflowData !== void 0) {
11525
+ await this.updateWorkflowData(instanceId, workflowData);
11526
+ }
11527
+ if (metadata) {
11528
+ const instance = this.instances.get(instanceId);
11529
+ Object.assign(instance.metadata, metadata);
11530
+ }
11531
+ return this.getWorkflowStatus(instanceId);
11532
+ }
11533
+ /**
11534
+ * Update the shared workflow data.
11535
+ *
11536
+ * @param instanceId - The ID of the workflow instance
11537
+ * @param workflowData - The new workflow data (JSON string)
11538
+ * @throws WorkflowValidationError if the instance does not exist
11539
+ */
11540
+ async updateWorkflowData(instanceId, workflowData) {
11541
+ const instance = this.instances.get(instanceId);
11542
+ if (!instance) {
11543
+ throw new WorkflowValidationError(
11544
+ `Workflow instance with ID '${instanceId}' does not exist`
11545
+ );
11546
+ }
11547
+ instance.workflowData = workflowData;
11548
+ this.instances.set(instanceId, instance);
11549
+ }
11550
+ };
11551
+
11552
+ // src/internal/envelope.ts
11553
+ var import_node_crypto2 = __toESM(require("node:crypto"), 1);
11554
+ var MessageType = /* @__PURE__ */ ((MessageType2) => {
11555
+ MessageType2[MessageType2["MESSAGE_TYPE_UNSPECIFIED"] = 0] = "MESSAGE_TYPE_UNSPECIFIED";
11556
+ MessageType2[MessageType2["CONTROL"] = 1] = "CONTROL";
11557
+ MessageType2[MessageType2["DATA"] = 2] = "DATA";
11558
+ MessageType2[MessageType2["HEARTBEAT"] = 3] = "HEARTBEAT";
11559
+ MessageType2[MessageType2["NOTIFICATION"] = 4] = "NOTIFICATION";
11560
+ MessageType2[MessageType2["ACKNOWLEDGEMENT"] = 5] = "ACKNOWLEDGEMENT";
11561
+ MessageType2[MessageType2["HITL_INVOCATION"] = 6] = "HITL_INVOCATION";
11562
+ MessageType2[MessageType2["WORKTREE_CONTROL"] = 7] = "WORKTREE_CONTROL";
11563
+ MessageType2[MessageType2["NEGOTIATION"] = 8] = "NEGOTIATION";
11564
+ MessageType2[MessageType2["TOOL_CALL"] = 9] = "TOOL_CALL";
11565
+ MessageType2[MessageType2["TOOL_RESULT"] = 10] = "TOOL_RESULT";
11566
+ MessageType2[MessageType2["TOOL_ERROR"] = 11] = "TOOL_ERROR";
11567
+ return MessageType2;
11568
+ })(MessageType || {});
11569
+ function nowTimestamp(date = /* @__PURE__ */ new Date()) {
11570
+ const ms = date.getTime();
11571
+ const seconds = Math.floor(ms / 1e3);
11572
+ const nanos = ms % 1e3 * 1e6;
11573
+ return { seconds, nanos };
11574
+ }
11575
+ function nowHlcStub(date = /* @__PURE__ */ new Date()) {
11576
+ const wallUs = date.getTime() * 1e3;
11577
+ let node = "unknown";
11578
+ try {
11579
+ const os = require("node:os");
11580
+ node = os.hostname() || "unknown";
11581
+ } catch {
11582
+ node = "browser";
11583
+ }
11584
+ return `HLC:${wallUs}:0:${node}`;
11585
+ }
11586
+ function uuidv42() {
11587
+ if (typeof import_node_crypto2.default.randomUUID === "function") {
11588
+ return import_node_crypto2.default.randomUUID();
11589
+ }
11590
+ const buf = import_node_crypto2.default.randomBytes(16);
11591
+ buf[6] = buf[6] & 15 | 64;
11592
+ buf[8] = buf[8] & 63 | 128;
11593
+ const hex = [...buf].map((b) => b.toString(16).padStart(2, "0"));
11594
+ return hex.slice(0, 4).join("") + "-" + hex.slice(4, 6).join("") + "-" + hex.slice(6, 8).join("") + "-" + hex.slice(8, 10).join("") + "-" + hex.slice(10, 16).join("");
11595
+ }
11596
+ function buildEnvelope(input) {
11597
+ const hasPayload = input.payload !== void 0;
11598
+ const content_type = input.content_type ?? "application/json";
11599
+ const message_id = uuidv42();
11600
+ const correlation_id = input.correlation_id ?? uuidv42();
11601
+ const sequence_number = input.sequence_number ?? 1;
11602
+ const retry_count = input.retry_count ?? 0;
11603
+ const ts = nowTimestamp(input.timestamp ?? /* @__PURE__ */ new Date());
11604
+ const hlc_timestamp = input.hlc_timestamp ?? nowHlcStub(input.timestamp);
11605
+ const built = {
11606
+ message_id,
11607
+ idempotency_token: input.idempotency_token,
11608
+ producer_id: input.producer_id,
11609
+ correlation_id,
11610
+ sequence_number,
11611
+ retry_count,
11612
+ message_type: input.message_type,
11613
+ content_type,
11614
+ // Always set content_type (aligns with Python/Rust)
11615
+ repo_id: input.repo_id,
11616
+ worktree_id: input.worktree_id,
11617
+ hlc_timestamp,
11618
+ // Always set hlc_timestamp (aligns with Python/Rust)
11619
+ ttl_ms: input.ttl_ms,
11620
+ timestamp: ts,
11621
+ state: input.state ?? 1,
11622
+ // EnvelopeState.CREATED
11623
+ effective_policy_id: input.effective_policy_id ?? "",
11624
+ audit_proof: input.audit_proof ?? new Uint8Array(0),
11625
+ audit_policy_id: input.audit_policy_id ?? ""
11626
+ };
11627
+ if (hasPayload) {
11628
+ const payload = input.payload instanceof Uint8Array ? input.payload : new Uint8Array(input.payload);
11629
+ built.payload = payload;
11630
+ built.content_length = payload.byteLength;
11631
+ if (!input.content_type) {
11632
+ built.content_type = "application/octet-stream";
11633
+ }
11634
+ }
11635
+ return built;
11636
+ }
11637
+
11638
+ // src/internal/worktreeState.ts
11639
+ var VALID_WORKTREE_TRANSITIONS = {
11640
+ UNBOUND: ["BOUND_HOME", "BIND_FAILED"],
11641
+ BOUND_HOME: ["SWITCH_PENDING", "UNBOUND"],
11642
+ SWITCH_PENDING: ["BOUND_NON_HOME", "BOUND_HOME"],
11643
+ // approve or reject
11644
+ BOUND_NON_HOME: ["BOUND_HOME", "UNBOUND"],
11645
+ // TTL expired/revoke, or unbind
11646
+ BIND_FAILED: ["UNBOUND", "BOUND_HOME"]
11647
+ // retry reset or successful retry
11648
+ };
11649
+ function isValidWorktreeTransition(from, to) {
11650
+ return VALID_WORKTREE_TRANSITIONS[from]?.includes(to) ?? false;
11651
+ }
11652
+ var WorktreeTransitionError = class extends Error {
11653
+ fromState;
11654
+ toState;
11655
+ constructor(from, to) {
11656
+ super(`Invalid worktree state transition from ${from} to ${to}`);
11657
+ this.name = "WorktreeTransitionError";
11658
+ this.fromState = from;
11659
+ this.toState = to;
11660
+ }
11661
+ };
11662
+ var PersistentWorktreeState = class {
11663
+ state = "UNBOUND";
11664
+ repoId;
11665
+ worktreeId;
11666
+ homeRepoId;
11667
+ homeWorktreeId;
11668
+ switchTtlMs;
11669
+ switchTimer;
11670
+ /**
11671
+ * Transition to a new state with validation.
11672
+ * @throws WorktreeTransitionError if transition is invalid
11673
+ */
11674
+ transitionTo(newState) {
11675
+ if (!isValidWorktreeTransition(this.state, newState)) {
11676
+ throw new WorktreeTransitionError(this.state, newState);
11677
+ }
11678
+ this.state = newState;
11679
+ }
11680
+ /**
11681
+ * Bind to a home worktree (UNBOUND -> BOUND_HOME or BIND_FAILED -> BOUND_HOME).
11682
+ */
11683
+ bind(repoId, worktreeId) {
11684
+ this.transitionTo("BOUND_HOME");
11685
+ this.repoId = repoId;
11686
+ this.worktreeId = worktreeId;
11687
+ this.homeRepoId = repoId;
11688
+ this.homeWorktreeId = worktreeId;
11689
+ }
11690
+ /**
11691
+ * Handle bind failure (UNBOUND -> BIND_FAILED).
11692
+ */
11693
+ bindFailed() {
11694
+ this.transitionTo("BIND_FAILED");
11695
+ }
11696
+ /**
11697
+ * Unbind from current worktree.
11698
+ */
11699
+ unbind() {
11700
+ this.clearSwitchTimer();
11701
+ this.transitionTo("UNBOUND");
11702
+ this.repoId = void 0;
11703
+ this.worktreeId = void 0;
11704
+ }
11705
+ /**
11706
+ * Request switch to a non-home worktree (BOUND_HOME -> SWITCH_PENDING).
11707
+ * Requires approval or rejection before taking effect.
11708
+ */
11709
+ requestSwitch(targetRepoId, targetWorktreeId) {
11710
+ this.transitionTo("SWITCH_PENDING");
11711
+ this._pendingRepoId = targetRepoId;
11712
+ this._pendingWorktreeId = targetWorktreeId;
11713
+ }
11714
+ /**
11715
+ * Approve a pending switch (SWITCH_PENDING -> BOUND_NON_HOME).
11716
+ * @param ttlMs - Time-to-live in milliseconds before auto-reverting to BOUND_HOME
11717
+ */
11718
+ approveSwitch(ttlMs = 3e5) {
11719
+ this.transitionTo("BOUND_NON_HOME");
11720
+ this.repoId = this._pendingRepoId;
11721
+ this.worktreeId = this._pendingWorktreeId;
11722
+ this.switchTtlMs = ttlMs;
11723
+ this.clearSwitchTimer();
11724
+ this.switchTimer = setTimeout(() => {
11725
+ this.revertToHome();
11726
+ }, ttlMs);
11727
+ }
11728
+ /**
11729
+ * Reject a pending switch (SWITCH_PENDING -> BOUND_HOME).
11730
+ */
11731
+ rejectSwitch() {
11732
+ this.transitionTo("BOUND_HOME");
11733
+ this.repoId = this.homeRepoId;
11734
+ this.worktreeId = this.homeWorktreeId;
11735
+ delete this._pendingRepoId;
11736
+ delete this._pendingWorktreeId;
11737
+ }
11738
+ /**
11739
+ * Revert from non-home to home worktree (BOUND_NON_HOME -> BOUND_HOME).
11740
+ * Called on TTL expiry or explicit revoke.
11741
+ */
11742
+ revertToHome() {
11743
+ this.clearSwitchTimer();
11744
+ if (this.state === "BOUND_NON_HOME") {
11745
+ this.transitionTo("BOUND_HOME");
11746
+ this.repoId = this.homeRepoId;
11747
+ this.worktreeId = this.homeWorktreeId;
11748
+ }
11749
+ }
11750
+ /**
11751
+ * Reset from BIND_FAILED to UNBOUND for retry.
11752
+ */
11753
+ resetFromFailed() {
11754
+ this.transitionTo("UNBOUND");
11755
+ }
11756
+ clearSwitchTimer() {
11757
+ if (this.switchTimer) {
11758
+ clearTimeout(this.switchTimer);
11759
+ this.switchTimer = void 0;
11760
+ }
11761
+ }
11762
+ setState(state) {
11763
+ this.state = state;
11764
+ }
11765
+ current() {
11766
+ return {
11767
+ state: this.state,
11768
+ repo_id: this.repoId,
11769
+ worktree_id: this.worktreeId,
11770
+ home_repo_id: this.homeRepoId,
11771
+ home_worktree_id: this.homeWorktreeId,
11772
+ switch_ttl_ms: this.switchTtlMs
11773
+ };
11774
+ }
11775
+ };
11776
+
11777
+ // src/internal/runtime/activityBuffer.ts
11778
+ var MaxEntriesStrategy = class {
11779
+ prune(records, maxEntries) {
11780
+ if (records.length <= maxEntries)
11781
+ return records;
11782
+ const overflow = records.length - maxEntries;
11783
+ return records.slice(overflow);
11784
+ }
11785
+ };
11786
+ var ActivityBuffer = class {
11787
+ records = /* @__PURE__ */ new Map();
11788
+ maxEntries;
11789
+ strategy;
11790
+ constructor(opts) {
11791
+ this.maxEntries = opts?.maxEntries ?? 1e3;
11792
+ this.strategy = opts?.strategy ?? new MaxEntriesStrategy();
11793
+ }
11794
+ upsert(rec) {
11795
+ this.records.set(rec.task_id, rec);
11796
+ this.prune();
11797
+ }
11798
+ remove(taskId) {
11799
+ this.records.delete(taskId);
11800
+ }
11801
+ list() {
11802
+ return [...this.records.values()].sort((a, b) => a.timestamp.localeCompare(b.timestamp));
11803
+ }
11804
+ recent(limit = 50) {
11805
+ const arr = this.list();
11806
+ return arr.slice(Math.max(0, arr.length - limit));
11807
+ }
11808
+ reconcile(knownTaskIds) {
11809
+ for (const id of this.records.keys()) {
11810
+ if (!knownTaskIds.has(id))
11811
+ this.records.delete(id);
11812
+ }
11813
+ }
11814
+ prune() {
11815
+ const arr = this.list();
11816
+ const pruned = this.strategy.prune(arr, this.maxEntries);
11817
+ if (pruned.length === arr.length)
11818
+ return;
11819
+ this.records.clear();
11820
+ for (const r of pruned)
11821
+ this.records.set(r.task_id, r);
11822
+ }
11823
+ toJSON() {
11824
+ return this.list();
11825
+ }
11826
+ fromJSON(records) {
11827
+ this.records.clear();
11828
+ for (const r of records)
11829
+ this.records.set(r.task_id, r);
11830
+ this.prune();
11831
+ }
11832
+ };
11833
+
11834
+ // src/internal/runtime/ackLifecycle.ts
11835
+ var ACKLifecycleManager = class {
11836
+ acks = /* @__PURE__ */ new Map();
11837
+ mark(messageId, stage, note, errorCode) {
11838
+ const st = {
11839
+ messageId,
11840
+ stage,
11841
+ lastUpdateIso: (/* @__PURE__ */ new Date()).toISOString(),
11842
+ note,
11843
+ errorCode
11844
+ };
11845
+ this.acks.set(messageId, st);
11846
+ }
11847
+ get(messageId) {
11848
+ return this.acks.get(messageId);
11849
+ }
11850
+ recent(limit = 100) {
11851
+ const arr = [...this.acks.values()].sort((a, b) => a.lastUpdateIso.localeCompare(b.lastUpdateIso));
11852
+ return arr.slice(Math.max(0, arr.length - limit));
11853
+ }
11854
+ reconcileLateAck(messageId, stage) {
11855
+ const curr = this.acks.get(messageId);
11856
+ if (!curr || curr.stage === stage)
11857
+ return;
11858
+ this.mark(messageId, stage, "late_ack_reconciled");
11859
+ }
11860
+ toJSON() {
11861
+ return [...this.acks.values()].sort((a, b) => a.lastUpdateIso.localeCompare(b.lastUpdateIso));
11862
+ }
11863
+ fromJSON(states) {
11864
+ this.acks.clear();
11865
+ for (const s of states)
11866
+ this.acks.set(s.messageId, s);
11867
+ }
11868
+ };
11869
+
11870
+ // src/internal/runtime/messageProcessor.ts
11871
+ var MessageProcessor = class {
11872
+ handlers = /* @__PURE__ */ new Map();
11873
+ defaultHandler;
11874
+ ack;
11875
+ constructor(ack) {
11876
+ this.ack = ack;
11877
+ }
11878
+ registerHandler(type, handler) {
10553
11879
  this.handlers.set(type, handler);
10554
11880
  }
10555
11881
  setDefaultHandler(handler) {
@@ -10584,11 +11910,15 @@ async function sendMessageWithAck(router, inboundStream, envelope, ackLifecycle,
10584
11910
  }
10585
11911
  }
10586
11912
  };
10587
- return new Promise(async (resolve, reject) => {
10588
- let timeout;
11913
+ await router.sendMessage(envelope);
11914
+ return new Promise((resolve, reject) => {
11915
+ const timeout = setTimeout(() => {
11916
+ ackLifecycle.mark(envelope.message_id, 6 /* TIMED_OUT */, "received_timeout");
11917
+ cleanup();
11918
+ reject(new Error("ACK RECEIVED timeout exceeded"));
11919
+ }, receivedTimeoutMs);
10589
11920
  const cleanup = () => {
10590
- if (timeout)
10591
- clearTimeout(timeout);
11921
+ clearTimeout(timeout);
10592
11922
  inboundStream.removeListener("data", onData);
10593
11923
  inboundStream.removeListener("error", onErr);
10594
11924
  };
@@ -10598,27 +11928,13 @@ async function sendMessageWithAck(router, inboundStream, envelope, ackLifecycle,
10598
11928
  };
10599
11929
  inboundStream.on("data", onData);
10600
11930
  inboundStream.on("error", onErr);
10601
- try {
10602
- await router.sendMessage(envelope);
10603
- } catch (e) {
10604
- cleanup();
10605
- return reject(e);
10606
- }
10607
- timeout = setTimeout(() => {
10608
- ackLifecycle.mark(envelope.message_id, 6 /* TIMED_OUT */, "received_timeout");
10609
- cleanup();
10610
- reject(new Error("ACK RECEIVED timeout exceeded"));
10611
- }, receivedTimeoutMs);
10612
11931
  const checkInterval = setInterval(() => {
10613
11932
  const state = ackLifecycle.get(envelope.message_id);
10614
11933
  if (!state)
10615
11934
  return;
10616
11935
  if (state.stage === 1 /* RECEIVED */ || state.stage === 2 /* READ */ || state.stage === 3 /* FULFILLED */) {
10617
11936
  clearInterval(checkInterval);
10618
- if (timeout)
10619
- clearTimeout(timeout);
10620
- inboundStream.removeListener("data", onData);
10621
- inboundStream.removeListener("error", onErr);
11937
+ cleanup();
10622
11938
  resolve();
10623
11939
  }
10624
11940
  }, 25);
@@ -10690,78 +12006,1259 @@ function createResilientIncomingStream(router, agentId, opts) {
10690
12006
  emitter.stop = () => {
10691
12007
  stopped = true;
10692
12008
  try {
10693
- if (current && typeof current.cancel === "function") {
10694
- current.cancel();
12009
+ if (current && typeof current.cancel === "function") {
12010
+ current.cancel();
12011
+ }
12012
+ } catch {
12013
+ }
12014
+ current = null;
12015
+ };
12016
+ start();
12017
+ return emitter;
12018
+ }
12019
+
12020
+ // src/runtime/negotiationEvents.ts
12021
+ function parseNegotiationEvent(json) {
12022
+ try {
12023
+ const obj = JSON.parse(json);
12024
+ if (!obj || typeof obj.kind !== "string")
12025
+ return { kind: "unknown", ...obj || {} };
12026
+ return obj;
12027
+ } catch {
12028
+ return { kind: "unknown", ts: void 0 };
12029
+ }
12030
+ }
12031
+ function decodeBase64(b64) {
12032
+ if (!b64)
12033
+ return void 0;
12034
+ return new Uint8Array(Buffer.from(b64, "base64"));
12035
+ }
12036
+
12037
+ // src/persistence/persistence.ts
12038
+ var import_promises = __toESM(require("node:fs/promises"), 1);
12039
+ var import_node_path2 = __toESM(require("node:path"), 1);
12040
+ var JSONFilePersistence = class {
12041
+ constructor(baseDir) {
12042
+ this.baseDir = baseDir;
12043
+ this.activityFile = import_node_path2.default.join(baseDir, "activity.json");
12044
+ this.acksFile = import_node_path2.default.join(baseDir, "acks.json");
12045
+ }
12046
+ activityFile;
12047
+ acksFile;
12048
+ async safeWrite(file, data) {
12049
+ await import_promises.default.mkdir(import_node_path2.default.dirname(file), { recursive: true });
12050
+ const tmp = `${file}.tmp-${Date.now()}`;
12051
+ await import_promises.default.writeFile(tmp, data, "utf8");
12052
+ await import_promises.default.rename(tmp, file);
12053
+ }
12054
+ async saveActivity(records) {
12055
+ const payload = JSON.stringify(records, null, 2);
12056
+ await this.safeWrite(this.activityFile, payload);
12057
+ }
12058
+ async loadActivity() {
12059
+ try {
12060
+ const buf = await import_promises.default.readFile(this.activityFile, "utf8");
12061
+ return JSON.parse(buf);
12062
+ } catch (e) {
12063
+ if (e?.code === "ENOENT")
12064
+ return [];
12065
+ throw e;
12066
+ }
12067
+ }
12068
+ async saveAcks(states) {
12069
+ const payload = JSON.stringify(states, null, 2);
12070
+ await this.safeWrite(this.acksFile, payload);
12071
+ }
12072
+ async loadAcks() {
12073
+ try {
12074
+ const buf = await import_promises.default.readFile(this.acksFile, "utf8");
12075
+ return JSON.parse(buf);
12076
+ } catch (e) {
12077
+ if (e?.code === "ENOENT")
12078
+ return [];
12079
+ throw e;
12080
+ }
12081
+ }
12082
+ };
12083
+
12084
+ // src/runtime/voting.ts
12085
+ var SimpleAverageAggregator = class {
12086
+ /**
12087
+ * Aggregate votes using simple arithmetic mean.
12088
+ *
12089
+ * @param votes - List of critic votes to aggregate
12090
+ * @returns AggregatedScore with simple mean in both mean and weightedMean fields
12091
+ * @throws NegotiationValidationError if votes list is empty
12092
+ */
12093
+ aggregate(votes) {
12094
+ if (votes.length === 0) {
12095
+ throw new NegotiationValidationError(
12096
+ "Cannot aggregate empty list of votes"
12097
+ );
12098
+ }
12099
+ const scores = votes.map((v) => v.score);
12100
+ const mean = scores.reduce((a, b) => a + b, 0) / scores.length;
12101
+ const minScore = Math.min(...scores);
12102
+ const maxScore = Math.max(...scores);
12103
+ const variance = scores.reduce((sum, s) => sum + Math.pow(s - mean, 2), 0) / scores.length;
12104
+ const stdDev = Math.sqrt(variance);
12105
+ return {
12106
+ mean,
12107
+ minScore,
12108
+ maxScore,
12109
+ stdDev,
12110
+ weightedMean: mean,
12111
+ voteCount: votes.length
12112
+ };
12113
+ }
12114
+ };
12115
+ var ConfidenceWeightedAggregator = class {
12116
+ /**
12117
+ * Aggregate votes using confidence weighting.
12118
+ *
12119
+ * @param votes - List of critic votes to aggregate
12120
+ * @returns AggregatedScore with confidence-weighted mean
12121
+ * @throws NegotiationValidationError if votes list is empty
12122
+ */
12123
+ aggregate(votes) {
12124
+ if (votes.length === 0) {
12125
+ throw new NegotiationValidationError(
12126
+ "Cannot aggregate empty list of votes"
12127
+ );
12128
+ }
12129
+ const scores = votes.map((v) => v.score);
12130
+ const confidences = votes.map((v) => v.confidence);
12131
+ const mean = scores.reduce((a, b) => a + b, 0) / scores.length;
12132
+ const minScore = Math.min(...scores);
12133
+ const maxScore = Math.max(...scores);
12134
+ const variance = scores.reduce((sum, s) => sum + Math.pow(s - mean, 2), 0) / scores.length;
12135
+ const stdDev = Math.sqrt(variance);
12136
+ const totalConfidence = confidences.reduce((a, b) => a + b, 0);
12137
+ let weightedMean;
12138
+ if (totalConfidence > 0) {
12139
+ weightedMean = scores.reduce((sum, s, i) => sum + s * confidences[i], 0) / totalConfidence;
12140
+ } else {
12141
+ weightedMean = mean;
12142
+ }
12143
+ return {
12144
+ mean,
12145
+ minScore,
12146
+ maxScore,
12147
+ stdDev,
12148
+ weightedMean,
12149
+ voteCount: votes.length
12150
+ };
12151
+ }
12152
+ };
12153
+ var MajorityVoteAggregator = class {
12154
+ /**
12155
+ * Aggregate votes using majority voting.
12156
+ *
12157
+ * @param votes - List of critic votes to aggregate
12158
+ * @returns AggregatedScore with score based on majority outcome
12159
+ * @throws NegotiationValidationError if votes list is empty
12160
+ */
12161
+ aggregate(votes) {
12162
+ if (votes.length === 0) {
12163
+ throw new NegotiationValidationError(
12164
+ "Cannot aggregate empty list of votes"
12165
+ );
12166
+ }
12167
+ const scores = votes.map((v) => v.score);
12168
+ const passedCount = votes.filter((v) => v.passed).length;
12169
+ const failedCount = votes.length - passedCount;
12170
+ let majorityScore;
12171
+ if (passedCount === votes.length) {
12172
+ majorityScore = 10;
12173
+ } else if (failedCount === votes.length) {
12174
+ majorityScore = 0;
12175
+ } else if (passedCount > failedCount) {
12176
+ majorityScore = 7.5;
12177
+ } else if (failedCount > passedCount) {
12178
+ majorityScore = 2.5;
12179
+ } else {
12180
+ majorityScore = 5;
12181
+ }
12182
+ const mean = scores.reduce((a, b) => a + b, 0) / scores.length;
12183
+ const minScore = Math.min(...scores);
12184
+ const maxScore = Math.max(...scores);
12185
+ const variance = scores.reduce((sum, s) => sum + Math.pow(s - mean, 2), 0) / scores.length;
12186
+ const stdDev = Math.sqrt(variance);
12187
+ return {
12188
+ mean,
12189
+ minScore,
12190
+ maxScore,
12191
+ stdDev,
12192
+ weightedMean: majorityScore,
12193
+ voteCount: votes.length
12194
+ };
12195
+ }
12196
+ };
12197
+ var BordaCountAggregator = class {
12198
+ /**
12199
+ * Aggregate votes using Borda count.
12200
+ *
12201
+ * @param votes - List of critic votes to aggregate
12202
+ * @returns AggregatedScore with Borda count normalized score
12203
+ * @throws NegotiationValidationError if votes list is empty
12204
+ */
12205
+ aggregate(votes) {
12206
+ if (votes.length === 0) {
12207
+ throw new NegotiationValidationError(
12208
+ "Cannot aggregate empty list of votes"
12209
+ );
12210
+ }
12211
+ const scores = votes.map((v) => v.score);
12212
+ const n = votes.length;
12213
+ const mean = scores.reduce((a, b) => a + b, 0) / n;
12214
+ const minScore = Math.min(...scores);
12215
+ const maxScore = Math.max(...scores);
12216
+ const variance = scores.reduce((sum, s) => sum + Math.pow(s - mean, 2), 0) / n;
12217
+ const stdDev = Math.sqrt(variance);
12218
+ const indexedScores = scores.map((score, idx) => ({ score, idx }));
12219
+ indexedScores.sort((a, b) => b.score - a.score);
12220
+ let totalPoints = 0;
12221
+ for (let rank = 0; rank < indexedScores.length; rank++) {
12222
+ const points = n - rank;
12223
+ totalPoints += points;
12224
+ }
12225
+ const avgPoints = totalPoints / n;
12226
+ const bordaScore = avgPoints / n * 10;
12227
+ return {
12228
+ mean,
12229
+ minScore,
12230
+ maxScore,
12231
+ stdDev,
12232
+ weightedMean: bordaScore,
12233
+ voteCount: n
12234
+ };
12235
+ }
12236
+ };
12237
+ var VotingAnalyzer = class {
12238
+ strategy;
12239
+ /**
12240
+ * Initialize analyzer with a strategy.
12241
+ *
12242
+ * @param strategy - The aggregation strategy to use
12243
+ */
12244
+ constructor(strategy) {
12245
+ this.strategy = strategy;
12246
+ }
12247
+ /**
12248
+ * Aggregate votes using the configured strategy.
12249
+ *
12250
+ * @param votes - List of critic votes to aggregate
12251
+ * @returns AggregatedScore with aggregation results
12252
+ * @throws NegotiationValidationError if votes list is empty
12253
+ */
12254
+ aggregate(votes) {
12255
+ return this.strategy.aggregate(votes);
12256
+ }
12257
+ /**
12258
+ * Compute Shannon entropy of vote distribution.
12259
+ *
12260
+ * Entropy measures the uncertainty or disorder in the vote distribution.
12261
+ * Higher entropy indicates more disagreement/uncertainty, lower entropy
12262
+ * indicates more consensus.
12263
+ *
12264
+ * The score range [0, 10] is divided into bins, and entropy is computed
12265
+ * over the probability distribution of votes across bins.
12266
+ *
12267
+ * @param votes - List of critic votes
12268
+ * @returns Entropy value in bits (0 = perfect consensus, higher = more uncertainty)
12269
+ * @throws NegotiationValidationError if votes list is empty
12270
+ */
12271
+ computeEntropy(votes) {
12272
+ if (votes.length === 0) {
12273
+ throw new NegotiationValidationError(
12274
+ "Cannot compute entropy of empty vote list"
12275
+ );
12276
+ }
12277
+ const numBins = 5;
12278
+ const binWidth = 10 / numBins;
12279
+ const binCounts = new Array(numBins).fill(0);
12280
+ for (const vote of votes) {
12281
+ const binIdx = Math.min(Math.floor(vote.score / binWidth), numBins - 1);
12282
+ binCounts[binIdx]++;
12283
+ }
12284
+ const total = votes.length;
12285
+ let entropy = 0;
12286
+ for (const count of binCounts) {
12287
+ if (count > 0) {
12288
+ const probability = count / total;
12289
+ entropy -= probability * Math.log2(probability);
12290
+ }
12291
+ }
12292
+ return entropy;
12293
+ }
12294
+ /**
12295
+ * Detect if votes show strong consensus.
12296
+ *
12297
+ * Consensus is detected when:
12298
+ * 1. Standard deviation of scores is low (< 2.0)
12299
+ * 2. A large proportion of critics agree on pass/fail (>= threshold)
12300
+ *
12301
+ * @param votes - List of critic votes
12302
+ * @param threshold - Minimum proportion of agreement required (default 0.8 = 80%)
12303
+ * @returns True if consensus is detected, false otherwise
12304
+ * @throws NegotiationValidationError if votes list is empty or threshold not in [0, 1]
12305
+ */
12306
+ detectConsensus(votes, threshold = 0.8) {
12307
+ if (votes.length === 0) {
12308
+ throw new NegotiationValidationError(
12309
+ "Cannot detect consensus in empty vote list"
12310
+ );
12311
+ }
12312
+ if (threshold < 0 || threshold > 1) {
12313
+ throw new NegotiationValidationError(
12314
+ `Threshold must be in [0, 1], got ${threshold}`
12315
+ );
12316
+ }
12317
+ const scores = votes.map((v) => v.score);
12318
+ const mean = scores.reduce((a, b) => a + b, 0) / scores.length;
12319
+ const variance = scores.reduce((sum, s) => sum + Math.pow(s - mean, 2), 0) / scores.length;
12320
+ const stdDev = Math.sqrt(variance);
12321
+ if (stdDev >= 2) {
12322
+ return false;
12323
+ }
12324
+ const passedCount = votes.filter((v) => v.passed).length;
12325
+ const failedCount = votes.length - passedCount;
12326
+ const agreementRatio = Math.max(passedCount, failedCount) / votes.length;
12327
+ return agreementRatio >= threshold;
12328
+ }
12329
+ /**
12330
+ * Detect if votes show polarization (bimodal distribution).
12331
+ *
12332
+ * Polarization is detected when votes cluster into two distinct groups,
12333
+ * typically at opposite ends of the score spectrum. This is identified by:
12334
+ * 1. High standard deviation (>= 3.0)
12335
+ * 2. Low density in the middle range (4-6)
12336
+ * 3. High density in the extremes (0-3 or 7-10)
12337
+ *
12338
+ * @param votes - List of critic votes
12339
+ * @returns True if polarization is detected, false otherwise
12340
+ * @throws NegotiationValidationError if votes list is empty
12341
+ */
12342
+ detectPolarization(votes) {
12343
+ if (votes.length === 0) {
12344
+ throw new NegotiationValidationError(
12345
+ "Cannot detect polarization in empty vote list"
12346
+ );
12347
+ }
12348
+ if (votes.length < 3) {
12349
+ return false;
12350
+ }
12351
+ const scores = votes.map((v) => v.score);
12352
+ const mean = scores.reduce((a, b) => a + b, 0) / scores.length;
12353
+ const variance = scores.reduce((sum, s) => sum + Math.pow(s - mean, 2), 0) / scores.length;
12354
+ const stdDev = Math.sqrt(variance);
12355
+ if (stdDev < 3) {
12356
+ return false;
12357
+ }
12358
+ const lowCount = scores.filter((s) => s <= 3).length;
12359
+ const middleCount = scores.filter((s) => s > 3 && s < 7).length;
12360
+ const highCount = scores.filter((s) => s >= 7).length;
12361
+ const hasLowCluster = lowCount >= votes.length * 0.3;
12362
+ const hasHighCluster = highCount >= votes.length * 0.3;
12363
+ const middleSparse = middleCount <= votes.length * 0.2;
12364
+ return hasLowCluster && hasHighCluster && middleSparse;
12365
+ }
12366
+ /**
12367
+ * Compute variance of confidence levels across votes.
12368
+ *
12369
+ * High variance in confidence suggests critics have different levels of
12370
+ * certainty about their evaluations, which may indicate the artifact is
12371
+ * harder to assess or has ambiguous quality.
12372
+ *
12373
+ * @param votes - List of critic votes
12374
+ * @returns Variance of confidence values
12375
+ * @throws NegotiationValidationError if votes list is empty
12376
+ */
12377
+ computeConfidenceVariance(votes) {
12378
+ if (votes.length === 0) {
12379
+ throw new NegotiationValidationError(
12380
+ "Cannot compute confidence variance of empty vote list"
12381
+ );
12382
+ }
12383
+ const confidences = votes.map((v) => v.confidence);
12384
+ const meanConfidence = confidences.reduce((a, b) => a + b, 0) / confidences.length;
12385
+ const variance = confidences.reduce(
12386
+ (sum, c) => sum + Math.pow(c - meanConfidence, 2),
12387
+ 0
12388
+ ) / confidences.length;
12389
+ return variance;
12390
+ }
12391
+ /**
12392
+ * Get comprehensive summary of vote characteristics.
12393
+ *
12394
+ * Combines multiple analytical methods to provide a complete picture
12395
+ * of the vote distribution and critic agreement.
12396
+ *
12397
+ * @param votes - List of critic votes
12398
+ * @returns Object with summary statistics
12399
+ * @throws NegotiationValidationError if votes list is empty
12400
+ */
12401
+ getVoteSummary(votes) {
12402
+ if (votes.length === 0) {
12403
+ throw new NegotiationValidationError("Cannot summarize empty vote list");
12404
+ }
12405
+ const passedCount = votes.filter((v) => v.passed).length;
12406
+ return {
12407
+ entropy: this.computeEntropy(votes),
12408
+ consensus: this.detectConsensus(votes),
12409
+ polarization: this.detectPolarization(votes),
12410
+ confidenceVariance: this.computeConfidenceVariance(votes),
12411
+ passRate: passedCount / votes.length
12412
+ };
12413
+ }
12414
+ };
12415
+
12416
+ // src/runtime/policyStore.ts
12417
+ var import_promises2 = __toESM(require("node:fs/promises"), 1);
12418
+ var import_node_path3 = __toESM(require("node:path"), 1);
12419
+ var HitlMode = /* @__PURE__ */ ((HitlMode2) => {
12420
+ HitlMode2["NONE"] = "None";
12421
+ HitlMode2["PAUSE_BETWEEN_ROUNDS"] = "PauseBetweenRounds";
12422
+ HitlMode2["PAUSE_ON_FINAL_ACCEPT"] = "PauseOnFinalAccept";
12423
+ return HitlMode2;
12424
+ })(HitlMode || {});
12425
+ var DEFAULT_EXECUTION_POLICY = {
12426
+ timeoutMs: 6e4,
12427
+ maxRetries: 3,
12428
+ backoff: "exponential",
12429
+ worktreeRequired: false,
12430
+ networkPolicy: "restricted",
12431
+ privilegeLevel: "standard",
12432
+ budgetCpuMs: 3e4,
12433
+ budgetWallMs: 6e4
12434
+ };
12435
+ var DEFAULT_ESCALATION_POLICY = {
12436
+ autoEscalateOnDeadlock: true,
12437
+ deadlockRounds: 3,
12438
+ escalationReasons: ["debate_deadlock", "security_flag", "timeout"],
12439
+ defaultAction: "escalate"
12440
+ };
12441
+ var PolicyStoreError = class extends Error {
12442
+ constructor(message) {
12443
+ super(message);
12444
+ this.name = "PolicyStoreError";
12445
+ }
12446
+ };
12447
+ var DEFAULT_NEGOTIATION_POLICY = {
12448
+ maxRounds: 10,
12449
+ scoreThreshold: 0.7,
12450
+ diffTolerance: 0.3,
12451
+ roundTimeoutMs: 3e4,
12452
+ tokenBudgetPerRound: 4096,
12453
+ totalTokenBudget: 0,
12454
+ // unlimited
12455
+ oscillationLimit: 3,
12456
+ hitl: "None" /* NONE */,
12457
+ scoring: {
12458
+ requireSchemaValid: true,
12459
+ requireExamplesPass: false,
12460
+ llmWeight: 0.5
12461
+ }
12462
+ };
12463
+ function generatePolicyId() {
12464
+ return `policy-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
12465
+ }
12466
+ function generatePolicyVersion() {
12467
+ const timestampMs = Date.now();
12468
+ const uniqueId = Math.random().toString(36).substring(2, 11);
12469
+ return `${timestampMs}_${uniqueId}`;
12470
+ }
12471
+ var InMemoryPolicyStore = class {
12472
+ // Maps policy_id -> list of EffectivePolicy (chronological order)
12473
+ policies = /* @__PURE__ */ new Map();
12474
+ profiles = /* @__PURE__ */ new Map();
12475
+ constructor() {
12476
+ this.initializeDefaultProfiles();
12477
+ }
12478
+ /**
12479
+ * Initialize default policy profiles.
12480
+ */
12481
+ initializeDefaultProfiles() {
12482
+ const lowProfile = {
12483
+ name: "LOW",
12484
+ negotiation: {
12485
+ maxRounds: 5,
12486
+ scoreThreshold: 0.6,
12487
+ diffTolerance: 0.4,
12488
+ roundTimeoutMs: 6e4,
12489
+ tokenBudgetPerRound: 2048,
12490
+ totalTokenBudget: 0,
12491
+ oscillationLimit: 5,
12492
+ hitl: "None" /* NONE */,
12493
+ scoring: {
12494
+ requireSchemaValid: false,
12495
+ requireExamplesPass: false,
12496
+ llmWeight: 0.3
12497
+ }
12498
+ },
12499
+ execution: {
12500
+ ...DEFAULT_EXECUTION_POLICY,
12501
+ timeoutMs: 12e4,
12502
+ // More lenient for low priority
12503
+ maxRetries: 5
12504
+ },
12505
+ escalation: {
12506
+ ...DEFAULT_ESCALATION_POLICY,
12507
+ deadlockRounds: 5
12508
+ // More tolerant
12509
+ }
12510
+ };
12511
+ const mediumProfile = {
12512
+ name: "MEDIUM",
12513
+ negotiation: { ...DEFAULT_NEGOTIATION_POLICY },
12514
+ execution: { ...DEFAULT_EXECUTION_POLICY },
12515
+ escalation: { ...DEFAULT_ESCALATION_POLICY }
12516
+ };
12517
+ const highProfile = {
12518
+ name: "HIGH",
12519
+ negotiation: {
12520
+ maxRounds: 15,
12521
+ scoreThreshold: 0.85,
12522
+ diffTolerance: 0.2,
12523
+ roundTimeoutMs: 2e4,
12524
+ tokenBudgetPerRound: 8192,
12525
+ totalTokenBudget: 1e5,
12526
+ oscillationLimit: 2,
12527
+ hitl: "PauseOnFinalAccept" /* PAUSE_ON_FINAL_ACCEPT */,
12528
+ scoring: {
12529
+ requireSchemaValid: true,
12530
+ requireExamplesPass: true,
12531
+ llmWeight: 0.7
12532
+ }
12533
+ },
12534
+ execution: {
12535
+ ...DEFAULT_EXECUTION_POLICY,
12536
+ timeoutMs: 3e4,
12537
+ // Stricter timeout
12538
+ maxRetries: 2,
12539
+ networkPolicy: "none"
12540
+ // More restrictive
12541
+ },
12542
+ escalation: {
12543
+ ...DEFAULT_ESCALATION_POLICY,
12544
+ deadlockRounds: 2,
12545
+ // Quick escalation
12546
+ autoEscalateOnDeadlock: true
12547
+ }
12548
+ };
12549
+ this.profiles.set("LOW", lowProfile);
12550
+ this.profiles.set("MEDIUM", mediumProfile);
12551
+ this.profiles.set("HIGH", highProfile);
12552
+ }
12553
+ /**
12554
+ * Get the latest version of a policy by its ID.
12555
+ *
12556
+ * @param policyId - The unique identifier of the policy
12557
+ * @returns The most recent effective policy if found, null otherwise
12558
+ */
12559
+ async getPolicy(policyId) {
12560
+ const versions = this.policies.get(policyId);
12561
+ if (!versions || versions.length === 0) {
12562
+ return null;
12563
+ }
12564
+ return versions[versions.length - 1];
12565
+ }
12566
+ /**
12567
+ * Save a policy snapshot to the version history.
12568
+ *
12569
+ * If the policy does not have an ID, one will be generated.
12570
+ * If the policy does not have a version, one will be generated.
12571
+ *
12572
+ * @param policy - The effective policy to save
12573
+ * @returns The policy ID
12574
+ */
12575
+ async savePolicy(policy) {
12576
+ const policyId = policy.policyId || generatePolicyId();
12577
+ const version2 = policy.version || generatePolicyVersion();
12578
+ const policyWithMeta = {
12579
+ ...policy,
12580
+ policyId,
12581
+ version: version2,
12582
+ createdAt: policy.createdAt || (/* @__PURE__ */ new Date()).toISOString()
12583
+ };
12584
+ const versions = this.policies.get(policyId) || [];
12585
+ versions.push(policyWithMeta);
12586
+ this.policies.set(policyId, versions);
12587
+ return policyId;
12588
+ }
12589
+ /**
12590
+ * List all policy IDs, optionally filtered by prefix.
12591
+ *
12592
+ * @param prefix - Optional prefix to filter policy IDs
12593
+ * @returns List of matching policy IDs
12594
+ */
12595
+ async listPolicies(prefix) {
12596
+ const allIds = Array.from(this.policies.keys());
12597
+ if (prefix === void 0) {
12598
+ return allIds;
12599
+ }
12600
+ return allIds.filter((id) => id.startsWith(prefix));
12601
+ }
12602
+ /**
12603
+ * Delete a policy by its ID (removes all versions).
12604
+ *
12605
+ * @param policyId - The unique identifier of the policy
12606
+ * @returns True if the policy was deleted, false if not found
12607
+ */
12608
+ async deletePolicy(policyId) {
12609
+ return this.policies.delete(policyId);
12610
+ }
12611
+ /**
12612
+ * Retrieve the complete version history for a policy.
12613
+ *
12614
+ * Returns policies in chronological order (oldest to newest).
12615
+ *
12616
+ * @param policyId - The unique identifier of the policy
12617
+ * @returns List of all versions of the policy
12618
+ */
12619
+ async getHistory(policyId) {
12620
+ const versions = this.policies.get(policyId);
12621
+ if (!versions) {
12622
+ return [];
12623
+ }
12624
+ return [...versions];
12625
+ }
12626
+ /**
12627
+ * Get a policy profile by name.
12628
+ *
12629
+ * @param name - The profile name
12630
+ * @returns The policy profile if found, null otherwise
12631
+ */
12632
+ async getProfile(name) {
12633
+ return this.profiles.get(name) || null;
12634
+ }
12635
+ /**
12636
+ * Save a policy profile.
12637
+ *
12638
+ * @param profile - The policy profile to save
12639
+ * @returns The profile name
12640
+ */
12641
+ async saveProfile(profile) {
12642
+ this.profiles.set(profile.name, profile);
12643
+ return profile.name;
12644
+ }
12645
+ /**
12646
+ * List all profile names.
12647
+ *
12648
+ * @returns List of profile names
12649
+ */
12650
+ async listProfiles() {
12651
+ return Array.from(this.profiles.keys());
12652
+ }
12653
+ /**
12654
+ * Create an effective policy from a profile and agent preferences.
12655
+ *
12656
+ * Clamps agent preferences to the profile's guardrails.
12657
+ *
12658
+ * @param profileName - The profile to use as base
12659
+ * @param agentPrefs - Optional agent preferences to apply
12660
+ * @param negotiationId - Optional negotiation ID
12661
+ * @returns The effective policy
12662
+ * @throws PolicyStoreError if the profile does not exist
12663
+ */
12664
+ async createEffectivePolicy(profileName, agentPrefs, negotiationId) {
12665
+ const profile = await this.getProfile(profileName);
12666
+ if (!profile) {
12667
+ throw new PolicyStoreError(`Profile '${profileName}' does not exist`);
12668
+ }
12669
+ const baseNegotiation = { ...profile.negotiation };
12670
+ const baseExecution = { ...profile.execution };
12671
+ const baseEscalation = { ...profile.escalation };
12672
+ const applied = {};
12673
+ if (agentPrefs) {
12674
+ for (const [agentId, prefs] of Object.entries(agentPrefs)) {
12675
+ const clamped = {};
12676
+ if (prefs.maxRounds !== void 0) {
12677
+ clamped.maxRounds = Math.min(prefs.maxRounds, baseNegotiation.maxRounds);
12678
+ }
12679
+ if (prefs.scoreThreshold !== void 0) {
12680
+ clamped.scoreThreshold = Math.max(
12681
+ prefs.scoreThreshold,
12682
+ baseNegotiation.scoreThreshold
12683
+ );
12684
+ }
12685
+ if (prefs.diffTolerance !== void 0) {
12686
+ clamped.diffTolerance = Math.min(
12687
+ prefs.diffTolerance,
12688
+ baseNegotiation.diffTolerance
12689
+ );
12690
+ }
12691
+ if (prefs.roundTimeoutMs !== void 0) {
12692
+ clamped.roundTimeoutMs = Math.min(
12693
+ prefs.roundTimeoutMs,
12694
+ baseNegotiation.roundTimeoutMs
12695
+ );
12696
+ }
12697
+ if (prefs.tokenBudgetPerRound !== void 0) {
12698
+ clamped.tokenBudgetPerRound = Math.min(
12699
+ prefs.tokenBudgetPerRound,
12700
+ baseNegotiation.tokenBudgetPerRound
12701
+ );
12702
+ }
12703
+ if (prefs.totalTokenBudget !== void 0 && baseNegotiation.totalTokenBudget > 0) {
12704
+ clamped.totalTokenBudget = Math.min(
12705
+ prefs.totalTokenBudget,
12706
+ baseNegotiation.totalTokenBudget
12707
+ );
12708
+ }
12709
+ if (prefs.oscillationLimit !== void 0) {
12710
+ clamped.oscillationLimit = Math.min(
12711
+ prefs.oscillationLimit,
12712
+ baseNegotiation.oscillationLimit
12713
+ );
12714
+ }
12715
+ applied[agentId] = clamped;
12716
+ }
12717
+ }
12718
+ const effectivePolicy = {
12719
+ policyId: generatePolicyId(),
12720
+ version: generatePolicyVersion(),
12721
+ negotiation: baseNegotiation,
12722
+ execution: baseExecution,
12723
+ escalation: baseEscalation,
12724
+ negotiationId,
12725
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
12726
+ };
12727
+ if (Object.keys(applied).length > 0) {
12728
+ effectivePolicy.applied = applied;
12729
+ }
12730
+ await this.savePolicy(effectivePolicy);
12731
+ return effectivePolicy;
12732
+ }
12733
+ };
12734
+ var JsonFilePolicyStore = class {
12735
+ directory;
12736
+ profiles = /* @__PURE__ */ new Map();
12737
+ /**
12738
+ * Create a new JSON file policy store.
12739
+ *
12740
+ * @param directory - Directory to store policy files
12741
+ */
12742
+ constructor(directory) {
12743
+ this.directory = directory;
12744
+ this.initializeDefaultProfiles();
12745
+ }
12746
+ /**
12747
+ * Initialize the store, creating the directory if needed.
12748
+ */
12749
+ async initialize() {
12750
+ await import_promises2.default.mkdir(this.directory, { recursive: true });
12751
+ }
12752
+ /**
12753
+ * Initialize default policy profiles.
12754
+ */
12755
+ initializeDefaultProfiles() {
12756
+ const lowProfile = {
12757
+ name: "LOW",
12758
+ negotiation: {
12759
+ maxRounds: 5,
12760
+ scoreThreshold: 0.6,
12761
+ diffTolerance: 0.4,
12762
+ roundTimeoutMs: 6e4,
12763
+ tokenBudgetPerRound: 2048,
12764
+ totalTokenBudget: 0,
12765
+ oscillationLimit: 5,
12766
+ hitl: "None" /* NONE */,
12767
+ scoring: {
12768
+ requireSchemaValid: false,
12769
+ requireExamplesPass: false,
12770
+ llmWeight: 0.3
12771
+ }
12772
+ },
12773
+ execution: {
12774
+ ...DEFAULT_EXECUTION_POLICY,
12775
+ timeoutMs: 12e4,
12776
+ maxRetries: 5
12777
+ },
12778
+ escalation: {
12779
+ ...DEFAULT_ESCALATION_POLICY,
12780
+ deadlockRounds: 5
12781
+ }
12782
+ };
12783
+ const mediumProfile = {
12784
+ name: "MEDIUM",
12785
+ negotiation: { ...DEFAULT_NEGOTIATION_POLICY },
12786
+ execution: { ...DEFAULT_EXECUTION_POLICY },
12787
+ escalation: { ...DEFAULT_ESCALATION_POLICY }
12788
+ };
12789
+ const highProfile = {
12790
+ name: "HIGH",
12791
+ negotiation: {
12792
+ maxRounds: 15,
12793
+ scoreThreshold: 0.85,
12794
+ diffTolerance: 0.2,
12795
+ roundTimeoutMs: 2e4,
12796
+ tokenBudgetPerRound: 8192,
12797
+ totalTokenBudget: 1e5,
12798
+ oscillationLimit: 2,
12799
+ hitl: "PauseOnFinalAccept" /* PAUSE_ON_FINAL_ACCEPT */,
12800
+ scoring: {
12801
+ requireSchemaValid: true,
12802
+ requireExamplesPass: true,
12803
+ llmWeight: 0.7
12804
+ }
12805
+ },
12806
+ execution: {
12807
+ ...DEFAULT_EXECUTION_POLICY,
12808
+ timeoutMs: 3e4,
12809
+ maxRetries: 2,
12810
+ networkPolicy: "none"
12811
+ },
12812
+ escalation: {
12813
+ ...DEFAULT_ESCALATION_POLICY,
12814
+ deadlockRounds: 2,
12815
+ autoEscalateOnDeadlock: true
12816
+ }
12817
+ };
12818
+ this.profiles.set("LOW", lowProfile);
12819
+ this.profiles.set("MEDIUM", mediumProfile);
12820
+ this.profiles.set("HIGH", highProfile);
12821
+ }
12822
+ /**
12823
+ * Sanitize a policy ID for use as a filename.
12824
+ */
12825
+ sanitizeId(policyId) {
12826
+ return policyId.replace(/[/\\]/g, "_");
12827
+ }
12828
+ /**
12829
+ * Get the file path for a policy.
12830
+ */
12831
+ getFilePath(policyId) {
12832
+ return import_node_path3.default.join(this.directory, `${this.sanitizeId(policyId)}.json`);
12833
+ }
12834
+ /**
12835
+ * Load versions from a file.
12836
+ */
12837
+ async loadFromFile(policyId) {
12838
+ const filePath = this.getFilePath(policyId);
12839
+ try {
12840
+ const data = await import_promises2.default.readFile(filePath, "utf-8");
12841
+ const parsed = JSON.parse(data);
12842
+ if (Array.isArray(parsed)) {
12843
+ return parsed;
10695
12844
  }
12845
+ return [parsed];
10696
12846
  } catch {
12847
+ return [];
10697
12848
  }
10698
- current = null;
10699
- };
10700
- start();
10701
- return emitter;
10702
- }
12849
+ }
12850
+ /**
12851
+ * Save versions to a file atomically.
12852
+ */
12853
+ async saveToFile(policyId, versions) {
12854
+ await this.initialize();
12855
+ const filePath = this.getFilePath(policyId);
12856
+ const tempPath = `${filePath}.tmp.${Date.now()}`;
12857
+ const data = JSON.stringify(versions, null, 2);
12858
+ await import_promises2.default.writeFile(tempPath, data, "utf-8");
12859
+ await import_promises2.default.rename(tempPath, filePath);
12860
+ }
12861
+ async getPolicy(policyId) {
12862
+ const versions = await this.loadFromFile(policyId);
12863
+ if (versions.length === 0) {
12864
+ return null;
12865
+ }
12866
+ return versions[versions.length - 1];
12867
+ }
12868
+ async savePolicy(policy) {
12869
+ const policyId = policy.policyId || generatePolicyId();
12870
+ const version2 = policy.version || generatePolicyVersion();
12871
+ const policyWithMeta = {
12872
+ ...policy,
12873
+ policyId,
12874
+ version: version2,
12875
+ createdAt: policy.createdAt || (/* @__PURE__ */ new Date()).toISOString()
12876
+ };
12877
+ const versions = await this.loadFromFile(policyId);
12878
+ versions.push(policyWithMeta);
12879
+ await this.saveToFile(policyId, versions);
12880
+ return policyId;
12881
+ }
12882
+ async listPolicies(prefix) {
12883
+ try {
12884
+ await this.initialize();
12885
+ const files = await import_promises2.default.readdir(this.directory);
12886
+ const policyIds = files.filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -5));
12887
+ if (prefix === void 0) {
12888
+ return policyIds;
12889
+ }
12890
+ return policyIds.filter((id) => id.startsWith(prefix));
12891
+ } catch {
12892
+ return [];
12893
+ }
12894
+ }
12895
+ async deletePolicy(policyId) {
12896
+ const filePath = this.getFilePath(policyId);
12897
+ try {
12898
+ await import_promises2.default.unlink(filePath);
12899
+ return true;
12900
+ } catch {
12901
+ return false;
12902
+ }
12903
+ }
12904
+ async getHistory(policyId) {
12905
+ return this.loadFromFile(policyId);
12906
+ }
12907
+ async getProfile(name) {
12908
+ return this.profiles.get(name) || null;
12909
+ }
12910
+ async saveProfile(profile) {
12911
+ this.profiles.set(profile.name, profile);
12912
+ return profile.name;
12913
+ }
12914
+ async listProfiles() {
12915
+ return Array.from(this.profiles.keys());
12916
+ }
12917
+ /**
12918
+ * Create an effective policy from a profile and agent preferences.
12919
+ */
12920
+ async createEffectivePolicy(profileName, agentPrefs, negotiationId) {
12921
+ const profile = await this.getProfile(profileName);
12922
+ if (!profile) {
12923
+ throw new PolicyStoreError(`Profile '${profileName}' does not exist`);
12924
+ }
12925
+ const baseNegotiation = { ...profile.negotiation };
12926
+ const baseExecution = { ...profile.execution };
12927
+ const baseEscalation = { ...profile.escalation };
12928
+ const applied = {};
12929
+ if (agentPrefs) {
12930
+ for (const [agentId, prefs] of Object.entries(agentPrefs)) {
12931
+ const clamped = {};
12932
+ if (prefs.maxRounds !== void 0) {
12933
+ clamped.maxRounds = Math.min(prefs.maxRounds, baseNegotiation.maxRounds);
12934
+ }
12935
+ if (prefs.scoreThreshold !== void 0) {
12936
+ clamped.scoreThreshold = Math.max(prefs.scoreThreshold, baseNegotiation.scoreThreshold);
12937
+ }
12938
+ if (prefs.diffTolerance !== void 0) {
12939
+ clamped.diffTolerance = Math.min(prefs.diffTolerance, baseNegotiation.diffTolerance);
12940
+ }
12941
+ if (prefs.roundTimeoutMs !== void 0) {
12942
+ clamped.roundTimeoutMs = Math.min(prefs.roundTimeoutMs, baseNegotiation.roundTimeoutMs);
12943
+ }
12944
+ if (prefs.tokenBudgetPerRound !== void 0) {
12945
+ clamped.tokenBudgetPerRound = Math.min(prefs.tokenBudgetPerRound, baseNegotiation.tokenBudgetPerRound);
12946
+ }
12947
+ if (prefs.totalTokenBudget !== void 0 && baseNegotiation.totalTokenBudget > 0) {
12948
+ clamped.totalTokenBudget = Math.min(prefs.totalTokenBudget, baseNegotiation.totalTokenBudget);
12949
+ }
12950
+ if (prefs.oscillationLimit !== void 0) {
12951
+ clamped.oscillationLimit = Math.min(prefs.oscillationLimit, baseNegotiation.oscillationLimit);
12952
+ }
12953
+ applied[agentId] = clamped;
12954
+ }
12955
+ }
12956
+ const effectivePolicy = {
12957
+ policyId: generatePolicyId(),
12958
+ version: generatePolicyVersion(),
12959
+ negotiation: baseNegotiation,
12960
+ execution: baseExecution,
12961
+ escalation: baseEscalation,
12962
+ negotiationId,
12963
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
12964
+ };
12965
+ if (Object.keys(applied).length > 0) {
12966
+ effectivePolicy.applied = applied;
12967
+ }
12968
+ await this.savePolicy(effectivePolicy);
12969
+ return effectivePolicy;
12970
+ }
12971
+ };
10703
12972
 
10704
- // src/runtime/negotiationEvents.ts
10705
- function parseNegotiationEvent(json) {
10706
- try {
10707
- const obj = JSON.parse(json);
10708
- if (!obj || typeof obj.kind !== "string")
10709
- return { kind: "unknown", ...obj || {} };
10710
- return obj;
10711
- } catch {
10712
- return { kind: "unknown", ts: void 0 };
12973
+ // src/runtime/agentState.ts
12974
+ var AgentState = /* @__PURE__ */ ((AgentState2) => {
12975
+ AgentState2[AgentState2["AGENT_STATE_UNSPECIFIED"] = 0] = "AGENT_STATE_UNSPECIFIED";
12976
+ AgentState2[AgentState2["INITIALIZING"] = 1] = "INITIALIZING";
12977
+ AgentState2[AgentState2["RUNNABLE"] = 2] = "RUNNABLE";
12978
+ AgentState2[AgentState2["SCHEDULED"] = 3] = "SCHEDULED";
12979
+ AgentState2[AgentState2["RUNNING"] = 4] = "RUNNING";
12980
+ AgentState2[AgentState2["WAITING"] = 5] = "WAITING";
12981
+ AgentState2[AgentState2["WAITING_RESOURCES"] = 6] = "WAITING_RESOURCES";
12982
+ AgentState2[AgentState2["SUSPENDED"] = 7] = "SUSPENDED";
12983
+ AgentState2[AgentState2["RESUMED"] = 8] = "RESUMED";
12984
+ AgentState2[AgentState2["COMPLETED"] = 9] = "COMPLETED";
12985
+ AgentState2[AgentState2["FAILED"] = 10] = "FAILED";
12986
+ AgentState2[AgentState2["SHUTTING_DOWN"] = 11] = "SHUTTING_DOWN";
12987
+ AgentState2[AgentState2["RECOVERING"] = 12] = "RECOVERING";
12988
+ return AgentState2;
12989
+ })(AgentState || {});
12990
+ var StateTransitionError2 = class extends Error {
12991
+ fromState;
12992
+ toState;
12993
+ constructor(fromState, toState) {
12994
+ const fromName = AgentState[fromState];
12995
+ const toName = AgentState[toState];
12996
+ super(`Invalid state transition from ${fromName} to ${toName}`);
12997
+ this.name = "StateTransitionError";
12998
+ this.fromState = fromState;
12999
+ this.toState = toState;
10713
13000
  }
13001
+ };
13002
+ var VALID_TRANSITIONS = /* @__PURE__ */ new Map([
13003
+ // INITIALIZING -> RUNNABLE, FAILED (init timeout per spec s8.2)
13004
+ [1 /* INITIALIZING */, /* @__PURE__ */ new Set([2 /* RUNNABLE */, 10 /* FAILED */])],
13005
+ // RUNNABLE -> SCHEDULED
13006
+ [2 /* RUNNABLE */, /* @__PURE__ */ new Set([3 /* SCHEDULED */])],
13007
+ // SCHEDULED -> RUNNING
13008
+ [3 /* SCHEDULED */, /* @__PURE__ */ new Set([4 /* RUNNING */])],
13009
+ // RUNNING -> WAITING, WAITING_RESOURCES, SUSPENDED, COMPLETED, FAILED, SHUTTING_DOWN
13010
+ [
13011
+ 4 /* RUNNING */,
13012
+ /* @__PURE__ */ new Set([
13013
+ 5 /* WAITING */,
13014
+ 6 /* WAITING_RESOURCES */,
13015
+ 7 /* SUSPENDED */,
13016
+ 9 /* COMPLETED */,
13017
+ 10 /* FAILED */,
13018
+ 11 /* SHUTTING_DOWN */
13019
+ ])
13020
+ ],
13021
+ // WAITING -> RUNNING
13022
+ [5 /* WAITING */, /* @__PURE__ */ new Set([4 /* RUNNING */])],
13023
+ // WAITING_RESOURCES -> RUNNING, FAILED (resource timeout)
13024
+ [
13025
+ 6 /* WAITING_RESOURCES */,
13026
+ /* @__PURE__ */ new Set([4 /* RUNNING */, 10 /* FAILED */])
13027
+ ],
13028
+ // SUSPENDED -> RESUMED, FAILED (suspension timeout per spec s8.3)
13029
+ [7 /* SUSPENDED */, /* @__PURE__ */ new Set([8 /* RESUMED */, 10 /* FAILED */])],
13030
+ // RESUMED -> RUNNING
13031
+ [8 /* RESUMED */, /* @__PURE__ */ new Set([4 /* RUNNING */])],
13032
+ // COMPLETED -> RUNNABLE
13033
+ [9 /* COMPLETED */, /* @__PURE__ */ new Set([2 /* RUNNABLE */])],
13034
+ // FAILED -> RECOVERING
13035
+ [10 /* FAILED */, /* @__PURE__ */ new Set([12 /* RECOVERING */])],
13036
+ // SHUTTING_DOWN -> FAILED (agent_shutdown_timeout)
13037
+ [11 /* SHUTTING_DOWN */, /* @__PURE__ */ new Set([10 /* FAILED */])],
13038
+ // RECOVERING -> RUNNABLE, SHUTTING_DOWN (recovery abort), FAILED (recovery timeout per spec s8.3)
13039
+ [
13040
+ 12 /* RECOVERING */,
13041
+ /* @__PURE__ */ new Set([2 /* RUNNABLE */, 11 /* SHUTTING_DOWN */, 10 /* FAILED */])
13042
+ ]
13043
+ ]);
13044
+ function isValidTransition(fromState, toState) {
13045
+ const validTargets = VALID_TRANSITIONS.get(fromState);
13046
+ if (!validTargets) {
13047
+ return false;
13048
+ }
13049
+ return validTargets.has(toState);
10714
13050
  }
10715
- function decodeBase64(b64) {
10716
- if (!b64)
10717
- return void 0;
10718
- return new Uint8Array(Buffer.from(b64, "base64"));
13051
+ function getValidTransitions(fromState) {
13052
+ const validTargets = VALID_TRANSITIONS.get(fromState);
13053
+ if (!validTargets) {
13054
+ return [];
13055
+ }
13056
+ return Array.from(validTargets);
10719
13057
  }
10720
-
10721
- // src/persistence/persistence.ts
10722
- var import_promises = __toESM(require("node:fs/promises"), 1);
10723
- var import_node_path2 = __toESM(require("node:path"), 1);
10724
- var JSONFilePersistence = class {
10725
- constructor(baseDir) {
10726
- this.baseDir = baseDir;
10727
- this.activityFile = import_node_path2.default.join(baseDir, "activity.json");
10728
- this.acksFile = import_node_path2.default.join(baseDir, "acks.json");
13058
+ var AgentStateMachine = class {
13059
+ state = 0 /* AGENT_STATE_UNSPECIFIED */;
13060
+ hooks;
13061
+ stateHistory = [];
13062
+ /**
13063
+ * Create a new agent state machine.
13064
+ *
13065
+ * @param hooks - Optional lifecycle hooks
13066
+ */
13067
+ constructor(hooks) {
13068
+ this.hooks = hooks || {};
10729
13069
  }
10730
- activityFile;
10731
- acksFile;
10732
- async safeWrite(file, data) {
10733
- await import_promises.default.mkdir(import_node_path2.default.dirname(file), { recursive: true });
10734
- const tmp = `${file}.tmp-${Date.now()}`;
10735
- await import_promises.default.writeFile(tmp, data, "utf8");
10736
- await import_promises.default.rename(tmp, file);
13070
+ /**
13071
+ * Get the current state.
13072
+ *
13073
+ * @returns The current agent state
13074
+ */
13075
+ getState() {
13076
+ return this.state;
10737
13077
  }
10738
- async saveActivity(records) {
10739
- const payload = JSON.stringify(records, null, 2);
10740
- await this.safeWrite(this.activityFile, payload);
13078
+ /**
13079
+ * Get the state history.
13080
+ *
13081
+ * @returns Array of state transitions with timestamps
13082
+ */
13083
+ getStateHistory() {
13084
+ return [...this.stateHistory];
10741
13085
  }
10742
- async loadActivity() {
10743
- try {
10744
- const buf = await import_promises.default.readFile(this.activityFile, "utf8");
10745
- return JSON.parse(buf);
10746
- } catch (e) {
10747
- if (e?.code === "ENOENT")
10748
- return [];
10749
- throw e;
13086
+ /**
13087
+ * Initialize the agent (transition to INITIALIZING).
13088
+ *
13089
+ * @throws StateTransitionError if already initialized
13090
+ */
13091
+ async initialize() {
13092
+ if (this.state !== 0 /* AGENT_STATE_UNSPECIFIED */) {
13093
+ throw new StateTransitionError2(this.state, 1 /* INITIALIZING */);
10750
13094
  }
13095
+ await this.transitionTo(1 /* INITIALIZING */);
10751
13096
  }
10752
- async saveAcks(states) {
10753
- const payload = JSON.stringify(states, null, 2);
10754
- await this.safeWrite(this.acksFile, payload);
13097
+ /**
13098
+ * Transition to a new state.
13099
+ *
13100
+ * @param toState - The target state
13101
+ * @param context - Optional context for the transition
13102
+ * @throws StateTransitionError if the transition is invalid
13103
+ */
13104
+ async transitionTo(toState, context) {
13105
+ if (this.state === 0 /* AGENT_STATE_UNSPECIFIED */ && toState === 1 /* INITIALIZING */) {
13106
+ await this.doTransition(toState, context);
13107
+ return;
13108
+ }
13109
+ if (!isValidTransition(this.state, toState)) {
13110
+ throw new StateTransitionError2(this.state, toState);
13111
+ }
13112
+ await this.doTransition(toState, context);
13113
+ }
13114
+ /**
13115
+ * Perform the state transition and call hooks.
13116
+ */
13117
+ async doTransition(toState, context) {
13118
+ const fromState = this.state;
13119
+ this.state = toState;
13120
+ this.stateHistory.push({
13121
+ state: toState,
13122
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
13123
+ context
13124
+ });
13125
+ if (this.hooks.onStateChange) {
13126
+ await this.hooks.onStateChange(fromState, toState, context);
13127
+ }
13128
+ await this.callSpecificHooks(fromState, toState, context);
13129
+ }
13130
+ /**
13131
+ * Call specific lifecycle hooks based on the transition.
13132
+ */
13133
+ async callSpecificHooks(fromState, toState, context) {
13134
+ switch (toState) {
13135
+ case 3 /* SCHEDULED */:
13136
+ if (this.hooks.onScheduled) {
13137
+ const taskId = context?.taskId || "unknown";
13138
+ await this.hooks.onScheduled(taskId, context);
13139
+ }
13140
+ break;
13141
+ case 7 /* SUSPENDED */:
13142
+ if (fromState === 4 /* RUNNING */ && this.hooks.onPreempt) {
13143
+ const reason = context?.reason || "preemption";
13144
+ await this.hooks.onPreempt(reason, context);
13145
+ }
13146
+ break;
13147
+ case 4 /* RUNNING */:
13148
+ if (fromState === 8 /* RESUMED */ && this.hooks.onResume) {
13149
+ await this.hooks.onResume(context);
13150
+ }
13151
+ break;
13152
+ case 5 /* WAITING */:
13153
+ if (this.hooks.onWait) {
13154
+ const reason = context?.reason || "waiting";
13155
+ await this.hooks.onWait(reason, context);
13156
+ }
13157
+ break;
13158
+ case 6 /* WAITING_RESOURCES */:
13159
+ if (this.hooks.onWaitResources) {
13160
+ const resources = context?.resources || [];
13161
+ await this.hooks.onWaitResources(resources, context);
13162
+ }
13163
+ break;
13164
+ case 9 /* COMPLETED */:
13165
+ if (this.hooks.onComplete) {
13166
+ await this.hooks.onComplete(context?.result, context);
13167
+ }
13168
+ break;
13169
+ case 10 /* FAILED */:
13170
+ if (this.hooks.onFail) {
13171
+ const error = context?.error || new Error("Unknown failure");
13172
+ await this.hooks.onFail(error, context);
13173
+ }
13174
+ break;
13175
+ case 11 /* SHUTTING_DOWN */:
13176
+ if (this.hooks.onShutdown) {
13177
+ const gracePeriodMs = context?.gracePeriodMs || 3e4;
13178
+ await this.hooks.onShutdown(gracePeriodMs, context);
13179
+ }
13180
+ break;
13181
+ case 12 /* RECOVERING */:
13182
+ if (this.hooks.onRecover) {
13183
+ await this.hooks.onRecover(context);
13184
+ }
13185
+ break;
13186
+ }
13187
+ }
13188
+ /**
13189
+ * Check if the agent can transition to a given state.
13190
+ *
13191
+ * @param toState - The target state
13192
+ * @returns True if the transition is valid
13193
+ */
13194
+ canTransitionTo(toState) {
13195
+ if (this.state === 0 /* AGENT_STATE_UNSPECIFIED */ && toState === 1 /* INITIALIZING */) {
13196
+ return true;
13197
+ }
13198
+ return isValidTransition(this.state, toState);
10755
13199
  }
10756
- async loadAcks() {
10757
- try {
10758
- const buf = await import_promises.default.readFile(this.acksFile, "utf8");
10759
- return JSON.parse(buf);
10760
- } catch (e) {
10761
- if (e?.code === "ENOENT")
10762
- return [];
10763
- throw e;
13200
+ /**
13201
+ * Get all states the agent can currently transition to.
13202
+ *
13203
+ * @returns Array of valid target states
13204
+ */
13205
+ getAvailableTransitions() {
13206
+ if (this.state === 0 /* AGENT_STATE_UNSPECIFIED */) {
13207
+ return [1 /* INITIALIZING */];
10764
13208
  }
13209
+ return getValidTransitions(this.state);
13210
+ }
13211
+ /**
13212
+ * Check if the agent is in a terminal state.
13213
+ *
13214
+ * Terminal states are states where the agent cannot make further
13215
+ * progress without external intervention.
13216
+ *
13217
+ * @returns True if in a terminal state
13218
+ */
13219
+ isTerminal() {
13220
+ return getValidTransitions(this.state).length === 0;
13221
+ }
13222
+ /**
13223
+ * Check if the agent is in an active state (executing work).
13224
+ *
13225
+ * @returns True if the agent is actively working
13226
+ */
13227
+ isActive() {
13228
+ return this.state === 4 /* RUNNING */ || this.state === 3 /* SCHEDULED */ || this.state === 8 /* RESUMED */;
13229
+ }
13230
+ /**
13231
+ * Check if the agent is in a waiting state.
13232
+ *
13233
+ * @returns True if the agent is waiting
13234
+ */
13235
+ isWaiting() {
13236
+ return this.state === 5 /* WAITING */ || this.state === 6 /* WAITING_RESOURCES */;
13237
+ }
13238
+ /**
13239
+ * Check if the agent is in a suspended or shutdown state.
13240
+ *
13241
+ * @returns True if the agent is suspended or shutting down
13242
+ */
13243
+ isSuspendedOrShuttingDown() {
13244
+ return this.state === 7 /* SUSPENDED */ || this.state === 11 /* SHUTTING_DOWN */;
13245
+ }
13246
+ /**
13247
+ * Update lifecycle hooks.
13248
+ *
13249
+ * @param hooks - New hooks to merge with existing hooks
13250
+ */
13251
+ setHooks(hooks) {
13252
+ this.hooks = { ...this.hooks, ...hooks };
13253
+ }
13254
+ /**
13255
+ * Reset the state machine to uninitialized state.
13256
+ *
13257
+ * This is primarily for testing purposes.
13258
+ */
13259
+ reset() {
13260
+ this.state = 0 /* AGENT_STATE_UNSPECIFIED */;
13261
+ this.stateHistory = [];
10765
13262
  }
10766
13263
  };
10767
13264
 
@@ -10774,7 +13271,8 @@ function computeIdempotencyToken(input) {
10774
13271
  h.update(input.operation);
10775
13272
  h.update("\n");
10776
13273
  h.update(Buffer.from(input.canonical_bytes));
10777
- return `v1:${h.digest("hex")}`;
13274
+ const hash16 = h.digest("hex").slice(0, 16);
13275
+ return `${input.producer_id}:${input.operation}:${hash16}`;
10778
13276
  }
10779
13277
 
10780
13278
  // src/runtime/persistenceAdapter.ts
@@ -10891,6 +13389,669 @@ function normalizeReportPaths(report) {
10891
13389
  return report;
10892
13390
  }
10893
13391
 
13392
+ // src/constants/index.ts
13393
+ var CommunicationClass = /* @__PURE__ */ ((CommunicationClass2) => {
13394
+ CommunicationClass2[CommunicationClass2["COMM_CLASS_UNSPECIFIED"] = 0] = "COMM_CLASS_UNSPECIFIED";
13395
+ CommunicationClass2[CommunicationClass2["PRIVILEGED"] = 1] = "PRIVILEGED";
13396
+ CommunicationClass2[CommunicationClass2["STANDARD"] = 2] = "STANDARD";
13397
+ CommunicationClass2[CommunicationClass2["BULK"] = 3] = "BULK";
13398
+ return CommunicationClass2;
13399
+ })(CommunicationClass || {});
13400
+ var DebateIntensity = /* @__PURE__ */ ((DebateIntensity2) => {
13401
+ DebateIntensity2[DebateIntensity2["DEBATE_INTENSITY_UNSPECIFIED"] = 0] = "DEBATE_INTENSITY_UNSPECIFIED";
13402
+ DebateIntensity2[DebateIntensity2["LOWEST"] = 1] = "LOWEST";
13403
+ DebateIntensity2[DebateIntensity2["LOW"] = 2] = "LOW";
13404
+ DebateIntensity2[DebateIntensity2["MEDIUM"] = 3] = "MEDIUM";
13405
+ DebateIntensity2[DebateIntensity2["HIGH"] = 4] = "HIGH";
13406
+ DebateIntensity2[DebateIntensity2["HIGHEST"] = 5] = "HIGHEST";
13407
+ return DebateIntensity2;
13408
+ })(DebateIntensity || {});
13409
+ var HitlReasonType = /* @__PURE__ */ ((HitlReasonType2) => {
13410
+ HitlReasonType2[HitlReasonType2["HITL_REASON_UNSPECIFIED"] = 0] = "HITL_REASON_UNSPECIFIED";
13411
+ HitlReasonType2[HitlReasonType2["CONFLICT"] = 1] = "CONFLICT";
13412
+ HitlReasonType2[HitlReasonType2["SECURITY_APPROVAL"] = 2] = "SECURITY_APPROVAL";
13413
+ HitlReasonType2[HitlReasonType2["TASK_ESCALATION"] = 3] = "TASK_ESCALATION";
13414
+ HitlReasonType2[HitlReasonType2["MANUAL_OVERRIDE"] = 4] = "MANUAL_OVERRIDE";
13415
+ HitlReasonType2[HitlReasonType2["WORKTREE_OVERRIDE"] = 5] = "WORKTREE_OVERRIDE";
13416
+ HitlReasonType2[HitlReasonType2["DEBATE_DEADLOCK"] = 6] = "DEBATE_DEADLOCK";
13417
+ HitlReasonType2[HitlReasonType2["TOOL_PRIVILEGE_ESCALATION"] = 7] = "TOOL_PRIVILEGE_ESCALATION";
13418
+ HitlReasonType2[HitlReasonType2["CONNECTOR_APPROVAL"] = 8] = "CONNECTOR_APPROVAL";
13419
+ return HitlReasonType2;
13420
+ })(HitlReasonType || {});
13421
+ var AckStage2 = /* @__PURE__ */ ((AckStage3) => {
13422
+ AckStage3[AckStage3["ACK_STAGE_UNSPECIFIED"] = 0] = "ACK_STAGE_UNSPECIFIED";
13423
+ AckStage3[AckStage3["RECEIVED"] = 1] = "RECEIVED";
13424
+ AckStage3[AckStage3["READ"] = 2] = "READ";
13425
+ AckStage3[AckStage3["FULFILLED"] = 3] = "FULFILLED";
13426
+ AckStage3[AckStage3["REJECTED"] = 4] = "REJECTED";
13427
+ AckStage3[AckStage3["FAILED"] = 5] = "FAILED";
13428
+ AckStage3[AckStage3["TIMED_OUT"] = 6] = "TIMED_OUT";
13429
+ return AckStage3;
13430
+ })(AckStage2 || {});
13431
+ var EnvelopeState = /* @__PURE__ */ ((EnvelopeState3) => {
13432
+ EnvelopeState3[EnvelopeState3["ENVELOPE_STATE_UNSPECIFIED"] = 0] = "ENVELOPE_STATE_UNSPECIFIED";
13433
+ EnvelopeState3[EnvelopeState3["SENT"] = 1] = "SENT";
13434
+ EnvelopeState3[EnvelopeState3["RECEIVED"] = 2] = "RECEIVED";
13435
+ EnvelopeState3[EnvelopeState3["READ"] = 3] = "READ";
13436
+ EnvelopeState3[EnvelopeState3["FULFILLED"] = 4] = "FULFILLED";
13437
+ EnvelopeState3[EnvelopeState3["REJECTED"] = 5] = "REJECTED";
13438
+ EnvelopeState3[EnvelopeState3["FAILED"] = 6] = "FAILED";
13439
+ EnvelopeState3[EnvelopeState3["TIMED_OUT"] = 7] = "TIMED_OUT";
13440
+ return EnvelopeState3;
13441
+ })(EnvelopeState || {});
13442
+ var WorktreeStateEnum = /* @__PURE__ */ ((WorktreeStateEnum2) => {
13443
+ WorktreeStateEnum2[WorktreeStateEnum2["WORKTREE_STATE_UNSPECIFIED"] = 0] = "WORKTREE_STATE_UNSPECIFIED";
13444
+ WorktreeStateEnum2[WorktreeStateEnum2["UNBOUND"] = 1] = "UNBOUND";
13445
+ WorktreeStateEnum2[WorktreeStateEnum2["BOUND_HOME"] = 2] = "BOUND_HOME";
13446
+ WorktreeStateEnum2[WorktreeStateEnum2["SWITCH_PENDING"] = 3] = "SWITCH_PENDING";
13447
+ WorktreeStateEnum2[WorktreeStateEnum2["BOUND_NON_HOME"] = 4] = "BOUND_NON_HOME";
13448
+ WorktreeStateEnum2[WorktreeStateEnum2["BIND_FAILED"] = 5] = "BIND_FAILED";
13449
+ return WorktreeStateEnum2;
13450
+ })(WorktreeStateEnum || {});
13451
+ var DEFAULT_ACK_TIMEOUT_MS = 1e4;
13452
+ var DEDUP_WINDOW_S = 3600;
13453
+ function isTerminalEnvelopeState(state) {
13454
+ return state === 4 /* FULFILLED */ || state === 5 /* REJECTED */ || state === 6 /* FAILED */ || state === 7 /* TIMED_OUT */;
13455
+ }
13456
+ function updateEnvelopeState(envelope, newState) {
13457
+ envelope.state = newState;
13458
+ return envelope;
13459
+ }
13460
+
13461
+ // src/audit.ts
13462
+ var import_node_crypto4 = __toESM(require("node:crypto"), 1);
13463
+ function uuidv43() {
13464
+ if (typeof import_node_crypto4.default.randomUUID === "function") {
13465
+ return import_node_crypto4.default.randomUUID();
13466
+ }
13467
+ const buf = import_node_crypto4.default.randomBytes(16);
13468
+ buf[6] = buf[6] & 15 | 64;
13469
+ buf[8] = buf[8] & 63 | 128;
13470
+ const hex = [...buf].map((b) => b.toString(16).padStart(2, "0"));
13471
+ return hex.slice(0, 4).join("") + "-" + hex.slice(4, 6).join("") + "-" + hex.slice(6, 8).join("") + "-" + hex.slice(8, 10).join("") + "-" + hex.slice(10, 16).join("");
13472
+ }
13473
+ function computeEnvelopeHash(envelope) {
13474
+ const envelopeCopy = { ...envelope };
13475
+ const payload = envelopeCopy.payload;
13476
+ const audit_proof = envelopeCopy.audit_proof;
13477
+ delete envelopeCopy.payload;
13478
+ delete envelopeCopy.audit_proof;
13479
+ const envelopeJson = JSON.stringify(envelopeCopy, Object.keys(envelopeCopy).sort());
13480
+ const hasher = import_node_crypto4.default.createHash("sha256");
13481
+ hasher.update(envelopeJson, "utf-8");
13482
+ if (payload) {
13483
+ if (payload instanceof Uint8Array) {
13484
+ hasher.update(payload);
13485
+ } else if (typeof payload === "string") {
13486
+ hasher.update(payload, "utf-8");
13487
+ }
13488
+ }
13489
+ if (audit_proof) {
13490
+ if (audit_proof instanceof Uint8Array) {
13491
+ hasher.update(audit_proof);
13492
+ } else if (typeof audit_proof === "string") {
13493
+ hasher.update(audit_proof, "utf-8");
13494
+ }
13495
+ }
13496
+ return hasher.digest("hex");
13497
+ }
13498
+ function createSimpleProof(envelope, actor_id) {
13499
+ const envelopeHash = computeEnvelopeHash(envelope);
13500
+ const timestamp = nowHlcStub();
13501
+ const proofInput = `${envelopeHash}:${actor_id}:${timestamp}`;
13502
+ const proofHash = import_node_crypto4.default.createHash("sha256").update(proofInput, "utf-8").digest();
13503
+ return {
13504
+ proof_id: uuidv43(),
13505
+ proof_type: "simple_hash",
13506
+ proof_data: new Uint8Array(proofHash),
13507
+ created_at: timestamp,
13508
+ verified: false
13509
+ };
13510
+ }
13511
+ function verifyAuditProof(envelope, proof) {
13512
+ if (proof.proof_type === "noop") {
13513
+ return true;
13514
+ }
13515
+ if (proof.proof_type === "simple_hash") {
13516
+ if (proof.proof_data.length === 0) {
13517
+ return false;
13518
+ }
13519
+ const envelopeHash = computeEnvelopeHash(envelope);
13520
+ if (proof.proof_data.length !== 32) {
13521
+ return false;
13522
+ }
13523
+ return true;
13524
+ }
13525
+ return false;
13526
+ }
13527
+ var NoOpAuditor = class {
13528
+ /**
13529
+ * Create a minimal no-op proof.
13530
+ *
13531
+ * @param envelope - The envelope (ignored)
13532
+ * @param action - The action (ignored)
13533
+ * @returns A minimal no-op proof
13534
+ */
13535
+ createProof(envelope, action) {
13536
+ return {
13537
+ proof_id: uuidv43(),
13538
+ proof_type: "noop",
13539
+ proof_data: new Uint8Array(0),
13540
+ created_at: nowHlcStub(),
13541
+ verified: true
13542
+ };
13543
+ }
13544
+ /**
13545
+ * Always returns true for no-op proofs.
13546
+ *
13547
+ * @param proof - The proof (ignored)
13548
+ * @returns Always true
13549
+ */
13550
+ verifyProof(proof) {
13551
+ return true;
13552
+ }
13553
+ /**
13554
+ * Create a minimal audit record without storing it.
13555
+ *
13556
+ * @param envelope - The envelope being audited
13557
+ * @param action - The action being performed
13558
+ * @param proof - Optional proof to attach
13559
+ * @returns A minimal audit record
13560
+ */
13561
+ record(envelope, action, proof) {
13562
+ return {
13563
+ record_id: uuidv43(),
13564
+ envelope_id: envelope.message_id ?? "unknown",
13565
+ action,
13566
+ actor_id: envelope.producer_id ?? "unknown",
13567
+ timestamp: nowHlcStub(),
13568
+ proof
13569
+ };
13570
+ }
13571
+ /**
13572
+ * Always returns empty array.
13573
+ *
13574
+ * @param envelope_id - The envelope ID (ignored)
13575
+ * @returns Empty array
13576
+ */
13577
+ query(envelope_id) {
13578
+ return [];
13579
+ }
13580
+ };
13581
+ var InMemoryAuditor = class {
13582
+ _records;
13583
+ /**
13584
+ * Initialize with empty record storage.
13585
+ */
13586
+ constructor() {
13587
+ this._records = /* @__PURE__ */ new Map();
13588
+ }
13589
+ /**
13590
+ * Create a simple hash-based proof.
13591
+ *
13592
+ * @param envelope - The envelope to create proof for
13593
+ * @param action - The action being performed
13594
+ * @returns A simple hash-based proof
13595
+ */
13596
+ createProof(envelope, action) {
13597
+ return createSimpleProof(envelope, envelope.producer_id ?? "unknown");
13598
+ }
13599
+ /**
13600
+ * Verify a proof using the verification module.
13601
+ *
13602
+ * @param proof - The proof to verify
13603
+ * @returns True if proof is valid, false otherwise
13604
+ */
13605
+ verifyProof(proof) {
13606
+ if (proof.proof_type === "noop") {
13607
+ return true;
13608
+ }
13609
+ if (proof.proof_type === "simple_hash") {
13610
+ return proof.proof_data.length > 0;
13611
+ }
13612
+ return false;
13613
+ }
13614
+ /**
13615
+ * Create and store an audit record.
13616
+ *
13617
+ * @param envelope - The envelope being audited
13618
+ * @param action - The action being performed
13619
+ * @param proof - Optional proof to attach
13620
+ * @returns The created audit record
13621
+ */
13622
+ record(envelope, action, proof) {
13623
+ const record = {
13624
+ record_id: uuidv43(),
13625
+ envelope_id: envelope.message_id ?? "unknown",
13626
+ action,
13627
+ actor_id: envelope.producer_id ?? "unknown",
13628
+ timestamp: nowHlcStub(),
13629
+ proof
13630
+ };
13631
+ const envelope_id = record.envelope_id;
13632
+ if (!this._records.has(envelope_id)) {
13633
+ this._records.set(envelope_id, []);
13634
+ }
13635
+ this._records.get(envelope_id).push(record);
13636
+ return record;
13637
+ }
13638
+ /**
13639
+ * Query all audit records for a specific envelope.
13640
+ *
13641
+ * @param envelope_id - The message_id of the envelope to query
13642
+ * @returns List of audit records for this envelope
13643
+ */
13644
+ query(envelope_id) {
13645
+ return this._records.get(envelope_id) ?? [];
13646
+ }
13647
+ /**
13648
+ * Get all audit records (useful for testing).
13649
+ *
13650
+ * @returns All audit records across all envelopes
13651
+ */
13652
+ getAllRecords() {
13653
+ const allRecords = [];
13654
+ for (const records of this._records.values()) {
13655
+ allRecords.push(...records);
13656
+ }
13657
+ return allRecords;
13658
+ }
13659
+ /**
13660
+ * Clear all stored records (useful for testing).
13661
+ */
13662
+ clear() {
13663
+ this._records.clear();
13664
+ }
13665
+ };
13666
+
13667
+ // src/agentConfig.ts
13668
+ var fs2 = __toESM(require("fs"), 1);
13669
+ var path4 = __toESM(require("path"), 1);
13670
+ function defaultEndpoints() {
13671
+ return {
13672
+ router: process.env.SW4RM_ROUTER_ADDR || "http://localhost:50051",
13673
+ registry: process.env.SW4RM_REGISTRY_ADDR || "http://localhost:50052",
13674
+ scheduler: process.env.SW4RM_SCHEDULER_ADDR || "http://localhost:50053",
13675
+ hitl: process.env.SW4RM_HITL_ADDR || "http://localhost:50054",
13676
+ worktree: process.env.SW4RM_WORKTREE_ADDR || "http://localhost:50055",
13677
+ tool: process.env.SW4RM_TOOL_ADDR || "http://localhost:50056",
13678
+ connector: process.env.SW4RM_CONNECTOR_ADDR || "http://localhost:50057",
13679
+ negotiation: process.env.SW4RM_NEGOTIATION_ADDR || "http://localhost:50058",
13680
+ reasoning: process.env.SW4RM_REASONING_ADDR || "http://localhost:50059",
13681
+ logging: process.env.SW4RM_LOGGING_ADDR || "http://localhost:50060"
13682
+ };
13683
+ }
13684
+ function defaultRetryPolicy() {
13685
+ return {
13686
+ maxAttempts: 3,
13687
+ initialBackoffMs: 200,
13688
+ maxBackoffMs: 2e3,
13689
+ multiplier: 2
13690
+ };
13691
+ }
13692
+ function defaultAgentConfig(agentId = "agent-1", name = "Agent") {
13693
+ return {
13694
+ agentId,
13695
+ name,
13696
+ description: void 0,
13697
+ version: "0.1.0",
13698
+ capabilities: [],
13699
+ endpoints: defaultEndpoints(),
13700
+ timeoutMs: 3e4,
13701
+ streamKeepaliveMs: 6e4,
13702
+ retry: defaultRetryPolicy(),
13703
+ metadata: {},
13704
+ communicationClass: 2,
13705
+ // STANDARD
13706
+ modalitiesSupported: ["application/json"],
13707
+ reasoningConnectors: [],
13708
+ publicKey: void 0
13709
+ };
13710
+ }
13711
+ function loadConfigFromEnv() {
13712
+ const config = defaultAgentConfig();
13713
+ if (process.env.AGENT_ID) {
13714
+ config.agentId = process.env.AGENT_ID;
13715
+ }
13716
+ if (process.env.AGENT_NAME) {
13717
+ config.name = process.env.AGENT_NAME;
13718
+ }
13719
+ if (process.env.AGENT_DESCRIPTION) {
13720
+ config.description = process.env.AGENT_DESCRIPTION;
13721
+ }
13722
+ if (process.env.AGENT_VERSION) {
13723
+ config.version = process.env.AGENT_VERSION;
13724
+ }
13725
+ if (process.env.AGENT_CAPABILITIES) {
13726
+ config.capabilities = process.env.AGENT_CAPABILITIES.split(",").map((s) => s.trim());
13727
+ }
13728
+ if (process.env.SW4RM_TIMEOUT_MS) {
13729
+ const timeout = parseInt(process.env.SW4RM_TIMEOUT_MS, 10);
13730
+ if (!isNaN(timeout)) {
13731
+ config.timeoutMs = timeout;
13732
+ }
13733
+ }
13734
+ if (process.env.SW4RM_STREAM_KEEPALIVE_MS) {
13735
+ const keepalive = parseInt(process.env.SW4RM_STREAM_KEEPALIVE_MS, 10);
13736
+ if (!isNaN(keepalive)) {
13737
+ config.streamKeepaliveMs = keepalive;
13738
+ }
13739
+ }
13740
+ if (process.env.SW4RM_RETRY_MAX_ATTEMPTS) {
13741
+ const attempts = parseInt(process.env.SW4RM_RETRY_MAX_ATTEMPTS, 10);
13742
+ if (!isNaN(attempts)) {
13743
+ config.retry.maxAttempts = attempts;
13744
+ }
13745
+ }
13746
+ if (process.env.SW4RM_COMMUNICATION_CLASS) {
13747
+ const cls = parseInt(process.env.SW4RM_COMMUNICATION_CLASS, 10);
13748
+ if (!isNaN(cls)) {
13749
+ config.communicationClass = cls;
13750
+ }
13751
+ }
13752
+ config.endpoints = defaultEndpoints();
13753
+ return config;
13754
+ }
13755
+ function defaultSW4RMConfig() {
13756
+ return {
13757
+ routerAddr: process.env.SW4RM_ROUTER_ADDR || "http://localhost:50051",
13758
+ registryAddr: process.env.SW4RM_REGISTRY_ADDR || "http://localhost:50052",
13759
+ defaultTimeoutMs: parseInt(process.env.SW4RM_DEFAULT_TIMEOUT_MS || "30000", 10),
13760
+ maxRetries: parseInt(process.env.SW4RM_MAX_RETRIES || "3", 10),
13761
+ enableMetrics: parseBool(process.env.SW4RM_ENABLE_METRICS, true),
13762
+ enableTracing: parseBool(process.env.SW4RM_ENABLE_TRACING, true),
13763
+ logLevel: process.env.SW4RM_LOG_LEVEL || "INFO",
13764
+ featureFlags: {}
13765
+ };
13766
+ }
13767
+ function parseBool(value, defaultValue) {
13768
+ if (value === void 0) {
13769
+ return defaultValue;
13770
+ }
13771
+ return ["true", "1", "yes", "on"].includes(value.toLowerCase());
13772
+ }
13773
+ function loadConfig(configPath) {
13774
+ let config = defaultSW4RMConfig();
13775
+ if (configPath) {
13776
+ if (!fs2.existsSync(configPath)) {
13777
+ throw new Error(`Configuration file not found: ${configPath}`);
13778
+ }
13779
+ const ext = path4.extname(configPath).toLowerCase();
13780
+ if (ext !== ".json") {
13781
+ throw new Error(
13782
+ `Unsupported configuration file format: ${ext}. Supported formats: .json`
13783
+ );
13784
+ }
13785
+ const fileContent = fs2.readFileSync(configPath, "utf8");
13786
+ const fileConfig = JSON.parse(fileContent);
13787
+ config = { ...config, ...fileConfig };
13788
+ }
13789
+ const envConfig = loadFromEnv();
13790
+ config = { ...config, ...envConfig };
13791
+ return config;
13792
+ }
13793
+ function loadFromEnv() {
13794
+ const envConfig = {};
13795
+ if (process.env.SW4RM_ROUTER_ADDR) {
13796
+ envConfig.routerAddr = process.env.SW4RM_ROUTER_ADDR;
13797
+ }
13798
+ if (process.env.SW4RM_REGISTRY_ADDR) {
13799
+ envConfig.registryAddr = process.env.SW4RM_REGISTRY_ADDR;
13800
+ }
13801
+ if (process.env.SW4RM_DEFAULT_TIMEOUT_MS) {
13802
+ const timeout = parseInt(process.env.SW4RM_DEFAULT_TIMEOUT_MS, 10);
13803
+ if (!isNaN(timeout)) {
13804
+ envConfig.defaultTimeoutMs = timeout;
13805
+ }
13806
+ }
13807
+ if (process.env.SW4RM_MAX_RETRIES) {
13808
+ const retries = parseInt(process.env.SW4RM_MAX_RETRIES, 10);
13809
+ if (!isNaN(retries)) {
13810
+ envConfig.maxRetries = retries;
13811
+ }
13812
+ }
13813
+ if (process.env.SW4RM_ENABLE_METRICS !== void 0) {
13814
+ envConfig.enableMetrics = parseBool(process.env.SW4RM_ENABLE_METRICS, true);
13815
+ }
13816
+ if (process.env.SW4RM_ENABLE_TRACING !== void 0) {
13817
+ envConfig.enableTracing = parseBool(process.env.SW4RM_ENABLE_TRACING, true);
13818
+ }
13819
+ if (process.env.SW4RM_LOG_LEVEL) {
13820
+ envConfig.logLevel = process.env.SW4RM_LOG_LEVEL.toUpperCase();
13821
+ }
13822
+ return envConfig;
13823
+ }
13824
+ var _globalConfig = null;
13825
+ function getConfig() {
13826
+ if (_globalConfig === null) {
13827
+ _globalConfig = loadConfig();
13828
+ }
13829
+ return _globalConfig;
13830
+ }
13831
+ function setConfig(config) {
13832
+ _globalConfig = config;
13833
+ }
13834
+ function resetConfig() {
13835
+ _globalConfig = null;
13836
+ }
13837
+
13838
+ // src/persistentActivityBuffer.ts
13839
+ var import_node_fs2 = require("node:fs");
13840
+ var import_node_path4 = require("node:path");
13841
+ var JSONFilePersistence2 = class {
13842
+ constructor(filePath = "sw4rm_activity.json") {
13843
+ this.filePath = filePath;
13844
+ }
13845
+ load() {
13846
+ if (!(0, import_node_fs2.existsSync)(this.filePath)) {
13847
+ return { records: {}, order: [] };
13848
+ }
13849
+ const raw = (0, import_node_fs2.readFileSync)(this.filePath, "utf-8");
13850
+ const data = JSON.parse(raw);
13851
+ return {
13852
+ records: data.records ?? {},
13853
+ order: data.order ?? []
13854
+ };
13855
+ }
13856
+ save(records, order) {
13857
+ const dir = (0, import_node_path4.dirname)(this.filePath);
13858
+ if (dir && !(0, import_node_fs2.existsSync)(dir)) {
13859
+ (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
13860
+ }
13861
+ (0, import_node_fs2.writeFileSync)(this.filePath, JSON.stringify({ records, order, version: "1.0" }, null, 2));
13862
+ }
13863
+ clear() {
13864
+ if ((0, import_node_fs2.existsSync)(this.filePath)) {
13865
+ (0, import_node_fs2.writeFileSync)(this.filePath, JSON.stringify({ records: {}, order: [], version: "1.0" }));
13866
+ }
13867
+ }
13868
+ };
13869
+ var PersistentActivityBuffer = class {
13870
+ byId = /* @__PURE__ */ new Map();
13871
+ byIdempotencyToken = /* @__PURE__ */ new Map();
13872
+ // token -> message_id
13873
+ order = [];
13874
+ maxItems;
13875
+ persistence;
13876
+ dedupWindowS;
13877
+ dirty = false;
13878
+ constructor(opts) {
13879
+ this.maxItems = opts?.maxItems ?? 1e4;
13880
+ this.persistence = opts?.persistence ?? new JSONFilePersistence2();
13881
+ this.dedupWindowS = opts?.dedupWindowS ?? 3600;
13882
+ this.loadFromPersistence();
13883
+ }
13884
+ loadFromPersistence() {
13885
+ try {
13886
+ const { records, order } = this.persistence.load();
13887
+ this.byId = new Map(Object.entries(records));
13888
+ this.order = order;
13889
+ for (const [mid, rec] of this.byId) {
13890
+ const token = rec.envelope?.idempotency_token;
13891
+ if (token) {
13892
+ this.byIdempotencyToken.set(token, mid);
13893
+ }
13894
+ }
13895
+ } catch {
13896
+ this.byId = /* @__PURE__ */ new Map();
13897
+ this.byIdempotencyToken = /* @__PURE__ */ new Map();
13898
+ this.order = [];
13899
+ }
13900
+ }
13901
+ saveToPersistence() {
13902
+ if (!this.dirty)
13903
+ return;
13904
+ try {
13905
+ const records = {};
13906
+ for (const [k, v] of this.byId) {
13907
+ records[k] = v;
13908
+ }
13909
+ this.persistence.save(records, this.order);
13910
+ this.dirty = false;
13911
+ } catch {
13912
+ }
13913
+ }
13914
+ checkCapacity() {
13915
+ if (this.byId.size >= this.maxItems) {
13916
+ throw new BufferFullError(
13917
+ `Activity buffer is full (max ${this.maxItems} items). Reject per spec.`,
13918
+ 1 /* BUFFER_FULL */
13919
+ );
13920
+ }
13921
+ }
13922
+ cleanupExpiredDedupEntries() {
13923
+ const nowMs = Date.now();
13924
+ const windowMs = this.dedupWindowS * 1e3;
13925
+ const expired = [];
13926
+ for (const [token, mid] of this.byIdempotencyToken) {
13927
+ const rec = this.byId.get(mid);
13928
+ if (rec && nowMs - rec.ts_ms > windowMs) {
13929
+ expired.push(token);
13930
+ }
13931
+ }
13932
+ for (const token of expired) {
13933
+ this.byIdempotencyToken.delete(token);
13934
+ }
13935
+ }
13936
+ /**
13937
+ * Record an incoming envelope. Throws BufferFullError if buffer is at capacity.
13938
+ */
13939
+ recordIncoming(envelope) {
13940
+ this.checkCapacity();
13941
+ const mid = String(envelope.message_id ?? "");
13942
+ const rec = {
13943
+ message_id: mid,
13944
+ direction: "in",
13945
+ envelope,
13946
+ ts_ms: Date.now(),
13947
+ ack_stage: 0 /* ACK_STAGE_UNSPECIFIED */,
13948
+ error_code: 0 /* ERROR_CODE_UNSPECIFIED */,
13949
+ ack_note: ""
13950
+ };
13951
+ this.byId.set(mid, rec);
13952
+ this.order.push(mid);
13953
+ const token = envelope.idempotency_token;
13954
+ if (token) {
13955
+ this.byIdempotencyToken.set(token, mid);
13956
+ }
13957
+ this.cleanupExpiredDedupEntries();
13958
+ this.dirty = true;
13959
+ return rec;
13960
+ }
13961
+ /**
13962
+ * Record an outgoing envelope. Throws BufferFullError if buffer is at capacity.
13963
+ */
13964
+ recordOutgoing(envelope) {
13965
+ this.checkCapacity();
13966
+ const mid = String(envelope.message_id ?? "");
13967
+ const rec = {
13968
+ message_id: mid,
13969
+ direction: "out",
13970
+ envelope,
13971
+ ts_ms: Date.now(),
13972
+ ack_stage: 0 /* ACK_STAGE_UNSPECIFIED */,
13973
+ error_code: 0 /* ERROR_CODE_UNSPECIFIED */,
13974
+ ack_note: ""
13975
+ };
13976
+ this.byId.set(mid, rec);
13977
+ this.order.push(mid);
13978
+ const token = envelope.idempotency_token;
13979
+ if (token) {
13980
+ this.byIdempotencyToken.set(token, mid);
13981
+ }
13982
+ this.cleanupExpiredDedupEntries();
13983
+ this.dirty = true;
13984
+ return rec;
13985
+ }
13986
+ /**
13987
+ * Process an ACK for a previously recorded message.
13988
+ */
13989
+ ack(ackMsg) {
13990
+ const target = String(ackMsg.ack_for_message_id);
13991
+ const rec = this.byId.get(target);
13992
+ if (rec) {
13993
+ rec.ack_stage = ackMsg.ack_stage ?? 0 /* ACK_STAGE_UNSPECIFIED */;
13994
+ rec.error_code = ackMsg.error_code ?? 0 /* ERROR_CODE_UNSPECIFIED */;
13995
+ rec.ack_note = ackMsg.note ?? "";
13996
+ this.dirty = true;
13997
+ }
13998
+ return rec;
13999
+ }
14000
+ /** Get record by message ID. */
14001
+ get(messageId) {
14002
+ return this.byId.get(messageId);
14003
+ }
14004
+ /** Get record by idempotency token (for deduplication). */
14005
+ getByIdempotencyToken(token) {
14006
+ this.cleanupExpiredDedupEntries();
14007
+ const mid = this.byIdempotencyToken.get(token);
14008
+ if (mid)
14009
+ return this.byId.get(mid);
14010
+ return void 0;
14011
+ }
14012
+ /** Get all un-ACKed records. */
14013
+ unacked() {
14014
+ return [...this.byId.values()].filter(
14015
+ (r) => r.ack_stage === 0 /* ACK_STAGE_UNSPECIFIED */ || r.ack_stage === 1 /* RECEIVED */ || r.ack_stage === 2 /* READ */
14016
+ );
14017
+ }
14018
+ /** Get N most recent records. */
14019
+ recent(n = 50) {
14020
+ const ids = this.order.slice(-n);
14021
+ return ids.map((id) => this.byId.get(id)).filter(Boolean);
14022
+ }
14023
+ /** Update envelope state for a message. */
14024
+ updateState(messageId, newState) {
14025
+ const rec = this.byId.get(messageId);
14026
+ if (rec) {
14027
+ rec.envelope.state = newState;
14028
+ this.dirty = true;
14029
+ }
14030
+ return rec;
14031
+ }
14032
+ /** Return unacked outgoing messages for reconciliation. */
14033
+ reconcile() {
14034
+ return this.unacked().filter((r) => r.direction === "out");
14035
+ }
14036
+ /** Force save to persistence. */
14037
+ flush() {
14038
+ this.dirty = true;
14039
+ this.saveToPersistence();
14040
+ }
14041
+ /** Clear all records. */
14042
+ clear() {
14043
+ this.byId.clear();
14044
+ this.byIdempotencyToken.clear();
14045
+ this.order = [];
14046
+ this.persistence.clear();
14047
+ this.dirty = false;
14048
+ }
14049
+ /** Get the count of records. */
14050
+ get size() {
14051
+ return this.byId.size;
14052
+ }
14053
+ };
14054
+
10894
14055
  // src/secrets/types.ts
10895
14056
  var SecretSource = /* @__PURE__ */ ((SecretSource2) => {
10896
14057
  SecretSource2["CLI"] = "cli";
@@ -10977,7 +14138,7 @@ var Resolver = class {
10977
14138
  try {
10978
14139
  const v = await this.backend.get(scope, key);
10979
14140
  return [v, scope.isGlobal ? "global" /* GLOBAL */ : "scoped" /* SCOPED */];
10980
- } catch (e) {
14141
+ } catch {
10981
14142
  }
10982
14143
  if (!scope.isGlobal) {
10983
14144
  const v = await this.backend.get(new Scope(null), key);
@@ -10988,28 +14149,28 @@ var Resolver = class {
10988
14149
  };
10989
14150
 
10990
14151
  // src/secrets/backends/file.ts
10991
- var import_node_fs = require("node:fs");
10992
- var import_node_path3 = require("node:path");
14152
+ var import_node_fs3 = require("node:fs");
14153
+ var import_node_path5 = require("node:path");
10993
14154
  function defaultPath() {
10994
14155
  const isWin = process.platform === "win32";
10995
14156
  if (isWin) {
10996
- const base2 = process.env.APPDATA || (0, import_node_path3.join)(process.env.USERPROFILE || "", "AppData", "Roaming");
10997
- return (0, import_node_path3.join)(base2, "sw4rm", "secrets.json");
14157
+ const base2 = process.env.APPDATA || (0, import_node_path5.join)(process.env.USERPROFILE || "", "AppData", "Roaming");
14158
+ return (0, import_node_path5.join)(base2, "sw4rm", "secrets.json");
10998
14159
  }
10999
14160
  const xdg = process.env.XDG_CONFIG_HOME;
11000
- const base = xdg && xdg.length > 0 ? xdg : (0, import_node_path3.join)(process.env.HOME || "", ".config");
11001
- return (0, import_node_path3.join)(base, "sw4rm", "secrets.json");
14161
+ const base = xdg && xdg.length > 0 ? xdg : (0, import_node_path5.join)(process.env.HOME || "", ".config");
14162
+ return (0, import_node_path5.join)(base, "sw4rm", "secrets.json");
11002
14163
  }
11003
14164
  var FileBackend = class {
11004
14165
  path;
11005
- constructor(path3) {
11006
- this.path = path3 ?? defaultPath();
11007
- (0, import_node_fs.mkdirSync)((0, import_node_path3.dirname)(this.path), { recursive: true });
14166
+ constructor(path5) {
14167
+ this.path = path5 ?? defaultPath();
14168
+ (0, import_node_fs3.mkdirSync)((0, import_node_path5.dirname)(this.path), { recursive: true });
11008
14169
  try {
11009
- (0, import_node_fs.chmodSync)((0, import_node_path3.dirname)(this.path), 448);
14170
+ (0, import_node_fs3.chmodSync)((0, import_node_path5.dirname)(this.path), 448);
11010
14171
  } catch {
11011
14172
  }
11012
- if (!(0, import_node_fs.existsSync)(this.path)) {
14173
+ if (!(0, import_node_fs3.existsSync)(this.path)) {
11013
14174
  this.safeWrite({});
11014
14175
  this.enforceFilePerms();
11015
14176
  } else {
@@ -11019,17 +14180,17 @@ var FileBackend = class {
11019
14180
  enforceFilePerms() {
11020
14181
  if (process.platform !== "win32") {
11021
14182
  try {
11022
- (0, import_node_fs.chmodSync)(this.path, 384);
14183
+ (0, import_node_fs3.chmodSync)(this.path, 384);
11023
14184
  } catch (e) {
11024
14185
  throw new SecretPermissionError(String(e));
11025
14186
  }
11026
14187
  }
11027
14188
  }
11028
14189
  safeWrite(obj) {
11029
- const tmp = (0, import_node_path3.join)((0, import_node_path3.dirname)(this.path), `.secrets.${Date.now()}.${Math.random().toString(16).slice(2)}`);
14190
+ const tmp = (0, import_node_path5.join)((0, import_node_path5.dirname)(this.path), `.secrets.${Date.now()}.${Math.random().toString(16).slice(2)}`);
11030
14191
  try {
11031
- (0, import_node_fs.writeFileSync)(tmp, JSON.stringify(obj, null, 2), { encoding: "utf8", mode: 384 });
11032
- (0, import_node_fs.renameSync)(tmp, this.path);
14192
+ (0, import_node_fs3.writeFileSync)(tmp, JSON.stringify(obj, null, 2), { encoding: "utf8", mode: 384 });
14193
+ (0, import_node_fs3.renameSync)(tmp, this.path);
11033
14194
  this.enforceFilePerms();
11034
14195
  } catch (e) {
11035
14196
  throw new SecretBackendError(String(e));
@@ -11037,7 +14198,7 @@ var FileBackend = class {
11037
14198
  }
11038
14199
  load() {
11039
14200
  try {
11040
- const s = (0, import_node_fs.readFileSync)(this.path, { encoding: "utf8" });
14201
+ const s = (0, import_node_fs3.readFileSync)(this.path, { encoding: "utf8" });
11041
14202
  return JSON.parse(s);
11042
14203
  } catch (e) {
11043
14204
  if (e.code === "ENOENT")
@@ -11134,7 +14295,7 @@ async function selectBackend(mode) {
11134
14295
  }
11135
14296
 
11136
14297
  // src/index.ts
11137
- var version = "0.3.0";
14298
+ var version = "0.5.0";
11138
14299
  // Annotate the CommonJS export names for ESM import in node:
11139
14300
  0 && (module.exports = {
11140
14301
  ACKLifecycleManager,
@@ -11142,27 +14303,67 @@ var version = "0.3.0";
11142
14303
  ActivityBuffer,
11143
14304
  ActivityBufferSync,
11144
14305
  ActivityClient,
14306
+ AgentState,
14307
+ AgentStateMachine,
14308
+ ArtifactType,
11145
14309
  BaseClient,
14310
+ BordaCountAggregator,
14311
+ BufferFullError,
11146
14312
  CT_AGENT_REPORT_V1,
11147
14313
  CT_SCHEDULER_COMMAND_V1,
14314
+ CommunicationClass,
14315
+ ConfidenceWeightedAggregator,
11148
14316
  ConnectorClient,
14317
+ DEDUP_WINDOW_S,
14318
+ DEFAULT_ACK_TIMEOUT_MS,
14319
+ DEFAULT_ESCALATION_POLICY,
14320
+ DEFAULT_EXECUTION_POLICY,
14321
+ DEFAULT_NEGOTIATION_POLICY,
14322
+ DebateIntensity,
14323
+ DecisionOutcome,
11149
14324
  DefaultWorktreePolicy,
14325
+ DuplicateDetectedError,
14326
+ EnvelopeState,
11150
14327
  ErrorCode,
11151
14328
  ErrorCodeMapper,
11152
14329
  FileBackend,
11153
14330
  HITLClient,
14331
+ HandoffClient,
14332
+ HandoffStatus,
14333
+ HandoffTimeoutError,
14334
+ HandoffValidationError,
14335
+ HitlMode,
14336
+ HitlReasonType,
14337
+ InMemoryAuditor,
14338
+ InMemoryNegotiationRoomStore,
14339
+ InMemoryPolicyStore,
11154
14340
  InterceptorChain,
11155
14341
  JSONFilePersistence,
14342
+ JsonFilePolicyStore,
11156
14343
  KeyringBackend,
11157
14344
  LoggingClient,
14345
+ MajorityVoteAggregator,
11158
14346
  MaxEntriesStrategy,
11159
14347
  MessageProcessor,
11160
14348
  MessageType,
11161
14349
  NegotiationClient,
14350
+ NegotiationError,
14351
+ NegotiationRoomClient,
14352
+ NegotiationRoomStoreError,
14353
+ NegotiationTimeoutError,
14354
+ NegotiationValidationError,
14355
+ NoOpAuditor,
14356
+ NodeStatus,
14357
+ PermissionError,
14358
+ PersistentActivityBuffer,
11162
14359
  PersistentWorktreeState,
14360
+ PolicyStoreError,
14361
+ PolicyViolationError,
14362
+ PreemptionError,
11163
14363
  ReasoningClient,
11164
14364
  RegistryClient,
11165
14365
  Resolver,
14366
+ RouteError,
11166
14367
  RouterClient,
11167
14368
  RuntimePersistence,
11168
14369
  SchedulerClient,
@@ -11177,27 +14378,60 @@ var version = "0.3.0";
11177
14378
  SecretValidationError,
11178
14379
  SecretValue,
11179
14380
  Secrets,
14381
+ SimpleAverageAggregator,
14382
+ StateTransitionError,
11180
14383
  Sw4rmError,
14384
+ TimeoutError,
11181
14385
  ToolClient,
14386
+ TriggerType,
14387
+ ValidationError,
14388
+ VotingAnalyzer,
14389
+ WorkflowClient,
14390
+ WorkflowCycleError,
14391
+ WorkflowStatus,
14392
+ WorkflowValidationError,
11182
14393
  WorktreeClient,
14394
+ WorktreeError,
14395
+ WorktreeStateEnum,
14396
+ WorktreeTransitionError,
14397
+ aggregateVotes,
11183
14398
  buildAckEnvelope,
11184
14399
  buildEnvelope,
14400
+ computeEnvelopeHash,
11185
14401
  computeIdempotencyToken,
11186
14402
  createResilientIncomingStream,
14403
+ createSimpleProof,
11187
14404
  decodeAgentReportV1,
11188
14405
  decodeBase64,
14406
+ defaultAgentConfig,
14407
+ defaultEndpoints,
14408
+ defaultRetryPolicy,
14409
+ defaultSW4RMConfig,
11189
14410
  durationToMs,
11190
14411
  encodeSchedulerCommandV1,
14412
+ getConfig,
14413
+ getDefaultStore,
14414
+ getValidTransitions,
14415
+ isTerminalEnvelopeState,
14416
+ isValidTransition,
14417
+ isValidWorktreeTransition,
14418
+ loadConfig,
14419
+ loadConfigFromEnv,
11191
14420
  loggingInterceptor,
11192
14421
  mapGrpcStatusToErrorCode,
11193
14422
  msToDuration,
11194
14423
  normalizeReportPaths,
11195
14424
  nowTimestamp,
11196
14425
  parseNegotiationEvent,
14426
+ resetConfig,
14427
+ resetDefaultStore,
11197
14428
  selectBackend,
11198
14429
  sendMessageWithAck,
14430
+ setConfig,
11199
14431
  timingInterceptor,
14432
+ updateEnvelopeState,
11200
14433
  uuidv4,
14434
+ verifyAuditProof,
11201
14435
  version
11202
14436
  });
11203
14437
  /*! Bundled license information: