@unbrained/pm-cli 2026.8.20 → 2026.8.22
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/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +38 -0
- package/dist/cli/error-guidance.d.ts +29 -4
- package/dist/cli/error-guidance.js +43 -43
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.js +40 -7
- package/dist/cli-bundle/bundle-manifest.json +150 -150
- package/dist/cli-bundle/chunks/{chunk-L4LGPBJU.js → chunk-BWX4SK46.js} +58 -58
- package/dist/cli-bundle/chunks/chunk-EMWDM5FI.js +13 -0
- package/dist/cli-bundle/chunks/chunk-HYG6LRL4.js +200 -0
- package/dist/cli-bundle/chunks/{chunk-TSMWLCHS.js → chunk-MYYI3ZOA.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-4GB2LTOQ.js → chunk-MZTZQTMS.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-7BRF2BX2.js → chunk-QI2CT3IX.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-SMWXHMVB.js +35 -0
- package/dist/cli-bundle/chunks/{chunk-US2ZQW2M.js → chunk-U6GQ4VMV.js} +47 -47
- package/dist/cli-bundle/chunks/{chunk-K3EN3LK2.js → chunk-VMMIL3SI.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-WG4STC36.js +5 -0
- package/dist/cli-bundle/chunks/{chunk-XYDDWBZN.js → chunk-YBPJAOQQ.js} +3 -3
- package/dist/cli-bundle/chunks/{register-list-query-JSAQCVOC.js → register-list-query-HZKBQNWW.js} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-XJPAW63D.js → register-mutation-HTKEEGRD.js} +2 -2
- package/dist/cli-bundle/chunks/{register-operations-DSOSB2XQ.js → register-operations-6EMRWJJY.js} +2 -2
- package/dist/cli-bundle/chunks/{register-setup-QUR6QL2C.js → register-setup-QK4OTOXN.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-TDR5OGG3.js → chunk-2ARQGDDW.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-AZBACT5T.js → chunk-2AZT5WXZ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-M32HFIQB.js → chunk-2POVTNLY.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-3LKU6PTJ.js +4 -0
- package/dist/cli-bundle/focused-chunks/chunk-5SHSBMX2.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-UGSS4F5X.js → chunk-6S2MO3Q3.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-5L7M4AI7.js → chunk-A2BC5PQL.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-C4S4A4JJ.js +5 -0
- package/dist/cli-bundle/focused-chunks/{chunk-OM65KHGF.js → chunk-D6RBZEJJ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-E2EWYPY6.js +16 -0
- package/dist/cli-bundle/focused-chunks/{chunk-G3C5ERXG.js → chunk-GMYPD4FX.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-L5LDSRO2.js +155 -0
- package/dist/cli-bundle/focused-chunks/{chunk-BLJCGGID.js → chunk-MB37AYN6.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-MCOR37QK.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-FUREQLQN.js → chunk-PH2OXXVZ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-325UXIO7.js → chunk-PMGJUFNQ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-R6SR45XU.js +50 -0
- package/dist/cli-bundle/focused-chunks/chunk-WZE4LIPW.js +8 -0
- package/dist/cli-bundle/main.js +13 -13
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +2 -2
- package/dist/cli-bundle/sdk-core.js +40 -40
- package/dist/cli-bundle/sdk-governance.js +1 -1
- package/dist/cli-bundle/sdk-graph.js +1 -1
- package/dist/cli-bundle/sdk-merge.js +32 -32
- package/dist/cli-bundle/sdk-query.js +1 -1
- package/dist/cli-bundle/sdk-runtime.js +1 -1
- package/dist/cli-bundle/sdk-testing.js +1 -1
- package/dist/cli-bundle/sdk.js +5 -5
- package/dist/core/extensions/extension-hook-runtime.js +22 -20
- package/dist/core/extensions/extension-types.d.ts +8 -1
- package/dist/core/extensions/extension-types.js +2 -2
- package/dist/core/extensions/loader.js +7 -3
- package/dist/core/extensions/service-ownership.d.ts +8 -0
- package/dist/core/extensions/service-ownership.js +20 -0
- package/dist/core/item/id.js +20 -5
- package/dist/core/item/item-format.js +27 -2
- package/dist/core/shared/errors.d.ts +20 -0
- package/dist/core/shared/errors.js +2 -2
- package/dist/core/store/item-store.js +6 -91
- package/dist/core/store/tracker-preflight.d.ts +7 -0
- package/dist/core/store/tracker-preflight.js +142 -0
- package/dist/sdk/agent/refusal-reachability.d.ts +1 -1
- package/dist/sdk/agent/tracker-preflight-contracts.d.ts +63 -0
- package/dist/sdk/agent/tracker-preflight-contracts.js +127 -0
- package/dist/sdk/annotations.js +6 -7
- package/dist/sdk/authoring.d.ts +1 -1
- package/dist/sdk/authoring.js +2 -2
- package/dist/sdk/cli-contracts/agent-output-contracts.d.ts +77 -0
- package/dist/sdk/cli-contracts/agent-output-contracts.js +324 -2
- package/dist/sdk/cli-contracts/commander-mutation-options.js +3 -3
- package/dist/sdk/cli-contracts/runtime-contracts.d.ts +3 -1
- package/dist/sdk/cli-contracts/runtime-contracts.js +4 -3
- package/dist/sdk/cli-contracts.d.ts +1 -1
- package/dist/sdk/cli-contracts.js +3 -3
- package/dist/sdk/config.d.ts +5 -0
- package/dist/sdk/config.js +5 -5
- package/dist/sdk/context-intent-runtime.js +7 -4
- package/dist/sdk/contracts.d.ts +1 -0
- package/dist/sdk/contracts.js +3 -2
- package/dist/sdk/dependencies.js +5 -7
- package/dist/sdk/dependency-flag-validation.d.ts +1 -1
- package/dist/sdk/dependency-flag-validation.js +10 -4
- package/dist/sdk/environment/tracker-preflight.d.ts +6 -0
- package/dist/sdk/environment/tracker-preflight.js +10 -0
- package/dist/sdk/eval.js +5 -7
- package/dist/sdk/extension/install-sources.d.ts +1 -1
- package/dist/sdk/extension/install-sources.js +6 -3
- package/dist/sdk/extension/output-ownership.d.ts +1 -0
- package/dist/sdk/extension/output-ownership.js +3 -2
- package/dist/sdk/files.js +6 -10
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +75 -15
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +81 -8
- package/dist/sdk/governance/assurance.d.ts +36 -2
- package/dist/sdk/governance/assurance.js +184 -10
- package/dist/sdk/governance/gc.js +5 -6
- package/dist/sdk/governance/health.d.ts +3 -0
- package/dist/sdk/governance/health.js +42 -11
- package/dist/sdk/governance/hierarchy-validation.d.ts +29 -0
- package/dist/sdk/governance/hierarchy-validation.js +109 -0
- package/dist/sdk/governance/reindex.js +5 -6
- package/dist/sdk/governance/validate.d.ts +2 -9
- package/dist/sdk/governance/validate.js +51 -109
- package/dist/sdk/graph/assembly.d.ts +6 -1
- package/dist/sdk/graph/assembly.js +16 -22
- package/dist/sdk/graph/governance-contracts.d.ts +1 -1
- package/dist/sdk/graph/governance-contracts.js +8 -2
- package/dist/sdk/graph/governance.d.ts +7 -5
- package/dist/sdk/graph/governance.js +76 -16
- package/dist/sdk/graph/hierarchy-integrity.d.ts +94 -0
- package/dist/sdk/graph/hierarchy-integrity.js +311 -0
- package/dist/sdk/graph/index.d.ts +2 -1
- package/dist/sdk/graph/index.js +3 -2
- package/dist/sdk/graph/remediation.js +32 -2
- package/dist/sdk/graph/run.d.ts +31 -2
- package/dist/sdk/graph/run.js +83 -36
- package/dist/sdk/graph/traversal.js +14 -5
- package/dist/sdk/graph/workspace-relationship-kind-registry.d.ts +8 -0
- package/dist/sdk/graph/workspace-relationship-kind-registry.js +28 -0
- package/dist/sdk/history-compact.js +6 -9
- package/dist/sdk/history-read.js +5 -7
- package/dist/sdk/history-redact.js +5 -6
- package/dist/sdk/history-repair.js +6 -9
- package/dist/sdk/improvement-ledger.js +7 -10
- package/dist/sdk/index.d.ts +4 -2
- package/dist/sdk/index.js +5 -3
- package/dist/sdk/item-children.js +21 -8
- package/dist/sdk/lifecycle/append.d.ts +0 -5
- package/dist/sdk/lifecycle/append.js +5 -6
- package/dist/sdk/lifecycle/claim.d.ts +0 -5
- package/dist/sdk/lifecycle/claim.js +6 -9
- package/dist/sdk/lifecycle/close-many.d.ts +0 -5
- package/dist/sdk/lifecycle/close-many.js +5 -6
- package/dist/sdk/lifecycle/close.d.ts +0 -5
- package/dist/sdk/lifecycle/close.js +5 -6
- package/dist/sdk/lifecycle/copy.d.ts +0 -5
- package/dist/sdk/lifecycle/copy.js +5 -6
- package/dist/sdk/lifecycle/create.d.ts +0 -5
- package/dist/sdk/lifecycle/create.js +127 -102
- package/dist/sdk/lifecycle/delete.js +5 -6
- package/dist/sdk/lifecycle/focus.d.ts +0 -5
- package/dist/sdk/lifecycle/focus.js +5 -6
- package/dist/sdk/lifecycle/hierarchy-mutation-lock.d.ts +15 -0
- package/dist/sdk/lifecycle/hierarchy-mutation-lock.js +25 -0
- package/dist/sdk/lifecycle/plan.d.ts +0 -5
- package/dist/sdk/lifecycle/plan.js +5 -6
- package/dist/sdk/lifecycle/restore.js +5 -6
- package/dist/sdk/lifecycle/update-many.d.ts +0 -5
- package/dist/sdk/lifecycle/update-many.js +5 -6
- package/dist/sdk/lifecycle/update.d.ts +2 -5
- package/dist/sdk/lifecycle/update.js +211 -84
- package/dist/sdk/linked-artifacts.js +6 -7
- package/dist/sdk/merge/install.js +5 -6
- package/dist/sdk/mutation-events.js +5 -7
- package/dist/sdk/package-import-adapters.js +6 -8
- package/dist/sdk/profile.js +6 -7
- package/dist/sdk/query/activity.js +5 -6
- package/dist/sdk/query/calendar.js +5 -6
- package/dist/sdk/query/complete-list.d.ts +3 -3
- package/dist/sdk/query/complete-list.js +46 -3
- package/dist/sdk/query/get.d.ts +0 -5
- package/dist/sdk/query/get.js +5 -6
- package/dist/sdk/query/history.d.ts +0 -5
- package/dist/sdk/query/history.js +5 -6
- package/dist/sdk/query/list.d.ts +4 -3
- package/dist/sdk/query/list.js +92 -54
- package/dist/sdk/query/search.js +5 -7
- package/dist/sdk/read-output-contracts.d.ts +5 -1
- package/dist/sdk/read-output-contracts.js +87 -22
- package/dist/sdk/relationship-context.js +3 -4
- package/dist/sdk/relationship-kinds/contract.d.ts +8 -0
- package/dist/sdk/relationship-kinds/contract.js +13 -13
- package/dist/sdk/relationships.d.ts +1 -1
- package/dist/sdk/relationships.js +27 -2
- package/dist/sdk/runtime.d.ts +3 -2
- package/dist/sdk/runtime.js +3 -2
- package/dist/sdk/schema-migration.js +6 -7
- package/dist/sdk/schema.js +5 -6
- package/dist/sdk/stats.js +5 -8
- package/dist/sdk/templates.js +5 -6
- package/dist/sdk/test/batch.js +15 -9
- package/dist/sdk/test/execution.js +12 -5
- package/dist/sdk/test/runs.js +5 -7
- package/dist/types.d.ts +11 -0
- package/dist/types.js +2 -2
- package/docs/AGENT_UX_CONTRACTS.md +24 -1
- package/docs/COMMANDS.md +29 -14
- package/docs/DEPENDENCY_KIND_CONTRACT.md +40 -1
- package/docs/DIAGNOSTIC_OUTPUT_CONTRACTS.md +98 -0
- package/docs/EXTENSIONS.md +2 -1
- package/docs/README.md +1 -0
- package/docs/READ_OUTPUT_CONTRACTS.md +9 -2
- package/docs/RECURRENCE_RECOVERY_CONTRACTS.md +37 -0
- package/docs/RELATIONSHIP_GRAPH.md +97 -12
- package/docs/SDK_PRIMITIVE_INVENTORY.md +15 -1
- package/docs/TESTING.md +15 -0
- package/marketplace.json +2 -2
- package/package.json +1 -1
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-digital-twin/package.json +1 -1
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/package.json +1 -1
- package/packages/pm-kanban/package.json +1 -1
- package/packages/pm-lifecycle-hooks/package.json +1 -1
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/package.json +1 -1
- package/packages/pm-vcs/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/sdk/public-surface.json +848 -56
- package/dist/cli-bundle/chunks/chunk-2RDVGYWE.js +0 -13
- package/dist/cli-bundle/chunks/chunk-BLVQHFSY.js +0 -35
- package/dist/cli-bundle/chunks/chunk-CU25EQVV.js +0 -5
- package/dist/cli-bundle/chunks/chunk-RS3IV2R6.js +0 -197
- package/dist/cli-bundle/focused-chunks/chunk-6AHG2YW7.js +0 -50
- package/dist/cli-bundle/focused-chunks/chunk-GXWQBE3T.js +0 -8
- package/dist/cli-bundle/focused-chunks/chunk-JWKEDZJI.js +0 -4
- package/dist/cli-bundle/focused-chunks/chunk-KYZ6JGPL.js +0 -155
- package/dist/cli-bundle/focused-chunks/chunk-Q47EX4DI.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-RIHDMCUM.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-T4ZFY7ZJ.js +0 -16
- package/dist/cli-bundle/focused-chunks/chunk-Z3PLWSGM.js +0 -2
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements extension runtime contracts and governance for Extension Hook Runtime.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="d1dd5d4f-5f08-5e52-b109-d066f92ae3b3")}catch(e){}}();
|
|
8
8
|
import { cloneCommandOptionsSnapshot, cloneContextSnapshot, cloneGlobalOptionsSnapshot, normalizeCommandName, } from "./extension-runtime-helpers.js";
|
|
9
9
|
import { stableValueEquals } from "../shared/serialization.js";
|
|
10
10
|
import { EXIT_CODE } from "../shared/constants.js";
|
|
@@ -480,6 +480,20 @@ function isLegacyOutputPayloadEcho(result, context, serviceContext) {
|
|
|
480
480
|
result !== null &&
|
|
481
481
|
stableValueEquals(result, serviceContext.payload));
|
|
482
482
|
}
|
|
483
|
+
function resolveMatchedServiceDecision(matched, decision, warnings) {
|
|
484
|
+
if (!decision.handled) {
|
|
485
|
+
return undefined;
|
|
486
|
+
}
|
|
487
|
+
if (matched.passThrough === true) {
|
|
488
|
+
warnings.push(`extension_service_pass_through_contract_violated:${matched.layer}:${matched.name}:${matched.service}`);
|
|
489
|
+
return undefined;
|
|
490
|
+
}
|
|
491
|
+
return {
|
|
492
|
+
handled: true,
|
|
493
|
+
result: decision.result,
|
|
494
|
+
warnings,
|
|
495
|
+
};
|
|
496
|
+
}
|
|
483
497
|
/** Implements run service override sync for the public runtime surface of this module. */
|
|
484
498
|
export function runServiceOverrideSync(services, context) {
|
|
485
499
|
const matches = matchingServiceOverrides(services, context.service);
|
|
@@ -499,15 +513,9 @@ export function runServiceOverrideSync(services, context) {
|
|
|
499
513
|
warnings.push(`extension_output_format_payload_echo_deprecated:${matched.layer}:${matched.name}`);
|
|
500
514
|
continue;
|
|
501
515
|
}
|
|
502
|
-
const
|
|
503
|
-
if (
|
|
504
|
-
|
|
505
|
-
}
|
|
506
|
-
return {
|
|
507
|
-
handled: true,
|
|
508
|
-
result: decision.result,
|
|
509
|
-
warnings,
|
|
510
|
-
};
|
|
516
|
+
const resolved = resolveMatchedServiceDecision(matched, resolveServiceOverrideValue(result, context), warnings);
|
|
517
|
+
if (resolved)
|
|
518
|
+
return resolved;
|
|
511
519
|
}
|
|
512
520
|
catch {
|
|
513
521
|
warnings.push(`extension_service_override_failed:${matched.layer}:${matched.name}:${matched.service}`);
|
|
@@ -534,15 +542,9 @@ export async function runServiceOverride(services, context) {
|
|
|
534
542
|
warnings.push(`extension_output_format_payload_echo_deprecated:${matched.layer}:${matched.name}`);
|
|
535
543
|
continue;
|
|
536
544
|
}
|
|
537
|
-
const
|
|
538
|
-
if (
|
|
539
|
-
|
|
540
|
-
}
|
|
541
|
-
return {
|
|
542
|
-
handled: true,
|
|
543
|
-
result: decision.result,
|
|
544
|
-
warnings,
|
|
545
|
-
};
|
|
545
|
+
const resolved = resolveMatchedServiceDecision(matched, resolveServiceOverrideValue(result, context), warnings);
|
|
546
|
+
if (resolved)
|
|
547
|
+
return resolved;
|
|
546
548
|
}
|
|
547
549
|
catch {
|
|
548
550
|
warnings.push(`extension_service_override_failed:${matched.layer}:${matched.name}:${matched.service}`);
|
|
@@ -695,4 +697,4 @@ export function runRendererOverride(renderers, context) {
|
|
|
695
697
|
}
|
|
696
698
|
}
|
|
697
699
|
//# sourceMappingURL=extension-hook-runtime.js.map
|
|
698
|
-
//# debugId=
|
|
700
|
+
//# debugId=d1dd5d4f-5f08-5e52-b109-d066f92ae3b3
|
|
@@ -483,6 +483,11 @@ export type ServiceOverrideDecision = {
|
|
|
483
483
|
};
|
|
484
484
|
/** Restricts service override values accepted by command, SDK, and storage contracts. */
|
|
485
485
|
export type ServiceOverride = (context: ServiceOverrideContext) => unknown | ServiceOverrideDecision;
|
|
486
|
+
/** Host-enforced ownership metadata for a service override. */
|
|
487
|
+
export interface ServiceOverrideOwnership {
|
|
488
|
+
/** Declare that the callback may only decline. Any handled result is ignored and diagnosed by the host. */
|
|
489
|
+
passThrough?: boolean;
|
|
490
|
+
}
|
|
486
491
|
/** Documents the registered extension hook payload exchanged by command, SDK, and package integrations. */
|
|
487
492
|
export interface RegisteredExtensionHook<THook> {
|
|
488
493
|
/** Value that configures or reports layer for this contract. */
|
|
@@ -1187,6 +1192,8 @@ export interface RegisteredExtensionServiceOverride {
|
|
|
1187
1192
|
service: ExtensionServiceName;
|
|
1188
1193
|
/** Value that configures or reports run for this contract. */
|
|
1189
1194
|
run: ServiceOverride;
|
|
1195
|
+
/** Whether the host forbids this callback from handling the service payload. */
|
|
1196
|
+
passThrough?: boolean;
|
|
1190
1197
|
}
|
|
1191
1198
|
/** Documents the registered extension renderer override payload exchanged by command, SDK, and package integrations. */
|
|
1192
1199
|
export interface RegisteredExtensionRendererOverride {
|
|
@@ -1464,7 +1471,7 @@ export interface ExtensionApi {
|
|
|
1464
1471
|
/** Value that configures or reports register preflight for this contract. */
|
|
1465
1472
|
registerPreflight(override: PreflightOverride | ScopedPreflightOverrideDefinition): void;
|
|
1466
1473
|
/** Value that configures or reports register service for this contract. */
|
|
1467
|
-
registerService(service: ExtensionServiceName, override: ServiceOverride): void;
|
|
1474
|
+
registerService(service: ExtensionServiceName, override: ServiceOverride, ownership?: ServiceOverrideOwnership): void;
|
|
1468
1475
|
/** Value that configures or reports register flags for this contract. */
|
|
1469
1476
|
registerFlags(targetCommand: string, flags: FlagDefinition[]): void;
|
|
1470
1477
|
/** Value that configures or reports register item fields for this contract. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Public contract for known extension capabilities, shared by SDK and presentation-layer consumers. */
|
|
2
2
|
|
|
3
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="87454a57-b62e-560a-b66f-3c15d4a95cc2")}catch(e){}}();
|
|
4
4
|
export const KNOWN_EXTENSION_CAPABILITIES = [
|
|
5
5
|
"commands",
|
|
6
6
|
"renderers",
|
|
@@ -100,4 +100,4 @@ export function createDefaultExtensionGovernancePolicy() {
|
|
|
100
100
|
};
|
|
101
101
|
}
|
|
102
102
|
//# sourceMappingURL=extension-types.js.map
|
|
103
|
-
//# debugId=
|
|
103
|
+
//# debugId=87454a57-b62e-560a-b66f-3c15d4a95cc2
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements extension runtime contracts and governance for Loader.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="10311c96-5cba-5021-a8c5-82abd6eeb6f5")}catch(e){}}();
|
|
8
8
|
import fs from "node:fs/promises";
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import { pathToFileURL } from "node:url";
|
|
@@ -19,6 +19,7 @@ import { KNOWN_ITEM_FIELD_TYPES, normalizeItemFieldType, suggestKnownItemFieldTy
|
|
|
19
19
|
import { snapshotExtensionModuleGraph } from "./module-graph-snapshot.js";
|
|
20
20
|
import { captureExtensionActivationRollback } from "./activation-transaction.js";
|
|
21
21
|
import { collectPreflightCollisionWarnings, normalizePreflightOverride, } from "./preflight-ownership.js";
|
|
22
|
+
import { normalizeServiceOverrideOwnership } from "./service-ownership.js";
|
|
22
23
|
import { assertCommandDefinitionMetadataStrings } from "./command-visibility-tier.js";
|
|
23
24
|
import { buildImportExportContext, resolveImportExportArtifactOutput, } from "./exporter-output-contract.js";
|
|
24
25
|
import { asRegistrationRecord, assertOptionalBooleanField, assertOptionalFlagDefaultField, assertOptionalStringArrayField, assertOptionalStringField, normalizeOptionalStringArrayField, } from "./registration-validation.js";
|
|
@@ -1569,7 +1570,7 @@ class ExtensionApiRegistrar {
|
|
|
1569
1570
|
...normalized,
|
|
1570
1571
|
});
|
|
1571
1572
|
}
|
|
1572
|
-
registerService(service, override) {
|
|
1573
|
+
registerService(service, override, ownership = {}) {
|
|
1573
1574
|
assertExtensionCapability(this.#loadedExtension, "services", "registerService");
|
|
1574
1575
|
const normalizedService = String(service).trim().toLowerCase();
|
|
1575
1576
|
if (!isExtensionServiceName(normalizedService)) {
|
|
@@ -1584,6 +1585,9 @@ class ExtensionApiRegistrar {
|
|
|
1584
1585
|
name: this.#loadedExtension.name,
|
|
1585
1586
|
service: normalizedService,
|
|
1586
1587
|
run: override,
|
|
1588
|
+
...(normalizeServiceOverrideOwnership(ownership)
|
|
1589
|
+
? { passThrough: true }
|
|
1590
|
+
: {}),
|
|
1587
1591
|
});
|
|
1588
1592
|
}
|
|
1589
1593
|
registerRenderer(format, renderer, ownership = {}) {
|
|
@@ -2216,4 +2220,4 @@ export const _testOnlyLoader = {
|
|
|
2216
2220
|
},
|
|
2217
2221
|
};
|
|
2218
2222
|
//# sourceMappingURL=loader.js.map
|
|
2219
|
-
//# debugId=
|
|
2223
|
+
//# debugId=10311c96-5cba-5021-a8c5-82abd6eeb6f5
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module core/extensions/service-ownership
|
|
3
|
+
*
|
|
4
|
+
* Validates host-enforced ownership metadata for extension service overrides.
|
|
5
|
+
*/
|
|
6
|
+
import type { ServiceOverrideOwnership } from "./extension-types.js";
|
|
7
|
+
/** Validate one service ownership declaration and return its normalized pass-through flag. */
|
|
8
|
+
export declare function normalizeServiceOverrideOwnership(ownership: ServiceOverrideOwnership): boolean;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** Validate one service ownership declaration and return its normalized pass-through flag. */
|
|
2
|
+
|
|
3
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a30142c8-b04d-5878-8497-c902ff299e94")}catch(e){}}();
|
|
4
|
+
export function normalizeServiceOverrideOwnership(ownership) {
|
|
5
|
+
if (ownership === null ||
|
|
6
|
+
typeof ownership !== "object" ||
|
|
7
|
+
Array.isArray(ownership)) {
|
|
8
|
+
throw new TypeError("registerService ownership must be an object");
|
|
9
|
+
}
|
|
10
|
+
if (Reflect.ownKeys(ownership).some((key) => key !== "passThrough")) {
|
|
11
|
+
throw new TypeError("registerService ownership supports only passThrough");
|
|
12
|
+
}
|
|
13
|
+
if (ownership.passThrough !== undefined &&
|
|
14
|
+
typeof ownership.passThrough !== "boolean") {
|
|
15
|
+
throw new TypeError("registerService ownership.passThrough must be a boolean when provided");
|
|
16
|
+
}
|
|
17
|
+
return ownership.passThrough === true;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=service-ownership.js.map
|
|
20
|
+
//# debugId=a30142c8-b04d-5878-8497-c902ff299e94
|
package/dist/core/item/id.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Defines item parsing, formatting, and lifecycle helpers for Id.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="6b3f1585-ab12-57ca-80eb-d3cebc384c52")}catch(e){}}();
|
|
8
8
|
import crypto from "node:crypto";
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import { TYPE_TO_FOLDER } from "../shared/constants.js";
|
|
@@ -12,10 +12,25 @@ import { pathExists } from "../fs/fs-utils.js";
|
|
|
12
12
|
import { nextReproducibleToken } from "../reproducibility/context.js";
|
|
13
13
|
/** Implements normalize prefix for the public runtime surface of this module. */
|
|
14
14
|
export function normalizePrefix(input) {
|
|
15
|
-
const normalized =
|
|
16
|
-
|
|
15
|
+
const normalized = [];
|
|
16
|
+
let separatorPending = false;
|
|
17
|
+
for (const character of (input ?? "").toLowerCase()) {
|
|
18
|
+
const codePoint = character.charCodeAt(0);
|
|
19
|
+
const isAsciiDigit = codePoint >= 48 && codePoint <= 57;
|
|
20
|
+
const isAsciiLetter = codePoint >= 97 && codePoint <= 122;
|
|
21
|
+
if (!isAsciiDigit && !isAsciiLetter) {
|
|
22
|
+
separatorPending = normalized.length > 0;
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
if (separatorPending) {
|
|
26
|
+
normalized.push("-");
|
|
27
|
+
separatorPending = false;
|
|
28
|
+
}
|
|
29
|
+
normalized.push(character);
|
|
30
|
+
}
|
|
31
|
+
if (normalized.length === 0)
|
|
17
32
|
return "pm-";
|
|
18
|
-
return normalized.
|
|
33
|
+
return `${normalized.join("")}-`;
|
|
19
34
|
}
|
|
20
35
|
/** Implements normalize raw item id for the public runtime surface of this module. */
|
|
21
36
|
export function normalizeRawItemId(input) {
|
|
@@ -91,4 +106,4 @@ export async function generateItemId(pmRoot, prefix, options = {}) {
|
|
|
91
106
|
throw new Error(`Unable to generate unique id after ${attempts} attempts`);
|
|
92
107
|
}
|
|
93
108
|
//# sourceMappingURL=id.js.map
|
|
94
|
-
//# debugId=
|
|
109
|
+
//# debugId=6b3f1585-ab12-57ca-80eb-d3cebc384c52
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Defines item parsing, formatting, and lifecycle helpers for Item Format.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="5eac19ec-235e-5e6f-8ae7-4725f99c9d7f")}catch(e){}}();
|
|
8
8
|
import { encode as encodeToon } from "@toon-format/toon";
|
|
9
9
|
import { isDeepStrictEqual } from "node:util";
|
|
10
10
|
import { CONFIDENCE_TEXT_VALUES, ISSUE_SEVERITY_VALUES, PLAN_STEP_STATUS_VALUES, RECURRENCE_FREQUENCY_VALUES, RECURRENCE_WEEKDAY_VALUES, STATUS_VALUES, weekdayOrderIndex, } from "../../types/index.js";
|
|
@@ -601,6 +601,30 @@ function normalizeTestRunMeasurements(value) {
|
|
|
601
601
|
.slice(0, 32);
|
|
602
602
|
return deduplicated.length > 0 ? deduplicated : undefined;
|
|
603
603
|
}
|
|
604
|
+
/** Normalize and bound command/context provenance retained for a test run. */
|
|
605
|
+
function normalizeTestRunExecutions(values) {
|
|
606
|
+
if (!Array.isArray(values))
|
|
607
|
+
return undefined;
|
|
608
|
+
const executions = values
|
|
609
|
+
.filter((execution) => execution &&
|
|
610
|
+
typeof execution.command === "string" &&
|
|
611
|
+
execution.command.trim().length > 0)
|
|
612
|
+
.slice(0, 32)
|
|
613
|
+
.map((execution) => ({
|
|
614
|
+
command: execution.command.trim(),
|
|
615
|
+
requested_pm_context_mode: execution.requested_pm_context_mode === "schema" ||
|
|
616
|
+
execution.requested_pm_context_mode === "tracker" ||
|
|
617
|
+
execution.requested_pm_context_mode === "auto"
|
|
618
|
+
? execution.requested_pm_context_mode
|
|
619
|
+
: undefined,
|
|
620
|
+
pm_context_mode: execution.pm_context_mode === "schema" ||
|
|
621
|
+
execution.pm_context_mode === "tracker" ||
|
|
622
|
+
execution.pm_context_mode === "auto"
|
|
623
|
+
? execution.pm_context_mode
|
|
624
|
+
: undefined,
|
|
625
|
+
}));
|
|
626
|
+
return executions.length > 0 ? executions : undefined;
|
|
627
|
+
}
|
|
604
628
|
function normalizeTestRunSummary(value) {
|
|
605
629
|
const runId = typeof value.run_id === "string" ? value.run_id.trim() : "";
|
|
606
630
|
const kind = value.kind === "test" || value.kind === "test-all" ? value.kind : "test";
|
|
@@ -623,6 +647,7 @@ function normalizeTestRunSummary(value) {
|
|
|
623
647
|
linked_tests: normalizeNonNegativeInteger(value.linked_tests),
|
|
624
648
|
fail_on_skipped_triggered: value.fail_on_skipped_triggered === true ? true : undefined,
|
|
625
649
|
measurements: normalizeTestRunMeasurements(value.measurements),
|
|
650
|
+
executions: normalizeTestRunExecutions(value.executions),
|
|
626
651
|
};
|
|
627
652
|
deleteUndefinedFields(summary);
|
|
628
653
|
return summary;
|
|
@@ -1393,4 +1418,4 @@ export const _testOnlyItemFormat = {
|
|
|
1393
1418
|
sortTests,
|
|
1394
1419
|
};
|
|
1395
1420
|
//# sourceMappingURL=item-format.js.map
|
|
1396
|
-
//# debugId=
|
|
1421
|
+
//# debugId=5eac19ec-235e-5e6f-8ae7-4725f99c9d7f
|
|
@@ -79,6 +79,10 @@ export interface PmCliErrorContext {
|
|
|
79
79
|
check?: string;
|
|
80
80
|
/** Serialization format involved in a parse failure. */
|
|
81
81
|
format?: string;
|
|
82
|
+
/** CLI flag whose supplied value violated a shared mutation grammar. */
|
|
83
|
+
flag?: string;
|
|
84
|
+
/** Supplied scalar value that violated a shared mutation grammar. */
|
|
85
|
+
value?: string;
|
|
82
86
|
/** Item format version involved in a compatibility failure. */
|
|
83
87
|
format_version?: number;
|
|
84
88
|
/** Schema type that determines the shape and validation rules for this value. */
|
|
@@ -99,6 +103,22 @@ export interface PmCliErrorContext {
|
|
|
99
103
|
nextSteps?: string[];
|
|
100
104
|
/** Exact selectors that could not be matched by a lossless removal. */
|
|
101
105
|
unmatched?: string[];
|
|
106
|
+
/** Dependency selectors that matched no stored edge. */
|
|
107
|
+
unmatched_selectors?: Array<{
|
|
108
|
+
id: string;
|
|
109
|
+
kind?: string;
|
|
110
|
+
source_kind?: string;
|
|
111
|
+
author?: string;
|
|
112
|
+
created_at?: string;
|
|
113
|
+
}>;
|
|
114
|
+
/** Compact stored dependency identities available when a removal failed. */
|
|
115
|
+
available_dependencies?: Array<{
|
|
116
|
+
id: string;
|
|
117
|
+
kind: string;
|
|
118
|
+
source_kind?: string;
|
|
119
|
+
author?: string;
|
|
120
|
+
created_at?: string;
|
|
121
|
+
}>;
|
|
102
122
|
/** Exact verifier findings that caused an integrity-sensitive operation to refuse. */
|
|
103
123
|
verification_errors?: string[];
|
|
104
124
|
/** Local dependency targets that could not be resolved before mutation. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Implements the exported pm cli error runtime abstraction for core/shared/errors.ts. */
|
|
2
2
|
|
|
3
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="922e2e27-1499-5466-98e4-322d0d742e40")}catch(e){}}();
|
|
4
4
|
export class PmCliError extends Error {
|
|
5
5
|
/** Value that configures or reports exit code for this contract. */
|
|
6
6
|
exitCode;
|
|
@@ -18,4 +18,4 @@ export class PmCliError extends Error {
|
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
//# sourceMappingURL=errors.js.map
|
|
21
|
-
//# debugId=
|
|
21
|
+
//# debugId=922e2e27-1499-5466-98e4-322d0d742e40
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Reads and writes tracker storage with format-aware helpers for Item Store.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="f49b5141-f348-5954-a87e-8fd957593113")}catch(e){}}();
|
|
8
8
|
import fs from "node:fs/promises";
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import { getActiveExtensionRegistrations, projectAfterCommandItemSnapshot, recordAfterCommandAffectedItem, runActiveOnReadHooks, runActiveBeforeMutationHooks, runActiveOnWriteHooks, runActiveServiceOverride, } from "../extensions/index.js";
|
|
@@ -22,6 +22,7 @@ import { normalizeItemId, normalizeRawItemId } from "../item/id.js";
|
|
|
22
22
|
import { acquireItemMetadataDerivedIndexLock, listAllDocumentCandidatesCached, listAllDocumentsCached, listAllDocumentsCachedLight, refreshItemMetadataDerivedIndex, } from "./item-metadata-cache.js";
|
|
23
23
|
import { getHistoryPath, getItemPath, ITEM_FILE_EXTENSIONS } from "./paths.js";
|
|
24
24
|
import { resolveGovernanceKnobs } from "./settings.js";
|
|
25
|
+
import { assertReadableTrackerRoot } from "./tracker-preflight.js";
|
|
25
26
|
import { resolveClaimPrincipal } from "../shared/author.js";
|
|
26
27
|
import { nowIso } from "../shared/time.js";
|
|
27
28
|
async function fileExists(targetPath) {
|
|
@@ -60,92 +61,6 @@ function resolveItemFormatSearchOrder(preferredFormat) {
|
|
|
60
61
|
}
|
|
61
62
|
return ["toon", "json_markdown"];
|
|
62
63
|
}
|
|
63
|
-
function trackerRootNotDirectoryError(pmRoot) {
|
|
64
|
-
return new PmCliError(`Tracker root is not a directory at ${pmRoot}.`, EXIT_CODE.USAGE, {
|
|
65
|
-
code: "tracker_root_not_directory",
|
|
66
|
-
reason: "not_a_directory",
|
|
67
|
-
nextSteps: [
|
|
68
|
-
"Pass the tracker directory itself, usually <workspace>/.agents/pm.",
|
|
69
|
-
],
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
function trackerRootUnreadableError(pmRoot) {
|
|
73
|
-
return new PmCliError(`Tracker root is not readable at ${pmRoot}.`, EXIT_CODE.GENERIC_FAILURE, {
|
|
74
|
-
code: "tracker_root_unreadable",
|
|
75
|
-
reason: "unreadable",
|
|
76
|
-
nextSteps: [
|
|
77
|
-
"Grant read and directory-search permission to the tracker root, then retry the SDK read.",
|
|
78
|
-
],
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
async function assertMissingMetadataRootAncestors(pmRoot) {
|
|
82
|
-
const filesystemRoot = path.parse(path.resolve(pmRoot)).root;
|
|
83
|
-
let ancestor = path.dirname(path.resolve(pmRoot));
|
|
84
|
-
while (ancestor !== filesystemRoot) {
|
|
85
|
-
let ancestorStats;
|
|
86
|
-
try {
|
|
87
|
-
ancestorStats = await fs.stat(ancestor);
|
|
88
|
-
}
|
|
89
|
-
catch (error) {
|
|
90
|
-
if (isErrno(error, "ENOTDIR")) {
|
|
91
|
-
throw trackerRootNotDirectoryError(pmRoot);
|
|
92
|
-
}
|
|
93
|
-
if (!isErrno(error, "ENOENT")) {
|
|
94
|
-
throw error;
|
|
95
|
-
}
|
|
96
|
-
ancestor = path.dirname(ancestor);
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
99
|
-
if (!ancestorStats.isDirectory()) {
|
|
100
|
-
throw trackerRootNotDirectoryError(pmRoot);
|
|
101
|
-
}
|
|
102
|
-
break;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
/** Require metadata enumeration to start from a real directory so an invalid source cannot masquerade as an empty tracker. */
|
|
106
|
-
async function assertItemMetadataRoot(pmRoot) {
|
|
107
|
-
let stats;
|
|
108
|
-
try {
|
|
109
|
-
stats = await fs.stat(pmRoot);
|
|
110
|
-
}
|
|
111
|
-
catch (error) {
|
|
112
|
-
if (isErrno(error, "ENOENT")) {
|
|
113
|
-
await assertMissingMetadataRootAncestors(pmRoot);
|
|
114
|
-
throw new PmCliError(`Tracker root does not exist at ${pmRoot}.`, EXIT_CODE.NOT_FOUND, {
|
|
115
|
-
code: "tracker_root_missing",
|
|
116
|
-
reason: "missing",
|
|
117
|
-
nextSteps: [
|
|
118
|
-
"Confirm the tracker root path and retry the SDK read.",
|
|
119
|
-
"Initialize a tracker before enumerating its item metadata.",
|
|
120
|
-
],
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
if (isErrno(error, "ENOTDIR")) {
|
|
124
|
-
throw trackerRootNotDirectoryError(pmRoot);
|
|
125
|
-
}
|
|
126
|
-
if (isErrno(error, "EACCES") || isErrno(error, "EPERM")) {
|
|
127
|
-
throw trackerRootUnreadableError(pmRoot);
|
|
128
|
-
}
|
|
129
|
-
throw error;
|
|
130
|
-
}
|
|
131
|
-
if (!stats.isDirectory()) {
|
|
132
|
-
throw trackerRootNotDirectoryError(pmRoot);
|
|
133
|
-
}
|
|
134
|
-
if (process.platform !== "win32" &&
|
|
135
|
-
((stats.mode & 0o444) === 0 || (stats.mode & 0o111) === 0)) {
|
|
136
|
-
throw trackerRootUnreadableError(pmRoot);
|
|
137
|
-
}
|
|
138
|
-
try {
|
|
139
|
-
const directory = await fs.opendir(pmRoot);
|
|
140
|
-
await directory.close();
|
|
141
|
-
}
|
|
142
|
-
catch (error) {
|
|
143
|
-
if (isErrno(error, "EACCES") || isErrno(error, "EPERM")) {
|
|
144
|
-
throw trackerRootUnreadableError(pmRoot);
|
|
145
|
-
}
|
|
146
|
-
throw error;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
64
|
/** Implements locate item for the public runtime surface of this module. */
|
|
150
65
|
export async function locateItem(pmRoot, rawId, idPrefix = "pm-", preferredFormat, typeToFolder = TYPE_TO_FOLDER) {
|
|
151
66
|
const normalizedId = normalizeItemId(rawId, idPrefix);
|
|
@@ -189,7 +104,7 @@ export async function readLocatedItem(item, options = {}) {
|
|
|
189
104
|
}
|
|
190
105
|
/** Implements list all item metadata for the public runtime surface of this module. */
|
|
191
106
|
export async function listAllItemMetadata(pmRoot, preferredFormat, typeToFolder = TYPE_TO_FOLDER, warnings, schema) {
|
|
192
|
-
await
|
|
107
|
+
await assertReadableTrackerRoot(pmRoot);
|
|
193
108
|
const documents = await listAllDocumentsCached(pmRoot, preferredFormat, typeToFolder, warnings, schema);
|
|
194
109
|
return documents.map((document) => document.metadata);
|
|
195
110
|
}
|
|
@@ -200,13 +115,13 @@ export async function listAllItemMetadata(pmRoot, preferredFormat, typeToFolder
|
|
|
200
115
|
* read just the light scalar/small fields — see {@link listAllDocumentsCachedLight}.
|
|
201
116
|
*/
|
|
202
117
|
export async function listAllItemMetadataLight(pmRoot, preferredFormat, typeToFolder = TYPE_TO_FOLDER, warnings, schema) {
|
|
203
|
-
await
|
|
118
|
+
await assertReadableTrackerRoot(pmRoot);
|
|
204
119
|
const documents = await listAllDocumentsCachedLight(pmRoot, preferredFormat, typeToFolder, warnings, schema);
|
|
205
120
|
return documents.map((document) => document.metadata);
|
|
206
121
|
}
|
|
207
122
|
/** List item metadata with bodies, optionally bypassing the derived-index fast path when an integrity workflow must re-read authoritative files. */
|
|
208
123
|
export async function listAllItemMetadataWithBody(pmRoot, preferredFormat, typeToFolder = TYPE_TO_FOLDER, warnings, schema, options = {}) {
|
|
209
|
-
await
|
|
124
|
+
await assertReadableTrackerRoot(pmRoot);
|
|
210
125
|
const candidates = await listAllDocumentCandidatesCached(pmRoot, preferredFormat, typeToFolder, warnings, schema, {
|
|
211
126
|
includeBody: true,
|
|
212
127
|
forceSourceScan: options.forceSourceScan,
|
|
@@ -727,4 +642,4 @@ export async function deleteItem(params) {
|
|
|
727
642
|
}
|
|
728
643
|
}
|
|
729
644
|
//# sourceMappingURL=item-store.js.map
|
|
730
|
-
//# debugId=
|
|
645
|
+
//# debugId=f49b5141-f348-5954-a87e-8fd957593113
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type PmCliErrorRecoveryPayload } from "../shared/errors.js";
|
|
2
|
+
/** Build the non-interactive, tokenized retry that initializes a selected tracker root. */
|
|
3
|
+
export declare function buildTrackerInitializationRecovery(pmRoot: string): PmCliErrorRecoveryPayload;
|
|
4
|
+
/** Require a tracker root to be a readable directory without requiring initialized settings. */
|
|
5
|
+
export declare function assertReadableTrackerRoot(pmRoot: string): Promise<void>;
|
|
6
|
+
/** Require the selected tracker root and its settings marker before an SDK command reads or mutates project state. */
|
|
7
|
+
export declare function assertInitializedTracker(pmRoot: string): Promise<void>;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module core/store/tracker-preflight
|
|
3
|
+
*
|
|
4
|
+
* Owns the filesystem preflight shared by tracker-reading SDK primitives.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="8b0efe32-43f5-51ed-b1d5-5c26a3ae5bf0")}catch(e){}}();
|
|
8
|
+
import fs from "node:fs/promises";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import { EXIT_CODE } from "../shared/constants.js";
|
|
11
|
+
import { PmCliError, } from "../shared/errors.js";
|
|
12
|
+
import { pathExists } from "../fs/fs-utils.js";
|
|
13
|
+
import { getSettingsPath } from "./paths.js";
|
|
14
|
+
function isErrno(error, code) {
|
|
15
|
+
return (typeof error === "object" &&
|
|
16
|
+
error !== null &&
|
|
17
|
+
"code" in error &&
|
|
18
|
+
error.code === code);
|
|
19
|
+
}
|
|
20
|
+
/** Build the non-interactive, tokenized retry that initializes a selected tracker root. */
|
|
21
|
+
export function buildTrackerInitializationRecovery(pmRoot) {
|
|
22
|
+
const suggestedRetryArguments = [
|
|
23
|
+
"--pm-path",
|
|
24
|
+
pmRoot,
|
|
25
|
+
"init",
|
|
26
|
+
"--defaults",
|
|
27
|
+
"--agent-guidance",
|
|
28
|
+
"skip",
|
|
29
|
+
];
|
|
30
|
+
return {
|
|
31
|
+
suggested_retry: `pm ${suggestedRetryArguments
|
|
32
|
+
.map((argument) => `'${argument.replaceAll("'", `'"'"'`)}'`)
|
|
33
|
+
.join(" ")}`,
|
|
34
|
+
suggested_retry_args: suggestedRetryArguments,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function trackerRootNotDirectoryError(pmRoot) {
|
|
38
|
+
return new PmCliError(`Tracker root is not a directory at ${pmRoot}.`, EXIT_CODE.USAGE, {
|
|
39
|
+
code: "tracker_root_not_directory",
|
|
40
|
+
reason: "not_a_directory",
|
|
41
|
+
resolved_path: pmRoot,
|
|
42
|
+
nextSteps: [
|
|
43
|
+
"Pass a tracker directory, usually <workspace>/.agents/pm, rather than a file path.",
|
|
44
|
+
],
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function trackerRootUnreadableError(pmRoot) {
|
|
48
|
+
return new PmCliError(`Tracker root is not readable at ${pmRoot}.`, EXIT_CODE.GENERIC_FAILURE, {
|
|
49
|
+
code: "tracker_root_unreadable",
|
|
50
|
+
reason: "unreadable",
|
|
51
|
+
resolved_path: pmRoot,
|
|
52
|
+
nextSteps: [
|
|
53
|
+
"Grant read and directory-search permission to the tracker root, then retry.",
|
|
54
|
+
],
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
async function assertMissingRootAncestors(pmRoot) {
|
|
58
|
+
const resolvedRoot = path.resolve(pmRoot);
|
|
59
|
+
const filesystemRoot = path.parse(resolvedRoot).root;
|
|
60
|
+
let ancestor = path.dirname(resolvedRoot);
|
|
61
|
+
while (ancestor !== filesystemRoot) {
|
|
62
|
+
let ancestorStats;
|
|
63
|
+
try {
|
|
64
|
+
ancestorStats = await fs.stat(ancestor);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
if (isErrno(error, "ENOTDIR")) {
|
|
68
|
+
throw trackerRootNotDirectoryError(pmRoot);
|
|
69
|
+
}
|
|
70
|
+
if (!isErrno(error, "ENOENT")) {
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
ancestor = path.dirname(ancestor);
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (!ancestorStats.isDirectory()) {
|
|
77
|
+
throw trackerRootNotDirectoryError(pmRoot);
|
|
78
|
+
}
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** Require a tracker root to be a readable directory without requiring initialized settings. */
|
|
83
|
+
export async function assertReadableTrackerRoot(pmRoot) {
|
|
84
|
+
let stats;
|
|
85
|
+
try {
|
|
86
|
+
stats = await fs.stat(pmRoot);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
if (isErrno(error, "ENOENT")) {
|
|
90
|
+
await assertMissingRootAncestors(pmRoot);
|
|
91
|
+
throw new PmCliError(`Tracker is not initialized at ${pmRoot}. Tracker root does not exist. Run pm init first.`, EXIT_CODE.NOT_FOUND, {
|
|
92
|
+
code: "tracker_root_missing",
|
|
93
|
+
reason: "missing",
|
|
94
|
+
resolved_path: pmRoot,
|
|
95
|
+
nextSteps: [
|
|
96
|
+
"Confirm the tracker root path or initialize it with the emitted retry.",
|
|
97
|
+
],
|
|
98
|
+
recovery: buildTrackerInitializationRecovery(pmRoot),
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
if (isErrno(error, "ENOTDIR")) {
|
|
102
|
+
throw trackerRootNotDirectoryError(pmRoot);
|
|
103
|
+
}
|
|
104
|
+
if (isErrno(error, "EACCES") || isErrno(error, "EPERM")) {
|
|
105
|
+
throw trackerRootUnreadableError(pmRoot);
|
|
106
|
+
}
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
if (!stats.isDirectory()) {
|
|
110
|
+
throw trackerRootNotDirectoryError(pmRoot);
|
|
111
|
+
}
|
|
112
|
+
if (process.platform !== "win32" &&
|
|
113
|
+
((stats.mode & 0o444) === 0 || (stats.mode & 0o111) === 0)) {
|
|
114
|
+
throw trackerRootUnreadableError(pmRoot);
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
const directory = await fs.opendir(pmRoot);
|
|
118
|
+
await directory.close();
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
if (isErrno(error, "EACCES") || isErrno(error, "EPERM")) {
|
|
122
|
+
throw trackerRootUnreadableError(pmRoot);
|
|
123
|
+
}
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/** Require the selected tracker root and its settings marker before an SDK command reads or mutates project state. */
|
|
128
|
+
export async function assertInitializedTracker(pmRoot) {
|
|
129
|
+
await assertReadableTrackerRoot(pmRoot);
|
|
130
|
+
if (await pathExists(getSettingsPath(pmRoot))) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
throw new PmCliError(`Tracker is not initialized at ${pmRoot}. Run pm init first.`, EXIT_CODE.NOT_FOUND, {
|
|
134
|
+
code: "tracker_not_initialized",
|
|
135
|
+
reason: "settings_missing",
|
|
136
|
+
resolved_path: pmRoot,
|
|
137
|
+
nextSteps: ["Initialize the selected tracker root with the emitted retry."],
|
|
138
|
+
recovery: buildTrackerInitializationRecovery(pmRoot),
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=tracker-preflight.js.map
|
|
142
|
+
//# debugId=8b0efe32-43f5-51ed-b1d5-5c26a3ae5bf0
|
|
@@ -37,7 +37,7 @@ export type PmRecoveryReferenceKind = (typeof PM_RECOVERY_REFERENCE_KINDS)[numbe
|
|
|
37
37
|
/** Behavioral promise attached to a recovery reference. */
|
|
38
38
|
export type PmRecoveryReferenceSemantics = "recovery" | "replacement" | "behavior_preserving";
|
|
39
39
|
/** Literal envelope fields recognized as recovery-reference producers. */
|
|
40
|
-
export declare const PM_RECOVERY_REFERENCE_FIELDS: readonly ("
|
|
40
|
+
export declare const PM_RECOVERY_REFERENCE_FIELDS: readonly ("suggested_retry" | "next_best_command" | "candidate_commands" | "next_steps" | "examples" | "restore_with" | "migration_hint" | "migration_hints" | "fallback_candidates" | "suggested_next_steps" | "example" | "candidate_command" | "next_step" | "retry_command")[];
|
|
41
41
|
/** One source file supplied to the producer-census analyzer. */
|
|
42
42
|
export interface PmRecoveryProducerSource {
|
|
43
43
|
/** Repository-relative source path. */
|