@evomap/evolver-core 2.0.0-beta.19 → 2.0.0-beta.22

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 (160) hide show
  1. package/assets/gep/genes.jsonl +5 -5
  2. package/dist/algo/bans.d.ts +10 -1
  3. package/dist/algo/bans.js +56 -6
  4. package/dist/algo/candidateAssembly.d.ts +25 -2
  5. package/dist/algo/candidateAssembly.js +143 -20
  6. package/dist/algo/capabilityCandidates.js +10 -0
  7. package/dist/algo/cycleEngine.d.ts +40 -5
  8. package/dist/algo/cycleEngine.js +277 -37
  9. package/dist/algo/evolutionEvent.d.ts +26 -0
  10. package/dist/algo/evolutionEvent.js +32 -0
  11. package/dist/algo/exploration.d.ts +7 -0
  12. package/dist/algo/exploration.js +16 -3
  13. package/dist/algo/geneHealth.d.ts +34 -1
  14. package/dist/algo/geneHealth.js +42 -0
  15. package/dist/algo/geneIntake.d.ts +46 -1
  16. package/dist/algo/geneIntake.js +121 -10
  17. package/dist/algo/geneSelection.d.ts +115 -6
  18. package/dist/algo/geneSelection.js +459 -32
  19. package/dist/algo/index.d.ts +4 -1
  20. package/dist/algo/index.js +4 -1
  21. package/dist/algo/kautoProjection.d.ts +41 -0
  22. package/dist/algo/kautoProjection.js +95 -0
  23. package/dist/algo/kautoValidator.d.ts +68 -0
  24. package/dist/algo/kautoValidator.js +256 -0
  25. package/dist/algo/orchestrator.d.ts +14 -1
  26. package/dist/algo/orchestrator.js +9 -2
  27. package/dist/algo/solidify.d.ts +11 -2
  28. package/dist/algo/solidify.js +37 -7
  29. package/dist/algo/ucb1.d.ts +53 -0
  30. package/dist/algo/ucb1.js +156 -0
  31. package/dist/assetrepair/hubRejection.d.ts +12 -0
  32. package/dist/assetrepair/hubRejection.js +109 -0
  33. package/dist/assetrepair/index.d.ts +2 -0
  34. package/dist/assetrepair/index.js +2 -0
  35. package/dist/assetrepair/repair.d.ts +33 -0
  36. package/dist/assetrepair/repair.js +155 -0
  37. package/dist/assetstore/assetSidecarRecords.js +5 -1
  38. package/dist/assetstore/assetStoreHealth.d.ts +2 -3
  39. package/dist/assetstore/assetStoreHealth.js +4 -10
  40. package/dist/assetstore/foreignJsonlSource.d.ts +48 -0
  41. package/dist/assetstore/foreignJsonlSource.js +150 -0
  42. package/dist/assetstore/index.d.ts +3 -0
  43. package/dist/assetstore/index.js +3 -0
  44. package/dist/assetstore/learningHistory.js +3 -3
  45. package/dist/assetstore/localAssetStoreSnapshot.d.ts +51 -0
  46. package/dist/assetstore/localAssetStoreSnapshot.js +329 -0
  47. package/dist/assetstore/localJsonl.d.ts +8 -0
  48. package/dist/assetstore/localJsonl.js +128 -3
  49. package/dist/assetstore/provenance.d.ts +38 -3
  50. package/dist/assetstore/provenance.js +103 -45
  51. package/dist/assetstore/provider.d.ts +4 -0
  52. package/dist/assetstore/reviewFilter.d.ts +19 -1
  53. package/dist/assetstore/reviewFilter.js +36 -0
  54. package/dist/assetstore/unionReadStore.d.ts +25 -0
  55. package/dist/assetstore/unionReadStore.js +119 -0
  56. package/dist/benchmark/antiGeneBenchmark.d.ts +2 -0
  57. package/dist/benchmark/antiGeneBenchmark.js +4 -3
  58. package/dist/benchmark/antiGeneRollout.d.ts +2 -0
  59. package/dist/benchmark/antiGeneRollout.js +4 -3
  60. package/dist/benchmark/index.d.ts +2 -1
  61. package/dist/benchmark/index.js +2 -1
  62. package/dist/benchmark/selectionFlatAbstention.d.ts +152 -0
  63. package/dist/benchmark/selectionFlatAbstention.js +481 -0
  64. package/dist/bootstrap/envFingerprint.d.ts +9 -0
  65. package/dist/bootstrap/envFingerprint.js +5 -0
  66. package/dist/bootstrap/index.d.ts +2 -1
  67. package/dist/bootstrap/index.js +2 -1
  68. package/dist/bootstrap/lifecycleBootstrap.d.ts +111 -0
  69. package/dist/bootstrap/lifecycleBootstrap.js +433 -0
  70. package/dist/bootstrap/v1EnvCompat.d.ts +3 -0
  71. package/dist/bootstrap/v1EnvCompat.js +48 -1
  72. package/dist/events/eventArchive.d.ts +2 -0
  73. package/dist/events/eventArchive.js +13 -3
  74. package/dist/events/eventSchema.d.ts +7 -7
  75. package/dist/events/eventStore.d.ts +2 -0
  76. package/dist/events/eventStore.js +5 -1
  77. package/dist/events/ingest.d.ts +2 -1
  78. package/dist/events/ingest.js +6 -0
  79. package/dist/exec/autoExec.d.ts +30 -3
  80. package/dist/exec/autoExec.js +294 -29
  81. package/dist/exec/autonomousCycle.d.ts +7 -0
  82. package/dist/exec/autonomousCycle.js +2 -0
  83. package/dist/exec/claudeBridge.d.ts +28 -6
  84. package/dist/exec/claudeBridge.js +411 -258
  85. package/dist/exec/executionBinding.d.ts +414 -0
  86. package/dist/exec/executionBinding.js +588 -0
  87. package/dist/exec/index.d.ts +1 -0
  88. package/dist/exec/index.js +1 -0
  89. package/dist/exec/proofOfWork.d.ts +1 -1
  90. package/dist/exec/proofOfWork.js +2 -2
  91. package/dist/exec/runnerRegistry.d.ts +5 -0
  92. package/dist/exec/runnerRegistry.js +54 -14
  93. package/dist/hub/capability.d.ts +40 -1
  94. package/dist/hub/conversationDistiller.d.ts +19 -0
  95. package/dist/hub/conversationDistiller.js +115 -37
  96. package/dist/hub/fake.d.ts +1 -0
  97. package/dist/hub/fake.js +1 -0
  98. package/dist/hub/index.d.ts +1 -0
  99. package/dist/hub/index.js +1 -0
  100. package/dist/hub/recipeCompose.d.ts +27 -0
  101. package/dist/hub/recipeCompose.js +90 -0
  102. package/dist/hub/sanitize.js +119 -5
  103. package/dist/index.d.ts +2 -0
  104. package/dist/index.js +2 -0
  105. package/dist/mailbox/ipcServer.d.ts +2 -0
  106. package/dist/mailbox/ipcServer.js +20 -0
  107. package/dist/mailbox/store.d.ts +52 -2
  108. package/dist/mailbox/store.js +546 -81
  109. package/dist/modelCompatibility.d.ts +164 -0
  110. package/dist/modelCompatibility.js +309 -0
  111. package/dist/observers/valueDigestObserver.d.ts +9 -0
  112. package/dist/observers/valueDigestObserver.js +35 -2
  113. package/dist/ops/cleanup.js +1 -1
  114. package/dist/ops/evolutionGraphProjection.d.ts +20 -0
  115. package/dist/ops/evolutionGraphProjection.js +315 -0
  116. package/dist/ops/index.d.ts +2 -1
  117. package/dist/ops/index.js +2 -1
  118. package/dist/ops/selfUpdate.d.ts +8 -0
  119. package/dist/ops/selfUpdate.js +24 -8
  120. package/dist/ops/valueOutreach.d.ts +3 -1
  121. package/dist/ops/valueOutreach.js +5 -1
  122. package/dist/personality/schema.d.ts +18 -18
  123. package/dist/schema/evolutionGraph.d.ts +784 -0
  124. package/dist/schema/evolutionGraph.js +187 -0
  125. package/dist/schema/index.d.ts +1 -0
  126. package/dist/schema/index.js +1 -0
  127. package/dist/schema/proofOfWork.d.ts +125 -6
  128. package/dist/schema/proofOfWork.js +102 -4
  129. package/dist/shadow/shadowHub.js +1 -0
  130. package/dist/signals/expand.d.ts +15 -1
  131. package/dist/signals/expand.js +148 -0
  132. package/dist/signals/index.d.ts +3 -1
  133. package/dist/signals/index.js +3 -1
  134. package/dist/signals/scopeVocabulary.d.ts +75 -0
  135. package/dist/signals/scopeVocabulary.js +91 -0
  136. package/dist/signals/taskDomain.d.ts +22 -0
  137. package/dist/signals/taskDomain.js +43 -0
  138. package/dist/trace/learningTrace.d.ts +7 -0
  139. package/dist/trace/learningTrace.js +22 -0
  140. package/dist/trace/trajectory.d.ts +8 -0
  141. package/dist/trace/trajectory.js +14 -2
  142. package/dist/util/fileLock.d.ts +92 -5
  143. package/dist/util/fileLock.js +809 -70
  144. package/dist/util/index.d.ts +2 -1
  145. package/dist/util/index.js +1 -1
  146. package/dist/verify/index.d.ts +2 -1
  147. package/dist/verify/index.js +1 -1
  148. package/dist/verify/sandboxRunner.d.ts +2 -0
  149. package/dist/verify/sandboxRunner.js +154 -10
  150. package/dist/verify/sandboxedValidation.d.ts +7 -2
  151. package/dist/verify/sandboxedValidation.js +102 -24
  152. package/dist/verify/validation.d.ts +24 -3
  153. package/dist/verify/validation.js +141 -24
  154. package/dist/wire/geneHints.d.ts +88 -16
  155. package/dist/wire/geneHints.js +124 -15
  156. package/dist/wire/index.d.ts +8 -3
  157. package/dist/wire/index.js +2 -2
  158. package/dist/wire/schemaGate.d.ts +21 -0
  159. package/dist/wire/schemaGate.js +119 -10
  160. package/package.json +5 -4
