@unbrained/pm-cli 2026.5.2 → 2026.5.3-6
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/AGENTS.md +8 -1
- package/CHANGELOG.md +58 -0
- package/README.md +9 -1
- package/dist/cli/bootstrap-args.d.ts +18 -0
- package/dist/cli/bootstrap-args.js +242 -0
- package/dist/cli/bootstrap-args.js.map +1 -0
- package/dist/cli/commander-usage.d.ts +17 -0
- package/dist/cli/commander-usage.js +178 -0
- package/dist/cli/commander-usage.js.map +1 -0
- package/dist/cli/commands/activity.js +1 -9
- package/dist/cli/commands/activity.js.map +1 -1
- package/dist/cli/commands/calendar.js +3 -29
- package/dist/cli/commands/calendar.js.map +1 -1
- package/dist/cli/commands/comments.js +1 -9
- package/dist/cli/commands/comments.js.map +1 -1
- package/dist/cli/commands/config.d.ts +21 -3
- package/dist/cli/commands/config.js +118 -2
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/context.d.ts +90 -1
- package/dist/cli/commands/context.js +485 -23
- package/dist/cli/commands/context.js.map +1 -1
- package/dist/cli/commands/dedupe-audit.js +2 -11
- package/dist/cli/commands/dedupe-audit.js.map +1 -1
- package/dist/cli/commands/history.js +1 -9
- package/dist/cli/commands/history.js.map +1 -1
- package/dist/cli/commands/learnings.js +1 -9
- package/dist/cli/commands/learnings.js.map +1 -1
- package/dist/cli/commands/list.js +3 -29
- package/dist/cli/commands/list.js.map +1 -1
- package/dist/cli/commands/normalize.js +9 -6
- package/dist/cli/commands/normalize.js.map +1 -1
- package/dist/cli/commands/notes.js +1 -9
- package/dist/cli/commands/notes.js.map +1 -1
- package/dist/cli/commands/reindex.js +2 -7
- package/dist/cli/commands/reindex.js.map +1 -1
- package/dist/cli/commands/search.js +4 -35
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/commands/test-runs.js +1 -11
- package/dist/cli/commands/test-runs.js.map +1 -1
- package/dist/cli/error-guidance.d.ts +13 -0
- package/dist/cli/error-guidance.js +43 -4
- package/dist/cli/error-guidance.js.map +1 -1
- package/dist/cli/extension-command-help.d.ts +48 -0
- package/dist/cli/extension-command-help.js +389 -0
- package/dist/cli/extension-command-help.js.map +1 -0
- package/dist/cli/help-content.js +9 -3
- package/dist/cli/help-content.js.map +1 -1
- package/dist/cli/help-json-payload.d.ts +25 -0
- package/dist/cli/help-json-payload.js +265 -0
- package/dist/cli/help-json-payload.js.map +1 -0
- package/dist/cli/main.js +996 -4468
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/migration-gates.d.ts +22 -0
- package/dist/cli/migration-gates.js +146 -0
- package/dist/cli/migration-gates.js.map +1 -0
- package/dist/cli/register-list-query.d.ts +2 -0
- package/dist/cli/register-list-query.js +317 -0
- package/dist/cli/register-list-query.js.map +1 -0
- package/dist/cli/register-mutation.d.ts +2 -0
- package/dist/cli/register-mutation.js +795 -0
- package/dist/cli/register-mutation.js.map +1 -0
- package/dist/cli/register-operations.d.ts +2 -0
- package/dist/cli/register-operations.js +610 -0
- package/dist/cli/register-operations.js.map +1 -0
- package/dist/cli/register-setup.d.ts +2 -0
- package/dist/cli/register-setup.js +334 -0
- package/dist/cli/register-setup.js.map +1 -0
- package/dist/cli/registration-helpers.d.ts +53 -0
- package/dist/cli/registration-helpers.js +669 -0
- package/dist/cli/registration-helpers.js.map +1 -0
- package/dist/cli/shared-parsers.d.ts +6 -0
- package/dist/cli/shared-parsers.js +40 -0
- package/dist/cli/shared-parsers.js.map +1 -0
- package/dist/core/search/http-client.d.ts +29 -0
- package/dist/core/search/http-client.js +64 -0
- package/dist/core/search/http-client.js.map +1 -0
- package/dist/core/search/providers.d.ts +3 -13
- package/dist/core/search/providers.js +19 -69
- package/dist/core/search/providers.js.map +1 -1
- package/dist/core/search/semantic-defaults.js +2 -7
- package/dist/core/search/semantic-defaults.js.map +1 -1
- package/dist/core/search/vector-stores.d.ts +3 -13
- package/dist/core/search/vector-stores.js +17 -66
- package/dist/core/search/vector-stores.js.map +1 -1
- package/dist/core/sentry/helpers.d.ts +23 -2
- package/dist/core/sentry/helpers.js +101 -3
- package/dist/core/sentry/helpers.js.map +1 -1
- package/dist/core/sentry/instrument.d.ts +21 -0
- package/dist/core/sentry/instrument.js +34 -3
- package/dist/core/sentry/instrument.js.map +1 -1
- package/dist/core/shared/constants.d.ts +3 -0
- package/dist/core/shared/constants.js +58 -1
- package/dist/core/shared/constants.js.map +1 -1
- package/dist/core/store/front-matter-cache.d.ts +6 -0
- package/dist/core/store/front-matter-cache.js +150 -0
- package/dist/core/store/front-matter-cache.js.map +1 -0
- package/dist/core/store/item-store.js +2 -1
- package/dist/core/store/item-store.js.map +1 -1
- package/dist/core/store/settings.js +36 -0
- package/dist/core/store/settings.js.map +1 -1
- package/dist/core/telemetry/observability.d.ts +24 -0
- package/dist/core/telemetry/observability.js +185 -0
- package/dist/core/telemetry/observability.js.map +1 -0
- package/dist/core/telemetry/runtime.d.ts +27 -3
- package/dist/core/telemetry/runtime.js +298 -13
- package/dist/core/telemetry/runtime.js.map +1 -1
- package/dist/sdk/cli-contracts.js +28 -0
- package/dist/sdk/cli-contracts.js.map +1 -1
- package/dist/types.d.ts +21 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -1
- package/docs/ARCHITECTURE.md +7 -1
- package/docs/COMMANDS.md +11 -1
- package/docs/RELEASING.md +56 -29
- package/package.json +8 -3
package/AGENTS.md
CHANGED
|
@@ -35,7 +35,7 @@ This document defines how coding agents must use `pm` for planning, execution, a
|
|
|
35
35
|
Before creating any new `pm` item, always check for an existing relevant item first.
|
|
36
36
|
|
|
37
37
|
- Search and list existing items before `pm create`:
|
|
38
|
-
- `pm context --limit 10`
|
|
38
|
+
- `pm context --limit 10` (brief snapshot; use `--depth standard` for hierarchy/progress/workload, `--depth deep` for full sections)
|
|
39
39
|
- `pm search "<keywords>" --limit 10`
|
|
40
40
|
- `pm list-open --limit 20`
|
|
41
41
|
- `pm list-in-progress --limit 20`
|
|
@@ -208,6 +208,13 @@ Use release when:
|
|
|
208
208
|
|
|
209
209
|
- Prefer default TOON output for list/search/get in agent loops.
|
|
210
210
|
- Prefer `pm context --limit <n>` as the first triage snapshot when selecting next work.
|
|
211
|
+
- `--depth brief` (default) shows only focus items + agenda -- minimal tokens.
|
|
212
|
+
- `--depth standard` adds hierarchy, activity, progress, and workload sections -- recommended for medium/large projects.
|
|
213
|
+
- `--depth deep` adds blockers, hot files, staleness, and test health -- use for full project orientation or debugging.
|
|
214
|
+
- `--section <name>` (repeatable) overrides `--depth` and includes only named sections (hierarchy, activity, progress, blockers, files, workload, staleness, tests).
|
|
215
|
+
- `--activity-limit <n>` controls recent activity entries (default 10).
|
|
216
|
+
- `--stale-threshold <value>` controls staleness cutoff in days (default 7d).
|
|
217
|
+
- Configure persistent defaults via `pm config project set context --default-depth standard --activity-limit 15`.
|
|
211
218
|
- Use `--json` only when strict machine parsing is required.
|
|
212
219
|
- Request narrow outputs:
|
|
213
220
|
- `--limit`
|
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,64 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2026.5.3-6] - 2026-05-03
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- Added npm/npx/bunx propagation retries to release publication verification so post-publish checks wait for registry availability instead of failing immediately on transient 404 windows.
|
|
14
|
+
|
|
15
|
+
## [2026.5.3-5] - 2026-05-03
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- Hardened release workflow reliability gating so Sentry threshold checks are skipped when the runner does not provide the `sentry` CLI binary, preventing false-negative publish blocks on GitHub-hosted runners.
|
|
19
|
+
|
|
20
|
+
## [2026.5.3-4] - 2026-05-03
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- Relaxed tag release version policy guard in `.github/workflows/release.yml` to validate tag/version consistency without blocking same-day retry tags when a previous tag run failed before npm publication.
|
|
24
|
+
- Hardened `scripts/release/run-release-pipeline.mjs` same-day retry version resolution so local retry cuts always advance beyond the currently checked-out package version when npm has not yet observed failed prior tags.
|
|
25
|
+
|
|
26
|
+
## [2026.5.3-3] - 2026-05-03
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
- Relaxed release compatibility health evaluation so compatibility gating only blocks on failing health checks, not warning-only health states, preventing false negatives on GitHub-hosted release runs.
|
|
30
|
+
|
|
31
|
+
## [2026.5.3-2] - 2026-05-03
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
- Added a scheduled auto-release workflow (`.github/workflows/auto-release.yml`) with one-release-per-UTC-day defaults, manual same-day override controls, and a shared release pipeline driver.
|
|
35
|
+
- Added release automation scripts under `scripts/release/` for changelog promotion, strict static quality checks, temporary-project backward-compatibility validation, Sentry/telemetry threshold gating, unified release gate execution, and full local pipeline orchestration.
|
|
36
|
+
- Added release automation contract coverage in `tests/integration/release-automation-contract.spec.ts`.
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
- Hardened CI, nightly, and release workflows with explicit static quality and compatibility migration gates.
|
|
40
|
+
- Release workflow now verifies published package availability via npm, npx, and bunx, and verifies GitHub release metadata after publication.
|
|
41
|
+
- Expanded release-readiness runtime checks to cover new release scripts, package commands, and auto-release workflow presence.
|
|
42
|
+
|
|
43
|
+
## [2026.5.3] - 2026-05-03
|
|
44
|
+
|
|
45
|
+
### Added
|
|
46
|
+
- Added progressive `pm context` depth, section, activity, staleness, and agenda controls so agents can request brief, standard, deep, or focused project snapshots without broad list scans.
|
|
47
|
+
- Added detailed CLI telemetry error classification for failed command finishes, including normalized `error_code`, `error_category`, and exit-code metadata for telemetry and local OTLP spans.
|
|
48
|
+
- Added regression coverage for bootstrap argument parsing, telemetry classification, Sentry helper filtering, migration gates, context output, and front-matter cache behavior.
|
|
49
|
+
|
|
50
|
+
### Changed
|
|
51
|
+
- Decomposed `src/cli/main.ts` from ~5800 lines into modular command registration files: `register-setup.ts`, `register-list-query.ts`, `register-mutation.ts`, `register-operations.ts`, and shared `registration-helpers.ts`, reducing main.ts to ~2550 lines while preserving all command behavior and help text.
|
|
52
|
+
- Centralized command argument parsing and command registration helpers to reduce CLI surface drift across help, contracts, completion, and runtime telemetry paths.
|
|
53
|
+
- Centralized shared HTTP request handling for embeddings and vector-store providers, reducing duplicated semantic search transport logic.
|
|
54
|
+
- Changed the built-in telemetry capture default from `max` to `redacted` so new installs preserve agent reliability diagnostics without sending local paths or personal identifiers by default.
|
|
55
|
+
- Hardened CI, nightly, and release workflows around the sandboxed test harness and release readiness contracts while preserving the free GitHub Actions release path.
|
|
56
|
+
|
|
57
|
+
### Fixed
|
|
58
|
+
- Hardened Sentry filtering so expected handled CLI usage/validation errors are logged as structured usage signals without reopening Sentry exception groups, while unexpected failures still capture normally.
|
|
59
|
+
- Hardened `pm normalize` closed-item backfill so it satisfies resolution metadata requirements without duplicating potentially sensitive `close_reason` text into new tracked fields.
|
|
60
|
+
|
|
61
|
+
### Performance
|
|
62
|
+
- Added persistent on-disk front-matter cache (`src/core/store/front-matter-cache.ts`) for `listAllFrontMatter` operations, using mtime+size fingerprinting for incremental refresh and context-fingerprint-based invalidation when preferred format or schema changes. Warm `list-open` drops from full-scan to ~60ms for 636-item corpora.
|
|
63
|
+
|
|
64
|
+
### Security
|
|
65
|
+
- Hardened telemetry and Sentry scrubbing so emails, private IPs, absolute local paths, bearer values, and inline credential assignments are redacted even when higher-detail telemetry capture is explicitly selected.
|
|
66
|
+
- Redacted sensitive infrastructure details from tracked project metadata and kept production telemetry/Sentry release audit notes in the ignored private operations area.
|
|
67
|
+
|
|
10
68
|
## [2026.5.2] - 2026-05-02
|
|
11
69
|
|
|
12
70
|
### Changed
|
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
| Settings, storage, search, and output | [Configuration](docs/CONFIGURATION.md) |
|
|
18
18
|
| Safe test execution and linked tests | [Testing](docs/TESTING.md) |
|
|
19
19
|
| Extension authoring | [Extensions](docs/EXTENSIONS.md) and [SDK](docs/SDK.md) |
|
|
20
|
-
| Maintainer release process | [Releasing](docs/RELEASING.md) |
|
|
20
|
+
| Maintainer release process (daily auto-release + local parity) | [Releasing](docs/RELEASING.md) |
|
|
21
21
|
| Contributor internals | [Architecture](docs/ARCHITECTURE.md) |
|
|
22
22
|
|
|
23
23
|
Full documentation starts at [docs/README.md](docs/README.md).
|
|
@@ -76,6 +76,14 @@ pm list-in-progress --limit 20
|
|
|
76
76
|
|
|
77
77
|
If no relevant item exists, create a parent lineage before child work, claim the child item, link changed files/docs/tests, and leave evidence comments before closing. The full workflow is in the [Agent Guide](docs/AGENT_GUIDE.md).
|
|
78
78
|
|
|
79
|
+
## Release Automation
|
|
80
|
+
|
|
81
|
+
- Daily release preparation runs in `.github/workflows/auto-release.yml`.
|
|
82
|
+
- Tag-driven publishing remains in `.github/workflows/release.yml`.
|
|
83
|
+
- Local parity commands:
|
|
84
|
+
- `pnpm release:pipeline:dry-run`
|
|
85
|
+
- `pnpm release:pipeline -- --telemetry-mode required`
|
|
86
|
+
|
|
79
87
|
## Core Model
|
|
80
88
|
|
|
81
89
|
- Items live under `.agents/pm/` as TOON by default, with JSON-front-matter markdown also supported.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface BootstrapGlobalOptions {
|
|
2
|
+
path?: string;
|
|
3
|
+
noExtensions: boolean;
|
|
4
|
+
noPager: boolean;
|
|
5
|
+
json: boolean;
|
|
6
|
+
quiet: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function parseBootstrapGlobalOptions(argv: string[]): BootstrapGlobalOptions;
|
|
9
|
+
export declare function stripGlobalBootstrapTokens(argv: string[]): string[];
|
|
10
|
+
export interface BootstrapHelpRequest {
|
|
11
|
+
requested: boolean;
|
|
12
|
+
commandPathTokens: string[];
|
|
13
|
+
}
|
|
14
|
+
export declare function parseBootstrapHelpRequest(argv: string[]): BootstrapHelpRequest;
|
|
15
|
+
export declare function parseBootstrapCommandName(argv: string[]): string | undefined;
|
|
16
|
+
export declare function applyBootstrapPagerPolicy(argv: string[]): void;
|
|
17
|
+
export declare function normalizeLegacyExtensionActionSyntax(argv: string[]): string[];
|
|
18
|
+
export declare function parseBootstrapTypeValue(argv: string[]): string | undefined;
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
function parseBootstrapPathToken(token, next) {
|
|
2
|
+
if (token === "--path") {
|
|
3
|
+
if (typeof next === "string" && next.length > 0) {
|
|
4
|
+
return {
|
|
5
|
+
consumed: 2,
|
|
6
|
+
pathValue: next,
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
return {
|
|
10
|
+
consumed: 1,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
if (!token.startsWith("--path=")) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
const value = token.slice("--path=".length);
|
|
17
|
+
if (value.length > 0) {
|
|
18
|
+
return {
|
|
19
|
+
consumed: 1,
|
|
20
|
+
pathValue: value,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
consumed: 1,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export function parseBootstrapGlobalOptions(argv) {
|
|
28
|
+
let pathValue;
|
|
29
|
+
let noExtensions = false;
|
|
30
|
+
let noPager = false;
|
|
31
|
+
let json = false;
|
|
32
|
+
let quiet = false;
|
|
33
|
+
let index = 0;
|
|
34
|
+
while (index < argv.length) {
|
|
35
|
+
const token = argv[index];
|
|
36
|
+
if (token === "--") {
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
if (token === "--no-extensions") {
|
|
40
|
+
noExtensions = true;
|
|
41
|
+
index += 1;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (token === "--no-pager") {
|
|
45
|
+
noPager = true;
|
|
46
|
+
index += 1;
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (token === "--json") {
|
|
50
|
+
json = true;
|
|
51
|
+
index += 1;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (token === "--quiet") {
|
|
55
|
+
quiet = true;
|
|
56
|
+
index += 1;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const parsedPath = parseBootstrapPathToken(token, argv[index + 1]);
|
|
60
|
+
if (parsedPath) {
|
|
61
|
+
if (parsedPath.pathValue !== undefined) {
|
|
62
|
+
pathValue = parsedPath.pathValue;
|
|
63
|
+
}
|
|
64
|
+
index += parsedPath.consumed;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
index += 1;
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
path: pathValue,
|
|
71
|
+
noExtensions,
|
|
72
|
+
noPager,
|
|
73
|
+
json,
|
|
74
|
+
quiet,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export function stripGlobalBootstrapTokens(argv) {
|
|
78
|
+
const remaining = [];
|
|
79
|
+
let index = 0;
|
|
80
|
+
while (index < argv.length) {
|
|
81
|
+
const token = argv[index];
|
|
82
|
+
if (token === "--") {
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
if (token === "--json" ||
|
|
86
|
+
token === "--quiet" ||
|
|
87
|
+
token === "--no-extensions" ||
|
|
88
|
+
token === "--no-pager" ||
|
|
89
|
+
token === "--profile" ||
|
|
90
|
+
token === "--explain") {
|
|
91
|
+
index += 1;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (token === "--path") {
|
|
95
|
+
index += 2;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if (token.startsWith("--path=")) {
|
|
99
|
+
index += 1;
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
remaining.push(token);
|
|
103
|
+
index += 1;
|
|
104
|
+
}
|
|
105
|
+
return remaining;
|
|
106
|
+
}
|
|
107
|
+
export function parseBootstrapHelpRequest(argv) {
|
|
108
|
+
const stripped = stripGlobalBootstrapTokens(argv);
|
|
109
|
+
const first = stripped[0]?.trim().toLowerCase();
|
|
110
|
+
if (first === "help") {
|
|
111
|
+
const commandPathTokens = [];
|
|
112
|
+
for (let index = 1; index < stripped.length; index += 1) {
|
|
113
|
+
const token = stripped[index];
|
|
114
|
+
if (token.startsWith("-")) {
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
commandPathTokens.push(token.trim().toLowerCase());
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
requested: true,
|
|
121
|
+
commandPathTokens,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
const helpFlagIndex = stripped.findIndex((token) => token === "--help" || token === "-h");
|
|
125
|
+
if (helpFlagIndex < 0) {
|
|
126
|
+
return {
|
|
127
|
+
requested: false,
|
|
128
|
+
commandPathTokens: [],
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
const commandPathTokens = [];
|
|
132
|
+
for (const token of stripped) {
|
|
133
|
+
if (token.startsWith("-")) {
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
commandPathTokens.push(token.trim().toLowerCase());
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
requested: true,
|
|
140
|
+
commandPathTokens,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
export function parseBootstrapCommandName(argv) {
|
|
144
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
145
|
+
const token = argv[index];
|
|
146
|
+
if (token === "--") {
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
if (token === "--path") {
|
|
150
|
+
index += 1;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
if (token.startsWith("--path=") ||
|
|
154
|
+
token === "--json" ||
|
|
155
|
+
token === "--quiet" ||
|
|
156
|
+
token === "--no-extensions" ||
|
|
157
|
+
token === "--no-pager" ||
|
|
158
|
+
token === "--profile" ||
|
|
159
|
+
token === "--explain") {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
if (token.startsWith("-")) {
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
return token.trim().toLowerCase();
|
|
166
|
+
}
|
|
167
|
+
return undefined;
|
|
168
|
+
}
|
|
169
|
+
function shouldDisablePagerForInvocation(argv, bootstrapGlobal) {
|
|
170
|
+
if (bootstrapGlobal.noPager) {
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
if (process.stdout.isTTY === true) {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
const helpRequest = parseBootstrapHelpRequest(argv);
|
|
177
|
+
return helpRequest.requested;
|
|
178
|
+
}
|
|
179
|
+
export function applyBootstrapPagerPolicy(argv) {
|
|
180
|
+
const bootstrapGlobal = parseBootstrapGlobalOptions(argv);
|
|
181
|
+
if (!shouldDisablePagerForInvocation(argv, bootstrapGlobal)) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
process.env.PAGER = "cat";
|
|
185
|
+
process.env.MANPAGER = "cat";
|
|
186
|
+
process.env.GIT_PAGER = "cat";
|
|
187
|
+
if (typeof process.env.LESS !== "string" || process.env.LESS.trim().length === 0) {
|
|
188
|
+
process.env.LESS = "FRX";
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
const EXTENSION_ACTION_SYNTAX_TOKENS = new Set([
|
|
192
|
+
"install",
|
|
193
|
+
"uninstall",
|
|
194
|
+
"explore",
|
|
195
|
+
"manage",
|
|
196
|
+
"doctor",
|
|
197
|
+
"adopt",
|
|
198
|
+
"adopt-all",
|
|
199
|
+
"activate",
|
|
200
|
+
"deactivate",
|
|
201
|
+
]);
|
|
202
|
+
export function normalizeLegacyExtensionActionSyntax(argv) {
|
|
203
|
+
const extensionIndex = argv.findIndex((token) => token === "extension");
|
|
204
|
+
if (extensionIndex < 0) {
|
|
205
|
+
return [...argv];
|
|
206
|
+
}
|
|
207
|
+
const actionToken = argv[extensionIndex + 1];
|
|
208
|
+
if (!actionToken || actionToken.startsWith("-")) {
|
|
209
|
+
return [...argv];
|
|
210
|
+
}
|
|
211
|
+
if (!EXTENSION_ACTION_SYNTAX_TOKENS.has(actionToken)) {
|
|
212
|
+
return [...argv];
|
|
213
|
+
}
|
|
214
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
215
|
+
return [...argv];
|
|
216
|
+
}
|
|
217
|
+
const forcedActionFlag = `--${actionToken}`;
|
|
218
|
+
if (argv.includes(forcedActionFlag)) {
|
|
219
|
+
return [...argv];
|
|
220
|
+
}
|
|
221
|
+
return [...argv.slice(0, extensionIndex + 1), forcedActionFlag, ...argv.slice(extensionIndex + 2)];
|
|
222
|
+
}
|
|
223
|
+
export function parseBootstrapTypeValue(argv) {
|
|
224
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
225
|
+
const token = argv[index];
|
|
226
|
+
if (token === "--type") {
|
|
227
|
+
const candidate = argv[index + 1];
|
|
228
|
+
if (typeof candidate === "string" && candidate.trim().length > 0) {
|
|
229
|
+
return candidate.trim();
|
|
230
|
+
}
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (token.startsWith("--type=")) {
|
|
234
|
+
const candidate = token.slice("--type=".length).trim();
|
|
235
|
+
if (candidate.length > 0) {
|
|
236
|
+
return candidate;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return undefined;
|
|
241
|
+
}
|
|
242
|
+
//# sourceMappingURL=bootstrap-args.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap-args.js","sourceRoot":"/","sources":["cli/bootstrap-args.ts"],"names":[],"mappings":"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","sourcesContent":["function parseBootstrapPathToken(\n token: string,\n next: string | undefined,\n): { consumed: number; pathValue?: string } | null {\n if (token === \"--path\") {\n if (typeof next === \"string\" && next.length > 0) {\n return {\n consumed: 2,\n pathValue: next,\n };\n }\n return {\n consumed: 1,\n };\n }\n\n if (!token.startsWith(\"--path=\")) {\n return null;\n }\n\n const value = token.slice(\"--path=\".length);\n if (value.length > 0) {\n return {\n consumed: 1,\n pathValue: value,\n };\n }\n return {\n consumed: 1,\n };\n}\n\nexport interface BootstrapGlobalOptions {\n path?: string;\n noExtensions: boolean;\n noPager: boolean;\n json: boolean;\n quiet: boolean;\n}\n\nexport function parseBootstrapGlobalOptions(argv: string[]): BootstrapGlobalOptions {\n let pathValue: string | undefined;\n let noExtensions = false;\n let noPager = false;\n let json = false;\n let quiet = false;\n let index = 0;\n while (index < argv.length) {\n const token = argv[index];\n if (token === \"--\") {\n break;\n }\n if (token === \"--no-extensions\") {\n noExtensions = true;\n index += 1;\n continue;\n }\n if (token === \"--no-pager\") {\n noPager = true;\n index += 1;\n continue;\n }\n if (token === \"--json\") {\n json = true;\n index += 1;\n continue;\n }\n if (token === \"--quiet\") {\n quiet = true;\n index += 1;\n continue;\n }\n const parsedPath = parseBootstrapPathToken(token, argv[index + 1]);\n if (parsedPath) {\n if (parsedPath.pathValue !== undefined) {\n pathValue = parsedPath.pathValue;\n }\n index += parsedPath.consumed;\n continue;\n }\n index += 1;\n }\n return {\n path: pathValue,\n noExtensions,\n noPager,\n json,\n quiet,\n };\n}\n\nexport function stripGlobalBootstrapTokens(argv: string[]): string[] {\n const remaining: string[] = [];\n let index = 0;\n while (index < argv.length) {\n const token = argv[index];\n if (token === \"--\") {\n break;\n }\n if (\n token === \"--json\" ||\n token === \"--quiet\" ||\n token === \"--no-extensions\" ||\n token === \"--no-pager\" ||\n token === \"--profile\" ||\n token === \"--explain\"\n ) {\n index += 1;\n continue;\n }\n if (token === \"--path\") {\n index += 2;\n continue;\n }\n if (token.startsWith(\"--path=\")) {\n index += 1;\n continue;\n }\n remaining.push(token);\n index += 1;\n }\n return remaining;\n}\n\nexport interface BootstrapHelpRequest {\n requested: boolean;\n commandPathTokens: string[];\n}\n\nexport function parseBootstrapHelpRequest(argv: string[]): BootstrapHelpRequest {\n const stripped = stripGlobalBootstrapTokens(argv);\n const first = stripped[0]?.trim().toLowerCase();\n if (first === \"help\") {\n const commandPathTokens: string[] = [];\n for (let index = 1; index < stripped.length; index += 1) {\n const token = stripped[index];\n if (token.startsWith(\"-\")) {\n break;\n }\n commandPathTokens.push(token.trim().toLowerCase());\n }\n return {\n requested: true,\n commandPathTokens,\n };\n }\n\n const helpFlagIndex = stripped.findIndex((token) => token === \"--help\" || token === \"-h\");\n if (helpFlagIndex < 0) {\n return {\n requested: false,\n commandPathTokens: [],\n };\n }\n\n const commandPathTokens: string[] = [];\n for (const token of stripped) {\n if (token.startsWith(\"-\")) {\n break;\n }\n commandPathTokens.push(token.trim().toLowerCase());\n }\n return {\n requested: true,\n commandPathTokens,\n };\n}\n\nexport function parseBootstrapCommandName(argv: string[]): string | undefined {\n for (let index = 0; index < argv.length; index += 1) {\n const token = argv[index];\n if (token === \"--\") {\n break;\n }\n if (token === \"--path\") {\n index += 1;\n continue;\n }\n if (\n token.startsWith(\"--path=\") ||\n token === \"--json\" ||\n token === \"--quiet\" ||\n token === \"--no-extensions\" ||\n token === \"--no-pager\" ||\n token === \"--profile\" ||\n token === \"--explain\"\n ) {\n continue;\n }\n if (token.startsWith(\"-\")) {\n continue;\n }\n return token.trim().toLowerCase();\n }\n return undefined;\n}\n\nfunction shouldDisablePagerForInvocation(argv: string[], bootstrapGlobal: BootstrapGlobalOptions): boolean {\n if (bootstrapGlobal.noPager) {\n return true;\n }\n if (process.stdout.isTTY === true) {\n return false;\n }\n const helpRequest = parseBootstrapHelpRequest(argv);\n return helpRequest.requested;\n}\n\nexport function applyBootstrapPagerPolicy(argv: string[]): void {\n const bootstrapGlobal = parseBootstrapGlobalOptions(argv);\n if (!shouldDisablePagerForInvocation(argv, bootstrapGlobal)) {\n return;\n }\n process.env.PAGER = \"cat\";\n process.env.MANPAGER = \"cat\";\n process.env.GIT_PAGER = \"cat\";\n if (typeof process.env.LESS !== \"string\" || process.env.LESS.trim().length === 0) {\n process.env.LESS = \"FRX\";\n }\n}\n\ntype ExtensionSubcommandAction =\n | \"init\"\n | \"install\"\n | \"uninstall\"\n | \"explore\"\n | \"manage\"\n | \"doctor\"\n | \"adopt\"\n | \"adopt-all\"\n | \"activate\"\n | \"deactivate\";\n\nconst EXTENSION_ACTION_SYNTAX_TOKENS = new Set<ExtensionSubcommandAction>([\n \"install\",\n \"uninstall\",\n \"explore\",\n \"manage\",\n \"doctor\",\n \"adopt\",\n \"adopt-all\",\n \"activate\",\n \"deactivate\",\n]);\n\nexport function normalizeLegacyExtensionActionSyntax(argv: string[]): string[] {\n const extensionIndex = argv.findIndex((token) => token === \"extension\");\n if (extensionIndex < 0) {\n return [...argv];\n }\n const actionToken = argv[extensionIndex + 1];\n if (!actionToken || actionToken.startsWith(\"-\")) {\n return [...argv];\n }\n if (!EXTENSION_ACTION_SYNTAX_TOKENS.has(actionToken as ExtensionSubcommandAction)) {\n return [...argv];\n }\n if (argv.includes(\"--help\") || argv.includes(\"-h\")) {\n return [...argv];\n }\n const forcedActionFlag = `--${actionToken}`;\n if (argv.includes(forcedActionFlag)) {\n return [...argv];\n }\n return [...argv.slice(0, extensionIndex + 1), forcedActionFlag, ...argv.slice(extensionIndex + 2)];\n}\n\nexport function parseBootstrapTypeValue(argv: string[]): string | undefined {\n for (let index = 0; index < argv.length; index += 1) {\n const token = argv[index];\n if (token === \"--type\") {\n const candidate = argv[index + 1];\n if (typeof candidate === \"string\" && candidate.trim().length > 0) {\n return candidate.trim();\n }\n continue;\n }\n if (token.startsWith(\"--type=\")) {\n const candidate = token.slice(\"--type=\".length).trim();\n if (candidate.length > 0) {\n return candidate;\n }\n }\n }\n return undefined;\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { type CommanderGuidanceContext } from "./error-guidance.js";
|
|
3
|
+
import type { ExtensionCommandHelpDescriptor } from "./extension-command-help.js";
|
|
4
|
+
export declare const BUILTIN_TYPE_HELP_VALUES: string;
|
|
5
|
+
export interface CommanderUsageContext extends CommanderGuidanceContext {
|
|
6
|
+
message: string;
|
|
7
|
+
commandName: string | undefined;
|
|
8
|
+
allowedTypes: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function collectRuntimeCommandPaths(root: Command, extensionDescriptors: ReadonlyMap<string, ExtensionCommandHelpDescriptor>): string[];
|
|
11
|
+
export declare function scoreCommandPathMatch(commandPath: string, queryToken: string): number;
|
|
12
|
+
export declare function buildUnknownCommandGuidanceFromRuntime(rawMessage: string, root: Command, extensionDescriptors: ReadonlyMap<string, ExtensionCommandHelpDescriptor>): CommanderGuidanceContext | undefined;
|
|
13
|
+
export declare function resolveChildCommandByToken(parent: Command, token: string): Command | undefined;
|
|
14
|
+
export declare function isKnownHelpCommandPath(root: Command, commandPathTokens: string[]): boolean;
|
|
15
|
+
export declare function resolveCommanderUsageContext(error: unknown, rootProgram: Command, extensionDescriptors: ReadonlyMap<string, ExtensionCommandHelpDescriptor>): Promise<CommanderUsageContext>;
|
|
16
|
+
export declare function formatCommanderUsageMessage(error: unknown, rootProgram: Command, extensionDescriptors: ReadonlyMap<string, ExtensionCommandHelpDescriptor>): Promise<string>;
|
|
17
|
+
export declare function formatCommanderUsageJson(error: unknown, rootProgram: Command, extensionDescriptors: ReadonlyMap<string, ExtensionCommandHelpDescriptor>): Promise<string>;
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { pathExists } from "../core/fs/fs-utils.js";
|
|
2
|
+
import { resolveItemTypeRegistry } from "../core/item/type-registry.js";
|
|
3
|
+
import { EXIT_CODE } from "../core/shared/constants.js";
|
|
4
|
+
import { getSettingsPath, resolvePmRoot } from "../core/store/paths.js";
|
|
5
|
+
import { readSettings } from "../core/store/settings.js";
|
|
6
|
+
import { BUILTIN_ITEM_TYPE_VALUES } from "../types/index.js";
|
|
7
|
+
import { getActiveExtensionRegistrations, runActiveServiceOverride, } from "../core/extensions/index.js";
|
|
8
|
+
import { formatCommanderErrorForDisplay, formatCommanderErrorForJson, } from "./error-guidance.js";
|
|
9
|
+
import { normalizeHelpCommandPath } from "./help-content.js";
|
|
10
|
+
import { getCommandPath } from "./registration-helpers.js";
|
|
11
|
+
import { normalizeLegacyExtensionActionSyntax, parseBootstrapGlobalOptions, parseBootstrapCommandName, } from "./bootstrap-args.js";
|
|
12
|
+
export const BUILTIN_TYPE_HELP_VALUES = BUILTIN_ITEM_TYPE_VALUES.join("|");
|
|
13
|
+
export function collectRuntimeCommandPaths(root, extensionDescriptors) {
|
|
14
|
+
const commandPaths = new Set();
|
|
15
|
+
const queue = [...root.commands];
|
|
16
|
+
while (queue.length > 0) {
|
|
17
|
+
const current = queue.shift();
|
|
18
|
+
if (!current) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const normalizedPath = normalizeHelpCommandPath(getCommandPath(current));
|
|
22
|
+
const hasInternalSegment = normalizedPath.split(" ").some((segment) => segment.startsWith("_"));
|
|
23
|
+
if (normalizedPath.length > 0 && !hasInternalSegment) {
|
|
24
|
+
commandPaths.add(normalizedPath);
|
|
25
|
+
}
|
|
26
|
+
queue.push(...current.commands);
|
|
27
|
+
}
|
|
28
|
+
for (const descriptorPath of extensionDescriptors.keys()) {
|
|
29
|
+
const normalizedPath = normalizeHelpCommandPath(descriptorPath);
|
|
30
|
+
const hasInternalSegment = normalizedPath.split(" ").some((segment) => segment.startsWith("_"));
|
|
31
|
+
if (normalizedPath.length > 0 && !hasInternalSegment) {
|
|
32
|
+
commandPaths.add(normalizedPath);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return [...commandPaths].sort((left, right) => left.localeCompare(right));
|
|
36
|
+
}
|
|
37
|
+
export function scoreCommandPathMatch(commandPath, queryToken) {
|
|
38
|
+
const normalizedPath = commandPath.trim().toLowerCase();
|
|
39
|
+
const normalizedToken = queryToken.trim().toLowerCase();
|
|
40
|
+
if (normalizedToken.length === 0) {
|
|
41
|
+
return Number.POSITIVE_INFINITY;
|
|
42
|
+
}
|
|
43
|
+
const pathSegments = normalizedPath.split(" ");
|
|
44
|
+
if (normalizedPath === normalizedToken) {
|
|
45
|
+
return 0;
|
|
46
|
+
}
|
|
47
|
+
if (pathSegments.includes(normalizedToken)) {
|
|
48
|
+
return 1;
|
|
49
|
+
}
|
|
50
|
+
if (pathSegments.some((segment) => segment.startsWith(normalizedToken))) {
|
|
51
|
+
return 2;
|
|
52
|
+
}
|
|
53
|
+
if (normalizedPath.includes(normalizedToken)) {
|
|
54
|
+
return 3;
|
|
55
|
+
}
|
|
56
|
+
return Number.POSITIVE_INFINITY;
|
|
57
|
+
}
|
|
58
|
+
export function buildUnknownCommandGuidanceFromRuntime(rawMessage, root, extensionDescriptors) {
|
|
59
|
+
const unknownCommandMatch = rawMessage.match(/unknown command '([^']+)'/i);
|
|
60
|
+
if (!unknownCommandMatch || typeof unknownCommandMatch[1] !== "string") {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
const normalizedUnknown = normalizeHelpCommandPath(unknownCommandMatch[1]);
|
|
64
|
+
if (normalizedUnknown.length === 0) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
const commandPaths = collectRuntimeCommandPaths(root, extensionDescriptors);
|
|
68
|
+
if (commandPaths.length === 0) {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
const primaryToken = normalizedUnknown.split(" ")[0] ?? normalizedUnknown;
|
|
72
|
+
const rankedCandidates = commandPaths
|
|
73
|
+
.map((commandPath) => {
|
|
74
|
+
const directScore = scoreCommandPathMatch(commandPath, normalizedUnknown);
|
|
75
|
+
const fallbackScore = primaryToken !== normalizedUnknown ? scoreCommandPathMatch(commandPath, primaryToken) : Number.POSITIVE_INFINITY;
|
|
76
|
+
const score = Math.min(directScore, fallbackScore);
|
|
77
|
+
return { commandPath, score };
|
|
78
|
+
})
|
|
79
|
+
.filter((entry) => Number.isFinite(entry.score))
|
|
80
|
+
.sort((left, right) => {
|
|
81
|
+
if (left.score !== right.score) {
|
|
82
|
+
return left.score - right.score;
|
|
83
|
+
}
|
|
84
|
+
return left.commandPath.localeCompare(right.commandPath);
|
|
85
|
+
})
|
|
86
|
+
.map((entry) => entry.commandPath);
|
|
87
|
+
const fallbackTopLevel = [...new Set(commandPaths.map((commandPath) => commandPath.split(" ")[0]).filter((segment) => segment.length > 0))];
|
|
88
|
+
fallbackTopLevel.sort((left, right) => left.localeCompare(right));
|
|
89
|
+
const suggestedPaths = (rankedCandidates.length > 0 ? rankedCandidates : fallbackTopLevel).slice(0, 3);
|
|
90
|
+
const examples = [...new Set(["pm --help", ...suggestedPaths.map((path) => `pm ${path} --help`)])];
|
|
91
|
+
return {
|
|
92
|
+
unknownCommandExamples: examples,
|
|
93
|
+
unknownCommandNextSteps: [
|
|
94
|
+
'Run "pm --help" to list commands available in this runtime, including active extensions.',
|
|
95
|
+
"Use one of the suggested command paths above with --help to inspect valid flags and usage.",
|
|
96
|
+
],
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
export function resolveChildCommandByToken(parent, token) {
|
|
100
|
+
const normalizedToken = token.trim().toLowerCase();
|
|
101
|
+
return parent.commands.find((candidate) => {
|
|
102
|
+
if (candidate.name().trim().toLowerCase() === normalizedToken) {
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
const aliases = typeof candidate.aliases === "function" ? candidate.aliases() : [];
|
|
106
|
+
return aliases.some((alias) => alias.trim().toLowerCase() === normalizedToken);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
export function isKnownHelpCommandPath(root, commandPathTokens) {
|
|
110
|
+
if (commandPathTokens.length === 0) {
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
let current = root;
|
|
114
|
+
let matchedAny = false;
|
|
115
|
+
for (const token of commandPathTokens) {
|
|
116
|
+
const next = resolveChildCommandByToken(current, token);
|
|
117
|
+
if (!next) {
|
|
118
|
+
return matchedAny;
|
|
119
|
+
}
|
|
120
|
+
matchedAny = true;
|
|
121
|
+
current = next;
|
|
122
|
+
}
|
|
123
|
+
return matchedAny;
|
|
124
|
+
}
|
|
125
|
+
export async function resolveCommanderUsageContext(error, rootProgram, extensionDescriptors) {
|
|
126
|
+
const rawMessage = typeof error === "object" && error !== null ? error.message : undefined;
|
|
127
|
+
const message = rawMessage ?? "Invalid command usage";
|
|
128
|
+
const invocationArgv = normalizeLegacyExtensionActionSyntax(process.argv.slice(2));
|
|
129
|
+
const bootstrapGlobal = parseBootstrapGlobalOptions(invocationArgv);
|
|
130
|
+
const commandName = parseBootstrapCommandName(invocationArgv);
|
|
131
|
+
let allowedTypes = BUILTIN_TYPE_HELP_VALUES;
|
|
132
|
+
try {
|
|
133
|
+
const pmRoot = resolvePmRoot(process.cwd(), bootstrapGlobal.path);
|
|
134
|
+
if (await pathExists(getSettingsPath(pmRoot))) {
|
|
135
|
+
const settings = await readSettings(pmRoot);
|
|
136
|
+
const typeRegistry = resolveItemTypeRegistry(settings, getActiveExtensionRegistrations());
|
|
137
|
+
if (typeRegistry.types.length > 0) {
|
|
138
|
+
allowedTypes = typeRegistry.types.join("|");
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
// Fall back to built-in type guidance when settings cannot be read.
|
|
144
|
+
}
|
|
145
|
+
const unknownCommandGuidance = buildUnknownCommandGuidanceFromRuntime(message, rootProgram, extensionDescriptors);
|
|
146
|
+
return {
|
|
147
|
+
message,
|
|
148
|
+
commandName,
|
|
149
|
+
allowedTypes,
|
|
150
|
+
...(unknownCommandGuidance ?? {}),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
export async function formatCommanderUsageMessage(error, rootProgram, extensionDescriptors) {
|
|
154
|
+
const usageContext = await resolveCommanderUsageContext(error, rootProgram, extensionDescriptors);
|
|
155
|
+
const { message, commandName, allowedTypes, unknownCommandExamples, unknownCommandNextSteps } = usageContext;
|
|
156
|
+
const formatted = formatCommanderErrorForDisplay(message, commandName, allowedTypes, {
|
|
157
|
+
unknownCommandExamples,
|
|
158
|
+
unknownCommandNextSteps,
|
|
159
|
+
});
|
|
160
|
+
const serviceOverride = await runActiveServiceOverride("help_format", {
|
|
161
|
+
message: formatted,
|
|
162
|
+
command: commandName,
|
|
163
|
+
allowed_types: allowedTypes,
|
|
164
|
+
});
|
|
165
|
+
if (serviceOverride.handled && typeof serviceOverride.result === "string") {
|
|
166
|
+
return serviceOverride.result;
|
|
167
|
+
}
|
|
168
|
+
return formatted;
|
|
169
|
+
}
|
|
170
|
+
export async function formatCommanderUsageJson(error, rootProgram, extensionDescriptors) {
|
|
171
|
+
const usageContext = await resolveCommanderUsageContext(error, rootProgram, extensionDescriptors);
|
|
172
|
+
const envelope = formatCommanderErrorForJson(usageContext.message, usageContext.commandName, usageContext.allowedTypes, EXIT_CODE.USAGE, {
|
|
173
|
+
unknownCommandExamples: usageContext.unknownCommandExamples,
|
|
174
|
+
unknownCommandNextSteps: usageContext.unknownCommandNextSteps,
|
|
175
|
+
});
|
|
176
|
+
return JSON.stringify(envelope, null, 2);
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=commander-usage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commander-usage.js","sourceRoot":"/","sources":["cli/commander-usage.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EACL,+BAA+B,EAC/B,wBAAwB,GACzB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAEL,8BAA8B,EAC9B,2BAA2B,GAC5B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EACL,oCAAoC,EACpC,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,qBAAqB,CAAC;AAG7B,MAAM,CAAC,MAAM,wBAAwB,GAAG,wBAAwB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAQ3E,MAAM,UAAU,0BAA0B,CACxC,IAAa,EACb,oBAAyE;IAEzE,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IACvC,MAAM,KAAK,GAAc,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC5C,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;QAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,SAAS;QACX,CAAC;QACD,MAAM,cAAc,GAAG,wBAAwB,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;QACzE,MAAM,kBAAkB,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;QAChG,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACrD,YAAY,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QACnC,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAClC,CAAC;IACD,KAAK,MAAM,cAAc,IAAI,oBAAoB,CAAC,IAAI,EAAE,EAAE,CAAC;QACzD,MAAM,cAAc,GAAG,wBAAwB,CAAC,cAAc,CAAC,CAAC;QAChE,MAAM,kBAAkB,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;QAChG,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACrD,YAAY,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,WAAmB,EAAE,UAAkB;IAC3E,MAAM,cAAc,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACxD,MAAM,eAAe,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACxD,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,MAAM,CAAC,iBAAiB,CAAC;IAClC,CAAC;IACD,MAAM,YAAY,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/C,IAAI,cAAc,KAAK,eAAe,EAAE,CAAC;QACvC,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,YAAY,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;QAC3C,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC;QACxE,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,cAAc,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;QAC7C,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,MAAM,CAAC,iBAAiB,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,sCAAsC,CACpD,UAAkB,EAClB,IAAa,EACb,oBAAyE;IAEzE,MAAM,mBAAmB,GAAG,UAAU,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAC3E,IAAI,CAAC,mBAAmB,IAAI,OAAO,mBAAmB,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;QACvE,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,iBAAiB,GAAG,wBAAwB,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3E,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,YAAY,GAAG,0BAA0B,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;IAC5E,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,YAAY,GAAG,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,iBAAiB,CAAC;IAC1E,MAAM,gBAAgB,GAAG,YAAY;SAClC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE;QACnB,MAAM,WAAW,GAAG,qBAAqB,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAC1E,MAAM,aAAa,GACjB,YAAY,KAAK,iBAAiB,CAAC,CAAC,CAAC,qBAAqB,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC;QACnH,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;QACnD,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;IAChC,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;SAC/C,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QAClC,CAAC;QACD,OAAO,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC3D,CAAC,CAAC;SACD,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAErC,MAAM,gBAAgB,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5I,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;IAClE,MAAM,cAAc,GAAG,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACvG,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAEnG,OAAO;QACL,sBAAsB,EAAE,QAAQ;QAChC,uBAAuB,EAAE;YACvB,0FAA0F;YAC1F,4FAA4F;SAC7F;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,MAAe,EAAE,KAAa;IACvE,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACnD,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE;QACxC,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,eAAe,EAAE,CAAC;YAC9D,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,SAAS,CAAC,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnF,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,eAAe,CAAC,CAAC;IACjF,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,IAAa,EAAE,iBAA2B;IAC/E,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,KAAK,MAAM,KAAK,IAAI,iBAAiB,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,0BAA0B,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACxD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,UAAU,CAAC;QACpB,CAAC;QACD,UAAU,GAAG,IAAI,CAAC;QAClB,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,KAAc,EACd,WAAoB,EACpB,oBAAyE;IAEzE,MAAM,UAAU,GAAG,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAE,KAA8B,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IACrH,MAAM,OAAO,GAAG,UAAU,IAAI,uBAAuB,CAAC;IACtD,MAAM,cAAc,GAAG,oCAAoC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACnF,MAAM,eAAe,GAAG,2BAA2B,CAAC,cAAc,CAAC,CAAC;IACpE,MAAM,WAAW,GAAG,yBAAyB,CAAC,cAAc,CAAC,CAAC;IAC9D,IAAI,YAAY,GAAG,wBAAwB,CAAC;IAC5C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,CAAC,IAAI,CAAC,CAAC;QAClE,IAAI,MAAM,UAAU,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;YAC9C,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;YAC5C,MAAM,YAAY,GAAG,uBAAuB,CAAC,QAAQ,EAAE,+BAA+B,EAAE,CAAC,CAAC;YAC1F,IAAI,YAAY,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAClC,YAAY,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,oEAAoE;IACtE,CAAC;IACD,MAAM,sBAAsB,GAAG,sCAAsC,CAAC,OAAO,EAAE,WAAW,EAAE,oBAAoB,CAAC,CAAC;IAClH,OAAO;QACL,OAAO;QACP,WAAW;QACX,YAAY;QACZ,GAAG,CAAC,sBAAsB,IAAI,EAAE,CAAC;KAClC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,KAAc,EACd,WAAoB,EACpB,oBAAyE;IAEzE,MAAM,YAAY,GAAG,MAAM,4BAA4B,CAAC,KAAK,EAAE,WAAW,EAAE,oBAAoB,CAAC,CAAC;IAClG,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,GAAG,YAAY,CAAC;IAC7G,MAAM,SAAS,GAAG,8BAA8B,CAAC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE;QACnF,sBAAsB;QACtB,uBAAuB;KACxB,CAAC,CAAC;IACH,MAAM,eAAe,GAAG,MAAM,wBAAwB,CAAC,aAAa,EAAE;QACpE,OAAO,EAAE,SAAS;QAClB,OAAO,EAAE,WAAW;QACpB,aAAa,EAAE,YAAY;KAC5B,CAAC,CAAC;IACH,IAAI,eAAe,CAAC,OAAO,IAAI,OAAO,eAAe,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC1E,OAAO,eAAe,CAAC,MAAM,CAAC;IAChC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,KAAc,EACd,WAAoB,EACpB,oBAAyE;IAEzE,MAAM,YAAY,GAAG,MAAM,4BAA4B,CAAC,KAAK,EAAE,WAAW,EAAE,oBAAoB,CAAC,CAAC;IAClG,MAAM,QAAQ,GAAG,2BAA2B,CAC1C,YAAY,CAAC,OAAO,EACpB,YAAY,CAAC,WAAW,EACxB,YAAY,CAAC,YAAY,EACzB,SAAS,CAAC,KAAK,EACf;QACE,sBAAsB,EAAE,YAAY,CAAC,sBAAsB;QAC3D,uBAAuB,EAAE,YAAY,CAAC,uBAAuB;KAC9D,CACF,CAAC;IACF,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAC3C,CAAC","sourcesContent":["import { Command } from \"commander\";\nimport { pathExists } from \"../core/fs/fs-utils.js\";\nimport { resolveItemTypeRegistry } from \"../core/item/type-registry.js\";\nimport { EXIT_CODE } from \"../core/shared/constants.js\";\nimport { getSettingsPath, resolvePmRoot } from \"../core/store/paths.js\";\nimport { readSettings } from \"../core/store/settings.js\";\nimport { BUILTIN_ITEM_TYPE_VALUES } from \"../types/index.js\";\nimport {\n getActiveExtensionRegistrations,\n runActiveServiceOverride,\n} from \"../core/extensions/index.js\";\nimport {\n type CommanderGuidanceContext,\n formatCommanderErrorForDisplay,\n formatCommanderErrorForJson,\n} from \"./error-guidance.js\";\nimport { normalizeHelpCommandPath } from \"./help-content.js\";\nimport { getCommandPath } from \"./registration-helpers.js\";\nimport {\n normalizeLegacyExtensionActionSyntax,\n parseBootstrapGlobalOptions,\n parseBootstrapCommandName,\n} from \"./bootstrap-args.js\";\nimport type { ExtensionCommandHelpDescriptor } from \"./extension-command-help.js\";\n\nexport const BUILTIN_TYPE_HELP_VALUES = BUILTIN_ITEM_TYPE_VALUES.join(\"|\");\n\nexport interface CommanderUsageContext extends CommanderGuidanceContext {\n message: string;\n commandName: string | undefined;\n allowedTypes: string;\n}\n\nexport function collectRuntimeCommandPaths(\n root: Command,\n extensionDescriptors: ReadonlyMap<string, ExtensionCommandHelpDescriptor>,\n): string[] {\n const commandPaths = new Set<string>();\n const queue: Command[] = [...root.commands];\n while (queue.length > 0) {\n const current = queue.shift();\n if (!current) {\n continue;\n }\n const normalizedPath = normalizeHelpCommandPath(getCommandPath(current));\n const hasInternalSegment = normalizedPath.split(\" \").some((segment) => segment.startsWith(\"_\"));\n if (normalizedPath.length > 0 && !hasInternalSegment) {\n commandPaths.add(normalizedPath);\n }\n queue.push(...current.commands);\n }\n for (const descriptorPath of extensionDescriptors.keys()) {\n const normalizedPath = normalizeHelpCommandPath(descriptorPath);\n const hasInternalSegment = normalizedPath.split(\" \").some((segment) => segment.startsWith(\"_\"));\n if (normalizedPath.length > 0 && !hasInternalSegment) {\n commandPaths.add(normalizedPath);\n }\n }\n return [...commandPaths].sort((left, right) => left.localeCompare(right));\n}\n\nexport function scoreCommandPathMatch(commandPath: string, queryToken: string): number {\n const normalizedPath = commandPath.trim().toLowerCase();\n const normalizedToken = queryToken.trim().toLowerCase();\n if (normalizedToken.length === 0) {\n return Number.POSITIVE_INFINITY;\n }\n const pathSegments = normalizedPath.split(\" \");\n if (normalizedPath === normalizedToken) {\n return 0;\n }\n if (pathSegments.includes(normalizedToken)) {\n return 1;\n }\n if (pathSegments.some((segment) => segment.startsWith(normalizedToken))) {\n return 2;\n }\n if (normalizedPath.includes(normalizedToken)) {\n return 3;\n }\n return Number.POSITIVE_INFINITY;\n}\n\nexport function buildUnknownCommandGuidanceFromRuntime(\n rawMessage: string,\n root: Command,\n extensionDescriptors: ReadonlyMap<string, ExtensionCommandHelpDescriptor>,\n): CommanderGuidanceContext | undefined {\n const unknownCommandMatch = rawMessage.match(/unknown command '([^']+)'/i);\n if (!unknownCommandMatch || typeof unknownCommandMatch[1] !== \"string\") {\n return undefined;\n }\n const normalizedUnknown = normalizeHelpCommandPath(unknownCommandMatch[1]);\n if (normalizedUnknown.length === 0) {\n return undefined;\n }\n const commandPaths = collectRuntimeCommandPaths(root, extensionDescriptors);\n if (commandPaths.length === 0) {\n return undefined;\n }\n\n const primaryToken = normalizedUnknown.split(\" \")[0] ?? normalizedUnknown;\n const rankedCandidates = commandPaths\n .map((commandPath) => {\n const directScore = scoreCommandPathMatch(commandPath, normalizedUnknown);\n const fallbackScore =\n primaryToken !== normalizedUnknown ? scoreCommandPathMatch(commandPath, primaryToken) : Number.POSITIVE_INFINITY;\n const score = Math.min(directScore, fallbackScore);\n return { commandPath, score };\n })\n .filter((entry) => Number.isFinite(entry.score))\n .sort((left, right) => {\n if (left.score !== right.score) {\n return left.score - right.score;\n }\n return left.commandPath.localeCompare(right.commandPath);\n })\n .map((entry) => entry.commandPath);\n\n const fallbackTopLevel = [...new Set(commandPaths.map((commandPath) => commandPath.split(\" \")[0]).filter((segment) => segment.length > 0))];\n fallbackTopLevel.sort((left, right) => left.localeCompare(right));\n const suggestedPaths = (rankedCandidates.length > 0 ? rankedCandidates : fallbackTopLevel).slice(0, 3);\n const examples = [...new Set([\"pm --help\", ...suggestedPaths.map((path) => `pm ${path} --help`)])];\n\n return {\n unknownCommandExamples: examples,\n unknownCommandNextSteps: [\n 'Run \"pm --help\" to list commands available in this runtime, including active extensions.',\n \"Use one of the suggested command paths above with --help to inspect valid flags and usage.\",\n ],\n };\n}\n\nexport function resolveChildCommandByToken(parent: Command, token: string): Command | undefined {\n const normalizedToken = token.trim().toLowerCase();\n return parent.commands.find((candidate) => {\n if (candidate.name().trim().toLowerCase() === normalizedToken) {\n return true;\n }\n const aliases = typeof candidate.aliases === \"function\" ? candidate.aliases() : [];\n return aliases.some((alias) => alias.trim().toLowerCase() === normalizedToken);\n });\n}\n\nexport function isKnownHelpCommandPath(root: Command, commandPathTokens: string[]): boolean {\n if (commandPathTokens.length === 0) {\n return true;\n }\n let current = root;\n let matchedAny = false;\n for (const token of commandPathTokens) {\n const next = resolveChildCommandByToken(current, token);\n if (!next) {\n return matchedAny;\n }\n matchedAny = true;\n current = next;\n }\n return matchedAny;\n}\n\nexport async function resolveCommanderUsageContext(\n error: unknown,\n rootProgram: Command,\n extensionDescriptors: ReadonlyMap<string, ExtensionCommandHelpDescriptor>,\n): Promise<CommanderUsageContext> {\n const rawMessage = typeof error === \"object\" && error !== null ? (error as { message?: string }).message : undefined;\n const message = rawMessage ?? \"Invalid command usage\";\n const invocationArgv = normalizeLegacyExtensionActionSyntax(process.argv.slice(2));\n const bootstrapGlobal = parseBootstrapGlobalOptions(invocationArgv);\n const commandName = parseBootstrapCommandName(invocationArgv);\n let allowedTypes = BUILTIN_TYPE_HELP_VALUES;\n try {\n const pmRoot = resolvePmRoot(process.cwd(), bootstrapGlobal.path);\n if (await pathExists(getSettingsPath(pmRoot))) {\n const settings = await readSettings(pmRoot);\n const typeRegistry = resolveItemTypeRegistry(settings, getActiveExtensionRegistrations());\n if (typeRegistry.types.length > 0) {\n allowedTypes = typeRegistry.types.join(\"|\");\n }\n }\n } catch {\n // Fall back to built-in type guidance when settings cannot be read.\n }\n const unknownCommandGuidance = buildUnknownCommandGuidanceFromRuntime(message, rootProgram, extensionDescriptors);\n return {\n message,\n commandName,\n allowedTypes,\n ...(unknownCommandGuidance ?? {}),\n };\n}\n\nexport async function formatCommanderUsageMessage(\n error: unknown,\n rootProgram: Command,\n extensionDescriptors: ReadonlyMap<string, ExtensionCommandHelpDescriptor>,\n): Promise<string> {\n const usageContext = await resolveCommanderUsageContext(error, rootProgram, extensionDescriptors);\n const { message, commandName, allowedTypes, unknownCommandExamples, unknownCommandNextSteps } = usageContext;\n const formatted = formatCommanderErrorForDisplay(message, commandName, allowedTypes, {\n unknownCommandExamples,\n unknownCommandNextSteps,\n });\n const serviceOverride = await runActiveServiceOverride(\"help_format\", {\n message: formatted,\n command: commandName,\n allowed_types: allowedTypes,\n });\n if (serviceOverride.handled && typeof serviceOverride.result === \"string\") {\n return serviceOverride.result;\n }\n return formatted;\n}\n\nexport async function formatCommanderUsageJson(\n error: unknown,\n rootProgram: Command,\n extensionDescriptors: ReadonlyMap<string, ExtensionCommandHelpDescriptor>,\n): Promise<string> {\n const usageContext = await resolveCommanderUsageContext(error, rootProgram, extensionDescriptors);\n const envelope = formatCommanderErrorForJson(\n usageContext.message,\n usageContext.commandName,\n usageContext.allowedTypes,\n EXIT_CODE.USAGE,\n {\n unknownCommandExamples: usageContext.unknownCommandExamples,\n unknownCommandNextSteps: usageContext.unknownCommandNextSteps,\n },\n );\n return JSON.stringify(envelope, null, 2);\n}\n"]}
|
|
@@ -11,15 +11,7 @@ import { listAllFrontMatter } from "../../core/store/item-store.js";
|
|
|
11
11
|
import { getSettingsPath, resolvePmRoot } from "../../core/store/paths.js";
|
|
12
12
|
import { readSettings } from "../../core/store/settings.js";
|
|
13
13
|
import { readHistoryEntries } from "./history.js";
|
|
14
|
-
|
|
15
|
-
if (raw === undefined)
|
|
16
|
-
return undefined;
|
|
17
|
-
const parsed = Number(raw);
|
|
18
|
-
if (!Number.isFinite(parsed) || parsed < 0) {
|
|
19
|
-
throw new PmCliError("Invalid --limit value", EXIT_CODE.USAGE);
|
|
20
|
-
}
|
|
21
|
-
return Math.floor(parsed);
|
|
22
|
-
}
|
|
14
|
+
import { parseLimit } from "../shared-parsers.js";
|
|
23
15
|
function parseNonEmptyFilter(raw, flagLabel) {
|
|
24
16
|
if (raw === undefined)
|
|
25
17
|
return undefined;
|