@unbrained/pm-cli 2026.8.5 → 2026.8.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/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +14 -0
- package/dist/cli/main.js +12 -37
- package/dist/cli/register-setup.d.ts +1 -1
- package/dist/cli/register-setup.js +46 -20
- package/dist/cli-bundle/bundle-manifest.json +391 -391
- package/dist/cli-bundle/chunks/append-XAJ5Z4XS.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-2WFXWAYX.js → chunk-343QETLI.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-RKAVWO3O.js → chunk-3KFVGGRE.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-VCKLFEUN.js → chunk-3ZJRFYY2.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-UZBWIUYD.js → chunk-4AVFKHHC.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-BPELKUQD.js → chunk-4OVGQW22.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-54FNT7U2.js → chunk-5PBP2ZP3.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-NY4T3JWN.js → chunk-5ZKQPA44.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-4YUBDMQM.js → chunk-A3XQ7VPU.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-OPVH7SKD.js → chunk-AJE3AHPD.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-V3774P7D.js → chunk-AOBDLU4T.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-VN5VITU3.js → chunk-AYRUGRNS.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-HWRRMBJO.js → chunk-BP6EMEDP.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-ZYHOB3SN.js → chunk-C3YABSJK.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-43HQQI6S.js → chunk-CA3BURYF.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-E2RKBKWB.js → chunk-D7I3TUGV.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-4VN6GS4U.js → chunk-DQGJ2RWT.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-YSO3YFZ4.js → chunk-DWOAOZHZ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-Q35VBGOQ.js → chunk-E7BFPLUZ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-LKDGK44W.js → chunk-F4NREH3G.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-OMXVBQ2N.js → chunk-FDBRXV25.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-3FTILRJ2.js → chunk-GU3TSEHD.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-HS7OVAUN.js +164 -0
- package/dist/cli-bundle/chunks/{chunk-OTHLDSFP.js → chunk-JFZIS6JF.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-7A5OT5J2.js → chunk-JQ4NZ5EB.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-BXQLRKWF.js → chunk-L6LGKJX3.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-CSI3WS5I.js → chunk-M357ZCOR.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-5ZBOIPGP.js → chunk-M4VEE3FK.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-7C4PTJG6.js → chunk-MCS73BKB.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-A62CYISG.js → chunk-MDTH7SAE.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-HNFD72UK.js → chunk-OXY3SJ3N.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-L3AZOELJ.js → chunk-PECV7L5T.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-DXDREUXT.js → chunk-Q3VOP62W.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-UP7DTVMD.js → chunk-QJ7C3JIW.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-42E7YPLG.js → chunk-R6LSRGPS.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-MHK6LIWE.js → chunk-R6RKEYYW.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-UN66FZRO.js → chunk-RAFUN7IX.js} +3 -3
- package/dist/cli-bundle/chunks/chunk-RUAU5OSH.js +2 -0
- package/dist/cli-bundle/chunks/chunk-SD3YXU2U.js +56 -0
- package/dist/cli-bundle/chunks/{chunk-SSF4PIUR.js → chunk-SV3YQ4RY.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-V3EUXXOF.js → chunk-SVV3DQES.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-45G53IU4.js → chunk-SXECIECW.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-T45OHXDW.js +8 -0
- package/dist/cli-bundle/chunks/{chunk-PMXJEU3F.js → chunk-TPKDJ5WL.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-M72BKL5Q.js → chunk-UVVXHGYS.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-WRL4KNDL.js → chunk-V663653R.js} +19 -19
- package/dist/cli-bundle/chunks/{chunk-R546TPDE.js → chunk-WSI5KZQJ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-6MSQJOTG.js → chunk-XPOQQJTX.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-XCEZYMNI.js → chunk-YCCDXBNU.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-LN2WFEU4.js → chunk-ZFBWCKYF.js} +2 -2
- package/dist/cli-bundle/chunks/close-DI66JMSB.js +2 -0
- package/dist/cli-bundle/chunks/close-many-VFKT6U3O.js +2 -0
- package/dist/cli-bundle/chunks/comments-E73HIEZJ.js +2 -0
- package/dist/cli-bundle/chunks/copy-WBYVLCPC.js +2 -0
- package/dist/cli-bundle/chunks/{create-XLKTXTUF.js → create-TG67IVFI.js} +2 -2
- package/dist/cli-bundle/chunks/delete-6XKUVVQN.js +2 -0
- package/dist/cli-bundle/chunks/{deps-ITTY3GIC.js → deps-AJUGP2OH.js} +2 -2
- package/dist/cli-bundle/chunks/{docs-W4OSRTYR.js → docs-QOCLDRKJ.js} +2 -2
- package/dist/cli-bundle/chunks/{files-EOK4AZI4.js → files-3ST5TY64.js} +2 -2
- package/dist/cli-bundle/chunks/focus-R2AWS63Y.js +2 -0
- package/dist/cli-bundle/chunks/{history-compact-7UGTMLL3.js → history-compact-7BJFML4S.js} +2 -2
- package/dist/cli-bundle/chunks/{history-redact-4DZRMD6Z.js → history-redact-WJN3HYXR.js} +2 -2
- package/dist/cli-bundle/chunks/{history-repair-UPOSZW5R.js → history-repair-XDNZUB7F.js} +2 -2
- package/dist/cli-bundle/chunks/{learnings-GMRNCBS3.js → learnings-SZMUPVNA.js} +2 -2
- package/dist/cli-bundle/chunks/{profile-2MUUMHRE.js → profile-KL53JIAC.js} +2 -2
- package/dist/cli-bundle/chunks/{register-list-query-LR3SQ5ZF.js → register-list-query-QH7ONPKU.js} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-SUOHFVWM.js → register-mutation-OCRQNZK4.js} +3 -3
- package/dist/cli-bundle/chunks/{register-operations-ARRRKOVN.js → register-operations-HIBJXRGB.js} +2 -2
- package/dist/cli-bundle/chunks/register-setup-QWBQ6HBS.js +2 -0
- package/dist/cli-bundle/chunks/restore-FXA5QPM7.js +2 -0
- package/dist/cli-bundle/chunks/{schema-FJ4EA3XF.js → schema-QJ27OTRV.js} +2 -2
- package/dist/cli-bundle/chunks/update-7GBO4SXG.js +2 -0
- package/dist/cli-bundle/chunks/update-many-VF6ZKQUO.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-B7LJWAZE.js → chunk-27DK4A5O.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-SV3O7TSH.js → chunk-4JC3AOGS.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-G6ETT4QK.js → chunk-6KDHXURF.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-PG2RIZBX.js → chunk-74CWP3A4.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-Y4LDYLLT.js → chunk-7AZDTGPA.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-7YTZ7A4E.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-A7BJ5SS6.js → chunk-CL3NB7VW.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-EAXXF2HW.js +4 -0
- package/dist/cli-bundle/focused-chunks/{chunk-UIL2M2NA.js → chunk-EYO4F74Z.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-7J5TUBUJ.js → chunk-GEYU23YS.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-WEM2E2PE.js → chunk-GIERI4YU.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-WVIVUWVL.js → chunk-GSW2Y7VZ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-VLYOEYML.js → chunk-LKQXXO62.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-MJ7HWSFK.js → chunk-MBBMTDD3.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-PIMMYG7Q.js → chunk-ME4XVOBJ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-IPWSFADF.js → chunk-N7QN3NE6.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-W7BJEWHX.js → chunk-QL5H3AQH.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-TQMFQYXR.js +29 -0
- package/dist/cli-bundle/focused-chunks/{chunk-RUR5I3TK.js → chunk-XNVXIQ4B.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-FGKY4MBE.js → chunk-YHDCGUIW.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-QVHKCI4T.js → chunk-YLPZHWX7.js} +2 -2
- package/dist/cli-bundle/main.js +13 -13
- 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 +25 -25
- 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 +1 -1
- 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 +1 -1
- package/dist/core/extensions/activation-summary.d.ts +4 -0
- package/dist/core/extensions/activation-summary.js +5 -2
- package/dist/core/extensions/contribution-inventory.d.ts +1 -0
- package/dist/core/extensions/contribution-inventory.js +35 -2
- package/dist/core/extensions/extension-hook-runtime.js +5 -3
- package/dist/core/extensions/extension-types.d.ts +18 -1
- package/dist/core/extensions/extension-types.js +2 -2
- package/dist/core/extensions/loader.js +5 -13
- package/dist/core/extensions/preflight-ownership.d.ts +5 -0
- package/dist/core/extensions/preflight-ownership.js +42 -0
- package/dist/sdk/cli-contracts/flag-contracts.d.ts +2 -0
- package/dist/sdk/cli-contracts/flag-contracts.js +8 -2
- 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/compose.d.ts +2 -2
- package/dist/sdk/compose.js +7 -2
- package/dist/sdk/define.d.ts +3 -1
- package/dist/sdk/define.js +3 -8
- package/dist/sdk/extension/install-sources.d.ts +43 -5
- package/dist/sdk/extension/install-sources.js +36 -2
- package/dist/sdk/extension/migrations.d.ts +114 -0
- package/dist/sdk/extension/migrations.js +175 -0
- package/dist/sdk/extension/scaffold.js +14 -9
- package/dist/sdk/extension/source-resolution.d.ts +50 -0
- package/dist/sdk/extension/source-resolution.js +66 -0
- package/dist/sdk/extension.d.ts +5 -1
- package/dist/sdk/extension.js +24 -26
- package/dist/sdk/governance/health.js +11 -2
- package/dist/sdk/index.d.ts +6 -2
- package/dist/sdk/index.js +8 -4
- package/dist/sdk/package-migrations.d.ts +10 -0
- package/dist/sdk/package-migrations.js +21 -0
- package/dist/sdk/runtime.d.ts +2 -0
- package/dist/sdk/runtime.js +6 -2
- package/docs/COMMANDS.md +9 -0
- package/docs/EXTENSIONS.md +2 -2
- package/docs/EXTENSION_LIFECYCLE.md +46 -0
- package/docs/README.md +1 -0
- package/docs/RELEASING.md +33 -20
- package/docs/SDK.md +31 -3
- package/marketplace.json +2 -2
- package/package.json +3 -3
- 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 +218 -20
- package/dist/cli-bundle/chunks/append-VXXGOXSG.js +0 -2
- package/dist/cli-bundle/chunks/chunk-EGJ4JTUG.js +0 -55
- package/dist/cli-bundle/chunks/chunk-FPBQHMFT.js +0 -8
- package/dist/cli-bundle/chunks/chunk-GE4KCSZP.js +0 -164
- package/dist/cli-bundle/chunks/chunk-YEWNL576.js +0 -2
- package/dist/cli-bundle/chunks/close-VZ3OQPN5.js +0 -2
- package/dist/cli-bundle/chunks/close-many-SB4TI27P.js +0 -2
- package/dist/cli-bundle/chunks/comments-BIF3Q4KY.js +0 -2
- package/dist/cli-bundle/chunks/copy-6AI5Z57X.js +0 -2
- package/dist/cli-bundle/chunks/delete-ZY2VHQTP.js +0 -2
- package/dist/cli-bundle/chunks/focus-DLBNWL7L.js +0 -2
- package/dist/cli-bundle/chunks/register-setup-O6AYP6NP.js +0 -2
- package/dist/cli-bundle/chunks/restore-ZVCVHTB5.js +0 -2
- package/dist/cli-bundle/chunks/update-YHV52CSS.js +0 -2
- package/dist/cli-bundle/chunks/update-many-M6YHVNXM.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-BIMTMOS7.js +0 -4
- package/dist/cli-bundle/focused-chunks/chunk-GJ2TG2CW.js +0 -28
- package/dist/cli-bundle/focused-chunks/chunk-N5XU5UVK.js +0 -2
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements extension package-management support for Install Sources.
|
|
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]="8994c8e2-8e3a-5e00-a3ca-7bd553c045d7")}catch(e){}}();
|
|
8
8
|
import { execFile } from "node:child_process";
|
|
9
9
|
import fs from "node:fs/promises";
|
|
10
10
|
import os from "node:os";
|
|
@@ -29,6 +29,39 @@ const LOCAL_PACKAGE_ARCHIVE_LIMITS = {
|
|
|
29
29
|
maxEntryBytes: 64 * 1024 * 1024,
|
|
30
30
|
};
|
|
31
31
|
let bundledPackageAliasesCache;
|
|
32
|
+
/** Resolve an already-installed npm package without executing package code. */
|
|
33
|
+
export async function findInstalledNpmPackageCandidate(packageName, cwd = process.cwd()) {
|
|
34
|
+
const normalized = packageName.trim();
|
|
35
|
+
if (!/^(@[^/\\\s]+\/[^/\\\s]+|[^@/\\\s][^/\\\s]*)$/u.test(normalized)) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
let current = path.resolve(cwd);
|
|
39
|
+
while (true) {
|
|
40
|
+
const directory = path.join(current, "node_modules", ...normalized.split("/"));
|
|
41
|
+
const manifestPath = path.join(directory, "package.json");
|
|
42
|
+
if (await pathExists(manifestPath)) {
|
|
43
|
+
try {
|
|
44
|
+
const manifest = JSON.parse(await fs.readFile(manifestPath, "utf8"));
|
|
45
|
+
if (manifest.name === normalized) {
|
|
46
|
+
return {
|
|
47
|
+
package: normalized,
|
|
48
|
+
...(typeof manifest.version === "string"
|
|
49
|
+
? { version: manifest.version }
|
|
50
|
+
: {}),
|
|
51
|
+
directory,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const parent = path.dirname(current);
|
|
60
|
+
if (parent === current)
|
|
61
|
+
return null;
|
|
62
|
+
current = parent;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
32
65
|
function parseGithubPathSpec(pathSpec, input, refOverride) {
|
|
33
66
|
const segments = pathSpec
|
|
34
67
|
.split("/")
|
|
@@ -916,6 +949,7 @@ export const _testOnlyInstallSources = {
|
|
|
916
949
|
resolveNpmSourceDirectoryWithRunner,
|
|
917
950
|
resolveNpmSourceDirectory,
|
|
918
951
|
resolveNpmPackSpec,
|
|
952
|
+
findInstalledNpmPackageCandidate,
|
|
919
953
|
resolvePackageExtensionDirectory,
|
|
920
954
|
runtimeDependencyInstallSpecs,
|
|
921
955
|
hasHostedPmCliDependency,
|
|
@@ -925,4 +959,4 @@ export const _testOnlyInstallSources = {
|
|
|
925
959
|
runNpmCommand,
|
|
926
960
|
};
|
|
927
961
|
//# sourceMappingURL=install-sources.js.map
|
|
928
|
-
//# debugId=
|
|
962
|
+
//# debugId=8994c8e2-8e3a-5e00-a3ca-7bd553c045d7
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type { RegisteredExtensionSchemaMigrationDefinition } from "../../core/extensions/extension-types.js";
|
|
2
|
+
import type { ExtensionCommandResult, ExtensionScope } from "../extension.js";
|
|
3
|
+
/** Durable lifecycle state of one extension migration in one workspace. */
|
|
4
|
+
export type ExtensionMigrationOutcomeStatus = "applied" | "failed";
|
|
5
|
+
/** One durable extension-migration outcome. */
|
|
6
|
+
export interface ExtensionMigrationStateEntry {
|
|
7
|
+
/** Stable layer/name/id identity. */
|
|
8
|
+
key: string;
|
|
9
|
+
/** Extension installation layer. */
|
|
10
|
+
layer: "global" | "project";
|
|
11
|
+
/** Owning extension name. */
|
|
12
|
+
extension: string;
|
|
13
|
+
/** Migration identifier declared by the extension. */
|
|
14
|
+
id: string;
|
|
15
|
+
/** Last durable outcome. */
|
|
16
|
+
status: ExtensionMigrationOutcomeStatus;
|
|
17
|
+
/** ISO timestamp for the last attempt. */
|
|
18
|
+
attempted_at: string;
|
|
19
|
+
/** Failure text retained only for failed outcomes. */
|
|
20
|
+
error?: string;
|
|
21
|
+
}
|
|
22
|
+
/** Versioned workspace state for extension migrations. */
|
|
23
|
+
export interface ExtensionMigrationState {
|
|
24
|
+
/** Storage schema version. */
|
|
25
|
+
version: 1;
|
|
26
|
+
/** Last state change timestamp. */
|
|
27
|
+
updated_at: string;
|
|
28
|
+
/** Deterministically sorted outcomes. */
|
|
29
|
+
entries: ExtensionMigrationStateEntry[];
|
|
30
|
+
}
|
|
31
|
+
/** Planned or executed row returned for one registered migration. */
|
|
32
|
+
export interface ExtensionMigrationReceipt {
|
|
33
|
+
/** Stable layer/name/id identity. */
|
|
34
|
+
key: string;
|
|
35
|
+
/** Extension installation layer. */
|
|
36
|
+
layer: "global" | "project";
|
|
37
|
+
/** Owning extension name. */
|
|
38
|
+
extension: string;
|
|
39
|
+
/** Migration identifier. */
|
|
40
|
+
id: string;
|
|
41
|
+
/** State observed before this invocation. */
|
|
42
|
+
before: "pending" | ExtensionMigrationOutcomeStatus;
|
|
43
|
+
/** Invocation outcome. */
|
|
44
|
+
outcome: "pending" | "applied" | "skipped" | "failed";
|
|
45
|
+
/** Failure text for failed execution. */
|
|
46
|
+
error?: string;
|
|
47
|
+
}
|
|
48
|
+
/** Structured plan/application envelope for extension migrations. */
|
|
49
|
+
export interface ExtensionMigrationRunResult {
|
|
50
|
+
/** Whether the invocation executed no failing migration. */
|
|
51
|
+
ok: boolean;
|
|
52
|
+
/** Whether execution was suppressed. */
|
|
53
|
+
dry_run: boolean;
|
|
54
|
+
/** Durable state path. */
|
|
55
|
+
state_path: string;
|
|
56
|
+
/** Total registered migrations in scope. */
|
|
57
|
+
total: number;
|
|
58
|
+
/** Pending rows in the returned receipt. */
|
|
59
|
+
pending_count: number;
|
|
60
|
+
/** Applied rows in the returned receipt. */
|
|
61
|
+
applied_count: number;
|
|
62
|
+
/** Already-applied rows skipped idempotently. */
|
|
63
|
+
skipped_count: number;
|
|
64
|
+
/** Failed rows in the returned receipt. */
|
|
65
|
+
failed_count: number;
|
|
66
|
+
/** Deterministically ordered per-migration receipts. */
|
|
67
|
+
migrations: ExtensionMigrationReceipt[];
|
|
68
|
+
}
|
|
69
|
+
/** Options for planning or applying active extension migrations. */
|
|
70
|
+
export interface RunExtensionMigrationsOptions {
|
|
71
|
+
/** Tracker root that owns durable migration state. */
|
|
72
|
+
pmRoot: string;
|
|
73
|
+
/** Active runtime registrations. */
|
|
74
|
+
migrations: RegisteredExtensionSchemaMigrationDefinition[];
|
|
75
|
+
/** Audit author written to workspace history. */
|
|
76
|
+
author: string;
|
|
77
|
+
/** Report pending work without invoking extension code. */
|
|
78
|
+
dryRun?: boolean;
|
|
79
|
+
/** Limit execution and receipts to one installation layer. */
|
|
80
|
+
scope?: "global" | "project";
|
|
81
|
+
}
|
|
82
|
+
/** Minimal lifecycle context required by the migration action dispatcher. */
|
|
83
|
+
export interface ExtensionMigrationActionContext {
|
|
84
|
+
/** Selected package scope. */
|
|
85
|
+
scope: ExtensionScope;
|
|
86
|
+
/** Tracker and settings roots for the invocation. */
|
|
87
|
+
resolvedRoots: {
|
|
88
|
+
pm_root: string;
|
|
89
|
+
settings_root: string;
|
|
90
|
+
};
|
|
91
|
+
/** Mutable warning collection shared with the lifecycle result. */
|
|
92
|
+
warnings: string[];
|
|
93
|
+
/** Migration-specific command options. */
|
|
94
|
+
options: {
|
|
95
|
+
dryRun?: boolean;
|
|
96
|
+
};
|
|
97
|
+
/** Relevant global runtime options. */
|
|
98
|
+
global: {
|
|
99
|
+
noExtensions?: boolean;
|
|
100
|
+
author?: string;
|
|
101
|
+
};
|
|
102
|
+
/** Construct the standard extension lifecycle result envelope. */
|
|
103
|
+
withResult: (details: Record<string, unknown>, ok?: boolean) => ExtensionCommandResult;
|
|
104
|
+
}
|
|
105
|
+
/** Return the durable workspace path for extension migration state. */
|
|
106
|
+
export declare function resolveExtensionMigrationStatePath(pmRoot: string): string;
|
|
107
|
+
/** Read durable extension migration outcomes, degrading absent state to empty. */
|
|
108
|
+
export declare function readExtensionMigrationState(pmRoot: string): Promise<ExtensionMigrationState>;
|
|
109
|
+
/** Overlay durable outcomes onto freshly activated migration definitions. */
|
|
110
|
+
export declare function applyStoredExtensionMigrationState(pmRoot: string, migrations: RegisteredExtensionSchemaMigrationDefinition[]): Promise<ExtensionMigrationState>;
|
|
111
|
+
/** Plan or apply active extension migrations with durable idempotency receipts. */
|
|
112
|
+
export declare function runExtensionMigrations(options: RunExtensionMigrationsOptions): Promise<ExtensionMigrationRunResult>;
|
|
113
|
+
/** Load active registrations and execute the extension lifecycle migrate action. */
|
|
114
|
+
export declare function runExtensionMigrateAction(context: ExtensionMigrationActionContext): Promise<ExtensionCommandResult>;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module sdk/extension/migrations
|
|
3
|
+
*
|
|
4
|
+
* Provides durable planning and execution for extension-owned schema migrations.
|
|
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]="56290db9-933c-590d-8b9f-df62ff45e515")}catch(e){}}();
|
|
8
|
+
import fs from "node:fs/promises";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import { pathExists } from "../../core/fs/fs-utils.js";
|
|
11
|
+
import { activateExtensions, loadExtensions } from "../../core/extensions/index.js";
|
|
12
|
+
import { writeWorkspaceJsonWithHistory } from "../../core/history/workspace-history.js";
|
|
13
|
+
import { readSettings } from "../../core/store/settings.js";
|
|
14
|
+
/** Return the durable workspace path for extension migration state. */
|
|
15
|
+
export function resolveExtensionMigrationStatePath(pmRoot) {
|
|
16
|
+
return path.join(pmRoot, "extension-migrations.json");
|
|
17
|
+
}
|
|
18
|
+
function migrationId(migration, index) {
|
|
19
|
+
const id = migration.definition.id;
|
|
20
|
+
return typeof id === "string" && id.trim().length > 0
|
|
21
|
+
? id.trim()
|
|
22
|
+
: `migration-${String(index + 1).padStart(3, "0")}`;
|
|
23
|
+
}
|
|
24
|
+
function migrationKey(migration, id) {
|
|
25
|
+
return `${migration.layer}:${migration.name}:${id}`;
|
|
26
|
+
}
|
|
27
|
+
/** Read durable extension migration outcomes, degrading absent state to empty. */
|
|
28
|
+
export async function readExtensionMigrationState(pmRoot) {
|
|
29
|
+
const statePath = resolveExtensionMigrationStatePath(pmRoot);
|
|
30
|
+
if (!(await pathExists(statePath))) {
|
|
31
|
+
return { version: 1, updated_at: "", entries: [] };
|
|
32
|
+
}
|
|
33
|
+
const parsed = JSON.parse(await fs.readFile(statePath, "utf8"));
|
|
34
|
+
return {
|
|
35
|
+
version: 1,
|
|
36
|
+
updated_at: typeof parsed.updated_at === "string" ? parsed.updated_at : "",
|
|
37
|
+
entries: Array.isArray(parsed.entries)
|
|
38
|
+
? parsed.entries.filter((entry) => typeof entry?.key === "string" &&
|
|
39
|
+
(entry.status === "applied" || entry.status === "failed"))
|
|
40
|
+
: [],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/** Overlay durable outcomes onto freshly activated migration definitions. */
|
|
44
|
+
export async function applyStoredExtensionMigrationState(pmRoot, migrations) {
|
|
45
|
+
const state = await readExtensionMigrationState(pmRoot);
|
|
46
|
+
const byKey = new Map(state.entries.map((entry) => [entry.key, entry]));
|
|
47
|
+
migrations.forEach((migration, index) => {
|
|
48
|
+
const id = migrationId(migration, index);
|
|
49
|
+
const entry = byKey.get(migrationKey(migration, id));
|
|
50
|
+
if (!entry)
|
|
51
|
+
return;
|
|
52
|
+
migration.definition.status = entry.status;
|
|
53
|
+
if (entry.status === "failed") {
|
|
54
|
+
migration.definition.reason = entry.error;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
delete migration.definition.reason;
|
|
58
|
+
delete migration.definition.error;
|
|
59
|
+
delete migration.definition.message;
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
return state;
|
|
63
|
+
}
|
|
64
|
+
/** Plan or apply active extension migrations with durable idempotency receipts. */
|
|
65
|
+
export async function runExtensionMigrations(options) {
|
|
66
|
+
const state = await applyStoredExtensionMigrationState(options.pmRoot, options.migrations);
|
|
67
|
+
const stateByKey = new Map(state.entries.map((entry) => [entry.key, entry]));
|
|
68
|
+
const receipts = [];
|
|
69
|
+
let changed = false;
|
|
70
|
+
const scopedMigrations = options.migrations
|
|
71
|
+
.map((migration, index) => ({ migration, index }))
|
|
72
|
+
.filter(({ migration }) => options.scope === undefined || migration.layer === options.scope);
|
|
73
|
+
for (const { migration, index } of scopedMigrations) {
|
|
74
|
+
const id = migrationId(migration, index);
|
|
75
|
+
const key = migrationKey(migration, id);
|
|
76
|
+
const stored = stateByKey.get(key);
|
|
77
|
+
const declaredStatus = String(migration.definition.status ?? "pending").toLowerCase();
|
|
78
|
+
const before = stored?.status ?? (declaredStatus === "applied" || declaredStatus === "failed" ? declaredStatus : "pending");
|
|
79
|
+
if (before === "applied") {
|
|
80
|
+
receipts.push({ key, layer: migration.layer, extension: migration.name, id, before, outcome: "skipped" });
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (options.dryRun === true) {
|
|
84
|
+
receipts.push({ key, layer: migration.layer, extension: migration.name, id, before, outcome: "pending" });
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const run = migration.runtime_definition?.run ?? migration.definition.run;
|
|
88
|
+
if (typeof run !== "function") {
|
|
89
|
+
receipts.push({ key, layer: migration.layer, extension: migration.name, id, before, outcome: "pending" });
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
const attemptedAt = new Date().toISOString();
|
|
93
|
+
try {
|
|
94
|
+
await Promise.resolve(run({ id, command: "migration", layer: migration.layer, extension: migration.name, pm_root: options.pmRoot, status: before }));
|
|
95
|
+
const entry = { key, layer: migration.layer, extension: migration.name, id, status: "applied", attempted_at: attemptedAt };
|
|
96
|
+
stateByKey.set(key, entry);
|
|
97
|
+
migration.definition.status = "applied";
|
|
98
|
+
delete migration.definition.reason;
|
|
99
|
+
delete migration.definition.error;
|
|
100
|
+
delete migration.definition.message;
|
|
101
|
+
receipts.push({ key, layer: migration.layer, extension: migration.name, id, before, outcome: "applied" });
|
|
102
|
+
changed = true;
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
106
|
+
const entry = { key, layer: migration.layer, extension: migration.name, id, status: "failed", attempted_at: attemptedAt, error: message };
|
|
107
|
+
stateByKey.set(key, entry);
|
|
108
|
+
migration.definition.status = "failed";
|
|
109
|
+
migration.definition.reason = message;
|
|
110
|
+
receipts.push({ key, layer: migration.layer, extension: migration.name, id, before, outcome: "failed", error: message });
|
|
111
|
+
changed = true;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (changed) {
|
|
115
|
+
const settings = await readSettings(options.pmRoot);
|
|
116
|
+
const nextState = {
|
|
117
|
+
version: 1,
|
|
118
|
+
updated_at: new Date().toISOString(),
|
|
119
|
+
entries: [...stateByKey.values()].sort((left, right) => left.key.localeCompare(right.key)),
|
|
120
|
+
};
|
|
121
|
+
await writeWorkspaceJsonWithHistory({
|
|
122
|
+
pmRoot: options.pmRoot,
|
|
123
|
+
filePath: resolveExtensionMigrationStatePath(options.pmRoot),
|
|
124
|
+
raw: `${JSON.stringify(nextState, null, 2)}\n`,
|
|
125
|
+
op: "extension_migrations_apply",
|
|
126
|
+
author: options.author,
|
|
127
|
+
lockTtlSeconds: settings.locks.ttl_seconds,
|
|
128
|
+
lockWaitMs: settings.locks.wait_ms,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
const pendingCount = receipts.filter((receipt) => receipt.outcome === "pending").length;
|
|
132
|
+
const appliedCount = receipts.filter((receipt) => receipt.outcome === "applied").length;
|
|
133
|
+
const skippedCount = receipts.filter((receipt) => receipt.outcome === "skipped").length;
|
|
134
|
+
const failedCount = receipts.filter((receipt) => receipt.outcome === "failed").length;
|
|
135
|
+
return {
|
|
136
|
+
ok: failedCount === 0,
|
|
137
|
+
dry_run: options.dryRun === true,
|
|
138
|
+
state_path: resolveExtensionMigrationStatePath(options.pmRoot),
|
|
139
|
+
total: receipts.length,
|
|
140
|
+
pending_count: pendingCount,
|
|
141
|
+
applied_count: appliedCount,
|
|
142
|
+
skipped_count: skippedCount,
|
|
143
|
+
failed_count: failedCount,
|
|
144
|
+
migrations: receipts,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/** Load active registrations and execute the extension lifecycle migrate action. */
|
|
148
|
+
export async function runExtensionMigrateAction(context) {
|
|
149
|
+
const settings = await readSettings(context.resolvedRoots.settings_root);
|
|
150
|
+
const loaded = await loadExtensions({
|
|
151
|
+
pmRoot: context.resolvedRoots.pm_root,
|
|
152
|
+
settings,
|
|
153
|
+
cwd: process.cwd(),
|
|
154
|
+
noExtensions: context.global.noExtensions === true,
|
|
155
|
+
});
|
|
156
|
+
const activated = await activateExtensions(loaded);
|
|
157
|
+
context.warnings.push(...loaded.warnings, ...activated.warnings);
|
|
158
|
+
const migration = await runExtensionMigrations({
|
|
159
|
+
pmRoot: context.resolvedRoots.pm_root,
|
|
160
|
+
migrations: activated.registrations.migrations,
|
|
161
|
+
author: typeof context.global.author === "string" &&
|
|
162
|
+
context.global.author.trim().length > 0
|
|
163
|
+
? context.global.author.trim()
|
|
164
|
+
: "pm-extension-migration",
|
|
165
|
+
dryRun: context.options.dryRun === true,
|
|
166
|
+
...(context.scope === "global" ? { scope: "global" } : {}),
|
|
167
|
+
});
|
|
168
|
+
return context.withResult({
|
|
169
|
+
migration,
|
|
170
|
+
load_failure_count: loaded.failed.length,
|
|
171
|
+
activation_failure_count: activated.failed.length,
|
|
172
|
+
}, migration.ok);
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=migrations.js.map
|
|
175
|
+
//# debugId=56290db9-933c-590d-8b9f-df62ff45e515
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements extension package-management support for Scaffold.
|
|
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]="30dfc6e4-27c5-56c0-981b-94e85b780f1f")}catch(e){}}();
|
|
8
8
|
import fs from "node:fs/promises";
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import { pathExists } from "../../core/fs/fs-utils.js";
|
|
@@ -276,8 +276,9 @@ const PACKAGE_CAPABILITY_README_SECTIONS = {
|
|
|
276
276
|
"",
|
|
277
277
|
"## Preflight Override",
|
|
278
278
|
"`index.ts` registers a preflight override through `api.registerPreflight`. pm",
|
|
279
|
-
"calls it
|
|
280
|
-
"
|
|
279
|
+
"calls it only for its declared command ownership to compute the migration/format",
|
|
280
|
+
"gate decision. Overlapping or legacy global ownership is diagnosed. Return only",
|
|
281
|
+
"the decision keys you want to",
|
|
281
282
|
"change; this starter echoes the current decision unchanged (a safe no-op) so",
|
|
282
283
|
"installing the package does not alter gate behavior. The `preflight`",
|
|
283
284
|
"capability in `manifest.json` grants the registration.",
|
|
@@ -765,15 +766,19 @@ function buildActivateBodyLines(extensionName, commandName, capability) {
|
|
|
765
766
|
...commandLines,
|
|
766
767
|
"",
|
|
767
768
|
" // Preflight overrides adjust pm's pre-run gate decision (extension",
|
|
768
|
-
" // migrations + item-format checks)
|
|
769
|
-
" //
|
|
769
|
+
" // migrations + item-format checks) for the commands it owns. Disjoint",
|
|
770
|
+
" // packages compose; overlapping or legacy global ownership is diagnosed.",
|
|
771
|
+
" // Return a delta of the keys you want to change",
|
|
770
772
|
" // (enforce_item_format_gate, run_preflight_item_format_sync,",
|
|
771
773
|
" // run_extension_migrations, enforce_mandatory_migration_gate); returning",
|
|
772
774
|
" // context.decision unchanged is a safe no-op so installing the package does",
|
|
773
775
|
" // not alter gate behavior — replace it with your policy, e.g.",
|
|
774
776
|
" // `{ run_extension_migrations: false }`. The `preflight` capability in",
|
|
775
777
|
" // manifest.json grants the registration.",
|
|
776
|
-
" api.registerPreflight(
|
|
778
|
+
" api.registerPreflight({",
|
|
779
|
+
` commands: [${JSON.stringify(commandName)}],`,
|
|
780
|
+
" run: (context) => context.decision,",
|
|
781
|
+
" });",
|
|
777
782
|
];
|
|
778
783
|
}
|
|
779
784
|
if (capability === "services") {
|
|
@@ -1339,7 +1344,7 @@ function buildDeclarativeBlueprintSurface(extensionName, commandName, capability
|
|
|
1339
1344
|
break;
|
|
1340
1345
|
case "preflight":
|
|
1341
1346
|
builderImports.push("definePreflightOverride");
|
|
1342
|
-
definitions.push("", "// Preflight overrides adjust pm's pre-run gate decision (extension migrations +", "// item-format checks)
|
|
1347
|
+
definitions.push("", "// Preflight overrides adjust pm's pre-run gate decision (extension migrations +", "// item-format checks) for the commands it owns. Scoped ownership composes with", "// other packages; overlapping or legacy global ownership is diagnosed.", "// Return a delta of the keys you want to change (enforce_item_format_gate,", "// run_preflight_item_format_sync, run_extension_migrations,", "// enforce_mandatory_migration_gate); returning context.decision unchanged is a", "// safe no-op - replace it with your policy, e.g. { run_extension_migrations: false }.", "export const preflightOverride = definePreflightOverride({", ` commands: [${JSON.stringify(commandName)}],`, " run: (context) => context.decision,", "});");
|
|
1343
1348
|
blueprintFields.push(" preflights: [preflightOverride],");
|
|
1344
1349
|
break;
|
|
1345
1350
|
case "services":
|
|
@@ -1963,7 +1968,7 @@ function buildDefineBuilderExports(extensionName, commandName, capability, names
|
|
|
1963
1968
|
lines.push("", "export const pingParser = defineParserOverride((context) => {", " const options = { ...context.options };", " if (options.shout === true) options.upper = true;", " delete options.shout;", " return { options };", "});");
|
|
1964
1969
|
}
|
|
1965
1970
|
if (capability === "preflight") {
|
|
1966
|
-
lines.push("", "// Return a delta of the gate-decision keys you want to change; returning", "// context.decision unchanged is a safe no-op (e.g. { run_extension_migrations: false }).", "export const preflightOverride = definePreflightOverride((context) => context.decision);");
|
|
1971
|
+
lines.push("", "// Return a delta of the gate-decision keys you want to change; returning", "// context.decision unchanged is a safe no-op (e.g. { run_extension_migrations: false }).", "export const preflightOverride = definePreflightOverride({", ` commands: [${JSON.stringify(commandName)}],`, " run: (context) => context.decision,", "});");
|
|
1967
1972
|
}
|
|
1968
1973
|
if (capability === "services") {
|
|
1969
1974
|
lines.push("", "export const outputService = defineServiceOverride((context) => {", ` if (context.command !== ${JSON.stringify(commandName)}) return { handled: false };`, ` return { rendered_by: ${JSON.stringify(extensionName)}, payload: context.payload };`, "});");
|
|
@@ -2295,4 +2300,4 @@ export async function scaffoldExtensionProject(target, vocabulary = "extension",
|
|
|
2295
2300
|
};
|
|
2296
2301
|
}
|
|
2297
2302
|
//# sourceMappingURL=scaffold.js.map
|
|
2298
|
-
//# debugId=
|
|
2303
|
+
//# debugId=30dfc6e4-27c5-56c0-981b-94e85b780f1f
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module sdk/extension/source-resolution
|
|
3
|
+
*
|
|
4
|
+
* Resolves install-source identity without executing package code.
|
|
5
|
+
*/
|
|
6
|
+
import { type InstallSource } from "./install-sources.js";
|
|
7
|
+
/** Selected install-source identity. */
|
|
8
|
+
export interface ExtensionInstallSourceSelection {
|
|
9
|
+
/** Selected source family. */
|
|
10
|
+
kind: "builtin" | "local" | "github" | "npm";
|
|
11
|
+
/** Canonical source input used for resolution. */
|
|
12
|
+
input: string;
|
|
13
|
+
/** Canonical package name when known. */
|
|
14
|
+
package?: string;
|
|
15
|
+
}
|
|
16
|
+
/** One source candidate and the explicit command that selects it. */
|
|
17
|
+
export interface ExtensionInstallSourceCandidate extends ExtensionInstallSourceSelection {
|
|
18
|
+
/** Installed candidate version when known. */
|
|
19
|
+
version?: string;
|
|
20
|
+
/** Installed candidate directory when relevant. */
|
|
21
|
+
directory?: string;
|
|
22
|
+
/** Unambiguous CLI command that selects this candidate. */
|
|
23
|
+
command: string;
|
|
24
|
+
}
|
|
25
|
+
/** Machine-readable explanation of how one install target resolved. */
|
|
26
|
+
export interface ExtensionInstallSourceResolution {
|
|
27
|
+
/** Exact target supplied by the caller. */
|
|
28
|
+
requested: string;
|
|
29
|
+
/** Source selected by the deterministic resolver. */
|
|
30
|
+
selected: ExtensionInstallSourceSelection;
|
|
31
|
+
/** Whether another locally available source could satisfy the same bare name. */
|
|
32
|
+
ambiguous: boolean;
|
|
33
|
+
/** Stable precedence rule used for the selection. */
|
|
34
|
+
precedence: "bundled_alias_before_installed_npm";
|
|
35
|
+
/** Every matching candidate and its explicit install command. */
|
|
36
|
+
candidates: ExtensionInstallSourceCandidate[];
|
|
37
|
+
}
|
|
38
|
+
/** Complete result of resolving one extension install target. */
|
|
39
|
+
export interface ResolvedExtensionInstallSource {
|
|
40
|
+
/** Normalized bundled alias, or null for non-bundled sources. */
|
|
41
|
+
bundledAliasName: string | null;
|
|
42
|
+
/** Bundled package name, or null when unavailable. */
|
|
43
|
+
bundledPackageName: string | null;
|
|
44
|
+
/** Parsed source passed to the install resolver. */
|
|
45
|
+
installSource: InstallSource;
|
|
46
|
+
/** Observable source-selection decision. */
|
|
47
|
+
sourceResolution: ExtensionInstallSourceResolution;
|
|
48
|
+
}
|
|
49
|
+
/** Resolve bundled-alias provenance and competing installed npm identity. */
|
|
50
|
+
export declare function resolveExtensionInstallSourceIdentity(explicitSourceInput: string, githubOption: string | undefined, ref: string | undefined): Promise<ResolvedExtensionInstallSource>;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module sdk/extension/source-resolution
|
|
3
|
+
*
|
|
4
|
+
* Resolves install-source identity without executing package code.
|
|
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]="39bc7f14-2d32-5b58-97ab-647f9f238273")}catch(e){}}();
|
|
8
|
+
import { findInstalledNpmPackageCandidate, parseExtensionInstallSource, } from "./install-sources.js";
|
|
9
|
+
import { resolveBundledExtensionAliasSource, resolveBundledPackageNpmName, } from "./bundled-catalog.js";
|
|
10
|
+
/** Resolve bundled-alias provenance and competing installed npm identity. */
|
|
11
|
+
export async function resolveExtensionInstallSourceIdentity(explicitSourceInput, githubOption, ref) {
|
|
12
|
+
const bundledAliasSource = typeof githubOption === "string"
|
|
13
|
+
? null
|
|
14
|
+
: await resolveBundledExtensionAliasSource(explicitSourceInput);
|
|
15
|
+
const bundledAliasName = bundledAliasSource === null
|
|
16
|
+
? null
|
|
17
|
+
: explicitSourceInput.trim().toLowerCase();
|
|
18
|
+
const bundledPackageName = bundledAliasName === null
|
|
19
|
+
? null
|
|
20
|
+
: await resolveBundledPackageNpmName(bundledAliasName);
|
|
21
|
+
const installSource = parseExtensionInstallSource(bundledAliasSource ?? explicitSourceInput, { forceGithub: typeof githubOption === "string", ref });
|
|
22
|
+
const installedNpmCandidate = bundledAliasName === null
|
|
23
|
+
? null
|
|
24
|
+
: await findInstalledNpmPackageCandidate(explicitSourceInput);
|
|
25
|
+
return {
|
|
26
|
+
bundledAliasName,
|
|
27
|
+
bundledPackageName,
|
|
28
|
+
installSource,
|
|
29
|
+
sourceResolution: {
|
|
30
|
+
requested: explicitSourceInput,
|
|
31
|
+
selected: {
|
|
32
|
+
kind: bundledAliasName === null ? installSource.kind : "builtin",
|
|
33
|
+
input: bundledAliasName ?? installSource.input,
|
|
34
|
+
...(bundledPackageName === null ? {} : { package: bundledPackageName }),
|
|
35
|
+
},
|
|
36
|
+
ambiguous: installedNpmCandidate !== null,
|
|
37
|
+
precedence: "bundled_alias_before_installed_npm",
|
|
38
|
+
candidates: [
|
|
39
|
+
...(bundledAliasName === null
|
|
40
|
+
? []
|
|
41
|
+
: [{
|
|
42
|
+
kind: "builtin",
|
|
43
|
+
input: bundledAliasName,
|
|
44
|
+
...(bundledPackageName === null
|
|
45
|
+
? {}
|
|
46
|
+
: { package: bundledPackageName }),
|
|
47
|
+
command: `pm install ${bundledAliasName}`,
|
|
48
|
+
}]),
|
|
49
|
+
...(installedNpmCandidate === null
|
|
50
|
+
? []
|
|
51
|
+
: [{
|
|
52
|
+
kind: "npm",
|
|
53
|
+
input: `npm:${installedNpmCandidate.package}`,
|
|
54
|
+
package: installedNpmCandidate.package,
|
|
55
|
+
...(installedNpmCandidate.version === undefined
|
|
56
|
+
? {}
|
|
57
|
+
: { version: installedNpmCandidate.version }),
|
|
58
|
+
directory: installedNpmCandidate.directory,
|
|
59
|
+
command: `pm install npm:${installedNpmCandidate.package}`,
|
|
60
|
+
}]),
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=source-resolution.js.map
|
|
66
|
+
//# debugId=39bc7f14-2d32-5b58-97ab-647f9f238273
|
package/dist/sdk/extension.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export { parseExtensionManifest, validateExtensionDirectory, readManagedExtensio
|
|
|
16
16
|
export type { ManagedExtensionSource, ManagedExtensionRecord, ManagedExtensionState, };
|
|
17
17
|
export type { ManagedExtensionStateReadResult } from "./extension/managed-state.js";
|
|
18
18
|
/** Restricts extension command action values accepted by command, SDK, and storage contracts. */
|
|
19
|
-
export type ExtensionCommandAction = "install" | "uninstall" | "explore" | "manage" | "describe" | "reload" | "doctor" | "catalog" | "adopt" | "adopt-all" | "activate" | "deactivate" | "init";
|
|
19
|
+
export type ExtensionCommandAction = "install" | "uninstall" | "explore" | "manage" | "describe" | "reload" | "doctor" | "catalog" | "adopt" | "adopt-all" | "activate" | "deactivate" | "migrate" | "init";
|
|
20
20
|
/** Restricts extension scope values accepted by command, SDK, and storage contracts. */
|
|
21
21
|
export type ExtensionScope = "project" | "global";
|
|
22
22
|
/** Restricts extension activation status values accepted by command, SDK, and storage contracts. */
|
|
@@ -59,6 +59,8 @@ export interface ExtensionCommandOptions {
|
|
|
59
59
|
activate?: boolean;
|
|
60
60
|
/** Value that configures or reports deactivate for this contract. */
|
|
61
61
|
deactivate?: boolean;
|
|
62
|
+
/** Plan or apply active extension migrations. */
|
|
63
|
+
migrate?: boolean;
|
|
62
64
|
/** Value that configures or reports project for this contract. */
|
|
63
65
|
project?: boolean;
|
|
64
66
|
/** Value that configures or reports local for this contract. */
|
|
@@ -93,6 +95,8 @@ export interface ExtensionCommandOptions {
|
|
|
93
95
|
declarative?: boolean;
|
|
94
96
|
/** Value that configures or reports vocabulary for this contract. */
|
|
95
97
|
vocabulary?: "extension" | "package";
|
|
98
|
+
/** Plan migration work without invoking extension code. */
|
|
99
|
+
dryRun?: boolean;
|
|
96
100
|
}
|
|
97
101
|
/** Documents the managed extension summary payload exchanged by command, SDK, and package integrations. */
|
|
98
102
|
export interface ManagedExtensionSummary {
|