opencode-swarm 6.68.1 → 6.70.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/cli/index.js +424 -89
- package/dist/config/schema.d.ts +2 -0
- package/dist/hooks/delegation-gate.d.ts +11 -0
- package/dist/hooks/guardrails.d.ts +36 -1
- package/dist/index.js +39179 -38344
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -16947,7 +16947,7 @@ var require_signal_exit = __commonJS((exports, module) => {
|
|
|
16947
16947
|
emitter.count -= 1;
|
|
16948
16948
|
};
|
|
16949
16949
|
module.exports.unload = unload;
|
|
16950
|
-
|
|
16950
|
+
emit2 = function emit3(event, code, signal) {
|
|
16951
16951
|
if (emitter.emitted[event]) {
|
|
16952
16952
|
return;
|
|
16953
16953
|
}
|
|
@@ -16963,8 +16963,8 @@ var require_signal_exit = __commonJS((exports, module) => {
|
|
|
16963
16963
|
var listeners = process3.listeners(sig);
|
|
16964
16964
|
if (listeners.length === emitter.count) {
|
|
16965
16965
|
unload();
|
|
16966
|
-
|
|
16967
|
-
|
|
16966
|
+
emit2("exit", null, sig);
|
|
16967
|
+
emit2("afterexit", null, sig);
|
|
16968
16968
|
if (isWin && sig === "SIGHUP") {
|
|
16969
16969
|
sig = "SIGINT";
|
|
16970
16970
|
}
|
|
@@ -17000,8 +17000,8 @@ var require_signal_exit = __commonJS((exports, module) => {
|
|
|
17000
17000
|
return;
|
|
17001
17001
|
}
|
|
17002
17002
|
process3.exitCode = code || 0;
|
|
17003
|
-
|
|
17004
|
-
|
|
17003
|
+
emit2("exit", process3.exitCode, null);
|
|
17004
|
+
emit2("afterexit", process3.exitCode, null);
|
|
17005
17005
|
originalProcessReallyExit.call(process3, process3.exitCode);
|
|
17006
17006
|
};
|
|
17007
17007
|
originalProcessEmit = process3.emit;
|
|
@@ -17011,8 +17011,8 @@ var require_signal_exit = __commonJS((exports, module) => {
|
|
|
17011
17011
|
process3.exitCode = arg;
|
|
17012
17012
|
}
|
|
17013
17013
|
var ret = originalProcessEmit.apply(this, arguments);
|
|
17014
|
-
|
|
17015
|
-
|
|
17014
|
+
emit2("exit", process3.exitCode, null);
|
|
17015
|
+
emit2("afterexit", process3.exitCode, null);
|
|
17016
17016
|
return ret;
|
|
17017
17017
|
} else {
|
|
17018
17018
|
return originalProcessEmit.apply(this, arguments);
|
|
@@ -17025,7 +17025,7 @@ var require_signal_exit = __commonJS((exports, module) => {
|
|
|
17025
17025
|
var EE;
|
|
17026
17026
|
var emitter;
|
|
17027
17027
|
var unload;
|
|
17028
|
-
var
|
|
17028
|
+
var emit2;
|
|
17029
17029
|
var sigListeners;
|
|
17030
17030
|
var loaded;
|
|
17031
17031
|
var load;
|
|
@@ -19205,7 +19205,8 @@ var AgentAuthorityRuleSchema = exports_external.object({
|
|
|
19205
19205
|
});
|
|
19206
19206
|
var AuthorityConfigSchema = exports_external.object({
|
|
19207
19207
|
enabled: exports_external.boolean().default(true),
|
|
19208
|
-
rules: exports_external.record(exports_external.string(), AgentAuthorityRuleSchema).default({})
|
|
19208
|
+
rules: exports_external.record(exports_external.string(), AgentAuthorityRuleSchema).default({}),
|
|
19209
|
+
universal_deny_prefixes: exports_external.array(exports_external.string().min(1)).default([])
|
|
19209
19210
|
});
|
|
19210
19211
|
var CouncilConfigSchema = exports_external.object({
|
|
19211
19212
|
enabled: exports_external.boolean().default(false),
|
|
@@ -19464,6 +19465,416 @@ init_manager2();
|
|
|
19464
19465
|
|
|
19465
19466
|
// src/state.ts
|
|
19466
19467
|
init_plan_schema();
|
|
19468
|
+
|
|
19469
|
+
// src/hooks/delegation-gate.ts
|
|
19470
|
+
init_telemetry();
|
|
19471
|
+
|
|
19472
|
+
// node_modules/quick-lru/index.js
|
|
19473
|
+
class QuickLRU extends Map {
|
|
19474
|
+
#size = 0;
|
|
19475
|
+
#cache = new Map;
|
|
19476
|
+
#oldCache = new Map;
|
|
19477
|
+
#maxSize;
|
|
19478
|
+
#maxAge;
|
|
19479
|
+
#onEviction;
|
|
19480
|
+
constructor(options = {}) {
|
|
19481
|
+
super();
|
|
19482
|
+
if (!(options.maxSize && options.maxSize > 0)) {
|
|
19483
|
+
throw new TypeError("`maxSize` must be a number greater than 0");
|
|
19484
|
+
}
|
|
19485
|
+
if (typeof options.maxAge === "number" && options.maxAge === 0) {
|
|
19486
|
+
throw new TypeError("`maxAge` must be a number greater than 0");
|
|
19487
|
+
}
|
|
19488
|
+
this.#maxSize = options.maxSize;
|
|
19489
|
+
this.#maxAge = options.maxAge || Number.POSITIVE_INFINITY;
|
|
19490
|
+
this.#onEviction = options.onEviction;
|
|
19491
|
+
}
|
|
19492
|
+
get __oldCache() {
|
|
19493
|
+
return this.#oldCache;
|
|
19494
|
+
}
|
|
19495
|
+
#emitEvictions(cache) {
|
|
19496
|
+
if (typeof this.#onEviction !== "function") {
|
|
19497
|
+
return;
|
|
19498
|
+
}
|
|
19499
|
+
for (const [key, item] of cache) {
|
|
19500
|
+
this.#onEviction(key, item.value);
|
|
19501
|
+
}
|
|
19502
|
+
}
|
|
19503
|
+
#deleteIfExpired(key, item) {
|
|
19504
|
+
if (typeof item.expiry === "number" && item.expiry <= Date.now()) {
|
|
19505
|
+
if (typeof this.#onEviction === "function") {
|
|
19506
|
+
this.#onEviction(key, item.value);
|
|
19507
|
+
}
|
|
19508
|
+
return this.delete(key);
|
|
19509
|
+
}
|
|
19510
|
+
return false;
|
|
19511
|
+
}
|
|
19512
|
+
#getOrDeleteIfExpired(key, item) {
|
|
19513
|
+
const deleted = this.#deleteIfExpired(key, item);
|
|
19514
|
+
if (deleted === false) {
|
|
19515
|
+
return item.value;
|
|
19516
|
+
}
|
|
19517
|
+
}
|
|
19518
|
+
#getItemValue(key, item) {
|
|
19519
|
+
return item.expiry ? this.#getOrDeleteIfExpired(key, item) : item.value;
|
|
19520
|
+
}
|
|
19521
|
+
#peek(key, cache) {
|
|
19522
|
+
const item = cache.get(key);
|
|
19523
|
+
return this.#getItemValue(key, item);
|
|
19524
|
+
}
|
|
19525
|
+
#set(key, value) {
|
|
19526
|
+
this.#cache.set(key, value);
|
|
19527
|
+
this.#size++;
|
|
19528
|
+
if (this.#size >= this.#maxSize) {
|
|
19529
|
+
this.#size = 0;
|
|
19530
|
+
this.#emitEvictions(this.#oldCache);
|
|
19531
|
+
this.#oldCache = this.#cache;
|
|
19532
|
+
this.#cache = new Map;
|
|
19533
|
+
}
|
|
19534
|
+
}
|
|
19535
|
+
#moveToRecent(key, item) {
|
|
19536
|
+
this.#oldCache.delete(key);
|
|
19537
|
+
this.#set(key, item);
|
|
19538
|
+
}
|
|
19539
|
+
*#entriesAscending() {
|
|
19540
|
+
for (const item of this.#oldCache) {
|
|
19541
|
+
const [key, value] = item;
|
|
19542
|
+
if (!this.#cache.has(key)) {
|
|
19543
|
+
const deleted = this.#deleteIfExpired(key, value);
|
|
19544
|
+
if (deleted === false) {
|
|
19545
|
+
yield item;
|
|
19546
|
+
}
|
|
19547
|
+
}
|
|
19548
|
+
}
|
|
19549
|
+
for (const item of this.#cache) {
|
|
19550
|
+
const [key, value] = item;
|
|
19551
|
+
const deleted = this.#deleteIfExpired(key, value);
|
|
19552
|
+
if (deleted === false) {
|
|
19553
|
+
yield item;
|
|
19554
|
+
}
|
|
19555
|
+
}
|
|
19556
|
+
}
|
|
19557
|
+
get(key) {
|
|
19558
|
+
if (this.#cache.has(key)) {
|
|
19559
|
+
const item = this.#cache.get(key);
|
|
19560
|
+
return this.#getItemValue(key, item);
|
|
19561
|
+
}
|
|
19562
|
+
if (this.#oldCache.has(key)) {
|
|
19563
|
+
const item = this.#oldCache.get(key);
|
|
19564
|
+
if (this.#deleteIfExpired(key, item) === false) {
|
|
19565
|
+
this.#moveToRecent(key, item);
|
|
19566
|
+
return item.value;
|
|
19567
|
+
}
|
|
19568
|
+
}
|
|
19569
|
+
}
|
|
19570
|
+
set(key, value, { maxAge = this.#maxAge } = {}) {
|
|
19571
|
+
const expiry = typeof maxAge === "number" && maxAge !== Number.POSITIVE_INFINITY ? Date.now() + maxAge : undefined;
|
|
19572
|
+
if (this.#cache.has(key)) {
|
|
19573
|
+
this.#cache.set(key, {
|
|
19574
|
+
value,
|
|
19575
|
+
expiry
|
|
19576
|
+
});
|
|
19577
|
+
} else {
|
|
19578
|
+
this.#set(key, { value, expiry });
|
|
19579
|
+
}
|
|
19580
|
+
return this;
|
|
19581
|
+
}
|
|
19582
|
+
has(key) {
|
|
19583
|
+
if (this.#cache.has(key)) {
|
|
19584
|
+
return !this.#deleteIfExpired(key, this.#cache.get(key));
|
|
19585
|
+
}
|
|
19586
|
+
if (this.#oldCache.has(key)) {
|
|
19587
|
+
return !this.#deleteIfExpired(key, this.#oldCache.get(key));
|
|
19588
|
+
}
|
|
19589
|
+
return false;
|
|
19590
|
+
}
|
|
19591
|
+
peek(key) {
|
|
19592
|
+
if (this.#cache.has(key)) {
|
|
19593
|
+
return this.#peek(key, this.#cache);
|
|
19594
|
+
}
|
|
19595
|
+
if (this.#oldCache.has(key)) {
|
|
19596
|
+
return this.#peek(key, this.#oldCache);
|
|
19597
|
+
}
|
|
19598
|
+
}
|
|
19599
|
+
expiresIn(key) {
|
|
19600
|
+
const item = this.#cache.get(key) ?? this.#oldCache.get(key);
|
|
19601
|
+
if (item) {
|
|
19602
|
+
return item.expiry ? item.expiry - Date.now() : Number.POSITIVE_INFINITY;
|
|
19603
|
+
}
|
|
19604
|
+
}
|
|
19605
|
+
delete(key) {
|
|
19606
|
+
const deleted = this.#cache.delete(key);
|
|
19607
|
+
if (deleted) {
|
|
19608
|
+
this.#size--;
|
|
19609
|
+
}
|
|
19610
|
+
return this.#oldCache.delete(key) || deleted;
|
|
19611
|
+
}
|
|
19612
|
+
clear() {
|
|
19613
|
+
this.#cache.clear();
|
|
19614
|
+
this.#oldCache.clear();
|
|
19615
|
+
this.#size = 0;
|
|
19616
|
+
}
|
|
19617
|
+
resize(newSize) {
|
|
19618
|
+
if (!(newSize && newSize > 0)) {
|
|
19619
|
+
throw new TypeError("`maxSize` must be a number greater than 0");
|
|
19620
|
+
}
|
|
19621
|
+
const items = [...this.#entriesAscending()];
|
|
19622
|
+
const removeCount = items.length - newSize;
|
|
19623
|
+
if (removeCount < 0) {
|
|
19624
|
+
this.#cache = new Map(items);
|
|
19625
|
+
this.#oldCache = new Map;
|
|
19626
|
+
this.#size = items.length;
|
|
19627
|
+
} else {
|
|
19628
|
+
if (removeCount > 0) {
|
|
19629
|
+
this.#emitEvictions(items.slice(0, removeCount));
|
|
19630
|
+
}
|
|
19631
|
+
this.#oldCache = new Map(items.slice(removeCount));
|
|
19632
|
+
this.#cache = new Map;
|
|
19633
|
+
this.#size = 0;
|
|
19634
|
+
}
|
|
19635
|
+
this.#maxSize = newSize;
|
|
19636
|
+
}
|
|
19637
|
+
evict(count = 1) {
|
|
19638
|
+
const requested = Number(count);
|
|
19639
|
+
if (!requested || requested <= 0) {
|
|
19640
|
+
return;
|
|
19641
|
+
}
|
|
19642
|
+
const items = [...this.#entriesAscending()];
|
|
19643
|
+
const evictCount = Math.trunc(Math.min(requested, Math.max(items.length - 1, 0)));
|
|
19644
|
+
if (evictCount <= 0) {
|
|
19645
|
+
return;
|
|
19646
|
+
}
|
|
19647
|
+
this.#emitEvictions(items.slice(0, evictCount));
|
|
19648
|
+
this.#oldCache = new Map(items.slice(evictCount));
|
|
19649
|
+
this.#cache = new Map;
|
|
19650
|
+
this.#size = 0;
|
|
19651
|
+
}
|
|
19652
|
+
*keys() {
|
|
19653
|
+
for (const [key] of this) {
|
|
19654
|
+
yield key;
|
|
19655
|
+
}
|
|
19656
|
+
}
|
|
19657
|
+
*values() {
|
|
19658
|
+
for (const [, value] of this) {
|
|
19659
|
+
yield value;
|
|
19660
|
+
}
|
|
19661
|
+
}
|
|
19662
|
+
*[Symbol.iterator]() {
|
|
19663
|
+
for (const item of this.#cache) {
|
|
19664
|
+
const [key, value] = item;
|
|
19665
|
+
const deleted = this.#deleteIfExpired(key, value);
|
|
19666
|
+
if (deleted === false) {
|
|
19667
|
+
yield [key, value.value];
|
|
19668
|
+
}
|
|
19669
|
+
}
|
|
19670
|
+
for (const item of this.#oldCache) {
|
|
19671
|
+
const [key, value] = item;
|
|
19672
|
+
if (!this.#cache.has(key)) {
|
|
19673
|
+
const deleted = this.#deleteIfExpired(key, value);
|
|
19674
|
+
if (deleted === false) {
|
|
19675
|
+
yield [key, value.value];
|
|
19676
|
+
}
|
|
19677
|
+
}
|
|
19678
|
+
}
|
|
19679
|
+
}
|
|
19680
|
+
*entriesDescending() {
|
|
19681
|
+
let items = [...this.#cache];
|
|
19682
|
+
for (let i = items.length - 1;i >= 0; --i) {
|
|
19683
|
+
const item = items[i];
|
|
19684
|
+
const [key, value] = item;
|
|
19685
|
+
const deleted = this.#deleteIfExpired(key, value);
|
|
19686
|
+
if (deleted === false) {
|
|
19687
|
+
yield [key, value.value];
|
|
19688
|
+
}
|
|
19689
|
+
}
|
|
19690
|
+
items = [...this.#oldCache];
|
|
19691
|
+
for (let i = items.length - 1;i >= 0; --i) {
|
|
19692
|
+
const item = items[i];
|
|
19693
|
+
const [key, value] = item;
|
|
19694
|
+
if (!this.#cache.has(key)) {
|
|
19695
|
+
const deleted = this.#deleteIfExpired(key, value);
|
|
19696
|
+
if (deleted === false) {
|
|
19697
|
+
yield [key, value.value];
|
|
19698
|
+
}
|
|
19699
|
+
}
|
|
19700
|
+
}
|
|
19701
|
+
}
|
|
19702
|
+
*entriesAscending() {
|
|
19703
|
+
for (const [key, value] of this.#entriesAscending()) {
|
|
19704
|
+
yield [key, value.value];
|
|
19705
|
+
}
|
|
19706
|
+
}
|
|
19707
|
+
get size() {
|
|
19708
|
+
if (!this.#size) {
|
|
19709
|
+
return this.#oldCache.size;
|
|
19710
|
+
}
|
|
19711
|
+
let oldCacheSize = 0;
|
|
19712
|
+
for (const key of this.#oldCache.keys()) {
|
|
19713
|
+
if (!this.#cache.has(key)) {
|
|
19714
|
+
oldCacheSize++;
|
|
19715
|
+
}
|
|
19716
|
+
}
|
|
19717
|
+
return Math.min(this.#size + oldCacheSize, this.#maxSize);
|
|
19718
|
+
}
|
|
19719
|
+
get maxSize() {
|
|
19720
|
+
return this.#maxSize;
|
|
19721
|
+
}
|
|
19722
|
+
get maxAge() {
|
|
19723
|
+
return this.#maxAge;
|
|
19724
|
+
}
|
|
19725
|
+
entries() {
|
|
19726
|
+
return this.entriesAscending();
|
|
19727
|
+
}
|
|
19728
|
+
forEach(callbackFunction, thisArgument = this) {
|
|
19729
|
+
for (const [key, value] of this.entriesAscending()) {
|
|
19730
|
+
callbackFunction.call(thisArgument, value, key, this);
|
|
19731
|
+
}
|
|
19732
|
+
}
|
|
19733
|
+
get [Symbol.toStringTag]() {
|
|
19734
|
+
return "QuickLRU";
|
|
19735
|
+
}
|
|
19736
|
+
toString() {
|
|
19737
|
+
return `QuickLRU(${this.size}/${this.maxSize})`;
|
|
19738
|
+
}
|
|
19739
|
+
[Symbol.for("nodejs.util.inspect.custom")]() {
|
|
19740
|
+
return this.toString();
|
|
19741
|
+
}
|
|
19742
|
+
}
|
|
19743
|
+
|
|
19744
|
+
// src/config/index.ts
|
|
19745
|
+
init_evidence_schema();
|
|
19746
|
+
init_plan_schema();
|
|
19747
|
+
|
|
19748
|
+
// src/config/spec-schema.ts
|
|
19749
|
+
init_zod();
|
|
19750
|
+
var ObligationSchema = exports_external.enum(["MUST", "SHALL", "SHOULD", "MAY"]);
|
|
19751
|
+
var SpecRequirementSchema = exports_external.object({
|
|
19752
|
+
id: exports_external.string().regex(/^FR-(?!000)\d{3}$/, "Requirement ID must match FR-### pattern (e.g., FR-001)"),
|
|
19753
|
+
obligation: ObligationSchema,
|
|
19754
|
+
text: exports_external.string().min(1)
|
|
19755
|
+
});
|
|
19756
|
+
var SpecScenarioSchema = exports_external.object({
|
|
19757
|
+
name: exports_external.string().min(1),
|
|
19758
|
+
given: exports_external.array(exports_external.string()).optional().default([]),
|
|
19759
|
+
when: exports_external.array(exports_external.string()).min(1, 'Scenario must have at least one "when" clause'),
|
|
19760
|
+
thenClauses: exports_external.array(exports_external.string()).min(1, 'Scenario must have at least one "then" clause')
|
|
19761
|
+
});
|
|
19762
|
+
var SpecSectionSchema = exports_external.object({
|
|
19763
|
+
name: exports_external.string().min(1),
|
|
19764
|
+
requirements: exports_external.array(SpecRequirementSchema).default([])
|
|
19765
|
+
});
|
|
19766
|
+
var SwarmSpecSchema = exports_external.object({
|
|
19767
|
+
title: exports_external.string().min(1),
|
|
19768
|
+
purpose: exports_external.string().min(1),
|
|
19769
|
+
sections: exports_external.array(SpecSectionSchema).min(1, "Spec must have at least one section")
|
|
19770
|
+
});
|
|
19771
|
+
var SpecDeltaSchema = exports_external.object({
|
|
19772
|
+
added: exports_external.array(SpecRequirementSchema).default([]),
|
|
19773
|
+
modified: exports_external.array(SpecRequirementSchema).default([]),
|
|
19774
|
+
removed: exports_external.array(SpecRequirementSchema).default([])
|
|
19775
|
+
});
|
|
19776
|
+
var DeltaSpecSchema = exports_external.union([
|
|
19777
|
+
SwarmSpecSchema,
|
|
19778
|
+
SpecDeltaSchema
|
|
19779
|
+
]);
|
|
19780
|
+
// src/agents/index.ts
|
|
19781
|
+
var warnedAgents = new Set;
|
|
19782
|
+
|
|
19783
|
+
// src/hooks/guardrails.ts
|
|
19784
|
+
init_manager();
|
|
19785
|
+
init_telemetry();
|
|
19786
|
+
init_utils();
|
|
19787
|
+
|
|
19788
|
+
// src/hooks/conflict-resolution.ts
|
|
19789
|
+
init_telemetry();
|
|
19790
|
+
|
|
19791
|
+
// src/hooks/extractors.ts
|
|
19792
|
+
function extractCurrentPhase(planContent) {
|
|
19793
|
+
if (!planContent) {
|
|
19794
|
+
return null;
|
|
19795
|
+
}
|
|
19796
|
+
const lines = planContent.split(`
|
|
19797
|
+
`);
|
|
19798
|
+
for (let i = 0;i < Math.min(20, lines.length); i++) {
|
|
19799
|
+
const line = lines[i].trim();
|
|
19800
|
+
const progressMatch = line.match(/^## Phase (\d+):?\s*(.*?)\s*\[IN PROGRESS\]/i);
|
|
19801
|
+
if (progressMatch) {
|
|
19802
|
+
const phaseNum = progressMatch[1];
|
|
19803
|
+
const description = progressMatch[2]?.trim() || "";
|
|
19804
|
+
return `Phase ${phaseNum}: ${description} [IN PROGRESS]`;
|
|
19805
|
+
}
|
|
19806
|
+
}
|
|
19807
|
+
for (let i = 0;i < Math.min(3, lines.length); i++) {
|
|
19808
|
+
const line = lines[i].trim();
|
|
19809
|
+
const phaseMatch = line.match(/Phase:\s*(\d+)/i);
|
|
19810
|
+
if (phaseMatch) {
|
|
19811
|
+
const phaseNum = phaseMatch[1];
|
|
19812
|
+
return `Phase ${phaseNum} [PENDING]`;
|
|
19813
|
+
}
|
|
19814
|
+
}
|
|
19815
|
+
return null;
|
|
19816
|
+
}
|
|
19817
|
+
function extractCurrentPhaseFromPlan(plan) {
|
|
19818
|
+
const phase = plan.phases.find((p) => p.id === plan.current_phase);
|
|
19819
|
+
if (!phase)
|
|
19820
|
+
return null;
|
|
19821
|
+
const statusMap = {
|
|
19822
|
+
pending: "PENDING",
|
|
19823
|
+
in_progress: "IN PROGRESS",
|
|
19824
|
+
complete: "COMPLETE",
|
|
19825
|
+
blocked: "BLOCKED"
|
|
19826
|
+
};
|
|
19827
|
+
const statusText = statusMap[phase.status] || "PENDING";
|
|
19828
|
+
return `Phase ${phase.id}: ${phase.name} [${statusText}]`;
|
|
19829
|
+
}
|
|
19830
|
+
|
|
19831
|
+
// src/hooks/model-limits.ts
|
|
19832
|
+
init_utils();
|
|
19833
|
+
var loggedFirstCalls = new Set;
|
|
19834
|
+
|
|
19835
|
+
// src/hooks/guardrails.ts
|
|
19836
|
+
var storedInputArgs = new Map;
|
|
19837
|
+
var toolCallsSinceLastWrite = new Map;
|
|
19838
|
+
var noOpWarningIssued = new Set;
|
|
19839
|
+
var consecutiveNoToolTurns = new Map;
|
|
19840
|
+
var DC_SAFE_TARGETS = new Set([
|
|
19841
|
+
"node_modules",
|
|
19842
|
+
".git",
|
|
19843
|
+
"dist",
|
|
19844
|
+
"build",
|
|
19845
|
+
"coverage",
|
|
19846
|
+
".next",
|
|
19847
|
+
".turbo",
|
|
19848
|
+
".cache",
|
|
19849
|
+
".venv",
|
|
19850
|
+
"venv",
|
|
19851
|
+
"__pycache__",
|
|
19852
|
+
"target",
|
|
19853
|
+
"out",
|
|
19854
|
+
".parcel-cache",
|
|
19855
|
+
".svelte-kit",
|
|
19856
|
+
".nuxt",
|
|
19857
|
+
".output",
|
|
19858
|
+
".angular",
|
|
19859
|
+
".gradle",
|
|
19860
|
+
"vendor"
|
|
19861
|
+
]);
|
|
19862
|
+
var DC_FS_ROOTS = new Set(["/", "C:\\", "C:/", "D:\\", "D:/", "E:\\", "E:/"]);
|
|
19863
|
+
var pathNormalizationCache = new QuickLRU({
|
|
19864
|
+
maxSize: 500
|
|
19865
|
+
});
|
|
19866
|
+
var globMatcherCache = new QuickLRU({
|
|
19867
|
+
maxSize: 200
|
|
19868
|
+
});
|
|
19869
|
+
|
|
19870
|
+
// src/hooks/delegation-gate.ts
|
|
19871
|
+
init_utils2();
|
|
19872
|
+
var pendingCoderScopeByTaskId = new Map;
|
|
19873
|
+
function clearPendingCoderScope() {
|
|
19874
|
+
pendingCoderScopeByTaskId.clear();
|
|
19875
|
+
}
|
|
19876
|
+
|
|
19877
|
+
// src/state.ts
|
|
19467
19878
|
init_telemetry();
|
|
19468
19879
|
var _rehydrationCache = null;
|
|
19469
19880
|
var swarmState = {
|
|
@@ -19496,6 +19907,7 @@ function resetSwarmState() {
|
|
|
19496
19907
|
_rehydrationCache = null;
|
|
19497
19908
|
swarmState.fullAutoEnabledInConfig = false;
|
|
19498
19909
|
swarmState.environmentProfiles.clear();
|
|
19910
|
+
clearPendingCoderScope();
|
|
19499
19911
|
}
|
|
19500
19912
|
function getAgentSession(sessionId) {
|
|
19501
19913
|
return swarmState.agentSessions.get(sessionId);
|
|
@@ -32178,43 +32590,6 @@ function tool(input) {
|
|
|
32178
32590
|
return input;
|
|
32179
32591
|
}
|
|
32180
32592
|
tool.schema = exports_external2;
|
|
32181
|
-
|
|
32182
|
-
// src/config/index.ts
|
|
32183
|
-
init_evidence_schema();
|
|
32184
|
-
init_plan_schema();
|
|
32185
|
-
|
|
32186
|
-
// src/config/spec-schema.ts
|
|
32187
|
-
init_zod();
|
|
32188
|
-
var ObligationSchema = exports_external.enum(["MUST", "SHALL", "SHOULD", "MAY"]);
|
|
32189
|
-
var SpecRequirementSchema = exports_external.object({
|
|
32190
|
-
id: exports_external.string().regex(/^FR-(?!000)\d{3}$/, "Requirement ID must match FR-### pattern (e.g., FR-001)"),
|
|
32191
|
-
obligation: ObligationSchema,
|
|
32192
|
-
text: exports_external.string().min(1)
|
|
32193
|
-
});
|
|
32194
|
-
var SpecScenarioSchema = exports_external.object({
|
|
32195
|
-
name: exports_external.string().min(1),
|
|
32196
|
-
given: exports_external.array(exports_external.string()).optional().default([]),
|
|
32197
|
-
when: exports_external.array(exports_external.string()).min(1, 'Scenario must have at least one "when" clause'),
|
|
32198
|
-
thenClauses: exports_external.array(exports_external.string()).min(1, 'Scenario must have at least one "then" clause')
|
|
32199
|
-
});
|
|
32200
|
-
var SpecSectionSchema = exports_external.object({
|
|
32201
|
-
name: exports_external.string().min(1),
|
|
32202
|
-
requirements: exports_external.array(SpecRequirementSchema).default([])
|
|
32203
|
-
});
|
|
32204
|
-
var SwarmSpecSchema = exports_external.object({
|
|
32205
|
-
title: exports_external.string().min(1),
|
|
32206
|
-
purpose: exports_external.string().min(1),
|
|
32207
|
-
sections: exports_external.array(SpecSectionSchema).min(1, "Spec must have at least one section")
|
|
32208
|
-
});
|
|
32209
|
-
var SpecDeltaSchema = exports_external.object({
|
|
32210
|
-
added: exports_external.array(SpecRequirementSchema).default([]),
|
|
32211
|
-
modified: exports_external.array(SpecRequirementSchema).default([]),
|
|
32212
|
-
removed: exports_external.array(SpecRequirementSchema).default([])
|
|
32213
|
-
});
|
|
32214
|
-
var DeltaSpecSchema = exports_external.union([
|
|
32215
|
-
SwarmSpecSchema,
|
|
32216
|
-
SpecDeltaSchema
|
|
32217
|
-
]);
|
|
32218
32593
|
// src/tools/create-tool.ts
|
|
32219
32594
|
function classifyToolError(error93) {
|
|
32220
32595
|
const msg = (error93 instanceof Error ? error93.message ?? "" : String(error93)).toLowerCase();
|
|
@@ -37537,7 +37912,7 @@ function validatePlanPhases(plan) {
|
|
|
37537
37912
|
}
|
|
37538
37913
|
return true;
|
|
37539
37914
|
}
|
|
37540
|
-
function
|
|
37915
|
+
function extractCurrentPhaseFromPlan2(plan) {
|
|
37541
37916
|
if (!plan) {
|
|
37542
37917
|
return { currentPhase: null, currentTask: null, incompleteTasks: [] };
|
|
37543
37918
|
}
|
|
@@ -37685,7 +38060,7 @@ async function getHandoffData(directory) {
|
|
|
37685
38060
|
const sessionContent = await readSwarmFileAsync(directory, "session/state.json");
|
|
37686
38061
|
const sessionState = parseSessionState(sessionContent);
|
|
37687
38062
|
const plan = await loadPlanJsonOnly(directory);
|
|
37688
|
-
const planInfo =
|
|
38063
|
+
const planInfo = extractCurrentPhaseFromPlan2(plan);
|
|
37689
38064
|
if (!plan) {
|
|
37690
38065
|
const planMdContent = await readSwarmFileAsync(directory, "plan.md");
|
|
37691
38066
|
if (planMdContent) {
|
|
@@ -43524,46 +43899,6 @@ async function handleSpecifyCommand(_directory, args) {
|
|
|
43524
43899
|
return "[MODE: SPECIFY] Please enter MODE: SPECIFY and generate a spec for this project.";
|
|
43525
43900
|
}
|
|
43526
43901
|
|
|
43527
|
-
// src/hooks/extractors.ts
|
|
43528
|
-
function extractCurrentPhase(planContent) {
|
|
43529
|
-
if (!planContent) {
|
|
43530
|
-
return null;
|
|
43531
|
-
}
|
|
43532
|
-
const lines = planContent.split(`
|
|
43533
|
-
`);
|
|
43534
|
-
for (let i = 0;i < Math.min(20, lines.length); i++) {
|
|
43535
|
-
const line = lines[i].trim();
|
|
43536
|
-
const progressMatch = line.match(/^## Phase (\d+):?\s*(.*?)\s*\[IN PROGRESS\]/i);
|
|
43537
|
-
if (progressMatch) {
|
|
43538
|
-
const phaseNum = progressMatch[1];
|
|
43539
|
-
const description = progressMatch[2]?.trim() || "";
|
|
43540
|
-
return `Phase ${phaseNum}: ${description} [IN PROGRESS]`;
|
|
43541
|
-
}
|
|
43542
|
-
}
|
|
43543
|
-
for (let i = 0;i < Math.min(3, lines.length); i++) {
|
|
43544
|
-
const line = lines[i].trim();
|
|
43545
|
-
const phaseMatch = line.match(/Phase:\s*(\d+)/i);
|
|
43546
|
-
if (phaseMatch) {
|
|
43547
|
-
const phaseNum = phaseMatch[1];
|
|
43548
|
-
return `Phase ${phaseNum} [PENDING]`;
|
|
43549
|
-
}
|
|
43550
|
-
}
|
|
43551
|
-
return null;
|
|
43552
|
-
}
|
|
43553
|
-
function extractCurrentPhaseFromPlan2(plan) {
|
|
43554
|
-
const phase = plan.phases.find((p) => p.id === plan.current_phase);
|
|
43555
|
-
if (!phase)
|
|
43556
|
-
return null;
|
|
43557
|
-
const statusMap = {
|
|
43558
|
-
pending: "PENDING",
|
|
43559
|
-
in_progress: "IN PROGRESS",
|
|
43560
|
-
complete: "COMPLETE",
|
|
43561
|
-
blocked: "BLOCKED"
|
|
43562
|
-
};
|
|
43563
|
-
const statusText = statusMap[phase.status] || "PENDING";
|
|
43564
|
-
return `Phase ${phase.id}: ${phase.name} [${statusText}]`;
|
|
43565
|
-
}
|
|
43566
|
-
|
|
43567
43902
|
// src/services/status-service.ts
|
|
43568
43903
|
init_utils2();
|
|
43569
43904
|
init_manager();
|
|
@@ -43623,7 +43958,7 @@ var DEFAULT_CONTEXT_BUDGET_CONFIG = {
|
|
|
43623
43958
|
async function getStatusData(directory, agents) {
|
|
43624
43959
|
const plan = await loadPlan(directory);
|
|
43625
43960
|
if (plan && plan.migration_status !== "migration_failed") {
|
|
43626
|
-
const currentPhase2 =
|
|
43961
|
+
const currentPhase2 = extractCurrentPhaseFromPlan(plan) || "Unknown";
|
|
43627
43962
|
let completedTasks2 = 0;
|
|
43628
43963
|
let totalTasks2 = 0;
|
|
43629
43964
|
for (const phase of plan.phases) {
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -509,6 +509,7 @@ export declare const AuthorityConfigSchema: z.ZodObject<{
|
|
|
509
509
|
blockedGlobs: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
510
510
|
allowedGlobs: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
511
511
|
}, z.core.$strip>>>;
|
|
512
|
+
universal_deny_prefixes: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
512
513
|
}, z.core.$strip>;
|
|
513
514
|
export type AuthorityConfig = z.infer<typeof AuthorityConfigSchema>;
|
|
514
515
|
export declare const CouncilConfigSchema: z.ZodObject<{
|
|
@@ -699,6 +700,7 @@ export declare const PluginConfigSchema: z.ZodObject<{
|
|
|
699
700
|
blockedGlobs: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
700
701
|
allowedGlobs: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
701
702
|
}, z.core.$strip>>>;
|
|
703
|
+
universal_deny_prefixes: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
702
704
|
}, z.core.$strip>>;
|
|
703
705
|
plan_cursor: z.ZodOptional<z.ZodObject<{
|
|
704
706
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -11,8 +11,19 @@ import type { DelegationEnvelope, EnvelopeValidationResult } from '../types/dele
|
|
|
11
11
|
* When messagesTransform sets declaredCoderScope on the architect session,
|
|
12
12
|
* the coder session may not exist yet. This map allows scope-guard to look up
|
|
13
13
|
* the scope by taskId when the session's declaredCoderScope is null.
|
|
14
|
+
*
|
|
15
|
+
* v6.70.0 gap-closure: this map is module-scoped (not inside `swarmState`) and
|
|
16
|
+
* is cleared by `resetSwarmState` via `clearPendingCoderScope()` below. Without
|
|
17
|
+
* that cleanup, a `/swarm close` followed by a new session with a colliding
|
|
18
|
+
* taskId (e.g. "1.1") would inherit stale scope from the previous swarm.
|
|
14
19
|
*/
|
|
15
20
|
export declare const pendingCoderScopeByTaskId: Map<string, string[]>;
|
|
21
|
+
/**
|
|
22
|
+
* v6.70.0 gap-closure: clears the pending coder-scope map. Exported as a
|
|
23
|
+
* helper (rather than importing the map directly from state.ts) to avoid the
|
|
24
|
+
* circular import `state.ts ↔ delegation-gate.ts`. Called by `resetSwarmState`.
|
|
25
|
+
*/
|
|
26
|
+
export declare function clearPendingCoderScope(): void;
|
|
16
27
|
/**
|
|
17
28
|
* Parses a string to extract a DelegationEnvelope.
|
|
18
29
|
* Returns null if no valid envelope is found.
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* - Layer 1 (Soft Warning @ warning_threshold): Sets warning flag for messagesTransform to inject warning
|
|
7
7
|
* - Layer 2 (Hard Block @ 100%): Throws error in toolBefore to block further calls, injects STOP message
|
|
8
8
|
*/
|
|
9
|
+
import * as path from 'node:path';
|
|
9
10
|
import { type AuthorityConfig, type GuardrailsConfig } from '../config/schema';
|
|
10
11
|
import { type FileZone } from '../context/zone-classifier';
|
|
11
12
|
/**
|
|
@@ -119,10 +120,44 @@ type AgentRule = {
|
|
|
119
120
|
allowedGlobs?: string[];
|
|
120
121
|
};
|
|
121
122
|
export declare const DEFAULT_AGENT_AUTHORITY_RULES: Record<string, AgentRule>;
|
|
123
|
+
/**
|
|
124
|
+
* Checks whether a write target path (or any ancestor strictly inside cwd)
|
|
125
|
+
* is a symlink. Writing through a symlink can redirect the write to a
|
|
126
|
+
* location outside the working directory, bypassing scope containment.
|
|
127
|
+
*
|
|
128
|
+
* The walk stops at cwd — cwd itself is NOT lstat'd. A user's chosen
|
|
129
|
+
* working directory may legitimately be reached via a symlink (e.g.,
|
|
130
|
+
* macOS's /tmp → /private/tmp), and that symlink does not constitute a
|
|
131
|
+
* redirect *within* the workspace. Only attacker-plantable symlinks
|
|
132
|
+
* BELOW cwd are relevant to this guard.
|
|
133
|
+
*
|
|
134
|
+
* ENOENT on any node in the chain is allowed — the file/dir doesn't exist yet.
|
|
135
|
+
* Any other lstat error (EPERM, EACCES, ENAMETOOLONG, …) fails closed:
|
|
136
|
+
* an unverifiable ancestor must not be written through, even if the OS
|
|
137
|
+
* would eventually reject the write. Defense-in-depth over optimism.
|
|
138
|
+
*
|
|
139
|
+
* @returns A block reason string if a symlink is detected, null if all clear.
|
|
140
|
+
*/
|
|
141
|
+
export declare function checkWriteTargetForSymlink(targetPath: string, cwd: string): string | null;
|
|
142
|
+
/**
|
|
143
|
+
* Returns true when `targetAbsolute` and `cwdAbsolute` resolve to different
|
|
144
|
+
* filesystem roots. On POSIX this is always false (single root `/`); on
|
|
145
|
+
* Windows it is true when the two paths sit on different drive letters or
|
|
146
|
+
* different UNC roots — the symptom Codex flagged on PR #501, where
|
|
147
|
+
* `path.relative('C:\\repo', 'D:\\secret.txt')` returns the absolute
|
|
148
|
+
* `'D:\\secret.txt'` and slips past `startsWith('../')` containment.
|
|
149
|
+
*
|
|
150
|
+
* Exposed (and accepts an injectable `pathLib`) so the cross-drive guard
|
|
151
|
+
* is falsifiable on Linux CI without depending on a Windows runner: tests
|
|
152
|
+
* pass `path.win32` / `path.posix` directly.
|
|
153
|
+
*/
|
|
154
|
+
export declare function isOnDifferentFilesystemRoot(targetAbsolute: string, cwdAbsolute: string, pathLib?: Pick<typeof path, 'parse'>): boolean;
|
|
122
155
|
/**
|
|
123
156
|
* Checks whether the given agent is authorised to write to the given file path.
|
|
124
157
|
*/
|
|
125
|
-
export declare function checkFileAuthority(agentName: string, filePath: string, cwd: string, authorityConfig?: AuthorityConfig
|
|
158
|
+
export declare function checkFileAuthority(agentName: string, filePath: string, cwd: string, authorityConfig?: AuthorityConfig, options?: {
|
|
159
|
+
declaredScope?: string[] | null;
|
|
160
|
+
}): {
|
|
126
161
|
allowed: true;
|
|
127
162
|
} | {
|
|
128
163
|
allowed: false;
|