@molecule/api-ai-tools 1.16.7 → 1.17.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 +341 -5
- package/dist/backends/local.d.ts.map +1 -1
- package/dist/backends/local.js +60 -14
- package/dist/command-plan.d.ts +71 -0
- package/dist/command-plan.d.ts.map +1 -0
- package/dist/command-plan.js +116 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -0
- package/dist/playwright-feedback-reporter.d.ts +16 -0
- package/dist/playwright-feedback-reporter.d.ts.map +1 -0
- package/dist/playwright-feedback-reporter.js +79 -0
- package/dist/playwright-feedback-selection.d.ts +13 -0
- package/dist/playwright-feedback-selection.d.ts.map +1 -0
- package/dist/playwright-feedback-selection.js +206 -0
- package/dist/playwright-feedback-types.d.ts +65 -0
- package/dist/playwright-feedback-types.d.ts.map +1 -0
- package/dist/playwright-feedback-types.js +1 -0
- package/dist/playwright-feedback.d.ts +42 -0
- package/dist/playwright-feedback.d.ts.map +1 -0
- package/dist/playwright-feedback.js +318 -0
- package/dist/suite-overlap.d.ts.map +1 -1
- package/dist/suite-overlap.js +2 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +49 -21
- package/dist/trace-artifacts.d.ts.map +1 -1
- package/dist/trace-artifacts.js +2 -1
- package/dist/utilities.d.ts +4 -1
- package/dist/utilities.d.ts.map +1 -1
- package/dist/utilities.js +14 -1
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@ AUTO-GENERATED — DO NOT EDIT THIS FILE.
|
|
|
3
3
|
Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
|
|
4
4
|
Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
|
|
5
5
|
To change this document, edit the module-level JSDoc in src/index.ts.
|
|
6
|
-
Generated: 2026-11-
|
|
6
|
+
Generated: 2026-11-06T13:53:38.704Z
|
|
7
7
|
-->
|
|
8
8
|
|
|
9
9
|
# @molecule/api-ai-tools
|
|
@@ -51,7 +51,7 @@ for await (const event of requireProvider().chat({ system, tools, messages, stre
|
|
|
51
51
|
## Installation
|
|
52
52
|
|
|
53
53
|
```bash
|
|
54
|
-
npm install @molecule/api-ai-tools @molecule/api-ai
|
|
54
|
+
npm install @molecule/api-ai-tools @molecule/api-ai typescript
|
|
55
55
|
```
|
|
56
56
|
|
|
57
57
|
## API
|
|
@@ -80,6 +80,36 @@ interface ForegroundBrowserProbe extends BrowserProbeLeak {
|
|
|
80
80
|
}
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
+
#### `CommandPlanStep`
|
|
84
|
+
|
|
85
|
+
One sequential command, with boundaries emitted by its launcher around execution.
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
interface CommandPlanStep {
|
|
89
|
+
/** Launcher's stable step identity. */
|
|
90
|
+
id: string
|
|
91
|
+
/** The logical command actually executed, including launch rewrites. */
|
|
92
|
+
command: string
|
|
93
|
+
/** Printed on its own line immediately before this step runs. */
|
|
94
|
+
startMarker: string
|
|
95
|
+
/** Printed on its own line after this step settles. */
|
|
96
|
+
endMarker: string
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
#### `CommandPlan`
|
|
101
|
+
|
|
102
|
+
A wrapper's ordered commands; metadata describes execution, never proof or completion.
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
interface CommandPlan {
|
|
106
|
+
/** Per-launch boundary identity, preventing ordinary suite output from matching a boundary. */
|
|
107
|
+
id: string
|
|
108
|
+
/** Steps execute in this order. */
|
|
109
|
+
steps: CommandPlanStep[]
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
83
113
|
#### `CommandSegment`
|
|
84
114
|
|
|
85
115
|
One statement or pipeline stage of a shell command: what it runs, and with what.
|
|
@@ -374,6 +404,111 @@ interface RunnerOutputFilter {
|
|
|
374
404
|
}
|
|
375
405
|
```
|
|
376
406
|
|
|
407
|
+
#### `FeedbackSource`
|
|
408
|
+
|
|
409
|
+
A source file already read by the caller. Paths are absolute.
|
|
410
|
+
|
|
411
|
+
```typescript
|
|
412
|
+
interface FeedbackSource {
|
|
413
|
+
path: string
|
|
414
|
+
content: string
|
|
415
|
+
}
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
#### `FeedbackSpec`
|
|
419
|
+
|
|
420
|
+
One supplied or scaffolded spec, with its normal, locally targeted runner command.
|
|
421
|
+
|
|
422
|
+
```typescript
|
|
423
|
+
interface FeedbackSpec extends FeedbackSource {
|
|
424
|
+
command: string
|
|
425
|
+
cwd: string
|
|
426
|
+
}
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
#### `FeedbackProject`
|
|
430
|
+
|
|
431
|
+
The inputs the host already knows; no suite discovery or vendor selection in the scheduler.
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
interface FeedbackProject {
|
|
435
|
+
/** Base for relative source-change paths, already resolved by the host. */
|
|
436
|
+
root?: string
|
|
437
|
+
sources: FeedbackSource[]
|
|
438
|
+
specs: FeedbackSpec[]
|
|
439
|
+
}
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
#### `PlaywrightFeedbackFailure`
|
|
443
|
+
|
|
444
|
+
A native failure, never a static prediction or a completed-suite proof.
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
interface PlaywrightFeedbackFailure {
|
|
448
|
+
spec: string
|
|
449
|
+
line: number
|
|
450
|
+
error: string
|
|
451
|
+
/** The native runner's locator or assertion, verbatim apart from redaction. */
|
|
452
|
+
locator: string
|
|
453
|
+
/** Playwright's own failure-time accessibility snapshot, when recorded. */
|
|
454
|
+
rendered?: string
|
|
455
|
+
/** Route render dependencies affected by this write, or the triggering source paths. */
|
|
456
|
+
sourceFiles: string[]
|
|
457
|
+
}
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
#### `PlaywrightFeedbackResult`
|
|
461
|
+
|
|
462
|
+
A diagnosis of one spec file at one source revision. A pass is not whole-suite proof.
|
|
463
|
+
|
|
464
|
+
```typescript
|
|
465
|
+
interface PlaywrightFeedbackResult {
|
|
466
|
+
spec: string
|
|
467
|
+
revision: number
|
|
468
|
+
durationMs: number
|
|
469
|
+
status: 'passed' | 'failed' | 'unavailable'
|
|
470
|
+
failures: PlaywrightFeedbackFailure[]
|
|
471
|
+
/** Native counts for this one diagnostic selection, never whole-suite proof. */
|
|
472
|
+
nativeStats?: PlaywrightReportStats
|
|
473
|
+
reason?: string
|
|
474
|
+
}
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
#### `PlaywrightFeedbackOptions`
|
|
478
|
+
|
|
479
|
+
Host operations for the same scheduler in a CLI process or a remote sandbox.
|
|
480
|
+
|
|
481
|
+
```typescript
|
|
482
|
+
interface PlaywrightFeedbackOptions {
|
|
483
|
+
load: () => Promise<FeedbackProject>
|
|
484
|
+
run: (
|
|
485
|
+
spec: FeedbackSpec,
|
|
486
|
+
sources: string[],
|
|
487
|
+
revision: number,
|
|
488
|
+
emit: (result: PlaywrightFeedbackResult) => void,
|
|
489
|
+
) => Promise<PlaywrightFeedbackResult>
|
|
490
|
+
/** Only current native failures are delivered. Passing apps receive no note. */
|
|
491
|
+
onFailures?: (result: PlaywrightFeedbackResult) => void
|
|
492
|
+
/** Operational state is separate from defect feedback. */
|
|
493
|
+
onResult?: (result: PlaywrightFeedbackResult) => void
|
|
494
|
+
debounceMs?: number
|
|
495
|
+
}
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
#### `PlaywrightFeedback`
|
|
499
|
+
|
|
500
|
+
A nonblocking source-change subscription.
|
|
501
|
+
|
|
502
|
+
```typescript
|
|
503
|
+
interface PlaywrightFeedback {
|
|
504
|
+
changed: (paths: readonly string[]) => void
|
|
505
|
+
takeFailures: () => PlaywrightFeedbackResult[]
|
|
506
|
+
/** Wait only in tests or shutdown; file writes and deploys must never await this. */
|
|
507
|
+
settled: () => Promise<void>
|
|
508
|
+
close: () => Promise<void>
|
|
509
|
+
}
|
|
510
|
+
```
|
|
511
|
+
|
|
377
512
|
#### `PlaywrightReportAttachment`
|
|
378
513
|
|
|
379
514
|
One artifact the runner saved for one test, as the report records it.
|
|
@@ -1798,6 +1933,94 @@ function browserProbeOverBudgetAdvice(probe: ForegroundBrowserProbe): string
|
|
|
1798
1933
|
|
|
1799
1934
|
**Returns:** The sentence the cut result carries.
|
|
1800
1935
|
|
|
1936
|
+
#### `createCommandPlan(steps)`
|
|
1937
|
+
|
|
1938
|
+
Give already-prepared logical commands unique log boundaries.
|
|
1939
|
+
|
|
1940
|
+
```typescript
|
|
1941
|
+
function createCommandPlan(steps: { id: string; command: string }[]): CommandPlan
|
|
1942
|
+
```
|
|
1943
|
+
|
|
1944
|
+
- `steps` — Commands in execution order.
|
|
1945
|
+
|
|
1946
|
+
**Returns:** Metadata for the wrapper and the launcher that executes its steps.
|
|
1947
|
+
|
|
1948
|
+
#### `commandWithPlan(command, plan)`
|
|
1949
|
+
|
|
1950
|
+
Preserve a wrapper's typed logical plan in its durable shell script, including across restarts.
|
|
1951
|
+
Shell comments keep this independent of the wrapper's executable, arguments and payload format.
|
|
1952
|
+
|
|
1953
|
+
```typescript
|
|
1954
|
+
function commandWithPlan(command: string, plan: CommandPlan): string
|
|
1955
|
+
```
|
|
1956
|
+
|
|
1957
|
+
- `command` — Executed wrapper.
|
|
1958
|
+
- `plan` — Commands the launcher will actually execute and delimit.
|
|
1959
|
+
|
|
1960
|
+
**Returns:** A shell command with a passive metadata header.
|
|
1961
|
+
|
|
1962
|
+
#### `commandPlan(command)`
|
|
1963
|
+
|
|
1964
|
+
Read the shared descriptor, never a launcher's private wrapper format.
|
|
1965
|
+
|
|
1966
|
+
```typescript
|
|
1967
|
+
function commandPlan(command: string): CommandPlan | null
|
|
1968
|
+
```
|
|
1969
|
+
|
|
1970
|
+
- `command` — Command or recovered task script.
|
|
1971
|
+
|
|
1972
|
+
**Returns:** A valid logical plan, or null for an ordinary command.
|
|
1973
|
+
|
|
1974
|
+
#### `logicalCommandText(command)`
|
|
1975
|
+
|
|
1976
|
+
Commands a wrapper will run, for static classification; live diagnostics use commandStepView.
|
|
1977
|
+
|
|
1978
|
+
```typescript
|
|
1979
|
+
function logicalCommandText(command: string): string
|
|
1980
|
+
```
|
|
1981
|
+
|
|
1982
|
+
- `command` — Executed command.
|
|
1983
|
+
|
|
1984
|
+
**Returns:** Logical commands in order, or the direct command unchanged.
|
|
1985
|
+
|
|
1986
|
+
#### `commandStepView(command, output)`
|
|
1987
|
+
|
|
1988
|
+
Select only the step that owns the latest log boundary. Completed steps cannot supply a live
|
|
1989
|
+
failure, target, retry policy, file selection or rerun. Before the first boundary and between
|
|
1990
|
+
steps the live command is unknown; no diagnostic is permitted.
|
|
1991
|
+
|
|
1992
|
+
```typescript
|
|
1993
|
+
function commandStepView(
|
|
1994
|
+
command: string,
|
|
1995
|
+
output: string,
|
|
1996
|
+
): {
|
|
1997
|
+
command: string
|
|
1998
|
+
output: string
|
|
1999
|
+
complete: boolean
|
|
2000
|
+
/** Unique execution step, including when adjacent steps run identical commands. */
|
|
2001
|
+
stepKey?: string
|
|
2002
|
+
}
|
|
2003
|
+
```
|
|
2004
|
+
|
|
2005
|
+
- `command` — Wrapper or direct command.
|
|
2006
|
+
- `output` — Whole log, or the boundary-preserving bounded read.
|
|
2007
|
+
|
|
2008
|
+
**Returns:** Active command and its output, plus whether the entire step's output is available.
|
|
2009
|
+
|
|
2010
|
+
#### `commandPlanLogRead(plan, limit)`
|
|
2011
|
+
|
|
2012
|
+
AWK program for a bounded read that retains the active boundary even after a long step and
|
|
2013
|
+
discards prior steps. A truncated step cannot establish a universal failure across its history.
|
|
2014
|
+
|
|
2015
|
+
```typescript
|
|
2016
|
+
function commandPlanLogRead(plan: CommandPlan, limit: number): string
|
|
2017
|
+
```
|
|
2018
|
+
|
|
2019
|
+
- `plan` — Logical plan whose boundaries the launcher emits.
|
|
2020
|
+
- `limit` — Maximum output characters retained for diagnosis.
|
|
2021
|
+
|
|
2022
|
+
**Returns:** An AWK program; callers shell-quote it like every other argument.
|
|
2023
|
+
|
|
1801
2024
|
#### `durationSeconds(word)`
|
|
1802
2025
|
|
|
1803
2026
|
The seconds a duration word stands for.
|
|
@@ -2432,6 +2655,96 @@ function pipelineExitCodeNote(command: string, exitCode: number, output: string)
|
|
|
2432
2655
|
|
|
2433
2656
|
**Returns:** One sentence naming the stage the code came from, or null.
|
|
2434
2657
|
|
|
2658
|
+
#### `selectFeedbackSpecs(project, changed)`
|
|
2659
|
+
|
|
2660
|
+
Prioritize spec files potentially affected by writes. Every file still runs: a click or
|
|
2661
|
+
a helper can navigate somewhere a literal-goto index cannot see. This index never excludes work.
|
|
2662
|
+
|
|
2663
|
+
```typescript
|
|
2664
|
+
function selectFeedbackSpecs(
|
|
2665
|
+
project: FeedbackProject,
|
|
2666
|
+
changed: readonly string[],
|
|
2667
|
+
): Array<{ spec: FeedbackSpec; sourceFiles: string[] }>
|
|
2668
|
+
```
|
|
2669
|
+
|
|
2670
|
+
- `project` — Caller-supplied source and runner inventory.
|
|
2671
|
+
- `changed` — Absolute source paths changed since the previous diagnosis.
|
|
2672
|
+
|
|
2673
|
+
**Returns:** Spec files to run, with their rendering-source context.
|
|
2674
|
+
|
|
2675
|
+
#### `isPlaywrightFeedbackSource(path)`
|
|
2676
|
+
|
|
2677
|
+
Whether a source change can alter markup, copy, styling or local runner configuration.
|
|
2678
|
+
|
|
2679
|
+
```typescript
|
|
2680
|
+
function isPlaywrightFeedbackSource(path: string): boolean
|
|
2681
|
+
```
|
|
2682
|
+
|
|
2683
|
+
- `path` — The path reported by the host's file-change subscription.
|
|
2684
|
+
|
|
2685
|
+
**Returns:** True for app source and data formats; never a correctness judgment.
|
|
2686
|
+
|
|
2687
|
+
#### `createPlaywrightFeedback(options)`
|
|
2688
|
+
|
|
2689
|
+
Subscribe to writes without making them wait for browser work.
|
|
2690
|
+
|
|
2691
|
+
```typescript
|
|
2692
|
+
function createPlaywrightFeedback(options: PlaywrightFeedbackOptions): PlaywrightFeedback
|
|
2693
|
+
```
|
|
2694
|
+
|
|
2695
|
+
- `options` — Source loader, native runner and delivery callbacks.
|
|
2696
|
+
|
|
2697
|
+
**Returns:** A source-change subscription; settle/close are for tests and shutdown only.
|
|
2698
|
+
|
|
2699
|
+
#### `readFeedbackSources(backend, sourceRoots, suiteFiles)`
|
|
2700
|
+
|
|
2701
|
+
Read explicit source roots and supplied helper/spec paths in one backend round trip.
|
|
2702
|
+
The standard filesystem and TypeScript parser own traversal/syntax; this is transport batching.
|
|
2703
|
+
|
|
2704
|
+
```typescript
|
|
2705
|
+
function readFeedbackSources(
|
|
2706
|
+
backend: ExecutionBackend,
|
|
2707
|
+
sourceRoots: readonly string[],
|
|
2708
|
+
suiteFiles: readonly string[],
|
|
2709
|
+
): Promise<FeedbackSource[]>
|
|
2710
|
+
```
|
|
2711
|
+
|
|
2712
|
+
- `backend` — Local or sandbox execution backend.
|
|
2713
|
+
- `sourceRoots` — App source directories, absolute.
|
|
2714
|
+
- `suiteFiles` — Supplied spec/helper paths, absolute.
|
|
2715
|
+
|
|
2716
|
+
**Returns:** Existing, bounded text sources. Missing/unsupported files are ignored.
|
|
2717
|
+
|
|
2718
|
+
#### `runPlaywrightFeedback(backend, spec, sourceFiles, revision, options)`
|
|
2719
|
+
|
|
2720
|
+
Run ONE spec's native command. Callers supply the correctly configured local command and
|
|
2721
|
+
append these runner flags at composition time (rather than modifying shell text here).
|
|
2722
|
+
Native failures are diagnosis, never proof that a complete supplied suite passed.
|
|
2723
|
+
|
|
2724
|
+
```typescript
|
|
2725
|
+
function runPlaywrightFeedback(
|
|
2726
|
+
backend: ExecutionBackend,
|
|
2727
|
+
spec: FeedbackSpec,
|
|
2728
|
+
sourceFiles: string[],
|
|
2729
|
+
revision: number,
|
|
2730
|
+
options: {
|
|
2731
|
+
command: (flags: string[]) => string
|
|
2732
|
+
scratchRoot?: string
|
|
2733
|
+
timeoutMs?: number
|
|
2734
|
+
emit?: (result: PlaywrightFeedbackResult) => void
|
|
2735
|
+
pollMs?: number
|
|
2736
|
+
},
|
|
2737
|
+
): Promise<PlaywrightFeedbackResult>
|
|
2738
|
+
```
|
|
2739
|
+
|
|
2740
|
+
- `backend` — Existing execution backend.
|
|
2741
|
+
- `spec` — The supplied spec and its normal per-file command.
|
|
2742
|
+
- `sourceFiles` — Triggering component files, known to the write/index.
|
|
2743
|
+
- `revision` — Source revision the scheduler will validate before delivery.
|
|
2744
|
+
- `options` — Output location, command composition and a bounded backend budget.
|
|
2745
|
+
|
|
2746
|
+
**Returns:** The actual native outcome and actionable failures only.
|
|
2747
|
+
|
|
2435
2748
|
#### `reportCarriesIdentities(status)`
|
|
2436
2749
|
|
|
2437
2750
|
The report statuses for which the report's own per-test identities and attachments may be used.
|
|
@@ -4456,7 +4769,7 @@ function failureBlocks(s: string): string[]
|
|
|
4456
4769
|
|
|
4457
4770
|
**Returns:** Each block, in order (empty when there are none).
|
|
4458
4771
|
|
|
4459
|
-
#### `runningOutputSliceCommand(log, own)`
|
|
4772
|
+
#### `runningOutputSliceCommand(log, own, command)`
|
|
4460
4773
|
|
|
4461
4774
|
The shell command whose stdout is the interesting part of a log that is still being written:
|
|
4462
4775
|
the failure lines so far (capped at {@link RUNNING_FAILURE_LINES}), then the end of the log.
|
|
@@ -4473,6 +4786,7 @@ function runningOutputSliceCommand(log: string, own?: string): string
|
|
|
4473
4786
|
|
|
4474
4787
|
- `log` — The task log path.
|
|
4475
4788
|
- `own` — A file the command redirects its own output to, if any.
|
|
4789
|
+
- `command` — Executed command, whose logical plan supplies live step boundaries if present.
|
|
4476
4790
|
|
|
4477
4791
|
**Returns:** The shell command, safe to hand to the execution backend as-is.
|
|
4478
4792
|
|
|
@@ -4488,7 +4802,7 @@ a duration — three bodies do not fit, and the repeat is invisible. This read i
|
|
|
4488
4802
|
anyone; it is parsed.
|
|
4489
4803
|
|
|
4490
4804
|
```typescript
|
|
4491
|
-
function runningCauseCommand(log: string, own?: string): string
|
|
4805
|
+
function runningCauseCommand(log: string, own?: string, command?: string): string
|
|
4492
4806
|
```
|
|
4493
4807
|
|
|
4494
4808
|
- `log` — The task log path.
|
|
@@ -5546,6 +5860,14 @@ Bytes of a running log a repeating-cause look reads back.
|
|
|
5546
5860
|
const REPEATING_CAUSE_TAIL_BYTES: 40000
|
|
5547
5861
|
```
|
|
5548
5862
|
|
|
5863
|
+
#### `COMMAND_PLAN_LOG_CHARS`
|
|
5864
|
+
|
|
5865
|
+
Whole-step history retained for wrapped plans; ordinary diagnostic logs fit inside this bound.
|
|
5866
|
+
|
|
5867
|
+
```typescript
|
|
5868
|
+
const COMMAND_PLAN_LOG_CHARS: 4000000
|
|
5869
|
+
```
|
|
5870
|
+
|
|
5549
5871
|
#### `RUNNING_LOG_READ_BYTES`
|
|
5550
5872
|
|
|
5551
5873
|
Bytes of a running log a diagnostic note reads back: one {@link REPEATING_CAUSE_TAIL_BYTES} window.
|
|
@@ -5677,7 +5999,21 @@ Peer dependencies:
|
|
|
5677
5999
|
### Runtime Dependencies
|
|
5678
6000
|
|
|
5679
6001
|
- `@molecule/api-ai`
|
|
5680
|
-
|
|
6002
|
+
- `typescript`
|
|
6003
|
+
|
|
6004
|
+
- **Background Playwright feedback:** `createPlaywrightFeedback({ load, run, onFailures })`
|
|
6005
|
+
coalesces `changed(paths)` events without delaying writes. Use `readFeedbackSources`
|
|
6006
|
+
to batch source reads over either backend and `runPlaywrightFeedback` to run each
|
|
6007
|
+
supplied spec through its native command. Its incremental reporter supplies exact
|
|
6008
|
+
locator failures and the failure-time page snapshot. Healthy runs emit no note;
|
|
6009
|
+
no suite schedules no runner. `settled()`/`close()` are for tests and shutdown,
|
|
6010
|
+
never a deployment barrier. Diagnoses are not whole-suite completion proof.
|
|
6011
|
+
- **Opaque command plans:** prepare each logical step with `streamingBackgroundCommand`,
|
|
6012
|
+
call `createCommandPlan`, and attach it to the executed wrapper with `commandWithPlan`.
|
|
6013
|
+
The launcher prints each step's `startMarker` and `endMarker` on their own lines around
|
|
6014
|
+
execution. `commandStepView` reads the active step for diagnostics; `logicalCommandText`
|
|
6015
|
+
exposes the planned commands for static classification. Preserve the descriptor when
|
|
6016
|
+
wrapping again. The metadata is advisory and never establishes a completed test result.
|
|
5681
6017
|
- **`yieldOnFirstFailureFor`** can yield one still-running deployed task's concrete diagnostic; callers opt out after a prior wait result or unknown history.
|
|
5682
6018
|
- **`wait_for_task` state probes report current progress without guessing log growth.**
|
|
5683
6019
|
A call shorter than one normal two-second poll omits both growth and no-growth
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../src/backends/local.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAEnD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB,
|
|
1
|
+
{"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../src/backends/local.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAEnD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB,CA6FxE"}
|
package/dist/backends/local.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* @module
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
7
|
+
import { spawn } from 'child_process';
|
|
8
8
|
import { mkdir, readdir, readFile, unlink, writeFile } from 'fs/promises';
|
|
9
9
|
import { dirname } from 'path';
|
|
10
10
|
/**
|
|
@@ -38,23 +38,69 @@ export function createLocalBackend(projectRoot) {
|
|
|
38
38
|
},
|
|
39
39
|
run(command, opts) {
|
|
40
40
|
return new Promise((resolve) => {
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
|
|
41
|
+
// A native runner owns children. execFile's timeout killed only sh,
|
|
42
|
+
// leaving the runner/browser alive. Use the OS process group, with a
|
|
43
|
+
// graceful signal followed by a bounded forceful cleanup of that group.
|
|
44
|
+
const grouped = process.platform !== 'win32';
|
|
45
|
+
const child = spawn('sh', ['-c', command], {
|
|
44
46
|
cwd: opts?.cwd || projectRoot,
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
detached: grouped,
|
|
48
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
49
|
+
});
|
|
50
|
+
let stdout = '', stderr = '', closed = false, code = 1;
|
|
51
|
+
let stopped;
|
|
52
|
+
let force;
|
|
53
|
+
const finish = () => {
|
|
54
|
+
if (closed && !force)
|
|
55
|
+
resolve({ stdout, stderr, exitCode: stopped === 'timeout' ? 124 : stopped ? 1 : code });
|
|
56
|
+
};
|
|
57
|
+
const signal = (value) => {
|
|
58
|
+
try {
|
|
59
|
+
if (grouped && child.pid)
|
|
60
|
+
process.kill(-child.pid, value);
|
|
61
|
+
else
|
|
62
|
+
child.kill(value);
|
|
51
63
|
}
|
|
52
|
-
|
|
53
|
-
|
|
64
|
+
catch (_error) {
|
|
65
|
+
/* the owned group already exited */
|
|
54
66
|
}
|
|
55
|
-
|
|
56
|
-
|
|
67
|
+
};
|
|
68
|
+
const stop = (why) => {
|
|
69
|
+
if (stopped)
|
|
70
|
+
return;
|
|
71
|
+
stopped = why;
|
|
72
|
+
signal('SIGTERM');
|
|
73
|
+
force = setTimeout(() => {
|
|
74
|
+
signal('SIGKILL');
|
|
75
|
+
force = undefined;
|
|
76
|
+
finish();
|
|
77
|
+
}, 1000);
|
|
78
|
+
};
|
|
79
|
+
const timeout = Math.min(opts?.timeout || 30_000, opts?.budgetMs || Infinity);
|
|
80
|
+
const deadline = setTimeout(() => stop('timeout'), timeout);
|
|
81
|
+
const collect = (text, channel) => {
|
|
82
|
+
if (stopped)
|
|
83
|
+
return;
|
|
84
|
+
if (stdout.length + stderr.length + text.length > 10 * 1024 * 1024) {
|
|
85
|
+
stderr += '\nCommand exceeded the 10 MB output limit.';
|
|
86
|
+
stop('output');
|
|
87
|
+
return;
|
|
57
88
|
}
|
|
89
|
+
if (channel === 'stdout')
|
|
90
|
+
stdout += text;
|
|
91
|
+
else
|
|
92
|
+
stderr += text;
|
|
93
|
+
};
|
|
94
|
+
child.stdout.setEncoding('utf8').on('data', (text) => collect(text, 'stdout'));
|
|
95
|
+
child.stderr.setEncoding('utf8').on('data', (text) => collect(text, 'stderr'));
|
|
96
|
+
child.on('error', (error) => {
|
|
97
|
+
stderr += error.message;
|
|
98
|
+
});
|
|
99
|
+
child.on('close', (exitCode) => {
|
|
100
|
+
closed = true;
|
|
101
|
+
code = exitCode ?? 1;
|
|
102
|
+
clearTimeout(deadline);
|
|
103
|
+
finish();
|
|
58
104
|
});
|
|
59
105
|
});
|
|
60
106
|
},
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/** One sequential command, with boundaries emitted by its launcher around execution. */
|
|
2
|
+
export interface CommandPlanStep {
|
|
3
|
+
/** Launcher's stable step identity. */
|
|
4
|
+
id: string;
|
|
5
|
+
/** The logical command actually executed, including launch rewrites. */
|
|
6
|
+
command: string;
|
|
7
|
+
/** Printed on its own line immediately before this step runs. */
|
|
8
|
+
startMarker: string;
|
|
9
|
+
/** Printed on its own line after this step settles. */
|
|
10
|
+
endMarker: string;
|
|
11
|
+
}
|
|
12
|
+
/** A wrapper's ordered commands; metadata describes execution, never proof or completion. */
|
|
13
|
+
export interface CommandPlan {
|
|
14
|
+
/** Per-launch boundary identity, preventing ordinary suite output from matching a boundary. */
|
|
15
|
+
id: string;
|
|
16
|
+
/** Steps execute in this order. */
|
|
17
|
+
steps: CommandPlanStep[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Give already-prepared logical commands unique log boundaries.
|
|
21
|
+
* @param steps - Commands in execution order.
|
|
22
|
+
* @returns Metadata for the wrapper and the launcher that executes its steps.
|
|
23
|
+
*/
|
|
24
|
+
export declare function createCommandPlan(steps: {
|
|
25
|
+
id: string;
|
|
26
|
+
command: string;
|
|
27
|
+
}[]): CommandPlan;
|
|
28
|
+
/**
|
|
29
|
+
* Preserve a wrapper's typed logical plan in its durable shell script, including across restarts.
|
|
30
|
+
* Shell comments keep this independent of the wrapper's executable, arguments and payload format.
|
|
31
|
+
* @param command - Executed wrapper.
|
|
32
|
+
* @param plan - Commands the launcher will actually execute and delimit.
|
|
33
|
+
* @returns A shell command with a passive metadata header.
|
|
34
|
+
*/
|
|
35
|
+
export declare function commandWithPlan(command: string, plan: CommandPlan): string;
|
|
36
|
+
/**
|
|
37
|
+
* Read the shared descriptor, never a launcher's private wrapper format.
|
|
38
|
+
* @param command - Command or recovered task script.
|
|
39
|
+
* @returns A valid logical plan, or null for an ordinary command.
|
|
40
|
+
*/
|
|
41
|
+
export declare function commandPlan(command: string): CommandPlan | null;
|
|
42
|
+
/**
|
|
43
|
+
* Commands a wrapper will run, for static classification; live diagnostics use commandStepView.
|
|
44
|
+
* @param command - Executed command.
|
|
45
|
+
* @returns Logical commands in order, or the direct command unchanged.
|
|
46
|
+
*/
|
|
47
|
+
export declare function logicalCommandText(command: string): string;
|
|
48
|
+
/**
|
|
49
|
+
* Select only the step that owns the latest log boundary. Completed steps cannot supply a live
|
|
50
|
+
* failure, target, retry policy, file selection or rerun. Before the first boundary and between
|
|
51
|
+
* steps the live command is unknown; no diagnostic is permitted.
|
|
52
|
+
* @param command - Wrapper or direct command.
|
|
53
|
+
* @param output - Whole log, or the boundary-preserving bounded read.
|
|
54
|
+
* @returns Active command and its output, plus whether the entire step's output is available.
|
|
55
|
+
*/
|
|
56
|
+
export declare function commandStepView(command: string, output: string): {
|
|
57
|
+
command: string;
|
|
58
|
+
output: string;
|
|
59
|
+
complete: boolean;
|
|
60
|
+
/** Unique execution step, including when adjacent steps run identical commands. */
|
|
61
|
+
stepKey?: string;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* AWK program for a bounded read that retains the active boundary even after a long step and
|
|
65
|
+
* discards prior steps. A truncated step cannot establish a universal failure across its history.
|
|
66
|
+
* @param plan - Logical plan whose boundaries the launcher emits.
|
|
67
|
+
* @param limit - Maximum output characters retained for diagnosis.
|
|
68
|
+
* @returns An AWK program; callers shell-quote it like every other argument.
|
|
69
|
+
*/
|
|
70
|
+
export declare function commandPlanLogRead(plan: CommandPlan, limit: number): string;
|
|
71
|
+
//# sourceMappingURL=command-plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-plan.d.ts","sourceRoot":"","sources":["../src/command-plan.ts"],"names":[],"mappings":"AAIA,wFAAwF;AACxF,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAA;IACV,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAA;IACf,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAA;IACnB,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,6FAA6F;AAC7F,MAAM,WAAW,WAAW;IAC1B,+FAA+F;IAC/F,EAAE,EAAE,MAAM,CAAA;IACV,mCAAmC;IACnC,KAAK,EAAE,eAAe,EAAE,CAAA;CACzB;AAKD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,WAAW,CAUvF;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,MAAM,CAE1E;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CA4B/D;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb;IACD,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,OAAO,CAAA;IACjB,mFAAmF;IACnF,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAsBA;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAQ3E"}
|