@danceiny/gotry 0.0.1-rc.15 → 0.0.1-rc.17
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/README.md +51 -13
- package/README.zh-CN.md +26 -12
- package/bin/gotry-booking-copilot.js +53 -0
- package/bin/gotry-bootstrap.js +357 -8
- package/bin/gotry-inner.js +442 -60
- package/bin/gotry-runtime-resolution.d.ts +27 -0
- package/bin/gotry-runtime-resolution.js +50 -0
- package/bin/gotry.js +1 -1
- package/cordis.gotry-patch.yml +15 -1
- package/data/airline-airports.json +39 -0
- package/dist/capabilities/agent-reach-deep.js +1 -1
- package/dist/capabilities/agent-reach.js +1 -1
- package/dist/capabilities/anything.js +1 -1
- package/dist/capabilities/artifacts.js +1 -1
- package/dist/capabilities/effect.js +293 -0
- package/dist/capabilities/fact-log.js +41 -0
- package/dist/capabilities/flyai.js +20 -6
- package/dist/capabilities/hbcli.js +43 -1
- package/dist/capabilities/incident-log.js +1 -1
- package/dist/capabilities/model-override.js +18 -0
- package/dist/capabilities/opensky.js +1 -1
- package/dist/capabilities/resilience.js +90 -0
- package/dist/capabilities/session/action-cache.js +1 -1
- package/dist/capabilities/session/adapters/ctrip-flight.js +1 -1
- package/dist/capabilities/session/adapters/meituan-local.js +1 -1
- package/dist/capabilities/session/benchmark.js +2 -1
- package/dist/capabilities/session/extension-bridge.js +358 -0
- package/dist/capabilities/session/extension-channel.js +93 -0
- package/dist/capabilities/session/extension-distribution.js +234 -0
- package/dist/capabilities/session/extract.js +1 -1
- package/dist/capabilities/session/golden-score.js +92 -0
- package/dist/capabilities/session/health-watch.js +216 -0
- package/dist/capabilities/session/read-guard.js +1 -1
- package/dist/capabilities/session/static-flight-golden.js +137 -0
- package/dist/capabilities/session/transport.js +1 -1
- package/dist/capabilities/session/wizard.js +147 -0
- package/dist/capabilities/session-consent.js +1 -1
- package/dist/capabilities/session-login.js +83 -1
- package/dist/capabilities/session-search.js +111 -2
- package/dist/capabilities/weather.js +168 -46
- package/dist/data/session-golden-20.json +25 -0
- package/dist/data/sf-golden-manifest.json +102 -0
- package/dist/data/sf-static-routes.json +91 -0
- package/dist/scripts/action-cache-tests.js +1 -1
- package/dist/scripts/agent-planning-budget-e2e.js +227 -0
- package/dist/scripts/agent-planning-budget-tests.js +173 -0
- package/dist/scripts/agent-reach-deep-tests.js +1 -1
- package/dist/scripts/agent-reach-tests.js +1 -1
- package/dist/scripts/agent-reach-wrapper-tests.js +1 -1
- package/dist/scripts/anything-tests.js +1 -1
- package/dist/scripts/async-collect.js +1 -1
- package/dist/scripts/benchmark-environment-bridge-e2e.js +981 -0
- package/dist/scripts/benchmark-environment-bridge-tests.js +2544 -0
- package/dist/scripts/booking-copilot-availability-ledger-binding-tests.js +335 -0
- package/dist/scripts/booking-copilot-availability-policy-v2-tests.js +1355 -0
- package/dist/scripts/booking-copilot-bin-proof-tests.js +89 -0
- package/dist/scripts/booking-copilot-crossrepo-fixture-server.js +113 -0
- package/dist/scripts/booking-copilot-dsh-core-proof-tests.js +356 -0
- package/dist/scripts/booking-copilot-dsh-planner-proof-tests.js +557 -0
- package/dist/scripts/booking-copilot-dsh-plugin-proof-tests.js +140 -0
- package/dist/scripts/booking-copilot-event-sequence-concurrency-proof-tests.js +202 -0
- package/dist/scripts/booking-copilot-gap-code-contract-proof-tests.js +102 -0
- package/dist/scripts/booking-copilot-operation-ledger-concurrency-proof-tests.js +374 -0
- package/dist/scripts/booking-copilot-receipt-ledger-concurrency-proof-tests.js +447 -0
- package/dist/scripts/booking-copilot-runtime-proof-tests.js +205 -0
- package/dist/scripts/booking-copilot-server-proof-tests.js +317 -0
- package/dist/scripts/booking-copilot-startup-proof-tests.js +283 -0
- package/dist/scripts/booking-copilot-v2-runtime-proof-tests.js +3935 -0
- package/dist/scripts/booking-saga-tests.js +1 -1
- package/dist/scripts/booking-surface-contract-proof-tests.js +393 -0
- package/dist/scripts/booking-surface-v2-contract-proof-tests.js +1174 -0
- package/dist/scripts/bootstrap-tests.js +59 -3
- package/dist/scripts/build-changelog.js +279 -0
- package/dist/scripts/changelog-tests.js +165 -0
- package/dist/scripts/companion-tests.js +1 -1
- package/dist/scripts/diff-test.js +1 -1
- package/dist/scripts/dsh-runtime-closure-tests.js +225 -0
- package/dist/scripts/dsh-runtime-closure.js +150 -0
- package/dist/scripts/effect-tests.js +474 -0
- package/dist/scripts/engine-run.js +1 -1
- package/dist/scripts/engine-tests.js +1 -1
- package/dist/scripts/evaluation-cadence-tests.js +347 -0
- package/dist/scripts/evaluation-contract-tests.js +574 -0
- package/dist/scripts/extension-distribution-cli.js +35 -0
- package/dist/scripts/extension-distribution-tests.js +341 -0
- package/dist/scripts/extension-tests.js +573 -0
- package/dist/scripts/fact-gate-tests.js +318 -0
- package/dist/scripts/flyai-tests.js +1 -1
- package/dist/scripts/hbcli-e2e-tests.js +180 -0
- package/dist/scripts/hbcli-tests.js +1 -1
- package/dist/scripts/health-watch-cli.js +51 -0
- package/dist/scripts/i18n-tests.js +1 -1
- package/dist/scripts/incident-tests.js +1 -1
- package/dist/scripts/journey-tests.js +1 -1
- package/dist/scripts/ledger-tests.js +1 -1
- package/dist/scripts/ledger-workflow-crash.js +1 -1
- package/dist/scripts/memory-capture-tests.js +1 -1
- package/dist/scripts/memory-decay-tests.js +1 -1
- package/dist/scripts/memory-metrics.js +1 -1
- package/dist/scripts/memory-value-report.js +1 -1
- package/dist/scripts/model-override-e2e.js +176 -0
- package/dist/scripts/nightly-evidence-tests.js +67 -4
- package/dist/scripts/nightly-evidence.js +59 -3
- package/dist/scripts/nudge-digest.js +1 -1
- package/dist/scripts/onboarding-tests.js +186 -0
- package/dist/scripts/opensky-check.js +1 -1
- package/dist/scripts/opensky-tests.js +1 -1
- package/dist/scripts/pnpm-dsh-closure-proof.js +20 -0
- package/dist/scripts/price-drift-tests.js +441 -0
- package/dist/scripts/price-drift-watch.js +491 -0
- package/dist/scripts/probe-poi-tests.js +1 -1
- package/dist/scripts/product-metrics.js +1 -1
- package/dist/scripts/publish-preverify.js +40 -4
- package/dist/scripts/realtime-pricing-tests.js +1 -1
- package/dist/scripts/replay-async.js +1 -1
- package/dist/scripts/replay-real.js +1 -1
- package/dist/scripts/replay.js +1 -1
- package/dist/scripts/session-attach-diagnose.js +1 -1
- package/dist/scripts/session-attach-poc.js +1 -1
- package/dist/scripts/session-benchmark.js +1 -1
- package/dist/scripts/session-extract-tests.js +1 -1
- package/dist/scripts/session-login.js +1 -1
- package/dist/scripts/session-tests.js +70 -20
- package/dist/scripts/sf-live-benchmark.js +338 -0
- package/dist/scripts/sf-live-cli-tests.js +21 -0
- package/dist/scripts/sf-soft-score-tests.js +108 -0
- package/dist/scripts/sf-summary.js +93 -0
- package/dist/scripts/skeleton-check.js +1 -1
- package/dist/scripts/skeleton-integration-test.js +1 -1
- package/dist/scripts/skills-contract-tests.js +1 -1
- package/dist/scripts/smoke-session-gate-tests.js +29 -0
- package/dist/scripts/smoke.js +154 -33
- package/dist/scripts/state-cli-tests.js +1 -1
- package/dist/scripts/state-cli.js +1 -1
- package/dist/scripts/static-golden-tests.js +299 -0
- package/dist/scripts/time-eval-tests.js +1 -1
- package/dist/scripts/travel-timeline-tests.js +1 -1
- package/dist/scripts/unified-tests.js +1 -1
- package/dist/scripts/weather-tests.js +694 -44
- package/dist/scripts/z3-race-tests.js +1 -1
- package/dist/src/artifact-gate.js +310 -0
- package/dist/src/benchmark-agent-conformance.js +370 -0
- package/dist/src/benchmark-environment-bridge.js +384 -0
- package/dist/src/benchmark-headless-child-diagnostics.js +173 -0
- package/dist/src/benchmark-tool-isolation.js +124 -0
- package/dist/src/bookable-facts.js +349 -0
- package/dist/src/booking-saga.js +1 -1
- package/dist/src/booking-surface/availability-policy-v2.js +830 -0
- package/dist/src/booking-surface/canonical-schema.js +113 -0
- package/dist/src/booking-surface/contracts-v2.js +89 -0
- package/dist/src/booking-surface/contracts.js +46 -0
- package/dist/src/booking-surface/dsh-planner.js +453 -0
- package/dist/src/booking-surface/dsh-plugin.js +93 -0
- package/dist/src/booking-surface/error-codes.js +94 -0
- package/dist/src/booking-surface/index.js +15 -0
- package/dist/src/booking-surface/profile.js +68 -0
- package/dist/src/booking-surface/runtime-v2.js +1771 -0
- package/dist/src/booking-surface/runtime.js +351 -0
- package/dist/src/booking-surface/server-v2.js +334 -0
- package/dist/src/booking-surface/server.js +302 -0
- package/dist/src/booking-surface/startup.js +159 -0
- package/dist/src/booking-surface/validation-v2.js +319 -0
- package/dist/src/booking-surface/validation.js +809 -0
- package/dist/src/bridge.js +1 -1
- package/dist/src/companions.js +1 -1
- package/dist/src/contracts.js +1 -1
- package/dist/src/dsh-llm.js +1 -1
- package/dist/src/engine.js +1 -1
- package/dist/src/evaluation-cadence.js +234 -0
- package/dist/src/evaluation-contracts.js +906 -0
- package/dist/src/i18n.js +1 -1
- package/dist/src/index.js +234 -60
- package/dist/src/journey.js +1 -1
- package/dist/src/loop.js +1 -1
- package/dist/src/memory-capture.js +1 -1
- package/dist/src/memory-decay.js +1 -1
- package/dist/src/memory-utility.js +1 -1
- package/dist/src/mock-llm.js +1 -1
- package/dist/src/model.js +1 -1
- package/dist/src/realtime-pricing.js +14 -7
- package/dist/src/slot-spec.js +1 -1
- package/dist/src/state-ledger.js +2 -1
- package/dist/src/time-anchor.js +1 -1
- package/dist/src/tool-budget.js +136 -0
- package/dist/src/tool-packet.js +1 -1
- package/dist/src/travel-slots.js +1 -1
- package/dist/src/travel-timeline.js +1 -1
- package/dist/src/unified.js +1 -1
- package/dist/src/wish-pool.js +1 -1
- package/dist/src/z3-shared.js +1 -1
- package/extension/README.md +50 -0
- package/extension/background.js +160 -0
- package/extension/content-bridge.js +41 -0
- package/extension/content-main.js +62 -0
- package/extension/manifest.json +32 -0
- package/package.json +291 -12
- package/schemas/booking.surface.v1.schema.json +927 -0
- package/schemas/booking.surface.v2.schema.json +61 -0
- package/ts/capabilities/fact-log.ts +54 -0
- package/ts/capabilities/flyai.ts +16 -3
- package/ts/capabilities/hbcli.ts +46 -0
- package/ts/capabilities/session/benchmark.ts +4 -1
- package/ts/capabilities/session/extension-bridge.ts +377 -0
- package/ts/capabilities/session/extension-channel.ts +95 -0
- package/ts/capabilities/session/extension-distribution.ts +264 -0
- package/ts/capabilities/session/golden-score.ts +139 -0
- package/ts/capabilities/session/health-watch.ts +257 -0
- package/ts/capabilities/session/static-flight-golden.ts +209 -0
- package/ts/capabilities/session/wizard.ts +140 -0
- package/ts/capabilities/session-login.ts +63 -2
- package/ts/capabilities/session-search.ts +105 -3
- package/ts/capabilities/weather.ts +141 -52
- package/ts/package.json +3 -3
- package/ts/src/artifact-gate.ts +365 -0
- package/ts/src/benchmark-agent-conformance.ts +448 -0
- package/ts/src/benchmark-environment-bridge.ts +348 -0
- package/ts/src/benchmark-headless-child-diagnostics.ts +184 -0
- package/ts/src/benchmark-tool-isolation.ts +166 -0
- package/ts/src/bookable-facts.ts +557 -0
- package/ts/src/booking-surface/availability-policy-v2.ts +523 -0
- package/ts/src/booking-surface/canonical-schema.js +113 -0
- package/ts/src/booking-surface/contracts-v2.ts +118 -0
- package/ts/src/booking-surface/contracts.ts +380 -0
- package/ts/src/booking-surface/dsh-planner.ts +452 -0
- package/ts/src/booking-surface/dsh-plugin.js +93 -0
- package/ts/src/booking-surface/error-codes.ts +101 -0
- package/ts/src/booking-surface/index.ts +12 -0
- package/ts/src/booking-surface/profile.ts +42 -0
- package/ts/src/booking-surface/runtime-v2.ts +1466 -0
- package/ts/src/booking-surface/runtime.ts +483 -0
- package/ts/src/booking-surface/server-v2.ts +247 -0
- package/ts/src/booking-surface/server.ts +324 -0
- package/ts/src/booking-surface/startup.ts +196 -0
- package/ts/src/booking-surface/validation-v2.ts +205 -0
- package/ts/src/booking-surface/validation.ts +453 -0
- package/ts/src/index.ts +161 -14
- package/ts/src/state-ledger.ts +1 -0
- package/ts/src/tool-budget.ts +165 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import test from 'node:test';
|
|
3
|
+
import { parsePnpmDshLock, parsePnpmRootDshImporter, REQUIRED_DSH_RUNTIME_PACKAGE_COUNT, validateDshRuntimeClosure, validatePnpmRootDshImporter } from './dsh-runtime-closure.js';
|
|
4
|
+
const VERSION = '0.1.2-alpha.3';
|
|
5
|
+
function validInput() {
|
|
6
|
+
return {
|
|
7
|
+
dependencies: {
|
|
8
|
+
'@deepseek-ai/dsh': VERSION,
|
|
9
|
+
'@deepseek-ai/dsh-session-title': VERSION
|
|
10
|
+
},
|
|
11
|
+
lockPackages: {
|
|
12
|
+
'node_modules/@deepseek-ai/dsh': {
|
|
13
|
+
version: VERSION
|
|
14
|
+
},
|
|
15
|
+
'node_modules/@deepseek-ai/dsh-session-title': {
|
|
16
|
+
version: VERSION
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
runtimeVersion: VERSION
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
test('accepts an exact coherent DSH prerelease closure', ()=>{
|
|
23
|
+
assert.deepEqual(validateDshRuntimeClosure(validInput()), {
|
|
24
|
+
names: [
|
|
25
|
+
'@deepseek-ai/dsh',
|
|
26
|
+
'@deepseek-ai/dsh-session-title'
|
|
27
|
+
],
|
|
28
|
+
version: VERSION
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
test('rejects a lock package missing from the published direct dependencies', ()=>{
|
|
32
|
+
const input = validInput();
|
|
33
|
+
input.dependencies = {
|
|
34
|
+
'@deepseek-ai/dsh': VERSION
|
|
35
|
+
};
|
|
36
|
+
assert.throws(()=>validateDshRuntimeClosure(input), /DSH closure 未精确声明/);
|
|
37
|
+
});
|
|
38
|
+
test('rejects an extra ranged DSH dependency absent from the tested lock closure', ()=>{
|
|
39
|
+
const input = validInput();
|
|
40
|
+
input.dependencies['@deepseek-ai/dsh-web'] = '^0.1.2-alpha.3';
|
|
41
|
+
assert.throws(()=>validateDshRuntimeClosure(input), /DSH manifest 与 lock 集合不一致/);
|
|
42
|
+
});
|
|
43
|
+
test('rejects a nested DSH package from another prerelease', ()=>{
|
|
44
|
+
const input = validInput();
|
|
45
|
+
input.lockPackages['node_modules/@deepseek-ai/dsh/node_modules/@deepseek-ai/dsh-session-title'] = {
|
|
46
|
+
version: '0.1.2-alpha.4'
|
|
47
|
+
};
|
|
48
|
+
assert.throws(()=>validateDshRuntimeClosure(input), /DSH lock 版本漂移/);
|
|
49
|
+
});
|
|
50
|
+
test('rejects drift from the runtime spawn guard version', ()=>{
|
|
51
|
+
const input = validInput();
|
|
52
|
+
input.runtimeVersion = '0.1.2-alpha.4';
|
|
53
|
+
assert.throws(()=>validateDshRuntimeClosure(input), /DSH runtime guard 版本漂移/);
|
|
54
|
+
});
|
|
55
|
+
test('parses each pnpm DSH resolution once across packages and snapshots', ()=>{
|
|
56
|
+
const lock = `
|
|
57
|
+
packages:
|
|
58
|
+
'@deepseek-ai/dsh@0.1.2-alpha.3': {}
|
|
59
|
+
'@deepseek-ai/dsh-session@0.1.2-alpha.3': {}
|
|
60
|
+
snapshots:
|
|
61
|
+
'@deepseek-ai/dsh@0.1.2-alpha.3': {}
|
|
62
|
+
`;
|
|
63
|
+
assert.deepEqual(parsePnpmDshLock(lock), {
|
|
64
|
+
'node_modules/@deepseek-ai/dsh': {
|
|
65
|
+
version: VERSION
|
|
66
|
+
},
|
|
67
|
+
'node_modules/@deepseek-ai/dsh-session': {
|
|
68
|
+
version: VERSION
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
test('preserves two pnpm resolutions of the same DSH package for mixed-version rejection', ()=>{
|
|
73
|
+
const lock = `
|
|
74
|
+
packages:
|
|
75
|
+
'@deepseek-ai/dsh@0.1.2-alpha.3': {}
|
|
76
|
+
'@deepseek-ai/dsh-session@0.1.2-alpha.3': {}
|
|
77
|
+
'@deepseek-ai/dsh-session@0.1.2-alpha.4': {}
|
|
78
|
+
`;
|
|
79
|
+
const parsed = parsePnpmDshLock(lock);
|
|
80
|
+
assert.equal(Object.keys(parsed).length, 3);
|
|
81
|
+
assert.throws(()=>validateDshRuntimeClosure({
|
|
82
|
+
dependencies: {
|
|
83
|
+
'@deepseek-ai/dsh': VERSION,
|
|
84
|
+
'@deepseek-ai/dsh-session': VERSION
|
|
85
|
+
},
|
|
86
|
+
lockPackages: parsed,
|
|
87
|
+
runtimeVersion: VERSION
|
|
88
|
+
}), /DSH lock 版本漂移/);
|
|
89
|
+
});
|
|
90
|
+
test('parses only the root pnpm importer DSH entries', ()=>{
|
|
91
|
+
const lock = `
|
|
92
|
+
lockfileVersion: '9.0'
|
|
93
|
+
importers:
|
|
94
|
+
.:
|
|
95
|
+
dependencies:
|
|
96
|
+
'@deepseek-ai/dsh':
|
|
97
|
+
specifier: 0.1.2-alpha.3
|
|
98
|
+
version: 0.1.2-alpha.3(peer@1.0.0)
|
|
99
|
+
'@deepseek-ai/dsh-session':
|
|
100
|
+
specifier: 0.1.2-alpha.3
|
|
101
|
+
version: 0.1.2-alpha.3
|
|
102
|
+
ts:
|
|
103
|
+
dependencies:
|
|
104
|
+
'@deepseek-ai/dsh-web':
|
|
105
|
+
specifier: 0.1.2-alpha.4
|
|
106
|
+
version: 0.1.2-alpha.4
|
|
107
|
+
packages: {}
|
|
108
|
+
`;
|
|
109
|
+
assert.deepEqual(parsePnpmRootDshImporter(lock), {
|
|
110
|
+
'@deepseek-ai/dsh': {
|
|
111
|
+
specifier: VERSION,
|
|
112
|
+
resolvedVersion: VERSION
|
|
113
|
+
},
|
|
114
|
+
'@deepseek-ai/dsh-session': {
|
|
115
|
+
specifier: VERSION,
|
|
116
|
+
resolvedVersion: VERSION
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
test('rejects a pnpm root importer missing a published DSH dependency', ()=>{
|
|
121
|
+
assert.throws(()=>validatePnpmRootDshImporter({
|
|
122
|
+
dependencies: validInput().dependencies,
|
|
123
|
+
importerEntries: {
|
|
124
|
+
'@deepseek-ai/dsh': {
|
|
125
|
+
specifier: VERSION,
|
|
126
|
+
resolvedVersion: VERSION
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
runtimeVersion: VERSION
|
|
130
|
+
}), /pnpm root importer 与 manifest 集合不一致/);
|
|
131
|
+
});
|
|
132
|
+
test('rejects a ranged DSH specifier in the pnpm root importer', ()=>{
|
|
133
|
+
assert.throws(()=>validatePnpmRootDshImporter({
|
|
134
|
+
dependencies: validInput().dependencies,
|
|
135
|
+
importerEntries: {
|
|
136
|
+
'@deepseek-ai/dsh': {
|
|
137
|
+
specifier: VERSION,
|
|
138
|
+
resolvedVersion: VERSION
|
|
139
|
+
},
|
|
140
|
+
'@deepseek-ai/dsh-session-title': {
|
|
141
|
+
specifier: '^0.1.2-alpha.3',
|
|
142
|
+
resolvedVersion: VERSION
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
runtimeVersion: VERSION
|
|
146
|
+
}), /pnpm root importer 未精确锁定/);
|
|
147
|
+
});
|
|
148
|
+
test('rejects a drifted resolved DSH version in the pnpm root importer', ()=>{
|
|
149
|
+
assert.throws(()=>validatePnpmRootDshImporter({
|
|
150
|
+
dependencies: validInput().dependencies,
|
|
151
|
+
importerEntries: {
|
|
152
|
+
'@deepseek-ai/dsh': {
|
|
153
|
+
specifier: VERSION,
|
|
154
|
+
resolvedVersion: '0.1.2-alpha.4'
|
|
155
|
+
},
|
|
156
|
+
'@deepseek-ai/dsh-session-title': {
|
|
157
|
+
specifier: VERSION,
|
|
158
|
+
resolvedVersion: VERSION
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
runtimeVersion: VERSION
|
|
162
|
+
}), /pnpm root importer resolved 版本漂移/);
|
|
163
|
+
});
|
|
164
|
+
test('rejects a missing resolved DSH version in the pnpm root importer', ()=>{
|
|
165
|
+
const lock = `
|
|
166
|
+
importers:
|
|
167
|
+
.:
|
|
168
|
+
dependencies:
|
|
169
|
+
'@deepseek-ai/dsh':
|
|
170
|
+
specifier: 0.1.2-alpha.3
|
|
171
|
+
`;
|
|
172
|
+
assert.throws(()=>parsePnpmRootDshImporter(lock), /pnpm root importer version 不可用/);
|
|
173
|
+
});
|
|
174
|
+
test('rejects duplicate resolved DSH versions in the pnpm root importer', ()=>{
|
|
175
|
+
const lock = `
|
|
176
|
+
importers:
|
|
177
|
+
.:
|
|
178
|
+
dependencies:
|
|
179
|
+
'@deepseek-ai/dsh':
|
|
180
|
+
specifier: 0.1.2-alpha.3
|
|
181
|
+
version: 0.1.2-alpha.3
|
|
182
|
+
version: 0.1.2-alpha.4
|
|
183
|
+
`;
|
|
184
|
+
assert.throws(()=>parsePnpmRootDshImporter(lock), /pnpm root importer version 不可用/);
|
|
185
|
+
});
|
|
186
|
+
test('rejects a coherent closure below the required package count', ()=>{
|
|
187
|
+
assert.throws(()=>validateDshRuntimeClosure({
|
|
188
|
+
...validInput(),
|
|
189
|
+
expectedPackageCount: REQUIRED_DSH_RUNTIME_PACKAGE_COUNT
|
|
190
|
+
}), /DSH closure 包数量不符/);
|
|
191
|
+
});
|
|
192
|
+
test('rejects a coherent root importer below the required package count', ()=>{
|
|
193
|
+
assert.throws(()=>validatePnpmRootDshImporter({
|
|
194
|
+
dependencies: validInput().dependencies,
|
|
195
|
+
importerEntries: {
|
|
196
|
+
'@deepseek-ai/dsh': {
|
|
197
|
+
specifier: VERSION,
|
|
198
|
+
resolvedVersion: VERSION
|
|
199
|
+
},
|
|
200
|
+
'@deepseek-ai/dsh-session-title': {
|
|
201
|
+
specifier: VERSION,
|
|
202
|
+
resolvedVersion: VERSION
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
runtimeVersion: VERSION,
|
|
206
|
+
expectedPackageCount: REQUIRED_DSH_RUNTIME_PACKAGE_COUNT
|
|
207
|
+
}), /pnpm root importer 包数量不符/);
|
|
208
|
+
});
|
|
209
|
+
test('rejects duplicate DSH entries in the pnpm root importer', ()=>{
|
|
210
|
+
const lock = `
|
|
211
|
+
importers:
|
|
212
|
+
.:
|
|
213
|
+
dependencies:
|
|
214
|
+
'@deepseek-ai/dsh':
|
|
215
|
+
specifier: 0.1.2-alpha.3
|
|
216
|
+
version: 0.1.2-alpha.3
|
|
217
|
+
'@deepseek-ai/dsh':
|
|
218
|
+
specifier: 0.1.2-alpha.3
|
|
219
|
+
version: 0.1.2-alpha.3
|
|
220
|
+
`;
|
|
221
|
+
assert.throws(()=>parsePnpmRootDshImporter(lock), /pnpm root importer DSH 依赖重复/);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
//# sourceURL=ts/scripts/dsh-runtime-closure-tests.ts
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
export const REQUIRED_DSH_RUNTIME_PACKAGE_COUNT = 216;
|
|
2
|
+
function yamlScalar(value) {
|
|
3
|
+
const trimmed = value.trim().replace(/\s+#.*$/, '');
|
|
4
|
+
const quoted = trimmed.match(/^(['"])(.*)\1$/);
|
|
5
|
+
return quoted?.[2] ?? trimmed;
|
|
6
|
+
}
|
|
7
|
+
function indentation(line) {
|
|
8
|
+
return line.match(/^ */)?.[0].length ?? 0;
|
|
9
|
+
}
|
|
10
|
+
function resolvedPnpmVersion(value) {
|
|
11
|
+
return yamlScalar(value).replace(/\(.+$/, '');
|
|
12
|
+
}
|
|
13
|
+
export function parsePnpmRootDshImporter(text) {
|
|
14
|
+
const lines = text.split(/\r?\n/);
|
|
15
|
+
const importers = lines.map((line, index)=>line === 'importers:' ? index : -1).filter((index)=>index >= 0);
|
|
16
|
+
if (importers.length !== 1) throw new Error('pnpm lock importers 区块不可用');
|
|
17
|
+
const importersStart = importers[0];
|
|
18
|
+
const importersEnd = lines.findIndex((line, index)=>index > importersStart && line.trim() !== '' && indentation(line) === 0);
|
|
19
|
+
const rootCandidates = lines.map((line, index)=>index > importersStart && (importersEnd < 0 || index < importersEnd) && /^ {2}(?:\.|'\.'|"\."):\s*$/.test(line) ? index : -1).filter((index)=>index >= 0);
|
|
20
|
+
if (rootCandidates.length !== 1) throw new Error('pnpm root importer 不唯一');
|
|
21
|
+
const rootStart = rootCandidates[0];
|
|
22
|
+
const rootEndRelative = lines.slice(rootStart + 1, importersEnd < 0 ? lines.length : importersEnd).findIndex((line)=>line.trim() !== '' && indentation(line) <= 2);
|
|
23
|
+
const rootEnd = rootEndRelative < 0 ? importersEnd < 0 ? lines.length : importersEnd : rootStart + 1 + rootEndRelative;
|
|
24
|
+
const dependencyBlocks = lines.map((line, index)=>index > rootStart && index < rootEnd && /^ {4}dependencies:\s*$/.test(line) ? index : -1).filter((index)=>index >= 0);
|
|
25
|
+
if (dependencyBlocks.length !== 1) throw new Error('pnpm root importer dependencies 区块不可用');
|
|
26
|
+
const dependenciesStart = dependencyBlocks[0];
|
|
27
|
+
const dependenciesEndRelative = lines.slice(dependenciesStart + 1, rootEnd).findIndex((line)=>line.trim() !== '' && indentation(line) <= 4);
|
|
28
|
+
const dependenciesEnd = dependenciesEndRelative < 0 ? rootEnd : dependenciesStart + 1 + dependenciesEndRelative;
|
|
29
|
+
const entries = lines.map((line, index)=>{
|
|
30
|
+
if (index <= dependenciesStart || index >= dependenciesEnd) return null;
|
|
31
|
+
const match = line.match(/^ {6}(['"]?)([^'":\s]+)\1:\s*$/);
|
|
32
|
+
return match ? {
|
|
33
|
+
index,
|
|
34
|
+
name: match[2]
|
|
35
|
+
} : null;
|
|
36
|
+
}).filter((entry)=>entry !== null);
|
|
37
|
+
const importerEntries = {};
|
|
38
|
+
for(let entryIndex = 0; entryIndex < entries.length; entryIndex += 1){
|
|
39
|
+
const entry = entries[entryIndex];
|
|
40
|
+
if (entry.name !== '@deepseek-ai/dsh' && !entry.name.startsWith('@deepseek-ai/dsh-')) continue;
|
|
41
|
+
if (Object.hasOwn(importerEntries, entry.name)) throw new Error(`pnpm root importer DSH 依赖重复:${entry.name}`);
|
|
42
|
+
const end = entries[entryIndex + 1]?.index ?? dependenciesEnd;
|
|
43
|
+
const block = lines.slice(entry.index + 1, end);
|
|
44
|
+
const specifiers = block.map((line)=>line.match(/^ {8}specifier:\s*(.+)$/)?.[1]).filter((value)=>value !== undefined);
|
|
45
|
+
if (specifiers.length !== 1) throw new Error(`pnpm root importer specifier 不可用:${entry.name}`);
|
|
46
|
+
const versions = block.map((line)=>line.match(/^ {8}version:\s*(.+)$/)?.[1]).filter((value)=>value !== undefined);
|
|
47
|
+
if (versions.length !== 1) throw new Error(`pnpm root importer version 不可用:${entry.name}`);
|
|
48
|
+
importerEntries[entry.name] = {
|
|
49
|
+
specifier: yamlScalar(specifiers[0]),
|
|
50
|
+
resolvedVersion: resolvedPnpmVersion(versions[0])
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return importerEntries;
|
|
54
|
+
}
|
|
55
|
+
export function validatePnpmRootDshImporter(input) {
|
|
56
|
+
const manifestNames = Object.keys(input.dependencies).filter((name)=>name === '@deepseek-ai/dsh' || name.startsWith('@deepseek-ai/dsh-')).sort();
|
|
57
|
+
const importerNames = Object.keys(input.importerEntries).sort();
|
|
58
|
+
const missing = manifestNames.filter((name)=>!importerNames.includes(name));
|
|
59
|
+
const extra = importerNames.filter((name)=>!manifestNames.includes(name));
|
|
60
|
+
if (missing.length > 0 || extra.length > 0) {
|
|
61
|
+
throw new Error(`pnpm root importer 与 manifest 集合不一致:missing=${missing.join(',') || '-'};extra=${extra.join(',') || '-'}`);
|
|
62
|
+
}
|
|
63
|
+
for (const name of importerNames){
|
|
64
|
+
const importerEntry = input.importerEntries[name];
|
|
65
|
+
if (input.dependencies[name] !== input.runtimeVersion || importerEntry.specifier !== input.runtimeVersion) {
|
|
66
|
+
throw new Error(`pnpm root importer 未精确锁定:${name}@${input.runtimeVersion}`);
|
|
67
|
+
}
|
|
68
|
+
if (importerEntry.resolvedVersion !== input.runtimeVersion) {
|
|
69
|
+
throw new Error(`pnpm root importer resolved 版本漂移:${name}@${importerEntry.resolvedVersion}(expected ${input.runtimeVersion})`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (input.expectedPackageCount !== undefined && importerNames.length !== input.expectedPackageCount) {
|
|
73
|
+
throw new Error(`pnpm root importer 包数量不符:${importerNames.length}(expected ${input.expectedPackageCount})`);
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
names: importerNames,
|
|
77
|
+
version: input.runtimeVersion
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
export function parsePnpmDshLock(text) {
|
|
81
|
+
const packages = {};
|
|
82
|
+
const seen = new Set();
|
|
83
|
+
const variants = new Map();
|
|
84
|
+
const entry = /^\s{2}['"]?(\@deepseek-ai\/dsh(?:-[^@'":\s]+)?)@([^'":\s(]+)(?:\([^'"]*\))?['"]?:/gm;
|
|
85
|
+
for (const match of text.matchAll(entry)){
|
|
86
|
+
const name = match[1];
|
|
87
|
+
const version = match[2];
|
|
88
|
+
const identity = `${name}@${version}`;
|
|
89
|
+
if (seen.has(identity)) continue;
|
|
90
|
+
seen.add(identity);
|
|
91
|
+
const variant = variants.get(name) ?? 0;
|
|
92
|
+
variants.set(name, variant + 1);
|
|
93
|
+
const prefix = variant === 0 ? '' : `.pnpm-variant-${variant}/node_modules/`;
|
|
94
|
+
packages[`node_modules/${prefix}${name}`] = {
|
|
95
|
+
version
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return packages;
|
|
99
|
+
}
|
|
100
|
+
export function validateDshRuntimeClosure(input) {
|
|
101
|
+
const dshVersion = input.dependencies['@deepseek-ai/dsh'];
|
|
102
|
+
if (typeof dshVersion !== 'string' || !/^\d+\.\d+\.\d+-[0-9A-Za-z.-]+$/.test(dshVersion)) {
|
|
103
|
+
throw new Error('@deepseek-ai/dsh 必须以精确 prerelease 版本声明');
|
|
104
|
+
}
|
|
105
|
+
if (dshVersion !== input.runtimeVersion) {
|
|
106
|
+
throw new Error(`DSH runtime guard 版本漂移:${input.runtimeVersion}(manifest ${dshVersion})`);
|
|
107
|
+
}
|
|
108
|
+
const dshNodes = Object.entries(input.lockPackages).flatMap(([path, metadata])=>{
|
|
109
|
+
const match = path.match(/(?:^|\/)node_modules\/(\@deepseek-ai\/dsh(?:-[^/]+)?)$/);
|
|
110
|
+
return match ? [
|
|
111
|
+
{
|
|
112
|
+
name: match[1],
|
|
113
|
+
version: metadata.version
|
|
114
|
+
}
|
|
115
|
+
] : [];
|
|
116
|
+
}).sort((left, right)=>left.name.localeCompare(right.name));
|
|
117
|
+
if (dshNodes.length === 0) throw new Error('package-lock 未解析到 DSH runtime closure');
|
|
118
|
+
for (const dependency of dshNodes){
|
|
119
|
+
if (dependency.version !== dshVersion) {
|
|
120
|
+
throw new Error(`DSH lock 版本漂移:${dependency.name}@${dependency.version ?? 'missing'}(expected ${dshVersion})`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const lockNames = [
|
|
124
|
+
...new Set(dshNodes.map((dependency)=>dependency.name))
|
|
125
|
+
].sort();
|
|
126
|
+
const manifestNames = Object.keys(input.dependencies).filter((name)=>name === '@deepseek-ai/dsh' || name.startsWith('@deepseek-ai/dsh-')).sort();
|
|
127
|
+
const missing = lockNames.filter((name)=>!manifestNames.includes(name));
|
|
128
|
+
const extra = manifestNames.filter((name)=>!lockNames.includes(name));
|
|
129
|
+
if (missing.length > 0) {
|
|
130
|
+
throw new Error(`DSH closure 未精确声明:${missing[0]}@${dshVersion}`);
|
|
131
|
+
}
|
|
132
|
+
if (extra.length > 0) {
|
|
133
|
+
throw new Error(`DSH manifest 与 lock 集合不一致:missing=${missing.join(',') || '-'};extra=${extra.join(',') || '-'}`);
|
|
134
|
+
}
|
|
135
|
+
for (const name of manifestNames){
|
|
136
|
+
if (input.dependencies[name] !== dshVersion) {
|
|
137
|
+
throw new Error(`DSH closure 未精确声明:${name}@${dshVersion}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (input.expectedPackageCount !== undefined && lockNames.length !== input.expectedPackageCount) {
|
|
141
|
+
throw new Error(`DSH closure 包数量不符:${lockNames.length}(expected ${input.expectedPackageCount})`);
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
names: lockNames,
|
|
145
|
+
version: dshVersion
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
//# sourceURL=ts/scripts/dsh-runtime-closure.ts
|