@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.
- package/assets/gep/genes.jsonl +5 -5
- package/dist/algo/bans.d.ts +10 -1
- package/dist/algo/bans.js +56 -6
- package/dist/algo/candidateAssembly.d.ts +25 -2
- package/dist/algo/candidateAssembly.js +143 -20
- package/dist/algo/capabilityCandidates.js +10 -0
- package/dist/algo/cycleEngine.d.ts +40 -5
- package/dist/algo/cycleEngine.js +277 -37
- package/dist/algo/evolutionEvent.d.ts +26 -0
- package/dist/algo/evolutionEvent.js +32 -0
- package/dist/algo/exploration.d.ts +7 -0
- package/dist/algo/exploration.js +16 -3
- package/dist/algo/geneHealth.d.ts +34 -1
- package/dist/algo/geneHealth.js +42 -0
- package/dist/algo/geneIntake.d.ts +46 -1
- package/dist/algo/geneIntake.js +121 -10
- package/dist/algo/geneSelection.d.ts +115 -6
- package/dist/algo/geneSelection.js +459 -32
- package/dist/algo/index.d.ts +4 -1
- package/dist/algo/index.js +4 -1
- package/dist/algo/kautoProjection.d.ts +41 -0
- package/dist/algo/kautoProjection.js +95 -0
- package/dist/algo/kautoValidator.d.ts +68 -0
- package/dist/algo/kautoValidator.js +256 -0
- package/dist/algo/orchestrator.d.ts +14 -1
- package/dist/algo/orchestrator.js +9 -2
- package/dist/algo/solidify.d.ts +11 -2
- package/dist/algo/solidify.js +37 -7
- package/dist/algo/ucb1.d.ts +53 -0
- package/dist/algo/ucb1.js +156 -0
- package/dist/assetrepair/hubRejection.d.ts +12 -0
- package/dist/assetrepair/hubRejection.js +109 -0
- package/dist/assetrepair/index.d.ts +2 -0
- package/dist/assetrepair/index.js +2 -0
- package/dist/assetrepair/repair.d.ts +33 -0
- package/dist/assetrepair/repair.js +155 -0
- package/dist/assetstore/assetSidecarRecords.js +5 -1
- package/dist/assetstore/assetStoreHealth.d.ts +2 -3
- package/dist/assetstore/assetStoreHealth.js +4 -10
- package/dist/assetstore/foreignJsonlSource.d.ts +48 -0
- package/dist/assetstore/foreignJsonlSource.js +150 -0
- package/dist/assetstore/index.d.ts +3 -0
- package/dist/assetstore/index.js +3 -0
- package/dist/assetstore/learningHistory.js +3 -3
- package/dist/assetstore/localAssetStoreSnapshot.d.ts +51 -0
- package/dist/assetstore/localAssetStoreSnapshot.js +329 -0
- package/dist/assetstore/localJsonl.d.ts +8 -0
- package/dist/assetstore/localJsonl.js +128 -3
- package/dist/assetstore/provenance.d.ts +38 -3
- package/dist/assetstore/provenance.js +103 -45
- package/dist/assetstore/provider.d.ts +4 -0
- package/dist/assetstore/reviewFilter.d.ts +19 -1
- package/dist/assetstore/reviewFilter.js +36 -0
- package/dist/assetstore/unionReadStore.d.ts +25 -0
- package/dist/assetstore/unionReadStore.js +119 -0
- package/dist/benchmark/antiGeneBenchmark.d.ts +2 -0
- package/dist/benchmark/antiGeneBenchmark.js +4 -3
- package/dist/benchmark/antiGeneRollout.d.ts +2 -0
- package/dist/benchmark/antiGeneRollout.js +4 -3
- package/dist/benchmark/index.d.ts +2 -1
- package/dist/benchmark/index.js +2 -1
- package/dist/benchmark/selectionFlatAbstention.d.ts +152 -0
- package/dist/benchmark/selectionFlatAbstention.js +481 -0
- package/dist/bootstrap/envFingerprint.d.ts +9 -0
- package/dist/bootstrap/envFingerprint.js +5 -0
- package/dist/bootstrap/index.d.ts +2 -1
- package/dist/bootstrap/index.js +2 -1
- package/dist/bootstrap/lifecycleBootstrap.d.ts +111 -0
- package/dist/bootstrap/lifecycleBootstrap.js +433 -0
- package/dist/bootstrap/v1EnvCompat.d.ts +3 -0
- package/dist/bootstrap/v1EnvCompat.js +48 -1
- package/dist/events/eventArchive.d.ts +2 -0
- package/dist/events/eventArchive.js +13 -3
- package/dist/events/eventSchema.d.ts +7 -7
- package/dist/events/eventStore.d.ts +2 -0
- package/dist/events/eventStore.js +5 -1
- package/dist/events/ingest.d.ts +2 -1
- package/dist/events/ingest.js +6 -0
- package/dist/exec/autoExec.d.ts +30 -3
- package/dist/exec/autoExec.js +294 -29
- package/dist/exec/autonomousCycle.d.ts +7 -0
- package/dist/exec/autonomousCycle.js +2 -0
- package/dist/exec/claudeBridge.d.ts +28 -6
- package/dist/exec/claudeBridge.js +411 -258
- package/dist/exec/executionBinding.d.ts +414 -0
- package/dist/exec/executionBinding.js +588 -0
- package/dist/exec/index.d.ts +1 -0
- package/dist/exec/index.js +1 -0
- package/dist/exec/proofOfWork.d.ts +1 -1
- package/dist/exec/proofOfWork.js +2 -2
- package/dist/exec/runnerRegistry.d.ts +5 -0
- package/dist/exec/runnerRegistry.js +54 -14
- package/dist/hub/capability.d.ts +40 -1
- package/dist/hub/conversationDistiller.d.ts +19 -0
- package/dist/hub/conversationDistiller.js +115 -37
- package/dist/hub/fake.d.ts +1 -0
- package/dist/hub/fake.js +1 -0
- package/dist/hub/index.d.ts +1 -0
- package/dist/hub/index.js +1 -0
- package/dist/hub/recipeCompose.d.ts +27 -0
- package/dist/hub/recipeCompose.js +90 -0
- package/dist/hub/sanitize.js +119 -5
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/mailbox/ipcServer.d.ts +2 -0
- package/dist/mailbox/ipcServer.js +20 -0
- package/dist/mailbox/store.d.ts +52 -2
- package/dist/mailbox/store.js +546 -81
- package/dist/modelCompatibility.d.ts +164 -0
- package/dist/modelCompatibility.js +309 -0
- package/dist/observers/valueDigestObserver.d.ts +9 -0
- package/dist/observers/valueDigestObserver.js +35 -2
- package/dist/ops/cleanup.js +1 -1
- package/dist/ops/evolutionGraphProjection.d.ts +20 -0
- package/dist/ops/evolutionGraphProjection.js +315 -0
- package/dist/ops/index.d.ts +2 -1
- package/dist/ops/index.js +2 -1
- package/dist/ops/selfUpdate.d.ts +8 -0
- package/dist/ops/selfUpdate.js +24 -8
- package/dist/ops/valueOutreach.d.ts +3 -1
- package/dist/ops/valueOutreach.js +5 -1
- package/dist/personality/schema.d.ts +18 -18
- package/dist/schema/evolutionGraph.d.ts +784 -0
- package/dist/schema/evolutionGraph.js +187 -0
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/index.js +1 -0
- package/dist/schema/proofOfWork.d.ts +125 -6
- package/dist/schema/proofOfWork.js +102 -4
- package/dist/shadow/shadowHub.js +1 -0
- package/dist/signals/expand.d.ts +15 -1
- package/dist/signals/expand.js +148 -0
- package/dist/signals/index.d.ts +3 -1
- package/dist/signals/index.js +3 -1
- package/dist/signals/scopeVocabulary.d.ts +75 -0
- package/dist/signals/scopeVocabulary.js +91 -0
- package/dist/signals/taskDomain.d.ts +22 -0
- package/dist/signals/taskDomain.js +43 -0
- package/dist/trace/learningTrace.d.ts +7 -0
- package/dist/trace/learningTrace.js +22 -0
- package/dist/trace/trajectory.d.ts +8 -0
- package/dist/trace/trajectory.js +14 -2
- package/dist/util/fileLock.d.ts +92 -5
- package/dist/util/fileLock.js +809 -70
- package/dist/util/index.d.ts +2 -1
- package/dist/util/index.js +1 -1
- package/dist/verify/index.d.ts +2 -1
- package/dist/verify/index.js +1 -1
- package/dist/verify/sandboxRunner.d.ts +2 -0
- package/dist/verify/sandboxRunner.js +154 -10
- package/dist/verify/sandboxedValidation.d.ts +7 -2
- package/dist/verify/sandboxedValidation.js +102 -24
- package/dist/verify/validation.d.ts +24 -3
- package/dist/verify/validation.js +141 -24
- package/dist/wire/geneHints.d.ts +88 -16
- package/dist/wire/geneHints.js +124 -15
- package/dist/wire/index.d.ts +8 -3
- package/dist/wire/index.js +2 -2
- package/dist/wire/schemaGate.d.ts +21 -0
- package/dist/wire/schemaGate.js +119 -10
- package/package.json +5 -4
package/dist/hub/sanitize.js
CHANGED
|
@@ -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
|
-
|
|
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';
|
|
@@ -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) => {
|
package/dist/mailbox/store.d.ts
CHANGED
|
@@ -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
|
-
/**
|
|
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
|
}
|