sintbot 1.0.15 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/CHANGELOG.en.json +118 -0
  2. package/CHANGELOG.json +118 -0
  3. package/README.md +20 -156
  4. package/README.zh-CN.md +20 -164
  5. package/THIRD-PARTY-NOTICES.md +394 -0
  6. package/bin/sintbot-v2.js +363 -0
  7. package/docs/AI-ASSISTED-INSTALL.md +19 -0
  8. package/docs/install.md +93 -0
  9. package/docs/zh-CN/AI-ASSISTED-INSTALL.md +19 -0
  10. package/docs/zh-CN/install.md +93 -0
  11. package/install.sh +84 -0
  12. package/package.json +74 -34
  13. package/src/agent/claudecode.js +149 -108
  14. package/src/agent/codexapp.js +458 -0
  15. package/src/agent/codexcode.js +210 -107
  16. package/src/agent/errtag.js +34 -0
  17. package/src/agent/privatecore.js +790 -0
  18. package/src/agent/privatecore.wasm +0 -0
  19. package/src/agent/runner.js +10 -8
  20. package/src/agent/winexec.js +35 -5
  21. package/src/c2install.js +117 -0
  22. package/src/config.js +2 -1
  23. package/src/core/c2cardeffectbridge.js +51 -0
  24. package/src/core/c2cardterminalpath.js +216 -0
  25. package/src/core/c2durableingress.js +148 -0
  26. package/src/core/c2durablejournal.js +1560 -0
  27. package/src/core/c2durableruntime.js +2361 -0
  28. package/src/core/c2eventidentity.js +90 -0
  29. package/src/core/c2globalfault.js +401 -0
  30. package/src/core/c2localeffectexecutor.js +193 -0
  31. package/src/core/c2payloadhandles.js +333 -0
  32. package/src/core/c2persistrelation.js +179 -0
  33. package/src/core/c2persiststate.js +342 -0
  34. package/src/core/c2platformrecoverysender.js +76 -0
  35. package/src/core/c2recoverygate.js +385 -0
  36. package/src/core/c2runnerinput.js +63 -0
  37. package/src/core/c2servicestartgate.js +103 -0
  38. package/src/core/c2sessionbridge.js +72 -0
  39. package/src/core/c2sourcequarantine.js +30 -0
  40. package/src/core/c2startuprecovery.js +105 -0
  41. package/src/core/c2successorbridge.js +151 -0
  42. package/src/core/c2terminaleffectbridge.js +154 -0
  43. package/src/core/c2terminalprune.js +108 -0
  44. package/src/core/c2turnprojection.js +177 -0
  45. package/src/core/enginecheckpoint.js +211 -0
  46. package/src/core/engineeffectcursor.js +394 -0
  47. package/src/core/enginestepcoordinator.js +183 -0
  48. package/src/core/store.js +52 -8
  49. package/src/core/v2engine.js +1469 -0
  50. package/src/platform/feishu.js +324 -67
  51. package/src/plugins.js +1 -9
  52. package/assets/design-styles/acid-pop.md +0 -155
  53. package/assets/design-styles/archive-index.md +0 -161
  54. package/assets/design-styles/art-deco.md +0 -164
  55. package/assets/design-styles/cinematic-noir.md +0 -178
  56. package/assets/design-styles/editorial.md +0 -121
  57. package/assets/design-styles/extra/README.md +0 -23
  58. package/assets/design-styles/extra/constructivism.md +0 -146
  59. package/assets/design-styles/extra/neo-brutalism.md +0 -175
  60. package/assets/design-styles/extra/new-wave.md +0 -166
  61. package/assets/design-styles/extra/nordic-material.md +0 -162
  62. package/assets/design-styles/extra/paris-couture.md +0 -162
  63. package/assets/design-styles/extra/tropical-modern.md +0 -168
  64. package/assets/design-styles/extra/ulm-functional.md +0 -182
  65. package/assets/design-styles/extra/wa-shikimen.md +0 -160
  66. package/assets/design-styles/extra/y2k-chrome.md +0 -172
  67. package/assets/design-styles/geometric-pop.md +0 -122
  68. package/assets/design-styles/hand-drawn.md +0 -117
  69. package/assets/design-styles/islamic-geometry.md +0 -155
  70. package/assets/design-styles/liquid-glass.md +0 -183
  71. package/assets/design-styles/neo-chinese.md +0 -136
  72. package/assets/design-styles/precision-mono.md +0 -156
  73. package/assets/design-styles/quiet-luxury.md +0 -163
  74. package/assets/design-styles/riso-print.md +0 -116
  75. package/assets/design-styles/soft-friendly.md +0 -174
  76. package/assets/design-styles/swiss-grid.md +0 -156
  77. package/assets/design-styles/tech-dark.md +0 -182
  78. package/assets/favicon.svg +0 -6
  79. package/assets/logo.svg +0 -24
  80. package/bin/sbot.js +0 -4711
  81. package/docs/slack-app-manifest.yaml +0 -104
  82. package/sbot.config.example.json +0 -235
  83. package/src/agent/askonce.js +0 -76
  84. package/src/agent/claudemodels.js +0 -60
  85. package/src/agent/claudestatus.js +0 -74
  86. package/src/agent/claudeusage.js +0 -200
  87. package/src/agent/codexstatus.js +0 -181
  88. package/src/agent/imagen.js +0 -458
  89. package/src/agent/quotaerr.js +0 -44
  90. package/src/agent/transienterr.js +0 -32
  91. package/src/cdp.js +0 -254
  92. package/src/clilang.js +0 -31
  93. package/src/core/cron.js +0 -182
  94. package/src/core/cronfire.js +0 -120
  95. package/src/core/cronrun.js +0 -116
  96. package/src/core/engine.js +0 -2762
  97. package/src/core/interfaces.js +0 -114
  98. package/src/core/issues.js +0 -185
  99. package/src/core/ledger.js +0 -30
  100. package/src/core/opsalert.js +0 -214
  101. package/src/core/pending.js +0 -123
  102. package/src/core/proxy.js +0 -424
  103. package/src/core/quotaalert.js +0 -79
  104. package/src/core/quotaerr.js +0 -55
  105. package/src/core/scheduler.js +0 -59
  106. package/src/design.js +0 -5161
  107. package/src/gitrepo.js +0 -150
  108. package/src/health.js +0 -353
  109. package/src/installdeps.js +0 -72
  110. package/src/leftover.js +0 -174
  111. package/src/platform/boardnotice.js +0 -77
  112. package/src/platform/boardops.js +0 -36
  113. package/src/platform/boardwatch.js +0 -447
  114. package/src/platform/cli.js +0 -45
  115. package/src/platform/slack.js +0 -1289
  116. package/src/platform/takeovercard.js +0 -37
  117. package/src/platform/wecom.js +0 -938
  118. package/src/platform/wecomcli.js +0 -128
  119. package/src/platform/wecomgate.js +0 -108
  120. package/src/platform/wecomname.js +0 -43
  121. package/src/platform/wecompoll.js +0 -241
  122. package/src/preview.js +0 -581
  123. package/src/projectmemory.js +0 -175
  124. package/src/service.js +0 -317
  125. package/src/ui/auth.js +0 -31
  126. package/src/ui/browser.html +0 -392
  127. package/src/ui/browserroutes.js +0 -234
  128. package/src/ui/console.html +0 -5494
  129. package/src/ui/dashboard.js +0 -168
  130. package/src/ui/feishulogin.js +0 -136
  131. package/src/ui/server.js +0 -2314
  132. package/src/ui/sessions.js +0 -78
  133. package/src/ui/takeover.js +0 -108
  134. package/src/updater.js +0 -243
  135. package/src/upgrade.js +0 -35
  136. package/src/usage.js +0 -144
@@ -0,0 +1,790 @@
1
+ // ABI v34 adapter for the private binary decision core. Manifest assembly still stays in JS.
2
+ const fs = require('node:fs')
3
+ const path = require('node:path')
4
+ const { createHash } = require('node:crypto')
5
+
6
+ const EXPECTED_SHA256 = 'c9b89e6f748c94415aa853be6ccaef35030f754b8898cb81b6cc0d02cf85e222'
7
+ let bytes
8
+ try {
9
+ bytes = fs.readFileSync(path.join(__dirname, 'privatecore.wasm'))
10
+ } catch (cause) {
11
+ throw new Error('SintBot binary core is missing or unreadable; reinstall the matching package', { cause })
12
+ }
13
+ if (createHash('sha256').update(bytes).digest('hex') !== EXPECTED_SHA256) {
14
+ throw new Error('SintBot binary core does not match its loader; reinstall the matching package')
15
+ }
16
+ let core
17
+ let compiled
18
+ function boot() {
19
+ compiled = compiled || new WebAssembly.Module(bytes)
20
+ core = new WebAssembly.Instance(compiled).exports
21
+ }
22
+ let engineStepPoisoned = false
23
+ function resetBinaryCore() { boot(); engineStepPoisoned = false }
24
+ try {
25
+ boot()
26
+ } catch (cause) {
27
+ throw new Error('SintBot binary core cannot start on this runtime', { cause })
28
+ }
29
+ if (core.abi_version() !== 34) throw new Error('SintBot binary core ABI mismatch')
30
+ const encoder = new TextEncoder()
31
+ const decoder = new TextDecoder('utf-8', { fatal: true })
32
+
33
+ function callText(name, text, ...args) {
34
+ const input = encoder.encode(String(text || ''))
35
+ const ptr = core.alloc(input.length)
36
+ try {
37
+ new Uint8Array(core.memory.buffer).set(input, ptr)
38
+ return core[name](ptr, input.length, ...args)
39
+ } finally {
40
+ new Uint8Array(core.memory.buffer).fill(0, ptr, ptr + input.length)
41
+ core.dealloc(ptr, input.length)
42
+ input.fill(0)
43
+ }
44
+ }
45
+
46
+ const HUMAN = {
47
+ overload: '模型这会儿排不上队(服务端过载)',
48
+ ratelimit: '请求太密,被暂时限流了',
49
+ gateway: '模型服务暂时不可用',
50
+ network: '暂时连不上模型服务(网络故障)',
51
+ }
52
+
53
+ function classifyError(text) {
54
+ const code = callText('classify_error', text)
55
+ if (code >= 1 && code <= 4) return {
56
+ quota: { kind: code === 4 ? 'account' : 'quota', window: code === 1 ? 'weekly' : code === 2 ? 'session' : null },
57
+ }
58
+ if (code === 9) return { sessionMissing: true }
59
+ const kind = { 5: 'overload', 6: 'ratelimit', 7: 'gateway', 8: 'network' }[code]
60
+ if (kind) return { transient: { kind, human: HUMAN[kind] } }
61
+ if (code !== 0) throw new Error(`SintBot binary core returned unknown result ${code}`)
62
+ return null
63
+ }
64
+
65
+ function routeBackend(runner, codexApp, codexSteer, codexProjectDocFallback) {
66
+ const flags = (codexApp ? 1 : 0) | (codexSteer ? 2 : 0) | (codexProjectDocFallback ? 4 : 0)
67
+ const code = callText('route_backend', runner, flags)
68
+ const route = { 0: 'claude', 1: 'codex-exec', 2: 'codex-app' }[code]
69
+ if (!route) throw new Error(`SintBot binary core returned unknown backend ${code}`)
70
+ return route
71
+ }
72
+
73
+ function sandboxTier(permissionMode) {
74
+ const code = callText('sandbox_tier', permissionMode)
75
+ if (code === 0) return 'read-only'
76
+ if (code === 1) return 'danger-full-access'
77
+ throw new Error(`SintBot binary core returned unknown sandbox tier ${code}`)
78
+ }
79
+
80
+ function appErrorOverride(status, hasKind, hasQuota, sessionMissing, hasTransient) {
81
+ const code = core.app_error_override(Number(status), Number(!!hasKind), Number(!!hasQuota), Number(!!sessionMissing), Number(!!hasTransient))
82
+ if (code === 0) return null
83
+ if (code === 1) return 'account'
84
+ if (code === 2) return 'network'
85
+ if (code === 3) return 'gateway'
86
+ throw new Error(`SintBot binary core returned unknown App error decision ${code}`)
87
+ }
88
+
89
+ function codexBuildPrompt(prompt, appendSystemPrompt, isResume) {
90
+ const promptBytes = encoder.encode(prompt)
91
+ const appendixBytes = encoder.encode(appendSystemPrompt || '')
92
+ const promptPtr = core.alloc(promptBytes.length)
93
+ let appendixPtr = 0, outputPtr = 0, outputSize = 0
94
+ try {
95
+ appendixPtr = core.alloc(appendixBytes.length)
96
+ new Uint8Array(core.memory.buffer).set(promptBytes, promptPtr)
97
+ new Uint8Array(core.memory.buffer).set(appendixBytes, appendixPtr)
98
+ outputPtr = core.codex_build_prompt(promptPtr, promptBytes.length, appendixPtr, appendixBytes.length, Number(!!isResume))
99
+ if (!outputPtr) throw new Error('SintBot binary core could not build Codex prompt')
100
+ const buffer = core.memory.buffer
101
+ if (outputPtr + 4 > buffer.byteLength) throw new Error('SintBot binary core returned an invalid Codex prompt')
102
+ const length = new DataView(buffer).getUint32(outputPtr, true)
103
+ outputSize = length + 4
104
+ if (outputPtr + outputSize > buffer.byteLength) throw new Error('SintBot binary core returned an invalid Codex prompt')
105
+ return decoder.decode(new Uint8Array(buffer, outputPtr + 4, length))
106
+ } finally {
107
+ const memory = new Uint8Array(core.memory.buffer)
108
+ if (outputPtr && outputSize && outputPtr + outputSize <= memory.length) memory.fill(0, outputPtr, outputPtr + outputSize)
109
+ if (outputPtr && outputSize) core.dealloc(outputPtr, outputSize)
110
+ memory.fill(0, promptPtr, promptPtr + promptBytes.length)
111
+ core.dealloc(promptPtr, promptBytes.length)
112
+ if (appendixPtr) {
113
+ memory.fill(0, appendixPtr, appendixPtr + appendixBytes.length)
114
+ core.dealloc(appendixPtr, appendixBytes.length)
115
+ }
116
+ promptBytes.fill(0)
117
+ appendixBytes.fill(0)
118
+ }
119
+ }
120
+
121
+ function codexBuildArgs(options) {
122
+ const input = encoder.encode(JSON.stringify(options))
123
+ const inputPtr = core.alloc(input.length)
124
+ let outputPtr = 0, outputSize = 0
125
+ try {
126
+ new Uint8Array(core.memory.buffer).set(input, inputPtr)
127
+ outputPtr = core.codex_build_args(inputPtr, input.length)
128
+ if (!outputPtr) throw new Error('SintBot binary core could not build Codex arguments')
129
+ const buffer = core.memory.buffer
130
+ if (outputPtr + 4 > buffer.byteLength) throw new Error('SintBot binary core returned invalid Codex arguments')
131
+ const length = new DataView(buffer).getUint32(outputPtr, true)
132
+ outputSize = length + 4
133
+ if (outputPtr + outputSize > buffer.byteLength) throw new Error('SintBot binary core returned invalid Codex arguments')
134
+ const args = JSON.parse(decoder.decode(new Uint8Array(buffer, outputPtr + 4, length)))
135
+ if (!Array.isArray(args) || !args.every((arg) => typeof arg === 'string')) {
136
+ throw new Error('SintBot binary core returned invalid Codex arguments')
137
+ }
138
+ return args
139
+ } finally {
140
+ const memory = new Uint8Array(core.memory.buffer)
141
+ if (outputPtr && outputSize && outputPtr + outputSize <= memory.length) memory.fill(0, outputPtr, outputPtr + outputSize)
142
+ if (outputPtr && outputSize) core.dealloc(outputPtr, outputSize)
143
+ memory.fill(0, inputPtr, inputPtr + input.length)
144
+ core.dealloc(inputPtr, input.length)
145
+ input.fill(0)
146
+ }
147
+ }
148
+
149
+ function appUsageFromTotal(total) {
150
+ const input = encoder.encode(JSON.stringify(total ?? null))
151
+ const inputPtr = core.alloc(input.length)
152
+ let outputPtr = 0, outputSize = 0
153
+ try {
154
+ new Uint8Array(core.memory.buffer).set(input, inputPtr)
155
+ outputPtr = core.app_usage_from_total(inputPtr, input.length)
156
+ if (!outputPtr) throw new Error('SintBot binary core could not map App usage')
157
+ const buffer = core.memory.buffer
158
+ if (outputPtr + 4 > buffer.byteLength) throw new Error('SintBot binary core returned invalid App usage')
159
+ const length = new DataView(buffer).getUint32(outputPtr, true)
160
+ outputSize = length + 4
161
+ if (outputPtr + outputSize > buffer.byteLength) throw new Error('SintBot binary core returned invalid App usage')
162
+ const usage = JSON.parse(decoder.decode(new Uint8Array(buffer, outputPtr + 4, length)))
163
+ if (usage !== null && (typeof usage !== 'object' || Array.isArray(usage))) {
164
+ throw new Error('SintBot binary core returned invalid App usage')
165
+ }
166
+ return usage
167
+ } finally {
168
+ const memory = new Uint8Array(core.memory.buffer)
169
+ if (outputPtr && outputSize && outputPtr + outputSize <= memory.length) memory.fill(0, outputPtr, outputPtr + outputSize)
170
+ if (outputPtr && outputSize) core.dealloc(outputPtr, outputSize)
171
+ memory.fill(0, inputPtr, inputPtr + input.length)
172
+ core.dealloc(inputPtr, input.length)
173
+ input.fill(0)
174
+ }
175
+ }
176
+
177
+ function settleUsage(prior, sessionKey, result) {
178
+ // Only numeric/accounting fields cross this ABI. A run result may also hold
179
+ // model text or tool output, which the usage decision must never receive.
180
+ const usage = result && result.usage
181
+ const projection = {
182
+ usage: usage ? {
183
+ input_tokens: usage.input_tokens,
184
+ cached_input_tokens: usage.cached_input_tokens,
185
+ output_tokens: usage.output_tokens,
186
+ cache_read_input_tokens: usage.cache_read_input_tokens,
187
+ cache_creation_input_tokens: usage.cache_creation_input_tokens,
188
+ } : null,
189
+ usageCumulative: result && result.usageCumulative,
190
+ contextTokens: result && result.contextTokens,
191
+ contextCompacted: result && result.contextCompacted,
192
+ }
193
+ const input = encoder.encode(JSON.stringify({ prior, sessionKey, result: projection }))
194
+ const inputPtr = core.alloc(input.length)
195
+ let outputPtr = 0, outputSize = 0
196
+ try {
197
+ new Uint8Array(core.memory.buffer).set(input, inputPtr)
198
+ outputPtr = core.settle_usage(inputPtr, input.length)
199
+ if (!outputPtr) throw new Error('SintBot binary core could not settle usage')
200
+ const buffer = core.memory.buffer
201
+ if (outputPtr + 4 > buffer.byteLength) throw new Error('SintBot binary core returned invalid usage decision')
202
+ const length = new DataView(buffer).getUint32(outputPtr, true)
203
+ outputSize = length + 4
204
+ if (outputPtr + outputSize > buffer.byteLength) throw new Error('SintBot binary core returned invalid usage decision')
205
+ const decision = JSON.parse(decoder.decode(new Uint8Array(buffer, outputPtr + 4, length)))
206
+ if (!decision || typeof decision !== 'object' || typeof decision.write !== 'boolean' ||
207
+ (decision.tokens !== null && (typeof decision.tokens !== 'object' || Array.isArray(decision.tokens))) ||
208
+ (decision.write && (!decision.stats || typeof decision.stats !== 'object' || Array.isArray(decision.stats)))) {
209
+ throw new Error('SintBot binary core returned invalid usage decision')
210
+ }
211
+ return decision
212
+ } finally {
213
+ const memory = new Uint8Array(core.memory.buffer)
214
+ if (outputPtr && outputSize && outputPtr + outputSize <= memory.length) memory.fill(0, outputPtr, outputPtr + outputSize)
215
+ if (outputPtr && outputSize) core.dealloc(outputPtr, outputSize)
216
+ memory.fill(0, inputPtr, inputPtr + input.length)
217
+ core.dealloc(inputPtr, input.length)
218
+ input.fill(0)
219
+ }
220
+ }
221
+
222
+ function appBuildRequest(options) {
223
+ const input = encoder.encode(JSON.stringify(options))
224
+ const inputPtr = core.alloc(input.length)
225
+ let outputPtr = 0, outputSize = 0
226
+ try {
227
+ new Uint8Array(core.memory.buffer).set(input, inputPtr)
228
+ outputPtr = core.app_build_request(inputPtr, input.length)
229
+ if (!outputPtr) throw new Error('SintBot binary core could not build App request')
230
+ const buffer = core.memory.buffer
231
+ if (outputPtr + 4 > buffer.byteLength) throw new Error('SintBot binary core returned invalid App request')
232
+ const length = new DataView(buffer).getUint32(outputPtr, true)
233
+ outputSize = length + 4
234
+ if (outputPtr + outputSize > buffer.byteLength) throw new Error('SintBot binary core returned invalid App request')
235
+ const request = JSON.parse(decoder.decode(new Uint8Array(buffer, outputPtr + 4, length)))
236
+ if (!request || !['thread/start', 'thread/resume', 'turn/start'].includes(request.method) ||
237
+ !request.params || typeof request.params !== 'object' || Array.isArray(request.params)) {
238
+ throw new Error('SintBot binary core returned invalid App request')
239
+ }
240
+ return request
241
+ } finally {
242
+ const memory = new Uint8Array(core.memory.buffer)
243
+ if (outputPtr && outputSize && outputPtr + outputSize <= memory.length) memory.fill(0, outputPtr, outputPtr + outputSize)
244
+ if (outputPtr && outputSize) core.dealloc(outputPtr, outputSize)
245
+ memory.fill(0, inputPtr, inputPtr + input.length)
246
+ core.dealloc(inputPtr, input.length)
247
+ input.fill(0)
248
+ }
249
+ }
250
+
251
+ function claudeBaseSkillAllows() {
252
+ const outputPtr = core.claude_base_skills()
253
+ if (!outputPtr) throw new Error('SintBot binary core could not provide Claude base skills')
254
+ let outputSize = 0
255
+ try {
256
+ const buffer = core.memory.buffer
257
+ if (outputPtr + 4 > buffer.byteLength) throw new Error('SintBot binary core returned invalid Claude base skills')
258
+ const length = new DataView(buffer).getUint32(outputPtr, true)
259
+ outputSize = length + 4
260
+ if (outputPtr + outputSize > buffer.byteLength) throw new Error('SintBot binary core returned invalid Claude base skills')
261
+ const skills = JSON.parse(decoder.decode(new Uint8Array(buffer, outputPtr + 4, length)))
262
+ if (!Array.isArray(skills) || !skills.every((s) => typeof s === 'string')) throw new Error('SintBot binary core returned invalid Claude base skills')
263
+ return skills
264
+ } finally {
265
+ const memory = new Uint8Array(core.memory.buffer)
266
+ if (outputSize && outputPtr + outputSize <= memory.length) memory.fill(0, outputPtr, outputPtr + outputSize)
267
+ if (outputSize) core.dealloc(outputPtr, outputSize)
268
+ }
269
+ }
270
+
271
+ function claudeBuildArgs(options) {
272
+ const input = encoder.encode(JSON.stringify(options))
273
+ const inputPtr = core.alloc(input.length)
274
+ let outputPtr = 0, outputSize = 0
275
+ try {
276
+ new Uint8Array(core.memory.buffer).set(input, inputPtr)
277
+ outputPtr = core.claude_build_args(inputPtr, input.length)
278
+ if (!outputPtr) throw new Error('SintBot binary core could not build Claude arguments')
279
+ const buffer = core.memory.buffer
280
+ if (outputPtr + 4 > buffer.byteLength) throw new Error('SintBot binary core returned invalid Claude arguments')
281
+ const length = new DataView(buffer).getUint32(outputPtr, true)
282
+ outputSize = length + 4
283
+ if (outputPtr + outputSize > buffer.byteLength) throw new Error('SintBot binary core returned invalid Claude arguments')
284
+ const args = JSON.parse(decoder.decode(new Uint8Array(buffer, outputPtr + 4, length)))
285
+ if (!Array.isArray(args) || !args.every((a) => typeof a === 'string')) throw new Error('SintBot binary core returned invalid Claude arguments')
286
+ return args
287
+ } finally {
288
+ const memory = new Uint8Array(core.memory.buffer)
289
+ if (outputPtr && outputSize && outputPtr + outputSize <= memory.length) memory.fill(0, outputPtr, outputPtr + outputSize)
290
+ if (outputPtr && outputSize) core.dealloc(outputPtr, outputSize)
291
+ memory.fill(0, inputPtr, inputPtr + input.length)
292
+ core.dealloc(inputPtr, input.length)
293
+ input.fill(0)
294
+ }
295
+ }
296
+
297
+ function claudeNormalizeEvent(event) {
298
+ const errorJson = event && event.is_error && Array.isArray(event.errors)
299
+ ? event.errors.map((item) => JSON.stringify(item) ?? null) : null
300
+ const input = encoder.encode(JSON.stringify({ event, errorJson }))
301
+ const inputPtr = core.alloc(input.length)
302
+ let outputPtr = 0, outputSize = 0
303
+ try {
304
+ new Uint8Array(core.memory.buffer).set(input, inputPtr)
305
+ outputPtr = core.claude_normalize_event(inputPtr, input.length)
306
+ if (!outputPtr) throw new Error('SintBot binary core could not normalize Claude event')
307
+ const buffer = core.memory.buffer
308
+ if (outputPtr + 4 > buffer.byteLength) throw new Error('SintBot binary core returned invalid Claude event')
309
+ const length = new DataView(buffer).getUint32(outputPtr, true)
310
+ outputSize = length + 4
311
+ if (outputPtr + outputSize > buffer.byteLength) throw new Error('SintBot binary core returned invalid Claude event')
312
+ const normalized = JSON.parse(decoder.decode(new Uint8Array(buffer, outputPtr + 4, length)))
313
+ if (!normalized || typeof normalized !== 'object' || Array.isArray(normalized)) {
314
+ throw new Error('SintBot binary core returned invalid Claude event')
315
+ }
316
+ return normalized
317
+ } finally {
318
+ const memory = new Uint8Array(core.memory.buffer)
319
+ if (outputPtr && outputSize && outputPtr + outputSize <= memory.length) memory.fill(0, outputPtr, outputPtr + outputSize)
320
+ if (outputPtr && outputSize) core.dealloc(outputPtr, outputSize)
321
+ memory.fill(0, inputPtr, inputPtr + input.length)
322
+ core.dealloc(inputPtr, input.length)
323
+ input.fill(0)
324
+ }
325
+ }
326
+
327
+ function coreJson(name, inputValue, context) {
328
+ const input = encoder.encode(JSON.stringify(inputValue))
329
+ const inputPtr = core.alloc(input.length)
330
+ let outputPtr = 0, outputSize = 0
331
+ try {
332
+ new Uint8Array(core.memory.buffer).set(input, inputPtr)
333
+ outputPtr = core[name](inputPtr, input.length)
334
+ if (!outputPtr) throw new Error(`SintBot binary core could not ${context}`)
335
+ const buffer = core.memory.buffer
336
+ if (outputPtr + 4 > buffer.byteLength) throw new Error(`SintBot binary core returned invalid ${context}`)
337
+ const length = new DataView(buffer).getUint32(outputPtr, true)
338
+ outputSize = length + 4
339
+ if (outputPtr + outputSize > buffer.byteLength) throw new Error(`SintBot binary core returned invalid ${context}`)
340
+ return JSON.parse(decoder.decode(new Uint8Array(buffer, outputPtr + 4, length)))
341
+ } finally {
342
+ const memory = new Uint8Array(core.memory.buffer)
343
+ if (outputPtr && outputSize && outputPtr + outputSize <= memory.length) memory.fill(0, outputPtr, outputPtr + outputSize)
344
+ if (outputPtr && outputSize) core.dealloc(outputPtr, outputSize)
345
+ memory.fill(0, inputPtr, inputPtr + input.length)
346
+ core.dealloc(inputPtr, input.length)
347
+ input.fill(0)
348
+ }
349
+ }
350
+
351
+ function claudePluginAllowRules(mcpNames, skillNames) {
352
+ if (!Array.isArray(mcpNames) || !Array.isArray(skillNames) ||
353
+ [...mcpNames, ...skillNames].some((name) => typeof name !== 'string')) {
354
+ throw new TypeError('invalid Claude plugin names')
355
+ }
356
+ const value = coreJson('claude_plugin_allow_rules', { mcpNames, skillNames }, 'decide Claude plugin permissions')
357
+ if (!Array.isArray(value) || value.some((rule) => typeof rule !== 'string')) {
358
+ throw new Error('SintBot binary core returned invalid Claude plugin permissions')
359
+ }
360
+ return value
361
+ }
362
+
363
+ function codexNormalizeEvent(event) {
364
+ const value = coreJson('codex_normalize_event', event, 'normalize Codex event')
365
+ if (value !== null && (typeof value !== 'object' || Array.isArray(value))) throw new Error('SintBot binary core returned invalid Codex event')
366
+ return value
367
+ }
368
+
369
+ function codexParseError(raw) {
370
+ const value = coreJson('codex_parse_error', String(raw || ''), 'parse Codex error')
371
+ if (!value || typeof value.text !== 'string' || typeof value.param !== 'string') throw new Error('SintBot binary core returned invalid Codex error')
372
+ return value
373
+ }
374
+
375
+ function appNormalizeItem(method, item) {
376
+ const value = coreJson('app_normalize_item', { method, item }, 'normalize App item')
377
+ if (value !== null && (typeof value !== 'object' || Array.isArray(value))) throw new Error('SintBot binary core returned invalid App item')
378
+ return value
379
+ }
380
+
381
+ function appStreamTail(finalText, streamed) {
382
+ const value = coreJson('app_stream_tail', { finalText, streamed }, 'reconcile App message deltas')
383
+ if (value !== null && typeof value !== 'string') throw new Error('SintBot binary core returned invalid App message tail')
384
+ return value
385
+ }
386
+
387
+ function appNoticeAction(method, { threadMatches, turnMatches, activeTurn, completed, codexApp, hasTurnId, hasItemId }) {
388
+ const flags = (threadMatches ? 1 : 0) | (turnMatches ? 2 : 0) | (activeTurn ? 4 : 0) |
389
+ (completed ? 8 : 0) | (codexApp ? 16 : 0) | (hasTurnId ? 32 : 0) | (hasItemId ? 64 : 0)
390
+ const code = callText('app_notice_action', method, flags)
391
+ if (code >= 0 && code <= 5) return code
392
+ throw new Error(`SintBot binary core returned unknown App notification action ${code}`)
393
+ }
394
+
395
+ function appDeltaNext(previous, delta) {
396
+ const previousBytes = new Uint8Array(previous.length * 2)
397
+ const deltaBytes = new Uint8Array(delta.length * 2)
398
+ for (let i = 0; i < previous.length; i++) {
399
+ const unit = previous.charCodeAt(i)
400
+ previousBytes[i * 2] = unit & 255
401
+ previousBytes[i * 2 + 1] = unit >>> 8
402
+ }
403
+ for (let i = 0; i < delta.length; i++) {
404
+ const unit = delta.charCodeAt(i)
405
+ deltaBytes[i * 2] = unit & 255
406
+ deltaBytes[i * 2 + 1] = unit >>> 8
407
+ }
408
+ const previousPtr = core.alloc(previousBytes.length)
409
+ let deltaPtr = 0, outputPtr = 0, outputSize = 0
410
+ try {
411
+ deltaPtr = core.alloc(deltaBytes.length)
412
+ new Uint8Array(core.memory.buffer).set(previousBytes, previousPtr)
413
+ new Uint8Array(core.memory.buffer).set(deltaBytes, deltaPtr)
414
+ outputPtr = core.app_delta_next(previousPtr, previousBytes.length, deltaPtr, deltaBytes.length)
415
+ if (!outputPtr) {
416
+ if (!delta.length) return null
417
+ throw new Error('SintBot binary core could not accumulate App message delta')
418
+ }
419
+ const buffer = core.memory.buffer
420
+ if (outputPtr + 4 > buffer.byteLength) throw new Error('SintBot binary core returned invalid App delta')
421
+ const length = new DataView(buffer).getUint32(outputPtr, true)
422
+ outputSize = length + 4
423
+ if (length !== previousBytes.length + deltaBytes.length || outputPtr + outputSize > buffer.byteLength) {
424
+ throw new Error('SintBot binary core returned invalid App delta')
425
+ }
426
+ const bytes = new Uint8Array(buffer, outputPtr + 4, length)
427
+ const units = new Uint16Array(length / 2)
428
+ for (let i = 0; i < units.length; i++) units[i] = bytes[i * 2] | (bytes[i * 2 + 1] << 8)
429
+ let result = ''
430
+ for (let i = 0; i < units.length; i += 8192) result += String.fromCharCode(...units.subarray(i, i + 8192))
431
+ return result
432
+ } finally {
433
+ const memory = new Uint8Array(core.memory.buffer)
434
+ if (outputPtr && outputSize && outputPtr + outputSize <= memory.length) memory.fill(0, outputPtr, outputPtr + outputSize)
435
+ if (outputPtr && outputSize) core.dealloc(outputPtr, outputSize)
436
+ memory.fill(0, previousPtr, previousPtr + previousBytes.length)
437
+ core.dealloc(previousPtr, previousBytes.length)
438
+ if (deltaPtr) {
439
+ memory.fill(0, deltaPtr, deltaPtr + deltaBytes.length)
440
+ core.dealloc(deltaPtr, deltaBytes.length)
441
+ }
442
+ previousBytes.fill(0)
443
+ deltaBytes.fill(0)
444
+ }
445
+ }
446
+
447
+ function appLandedAction(itemType, done, hasClientId, alreadyLanded) {
448
+ const flags = (done ? 1 : 0) | (hasClientId ? 2 : 0) | (alreadyLanded ? 4 : 0)
449
+ const code = callText('app_landed_action', itemType, flags)
450
+ if (code === 0) return false
451
+ if (code === 1) return true
452
+ throw new Error(`SintBot binary core returned unknown App landing action ${code}`)
453
+ }
454
+
455
+ function appCompletionAction(status, matchesTurn, completed, hasEffort, retriedEffort, effortRejected) {
456
+ const flags = (matchesTurn ? 1 : 0) | (completed ? 2 : 0) | (hasEffort ? 4 : 0) |
457
+ (retriedEffort ? 8 : 0) | (effortRejected ? 16 : 0)
458
+ const code = callText('app_completion_action', status, flags)
459
+ if (code >= 0 && code <= 4) return code
460
+ throw new Error(`SintBot binary core returned unknown App completion action ${code}`)
461
+ }
462
+
463
+ // The host owns opaque turn IDs; the core selects which completion can settle
464
+ // the active turn or be retained until turn/start returns its ID.
465
+ function appCompletionNoticeAction({ threadMatches, hasTurnId, activeTurn, activeTurnMatches, pendingStart, completed }) {
466
+ const flags = (threadMatches ? 1 : 0) | (hasTurnId ? 2 : 0) | (activeTurn ? 4 : 0) |
467
+ (activeTurnMatches ? 8 : 0) | (pendingStart ? 16 : 0) | (completed ? 32 : 0)
468
+ const code = core.app_completion_notice_action(flags)
469
+ if (code >= 0 && code <= 2) return code
470
+ throw new Error(`SintBot binary core returned unknown App completion notice action ${code}`)
471
+ }
472
+
473
+ function manifestFeatures(features) {
474
+ const keys = ['boards', 'cardPinned', 'download', 'editRecall', 'history', 'imagen',
475
+ 'noticeCard', 'plainSend', 'react', 'skills', 'takeoverCard', 'mediaByPath']
476
+ const projected = {}
477
+ for (const key of keys) if (key !== 'mediaByPath') projected[key] = features ? features[key] : undefined
478
+ projected.mediaMarker = features ? features.mediaMarker : undefined
479
+ const value = coreJson('manifest_features', { features: projected }, 'select manifest platform features')
480
+ if (!value || keys.some((key) => typeof value[key] !== 'boolean')) {
481
+ throw new Error('SintBot binary core returned invalid manifest features')
482
+ }
483
+ return value
484
+ }
485
+
486
+ function systemAppendix(noReply) {
487
+ const bytes = encoder.encode(String(noReply))
488
+ const ptr = core.alloc(bytes.length)
489
+ let outputPtr = 0, outputSize = 0
490
+ try {
491
+ new Uint8Array(core.memory.buffer).set(bytes, ptr)
492
+ outputPtr = core.system_appendix(ptr, bytes.length)
493
+ if (!outputPtr) throw new Error('SintBot binary core could not render group appendix')
494
+ const buffer = core.memory.buffer
495
+ if (outputPtr + 4 > buffer.byteLength) throw new Error('SintBot binary core returned invalid group appendix')
496
+ const length = new DataView(buffer).getUint32(outputPtr, true)
497
+ outputSize = length + 4
498
+ if (outputPtr + outputSize > buffer.byteLength) throw new Error('SintBot binary core returned invalid group appendix')
499
+ return decoder.decode(new Uint8Array(buffer, outputPtr + 4, length))
500
+ } finally {
501
+ const memory = new Uint8Array(core.memory.buffer)
502
+ if (outputPtr && outputSize && outputPtr + outputSize <= memory.length) memory.fill(0, outputPtr, outputPtr + outputSize)
503
+ if (outputPtr && outputSize) core.dealloc(outputPtr, outputSize)
504
+ memory.fill(0, ptr, ptr + bytes.length)
505
+ core.dealloc(ptr, bytes.length)
506
+ bytes.fill(0)
507
+ }
508
+ }
509
+
510
+ function codexEffortRejection(result) {
511
+ const value = result && { isError: result.isError, effortRejected: result.effortRejected, text: result.text }
512
+ const code = callText('codex_effort_rejection', JSON.stringify(value))
513
+ if (code === 0) return false
514
+ if (code === 1) return true
515
+ throw new Error(`SintBot binary core returned unknown Codex effort decision ${code}`)
516
+ }
517
+
518
+ function parseResetFields(text) {
519
+ const value = coreJson('parse_reset_fields', String(text || ''), 'parse reset time')
520
+ if (value !== null && (!value || typeof value !== 'object' || Array.isArray(value) ||
521
+ (value.month !== null && !Number.isInteger(value.month)) ||
522
+ (value.day !== null && !Number.isInteger(value.day)) ||
523
+ !Number.isInteger(value.hour) || !Number.isInteger(value.minute) ||
524
+ (value.zone !== null && typeof value.zone !== 'string'))) {
525
+ throw new Error('SintBot binary core returned invalid reset time')
526
+ }
527
+ return value
528
+ }
529
+
530
+ function chooseResetEpoch(now, primary, nextYear, dated) {
531
+ const result = core.choose_reset_epoch(now, primary, nextYear, Number(!!dated))
532
+ return Number.isNaN(result) ? null : result
533
+ }
534
+
535
+ function wecomGatePrompt(input) {
536
+ const value = coreJson('wecom_gate_prompt', input, 'render WeCom gate prompt')
537
+ if (!value || typeof value.system !== 'string' || typeof value.user !== 'string') {
538
+ throw new Error('SintBot binary core returned invalid WeCom gate prompt')
539
+ }
540
+ return value
541
+ }
542
+
543
+ function manifestHeader(input) {
544
+ const lines = coreJson('manifest_header', input, 'render manifest header')
545
+ if (!Array.isArray(lines) || !lines.every((line) => typeof line === 'string')) {
546
+ throw new Error('SintBot binary core returned invalid manifest header')
547
+ }
548
+ return lines
549
+ }
550
+
551
+ function manifestContext(input) {
552
+ const lines = coreJson('manifest_context', input, 'render manifest context')
553
+ if (!Array.isArray(lines) || !lines.every((line) => typeof line === 'string')) {
554
+ throw new Error('SintBot binary core returned invalid manifest context')
555
+ }
556
+ return lines
557
+ }
558
+
559
+ function manifestSkills(input) {
560
+ const lines = coreJson('manifest_skills', input, 'render manifest platform skills')
561
+ if (!Array.isArray(lines) || !lines.every((line) => typeof line === 'string')) throw new Error('SintBot binary core returned invalid manifest platform skills')
562
+ return lines
563
+ }
564
+
565
+ function manifestStyleBoard(input) {
566
+ const lines = coreJson('manifest_style_board', input, 'render manifest style and board rules')
567
+ if (!Array.isArray(lines) || !lines.every((line) => typeof line === 'string')) throw new Error('SintBot binary core returned invalid manifest style and board rules')
568
+ return lines
569
+ }
570
+
571
+ function manifestImagenAsset(input) {
572
+ const lines = coreJson('manifest_imagen_asset', input, 'render manifest image and asset rules')
573
+ if (!Array.isArray(lines) || !lines.every((line) => typeof line === 'string')) throw new Error('SintBot binary core returned invalid manifest image and asset rules')
574
+ return lines
575
+ }
576
+
577
+ function manifestRuntime(input) {
578
+ const lines = coreJson('manifest_runtime', input, 'render manifest runtime rules')
579
+ if (!Array.isArray(lines) || !lines.every((line) => typeof line === 'string')) throw new Error('SintBot binary core returned invalid manifest runtime rules')
580
+ return lines
581
+ }
582
+
583
+ function imagenPrompt(input) {
584
+ const value = coreJson('imagen_prompt', input, 'render image prompt')
585
+ if (typeof value !== 'string') throw new Error('SintBot binary core returned invalid image prompt')
586
+ return value
587
+ }
588
+
589
+ function turnPrompt(input) {
590
+ const value = coreJson('turn_prompt', input, 'render turn prompt')
591
+ if (typeof value !== 'string') throw new Error('SintBot binary core returned invalid turn prompt')
592
+ return value
593
+ }
594
+
595
+ function compactEvent(subtype) {
596
+ const code = callText('compact_event', subtype)
597
+ if (code === 0) return false
598
+ if (code === 1) return true
599
+ throw new Error(`SintBot binary core returned unknown compaction decision ${code}`)
600
+ }
601
+
602
+ function engineQueueStep(state, event) {
603
+ const value = coreJson('engine_queue_step', { state, event }, 'advance engine queue')
604
+ if (!value || !value.state || !Array.isArray(value.state.queue) ||
605
+ !Array.isArray(value.effects) || !Number.isInteger(value.runLen) ||
606
+ !Number.isInteger(value.visibleQueue)) throw new Error('SintBot binary core returned invalid engine queue transition')
607
+ return value
608
+ }
609
+
610
+ function engineSlotsStep(state, event) {
611
+ const value = coreJson('engine_slots_step', { state, event }, 'advance engine slots')
612
+ if (!value || !value.state || typeof value.state !== 'object' ||
613
+ !Array.isArray(value.state.waiters) || !Array.isArray(value.effects) ||
614
+ value.effects.some((effect) => !effect || !['grant', 'reject'].includes(effect.type) || typeof effect.id !== 'string')) {
615
+ throw new Error('SintBot binary core returned invalid engine slots transition')
616
+ }
617
+ return value
618
+ }
619
+
620
+ function engineTurnStep(state, event) {
621
+ const value = coreJson('engine_turn_step', { state, event }, 'advance engine turn identity')
622
+ if (!value || !value.state || Array.isArray(value.state) || typeof value.state !== 'object' ||
623
+ !Number.isSafeInteger(value.state.epoch) || value.state.epoch < 0 ||
624
+ !(value.state.active === null || (Number.isSafeInteger(value.state.active) && value.state.active > 0)) ||
625
+ !Array.isArray(value.effects) || value.effects.some((effect) => !effect ||
626
+ !['turnToken', 'effectAllowed'].includes(effect.type) ||
627
+ !Number.isSafeInteger(effect.type === 'turnToken' ? effect.value : effect.turnToken))) {
628
+ throw new Error('SintBot binary core returned invalid engine turn transition')
629
+ }
630
+ return value
631
+ }
632
+
633
+ function engineSessionStep(state, event) {
634
+ const value = coreJson('engine_session_step', { state, event }, 'advance engine session')
635
+ const next = value && value.state
636
+ if (!next || Array.isArray(next) || typeof next !== 'object' ||
637
+ !Number.isSafeInteger(next.epoch) || next.epoch < 0 ||
638
+ typeof next.closeSeen !== 'boolean' || typeof next.settled !== 'boolean' ||
639
+ !Array.isArray(value.effects) || value.effects.some((effect) => !effect ||
640
+ !['writeSession', 'markTainted', 'resetSessionAndStats'].includes(effect.type))) {
641
+ throw new Error('SintBot binary core returned invalid engine session transition')
642
+ }
643
+ return value
644
+ }
645
+
646
+ function engineHandoffStep(state, event) {
647
+ const value = coreJson('engine_handoff_step', { state, event }, 'advance engine handoff')
648
+ const next = value && value.state
649
+ if (!next || Array.isArray(next) || typeof next !== 'object' ||
650
+ !['idle', 'running', 'releasing', 'handoff', 'sealed'].includes(next.phase) ||
651
+ !(next.turnToken === null || (Number.isSafeInteger(next.turnToken) && next.turnToken > 0)) ||
652
+ ![0, 1].includes(next.attempt) || !Array.isArray(next.acceptedReceiptIds) ||
653
+ !(next.nextJobId === null || typeof next.nextJobId === 'string') ||
654
+ !Array.isArray(value.effects) || value.effects.some((effect) => !effect ||
655
+ !['attemptQueueRelease', 'retryQueueRelease', 'sealGroup', 'notifyAccepted',
656
+ 'holdHandoff', 'scheduleDispatch', 'clearHandoff', 'dispatch'].includes(effect.type))) {
657
+ throw new Error('SintBot binary core returned invalid engine handoff transition')
658
+ }
659
+ return value
660
+ }
661
+
662
+ function engineIntakeStep(state, event) {
663
+ const value = coreJson('engine_intake_step', { state, event }, 'advance engine intake')
664
+ const next = value && value.state
665
+ if (!next || Array.isArray(next) || typeof next !== 'object' ||
666
+ !Number.isSafeInteger(next.watermark) || next.watermark < 0 ||
667
+ !Array.isArray(next.seen) || typeof next.unboundNotified !== 'boolean' ||
668
+ !(next.pending === null || (next.pending && typeof next.pending === 'object' &&
669
+ typeof next.pending.key === 'string' && Number.isSafeInteger(next.pending.at) &&
670
+ Number.isSafeInteger(next.pending.watermark))) ||
671
+ !Array.isArray(value.effects) || value.effects.some((effect) => !effect ||
672
+ !['notifyOrphan', 'sendUnboundGuide', 'clearQueue', 'handleCommand',
673
+ 'persistReceipt', 'dispatch'].includes(effect.type))) {
674
+ throw new Error('SintBot binary core returned invalid engine intake transition')
675
+ }
676
+ return value
677
+ }
678
+
679
+ function engineLifecycleStep(state, event) {
680
+ const value = coreJson('engine_lifecycle_step', { state, event }, 'advance engine lifecycle')
681
+ if (!value || !value.state || Array.isArray(value.state) || typeof value.state !== 'object' ||
682
+ !Array.isArray(value.effects) || value.effects.some((effect) => !effect || typeof effect.type !== 'string')) {
683
+ throw new Error('SintBot binary core returned invalid engine lifecycle transition')
684
+ }
685
+ return value
686
+ }
687
+
688
+ function engineTerminalStep(state, event) {
689
+ const value = coreJson('engine_terminal_step', { state, event }, 'advance engine terminal state')
690
+ const next = value && value.state
691
+ const outcome = next && next.outcome
692
+ const fields = ['silent', 'nothingProduced', 'sideEffects', 'sessionMissing',
693
+ 'lostRetry', 'network', 'quotaError', 'resumed']
694
+ if (!next || next.finalized !== true || !outcome ||
695
+ !['stopped', 'error', 'no-reply', 'empty', 'ok'].includes(outcome.status) ||
696
+ fields.some((field) => typeof outcome[field] !== 'boolean') ||
697
+ !Array.isArray(value.effects) || value.effects.some((effect) => !effect ||
698
+ !['markTainted', 'clearTainted', 'clearExhausted', 'verifyTurn'].includes(effect.type) ||
699
+ (effect.type === 'verifyTurn' && typeof effect.success !== 'boolean'))) {
700
+ throw new Error('SintBot binary core returned invalid engine terminal transition')
701
+ }
702
+ return value
703
+ }
704
+
705
+ function engineSteerStep(state, event) {
706
+ const value = coreJson('engine_steer_step', { state, event }, 'advance Codex follow-up')
707
+ if (!value || !value.state || Array.isArray(value.state) || typeof value.state !== 'object' ||
708
+ !Array.isArray(value.state.entries) || !Array.isArray(value.effects) ||
709
+ value.effects.some((effect) => !effect || typeof effect.type !== 'string')) {
710
+ throw new Error('SintBot binary core returned invalid Codex follow-up transition')
711
+ }
712
+ return value
713
+ }
714
+
715
+ function engineRecoveryStep(event) {
716
+ const value = coreJson('engine_recovery_step', event, 'advance engine recovery')
717
+ if (!value || !Array.isArray(value.effects)) throw new Error('SintBot binary core returned invalid engine recovery transition')
718
+ return value
719
+ }
720
+
721
+ function engineFailoverStep(event) {
722
+ const value = coreJson('engine_failover_step', event, 'advance engine failover')
723
+ if (!value || !Array.isArray(value.effects)) throw new Error('SintBot binary core returned invalid engine failover transition')
724
+ return value
725
+ }
726
+
727
+ // This stateful C2 entry is deliberately outside guarded(): a failed step may
728
+ // have mutated WASM memory before throwing, so later events must wait for an
729
+ // explicit instance rebuild from the host's last committed state.
730
+ function engineStep(state, event, admission = null) {
731
+ if (engineStepPoisoned) throw new Error('SintBot binary core C2 state needs recovery')
732
+ if (!state || ![1, 2].includes(state.version) || !Number.isSafeInteger(state.seq) || state.seq < 0 ||
733
+ !state.lanes || typeof state.lanes !== 'object' || Array.isArray(state.lanes) ||
734
+ !event || typeof event.id !== 'string' || !event.id ||
735
+ typeof event.domain !== 'string' || !event.domain ||
736
+ typeof event.scope !== 'string' || !event.scope ||
737
+ !Number.isSafeInteger(event.expectedCursor) || event.expectedCursor !== state.seq ||
738
+ !event.payload || typeof event.payload !== 'object' || Array.isArray(event.payload) ||
739
+ (state.version === 1 && admission !== null) ||
740
+ (state.version === 2 && (!admission || admission.version !== 1 ||
741
+ admission.cursor !== state.seq || admission.eventId !== event.id ||
742
+ admission.unseen !== true || Object.keys(admission).length !== 4))) {
743
+ throw new TypeError('invalid C2 step input')
744
+ }
745
+ try {
746
+ const input = state.version === 2 ? { state, event, admission } : { state, event }
747
+ const value = coreJson('engine_step', input, 'advance C2 engine')
748
+ if (!value || !value.state || value.state.version !== state.version ||
749
+ !Number.isSafeInteger(value.state.seq) || value.state.seq !== state.seq + 1 ||
750
+ !value.state.lanes || typeof value.state.lanes !== 'object' || Array.isArray(value.state.lanes) ||
751
+ value.cursor !== value.state.seq || value.eventId !== event.id ||
752
+ !Array.isArray(value.effects) || value.effects.some((effect, index) =>
753
+ !effect || typeof effect !== 'object' || typeof effect.type !== 'string' ||
754
+ effect.effectId !== `sbot-c2-effect-v1:${Buffer.byteLength(event.id)}:${event.id}:${index}`) ||
755
+ !value.decision || typeof value.decision !== 'object' || Array.isArray(value.decision)) {
756
+ throw new Error('SintBot binary core returned invalid C2 engine transition')
757
+ }
758
+ return value
759
+ } catch (error) {
760
+ engineStepPoisoned = true
761
+ throw error
762
+ }
763
+ }
764
+
765
+ function manifestPolicy(permissionMode, isCodex, allowedTools, disallowedTools) {
766
+ const value = coreJson('manifest_policy', { permissionMode, isCodex, allowedTools, disallowedTools }, 'decide manifest permissions')
767
+ if (!value || !Number.isInteger(value.tier) || value.tier < 0 || value.tier > 3 ||
768
+ typeof value.full !== 'boolean' || typeof value.pushDenied !== 'boolean') {
769
+ throw new Error('SintBot binary core returned invalid manifest policy')
770
+ }
771
+ return value
772
+ }
773
+
774
+ // A trap or exhausted stack can leave the instance's own stack pointer wrong, and
775
+ // C1 calls hold no state, so the next call simply gets a fresh instance.
776
+ function guarded(fn) {
777
+ return (...args) => {
778
+ try {
779
+ return fn(...args)
780
+ } catch (error) {
781
+ if (error instanceof WebAssembly.RuntimeError || error instanceof RangeError) boot()
782
+ throw error
783
+ }
784
+ }
785
+ }
786
+
787
+ const entries = { classifyError, routeBackend, sandboxTier, appErrorOverride, appNormalizeItem, appStreamTail, appNoticeAction, appDeltaNext, appLandedAction, appCompletionAction, appCompletionNoticeAction, manifestFeatures, manifestHeader, manifestContext, manifestSkills, manifestStyleBoard, manifestImagenAsset, manifestRuntime, manifestPolicy, systemAppendix, codexEffortRejection, wecomGatePrompt, imagenPrompt, turnPrompt, compactEvent, engineQueueStep, engineSlotsStep, engineTurnStep, engineSessionStep, engineHandoffStep, engineIntakeStep, engineLifecycleStep, engineTerminalStep, engineSteerStep, engineRecoveryStep, engineFailoverStep, parseResetFields, chooseResetEpoch, codexBuildPrompt, codexBuildArgs, appUsageFromTotal, settleUsage, appBuildRequest, claudeBaseSkillAllows, claudeBuildArgs, claudePluginAllowRules, claudeNormalizeEvent, codexNormalizeEvent, codexParseError }
788
+ for (const name of Object.keys(entries)) entries[name] = guarded(entries[name])
789
+
790
+ module.exports = { ...entries, engineStep, resetBinaryCore, HUMAN_BY_KIND: HUMAN }