@sw4rm/js-sdk 0.4.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.
package/dist/esm/index.js CHANGED
@@ -1860,7 +1860,7 @@ var require_fetch = __commonJS({
1860
1860
  module2.exports = fetch;
1861
1861
  var asPromise = require_aspromise();
1862
1862
  var inquire2 = require_inquire();
1863
- var fs = inquire2("fs");
1863
+ var fs3 = inquire2("fs");
1864
1864
  function fetch(filename, options, callback) {
1865
1865
  if (typeof options === "function") {
1866
1866
  callback = options;
@@ -1869,8 +1869,8 @@ var require_fetch = __commonJS({
1869
1869
  options = {};
1870
1870
  if (!callback)
1871
1871
  return asPromise(fetch, this, filename, options);
1872
- if (!options.xhr && fs && fs.readFile)
1873
- return fs.readFile(filename, function fetchReadFileCallback(err, contents) {
1872
+ if (!options.xhr && fs3 && fs3.readFile)
1873
+ return fs3.readFile(filename, function fetchReadFileCallback(err, contents) {
1874
1874
  return err && typeof XMLHttpRequest !== "undefined" ? fetch.xhr(filename, options, callback) : err ? callback(err) : callback(null, options.binary ? contents : contents.toString("utf8"));
1875
1875
  });
1876
1876
  return fetch.xhr(filename, options, callback);
@@ -1908,15 +1908,15 @@ var require_fetch = __commonJS({
1908
1908
  var require_path = __commonJS({
1909
1909
  "node_modules/@protobufjs/path/index.js"(exports2) {
1910
1910
  "use strict";
1911
- var path4 = exports2;
1911
+ var path5 = exports2;
1912
1912
  var isAbsolute = (
1913
1913
  /**
1914
1914
  * Tests if the specified path is absolute.
1915
1915
  * @param {string} path Path to test
1916
1916
  * @returns {boolean} `true` if path is absolute
1917
1917
  */
1918
- path4.isAbsolute = function isAbsolute2(path5) {
1919
- return /^(?:\/|\w+:)/.test(path5);
1918
+ path5.isAbsolute = function isAbsolute2(path6) {
1919
+ return /^(?:\/|\w+:)/.test(path6);
1920
1920
  }
1921
1921
  );
1922
1922
  var normalize = (
@@ -1925,9 +1925,9 @@ var require_path = __commonJS({
1925
1925
  * @param {string} path Path to normalize
1926
1926
  * @returns {string} Normalized path
1927
1927
  */
1928
- path4.normalize = function normalize2(path5) {
1929
- path5 = path5.replace(/\\/g, "/").replace(/\/{2,}/g, "/");
1930
- var parts = path5.split("/"), absolute = isAbsolute(path5), prefix = "";
1928
+ path5.normalize = function normalize2(path6) {
1929
+ path6 = path6.replace(/\\/g, "/").replace(/\/{2,}/g, "/");
1930
+ var parts = path6.split("/"), absolute = isAbsolute(path6), prefix = "";
1931
1931
  if (absolute)
1932
1932
  prefix = parts.shift() + "/";
1933
1933
  for (var i = 0; i < parts.length; ) {
@@ -1946,7 +1946,7 @@ var require_path = __commonJS({
1946
1946
  return prefix + parts.join("/");
1947
1947
  }
1948
1948
  );
1949
- path4.resolve = function resolve(originPath, includePath, alreadyNormalized) {
1949
+ path5.resolve = function resolve(originPath, includePath, alreadyNormalized) {
1950
1950
  if (!alreadyNormalized)
1951
1951
  includePath = normalize(includePath);
1952
1952
  if (isAbsolute(includePath))
@@ -2097,16 +2097,16 @@ var require_namespace = __commonJS({
2097
2097
  object.onRemove(this);
2098
2098
  return clearCache(this);
2099
2099
  };
2100
- Namespace.prototype.define = function define2(path4, json) {
2101
- if (util.isString(path4))
2102
- path4 = path4.split(".");
2103
- else if (!Array.isArray(path4))
2100
+ Namespace.prototype.define = function define2(path5, json) {
2101
+ if (util.isString(path5))
2102
+ path5 = path5.split(".");
2103
+ else if (!Array.isArray(path5))
2104
2104
  throw TypeError("illegal path");
2105
- if (path4 && path4.length && path4[0] === "")
2105
+ if (path5 && path5.length && path5[0] === "")
2106
2106
  throw Error("path must be relative");
2107
2107
  var ptr = this;
2108
- while (path4.length > 0) {
2109
- var part = path4.shift();
2108
+ while (path5.length > 0) {
2109
+ var part = path5.shift();
2110
2110
  if (ptr.nested && ptr.nested[part]) {
2111
2111
  ptr = ptr.nested[part];
2112
2112
  if (!(ptr instanceof Namespace))
@@ -2143,26 +2143,26 @@ var require_namespace = __commonJS({
2143
2143
  });
2144
2144
  return this;
2145
2145
  };
2146
- Namespace.prototype.lookup = function lookup(path4, filterTypes, parentAlreadyChecked) {
2146
+ Namespace.prototype.lookup = function lookup(path5, filterTypes, parentAlreadyChecked) {
2147
2147
  if (typeof filterTypes === "boolean") {
2148
2148
  parentAlreadyChecked = filterTypes;
2149
2149
  filterTypes = void 0;
2150
2150
  } else if (filterTypes && !Array.isArray(filterTypes))
2151
2151
  filterTypes = [filterTypes];
2152
- if (util.isString(path4) && path4.length) {
2153
- if (path4 === ".")
2152
+ if (util.isString(path5) && path5.length) {
2153
+ if (path5 === ".")
2154
2154
  return this.root;
2155
- path4 = path4.split(".");
2156
- } else if (!path4.length)
2155
+ path5 = path5.split(".");
2156
+ } else if (!path5.length)
2157
2157
  return this;
2158
- var flatPath = path4.join(".");
2159
- if (path4[0] === "")
2160
- return this.root.lookup(path4.slice(1), filterTypes);
2158
+ var flatPath = path5.join(".");
2159
+ if (path5[0] === "")
2160
+ return this.root.lookup(path5.slice(1), filterTypes);
2161
2161
  var found = this.root._fullyQualifiedObjects && this.root._fullyQualifiedObjects["." + flatPath];
2162
2162
  if (found && (!filterTypes || filterTypes.indexOf(found.constructor) > -1)) {
2163
2163
  return found;
2164
2164
  }
2165
- found = this._lookupImpl(path4, flatPath);
2165
+ found = this._lookupImpl(path5, flatPath);
2166
2166
  if (found && (!filterTypes || filterTypes.indexOf(found.constructor) > -1)) {
2167
2167
  return found;
2168
2168
  }
@@ -2170,7 +2170,7 @@ var require_namespace = __commonJS({
2170
2170
  return null;
2171
2171
  var current = this;
2172
2172
  while (current.parent) {
2173
- found = current.parent._lookupImpl(path4, flatPath);
2173
+ found = current.parent._lookupImpl(path5, flatPath);
2174
2174
  if (found && (!filterTypes || filterTypes.indexOf(found.constructor) > -1)) {
2175
2175
  return found;
2176
2176
  }
@@ -2178,49 +2178,49 @@ var require_namespace = __commonJS({
2178
2178
  }
2179
2179
  return null;
2180
2180
  };
2181
- Namespace.prototype._lookupImpl = function lookup(path4, flatPath) {
2181
+ Namespace.prototype._lookupImpl = function lookup(path5, flatPath) {
2182
2182
  if (Object.prototype.hasOwnProperty.call(this._lookupCache, flatPath)) {
2183
2183
  return this._lookupCache[flatPath];
2184
2184
  }
2185
- var found = this.get(path4[0]);
2185
+ var found = this.get(path5[0]);
2186
2186
  var exact = null;
2187
2187
  if (found) {
2188
- if (path4.length === 1) {
2188
+ if (path5.length === 1) {
2189
2189
  exact = found;
2190
2190
  } else if (found instanceof Namespace) {
2191
- path4 = path4.slice(1);
2192
- exact = found._lookupImpl(path4, path4.join("."));
2191
+ path5 = path5.slice(1);
2192
+ exact = found._lookupImpl(path5, path5.join("."));
2193
2193
  }
2194
2194
  } else {
2195
2195
  for (var i = 0; i < this.nestedArray.length; ++i)
2196
- if (this._nestedArray[i] instanceof Namespace && (found = this._nestedArray[i]._lookupImpl(path4, flatPath)))
2196
+ if (this._nestedArray[i] instanceof Namespace && (found = this._nestedArray[i]._lookupImpl(path5, flatPath)))
2197
2197
  exact = found;
2198
2198
  }
2199
2199
  this._lookupCache[flatPath] = exact;
2200
2200
  return exact;
2201
2201
  };
2202
- Namespace.prototype.lookupType = function lookupType(path4) {
2203
- var found = this.lookup(path4, [Type]);
2202
+ Namespace.prototype.lookupType = function lookupType(path5) {
2203
+ var found = this.lookup(path5, [Type]);
2204
2204
  if (!found)
2205
- throw Error("no such type: " + path4);
2205
+ throw Error("no such type: " + path5);
2206
2206
  return found;
2207
2207
  };
2208
- Namespace.prototype.lookupEnum = function lookupEnum(path4) {
2209
- var found = this.lookup(path4, [Enum]);
2208
+ Namespace.prototype.lookupEnum = function lookupEnum(path5) {
2209
+ var found = this.lookup(path5, [Enum]);
2210
2210
  if (!found)
2211
- throw Error("no such Enum '" + path4 + "' in " + this);
2211
+ throw Error("no such Enum '" + path5 + "' in " + this);
2212
2212
  return found;
2213
2213
  };
2214
- Namespace.prototype.lookupTypeOrEnum = function lookupTypeOrEnum(path4) {
2215
- var found = this.lookup(path4, [Type, Enum]);
2214
+ Namespace.prototype.lookupTypeOrEnum = function lookupTypeOrEnum(path5) {
2215
+ var found = this.lookup(path5, [Type, Enum]);
2216
2216
  if (!found)
2217
- throw Error("no such Type or Enum '" + path4 + "' in " + this);
2217
+ throw Error("no such Type or Enum '" + path5 + "' in " + this);
2218
2218
  return found;
2219
2219
  };
2220
- Namespace.prototype.lookupService = function lookupService(path4) {
2221
- var found = this.lookup(path4, [Service]);
2220
+ Namespace.prototype.lookupService = function lookupService(path5) {
2221
+ var found = this.lookup(path5, [Service]);
2222
2222
  if (!found)
2223
- throw Error("no such Service '" + path4 + "' in " + this);
2223
+ throw Error("no such Service '" + path5 + "' in " + this);
2224
2224
  return found;
2225
2225
  };
2226
2226
  Namespace._configure = function(Type_, Service_, Enum_) {
@@ -3621,14 +3621,14 @@ var require_util = __commonJS({
3621
3621
  Object.defineProperty(object, "$type", { value: enm, enumerable: false });
3622
3622
  return enm;
3623
3623
  };
3624
- util.setProperty = function setProperty(dst, path4, value, ifNotSet) {
3625
- function setProp(dst2, path5, value2) {
3626
- var part = path5.shift();
3624
+ util.setProperty = function setProperty(dst, path5, value, ifNotSet) {
3625
+ function setProp(dst2, path6, value2) {
3626
+ var part = path6.shift();
3627
3627
  if (part === "__proto__" || part === "prototype") {
3628
3628
  return dst2;
3629
3629
  }
3630
- if (path5.length > 0) {
3631
- dst2[part] = setProp(dst2[part] || {}, path5, value2);
3630
+ if (path6.length > 0) {
3631
+ dst2[part] = setProp(dst2[part] || {}, path6, value2);
3632
3632
  } else {
3633
3633
  var prevValue = dst2[part];
3634
3634
  if (prevValue && ifNotSet)
@@ -3641,10 +3641,10 @@ var require_util = __commonJS({
3641
3641
  }
3642
3642
  if (typeof dst !== "object")
3643
3643
  throw TypeError("dst must be an object");
3644
- if (!path4)
3644
+ if (!path5)
3645
3645
  throw TypeError("path must be specified");
3646
- path4 = path4.split(".");
3647
- return setProp(dst, path4, value);
3646
+ path5 = path5.split(".");
3647
+ return setProp(dst, path5, value);
3648
3648
  };
3649
3649
  Object.defineProperty(util, "decorateRoot", {
3650
3650
  get: function() {
@@ -4191,12 +4191,12 @@ var require_object = __commonJS({
4191
4191
  */
4192
4192
  fullName: {
4193
4193
  get: function() {
4194
- var path4 = [this.name], ptr = this.parent;
4194
+ var path5 = [this.name], ptr = this.parent;
4195
4195
  while (ptr) {
4196
- path4.unshift(ptr.name);
4196
+ path5.unshift(ptr.name);
4197
4197
  ptr = ptr.parent;
4198
4198
  }
4199
- return path4.join(".");
4199
+ return path5.join(".");
4200
4200
  }
4201
4201
  }
4202
4202
  });
@@ -8178,19 +8178,19 @@ var require_util2 = __commonJS({
8178
8178
  "use strict";
8179
8179
  Object.defineProperty(exports2, "__esModule", { value: true });
8180
8180
  exports2.addCommonProtos = exports2.loadProtosWithOptionsSync = exports2.loadProtosWithOptions = void 0;
8181
- var fs = __require("fs");
8182
- var path4 = __require("path");
8181
+ var fs3 = __require("fs");
8182
+ var path5 = __require("path");
8183
8183
  var Protobuf = require_protobufjs();
8184
8184
  function addIncludePathResolver(root, includePaths) {
8185
8185
  const originalResolvePath = root.resolvePath;
8186
8186
  root.resolvePath = (origin, target) => {
8187
- if (path4.isAbsolute(target)) {
8187
+ if (path5.isAbsolute(target)) {
8188
8188
  return target;
8189
8189
  }
8190
8190
  for (const directory of includePaths) {
8191
- const fullPath = path4.join(directory, target);
8191
+ const fullPath = path5.join(directory, target);
8192
8192
  try {
8193
- fs.accessSync(fullPath, fs.constants.R_OK);
8193
+ fs3.accessSync(fullPath, fs3.constants.R_OK);
8194
8194
  return fullPath;
8195
8195
  } catch (err) {
8196
8196
  continue;
@@ -9482,6 +9482,7 @@ var require_src2 = __commonJS({
9482
9482
 
9483
9483
  // src/internal/baseClient.ts
9484
9484
  var protoLoader = __toESM(require_src2(), 1);
9485
+ import fs from "node:fs";
9485
9486
  import path from "node:path";
9486
9487
  import { fileURLToPath } from "node:url";
9487
9488
  import * as grpc from "@grpc/grpc-js";
@@ -9502,6 +9503,8 @@ var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
9502
9503
  ErrorCode2[ErrorCode2["PARTIAL_DELIVERY"] = 11] = "PARTIAL_DELIVERY";
9503
9504
  ErrorCode2[ErrorCode2["FORCED_PREEMPTION"] = 12] = "FORCED_PREEMPTION";
9504
9505
  ErrorCode2[ErrorCode2["TTL_EXPIRED"] = 13] = "TTL_EXPIRED";
9506
+ ErrorCode2[ErrorCode2["DUPLICATE_DETECTED"] = 14] = "DUPLICATE_DETECTED";
9507
+ ErrorCode2[ErrorCode2["ALREADY_IN_PROGRESS"] = 15] = "ALREADY_IN_PROGRESS";
9505
9508
  ErrorCode2[ErrorCode2["INTERNAL_ERROR"] = 99] = "INTERNAL_ERROR";
9506
9509
  return ErrorCode2;
9507
9510
  })(ErrorCode || {});
@@ -9517,6 +9520,54 @@ var Sw4rmError = class extends Error {
9517
9520
  this.details = opts?.details;
9518
9521
  }
9519
9522
  };
9523
+ var ValidationError = class extends Sw4rmError {
9524
+ constructor(message, code = 6 /* VALIDATION_ERROR */, opts) {
9525
+ super(message, code, opts);
9526
+ this.name = "ValidationError";
9527
+ }
9528
+ };
9529
+ var TimeoutError = class extends Sw4rmError {
9530
+ constructor(message, code = 3 /* ACK_TIMEOUT */, opts) {
9531
+ super(message, code, opts);
9532
+ this.name = "TimeoutError";
9533
+ }
9534
+ };
9535
+ var StateTransitionError = class extends Sw4rmError {
9536
+ constructor(message, code = 99 /* INTERNAL_ERROR */, opts) {
9537
+ super(message, code, opts);
9538
+ this.name = "StateTransitionError";
9539
+ }
9540
+ };
9541
+ var NegotiationError = class extends Sw4rmError {
9542
+ constructor(message, code = 99 /* INTERNAL_ERROR */, opts) {
9543
+ super(message, code, opts);
9544
+ this.name = "NegotiationError";
9545
+ }
9546
+ };
9547
+ var BufferFullError = class extends Sw4rmError {
9548
+ constructor(message, code = 1 /* BUFFER_FULL */, opts) {
9549
+ super(message, code, opts);
9550
+ this.name = "BufferFullError";
9551
+ }
9552
+ };
9553
+ var RouteError = class extends Sw4rmError {
9554
+ constructor(message, code = 2 /* NO_ROUTE */, opts) {
9555
+ super(message, code, opts);
9556
+ this.name = "RouteError";
9557
+ }
9558
+ };
9559
+ var PermissionError = class extends Sw4rmError {
9560
+ constructor(message, code = 7 /* PERMISSION_DENIED */, opts) {
9561
+ super(message, code, opts);
9562
+ this.name = "PermissionError";
9563
+ }
9564
+ };
9565
+ var DuplicateDetectedError = class extends Sw4rmError {
9566
+ constructor(message, code = 14 /* DUPLICATE_DETECTED */, opts) {
9567
+ super(message, code, opts);
9568
+ this.name = "DuplicateDetectedError";
9569
+ }
9570
+ };
9520
9571
  var GrpcStatus = {
9521
9572
  OK: 0,
9522
9573
  CANCELLED: 1,
@@ -9536,6 +9587,28 @@ var GrpcStatus = {
9536
9587
  DATA_LOSS: 15,
9537
9588
  UNAUTHENTICATED: 16
9538
9589
  };
9590
+ var PreemptionError = class extends Sw4rmError {
9591
+ agentId;
9592
+ reason;
9593
+ constructor(agentId, reason, code = 12 /* FORCED_PREEMPTION */, opts) {
9594
+ super(`Agent ${agentId} preempted: ${reason}`, code, opts);
9595
+ this.name = "PreemptionError";
9596
+ this.agentId = agentId;
9597
+ this.reason = reason;
9598
+ }
9599
+ };
9600
+ var WorktreeError = class extends Sw4rmError {
9601
+ constructor(message, code = 99 /* INTERNAL_ERROR */, opts) {
9602
+ super(message, code, opts);
9603
+ this.name = "WorktreeError";
9604
+ }
9605
+ };
9606
+ var PolicyViolationError = class extends Sw4rmError {
9607
+ constructor(message, code = 7 /* PERMISSION_DENIED */, opts) {
9608
+ super(message, code, opts);
9609
+ this.name = "PolicyViolationError";
9610
+ }
9611
+ };
9539
9612
  function mapGrpcStatusToErrorCode(status) {
9540
9613
  switch (status) {
9541
9614
  case GrpcStatus.OK:
@@ -9649,12 +9722,12 @@ var BaseClient = class {
9649
9722
  errorMapper = new ErrorCodeMapper();
9650
9723
  constructor(opts) {
9651
9724
  this.address = opts.address;
9652
- this.deadlineMs = opts.deadlineMs ?? 1e4;
9725
+ this.deadlineMs = opts.deadlineMs ?? 3e4;
9653
9726
  this.retry = opts.retry ?? { maxAttempts: 3, initialBackoffMs: 200, maxBackoffMs: 2e3, multiplier: 2 };
9654
9727
  this.userAgent = opts.userAgent ?? "sw4rm-js-sdk/0.1";
9655
9728
  const __filename = fileURLToPath(import.meta.url);
9656
9729
  const __dirname = path.dirname(__filename);
9657
- const protosDir = path.resolve(__dirname, "../../../../protos");
9730
+ const protosDir = this.resolveProtosDir(__dirname);
9658
9731
  const loaderOpts = {
9659
9732
  keepCase: true,
9660
9733
  longs: String,
@@ -9674,10 +9747,13 @@ var BaseClient = class {
9674
9747
  "tool.proto",
9675
9748
  "connector.proto",
9676
9749
  "negotiation.proto",
9750
+ "negotiation_room.proto",
9677
9751
  "reasoning.proto",
9678
9752
  "logging.proto",
9679
9753
  "policy.proto",
9680
- "activity.proto"
9754
+ "activity.proto",
9755
+ "handoff.proto",
9756
+ "workflow.proto"
9681
9757
  ], loaderOpts);
9682
9758
  this.root = grpc.loadPackageDefinition(this.pkgDef);
9683
9759
  this.interceptors.use(timingInterceptor());
@@ -9687,6 +9763,27 @@ var BaseClient = class {
9687
9763
  if (opts.errorMapper)
9688
9764
  opts.errorMapper(this.errorMapper);
9689
9765
  }
9766
+ /**
9767
+ * Resolves the protos directory, checking multiple locations:
9768
+ * 1. npm package: ./protos relative to package root
9769
+ * 2. Monorepo dev: ../../../../protos relative to this file
9770
+ */
9771
+ resolveProtosDir(dirname3) {
9772
+ const candidates = [
9773
+ // npm package structure: node_modules/@sw4rm/js-sdk/protos
9774
+ path.resolve(dirname3, "../../protos"),
9775
+ // Alternative npm structure: dist/esm/internal -> protos
9776
+ path.resolve(dirname3, "../../../protos"),
9777
+ // Monorepo development: sdks/js_sdk/src/internal -> protos
9778
+ path.resolve(dirname3, "../../../../protos")
9779
+ ];
9780
+ for (const candidate of candidates) {
9781
+ if (fs.existsSync(candidate) && fs.existsSync(path.join(candidate, "common.proto"))) {
9782
+ return candidate;
9783
+ }
9784
+ }
9785
+ return candidates[candidates.length - 1];
9786
+ }
9690
9787
  channelCredentials() {
9691
9788
  return grpc.credentials.createInsecure();
9692
9789
  }
@@ -10274,6 +10371,95 @@ var RegistryClient = class extends BaseClient {
10274
10371
  }
10275
10372
  };
10276
10373
 
10374
+ // src/clients/negotiationRoomStore.ts
10375
+ var NegotiationRoomStoreError = class extends Error {
10376
+ constructor(message) {
10377
+ super(message);
10378
+ this.name = "NegotiationRoomStoreError";
10379
+ }
10380
+ };
10381
+ var InMemoryNegotiationRoomStore = class {
10382
+ proposals = /* @__PURE__ */ new Map();
10383
+ votes = /* @__PURE__ */ new Map();
10384
+ decisions = /* @__PURE__ */ new Map();
10385
+ async hasProposal(artifactId) {
10386
+ return this.proposals.has(artifactId);
10387
+ }
10388
+ async getProposal(artifactId) {
10389
+ return this.proposals.get(artifactId) || null;
10390
+ }
10391
+ async saveProposal(proposal) {
10392
+ const artifactId = proposal.artifactId;
10393
+ if (this.proposals.has(artifactId)) {
10394
+ throw new NegotiationRoomStoreError(
10395
+ `Proposal with artifact_id '${artifactId}' already exists`
10396
+ );
10397
+ }
10398
+ const proposalWithTimestamp = {
10399
+ ...proposal,
10400
+ createdAt: proposal.createdAt || (/* @__PURE__ */ new Date()).toISOString()
10401
+ };
10402
+ this.proposals.set(artifactId, proposalWithTimestamp);
10403
+ this.votes.set(artifactId, []);
10404
+ }
10405
+ async listProposals(negotiationRoomId) {
10406
+ const allProposals = Array.from(this.proposals.values());
10407
+ if (negotiationRoomId === void 0) {
10408
+ return allProposals;
10409
+ }
10410
+ return allProposals.filter((p) => p.negotiationRoomId === negotiationRoomId);
10411
+ }
10412
+ async getVotes(artifactId) {
10413
+ return [...this.votes.get(artifactId) || []];
10414
+ }
10415
+ async addVote(vote) {
10416
+ const artifactId = vote.artifactId;
10417
+ const criticId = vote.criticId;
10418
+ const existingVotes = this.votes.get(artifactId) || [];
10419
+ for (const existingVote of existingVotes) {
10420
+ if (existingVote.criticId === criticId) {
10421
+ throw new NegotiationRoomStoreError(
10422
+ `Critic '${criticId}' has already voted for artifact '${artifactId}'`
10423
+ );
10424
+ }
10425
+ }
10426
+ const voteWithTimestamp = {
10427
+ ...vote,
10428
+ votedAt: vote.votedAt || (/* @__PURE__ */ new Date()).toISOString()
10429
+ };
10430
+ if (!this.votes.has(artifactId)) {
10431
+ this.votes.set(artifactId, []);
10432
+ }
10433
+ this.votes.get(artifactId).push(voteWithTimestamp);
10434
+ }
10435
+ async getDecision(artifactId) {
10436
+ return this.decisions.get(artifactId) || null;
10437
+ }
10438
+ async saveDecision(decision) {
10439
+ const artifactId = decision.artifactId;
10440
+ if (this.decisions.has(artifactId)) {
10441
+ throw new NegotiationRoomStoreError(
10442
+ `Decision already exists for artifact_id '${artifactId}'`
10443
+ );
10444
+ }
10445
+ const decisionWithTimestamp = {
10446
+ ...decision,
10447
+ decidedAt: decision.decidedAt || (/* @__PURE__ */ new Date()).toISOString()
10448
+ };
10449
+ this.decisions.set(artifactId, decisionWithTimestamp);
10450
+ }
10451
+ };
10452
+ var defaultStore = null;
10453
+ function getDefaultStore() {
10454
+ if (defaultStore === null) {
10455
+ defaultStore = new InMemoryNegotiationRoomStore();
10456
+ }
10457
+ return defaultStore;
10458
+ }
10459
+ function resetDefaultStore() {
10460
+ defaultStore = null;
10461
+ }
10462
+
10277
10463
  // src/clients/negotiationRoom.ts
10278
10464
  var ArtifactType = /* @__PURE__ */ ((ArtifactType2) => {
10279
10465
  ArtifactType2[ArtifactType2["ARTIFACT_TYPE_UNSPECIFIED"] = 0] = "ARTIFACT_TYPE_UNSPECIFIED";
@@ -10315,9 +10501,16 @@ function validateVote(vote) {
10315
10501
  }
10316
10502
  }
10317
10503
  var NegotiationRoomClient = class {
10318
- proposals = /* @__PURE__ */ new Map();
10319
- votes = /* @__PURE__ */ new Map();
10320
- decisions = /* @__PURE__ */ new Map();
10504
+ store;
10505
+ /**
10506
+ * Create a new negotiation room client.
10507
+ *
10508
+ * @param options - Configuration options. If no store is provided,
10509
+ * uses the shared default in-memory store.
10510
+ */
10511
+ constructor(options = {}) {
10512
+ this.store = options.store || getDefaultStore();
10513
+ }
10321
10514
  /**
10322
10515
  * Submit an artifact proposal for multi-agent review.
10323
10516
  *
@@ -10345,19 +10538,8 @@ var NegotiationRoomClient = class {
10345
10538
  * ```
10346
10539
  */
10347
10540
  async submitProposal(proposal) {
10348
- const artifactId = proposal.artifactId;
10349
- if (this.proposals.has(artifactId)) {
10350
- throw new NegotiationValidationError(
10351
- `Proposal with artifact_id '${artifactId}' already exists`
10352
- );
10353
- }
10354
- const proposalWithTimestamp = {
10355
- ...proposal,
10356
- createdAt: proposal.createdAt || (/* @__PURE__ */ new Date()).toISOString()
10357
- };
10358
- this.proposals.set(artifactId, proposalWithTimestamp);
10359
- this.votes.set(artifactId, []);
10360
- return artifactId;
10541
+ await this.store.saveProposal(proposal);
10542
+ return proposal.artifactId;
10361
10543
  }
10362
10544
  /**
10363
10545
  * Submit a critic's vote for an artifact.
@@ -10389,26 +10571,13 @@ var NegotiationRoomClient = class {
10389
10571
  */
10390
10572
  async submitVote(vote) {
10391
10573
  const artifactId = vote.artifactId;
10392
- if (!this.proposals.has(artifactId)) {
10574
+ if (!await this.store.hasProposal(artifactId)) {
10393
10575
  throw new NegotiationValidationError(
10394
10576
  `No proposal found for artifact_id '${artifactId}'`
10395
10577
  );
10396
10578
  }
10397
10579
  validateVote(vote);
10398
- const existingVotes = this.votes.get(artifactId) || [];
10399
- for (const existingVote of existingVotes) {
10400
- if (existingVote.criticId === vote.criticId) {
10401
- throw new NegotiationValidationError(
10402
- `Critic '${vote.criticId}' has already voted for artifact '${artifactId}'`
10403
- );
10404
- }
10405
- }
10406
- const voteWithTimestamp = {
10407
- ...vote,
10408
- votedAt: vote.votedAt || (/* @__PURE__ */ new Date()).toISOString()
10409
- };
10410
- existingVotes.push(voteWithTimestamp);
10411
- this.votes.set(artifactId, existingVotes);
10580
+ await this.store.addVote(vote);
10412
10581
  }
10413
10582
  /**
10414
10583
  * Retrieve all votes for a specific artifact.
@@ -10428,12 +10597,12 @@ var NegotiationRoomClient = class {
10428
10597
  * ```
10429
10598
  */
10430
10599
  async getVotes(artifactId) {
10431
- if (!this.proposals.has(artifactId)) {
10600
+ if (!await this.store.hasProposal(artifactId)) {
10432
10601
  throw new NegotiationValidationError(
10433
10602
  `No proposal found for artifact_id '${artifactId}'`
10434
10603
  );
10435
10604
  }
10436
- return this.votes.get(artifactId) || [];
10605
+ return this.store.getVotes(artifactId);
10437
10606
  }
10438
10607
  /**
10439
10608
  * Retrieve the decision for a specific artifact if available.
@@ -10454,12 +10623,12 @@ var NegotiationRoomClient = class {
10454
10623
  * ```
10455
10624
  */
10456
10625
  async getDecision(artifactId) {
10457
- if (!this.proposals.has(artifactId)) {
10626
+ if (!await this.store.hasProposal(artifactId)) {
10458
10627
  throw new NegotiationValidationError(
10459
10628
  `No proposal found for artifact_id '${artifactId}'`
10460
10629
  );
10461
10630
  }
10462
- return this.decisions.get(artifactId) || null;
10631
+ return this.store.getDecision(artifactId);
10463
10632
  }
10464
10633
  /**
10465
10634
  * Store a decision for an artifact.
@@ -10490,21 +10659,12 @@ var NegotiationRoomClient = class {
10490
10659
  */
10491
10660
  async storeDecision(decision) {
10492
10661
  const artifactId = decision.artifactId;
10493
- if (!this.proposals.has(artifactId)) {
10662
+ if (!await this.store.hasProposal(artifactId)) {
10494
10663
  throw new NegotiationValidationError(
10495
10664
  `No proposal found for artifact_id '${artifactId}'`
10496
10665
  );
10497
10666
  }
10498
- if (this.decisions.has(artifactId)) {
10499
- throw new NegotiationValidationError(
10500
- `Decision already exists for artifact_id '${artifactId}'`
10501
- );
10502
- }
10503
- const decisionWithTimestamp = {
10504
- ...decision,
10505
- decidedAt: decision.decidedAt || (/* @__PURE__ */ new Date()).toISOString()
10506
- };
10507
- this.decisions.set(artifactId, decisionWithTimestamp);
10667
+ await this.store.saveDecision(decision);
10508
10668
  }
10509
10669
  /**
10510
10670
  * Wait for a decision to be made on an artifact.
@@ -10528,14 +10688,14 @@ var NegotiationRoomClient = class {
10528
10688
  * ```
10529
10689
  */
10530
10690
  async waitForDecision(artifactId, timeoutMs = 3e4, pollIntervalMs = 100) {
10531
- if (!this.proposals.has(artifactId)) {
10691
+ if (!await this.store.hasProposal(artifactId)) {
10532
10692
  throw new NegotiationValidationError(
10533
10693
  `No proposal found for artifact_id '${artifactId}'`
10534
10694
  );
10535
10695
  }
10536
10696
  const startTime = Date.now();
10537
10697
  while (Date.now() - startTime < timeoutMs) {
10538
- const decision = await this.getDecision(artifactId);
10698
+ const decision = await this.store.getDecision(artifactId);
10539
10699
  if (decision !== null) {
10540
10700
  return decision;
10541
10701
  }
@@ -10561,7 +10721,7 @@ var NegotiationRoomClient = class {
10561
10721
  * ```
10562
10722
  */
10563
10723
  async getProposal(artifactId) {
10564
- return this.proposals.get(artifactId) || null;
10724
+ return this.store.getProposal(artifactId);
10565
10725
  }
10566
10726
  /**
10567
10727
  * List all proposals, optionally filtered by negotiation room.
@@ -10576,13 +10736,7 @@ var NegotiationRoomClient = class {
10576
10736
  * ```
10577
10737
  */
10578
10738
  async listProposals(negotiationRoomId) {
10579
- const allProposals = Array.from(this.proposals.values());
10580
- if (negotiationRoomId === void 0) {
10581
- return allProposals;
10582
- }
10583
- return allProposals.filter(
10584
- (p) => p.negotiationRoomId === negotiationRoomId
10585
- );
10739
+ return this.store.listProposals(negotiationRoomId);
10586
10740
  }
10587
10741
  };
10588
10742
  function aggregateVotes(votes) {
@@ -11210,6 +11364,31 @@ var WorkflowClient = class {
11210
11364
  instance.completedAt = (/* @__PURE__ */ new Date()).toISOString();
11211
11365
  }
11212
11366
  }
11367
+ /**
11368
+ * Resume a workflow by marking a node as completed and advancing dependents.
11369
+ *
11370
+ * Implements the ResumeWorkflow RPC (spec §17.7 MUST). Marks the specified
11371
+ * node as COMPLETED, updates workflow data if provided, then transitions
11372
+ * dependent nodes from PENDING to READY when all their dependencies are met.
11373
+ *
11374
+ * @param instanceId - The ID of the workflow instance
11375
+ * @param nodeId - The ID of the node to mark as completed
11376
+ * @param workflowData - Optional updated workflow data (JSON string)
11377
+ * @param metadata - Optional metadata for the resume operation
11378
+ * @returns The updated workflow instance
11379
+ * @throws WorkflowValidationError if the instance or node does not exist
11380
+ */
11381
+ async resumeWorkflow(instanceId, nodeId, workflowData, metadata) {
11382
+ await this.updateNodeState(instanceId, nodeId, 4 /* COMPLETED */);
11383
+ if (workflowData !== void 0) {
11384
+ await this.updateWorkflowData(instanceId, workflowData);
11385
+ }
11386
+ if (metadata) {
11387
+ const instance = this.instances.get(instanceId);
11388
+ Object.assign(instance.metadata, metadata);
11389
+ }
11390
+ return this.getWorkflowStatus(instanceId);
11391
+ }
11213
11392
  /**
11214
11393
  * Update the shared workflow data.
11215
11394
  *
@@ -11231,6 +11410,21 @@ var WorkflowClient = class {
11231
11410
 
11232
11411
  // src/internal/envelope.ts
11233
11412
  import crypto2 from "node:crypto";
11413
+ var MessageType = /* @__PURE__ */ ((MessageType2) => {
11414
+ MessageType2[MessageType2["MESSAGE_TYPE_UNSPECIFIED"] = 0] = "MESSAGE_TYPE_UNSPECIFIED";
11415
+ MessageType2[MessageType2["CONTROL"] = 1] = "CONTROL";
11416
+ MessageType2[MessageType2["DATA"] = 2] = "DATA";
11417
+ MessageType2[MessageType2["HEARTBEAT"] = 3] = "HEARTBEAT";
11418
+ MessageType2[MessageType2["NOTIFICATION"] = 4] = "NOTIFICATION";
11419
+ MessageType2[MessageType2["ACKNOWLEDGEMENT"] = 5] = "ACKNOWLEDGEMENT";
11420
+ MessageType2[MessageType2["HITL_INVOCATION"] = 6] = "HITL_INVOCATION";
11421
+ MessageType2[MessageType2["WORKTREE_CONTROL"] = 7] = "WORKTREE_CONTROL";
11422
+ MessageType2[MessageType2["NEGOTIATION"] = 8] = "NEGOTIATION";
11423
+ MessageType2[MessageType2["TOOL_CALL"] = 9] = "TOOL_CALL";
11424
+ MessageType2[MessageType2["TOOL_RESULT"] = 10] = "TOOL_RESULT";
11425
+ MessageType2[MessageType2["TOOL_ERROR"] = 11] = "TOOL_ERROR";
11426
+ return MessageType2;
11427
+ })(MessageType || {});
11234
11428
  function nowTimestamp(date = /* @__PURE__ */ new Date()) {
11235
11429
  const ms = date.getTime();
11236
11430
  const seconds = Math.floor(ms / 1e3);
@@ -11238,7 +11432,15 @@ function nowTimestamp(date = /* @__PURE__ */ new Date()) {
11238
11432
  return { seconds, nanos };
11239
11433
  }
11240
11434
  function nowHlcStub(date = /* @__PURE__ */ new Date()) {
11241
- return String(date.getTime());
11435
+ const wallUs = date.getTime() * 1e3;
11436
+ let node = "unknown";
11437
+ try {
11438
+ const os = __require("node:os");
11439
+ node = os.hostname() || "unknown";
11440
+ } catch {
11441
+ node = "browser";
11442
+ }
11443
+ return `HLC:${wallUs}:0:${node}`;
11242
11444
  }
11243
11445
  function uuidv42() {
11244
11446
  if (typeof crypto2.randomUUID === "function") {
@@ -11274,7 +11476,12 @@ function buildEnvelope(input) {
11274
11476
  hlc_timestamp,
11275
11477
  // Always set hlc_timestamp (aligns with Python/Rust)
11276
11478
  ttl_ms: input.ttl_ms,
11277
- timestamp: ts
11479
+ timestamp: ts,
11480
+ state: input.state ?? 1,
11481
+ // EnvelopeState.CREATED
11482
+ effective_policy_id: input.effective_policy_id ?? "",
11483
+ audit_proof: input.audit_proof ?? new Uint8Array(0),
11484
+ audit_policy_id: input.audit_policy_id ?? ""
11278
11485
  };
11279
11486
  if (hasPayload) {
11280
11487
  const payload = input.payload instanceof Uint8Array ? input.payload : new Uint8Array(input.payload);
@@ -11288,25 +11495,141 @@ function buildEnvelope(input) {
11288
11495
  }
11289
11496
 
11290
11497
  // src/internal/worktreeState.ts
11498
+ var VALID_WORKTREE_TRANSITIONS = {
11499
+ UNBOUND: ["BOUND_HOME", "BIND_FAILED"],
11500
+ BOUND_HOME: ["SWITCH_PENDING", "UNBOUND"],
11501
+ SWITCH_PENDING: ["BOUND_NON_HOME", "BOUND_HOME"],
11502
+ // approve or reject
11503
+ BOUND_NON_HOME: ["BOUND_HOME", "UNBOUND"],
11504
+ // TTL expired/revoke, or unbind
11505
+ BIND_FAILED: ["UNBOUND", "BOUND_HOME"]
11506
+ // retry reset or successful retry
11507
+ };
11508
+ function isValidWorktreeTransition(from, to) {
11509
+ return VALID_WORKTREE_TRANSITIONS[from]?.includes(to) ?? false;
11510
+ }
11511
+ var WorktreeTransitionError = class extends Error {
11512
+ fromState;
11513
+ toState;
11514
+ constructor(from, to) {
11515
+ super(`Invalid worktree state transition from ${from} to ${to}`);
11516
+ this.name = "WorktreeTransitionError";
11517
+ this.fromState = from;
11518
+ this.toState = to;
11519
+ }
11520
+ };
11291
11521
  var PersistentWorktreeState = class {
11292
11522
  state = "UNBOUND";
11293
11523
  repoId;
11294
11524
  worktreeId;
11525
+ homeRepoId;
11526
+ homeWorktreeId;
11527
+ switchTtlMs;
11528
+ switchTimer;
11529
+ /**
11530
+ * Transition to a new state with validation.
11531
+ * @throws WorktreeTransitionError if transition is invalid
11532
+ */
11533
+ transitionTo(newState) {
11534
+ if (!isValidWorktreeTransition(this.state, newState)) {
11535
+ throw new WorktreeTransitionError(this.state, newState);
11536
+ }
11537
+ this.state = newState;
11538
+ }
11539
+ /**
11540
+ * Bind to a home worktree (UNBOUND -> BOUND_HOME or BIND_FAILED -> BOUND_HOME).
11541
+ */
11295
11542
  bind(repoId, worktreeId) {
11543
+ this.transitionTo("BOUND_HOME");
11296
11544
  this.repoId = repoId;
11297
11545
  this.worktreeId = worktreeId;
11298
- this.state = "BOUND_HOME";
11546
+ this.homeRepoId = repoId;
11547
+ this.homeWorktreeId = worktreeId;
11299
11548
  }
11549
+ /**
11550
+ * Handle bind failure (UNBOUND -> BIND_FAILED).
11551
+ */
11552
+ bindFailed() {
11553
+ this.transitionTo("BIND_FAILED");
11554
+ }
11555
+ /**
11556
+ * Unbind from current worktree.
11557
+ */
11300
11558
  unbind() {
11559
+ this.clearSwitchTimer();
11560
+ this.transitionTo("UNBOUND");
11301
11561
  this.repoId = void 0;
11302
11562
  this.worktreeId = void 0;
11303
- this.state = "UNBOUND";
11563
+ }
11564
+ /**
11565
+ * Request switch to a non-home worktree (BOUND_HOME -> SWITCH_PENDING).
11566
+ * Requires approval or rejection before taking effect.
11567
+ */
11568
+ requestSwitch(targetRepoId, targetWorktreeId) {
11569
+ this.transitionTo("SWITCH_PENDING");
11570
+ this._pendingRepoId = targetRepoId;
11571
+ this._pendingWorktreeId = targetWorktreeId;
11572
+ }
11573
+ /**
11574
+ * Approve a pending switch (SWITCH_PENDING -> BOUND_NON_HOME).
11575
+ * @param ttlMs - Time-to-live in milliseconds before auto-reverting to BOUND_HOME
11576
+ */
11577
+ approveSwitch(ttlMs = 3e5) {
11578
+ this.transitionTo("BOUND_NON_HOME");
11579
+ this.repoId = this._pendingRepoId;
11580
+ this.worktreeId = this._pendingWorktreeId;
11581
+ this.switchTtlMs = ttlMs;
11582
+ this.clearSwitchTimer();
11583
+ this.switchTimer = setTimeout(() => {
11584
+ this.revertToHome();
11585
+ }, ttlMs);
11586
+ }
11587
+ /**
11588
+ * Reject a pending switch (SWITCH_PENDING -> BOUND_HOME).
11589
+ */
11590
+ rejectSwitch() {
11591
+ this.transitionTo("BOUND_HOME");
11592
+ this.repoId = this.homeRepoId;
11593
+ this.worktreeId = this.homeWorktreeId;
11594
+ delete this._pendingRepoId;
11595
+ delete this._pendingWorktreeId;
11596
+ }
11597
+ /**
11598
+ * Revert from non-home to home worktree (BOUND_NON_HOME -> BOUND_HOME).
11599
+ * Called on TTL expiry or explicit revoke.
11600
+ */
11601
+ revertToHome() {
11602
+ this.clearSwitchTimer();
11603
+ if (this.state === "BOUND_NON_HOME") {
11604
+ this.transitionTo("BOUND_HOME");
11605
+ this.repoId = this.homeRepoId;
11606
+ this.worktreeId = this.homeWorktreeId;
11607
+ }
11608
+ }
11609
+ /**
11610
+ * Reset from BIND_FAILED to UNBOUND for retry.
11611
+ */
11612
+ resetFromFailed() {
11613
+ this.transitionTo("UNBOUND");
11614
+ }
11615
+ clearSwitchTimer() {
11616
+ if (this.switchTimer) {
11617
+ clearTimeout(this.switchTimer);
11618
+ this.switchTimer = void 0;
11619
+ }
11304
11620
  }
11305
11621
  setState(state) {
11306
11622
  this.state = state;
11307
11623
  }
11308
11624
  current() {
11309
- return { state: this.state, repo_id: this.repoId, worktree_id: this.worktreeId };
11625
+ return {
11626
+ state: this.state,
11627
+ repo_id: this.repoId,
11628
+ worktree_id: this.worktreeId,
11629
+ home_repo_id: this.homeRepoId,
11630
+ home_worktree_id: this.homeWorktreeId,
11631
+ switch_ttl_ms: this.switchTtlMs
11632
+ };
11310
11633
  }
11311
11634
  };
11312
11635
 
@@ -11368,16 +11691,6 @@ var ActivityBuffer = class {
11368
11691
  };
11369
11692
 
11370
11693
  // src/internal/runtime/ackLifecycle.ts
11371
- var AckStage = /* @__PURE__ */ ((AckStage2) => {
11372
- AckStage2[AckStage2["ACK_STAGE_UNSPECIFIED"] = 0] = "ACK_STAGE_UNSPECIFIED";
11373
- AckStage2[AckStage2["RECEIVED"] = 1] = "RECEIVED";
11374
- AckStage2[AckStage2["READ"] = 2] = "READ";
11375
- AckStage2[AckStage2["FULFILLED"] = 3] = "FULFILLED";
11376
- AckStage2[AckStage2["REJECTED"] = 4] = "REJECTED";
11377
- AckStage2[AckStage2["FAILED"] = 5] = "FAILED";
11378
- AckStage2[AckStage2["TIMED_OUT"] = 6] = "TIMED_OUT";
11379
- return AckStage2;
11380
- })(AckStage || {});
11381
11694
  var ACKLifecycleManager = class {
11382
11695
  acks = /* @__PURE__ */ new Map();
11383
11696
  mark(messageId, stage, note, errorCode) {
@@ -11414,21 +11727,6 @@ var ACKLifecycleManager = class {
11414
11727
  };
11415
11728
 
11416
11729
  // src/internal/runtime/messageProcessor.ts
11417
- var MessageType = /* @__PURE__ */ ((MessageType3) => {
11418
- MessageType3[MessageType3["MESSAGE_TYPE_UNSPECIFIED"] = 0] = "MESSAGE_TYPE_UNSPECIFIED";
11419
- MessageType3[MessageType3["CONTROL"] = 1] = "CONTROL";
11420
- MessageType3[MessageType3["DATA"] = 2] = "DATA";
11421
- MessageType3[MessageType3["HEARTBEAT"] = 3] = "HEARTBEAT";
11422
- MessageType3[MessageType3["NOTIFICATION"] = 4] = "NOTIFICATION";
11423
- MessageType3[MessageType3["ACKNOWLEDGEMENT"] = 5] = "ACKNOWLEDGEMENT";
11424
- MessageType3[MessageType3["HITL_INVOCATION"] = 6] = "HITL_INVOCATION";
11425
- MessageType3[MessageType3["WORKTREE_CONTROL"] = 7] = "WORKTREE_CONTROL";
11426
- MessageType3[MessageType3["NEGOTIATION"] = 8] = "NEGOTIATION";
11427
- MessageType3[MessageType3["TOOL_CALL"] = 9] = "TOOL_CALL";
11428
- MessageType3[MessageType3["TOOL_RESULT"] = 10] = "TOOL_RESULT";
11429
- MessageType3[MessageType3["TOOL_ERROR"] = 11] = "TOOL_ERROR";
11430
- return MessageType3;
11431
- })(MessageType || {});
11432
11730
  var MessageProcessor = class {
11433
11731
  handlers = /* @__PURE__ */ new Map();
11434
11732
  defaultHandler;
@@ -12548,7 +12846,7 @@ var AgentState = /* @__PURE__ */ ((AgentState2) => {
12548
12846
  AgentState2[AgentState2["RECOVERING"] = 12] = "RECOVERING";
12549
12847
  return AgentState2;
12550
12848
  })(AgentState || {});
12551
- var StateTransitionError = class extends Error {
12849
+ var StateTransitionError2 = class extends Error {
12552
12850
  fromState;
12553
12851
  toState;
12554
12852
  constructor(fromState, toState) {
@@ -12561,8 +12859,8 @@ var StateTransitionError = class extends Error {
12561
12859
  }
12562
12860
  };
12563
12861
  var VALID_TRANSITIONS = /* @__PURE__ */ new Map([
12564
- // INITIALIZING -> RUNNABLE
12565
- [1 /* INITIALIZING */, /* @__PURE__ */ new Set([2 /* RUNNABLE */])],
12862
+ // INITIALIZING -> RUNNABLE, FAILED (init timeout per spec s8.2)
12863
+ [1 /* INITIALIZING */, /* @__PURE__ */ new Set([2 /* RUNNABLE */, 10 /* FAILED */])],
12566
12864
  // RUNNABLE -> SCHEDULED
12567
12865
  [2 /* RUNNABLE */, /* @__PURE__ */ new Set([3 /* SCHEDULED */])],
12568
12866
  // SCHEDULED -> RUNNING
@@ -12586,8 +12884,8 @@ var VALID_TRANSITIONS = /* @__PURE__ */ new Map([
12586
12884
  6 /* WAITING_RESOURCES */,
12587
12885
  /* @__PURE__ */ new Set([4 /* RUNNING */, 10 /* FAILED */])
12588
12886
  ],
12589
- // SUSPENDED -> RESUMED
12590
- [7 /* SUSPENDED */, /* @__PURE__ */ new Set([8 /* RESUMED */])],
12887
+ // SUSPENDED -> RESUMED, FAILED (suspension timeout per spec s8.3)
12888
+ [7 /* SUSPENDED */, /* @__PURE__ */ new Set([8 /* RESUMED */, 10 /* FAILED */])],
12591
12889
  // RESUMED -> RUNNING
12592
12890
  [8 /* RESUMED */, /* @__PURE__ */ new Set([4 /* RUNNING */])],
12593
12891
  // COMPLETED -> RUNNABLE
@@ -12596,10 +12894,10 @@ var VALID_TRANSITIONS = /* @__PURE__ */ new Map([
12596
12894
  [10 /* FAILED */, /* @__PURE__ */ new Set([12 /* RECOVERING */])],
12597
12895
  // SHUTTING_DOWN -> FAILED (agent_shutdown_timeout)
12598
12896
  [11 /* SHUTTING_DOWN */, /* @__PURE__ */ new Set([10 /* FAILED */])],
12599
- // RECOVERING -> RUNNABLE, SHUTTING_DOWN (recovery abort)
12897
+ // RECOVERING -> RUNNABLE, SHUTTING_DOWN (recovery abort), FAILED (recovery timeout per spec s8.3)
12600
12898
  [
12601
12899
  12 /* RECOVERING */,
12602
- /* @__PURE__ */ new Set([2 /* RUNNABLE */, 11 /* SHUTTING_DOWN */])
12900
+ /* @__PURE__ */ new Set([2 /* RUNNABLE */, 11 /* SHUTTING_DOWN */, 10 /* FAILED */])
12603
12901
  ]
12604
12902
  ]);
12605
12903
  function isValidTransition(fromState, toState) {
@@ -12651,7 +12949,7 @@ var AgentStateMachine = class {
12651
12949
  */
12652
12950
  async initialize() {
12653
12951
  if (this.state !== 0 /* AGENT_STATE_UNSPECIFIED */) {
12654
- throw new StateTransitionError(this.state, 1 /* INITIALIZING */);
12952
+ throw new StateTransitionError2(this.state, 1 /* INITIALIZING */);
12655
12953
  }
12656
12954
  await this.transitionTo(1 /* INITIALIZING */);
12657
12955
  }
@@ -12668,7 +12966,7 @@ var AgentStateMachine = class {
12668
12966
  return;
12669
12967
  }
12670
12968
  if (!isValidTransition(this.state, toState)) {
12671
- throw new StateTransitionError(this.state, toState);
12969
+ throw new StateTransitionError2(this.state, toState);
12672
12970
  }
12673
12971
  await this.doTransition(toState, context);
12674
12972
  }
@@ -12832,7 +13130,8 @@ function computeIdempotencyToken(input) {
12832
13130
  h.update(input.operation);
12833
13131
  h.update("\n");
12834
13132
  h.update(Buffer.from(input.canonical_bytes));
12835
- return `v1:${h.digest("hex")}`;
13133
+ const hash16 = h.digest("hex").slice(0, 16);
13134
+ return `${input.producer_id}:${input.operation}:${hash16}`;
12836
13135
  }
12837
13136
 
12838
13137
  // src/runtime/persistenceAdapter.ts
@@ -12949,6 +13248,669 @@ function normalizeReportPaths(report) {
12949
13248
  return report;
12950
13249
  }
12951
13250
 
13251
+ // src/constants/index.ts
13252
+ var CommunicationClass = /* @__PURE__ */ ((CommunicationClass2) => {
13253
+ CommunicationClass2[CommunicationClass2["COMM_CLASS_UNSPECIFIED"] = 0] = "COMM_CLASS_UNSPECIFIED";
13254
+ CommunicationClass2[CommunicationClass2["PRIVILEGED"] = 1] = "PRIVILEGED";
13255
+ CommunicationClass2[CommunicationClass2["STANDARD"] = 2] = "STANDARD";
13256
+ CommunicationClass2[CommunicationClass2["BULK"] = 3] = "BULK";
13257
+ return CommunicationClass2;
13258
+ })(CommunicationClass || {});
13259
+ var DebateIntensity = /* @__PURE__ */ ((DebateIntensity2) => {
13260
+ DebateIntensity2[DebateIntensity2["DEBATE_INTENSITY_UNSPECIFIED"] = 0] = "DEBATE_INTENSITY_UNSPECIFIED";
13261
+ DebateIntensity2[DebateIntensity2["LOWEST"] = 1] = "LOWEST";
13262
+ DebateIntensity2[DebateIntensity2["LOW"] = 2] = "LOW";
13263
+ DebateIntensity2[DebateIntensity2["MEDIUM"] = 3] = "MEDIUM";
13264
+ DebateIntensity2[DebateIntensity2["HIGH"] = 4] = "HIGH";
13265
+ DebateIntensity2[DebateIntensity2["HIGHEST"] = 5] = "HIGHEST";
13266
+ return DebateIntensity2;
13267
+ })(DebateIntensity || {});
13268
+ var HitlReasonType = /* @__PURE__ */ ((HitlReasonType2) => {
13269
+ HitlReasonType2[HitlReasonType2["HITL_REASON_UNSPECIFIED"] = 0] = "HITL_REASON_UNSPECIFIED";
13270
+ HitlReasonType2[HitlReasonType2["CONFLICT"] = 1] = "CONFLICT";
13271
+ HitlReasonType2[HitlReasonType2["SECURITY_APPROVAL"] = 2] = "SECURITY_APPROVAL";
13272
+ HitlReasonType2[HitlReasonType2["TASK_ESCALATION"] = 3] = "TASK_ESCALATION";
13273
+ HitlReasonType2[HitlReasonType2["MANUAL_OVERRIDE"] = 4] = "MANUAL_OVERRIDE";
13274
+ HitlReasonType2[HitlReasonType2["WORKTREE_OVERRIDE"] = 5] = "WORKTREE_OVERRIDE";
13275
+ HitlReasonType2[HitlReasonType2["DEBATE_DEADLOCK"] = 6] = "DEBATE_DEADLOCK";
13276
+ HitlReasonType2[HitlReasonType2["TOOL_PRIVILEGE_ESCALATION"] = 7] = "TOOL_PRIVILEGE_ESCALATION";
13277
+ HitlReasonType2[HitlReasonType2["CONNECTOR_APPROVAL"] = 8] = "CONNECTOR_APPROVAL";
13278
+ return HitlReasonType2;
13279
+ })(HitlReasonType || {});
13280
+ var AckStage2 = /* @__PURE__ */ ((AckStage3) => {
13281
+ AckStage3[AckStage3["ACK_STAGE_UNSPECIFIED"] = 0] = "ACK_STAGE_UNSPECIFIED";
13282
+ AckStage3[AckStage3["RECEIVED"] = 1] = "RECEIVED";
13283
+ AckStage3[AckStage3["READ"] = 2] = "READ";
13284
+ AckStage3[AckStage3["FULFILLED"] = 3] = "FULFILLED";
13285
+ AckStage3[AckStage3["REJECTED"] = 4] = "REJECTED";
13286
+ AckStage3[AckStage3["FAILED"] = 5] = "FAILED";
13287
+ AckStage3[AckStage3["TIMED_OUT"] = 6] = "TIMED_OUT";
13288
+ return AckStage3;
13289
+ })(AckStage2 || {});
13290
+ var EnvelopeState = /* @__PURE__ */ ((EnvelopeState3) => {
13291
+ EnvelopeState3[EnvelopeState3["ENVELOPE_STATE_UNSPECIFIED"] = 0] = "ENVELOPE_STATE_UNSPECIFIED";
13292
+ EnvelopeState3[EnvelopeState3["SENT"] = 1] = "SENT";
13293
+ EnvelopeState3[EnvelopeState3["RECEIVED"] = 2] = "RECEIVED";
13294
+ EnvelopeState3[EnvelopeState3["READ"] = 3] = "READ";
13295
+ EnvelopeState3[EnvelopeState3["FULFILLED"] = 4] = "FULFILLED";
13296
+ EnvelopeState3[EnvelopeState3["REJECTED"] = 5] = "REJECTED";
13297
+ EnvelopeState3[EnvelopeState3["FAILED"] = 6] = "FAILED";
13298
+ EnvelopeState3[EnvelopeState3["TIMED_OUT"] = 7] = "TIMED_OUT";
13299
+ return EnvelopeState3;
13300
+ })(EnvelopeState || {});
13301
+ var WorktreeStateEnum = /* @__PURE__ */ ((WorktreeStateEnum2) => {
13302
+ WorktreeStateEnum2[WorktreeStateEnum2["WORKTREE_STATE_UNSPECIFIED"] = 0] = "WORKTREE_STATE_UNSPECIFIED";
13303
+ WorktreeStateEnum2[WorktreeStateEnum2["UNBOUND"] = 1] = "UNBOUND";
13304
+ WorktreeStateEnum2[WorktreeStateEnum2["BOUND_HOME"] = 2] = "BOUND_HOME";
13305
+ WorktreeStateEnum2[WorktreeStateEnum2["SWITCH_PENDING"] = 3] = "SWITCH_PENDING";
13306
+ WorktreeStateEnum2[WorktreeStateEnum2["BOUND_NON_HOME"] = 4] = "BOUND_NON_HOME";
13307
+ WorktreeStateEnum2[WorktreeStateEnum2["BIND_FAILED"] = 5] = "BIND_FAILED";
13308
+ return WorktreeStateEnum2;
13309
+ })(WorktreeStateEnum || {});
13310
+ var DEFAULT_ACK_TIMEOUT_MS = 1e4;
13311
+ var DEDUP_WINDOW_S = 3600;
13312
+ function isTerminalEnvelopeState(state) {
13313
+ return state === 4 /* FULFILLED */ || state === 5 /* REJECTED */ || state === 6 /* FAILED */ || state === 7 /* TIMED_OUT */;
13314
+ }
13315
+ function updateEnvelopeState(envelope, newState) {
13316
+ envelope.state = newState;
13317
+ return envelope;
13318
+ }
13319
+
13320
+ // src/audit.ts
13321
+ import crypto4 from "node:crypto";
13322
+ function uuidv43() {
13323
+ if (typeof crypto4.randomUUID === "function") {
13324
+ return crypto4.randomUUID();
13325
+ }
13326
+ const buf = crypto4.randomBytes(16);
13327
+ buf[6] = buf[6] & 15 | 64;
13328
+ buf[8] = buf[8] & 63 | 128;
13329
+ const hex = [...buf].map((b) => b.toString(16).padStart(2, "0"));
13330
+ 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("");
13331
+ }
13332
+ function computeEnvelopeHash(envelope) {
13333
+ const envelopeCopy = { ...envelope };
13334
+ const payload = envelopeCopy.payload;
13335
+ const audit_proof = envelopeCopy.audit_proof;
13336
+ delete envelopeCopy.payload;
13337
+ delete envelopeCopy.audit_proof;
13338
+ const envelopeJson = JSON.stringify(envelopeCopy, Object.keys(envelopeCopy).sort());
13339
+ const hasher = crypto4.createHash("sha256");
13340
+ hasher.update(envelopeJson, "utf-8");
13341
+ if (payload) {
13342
+ if (payload instanceof Uint8Array) {
13343
+ hasher.update(payload);
13344
+ } else if (typeof payload === "string") {
13345
+ hasher.update(payload, "utf-8");
13346
+ }
13347
+ }
13348
+ if (audit_proof) {
13349
+ if (audit_proof instanceof Uint8Array) {
13350
+ hasher.update(audit_proof);
13351
+ } else if (typeof audit_proof === "string") {
13352
+ hasher.update(audit_proof, "utf-8");
13353
+ }
13354
+ }
13355
+ return hasher.digest("hex");
13356
+ }
13357
+ function createSimpleProof(envelope, actor_id) {
13358
+ const envelopeHash = computeEnvelopeHash(envelope);
13359
+ const timestamp = nowHlcStub();
13360
+ const proofInput = `${envelopeHash}:${actor_id}:${timestamp}`;
13361
+ const proofHash = crypto4.createHash("sha256").update(proofInput, "utf-8").digest();
13362
+ return {
13363
+ proof_id: uuidv43(),
13364
+ proof_type: "simple_hash",
13365
+ proof_data: new Uint8Array(proofHash),
13366
+ created_at: timestamp,
13367
+ verified: false
13368
+ };
13369
+ }
13370
+ function verifyAuditProof(envelope, proof) {
13371
+ if (proof.proof_type === "noop") {
13372
+ return true;
13373
+ }
13374
+ if (proof.proof_type === "simple_hash") {
13375
+ if (proof.proof_data.length === 0) {
13376
+ return false;
13377
+ }
13378
+ const envelopeHash = computeEnvelopeHash(envelope);
13379
+ if (proof.proof_data.length !== 32) {
13380
+ return false;
13381
+ }
13382
+ return true;
13383
+ }
13384
+ return false;
13385
+ }
13386
+ var NoOpAuditor = class {
13387
+ /**
13388
+ * Create a minimal no-op proof.
13389
+ *
13390
+ * @param envelope - The envelope (ignored)
13391
+ * @param action - The action (ignored)
13392
+ * @returns A minimal no-op proof
13393
+ */
13394
+ createProof(envelope, action) {
13395
+ return {
13396
+ proof_id: uuidv43(),
13397
+ proof_type: "noop",
13398
+ proof_data: new Uint8Array(0),
13399
+ created_at: nowHlcStub(),
13400
+ verified: true
13401
+ };
13402
+ }
13403
+ /**
13404
+ * Always returns true for no-op proofs.
13405
+ *
13406
+ * @param proof - The proof (ignored)
13407
+ * @returns Always true
13408
+ */
13409
+ verifyProof(proof) {
13410
+ return true;
13411
+ }
13412
+ /**
13413
+ * Create a minimal audit record without storing it.
13414
+ *
13415
+ * @param envelope - The envelope being audited
13416
+ * @param action - The action being performed
13417
+ * @param proof - Optional proof to attach
13418
+ * @returns A minimal audit record
13419
+ */
13420
+ record(envelope, action, proof) {
13421
+ return {
13422
+ record_id: uuidv43(),
13423
+ envelope_id: envelope.message_id ?? "unknown",
13424
+ action,
13425
+ actor_id: envelope.producer_id ?? "unknown",
13426
+ timestamp: nowHlcStub(),
13427
+ proof
13428
+ };
13429
+ }
13430
+ /**
13431
+ * Always returns empty array.
13432
+ *
13433
+ * @param envelope_id - The envelope ID (ignored)
13434
+ * @returns Empty array
13435
+ */
13436
+ query(envelope_id) {
13437
+ return [];
13438
+ }
13439
+ };
13440
+ var InMemoryAuditor = class {
13441
+ _records;
13442
+ /**
13443
+ * Initialize with empty record storage.
13444
+ */
13445
+ constructor() {
13446
+ this._records = /* @__PURE__ */ new Map();
13447
+ }
13448
+ /**
13449
+ * Create a simple hash-based proof.
13450
+ *
13451
+ * @param envelope - The envelope to create proof for
13452
+ * @param action - The action being performed
13453
+ * @returns A simple hash-based proof
13454
+ */
13455
+ createProof(envelope, action) {
13456
+ return createSimpleProof(envelope, envelope.producer_id ?? "unknown");
13457
+ }
13458
+ /**
13459
+ * Verify a proof using the verification module.
13460
+ *
13461
+ * @param proof - The proof to verify
13462
+ * @returns True if proof is valid, false otherwise
13463
+ */
13464
+ verifyProof(proof) {
13465
+ if (proof.proof_type === "noop") {
13466
+ return true;
13467
+ }
13468
+ if (proof.proof_type === "simple_hash") {
13469
+ return proof.proof_data.length > 0;
13470
+ }
13471
+ return false;
13472
+ }
13473
+ /**
13474
+ * Create and store an audit record.
13475
+ *
13476
+ * @param envelope - The envelope being audited
13477
+ * @param action - The action being performed
13478
+ * @param proof - Optional proof to attach
13479
+ * @returns The created audit record
13480
+ */
13481
+ record(envelope, action, proof) {
13482
+ const record = {
13483
+ record_id: uuidv43(),
13484
+ envelope_id: envelope.message_id ?? "unknown",
13485
+ action,
13486
+ actor_id: envelope.producer_id ?? "unknown",
13487
+ timestamp: nowHlcStub(),
13488
+ proof
13489
+ };
13490
+ const envelope_id = record.envelope_id;
13491
+ if (!this._records.has(envelope_id)) {
13492
+ this._records.set(envelope_id, []);
13493
+ }
13494
+ this._records.get(envelope_id).push(record);
13495
+ return record;
13496
+ }
13497
+ /**
13498
+ * Query all audit records for a specific envelope.
13499
+ *
13500
+ * @param envelope_id - The message_id of the envelope to query
13501
+ * @returns List of audit records for this envelope
13502
+ */
13503
+ query(envelope_id) {
13504
+ return this._records.get(envelope_id) ?? [];
13505
+ }
13506
+ /**
13507
+ * Get all audit records (useful for testing).
13508
+ *
13509
+ * @returns All audit records across all envelopes
13510
+ */
13511
+ getAllRecords() {
13512
+ const allRecords = [];
13513
+ for (const records of this._records.values()) {
13514
+ allRecords.push(...records);
13515
+ }
13516
+ return allRecords;
13517
+ }
13518
+ /**
13519
+ * Clear all stored records (useful for testing).
13520
+ */
13521
+ clear() {
13522
+ this._records.clear();
13523
+ }
13524
+ };
13525
+
13526
+ // src/agentConfig.ts
13527
+ import * as fs2 from "fs";
13528
+ import * as path4 from "path";
13529
+ function defaultEndpoints() {
13530
+ return {
13531
+ router: process.env.SW4RM_ROUTER_ADDR || "http://localhost:50051",
13532
+ registry: process.env.SW4RM_REGISTRY_ADDR || "http://localhost:50052",
13533
+ scheduler: process.env.SW4RM_SCHEDULER_ADDR || "http://localhost:50053",
13534
+ hitl: process.env.SW4RM_HITL_ADDR || "http://localhost:50054",
13535
+ worktree: process.env.SW4RM_WORKTREE_ADDR || "http://localhost:50055",
13536
+ tool: process.env.SW4RM_TOOL_ADDR || "http://localhost:50056",
13537
+ connector: process.env.SW4RM_CONNECTOR_ADDR || "http://localhost:50057",
13538
+ negotiation: process.env.SW4RM_NEGOTIATION_ADDR || "http://localhost:50058",
13539
+ reasoning: process.env.SW4RM_REASONING_ADDR || "http://localhost:50059",
13540
+ logging: process.env.SW4RM_LOGGING_ADDR || "http://localhost:50060"
13541
+ };
13542
+ }
13543
+ function defaultRetryPolicy() {
13544
+ return {
13545
+ maxAttempts: 3,
13546
+ initialBackoffMs: 200,
13547
+ maxBackoffMs: 2e3,
13548
+ multiplier: 2
13549
+ };
13550
+ }
13551
+ function defaultAgentConfig(agentId = "agent-1", name = "Agent") {
13552
+ return {
13553
+ agentId,
13554
+ name,
13555
+ description: void 0,
13556
+ version: "0.1.0",
13557
+ capabilities: [],
13558
+ endpoints: defaultEndpoints(),
13559
+ timeoutMs: 3e4,
13560
+ streamKeepaliveMs: 6e4,
13561
+ retry: defaultRetryPolicy(),
13562
+ metadata: {},
13563
+ communicationClass: 2,
13564
+ // STANDARD
13565
+ modalitiesSupported: ["application/json"],
13566
+ reasoningConnectors: [],
13567
+ publicKey: void 0
13568
+ };
13569
+ }
13570
+ function loadConfigFromEnv() {
13571
+ const config = defaultAgentConfig();
13572
+ if (process.env.AGENT_ID) {
13573
+ config.agentId = process.env.AGENT_ID;
13574
+ }
13575
+ if (process.env.AGENT_NAME) {
13576
+ config.name = process.env.AGENT_NAME;
13577
+ }
13578
+ if (process.env.AGENT_DESCRIPTION) {
13579
+ config.description = process.env.AGENT_DESCRIPTION;
13580
+ }
13581
+ if (process.env.AGENT_VERSION) {
13582
+ config.version = process.env.AGENT_VERSION;
13583
+ }
13584
+ if (process.env.AGENT_CAPABILITIES) {
13585
+ config.capabilities = process.env.AGENT_CAPABILITIES.split(",").map((s) => s.trim());
13586
+ }
13587
+ if (process.env.SW4RM_TIMEOUT_MS) {
13588
+ const timeout = parseInt(process.env.SW4RM_TIMEOUT_MS, 10);
13589
+ if (!isNaN(timeout)) {
13590
+ config.timeoutMs = timeout;
13591
+ }
13592
+ }
13593
+ if (process.env.SW4RM_STREAM_KEEPALIVE_MS) {
13594
+ const keepalive = parseInt(process.env.SW4RM_STREAM_KEEPALIVE_MS, 10);
13595
+ if (!isNaN(keepalive)) {
13596
+ config.streamKeepaliveMs = keepalive;
13597
+ }
13598
+ }
13599
+ if (process.env.SW4RM_RETRY_MAX_ATTEMPTS) {
13600
+ const attempts = parseInt(process.env.SW4RM_RETRY_MAX_ATTEMPTS, 10);
13601
+ if (!isNaN(attempts)) {
13602
+ config.retry.maxAttempts = attempts;
13603
+ }
13604
+ }
13605
+ if (process.env.SW4RM_COMMUNICATION_CLASS) {
13606
+ const cls = parseInt(process.env.SW4RM_COMMUNICATION_CLASS, 10);
13607
+ if (!isNaN(cls)) {
13608
+ config.communicationClass = cls;
13609
+ }
13610
+ }
13611
+ config.endpoints = defaultEndpoints();
13612
+ return config;
13613
+ }
13614
+ function defaultSW4RMConfig() {
13615
+ return {
13616
+ routerAddr: process.env.SW4RM_ROUTER_ADDR || "http://localhost:50051",
13617
+ registryAddr: process.env.SW4RM_REGISTRY_ADDR || "http://localhost:50052",
13618
+ defaultTimeoutMs: parseInt(process.env.SW4RM_DEFAULT_TIMEOUT_MS || "30000", 10),
13619
+ maxRetries: parseInt(process.env.SW4RM_MAX_RETRIES || "3", 10),
13620
+ enableMetrics: parseBool(process.env.SW4RM_ENABLE_METRICS, true),
13621
+ enableTracing: parseBool(process.env.SW4RM_ENABLE_TRACING, true),
13622
+ logLevel: process.env.SW4RM_LOG_LEVEL || "INFO",
13623
+ featureFlags: {}
13624
+ };
13625
+ }
13626
+ function parseBool(value, defaultValue) {
13627
+ if (value === void 0) {
13628
+ return defaultValue;
13629
+ }
13630
+ return ["true", "1", "yes", "on"].includes(value.toLowerCase());
13631
+ }
13632
+ function loadConfig(configPath) {
13633
+ let config = defaultSW4RMConfig();
13634
+ if (configPath) {
13635
+ if (!fs2.existsSync(configPath)) {
13636
+ throw new Error(`Configuration file not found: ${configPath}`);
13637
+ }
13638
+ const ext = path4.extname(configPath).toLowerCase();
13639
+ if (ext !== ".json") {
13640
+ throw new Error(
13641
+ `Unsupported configuration file format: ${ext}. Supported formats: .json`
13642
+ );
13643
+ }
13644
+ const fileContent = fs2.readFileSync(configPath, "utf8");
13645
+ const fileConfig = JSON.parse(fileContent);
13646
+ config = { ...config, ...fileConfig };
13647
+ }
13648
+ const envConfig = loadFromEnv();
13649
+ config = { ...config, ...envConfig };
13650
+ return config;
13651
+ }
13652
+ function loadFromEnv() {
13653
+ const envConfig = {};
13654
+ if (process.env.SW4RM_ROUTER_ADDR) {
13655
+ envConfig.routerAddr = process.env.SW4RM_ROUTER_ADDR;
13656
+ }
13657
+ if (process.env.SW4RM_REGISTRY_ADDR) {
13658
+ envConfig.registryAddr = process.env.SW4RM_REGISTRY_ADDR;
13659
+ }
13660
+ if (process.env.SW4RM_DEFAULT_TIMEOUT_MS) {
13661
+ const timeout = parseInt(process.env.SW4RM_DEFAULT_TIMEOUT_MS, 10);
13662
+ if (!isNaN(timeout)) {
13663
+ envConfig.defaultTimeoutMs = timeout;
13664
+ }
13665
+ }
13666
+ if (process.env.SW4RM_MAX_RETRIES) {
13667
+ const retries = parseInt(process.env.SW4RM_MAX_RETRIES, 10);
13668
+ if (!isNaN(retries)) {
13669
+ envConfig.maxRetries = retries;
13670
+ }
13671
+ }
13672
+ if (process.env.SW4RM_ENABLE_METRICS !== void 0) {
13673
+ envConfig.enableMetrics = parseBool(process.env.SW4RM_ENABLE_METRICS, true);
13674
+ }
13675
+ if (process.env.SW4RM_ENABLE_TRACING !== void 0) {
13676
+ envConfig.enableTracing = parseBool(process.env.SW4RM_ENABLE_TRACING, true);
13677
+ }
13678
+ if (process.env.SW4RM_LOG_LEVEL) {
13679
+ envConfig.logLevel = process.env.SW4RM_LOG_LEVEL.toUpperCase();
13680
+ }
13681
+ return envConfig;
13682
+ }
13683
+ var _globalConfig = null;
13684
+ function getConfig() {
13685
+ if (_globalConfig === null) {
13686
+ _globalConfig = loadConfig();
13687
+ }
13688
+ return _globalConfig;
13689
+ }
13690
+ function setConfig(config) {
13691
+ _globalConfig = config;
13692
+ }
13693
+ function resetConfig() {
13694
+ _globalConfig = null;
13695
+ }
13696
+
13697
+ // src/persistentActivityBuffer.ts
13698
+ import { readFileSync as readFileSync2, writeFileSync, existsSync as existsSync2, mkdirSync } from "node:fs";
13699
+ import { dirname } from "node:path";
13700
+ var JSONFilePersistence2 = class {
13701
+ constructor(filePath = "sw4rm_activity.json") {
13702
+ this.filePath = filePath;
13703
+ }
13704
+ load() {
13705
+ if (!existsSync2(this.filePath)) {
13706
+ return { records: {}, order: [] };
13707
+ }
13708
+ const raw = readFileSync2(this.filePath, "utf-8");
13709
+ const data = JSON.parse(raw);
13710
+ return {
13711
+ records: data.records ?? {},
13712
+ order: data.order ?? []
13713
+ };
13714
+ }
13715
+ save(records, order) {
13716
+ const dir = dirname(this.filePath);
13717
+ if (dir && !existsSync2(dir)) {
13718
+ mkdirSync(dir, { recursive: true });
13719
+ }
13720
+ writeFileSync(this.filePath, JSON.stringify({ records, order, version: "1.0" }, null, 2));
13721
+ }
13722
+ clear() {
13723
+ if (existsSync2(this.filePath)) {
13724
+ writeFileSync(this.filePath, JSON.stringify({ records: {}, order: [], version: "1.0" }));
13725
+ }
13726
+ }
13727
+ };
13728
+ var PersistentActivityBuffer = class {
13729
+ byId = /* @__PURE__ */ new Map();
13730
+ byIdempotencyToken = /* @__PURE__ */ new Map();
13731
+ // token -> message_id
13732
+ order = [];
13733
+ maxItems;
13734
+ persistence;
13735
+ dedupWindowS;
13736
+ dirty = false;
13737
+ constructor(opts) {
13738
+ this.maxItems = opts?.maxItems ?? 1e4;
13739
+ this.persistence = opts?.persistence ?? new JSONFilePersistence2();
13740
+ this.dedupWindowS = opts?.dedupWindowS ?? 3600;
13741
+ this.loadFromPersistence();
13742
+ }
13743
+ loadFromPersistence() {
13744
+ try {
13745
+ const { records, order } = this.persistence.load();
13746
+ this.byId = new Map(Object.entries(records));
13747
+ this.order = order;
13748
+ for (const [mid, rec] of this.byId) {
13749
+ const token = rec.envelope?.idempotency_token;
13750
+ if (token) {
13751
+ this.byIdempotencyToken.set(token, mid);
13752
+ }
13753
+ }
13754
+ } catch {
13755
+ this.byId = /* @__PURE__ */ new Map();
13756
+ this.byIdempotencyToken = /* @__PURE__ */ new Map();
13757
+ this.order = [];
13758
+ }
13759
+ }
13760
+ saveToPersistence() {
13761
+ if (!this.dirty)
13762
+ return;
13763
+ try {
13764
+ const records = {};
13765
+ for (const [k, v] of this.byId) {
13766
+ records[k] = v;
13767
+ }
13768
+ this.persistence.save(records, this.order);
13769
+ this.dirty = false;
13770
+ } catch {
13771
+ }
13772
+ }
13773
+ checkCapacity() {
13774
+ if (this.byId.size >= this.maxItems) {
13775
+ throw new BufferFullError(
13776
+ `Activity buffer is full (max ${this.maxItems} items). Reject per spec.`,
13777
+ 1 /* BUFFER_FULL */
13778
+ );
13779
+ }
13780
+ }
13781
+ cleanupExpiredDedupEntries() {
13782
+ const nowMs = Date.now();
13783
+ const windowMs = this.dedupWindowS * 1e3;
13784
+ const expired = [];
13785
+ for (const [token, mid] of this.byIdempotencyToken) {
13786
+ const rec = this.byId.get(mid);
13787
+ if (rec && nowMs - rec.ts_ms > windowMs) {
13788
+ expired.push(token);
13789
+ }
13790
+ }
13791
+ for (const token of expired) {
13792
+ this.byIdempotencyToken.delete(token);
13793
+ }
13794
+ }
13795
+ /**
13796
+ * Record an incoming envelope. Throws BufferFullError if buffer is at capacity.
13797
+ */
13798
+ recordIncoming(envelope) {
13799
+ this.checkCapacity();
13800
+ const mid = String(envelope.message_id ?? "");
13801
+ const rec = {
13802
+ message_id: mid,
13803
+ direction: "in",
13804
+ envelope,
13805
+ ts_ms: Date.now(),
13806
+ ack_stage: 0 /* ACK_STAGE_UNSPECIFIED */,
13807
+ error_code: 0 /* ERROR_CODE_UNSPECIFIED */,
13808
+ ack_note: ""
13809
+ };
13810
+ this.byId.set(mid, rec);
13811
+ this.order.push(mid);
13812
+ const token = envelope.idempotency_token;
13813
+ if (token) {
13814
+ this.byIdempotencyToken.set(token, mid);
13815
+ }
13816
+ this.cleanupExpiredDedupEntries();
13817
+ this.dirty = true;
13818
+ return rec;
13819
+ }
13820
+ /**
13821
+ * Record an outgoing envelope. Throws BufferFullError if buffer is at capacity.
13822
+ */
13823
+ recordOutgoing(envelope) {
13824
+ this.checkCapacity();
13825
+ const mid = String(envelope.message_id ?? "");
13826
+ const rec = {
13827
+ message_id: mid,
13828
+ direction: "out",
13829
+ envelope,
13830
+ ts_ms: Date.now(),
13831
+ ack_stage: 0 /* ACK_STAGE_UNSPECIFIED */,
13832
+ error_code: 0 /* ERROR_CODE_UNSPECIFIED */,
13833
+ ack_note: ""
13834
+ };
13835
+ this.byId.set(mid, rec);
13836
+ this.order.push(mid);
13837
+ const token = envelope.idempotency_token;
13838
+ if (token) {
13839
+ this.byIdempotencyToken.set(token, mid);
13840
+ }
13841
+ this.cleanupExpiredDedupEntries();
13842
+ this.dirty = true;
13843
+ return rec;
13844
+ }
13845
+ /**
13846
+ * Process an ACK for a previously recorded message.
13847
+ */
13848
+ ack(ackMsg) {
13849
+ const target = String(ackMsg.ack_for_message_id);
13850
+ const rec = this.byId.get(target);
13851
+ if (rec) {
13852
+ rec.ack_stage = ackMsg.ack_stage ?? 0 /* ACK_STAGE_UNSPECIFIED */;
13853
+ rec.error_code = ackMsg.error_code ?? 0 /* ERROR_CODE_UNSPECIFIED */;
13854
+ rec.ack_note = ackMsg.note ?? "";
13855
+ this.dirty = true;
13856
+ }
13857
+ return rec;
13858
+ }
13859
+ /** Get record by message ID. */
13860
+ get(messageId) {
13861
+ return this.byId.get(messageId);
13862
+ }
13863
+ /** Get record by idempotency token (for deduplication). */
13864
+ getByIdempotencyToken(token) {
13865
+ this.cleanupExpiredDedupEntries();
13866
+ const mid = this.byIdempotencyToken.get(token);
13867
+ if (mid)
13868
+ return this.byId.get(mid);
13869
+ return void 0;
13870
+ }
13871
+ /** Get all un-ACKed records. */
13872
+ unacked() {
13873
+ return [...this.byId.values()].filter(
13874
+ (r) => r.ack_stage === 0 /* ACK_STAGE_UNSPECIFIED */ || r.ack_stage === 1 /* RECEIVED */ || r.ack_stage === 2 /* READ */
13875
+ );
13876
+ }
13877
+ /** Get N most recent records. */
13878
+ recent(n = 50) {
13879
+ const ids = this.order.slice(-n);
13880
+ return ids.map((id) => this.byId.get(id)).filter(Boolean);
13881
+ }
13882
+ /** Update envelope state for a message. */
13883
+ updateState(messageId, newState) {
13884
+ const rec = this.byId.get(messageId);
13885
+ if (rec) {
13886
+ rec.envelope.state = newState;
13887
+ this.dirty = true;
13888
+ }
13889
+ return rec;
13890
+ }
13891
+ /** Return unacked outgoing messages for reconciliation. */
13892
+ reconcile() {
13893
+ return this.unacked().filter((r) => r.direction === "out");
13894
+ }
13895
+ /** Force save to persistence. */
13896
+ flush() {
13897
+ this.dirty = true;
13898
+ this.saveToPersistence();
13899
+ }
13900
+ /** Clear all records. */
13901
+ clear() {
13902
+ this.byId.clear();
13903
+ this.byIdempotencyToken.clear();
13904
+ this.order = [];
13905
+ this.persistence.clear();
13906
+ this.dirty = false;
13907
+ }
13908
+ /** Get the count of records. */
13909
+ get size() {
13910
+ return this.byId.size;
13911
+ }
13912
+ };
13913
+
12952
13914
  // src/secrets/types.ts
12953
13915
  var SecretSource = /* @__PURE__ */ ((SecretSource2) => {
12954
13916
  SecretSource2["CLI"] = "cli";
@@ -13046,8 +14008,8 @@ var Resolver = class {
13046
14008
  };
13047
14009
 
13048
14010
  // src/secrets/backends/file.ts
13049
- import { mkdirSync, readFileSync, renameSync, writeFileSync, existsSync, chmodSync } from "node:fs";
13050
- import { join, dirname } from "node:path";
14011
+ import { mkdirSync as mkdirSync2, readFileSync as readFileSync3, renameSync, writeFileSync as writeFileSync2, existsSync as existsSync3, chmodSync } from "node:fs";
14012
+ import { join, dirname as dirname2 } from "node:path";
13051
14013
  function defaultPath() {
13052
14014
  const isWin = process.platform === "win32";
13053
14015
  if (isWin) {
@@ -13060,14 +14022,14 @@ function defaultPath() {
13060
14022
  }
13061
14023
  var FileBackend = class {
13062
14024
  path;
13063
- constructor(path4) {
13064
- this.path = path4 ?? defaultPath();
13065
- mkdirSync(dirname(this.path), { recursive: true });
14025
+ constructor(path5) {
14026
+ this.path = path5 ?? defaultPath();
14027
+ mkdirSync2(dirname2(this.path), { recursive: true });
13066
14028
  try {
13067
- chmodSync(dirname(this.path), 448);
14029
+ chmodSync(dirname2(this.path), 448);
13068
14030
  } catch {
13069
14031
  }
13070
- if (!existsSync(this.path)) {
14032
+ if (!existsSync3(this.path)) {
13071
14033
  this.safeWrite({});
13072
14034
  this.enforceFilePerms();
13073
14035
  } else {
@@ -13084,9 +14046,9 @@ var FileBackend = class {
13084
14046
  }
13085
14047
  }
13086
14048
  safeWrite(obj) {
13087
- const tmp = join(dirname(this.path), `.secrets.${Date.now()}.${Math.random().toString(16).slice(2)}`);
14049
+ const tmp = join(dirname2(this.path), `.secrets.${Date.now()}.${Math.random().toString(16).slice(2)}`);
13088
14050
  try {
13089
- writeFileSync(tmp, JSON.stringify(obj, null, 2), { encoding: "utf8", mode: 384 });
14051
+ writeFileSync2(tmp, JSON.stringify(obj, null, 2), { encoding: "utf8", mode: 384 });
13090
14052
  renameSync(tmp, this.path);
13091
14053
  this.enforceFilePerms();
13092
14054
  } catch (e) {
@@ -13095,7 +14057,7 @@ var FileBackend = class {
13095
14057
  }
13096
14058
  load() {
13097
14059
  try {
13098
- const s = readFileSync(this.path, { encoding: "utf8" });
14060
+ const s = readFileSync3(this.path, { encoding: "utf8" });
13099
14061
  return JSON.parse(s);
13100
14062
  } catch (e) {
13101
14063
  if (e.code === "ENOENT")
@@ -13192,10 +14154,10 @@ async function selectBackend(mode) {
13192
14154
  }
13193
14155
 
13194
14156
  // src/index.ts
13195
- var version = "0.4.0";
14157
+ var version = "0.5.0";
13196
14158
  export {
13197
14159
  ACKLifecycleManager,
13198
- AckStage,
14160
+ AckStage2 as AckStage,
13199
14161
  ActivityBuffer,
13200
14162
  ActivityBufferSync,
13201
14163
  ActivityClient,
@@ -13204,15 +14166,22 @@ export {
13204
14166
  ArtifactType,
13205
14167
  BaseClient,
13206
14168
  BordaCountAggregator,
14169
+ BufferFullError,
13207
14170
  CT_AGENT_REPORT_V1,
13208
14171
  CT_SCHEDULER_COMMAND_V1,
14172
+ CommunicationClass,
13209
14173
  ConfidenceWeightedAggregator,
13210
14174
  ConnectorClient,
14175
+ DEDUP_WINDOW_S,
14176
+ DEFAULT_ACK_TIMEOUT_MS,
13211
14177
  DEFAULT_ESCALATION_POLICY,
13212
14178
  DEFAULT_EXECUTION_POLICY,
13213
14179
  DEFAULT_NEGOTIATION_POLICY,
14180
+ DebateIntensity,
13214
14181
  DecisionOutcome,
13215
14182
  DefaultWorktreePolicy,
14183
+ DuplicateDetectedError,
14184
+ EnvelopeState,
13216
14185
  ErrorCode,
13217
14186
  ErrorCodeMapper,
13218
14187
  FileBackend,
@@ -13222,6 +14191,9 @@ export {
13222
14191
  HandoffTimeoutError,
13223
14192
  HandoffValidationError,
13224
14193
  HitlMode,
14194
+ HitlReasonType,
14195
+ InMemoryAuditor,
14196
+ InMemoryNegotiationRoomStore,
13225
14197
  InMemoryPolicyStore,
13226
14198
  InterceptorChain,
13227
14199
  JSONFilePersistence,
@@ -13233,15 +14205,23 @@ export {
13233
14205
  MessageProcessor,
13234
14206
  MessageType,
13235
14207
  NegotiationClient,
14208
+ NegotiationError,
13236
14209
  NegotiationRoomClient,
14210
+ NegotiationRoomStoreError,
13237
14211
  NegotiationTimeoutError,
13238
14212
  NegotiationValidationError,
14213
+ NoOpAuditor,
13239
14214
  NodeStatus,
14215
+ PermissionError,
14216
+ PersistentActivityBuffer,
13240
14217
  PersistentWorktreeState,
13241
14218
  PolicyStoreError,
14219
+ PolicyViolationError,
14220
+ PreemptionError,
13242
14221
  ReasoningClient,
13243
14222
  RegistryClient,
13244
14223
  Resolver,
14224
+ RouteError,
13245
14225
  RouterClient,
13246
14226
  RuntimePersistence,
13247
14227
  SchedulerClient,
@@ -13259,35 +14239,57 @@ export {
13259
14239
  SimpleAverageAggregator,
13260
14240
  StateTransitionError,
13261
14241
  Sw4rmError,
14242
+ TimeoutError,
13262
14243
  ToolClient,
13263
14244
  TriggerType,
14245
+ ValidationError,
13264
14246
  VotingAnalyzer,
13265
14247
  WorkflowClient,
13266
14248
  WorkflowCycleError,
13267
14249
  WorkflowStatus,
13268
14250
  WorkflowValidationError,
13269
14251
  WorktreeClient,
14252
+ WorktreeError,
14253
+ WorktreeStateEnum,
14254
+ WorktreeTransitionError,
13270
14255
  aggregateVotes,
13271
14256
  buildAckEnvelope,
13272
14257
  buildEnvelope,
14258
+ computeEnvelopeHash,
13273
14259
  computeIdempotencyToken,
13274
14260
  createResilientIncomingStream,
14261
+ createSimpleProof,
13275
14262
  decodeAgentReportV1,
13276
14263
  decodeBase64,
14264
+ defaultAgentConfig,
14265
+ defaultEndpoints,
14266
+ defaultRetryPolicy,
14267
+ defaultSW4RMConfig,
13277
14268
  durationToMs,
13278
14269
  encodeSchedulerCommandV1,
14270
+ getConfig,
14271
+ getDefaultStore,
13279
14272
  getValidTransitions,
14273
+ isTerminalEnvelopeState,
13280
14274
  isValidTransition,
14275
+ isValidWorktreeTransition,
14276
+ loadConfig,
14277
+ loadConfigFromEnv,
13281
14278
  loggingInterceptor,
13282
14279
  mapGrpcStatusToErrorCode,
13283
14280
  msToDuration,
13284
14281
  normalizeReportPaths,
13285
14282
  nowTimestamp,
13286
14283
  parseNegotiationEvent,
14284
+ resetConfig,
14285
+ resetDefaultStore,
13287
14286
  selectBackend,
13288
14287
  sendMessageWithAck,
14288
+ setConfig,
13289
14289
  timingInterceptor,
14290
+ updateEnvelopeState,
13290
14291
  uuidv4,
14292
+ verifyAuditProof,
13291
14293
  version
13292
14294
  };
13293
14295
  /*! Bundled license information: