@event4u/agent-config 17.0.0 → 17.1.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/.augment-plugin/marketplace.json +3 -3
- package/.augment-plugin/plugin.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +104 -485
- package/README.md +2 -1
- package/dist/agent-src/contexts/execution/host-capability-manifest.md +5 -3
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +5 -1
- package/dist/cli-delegate/{chunk-IROAQ77A.js → chunk-3PK3VZHB.js} +107 -9
- package/dist/cli-delegate/{chunk-2SFOOFJJ.js → chunk-BZJ4Y3CI.js} +1 -1
- package/dist/cli-delegate/{chunk-CAL76ADI.js → chunk-CMZEKSNN.js} +52 -10
- package/dist/cli-delegate/{chunk-ESUNQ5XR.js → chunk-E3CFULNX.js} +22 -4
- package/dist/cli-delegate/{chunk-GOMILC3O.js → chunk-QBHEI5N4.js} +4 -3
- package/dist/cli-delegate/{chunk-SIOMDAKL.js → chunk-VYZGJLCA.js} +29 -39
- package/dist/cli-delegate/chunk-W5JXMF2T.js +77 -0
- package/dist/cli-delegate/{chunk-4SHNERBL.js → chunk-XIAPY44N.js} +1 -1
- package/dist/cli-delegate/{chunk-JHMMWNJ2.js → chunk-YHAPONWV.js} +1 -1
- package/dist/cli-delegate/cmd_conformance.js +9 -8
- package/dist/cli-delegate/cmd_doctor.js +4 -4
- package/dist/cli-delegate/cmd_doctor_neighbours.js +2 -2
- package/dist/cli-delegate/cmd_explain.js +1 -1
- package/dist/cli-delegate/cmd_export.js +6 -6
- package/dist/cli-delegate/cmd_fleet.js +3 -3
- package/dist/cli-delegate/cmd_preflight.js +3 -3
- package/dist/cli-delegate/cmd_prune.js +6 -6
- package/dist/cli-delegate/cmd_settings_migrate.js +6 -6
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +6 -6
- package/dist/cli-delegate/cmd_uninstall.js +6 -6
- package/dist/cli-delegate/cmd_update.js +9 -13
- package/dist/cli-delegate/cmd_validate.js +6 -6
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +4 -4
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +2 -2
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +2 -2
- package/dist/hooks/dispatch.js +98 -74
- package/dist/hooks/dispatch.sha256 +1 -1
- package/dist/install/claudeRuleRewrite.js +10 -3
- package/dist/install/conflict.js +24 -2
- package/dist/install/conflictTracker.js +14 -3
- package/dist/install/install.mjs +222 -117
- package/dist/install/installThinLayer.js +1 -0
- package/dist/install/loggedWrites.js +142 -0
- package/dist/install/paths.js +12 -2
- package/dist/install/preserve.js +25 -4
- package/dist/install/txlog.js +10 -6
- package/dist/mcp/registry-manifest.json +2 -2
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +845 -294
- package/dist/scripts/_lib/egress_rules.js +4 -1
- package/dist/scripts/_lib/identifier_redaction.js +35 -2
- package/dist/scripts/ai_council/seat_policy.js +7 -1
- package/dist/server/schemas/settings.js +1 -1
- package/package.json +1 -1
- package/src/config/ci-local-parity.yml +1 -1
- package/src/config/gate-coverage.yml +27 -7
- package/src/config/gate-violation-baselines.json +8 -2
- package/src/config/hook-bundle-budget.json +2 -2
- package/src/config/production-entries.json +18 -0
- package/src/config/release-gate-locality.yml +0 -7
- package/src/install/claudeRuleRewrite.ts +10 -1
- package/src/install/conflict.ts +24 -1
- package/src/install/conflictTracker.ts +18 -2
- package/src/install/installThinLayer.ts +6 -0
- package/src/install/loggedWrites.ts +148 -0
- package/src/install/paths.ts +11 -2
- package/src/install/preserve.ts +40 -4
- package/src/install/txlog.ts +10 -6
- package/src/scripts/_cli/cmd_conformance.ts +3 -2
- package/src/scripts/_cli/cmd_update.ts +15 -17
- package/src/scripts/_lib/council_settings_block.ts +9 -2
- package/src/scripts/_lib/egress_rules.ts +4 -1
- package/src/scripts/_lib/host_capability.ts +10 -5
- package/src/scripts/_lib/identifier_redaction.ts +38 -2
- package/src/scripts/_lib/price_freshness.ts +112 -0
- package/src/scripts/_lib/production_reach.ts +194 -0
- package/src/scripts/_lib/quota_parked.ts +17 -28
- package/src/scripts/_lib/release_findings_ingest.ts +13 -335
- package/src/scripts/_lib/tier_downshift_verdict.ts +81 -35
- package/src/scripts/ai_council/chairman.ts +5 -2
- package/src/scripts/ai_council/clients.ts +4 -3
- package/src/scripts/ai_council/free_hand_shadow.ts +24 -12
- package/src/scripts/ai_council/free_route_catalog.ts +142 -5
- package/src/scripts/ai_council/free_route_client.ts +4 -0
- package/src/scripts/ai_council/hand_payload.ts +115 -7
- package/src/scripts/ai_council/orchestrator.ts +7 -10
- package/src/scripts/ai_council/route_chooser.ts +1 -1
- package/src/scripts/ai_council/route_member.ts +66 -4
- package/src/scripts/ai_council/seat_policy.ts +8 -1
- package/src/scripts/ai_council/self_hosted_probe.ts +327 -0
- package/src/scripts/ai_council/status_surface.ts +2 -0
- package/src/scripts/ask_transport.ts +137 -15
- package/src/scripts/check_finding_dispositions.ts +25 -71
- package/src/scripts/check_release_pr_shape.ts +3 -3
- package/src/scripts/check_step_production_reach.ts +257 -0
- package/src/scripts/council_cli.ts +10 -8
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +3 -0
- package/src/scripts/hooks/dispatch_hook.ts +2 -2
- package/src/scripts/hooks/payload_stub.ts +27 -0
- package/src/scripts/hooks/spawn_guard_shadow_hook.ts +29 -70
- package/src/scripts/hooks/subagent_ledger_hook.ts +80 -0
- package/src/scripts/install.ts +2 -2
- package/src/scripts/lint_decision_classes.ts +34 -0
- package/src/scripts/lint_hook_manifest.ts +24 -0
- package/src/scripts/lint_roadmap_blockers.ts +52 -3
- package/src/scripts/release.ts +5 -9
- package/src/scripts/release_drill.ts +11 -165
- package/src/scripts/release_publication.ts +0 -9
- package/src/scripts/report_production_reach.ts +35 -0
- package/src/scripts/worker_reuse_shadow_report.ts +399 -1
- package/src/server/schemas/settings.ts +1 -1
- package/dist/cli-delegate/chunk-A4QJ6ENT.js +0 -50
- /package/dist/cli-delegate/{chunk-E6XNBVE4.js → chunk-KR5ZIFPO.js} +0 -0
|
@@ -202,27 +202,6 @@ interface WorldConfig {
|
|
|
202
202
|
merge_fails_hard?: boolean;
|
|
203
203
|
/** PR checks fail (watch exits non-zero) — the release must die. */
|
|
204
204
|
checks_fail?: boolean;
|
|
205
|
-
/**
|
|
206
|
-
* Step 7's world — two knobs, because the step asks two questions.
|
|
207
|
-
*
|
|
208
|
-
* It VERIFIES: the ledger is produced by the self-review workflow, so the
|
|
209
|
-
* only things a scenario can vary are whether the file is on the remote
|
|
210
|
-
* branch and what the disposition gate answers. An earlier version of this
|
|
211
|
-
* step ingested, and carried four more knobs for run discovery and artifact
|
|
212
|
-
* download; those went with it when the owner moved the ingest into CI.
|
|
213
|
-
*/
|
|
214
|
-
ledger_on_branch?: boolean;
|
|
215
|
-
/**
|
|
216
|
-
* Whether the ledger is on the TRUNK — the ref the merged path asks.
|
|
217
|
-
*
|
|
218
|
-
* Separate from `ledger_on_branch` because the two states worth testing are
|
|
219
|
-
* exactly the ones a single boolean cannot express: present on the branch
|
|
220
|
-
* and not on the trunk, and the reverse. Defaults to `ledger_on_branch`, so
|
|
221
|
-
* every scenario written before this knob keeps its answer.
|
|
222
|
-
*/
|
|
223
|
-
ledger_on_trunk?: boolean;
|
|
224
|
-
/** Exit code + streams the disposition gate answers with. */
|
|
225
|
-
disposition_verdict?: { status: number; stdout: string; stderr: string };
|
|
226
205
|
/**
|
|
227
206
|
* Content `git show <target>:CHANGELOG.md` returns.
|
|
228
207
|
*
|
|
@@ -277,8 +256,7 @@ interface WorldConfig {
|
|
|
277
256
|
tag_already_remote?: boolean;
|
|
278
257
|
/**
|
|
279
258
|
* The release PR is ALREADY merged when the run starts — the real
|
|
280
|
-
* resume-after-merge state, in which steps 1 through
|
|
281
|
-
* verifies the ledger (on the trunk, since the branch is gone) and step 8
|
|
259
|
+
* resume-after-merge state, in which steps 1 through 7 skip and step 8
|
|
282
260
|
* is the first step that does work.
|
|
283
261
|
*
|
|
284
262
|
* Added 2026-09-02 with `guard_release_branch_push`. Before that guard, a
|
|
@@ -383,9 +361,6 @@ class FakeWorld {
|
|
|
383
361
|
private merge_races_once: boolean;
|
|
384
362
|
private merge_fails_hard: boolean;
|
|
385
363
|
private checks_fail: boolean;
|
|
386
|
-
private readonly ledger_on_branch: boolean;
|
|
387
|
-
private readonly ledger_on_trunk: boolean | undefined;
|
|
388
|
-
private readonly disposition_verdict: { status: number; stdout: string; stderr: string };
|
|
389
364
|
private readonly changelog: string;
|
|
390
365
|
/** Working-tree content; see `WorldConfig.changelog_file`. */
|
|
391
366
|
readonly changelog_file: string;
|
|
@@ -410,12 +385,6 @@ class FakeWorld {
|
|
|
410
385
|
this.checks_fail = cfg.checks_fail ?? false;
|
|
411
386
|
this.pr_merged = cfg.pr_already_merged ?? false;
|
|
412
387
|
this.release_verify_fails = cfg.release_verify_fails ?? false;
|
|
413
|
-
// Defaults keep every pre-2026-09-11 scenario green: the ledger is
|
|
414
|
-
// already on the branch and the gate is happy, so step 7 is a two-call
|
|
415
|
-
// no-op and the sequencing scenarios stay about sequencing.
|
|
416
|
-
this.ledger_on_branch = cfg.ledger_on_branch ?? true;
|
|
417
|
-
this.ledger_on_trunk = cfg.ledger_on_trunk;
|
|
418
|
-
this.disposition_verdict = cfg.disposition_verdict ?? { status: 0, stdout: '', stderr: '' };
|
|
419
388
|
}
|
|
420
389
|
|
|
421
390
|
exec(args: readonly string[]): ExecResult {
|
|
@@ -590,21 +559,6 @@ class FakeWorld {
|
|
|
590
559
|
return OK;
|
|
591
560
|
}
|
|
592
561
|
|
|
593
|
-
// Step 7 — the findings ledger.
|
|
594
|
-
if (cmd.startsWith('git cat-file -e ')) {
|
|
595
|
-
// REF-AWARE, because one boolean for every ref made the two states
|
|
596
|
-
// that distinguish right from wrong inexpressible: on the branch
|
|
597
|
-
// but not the trunk, and the reverse. A fourth review named the
|
|
598
|
-
// merged-path scenario as asserting a string in the argv rather
|
|
599
|
-
// than the ref that was read.
|
|
600
|
-
const onTrunk = this.ledger_on_trunk ?? this.ledger_on_branch;
|
|
601
|
-
const present = cmd.includes('/main:') ? onTrunk : this.ledger_on_branch;
|
|
602
|
-
return present ? OK : { ...OK, status: 1 };
|
|
603
|
-
}
|
|
604
|
-
if (cmd.includes('check_finding_dispositions --release')) {
|
|
605
|
-
return { ...this.disposition_verdict };
|
|
606
|
-
}
|
|
607
|
-
|
|
608
562
|
throw new Error(`FakeWorld: unscripted command: ${cmd}`);
|
|
609
563
|
}
|
|
610
564
|
}
|
|
@@ -777,48 +731,20 @@ const SCENARIOS: Record<string, Scenario> = {
|
|
|
777
731
|
},
|
|
778
732
|
},
|
|
779
733
|
|
|
780
|
-
'findings-ledger-
|
|
734
|
+
'no-findings-ledger-does-not-stop-the-release': {
|
|
781
735
|
summary:
|
|
782
|
-
'step 7:
|
|
783
|
-
//
|
|
784
|
-
//
|
|
785
|
-
//
|
|
786
|
-
//
|
|
787
|
-
|
|
788
|
-
// TRUE here, and on a resumed run the PR number is already in hand — so
|
|
789
|
-
// a scenario that kept the default could not see the `--pr` flag being
|
|
790
|
-
// dropped, which is exactly the hole this scenario asserts against.
|
|
791
|
-
config: { ledger_on_branch: true, resume: false },
|
|
736
|
+
'step 7: a release waits for no review ledger — everything on main is already reviewed and merged (owner, 2026-10-22)',
|
|
737
|
+
// The 17.0.0 cut stopped here for a day: a ledger the self-review never
|
|
738
|
+
// finished, on a branch whose every commit had been reviewed on main.
|
|
739
|
+
// The world scripts no ledger command, so reading one would throw;
|
|
740
|
+
// `resume: false` so a first run is covered, not only a resumed one.
|
|
741
|
+
config: { resume: false },
|
|
792
742
|
expect_success: true,
|
|
793
743
|
verify: (w) => {
|
|
794
744
|
const f: string[] = [];
|
|
795
|
-
const probe = w.calls.find((c) => c.startsWith('git cat-file -e '));
|
|
796
|
-
_expect(probe !== undefined, 'the ledger presence was never probed', f);
|
|
797
745
|
_expect(
|
|
798
|
-
(
|
|
799
|
-
|
|
800
|
-
f,
|
|
801
|
-
);
|
|
802
|
-
_expect(
|
|
803
|
-
!w.calls.some((c) => c.includes('--ingest')),
|
|
804
|
-
'step 7 ingested — that belongs to the workflow now, not the release',
|
|
805
|
-
f,
|
|
806
|
-
);
|
|
807
|
-
_expect(
|
|
808
|
-
!w.calls.some((c) => c.startsWith('gh run download')),
|
|
809
|
-
'step 7 downloaded an artifact — the release no longer produces the ledger',
|
|
810
|
-
f,
|
|
811
|
-
);
|
|
812
|
-
// `--pr` is what makes the gate compare the review's own report
|
|
813
|
-
// against the committed ledger. The PR number used to come only
|
|
814
|
-
// from the resume-time probe, so on a FIRST run — this scenario —
|
|
815
|
-
// the flag was silently dropped and the release passed a strictly
|
|
816
|
-
// weaker check than the one it was trying to pre-satisfy.
|
|
817
|
-
_expect(
|
|
818
|
-
w.calls.some(
|
|
819
|
-
(c) => c.includes('check_finding_dispositions --release') && c.includes('--pr '),
|
|
820
|
-
),
|
|
821
|
-
'the disposition gate ran without --pr, so an un-ingested finding would pass here',
|
|
746
|
+
!w.calls.some((c) => c.includes('check_finding_dispositions') || c.startsWith('git cat-file -e ')),
|
|
747
|
+
'the release read the findings ledger',
|
|
822
748
|
f,
|
|
823
749
|
);
|
|
824
750
|
_expect(
|
|
@@ -826,87 +752,7 @@ const SCENARIOS: Record<string, Scenario> = {
|
|
|
826
752
|
'the release never reached the merge',
|
|
827
753
|
f,
|
|
828
754
|
);
|
|
829
|
-
|
|
830
|
-
},
|
|
831
|
-
},
|
|
832
|
-
'findings-ledger-absent-stops-the-release': {
|
|
833
|
-
summary:
|
|
834
|
-
'step 7: no ledger on the remote branch — the release STOPS rather than merging and tagging without one',
|
|
835
|
-
config: { ledger_on_branch: false },
|
|
836
|
-
expect_success: false,
|
|
837
|
-
verify: (w, error) => {
|
|
838
|
-
const f: string[] = [];
|
|
839
|
-
_expect(
|
|
840
|
-
(error ?? '').includes('is not on origin/'),
|
|
841
|
-
`the stop did not name the ref it checked: ${error ?? '(no error)'}`,
|
|
842
|
-
f,
|
|
843
|
-
);
|
|
844
|
-
_expect(
|
|
845
|
-
!w.calls.includes(`gh pr merge ${w.branch} --merge --delete-branch`),
|
|
846
|
-
'merged with no ledger — the failure this step exists to end',
|
|
847
|
-
f,
|
|
848
|
-
);
|
|
849
|
-
_expect(!w.tag_remote, 'tagged with no ledger', f);
|
|
850
|
-
return f;
|
|
851
|
-
},
|
|
852
|
-
},
|
|
853
|
-
'findings-ledger-absent-after-a-hand-merge-still-stops': {
|
|
854
|
-
summary:
|
|
855
|
-
'step 7: the PR is already merged and no ledger reached the trunk — the release STOPS instead of tagging a version whose ledger does not exist',
|
|
856
|
-
// The reachable path to a shipped version with no ledger, and the one
|
|
857
|
-
// the old code asserted away: the ingest produces nothing, step 7
|
|
858
|
-
// stops, a human merges the PR, and the resumed run used to print "the
|
|
859
|
-
// ledger rode in with it" without reading anything.
|
|
860
|
-
// The two knobs differ on purpose: the ledger IS on the release branch
|
|
861
|
-
// and is NOT on the trunk. A run that read the branch ref would pass
|
|
862
|
-
// here, which is the wrong answer — the branch is deleted and the merge
|
|
863
|
-
// is what decides whether the ledger shipped.
|
|
864
|
-
config: { pr_already_merged: true, ledger_on_branch: true, ledger_on_trunk: false },
|
|
865
|
-
expect_success: false,
|
|
866
|
-
verify: (w, error) => {
|
|
867
|
-
const f: string[] = [];
|
|
868
|
-
_expect(
|
|
869
|
-
(error ?? '').includes('already merged'),
|
|
870
|
-
`the stop did not name the merged state: ${error ?? '(no error)'}`,
|
|
871
|
-
f,
|
|
872
|
-
);
|
|
873
|
-
_expect(
|
|
874
|
-
w.calls.some((c) => c.startsWith('git cat-file -e ') && c.includes('/main:')),
|
|
875
|
-
'the merged path never asked the trunk whether the ledger is there',
|
|
876
|
-
f,
|
|
877
|
-
);
|
|
878
|
-
_expect(!w.tag_remote, 'tagged a version whose findings ledger does not exist', f);
|
|
879
|
-
return f;
|
|
880
|
-
},
|
|
881
|
-
},
|
|
882
|
-
'findings-ledger-undispositioned-stops-and-shows-why': {
|
|
883
|
-
summary:
|
|
884
|
-
'step 7: the disposition gate refuses — the release stops and the operator is shown the gate report, not just its scan line',
|
|
885
|
-
config: {
|
|
886
|
-
ledger_on_branch: true,
|
|
887
|
-
disposition_verdict: {
|
|
888
|
-
status: 1,
|
|
889
|
-
stdout: 'scanned: 1',
|
|
890
|
-
stderr: '- `a1` (critical security: x): no disposition status',
|
|
891
|
-
},
|
|
892
|
-
},
|
|
893
|
-
expect_success: false,
|
|
894
|
-
verify: (w, error) => {
|
|
895
|
-
const f: string[] = [];
|
|
896
|
-
// The defect an independent review reproduced: the stop message
|
|
897
|
-
// preferred stdout, so the operator saw `scanned: 1` and the entire
|
|
898
|
-
// per-finding diagnosis — which the gate writes to stderr — was
|
|
899
|
-
// discarded on the one path where the message has to carry content.
|
|
900
|
-
_expect(
|
|
901
|
-
(error ?? '').includes('no disposition status'),
|
|
902
|
-
`the gate's own diagnosis was swallowed: ${error ?? '(no error)'}`,
|
|
903
|
-
f,
|
|
904
|
-
);
|
|
905
|
-
_expect(
|
|
906
|
-
!w.calls.includes(`gh pr merge ${w.branch} --merge --delete-branch`),
|
|
907
|
-
'merged over an undispositioned ledger',
|
|
908
|
-
f,
|
|
909
|
-
);
|
|
755
|
+
_expect(w.tag_remote, 'the release never pushed its tag', f);
|
|
910
756
|
return f;
|
|
911
757
|
},
|
|
912
758
|
},
|
|
@@ -229,15 +229,6 @@ export function _failed_checks_report(names: readonly string[]): string {
|
|
|
229
229
|
'gate output lists the deriving commits (release-truth Phase 2).',
|
|
230
230
|
);
|
|
231
231
|
}
|
|
232
|
-
if (names.includes('Blocking review findings dispositioned')) {
|
|
233
|
-
lines.push(
|
|
234
|
-
'',
|
|
235
|
-
'Dispositions: a blocking/high self-review finding has no committed',
|
|
236
|
-
'disposition. Ingest + adjudicate it in',
|
|
237
|
-
'agents/evidence/release-findings/<version>.json (release-truth Phase 3):',
|
|
238
|
-
' ./scripts-run src/scripts/check_finding_dispositions --ingest <findings.json>',
|
|
239
|
-
);
|
|
240
|
-
}
|
|
241
232
|
lines.push('', 'After fixing, resume with: task release -- --resume --yes', '');
|
|
242
233
|
return lines.join('\n');
|
|
243
234
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Print the production entries and the size and digest of their import closure
|
|
4
|
+
* (road-to-a-tick-the-shipped-path-earns 3.1). Two runs over one tree print the
|
|
5
|
+
* same digest; a moved entry or a new edge changes it.
|
|
6
|
+
*
|
|
7
|
+
* Usage: ./scripts-run src/scripts/report_production_reach [--entries]
|
|
8
|
+
*/
|
|
9
|
+
import { createHash } from 'node:crypto';
|
|
10
|
+
import * as path from 'node:path';
|
|
11
|
+
import { fileURLToPath } from 'node:url';
|
|
12
|
+
|
|
13
|
+
import { productionReach, worktreeOf } from './_lib/production_reach.js';
|
|
14
|
+
|
|
15
|
+
const REPO_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..');
|
|
16
|
+
|
|
17
|
+
export function main(argv: readonly string[]): number {
|
|
18
|
+
const reach = productionReach(worktreeOf(REPO_ROOT));
|
|
19
|
+
const digest = createHash('sha256')
|
|
20
|
+
.update([...reach.modules].sort().join('\n'))
|
|
21
|
+
.update('\0')
|
|
22
|
+
.update([...reach.symbols].sort().join('\n'))
|
|
23
|
+
.digest('hex')
|
|
24
|
+
.slice(0, 16);
|
|
25
|
+
if (argv.includes('--entries')) for (const e of reach.entries) process.stdout.write(`${e}\n`);
|
|
26
|
+
process.stdout.write(
|
|
27
|
+
`production reach: ${reach.entries.size} entries · ${reach.modules.size} modules · ` +
|
|
28
|
+
`${reach.symbols.size} reached symbols · digest ${digest}\n`,
|
|
29
|
+
);
|
|
30
|
+
return 0;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (process.argv[1] !== undefined && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
34
|
+
process.exit(main(process.argv.slice(2)));
|
|
35
|
+
}
|