@sublang/slc 0.15.0 → 0.16.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.
- package/README.md +65 -5
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +35 -1
- package/dist/app.js.map +1 -1
- package/dist/artifacts.d.ts +2 -0
- package/dist/artifacts.d.ts.map +1 -1
- package/dist/artifacts.js.map +1 -1
- package/dist/config-file.d.ts +2 -0
- package/dist/config-file.d.ts.map +1 -1
- package/dist/config-file.js +2 -0
- package/dist/config-file.js.map +1 -1
- package/dist/emitted-imports.d.ts +6 -0
- package/dist/emitted-imports.d.ts.map +1 -1
- package/dist/emitted-imports.js +21 -0
- package/dist/emitted-imports.js.map +1 -1
- package/dist/entry-module.d.ts +5 -0
- package/dist/entry-module.d.ts.map +1 -1
- package/dist/entry-module.js +9 -8
- package/dist/entry-module.js.map +1 -1
- package/dist/invocation.d.ts +6 -0
- package/dist/invocation.d.ts.map +1 -1
- package/dist/invocation.js +20 -0
- package/dist/invocation.js.map +1 -1
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +227 -6
- package/dist/runner.js.map +1 -1
- package/dist/slc.config.template.yaml +1 -1
- package/dist/verify-coverage.d.ts +1 -0
- package/dist/verify-coverage.d.ts.map +1 -1
- package/dist/verify-coverage.js +91 -13
- package/dist/verify-coverage.js.map +1 -1
- package/dist/verify-support.d.ts +2 -1
- package/dist/verify-support.d.ts.map +1 -1
- package/dist/verify-support.js +4 -3
- package/dist/verify-support.js.map +1 -1
- package/dist/verify.d.ts +4 -1
- package/dist/verify.d.ts.map +1 -1
- package/dist/verify.js +9 -6
- package/dist/verify.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify-coverage.d.ts","sourceRoot":"","sources":["../src/verify-coverage.ts"],"names":[],"mappings":"AA8BA,OAAO,EAeL,KAAK,iBAAiB,EACvB,MAAM,aAAa,CAAC;AAErB,sEAAsE;AACtE,eAAO,MAAM,aAAa,YAAY,CAAC;AAavC,iFAAiF;AACjF,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,cAGC;CACF;AAyDD,6DAA6D;AAC7D,UAAU,WAAW;IACnB,MAAM,EAAE,iBAAiB,GAAG;QAAE,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,OAAO,CAAC,eAAe,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,WAAW,CAAC;IAC3E,mEAAmE;IACnE,eAAe,CAAC,EAAE;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACjC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACnC,CAAC;IACF,4EAA4E;IAC5E,IAAI,CAAC,EAAE,qBAAqB,CAAC;CAC9B;AAyBD,UAAU,qBAAqB;IAC7B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAC/C,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjC;AAqJD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,OAAO,GAAG,WAAW,CAwB3D;
|
|
1
|
+
{"version":3,"file":"verify-coverage.d.ts","sourceRoot":"","sources":["../src/verify-coverage.ts"],"names":[],"mappings":"AA8BA,OAAO,EAeL,KAAK,iBAAiB,EACvB,MAAM,aAAa,CAAC;AAErB,sEAAsE;AACtE,eAAO,MAAM,aAAa,YAAY,CAAC;AAavC,iFAAiF;AACjF,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,cAGC;CACF;AAyDD,6DAA6D;AAC7D,UAAU,WAAW;IACnB,MAAM,EAAE,iBAAiB,GAAG;QAAE,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,OAAO,CAAC,eAAe,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,WAAW,CAAC;IAC3E,mEAAmE;IACnE,eAAe,CAAC,EAAE;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACjC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACnC,CAAC;IACF,4EAA4E;IAC5E,IAAI,CAAC,EAAE,qBAAqB,CAAC;CAC9B;AAyBD,UAAU,qBAAqB;IAC7B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAC/C,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjC;AAqJD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,OAAO,GAAG,WAAW,CAwB3D;AAirCD,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAU/D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,CAAC,GAAG,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,KAAK,OAAO,EAC7D,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,WAAW,GAAE,SAAS,OAAO,EAAO,GACnC,OAAO,CAST;AAg6DD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,CAqLjE;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,OAAO,EAClB,IAAI,GAAE;IACJ,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;CACf,GACL,OAAO,CAAC,MAAM,EAAE,CAAC,CAkCnB;AAo0BD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,MAAM,CA8BT;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1D,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAoBnD"}
|
package/dist/verify-coverage.js
CHANGED
|
@@ -285,18 +285,20 @@ function initializedCoverageContext(machine, dynamic) {
|
|
|
285
285
|
};
|
|
286
286
|
}
|
|
287
287
|
/** The `Output shall include` clause a result description declares. */
|
|
288
|
-
const OUTPUT_CLAUSE = /Output shall include\s
|
|
289
|
-
/** Every backticked
|
|
290
|
-
const REQUIRED_FIELD = /`([A-Za-z_$][A-Za-z0-9_$]*)
|
|
288
|
+
const OUTPUT_CLAUSE = /(?:Output shall include|输出应包含)\s*(.*)$/s;
|
|
289
|
+
/** Every plain or annotated backticked identifier field inside that clause. */
|
|
290
|
+
const REQUIRED_FIELD = /`([A-Za-z_$][A-Za-z0-9_$]*)(?::[^`]*)?`/g;
|
|
291
291
|
/** Structured fields named by the generic Captain result contracts. */
|
|
292
292
|
const STRUCTURED_RESULT_FIELD = /\b(response|question|remainingPlan|nextPlaybookId|nextPlaybookInput)\b/g;
|
|
293
293
|
function requiredFields(description) {
|
|
294
|
-
const clause = OUTPUT_CLAUSE.exec(description)?.[1]
|
|
294
|
+
const clause = OUTPUT_CLAUSE.exec(description)?.[1];
|
|
295
|
+
// An explicit clause owns the payload schema. Generic Captain words in the
|
|
296
|
+
// preceding outcome prose must not invent extra fields in a closed record.
|
|
297
|
+
// Preserve older Captain descriptions that predate explicit output clauses.
|
|
295
298
|
return [
|
|
296
299
|
...new Set([
|
|
297
|
-
...
|
|
298
|
-
|
|
299
|
-
]),
|
|
300
|
+
...(clause ?? description).matchAll(clause === undefined ? STRUCTURED_RESULT_FIELD : REQUIRED_FIELD),
|
|
301
|
+
].map((match) => match[1])),
|
|
300
302
|
];
|
|
301
303
|
}
|
|
302
304
|
function synthesizedFieldValue(field) {
|
|
@@ -623,6 +625,7 @@ function persistedSnapshotWithContext(provided, context) {
|
|
|
623
625
|
function makeActor(machine, script, playbookScript = () => null, restoredContext, observeTransition) {
|
|
624
626
|
coverageCheckpoint();
|
|
625
627
|
const coverageErrors = [];
|
|
628
|
+
const coverageTransitions = [];
|
|
626
629
|
const workActor = fromPromise(async ({ input, self, }) => {
|
|
627
630
|
const output = await script(input ?? {}, self.id);
|
|
628
631
|
if (output === null)
|
|
@@ -671,7 +674,18 @@ function makeActor(machine, script, playbookScript = () => null, restoredContext
|
|
|
671
674
|
}
|
|
672
675
|
const source = transition.source;
|
|
673
676
|
const target = transition.target;
|
|
674
|
-
|
|
677
|
+
const event = inspection.event;
|
|
678
|
+
const arms = source?.transitions?.get(typeof event === 'object' && event !== null
|
|
679
|
+
? String(event.type)
|
|
680
|
+
: '');
|
|
681
|
+
const observed = {
|
|
682
|
+
root: source === provided.root,
|
|
683
|
+
...(typeof event === 'object' && event !== null
|
|
684
|
+
? { event: event }
|
|
685
|
+
: {}),
|
|
686
|
+
...(arms === undefined
|
|
687
|
+
? {}
|
|
688
|
+
: { armIndex: arms.indexOf(transition) }),
|
|
675
689
|
...(typeof source === 'object' &&
|
|
676
690
|
source !== null &&
|
|
677
691
|
typeof source.id === 'string'
|
|
@@ -684,7 +698,9 @@ function makeActor(machine, script, playbookScript = () => null, restoredContext
|
|
|
684
698
|
? [candidate.id]
|
|
685
699
|
: [])
|
|
686
700
|
: [],
|
|
687
|
-
}
|
|
701
|
+
};
|
|
702
|
+
coverageTransitions.push(observed);
|
|
703
|
+
observeTransition?.(observed);
|
|
688
704
|
}
|
|
689
705
|
}
|
|
690
706
|
const event = inspection.event;
|
|
@@ -703,6 +719,9 @@ function makeActor(machine, script, playbookScript = () => null, restoredContext
|
|
|
703
719
|
Object.defineProperty(actor, 'coverageErrors', {
|
|
704
720
|
value: coverageErrors,
|
|
705
721
|
});
|
|
722
|
+
Object.defineProperty(actor, 'coverageTransitions', {
|
|
723
|
+
value: coverageTransitions,
|
|
724
|
+
});
|
|
706
725
|
actor.subscribe({ error: () => { } });
|
|
707
726
|
actor.start();
|
|
708
727
|
coverageCheckpoint();
|
|
@@ -2330,11 +2349,27 @@ export function fsmCoverageTestTimeout(fsmModule) {
|
|
|
2330
2349
|
: playbooks.reduce((total, playbook) => total +
|
|
2331
2350
|
transitionArms(playbook.invocation.onDone).length +
|
|
2332
2351
|
transitionArms(playbook.invocation.onError).length, 0);
|
|
2352
|
+
if (!controller) {
|
|
2353
|
+
for (const [index, arm] of transitionArms((config.on ?? {})[INTERRUPT_EVENT]).entries()) {
|
|
2354
|
+
const targetName = rawArmTarget(arm);
|
|
2355
|
+
const target = targetName === undefined
|
|
2356
|
+
? undefined
|
|
2357
|
+
: stateRefForTarget(refs, targetName);
|
|
2358
|
+
const captain = captains.find((candidate) => target !== undefined && sameStateRef(candidate.ref, target));
|
|
2359
|
+
if (captain !== undefined &&
|
|
2360
|
+
captain.binding.actor !== 'script' &&
|
|
2361
|
+
!interruptDriveForRef(machine, refs, captain.ref, captainPublicStateId(captain), [], index).satisfiable)
|
|
2362
|
+
pathSearches += 1;
|
|
2363
|
+
}
|
|
2364
|
+
}
|
|
2333
2365
|
for (const captain of captains) {
|
|
2334
2366
|
const resultKeys = Object.keys(captain.binding.result);
|
|
2335
2367
|
const guardedDoneArms = transitionArms(captain.invocation.onDone).filter((arm) => armGuard(arm) !== undefined).length;
|
|
2336
2368
|
const errorArms = transitionArms(captain.invocation.onError).length;
|
|
2337
|
-
if (!controller &&
|
|
2369
|
+
if (!controller &&
|
|
2370
|
+
(rootInterruptProbes === 0 ||
|
|
2371
|
+
(captain.binding.actor !== 'script' &&
|
|
2372
|
+
!interruptDriveForRef(machine, refs, captain.ref, captainInterruptTarget(captain)).satisfiable))) {
|
|
2338
2373
|
pathSearches +=
|
|
2339
2374
|
resultKeys.length +
|
|
2340
2375
|
(resultKeys.includes(NEEDS_BOSS_REPLY) ? 1 : 0) +
|
|
@@ -2559,6 +2594,45 @@ async function runFsmCoverage(fsmModule, sourceText) {
|
|
|
2559
2594
|
}
|
|
2560
2595
|
const drive = interruptDriveForRef(machine, refs, target, targetId, sourceCandidates, armIndex);
|
|
2561
2596
|
if (!drive.satisfiable) {
|
|
2597
|
+
if (!isController &&
|
|
2598
|
+
targetCaptain !== undefined &&
|
|
2599
|
+
targetCaptain.binding.actor !== 'script') {
|
|
2600
|
+
const guard = orderedArmPredicate(machine, transitionArms((machine.config.on ?? {})[INTERRUPT_EVENT]), armIndex);
|
|
2601
|
+
const reached = await searchCoverageEntry(machine, { kind: 'acting', value: targetCaptain }, refs, captains, playbooks, sourceCandidates, async (actor) => {
|
|
2602
|
+
try {
|
|
2603
|
+
if (guard === undefined ||
|
|
2604
|
+
!guard.run({
|
|
2605
|
+
context: actor.getSnapshot().context,
|
|
2606
|
+
event: drive.event,
|
|
2607
|
+
}))
|
|
2608
|
+
return false;
|
|
2609
|
+
}
|
|
2610
|
+
catch {
|
|
2611
|
+
coverageCheckpoint();
|
|
2612
|
+
return false;
|
|
2613
|
+
}
|
|
2614
|
+
const before = actor.coverageTransitions.length;
|
|
2615
|
+
actor.send(drive.event);
|
|
2616
|
+
const completed = await settle(actor, atState(target));
|
|
2617
|
+
return (completed &&
|
|
2618
|
+
actor.coverageTransitions
|
|
2619
|
+
.slice(before)
|
|
2620
|
+
.some((transition) => transition.root &&
|
|
2621
|
+
transition.armIndex === armIndex &&
|
|
2622
|
+
transition.event === drive.event &&
|
|
2623
|
+
transition.targetIds.includes(resolvedStateNode(machine, target)?.id ?? '')));
|
|
2624
|
+
});
|
|
2625
|
+
if (reached.covered)
|
|
2626
|
+
continue;
|
|
2627
|
+
if (reached.inputFailure !== undefined) {
|
|
2628
|
+
findings.push(`${INTERRUPT_EVENT} target ${arm.target}: ${reached.inputFailure}`);
|
|
2629
|
+
continue;
|
|
2630
|
+
}
|
|
2631
|
+
if (reached.limitation !== undefined) {
|
|
2632
|
+
findings.push(`${INTERRUPT_EVENT} target ${arm.target}: ${reached.limitation}`);
|
|
2633
|
+
continue;
|
|
2634
|
+
}
|
|
2635
|
+
}
|
|
2562
2636
|
findings.push(`${INTERRUPT_EVENT} target ${arm.target} is unsatisfiable under context/event probing`);
|
|
2563
2637
|
continue;
|
|
2564
2638
|
}
|
|
@@ -2608,7 +2682,10 @@ async function runFsmCoverage(fsmModule, sourceText) {
|
|
|
2608
2682
|
return findings;
|
|
2609
2683
|
for (const captain of captains) {
|
|
2610
2684
|
await coverageYield();
|
|
2611
|
-
if (!
|
|
2685
|
+
if (!isController &&
|
|
2686
|
+
(!canJump ||
|
|
2687
|
+
(captain.binding.actor !== 'script' &&
|
|
2688
|
+
!interruptDriveForRef(machine, refs, captain.ref, captainInterruptTarget(captain), sourceCandidates).satisfiable))) {
|
|
2612
2689
|
findings.push(...(await probeNonPreemptiveActor(machine, captain, refs, captains, playbooks, [...stateCandidates, ...sourceCandidates])));
|
|
2613
2690
|
continue;
|
|
2614
2691
|
}
|
|
@@ -3021,9 +3098,10 @@ export async function emitFsmCoverageTest(opts) {
|
|
|
3021
3098
|
fsmSourceFile: `./${opts.basename}.fsm.ts`,
|
|
3022
3099
|
verifyModule: opts.verifyModule ?? VERIFY_MODULE,
|
|
3023
3100
|
});
|
|
3024
|
-
|
|
3101
|
+
if (opts.write === undefined)
|
|
3102
|
+
await mkdir(opts.artifactDir, { recursive: true });
|
|
3025
3103
|
const path = join(opts.artifactDir, `${opts.basename}.fsm.coverage.test.ts`);
|
|
3026
|
-
await writeFile(path, content);
|
|
3104
|
+
await (opts.write ?? writeFile)(path, content);
|
|
3027
3105
|
return {
|
|
3028
3106
|
path,
|
|
3029
3107
|
diagnostics: findings.map((finding) => `fsm coverage: ${finding}`),
|