@@ -10,12 +10,9 @@ export const REDACTED = '[REDACTED]';
10
10
  const REDACT_PATTERNS = [
11
11
  // API keys & tokens (generic)
12
12
  /Bearer\s+[A-Za-z0-9-._~+/]+=*/g,
13
- /"?node_secret"?\s*[:=]\s*["']?[A-Za-z0-9-._~+/]{16,}["']?/gi,
13
+ /\bBasic\s+[A-Za-z0-9+/]{8,}={0,2}(?=$|[\s,;)}\]])/gi,
14
+ /\b(?:AIza[0-9A-Za-z_-]{20,}|ya29\.[0-9A-Za-z_-]{20,}|(?:xai|hf|glpat|dop_v1|pk_live|pk_test|sk_live|sk_test|rk_live|rk_test)[-_][A-Za-z0-9_-]{16,}|sq0(?:atp|csp)-[A-Za-z0-9_-]{16,})\b/g,
14
15
  /sk-[A-Za-z0-9]{20,}/g,
15
- /"?token"?[=:]\s*["']?[A-Za-z0-9-._~+/]{16,}["']?/gi,
16
- /api[_-]?key[=:]\s*["']?[A-Za-z0-9-._~+/]{16,}["']?/gi,
17
- /secret[=:]\s*["']?[A-Za-z0-9-._~+/]{16,}["']?/gi,
18
- /password[=:]\s*["']?[^\s"',;)}\]]{6,}["']?/gi,
19
16
  // GitHub tokens (ghp_, gho_, ghu_, ghs_, ghr_, github_pat_)
20
17
  /ghp_[A-Za-z0-9]{36,}/g,
21
18
  /gho_[A-Za-z0-9]{36,}/g,
@@ -55,6 +52,120 @@ const REDACT_PATTERNS = [
55
52
  /\.env\.[a-zA-Z]+\b/g,
56
53
  /(?<=[\\/])\.env\b/g,
57
54
  ];
55
+ // 结构化执行诊断可能来自 JSON、YAML 或键值输出,字段名与分隔符之间也可能有空格。
56
+ // 这里只识别字段前缀,值由下面两个小解析器分别读取:带引号的值读取到匹配的闭合引号,
57
+ // 不带引号的值在空白或结构分隔符处停止,避免把凭据后的普通说明文字一起吞掉。
58
+ const STRUCTURED_CREDENTIAL_PREFIX = /(?<![A-Za-z0-9_-])(["']?)(node[_-]?secret|access[_-]?token|refresh[_-]?token|id[_-]?token|session[_-]?token|api[_-]?key|client[_-]?secret|private[_-]?key|token|secret|password|passwd|passphrase|credential|credentials|authorization|auth|bearer|cookie|dsn|webhook|signature)\1(\s*[:=]\s*)/gi;
59
+ const OPAQUE_CREDENTIAL_PATTERN = /(?<![A-Za-z0-9_-])[A-Za-z0-9][A-Za-z0-9._~+=-]{31,}(?![A-Za-z0-9_-])/g;
60
+ const AMBIGUOUS_STRUCTURED_KEYS = new Set([
61
+ 'token', 'secret', 'credential', 'credentials', 'authorization', 'auth', 'cookie', 'signature',
62
+ ]);
63
+ const DIAGNOSTIC_STATUS_VALUE = /^(?:ok|success|successful|succeeded|failed|failure|pending|missing|invalid|expired|mismatch|denied|unavailable|refresh needed|not configured|not found|none|null|true|false|enabled|disabled|present|absent|unknown|skipped|unsupported)$/i;
64
+ const DIAGNOSTIC_ASSIGNMENT_VALUE = /^(?:policy|mode|state|status|configured|enabled)=(?:ok|success|successful|succeeded|failed|failure|pending|missing|invalid|expired|mismatch|denied|unavailable|none|null|true|false|enabled|disabled|present|absent|unknown|skipped|unsupported)$/i;
65
+ function unquoteStructuredValue(value) {
66
+ const trimmed = value.trim();
67
+ if (trimmed.length >= 2 && ((trimmed.startsWith('"') && trimmed.endsWith('"')) || (trimmed.startsWith("'") && trimmed.endsWith("'")))) {
68
+ return trimmed.slice(1, -1).trim();
69
+ }
70
+ return trimmed;
71
+ }
72
+ function shouldRedactStructuredField(key, rawValue) {
73
+ const normalizedKey = key.toLowerCase().replace(/[_-]/g, '');
74
+ if (!AMBIGUOUS_STRUCTURED_KEYS.has(normalizedKey))
75
+ return true;
76
+ const value = unquoteStructuredValue(rawValue);
77
+ const normalizedStatus = value.replace(/[_-]+/g, ' ').replace(/\s+/g, ' ').trim();
78
+ if (!value
79
+ || /^\[redacted\]$/i.test(value)
80
+ || DIAGNOSTIC_STATUS_VALUE.test(normalizedStatus)
81
+ || DIAGNOSTIC_ASSIGNMENT_VALUE.test(value))
82
+ return false;
83
+ if (/^(?:Bearer|Digest|NTLM|Negotiate|AWS)\s+\S+/i.test(value))
84
+ return true;
85
+ if (/^Basic\s+[A-Za-z0-9+/]{8,}={0,2}$/i.test(value))
86
+ return true;
87
+ // 歧义字段只有在值呈现紧凑凭据形态时才脱敏,保留“auth: denied by policy”等诊断上下文。
88
+ return !/\s/.test(value) && value.length >= 8;
89
+ }
90
+ function readQuotedStructuredValue(input, start) {
91
+ const quote = input[start];
92
+ if (quote !== '"' && quote !== "'")
93
+ return undefined;
94
+ let escaped = false;
95
+ for (let index = start + 1; index < input.length; index += 1) {
96
+ const char = input[index];
97
+ if (escaped) {
98
+ escaped = false;
99
+ continue;
100
+ }
101
+ if (char === '\\') {
102
+ escaped = true;
103
+ continue;
104
+ }
105
+ if (char === quote) {
106
+ const end = index + 1;
107
+ return { end, raw: input.slice(start, end), quote };
108
+ }
109
+ if (char === '\r' || char === '\n')
110
+ break;
111
+ }
112
+ return undefined;
113
+ }
114
+ function readUnquotedStructuredValue(input, start) {
115
+ if (input.startsWith(REDACTED, start)) {
116
+ return { end: start + REDACTED.length, raw: REDACTED, quote: '' };
117
+ }
118
+ let end = start;
119
+ while (end < input.length) {
120
+ const char = input[end] ?? '';
121
+ if (/[\s,;)}\]]/.test(char) || (char === ':' && /\s/.test(input[end + 1] ?? '')))
122
+ break;
123
+ end += 1;
124
+ }
125
+ if (end === start)
126
+ return undefined;
127
+ return { end, raw: input.slice(start, end), quote: '' };
128
+ }
129
+ function redactStructuredCredentials(input) {
130
+ let cursor = 0;
131
+ let output = '';
132
+ STRUCTURED_CREDENTIAL_PREFIX.lastIndex = 0;
133
+ let match = STRUCTURED_CREDENTIAL_PREFIX.exec(input);
134
+ while (match) {
135
+ if (match.index < cursor) {
136
+ match = STRUCTURED_CREDENTIAL_PREFIX.exec(input);
137
+ continue;
138
+ }
139
+ const valueStart = STRUCTURED_CREDENTIAL_PREFIX.lastIndex;
140
+ const span = readQuotedStructuredValue(input, valueStart) ?? readUnquotedStructuredValue(input, valueStart);
141
+ if (!span) {
142
+ match = STRUCTURED_CREDENTIAL_PREFIX.exec(input);
143
+ continue;
144
+ }
145
+ output += input.slice(cursor, valueStart);
146
+ output += shouldRedactStructuredField(match[2] ?? '', span.raw)
147
+ ? `${span.quote}${REDACTED}${span.quote}`
148
+ : span.raw;
149
+ cursor = span.end;
150
+ STRUCTURED_CREDENTIAL_PREFIX.lastIndex = span.end;
151
+ match = STRUCTURED_CREDENTIAL_PREFIX.exec(input);
152
+ }
153
+ return cursor === 0 ? input : output + input.slice(cursor);
154
+ }
155
+ function isOpaqueCredential(candidate) {
156
+ const compact = candidate.replace(/[._~+/=-]/g, '');
157
+ const classes = Number(/[a-z]/.test(compact)) + Number(/[A-Z]/.test(compact)) + Number(/[0-9]/.test(compact));
158
+ if (compact.length < 24 || classes < 3 || /^[0-9a-f]+$/i.test(compact))
159
+ return false;
160
+ const frequencies = new Map();
161
+ for (const char of compact)
162
+ frequencies.set(char, (frequencies.get(char) ?? 0) + 1);
163
+ const entropy = [...frequencies.values()].reduce((sum, count) => {
164
+ const probability = count / compact.length;
165
+ return sum - probability * Math.log2(probability);
166
+ }, 0);
167
+ return entropy >= 3.5;
168
+ }
58
169
  // Post-filter allowlist (ported from v1 src/gep/sanitize.js, PR #151): strings the patterns above — and the path
59
170
  // anonymizer below — WILL catch but that are not actually sensitive. If any entry matches a captured string it is
60
171
  // kept verbatim instead of being redacted / anonymized / flagged as a leak. Keeping this as a post-filter rather
@@ -104,6 +215,9 @@ export function redactString(s) {
104
215
  p.lastIndex = 0;
105
216
  out = out.replace(p, (m) => (isAllowlisted(m) ? m : REDACTED));
106
217
  }
218
+ out = redactStructuredCredentials(out);
219
+ OPAQUE_CREDENTIAL_PATTERN.lastIndex = 0;
220
+ out = out.replace(OPAQUE_CREDENTIAL_PATTERN, (candidate) => (isOpaqueCredential(candidate) ? REDACTED : candidate));
107
221
  for (const [p, rep] of ANONYMIZE_PATTERNS) {
108
222
  p.lastIndex = 0;
109
223
  out = out.replace(p, (m) => (isAllowlisted(m) ? m : rep));
package/dist/index.d.ts CHANGED
@@ -10,6 +10,7 @@ export * as daemon from './daemon/index.js';
10
10
  export * as material from './material/index.js';
11
11
  export * as mailbox from './mailbox/index.js';
12
12
  export * as assetstore from './assetstore/index.js';
13
+ export * as assetrepair from './assetrepair/index.js';
13
14
  export * as strategy from './strategy/index.js';
14
15
  export * as algo from './algo/index.js';
15
16
  export * as personality from './personality/index.js';
@@ -27,4 +28,5 @@ export * as util from './util/index.js';
27
28
  export * as trace from './trace/index.js';
28
29
  export * as issueReporter from './issueReporter/index.js';
29
30
  export * as feedback from './feedback/index.js';
31
+ export * as compatibility from './modelCompatibility.js';
30
32
  export { isValidationCommandAllowed } from './verify/validation.js';
package/dist/index.js CHANGED
@@ -10,6 +10,7 @@ export * as daemon from './daemon/index.js';
10
10
  export * as material from './material/index.js';
11
11
  export * as mailbox from './mailbox/index.js';
12
12
  export * as assetstore from './assetstore/index.js';
13
+ export * as assetrepair from './assetrepair/index.js';
13
14
  export * as strategy from './strategy/index.js';
14
15
  export * as algo from './algo/index.js';
15
16
  export * as personality from './personality/index.js';
@@ -27,5 +28,6 @@ export * as util from './util/index.js';
27
28
  export * as trace from './trace/index.js';
28
29
  export * as issueReporter from './issueReporter/index.js';
29
30
  export * as feedback from './feedback/index.js';
31
+ export * as compatibility from './modelCompatibility.js';
30
32
  // Re-export commonly used validation functions at top level for convenience
31
33
  export { isValidationCommandAllowed } from './verify/validation.js';
@@ -22,6 +22,8 @@ export interface IpcRouteContext {
22
22
  route: string;
23
23
  now: number;
24
24
  store: MailboxStore;
25
+ /** 请求连接中止或响应提前关闭时触发;长任务应将其传给可取消的宿主执行器。 */
26
+ signal?: AbortSignal;
25
27
  readJson: () => Promise<unknown>;
26
28
  json: (code: number, body: unknown) => void;
27
29
  }
@@ -84,6 +84,20 @@ export class MailboxIpcServer {
84
84
  return new Promise((resolve, reject) => this.server.close((e) => (e ? reject(e) : resolve())));
85
85
  }
86
86
  async handle(req, res) {
87
+ const requestAbort = new AbortController();
88
+ const abortRequest = () => {
89
+ if (!requestAbort.signal.aborted)
90
+ requestAbort.abort(new Error('ipc_request_aborted'));
91
+ };
92
+ // 请求/响应 close 既可能表示客户端提前断开,也可能只是正常响应结束。
93
+ // 只有响应尚未完成时才传播取消,避免正常返回把后台验证误判为客户端取消。
94
+ const abortIfResponseOpen = () => {
95
+ if (!res.writableEnded && !res.writableFinished)
96
+ abortRequest();
97
+ };
98
+ req.once('aborted', abortIfResponseOpen);
99
+ req.socket.once('close', abortIfResponseOpen);
100
+ res.once('close', abortIfResponseOpen);
87
101
  try {
88
102
  const ra = req.socket.remoteAddress ?? '';
89
103
  if (!LOOPBACK.has(ra))
@@ -109,6 +123,7 @@ export class MailboxIpcServer {
109
123
  route,
110
124
  now,
111
125
  store: this.store,
126
+ signal: requestAbort.signal,
112
127
  readJson: () => this.readJson(req),
113
128
  json: (code, body) => this.json(res, code, body),
114
129
  });
@@ -215,6 +230,11 @@ export class MailboxIpcServer {
215
230
  catch (e) {
216
231
  return this.json(res, 400, { error: e instanceof Error ? e.message : String(e), code: 'invalid_request' });
217
232
  }
233
+ finally {
234
+ req.off('aborted', abortIfResponseOpen);
235
+ req.socket.off('close', abortIfResponseOpen);
236
+ res.off('close', abortIfResponseOpen);
237
+ }
218
238
  }
219
239
  readJson(req) {
220
240
  return new Promise((resolve, reject) => {
@@ -1,14 +1,59 @@
1
1
  import { type Envelope, type Status, type CreateEnvelopeInput } from './envelope.js';
2
2
  export declare const MAX_ATTEMPTS = 5;
3
3
  export declare const DEFAULT_IMPORT_JSONL_MAX_LINE_BYTES: number;
4
+ export declare const DEFAULT_IMPORT_JSONL_MAX_BYTES: number;
5
+ export declare const DEFAULT_IMPORT_JSONL_MAX_RECORDS = 100000;
4
6
  export declare const MAILBOX_CLAIM_OWNER: unique symbol;
5
7
  export type ClaimedEnvelope = Envelope & {
6
8
  readonly [MAILBOX_CLAIM_OWNER]: string;
7
9
  };
10
+ export type MailboxImportRecord = Readonly<{
11
+ kind: 'message';
12
+ envelope: Readonly<Envelope>;
13
+ }> | Readonly<{
14
+ kind: 'update';
15
+ id: string;
16
+ fields: Readonly<Record<string, unknown>>;
17
+ }>;
18
+ export type PreparedMailboxImport = Readonly<{
19
+ records: readonly MailboxImportRecord[];
20
+ sourceRecords: number;
21
+ messageCandidates: number;
22
+ uniqueMessageCandidates: number;
23
+ updateCandidates: number;
24
+ }>;
25
+ export type MailboxImportPreview = Readonly<{
26
+ sourceRecords: number;
27
+ messageCandidates: number;
28
+ uniqueMessageCandidates: number;
29
+ updateCandidates: number;
30
+ insertedMessages: number;
31
+ updatedMessages: number;
32
+ managedMessages: number;
33
+ protectedMessages: number;
34
+ }>;
35
+ export type MailboxJsonlImportErrorCode = 'line_too_large' | 'journal_too_large' | 'too_many_records' | 'invalid_utf8' | 'invalid_json' | 'invalid_record' | 'invalid_update' | 'unsupported_operation' | 'invalid_message';
36
+ export declare class MailboxJsonlImportError extends Error {
37
+ readonly code: MailboxJsonlImportErrorCode;
38
+ readonly line: number;
39
+ constructor(code: MailboxJsonlImportErrorCode, line: number, message: string);
40
+ }
8
41
  export declare function mailboxClaimOwner(envelope: Envelope): string | undefined;
9
42
  export declare function expBackoffMs(attempt: number): number;
10
43
  /** Read one mailbox state value without creating, migrating, or taking write ownership of the database. */
11
44
  export declare function readMailboxState(path: string, key: string): string | undefined;
45
+ /**
46
+ * Parse and normalize a V1 mailbox journal without opening or mutating a V2 mailbox.
47
+ * The returned batch is sealed so dry-run and apply can consume the exact same records.
48
+ */
49
+ export declare function prepareMailboxJsonlImport(source: string | number, options?: {
50
+ maxLineBytes?: number;
51
+ maxBytes?: number;
52
+ maxRecords?: number;
53
+ now?: number;
54
+ }): PreparedMailboxImport;
55
+ /** Preview a prepared import against an optional existing mailbox without creating or migrating it. */
56
+ export declare function previewPreparedMailboxImport(batch: PreparedMailboxImport, mailboxPath?: string): MailboxImportPreview;
12
57
  /** mailbox sqlite 引擎 (WAL + busy_timeout). 状态机 pending→in_flight→done/failed/expired + 租约 + 重试/DLQ. */
13
58
  export declare class MailboxStore {
14
59
  private readonly db;
@@ -117,8 +162,13 @@ export declare class MailboxStore {
117
162
  markProcessedIf(sourceKey: string, markerKey: string, markerResult: unknown, now: number, matches: (sourceResult: unknown) => boolean): boolean;
118
163
  deleteProcessed(keys: readonly string[]): void;
119
164
  private messageClaimOwner;
120
- /** v1 messages.jsonl sqlite 迁移(幂等可重入). */
165
+ /** Build the target-aware plan shared by preview and apply. */
166
+ private buildPreparedImportPlan;
167
+ /** Preview the exact import result against the current mailbox snapshot without writing to it. */
168
+ previewPreparedImport(batch: PreparedMailboxImport): MailboxImportPreview;
169
+ private writeImportedEnvelopeFields;
170
+ /** Apply a parsed batch; planning and writes share one transaction and one normalized journal. */
171
+ importPrepared(batch: PreparedMailboxImport): number;
121
172
  importJsonl(source: string | number): number;
122
- private applyImportedV1Update;
123
173
  close(): void;
124
174
  }