opencode-plugin-flow 5.3.1 → 5.3.3
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/CHANGELOG.md +36 -0
- package/README.md +33 -25
- package/dist/cli.js +729 -62
- package/dist/cli.js.map +6 -5
- package/dist/index.js +49 -18
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
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.
|
|
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
|
|
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.
|
|
11765
|
-
acquired.registry.
|
|
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 =
|
|
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)
|
|
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=
|
|
14417
|
+
//# debugId=76FD7162667D6AAB64756E2164756E21
|