opencode-plugin-flow 5.3.2 → 5.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -11423,6 +11423,7 @@ var REGISTRY_FORMAT_VERSION = 1;
11423
11423
  var MAX_PACKAGE_NAME_LENGTH = 214;
11424
11424
  var MAX_VERSION_LENGTH = 256;
11425
11425
  var MAX_INSTANCE_ID_LENGTH = 128;
11426
+ var MAX_SCOPE_ID_LENGTH = 32768;
11426
11427
  var FLOW_LEADERSHIP_PROTOCOL_VERSION = 1;
11427
11428
  var FLOW_LEADERSHIP_MAX_INSTANCES = 32;
11428
11429
  var FLOW_LEADERSHIP_REGISTRY_SYMBOL = Symbol.for(REGISTRY_KIND);
@@ -11534,6 +11535,11 @@ function validateIdentity(identity) {
11534
11535
  throw new TypeError("Flow leadership protocol version must be a positive safe integer.");
11535
11536
  }
11536
11537
  }
11538
+ function validateScopeId(scopeId) {
11539
+ if (scopeId.length === 0 || scopeId.length > MAX_SCOPE_ID_LENGTH || scopeId.includes("\x00")) {
11540
+ throw new TypeError(`Flow leadership scope ID must be a non-empty string without null bytes and at most ${MAX_SCOPE_ID_LENGTH} characters.`);
11541
+ }
11542
+ }
11537
11543
  function snapshotIdentity(identity) {
11538
11544
  return Object.freeze({
11539
11545
  packageName: identity.packageName,
@@ -11542,19 +11548,29 @@ function snapshotIdentity(identity) {
11542
11548
  instanceId: identity.instanceId
11543
11549
  });
11544
11550
  }
11551
+ function scopedRegistration(identity, scopeId) {
11552
+ return Object.freeze({ ...identity, scopeId });
11553
+ }
11545
11554
  function isRegisteredFlowInstance(value) {
11546
11555
  if (typeof value !== "object" || value === null)
11547
11556
  return false;
11548
11557
  const candidate = value;
11549
- return typeof candidate.packageName === "string" && candidate.packageName.length > 0 && candidate.packageName.length <= MAX_PACKAGE_NAME_LENGTH && candidate.packageName.trim() === candidate.packageName && typeof candidate.version === "string" && parseSemanticVersion(candidate.version) !== null && typeof candidate.protocolVersion === "number" && Number.isSafeInteger(candidate.protocolVersion) && candidate.protocolVersion >= 1 && typeof candidate.instanceId === "string" && candidate.instanceId.length > 0 && candidate.instanceId.length <= MAX_INSTANCE_ID_LENGTH && candidate.instanceId.trim() === candidate.instanceId;
11558
+ return typeof candidate.packageName === "string" && candidate.packageName.length > 0 && candidate.packageName.length <= MAX_PACKAGE_NAME_LENGTH && candidate.packageName.trim() === candidate.packageName && typeof candidate.version === "string" && parseSemanticVersion(candidate.version) !== null && typeof candidate.protocolVersion === "number" && Number.isSafeInteger(candidate.protocolVersion) && candidate.protocolVersion >= 1 && typeof candidate.instanceId === "string" && candidate.instanceId.length > 0 && candidate.instanceId.length <= MAX_INSTANCE_ID_LENGTH && candidate.instanceId.trim() === candidate.instanceId && (candidate.scopeId === undefined || typeof candidate.scopeId === "string" && candidate.scopeId.length > 0 && candidate.scopeId.length <= MAX_SCOPE_ID_LENGTH && !candidate.scopeId.includes("\x00"));
11550
11559
  }
11551
11560
  function isCompatibleRegistry(value) {
11552
11561
  if (typeof value !== "object" || value === null)
11553
11562
  return false;
11554
11563
  const candidate = value;
11555
- if (candidate.kind !== REGISTRY_KIND || candidate.formatVersion !== REGISTRY_FORMAT_VERSION || !(candidate.registrations instanceof Map) || typeof candidate.capacityExceeded !== "boolean" || candidate.registrations.size > FLOW_LEADERSHIP_MAX_INSTANCES) {
11564
+ if (candidate.kind !== REGISTRY_KIND || candidate.formatVersion !== REGISTRY_FORMAT_VERSION || !(candidate.registrations instanceof Map) || typeof candidate.capacityExceeded !== "boolean" || candidate.capacityExceededScopes !== undefined && !(candidate.capacityExceededScopes instanceof Set)) {
11556
11565
  return false;
11557
11566
  }
11567
+ if (candidate.capacityExceededScopes) {
11568
+ for (const scopeId of candidate.capacityExceededScopes) {
11569
+ if (typeof scopeId !== "string" || scopeId.length === 0 || scopeId.length > MAX_SCOPE_ID_LENGTH || scopeId.includes("\x00")) {
11570
+ return false;
11571
+ }
11572
+ }
11573
+ }
11558
11574
  for (const [instanceId, registration] of candidate.registrations) {
11559
11575
  if (typeof instanceId !== "string" || !isRegisteredFlowInstance(registration) || registration.instanceId !== instanceId) {
11560
11576
  return false;
@@ -11574,7 +11590,8 @@ function createRegistry() {
11574
11590
  kind: REGISTRY_KIND,
11575
11591
  formatVersion: REGISTRY_FORMAT_VERSION,
11576
11592
  registrations: new Map,
11577
- capacityExceeded: false
11593
+ capacityExceeded: false,
11594
+ capacityExceededScopes: new Set
11578
11595
  };
11579
11596
  }
11580
11597
  function acquireRegistry() {
@@ -11640,7 +11657,7 @@ function incompatibleStatus(instanceId) {
11640
11657
  message: "Flow is disabled because the process-global leadership registry is incompatible; its existing value was left untouched."
11641
11658
  });
11642
11659
  }
11643
- function queryRegistryStatus(instanceId, expectedRecord, matchAnyRecord, localReason, released) {
11660
+ function queryRegistryStatus(scopeId, instanceId, expectedRecord, matchAnyRecord, localReason, released) {
11644
11661
  if (released) {
11645
11662
  return freezeStatus({
11646
11663
  instanceId,
@@ -11671,13 +11688,13 @@ function queryRegistryStatus(instanceId, expectedRecord, matchAnyRecord, localRe
11671
11688
  }
11672
11689
  if (!isCompatibleRegistry(value))
11673
11690
  return incompatibleStatus(instanceId);
11674
- const records = [...value.registrations.values()].sort(compareRegistrations);
11691
+ const records = [...value.registrations.values()].filter((registration) => registration.scopeId === undefined || registration.scopeId === scopeId).sort(compareRegistrations);
11675
11692
  const current = value.registrations.get(instanceId);
11676
- const registered = current !== undefined && (matchAnyRecord || current === expectedRecord);
11693
+ const registered = current !== undefined && (current.scopeId === undefined || current.scopeId === scopeId) && (matchAnyRecord || current === expectedRecord);
11677
11694
  const leader = diagnosticLeader(records);
11678
11695
  const registrations = records.map(snapshotIdentity);
11679
11696
  const leaderSnapshot = leader ? snapshotIdentity(leader) : null;
11680
- if (value.capacityExceeded || localReason === "registry-capacity-exceeded") {
11697
+ if (value.capacityExceeded || value.capacityExceededScopes?.has(scopeId) || localReason === "registry-capacity-exceeded") {
11681
11698
  return freezeStatus({
11682
11699
  instanceId,
11683
11700
  registered,
@@ -11687,7 +11704,7 @@ function queryRegistryStatus(instanceId, expectedRecord, matchAnyRecord, localRe
11687
11704
  registeredCount: records.length,
11688
11705
  diagnosticLeader: leaderSnapshot,
11689
11706
  registrations,
11690
- message: `Flow is disabled because the leadership registry exceeded its bounded capacity of ${FLOW_LEADERSHIP_MAX_INSTANCES} instances.`
11707
+ message: `Flow is disabled because this project leadership scope exceeded its bounded capacity of ${FLOW_LEADERSHIP_MAX_INSTANCES} instances.`
11691
11708
  });
11692
11709
  }
11693
11710
  if (!registered || !current) {
@@ -11728,7 +11745,7 @@ function queryRegistryStatus(instanceId, expectedRecord, matchAnyRecord, localRe
11728
11745
  registeredCount: records.length,
11729
11746
  diagnosticLeader: snapshotIdentity(leader),
11730
11747
  registrations,
11731
- message: `Flow is disabled while ${records.length} instances are registered. The deterministic diagnostic leader is ${identityLabel(leader)}.`
11748
+ message: `Flow is disabled while ${records.length} instances are registered in this project context. The deterministic diagnostic leader is ${identityLabel(leader)}.`
11732
11749
  });
11733
11750
  }
11734
11751
  function identitiesMatch(left, right) {
@@ -11743,12 +11760,20 @@ function removeEmptyRegistry(registry) {
11743
11760
  Reflect.deleteProperty(globalThis, FLOW_LEADERSHIP_REGISTRY_SYMBOL);
11744
11761
  } catch {}
11745
11762
  }
11763
+ function clearEmptyScopeCapacity(registry, scopeId) {
11764
+ if ([...registry.registrations.values()].some((registration) => registration.scopeId === scopeId)) {
11765
+ return;
11766
+ }
11767
+ registry.capacityExceededScopes?.delete(scopeId);
11768
+ }
11746
11769
  function createFlowPluginInstanceId() {
11747
11770
  return globalThis.crypto.randomUUID();
11748
11771
  }
11749
- function registerFlowPluginInstance(input) {
11772
+ function registerFlowPluginInstance(scopeId, input) {
11773
+ validateScopeId(scopeId);
11750
11774
  validateIdentity(input);
11751
11775
  const identity = snapshotIdentity(input);
11776
+ const registration = scopedRegistration(identity, scopeId);
11752
11777
  const acquired = acquireRegistry();
11753
11778
  let record = null;
11754
11779
  let localReason = null;
@@ -11757,23 +11782,25 @@ function registerFlowPluginInstance(input) {
11757
11782
  } else {
11758
11783
  const existing = acquired.registry.registrations.get(identity.instanceId);
11759
11784
  if (existing) {
11760
- if (!identitiesMatch(existing, identity)) {
11785
+ if (!identitiesMatch(existing, identity) || existing.scopeId !== scopeId) {
11761
11786
  throw new Error(`Flow leadership instance ID '${identity.instanceId}' is already registered with different identity data.`);
11762
11787
  }
11763
11788
  record = existing;
11764
- } else if (acquired.registry.registrations.size >= FLOW_LEADERSHIP_MAX_INSTANCES) {
11765
- acquired.registry.capacityExceeded = true;
11789
+ } else if ([...acquired.registry.registrations.values()].filter((candidate) => candidate.scopeId === undefined || candidate.scopeId === scopeId).length >= FLOW_LEADERSHIP_MAX_INSTANCES) {
11790
+ acquired.registry.capacityExceededScopes ??= new Set;
11791
+ acquired.registry.capacityExceededScopes.add(scopeId);
11766
11792
  localReason = "registry-capacity-exceeded";
11767
11793
  } else {
11768
- record = identity;
11794
+ record = registration;
11769
11795
  acquired.registry.registrations.set(identity.instanceId, record);
11770
11796
  }
11771
11797
  }
11772
11798
  let released = false;
11773
11799
  return Object.freeze({
11774
11800
  identity,
11801
+ scopeId,
11775
11802
  query() {
11776
- return queryRegistryStatus(identity.instanceId, record, false, localReason, released);
11803
+ return queryRegistryStatus(scopeId, identity.instanceId, record, false, localReason, released);
11777
11804
  },
11778
11805
  isOperational() {
11779
11806
  return this.query().operational;
@@ -11787,11 +11814,14 @@ function registerFlowPluginInstance(input) {
11787
11814
  if (released || !record)
11788
11815
  return false;
11789
11816
  const value = readRegistrySlot();
11790
- if (!isCompatibleRegistry(value) || value.registrations.get(identity.instanceId) !== record) {
11817
+ if (!isCompatibleRegistry(value))
11818
+ return false;
11819
+ if (value.registrations.get(identity.instanceId) !== record) {
11791
11820
  return false;
11792
11821
  }
11793
11822
  value.registrations.delete(identity.instanceId);
11794
11823
  released = true;
11824
+ clearEmptyScopeCapacity(value, scopeId);
11795
11825
  removeEmptyRegistry(value);
11796
11826
  return true;
11797
11827
  }
@@ -14291,7 +14321,7 @@ function guardFlowTools(tools, handle) {
14291
14321
  var FlowPlugin = async (ctx) => {
14292
14322
  const log = createFlowLog(ctx);
14293
14323
  const version = resolveFlowPluginVersion();
14294
- const leadership = registerFlowPluginInstance({
14324
+ const leadership = registerFlowPluginInstance(ctx.directory, {
14295
14325
  packageName: "opencode-plugin-flow",
14296
14326
  version,
14297
14327
  protocolVersion: FLOW_LEADERSHIP_PROTOCOL_VERSION,
@@ -14302,6 +14332,7 @@ var FlowPlugin = async (ctx) => {
14302
14332
  version,
14303
14333
  protocolVersion: FLOW_LEADERSHIP_PROTOCOL_VERSION,
14304
14334
  instanceId: leadership.identity.instanceId,
14335
+ projectDirectory: leadership.scopeId,
14305
14336
  leadershipReason: initialLeadership.reason,
14306
14337
  registeredCount: initialLeadership.registeredCount
14307
14338
  });
@@ -14383,4 +14414,4 @@ export {
14383
14414
  plugin_default as default
14384
14415
  };
14385
14416
 
14386
- //# debugId=D39ED623FE37015764756E2164756E21
14417
+ //# debugId=76FD7162667D6AAB64756E2164756E21