upstream-radar 0.43.4 → 0.44.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-zh-CN.md +92 -77
- package/README.md +125 -94
- package/dist/src/cli.js +177 -5
- package/dist/src/cli.js.map +1 -1
- package/dist/src/dsh-compatibility-ledger.d.ts +2 -0
- package/dist/src/dsh-compatibility-ledger.d.ts.map +1 -1
- package/dist/src/dsh-compatibility-ledger.js +5 -0
- package/dist/src/dsh-compatibility-ledger.js.map +1 -1
- package/dist/src/dsh-directory-feed.d.ts +7 -3
- package/dist/src/dsh-directory-feed.d.ts.map +1 -1
- package/dist/src/dsh-directory-feed.js +59 -25
- package/dist/src/dsh-directory-feed.js.map +1 -1
- package/dist/src/dsh-headless-agent-plan.d.ts +7 -0
- package/dist/src/dsh-headless-agent-plan.d.ts.map +1 -1
- package/dist/src/dsh-headless-agent-plan.js +20 -1
- package/dist/src/dsh-headless-agent-plan.js.map +1 -1
- package/dist/src/dsh-install-observation.d.ts +6 -0
- package/dist/src/dsh-install-observation.d.ts.map +1 -1
- package/dist/src/dsh-install-observation.js +2 -2
- package/dist/src/dsh-install-observation.js.map +1 -1
- package/dist/src/dsh-install-plan.d.ts +7 -0
- package/dist/src/dsh-install-plan.d.ts.map +1 -1
- package/dist/src/dsh-install-plan.js +8 -2
- package/dist/src/dsh-install-plan.js.map +1 -1
- package/dist/src/dsh-surface-observation.d.ts +160 -0
- package/dist/src/dsh-surface-observation.d.ts.map +1 -0
- package/dist/src/dsh-surface-observation.js +1031 -0
- package/dist/src/dsh-surface-observation.js.map +1 -0
- package/dist/src/dsh-surface.d.ts +127 -0
- package/dist/src/dsh-surface.d.ts.map +1 -0
- package/dist/src/dsh-surface.js +667 -0
- package/dist/src/dsh-surface.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/upstream-observer.d.ts +6 -0
- package/dist/src/upstream-observer.d.ts.map +1 -1
- package/dist/src/upstream-observer.js +206 -127
- package/dist/src/upstream-observer.js.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/docs/README.zh-CN.md +19 -19
- package/package.json +1 -1
package/dist/src/cli.js
CHANGED
|
@@ -7,6 +7,7 @@ import { renderCompatibilityBenchmark, runCompatibilityBenchmark } from './compa
|
|
|
7
7
|
import { assessCompatibilityChange } from './compatibility.js';
|
|
8
8
|
import { probeDshLoad, probeDshLoadMatrix, renderDshLoadMatrix, renderDshLoadProbe } from './dsh-probe.js';
|
|
9
9
|
import { observeDshPluginInstall, renderDshInstallObservation, } from './dsh-install-observation.js';
|
|
10
|
+
import { observeDshPluginSurface, renderDshSurfaceObservation, } from './dsh-surface-observation.js';
|
|
10
11
|
import { renderDshPluginReview, reviewDshPlugin } from './dsh-review.js';
|
|
11
12
|
import { createAnalysisTask, renderAgentAnalysisPrompt } from './dsh-analysis.js';
|
|
12
13
|
import { createDshCaseReport, renderDshCase } from './dsh-case.js';
|
|
@@ -205,7 +206,8 @@ Usage:
|
|
|
205
206
|
[--report <report.md>] [--dsh-version <v1>,<v2>,...]
|
|
206
207
|
[--reverse-index <index.json>]
|
|
207
208
|
[--dsh-agent-command <executable>]
|
|
208
|
-
[--dsh-agent-arg <argument>] [--llm-env-file <path>]
|
|
209
|
+
[--dsh-agent-arg <argument>] [--llm-env-file <path>]
|
|
210
|
+
[--retry-pending | --retry-pending-only]
|
|
209
211
|
[--ecosystem <dsh|codex|pi>] [--id <id>] [--package <name>]
|
|
210
212
|
[--package-path <path>] [--lockfile <path>] [--lockfile-type <npm|pnpm>]
|
|
211
213
|
[--ref <branch>] [--json]
|
|
@@ -238,6 +240,11 @@ keys; it never writes the key or endpoint to observations.json.
|
|
|
238
240
|
If a ModelBest-style base URL ends in /llm/v1, a 404 also retries the known
|
|
239
241
|
/llm/openai/v1 path.
|
|
240
242
|
|
|
243
|
+
--retry-pending-only consumes durable Agent tasks from observations.json
|
|
244
|
+
without reading GitHub/npm, reviewing artifacts, or changing source observation
|
|
245
|
+
points. It requires an Agent or model configuration and fails while any retry
|
|
246
|
+
still remains pending.
|
|
247
|
+
|
|
241
248
|
The exact npm artifact review is independent of the DSH Agent/model. It runs
|
|
242
249
|
when a meaningful change has a published package, and its dependency findings
|
|
243
250
|
remain in the report even when no model is configured or the model endpoint is
|
|
@@ -275,6 +282,14 @@ Usage:
|
|
|
275
282
|
upstream-radar probe dsh-install [npm:]<package>@<exact-version>
|
|
276
283
|
--dsh-version <exact-version> --isolation-provider <provider> --execute
|
|
277
284
|
[--allow-build <package>]... [--timeout <seconds>] [--report <report.json>] [--json]
|
|
285
|
+
upstream-radar probe dsh-surface [npm:]<package>@<exact-version>
|
|
286
|
+
--dsh-version <exact-version> --case-id <id> --source-case-id <id>
|
|
287
|
+
--source-fingerprint <sha256:...> --contract-fingerprint <sha256:...>
|
|
288
|
+
--plane <web|tui> --profile <name> --runtime-id <id>
|
|
289
|
+
--artifact-sha256 <hex> --isolation-provider <provider> --execute
|
|
290
|
+
[--allow-build <package>]...
|
|
291
|
+
[--driver-root <path>] [--chromium-executable <path>]
|
|
292
|
+
[--artifacts <directory>] [--timeout <seconds>] [--report <report.json>] [--json]
|
|
278
293
|
|
|
279
294
|
The load probes disable lifecycle scripts and check bundle registration/load.
|
|
280
295
|
The dsh-install probe deliberately executes the exact plugin's lifecycle scripts
|
|
@@ -282,6 +297,10 @@ and loads the bundle while recording Linux process, network, and file-change
|
|
|
282
297
|
evidence. Run it only inside a disposable, secret-free Linux environment. It
|
|
283
298
|
requires both --execute and UPSTREAM_RADAR_ISOLATED_RUNNER=1.
|
|
284
299
|
Radar records the caller's isolation-provider claim but cannot verify it.
|
|
300
|
+
The dsh-surface probe adds plane-specific proof: Chromium must observe DSH hand
|
|
301
|
+
off from its boot page after activating the client graph, or a real PTY must observe a
|
|
302
|
+
TUI frame, bounded input, and controlled shutdown. It has the same disposable,
|
|
303
|
+
secret-free execution requirement.
|
|
285
304
|
`,
|
|
286
305
|
review: `Upstream Radar — review one exact published DSH plugin in one command
|
|
287
306
|
|
|
@@ -471,13 +490,14 @@ Usage:
|
|
|
471
490
|
upstream-radar doctor [config.json] [options]
|
|
472
491
|
upstream-radar scan <directory-or-github-url> [--json] [--fail-on <warn|review|block|never>]
|
|
473
492
|
upstream-radar inspect [npm:]<package>@<exact-version> [--deep] [--json] [--fail-on <warn|review|block|never>]
|
|
474
|
-
upstream-radar observe <targets.yml|github-url> [--state <observations.json>] [--report <report.md>] [--dsh-version <v1>,<v2>,...] [--reverse-index <index.json>] [--dsh-agent-command <executable>] [--dsh-agent-arg <argument>] [--llm-env-file <path>] [--retry-pending] [--ecosystem <dsh|codex|pi>] [--id <id>] [--package <name>] [--package-path <path>] [--lockfile <path>] [--lockfile-type <npm|pnpm>] [--ref <branch>] [--json]
|
|
493
|
+
upstream-radar observe <targets.yml|github-url> [--state <observations.json>] [--report <report.md>] [--dsh-version <v1>,<v2>,...] [--reverse-index <index.json>] [--dsh-agent-command <executable>] [--dsh-agent-arg <argument>] [--llm-env-file <path>] [--retry-pending | --retry-pending-only] [--ecosystem <dsh|codex|pi>] [--id <id>] [--package <name>] [--package-path <path>] [--lockfile <path>] [--lockfile-type <npm|pnpm>] [--ref <branch>] [--json]
|
|
475
494
|
upstream-radar graph <npm-lock|pnpm-lock> <lockfile> [--root <package>@<exact-version>] [--json]
|
|
476
495
|
upstream-radar graph reverse <reports-directory> [--package <name>@<exact-version>] [--output <index.json>] [--json]
|
|
477
496
|
upstream-radar profile-check [profile-directory] [--patch <path>] [--report <path>] [--summary] [--json]
|
|
478
497
|
upstream-radar probe dsh-load <package.tgz> [--dsh-version <exact-version>] [--timeout <seconds>] [--keep-profile] [--json]
|
|
479
498
|
upstream-radar probe dsh-matrix <package.tgz> --dsh-version <v1>[,<v2>,...] [--timeout <seconds>] [--keep-profile] [--json]
|
|
480
499
|
upstream-radar probe dsh-install [npm:]<package>@<exact-version> --dsh-version <exact-version> [--case-id <stable-label>] --isolation-provider <github-actions-hosted-runner|firecracker|other> --execute [--allow-build <package>]... [--timeout <seconds>] [--report <report.json>] [--json]
|
|
500
|
+
upstream-radar probe dsh-surface [npm:]<package>@<exact-version> --dsh-version <exact-version> --case-id <stable-label> --source-case-id <stable-label> --source-fingerprint <sha256:...> --contract-fingerprint <sha256:...> --plane <web|tui> --profile <name> --runtime-id <id> --artifact-sha256 <hex> --isolation-provider <github-actions-hosted-runner|firecracker|other> --execute [--allow-build <package>]... [--driver-root <path>] [--chromium-executable <path>] [--artifacts <directory>] [--timeout <seconds>] [--report <report.json>] [--json]
|
|
481
501
|
upstream-radar review dsh-plugin [npm:]<package>@<exact-version> --dsh-version <v1>,<v2>,... [--json]
|
|
482
502
|
upstream-radar demo [--json]
|
|
483
503
|
upstream-radar case dsh-web-ui [--json]
|
|
@@ -1214,8 +1234,10 @@ async function runProbe(args) {
|
|
|
1214
1234
|
const mode = args[0];
|
|
1215
1235
|
if (mode === 'dsh-install')
|
|
1216
1236
|
return runDshInstallObservation(args.slice(1));
|
|
1237
|
+
if (mode === 'dsh-surface')
|
|
1238
|
+
return runDshSurfaceObservation(args.slice(1));
|
|
1217
1239
|
if (mode !== 'dsh-load' && mode !== 'dsh-matrix')
|
|
1218
|
-
throw new Error('probe requires dsh-load or dsh-
|
|
1240
|
+
throw new Error('probe requires dsh-load, dsh-matrix, dsh-install or dsh-surface');
|
|
1219
1241
|
const packagePath = args[1];
|
|
1220
1242
|
if (packagePath === undefined || packagePath.startsWith('-'))
|
|
1221
1243
|
throw new Error(`probe ${mode} requires a package.tgz file`);
|
|
@@ -1366,6 +1388,144 @@ async function runDshInstallObservation(args) {
|
|
|
1366
1388
|
process.stdout.write(json ? `${JSON.stringify(report, null, 2)}\n` : renderDshInstallObservation(report));
|
|
1367
1389
|
return report.result === 'compatible' ? 0 : report.result === 'unknown' ? 1 : 2;
|
|
1368
1390
|
}
|
|
1391
|
+
async function runDshSurfaceObservation(args) {
|
|
1392
|
+
const packageSpec = args[0];
|
|
1393
|
+
if (packageSpec === undefined || packageSpec.startsWith('-')) {
|
|
1394
|
+
throw new Error('probe dsh-surface requires an exact npm package');
|
|
1395
|
+
}
|
|
1396
|
+
let dshVersion;
|
|
1397
|
+
let caseId;
|
|
1398
|
+
let sourceCaseId;
|
|
1399
|
+
let sourceFingerprint;
|
|
1400
|
+
let contractFingerprint;
|
|
1401
|
+
let plane;
|
|
1402
|
+
let profile;
|
|
1403
|
+
let runtimeId;
|
|
1404
|
+
let artifactSha256;
|
|
1405
|
+
let isolationProvider;
|
|
1406
|
+
let timeoutSeconds = 300;
|
|
1407
|
+
let reportPath;
|
|
1408
|
+
let artifactsDirectory;
|
|
1409
|
+
let driverRoot;
|
|
1410
|
+
let chromiumExecutable;
|
|
1411
|
+
const allowedBuilds = [];
|
|
1412
|
+
let execute = false;
|
|
1413
|
+
let json = false;
|
|
1414
|
+
for (let index = 1; index < args.length; index += 1) {
|
|
1415
|
+
const argument = args[index];
|
|
1416
|
+
if (argument === '--execute')
|
|
1417
|
+
execute = true;
|
|
1418
|
+
else if (argument === '--json')
|
|
1419
|
+
json = true;
|
|
1420
|
+
else if (argument === '--dsh-version' || argument === '--case-id' || argument === '--source-case-id'
|
|
1421
|
+
|| argument === '--source-fingerprint' || argument === '--contract-fingerprint' || argument === '--plane'
|
|
1422
|
+
|| argument === '--profile' || argument === '--runtime-id' || argument === '--artifact-sha256'
|
|
1423
|
+
|| argument === '--isolation-provider' || argument === '--timeout' || argument === '--report'
|
|
1424
|
+
|| argument === '--artifacts' || argument === '--driver-root' || argument === '--chromium-executable'
|
|
1425
|
+
|| argument === '--allow-build') {
|
|
1426
|
+
const value = args[index + 1];
|
|
1427
|
+
if (value === undefined || value.startsWith('-'))
|
|
1428
|
+
throw new Error(`${argument} requires a value`);
|
|
1429
|
+
if (argument === '--dsh-version')
|
|
1430
|
+
dshVersion = value;
|
|
1431
|
+
else if (argument === '--case-id')
|
|
1432
|
+
caseId = value;
|
|
1433
|
+
else if (argument === '--source-case-id')
|
|
1434
|
+
sourceCaseId = value;
|
|
1435
|
+
else if (argument === '--source-fingerprint')
|
|
1436
|
+
sourceFingerprint = value;
|
|
1437
|
+
else if (argument === '--contract-fingerprint')
|
|
1438
|
+
contractFingerprint = value;
|
|
1439
|
+
else if (argument === '--plane') {
|
|
1440
|
+
if (value !== 'web' && value !== 'tui')
|
|
1441
|
+
throw new Error('--plane must be web or tui');
|
|
1442
|
+
plane = value;
|
|
1443
|
+
}
|
|
1444
|
+
else if (argument === '--profile')
|
|
1445
|
+
profile = value;
|
|
1446
|
+
else if (argument === '--runtime-id')
|
|
1447
|
+
runtimeId = value;
|
|
1448
|
+
else if (argument === '--artifact-sha256')
|
|
1449
|
+
artifactSha256 = value;
|
|
1450
|
+
else if (argument === '--isolation-provider') {
|
|
1451
|
+
if (value !== 'github-actions-hosted-runner' && value !== 'firecracker' && value !== 'other') {
|
|
1452
|
+
throw new Error('--isolation-provider must be github-actions-hosted-runner, firecracker or other');
|
|
1453
|
+
}
|
|
1454
|
+
isolationProvider = value;
|
|
1455
|
+
}
|
|
1456
|
+
else if (argument === '--timeout') {
|
|
1457
|
+
const parsed = Number(value);
|
|
1458
|
+
if (!Number.isSafeInteger(parsed) || parsed < 30 || parsed > 600)
|
|
1459
|
+
throw new Error('--timeout must be an integer between 30 and 600 seconds');
|
|
1460
|
+
timeoutSeconds = parsed;
|
|
1461
|
+
}
|
|
1462
|
+
else if (argument === '--report')
|
|
1463
|
+
reportPath = value;
|
|
1464
|
+
else if (argument === '--artifacts')
|
|
1465
|
+
artifactsDirectory = value;
|
|
1466
|
+
else if (argument === '--driver-root')
|
|
1467
|
+
driverRoot = value;
|
|
1468
|
+
else if (argument === '--chromium-executable')
|
|
1469
|
+
chromiumExecutable = value;
|
|
1470
|
+
else
|
|
1471
|
+
allowedBuilds.push(value);
|
|
1472
|
+
index += 1;
|
|
1473
|
+
}
|
|
1474
|
+
else {
|
|
1475
|
+
throw new Error(`unknown option for probe dsh-surface: ${argument}`);
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1478
|
+
const required = [
|
|
1479
|
+
['--dsh-version', dshVersion],
|
|
1480
|
+
['--case-id', caseId],
|
|
1481
|
+
['--source-case-id', sourceCaseId],
|
|
1482
|
+
['--source-fingerprint', sourceFingerprint],
|
|
1483
|
+
['--contract-fingerprint', contractFingerprint],
|
|
1484
|
+
['--plane', plane],
|
|
1485
|
+
['--profile', profile],
|
|
1486
|
+
['--runtime-id', runtimeId],
|
|
1487
|
+
['--artifact-sha256', artifactSha256],
|
|
1488
|
+
['--isolation-provider', isolationProvider],
|
|
1489
|
+
];
|
|
1490
|
+
const missing = required.find(([, value]) => value === undefined);
|
|
1491
|
+
if (missing !== undefined)
|
|
1492
|
+
throw new Error(`probe dsh-surface requires ${missing[0]}`);
|
|
1493
|
+
if (!execute)
|
|
1494
|
+
throw new Error('probe dsh-surface requires --execute because third-party code may run');
|
|
1495
|
+
if (process.env.UPSTREAM_RADAR_ISOLATED_RUNNER !== '1') {
|
|
1496
|
+
throw new Error('probe dsh-surface requires UPSTREAM_RADAR_ISOLATED_RUNNER=1 in the disposable environment');
|
|
1497
|
+
}
|
|
1498
|
+
const report = await observeDshPluginSurface({
|
|
1499
|
+
packageSpec,
|
|
1500
|
+
dshVersion: dshVersion,
|
|
1501
|
+
caseId: caseId,
|
|
1502
|
+
sourceCaseId: sourceCaseId,
|
|
1503
|
+
sourceFingerprint: sourceFingerprint,
|
|
1504
|
+
contractFingerprint: contractFingerprint,
|
|
1505
|
+
plane: plane,
|
|
1506
|
+
profile: profile,
|
|
1507
|
+
runtimeId: runtimeId,
|
|
1508
|
+
expectedArtifactSha256: artifactSha256,
|
|
1509
|
+
allowedBuilds,
|
|
1510
|
+
allowExecution: true,
|
|
1511
|
+
isolationProvider: isolationProvider,
|
|
1512
|
+
timeoutMs: timeoutSeconds * 1_000,
|
|
1513
|
+
...(artifactsDirectory === undefined ? {} : { artifactsDirectory }),
|
|
1514
|
+
...(driverRoot === undefined ? {} : { driverRoot }),
|
|
1515
|
+
...(chromiumExecutable === undefined ? {} : { chromiumExecutable }),
|
|
1516
|
+
});
|
|
1517
|
+
if (reportPath !== undefined) {
|
|
1518
|
+
const absoluteReportPath = resolve(reportPath);
|
|
1519
|
+
await mkdir(dirname(absoluteReportPath), { recursive: true });
|
|
1520
|
+
// Surface reports are an explicit hand-off from the unprivileged observer
|
|
1521
|
+
// container to the GitHub runner. They contain bounded compatibility
|
|
1522
|
+
// evidence and no inherited secrets, so the runner must be able to read
|
|
1523
|
+
// and upload them even when the container uses a different uid.
|
|
1524
|
+
await writeFile(absoluteReportPath, `${JSON.stringify(report, null, 2)}\n`, { mode: 0o644 });
|
|
1525
|
+
}
|
|
1526
|
+
process.stdout.write(json ? `${JSON.stringify(report, null, 2)}\n` : renderDshSurfaceObservation(report));
|
|
1527
|
+
return report.result === 'compatible' ? 0 : report.result === 'surface-incompatible' ? 2 : 1;
|
|
1528
|
+
}
|
|
1369
1529
|
async function runDshPluginReview(args) {
|
|
1370
1530
|
if (args[0] !== 'dsh-plugin')
|
|
1371
1531
|
throw new Error('review requires dsh-plugin');
|
|
@@ -1852,6 +2012,7 @@ async function runObserve(args) {
|
|
|
1852
2012
|
let reverseIndexPath;
|
|
1853
2013
|
let registry;
|
|
1854
2014
|
let retryPending = false;
|
|
2015
|
+
let retryPendingOnly = false;
|
|
1855
2016
|
let json = false;
|
|
1856
2017
|
let inlineEcosystem;
|
|
1857
2018
|
let inlineId;
|
|
@@ -1870,6 +2031,9 @@ async function runObserve(args) {
|
|
|
1870
2031
|
else if (argument === '--retry-pending') {
|
|
1871
2032
|
retryPending = true;
|
|
1872
2033
|
}
|
|
2034
|
+
else if (argument === '--retry-pending-only') {
|
|
2035
|
+
retryPendingOnly = true;
|
|
2036
|
+
}
|
|
1873
2037
|
else if (argument === '--ecosystem' || argument === '--id' || argument === '--package' || argument === '--package-path' || argument === '--lockfile' || argument === '--lockfile-type' || argument === '--ref' || argument === '--dsh-version' || argument === '--state' || argument === '--report' || argument === '--reverse-index' || argument === '--dsh-agent-command' || argument === '--dsh-agent-arg' || argument === '--llm-env-file' || argument === '--registry') {
|
|
1874
2038
|
const value = args[index + 1];
|
|
1875
2039
|
if (value === undefined || (value.startsWith('-') && argument !== '--dsh-agent-arg'))
|
|
@@ -1959,10 +2123,17 @@ async function runObserve(args) {
|
|
|
1959
2123
|
if (agentCommand !== undefined && llmEnvFile !== undefined) {
|
|
1960
2124
|
throw new Error('observe accepts either --dsh-agent-command or --llm-env-file, not both');
|
|
1961
2125
|
}
|
|
2126
|
+
if (retryPending && retryPendingOnly) {
|
|
2127
|
+
throw new Error('observe accepts either --retry-pending or --retry-pending-only, not both');
|
|
2128
|
+
}
|
|
2129
|
+
if (retryPendingOnly && agentCommand === undefined && llmEnvFile === undefined) {
|
|
2130
|
+
throw new Error('--retry-pending-only requires --dsh-agent-command or --llm-env-file');
|
|
2131
|
+
}
|
|
1962
2132
|
const result = await runObserver(config, previousState, {
|
|
1963
2133
|
source,
|
|
1964
2134
|
...(reverseDependencyIndex === undefined ? {} : { reverseDependencyIndex }),
|
|
1965
2135
|
retryPending,
|
|
2136
|
+
retryPendingOnly,
|
|
1966
2137
|
artifactReviewer: async (spec, target) => reviewObserverArtifact(spec, target, registry),
|
|
1967
2138
|
...(agentOptions === undefined ? {} : {
|
|
1968
2139
|
agent: (task, prompt) => runDshAgentCommand(task, prompt, agentOptions),
|
|
@@ -1978,10 +2149,11 @@ async function runObserve(args) {
|
|
|
1978
2149
|
}
|
|
1979
2150
|
process.stdout.write(json ? reportJson : renderObserverReport(result.report));
|
|
1980
2151
|
const observerExit = observerExitCode(result.report);
|
|
2152
|
+
const pendingRetryExit = retryPendingOnly && result.report.pendingTasks.length > 0 ? 1 : 0;
|
|
1981
2153
|
if (result.report.agent.failed > 0) {
|
|
1982
|
-
process.stderr.write(
|
|
2154
|
+
process.stderr.write(`upstream-radar: DSH Agent/model analysis remains pending. See the report and rerun with ${retryPendingOnly ? '--retry-pending-only' : '--retry-pending'}.\n`);
|
|
1983
2155
|
}
|
|
1984
|
-
return observerExit;
|
|
2156
|
+
return observerExit === 0 && pendingRetryExit === 0 ? 0 : 1;
|
|
1985
2157
|
}
|
|
1986
2158
|
async function runQuickstart(args) {
|
|
1987
2159
|
let directory = process.cwd();
|