@molecule/api-ai-tools 1.9.19 → 1.10.1
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 +104 -7
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +2 -1
- package/dist/suite-overlap.d.ts +26 -1
- package/dist/suite-overlap.d.ts.map +1 -1
- package/dist/suite-overlap.js +66 -2
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +237 -19
- package/dist/trace-artifacts.d.ts +38 -0
- package/dist/trace-artifacts.d.ts.map +1 -1
- package/dist/trace-artifacts.js +212 -2
- package/dist/types.d.ts +19 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utilities.d.ts +9 -4
- package/dist/utilities.d.ts.map +1 -1
- package/dist/utilities.js +6 -4
- package/package.json +1 -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-10-
|
|
6
|
+
Generated: 2026-10-18T22:07:04.913Z
|
|
7
7
|
-->
|
|
8
8
|
|
|
9
9
|
# @molecule/api-ai-tools
|
|
@@ -339,6 +339,17 @@ interface LeadingSleep {
|
|
|
339
339
|
}
|
|
340
340
|
```
|
|
341
341
|
|
|
342
|
+
#### `RunEnvSetting`
|
|
343
|
+
|
|
344
|
+
One `NAME=value` the request requires of a suite run.
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
interface RunEnvSetting {
|
|
348
|
+
name: string
|
|
349
|
+
value: string
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
342
353
|
#### `SuiteRunInFlight`
|
|
343
354
|
|
|
344
355
|
One suite run, as the rule that decides whether a second may start beside it reads it.
|
|
@@ -578,6 +589,33 @@ interface TraceMissingText {
|
|
|
578
589
|
}
|
|
579
590
|
```
|
|
580
591
|
|
|
592
|
+
#### `TraceReadContradiction`
|
|
593
|
+
|
|
594
|
+
A write the trace recorded answering a boolean field, and a LATER GET of the same resource
|
|
595
|
+
answering the opposite for that field.
|
|
596
|
+
|
|
597
|
+
This is the pair that reads as a frontend race and is not one: xr-molecule-flash-m181's follow
|
|
598
|
+
test sent `POST /api/profiles/:username/follow` and the API answered
|
|
599
|
+
`{"profile":{…,"following":true}}`, then a `GET /api/profiles/:username` answered
|
|
600
|
+
`{"profile":{…,"following":false}}` — the READ route never saw the viewer, so it hydrated
|
|
601
|
+
`following` from nobody. The run rewrote the profile component twice, the API client once, and
|
|
602
|
+
added optimistic state before anyone read the route's middleware; the write itself was fine.
|
|
603
|
+
|
|
604
|
+
```typescript
|
|
605
|
+
interface TraceReadContradiction {
|
|
606
|
+
/** The boolean field both answered (`following`, `favorited`). */
|
|
607
|
+
field: string
|
|
608
|
+
/** What the write's response said it is. */
|
|
609
|
+
writeValue: boolean
|
|
610
|
+
/** What the later read's response said it is. */
|
|
611
|
+
readValue: boolean
|
|
612
|
+
/** The write that answered it (`POST /api/profiles/x/follow`). */
|
|
613
|
+
write: TraceRequest
|
|
614
|
+
/** The later GET of the same resource (`GET /api/profiles/x`). */
|
|
615
|
+
read: TraceRequest
|
|
616
|
+
}
|
|
617
|
+
```
|
|
618
|
+
|
|
581
619
|
#### `TraceArtifact`
|
|
582
620
|
|
|
583
621
|
What one trace says: the test it belongs to, the requests it made, and its console lines.
|
|
@@ -658,6 +696,15 @@ interface TraceArtifact {
|
|
|
658
696
|
* read before this field existed.
|
|
659
697
|
*/
|
|
660
698
|
missingText?: TraceMissingText
|
|
699
|
+
/**
|
|
700
|
+
* A write's answer a later GET of the same resource contradicted — the read route does not see
|
|
701
|
+
* the viewer (xr-molecule-flash-m181's `following`). The note leads with it and sends the run at
|
|
702
|
+
* the route's middleware, not the page's state handling.
|
|
703
|
+
*
|
|
704
|
+
* Absent when no write and later read in the trace answered the same boolean field differently,
|
|
705
|
+
* and on traces read before this field existed.
|
|
706
|
+
*/
|
|
707
|
+
readContradiction?: TraceReadContradiction
|
|
661
708
|
}
|
|
662
709
|
```
|
|
663
710
|
|
|
@@ -914,6 +961,26 @@ interface ToolBuildConfig {
|
|
|
914
961
|
*/
|
|
915
962
|
excludedTestTitles?: () => readonly string[]
|
|
916
963
|
|
|
964
|
+
/**
|
|
965
|
+
* The `NAME=value` settings the person's request REQUIRES of a suite run (molecule-dev's
|
|
966
|
+
* `requiredRunSettings` — its mode, say), asked when the cause note composes a narrowed re-run
|
|
967
|
+
* of a finished run's failures. A re-run composed from the executor's own command inherits what
|
|
968
|
+
* that command set — and nothing it left out, so a run that measured the suite in `spa` handed
|
|
969
|
+
* back a re-run that would measure `spa` again (xr-molecule-flash-m182 +12:06: the request names
|
|
970
|
+
* `TEST_MODE=fullstack`, the run and its re-run both omitted it).
|
|
971
|
+
*
|
|
972
|
+
* A getter, not an array: the request is read per turn while the tool set is built once, and
|
|
973
|
+
* what the suite's own files read is the consumer's reading. Unset answers "nothing required".
|
|
974
|
+
*
|
|
975
|
+
* @param command - The command the finished run was started with.
|
|
976
|
+
* @param cwd - The resolved working directory it ran in.
|
|
977
|
+
* @returns The settings to put on a re-run of that command.
|
|
978
|
+
*/
|
|
979
|
+
requiredSuiteEnv?: (
|
|
980
|
+
command: string,
|
|
981
|
+
cwd: string,
|
|
982
|
+
) => Promise<readonly { name: string; value: string }[] | null | undefined>
|
|
983
|
+
|
|
917
984
|
/**
|
|
918
985
|
* The supplied suite's own budget, when the Playwright config a command would load sets
|
|
919
986
|
* different settings, asked BEFORE the run executes. The consumer knows where the suite and its
|
|
@@ -1901,7 +1968,7 @@ function withSuiteConfig(command: string, config: string | null | undefined): st
|
|
|
1901
1968
|
|
|
1902
1969
|
**Returns:** The command with the flag, or the command unchanged.
|
|
1903
1970
|
|
|
1904
|
-
#### `scopedRerunCommand(command, locations, excluded, config, cwd)`
|
|
1971
|
+
#### `scopedRerunCommand(command, locations, excluded, config, cwd, env)`
|
|
1905
1972
|
|
|
1906
1973
|
The whole-suite command made scoped to the tests it should re-run instead: the same
|
|
1907
1974
|
invocation — same directory, same settings — with the named `file:line`s in place of the whole
|
|
@@ -1924,6 +1991,7 @@ function scopedRerunCommand(
|
|
|
1924
1991
|
excluded?: readonly string[],
|
|
1925
1992
|
config?: string | null,
|
|
1926
1993
|
cwd?: string | null,
|
|
1994
|
+
env?: readonly RunEnvSetting[],
|
|
1927
1995
|
): string
|
|
1928
1996
|
```
|
|
1929
1997
|
|
|
@@ -1932,9 +2000,32 @@ function scopedRerunCommand(
|
|
|
1932
2000
|
- `excluded` — The test titles the request carves out. They are inverted out (`--grep-invert`) so a re-run of the failing locations cannot report one of them again — xr-molecule-flash-m101 re-ran the whole 139-test suite and spent ~4 minutes to be told about a test the request had already said does not count.
|
|
1933
2001
|
- `config` — The config the run loaded, when the caller knows it; added when the command does not name one.
|
|
1934
2002
|
- `cwd` — The directory `exec_command` was given, when it was; the base a location is resolved against when the command does not `cd` anywhere.
|
|
2003
|
+
- `env` — The settings the REQUEST requires of the suite and this run left out ({@link withRunEnv}): the re-run carries them, so a re-run of a run measured in the wrong mode is not measured in that mode again (xr-molecule-flash-m182 +12:06).
|
|
1935
2004
|
|
|
1936
2005
|
**Returns:** The scoped command, or the command unchanged when it runs no Playwright suite.
|
|
1937
2006
|
|
|
2007
|
+
#### `withRunEnv(command, settings)`
|
|
2008
|
+
|
|
2009
|
+
The command with the request's required settings put in front of its RUN statement — the ONE
|
|
2010
|
+
place every composed re-run gets them (xr-molecule-flash-m182).
|
|
2011
|
+
|
|
2012
|
+
The settings are written at the statement's own assignment offset, never in front of the whole
|
|
2013
|
+
command: a shell binds an assignment there to the statement's program, while one in front of the
|
|
2014
|
+
whole command is the environment of its FIRST statement alone (`APP_BASE=… cd app && npx
|
|
2015
|
+
playwright test` sets the variable for `cd`; xr-molecule-flash-m103 +28:08). A name the command
|
|
2016
|
+
gives a different value is replaced, and one it already gives the required value is left as
|
|
2017
|
+
written. When the parse cannot place the statement (a run inside a nested `sh -c '…'`), the
|
|
2018
|
+
settings become `export`s, which no statement boundary can swallow.
|
|
2019
|
+
|
|
2020
|
+
```typescript
|
|
2021
|
+
function withRunEnv(command: string, settings?: readonly RunEnvSetting[]): string
|
|
2022
|
+
```
|
|
2023
|
+
|
|
2024
|
+
- `command` — The command to carry them.
|
|
2025
|
+
- `settings` — The `NAME`/`value` pairs the request requires.
|
|
2026
|
+
|
|
2027
|
+
**Returns:** The command, or the command unchanged when it already carries every setting.
|
|
2028
|
+
|
|
1938
2029
|
#### `suiteRunInTheWay(candidate, inFlight)`
|
|
1939
2030
|
|
|
1940
2031
|
The run in flight that makes a second run a hazard, or null when nothing is in the way.
|
|
@@ -3415,14 +3506,20 @@ reads as ten defects in the app.
|
|
|
3415
3506
|
function failureCausesNote(
|
|
3416
3507
|
log: string,
|
|
3417
3508
|
excluded?: readonly string[],
|
|
3418
|
-
run?: {
|
|
3509
|
+
run?: {
|
|
3510
|
+
command: string
|
|
3511
|
+
cwd?: string
|
|
3512
|
+
log?: string
|
|
3513
|
+
config?: string | null
|
|
3514
|
+
env?: readonly RunEnvSetting[]
|
|
3515
|
+
},
|
|
3419
3516
|
pageErrors?: readonly CausePageErrors[],
|
|
3420
3517
|
): string | null
|
|
3421
3518
|
```
|
|
3422
3519
|
|
|
3423
3520
|
- `log` — The finished run's output.
|
|
3424
3521
|
- `excluded` — The test titles the request carves out, if the caller knows them.
|
|
3425
|
-
- `run` — How the run was started, when the caller knows it: the narrowed re-run is built from `command`/`cwd`/`config`, and `log` (the path the output was written to) is what the "left out" sentence greps when more causes exist than the result has room for.
|
|
3522
|
+
- `run` — How the run was started, when the caller knows it: the narrowed re-run is built from `command`/`cwd`/`config`/`env`, and `log` (the path the output was written to) is what the "left out" sentence greps when more causes exist than the result has room for.
|
|
3426
3523
|
|
|
3427
3524
|
**Returns:** The note, or null.
|
|
3428
3525
|
|
|
@@ -3441,13 +3538,13 @@ refused while the run walks ({@link suiteRunInTheWay}).
|
|
|
3441
3538
|
|
|
3442
3539
|
```typescript
|
|
3443
3540
|
function rerunOfRunningSuite(
|
|
3444
|
-
run: { command: string; cwd?: string; config?: string | null },
|
|
3541
|
+
run: { command: string; cwd?: string; config?: string | null; env?: readonly RunEnvSetting[] },
|
|
3445
3542
|
locations: readonly string[],
|
|
3446
3543
|
excluded?: readonly string[],
|
|
3447
3544
|
): string | null
|
|
3448
3545
|
```
|
|
3449
3546
|
|
|
3450
|
-
- `run` — The run in flight: the command it was started with, as it was run, the directory that command ran in,
|
|
3547
|
+
- `run` — The run in flight: the command it was started with, as it was run, the directory that command ran in, the config it loaded when the caller knows it, and the settings the request required and the run left out (`env`) — the re-run carries them, so it never reproduces the configuration the run was measured under by mistake (m182).
|
|
3451
3548
|
- `locations` — The failing `file:line`s to re-run, as the run's log printed them.
|
|
3452
3549
|
- `excluded` — The test titles the request carves out: the re-run inverts them out (`--grep-invert`) so it cannot report them again.
|
|
3453
3550
|
|
|
@@ -3486,7 +3583,7 @@ function repeatingFailureNote(
|
|
|
3486
3583
|
log: string
|
|
3487
3584
|
stop: string
|
|
3488
3585
|
universal?: UniversalCause | null
|
|
3489
|
-
run?: { command: string; cwd?: string }
|
|
3586
|
+
run?: { command: string; cwd?: string; env?: readonly RunEnvSetting[] }
|
|
3490
3587
|
editsInvalidateRun?: boolean
|
|
3491
3588
|
},
|
|
3492
3589
|
): string
|
package/dist/schemas.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAElD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,UAAU,CAAA;CACvB;AAED;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAElD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,UAAU,CAAA;CACvB;AAED;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CA2U1C,CAAA"}
|
package/dist/schemas.js
CHANGED
|
@@ -132,7 +132,8 @@ export const TOOL_SCHEMAS = {
|
|
|
132
132
|
},
|
|
133
133
|
include: {
|
|
134
134
|
type: 'string',
|
|
135
|
-
description: "File glob pattern to filter files (e.g. '*.ts', '*.tsx').
|
|
135
|
+
description: "File glob pattern to filter files (e.g. '*.ts', '*.tsx'). Several extensions go in one " +
|
|
136
|
+
"brace group of comma-separated alternatives: '*.{ts,tsx,yml,json,md}' (up to 16). Optional.",
|
|
136
137
|
},
|
|
137
138
|
contextLines: {
|
|
138
139
|
type: 'number',
|
package/dist/suite-overlap.d.ts
CHANGED
|
@@ -105,9 +105,34 @@ export declare function withSuiteConfig(command: string, config: string | null |
|
|
|
105
105
|
* does not name one.
|
|
106
106
|
* @param cwd - The directory `exec_command` was given, when it was; the base a location is
|
|
107
107
|
* resolved against when the command does not `cd` anywhere.
|
|
108
|
+
* @param env - The settings the REQUEST requires of the suite and this run left out
|
|
109
|
+
* ({@link withRunEnv}): the re-run carries them, so a re-run of a run measured in the wrong
|
|
110
|
+
* mode is not measured in that mode again (xr-molecule-flash-m182 +12:06).
|
|
108
111
|
* @returns The scoped command, or the command unchanged when it runs no Playwright suite.
|
|
109
112
|
*/
|
|
110
|
-
export declare function scopedRerunCommand(command: string, locations: readonly string[], excluded?: readonly string[], config?: string | null, cwd?: string | null): string;
|
|
113
|
+
export declare function scopedRerunCommand(command: string, locations: readonly string[], excluded?: readonly string[], config?: string | null, cwd?: string | null, env?: readonly RunEnvSetting[]): string;
|
|
114
|
+
/** One `NAME=value` the request requires of a suite run. */
|
|
115
|
+
export interface RunEnvSetting {
|
|
116
|
+
name: string;
|
|
117
|
+
value: string;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* The command with the request's required settings put in front of its RUN statement — the ONE
|
|
121
|
+
* place every composed re-run gets them (xr-molecule-flash-m182).
|
|
122
|
+
*
|
|
123
|
+
* The settings are written at the statement's own assignment offset, never in front of the whole
|
|
124
|
+
* command: a shell binds an assignment there to the statement's program, while one in front of the
|
|
125
|
+
* whole command is the environment of its FIRST statement alone (`APP_BASE=… cd app && npx
|
|
126
|
+
* playwright test` sets the variable for `cd`; xr-molecule-flash-m103 +28:08). A name the command
|
|
127
|
+
* gives a different value is replaced, and one it already gives the required value is left as
|
|
128
|
+
* written. When the parse cannot place the statement (a run inside a nested `sh -c '…'`), the
|
|
129
|
+
* settings become `export`s, which no statement boundary can swallow.
|
|
130
|
+
*
|
|
131
|
+
* @param command - The command to carry them.
|
|
132
|
+
* @param settings - The `NAME`/`value` pairs the request requires.
|
|
133
|
+
* @returns The command, or the command unchanged when it already carries every setting.
|
|
134
|
+
*/
|
|
135
|
+
export declare function withRunEnv(command: string, settings?: readonly RunEnvSetting[]): string;
|
|
111
136
|
/**
|
|
112
137
|
* One suite run, as the rule that decides whether a second may start beside it reads it.
|
|
113
138
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"suite-overlap.d.ts","sourceRoot":"","sources":["../src/suite-overlap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAQH;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAoB1D;AAKD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAS1F;AAqCD
|
|
1
|
+
{"version":3,"file":"suite-overlap.d.ts","sourceRoot":"","sources":["../src/suite-overlap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAQH;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAoB1D;AAKD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAS1F;AAqCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,QAAQ,GAAE,SAAS,MAAM,EAAO,EAChC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,EACtB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,EACnB,GAAG,GAAE,SAAS,aAAa,EAAO,GACjC,MAAM,CA8CR;AAED,4DAA4D;AAC5D,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd;AAmCD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,SAAS,aAAa,EAAO,GAAG,MAAM,CAe3F;AAkHD;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+FAA+F;IAC/F,SAAS,EAAE,OAAO,CAAA;IAClB,oFAAoF;IACpF,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,gBAAgB,EACzD,SAAS,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,EAC7B,QAAQ,EAAE,SAAS,CAAC,EAAE,GACrB,CAAC,GAAG,IAAI,CAMV;AA2FD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACvC;AAmCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAYtF"}
|
package/dist/suite-overlap.js
CHANGED
|
@@ -179,9 +179,12 @@ function redirectToFreshFile(command) {
|
|
|
179
179
|
* does not name one.
|
|
180
180
|
* @param cwd - The directory `exec_command` was given, when it was; the base a location is
|
|
181
181
|
* resolved against when the command does not `cd` anywhere.
|
|
182
|
+
* @param env - The settings the REQUEST requires of the suite and this run left out
|
|
183
|
+
* ({@link withRunEnv}): the re-run carries them, so a re-run of a run measured in the wrong
|
|
184
|
+
* mode is not measured in that mode again (xr-molecule-flash-m182 +12:06).
|
|
182
185
|
* @returns The scoped command, or the command unchanged when it runs no Playwright suite.
|
|
183
186
|
*/
|
|
184
|
-
export function scopedRerunCommand(command, locations, excluded = [], config, cwd) {
|
|
187
|
+
export function scopedRerunCommand(command, locations, excluded = [], config, cwd, env = []) {
|
|
185
188
|
const run = playwrightStatement(command);
|
|
186
189
|
if (run === null)
|
|
187
190
|
return command;
|
|
@@ -223,7 +226,68 @@ export function scopedRerunCommand(command, locations, excluded = [], config, cw
|
|
|
223
226
|
// X1 xr-molecule-flash-m157 (+14:02) was handed a re-run that still carried the chain's second
|
|
224
227
|
// whole walk — 4.5 minutes measuring code it had not changed.
|
|
225
228
|
const rerunTail = suiteRunStatements(tail).length > 0 ? '' : tail;
|
|
226
|
-
return `${redirectToFreshFile(scoped)}${redirectToFreshFile(rerunTail)}
|
|
229
|
+
return withRunEnv(`${redirectToFreshFile(scoped)}${redirectToFreshFile(rerunTail)}`, env);
|
|
230
|
+
}
|
|
231
|
+
/** A `NAME=value` word in command position, optionally behind `export`/`env`. */
|
|
232
|
+
const ENV_WORD = /(^|[\s;&|(])(?:export[ \t]+|env[ \t]+)?([A-Za-z_][A-Za-z0-9_]*)=('[^']*'|"[^"]*"|[^\s;&|]+)/g;
|
|
233
|
+
/** The value a command gives a name, unquoted, or null when it sets none. */
|
|
234
|
+
function envValueOf(command, name) {
|
|
235
|
+
for (const m of command.matchAll(ENV_WORD)) {
|
|
236
|
+
if (m[2] !== name)
|
|
237
|
+
continue;
|
|
238
|
+
return (m[3] ?? '').replace(/^(['"])(.*)\1$/, '$2');
|
|
239
|
+
}
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
/** The command with one `NAME=value` word taken out, whitespace and all. */
|
|
243
|
+
function withoutEnvWord(command, name) {
|
|
244
|
+
const pattern = new RegExp(`(^|[\\s;&|(])(?:export[ \\t]+|env[ \\t]+)?${name}=('[^']*'|"[^"]*"|[^\\s;&|]+)`);
|
|
245
|
+
const m = pattern.exec(command);
|
|
246
|
+
if (!m)
|
|
247
|
+
return command;
|
|
248
|
+
const start = m.index + m[1].length;
|
|
249
|
+
const end = m.index + m[0].length;
|
|
250
|
+
const left = /[ \t]*$/.exec(command.slice(0, start))?.[0] ?? '';
|
|
251
|
+
const chain = /^[ \t]*(?:&&|\|\||;)[ \t]*/.exec(command.slice(end));
|
|
252
|
+
// A word between two chained statements takes the following operator with it, so the result is
|
|
253
|
+
// `a && b` and not `a && && b`.
|
|
254
|
+
if (chain && left.length > 0)
|
|
255
|
+
return command.slice(0, start) + command.slice(end + chain[0].length);
|
|
256
|
+
if (left.length > 0)
|
|
257
|
+
return command.slice(0, start - left.length) + command.slice(end);
|
|
258
|
+
const right = /^[ \t]*/.exec(command.slice(end))?.[0] ?? '';
|
|
259
|
+
return command.slice(0, start) + command.slice(end + right.length);
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* The command with the request's required settings put in front of its RUN statement — the ONE
|
|
263
|
+
* place every composed re-run gets them (xr-molecule-flash-m182).
|
|
264
|
+
*
|
|
265
|
+
* The settings are written at the statement's own assignment offset, never in front of the whole
|
|
266
|
+
* command: a shell binds an assignment there to the statement's program, while one in front of the
|
|
267
|
+
* whole command is the environment of its FIRST statement alone (`APP_BASE=… cd app && npx
|
|
268
|
+
* playwright test` sets the variable for `cd`; xr-molecule-flash-m103 +28:08). A name the command
|
|
269
|
+
* gives a different value is replaced, and one it already gives the required value is left as
|
|
270
|
+
* written. When the parse cannot place the statement (a run inside a nested `sh -c '…'`), the
|
|
271
|
+
* settings become `export`s, which no statement boundary can swallow.
|
|
272
|
+
*
|
|
273
|
+
* @param command - The command to carry them.
|
|
274
|
+
* @param settings - The `NAME`/`value` pairs the request requires.
|
|
275
|
+
* @returns The command, or the command unchanged when it already carries every setting.
|
|
276
|
+
*/
|
|
277
|
+
export function withRunEnv(command, settings = []) {
|
|
278
|
+
const added = [];
|
|
279
|
+
let out = command;
|
|
280
|
+
for (const setting of settings) {
|
|
281
|
+
if (envValueOf(out, setting.name) === setting.value)
|
|
282
|
+
continue;
|
|
283
|
+
out = withoutEnvWord(out, setting.name);
|
|
284
|
+
added.push(`${setting.name}=${setting.value}`);
|
|
285
|
+
}
|
|
286
|
+
if (added.length === 0)
|
|
287
|
+
return command;
|
|
288
|
+
const at = locatedCommandSegments(out).find((entry) => entry.segment !== null && PLAYWRIGHT_RUN.test(entry.segment.text))?.assignmentOffset ?? null;
|
|
289
|
+
const words = added.join(' ');
|
|
290
|
+
return at === null ? `export ${words} && ${out}` : `${out.slice(0, at)}${words} ${out.slice(at)}`;
|
|
227
291
|
}
|
|
228
292
|
/** A directory a `cd` can name literally: no `~`, no variable, no glob. */
|
|
229
293
|
const LITERAL_DIR = /^[A-Za-z0-9_./+-]+$/;
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AA4K9C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAahG;AA6ZD,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAqFnE;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAEA,CAAA;AAE9B;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,wBAAwB,QAI6C,CAAA;AA2ElF;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAUhE;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,qBAAqB;IACpC,iFAAiF;IACjF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,8FAA8F;IAC9F,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;CAC5B;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAA;AAoBpF;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,CAAC,GACxE,qBAAqB,CAkBvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAsB,4BAA4B,CAChD,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,qBAAqB,GAC5B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiCxB;AA2GD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,EAAE,CAyuFxF"}
|