@unbrained/pm-cli 2026.8.16 → 2026.8.17
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 +30 -3
- package/README.md +13 -13
- package/dist/cli/public.d.ts +2 -0
- package/dist/cli/public.js +21 -0
- package/dist/cli/register-mutation.js +4 -4
- package/dist/cli-bundle/bundle-manifest.json +151 -151
- package/dist/cli-bundle/chunks/{chunk-I2LUWWR5.js → chunk-2QLOXC3V.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-URW4QRMI.js → chunk-3UEGXBMR.js} +22 -22
- package/dist/cli-bundle/chunks/chunk-4JPYF536.js +35 -0
- package/dist/cli-bundle/chunks/chunk-6VDLG2FC.js +13 -0
- package/dist/cli-bundle/chunks/chunk-7IBRGCHX.js +2 -0
- package/dist/cli-bundle/chunks/chunk-HBJAS566.js +8 -0
- package/dist/cli-bundle/chunks/chunk-ION3E43Q.js +197 -0
- package/dist/cli-bundle/chunks/{chunk-73UGEBRS.js → chunk-JOKATURE.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-RIS565OA.js → chunk-TPXZIBIV.js} +5 -5
- package/dist/cli-bundle/chunks/chunk-YM2YAMF7.js +2 -0
- package/dist/cli-bundle/chunks/{register-list-query-EYCXHZAG.js → register-list-query-Q7KII4G5.js} +2 -2
- package/dist/cli-bundle/chunks/register-mutation-4WBRPXLV.js +20 -0
- package/dist/cli-bundle/chunks/{register-operations-KGDNRMCL.js → register-operations-SSENDH5B.js} +2 -2
- package/dist/cli-bundle/chunks/{register-setup-NVXBOD5I.js → register-setup-DOSFBGKE.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-TZATVC4G.js → chunk-267MUUS6.js} +11 -11
- package/dist/cli-bundle/focused-chunks/chunk-2NNFLLNG.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-HAACPSUW.js → chunk-2QSAKMIH.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-6ROKKT4X.js → chunk-ATEY76SX.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-BUCG4ZI2.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-SSNDYZTM.js → chunk-CYFK5UPB.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-EHXIKD6K.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-J4UFYHOD.js → chunk-KGEXTMPG.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-KP2VQQVQ.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-MHPIL773.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-POEEAD2V.js +4 -0
- package/dist/cli-bundle/focused-chunks/{chunk-T46KLOIB.js → chunk-SALH6B6K.js} +47 -47
- package/dist/cli-bundle/focused-chunks/{chunk-CODV5LUT.js → chunk-SYZENPIT.js} +3 -3
- package/dist/cli-bundle/focused-chunks/{chunk-4JPEBFFC.js → chunk-XKAMP5OU.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-NJ5RLEFD.js → chunk-XPIC53VA.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-C7JUBRFP.js → chunk-ZQPGZZWQ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-ZT2DJS27.js +155 -0
- package/dist/cli-bundle/main.js +2 -2
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +1 -1
- package/dist/cli-bundle/sdk-core.js +31 -31
- 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 +4 -2
- package/dist/core/extensions/loader.js +10 -6
- package/dist/core/extensions/manifest-schema.d.ts +20 -0
- package/dist/core/extensions/manifest-schema.js +52 -0
- package/dist/core/history/replay.js +32 -14
- package/dist/core/schema/fields-file.d.ts +1 -1
- package/dist/core/schema/fields-file.js +2 -2
- package/dist/core/schema/runtime-field-values.js +115 -9
- package/dist/core/schema/runtime-schema.d.ts +3 -1
- package/dist/core/schema/runtime-schema.js +124 -3
- package/dist/core/shared/errors.d.ts +10 -0
- package/dist/core/shared/errors.js +2 -2
- package/dist/core/shared/time.d.ts +2 -0
- package/dist/core/shared/time.js +27 -2
- package/dist/sdk/agent/refusal-reachability.d.ts +46 -6
- package/dist/sdk/agent/refusal-reachability.js +350 -8
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +5 -4
- package/dist/sdk/compose.d.ts +6 -2
- package/dist/sdk/compose.js +33 -3
- package/dist/sdk/context-intent-contracts.d.ts +8 -4
- package/dist/sdk/context-intent-contracts.js +76 -31
- package/dist/sdk/dependency-flag-validation.d.ts +9 -2
- package/dist/sdk/dependency-flag-validation.js +101 -35
- package/dist/sdk/environment/host-environment-errors.js +25 -7
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +26 -2
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +14 -2
- package/dist/sdk/governance/assurance-action.d.ts +3 -7
- package/dist/sdk/governance/assurance-action.js +97 -2
- package/dist/sdk/governance/boundary-fixtures.d.ts +86 -0
- package/dist/sdk/governance/boundary-fixtures.js +201 -0
- package/dist/sdk/governance/defect-recurrence-signals.d.ts +10 -0
- package/dist/sdk/governance/defect-recurrence-signals.js +25 -0
- package/dist/sdk/governance/defect-recurrence.d.ts +242 -0
- package/dist/sdk/governance/defect-recurrence.js +523 -0
- package/dist/sdk/governance.d.ts +2 -0
- package/dist/sdk/governance.js +4 -2
- package/dist/sdk/graph/governance.js +3 -2
- package/dist/sdk/guide-topics.js +191 -2
- package/dist/sdk/index.d.ts +3 -0
- package/dist/sdk/index.js +4 -2
- package/dist/sdk/lifecycle/create.js +4 -2
- package/dist/sdk/lifecycle/update-many.js +15 -2
- package/dist/sdk/lifecycle/update.js +5 -2
- package/dist/sdk/linked-artifacts.js +63 -14
- package/dist/sdk/query/get.d.ts +2 -0
- package/dist/sdk/query/get.js +32 -7
- package/dist/sdk/relationship-analytics.js +90 -14
- package/dist/sdk/relationship-kinds/contract.d.ts +4 -0
- package/dist/sdk/relationship-kinds/contract.js +3 -2
- package/dist/sdk/relationships.d.ts +1 -1
- package/dist/sdk/relationships.js +11 -2
- package/dist/sdk/schema.d.ts +1 -0
- package/dist/sdk/schema.js +2 -2
- package/dist/sdk/test/execution.d.ts +6 -2
- package/dist/sdk/test/execution.js +39 -13
- package/dist/types.d.ts +29 -2
- package/dist/types.js +4 -2
- package/docs/CONFIGURATION.md +58 -1
- package/docs/CONTEXT_INTEGRITY_CONTRACTS.md +58 -0
- package/docs/DEFECT_RECURRENCE.md +134 -0
- package/docs/DEPENDENCY_KIND_CONTRACT.md +12 -2
- package/docs/README.md +2 -0
- package/docs/RELATIONSHIP_GRAPH.md +16 -2
- package/docs/SDK.md +38 -5
- package/docs/SDK_RUNTIME_BOUNDARIES.md +9 -1
- package/docs/TESTING.md +18 -1
- package/docs/TRUSTWORTHY_CONTEXT_EVIDENCE.md +1 -1
- package/marketplace.json +2 -2
- package/package.json +6 -4
- 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-claude/skills/pm-audit/SKILL.md +26 -0
- package/plugins/pm-claude/skills/pm-developer/SKILL.md +26 -0
- package/plugins/pm-claude/skills/pm-planner/SKILL.md +26 -0
- package/plugins/pm-claude/skills/pm-release/SKILL.md +26 -0
- package/plugins/pm-claude/skills/pm-workflow/SKILL.md +26 -0
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/pm-codex/skills/pm-auditor/SKILL.md +26 -0
- package/plugins/pm-codex/skills/pm-native/SKILL.md +26 -0
- package/plugins/pm-codex/skills/pm-release/SKILL.md +26 -0
- package/sdk/public-surface.json +588 -20
- package/dist/cli-bundle/chunks/chunk-47OQEOQB.js +0 -2
- package/dist/cli-bundle/chunks/chunk-HCIYWD6M.js +0 -35
- package/dist/cli-bundle/chunks/chunk-IC5W2T34.js +0 -2
- package/dist/cli-bundle/chunks/chunk-PANOOBIS.js +0 -13
- package/dist/cli-bundle/chunks/chunk-TK6N7HGM.js +0 -8
- package/dist/cli-bundle/chunks/chunk-TOFG2URD.js +0 -197
- package/dist/cli-bundle/chunks/register-mutation-7YVIG54J.js +0 -20
- package/dist/cli-bundle/focused-chunks/chunk-5NMFSX26.js +0 -155
- package/dist/cli-bundle/focused-chunks/chunk-725JSCMP.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-DQ6SMTBF.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-JX5Z344Q.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-L4RDYBIQ.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-QYZERYR5.js +0 -4
- package/dist/cli-bundle/focused-chunks/chunk-WY3WRPVN.js +0 -2
package/dist/core/shared/time.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Provides shared primitives and utilities for Time.
|
|
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]="7887e752-b1b8-5c5e-9dd8-93b41cb757af")}catch(e){}}();
|
|
8
8
|
import { PmCliError } from "./errors.js";
|
|
9
9
|
import { evictOldestMemoEntries } from "./memo.js";
|
|
10
10
|
import { EXIT_CODE } from "./constants.js";
|
|
@@ -15,6 +15,7 @@ const COMPACT_DATE = /^(\d{4})(\d{2})(\d{2})$/;
|
|
|
15
15
|
const COMPACT_DATETIME = /^(\d{4})(\d{2})(\d{2})(?:[T\s]?)(\d{2})(\d{2})(\d{2})?([.,]\d{1,3})?(Z|[+-]\d{2}:?\d{2})?$/i;
|
|
16
16
|
const HYPHEN_TIME = /^(\d{4}-\d{2}-\d{2})[T\s](\d{2})-(\d{2})(?:-(\d{2}))?([.,]\d{1,3})?(Z|[+-]\d{2}:?\d{2})?$/i;
|
|
17
17
|
const COMPACT_TIME = /^(\d{4}-\d{2}-\d{2})[T\s](\d{2})(\d{2})(\d{2})?([.,]\d{1,3})?(Z|[+-]\d{2}:?\d{2})?$/i;
|
|
18
|
+
const RFC_3339_DATE_TIME = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?(?:Z|[+-](\d{2}):(\d{2}))$/i;
|
|
18
19
|
/** Implements now iso for the public runtime surface of this module. */
|
|
19
20
|
export function nowIso() {
|
|
20
21
|
return nextReproducibleTimestamp() ?? new Date().toISOString();
|
|
@@ -23,6 +24,30 @@ export function nowIso() {
|
|
|
23
24
|
export function isTimestampLiteral(input) {
|
|
24
25
|
return Number.isFinite(Date.parse(input));
|
|
25
26
|
}
|
|
27
|
+
/** Return whether a string is a calendar-valid RFC 3339 date-time. */
|
|
28
|
+
export function isRfc3339DateTime(input) {
|
|
29
|
+
const match = RFC_3339_DATE_TIME.exec(input);
|
|
30
|
+
if (!match || !Number.isFinite(Date.parse(input)))
|
|
31
|
+
return false;
|
|
32
|
+
const [, yearRaw, monthRaw, dayRaw, hourRaw, minuteRaw, secondRaw, offsetHourRaw, offsetMinuteRaw,] = match;
|
|
33
|
+
const [year, month, day, hour, minute, second] = [
|
|
34
|
+
yearRaw,
|
|
35
|
+
monthRaw,
|
|
36
|
+
dayRaw,
|
|
37
|
+
hourRaw,
|
|
38
|
+
minuteRaw,
|
|
39
|
+
secondRaw,
|
|
40
|
+
].map(Number);
|
|
41
|
+
return (month >= 1 &&
|
|
42
|
+
month <= 12 &&
|
|
43
|
+
day >= 1 &&
|
|
44
|
+
day <= daysInUtcMonth(year, month - 1) &&
|
|
45
|
+
hour <= 23 &&
|
|
46
|
+
minute <= 59 &&
|
|
47
|
+
second <= 59 &&
|
|
48
|
+
(offsetHourRaw === undefined || Number(offsetHourRaw) <= 23) &&
|
|
49
|
+
(offsetMinuteRaw === undefined || Number(offsetMinuteRaw) <= 59));
|
|
50
|
+
}
|
|
26
51
|
/**
|
|
27
52
|
* Memoized `Date.parse` for {@link compareTimestampStrings}. Sort comparators call it
|
|
28
53
|
* O(n log n) times over a corpus whose timestamp strings repeat heavily, and
|
|
@@ -273,4 +298,4 @@ export const _testOnly = {
|
|
|
273
298
|
isWhitespaceCharacter,
|
|
274
299
|
};
|
|
275
300
|
//# sourceMappingURL=time.js.map
|
|
276
|
-
//# debugId=
|
|
301
|
+
//# debugId=7887e752-b1b8-5c5e-9dd8-93b41cb757af
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module sdk/agent/refusal-reachability
|
|
3
|
-
*
|
|
4
|
-
* Verifies real-entrypoint observations against refusal states declared by the
|
|
5
|
-
* generated public error-code catalog.
|
|
6
|
-
*/
|
|
7
1
|
import type { PmErrorCodeContract, PmErrorCodeClass } from "../error-code-catalog.js";
|
|
8
2
|
/** One recorded result from driving a real public entrypoint into a refusal. */
|
|
9
3
|
export interface PmRefusalProbeObservation {
|
|
@@ -42,6 +36,50 @@ export declare const PM_RECOVERY_REFERENCE_KINDS: readonly ["suggested_retry", "
|
|
|
42
36
|
export type PmRecoveryReferenceKind = (typeof PM_RECOVERY_REFERENCE_KINDS)[number];
|
|
43
37
|
/** Behavioral promise attached to a recovery reference. */
|
|
44
38
|
export type PmRecoveryReferenceSemantics = "recovery" | "replacement" | "behavior_preserving";
|
|
39
|
+
/** Literal envelope fields recognized as recovery-reference producers. */
|
|
40
|
+
export declare const PM_RECOVERY_REFERENCE_FIELDS: readonly ("restore_with" | "migration_hint" | "migration_hints" | "suggested_retry" | "next_best_command" | "fallback_candidates" | "examples" | "next_steps" | "suggested_next_steps" | "candidate_commands" | "candidate_command" | "example" | "next_step" | "retry_command")[];
|
|
41
|
+
/** One source file supplied to the producer-census analyzer. */
|
|
42
|
+
export interface PmRecoveryProducerSource {
|
|
43
|
+
/** Repository-relative source path. */
|
|
44
|
+
path: string;
|
|
45
|
+
/** Complete source text. */
|
|
46
|
+
content: string;
|
|
47
|
+
}
|
|
48
|
+
/** One literal recovery field emitted from a source location. */
|
|
49
|
+
export interface PmRecoveryProducerLocation {
|
|
50
|
+
/** Repository-relative producer source path. */
|
|
51
|
+
path: string;
|
|
52
|
+
/** One-based source line. */
|
|
53
|
+
line: number;
|
|
54
|
+
/** Literal structured-envelope field. */
|
|
55
|
+
field: (typeof PM_RECOVERY_REFERENCE_FIELDS)[number];
|
|
56
|
+
/** Normalized recovery kind. */
|
|
57
|
+
kind: PmRecoveryReferenceKind;
|
|
58
|
+
}
|
|
59
|
+
/** Producer-census failure that requires a new field contract or producer. */
|
|
60
|
+
export interface PmRecoveryProducerCensusFinding {
|
|
61
|
+
/** Stable finding kind. */
|
|
62
|
+
kind: "invalid_source" | "missing_kind_producer" | "unknown_recovery_field";
|
|
63
|
+
/** Source path or normalized kind. */
|
|
64
|
+
subject: string;
|
|
65
|
+
/** Actionable explanation. */
|
|
66
|
+
detail: string;
|
|
67
|
+
}
|
|
68
|
+
/** Complete literal producer-table census for recovery references. */
|
|
69
|
+
export interface PmRecoveryProducerCensusReport {
|
|
70
|
+
/** Whether every recovery kind has a producer and no unknown fields exist. */
|
|
71
|
+
ok: boolean;
|
|
72
|
+
/** Source files inspected. */
|
|
73
|
+
scanned_file_count: number;
|
|
74
|
+
/** Literal producer locations. */
|
|
75
|
+
producer_count: number;
|
|
76
|
+
/** Stable counts by normalized recovery kind. */
|
|
77
|
+
producer_count_by_kind: Record<PmRecoveryReferenceKind, number>;
|
|
78
|
+
/** Stable producer locations. */
|
|
79
|
+
producers: PmRecoveryProducerLocation[];
|
|
80
|
+
/** Missing-kind or unknown-field findings. */
|
|
81
|
+
findings: PmRecoveryProducerCensusFinding[];
|
|
82
|
+
}
|
|
45
83
|
/** One derived promise that another invocation or command path is reachable. */
|
|
46
84
|
export interface PmRecoveryReferenceObligation {
|
|
47
85
|
/** Stable reference identifier derived from its emitting envelope. */
|
|
@@ -101,6 +139,8 @@ export interface PmRecoveryReferenceReport {
|
|
|
101
139
|
/** Stable, sorted conformance findings. */
|
|
102
140
|
findings: PmRecoveryReferenceFinding[];
|
|
103
141
|
}
|
|
142
|
+
/** Census syntax-parsed structured-envelope producers without executing source code. */
|
|
143
|
+
export declare function censusPmRecoveryReferenceProducers(sources: readonly PmRecoveryProducerSource[]): PmRecoveryProducerCensusReport;
|
|
104
144
|
/** Derive typed obligations from every recognized recovery field in an emitted envelope. */
|
|
105
145
|
export declare function derivePmRecoveryReferenceObligations(probeId: string, envelope: unknown): PmRecoveryReferenceObligation[];
|
|
106
146
|
/** Compare declared refusal states with real-entrypoint observations. */
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* @module sdk/agent/refusal-reachability
|
|
3
|
+
*
|
|
4
|
+
* Verifies real-entrypoint observations against refusal states declared by the
|
|
5
|
+
* generated public error-code catalog.
|
|
6
|
+
*/
|
|
2
7
|
|
|
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]="
|
|
8
|
+
!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]="70af2366-a675-5631-8edb-4ebeef4bb786")}catch(e){}}();
|
|
9
|
+
import { stripTypeScriptTypes } from "node:module";
|
|
10
|
+
/** Recovery-reference kinds emitted by structured refusal envelopes. */
|
|
4
11
|
export const PM_RECOVERY_REFERENCE_KINDS = [
|
|
5
12
|
"suggested_retry",
|
|
6
13
|
"candidate_command",
|
|
@@ -11,12 +18,20 @@ export const PM_RECOVERY_REFERENCE_KINDS = [
|
|
|
11
18
|
];
|
|
12
19
|
const RECOVERY_REFERENCE_FIELD_CONTRACTS = {
|
|
13
20
|
suggested_retry: { kind: "suggested_retry", semantics: "recovery" },
|
|
21
|
+
retry_command: { kind: "suggested_retry", semantics: "recovery" },
|
|
14
22
|
candidate_command: { kind: "candidate_command", semantics: "recovery" },
|
|
15
23
|
candidate_commands: { kind: "candidate_command", semantics: "recovery" },
|
|
24
|
+
fallback_candidates: {
|
|
25
|
+
kind: "candidate_command",
|
|
26
|
+
semantics: "recovery",
|
|
27
|
+
nested_value_field: "command",
|
|
28
|
+
},
|
|
29
|
+
next_best_command: { kind: "candidate_command", semantics: "recovery" },
|
|
16
30
|
example: { kind: "example", semantics: "recovery" },
|
|
17
31
|
examples: { kind: "example", semantics: "recovery" },
|
|
18
32
|
next_step: { kind: "next_step", semantics: "recovery" },
|
|
19
33
|
next_steps: { kind: "next_step", semantics: "recovery" },
|
|
34
|
+
suggested_next_steps: { kind: "next_step", semantics: "recovery" },
|
|
20
35
|
migration_hint: { kind: "migration_hint", semantics: "replacement" },
|
|
21
36
|
migration_hints: { kind: "migration_hint", semantics: "replacement" },
|
|
22
37
|
restore_with: {
|
|
@@ -24,6 +39,322 @@ const RECOVERY_REFERENCE_FIELD_CONTRACTS = {
|
|
|
24
39
|
semantics: "behavior_preserving",
|
|
25
40
|
},
|
|
26
41
|
};
|
|
42
|
+
/** Literal envelope fields recognized as recovery-reference producers. */
|
|
43
|
+
export const PM_RECOVERY_REFERENCE_FIELDS = Object.freeze(Object.keys(RECOVERY_REFERENCE_FIELD_CONTRACTS));
|
|
44
|
+
/** Resolve an own recovery-field contract without trusting object prototypes. */
|
|
45
|
+
function recoveryReferenceContract(field) {
|
|
46
|
+
if (!Object.hasOwn(RECOVERY_REFERENCE_FIELD_CONTRACTS, field))
|
|
47
|
+
return undefined;
|
|
48
|
+
return RECOVERY_REFERENCE_FIELD_CONTRACTS[field];
|
|
49
|
+
}
|
|
50
|
+
const SOURCE_REGEXP_PREFIX_PUNCTUATORS = new Set([
|
|
51
|
+
..."=([{,:;!?&|+-*%^~<>",
|
|
52
|
+
"=>",
|
|
53
|
+
]);
|
|
54
|
+
function compareCodeUnits(left, right) {
|
|
55
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
56
|
+
}
|
|
57
|
+
function skipQuotedSourceToken(source, index) {
|
|
58
|
+
const quote = source[index];
|
|
59
|
+
let next = index + 1;
|
|
60
|
+
let value = "";
|
|
61
|
+
while (next < source.length && source[next] !== quote) {
|
|
62
|
+
if (source[next] === "\\")
|
|
63
|
+
next += 2;
|
|
64
|
+
else {
|
|
65
|
+
value += source[next];
|
|
66
|
+
next += 1;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (source[next] === quote)
|
|
70
|
+
next += 1;
|
|
71
|
+
return { next, value };
|
|
72
|
+
}
|
|
73
|
+
function canStartRegularExpression(previous) {
|
|
74
|
+
return (previous === undefined ||
|
|
75
|
+
(previous.kind === "punctuator" &&
|
|
76
|
+
SOURCE_REGEXP_PREFIX_PUNCTUATORS.has(previous.value)) ||
|
|
77
|
+
(previous.kind === "identifier" &&
|
|
78
|
+
["return", "case", "throw", "else", "yield"].includes(previous.value)));
|
|
79
|
+
}
|
|
80
|
+
function sourceTriviaEnd(source, index) {
|
|
81
|
+
if (/\s/u.test(source[index]))
|
|
82
|
+
return index + 1;
|
|
83
|
+
if (source.startsWith("//", index)) {
|
|
84
|
+
const newline = source.indexOf("\n", index + 2);
|
|
85
|
+
return newline === -1 ? source.length : newline + 1;
|
|
86
|
+
}
|
|
87
|
+
if (!source.startsWith("/*", index))
|
|
88
|
+
return undefined;
|
|
89
|
+
// stripTypeScriptTypes validates block-comment termination before tokenization.
|
|
90
|
+
return source.indexOf("*/", index + 2) + 2;
|
|
91
|
+
}
|
|
92
|
+
function regularExpressionEnd(source, index, previous) {
|
|
93
|
+
if (source[index] !== "/" || !canStartRegularExpression(previous))
|
|
94
|
+
return undefined;
|
|
95
|
+
let next = index + 1;
|
|
96
|
+
let inClass = false;
|
|
97
|
+
while (next < source.length) {
|
|
98
|
+
if (source[next] === "\\")
|
|
99
|
+
next += 2;
|
|
100
|
+
else if (source[next] === "[") {
|
|
101
|
+
inClass = true;
|
|
102
|
+
next += 1;
|
|
103
|
+
}
|
|
104
|
+
else if (source[next] === "]") {
|
|
105
|
+
inClass = false;
|
|
106
|
+
next += 1;
|
|
107
|
+
}
|
|
108
|
+
else if (source[next] === "/" && !inClass) {
|
|
109
|
+
next += 1;
|
|
110
|
+
while (/[A-Za-z]/u.test(source.charAt(next)))
|
|
111
|
+
next += 1;
|
|
112
|
+
return next;
|
|
113
|
+
}
|
|
114
|
+
else
|
|
115
|
+
next += 1;
|
|
116
|
+
}
|
|
117
|
+
return next;
|
|
118
|
+
}
|
|
119
|
+
function readSourceSyntaxToken(source, index) {
|
|
120
|
+
const character = source[index];
|
|
121
|
+
if (character === "'" || character === '"' || character === "`") {
|
|
122
|
+
const quoted = skipQuotedSourceToken(source, index);
|
|
123
|
+
return character === "`"
|
|
124
|
+
? { next: quoted.next }
|
|
125
|
+
: {
|
|
126
|
+
next: quoted.next,
|
|
127
|
+
token: { kind: "string", value: quoted.value, offset: index + 1 },
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
if (/[A-Za-z_$]/u.test(character)) {
|
|
131
|
+
let next = index + 1;
|
|
132
|
+
while (/[A-Za-z0-9_$]/u.test(source[next] ?? ""))
|
|
133
|
+
next += 1;
|
|
134
|
+
return {
|
|
135
|
+
next,
|
|
136
|
+
token: {
|
|
137
|
+
kind: "identifier",
|
|
138
|
+
value: source.slice(index, next),
|
|
139
|
+
offset: index,
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
const punctuator = source.startsWith("=>", index) ? "=>" : character;
|
|
144
|
+
return {
|
|
145
|
+
next: index + punctuator.length,
|
|
146
|
+
token: { kind: "punctuator", value: punctuator, offset: index },
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/** Tokenize executable JavaScript while ignoring comments, templates, and regex bodies. */
|
|
150
|
+
function tokenizeExecutableSource(source) {
|
|
151
|
+
const tokens = [];
|
|
152
|
+
let index = 0;
|
|
153
|
+
while (index < source.length) {
|
|
154
|
+
const ignoredEnd = sourceTriviaEnd(source, index);
|
|
155
|
+
if (ignoredEnd !== undefined) {
|
|
156
|
+
index = ignoredEnd;
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
const regexEnd = regularExpressionEnd(source, index, tokens.at(-1));
|
|
160
|
+
if (regexEnd !== undefined) {
|
|
161
|
+
index = regexEnd;
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
const read = readSourceSyntaxToken(source, index);
|
|
165
|
+
if (read.token)
|
|
166
|
+
tokens.push(read.token);
|
|
167
|
+
index = read.next;
|
|
168
|
+
}
|
|
169
|
+
return tokens;
|
|
170
|
+
}
|
|
171
|
+
const SOURCE_BRACE_FRAME_KINDS = new Set([
|
|
172
|
+
"object",
|
|
173
|
+
"block",
|
|
174
|
+
"pattern",
|
|
175
|
+
]);
|
|
176
|
+
const SOURCE_PATTERN_DECLARATIONS = new Set(["const", "let", "var"]);
|
|
177
|
+
const SOURCE_CLOSING_TOKENS = new Set(["}", ")", "]"]);
|
|
178
|
+
const SOURCE_OBJECT_PRECEDERS = new Set([
|
|
179
|
+
"=",
|
|
180
|
+
"(",
|
|
181
|
+
"[",
|
|
182
|
+
",",
|
|
183
|
+
":",
|
|
184
|
+
"?",
|
|
185
|
+
"return",
|
|
186
|
+
]);
|
|
187
|
+
function objectFrameKind(tokens, index, stack) {
|
|
188
|
+
const enclosingBrace = [...stack]
|
|
189
|
+
.reverse()
|
|
190
|
+
.find((frame) => SOURCE_BRACE_FRAME_KINDS.has(frame.kind));
|
|
191
|
+
if (enclosingBrace?.kind === "pattern")
|
|
192
|
+
return "pattern";
|
|
193
|
+
if (stack.at(-1)?.kind === "paren" && stack.at(-1)?.parameter_list)
|
|
194
|
+
return "pattern";
|
|
195
|
+
const previous = tokens[index - 1];
|
|
196
|
+
if (previous?.kind === "identifier" &&
|
|
197
|
+
SOURCE_PATTERN_DECLARATIONS.has(previous.value)) {
|
|
198
|
+
return "pattern";
|
|
199
|
+
}
|
|
200
|
+
if (previous?.value === "=>" || previous?.value === ")")
|
|
201
|
+
return "block";
|
|
202
|
+
return previous && SOURCE_OBJECT_PRECEDERS.has(previous.value)
|
|
203
|
+
? "object"
|
|
204
|
+
: "block";
|
|
205
|
+
}
|
|
206
|
+
function openingSourceFrame(tokens, index, stack) {
|
|
207
|
+
const token = tokens[index];
|
|
208
|
+
if (token.value === "{") {
|
|
209
|
+
const kind = objectFrameKind(tokens, index, stack);
|
|
210
|
+
return {
|
|
211
|
+
kind,
|
|
212
|
+
...(kind === "object" ? { member_start: true, candidates: [] } : {}),
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
if (token.value === "[")
|
|
216
|
+
return { kind: "array" };
|
|
217
|
+
if (token.value !== "(")
|
|
218
|
+
return undefined;
|
|
219
|
+
const previous = tokens[index - 1];
|
|
220
|
+
const beforePrevious = tokens[index - 2];
|
|
221
|
+
const parameterList = previous?.value === "function" || beforePrevious?.value === "function";
|
|
222
|
+
return { kind: "paren", ...(parameterList ? { parameter_list: true } : {}) };
|
|
223
|
+
}
|
|
224
|
+
function staticObjectMember(frame, token, next) {
|
|
225
|
+
if (frame?.kind !== "object" ||
|
|
226
|
+
!frame.member_start ||
|
|
227
|
+
(token.kind !== "identifier" && token.kind !== "string") ||
|
|
228
|
+
next?.value !== ":" ||
|
|
229
|
+
!/^[A-Za-z][A-Za-z0-9_]*$/u.test(token.value)) {
|
|
230
|
+
return undefined;
|
|
231
|
+
}
|
|
232
|
+
return { field: token.value, offset: token.offset };
|
|
233
|
+
}
|
|
234
|
+
function isPatternLikeObjectClosure(tokens, index) {
|
|
235
|
+
return ((tokens[index + 1]?.value === ")" && tokens[index + 2]?.value === "=>") ||
|
|
236
|
+
tokens[index + 1]?.value === "=");
|
|
237
|
+
}
|
|
238
|
+
/** Parse static object-literal members without treating patterns or labels as producers. */
|
|
239
|
+
function scanSourcePropertyTokens(source) {
|
|
240
|
+
const tokens = tokenizeExecutableSource(stripTypeScriptTypes(source, { mode: "strip" }));
|
|
241
|
+
const properties = [];
|
|
242
|
+
const stack = [];
|
|
243
|
+
for (const [index, token] of tokens.entries()) {
|
|
244
|
+
const frame = stack.at(-1);
|
|
245
|
+
const property = staticObjectMember(frame, token, tokens[index + 1]);
|
|
246
|
+
if (property)
|
|
247
|
+
frame.candidates.push(property);
|
|
248
|
+
const opening = openingSourceFrame(tokens, index, stack);
|
|
249
|
+
if (opening) {
|
|
250
|
+
stack.push(opening);
|
|
251
|
+
}
|
|
252
|
+
else if (SOURCE_CLOSING_TOKENS.has(token.value)) {
|
|
253
|
+
const closed = stack.pop();
|
|
254
|
+
if (closed?.kind === "object" &&
|
|
255
|
+
!isPatternLikeObjectClosure(tokens, index)) {
|
|
256
|
+
properties.push(...closed.candidates);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
else if (token.value === "," && frame?.kind === "object") {
|
|
260
|
+
frame.member_start = true;
|
|
261
|
+
}
|
|
262
|
+
else if (frame?.kind === "object" && token.value !== ":") {
|
|
263
|
+
frame.member_start = false;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return properties;
|
|
267
|
+
}
|
|
268
|
+
function sourceLineStarts(source) {
|
|
269
|
+
const starts = [0];
|
|
270
|
+
for (let index = 0; index < source.length; index += 1) {
|
|
271
|
+
if (source[index] === "\n")
|
|
272
|
+
starts.push(index + 1);
|
|
273
|
+
}
|
|
274
|
+
return starts;
|
|
275
|
+
}
|
|
276
|
+
function sourceLineAtOffset(starts, offset) {
|
|
277
|
+
let low = 0;
|
|
278
|
+
let high = starts.length;
|
|
279
|
+
while (low < high) {
|
|
280
|
+
const middle = Math.floor((low + high) / 2);
|
|
281
|
+
if (starts[middle] <= offset)
|
|
282
|
+
low = middle + 1;
|
|
283
|
+
else
|
|
284
|
+
high = middle;
|
|
285
|
+
}
|
|
286
|
+
return low;
|
|
287
|
+
}
|
|
288
|
+
/** Census syntax-parsed structured-envelope producers without executing source code. */
|
|
289
|
+
export function censusPmRecoveryReferenceProducers(sources) {
|
|
290
|
+
const producers = [];
|
|
291
|
+
const findings = [];
|
|
292
|
+
for (const source of [...sources].sort((left, right) => compareCodeUnits(left.path, right.path))) {
|
|
293
|
+
const lineStarts = sourceLineStarts(source.content);
|
|
294
|
+
let properties;
|
|
295
|
+
try {
|
|
296
|
+
properties = scanSourcePropertyTokens(source.content);
|
|
297
|
+
}
|
|
298
|
+
catch (error) {
|
|
299
|
+
findings.push({
|
|
300
|
+
kind: "invalid_source",
|
|
301
|
+
subject: source.path,
|
|
302
|
+
detail: `${source.path} could not be parsed for recovery producers: ${String(error)}.`,
|
|
303
|
+
});
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
for (const property of properties) {
|
|
307
|
+
const field = property.field;
|
|
308
|
+
const line = sourceLineAtOffset(lineStarts, property.offset);
|
|
309
|
+
const contract = recoveryReferenceContract(field);
|
|
310
|
+
if (contract) {
|
|
311
|
+
producers.push({
|
|
312
|
+
path: source.path,
|
|
313
|
+
line,
|
|
314
|
+
field: field,
|
|
315
|
+
kind: contract.kind,
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
else if (/(?:retry_command|candidate_command|fallback_candidate|next_best_command|example|next_step|migration_hint|restore_with)/u.test(field) &&
|
|
319
|
+
!/(?:_total|_truncated)$/u.test(field)) {
|
|
320
|
+
findings.push({
|
|
321
|
+
kind: "unknown_recovery_field",
|
|
322
|
+
subject: `${source.path}:${line}:${field}`,
|
|
323
|
+
detail: `${field} resembles a recovery reference but has no typed field contract.`,
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
const producerCountByKind = Object.fromEntries(PM_RECOVERY_REFERENCE_KINDS.map((kind) => [
|
|
329
|
+
kind,
|
|
330
|
+
producers.filter((producer) => producer.kind === kind).length,
|
|
331
|
+
]));
|
|
332
|
+
for (const kind of PM_RECOVERY_REFERENCE_KINDS) {
|
|
333
|
+
if (producerCountByKind[kind] === 0) {
|
|
334
|
+
findings.push({
|
|
335
|
+
kind: "missing_kind_producer",
|
|
336
|
+
subject: kind,
|
|
337
|
+
detail: `No source producer emits the ${kind} recovery-reference kind.`,
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
producers.sort((left, right) => left.path !== right.path
|
|
342
|
+
? compareCodeUnits(left.path, right.path)
|
|
343
|
+
: left.line !== right.line
|
|
344
|
+
? left.line - right.line
|
|
345
|
+
: compareCodeUnits(left.field, right.field));
|
|
346
|
+
findings.sort((left, right) => left.subject !== right.subject
|
|
347
|
+
? compareCodeUnits(left.subject, right.subject)
|
|
348
|
+
: compareCodeUnits(left.kind, right.kind));
|
|
349
|
+
return {
|
|
350
|
+
ok: findings.length === 0,
|
|
351
|
+
scanned_file_count: sources.length,
|
|
352
|
+
producer_count: producers.length,
|
|
353
|
+
producer_count_by_kind: producerCountByKind,
|
|
354
|
+
producers,
|
|
355
|
+
findings,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
27
358
|
/** Derive typed obligations from every recognized recovery field in an emitted envelope. */
|
|
28
359
|
export function derivePmRecoveryReferenceObligations(probeId, envelope) {
|
|
29
360
|
const obligations = [];
|
|
@@ -34,16 +365,27 @@ export function derivePmRecoveryReferenceObligations(probeId, envelope) {
|
|
|
34
365
|
}
|
|
35
366
|
if (typeof value !== "object" || value === null)
|
|
36
367
|
return;
|
|
37
|
-
for (const [key, entry] of Object.entries(value).sort(([left], [right]) => left
|
|
38
|
-
const baseContract =
|
|
368
|
+
for (const [key, entry] of Object.entries(value).sort(([left], [right]) => compareCodeUnits(left, right))) {
|
|
369
|
+
const baseContract = recoveryReferenceContract(key);
|
|
39
370
|
const contract = baseContract?.kind === "migration_hint" &&
|
|
40
371
|
value.semantics === "behavior_preserving"
|
|
41
372
|
? { ...baseContract, semantics: "behavior_preserving" }
|
|
42
373
|
: baseContract;
|
|
43
|
-
const entries =
|
|
374
|
+
const entries = [entry].flat();
|
|
44
375
|
if (contract !== undefined) {
|
|
45
376
|
entries.forEach((candidate, index) => {
|
|
46
|
-
|
|
377
|
+
const nestedValueField = "nested_value_field" in contract &&
|
|
378
|
+
typeof contract.nested_value_field === "string"
|
|
379
|
+
? contract.nested_value_field
|
|
380
|
+
: undefined;
|
|
381
|
+
const resolvedCandidate = nestedValueField &&
|
|
382
|
+
typeof candidate === "object" &&
|
|
383
|
+
candidate !== null &&
|
|
384
|
+
!Array.isArray(candidate)
|
|
385
|
+
? candidate[nestedValueField]
|
|
386
|
+
: candidate;
|
|
387
|
+
if (typeof resolvedCandidate !== "string" ||
|
|
388
|
+
resolvedCandidate.trim().length === 0)
|
|
47
389
|
return;
|
|
48
390
|
const coordinate = [...path, key, String(index)]
|
|
49
391
|
.map((segment) => encodeURIComponent(segment))
|
|
@@ -53,7 +395,7 @@ export function derivePmRecoveryReferenceObligations(probeId, envelope) {
|
|
|
53
395
|
probe_id: probeId,
|
|
54
396
|
kind: contract.kind,
|
|
55
397
|
semantics: contract.semantics,
|
|
56
|
-
value:
|
|
398
|
+
value: resolvedCandidate,
|
|
57
399
|
});
|
|
58
400
|
});
|
|
59
401
|
}
|
|
@@ -225,4 +567,4 @@ export function verifyPmRecoveryReferences(obligations, observations) {
|
|
|
225
567
|
};
|
|
226
568
|
}
|
|
227
569
|
//# sourceMappingURL=refusal-reachability.js.map
|
|
228
|
-
//# debugId=
|
|
570
|
+
//# debugId=70af2366-a675-5631-8edb-4ebeef4bb786
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Defines SDK command-contract metadata for Tool Parameter Tables.
|
|
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]="4749819e-f2af-5a17-9d32-2e2770c497c3")}catch(e){}}();
|
|
8
8
|
import { PLAN_HARNESS_VALUES, PLAN_MODE_VALUES, PLAN_STEP_LINK_KIND_VALUES, PLAN_STEP_STATUS_VALUES, } from "../../types/index.js";
|
|
9
9
|
import { PM_READ_OUTPUT_SESSION_MAX_SEEN_ITEM_IDS } from "../read-output-session.js";
|
|
10
10
|
import { ASSURANCE_DEFINITION_SCHEMA } from "./schemas/assurance-definition.js";
|
|
@@ -664,6 +664,7 @@ export const PM_TOOL_ACTION_SCOPED_PARAMETER_PROPERTIES = {
|
|
|
664
664
|
"apply",
|
|
665
665
|
"derive",
|
|
666
666
|
"promote",
|
|
667
|
+
"risk",
|
|
667
668
|
],
|
|
668
669
|
},
|
|
669
670
|
preset: {
|
|
@@ -1893,8 +1894,8 @@ export const PM_TOOL_PARAMETER_METADATA = {
|
|
|
1893
1894
|
export const PM_TOOL_ACTION_SCOPED_PARAMETER_METADATA = {
|
|
1894
1895
|
assurance: {
|
|
1895
1896
|
subcommand: {
|
|
1896
|
-
description: "Assurance operation: list, show, put, remove, run, verdicts, presets, apply, derive, or
|
|
1897
|
-
examples: ["list", "run", "derive", "promote"],
|
|
1897
|
+
description: "Assurance operation: list, show, put, remove, run, verdicts, presets, apply, derive, promote, or risk.",
|
|
1898
|
+
examples: ["list", "run", "derive", "promote", "risk"],
|
|
1898
1899
|
},
|
|
1899
1900
|
kind: {
|
|
1900
1901
|
description: "Assurance declaration kind for registry operations: measurement, assertion, or gate.",
|
|
@@ -2066,4 +2067,4 @@ export const PM_TOOL_ACTION_SCOPED_PARAMETER_METADATA = {
|
|
|
2066
2067
|
},
|
|
2067
2068
|
};
|
|
2068
2069
|
//# sourceMappingURL=tool-parameter-tables.js.map
|
|
2069
|
-
//# debugId=
|
|
2070
|
+
//# debugId=4749819e-f2af-5a17-9d32-2e2770c497c3
|
package/dist/sdk/compose.d.ts
CHANGED
|
@@ -460,7 +460,7 @@ export interface ExtensionManifestCompatibilityManifest {
|
|
|
460
460
|
* load, while `*_unchecked`/`*_exceeded_warn` are advisory (the extension still
|
|
461
461
|
* loads).
|
|
462
462
|
*/
|
|
463
|
-
export type ExtensionManifestCompatibilityCode = "pm_min_version_invalid" | "pm_min_version_unchecked" | "pm_min_version_unmet" | "pm_max_version_invalid" | "pm_max_version_unchecked" | "pm_max_version_exceeded" | "pm_max_version_exceeded_warn";
|
|
463
|
+
export type ExtensionManifestCompatibilityCode = "pm_min_version_invalid" | "pm_min_version_unchecked" | "pm_min_version_unmet" | "pm_max_version_invalid" | "pm_max_version_unchecked" | "pm_max_version_exceeded" | "pm_max_version_exceeded_warn" | "manifest_unknown_key" | "no_version_bounds_declared";
|
|
464
464
|
/**
|
|
465
465
|
* A single version-bound issue {@link checkExtensionManifestCompatibility} found
|
|
466
466
|
* when evaluating a manifest against a target pm version.
|
|
@@ -471,13 +471,17 @@ export interface ExtensionManifestCompatibilityFinding {
|
|
|
471
471
|
/** `error` when the bound blocks the load against the target version, `warning` when it is advisory. */
|
|
472
472
|
severity: "error" | "warning";
|
|
473
473
|
/** Which manifest bound produced the finding. */
|
|
474
|
-
constraint: PmVersionBoundKind;
|
|
474
|
+
constraint: PmVersionBoundKind | "manifest";
|
|
475
475
|
/** The declared bound value, verbatim. */
|
|
476
476
|
required: string;
|
|
477
477
|
/** The target pm version the bound was evaluated against. */
|
|
478
478
|
current: string;
|
|
479
479
|
/** Human-readable explanation of the outcome and its effect on loading. */
|
|
480
480
|
message: string;
|
|
481
|
+
/** JSON-style manifest location responsible for a schema-level finding. */
|
|
482
|
+
path?: string;
|
|
483
|
+
/** Canonical manifest key that replaces a recognized legacy or mistaken spelling. */
|
|
484
|
+
suggested_key?: "pm_min_version" | "pm_max_version";
|
|
481
485
|
}
|
|
482
486
|
/**
|
|
483
487
|
* The structured result of {@link checkExtensionManifestCompatibility}.
|
package/dist/sdk/compose.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
|
|
2
|
-
!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]="
|
|
2
|
+
!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]="705476d3-74b8-540d-b646-956e24f703d4")}catch(e){}}();
|
|
3
3
|
import { normalizeKnownExtensionCapability, resolveLegacyExtensionCapabilityAlias, } from "../core/extensions/extension-capability-aliases.js";
|
|
4
4
|
import { normalizeCommandName } from "../core/extensions/extension-runtime-helpers.js";
|
|
5
5
|
import { RESERVED_ITEM_FIELD_NAMES } from "../core/extensions/item-fields.js";
|
|
6
6
|
import { describeExtensionLongFlagFailure, findExtensionFlagTokenFailure, } from "../core/extensions/flag-definition-validation.js";
|
|
7
7
|
import { evaluatePmMaxVersionBound, evaluatePmMinVersionBound, } from "../core/extensions/version-compat.js";
|
|
8
|
+
import { inspectExtensionManifestSchema } from "../core/extensions/manifest-schema.js";
|
|
8
9
|
/**
|
|
9
10
|
* Typed identity helper for extension module exports.
|
|
10
11
|
*
|
|
@@ -903,7 +904,7 @@ function toCompatibilityFinding(evaluation, pmVersion) {
|
|
|
903
904
|
return null;
|
|
904
905
|
}
|
|
905
906
|
const code = `${evaluation.kind}_${evaluation.status}`;
|
|
906
|
-
let message;
|
|
907
|
+
let message = "";
|
|
907
908
|
switch (code) {
|
|
908
909
|
case "pm_min_version_invalid":
|
|
909
910
|
message = `pm_min_version "${evaluation.required}" is not a valid version; the extension is treated as incompatible and the loader skips it.`;
|
|
@@ -962,6 +963,35 @@ export function checkExtensionManifestCompatibility(manifest, target) {
|
|
|
962
963
|
const minEvaluation = evaluatePmMinVersionBound(manifest.pm_min_version, target.pmVersion);
|
|
963
964
|
const maxEvaluation = evaluatePmMaxVersionBound(manifest.pm_max_version, target.pmVersion, target.pmMaxVersionExceededMode ?? "block");
|
|
964
965
|
const findings = [];
|
|
966
|
+
const schema = inspectExtensionManifestSchema(manifest);
|
|
967
|
+
for (const key of schema.unknownKeys) {
|
|
968
|
+
findings.push({
|
|
969
|
+
code: "manifest_unknown_key",
|
|
970
|
+
severity: "warning",
|
|
971
|
+
constraint: "manifest",
|
|
972
|
+
required: key,
|
|
973
|
+
current: target.pmVersion,
|
|
974
|
+
path: key,
|
|
975
|
+
...(key === "compatibility"
|
|
976
|
+
? { suggested_key: "pm_min_version" }
|
|
977
|
+
: {}),
|
|
978
|
+
message: key === "compatibility"
|
|
979
|
+
? 'Manifest key "compatibility" is ignored; declare the canonical pm_min_version and optional pm_max_version fields instead.'
|
|
980
|
+
: `Manifest key "${key}" is not part of the extension manifest contract and will be ignored.`,
|
|
981
|
+
});
|
|
982
|
+
}
|
|
983
|
+
if (schema.missingVersionBounds) {
|
|
984
|
+
findings.push({
|
|
985
|
+
code: "no_version_bounds_declared",
|
|
986
|
+
severity: "warning",
|
|
987
|
+
constraint: "manifest",
|
|
988
|
+
required: "pm_min_version",
|
|
989
|
+
current: target.pmVersion,
|
|
990
|
+
path: "$",
|
|
991
|
+
suggested_key: "pm_min_version",
|
|
992
|
+
message: "No canonical pm version bounds are declared; add pm_min_version so compatibility intent is explicit.",
|
|
993
|
+
});
|
|
994
|
+
}
|
|
965
995
|
const minFinding = toCompatibilityFinding(minEvaluation, target.pmVersion);
|
|
966
996
|
if (minFinding !== null) {
|
|
967
997
|
findings.push(minFinding);
|
|
@@ -1071,4 +1101,4 @@ export function preflightExtension(blueprint, options = {}) {
|
|
|
1071
1101
|
};
|
|
1072
1102
|
}
|
|
1073
1103
|
//# sourceMappingURL=compose.js.map
|
|
1074
|
-
//# debugId=
|
|
1104
|
+
//# debugId=705476d3-74b8-540d-b646-956e24f703d4
|