@wrongstack/core 0.273.0 → 0.273.1
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/{agent-bridge-BZ2enORi.d.ts → agent-bridge-DpKIxHhE.d.ts} +1 -1
- package/dist/{agent-subagent-runner-ehb4xGvd.d.ts → agent-subagent-runner-Dx7fZ1bE.d.ts} +7 -7
- package/dist/{brain-BxN2k2HP.d.ts → brain-BDcQaku-.d.ts} +11 -5
- package/dist/{compactor-72ug-ZRB.d.ts → compactor-BuSdj3fq.d.ts} +1 -1
- package/dist/{config-C8IYxlO8.d.ts → config-CR2yoG8c.d.ts} +54 -4
- package/dist/{context-Dw55zZ_Q.d.ts → context-DulAr8Zo.d.ts} +24 -0
- package/dist/coordination/index.d.ts +23 -16
- package/dist/coordination/index.js +113 -13
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +26 -26
- package/dist/defaults/index.js +405 -8
- package/dist/defaults/index.js.map +1 -1
- package/dist/execution/index.d.ts +15 -15
- package/dist/execution/index.js +75 -1
- package/dist/execution/index.js.map +1 -1
- package/dist/execution/prompt-enhancer.d.ts +1 -1
- package/dist/extension/index.d.ts +6 -6
- package/dist/{global-mailbox-C9dsc9Y_.d.ts → global-mailbox-CwcubDkA.d.ts} +1 -1
- package/dist/{goal-preamble-NhflDjYb.d.ts → goal-preamble-Bu0a2uCG.d.ts} +9 -9
- package/dist/{goal-store-Cx363x7Z.d.ts → goal-store-CTmFuZ8J.d.ts} +1 -1
- package/dist/hq/index.d.ts +5 -5
- package/dist/{index-B7fHDt0B.d.ts → index-CTq5wU3m.d.ts} +5 -5
- package/dist/{index-BbVprU-9.d.ts → index-CxP-HBhX.d.ts} +2 -2
- package/dist/index.d.ts +63 -42
- package/dist/index.js +598 -56
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +6 -6
- package/dist/kernel/index.d.ts +11 -11
- package/dist/kernel/index.js.map +1 -1
- package/dist/{mcp-servers-B6fSRNC1.d.ts → mcp-servers-BQaOE71z.d.ts} +3 -3
- package/dist/models/index.d.ts +5 -5
- package/dist/{models-registry-4C6Wr91w.d.ts → models-registry-BEcny4kP.d.ts} +1 -1
- package/dist/{multi-agent-coordinator-q1skFeNP.d.ts → multi-agent-coordinator-Bx8EFkv2.d.ts} +1 -1
- package/dist/{null-fleet-bus-C9rrgQwc.d.ts → null-fleet-bus-BC5ZXCQw.d.ts} +6 -6
- package/dist/observability/index.d.ts +2 -2
- package/dist/{parallel-eternal-engine-CtXly2Sf.d.ts → parallel-eternal-engine-C345TI3n.d.ts} +9 -9
- package/dist/{path-resolver-Bim6G5Jz.d.ts → path-resolver-C-W_wzkF.d.ts} +3 -3
- package/dist/{permission-CC7XFYWG.d.ts → permission-CsBGZkxp.d.ts} +1 -1
- package/dist/{permission-policy-cYR4RJmw.d.ts → permission-policy-g3Sg0GdZ.d.ts} +2 -2
- package/dist/{pipeline-CNVKuQDQ.d.ts → pipeline-xnw_24Z8.d.ts} +2 -2
- package/dist/{plan-templates-C4wXMmiM.d.ts → plan-templates-DGaiYEcS.d.ts} +31 -5
- package/dist/{provider-model-resolve-DFd3IPpw.d.ts → provider-model-resolve-Cz6OlIOp.d.ts} +3 -3
- package/dist/{provider-runner-BpM0mdBE.d.ts → provider-runner-7J0HqF6B.d.ts} +3 -3
- package/dist/{retry-policy-BV7nzeAd.d.ts → retry-policy-kqXJOVkX.d.ts} +1 -1
- package/dist/sdd/index.d.ts +9 -9
- package/dist/{secret-vault-eMBKfheR.d.ts → secret-vault-CMQUr-eB.d.ts} +1 -1
- package/dist/security/index.d.ts +5 -5
- package/dist/{selector-C4ORTOid.d.ts → selector-B4r34PWR.d.ts} +1 -1
- package/dist/{session-event-bridge-CeNpUL9w.d.ts → session-event-bridge-BD3LoyLC.d.ts} +1 -1
- package/dist/{session-reader-BepLSnGL.d.ts → session-reader-DjrKGD9c.d.ts} +1 -1
- package/dist/storage/index.d.ts +11 -11
- package/dist/storage/index.js +377 -11
- package/dist/storage/index.js.map +1 -1
- package/dist/tools/index.d.ts +2 -2
- package/dist/types/index.d.ts +19 -19
- package/dist/types/index.js +28 -0
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +2 -2
- package/dist/{worktree-manager-BDuXTaWL.d.ts → worktree-manager-DHdrWQ_7.d.ts} +1 -1
- package/package.json +1 -1
package/dist/storage/index.js
CHANGED
|
@@ -746,6 +746,91 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
746
746
|
}
|
|
747
747
|
}
|
|
748
748
|
}
|
|
749
|
+
/**
|
|
750
|
+
* Streaming search over a session's JSONL. Walks the file once, parses
|
|
751
|
+
* each event lazily, and yields only the events that match `predicate`.
|
|
752
|
+
* Stops as soon as `opts.limit` matches are collected.
|
|
753
|
+
*
|
|
754
|
+
* Why this exists: `load()` parses the entire file into memory and
|
|
755
|
+
* rebuilds `messages`/`toolCallEnds` for every caller. `search()` only
|
|
756
|
+
* needs to know which events contain matching text — a per-line
|
|
757
|
+
* predicate is enough. The full parse work (and the `_loadCache` poll)
|
|
758
|
+
* is wasted in that case.
|
|
759
|
+
*
|
|
760
|
+
* Memory: O(hits) regardless of file size. Disk: one linear scan,
|
|
761
|
+
* terminated at `limit` if the caller asked for one.
|
|
762
|
+
*
|
|
763
|
+
* Errors: missing file yields []. Corrupt lines are skipped (same
|
|
764
|
+
* policy as `load()`). Aborting via `signal` rejects with `AbortError`.
|
|
765
|
+
*/
|
|
766
|
+
async searchEvents(id, predicate, opts) {
|
|
767
|
+
const file = this.sessionPath(id, ".jsonl");
|
|
768
|
+
const limit = opts?.limit;
|
|
769
|
+
const signal = opts?.signal;
|
|
770
|
+
const out = [];
|
|
771
|
+
let stat7;
|
|
772
|
+
try {
|
|
773
|
+
stat7 = await fsp.stat(file);
|
|
774
|
+
} catch (err) {
|
|
775
|
+
if (err.code === "ENOENT") return [];
|
|
776
|
+
throw err;
|
|
777
|
+
}
|
|
778
|
+
if (stat7.size === 0) return [];
|
|
779
|
+
let fh;
|
|
780
|
+
try {
|
|
781
|
+
fh = await fsp.open(file, "r");
|
|
782
|
+
const CHUNK = 64 * 1024;
|
|
783
|
+
const buf = Buffer.alloc(CHUNK);
|
|
784
|
+
let leftover = "";
|
|
785
|
+
let eventIndex = 0;
|
|
786
|
+
for (let position = 0; ; position += buf.byteLength) {
|
|
787
|
+
if (signal?.aborted) {
|
|
788
|
+
const reason = signal.reason ?? new DOMException("Aborted", "AbortError");
|
|
789
|
+
throw reason;
|
|
790
|
+
}
|
|
791
|
+
const { bytesRead } = await fh.read(buf, 0, CHUNK, position);
|
|
792
|
+
if (bytesRead === 0) break;
|
|
793
|
+
const text = leftover + buf.subarray(0, bytesRead).toString("utf8");
|
|
794
|
+
const parts = text.split("\n");
|
|
795
|
+
leftover = parts.pop() ?? "";
|
|
796
|
+
for (const line of parts) {
|
|
797
|
+
if (!line) continue;
|
|
798
|
+
let ev;
|
|
799
|
+
try {
|
|
800
|
+
const parsed = JSON.parse(line);
|
|
801
|
+
if (parsed === null || typeof parsed !== "object" || typeof parsed.type !== "string" || typeof parsed.ts !== "string") {
|
|
802
|
+
continue;
|
|
803
|
+
}
|
|
804
|
+
ev = parsed;
|
|
805
|
+
} catch {
|
|
806
|
+
continue;
|
|
807
|
+
}
|
|
808
|
+
if (predicate(ev, eventIndex, ev.ts)) {
|
|
809
|
+
out.push({ event: ev, eventIndex, ts: ev.ts });
|
|
810
|
+
if (limit !== void 0 && out.length >= limit) {
|
|
811
|
+
return out;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
eventIndex++;
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
if (leftover.trim()) {
|
|
818
|
+
try {
|
|
819
|
+
const parsed = JSON.parse(leftover);
|
|
820
|
+
if (parsed !== null && typeof parsed === "object" && typeof parsed.type === "string" && typeof parsed.ts === "string") {
|
|
821
|
+
const ev = parsed;
|
|
822
|
+
if (predicate(ev, eventIndex, ev.ts)) {
|
|
823
|
+
out.push({ event: ev, eventIndex, ts: ev.ts });
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
} catch {
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
return out;
|
|
830
|
+
} finally {
|
|
831
|
+
if (fh) await fh.close().catch(() => void 0);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
749
834
|
async list(limit = 20) {
|
|
750
835
|
try {
|
|
751
836
|
await ensureDir(this.dir);
|
|
@@ -3660,6 +3745,9 @@ function isContextWindowModeId(id) {
|
|
|
3660
3745
|
return CONTEXT_WINDOW_MODES.some((m) => m.id === id);
|
|
3661
3746
|
}
|
|
3662
3747
|
|
|
3748
|
+
// src/types/config.ts
|
|
3749
|
+
var DEFAULT_TUI_THINKING_WORD = "thinking";
|
|
3750
|
+
|
|
3663
3751
|
// src/types/default-config.ts
|
|
3664
3752
|
var DEFAULT_TOOLS_CONFIG = Object.freeze({
|
|
3665
3753
|
defaultExecutionStrategy: "smart",
|
|
@@ -3678,6 +3766,10 @@ var DEFAULT_CONTEXT_CONFIG = Object.freeze({
|
|
|
3678
3766
|
var DEFAULT_AUTONOMY_CONFIG = Object.freeze({
|
|
3679
3767
|
autoProceedDelayMs: 45e3
|
|
3680
3768
|
});
|
|
3769
|
+
var DEFAULT_CIRCUIT_BREAKER_CONFIG = Object.freeze({
|
|
3770
|
+
enabled: false,
|
|
3771
|
+
autoKillResetMs: 6e4
|
|
3772
|
+
});
|
|
3681
3773
|
var DEFAULT_SESSION_LOGGING_CONFIG = Object.freeze({
|
|
3682
3774
|
auditLevel: "standard",
|
|
3683
3775
|
sampling: {
|
|
@@ -3704,7 +3796,8 @@ var BEHAVIOR_DEFAULTS = {
|
|
|
3704
3796
|
hardThreshold: 0.9,
|
|
3705
3797
|
autoCompact: true,
|
|
3706
3798
|
preserveK: DEFAULT_CONTEXT_CONFIG.preserveK,
|
|
3707
|
-
eliseThreshold: DEFAULT_CONTEXT_CONFIG.eliseThreshold
|
|
3799
|
+
eliseThreshold: DEFAULT_CONTEXT_CONFIG.eliseThreshold,
|
|
3800
|
+
strategy: "hybrid"
|
|
3708
3801
|
},
|
|
3709
3802
|
tools: {
|
|
3710
3803
|
defaultExecutionStrategy: DEFAULT_TOOLS_CONFIG.defaultExecutionStrategy,
|
|
@@ -3727,6 +3820,13 @@ var BEHAVIOR_DEFAULTS = {
|
|
|
3727
3820
|
allowOutsideProjectRoot: true
|
|
3728
3821
|
},
|
|
3729
3822
|
mcpServers: {},
|
|
3823
|
+
fallbackAuto: true,
|
|
3824
|
+
maxConcurrent: 4,
|
|
3825
|
+
yolo: false,
|
|
3826
|
+
nextPrediction: false,
|
|
3827
|
+
hints: true,
|
|
3828
|
+
debugStream: false,
|
|
3829
|
+
configScope: "global",
|
|
3730
3830
|
indexing: {
|
|
3731
3831
|
onSessionStart: true,
|
|
3732
3832
|
onEdit: true,
|
|
@@ -3734,8 +3834,55 @@ var BEHAVIOR_DEFAULTS = {
|
|
|
3734
3834
|
debounceMs: 400
|
|
3735
3835
|
},
|
|
3736
3836
|
session: { ...DEFAULT_SESSION_LOGGING_CONFIG },
|
|
3737
|
-
autonomy: {
|
|
3837
|
+
autonomy: {
|
|
3838
|
+
defaultMode: "off",
|
|
3839
|
+
autoProceedDelayMs: DEFAULT_AUTONOMY_CONFIG.autoProceedDelayMs,
|
|
3840
|
+
autoProceedMaxIterations: 50,
|
|
3841
|
+
autonomyNextPrompt: "auto {{suggestion}}",
|
|
3842
|
+
terminalTitleAnimation: true,
|
|
3843
|
+
yolo: false,
|
|
3844
|
+
streamFleet: true,
|
|
3845
|
+
chime: false,
|
|
3846
|
+
confirmExit: true,
|
|
3847
|
+
mouseMode: false,
|
|
3848
|
+
enhance: true,
|
|
3849
|
+
enhanceDelayMs: 6e4,
|
|
3850
|
+
enhanceLanguage: "original",
|
|
3851
|
+
statuslineMode: "detailed",
|
|
3852
|
+
thinkingWord: DEFAULT_TUI_THINKING_WORD
|
|
3853
|
+
},
|
|
3854
|
+
circuitBreaker: { ...DEFAULT_CIRCUIT_BREAKER_CONFIG },
|
|
3855
|
+
modelRuntime: {
|
|
3856
|
+
reasoning: { mode: "auto", effort: "high", preserve: false },
|
|
3857
|
+
cache: {}
|
|
3858
|
+
}
|
|
3738
3859
|
};
|
|
3860
|
+
function isPlainRecord(value) {
|
|
3861
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3862
|
+
}
|
|
3863
|
+
function cloneJsonValue(value) {
|
|
3864
|
+
return structuredClone(value);
|
|
3865
|
+
}
|
|
3866
|
+
function fillMissingDefaults(target, defaults) {
|
|
3867
|
+
const value = cloneJsonValue(target);
|
|
3868
|
+
const changed = fillMissingDefaultsInPlace(value, defaults);
|
|
3869
|
+
return { value, changed };
|
|
3870
|
+
}
|
|
3871
|
+
function fillMissingDefaultsInPlace(target, defaults) {
|
|
3872
|
+
let changed = false;
|
|
3873
|
+
for (const [key, defaultValue] of Object.entries(defaults)) {
|
|
3874
|
+
if (!Object.prototype.hasOwnProperty.call(target, key)) {
|
|
3875
|
+
target[key] = cloneJsonValue(defaultValue);
|
|
3876
|
+
changed = true;
|
|
3877
|
+
continue;
|
|
3878
|
+
}
|
|
3879
|
+
const current = target[key];
|
|
3880
|
+
if (isPlainRecord(current) && isPlainRecord(defaultValue)) {
|
|
3881
|
+
changed = fillMissingDefaultsInPlace(current, defaultValue) || changed;
|
|
3882
|
+
}
|
|
3883
|
+
}
|
|
3884
|
+
return changed;
|
|
3885
|
+
}
|
|
3739
3886
|
function envBool(v) {
|
|
3740
3887
|
return !/^(0|false|no|off)$/i.test(v.trim());
|
|
3741
3888
|
}
|
|
@@ -3787,27 +3934,139 @@ var defaultIndexing = {
|
|
|
3787
3934
|
watchExternal: true,
|
|
3788
3935
|
debounceMs: 400
|
|
3789
3936
|
};
|
|
3790
|
-
var
|
|
3937
|
+
var IN_PROJECT_ALLOWED_KEYS = /* @__PURE__ */ new Set([
|
|
3938
|
+
"version",
|
|
3939
|
+
"model",
|
|
3940
|
+
"cwd",
|
|
3941
|
+
"context",
|
|
3942
|
+
"tools",
|
|
3943
|
+
"features",
|
|
3944
|
+
"autonomy",
|
|
3945
|
+
"indexing",
|
|
3946
|
+
"session",
|
|
3947
|
+
"log",
|
|
3948
|
+
"launch",
|
|
3949
|
+
"nextPrediction",
|
|
3950
|
+
"hints",
|
|
3951
|
+
"debugStream",
|
|
3952
|
+
"configScope",
|
|
3953
|
+
"maxConcurrent",
|
|
3954
|
+
"fallbackModels",
|
|
3955
|
+
"fallbackAuto",
|
|
3956
|
+
"models",
|
|
3957
|
+
"modelMatrix",
|
|
3958
|
+
"circuitBreaker",
|
|
3959
|
+
"adaptiveConcurrency",
|
|
3960
|
+
"modelRuntime"
|
|
3961
|
+
]);
|
|
3962
|
+
var KNOWN_DENIED_IN_PROJECT = [
|
|
3963
|
+
{ key: "provider", reason: "Provider id override; can intercept prompts/responses." },
|
|
3964
|
+
{ key: "apiKey", reason: "Overrides user API key; exfiltrates prompts." },
|
|
3965
|
+
{ key: "baseUrl", reason: "Redirects provider endpoint; leaks real API key." },
|
|
3966
|
+
{ key: "providers", reason: "Per-provider apiKey/baseUrl/oauthConfig; same redirect/exfil." },
|
|
3967
|
+
{ key: "mcpServers", reason: "Arbitrary command/args/env spawned at boot (RCE)." },
|
|
3968
|
+
{ key: "hooks", reason: "Shell command arrays on lifecycle events (RCE)." },
|
|
3969
|
+
{ key: "plugins", reason: "Dynamic npm package load at boot (RCE)." },
|
|
3970
|
+
{ key: "sync", reason: "Carries githubToken credential and target repo." },
|
|
3971
|
+
{ key: "yolo", reason: "Disables all permission confirmation prompts." },
|
|
3972
|
+
{ key: "extensions", reason: "Per-plugin config can carry command/credential fields." },
|
|
3973
|
+
{ key: "hq", reason: "Carries HQ client token credential and endpoint URL." }
|
|
3974
|
+
];
|
|
3975
|
+
var KNOWN_CONFIG_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
3976
|
+
"version",
|
|
3791
3977
|
"provider",
|
|
3978
|
+
"model",
|
|
3792
3979
|
"apiKey",
|
|
3793
3980
|
"baseUrl",
|
|
3981
|
+
"maxConcurrent",
|
|
3794
3982
|
"providers",
|
|
3983
|
+
"models",
|
|
3984
|
+
"modelMatrix",
|
|
3985
|
+
"context",
|
|
3986
|
+
"tools",
|
|
3795
3987
|
"mcpServers",
|
|
3988
|
+
"fallbackModels",
|
|
3989
|
+
"fallbackAuto",
|
|
3796
3990
|
"hooks",
|
|
3797
3991
|
"plugins",
|
|
3798
|
-
"
|
|
3992
|
+
"log",
|
|
3993
|
+
"features",
|
|
3799
3994
|
"yolo",
|
|
3995
|
+
"nextPrediction",
|
|
3996
|
+
"cwd",
|
|
3997
|
+
"autonomy",
|
|
3998
|
+
"hints",
|
|
3999
|
+
"debugStream",
|
|
4000
|
+
"configScope",
|
|
4001
|
+
"indexing",
|
|
4002
|
+
"circuitBreaker",
|
|
4003
|
+
"adaptiveConcurrency",
|
|
4004
|
+
"launch",
|
|
4005
|
+
"session",
|
|
4006
|
+
"modelRuntime",
|
|
4007
|
+
"hq",
|
|
4008
|
+
"sync",
|
|
3800
4009
|
"extensions"
|
|
3801
4010
|
]);
|
|
4011
|
+
function assertInProjectAllowListComplete() {
|
|
4012
|
+
const missingFromBoth = [];
|
|
4013
|
+
for (const key of KNOWN_CONFIG_TOP_LEVEL_KEYS) {
|
|
4014
|
+
if (IN_PROJECT_ALLOWED_KEYS.has(key)) continue;
|
|
4015
|
+
const denied = KNOWN_DENIED_IN_PROJECT.find((d) => d.key === key);
|
|
4016
|
+
if (!denied) missingFromBoth.push(key);
|
|
4017
|
+
}
|
|
4018
|
+
const staleDenials = KNOWN_DENIED_IN_PROJECT.filter((d) => !KNOWN_CONFIG_TOP_LEVEL_KEYS.has(d.key)).map((d) => d.key);
|
|
4019
|
+
const duplicate = KNOWN_DENIED_IN_PROJECT.filter((d) => IN_PROJECT_ALLOWED_KEYS.has(d.key)).map((d) => d.key);
|
|
4020
|
+
const problems = [];
|
|
4021
|
+
if (missingFromBoth.length > 0) {
|
|
4022
|
+
problems.push(
|
|
4023
|
+
`new Config field(s) not classified as allowed or denied for in-project config: ` + missingFromBoth.join(", ") + ". Add each to IN_PROJECT_ALLOWED_KEYS (if safe) or KNOWN_DENIED_IN_PROJECT (with a reason)."
|
|
4024
|
+
);
|
|
4025
|
+
}
|
|
4026
|
+
if (staleDenials.length > 0) {
|
|
4027
|
+
problems.push(
|
|
4028
|
+
`KNOWN_DENIED_IN_PROJECT references keys that no longer exist on Config: ` + staleDenials.join(", ") + ". Remove them or restore the field on Config."
|
|
4029
|
+
);
|
|
4030
|
+
}
|
|
4031
|
+
if (duplicate.length > 0) {
|
|
4032
|
+
problems.push(
|
|
4033
|
+
`field(s) appear in BOTH IN_PROJECT_ALLOWED_KEYS and KNOWN_DENIED_IN_PROJECT: ` + duplicate.join(", ") + ". The allow-list wins at runtime; remove from one of the two."
|
|
4034
|
+
);
|
|
4035
|
+
}
|
|
4036
|
+
if (problems.length > 0) {
|
|
4037
|
+
throw new Error(
|
|
4038
|
+
`stripUnsafeInProjectFields drift check failed:
|
|
4039
|
+
- ${problems.join("\n - ")}`
|
|
4040
|
+
);
|
|
4041
|
+
}
|
|
4042
|
+
}
|
|
4043
|
+
var driftChecked = false;
|
|
3802
4044
|
function stripUnsafeInProjectFields(inProject, sourcePath, warn = (msg) => console.warn(msg)) {
|
|
4045
|
+
if (!driftChecked) {
|
|
4046
|
+
assertInProjectAllowListComplete();
|
|
4047
|
+
driftChecked = true;
|
|
4048
|
+
}
|
|
3803
4049
|
const stripped = [];
|
|
3804
4050
|
const out = {};
|
|
3805
4051
|
for (const [k, v] of Object.entries(inProject)) {
|
|
3806
|
-
if (
|
|
3807
|
-
|
|
4052
|
+
if (IN_PROJECT_ALLOWED_KEYS.has(k)) {
|
|
4053
|
+
out[k] = v;
|
|
3808
4054
|
continue;
|
|
3809
4055
|
}
|
|
3810
|
-
|
|
4056
|
+
stripped.push(k);
|
|
4057
|
+
}
|
|
4058
|
+
const outTools = out["tools"];
|
|
4059
|
+
if (outTools && typeof outTools === "object") {
|
|
4060
|
+
const execCfg = outTools["exec"];
|
|
4061
|
+
if (execCfg && typeof execCfg === "object" && "allow" in execCfg) {
|
|
4062
|
+
const clonedExec = { ...execCfg };
|
|
4063
|
+
delete clonedExec["allow"];
|
|
4064
|
+
out["tools"] = {
|
|
4065
|
+
...outTools,
|
|
4066
|
+
exec: clonedExec
|
|
4067
|
+
};
|
|
4068
|
+
stripped.push("tools.exec.allow");
|
|
4069
|
+
}
|
|
3811
4070
|
}
|
|
3812
4071
|
if (stripped.length > 0) {
|
|
3813
4072
|
warn(
|
|
@@ -3816,7 +4075,7 @@ function stripUnsafeInProjectFields(inProject, sourcePath, warn = (msg) => conso
|
|
|
3816
4075
|
event: "config.in_project_unsafe_fields_ignored",
|
|
3817
4076
|
path: sourcePath,
|
|
3818
4077
|
ignoredKeys: stripped,
|
|
3819
|
-
message: `Ignored ${stripped.length}
|
|
4078
|
+
message: `Ignored ${stripped.length} field(s) from the repo-committed config "${sourcePath}": ${stripped.join(", ")}. Only a small allow-list of benign preferences (model, context, tools limits, features, \u2026) may be set by <project>/.wrongstack/config.json. Everything else must live in your personal ~/.wrongstack/config.json.`,
|
|
3820
4079
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
3821
4080
|
})
|
|
3822
4081
|
);
|
|
@@ -3860,6 +4119,7 @@ var DefaultConfigLoader = class {
|
|
|
3860
4119
|
}
|
|
3861
4120
|
async load(opts = {}) {
|
|
3862
4121
|
let cfg = { ...BEHAVIOR_DEFAULTS };
|
|
4122
|
+
await this.ensureGlobalDefaults();
|
|
3863
4123
|
const inProjectCollides = samePath(this.paths.inProjectConfig, this.paths.globalConfig) || samePath(this.paths.inProjectConfig, this.paths.projectLocalConfig);
|
|
3864
4124
|
const [global, local, inProject] = await Promise.all([
|
|
3865
4125
|
this.readJson(this.paths.globalConfig),
|
|
@@ -3924,6 +4184,80 @@ var DefaultConfigLoader = class {
|
|
|
3924
4184
|
}
|
|
3925
4185
|
return Object.freeze(cfg);
|
|
3926
4186
|
}
|
|
4187
|
+
async ensureGlobalDefaults() {
|
|
4188
|
+
const fp = this.paths.globalConfig;
|
|
4189
|
+
const t0 = Date.now();
|
|
4190
|
+
try {
|
|
4191
|
+
await withFileLock(fp, async () => {
|
|
4192
|
+
let parsed;
|
|
4193
|
+
try {
|
|
4194
|
+
const raw = await fsp.readFile(fp, "utf8");
|
|
4195
|
+
const result = safeParse(raw);
|
|
4196
|
+
if (!result.ok || !isPlainRecord(result.value)) {
|
|
4197
|
+
return;
|
|
4198
|
+
}
|
|
4199
|
+
parsed = result.value;
|
|
4200
|
+
} catch (err) {
|
|
4201
|
+
if (err.code !== "ENOENT") {
|
|
4202
|
+
this.events?.emit("storage.error", {
|
|
4203
|
+
sessionId: "~config~",
|
|
4204
|
+
store: "config",
|
|
4205
|
+
filePath: fp,
|
|
4206
|
+
operation: "ensure_defaults",
|
|
4207
|
+
outcome: "failure",
|
|
4208
|
+
error: storageErrorString(err),
|
|
4209
|
+
recoverable: false,
|
|
4210
|
+
durationMs: Date.now() - t0,
|
|
4211
|
+
...this.traceId !== void 0 ? { traceId: this.traceId } : {}
|
|
4212
|
+
});
|
|
4213
|
+
console.warn(JSON.stringify({
|
|
4214
|
+
level: "warn",
|
|
4215
|
+
event: "config.defaults_read_failed",
|
|
4216
|
+
path: fp,
|
|
4217
|
+
message: toErrorMessage(err),
|
|
4218
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
4219
|
+
}));
|
|
4220
|
+
return;
|
|
4221
|
+
}
|
|
4222
|
+
parsed = {};
|
|
4223
|
+
}
|
|
4224
|
+
const { value, changed } = fillMissingDefaults(
|
|
4225
|
+
parsed,
|
|
4226
|
+
BEHAVIOR_DEFAULTS
|
|
4227
|
+
);
|
|
4228
|
+
if (!changed) return;
|
|
4229
|
+
await atomicWrite(fp, JSON.stringify(value, null, 2), { mode: 384 });
|
|
4230
|
+
this.events?.emit("storage.write", {
|
|
4231
|
+
sessionId: "~config~",
|
|
4232
|
+
store: "config",
|
|
4233
|
+
filePath: fp,
|
|
4234
|
+
operation: "ensure_defaults",
|
|
4235
|
+
outcome: "success",
|
|
4236
|
+
durationMs: Date.now() - t0,
|
|
4237
|
+
...this.traceId !== void 0 ? { traceId: this.traceId } : {}
|
|
4238
|
+
});
|
|
4239
|
+
});
|
|
4240
|
+
} catch (err) {
|
|
4241
|
+
this.events?.emit("storage.error", {
|
|
4242
|
+
sessionId: "~config~",
|
|
4243
|
+
store: "config",
|
|
4244
|
+
filePath: fp,
|
|
4245
|
+
operation: "ensure_defaults",
|
|
4246
|
+
outcome: "failure",
|
|
4247
|
+
error: storageErrorString(err),
|
|
4248
|
+
recoverable: false,
|
|
4249
|
+
durationMs: Date.now() - t0,
|
|
4250
|
+
...this.traceId !== void 0 ? { traceId: this.traceId } : {}
|
|
4251
|
+
});
|
|
4252
|
+
console.warn(JSON.stringify({
|
|
4253
|
+
level: "warn",
|
|
4254
|
+
event: "config.defaults_write_failed",
|
|
4255
|
+
path: fp,
|
|
4256
|
+
message: toErrorMessage(err),
|
|
4257
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
4258
|
+
}));
|
|
4259
|
+
}
|
|
4260
|
+
}
|
|
3927
4261
|
/**
|
|
3928
4262
|
* Persist a sync config to ~/.wrongstack/sync.json, with the token encrypted
|
|
3929
4263
|
* by the vault (if provided). The file is isolated from the main config
|
|
@@ -4386,6 +4720,34 @@ var DefaultSessionReader = class {
|
|
|
4386
4720
|
ids = filtered.map((s) => s.id);
|
|
4387
4721
|
}
|
|
4388
4722
|
const hits = [];
|
|
4723
|
+
const streaming = this.store.searchEvents?.bind(this.store);
|
|
4724
|
+
if (streaming) {
|
|
4725
|
+
for (const id of ids) {
|
|
4726
|
+
const matched = await streaming(
|
|
4727
|
+
id,
|
|
4728
|
+
(ev) => {
|
|
4729
|
+
if (allowedTypes && !allowedTypes.has(ev.type)) return false;
|
|
4730
|
+
const text = eventText(ev);
|
|
4731
|
+
if (text === null) return false;
|
|
4732
|
+
return matcher(text) !== null;
|
|
4733
|
+
},
|
|
4734
|
+
{ limit: limit - hits.length }
|
|
4735
|
+
);
|
|
4736
|
+
for (const m of matched) {
|
|
4737
|
+
const text = expectDefined(eventText(m.event));
|
|
4738
|
+
const hit = expectDefined(matcher(text));
|
|
4739
|
+
hits.push({
|
|
4740
|
+
sessionId: id,
|
|
4741
|
+
eventIndex: m.eventIndex,
|
|
4742
|
+
ts: m.ts,
|
|
4743
|
+
type: m.event.type,
|
|
4744
|
+
snippet: snippetOf(text, hit.start, hit.end)
|
|
4745
|
+
});
|
|
4746
|
+
if (hits.length >= limit) return hits;
|
|
4747
|
+
}
|
|
4748
|
+
}
|
|
4749
|
+
return hits;
|
|
4750
|
+
}
|
|
4389
4751
|
for (const id of ids) {
|
|
4390
4752
|
let data;
|
|
4391
4753
|
try {
|
|
@@ -6127,6 +6489,10 @@ var AGENT_REAP_MS = 3e4;
|
|
|
6127
6489
|
var AGENT_SWEEP_INTERVAL_MS = 1e4;
|
|
6128
6490
|
var PARTIAL_TEXT_CAP = 1200;
|
|
6129
6491
|
var PARTIAL_FLUSH_THROTTLE_MS = 300;
|
|
6492
|
+
function clampPct(pct) {
|
|
6493
|
+
if (!Number.isFinite(pct)) return 0;
|
|
6494
|
+
return Math.max(0, Math.min(100, pct));
|
|
6495
|
+
}
|
|
6130
6496
|
var AgentStatusTracker = class {
|
|
6131
6497
|
events;
|
|
6132
6498
|
registry;
|
|
@@ -6278,7 +6644,7 @@ var AgentStatusTracker = class {
|
|
|
6278
6644
|
this.events.onPattern("ctx.pct", (_e, payload) => {
|
|
6279
6645
|
const p = payload;
|
|
6280
6646
|
if (typeof p?.load === "number" && Number.isFinite(p.load)) {
|
|
6281
|
-
this.leaderCtxPct = Math.round(p.load * 100);
|
|
6647
|
+
this.leaderCtxPct = clampPct(Math.round(p.load * 100));
|
|
6282
6648
|
this.flush();
|
|
6283
6649
|
}
|
|
6284
6650
|
})
|
|
@@ -6320,7 +6686,7 @@ var AgentStatusTracker = class {
|
|
|
6320
6686
|
const p = payload;
|
|
6321
6687
|
if (!p?.subagentId) return;
|
|
6322
6688
|
const entry = touch(p.subagentId);
|
|
6323
|
-
if (typeof p.load === "number") entry.ctxPct = Math.round(p.load * 100);
|
|
6689
|
+
if (typeof p.load === "number") entry.ctxPct = clampPct(Math.round(p.load * 100));
|
|
6324
6690
|
this.flush();
|
|
6325
6691
|
})
|
|
6326
6692
|
);
|
|
@@ -6481,7 +6847,7 @@ var AgentStatusTracker = class {
|
|
|
6481
6847
|
const providerMax = c.provider?.capabilities?.maxContext;
|
|
6482
6848
|
const maxContext = typeof metaLimit === "number" && metaLimit > 0 ? metaLimit : typeof providerMax === "number" && providerMax > 0 ? providerMax : void 0;
|
|
6483
6849
|
if (typeof c.lastRequestTokens === "number" && c.lastRequestTokens > 0 && maxContext !== void 0) {
|
|
6484
|
-
this.leaderCtxPct = Math.round(c.lastRequestTokens / maxContext * 100);
|
|
6850
|
+
this.leaderCtxPct = clampPct(Math.round(c.lastRequestTokens / maxContext * 100));
|
|
6485
6851
|
}
|
|
6486
6852
|
}
|
|
6487
6853
|
};
|