@acidicsoil/portable-capabilities 0.1.9 → 0.1.13

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.
@@ -1997,13 +1997,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
1997
1997
  * @param {string} source - expected values are default/config/env/cli/implied
1998
1998
  * @return {Command} `this` command for chaining
1999
1999
  */
2000
- setOptionValueWithSource(key, value, source3) {
2000
+ setOptionValueWithSource(key, value, source2) {
2001
2001
  if (this._storeOptionsAsProperties) {
2002
2002
  this[key] = value;
2003
2003
  } else {
2004
2004
  this._optionValues[key] = value;
2005
2005
  }
2006
- this._optionValueSources[key] = source3;
2006
+ this._optionValueSources[key] = source2;
2007
2007
  return this;
2008
2008
  }
2009
2009
  /**
@@ -2024,13 +2024,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
2024
2024
  * @return {string}
2025
2025
  */
2026
2026
  getOptionValueSourceWithGlobals(key) {
2027
- let source3;
2027
+ let source2;
2028
2028
  this._getCommandAndAncestors().forEach((cmd) => {
2029
2029
  if (cmd.getOptionValueSource(key) !== void 0) {
2030
- source3 = cmd.getOptionValueSource(key);
2030
+ source2 = cmd.getOptionValueSource(key);
2031
2031
  }
2032
2032
  });
2033
- return source3;
2033
+ return source2;
2034
2034
  }
2035
2035
  /**
2036
2036
  * Get user arguments from implied or explicit arguments.
@@ -2900,8 +2900,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
2900
2900
  const getErrorMessage = (option2) => {
2901
2901
  const bestOption = findBestOptionFromValue(option2);
2902
2902
  const optionKey = bestOption.attributeName();
2903
- const source3 = this.getOptionValueSource(optionKey);
2904
- if (source3 === "env") {
2903
+ const source2 = this.getOptionValueSource(optionKey);
2904
+ if (source2 === "env") {
2905
2905
  return `environment variable '${bestOption.envVar}'`;
2906
2906
  }
2907
2907
  return `option '${bestOption.flags}'`;
@@ -7802,11 +7802,11 @@ var getToStream = (destination7, to = "stdin") => {
7802
7802
  }
7803
7803
  return destinationStream;
7804
7804
  };
7805
- var getFromStream = (source3, from = "stdout") => {
7805
+ var getFromStream = (source2, from = "stdout") => {
7806
7806
  const isWritable = false;
7807
- const { options, fileDescriptors } = SUBPROCESS_OPTIONS.get(source3);
7807
+ const { options, fileDescriptors } = SUBPROCESS_OPTIONS.get(source2);
7808
7808
  const fdNumber = getFdNumber(fileDescriptors, from, isWritable);
7809
- const sourceStream = fdNumber === "all" ? source3.all : source3.stdio[fdNumber];
7809
+ const sourceStream = fdNumber === "all" ? source2.all : source2.stdio[fdNumber];
7810
7810
  if (sourceStream === null || sourceStream === void 0) {
7811
7811
  throw new TypeError(getInvalidStdioOptionMessage(fdNumber, from, options, isWritable));
7812
7812
  }
@@ -9508,17 +9508,17 @@ var PASSTHROUGH_LISTENERS_PER_STREAM = 1;
9508
9508
 
9509
9509
  // node_modules/.pnpm/execa@10.0.0/node_modules/execa/lib/io/pipeline.js
9510
9510
  import { finished as finished3 } from "node:stream/promises";
9511
- var pipeStreams = (source3, destination7) => {
9512
- source3.pipe(destination7);
9513
- onSourceFinish(source3, destination7);
9514
- onDestinationFinish(source3, destination7);
9511
+ var pipeStreams = (source2, destination7) => {
9512
+ source2.pipe(destination7);
9513
+ onSourceFinish(source2, destination7);
9514
+ onDestinationFinish(source2, destination7);
9515
9515
  };
9516
- var onSourceFinish = async (source3, destination7) => {
9517
- if (isStandardStream(source3) || isStandardStream(destination7)) {
9516
+ var onSourceFinish = async (source2, destination7) => {
9517
+ if (isStandardStream(source2) || isStandardStream(destination7)) {
9518
9518
  return;
9519
9519
  }
9520
9520
  try {
9521
- await finished3(source3, { cleanup: true, readable: true, writable: false });
9521
+ await finished3(source2, { cleanup: true, readable: true, writable: false });
9522
9522
  } catch {
9523
9523
  }
9524
9524
  endDestinationStream(destination7);
@@ -9528,19 +9528,19 @@ var endDestinationStream = (destination7) => {
9528
9528
  destination7.end();
9529
9529
  }
9530
9530
  };
9531
- var onDestinationFinish = async (source3, destination7) => {
9532
- if (isStandardStream(source3) || isStandardStream(destination7)) {
9531
+ var onDestinationFinish = async (source2, destination7) => {
9532
+ if (isStandardStream(source2) || isStandardStream(destination7)) {
9533
9533
  return;
9534
9534
  }
9535
9535
  try {
9536
9536
  await finished3(destination7, { cleanup: true, readable: false, writable: true });
9537
9537
  } catch {
9538
9538
  }
9539
- abortSourceStream(source3);
9539
+ abortSourceStream(source2);
9540
9540
  };
9541
- var abortSourceStream = (source3) => {
9542
- if (source3.readable) {
9543
- source3.destroy();
9541
+ var abortSourceStream = (source2) => {
9542
+ if (source2.readable) {
9543
+ source2.destroy();
9544
9544
  }
9545
9545
  };
9546
9546
 
@@ -10264,7 +10264,7 @@ var createWritableStream = (subprocess, writableOptions) => Writable3.toWeb(subp
10264
10264
  var createTransformStream = (subprocess, duplexOptions) => Duplex3.toWeb(subprocess.duplex(duplexOptions));
10265
10265
 
10266
10266
  // node_modules/.pnpm/execa@10.0.0/node_modules/execa/lib/pipe/pipe-arguments.js
10267
- var normalizePipeArguments = ({ source: source3, sourcePromise, boundOptions, createNested }, ...pipeArguments) => {
10267
+ var normalizePipeArguments = ({ source: source2, sourcePromise, boundOptions, createNested }, ...pipeArguments) => {
10268
10268
  const startTime = getStartTime();
10269
10269
  const {
10270
10270
  destination: destination7,
@@ -10273,8 +10273,8 @@ var normalizePipeArguments = ({ source: source3, sourcePromise, boundOptions, cr
10273
10273
  from,
10274
10274
  unpipeSignal
10275
10275
  } = getDestinationStream(boundOptions, createNested, pipeArguments);
10276
- const { sourceStream, sourceError } = getSourceStream(source3, from);
10277
- const { options: sourceOptions, fileDescriptors } = SUBPROCESS_OPTIONS.get(source3);
10276
+ const { sourceStream, sourceError } = getSourceStream(source2, from);
10277
+ const { options: sourceOptions, fileDescriptors } = SUBPROCESS_OPTIONS.get(source2);
10278
10278
  return {
10279
10279
  sourcePromise,
10280
10280
  sourceStream,
@@ -10327,9 +10327,9 @@ var getDestination = (boundOptions, createNested, firstArgument, ...pipeArgument
10327
10327
  throw new TypeError(`The first argument must be a template string, an options object, or an Execa subprocess: ${firstArgument}`);
10328
10328
  };
10329
10329
  var mapDestinationArguments = ({ options }) => ({ options: { ...options, stdin: "pipe", piped: true } });
10330
- var getSourceStream = (source3, from) => {
10330
+ var getSourceStream = (source2, from) => {
10331
10331
  try {
10332
- const sourceStream = getFromStream(source3, from);
10332
+ const sourceStream = getFromStream(source2, from);
10333
10333
  return { sourceStream };
10334
10334
  } catch (error) {
10335
10335
  return { sourceError: error };
@@ -11733,7 +11733,7 @@ function writeEnvelope(envelope, format2) {
11733
11733
  }
11734
11734
 
11735
11735
  // packages/cli/src/release.ts
11736
- var cliVersion = true ? "0.1.9" : createRequire(import.meta.url)("../../../package.json").version;
11736
+ var cliVersion = true ? "0.1.13" : createRequire(import.meta.url)("../../../package.json").version;
11737
11737
 
11738
11738
  // packages/adapters/src/antigravity/materialize.ts
11739
11739
  import { resolve as resolve2 } from "node:path";
@@ -11892,7 +11892,7 @@ var antigravityRuntimeDescriptor = {
11892
11892
  schemaVersion: "1.0",
11893
11893
  id: "antigravity",
11894
11894
  aliases: ["google-antigravity", "antigravity-cli"],
11895
- supportedVersions: [">=2.0.0"],
11895
+ supportedVersions: [">=1.1.4 <2.0.0"],
11896
11896
  locations: [
11897
11897
  {
11898
11898
  id: "antigravity-project-skills",
@@ -11991,11 +11991,11 @@ var antigravityRuntimeDescriptor = {
11991
11991
  evidenceState: "source-observed"
11992
11992
  },
11993
11993
  {
11994
- id: "antigravity-2.0-rules",
11994
+ id: "antigravity-workspace-rules",
11995
11995
  semanticKind: "rule",
11996
11996
  integrationMode: "declarative",
11997
11997
  adapterId: markdown,
11998
- discovery: "2.0 workspace rules are discovered from .agents/rules.",
11998
+ discovery: "Workspace rules may be discovered from .agents/rules when verified for a supported client.",
11999
11999
  invocation: "Rules apply according to their activation mode.",
12000
12000
  precedence: ["workspace", "global"],
12001
12001
  evidenceClaimIds: ["antigravity.cli.discovery.rules"],
@@ -12003,11 +12003,11 @@ var antigravityRuntimeDescriptor = {
12003
12003
  evidenceState: "source-observed"
12004
12004
  },
12005
12005
  {
12006
- id: "antigravity-2.0-agents",
12006
+ id: "antigravity-workspace-agents",
12007
12007
  semanticKind: "agent",
12008
12008
  integrationMode: "declarative",
12009
12009
  adapterId: markdown,
12010
- discovery: "Custom agents are discovered from .agents/agents.",
12010
+ discovery: "Workspace agents may be discovered from .agents/agents when verified for a supported client.",
12011
12011
  invocation: "Invoke through the native subagent interface.",
12012
12012
  precedence: ["workspace", "global"],
12013
12013
  evidenceClaimIds: ["antigravity.cli.discovery.agents"],
@@ -12015,11 +12015,11 @@ var antigravityRuntimeDescriptor = {
12015
12015
  evidenceState: "source-observed"
12016
12016
  },
12017
12017
  {
12018
- id: "antigravity-2.0-hooks",
12018
+ id: "antigravity-workspace-hooks",
12019
12019
  semanticKind: "hook",
12020
12020
  integrationMode: "declarative",
12021
12021
  adapterId: hook,
12022
- discovery: "hooks.json is discovered at workspace scope.",
12022
+ discovery: "Workspace hooks may be discovered from hooks.json when verified for a supported client.",
12023
12023
  invocation: "Hooks participate in native tool and invocation events.",
12024
12024
  precedence: ["workspace", "global", "plugin"],
12025
12025
  evidenceClaimIds: ["antigravity.cli.hooks"],
@@ -12027,11 +12027,11 @@ var antigravityRuntimeDescriptor = {
12027
12027
  evidenceState: "source-observed"
12028
12028
  },
12029
12029
  {
12030
- id: "antigravity-2.0-mcp",
12030
+ id: "antigravity-workspace-mcp",
12031
12031
  semanticKind: "mcp",
12032
12032
  integrationMode: "declarative",
12033
12033
  adapterId: mcp,
12034
- discovery: "mcp_config.json is discovered at workspace scope.",
12034
+ discovery: "Workspace MCP may be discovered from mcp_config.json when verified for a supported client.",
12035
12035
  invocation: "MCP servers are exposed as native tools.",
12036
12036
  precedence: ["workspace", "global"],
12037
12037
  evidenceClaimIds: ["antigravity.cli.mcp"],
@@ -12079,148 +12079,148 @@ var antigravityRuntimeDescriptor = {
12079
12079
  // packages/adapters/src/antigravity/runtime-evidence.ts
12080
12080
  import { createHash as createHash7 } from "node:crypto";
12081
12081
  var digest2 = (value) => createHash7("sha256").update(value).digest("hex");
12082
- var retrievedAt = "2026-08-10T00:00:00.000Z";
12083
- var source = "docs/RFC/runtime-capability-profiles-revised.md";
12084
- var sourceClaim = (id, category, subject, assertion, locator, state = "source-observed", mode = "2.0") => ({
12085
- schemaVersion: "1.0",
12086
- id,
12087
- runtimeId: "antigravity",
12088
- category,
12089
- subject,
12090
- assertion,
12091
- versionRange: `product-mode:${mode}; >=2.0.0`,
12092
- sourceType: "official-source",
12093
- source,
12094
- sourceLocator: locator,
12095
- sourceDigest: digest2(`${id}:${assertion}:${locator}`),
12096
- state,
12097
- confidence: state === "unknown" ? "medium" : "high",
12098
- verificationStatus: state === "unknown" ? "unverified" : "verified",
12099
- stability: state === "unknown" ? "version-gated" : "stable",
12100
- verifiedAt: retrievedAt
12101
- });
12082
+ var retrievedAt = "2026-08-15T00:00:00.000Z";
12083
+ var cliVersionRange = ">=1.1.4 <2.0.0";
12084
+ var cliDocs = "https://codelabs.developers.google.com/antigravity/how-to-create-agent-skills-for-antigravity-cli";
12085
+ var productDocs = "https://www.antigravity.google/product/antigravity-cli";
12086
+ var sourceClaim = (id, category, subject, assertion, locator, options = {}) => {
12087
+ const state = options.state ?? "source-observed";
12088
+ return {
12089
+ schemaVersion: "1.0",
12090
+ id,
12091
+ runtimeId: "antigravity",
12092
+ category,
12093
+ subject,
12094
+ assertion,
12095
+ versionRange: options.versionRange ?? cliVersionRange,
12096
+ sourceType: "official-docs",
12097
+ source: options.source ?? cliDocs,
12098
+ sourceLocator: locator,
12099
+ sourceDigest: digest2(`${id}:${assertion}:${locator}`),
12100
+ state,
12101
+ confidence: state === "unknown" ? "low" : "high",
12102
+ verificationStatus: state === "unknown" ? "unverified" : "verified",
12103
+ stability: state === "unknown" ? "version-gated" : "stable",
12104
+ verifiedAt: retrievedAt
12105
+ };
12106
+ };
12102
12107
  var antigravityRuntimeEvidence = [
12103
12108
  sourceClaim(
12104
12109
  "antigravity.location.project-skills",
12105
12110
  "location",
12106
12111
  "workspace skill root",
12107
- "Antigravity discovers workspace skills beneath .agents/skills.",
12108
- "Section 9: .agents/skills/<name>/SKILL.md"
12112
+ "Antigravity CLI discovers workspace skills beneath .agents/skills.",
12113
+ "Skill location: .agents/skills/<skill-name>/SKILL.md"
12109
12114
  ),
12110
12115
  sourceClaim(
12111
12116
  "antigravity.location.project-rules",
12112
12117
  "location",
12113
12118
  "workspace rule root",
12114
- "Antigravity discovers workspace rules beneath .agents/rules.",
12115
- "Section 9: .agents/rules/*.md"
12119
+ "The native workspace rule path is not established by the verified CLI skill documentation.",
12120
+ "Workspace rule path: not established",
12121
+ { source: productDocs, state: "unknown" }
12116
12122
  ),
12117
12123
  sourceClaim(
12118
12124
  "antigravity.location.project-agents",
12119
12125
  "location",
12120
12126
  "workspace agent root",
12121
- "Antigravity discovers custom agents beneath .agents/agents.",
12122
- "Section 3: .agents/agents/<name>.md"
12127
+ "The native workspace agent path is not established by the verified CLI skill documentation.",
12128
+ "Workspace agent path: not established",
12129
+ { source: productDocs, state: "unknown" }
12123
12130
  ),
12124
12131
  sourceClaim(
12125
12132
  "antigravity.location.project-hooks",
12126
12133
  "location",
12127
12134
  "workspace hook config",
12128
- "Antigravity discovers workspace hooks from .agents/hooks.json.",
12129
- "Section 3: .agents/hooks.json"
12135
+ "The native workspace hook path is not established by the verified CLI skill documentation.",
12136
+ "Workspace hook path: not established",
12137
+ { source: productDocs, state: "unknown" }
12130
12138
  ),
12131
12139
  sourceClaim(
12132
12140
  "antigravity.location.project-mcp",
12133
12141
  "location",
12134
12142
  "workspace MCP config",
12135
- "Antigravity discovers workspace MCP servers from .agents/mcp_config.json.",
12136
- "Section 3: .agents/mcp_config.json"
12143
+ "The native workspace MCP configuration path is not established by the verified CLI skill documentation.",
12144
+ "Workspace MCP path: not established",
12145
+ { source: productDocs, state: "unknown" }
12137
12146
  ),
12138
12147
  sourceClaim(
12139
12148
  "antigravity.location.plugins",
12140
12149
  "location",
12141
12150
  "CLI plugin staging root",
12142
- "Antigravity CLI stages plugins beneath the documented Gemini plugin root.",
12143
- "Section 2: ~/.gemini/antigravity-cli/plugins/<plugin-name>/"
12151
+ "The native CLI plugin staging path is not established by the verified CLI skill documentation.",
12152
+ "CLI plugin staging path: not established",
12153
+ { source: productDocs, state: "unknown" }
12144
12154
  ),
12145
12155
  sourceClaim(
12146
12156
  "antigravity.workflow.storage",
12147
12157
  "location",
12148
12158
  "workflow storage",
12149
12159
  "Workflow physical storage path is not established by primary public documentation.",
12150
- "Section 9: workflow storage unknown",
12151
- "unknown"
12160
+ "Workflow storage path: not established",
12161
+ { source: productDocs, state: "unknown" }
12152
12162
  ),
12153
12163
  sourceClaim(
12154
12164
  "antigravity.cli.discovery.skills",
12155
12165
  "discovery",
12156
12166
  "CLI skill discovery",
12157
- "Antigravity CLI discovers project skills from .agents/skills.",
12158
- "Section 3; CLI mode; source observation only",
12159
- "source-observed",
12160
- "cli"
12167
+ "Antigravity CLI automatically discovers project skills from .agents/skills.",
12168
+ "Skill discovery and /skills listing"
12161
12169
  ),
12162
12170
  sourceClaim(
12163
12171
  "antigravity.cli.invocation.skills",
12164
12172
  "invocation",
12165
12173
  "CLI skill invocation",
12166
- "Antigravity CLI skill invocation is documented but not runtime-observed.",
12167
- "Section 6; CLI mode; runtime unavailable",
12168
- "source-observed",
12169
- "cli"
12174
+ "Antigravity CLI can list and invoke a discovered skill from the project workspace.",
12175
+ "Launch with agy; invoke through the skill-aware CLI workflow"
12170
12176
  ),
12171
12177
  sourceClaim(
12172
12178
  "antigravity.ide.discovery.skills",
12173
12179
  "discovery",
12174
12180
  "IDE skill discovery",
12175
- "Antigravity IDE uses the shared .agents/skills workspace root.",
12176
- "Section 3; IDE mode; runtime unavailable",
12177
- "source-observed",
12178
- "ide"
12181
+ "IDE skill discovery is not established by the verified CLI skill documentation.",
12182
+ "IDE skill discovery: not established",
12183
+ { source: productDocs, state: "unknown" }
12179
12184
  ),
12180
12185
  sourceClaim(
12181
12186
  "antigravity.cli.discovery.rules",
12182
12187
  "discovery",
12183
- "2.0 rule discovery",
12184
- "Workspace rules are discovered from .agents/rules.",
12185
- "Section 3; Antigravity 2.0 mode",
12186
- "source-observed",
12187
- "2.0"
12188
+ "workspace rule discovery",
12189
+ "Workspace rule discovery is not established by the verified CLI skill documentation.",
12190
+ "Workspace rule discovery: not established",
12191
+ { source: productDocs, state: "unknown" }
12188
12192
  ),
12189
12193
  sourceClaim(
12190
12194
  "antigravity.cli.discovery.agents",
12191
12195
  "discovery",
12192
- "2.0 agent discovery",
12193
- "Custom agents are discovered from .agents/agents.",
12194
- "Section 3; Antigravity 2.0 mode",
12195
- "source-observed",
12196
- "2.0"
12196
+ "workspace agent discovery",
12197
+ "Workspace agent discovery is not established by the verified CLI skill documentation.",
12198
+ "Workspace agent discovery: not established",
12199
+ { source: productDocs, state: "unknown" }
12197
12200
  ),
12198
12201
  sourceClaim(
12199
12202
  "antigravity.cli.hooks",
12200
12203
  "hooks",
12201
- "2.0 hook registration",
12202
- "Workspace hooks use .agents/hooks.json and typed tool decisions.",
12203
- "Section 6; Antigravity 2.0 mode",
12204
- "source-observed",
12205
- "2.0"
12204
+ "workspace hook registration",
12205
+ "Workspace hook registration is not established by the verified CLI skill documentation.",
12206
+ "Workspace hook registration: not established",
12207
+ { source: productDocs, state: "unknown" }
12206
12208
  ),
12207
12209
  sourceClaim(
12208
12210
  "antigravity.cli.mcp",
12209
12211
  "mcp",
12210
- "2.0 MCP registration",
12211
- "Workspace MCP uses .agents/mcp_config.json.",
12212
- "Section 3; Antigravity 2.0 mode",
12213
- "source-observed",
12214
- "2.0"
12212
+ "workspace MCP registration",
12213
+ "Workspace MCP registration is not established by the verified CLI skill documentation.",
12214
+ "Workspace MCP registration: not established",
12215
+ { source: productDocs, state: "unknown" }
12215
12216
  ),
12216
12217
  sourceClaim(
12217
12218
  "antigravity.cli.plugins",
12218
12219
  "plugin",
12219
12220
  "CLI plugin registration",
12220
- "CLI plugins require staged bundles with plugin.json.",
12221
- "Section 5; CLI mode",
12222
- "source-observed",
12223
- "cli"
12221
+ "CLI plugin registration is not established by the verified CLI skill documentation.",
12222
+ "CLI plugin registration: not established",
12223
+ { source: productDocs, state: "unknown" }
12224
12224
  )
12225
12225
  ];
12226
12226
 
@@ -13073,6 +13073,7 @@ var codexRuntimeEvidence = Object.freeze([
13073
13073
  ]);
13074
13074
 
13075
13075
  // packages/adapters/src/dcode/materialize.ts
13076
+ import { readFile as readFile3 } from "node:fs/promises";
13076
13077
  import { resolve as resolve5 } from "node:path";
13077
13078
  var marker4 = "<!-- portable-capabilities:owned dcode -->";
13078
13079
  function destination4(value) {
@@ -13118,7 +13119,32 @@ function registration3(operation) {
13118
13119
  return `${JSON.stringify({ adapterId: operation.adapterId, kind: operation.kind, target: operation.target }, null, 2)}
13119
13120
  `;
13120
13121
  }
13121
- function prepareDCodeMaterialization(plan, root) {
13122
+ async function mergedInstructions(root, path9, operations, removedIds) {
13123
+ let existing;
13124
+ try {
13125
+ existing = await readFile3(resolve5(root, path9), "utf8");
13126
+ } catch (error) {
13127
+ if (error.code !== "ENOENT") throw error;
13128
+ }
13129
+ if (!existing && operations.length === 0) return void 0;
13130
+ const selectedIds = new Set(operations.map((operation) => operation.id));
13131
+ const existingText = existing ?? "";
13132
+ const firstHeading = existingText.search(/^## .+$/mu);
13133
+ const preamble = firstHeading >= 0 ? existingText.slice(0, firstHeading).trim() : existingText.trim();
13134
+ const sections = firstHeading >= 0 ? existingText.slice(firstHeading).split(/(?=^## .+$)/mu) : [];
13135
+ const retained = sections.filter((section) => {
13136
+ const id = section.match(/^## ([^\n]+)/u)?.[1] ?? "";
13137
+ return !selectedIds.has(id) && !removedIds.some((removedId) => id.startsWith(`${removedId}:`));
13138
+ }).map((section) => section.trim());
13139
+ const generated = operations.slice().sort((left, right) => left.id.localeCompare(right.id)).map((operation) => `## ${operation.id}
13140
+
13141
+ ${operation.content.trim()}`);
13142
+ const sectionsToWrite = [...retained, ...generated];
13143
+ return sectionsToWrite.length > 0 ? `${preamble || marker4}
13144
+ ${sectionsToWrite.join("\n\n")}
13145
+ ` : void 0;
13146
+ }
13147
+ async function prepareDCodeMaterialization(plan, root) {
13122
13148
  if (plan.runtimeId !== "dcode") throw new Error(`DCode adapter cannot prepare ${plan.runtimeId}`);
13123
13149
  const mutations = [];
13124
13150
  const diagnostics = [];
@@ -13220,28 +13246,39 @@ function prepareDCodeMaterialization(plan, root) {
13220
13246
  );
13221
13247
  }
13222
13248
  }
13223
- if (instructionOperations.length > 0) {
13249
+ const instructionRemovals = plan.operations.filter(
13250
+ (operation) => operation.kind === "RemoveOwnedArtifact" && /^\.deepagents\/skills\/[^/]+\/SKILL\.md$/u.test(destination4(operation.detail))
13251
+ );
13252
+ if (instructionOperations.length > 0 || instructionRemovals.length > 0) {
13224
13253
  const instructionPath = ".deepagents/AGENTS.md";
13225
13254
  confined4(root, instructionPath);
13226
- const content = instructionOperations.sort((left, right) => left.id.localeCompare(right.id)).map((operation) => `## ${operation.id}
13227
-
13228
- ${operation.content.trim()}`).join("\n\n");
13229
- const first = instructionOperations[0];
13230
- mutations.push({
13231
- path: instructionPath,
13232
- kind: "write",
13233
- content: `<!-- portable-capabilities:owned dcode -->
13234
- ${content}
13235
- `,
13236
- mode: 420,
13237
- operationId: "dcode:shared-instructions",
13238
- sourceProjectionOperationId: first.sourceProjectionOperationId,
13239
- ownershipIntent: first.ownershipIntent,
13240
- approval: first.approval,
13241
- rollback: first.rollback,
13242
- upgrade: first.upgrade,
13243
- uninstall: first.uninstall
13255
+ const first = instructionOperations[0] ?? instructionRemovals[0];
13256
+ if (!first) throw new Error("DCode shared instruction operation is missing");
13257
+ const removedIds = instructionRemovals.flatMap((operation) => {
13258
+ const match = operation.detail.match(/^\.deepagents\/skills\/([^/]+)\/SKILL\.md$/u);
13259
+ return match?.[1] ? [match[1]] : [];
13244
13260
  });
13261
+ const content = await mergedInstructions(
13262
+ root,
13263
+ instructionPath,
13264
+ instructionOperations,
13265
+ removedIds
13266
+ );
13267
+ mutations.push(
13268
+ content ? {
13269
+ path: instructionPath,
13270
+ kind: "write",
13271
+ content,
13272
+ mode: 420,
13273
+ operationId: "dcode:shared-instructions",
13274
+ sourceProjectionOperationId: first.sourceProjectionOperationId,
13275
+ ownershipIntent: first.ownershipIntent,
13276
+ approval: first.approval,
13277
+ rollback: first.rollback,
13278
+ upgrade: first.upgrade,
13279
+ uninstall: first.uninstall
13280
+ } : { path: instructionPath, kind: "remove", ...metadata3(first) }
13281
+ );
13245
13282
  }
13246
13283
  return Object.freeze({
13247
13284
  runtimeId: plan.runtimeId,
@@ -13253,7 +13290,7 @@ ${content}
13253
13290
 
13254
13291
  // packages/adapters/src/dcode/runtime-descriptor.ts
13255
13292
  var markdown3 = "materialize-markdown";
13256
- var source2 = "source-observed";
13293
+ var source = "source-observed";
13257
13294
  var dcodeRuntimeDescriptor = {
13258
13295
  schemaVersion: "1.0",
13259
13296
  id: "dcode",
@@ -13312,7 +13349,7 @@ var dcodeRuntimeDescriptor = {
13312
13349
  precedence: ["project"],
13313
13350
  evidenceClaimIds: ["dcode.discovery.cli-skill", "dcode.invocation.cli-skill"],
13314
13351
  stability: "stable",
13315
- evidenceState: source2
13352
+ evidenceState: source
13316
13353
  },
13317
13354
  {
13318
13355
  id: "dcode-cli-instructions",
@@ -13324,7 +13361,7 @@ var dcodeRuntimeDescriptor = {
13324
13361
  precedence: ["project"],
13325
13362
  evidenceClaimIds: ["dcode.location.project-root"],
13326
13363
  stability: "stable",
13327
- evidenceState: source2
13364
+ evidenceState: source
13328
13365
  },
13329
13366
  {
13330
13367
  id: "dcode-cli-sync-subagents",
@@ -13336,7 +13373,7 @@ var dcodeRuntimeDescriptor = {
13336
13373
  precedence: ["project", "user"],
13337
13374
  evidenceClaimIds: ["dcode.cli.sync-subagents"],
13338
13375
  stability: "version-gated",
13339
- evidenceState: source2
13376
+ evidenceState: source
13340
13377
  },
13341
13378
  {
13342
13379
  id: "dcode-cli-memory",
@@ -13348,7 +13385,7 @@ var dcodeRuntimeDescriptor = {
13348
13385
  precedence: ["project", "user"],
13349
13386
  evidenceClaimIds: ["dcode.cli.memory"],
13350
13387
  stability: "version-gated",
13351
- evidenceState: source2
13388
+ evidenceState: source
13352
13389
  },
13353
13390
  {
13354
13391
  id: "dcode-cli-mcp",
@@ -13360,7 +13397,7 @@ var dcodeRuntimeDescriptor = {
13360
13397
  precedence: ["project", "user"],
13361
13398
  evidenceClaimIds: ["dcode.cli.mcp"],
13362
13399
  stability: "version-gated",
13363
- evidenceState: source2
13400
+ evidenceState: source
13364
13401
  },
13365
13402
  {
13366
13403
  id: "dcode-cli-configuration",
@@ -13372,7 +13409,7 @@ var dcodeRuntimeDescriptor = {
13372
13409
  precedence: ["project", "user"],
13373
13410
  evidenceClaimIds: ["dcode.cli.configuration"],
13374
13411
  stability: "version-gated",
13375
- evidenceState: source2
13412
+ evidenceState: source
13376
13413
  },
13377
13414
  {
13378
13415
  id: "dcode-cli-advisory-hooks",
@@ -13384,7 +13421,7 @@ var dcodeRuntimeDescriptor = {
13384
13421
  precedence: ["project", "user"],
13385
13422
  evidenceClaimIds: ["dcode.hooks.advisory"],
13386
13423
  stability: "version-gated",
13387
- evidenceState: source2
13424
+ evidenceState: source
13388
13425
  },
13389
13426
  {
13390
13427
  id: "dcode-sdk-tools",
@@ -13396,7 +13433,7 @@ var dcodeRuntimeDescriptor = {
13396
13433
  precedence: ["sdk"],
13397
13434
  evidenceClaimIds: ["dcode.sdk.tools"],
13398
13435
  stability: "version-gated",
13399
- evidenceState: source2
13436
+ evidenceState: source
13400
13437
  },
13401
13438
  {
13402
13439
  id: "dcode-cli-async-subagents",
@@ -15048,7 +15085,8 @@ var piRuntimeDescriptor = {
15048
15085
  // packages/adapters/src/pi/runtime-evidence.ts
15049
15086
  import { createHash as createHash13 } from "node:crypto";
15050
15087
  var digest8 = (value) => createHash13("sha256").update(value).digest("hex");
15051
- var observedAt2 = "2026-08-08T04:24:00-05:00";
15088
+ var observedAt2 = "2026-08-15T00:00:00.000Z";
15089
+ var skillsDocs = "https://pi.dev/docs/latest/skills";
15052
15090
  var piRuntimeEvidence = [
15053
15091
  {
15054
15092
  schemaVersion: "1.0",
@@ -15110,13 +15148,13 @@ var piRuntimeEvidence = [
15110
15148
  runtimeId: "pi",
15111
15149
  category: "discovery",
15112
15150
  subject: "native skill discovery",
15113
- assertion: "Pi natively discovers a project skill with extensions disabled.",
15114
- versionRange: "=0.64.0",
15115
- sourceType: "runtime-probe",
15116
- source: "pi",
15117
- sourceLocator: "packages/conformance/src/tracer/pi-native-evidence.json",
15118
- sourceDigest: digest8("Pi native discovery with extensions disabled"),
15119
- state: "runtime-observed",
15151
+ assertion: "Pi discovers project skills beneath .pi/skills.",
15152
+ versionRange: ">=0.64.0",
15153
+ sourceType: "official-docs",
15154
+ source: skillsDocs,
15155
+ sourceLocator: "Project skills: .pi/skills/",
15156
+ sourceDigest: digest8("Pi project skills .pi/skills official docs"),
15157
+ state: "source-observed",
15120
15158
  confidence: "high",
15121
15159
  verificationStatus: "verified",
15122
15160
  stability: "stable",
@@ -15128,13 +15166,13 @@ var piRuntimeEvidence = [
15128
15166
  runtimeId: "pi",
15129
15167
  category: "invocation",
15130
15168
  subject: "native skill invocation",
15131
- assertion: "Pi invokes a discovered project skill with extensions disabled.",
15132
- versionRange: "=0.64.0",
15133
- sourceType: "runtime-probe",
15134
- source: "pi",
15135
- sourceLocator: "packages/conformance/src/tracer/pi-native-evidence.json",
15136
- sourceDigest: digest8("Pi native invocation with extensions disabled"),
15137
- state: "runtime-observed",
15169
+ assertion: "Pi loads a discovered skill when its description matches the task or the user invokes /skill:name.",
15170
+ versionRange: ">=0.64.0",
15171
+ sourceType: "official-docs",
15172
+ source: skillsDocs,
15173
+ sourceLocator: "Skill loading and invocation: /skill:name",
15174
+ sourceDigest: digest8("Pi skill invocation official docs"),
15175
+ state: "source-observed",
15138
15176
  confidence: "high",
15139
15177
  verificationStatus: "verified",
15140
15178
  stability: "stable",
@@ -15253,19 +15291,19 @@ function normalizeSetupRequest(input) {
15253
15291
  // packages/cli/src/setup/service.ts
15254
15292
  import { createHash as createHash16 } from "node:crypto";
15255
15293
  import { existsSync as existsSync2 } from "node:fs";
15256
- import { readdir as readdir3, readFile as readFile5 } from "node:fs/promises";
15294
+ import { readdir as readdir3, readFile as readFile6 } from "node:fs/promises";
15257
15295
  import { dirname as dirname4, isAbsolute as isAbsolute3, relative as relative3, resolve as resolve11 } from "node:path";
15258
15296
  import { fileURLToPath as fileURLToPath4 } from "node:url";
15259
15297
  import { parse as parse3 } from "yaml";
15260
15298
 
15261
15299
  // packages/cli/src/installation/lifecycle.ts
15262
15300
  import { createHash as createHash15 } from "node:crypto";
15263
- import { chmod, copyFile, lstat as lstat2, mkdir as mkdir3, readFile as readFile4, rename as rename2, rm, writeFile as writeFile3 } from "node:fs/promises";
15301
+ import { chmod, copyFile, lstat as lstat2, mkdir as mkdir3, readFile as readFile5, rename as rename2, rm, writeFile as writeFile3 } from "node:fs/promises";
15264
15302
  import { dirname as dirname3, isAbsolute as isAbsolute2, join as join3, relative as relative2, resolve as resolve10, sep } from "node:path";
15265
15303
 
15266
15304
  // packages/cli/src/installation/manifest.ts
15267
15305
  import { createHash as createHash14 } from "node:crypto";
15268
- import { mkdir as mkdir2, readFile as readFile3, rename, stat, writeFile as writeFile2 } from "node:fs/promises";
15306
+ import { mkdir as mkdir2, readFile as readFile4, rename, stat, writeFile as writeFile2 } from "node:fs/promises";
15269
15307
  import { dirname as dirname2, join as join2 } from "node:path";
15270
15308
  var installationManifestName = ".portable-capabilities-manifest.json";
15271
15309
  var installationJournalName = ".portable-capabilities-journal.json";
@@ -15319,7 +15357,7 @@ function verifyInstallationManifestDigest(manifest) {
15319
15357
  }
15320
15358
  }
15321
15359
  async function digestFile(path9) {
15322
- return digestBytes(await readFile3(path9));
15360
+ return digestBytes(await readFile4(path9));
15323
15361
  }
15324
15362
  function manifestPath(targetRoot) {
15325
15363
  return join2(targetRoot, installationManifestName);
@@ -15330,7 +15368,7 @@ function journalPath(targetRoot) {
15330
15368
  async function readInstallationManifest(targetRoot) {
15331
15369
  try {
15332
15370
  const parsed = JSON.parse(
15333
- await readFile3(manifestPath(targetRoot), "utf8")
15371
+ await readFile4(manifestPath(targetRoot), "utf8")
15334
15372
  );
15335
15373
  if (parsed.schemaVersion !== "1.1.0" || !Array.isArray(parsed.entries)) {
15336
15374
  throw new Error("Invalid installation manifest shape");
@@ -15400,10 +15438,10 @@ async function writeJournal(targetRoot, journal) {
15400
15438
  );
15401
15439
  await rename2(temporary, path9);
15402
15440
  }
15403
- async function copyAtomically(source3, target, mode) {
15441
+ async function copyAtomically(source2, target, mode) {
15404
15442
  await mkdir3(dirname3(target), { recursive: true });
15405
15443
  const temporary = `${target}.pc-stage-${process.pid}`;
15406
- await copyFile(source3, temporary);
15444
+ await copyFile(source2, temporary);
15407
15445
  await chmod(temporary, mode);
15408
15446
  await rename2(temporary, target);
15409
15447
  }
@@ -15422,13 +15460,13 @@ function result(operation, state, values = {}) {
15422
15460
  };
15423
15461
  }
15424
15462
  async function backupPath(targetRoot, transactionRoot, path9) {
15425
- const source3 = await assertNoSymlinkInPreparedPath(targetRoot, path9);
15426
- if (!await pathExists(source3)) return false;
15463
+ const source2 = await assertNoSymlinkInPreparedPath(targetRoot, path9);
15464
+ if (!await pathExists(source2)) return false;
15427
15465
  await assertNoSymlinkInPreparedPath(targetRoot, path9);
15428
15466
  const target = join3(transactionRoot, "backup", path9);
15429
15467
  await mkdir3(dirname3(target), { recursive: true });
15430
15468
  await assertNoSymlinkInPreparedPath(targetRoot, path9);
15431
- await copyFile(source3, target);
15469
+ await copyFile(source2, target);
15432
15470
  return true;
15433
15471
  }
15434
15472
  async function restoreTransaction(targetRoot, transactionRoot, mutations, manifestHadOriginal, options) {
@@ -15607,6 +15645,19 @@ async function assertPlanPathsSafe(targetRoot, plan) {
15607
15645
  }
15608
15646
  async function executePreparedInstallation(options) {
15609
15647
  const manifest = await readInstallationManifest(options.targetRoot);
15648
+ const operation = options.preparedOperation ?? "install";
15649
+ if (options.preparedDiagnostics?.length) {
15650
+ return result(operation, "degraded", {
15651
+ ok: false,
15652
+ diagnostics: options.preparedDiagnostics
15653
+ });
15654
+ }
15655
+ if (options.preparedMutations.length === 0) {
15656
+ return result(operation, "degraded", {
15657
+ ok: false,
15658
+ diagnostics: ["No prepared mutations can be installed"]
15659
+ });
15660
+ }
15610
15661
  const duplicatePaths = /* @__PURE__ */ new Set();
15611
15662
  for (const mutation of options.preparedMutations) {
15612
15663
  if (duplicatePaths.has(mutation.path)) {
@@ -15635,7 +15686,7 @@ async function executePreparedInstallation(options) {
15635
15686
  const exists = await pathExists(target);
15636
15687
  if (mutation.ownershipIntent === "preserve-user" && exists) continue;
15637
15688
  if (exists && mutation.kind === "write" && mutation.ownershipIntent === "own") {
15638
- const current = await readFile4(target, "utf8");
15689
+ const current = await readFile5(target, "utf8");
15639
15690
  const ownedEntry = manifest?.entries.find((entry) => entry.path === mutation.path);
15640
15691
  const isManifestOwned = ownedEntry !== void 0 && await digestFile(target) === ownedEntry.digest;
15641
15692
  if (!current.includes("portable-capabilities:owned") && !isManifestOwned)
@@ -15681,7 +15732,6 @@ async function executePreparedInstallation(options) {
15681
15732
  packageIdentities,
15682
15733
  entries: nextEntries
15683
15734
  };
15684
- const operation = options.preparedOperation ?? "install";
15685
15735
  if (options.dryRun)
15686
15736
  return result(operation, manifest ? "healthy" : "missing", {
15687
15737
  dryRun: true,
@@ -15716,63 +15766,6 @@ async function statusInstallation(targetRoot) {
15716
15766
  manifest
15717
15767
  });
15718
15768
  }
15719
- async function removeInstallation(targetRoot, faultInjector, capabilityIds) {
15720
- const manifest = await readInstallationManifest(targetRoot);
15721
- if (!manifest) return result("remove", "missing", { ok: false });
15722
- const selected = new Set(capabilityIds ?? []);
15723
- const scoped = (path9) => {
15724
- if (selected.size === 0) return true;
15725
- const normalized = path9.replaceAll("\\", "/");
15726
- return [...selected].some(
15727
- (id) => normalized.includes(`/skills/${id}/`) || normalized.endsWith(`/skills/${id}`)
15728
- );
15729
- };
15730
- const classifications = await classifyManifestEntries(manifest);
15731
- const unchanged = new Set(
15732
- classifications.unchanged.filter((entry) => scoped(entry.path)).map((entry) => entry.path)
15733
- );
15734
- const removes = manifest.entries.filter((entry) => unchanged.has(entry.path)).map((entry) => entry.path);
15735
- const preserved = manifest.entries.filter((entry) => !unchanged.has(entry.path));
15736
- const nextManifest = preserved.length ? (() => {
15737
- const entries = Object.freeze(preserved);
15738
- const preservedPaths = new Set(entries.map((entry) => entry.path));
15739
- const packageIdentities = Object.freeze(
15740
- manifest.packageIdentities.filter((identity3) => preservedPaths.has(identity3.lockPath))
15741
- );
15742
- const packageDigest = packageEntriesDigest(entries, packageIdentities);
15743
- const base = {
15744
- runtimeId: manifest.runtimeId,
15745
- packageVersion: manifest.packageVersion,
15746
- targetRoot: manifest.targetRoot,
15747
- journalVersion: manifest.journalVersion,
15748
- lifecycleState: "modified",
15749
- packageIdentities,
15750
- entries
15751
- };
15752
- return {
15753
- ...manifest,
15754
- ...base,
15755
- packageDigest,
15756
- installationDigest: installationOwnershipDigest(packageDigest, base)
15757
- };
15758
- })() : void 0;
15759
- return commitPlan(
15760
- "remove",
15761
- {
15762
- sourceRoot: targetRoot,
15763
- targetRoot,
15764
- runtimeId: manifest.runtimeId,
15765
- packageVersion: manifest.packageVersion,
15766
- ...faultInjector ? { faultInjector } : {}
15767
- },
15768
- {
15769
- writes: [],
15770
- removes,
15771
- preserved: preserved.map((entry) => entry.path),
15772
- ...nextManifest ? { nextManifest } : {}
15773
- }
15774
- );
15775
- }
15776
15769
 
15777
15770
  // packages/cli/src/setup/service.ts
15778
15771
  function roleFacet(role, name) {
@@ -15833,7 +15826,7 @@ async function loadCanonicalArtifact(catalogRoot, capabilityId) {
15833
15826
  if (!capabilityId || /[\\/]/u.test(capabilityId))
15834
15827
  throw new Error("capability IDs must be single path segments");
15835
15828
  const file = resolve11(catalogRoot, "roles", `${capabilityId}.yaml`);
15836
- const role = parse3(await readFile5(file, "utf8"));
15829
+ const role = parse3(await readFile6(file, "utf8"));
15837
15830
  if (role.schemaVersion !== "1.0" || role.id !== capabilityId || !role.purpose || !Array.isArray(role.inputs) || !role.output || !role.family || !role.taxonomy || !Array.isArray(role.precedence) || !Array.isArray(role.requiredBehavior) || !Array.isArray(role.forbiddenBehavior) || !Array.isArray(role.evaluation?.criteria)) {
15838
15831
  throw new Error(`Invalid canonical capability: ${file}`);
15839
15832
  }
@@ -15842,7 +15835,7 @@ async function loadCanonicalArtifact(catalogRoot, capabilityId) {
15842
15835
  const schemaRelativePath = relative3(resolve11(catalogRoot), schemaFile);
15843
15836
  if (isAbsolute3(schemaRelativePath) || schemaRelativePath.startsWith(".."))
15844
15837
  throw new Error(`Canonical output schema escapes catalog: ${role.output.schema}`);
15845
- const schemaContent = await readFile5(schemaFile, "utf8");
15838
+ const schemaContent = await readFile6(schemaFile, "utf8");
15846
15839
  const contract = operationalContract(role);
15847
15840
  const contractContent = `${JSON.stringify(
15848
15841
  { ...role, output: { ...role.output, schema: "resources/output.schema.json" } },
@@ -15915,6 +15908,35 @@ function previewSetup(request, artifact, descriptor, claims, ownershipManifest)
15915
15908
  const body = { ...plan, selectedSurfaces, conversions, conflicts };
15916
15909
  return { ...body, digest: stableDigest(body) };
15917
15910
  }
15911
+ function negotiationDiagnostics(previews) {
15912
+ return previews.flatMap(
15913
+ (preview) => preview.negotiations.filter((negotiation) => negotiation.installationMode !== "automatic").map((negotiation) => {
15914
+ const evidence = negotiation.evidenceClaimIds.join(", ") || "no evidence claims";
15915
+ return `${negotiation.intent}: ${negotiation.installationMode} (${negotiation.reason}) [${evidence}]`;
15916
+ })
15917
+ );
15918
+ }
15919
+ function composeInstallationPlan(previews, artifacts, runtimeId) {
15920
+ const first = previews[0]?.installationPlan;
15921
+ if (!first) throw new Error("at least one installation plan is required");
15922
+ const operations = previews.flatMap((preview, index) => {
15923
+ const capabilityId = artifacts[index]?.id;
15924
+ if (!capabilityId) throw new Error("installation plan is missing its capability");
15925
+ return preview.installationPlan.operations.map((operation) => ({
15926
+ ...operation,
15927
+ id: `${capabilityId}:${operation.id}`,
15928
+ sourceProjectionOperationId: `${capabilityId}:${operation.sourceProjectionOperationId}`
15929
+ }));
15930
+ });
15931
+ const base = {
15932
+ schemaVersion: first.schemaVersion,
15933
+ id: `installation:${runtimeId}:${artifacts.map((artifact) => artifact.id).join(",")}`,
15934
+ runtimeId,
15935
+ scope: first.scope,
15936
+ operations
15937
+ };
15938
+ return { ...base, digest: stableDigest(base) };
15939
+ }
15918
15940
  function defaultCatalogRoot() {
15919
15941
  const moduleDir = dirname4(fileURLToPath4(import.meta.url));
15920
15942
  const packagedCatalog = [resolve11(moduleDir, "catalog"), resolve11(moduleDir, "../catalog")].find(
@@ -15973,23 +15995,35 @@ async function executeSetupSelection(request, artifacts, descriptor, claims, con
15973
15995
  ...context.faultInjector ? { faultInjector: context.faultInjector } : {}
15974
15996
  };
15975
15997
  const runtime = resolveProductionRuntime(executionRequest.runtimeId);
15976
- const lifecycle = executionRequest.intent === "setup" || executionRequest.intent === "update" ? await executePreparedInstallation({
15977
- ...lifecycleOptions,
15978
- preparedOperation: executionRequest.intent === "update" ? "upgrade" : "install",
15979
- preparedMutations: (await Promise.all(
15980
- previews.map((preview) => runtime.prepare(preview.installationPlan, targetRoot))
15981
- )).flatMap((prepared) => prepared.mutations)
15982
- }) : executionRequest.intent === "remove" ? await removeInstallation(
15983
- targetRoot,
15984
- context.faultInjector,
15985
- executionRequest.capabilityIds
15986
- ) : await statusInstallation(targetRoot);
15998
+ const lifecycle = executionRequest.intent === "setup" || executionRequest.intent === "update" || executionRequest.intent === "remove" ? await (async () => {
15999
+ const installationPlan = composeInstallationPlan(
16000
+ previews,
16001
+ planningArtifacts,
16002
+ executionRequest.runtimeId
16003
+ );
16004
+ const prepared = await runtime.prepare(installationPlan, targetRoot);
16005
+ if (prepared.runtimeId !== installationPlan.runtimeId || prepared.planId !== installationPlan.id) {
16006
+ throw new Error(`Materializer returned an invalid ${executionRequest.runtimeId} plan`);
16007
+ }
16008
+ const duplicatePath = prepared.mutations.map((mutation) => mutation.path).find((path9, index, paths) => paths.indexOf(path9) !== index);
16009
+ if (duplicatePath)
16010
+ throw new Error(`Selection produced duplicate prepared path: ${duplicatePath}`);
16011
+ const preparedDiagnostics = [
16012
+ ...prepared.diagnostics?.map(
16013
+ (diagnostic6) => `${diagnostic6.kind}: ${diagnostic6.message}`
16014
+ ) ?? [],
16015
+ ...executionRequest.intent === "remove" ? [] : negotiationDiagnostics(previews)
16016
+ ];
16017
+ return executePreparedInstallation({
16018
+ ...lifecycleOptions,
16019
+ preparedOperation: executionRequest.intent === "update" ? "upgrade" : executionRequest.intent === "remove" ? "remove" : "install",
16020
+ preparedMutations: prepared.mutations,
16021
+ ...preparedDiagnostics.length > 0 ? { preparedDiagnostics } : {}
16022
+ });
16023
+ })() : await statusInstallation(targetRoot);
15987
16024
  return { request, previews, lifecycle };
15988
16025
  }
15989
16026
 
15990
- // packages/cli/src/wizard.ts
15991
- import { execFileSync } from "node:child_process";
15992
-
15993
16027
  // node_modules/.pnpm/@clack+core@1.4.3/node_modules/@clack/core/dist/index.mjs
15994
16028
  import { styleText } from "node:util";
15995
16029
  import { stdout, stdin } from "node:process";
@@ -17197,6 +17231,73 @@ ${r2}
17197
17231
  }
17198
17232
  }).prompt();
17199
17233
 
17234
+ // packages/cli/src/setup/probe.ts
17235
+ import { execFileSync } from "node:child_process";
17236
+ var executables = Object.freeze({
17237
+ antigravity: "agy",
17238
+ "claude-code": "claude",
17239
+ codex: "codex",
17240
+ dcode: "dcode",
17241
+ "oh-my-pi": "omp",
17242
+ opencode: "opencode",
17243
+ pi: "pi"
17244
+ });
17245
+ function resolveRuntimeProbe(runtimeId) {
17246
+ const runtime = resolveProductionRuntime(runtimeId);
17247
+ const canonicalId = runtime.descriptor.id;
17248
+ const executable = executables[canonicalId];
17249
+ if (!executable) throw new Error(`No runtime probe configured for ${canonicalId}`);
17250
+ return {
17251
+ runtimeId: canonicalId,
17252
+ executable,
17253
+ args: ["--version"],
17254
+ supportedVersions: runtime.descriptor.supportedVersions
17255
+ };
17256
+ }
17257
+ function parseVersion2(output) {
17258
+ return output.match(/\bv?(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)\b/u)?.[1];
17259
+ }
17260
+ function defaultRun(probe) {
17261
+ return execFileSync(probe.executable, probe.args, {
17262
+ encoding: "utf8",
17263
+ stdio: ["ignore", "pipe", "pipe"],
17264
+ timeout: 5e3
17265
+ });
17266
+ }
17267
+ function probeRuntimeVersion(runtimeId, options = {}) {
17268
+ const probe = resolveRuntimeProbe(runtimeId);
17269
+ let output;
17270
+ try {
17271
+ output = (options.run ?? defaultRun)(probe);
17272
+ } catch (error) {
17273
+ const code = error.code;
17274
+ const unavailable = code === "ENOENT" || code === "EACCES";
17275
+ return {
17276
+ status: unavailable ? "unavailable" : "failed",
17277
+ runtimeId: probe.runtimeId,
17278
+ executable: probe.executable,
17279
+ reason: unavailable ? `${probe.executable} is not installed or is not executable` : error instanceof Error ? error.message : String(error)
17280
+ };
17281
+ }
17282
+ const version = parseVersion2(output);
17283
+ if (!version)
17284
+ return {
17285
+ status: "unknown-version",
17286
+ runtimeId: probe.runtimeId,
17287
+ executable: probe.executable,
17288
+ reason: "version probe returned no parseable semantic version"
17289
+ };
17290
+ if (!probe.supportedVersions.some((range) => isRuntimeVersionInRange(range, version)))
17291
+ return {
17292
+ status: "unsupported-version",
17293
+ runtimeId: probe.runtimeId,
17294
+ executable: probe.executable,
17295
+ version,
17296
+ reason: `version ${version} is outside the supported runtime ranges`
17297
+ };
17298
+ return { status: "detected", runtimeId: probe.runtimeId, executable: probe.executable, version };
17299
+ }
17300
+
17200
17301
  // packages/cli/src/wizard.ts
17201
17302
  var supportedRuntimes = [...productionRuntimeRegistry.keys()];
17202
17303
  function unwrap(value) {
@@ -17207,17 +17308,6 @@ function unwrap(value) {
17207
17308
  }
17208
17309
  return value;
17209
17310
  }
17210
- function detectRuntimeVersion(runtime) {
17211
- try {
17212
- const output = execFileSync(runtime, ["--version"], {
17213
- encoding: "utf8",
17214
- stdio: ["ignore", "pipe", "pipe"]
17215
- });
17216
- return output.match(/\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?/)?.[0] ?? "unknown";
17217
- } catch {
17218
- return "unknown";
17219
- }
17220
- }
17221
17311
  async function runInstallWizard() {
17222
17312
  intro("Portable Capabilities setup");
17223
17313
  try {
@@ -17237,6 +17327,12 @@ async function runInstallWizard() {
17237
17327
  options: supportedRuntimes.map((value) => ({ value, label: value }))
17238
17328
  })
17239
17329
  );
17330
+ const probe = probeRuntimeVersion(runtime);
17331
+ if (probe.status !== "detected" || !probe.version) {
17332
+ log.error(`${runtime}: ${probe.reason ?? probe.status}`);
17333
+ process.exitCode = 4;
17334
+ return;
17335
+ }
17240
17336
  const target = String(
17241
17337
  unwrap(
17242
17338
  await text({
@@ -17254,7 +17350,7 @@ async function runInstallWizard() {
17254
17350
  );
17255
17351
  const request = normalizeSetupRequest({
17256
17352
  runtimeId: runtime,
17257
- runtimeVersion: detectRuntimeVersion(runtime),
17353
+ runtimeVersion: probe.version,
17258
17354
  scope: "project",
17259
17355
  projectDirectory: target,
17260
17356
  capabilityIds,
@@ -17276,7 +17372,7 @@ async function runInstallWizard() {
17276
17372
  runtimeEntry.claims,
17277
17373
  { sourceRoot: process.cwd(), packageVersion: cliVersion }
17278
17374
  );
17279
- if (!result2.lifecycle || !result2.lifecycle.ok) {
17375
+ if (!result2.lifecycle?.ok) {
17280
17376
  for (const diagnostic6 of result2.lifecycle?.diagnostics ?? ["Approval required."])
17281
17377
  log.error(diagnostic6);
17282
17378
  process.exitCode = 4;