@hasna/skills 0.10.81 → 0.10.83

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/bin/index.js CHANGED
@@ -36888,7 +36888,7 @@ var package_default;
36888
36888
  var init_package = __esm(() => {
36889
36889
  package_default = {
36890
36890
  name: "@hasna/skills",
36891
- version: "0.10.81",
36891
+ version: "0.10.83",
36892
36892
  description: "Skills library for AI coding agents",
36893
36893
  type: "module",
36894
36894
  bin: {
@@ -40624,7 +40624,7 @@ function hashClaudePluginCacheOrphanMarker(path, budget2, changes) {
40624
40624
  if (!before2)
40625
40625
  return null;
40626
40626
  const uid = process.getuid?.();
40627
- if (!before2.isFile() || uid === undefined || before2.uid !== uid || before2.size > 32)
40627
+ if (!before2.isFile() || uid === undefined || before2.uid !== uid || before2.size > 32 || (before2.mode & 73) !== 0)
40628
40628
  throw new Error("Invalid Claude orphan marker file or owner");
40629
40629
  const fd = openSync3(path, constants4.O_RDONLY | constants4.O_NOFOLLOW | constants4.O_NONBLOCK);
40630
40630
  try {
@@ -48216,7 +48216,7 @@ function safe2(path) {
48216
48216
  function same2(before2, after2) {
48217
48217
  return Boolean(after2 && after2.isDirectory() && before2.dev === after2.dev && before2.ino === after2.ino && before2.mtimeMs === after2.mtimeMs && before2.ctimeMs === after2.ctimeMs);
48218
48218
  }
48219
- function capture(path, budget2, excludedRoots, omittedRoots = [], rows) {
48219
+ function capture(path, budget2, excludedRoots, omittedRoots = [], rows, claudeMarkers) {
48220
48220
  safe2(path);
48221
48221
  if (omittedRoots.some((root2) => path === root2 || path.startsWith(root2 + "/")))
48222
48222
  return { path, sha256: null };
@@ -48244,6 +48244,11 @@ function capture(path, budget2, excludedRoots, omittedRoots = [], rows) {
48244
48244
  need3(child2.length <= AGENT_POLICY_LIMITS.pathCharacters, "Native discovery directory path limit exceeded");
48245
48245
  const stat = lstatSync7(child2);
48246
48246
  need3(stat.isFile() || stat.isDirectory(), "Refusing symlink or special native discovery directory member");
48247
+ if (claudeMarkers && isClaudePluginCacheOrphanMarker(child2)) {
48248
+ need3(hashClaudePluginCacheOrphanMarker(child2) !== null, "Claude orphan marker changed while reading directory");
48249
+ if (claudeMarkers === "omit")
48250
+ continue;
48251
+ }
48247
48252
  const row = JSON.stringify([childRelative, stat.isDirectory() ? "directory" : "file"]) + `
48248
48253
  `;
48249
48254
  budget2.bytes += Buffer.byteLength(row);
@@ -48300,25 +48305,33 @@ function verifyDiscoveryDirectoryProjection(directories, omittedRoots, tolerance
48300
48305
  witnessChanged(new NativeDiscoveryWitnessChange("membership", directories[i].path, "Native discovery directory membership changed outside retired Codex roots"), tolerance, tolerance?.acceptsMembership(directories[i].path) === true);
48301
48306
  }
48302
48307
  }
48303
- function captureDiscoveryDirectories(paths, excludedRoots = []) {
48308
+ function captureOrdinaryDirectories(paths, excludedRoots, claudeMarkers) {
48304
48309
  need3(Array.isArray(paths) && paths.length <= AGENT_POLICY_LIMITS.discoveryDirectories && new Set(paths).size === paths.length, "Invalid native discovery directory collection");
48305
48310
  const budget2 = { entries: 0, bytes: 0 };
48306
48311
  for (const root of excludedRoots)
48307
48312
  safe2(root);
48308
- return paths.map((path) => capture(path, budget2, excludedRoots));
48313
+ return paths.map((path) => capture(path, budget2, excludedRoots, [], undefined, claudeMarkers));
48314
+ }
48315
+ function captureDiscoveryDirectories(paths, excludedRoots = []) {
48316
+ return captureOrdinaryDirectories(paths, excludedRoots, "omit");
48309
48317
  }
48310
48318
  function verifyDiscoveryDirectories(directories, excludedRoots = [], tolerance) {
48311
48319
  need3(Array.isArray(directories) && directories.length <= AGENT_POLICY_LIMITS.discoveryDirectories, "Invalid native discovery directory collection");
48312
48320
  for (const directory of directories)
48313
48321
  need3(directory && typeof directory === "object" && (directory.sha256 === null || typeof directory.sha256 === "string" && /^[a-f0-9]{64}$/.test(directory.sha256)), "Invalid native discovery directory digest");
48314
48322
  const current = captureDiscoveryDirectories(directories.map((directory) => directory.path), excludedRoots);
48323
+ let legacy;
48315
48324
  for (let i = 0;i < directories.length; i++)
48316
48325
  if (current[i].sha256 !== directories[i].sha256) {
48326
+ legacy ??= captureOrdinaryDirectories(directories.map((directory) => directory.path), excludedRoots, "retain");
48327
+ if (legacy[i].sha256 === directories[i].sha256)
48328
+ continue;
48317
48329
  witnessChanged(new NativeDiscoveryWitnessChange("membership", directories[i].path, `Native discovery directory membership changed; run skills hook install with a fresh discovery review: ${directories[i].path}`), tolerance, tolerance?.acceptsMembership(directories[i].path) === true);
48318
48330
  }
48319
48331
  }
48320
48332
  var init_agent_discovery_directories = __esm(() => {
48321
48333
  init_agent_policy_limits();
48334
+ init_claude_plugin_cache_marker();
48322
48335
  init_native_discovery_witness_change();
48323
48336
  });
48324
48337
 
@@ -57442,6 +57455,7 @@ var init_hook_diagnostics = __esm(() => {
57442
57455
  "CACHED_PROFILE_EXPIRED",
57443
57456
  "CACHED_PROFILE_MISSING",
57444
57457
  "CACHED_BUNDLE_MISSING",
57458
+ "PROFILE_LOCK_MISMATCH",
57445
57459
  "SESSION_RECONCILIATION_REQUIRED",
57446
57460
  "SESSION_RENEWAL_TIMEOUT",
57447
57461
  "SESSION_WRITE_BUSY",
@@ -67851,7 +67865,7 @@ function checkedPublicationView(value, skillId, intentId, declaration) {
67851
67865
  return invalid3();
67852
67866
  return Object.freeze({ ...value });
67853
67867
  }
67854
- async function boundedJson(url, init, token, mutation, budget2 = 15000, signal, create3 = false) {
67868
+ async function boundedJson(url, init, token, mutation, budget2 = 15000, signal, create3 = false, readBinding) {
67855
67869
  const controller = new AbortController;
67856
67870
  let reader;
67857
67871
  let response;
@@ -67867,8 +67881,18 @@ async function boundedJson(url, init, token, mutation, budget2 = 15000, signal,
67867
67881
  redirect: "error",
67868
67882
  credentials: "omit",
67869
67883
  signal: controller.signal,
67870
- headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` }
67884
+ headers: {
67885
+ "Content-Type": "application/json",
67886
+ Authorization: `Bearer ${token}`,
67887
+ ...readBinding ? {
67888
+ "x-skills-user-id": readBinding.userId,
67889
+ "x-skills-workspace-id": readBinding.organizationId,
67890
+ "x-skills-membership-id": readBinding.membershipId
67891
+ } : {}
67892
+ }
67871
67893
  });
67894
+ if (readBinding && response.ok && response.status !== 200)
67895
+ return invalid3();
67872
67896
  const length = response.headers.get("content-length");
67873
67897
  if (length !== null && (!/^\d+$/.test(length) || Number(length) > 65536))
67874
67898
  return invalid3();
@@ -67936,6 +67960,81 @@ async function boundedJson(url, init, token, mutation, budget2 = 15000, signal,
67936
67960
  response?.body?.cancel().catch(() => {});
67937
67961
  }
67938
67962
  }
67963
+ function historyDate(value) {
67964
+ if (typeof value !== "string")
67965
+ return false;
67966
+ const parts = /^(\d{4})-(\d{2})-(\d{2})(T| )(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,9}))?(Z|[+-](\d{2})(?::(\d{2}))?)$/.exec(value);
67967
+ if (!parts)
67968
+ return false;
67969
+ const [, y, m, d, separator, h, minute, second, fraction, zone, offsetHour, offsetMinute] = parts;
67970
+ if (separator === " " ? zone === "Z" || (fraction?.length ?? 0) > 6 : zone !== "Z" && offsetMinute === undefined)
67971
+ return false;
67972
+ const year = Number(y), month = Number(m), day = Number(d);
67973
+ const leap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
67974
+ const days = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
67975
+ return year > 0 && month >= 1 && month <= 12 && day >= 1 && day <= days[month - 1] && Number(h) <= 23 && Number(minute) <= 59 && Number(second) <= 59 && (zone === "Z" || Number(offsetHour) <= 23 && Number(offsetMinute ?? 0) <= 59);
67976
+ }
67977
+ function privateHistory(value, organizationId, skillId, limit, cursor) {
67978
+ if (!record7(value) || value.organizationId !== organizationId || value.skillId !== skillId || typeof value.slug !== "string" || !/^[a-z0-9-]+$/.test(value.slug) || !(value.currentVersion === null || historyText(value.currentVersion)) || !(value.currentVersionId === null || publicationUuid(value.currentVersionId)) || value.currentVersion === null !== (value.currentVersionId === null) || !(value.nextCursor === null || publicationUuid(value.nextCursor)) || !Array.isArray(value.versions) || value.versions.length > limit)
67979
+ return historyResponse();
67980
+ const seen = new Set;
67981
+ let previous = cursor;
67982
+ const versions = value.versions.map((row) => {
67983
+ if (!record7(row) || !publicationUuid(row.id) || seen.has(row.id) || previous !== undefined && row.id >= previous || !historyText(row.version) || !(row.releasedAt === null || historyDate(row.releasedAt)) || !historyDate(row.createdAt) || row.id === value.currentVersionId !== (row.version === value.currentVersion))
67984
+ return historyResponse();
67985
+ seen.add(row.id);
67986
+ previous = row.id;
67987
+ return Object.freeze({ id: row.id, version: row.version, releasedAt: row.releasedAt, createdAt: row.createdAt });
67988
+ });
67989
+ if (value.nextCursor !== null && (!versions.length || value.nextCursor !== versions.at(-1).id))
67990
+ return historyResponse();
67991
+ return Object.freeze({
67992
+ organizationId,
67993
+ skillId,
67994
+ slug: value.slug,
67995
+ currentVersion: value.currentVersion,
67996
+ currentVersionId: value.currentVersionId,
67997
+ versions: Object.freeze(versions),
67998
+ nextCursor: value.nextCursor
67999
+ });
68000
+ }
68001
+
68002
+ class RemotePrivateSkillHistoryClient {
68003
+ apiOrigin;
68004
+ organizationId;
68005
+ userId;
68006
+ membershipId;
68007
+ #token;
68008
+ constructor(apiUrl, session) {
68009
+ const checked = parseWorkspaceSession(session, { userId: session?.user?.id, membershipId: session?.user?.membershipId });
68010
+ this.apiOrigin = normalizeSkillsApiOrigin(apiUrl);
68011
+ this.#token = checked.token;
68012
+ this.organizationId = checked.organization.id;
68013
+ this.userId = checked.user.id;
68014
+ this.membershipId = checked.user.membershipId;
68015
+ Object.freeze(this);
68016
+ }
68017
+ async listVersions(skillId, options = {}) {
68018
+ if (!publicationUuid(skillId) || options.limit !== undefined && (!Number.isSafeInteger(options.limit) || options.limit < 1 || options.limit > 50) || options.cursor !== undefined && !publicationUuid(options.cursor) || options.timeoutMs !== undefined && (!Number.isSafeInteger(options.timeoutMs) || options.timeoutMs < 1 || options.timeoutMs > 15000))
68019
+ return historyInput();
68020
+ const limit = options.limit ?? 20, cursor = options.cursor;
68021
+ const query = new URLSearchParams;
68022
+ if (options.limit !== undefined)
68023
+ query.set("limit", String(limit));
68024
+ if (cursor !== undefined)
68025
+ query.set("cursor", cursor);
68026
+ const path = `/api/v1/skills/${skillId}/versions${query.size ? `?${query}` : ""}`;
68027
+ let value;
68028
+ try {
68029
+ value = await boundedJson(skillsApiRequestUrl(this.apiOrigin, path), { method: "GET" }, this.#token, false, options.timeoutMs, options.signal, false, this);
68030
+ } catch (error) {
68031
+ if (error instanceof PrivatePublicationError && error.code === "INVALID_PUBLICATION_RESPONSE")
68032
+ return historyResponse();
68033
+ throw new PrivatePublicationError("PRIVATE_HISTORY_UNAVAILABLE", "Unable to read private version history. Check the selected server, current membership and fresh sign-in; no skill or credential was changed.", false, error instanceof PrivatePublicationError ? error.status : undefined);
68034
+ }
68035
+ return privateHistory(value, this.organizationId, skillId, limit, cursor);
68036
+ }
68037
+ }
67939
68038
 
67940
68039
  class RemotePrivatePublicationsClient {
67941
68040
  apiOrigin;
@@ -68109,7 +68208,11 @@ var PRIVATE_PUBLICATION_MAX_BYTES, skillCreateFailures, failures, PrivatePublica
68109
68208
  throw new PrivatePublicationError("INVALID_PUBLICATION_INPUT", "Invalid publication input or recovery data.");
68110
68209
  }, invalid3 = () => {
68111
68210
  throw new PrivatePublicationError("INVALID_PUBLICATION_RESPONSE", "The server returned an invalid publication result.");
68112
- }, publicationUuid = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), hash4 = (v) => typeof v === "string" && /^[a-f0-9]{64}$/.test(v), record7 = (v) => !!v && typeof v === "object" && !Array.isArray(v), exact = (v, keys3) => record7(v) && Object.keys(v).sort().join(",") === keys3.sort().join(","), date = (v) => typeof v === "string" && /^\d{4}-\d\d-\d\dT[0-9:.]+(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(v) && Number.isFinite(Date.parse(v)), publicationSha256 = (bytes) => createHash31("sha256").update(bytes).digest("hex");
68211
+ }, publicationUuid = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), hash4 = (v) => typeof v === "string" && /^[a-f0-9]{64}$/.test(v), record7 = (v) => !!v && typeof v === "object" && !Array.isArray(v), exact = (v, keys3) => record7(v) && Object.keys(v).sort().join(",") === keys3.sort().join(","), date = (v) => typeof v === "string" && /^\d{4}-\d\d-\d\dT[0-9:.]+(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(v) && Number.isFinite(Date.parse(v)), publicationSha256 = (bytes) => createHash31("sha256").update(bytes).digest("hex"), historyInput = () => {
68212
+ throw new PrivatePublicationError("INVALID_PRIVATE_HISTORY_INPUT", "Provide a private skill UUID, limit from 1 to 50, and an optional UUID cursor; timeoutMs must be from 1 to 15000.");
68213
+ }, historyResponse = () => {
68214
+ throw new PrivatePublicationError("INVALID_PRIVATE_HISTORY_RESPONSE", "The server returned invalid private version history.");
68215
+ }, historyText = (value) => typeof value === "string" && value.length > 0 && value.length <= 128 && !/[\p{Cc}\p{Cs}\u2028\u2029]/u.test(value);
68113
68216
  var init_remote_private_publications = __esm(() => {
68114
68217
  init_fleet_credentials();
68115
68218
  init_remote_workspace_selection();
@@ -89514,6 +89617,10 @@ class RemoteSkillsAuthClient {
89514
89617
  const origin = this.apiOrigin, captured = workspaceContext(context);
89515
89618
  return new RemotePrivatePublicationsClient(origin, await this.switchWorkspace(email4, code, captured));
89516
89619
  }
89620
+ async openPrivateSkillHistory(email4, code, context) {
89621
+ const origin = this.apiOrigin, captured = workspaceContext(context);
89622
+ return new RemotePrivateSkillHistoryClient(origin, await this.switchWorkspace(email4, code, captured));
89623
+ }
89517
89624
  requestInvitationEmailChallenge(input2) {
89518
89625
  return requestInvitationEmail(this.apiOrigin, "challenge", input2);
89519
89626
  }
@@ -116446,7 +116553,7 @@ var init_remote_invitation_tools = __esm(() => {
116446
116553
  });
116447
116554
 
116448
116555
  // src/lib/private-publication-customer.ts
116449
- function preparePrivatePublicationSession(requested) {
116556
+ function preparePrivateSession(requested, action, open2) {
116450
116557
  const selectors = [
116451
116558
  "HASNA_PROFILE",
116452
116559
  "HASNA_HOME",
@@ -116460,7 +116567,7 @@ function preparePrivatePublicationSession(requested) {
116460
116567
  "SKILLS_API_KEY"
116461
116568
  ];
116462
116569
  const before2 = new Map(selectors.map((key2) => [key2, process.env[key2]]));
116463
- const profile = selectedSkillsProfile(process.env), pending = prepareProfileWorkspace("Manage private publications");
116570
+ const profile = selectedSkillsProfile(process.env), pending = prepareProfileWorkspace(action);
116464
116571
  const captured = requested ? { ...requested } : undefined;
116465
116572
  const unchanged3 = () => {
116466
116573
  if (selectors.some((key2) => process.env[key2] !== before2.get(key2)) || selectedSkillsProfile(process.env) !== profile)
@@ -116474,12 +116581,18 @@ function preparePrivatePublicationSession(requested) {
116474
116581
  throw new PrivatePublicationError("PUBLICATION_CONTEXT_REQUIRED", "Provide the observed user and membership IDs, or select an enrolled workspace profile.");
116475
116582
  unchanged3();
116476
116583
  target.unchanged();
116477
- const client2 = await new RemoteSkillsAuthClient(target.origin).openPrivatePublications(email5, code2, context2);
116584
+ const client2 = await open2(new RemoteSkillsAuthClient(target.origin), email5, code2, context2);
116478
116585
  unchanged3();
116479
116586
  target.unchanged();
116480
116587
  return client2;
116481
116588
  } };
116482
116589
  }
116590
+ function preparePrivatePublicationSession(requested) {
116591
+ return preparePrivateSession(requested, "Manage private publications", (auth, email5, code2, context2) => auth.openPrivatePublications(email5, code2, context2));
116592
+ }
116593
+ function preparePrivateSkillHistorySession(requested) {
116594
+ return preparePrivateSession(requested, "Read private version history", (auth, email5, code2, context2) => auth.openPrivateSkillHistory(email5, code2, context2));
116595
+ }
116483
116596
  async function privatePublicationSession(email5, code2, requested) {
116484
116597
  return preparePrivatePublicationSession(requested).verify(email5, code2);
116485
116598
  }
@@ -117201,7 +117314,7 @@ var exports_runtime_mcp = {};
117201
117314
  __export(exports_runtime_mcp, {
117202
117315
  handleMcp: () => handleMcp
117203
117316
  });
117204
- import { existsSync as existsSync33, lstatSync as lstatSync40, mkdirSync as mkdirSync26, readFileSync as readFileSync43, renameSync as renameSync14, rmdirSync as rmdirSync4, statSync as statSync22, writeFileSync as writeFileSync23 } from "fs";
117317
+ import { closeSync as closeSync29, constants as constants28, existsSync as existsSync33, fstatSync as fstatSync29, lstatSync as lstatSync40, mkdirSync as mkdirSync26, openSync as openSync29, readFileSync as readFileSync43, readSync as readSync21, renameSync as renameSync14, rmdirSync as rmdirSync4, statSync as statSync22, writeFileSync as writeFileSync23 } from "fs";
117205
117318
  import { randomUUID as randomUUID10 } from "crypto";
117206
117319
  import { homedir as homedir10 } from "os";
117207
117320
  import { dirname as dirname40, isAbsolute as isAbsolute38, join as join66 } from "path";
@@ -117270,10 +117383,14 @@ async function registerClaudeMcp(command, server2, environment) {
117270
117383
  const desired = { type: "stdio", ...server2, env: environment };
117271
117384
  try {
117272
117385
  const path = claudeUserConfigPath();
117386
+ const firstRun = lstatSync40(path, { throwIfNoEntry: false }) === undefined ? claudeFirstRunPathWitness(path) : undefined;
117273
117387
  const before2 = withClaudeConfigLock(path, () => {
117274
117388
  if (claudeUserConfigPath() !== path)
117275
117389
  throw new Error;
117390
+ firstRun?.();
117276
117391
  const bytes = readClaudeConfig(path);
117392
+ if (firstRun && bytes !== null)
117393
+ throw new Error;
117277
117394
  if (bytes !== null) {
117278
117395
  const backup = `${path}.skills-mcp-${randomUUID10()}.backup`;
117279
117396
  writeFileSync23(backup, bytes, { flag: "wx", mode: 384 });
@@ -117308,11 +117425,11 @@ async function registerClaudeMcp(command, server2, environment) {
117308
117425
  return withClaudeConfigLock(path, () => {
117309
117426
  if (claudeUserConfigPath() !== path)
117310
117427
  throw new Error;
117311
- const current = readClaudeConfig(path);
117428
+ const current = firstRun ? readClaudeFirstRunConfig(path, firstRun) : readClaudeConfig(path);
117312
117429
  const previous = parseClaudeConfig(before2), data = parseClaudeConfig(current);
117313
117430
  if (exitCode === 0) {
117314
117431
  const actual = isPlainObject4(data.mcpServers) ? data.mcpServers[MCP_SERVER_NAME] : undefined;
117315
- if (!claudeNativeConfigPreserved(previous, data) || !isPlainObject4(actual) || !isDeepStrictEqual17({ ...actual, env: actual.env ?? {} }, desired))
117432
+ if (!claudeNativeConfigPreserved(previous, data, firstRun !== undefined && before2 === null) || !isPlainObject4(actual) || !isDeepStrictEqual17({ ...actual, env: actual.env ?? {} }, desired))
117316
117433
  throw new Error;
117317
117434
  } else {
117318
117435
  if (!cliUnavailable && (!duplicateAccepted || !isPlainObject4(previous.mcpServers) || !previous.mcpServers[MCP_SERVER_NAME]))
@@ -117326,7 +117443,7 @@ async function registerClaudeMcp(command, server2, environment) {
117326
117443
  writeFileSync23(temporary, next, { flag: "wx", mode: 384 });
117327
117444
  if (!readFileSync43(temporary).equals(next))
117328
117445
  throw new Error;
117329
- const latest = readClaudeConfig(path);
117446
+ const latest = firstRun ? readClaudeFirstRunConfig(path, firstRun) : readClaudeConfig(path);
117330
117447
  if (claudeUserConfigPath() !== path || (before2 === null ? latest !== null : latest === null || !latest.equals(before2)))
117331
117448
  throw new Error;
117332
117449
  renameSync14(temporary, path);
@@ -117360,27 +117477,92 @@ function claudeUserConfigPath() {
117360
117477
  return modern;
117361
117478
  }
117362
117479
  function readClaudeConfig(path) {
117363
- if (!existsSync33(path))
117480
+ const info = lstatSync40(path, { throwIfNoEntry: false });
117481
+ if (info === undefined)
117364
117482
  return null;
117365
- const info = lstatSync40(path);
117366
117483
  if (!info.isFile() || info.size > 16777216)
117367
117484
  throw new Error;
117368
117485
  const bytes = readFileSync43(path);
117369
117486
  parseClaudeConfig(bytes);
117370
117487
  return bytes;
117371
117488
  }
117489
+ function claudeFirstRunPathWitness(path) {
117490
+ if (!process.getuid || constants28.O_NOFOLLOW === undefined)
117491
+ throw new Error;
117492
+ const uid2 = BigInt(process.getuid()), canonical9 = canonicalSystemPath(path);
117493
+ const identity6 = (info) => `${info.dev}:${info.ino}:${info.uid}:${info.gid}:${info.mode}`;
117494
+ const directories = [];
117495
+ for (let cursor2 = dirname40(canonical9);; cursor2 = dirname40(cursor2)) {
117496
+ directories.unshift({ path: cursor2, identity: "" });
117497
+ if (dirname40(cursor2) === cursor2)
117498
+ break;
117499
+ }
117500
+ const verify = () => {
117501
+ if (canonicalSystemPath(path) !== canonical9)
117502
+ throw new Error;
117503
+ for (const directory3 of directories) {
117504
+ const info = lstatSync40(directory3.path, { bigint: true });
117505
+ if (!info.isDirectory() || identity6(info) !== directory3.identity)
117506
+ throw new Error;
117507
+ }
117508
+ };
117509
+ for (const directory3 of directories) {
117510
+ let info = lstatSync40(directory3.path, { bigint: true, throwIfNoEntry: false });
117511
+ if (!info) {
117512
+ mkdirSync26(directory3.path, { mode: 448 });
117513
+ info = lstatSync40(directory3.path, { bigint: true });
117514
+ }
117515
+ if (!info.isDirectory() || info.uid !== 0n && info.uid !== uid2 || (info.mode & 0o022n) !== 0n && !(info.uid === 0n && (info.mode & 0o1000n) !== 0n))
117516
+ throw new Error;
117517
+ directory3.identity = identity6(info);
117518
+ }
117519
+ verify();
117520
+ if (lstatSync40(path, { throwIfNoEntry: false }) !== undefined)
117521
+ throw new Error;
117522
+ return verify;
117523
+ }
117524
+ function readClaudeFirstRunConfig(path, verifyPath) {
117525
+ verifyPath();
117526
+ const before2 = lstatSync40(path, { bigint: true, throwIfNoEntry: false });
117527
+ if (!before2)
117528
+ return null;
117529
+ const identity6 = (info) => `${info.dev}:${info.ino}:${info.uid}:${info.gid}:${info.mode}:${info.nlink}:${info.size}:${info.mtimeNs}:${info.ctimeNs}`;
117530
+ if (!before2.isFile() || before2.nlink !== 1n || before2.uid !== BigInt(process.getuid()) || (before2.mode & 0o022n) !== 0n || before2.size > 16n * 1024n * 1024n)
117531
+ throw new Error;
117532
+ const fd = openSync29(path, constants28.O_RDONLY | constants28.O_NOFOLLOW | constants28.O_NONBLOCK);
117533
+ try {
117534
+ if (identity6(fstatSync29(fd, { bigint: true })) !== identity6(before2))
117535
+ throw new Error;
117536
+ const bytes = Buffer.alloc(Number(before2.size) + 1);
117537
+ let length = 0;
117538
+ while (length < bytes.length) {
117539
+ const count = readSync21(fd, bytes, length, bytes.length - length, null);
117540
+ if (!count)
117541
+ break;
117542
+ length += count;
117543
+ }
117544
+ if (BigInt(length) !== before2.size || identity6(fstatSync29(fd, { bigint: true })) !== identity6(before2) || identity6(lstatSync40(path, { bigint: true })) !== identity6(before2))
117545
+ throw new Error;
117546
+ const content = bytes.subarray(0, length);
117547
+ verifyPath();
117548
+ parseClaudeConfig(content);
117549
+ return content;
117550
+ } finally {
117551
+ closeSync29(fd);
117552
+ }
117553
+ }
117372
117554
  function parseClaudeConfig(bytes) {
117373
117555
  const data = bytes === null ? {} : JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
117374
117556
  if (!isPlainObject4(data) || data.mcpServers !== undefined && !isPlainObject4(data.mcpServers))
117375
117557
  throw new Error;
117376
117558
  return data;
117377
117559
  }
117378
- function claudeNativeConfigPreserved(before2, after2) {
117560
+ function claudeNativeConfigPreserved(before2, after2, firstRun = false) {
117379
117561
  const previous = withoutClaudeSkills(before2), current = withoutClaudeSkills(after2);
117380
117562
  for (const key2 of Object.keys(current)) {
117381
117563
  if (Object.hasOwn(previous, key2))
117382
117564
  continue;
117383
- if (!isClaudeBootstrapAddition(key2, current[key2]))
117565
+ if (!(firstRun && key2 === "userID" && typeof current[key2] === "string" && /^[0-9a-f]{64}$/i.test(current[key2])) && !isClaudeBootstrapAddition(key2, current[key2]))
117384
117566
  return false;
117385
117567
  delete current[key2];
117386
117568
  }
@@ -117562,6 +117744,7 @@ var MCP_SERVER_NAME = "skills", MCP_COMMAND_NAME = "skills-mcp";
117562
117744
  var init_runtime_mcp = __esm(() => {
117563
117745
  init_source();
117564
117746
  init_installer();
117747
+ init_agent_integration();
117565
117748
  init_credential_profile_command();
117566
117749
  init_mcp_registration_environment();
117567
117750
  });
@@ -120456,30 +120639,30 @@ var exports_recurring = {};
120456
120639
  __export(exports_recurring, {
120457
120640
  registerRecurringCommands: () => registerRecurringCommands
120458
120641
  });
120459
- import { constants as constants28, closeSync as closeSync29, fstatSync as fstatSync29, lstatSync as lstatSync43, openSync as openSync29, readSync as readSync21 } from "fs";
120642
+ import { constants as constants29, closeSync as closeSync30, fstatSync as fstatSync30, lstatSync as lstatSync43, openSync as openSync30, readSync as readSync22 } from "fs";
120460
120643
  import { createInterface as createInterface2 } from "readline";
120461
120644
  function readRequest(path) {
120462
- const fd = openSync29(path, constants28.O_RDONLY | constants28.O_NOFOLLOW | constants28.O_NONBLOCK);
120645
+ const fd = openSync30(path, constants29.O_RDONLY | constants29.O_NOFOLLOW | constants29.O_NONBLOCK);
120463
120646
  try {
120464
- const before2 = fstatSync29(fd);
120647
+ const before2 = fstatSync30(fd);
120465
120648
  if (!before2.isFile() || before2.size > 1048576 || before2.size < 1)
120466
120649
  throw new RecurringInputError;
120467
120650
  const bytes = Buffer.alloc(before2.size + 1);
120468
120651
  let length = 0;
120469
120652
  while (length < bytes.length) {
120470
- const n2 = readSync21(fd, bytes, length, bytes.length - length, length);
120653
+ const n2 = readSync22(fd, bytes, length, bytes.length - length, length);
120471
120654
  if (!n2)
120472
120655
  break;
120473
120656
  length += n2;
120474
120657
  }
120475
- const after2 = fstatSync29(fd), current = lstatSync43(path);
120658
+ const after2 = fstatSync30(fd), current = lstatSync43(path);
120476
120659
  if (length !== before2.size || after2.size !== before2.size || before2.mtimeMs !== after2.mtimeMs || before2.ctimeMs !== after2.ctimeMs || current.dev !== before2.dev || current.ino !== before2.ino || !current.isFile() || current.isSymbolicLink())
120477
120660
  throw new RecurringInputError;
120478
120661
  return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, length)));
120479
120662
  } catch {
120480
120663
  throw new RecurringInputError;
120481
120664
  } finally {
120482
- closeSync29(fd);
120665
+ closeSync30(fd);
120483
120666
  }
120484
120667
  }
120485
120668
  async function acceptAtTerminal(draft) {
@@ -123119,7 +123302,7 @@ var init_claude_installer_binding = __esm(() => {
123119
123302
  });
123120
123303
 
123121
123304
  // src/cli/commands/claude-installer-capture.ts
123122
- import { closeSync as closeSync30, constants as constants29, fstatSync as fstatSync30, lstatSync as lstatSync48, openSync as openSync30, readSync as readSync22 } from "fs";
123305
+ import { closeSync as closeSync31, constants as constants30, fstatSync as fstatSync31, lstatSync as lstatSync48, openSync as openSync31, readSync as readSync23 } from "fs";
123123
123306
  import { isAbsolute as isAbsolute46, resolve as resolve44 } from "path";
123124
123307
  function need11(condition, code2) {
123125
123308
  if (!condition)
@@ -123141,19 +123324,19 @@ function readRequest2(path) {
123141
123324
  const before2 = lstatSync48(path, { throwIfNoEntry: false });
123142
123325
  if (!before2?.isFile() || before2.isSymbolicLink() || before2.size > MAX_REQUEST_BYTES)
123143
123326
  throw new CaptureRefusal("INVALID_REQUEST_FILE: --request must name a regular non-symlink JSON file no larger than 64 KiB");
123144
- const fd = openSync30(path, constants29.O_RDONLY | (constants29.O_NOFOLLOW ?? 0) | constants29.O_NONBLOCK);
123327
+ const fd = openSync31(path, constants30.O_RDONLY | (constants30.O_NOFOLLOW ?? 0) | constants30.O_NONBLOCK);
123145
123328
  try {
123146
- const opened = fstatSync30(fd);
123329
+ const opened = fstatSync31(fd);
123147
123330
  need11(opened.isFile() && opened.dev === before2.dev && opened.ino === before2.ino && opened.size === before2.size, "INVALID_REQUEST_FILE: --request must remain the same regular file while read");
123148
123331
  const bytes = Buffer.alloc(MAX_REQUEST_BYTES + 1);
123149
123332
  let length = 0;
123150
123333
  while (length < bytes.length) {
123151
- const count = readSync22(fd, bytes, length, bytes.length - length, null);
123334
+ const count = readSync23(fd, bytes, length, bytes.length - length, null);
123152
123335
  if (!count)
123153
123336
  break;
123154
123337
  length += count;
123155
123338
  }
123156
- const after2 = fstatSync30(fd), current = lstatSync48(path);
123339
+ const after2 = fstatSync31(fd), current = lstatSync48(path);
123157
123340
  need11(length <= MAX_REQUEST_BYTES && length === opened.size && after2.size === opened.size && after2.mtimeMs === opened.mtimeMs && after2.ctimeMs === opened.ctimeMs && current.dev === opened.dev && current.ino === opened.ino && current.mtimeMs === opened.mtimeMs && current.ctimeMs === opened.ctimeMs, "INVALID_REQUEST_FILE: --request must remain unchanged while read");
123158
123341
  try {
123159
123342
  return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, length)));
@@ -123161,7 +123344,7 @@ function readRequest2(path) {
123161
123344
  throw new CaptureRefusal("INVALID_REQUEST_JSON: --request must contain one valid UTF-8 JSON object");
123162
123345
  }
123163
123346
  } finally {
123164
- closeSync30(fd);
123347
+ closeSync31(fd);
123165
123348
  }
123166
123349
  }
123167
123350
  function paths(value) {
@@ -123305,7 +123488,7 @@ var exports_agent_integration = {};
123305
123488
  __export(exports_agent_integration, {
123306
123489
  registerAgentIntegration: () => registerAgentIntegration
123307
123490
  });
123308
- import { existsSync as existsSync36, lstatSync as lstatSync49, readFileSync as readFileSync50, readSync as readSync23, writeFileSync as writeFileSync27 } from "fs";
123491
+ import { existsSync as existsSync36, lstatSync as lstatSync49, readFileSync as readFileSync50, readSync as readSync24, writeFileSync as writeFileSync27 } from "fs";
123309
123492
  import { createHash as createHash48 } from "crypto";
123310
123493
  import { homedir as homedir14 } from "os";
123311
123494
  import { basename as basename25, isAbsolute as isAbsolute47, resolve as resolve45 } from "path";
@@ -123420,7 +123603,7 @@ function registerAgentIntegration(parent) {
123420
123603
  const bytes = Buffer.alloc(1024 * 1024 + 1);
123421
123604
  let length = 0;
123422
123605
  while (length < bytes.length) {
123423
- const count = readSync23(0, bytes, length, bytes.length - length, null);
123606
+ const count = readSync24(0, bytes, length, bytes.length - length, null);
123424
123607
  if (!count)
123425
123608
  break;
123426
123609
  length += count;
@@ -123976,17 +124159,17 @@ var exports_profiles = {};
123976
124159
  __export(exports_profiles, {
123977
124160
  registerProfiles: () => registerProfiles
123978
124161
  });
123979
- import { closeSync as closeSync31, constants as constants30, fstatSync as fstatSync31, openSync as openSync31, readSync as readSync24, writeFileSync as writeFileSync28 } from "fs";
124162
+ import { closeSync as closeSync32, constants as constants31, fstatSync as fstatSync32, openSync as openSync32, readSync as readSync25, writeFileSync as writeFileSync28 } from "fs";
123980
124163
  function readProfileInput(path) {
123981
- const fd = openSync31(path, constants30.O_RDONLY | constants30.O_NONBLOCK);
124164
+ const fd = openSync32(path, constants31.O_RDONLY | constants31.O_NONBLOCK);
123982
124165
  try {
123983
- const stat3 = fstatSync31(fd);
124166
+ const stat3 = fstatSync32(fd);
123984
124167
  if (!stat3.isFile() || stat3.size > MAX_PROFILE_DOCUMENT_BYTES)
123985
124168
  throw new Error("Profile input exceeds the size limit or is not a regular file");
123986
124169
  const bytes = Buffer.alloc(MAX_PROFILE_DOCUMENT_BYTES + 1);
123987
124170
  let size2 = 0;
123988
124171
  while (size2 < bytes.length) {
123989
- const read3 = readSync24(fd, bytes, size2, bytes.length - size2, null);
124172
+ const read3 = readSync25(fd, bytes, size2, bytes.length - size2, null);
123990
124173
  if (!read3)
123991
124174
  break;
123992
124175
  size2 += read3;
@@ -123995,7 +124178,7 @@ function readProfileInput(path) {
123995
124178
  throw new Error("Profile input exceeds the size limit");
123996
124179
  return new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, size2));
123997
124180
  } finally {
123998
- closeSync31(fd);
124181
+ closeSync32(fd);
123999
124182
  }
124000
124183
  }
124001
124184
  function registerProfiles(parent) {
@@ -124409,23 +124592,23 @@ __export(exports_grants, {
124409
124592
  registerGrants: () => registerGrants
124410
124593
  });
124411
124594
  import {
124412
- constants as constants31,
124413
- closeSync as closeSync32,
124414
- fstatSync as fstatSync32,
124415
- openSync as openSync32,
124416
- readSync as readSync25,
124595
+ constants as constants32,
124596
+ closeSync as closeSync33,
124597
+ fstatSync as fstatSync33,
124598
+ openSync as openSync33,
124599
+ readSync as readSync26,
124417
124600
  writeFileSync as writeFileSync29
124418
124601
  } from "fs";
124419
124602
  function readInput(path) {
124420
- const fd = openSync32(path, constants31.O_RDONLY | constants31.O_NONBLOCK);
124603
+ const fd = openSync33(path, constants32.O_RDONLY | constants32.O_NONBLOCK);
124421
124604
  try {
124422
- const stat3 = fstatSync32(fd);
124605
+ const stat3 = fstatSync33(fd);
124423
124606
  if (!stat3.isFile() || stat3.size > MAX_EXECUTION_GRANT_BYTES)
124424
124607
  throw new Error("Grant input must be a regular file within the policy size limit.");
124425
124608
  const bytes = Buffer.alloc(MAX_EXECUTION_GRANT_BYTES + 1);
124426
124609
  let size2 = 0;
124427
124610
  while (size2 < bytes.length) {
124428
- const count = readSync25(fd, bytes, size2, bytes.length - size2, null);
124611
+ const count = readSync26(fd, bytes, size2, bytes.length - size2, null);
124429
124612
  if (!count)
124430
124613
  break;
124431
124614
  size2 += count;
@@ -124438,7 +124621,7 @@ function readInput(path) {
124438
124621
  throw new Error("Grant input must be a JSON document containing a grants array.");
124439
124622
  }
124440
124623
  } finally {
124441
- closeSync32(fd);
124624
+ closeSync33(fd);
124442
124625
  }
124443
124626
  }
124444
124627
  function registerGrants(parent) {
@@ -125221,17 +125404,17 @@ var exports_metadata = {};
125221
125404
  __export(exports_metadata, {
125222
125405
  registerMetadata: () => registerMetadata
125223
125406
  });
125224
- import { closeSync as closeSync33, constants as constants32, fstatSync as fstatSync33, openSync as openSync33, readFileSync as readFileSync53, readSync as readSync26, writeFileSync as writeFileSync32 } from "fs";
125407
+ import { closeSync as closeSync34, constants as constants33, fstatSync as fstatSync34, openSync as openSync34, readFileSync as readFileSync53, readSync as readSync27, writeFileSync as writeFileSync32 } from "fs";
125225
125408
  function readPlan(path) {
125226
- const fd = openSync33(path, constants32.O_RDONLY | constants32.O_NONBLOCK | constants32.O_NOFOLLOW);
125409
+ const fd = openSync34(path, constants33.O_RDONLY | constants33.O_NONBLOCK | constants33.O_NOFOLLOW);
125227
125410
  try {
125228
- const stat3 = fstatSync33(fd);
125411
+ const stat3 = fstatSync34(fd);
125229
125412
  if (!stat3.isFile() || stat3.size > 8 * 1024 * 1024)
125230
125413
  throw new SkillMetadataUpdateError("INVALID_METADATA_PLAN");
125231
125414
  const bytes = Buffer.alloc(stat3.size + 1);
125232
125415
  let size2 = 0;
125233
125416
  while (size2 < bytes.length) {
125234
- const count = readSync26(fd, bytes, size2, bytes.length - size2, null);
125417
+ const count = readSync27(fd, bytes, size2, bytes.length - size2, null);
125235
125418
  if (!count)
125236
125419
  break;
125237
125420
  size2 += count;
@@ -125240,7 +125423,7 @@ function readPlan(path) {
125240
125423
  throw new SkillMetadataUpdateError("INVALID_METADATA_PLAN");
125241
125424
  return metadataPlan(JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, size2))));
125242
125425
  } finally {
125243
- closeSync33(fd);
125426
+ closeSync34(fd);
125244
125427
  }
125245
125428
  }
125246
125429
  function failure(error61) {
@@ -125606,7 +125789,7 @@ var init_registry_sync = __esm(() => {
125606
125789
  });
125607
125790
 
125608
125791
  // src/lib/review-export.ts
125609
- import { constants as constants33, closeSync as closeSync34, existsSync as existsSync38, fstatSync as fstatSync34, fsyncSync as fsyncSync10, lstatSync as lstatSync51, openSync as openSync34, realpathSync as realpathSync25, statSync as statSync27, writeFileSync as writeFileSync34 } from "fs";
125792
+ import { constants as constants34, closeSync as closeSync35, existsSync as existsSync38, fstatSync as fstatSync35, fsyncSync as fsyncSync10, lstatSync as lstatSync51, openSync as openSync35, realpathSync as realpathSync25, statSync as statSync27, writeFileSync as writeFileSync34 } from "fs";
125610
125793
  import { basename as basename26, dirname as dirname52, isAbsolute as isAbsolute49, join as join80, parse as parse13, resolve as resolve48, sep as sep25 } from "path";
125611
125794
  function exactVersion(spec) {
125612
125795
  const at2 = spec.indexOf("@");
@@ -125670,16 +125853,16 @@ async function exportSkillVersionForReview(spec, output2, client2) {
125670
125853
  if (bytes.byteLength !== metadata2.bundleByteSize || sha256Hex(bytes) !== metadata2.bundleSha256.toLowerCase()) {
125671
125854
  throw new Error("Published bundle bytes do not match the exact version metadata.");
125672
125855
  }
125673
- const fd = openSync34(target, constants33.O_WRONLY | constants33.O_CREAT | constants33.O_EXCL | constants33.O_NOFOLLOW, 384);
125856
+ const fd = openSync35(target, constants34.O_WRONLY | constants34.O_CREAT | constants34.O_EXCL | constants34.O_NOFOLLOW, 384);
125674
125857
  try {
125675
125858
  writeFileSync34(fd, bytes);
125676
125859
  fsyncSync10(fd);
125677
- if (fstatSync34(fd).size !== bytes.byteLength)
125860
+ if (fstatSync35(fd).size !== bytes.byteLength)
125678
125861
  throw new Error("Incomplete review output write.");
125679
125862
  } catch (error61) {
125680
125863
  throw new Error(`Review output write failed. A private partial file may remain at ${target}; use Trash to remove it before reusing this path.`, { cause: error61 });
125681
125864
  } finally {
125682
- closeSync34(fd);
125865
+ closeSync35(fd);
125683
125866
  }
125684
125867
  return { slug: slug2, version: version2, bundleSha256: metadata2.bundleSha256.toLowerCase(), bundleByteSize: bytes.byteLength, output: target };
125685
125868
  }
@@ -126217,7 +126400,7 @@ function verifySessionOptions(options) {
126217
126400
  if (options.userId === undefined !== (options.membershipId === undefined) || options.userId !== undefined && (!publicationUuid(options.userId) || !publicationUuid(options.membershipId)))
126218
126401
  throw new PrivatePublicationError("PUBLICATION_CONTEXT_REQUIRED", "Provide both observed --user-id and --membership-id UUIDs.");
126219
126402
  if (!options.codeStdin && (options.json || !process.stdin.isTTY || !process.stderr.isTTY))
126220
- throw new PrivatePublicationError("PUBLICATION_CODE_REQUIRED", "Use --code-stdin with a fresh code for noninteractive publishing.");
126403
+ throw new PrivatePublicationError("PUBLICATION_CODE_REQUIRED", "Use --code-stdin with a fresh code for noninteractive private-skill commands.");
126221
126404
  }
126222
126405
  function verifyOptions(options, action) {
126223
126406
  verifySessionOptions(options);
@@ -126273,6 +126456,45 @@ function registerPrivatePublications(parent) {
126273
126456
  process.exitCode = 1;
126274
126457
  }
126275
126458
  });
126459
+ group.command("versions").allowExcessArguments(false).description("Read one page of a private skill's versions and current version using fresh interactive sign-in").argument("<skill-id>", "Private or team skill UUID from the workspace catalog or create result").requiredOption("--email <email>", "Account email for fresh interactive verification").option("--user-id <uuid>", "Observed account UUID (required without an enrolled named profile)").option("--membership-id <uuid>", "Observed workspace membership UUID").option("--code-stdin", "Read a fresh six-digit verification code from stdin").option("--limit <count>", "Page size from 1 to 50", "20").option("--cursor <uuid>", "Read the next page using its returned cursor").option("--json", "Output validated history metadata without credentials or source content").action(async (skillId, options) => {
126460
+ try {
126461
+ if (!publicationUuid(skillId) || !/^[1-9]\d?$/.test(options.limit) || Number(options.limit) > 50 || options.cursor !== undefined && !publicationUuid(options.cursor))
126462
+ throw new PrivatePublicationError("INVALID_PRIVATE_HISTORY_INPUT", "Provide a private skill UUID, --limit from 1 to 50, and an optional UUID --cursor.");
126463
+ verifySessionOptions(options);
126464
+ const context2 = options.userId ? { userId: options.userId, membershipId: options.membershipId } : undefined;
126465
+ const pending = preparePrivateSkillHistorySession(context2);
126466
+ let code2;
126467
+ if (options.codeStdin)
126468
+ code2 = await readCode();
126469
+ else {
126470
+ await new RemoteSkillsAuthClient(pending.origin).requestCode(options.email);
126471
+ code2 = await promptCode();
126472
+ }
126473
+ if (code2 === null)
126474
+ return;
126475
+ const client2 = await pending.verify(options.email, code2);
126476
+ const history = await client2.listVersions(skillId, { limit: Number(options.limit), cursor: options.cursor });
126477
+ if (options.json)
126478
+ console.log(JSON.stringify(history));
126479
+ else {
126480
+ console.log(`Private versions of ${history.slug} (${history.skillId})`);
126481
+ console.log(`Current version: ${history.currentVersion ?? "Not published yet"}`);
126482
+ if (!history.versions.length)
126483
+ console.log("No versions on this page.");
126484
+ for (const version2 of history.versions)
126485
+ console.log(` ${version2.version}${version2.id === history.currentVersionId ? " (current)" : ""} published: ${version2.releasedAt ?? "Not released"} created: ${version2.createdAt}`);
126486
+ if (history.nextCursor)
126487
+ console.log(`More versions: repeat this command with --cursor ${history.nextCursor} and fresh verification.`);
126488
+ }
126489
+ } catch (error61) {
126490
+ const result2 = error61 instanceof PrivatePublicationError ? privatePublicationCustomerError(error61) : { error: "Unable to read private version history. Check the selected account, workspace and fresh verification; no skill or credential was changed.", code: "PRIVATE_HISTORY_UNAVAILABLE", uncertain: false };
126491
+ if (options.json)
126492
+ console.log(JSON.stringify(result2));
126493
+ else
126494
+ console.error(result2.error);
126495
+ process.exitCode = 1;
126496
+ }
126497
+ });
126276
126498
  const publishCommand = group.command("publish").allowExcessArguments(false).description("Publish private source with explicit current-version comparison").requiredOption("--recovery-dir <directory>", "New recovery directory for publish; existing directory for other actions").requiredOption("--email <email>", "Account email for fresh interactive verification").option("--user-id <uuid>", "Observed account UUID (required without an enrolled named profile)").option("--membership-id <uuid>", "Observed workspace membership UUID").option("--code-stdin", "Read a fresh six-digit verification code from stdin").option("--json", "Output a safe result without session credentials or upload URLs").option("--confirm", "Explicitly approve this action").argument("<directory>", "Validated local skill directory").requiredOption("--skill-id <uuid>", "Existing private/team skill UUID").option("--expected-current-version <uuid>", "Compare against the observed current version UUID").option("--expect-empty", "Require the skill to have no current version").option("--idempotency-key <uuid>", "Stable intent key; generated and saved before begin when omitted").option("--wait-seconds <seconds>", "Bounded status wait from 0 to 300", "60");
126277
126499
  const statusCommand = group.command("status").allowExcessArguments(false).description("Inspect the exact saved publication").requiredOption("--recovery-dir <directory>", "New recovery directory for publish; existing directory for other actions").requiredOption("--email <email>", "Account email for fresh interactive verification").option("--user-id <uuid>", "Observed account UUID (required without an enrolled named profile)").option("--membership-id <uuid>", "Observed workspace membership UUID").option("--code-stdin", "Read a fresh six-digit verification code from stdin").option("--json", "Output a safe result without session credentials or upload URLs");
126278
126500
  const resumeCommand = group.command("resume").allowExcessArguments(false).description("Reconcile the saved intent without creating a replacement").requiredOption("--recovery-dir <directory>", "New recovery directory for publish; existing directory for other actions").requiredOption("--email <email>", "Account email for fresh interactive verification").option("--user-id <uuid>", "Observed account UUID (required without an enrolled named profile)").option("--membership-id <uuid>", "Observed workspace membership UUID").option("--code-stdin", "Read a fresh six-digit verification code from stdin").option("--json", "Output a safe result without session credentials or upload URLs").option("--confirm", "Explicitly approve this action").option("--wait-seconds <seconds>", "Bounded status wait from 0 to 300", "60");