@wrongstack/core 0.310.1 → 0.313.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/chronicle/index.js +84 -6391
- package/dist/chronicle/project-server.js +84 -4868
- package/dist/chunk-2BUUIMQB.js +225 -0
- package/dist/chunk-2FK4WTFF.js +207 -0
- package/dist/chunk-2FQL4PDC.js +292 -0
- package/dist/chunk-2KKODIQU.js +2256 -0
- package/dist/chunk-2YU4WVBW.js +134 -0
- package/dist/chunk-3E244UDA.js +356 -0
- package/dist/chunk-3XPVB7BA.js +135 -0
- package/dist/chunk-4LJJYBAU.js +388 -0
- package/dist/chunk-4VWO3ZXL.js +342 -0
- package/dist/chunk-4XV6IR37.js +187 -0
- package/dist/chunk-4ZHTKJHM.js +183 -0
- package/dist/chunk-52RTVH4M.js +361 -0
- package/dist/chunk-57GEWK5X.js +26 -0
- package/dist/chunk-5DSMEVA4.js +931 -0
- package/dist/chunk-5RP3QTRL.js +1223 -0
- package/dist/chunk-5S437PRC.js +50 -0
- package/dist/chunk-5XDUGTKN.js +511 -0
- package/dist/chunk-62V2AFVG.js +422 -0
- package/dist/chunk-65RDIOR2.js +2470 -0
- package/dist/chunk-6AKOTGLM.js +597 -0
- package/dist/chunk-7ZHZE5EO.js +28 -0
- package/dist/chunk-A455ATZB.js +140 -0
- package/dist/chunk-AD7ZFZCS.js +46 -0
- package/dist/chunk-AI4LLQ2U.js +856 -0
- package/dist/chunk-ASX6AW36.js +789 -0
- package/dist/chunk-AT4V4XGI.js +3522 -0
- package/dist/chunk-AWNQ6ED6.js +311 -0
- package/dist/chunk-B4AMLZPB.js +9 -0
- package/dist/chunk-BAKVJLEV.js +417 -0
- package/dist/chunk-BJHVULHO.js +55 -0
- package/dist/chunk-CB2HFKTP.js +9 -0
- package/dist/chunk-CE4ZOCOI.js +1640 -0
- package/dist/chunk-CQQL4ZOQ.js +151 -0
- package/dist/chunk-DEIQMBD2.js +65 -0
- package/dist/chunk-E6I5RXVK.js +58 -0
- package/dist/chunk-EFEHDQGY.js +1589 -0
- package/dist/chunk-EODDVJBM.js +82 -0
- package/dist/chunk-EPC3GZD4.js +308 -0
- package/dist/chunk-FAYRX2AD.js +13 -0
- package/dist/chunk-FFSX2QDQ.js +362 -0
- package/dist/chunk-FHAMQS7Q.js +5856 -0
- package/dist/chunk-FIV4IJL7.js +2263 -0
- package/dist/chunk-FNXVT7HF.js +52 -0
- package/dist/chunk-FSWCWSTS.js +395 -0
- package/dist/chunk-FW5LDDMJ.js +16464 -0
- package/dist/chunk-FXQLIX3K.js +211 -0
- package/dist/chunk-G5AAKEEZ.js +228 -0
- package/dist/chunk-G5S3S5ZN.js +38 -0
- package/dist/chunk-GAZEWQEZ.js +231 -0
- package/dist/chunk-GFJOMSHG.js +125 -0
- package/dist/chunk-GFXZTHNI.js +158 -0
- package/dist/chunk-GM54GJBU.js +960 -0
- package/dist/chunk-GPQ3NJPR.js +900 -0
- package/dist/chunk-GTCU6DZ3.js +1 -0
- package/dist/chunk-H5E77KUJ.js +15 -0
- package/dist/chunk-H72H4XDU.js +1023 -0
- package/dist/chunk-HA4ZYA6T.js +178 -0
- package/dist/chunk-I45KAW2N.js +5020 -0
- package/dist/chunk-IQ35HMQL.js +1396 -0
- package/dist/chunk-IYFBFX34.js +86 -0
- package/dist/chunk-JJPMWPB6.js +109 -0
- package/dist/chunk-JTHKOYWU.js +663 -0
- package/dist/chunk-JVGPR3TS.js +365 -0
- package/dist/chunk-JVKB2TBL.js +48 -0
- package/dist/chunk-JX7VBZDK.js +31 -0
- package/dist/chunk-K3G6JBUC.js +5232 -0
- package/dist/chunk-K4YUNKU7.js +589 -0
- package/dist/chunk-KBZGE6LN.js +710 -0
- package/dist/chunk-KDQJCT2J.js +45 -0
- package/dist/chunk-KI4L2DUL.js +560 -0
- package/dist/chunk-KJ2ZTQSL.js +47 -0
- package/dist/chunk-KSJ5UTP7.js +154 -0
- package/dist/chunk-LHOA5DWA.js +28 -0
- package/dist/chunk-LX5QWLBL.js +27 -0
- package/dist/chunk-LZDDLNCZ.js +279 -0
- package/dist/chunk-M2WF6AXG.js +115 -0
- package/dist/chunk-M7BS2K6U.js +1 -0
- package/dist/chunk-NDBIPFNY.js +102 -0
- package/dist/chunk-NEMIWEXC.js +1199 -0
- package/dist/chunk-NFAYHPRH.js +323 -0
- package/dist/chunk-O37BQ65S.js +21 -0
- package/dist/chunk-O74MJHXU.js +187 -0
- package/dist/chunk-OJZEX73F.js +112 -0
- package/dist/chunk-PAAWLLZX.js +74 -0
- package/dist/chunk-PFXFQQRT.js +339 -0
- package/dist/chunk-PFZO3C6H.js +14 -0
- package/dist/chunk-PHH7LD45.js +113 -0
- package/dist/chunk-QRTG4XTI.js +188 -0
- package/dist/chunk-QVOVMXJR.js +1351 -0
- package/dist/chunk-RCQYT2I4.js +757 -0
- package/dist/chunk-RD6DEE36.js +1178 -0
- package/dist/chunk-RJIZEJ42.js +30 -0
- package/dist/chunk-RPOA7IAE.js +150 -0
- package/dist/chunk-SN2DQRL6.js +1172 -0
- package/dist/chunk-SQJVFEBV.js +41 -0
- package/dist/chunk-SQP64RCS.js +5391 -0
- package/dist/chunk-SVT4RNTR.js +49 -0
- package/dist/chunk-SWUFN7XM.js +43 -0
- package/dist/chunk-SXMVYC5H.js +174 -0
- package/dist/chunk-SZ6AYUIZ.js +23 -0
- package/dist/chunk-T3KGZBU5.js +3171 -0
- package/dist/chunk-TBRL2RCC.js +9 -0
- package/dist/chunk-TRT2HRWZ.js +18 -0
- package/dist/chunk-TYW2GI5I.js +1077 -0
- package/dist/chunk-UIWONWVG.js +4959 -0
- package/dist/chunk-VB3H5WWB.js +151 -0
- package/dist/chunk-W4A6QA3D.js +258 -0
- package/dist/chunk-WBPVKEEE.js +227 -0
- package/dist/chunk-WEBMSQP2.js +123 -0
- package/dist/chunk-WOEZV3Q4.js +333 -0
- package/dist/chunk-WQQON3SV.js +473 -0
- package/dist/chunk-WQTOVMGV.js +119 -0
- package/dist/chunk-WZO23AWO.js +2779 -0
- package/dist/chunk-XBDP4QPW.js +7 -0
- package/dist/chunk-XEBHSJLT.js +103 -0
- package/dist/chunk-XQ2ECNK3.js +1 -0
- package/dist/chunk-XQ2XGIBF.js +2086 -0
- package/dist/chunk-Y2GE5TSI.js +355 -0
- package/dist/chunk-YBUJCZ57.js +351 -0
- package/dist/chunk-YNCVSFGF.js +149 -0
- package/dist/chunk-YUPMXOGP.js +282 -0
- package/dist/chunk-YY6APYUM.js +49 -0
- package/dist/chunk-Z2IJUO45.js +691 -0
- package/dist/chunk-ZEHUCJHY.js +129 -0
- package/dist/chunk-ZYU2YOJ6.js +1496 -0
- package/dist/chunk-ZZ4V3WIZ.js +163 -0
- package/dist/coordination/agents/index.js +145 -6260
- package/dist/coordination/index.js +365 -34323
- package/dist/coordination/mailbox-project-server.js +48 -3220
- package/dist/coordination/mailbox-types.d.ts +13 -1
- package/dist/coordination/provider-status-tracker.d.ts +4 -0
- package/dist/coordination/sqlite-mailbox.d.ts +2 -1
- package/dist/core/agent.d.ts +14 -1
- package/dist/core/index.js +267 -12479
- package/dist/core/model-ref.js +5 -23
- package/dist/core/provider-runner.d.ts +36 -1
- package/dist/design/index.js +50 -1087
- package/dist/execution/index.d.ts +1 -1
- package/dist/execution/index.js +1599 -21887
- package/dist/execution/prompt-enhancer.js +16 -535
- package/dist/execution/retry-policy.d.ts +31 -1
- package/dist/extension/index.js +7 -311
- package/dist/goal/index.js +33 -3435
- package/dist/hooks/index.js +14 -1138
- package/dist/hq/index.js +112 -5139
- package/dist/hq/protocol.js +21 -668
- package/dist/index.js +1410 -92655
- package/dist/infrastructure/index.js +64 -4811
- package/dist/kernel/events/provider-events.d.ts +15 -0
- package/dist/kernel/events/wrongtrace-events.d.ts +26 -0
- package/dist/kernel/events.d.ts +16 -7
- package/dist/kernel/index.js +14 -992
- package/dist/models/index.js +40 -1117
- package/dist/notifications/index.js +3 -108
- package/dist/observability/index.js +17 -279
- package/dist/plugin/index.js +584 -14835
- package/dist/prompts/index.js +14 -948
- package/dist/registry/index.js +9 -822
- package/dist/registry-R23UBE7H.js +14 -0
- package/dist/replay/index.js +6 -84
- package/dist/review-finding-store-DKAV3AS6.js +21 -0
- package/dist/review-report-store-OWY3EC3N.js +19 -0
- package/dist/security/index.js +114 -2202
- package/dist/session-catalog/index.js +36 -2103
- package/dist/session-catalog/project-server.js +42 -1435
- package/dist/skills/index.js +35 -1578
- package/dist/storage/index.js +182 -15600
- package/dist/tasking/index.js +10 -676
- package/dist/tools/index.js +52 -9589
- package/dist/types/config/autonomy.d.ts +5 -0
- package/dist/types/config/tools.d.ts +2 -2
- package/dist/types/config/ui.d.ts +1 -1
- package/dist/types/errors.d.ts +18 -0
- package/dist/types/index.js +121 -1341
- package/dist/types/provider-runner.d.ts +8 -0
- package/dist/types/session-markers.js +8 -144
- package/dist/utils/error.js +3 -4
- package/dist/utils/expect-defined.js +3 -9
- package/dist/utils/heap-watchdog.js +6 -706
- package/dist/utils/index.js +269 -5685
- package/dist/utils/sage-output-block.js +5 -42
- package/dist/wiring/proxy-rewrite.d.ts +92 -4
- package/dist/wiring/proxy-rewrite.js +20 -61
- package/dist/worktree/index.js +6 -887
- package/package.json +4 -4
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
// src/utils/child-env.ts
|
|
2
|
+
var ALLOWED_KEYS = /* @__PURE__ */ new Set([
|
|
3
|
+
"PATH",
|
|
4
|
+
"HOME",
|
|
5
|
+
"USER",
|
|
6
|
+
"USERNAME",
|
|
7
|
+
"LOGNAME",
|
|
8
|
+
"SHELL",
|
|
9
|
+
"LANG",
|
|
10
|
+
"LC_ALL",
|
|
11
|
+
"LC_CTYPE",
|
|
12
|
+
"TERM",
|
|
13
|
+
"TZ",
|
|
14
|
+
"TMPDIR",
|
|
15
|
+
"TEMP",
|
|
16
|
+
"TMP",
|
|
17
|
+
"PWD",
|
|
18
|
+
"OLDPWD",
|
|
19
|
+
"COMSPEC",
|
|
20
|
+
"SYSTEMROOT",
|
|
21
|
+
"SYSTEMDRIVE",
|
|
22
|
+
"WINDIR",
|
|
23
|
+
"PROGRAMFILES",
|
|
24
|
+
"PROGRAMFILES(X86)",
|
|
25
|
+
"PROGRAMDATA",
|
|
26
|
+
"APPDATA",
|
|
27
|
+
"LOCALAPPDATA",
|
|
28
|
+
"USERPROFILE",
|
|
29
|
+
"PUBLIC",
|
|
30
|
+
"PATHEXT"
|
|
31
|
+
]);
|
|
32
|
+
var SECRET_NAME_PARTS = [
|
|
33
|
+
"TOKEN",
|
|
34
|
+
"SECRET",
|
|
35
|
+
"PASSWORD",
|
|
36
|
+
"PASSWD",
|
|
37
|
+
// WRONGSTACK_VAULT_PASSPHRASE is the vault KEK. Without this entry it matched
|
|
38
|
+
// no rule here and fell through to the `WRONGSTACK_` prefix allow-rule, so the
|
|
39
|
+
// key that protects the credential vault was forwarded to every child process
|
|
40
|
+
// — including the agent's own exec/bash tools and MCP stdio servers (WS-033).
|
|
41
|
+
"PASSPHRASE",
|
|
42
|
+
"AUTH",
|
|
43
|
+
"CRED",
|
|
44
|
+
"BEARER",
|
|
45
|
+
"COOKIE",
|
|
46
|
+
"PRIVATE"
|
|
47
|
+
];
|
|
48
|
+
function looksSecret(name) {
|
|
49
|
+
const upper = name.toUpperCase();
|
|
50
|
+
for (const p of SECRET_NAME_PARTS) {
|
|
51
|
+
if (upper.includes(p)) return true;
|
|
52
|
+
}
|
|
53
|
+
if (/(?:^|_)KEY(?:$|_|S$)/i.test(upper)) return true;
|
|
54
|
+
if (/API[_-]?KEY/i.test(upper)) return true;
|
|
55
|
+
if (/ACCESS[_-]?KEY/i.test(upper)) return true;
|
|
56
|
+
if (/SESSION[_-]?ID/i.test(upper) === false && /SESSION/i.test(upper)) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
function valueHasEmbeddedCredential(value) {
|
|
62
|
+
return /\b[a-z][a-z0-9+.-]*:\/\/[^/\s:@]*:[^/\s@]+@/i.test(value);
|
|
63
|
+
}
|
|
64
|
+
var NODE_OPTIONS_INJECTION_FLAG = /^(?:--require|-r|--import|--loader|--experimental-loader)$/;
|
|
65
|
+
var NODE_OPTIONS_INJECTION_FLAG_EQ = /^(?:--require|-r|--import|--loader|--experimental-loader)=/;
|
|
66
|
+
function sanitizeNodeOptions(value) {
|
|
67
|
+
const tokens = value.split(/\s+/).filter(Boolean);
|
|
68
|
+
const kept = [];
|
|
69
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
70
|
+
const tok = tokens[i];
|
|
71
|
+
if (NODE_OPTIONS_INJECTION_FLAG_EQ.test(tok)) continue;
|
|
72
|
+
if (NODE_OPTIONS_INJECTION_FLAG.test(tok)) {
|
|
73
|
+
i++;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
kept.push(tok);
|
|
77
|
+
}
|
|
78
|
+
return kept.join(" ");
|
|
79
|
+
}
|
|
80
|
+
var gitIdentity = null;
|
|
81
|
+
function configureChildEnvGitIdentity(identity) {
|
|
82
|
+
const name = identity?.name?.trim();
|
|
83
|
+
const email = identity?.email?.trim();
|
|
84
|
+
gitIdentity = name || email ? { name: name || void 0, email: email || void 0 } : null;
|
|
85
|
+
}
|
|
86
|
+
function getChildEnvGitIdentity() {
|
|
87
|
+
return gitIdentity;
|
|
88
|
+
}
|
|
89
|
+
function buildChildEnv(optsOrSessionId) {
|
|
90
|
+
const opts = typeof optsOrSessionId === "string" ? { sessionId: optsOrSessionId } : optsOrSessionId ?? {};
|
|
91
|
+
const hasOwn = Object.hasOwn(process.env, "WRONGSTACK_CHILD_ENV_PASSTHROUGH");
|
|
92
|
+
const legacyHasOwn = Object.hasOwn(process.env, "WRONGSTACK_BASH_ENV_PASSTHROUGH");
|
|
93
|
+
const passthrough = hasOwn && process.env["WRONGSTACK_CHILD_ENV_PASSTHROUGH"] === "1" || legacyHasOwn && process.env["WRONGSTACK_BASH_ENV_PASSTHROUGH"] === "1";
|
|
94
|
+
if (passthrough && !process.env["CI"]) {
|
|
95
|
+
console.warn(
|
|
96
|
+
"[agent] WARNING: WRONGSTACK_*_ENV_PASSTHROUGH=1 is active \u2014\n all parent env vars (including API keys) forwarded to child processes.\n Do not use on shared or multi-tenant systems."
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
const out = {};
|
|
100
|
+
const nodeEnvDefaulted = process.env["WRONGSTACK_NODE_ENV_DEFAULTED"] === "1";
|
|
101
|
+
for (const [k, v] of Object.entries(process.env)) {
|
|
102
|
+
if (v === void 0) continue;
|
|
103
|
+
if (nodeEnvDefaulted && (k === "NODE_ENV" || k === "WRONGSTACK_NODE_ENV_DEFAULTED")) continue;
|
|
104
|
+
if (passthrough) {
|
|
105
|
+
out[k] = v;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
const upper = k.toUpperCase();
|
|
109
|
+
if (valueHasEmbeddedCredential(v)) continue;
|
|
110
|
+
if (ALLOWED_KEYS.has(upper)) {
|
|
111
|
+
out[k] = v;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (looksSecret(upper)) continue;
|
|
115
|
+
if (upper === "NODE_OPTIONS") {
|
|
116
|
+
const sanitized = sanitizeNodeOptions(v);
|
|
117
|
+
if (sanitized) out[k] = sanitized;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (upper.startsWith("NODE_") || upper.startsWith("NPM_") || upper.startsWith("PNPM_") || upper.startsWith("YARN_") || upper.startsWith("GIT_") || upper.startsWith("CI") || upper.startsWith("XDG_") || // Our own non-secret knobs (WRONGSTACK_HOME, WRONGSTACK_SESSION_ID, …).
|
|
121
|
+
// Secrets never live in WRONGSTACK_* env vars (they're in the encrypted
|
|
122
|
+
// vault). Forwarding keeps child wstack processes — e.g. ones spawned
|
|
123
|
+
// by the test suite — inside the same redirected global root.
|
|
124
|
+
upper.startsWith("WRONGSTACK_") || upper === "EDITOR" || upper === "VISUAL" || upper === "PAGER") {
|
|
125
|
+
out[k] = v;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (gitIdentity) {
|
|
129
|
+
if (gitIdentity.name) {
|
|
130
|
+
out["GIT_AUTHOR_NAME"] = gitIdentity.name;
|
|
131
|
+
out["GIT_COMMITTER_NAME"] = gitIdentity.name;
|
|
132
|
+
}
|
|
133
|
+
if (gitIdentity.email) {
|
|
134
|
+
out["GIT_AUTHOR_EMAIL"] = gitIdentity.email;
|
|
135
|
+
out["GIT_COMMITTER_EMAIL"] = gitIdentity.email;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (opts.extra) {
|
|
139
|
+
Object.assign(out, opts.extra);
|
|
140
|
+
}
|
|
141
|
+
if (opts.sessionId) out["WRONGSTACK_SESSION_ID"] = opts.sessionId;
|
|
142
|
+
return out;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export {
|
|
146
|
+
sanitizeNodeOptions,
|
|
147
|
+
configureChildEnvGitIdentity,
|
|
148
|
+
getChildEnvGitIdentity,
|
|
149
|
+
buildChildEnv
|
|
150
|
+
};
|
|
151
|
+
//# sourceMappingURL=chunk-VB3H5WWB.js.map
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
// src/coordination/mailbox-type-properties.ts
|
|
2
|
+
var MAILBOX_TYPE_PROPERTIES = {
|
|
3
|
+
note: {
|
|
4
|
+
category: "informational",
|
|
5
|
+
expectsReply: false,
|
|
6
|
+
requiresAction: false,
|
|
7
|
+
backgroundEligible: false,
|
|
8
|
+
outOfBand: false,
|
|
9
|
+
renderPriority: 20,
|
|
10
|
+
recipientObligation: "Read for context; no reply needed.",
|
|
11
|
+
senderGuidance: "General-purpose FYI. Use when no more specific type applies."
|
|
12
|
+
},
|
|
13
|
+
ask: {
|
|
14
|
+
category: "actionable",
|
|
15
|
+
expectsReply: true,
|
|
16
|
+
requiresAction: true,
|
|
17
|
+
backgroundEligible: true,
|
|
18
|
+
outOfBand: false,
|
|
19
|
+
renderPriority: 10,
|
|
20
|
+
recipientObligation: "Answer as soon as possible \u2014 the sender is waiting.",
|
|
21
|
+
senderGuidance: "Blocking question. Only use when you need an answer to proceed."
|
|
22
|
+
},
|
|
23
|
+
assign: {
|
|
24
|
+
category: "actionable",
|
|
25
|
+
expectsReply: false,
|
|
26
|
+
requiresAction: true,
|
|
27
|
+
backgroundEligible: true,
|
|
28
|
+
outOfBand: false,
|
|
29
|
+
renderPriority: 10,
|
|
30
|
+
recipientObligation: "Accept or decline; act on it when current operation allows.",
|
|
31
|
+
senderGuidance: 'Task delegation. Must be directed to a specific recipient (not "*").'
|
|
32
|
+
},
|
|
33
|
+
steer: {
|
|
34
|
+
category: "actionable",
|
|
35
|
+
expectsReply: false,
|
|
36
|
+
requiresAction: true,
|
|
37
|
+
backgroundEligible: true,
|
|
38
|
+
outOfBand: false,
|
|
39
|
+
renderPriority: 0,
|
|
40
|
+
// Always rendered first
|
|
41
|
+
recipientObligation: "Pause current approach, adjust per instruction, then resume.",
|
|
42
|
+
senderGuidance: "Mid-task direction change. The recipient is already working on something."
|
|
43
|
+
},
|
|
44
|
+
btw: {
|
|
45
|
+
category: "informational",
|
|
46
|
+
expectsReply: false,
|
|
47
|
+
requiresAction: false,
|
|
48
|
+
backgroundEligible: false,
|
|
49
|
+
outOfBand: false,
|
|
50
|
+
renderPriority: 30,
|
|
51
|
+
recipientObligation: "Absorb the information and stay on current task; no reply needed.",
|
|
52
|
+
senderGuidance: "Low-priority aside. Non-urgent info that can wait."
|
|
53
|
+
},
|
|
54
|
+
broadcast: {
|
|
55
|
+
category: "routing",
|
|
56
|
+
expectsReply: false,
|
|
57
|
+
requiresAction: false,
|
|
58
|
+
backgroundEligible: false,
|
|
59
|
+
outOfBand: false,
|
|
60
|
+
renderPriority: 20,
|
|
61
|
+
recipientObligation: 'Read if addressed to you (direct recipient, alias, or "*").',
|
|
62
|
+
senderGuidance: 'Multi-recipient envelope. Auto-selected when to is "*" or "@session".'
|
|
63
|
+
},
|
|
64
|
+
status: {
|
|
65
|
+
category: "informational",
|
|
66
|
+
expectsReply: false,
|
|
67
|
+
requiresAction: false,
|
|
68
|
+
backgroundEligible: false,
|
|
69
|
+
outOfBand: false,
|
|
70
|
+
renderPriority: 40,
|
|
71
|
+
recipientObligation: "Use to avoid redundant work; never act on as a task or question.",
|
|
72
|
+
senderGuidance: "Agent/system status update. Machine-generated, not for human-originated messages."
|
|
73
|
+
},
|
|
74
|
+
result: {
|
|
75
|
+
category: "informational",
|
|
76
|
+
expectsReply: false,
|
|
77
|
+
requiresAction: false,
|
|
78
|
+
backgroundEligible: true,
|
|
79
|
+
outOfBand: false,
|
|
80
|
+
renderPriority: 10,
|
|
81
|
+
recipientObligation: "Factor into next decision; treat as evidence, not a new task.",
|
|
82
|
+
senderGuidance: "Task completion notice. Share the outcome of finished work."
|
|
83
|
+
},
|
|
84
|
+
review: {
|
|
85
|
+
category: "actionable",
|
|
86
|
+
expectsReply: false,
|
|
87
|
+
requiresAction: true,
|
|
88
|
+
backgroundEligible: true,
|
|
89
|
+
outOfBand: false,
|
|
90
|
+
renderPriority: 10,
|
|
91
|
+
recipientObligation: "Inspect when convenient; no immediate reply required.",
|
|
92
|
+
senderGuidance: "Passive review request (code/doc/PR). No reply required."
|
|
93
|
+
},
|
|
94
|
+
control: {
|
|
95
|
+
category: "control_signal",
|
|
96
|
+
expectsReply: false,
|
|
97
|
+
requiresAction: false,
|
|
98
|
+
backgroundEligible: false,
|
|
99
|
+
outOfBand: true,
|
|
100
|
+
renderPriority: 999,
|
|
101
|
+
// Never rendered
|
|
102
|
+
recipientObligation: 'Handled by the agent loop, NOT folded into conversation. "interrupt" causes cooperative halt.',
|
|
103
|
+
senderGuidance: "RESERVED for runtime use. Agents must NOT send control messages."
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// src/coordination/mailbox-predicates.ts
|
|
108
|
+
function mailboxIdentityBase(agentId) {
|
|
109
|
+
return agentId.split(/[@#]/, 1)[0].trim().toLowerCase();
|
|
110
|
+
}
|
|
111
|
+
function isMailboxLeader(agentId, role) {
|
|
112
|
+
return mailboxIdentityBase(agentId) === "leader" || role?.trim().toLowerCase() === "leader";
|
|
113
|
+
}
|
|
114
|
+
function isMailboxSenderInFamily(senderId, family) {
|
|
115
|
+
const base = mailboxIdentityBase(senderId);
|
|
116
|
+
const normalizedFamily = family.trim().toLowerCase();
|
|
117
|
+
if (normalizedFamily.length === 0) return false;
|
|
118
|
+
return base === normalizedFamily || base.startsWith(`${normalizedFamily}-`);
|
|
119
|
+
}
|
|
120
|
+
function isMailboxMessageVisibleTo(message, agentId, role) {
|
|
121
|
+
return message.audience !== "leaders" || isMailboxLeader(agentId, role);
|
|
122
|
+
}
|
|
123
|
+
function validateSendType(type, to) {
|
|
124
|
+
if (type === "control") {
|
|
125
|
+
throw new TypeError('Type "control" is reserved for runtime use and cannot be set by agents');
|
|
126
|
+
}
|
|
127
|
+
const isMultiRecipient = to === "*" || to.startsWith("@session:");
|
|
128
|
+
if (type === "assign" && isMultiRecipient) {
|
|
129
|
+
throw new TypeError(
|
|
130
|
+
`Type "assign" requires a specific recipient \u2014 multi-recipient target "${to}" is ambiguous`
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
if (type === "steer" && isMultiRecipient) {
|
|
134
|
+
throw new TypeError(
|
|
135
|
+
`Type "steer" requires a specific recipient \u2014 multi-recipient target "${to}" is ambiguous`
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
var SESSION_RECIPIENT_PREFIX = "@session:";
|
|
140
|
+
function sessionRecipient(sessionId) {
|
|
141
|
+
const normalizedSessionId = sessionId.trim();
|
|
142
|
+
if (!normalizedSessionId) {
|
|
143
|
+
throw new TypeError('sessionId is required for the "@session" recipient');
|
|
144
|
+
}
|
|
145
|
+
return `${SESSION_RECIPIENT_PREFIX}${normalizedSessionId}`;
|
|
146
|
+
}
|
|
147
|
+
function normalizeRecipient(to, sessionId) {
|
|
148
|
+
const trimmed = to.trim();
|
|
149
|
+
const normalized = trimmed.toLowerCase();
|
|
150
|
+
if (normalized === "all") return "*";
|
|
151
|
+
if (normalized === "@session") return sessionRecipient(sessionId ?? "");
|
|
152
|
+
return trimmed;
|
|
153
|
+
}
|
|
154
|
+
function isMailboxReceiptRecordV2(value) {
|
|
155
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
156
|
+
const v = value;
|
|
157
|
+
if (v["__mailboxReceipt"] !== 2) return false;
|
|
158
|
+
if (typeof v["messageId"] !== "string" || v["messageId"].length === 0) return false;
|
|
159
|
+
if (typeof v["actorId"] !== "string" || v["actorId"].length === 0) return false;
|
|
160
|
+
if (typeof v["timestamp"] !== "string" || v["timestamp"].length === 0) return false;
|
|
161
|
+
if ("read" in v && typeof v["read"] !== "boolean") return false;
|
|
162
|
+
if ("completed" in v && typeof v["completed"] !== "boolean") return false;
|
|
163
|
+
if ("outcome" in v && v["outcome"] !== void 0 && typeof v["outcome"] !== "string")
|
|
164
|
+
return false;
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
function isActionRequiredForActor(message, projection) {
|
|
168
|
+
if (projection.legacyGlobalCompletion) return false;
|
|
169
|
+
if (message.deletedAt !== void 0) return false;
|
|
170
|
+
if (projection.completedByMe) return false;
|
|
171
|
+
return MAILBOX_TYPE_PROPERTIES[message.type]?.requiresAction === true;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// src/coordination/mailbox-auth-types.ts
|
|
175
|
+
var MAILBOX_CAPABILITY_IMPLICATIONS = {
|
|
176
|
+
"mail.read.all": ["mail.read.self"],
|
|
177
|
+
"mail.events.all": ["mail.events.self"],
|
|
178
|
+
"mail.send.directive": ["mail.send.actionable", "mail.send.informational"],
|
|
179
|
+
"mail.send.actionable": ["mail.send.informational"],
|
|
180
|
+
// Leaf capabilities imply nothing further.
|
|
181
|
+
"mail.send.informational": [],
|
|
182
|
+
"mail.read.self": [],
|
|
183
|
+
"mail.ack.self": [],
|
|
184
|
+
"mail.events.self": [],
|
|
185
|
+
"mail.presence.register.self": [],
|
|
186
|
+
"mail.presence.heartbeat.self": [],
|
|
187
|
+
"mail.presence.deregister.self": [],
|
|
188
|
+
"mail.presence.read": [],
|
|
189
|
+
"mail.retention.purge": [],
|
|
190
|
+
"mail.retention.clear": [],
|
|
191
|
+
"mail.admin.receipts": []
|
|
192
|
+
};
|
|
193
|
+
function expandMailboxCapabilities(caps) {
|
|
194
|
+
const result = /* @__PURE__ */ new Set();
|
|
195
|
+
const queue = [...caps];
|
|
196
|
+
while (queue.length > 0) {
|
|
197
|
+
const cap = queue.pop();
|
|
198
|
+
if (result.has(cap)) continue;
|
|
199
|
+
result.add(cap);
|
|
200
|
+
const implied = MAILBOX_CAPABILITY_IMPLICATIONS[cap];
|
|
201
|
+
if (implied) queue.push(...implied);
|
|
202
|
+
}
|
|
203
|
+
return result;
|
|
204
|
+
}
|
|
205
|
+
function hasMailboxCapability(actor, cap) {
|
|
206
|
+
if (actor.capabilities.has(cap)) return true;
|
|
207
|
+
const expanded = expandMailboxCapabilities(actor.capabilities);
|
|
208
|
+
return expanded.has(cap);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// src/coordination/mailbox-session-sync.ts
|
|
212
|
+
function isAffectedBySessionAffinity(message) {
|
|
213
|
+
return message.sessionAffinity !== void 0;
|
|
214
|
+
}
|
|
215
|
+
async function acceptMailboxMessageForSession(message, currentSessionId, ctx) {
|
|
216
|
+
if (!isAffectedBySessionAffinity(message)) return true;
|
|
217
|
+
const affinity = message.sessionAffinity;
|
|
218
|
+
if (affinity === null || typeof affinity !== "object" || Array.isArray(affinity)) {
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
if (affinity.sessionId !== void 0 && typeof affinity.sessionId !== "string" || affinity.reportId !== void 0 && typeof affinity.reportId !== "string") {
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
if (!currentSessionId) {
|
|
225
|
+
return ctx?.allowUnscoped === true;
|
|
226
|
+
}
|
|
227
|
+
if (typeof affinity.sessionId === "string" && affinity.sessionId.length > 0) {
|
|
228
|
+
if (affinity.sessionId !== currentSessionId) return false;
|
|
229
|
+
return true;
|
|
230
|
+
}
|
|
231
|
+
if (affinity.reportId && ctx?.resolveChimeraReportSessionId) {
|
|
232
|
+
try {
|
|
233
|
+
const resolved = await ctx.resolveChimeraReportSessionId(affinity.reportId);
|
|
234
|
+
if (resolved === currentSessionId) return true;
|
|
235
|
+
if (resolved !== void 0) return false;
|
|
236
|
+
} catch {
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (ctx?.allowUnscoped === true) return true;
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export {
|
|
244
|
+
MAILBOX_TYPE_PROPERTIES,
|
|
245
|
+
hasMailboxCapability,
|
|
246
|
+
mailboxIdentityBase,
|
|
247
|
+
isMailboxLeader,
|
|
248
|
+
isMailboxSenderInFamily,
|
|
249
|
+
isMailboxMessageVisibleTo,
|
|
250
|
+
validateSendType,
|
|
251
|
+
SESSION_RECIPIENT_PREFIX,
|
|
252
|
+
sessionRecipient,
|
|
253
|
+
normalizeRecipient,
|
|
254
|
+
isMailboxReceiptRecordV2,
|
|
255
|
+
isActionRequiredForActor,
|
|
256
|
+
acceptMailboxMessageForSession
|
|
257
|
+
};
|
|
258
|
+
//# sourceMappingURL=chunk-W4A6QA3D.js.map
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import {
|
|
2
|
+
color,
|
|
3
|
+
writeErr
|
|
4
|
+
} from "./chunk-4VWO3ZXL.js";
|
|
5
|
+
|
|
6
|
+
// src/infrastructure/logger.ts
|
|
7
|
+
import * as fsp from "node:fs/promises";
|
|
8
|
+
import * as path from "node:path";
|
|
9
|
+
var LEVEL_RANK = {
|
|
10
|
+
error: 0,
|
|
11
|
+
warn: 1,
|
|
12
|
+
info: 2,
|
|
13
|
+
debug: 3,
|
|
14
|
+
trace: 4
|
|
15
|
+
};
|
|
16
|
+
var COLORS = {
|
|
17
|
+
error: color.red,
|
|
18
|
+
warn: color.yellow,
|
|
19
|
+
info: color.cyan,
|
|
20
|
+
debug: color.gray,
|
|
21
|
+
trace: color.dim
|
|
22
|
+
};
|
|
23
|
+
var LOG_LEVELS = /* @__PURE__ */ new Set(["error", "warn", "info", "debug", "trace"]);
|
|
24
|
+
var LOG_FORMATS = /* @__PURE__ */ new Set(["pretty", "json"]);
|
|
25
|
+
var DefaultLogger = class _DefaultLogger {
|
|
26
|
+
/** How many file writes between rotation size checks (statSync is not free). */
|
|
27
|
+
static ROTATE_CHECK_EVERY = 100;
|
|
28
|
+
static MAX_PENDING_FILE_WRITES = 2e3;
|
|
29
|
+
static MAX_PENDING_FILE_BYTES = 8 * 1024 * 1024;
|
|
30
|
+
level;
|
|
31
|
+
file;
|
|
32
|
+
bindings;
|
|
33
|
+
format;
|
|
34
|
+
stderr;
|
|
35
|
+
maxFileBytes;
|
|
36
|
+
writesSinceRotateCheck = 0;
|
|
37
|
+
/**
|
|
38
|
+
* Serialized async tail for file writes. Every appendFile (and any
|
|
39
|
+
* chained rotation) is awaited through this promise so file I/O
|
|
40
|
+
* never overlaps itself — preserving the per-line ordering the
|
|
41
|
+
* sync version had, but without blocking the caller thread. Any
|
|
42
|
+
* rejection is swallowed (`catch(() => {})`) because logging must
|
|
43
|
+
* never crash the host.
|
|
44
|
+
*
|
|
45
|
+
* Children share the parent's tail: `child.tail === parent.tail`
|
|
46
|
+
* for the lifetime of the chain. Read/write access goes through
|
|
47
|
+
* `_tail` so that, when a child has been wired to a parent, both
|
|
48
|
+
* `enqueueRotate` and `log` always observe the parent's current tail
|
|
49
|
+
* rather than a stale snapshot taken at `child()` time.
|
|
50
|
+
*/
|
|
51
|
+
tail = Promise.resolve();
|
|
52
|
+
parent = null;
|
|
53
|
+
pendingFileWrites = 0;
|
|
54
|
+
pendingFileBytes = 0;
|
|
55
|
+
get root() {
|
|
56
|
+
return this.parent ? this.parent.root : this;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Resolve the current tail. For the root logger this is the field;
|
|
60
|
+
* for a child logger we always read through the parent so that a
|
|
61
|
+
* child's appends land on the parent's most recent tail, and a
|
|
62
|
+
* parent's `flush()` waits for everything the child chained.
|
|
63
|
+
*/
|
|
64
|
+
get _tail() {
|
|
65
|
+
return this.parent ? this.parent._tail : this.tail;
|
|
66
|
+
}
|
|
67
|
+
set _tail(next) {
|
|
68
|
+
if (this.parent) this.parent.tail = next;
|
|
69
|
+
else this.tail = next;
|
|
70
|
+
}
|
|
71
|
+
constructor(opts = {}) {
|
|
72
|
+
this.level = opts.level ?? parseLogLevel(process.env.WRONGSTACK_LOG_LEVEL);
|
|
73
|
+
this.file = opts.file;
|
|
74
|
+
this.bindings = opts.bindings ?? {};
|
|
75
|
+
this.format = opts.format ?? parseLogFormat(process.env.WRONGSTACK_LOG_FORMAT);
|
|
76
|
+
this.stderr = opts.stderr !== false;
|
|
77
|
+
this.maxFileBytes = opts.maxFileBytes ?? 10 * 1024 * 1024;
|
|
78
|
+
if (this.file) {
|
|
79
|
+
const dir = path.dirname(this.file);
|
|
80
|
+
this._tail = this._tail.then(async () => {
|
|
81
|
+
await fsp.mkdir(dir, { recursive: true });
|
|
82
|
+
}).catch(() => void 0);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
error(msg, ctx) {
|
|
86
|
+
this.log("error", msg, ctx);
|
|
87
|
+
}
|
|
88
|
+
warn(msg, ctx) {
|
|
89
|
+
this.log("warn", msg, ctx);
|
|
90
|
+
}
|
|
91
|
+
info(msg, ctx) {
|
|
92
|
+
this.log("info", msg, ctx);
|
|
93
|
+
}
|
|
94
|
+
debug(msg, ctx) {
|
|
95
|
+
this.log("debug", msg, ctx);
|
|
96
|
+
}
|
|
97
|
+
trace(msg, ctx) {
|
|
98
|
+
this.log("trace", msg, ctx);
|
|
99
|
+
}
|
|
100
|
+
child(bindings) {
|
|
101
|
+
const child = Object.create(_DefaultLogger.prototype);
|
|
102
|
+
child.level = this.level;
|
|
103
|
+
child.file = this.file;
|
|
104
|
+
child.bindings = { ...this.bindings, ...bindings };
|
|
105
|
+
child.format = this.format;
|
|
106
|
+
child.stderr = this.stderr;
|
|
107
|
+
child.maxFileBytes = this.maxFileBytes;
|
|
108
|
+
child.parent = this;
|
|
109
|
+
child.writesSinceRotateCheck = this.writesSinceRotateCheck;
|
|
110
|
+
return child;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Wait until all queued file writes (and any pending rotation) have
|
|
114
|
+
* completed. `log()` is fire-and-forget by design — the caller never
|
|
115
|
+
* blocks on disk — so tests, shutdown handlers, and processes that
|
|
116
|
+
* need a deterministic "everything is on disk now" guarantee should
|
|
117
|
+
* `await logger.flush()` before reading the file or exiting.
|
|
118
|
+
*/
|
|
119
|
+
flush() {
|
|
120
|
+
return this._tail;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Size-based rotation: when the file outgrows `maxFileBytes`, rename it to
|
|
124
|
+
* `<file>.1` (dropping the previous `.1`) so the live file restarts empty.
|
|
125
|
+
* Checked on the first write and every ROTATE_CHECK_EVERY writes after.
|
|
126
|
+
* Best-effort: a rename can fail on Windows while another process holds
|
|
127
|
+
* the file — the next check retries. Multiple processes appending to the
|
|
128
|
+
* same log all run this check; whoever crosses the threshold first wins.
|
|
129
|
+
*
|
|
130
|
+
* Async: the rotation runs on the file-write tail (so its writes don't
|
|
131
|
+
* interleave with the next append), and the caller never blocks on a
|
|
132
|
+
* statSync / renameSync syscall on the hot log path.
|
|
133
|
+
*/
|
|
134
|
+
enqueueRotate(file) {
|
|
135
|
+
if (this.writesSinceRotateCheck++ % _DefaultLogger.ROTATE_CHECK_EVERY !== 0) return;
|
|
136
|
+
this._tail = this._tail.then(async () => {
|
|
137
|
+
let st;
|
|
138
|
+
try {
|
|
139
|
+
st = await fsp.stat(file);
|
|
140
|
+
} catch {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
if (st.size < this.maxFileBytes) return;
|
|
144
|
+
try {
|
|
145
|
+
await fsp.rm(`${file}.1`, { force: true });
|
|
146
|
+
await fsp.rename(file, `${file}.1`);
|
|
147
|
+
} catch {
|
|
148
|
+
}
|
|
149
|
+
}).catch(() => void 0);
|
|
150
|
+
}
|
|
151
|
+
log(level, msg, ctx) {
|
|
152
|
+
const r = LEVEL_RANK[level];
|
|
153
|
+
const allowed = LEVEL_RANK[this.level];
|
|
154
|
+
if (r > allowed) return;
|
|
155
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
156
|
+
const entry = { ts, level, msg, ...this.bindings };
|
|
157
|
+
if (ctx !== void 0) {
|
|
158
|
+
entry.ctx = ctx instanceof Error ? { message: ctx.message, stack: ctx.stack } : ctx;
|
|
159
|
+
}
|
|
160
|
+
if (this.file) {
|
|
161
|
+
const line = `${JSON.stringify(entry)}
|
|
162
|
+
`;
|
|
163
|
+
const bytes = Buffer.byteLength(line, "utf8");
|
|
164
|
+
const root = this.root;
|
|
165
|
+
if (root.pendingFileWrites < _DefaultLogger.MAX_PENDING_FILE_WRITES && bytes <= _DefaultLogger.MAX_PENDING_FILE_BYTES && root.pendingFileBytes + bytes <= _DefaultLogger.MAX_PENDING_FILE_BYTES) {
|
|
166
|
+
root.pendingFileWrites += 1;
|
|
167
|
+
root.pendingFileBytes += bytes;
|
|
168
|
+
this.enqueueRotate(this.file);
|
|
169
|
+
this._tail = this._tail.then(() => fsp.appendFile(this.file, line, { mode: 384 })).catch(() => void 0).finally(() => {
|
|
170
|
+
root.pendingFileWrites = Math.max(0, root.pendingFileWrites - 1);
|
|
171
|
+
root.pendingFileBytes = Math.max(0, root.pendingFileBytes - bytes);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (!this.stderr) return;
|
|
176
|
+
if (this.format === "json") {
|
|
177
|
+
writeErr(`${JSON.stringify(entry)}
|
|
178
|
+
`);
|
|
179
|
+
} else {
|
|
180
|
+
const head = `${color.dim(ts)} ${COLORS[level](level.toUpperCase().padEnd(5))} ${msg}`;
|
|
181
|
+
if (ctx !== void 0) {
|
|
182
|
+
writeErr(`${head} ${formatCtx(ctx)}
|
|
183
|
+
`);
|
|
184
|
+
} else {
|
|
185
|
+
writeErr(`${head}
|
|
186
|
+
`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
function parseLogLevel(raw) {
|
|
192
|
+
return raw && LOG_LEVELS.has(raw) ? raw : "info";
|
|
193
|
+
}
|
|
194
|
+
function parseLogFormat(raw) {
|
|
195
|
+
return raw && LOG_FORMATS.has(raw) ? raw : "pretty";
|
|
196
|
+
}
|
|
197
|
+
function formatCtx(ctx) {
|
|
198
|
+
if (ctx instanceof Error) return color.dim(ctx.message);
|
|
199
|
+
if (typeof ctx === "string") return color.dim(ctx);
|
|
200
|
+
try {
|
|
201
|
+
return color.dim(JSON.stringify(ctx));
|
|
202
|
+
} catch {
|
|
203
|
+
return color.dim(String(ctx));
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
var noOpLogger = {
|
|
207
|
+
// 'error' is the quietest level the Logger contract offers; the methods
|
|
208
|
+
// discard everything regardless, this only matters to level checks.
|
|
209
|
+
level: "error",
|
|
210
|
+
error: () => {
|
|
211
|
+
},
|
|
212
|
+
warn: () => {
|
|
213
|
+
},
|
|
214
|
+
info: () => {
|
|
215
|
+
},
|
|
216
|
+
debug: () => {
|
|
217
|
+
},
|
|
218
|
+
trace: () => {
|
|
219
|
+
},
|
|
220
|
+
child: () => noOpLogger
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
export {
|
|
224
|
+
DefaultLogger,
|
|
225
|
+
noOpLogger
|
|
226
|
+
};
|
|
227
|
+
//# sourceMappingURL=chunk-WBPVKEEE.js.map
|