@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.
Files changed (187) hide show
  1. package/dist/chronicle/index.js +84 -6391
  2. package/dist/chronicle/project-server.js +84 -4868
  3. package/dist/chunk-2BUUIMQB.js +225 -0
  4. package/dist/chunk-2FK4WTFF.js +207 -0
  5. package/dist/chunk-2FQL4PDC.js +292 -0
  6. package/dist/chunk-2KKODIQU.js +2256 -0
  7. package/dist/chunk-2YU4WVBW.js +134 -0
  8. package/dist/chunk-3E244UDA.js +356 -0
  9. package/dist/chunk-3XPVB7BA.js +135 -0
  10. package/dist/chunk-4LJJYBAU.js +388 -0
  11. package/dist/chunk-4VWO3ZXL.js +342 -0
  12. package/dist/chunk-4XV6IR37.js +187 -0
  13. package/dist/chunk-4ZHTKJHM.js +183 -0
  14. package/dist/chunk-52RTVH4M.js +361 -0
  15. package/dist/chunk-57GEWK5X.js +26 -0
  16. package/dist/chunk-5DSMEVA4.js +931 -0
  17. package/dist/chunk-5RP3QTRL.js +1223 -0
  18. package/dist/chunk-5S437PRC.js +50 -0
  19. package/dist/chunk-5XDUGTKN.js +511 -0
  20. package/dist/chunk-62V2AFVG.js +422 -0
  21. package/dist/chunk-65RDIOR2.js +2470 -0
  22. package/dist/chunk-6AKOTGLM.js +597 -0
  23. package/dist/chunk-7ZHZE5EO.js +28 -0
  24. package/dist/chunk-A455ATZB.js +140 -0
  25. package/dist/chunk-AD7ZFZCS.js +46 -0
  26. package/dist/chunk-AI4LLQ2U.js +856 -0
  27. package/dist/chunk-ASX6AW36.js +789 -0
  28. package/dist/chunk-AT4V4XGI.js +3522 -0
  29. package/dist/chunk-AWNQ6ED6.js +311 -0
  30. package/dist/chunk-B4AMLZPB.js +9 -0
  31. package/dist/chunk-BAKVJLEV.js +417 -0
  32. package/dist/chunk-BJHVULHO.js +55 -0
  33. package/dist/chunk-CB2HFKTP.js +9 -0
  34. package/dist/chunk-CE4ZOCOI.js +1640 -0
  35. package/dist/chunk-CQQL4ZOQ.js +151 -0
  36. package/dist/chunk-DEIQMBD2.js +65 -0
  37. package/dist/chunk-E6I5RXVK.js +58 -0
  38. package/dist/chunk-EFEHDQGY.js +1589 -0
  39. package/dist/chunk-EODDVJBM.js +82 -0
  40. package/dist/chunk-EPC3GZD4.js +308 -0
  41. package/dist/chunk-FAYRX2AD.js +13 -0
  42. package/dist/chunk-FFSX2QDQ.js +362 -0
  43. package/dist/chunk-FHAMQS7Q.js +5856 -0
  44. package/dist/chunk-FIV4IJL7.js +2263 -0
  45. package/dist/chunk-FNXVT7HF.js +52 -0
  46. package/dist/chunk-FSWCWSTS.js +395 -0
  47. package/dist/chunk-FW5LDDMJ.js +16464 -0
  48. package/dist/chunk-FXQLIX3K.js +211 -0
  49. package/dist/chunk-G5AAKEEZ.js +228 -0
  50. package/dist/chunk-G5S3S5ZN.js +38 -0
  51. package/dist/chunk-GAZEWQEZ.js +231 -0
  52. package/dist/chunk-GFJOMSHG.js +125 -0
  53. package/dist/chunk-GFXZTHNI.js +158 -0
  54. package/dist/chunk-GM54GJBU.js +960 -0
  55. package/dist/chunk-GPQ3NJPR.js +900 -0
  56. package/dist/chunk-GTCU6DZ3.js +1 -0
  57. package/dist/chunk-H5E77KUJ.js +15 -0
  58. package/dist/chunk-H72H4XDU.js +1023 -0
  59. package/dist/chunk-HA4ZYA6T.js +178 -0
  60. package/dist/chunk-I45KAW2N.js +5020 -0
  61. package/dist/chunk-IQ35HMQL.js +1396 -0
  62. package/dist/chunk-IYFBFX34.js +86 -0
  63. package/dist/chunk-JJPMWPB6.js +109 -0
  64. package/dist/chunk-JTHKOYWU.js +663 -0
  65. package/dist/chunk-JVGPR3TS.js +365 -0
  66. package/dist/chunk-JVKB2TBL.js +48 -0
  67. package/dist/chunk-JX7VBZDK.js +31 -0
  68. package/dist/chunk-K3G6JBUC.js +5232 -0
  69. package/dist/chunk-K4YUNKU7.js +589 -0
  70. package/dist/chunk-KBZGE6LN.js +710 -0
  71. package/dist/chunk-KDQJCT2J.js +45 -0
  72. package/dist/chunk-KI4L2DUL.js +560 -0
  73. package/dist/chunk-KJ2ZTQSL.js +47 -0
  74. package/dist/chunk-KSJ5UTP7.js +154 -0
  75. package/dist/chunk-LHOA5DWA.js +28 -0
  76. package/dist/chunk-LX5QWLBL.js +27 -0
  77. package/dist/chunk-LZDDLNCZ.js +279 -0
  78. package/dist/chunk-M2WF6AXG.js +115 -0
  79. package/dist/chunk-M7BS2K6U.js +1 -0
  80. package/dist/chunk-NDBIPFNY.js +102 -0
  81. package/dist/chunk-NEMIWEXC.js +1199 -0
  82. package/dist/chunk-NFAYHPRH.js +323 -0
  83. package/dist/chunk-O37BQ65S.js +21 -0
  84. package/dist/chunk-O74MJHXU.js +187 -0
  85. package/dist/chunk-OJZEX73F.js +112 -0
  86. package/dist/chunk-PAAWLLZX.js +74 -0
  87. package/dist/chunk-PFXFQQRT.js +339 -0
  88. package/dist/chunk-PFZO3C6H.js +14 -0
  89. package/dist/chunk-PHH7LD45.js +113 -0
  90. package/dist/chunk-QRTG4XTI.js +188 -0
  91. package/dist/chunk-QVOVMXJR.js +1351 -0
  92. package/dist/chunk-RCQYT2I4.js +757 -0
  93. package/dist/chunk-RD6DEE36.js +1178 -0
  94. package/dist/chunk-RJIZEJ42.js +30 -0
  95. package/dist/chunk-RPOA7IAE.js +150 -0
  96. package/dist/chunk-SN2DQRL6.js +1172 -0
  97. package/dist/chunk-SQJVFEBV.js +41 -0
  98. package/dist/chunk-SQP64RCS.js +5391 -0
  99. package/dist/chunk-SVT4RNTR.js +49 -0
  100. package/dist/chunk-SWUFN7XM.js +43 -0
  101. package/dist/chunk-SXMVYC5H.js +174 -0
  102. package/dist/chunk-SZ6AYUIZ.js +23 -0
  103. package/dist/chunk-T3KGZBU5.js +3171 -0
  104. package/dist/chunk-TBRL2RCC.js +9 -0
  105. package/dist/chunk-TRT2HRWZ.js +18 -0
  106. package/dist/chunk-TYW2GI5I.js +1077 -0
  107. package/dist/chunk-UIWONWVG.js +4959 -0
  108. package/dist/chunk-VB3H5WWB.js +151 -0
  109. package/dist/chunk-W4A6QA3D.js +258 -0
  110. package/dist/chunk-WBPVKEEE.js +227 -0
  111. package/dist/chunk-WEBMSQP2.js +123 -0
  112. package/dist/chunk-WOEZV3Q4.js +333 -0
  113. package/dist/chunk-WQQON3SV.js +473 -0
  114. package/dist/chunk-WQTOVMGV.js +119 -0
  115. package/dist/chunk-WZO23AWO.js +2779 -0
  116. package/dist/chunk-XBDP4QPW.js +7 -0
  117. package/dist/chunk-XEBHSJLT.js +103 -0
  118. package/dist/chunk-XQ2ECNK3.js +1 -0
  119. package/dist/chunk-XQ2XGIBF.js +2086 -0
  120. package/dist/chunk-Y2GE5TSI.js +355 -0
  121. package/dist/chunk-YBUJCZ57.js +351 -0
  122. package/dist/chunk-YNCVSFGF.js +149 -0
  123. package/dist/chunk-YUPMXOGP.js +282 -0
  124. package/dist/chunk-YY6APYUM.js +49 -0
  125. package/dist/chunk-Z2IJUO45.js +691 -0
  126. package/dist/chunk-ZEHUCJHY.js +129 -0
  127. package/dist/chunk-ZYU2YOJ6.js +1496 -0
  128. package/dist/chunk-ZZ4V3WIZ.js +163 -0
  129. package/dist/coordination/agents/index.js +145 -6260
  130. package/dist/coordination/index.js +365 -34323
  131. package/dist/coordination/mailbox-project-server.js +48 -3220
  132. package/dist/coordination/mailbox-types.d.ts +13 -1
  133. package/dist/coordination/provider-status-tracker.d.ts +4 -0
  134. package/dist/coordination/sqlite-mailbox.d.ts +2 -1
  135. package/dist/core/agent.d.ts +14 -1
  136. package/dist/core/index.js +267 -12479
  137. package/dist/core/model-ref.js +5 -23
  138. package/dist/core/provider-runner.d.ts +36 -1
  139. package/dist/design/index.js +50 -1087
  140. package/dist/execution/index.d.ts +1 -1
  141. package/dist/execution/index.js +1599 -21887
  142. package/dist/execution/prompt-enhancer.js +16 -535
  143. package/dist/execution/retry-policy.d.ts +31 -1
  144. package/dist/extension/index.js +7 -311
  145. package/dist/goal/index.js +33 -3435
  146. package/dist/hooks/index.js +14 -1138
  147. package/dist/hq/index.js +112 -5139
  148. package/dist/hq/protocol.js +21 -668
  149. package/dist/index.js +1410 -92655
  150. package/dist/infrastructure/index.js +64 -4811
  151. package/dist/kernel/events/provider-events.d.ts +15 -0
  152. package/dist/kernel/events/wrongtrace-events.d.ts +26 -0
  153. package/dist/kernel/events.d.ts +16 -7
  154. package/dist/kernel/index.js +14 -992
  155. package/dist/models/index.js +40 -1117
  156. package/dist/notifications/index.js +3 -108
  157. package/dist/observability/index.js +17 -279
  158. package/dist/plugin/index.js +584 -14835
  159. package/dist/prompts/index.js +14 -948
  160. package/dist/registry/index.js +9 -822
  161. package/dist/registry-R23UBE7H.js +14 -0
  162. package/dist/replay/index.js +6 -84
  163. package/dist/review-finding-store-DKAV3AS6.js +21 -0
  164. package/dist/review-report-store-OWY3EC3N.js +19 -0
  165. package/dist/security/index.js +114 -2202
  166. package/dist/session-catalog/index.js +36 -2103
  167. package/dist/session-catalog/project-server.js +42 -1435
  168. package/dist/skills/index.js +35 -1578
  169. package/dist/storage/index.js +182 -15600
  170. package/dist/tasking/index.js +10 -676
  171. package/dist/tools/index.js +52 -9589
  172. package/dist/types/config/autonomy.d.ts +5 -0
  173. package/dist/types/config/tools.d.ts +2 -2
  174. package/dist/types/config/ui.d.ts +1 -1
  175. package/dist/types/errors.d.ts +18 -0
  176. package/dist/types/index.js +121 -1341
  177. package/dist/types/provider-runner.d.ts +8 -0
  178. package/dist/types/session-markers.js +8 -144
  179. package/dist/utils/error.js +3 -4
  180. package/dist/utils/expect-defined.js +3 -9
  181. package/dist/utils/heap-watchdog.js +6 -706
  182. package/dist/utils/index.js +269 -5685
  183. package/dist/utils/sage-output-block.js +5 -42
  184. package/dist/wiring/proxy-rewrite.d.ts +92 -4
  185. package/dist/wiring/proxy-rewrite.js +20 -61
  186. package/dist/worktree/index.js +6 -887
  187. 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