@aident-ai/cli 0.2.0 → 0.2.1-rc.0

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.
Files changed (4) hide show
  1. package/README.md +1 -0
  2. package/dist/cli.mjs +5555 -1880
  3. package/dist/dsh.mjs +447 -142
  4. package/package.json +1 -1
package/dist/dsh.mjs CHANGED
@@ -1,4 +1,36 @@
1
+ var __create = Object.create;
2
+ var __getProtoOf = Object.getPrototypeOf;
1
3
  var __defProp = Object.defineProperty;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ function __accessProp(key) {
7
+ return this[key];
8
+ }
9
+ var __toESMCache_node;
10
+ var __toESMCache_esm;
11
+ var __toESM = (mod, isNodeMode, target) => {
12
+ var canCache = mod != null && typeof mod === "object";
13
+ if (canCache) {
14
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
15
+ var cached = cache.get(mod);
16
+ if (cached)
17
+ return cached;
18
+ }
19
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
20
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
21
+ if (mod && typeof mod === "object" || typeof mod === "function") {
22
+ for (let key of __getOwnPropNames(mod))
23
+ if (!__hasOwnProp.call(to, key))
24
+ __defProp(to, key, {
25
+ get: __accessProp.bind(mod, key),
26
+ enumerable: true
27
+ });
28
+ }
29
+ if (canCache)
30
+ cache.set(mod, to);
31
+ return to;
32
+ };
33
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
2
34
  var __returnValue = (v) => v;
3
35
  function __exportSetter(name, newValue) {
4
36
  this[name] = __returnValue.bind(null, newValue);
@@ -637,7 +669,7 @@ function normalizeBaseUrl(url) {
637
669
  }
638
670
 
639
671
  // src/version.ts
640
- var VERSION = "0.2.0";
672
+ var VERSION = "0.2.1-rc.0";
641
673
 
642
674
  // src/catalogCache.ts
643
675
  var CACHE_TTL_MS = 5 * 60 * 1000;
@@ -688,8 +720,8 @@ function isCommandCatalog(value) {
688
720
 
689
721
  // src/loadoutSkill.ts
690
722
  import { createHash as createHash3 } from "node:crypto";
691
- import { lstat as lstat2, readdir as readdir2, readFile as readFile5, realpath as realpath2 } from "node:fs/promises";
692
- import { basename, dirname as dirname2, join as join6 } from "node:path";
723
+ import { lstat as lstat3, readdir as readdir2, readFile as readFile5, realpath as realpath2 } from "node:fs/promises";
724
+ import { basename, dirname as dirname3, join as join6 } from "node:path";
693
725
 
694
726
  // src/loadoutSkillHosts.ts
695
727
  import { existsSync } from "node:fs";
@@ -864,10 +896,11 @@ function getConfiguredScope(root, repositoryRoot) {
864
896
 
865
897
  // src/update.ts
866
898
  import { execFile } from "node:child_process";
899
+ import { randomUUID as randomUUID2 } from "node:crypto";
867
900
  import { constants } from "node:fs";
868
- import { access, mkdir as mkdir4, readFile as readFile4, realpath, writeFile as writeFile4 } from "node:fs/promises";
901
+ import { access, lstat as lstat2, mkdir as mkdir4, readFile as readFile4, realpath, rename as rename2, symlink, unlink as unlink2, writeFile as writeFile4 } from "node:fs/promises";
869
902
  import { homedir as homedir3 } from "node:os";
870
- import { delimiter, isAbsolute as isAbsolute2, join as join5, posix, win32 as win322 } from "node:path";
903
+ import { delimiter, dirname as dirname2, isAbsolute as isAbsolute2, join as join5, posix, win32 as win322 } from "node:path";
871
904
 
872
905
  // src/directoryLock.ts
873
906
  import { randomUUID } from "node:crypto";
@@ -888,14 +921,14 @@ async function tryAcquireDirectoryLock(path, options = {}) {
888
921
  if (!existing?.isDirectory())
889
922
  return null;
890
923
  const ownerBefore = await readLockOwner(path);
891
- if (now - existing.mtimeMs < staleAfterMs)
892
- return null;
893
924
  if (ownerBefore) {
894
925
  if ((options.isProcessAlive ?? isProcessAlive)(ownerBefore.pid))
895
926
  return null;
896
927
  if (!await containsOnlyOwnerFile(path))
897
928
  return null;
898
929
  } else {
930
+ if (now - existing.mtimeMs < staleAfterMs)
931
+ return null;
899
932
  if (!await isEmptyDirectory(path) && !await containsOnlyOwnerFile(path))
900
933
  return null;
901
934
  }
@@ -1010,113 +1043,113 @@ function hasCode(error, code) {
1010
1043
  // ../../node_modules/zod/v3/external.js
1011
1044
  var exports_external = {};
1012
1045
  __export(exports_external, {
1013
- void: () => voidType,
1014
- util: () => util,
1015
- unknown: () => unknownType,
1016
- union: () => unionType,
1017
- undefined: () => undefinedType,
1018
- tuple: () => tupleType,
1019
- transformer: () => effectsType,
1020
- symbol: () => symbolType,
1021
- string: () => stringType,
1022
- strictObject: () => strictObjectType,
1023
- setErrorMap: () => setErrorMap,
1024
- set: () => setType,
1025
- record: () => recordType,
1026
- quotelessJson: () => quotelessJson,
1027
- promise: () => promiseType,
1028
- preprocess: () => preprocessType,
1029
- pipeline: () => pipelineType,
1030
- ostring: () => ostring,
1031
- optional: () => optionalType,
1032
- onumber: () => onumber,
1033
- oboolean: () => oboolean,
1034
- objectUtil: () => objectUtil,
1035
- object: () => objectType,
1036
- number: () => numberType,
1037
- nullable: () => nullableType,
1038
- null: () => nullType,
1039
- never: () => neverType,
1040
- nativeEnum: () => nativeEnumType,
1041
- nan: () => nanType,
1042
- map: () => mapType,
1043
- makeIssue: () => makeIssue,
1044
- literal: () => literalType,
1045
- lazy: () => lazyType,
1046
- late: () => late,
1047
- isValid: () => isValid,
1048
- isDirty: () => isDirty,
1049
- isAsync: () => isAsync,
1050
- isAborted: () => isAborted,
1051
- intersection: () => intersectionType,
1052
- instanceof: () => instanceOfType,
1053
- getParsedType: () => getParsedType,
1054
- getErrorMap: () => getErrorMap,
1055
- function: () => functionType,
1056
- enum: () => enumType,
1057
- effect: () => effectsType,
1058
- discriminatedUnion: () => discriminatedUnionType,
1059
- defaultErrorMap: () => en_default,
1060
- datetimeRegex: () => datetimeRegex,
1061
- date: () => dateType,
1062
- custom: () => custom,
1063
- coerce: () => coerce,
1064
- boolean: () => booleanType,
1065
- bigint: () => bigIntType,
1066
- array: () => arrayType,
1067
- any: () => anyType,
1068
- addIssueToContext: () => addIssueToContext,
1069
- ZodVoid: () => ZodVoid,
1070
- ZodUnknown: () => ZodUnknown,
1071
- ZodUnion: () => ZodUnion,
1072
- ZodUndefined: () => ZodUndefined,
1073
- ZodType: () => ZodType,
1074
- ZodTuple: () => ZodTuple,
1075
- ZodTransformer: () => ZodEffects,
1076
- ZodSymbol: () => ZodSymbol,
1077
- ZodString: () => ZodString,
1078
- ZodSet: () => ZodSet,
1079
- ZodSchema: () => ZodType,
1080
- ZodRecord: () => ZodRecord,
1081
- ZodReadonly: () => ZodReadonly,
1082
- ZodPromise: () => ZodPromise,
1083
- ZodPipeline: () => ZodPipeline,
1084
- ZodParsedType: () => ZodParsedType,
1085
- ZodOptional: () => ZodOptional,
1086
- ZodObject: () => ZodObject,
1087
- ZodNumber: () => ZodNumber,
1088
- ZodNullable: () => ZodNullable,
1089
- ZodNull: () => ZodNull,
1090
- ZodNever: () => ZodNever,
1091
- ZodNativeEnum: () => ZodNativeEnum,
1092
- ZodNaN: () => ZodNaN,
1093
- ZodMap: () => ZodMap,
1094
- ZodLiteral: () => ZodLiteral,
1095
- ZodLazy: () => ZodLazy,
1096
- ZodIssueCode: () => ZodIssueCode,
1097
- ZodIntersection: () => ZodIntersection,
1098
- ZodFunction: () => ZodFunction,
1099
- ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind,
1100
- ZodError: () => ZodError,
1101
- ZodEnum: () => ZodEnum,
1102
- ZodEffects: () => ZodEffects,
1103
- ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
1104
- ZodDefault: () => ZodDefault,
1105
- ZodDate: () => ZodDate,
1106
- ZodCatch: () => ZodCatch,
1107
- ZodBranded: () => ZodBranded,
1108
- ZodBoolean: () => ZodBoolean,
1109
- ZodBigInt: () => ZodBigInt,
1110
- ZodArray: () => ZodArray,
1111
- ZodAny: () => ZodAny,
1112
- Schema: () => ZodType,
1113
- ParseStatus: () => ParseStatus,
1114
- OK: () => OK,
1115
- NEVER: () => NEVER,
1116
- INVALID: () => INVALID,
1117
- EMPTY_PATH: () => EMPTY_PATH,
1046
+ BRAND: () => BRAND,
1118
1047
  DIRTY: () => DIRTY,
1119
- BRAND: () => BRAND
1048
+ EMPTY_PATH: () => EMPTY_PATH,
1049
+ INVALID: () => INVALID,
1050
+ NEVER: () => NEVER,
1051
+ OK: () => OK,
1052
+ ParseStatus: () => ParseStatus,
1053
+ Schema: () => ZodType,
1054
+ ZodAny: () => ZodAny,
1055
+ ZodArray: () => ZodArray,
1056
+ ZodBigInt: () => ZodBigInt,
1057
+ ZodBoolean: () => ZodBoolean,
1058
+ ZodBranded: () => ZodBranded,
1059
+ ZodCatch: () => ZodCatch,
1060
+ ZodDate: () => ZodDate,
1061
+ ZodDefault: () => ZodDefault,
1062
+ ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
1063
+ ZodEffects: () => ZodEffects,
1064
+ ZodEnum: () => ZodEnum,
1065
+ ZodError: () => ZodError,
1066
+ ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind,
1067
+ ZodFunction: () => ZodFunction,
1068
+ ZodIntersection: () => ZodIntersection,
1069
+ ZodIssueCode: () => ZodIssueCode,
1070
+ ZodLazy: () => ZodLazy,
1071
+ ZodLiteral: () => ZodLiteral,
1072
+ ZodMap: () => ZodMap,
1073
+ ZodNaN: () => ZodNaN,
1074
+ ZodNativeEnum: () => ZodNativeEnum,
1075
+ ZodNever: () => ZodNever,
1076
+ ZodNull: () => ZodNull,
1077
+ ZodNullable: () => ZodNullable,
1078
+ ZodNumber: () => ZodNumber,
1079
+ ZodObject: () => ZodObject,
1080
+ ZodOptional: () => ZodOptional,
1081
+ ZodParsedType: () => ZodParsedType,
1082
+ ZodPipeline: () => ZodPipeline,
1083
+ ZodPromise: () => ZodPromise,
1084
+ ZodReadonly: () => ZodReadonly,
1085
+ ZodRecord: () => ZodRecord,
1086
+ ZodSchema: () => ZodType,
1087
+ ZodSet: () => ZodSet,
1088
+ ZodString: () => ZodString,
1089
+ ZodSymbol: () => ZodSymbol,
1090
+ ZodTransformer: () => ZodEffects,
1091
+ ZodTuple: () => ZodTuple,
1092
+ ZodType: () => ZodType,
1093
+ ZodUndefined: () => ZodUndefined,
1094
+ ZodUnion: () => ZodUnion,
1095
+ ZodUnknown: () => ZodUnknown,
1096
+ ZodVoid: () => ZodVoid,
1097
+ addIssueToContext: () => addIssueToContext,
1098
+ any: () => anyType,
1099
+ array: () => arrayType,
1100
+ bigint: () => bigIntType,
1101
+ boolean: () => booleanType,
1102
+ coerce: () => coerce,
1103
+ custom: () => custom,
1104
+ date: () => dateType,
1105
+ datetimeRegex: () => datetimeRegex,
1106
+ defaultErrorMap: () => en_default,
1107
+ discriminatedUnion: () => discriminatedUnionType,
1108
+ effect: () => effectsType,
1109
+ enum: () => enumType,
1110
+ function: () => functionType,
1111
+ getErrorMap: () => getErrorMap,
1112
+ getParsedType: () => getParsedType,
1113
+ instanceof: () => instanceOfType,
1114
+ intersection: () => intersectionType,
1115
+ isAborted: () => isAborted,
1116
+ isAsync: () => isAsync,
1117
+ isDirty: () => isDirty,
1118
+ isValid: () => isValid,
1119
+ late: () => late,
1120
+ lazy: () => lazyType,
1121
+ literal: () => literalType,
1122
+ makeIssue: () => makeIssue,
1123
+ map: () => mapType,
1124
+ nan: () => nanType,
1125
+ nativeEnum: () => nativeEnumType,
1126
+ never: () => neverType,
1127
+ null: () => nullType,
1128
+ nullable: () => nullableType,
1129
+ number: () => numberType,
1130
+ object: () => objectType,
1131
+ objectUtil: () => objectUtil,
1132
+ oboolean: () => oboolean,
1133
+ onumber: () => onumber,
1134
+ optional: () => optionalType,
1135
+ ostring: () => ostring,
1136
+ pipeline: () => pipelineType,
1137
+ preprocess: () => preprocessType,
1138
+ promise: () => promiseType,
1139
+ quotelessJson: () => quotelessJson,
1140
+ record: () => recordType,
1141
+ set: () => setType,
1142
+ setErrorMap: () => setErrorMap,
1143
+ strictObject: () => strictObjectType,
1144
+ string: () => stringType,
1145
+ symbol: () => symbolType,
1146
+ transformer: () => effectsType,
1147
+ tuple: () => tupleType,
1148
+ undefined: () => undefinedType,
1149
+ union: () => unionType,
1150
+ unknown: () => unknownType,
1151
+ util: () => util,
1152
+ void: () => voidType
1120
1153
  });
1121
1154
 
1122
1155
  // ../../node_modules/zod/v3/helpers/util.js
@@ -5077,7 +5110,7 @@ async function detectCliInstallOwnership(executablePath = process.argv[1], homeD
5077
5110
  });
5078
5111
  }
5079
5112
  }
5080
- if (paths.some(isAidentCliPackagePath)) {
5113
+ if (paths.some(isAidentCliPackagePath) || platform === "win32") {
5081
5114
  for (const manager of ["pnpm" /* Pnpm */, "npm" /* Npm */]) {
5082
5115
  if (matches.has(manager))
5083
5116
  continue;
@@ -5085,7 +5118,9 @@ async function detectCliInstallOwnership(executablePath = process.argv[1], homeD
5085
5118
  if (!managerExecutablePath)
5086
5119
  continue;
5087
5120
  const globalInstall = await getManagerGlobalInstall(manager, managerExecutablePath, runFile, resolveRealpath, platform);
5088
- if (globalInstall && paths.some((path) => isPathWithin(globalInstall.packageRoot, path))) {
5121
+ const packagePathOwned = globalInstall && paths.some((path) => isPathWithin(globalInstall.packageRoot, path));
5122
+ const shimOwned = globalInstall && platform === "win32" && await isWindowsPackageManagerShim(executablePath, manager, globalInstall.managerInstallRoot, globalInstall.managerBinRoot, readTextFile);
5123
+ if (globalInstall && (packagePathOwned || shimOwned)) {
5089
5124
  matches.set(manager, {
5090
5125
  ...ownership(manager, executablePath, resolvedExecutablePath),
5091
5126
  managerExecutablePath,
@@ -5100,6 +5135,19 @@ async function detectCliInstallOwnership(executablePath = process.argv[1], homeD
5100
5135
  return [...matches.values()][0];
5101
5136
  return unknownOwnership(executablePath);
5102
5137
  }
5138
+ async function isWindowsPackageManagerShim(executablePath, manager, managerInstallRoot, managerBinRoot, readTextFile) {
5139
+ if (!/^aident(?:\.cmd|\.ps1)?$/i.test(win322.basename(executablePath)))
5140
+ return false;
5141
+ const expectedBinRoot = manager === "pnpm" /* Pnpm */ ? managerBinRoot : managerInstallRoot;
5142
+ if (!expectedBinRoot || normalizePath(win322.dirname(executablePath), "win32") !== normalizePath(expectedBinRoot, "win32")) {
5143
+ return false;
5144
+ }
5145
+ const content = await readTextFile(executablePath).catch(() => "");
5146
+ if (content.length > 16384)
5147
+ return false;
5148
+ const normalized = normalizePath(content, "win32");
5149
+ return normalized.includes("@aident-ai/cli") && normalized.includes("dist/cli.mjs");
5150
+ }
5103
5151
  async function updateCli(params, deps = {}) {
5104
5152
  if (!isAidentSemver(params.currentVersion)) {
5105
5153
  throw new Error(`Invalid installed Aident CLI version: ${params.currentVersion}`);
@@ -5198,6 +5246,137 @@ async function updateCli(params, deps = {}) {
5198
5246
  await lock.release();
5199
5247
  }
5200
5248
  }
5249
+ async function replacePackageManagedCliWithNative(params, deps = {}) {
5250
+ const platform = params.platform ?? process.platform;
5251
+ const resolveRealpath = deps.realpath ?? realpath;
5252
+ const runFile = deps.execFile ?? runExecFile;
5253
+ const readVersion = deps.readVersion ?? (async (path, options) => parseCliVersionOutput((await runFile(path, ["--version"], options)).stdout));
5254
+ const [activeRealpath, nativeRealpath] = await Promise.all([
5255
+ resolveRealpath(params.activeExecutablePath).catch(() => params.activeExecutablePath),
5256
+ resolveRealpath(params.nativeExecutablePath)
5257
+ ]);
5258
+ const nativeVersion = await readVersion(params.nativeExecutablePath);
5259
+ if (!nativeVersion)
5260
+ throw new Error("The bundled Aident CLI could not report a valid version");
5261
+ if (normalizePath(activeRealpath, platform) === normalizePath(nativeRealpath, platform)) {
5262
+ return {
5263
+ status: "current",
5264
+ owner: "native",
5265
+ version: nativeVersion,
5266
+ activePath: params.activeExecutablePath
5267
+ };
5268
+ }
5269
+ const detectOwnership = deps.detectInstallOwnership ?? (() => detectCliInstallOwnership(params.activeExecutablePath, params.homeDir ?? homedir3(), {
5270
+ platform,
5271
+ execFile: (file, args) => runFile(file, args)
5272
+ }));
5273
+ const ownership = await detectOwnership();
5274
+ if (!["npm" /* Npm */, "pnpm" /* Pnpm */, "bun" /* Bun */, "volta" /* Volta */].includes(ownership.method)) {
5275
+ throw new Error(`The existing Aident CLI owner is ${ownership.method} and cannot be replaced automatically`);
5276
+ }
5277
+ assertCompletePackageManagerOwnership(ownership);
5278
+ const prepareUpdateDirectory = deps.prepareUpdateDirectory ?? prepareCliUpdateDirectory;
5279
+ const updateDirectory = await prepareUpdateDirectory();
5280
+ const acquireLock = deps.acquireLock ?? acquireCliUpdateLock;
5281
+ const lock = await acquireLock();
5282
+ if (!lock)
5283
+ throw new Error("Another Aident CLI update is already running");
5284
+ let createdActivationLink = false;
5285
+ let transactionId;
5286
+ try {
5287
+ const prepareManagerConfig = deps.prepareManagerConfig ?? prepareTrustedManagerConfig;
5288
+ const managerConfig = await prepareManagerConfig(updateDirectory, ownership);
5289
+ const managerExecOptions = getManagerExecOptions(updateDirectory, ownership, managerConfig);
5290
+ const previousVersion = await readVersion(params.activeExecutablePath);
5291
+ if (!previousVersion)
5292
+ throw new Error("The existing Aident CLI could not report a valid version");
5293
+ transactionId = randomUUID2();
5294
+ const activationExists = await (deps.pathExists ?? pathExists)(params.activationPath);
5295
+ if (activationExists) {
5296
+ const activationRealpath = await resolveRealpath(params.activationPath).catch(() => params.activationPath);
5297
+ if (normalizePath(activationRealpath, platform) !== normalizePath(nativeRealpath, platform) && normalizePath(activationRealpath, platform) !== normalizePath(activeRealpath, platform)) {
5298
+ throw new Error("The native Aident command path is owned by another executable");
5299
+ }
5300
+ }
5301
+ const removeInvocation = getRemovalInvocation(ownership, managerConfig);
5302
+ try {
5303
+ await runFile(removeInvocation.file, removeInvocation.args, managerExecOptions);
5304
+ if (!await (deps.pathExists ?? pathExists)(params.activationPath)) {
5305
+ await (deps.createSymlink ?? createNativeCliSymlink)(params.nativeExecutablePath, params.activationPath);
5306
+ createdActivationLink = true;
5307
+ }
5308
+ const activationRealpath = await resolveRealpath(params.activationPath);
5309
+ const activatedVersion = await readVersion(params.activationPath);
5310
+ if (normalizePath(activationRealpath, platform) !== normalizePath(nativeRealpath, platform) || activatedVersion !== nativeVersion) {
5311
+ throw new Error("The bundled Aident CLI did not become the active command");
5312
+ }
5313
+ await (deps.writeReplacementState ?? writePackageManagedCliReplacementState)(params.homeDir ?? homedir3(), {
5314
+ schemaVersion: 1,
5315
+ transactionId,
5316
+ previousVersion,
5317
+ activeExecutablePath: params.activeExecutablePath,
5318
+ nativeExecutablePath: params.nativeExecutablePath,
5319
+ activationPath: params.activationPath,
5320
+ createdActivationLink,
5321
+ ownership
5322
+ });
5323
+ } catch (error) {
5324
+ if (createdActivationLink) {
5325
+ await (deps.removeFile ?? unlink2)(params.activationPath).catch(() => {
5326
+ return;
5327
+ });
5328
+ }
5329
+ const restored = await restorePackageManagedCli(runFile, ownership, managerConfig, managerExecOptions, params.activeExecutablePath, previousVersion, updateDirectory, readVersion);
5330
+ await (deps.removeReplacementState ?? removePackageManagedCliReplacementState)(params.homeDir ?? homedir3()).catch(() => {
5331
+ return;
5332
+ });
5333
+ throw sanitizedExecError(`Aident CLI replacement failed${restored ? "; restored the previous package-managed CLI" : "; rollback failed"}`, error);
5334
+ }
5335
+ return {
5336
+ status: "replaced",
5337
+ owner: ownership.method,
5338
+ version: nativeVersion,
5339
+ previousVersion,
5340
+ activePath: params.activationPath,
5341
+ transactionId
5342
+ };
5343
+ } finally {
5344
+ await lock.release();
5345
+ }
5346
+ }
5347
+ async function completePackageManagedCliReplacement(transactionId, homeDir = homedir3()) {
5348
+ const state = await readPackageManagedCliReplacementState(homeDir);
5349
+ if (!state || state.transactionId !== transactionId)
5350
+ throw new Error("Aident CLI replacement transaction not found");
5351
+ await removePackageManagedCliReplacementState(homeDir);
5352
+ }
5353
+ async function rollbackPackageManagedCliReplacement(transactionId, homeDir = homedir3()) {
5354
+ const state = await readPackageManagedCliReplacementState(homeDir);
5355
+ if (!state || state.transactionId !== transactionId)
5356
+ throw new Error("Aident CLI replacement transaction not found");
5357
+ assertCompletePackageManagerOwnership(state.ownership);
5358
+ const updateDirectory = await prepareCliUpdateDirectory();
5359
+ const lock = await acquireCliUpdateLock();
5360
+ if (!lock)
5361
+ throw new Error("Another Aident CLI update is already running");
5362
+ try {
5363
+ if (state.createdActivationLink) {
5364
+ const activationRealpath = await realpath(state.activationPath).catch(() => null);
5365
+ const nativeRealpath = await realpath(state.nativeExecutablePath).catch(() => state.nativeExecutablePath);
5366
+ if (activationRealpath && normalizePath(activationRealpath) === normalizePath(nativeRealpath)) {
5367
+ await unlink2(state.activationPath);
5368
+ }
5369
+ }
5370
+ const config = await prepareTrustedManagerConfig(updateDirectory, state.ownership);
5371
+ const options = getManagerExecOptions(updateDirectory, state.ownership, config);
5372
+ const restored = await restorePackageManagedCli(runExecFile, state.ownership, config, options, state.activeExecutablePath, state.previousVersion, updateDirectory, async (path, execOptions) => parseCliVersionOutput((await runExecFile(path, ["--version"], execOptions)).stdout));
5373
+ if (!restored)
5374
+ throw new Error("Failed to restore the previous package-managed Aident CLI");
5375
+ await removePackageManagedCliReplacementState(homeDir);
5376
+ } finally {
5377
+ await lock.release();
5378
+ }
5379
+ }
5201
5380
  function manualUpdateResult(currentVersion, targetVersion, method) {
5202
5381
  return {
5203
5382
  status: "manual-required" /* ManualRequired */,
@@ -5413,6 +5592,109 @@ function getUpdateInvocation(ownership2, targetVersion, config) {
5413
5592
  throw new Error(`No update invocation exists for ${ownership2.method}`);
5414
5593
  }
5415
5594
  }
5595
+ function getRemovalInvocation(ownership2, config) {
5596
+ const managerExecutablePath = ownership2.managerExecutablePath;
5597
+ switch (ownership2.method) {
5598
+ case "npm" /* Npm */:
5599
+ return {
5600
+ file: managerExecutablePath,
5601
+ args: [
5602
+ `--userconfig=${config.npmUserConfig}`,
5603
+ `--globalconfig=${config.npmGlobalConfig}`,
5604
+ `--prefix=${ownership2.managerInstallRoot}`,
5605
+ "uninstall",
5606
+ "--global",
5607
+ "--ignore-scripts",
5608
+ AIDENT_CLI_PACKAGE
5609
+ ]
5610
+ };
5611
+ case "pnpm" /* Pnpm */:
5612
+ return {
5613
+ file: managerExecutablePath,
5614
+ args: [
5615
+ `--global-dir=${ownership2.managerInstallRoot}`,
5616
+ `--global-bin-dir=${ownership2.managerBinRoot}`,
5617
+ "remove",
5618
+ "--global",
5619
+ "--ignore-scripts",
5620
+ AIDENT_CLI_PACKAGE
5621
+ ]
5622
+ };
5623
+ case "bun" /* Bun */:
5624
+ return {
5625
+ file: managerExecutablePath,
5626
+ args: [`--config=${config.bunConfig}`, "remove", "--global", AIDENT_CLI_PACKAGE]
5627
+ };
5628
+ case "volta" /* Volta */:
5629
+ return { file: managerExecutablePath, args: ["uninstall", AIDENT_CLI_PACKAGE] };
5630
+ case "ephemeral" /* Ephemeral */:
5631
+ case "unknown" /* Unknown */:
5632
+ throw new Error(`No removal invocation exists for ${ownership2.method}`);
5633
+ }
5634
+ }
5635
+ function assertCompletePackageManagerOwnership(ownership2) {
5636
+ if (!ownership2.managerExecutablePath || !ownership2.managerInstallRoot) {
5637
+ throw new Error("Aident CLI package-manager ownership is incomplete");
5638
+ }
5639
+ if ((ownership2.method === "pnpm" /* Pnpm */ || ownership2.method === "bun" /* Bun */) && !ownership2.managerBinRoot) {
5640
+ throw new Error("Aident CLI package-manager binary ownership is incomplete");
5641
+ }
5642
+ }
5643
+ async function restorePackageManagedCli(exec, ownership2, config, managerExecOptions, activeExecutablePath, previousVersion, updateDirectory, readVersion) {
5644
+ if (await readVersion(activeExecutablePath).catch(() => null) === previousVersion)
5645
+ return true;
5646
+ const invocation = getUpdateInvocation(ownership2, previousVersion, config);
5647
+ try {
5648
+ await exec(invocation.file, invocation.args, managerExecOptions);
5649
+ return await readVersion(activeExecutablePath, { cwd: updateDirectory }).catch(() => null) === previousVersion;
5650
+ } catch {
5651
+ return false;
5652
+ }
5653
+ }
5654
+ async function pathExists(path) {
5655
+ return lstat2(path).then(() => true).catch(() => false);
5656
+ }
5657
+ function getPackageManagedCliReplacementStatePath(homeDir) {
5658
+ return join5(homeDir, ".aident", "cli-replacement.json");
5659
+ }
5660
+ async function writePackageManagedCliReplacementState(homeDir, state) {
5661
+ const path = getPackageManagedCliReplacementStatePath(homeDir);
5662
+ const temporary = `${path}.${state.transactionId}.tmp`;
5663
+ await mkdir4(dirname2(path), { recursive: true, mode: 448 });
5664
+ await writeFile4(temporary, `${JSON.stringify(state)}
5665
+ `, { mode: 384, flag: "wx" });
5666
+ await rename2(temporary, path);
5667
+ }
5668
+ async function readPackageManagedCliReplacementState(homeDir) {
5669
+ try {
5670
+ const content = await readFile4(getPackageManagedCliReplacementStatePath(homeDir), "utf8");
5671
+ if (content.length > 16384)
5672
+ return null;
5673
+ const state = JSON.parse(content);
5674
+ if (state.schemaVersion !== 1 || !/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(state.transactionId) || !isAidentSemver(state.previousVersion) || !isAbsolute2(state.activeExecutablePath) || !isAbsolute2(state.nativeExecutablePath) || !isAbsolute2(state.activationPath) || typeof state.createdActivationLink !== "boolean" || !isPackageManagedCliOwnershipState(state.ownership)) {
5675
+ return null;
5676
+ }
5677
+ return state;
5678
+ } catch {
5679
+ return null;
5680
+ }
5681
+ }
5682
+ function isPackageManagedCliOwnershipState(value) {
5683
+ if (!value || typeof value !== "object")
5684
+ return false;
5685
+ const ownership2 = value;
5686
+ if (!ownership2.method || !["npm" /* Npm */, "pnpm" /* Pnpm */, "bun" /* Bun */, "volta" /* Volta */].includes(ownership2.method) || typeof ownership2.managerExecutablePath !== "string" || !isAbsolute2(ownership2.managerExecutablePath) || typeof ownership2.managerInstallRoot !== "string" || !isAbsolute2(ownership2.managerInstallRoot)) {
5687
+ return false;
5688
+ }
5689
+ return ownership2.method !== "pnpm" /* Pnpm */ && ownership2.method !== "bun" /* Bun */ || typeof ownership2.managerBinRoot === "string" && isAbsolute2(ownership2.managerBinRoot);
5690
+ }
5691
+ async function removePackageManagedCliReplacementState(homeDir) {
5692
+ await unlink2(getPackageManagedCliReplacementStatePath(homeDir));
5693
+ }
5694
+ async function createNativeCliSymlink(target, path) {
5695
+ await mkdir4(dirname2(path), { recursive: true });
5696
+ await symlink(target, path, process.platform === "win32" ? "file" : undefined);
5697
+ }
5416
5698
  function getManagerCommand(method, platform = process.platform) {
5417
5699
  const windows = platform === "win32";
5418
5700
  switch (method) {
@@ -5556,9 +5838,17 @@ function runExecFile(file, args, options = {}) {
5556
5838
  });
5557
5839
  }
5558
5840
  function getPlatformExecFileInvocation(file, args, platform = process.platform, commandProcessor = process.env.ComSpec) {
5559
- if (platform !== "win32" || !/\.(?:cmd|bat)$/i.test(file)) {
5841
+ if (platform !== "win32") {
5560
5842
  return { file, args: [...args] };
5561
5843
  }
5844
+ if (/\.ps1$/i.test(file)) {
5845
+ return {
5846
+ file: "powershell.exe",
5847
+ args: ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File", file, ...args]
5848
+ };
5849
+ }
5850
+ if (!/\.(?:cmd|bat)$/i.test(file))
5851
+ return { file, args: [...args] };
5562
5852
  if ([file, ...args].some((value) => /["%!^&|<>()\r\n]/.test(value))) {
5563
5853
  throw new Error("Unsafe Windows package-manager command path or argument");
5564
5854
  }
@@ -5659,6 +5949,12 @@ var AidentDesktopArtifactFormat;
5659
5949
  AidentDesktopArtifactFormat2["WindowsNsisV1"] = "windows-nsis-v1";
5660
5950
  AidentDesktopArtifactFormat2["LinuxTarZstV1"] = "linux-tar-zst-v1";
5661
5951
  })(AidentDesktopArtifactFormat ||= {});
5952
+ var AidentDesktopChannel;
5953
+ ((AidentDesktopChannel2) => {
5954
+ AidentDesktopChannel2["Staging"] = "staging";
5955
+ AidentDesktopChannel2["Rc"] = "rc";
5956
+ AidentDesktopChannel2["Stable"] = "stable";
5957
+ })(AidentDesktopChannel ||= {});
5662
5958
  var AidentOnboardingUiArtifactSchema = zod_default.object({
5663
5959
  format: zod_default.literal("aident-onboarding-ui-v1"),
5664
5960
  version: AidentSemverSchema,
@@ -5712,7 +6008,7 @@ var AidentDesktopArtifactSchema = zod_default.object({
5712
6008
  }).strict();
5713
6009
  var AidentDesktopChannelManifestSchema = zod_default.object({
5714
6010
  schemaVersion: zod_default.literal(1),
5715
- channel: zod_default.enum(["stable", "rc"]),
6011
+ channel: zod_default.nativeEnum(AidentDesktopChannel),
5716
6012
  desktopVersion: AidentSemverSchema,
5717
6013
  cliVersion: AidentSemverSchema,
5718
6014
  sourceCommit: zod_default.string().regex(/^[a-f0-9]{40}$/),
@@ -5893,6 +6189,15 @@ var KNOWN_CLEAN_LOADOUT_SKILL_REQUIRED_FILE_GIT_BLOB_SHA1 = {
5893
6189
  "references/mcp.md": "3e92c88b1ef94e863bd4ce977a36abc3a0df2138",
5894
6190
  "references/troubleshooting.md": "f819915c8829b028630ef1f8f29ae9433a072ca8"
5895
6191
  }
6192
+ ],
6193
+ "0.4.16": [
6194
+ {
6195
+ "SKILL.md": "bc15dbd5e86fc76a1f9a9870d7a910612f65ccb0",
6196
+ "references/api.md": "240b913e8c85492f2441326033db91747c54863e",
6197
+ "references/loadout.md": "be4dbd9e0aad75afe647800f64d2bb16c22d03a8",
6198
+ "references/mcp.md": "3e92c88b1ef94e863bd4ce977a36abc3a0df2138",
6199
+ "references/troubleshooting.md": "f819915c8829b028630ef1f8f29ae9433a072ca8"
6200
+ }
5896
6201
  ]
5897
6202
  };
5898
6203
  async function fetchLoadoutSkillMetadata(baseUrl) {
@@ -5931,7 +6236,7 @@ async function getLoadoutSkillInventory(candidates = getInstalledLoadoutSkillCan
5931
6236
  const resolvedManagedReleasesRoot = await realpath2(managedReleasesRoot).catch(() => managedReleasesRoot);
5932
6237
  const inspected = await Promise.all(candidates.map(async (candidate) => ({
5933
6238
  candidate,
5934
- installation: await inspectLoadoutSkillDirectory(dirname2(candidate.path), resolvedManagedReleasesRoot)
6239
+ installation: await inspectLoadoutSkillDirectory(dirname3(candidate.path), resolvedManagedReleasesRoot)
5935
6240
  })));
5936
6241
  const installations = [];
5937
6242
  const byRealPath = new Map;
@@ -5961,7 +6266,7 @@ async function inspectLoadoutSkillDirectory(skillDirectory, managedReleasesRoot
5961
6266
  const skillPath = join6(resolvedDirectory, "SKILL.md");
5962
6267
  let skillContent;
5963
6268
  try {
5964
- const skillStat = await lstat2(skillPath);
6269
+ const skillStat = await lstat3(skillPath);
5965
6270
  if (!skillStat.isFile()) {
5966
6271
  return emptyInspection("malformed" /* Malformed */, resolvedDirectory, "SKILL.md is not a file");
5967
6272
  }
@@ -5984,7 +6289,7 @@ async function inspectLoadoutSkillDirectory(skillDirectory, managedReleasesRoot
5984
6289
  for (const path of LOADOUT_SKILL_REQUIRED_FILES.slice(1)) {
5985
6290
  try {
5986
6291
  const fullPath = join6(resolvedDirectory, path);
5987
- const fileStat = await lstat2(fullPath);
6292
+ const fileStat = await lstat3(fullPath);
5988
6293
  if (!fileStat.isFile()) {
5989
6294
  return emptyInspection("malformed" /* Malformed */, resolvedDirectory, `${path} is not a file`, frontmatter.version);
5990
6295
  }
@@ -6087,7 +6392,7 @@ function isManagedReleasePath(directory, artifactSha256, managedReleasesRoot) {
6087
6392
  const normalized = path.replaceAll("\\", "/");
6088
6393
  return process.platform === "win32" ? normalized.toLowerCase() : normalized;
6089
6394
  };
6090
- return normalize(dirname2(directory)) === normalize(managedReleasesRoot) && normalize(basename(directory)) === normalize(artifactSha256);
6395
+ return normalize(dirname3(directory)) === normalize(managedReleasesRoot) && normalize(basename(directory)) === normalize(artifactSha256);
6091
6396
  }
6092
6397
  function stateForMissing(error) {
6093
6398
  return isMissingError(error) ? "missing" /* Missing */ : "malformed" /* Malformed */;
@@ -6441,7 +6746,7 @@ function isExpired(creds) {
6441
6746
 
6442
6747
  // src/loadoutFavoriteSkills.ts
6443
6748
  import { createHash as createHash4 } from "node:crypto";
6444
- import { lstat as lstat3, mkdir as mkdir6, readFile as readFile7, readlink, rename as rename2, rm as rm2, symlink, writeFile as writeFile6 } from "node:fs/promises";
6749
+ import { lstat as lstat4, mkdir as mkdir6, readFile as readFile7, readlink, rename as rename3, rm as rm2, symlink as symlink2, writeFile as writeFile6 } from "node:fs/promises";
6445
6750
  import { homedir as homedir4 } from "node:os";
6446
6751
  import path from "node:path";
6447
6752
 
@@ -6545,9 +6850,9 @@ function entrypointContent(pkg, content) {
6545
6850
  ].join(`
6546
6851
  `);
6547
6852
  }
6548
- async function pathExists(target) {
6853
+ async function pathExists2(target) {
6549
6854
  try {
6550
- await lstat3(target);
6855
+ await lstat4(target);
6551
6856
  return true;
6552
6857
  } catch (error) {
6553
6858
  if (error.code === "ENOENT")
@@ -6583,17 +6888,17 @@ async function writeManifest(home, manifest) {
6583
6888
  await mkdir6(path.dirname(manifestPath), { recursive: true, mode: 448 });
6584
6889
  await writeFile6(temporaryPath, `${JSON.stringify(manifest, null, 2)}
6585
6890
  `, { mode: 384 });
6586
- await rename2(temporaryPath, manifestPath);
6891
+ await rename3(temporaryPath, manifestPath);
6587
6892
  }
6588
6893
  async function removeOwnedSkill(skill) {
6589
6894
  for (const linkPath of skill.linkPaths) {
6590
- if (!await pathExists(linkPath))
6895
+ if (!await pathExists2(linkPath))
6591
6896
  continue;
6592
- const stat = await lstat3(linkPath);
6897
+ const stat = await lstat4(linkPath);
6593
6898
  if (stat.isSymbolicLink())
6594
6899
  await rm2(linkPath);
6595
6900
  }
6596
- if (await pathExists(skill.installPath))
6901
+ if (await pathExists2(skill.installPath))
6597
6902
  await rm2(skill.installPath, { recursive: true });
6598
6903
  }
6599
6904
  async function reconcileLoadoutFavoriteSkills(payload, home = getHome(), env = process.env) {
@@ -6632,13 +6937,13 @@ async function reconcileLoadoutFavoriteSkills(payload, home = getHome(), env = p
6632
6937
  const installPath = path.join(getCanonicalRoot(home, env), nextCommandName);
6633
6938
  const linkPaths = getHarnessRoots(home, env).map((root) => path.join(root, nextCommandName));
6634
6939
  const conflictingPath = (await Promise.all([installPath, ...linkPaths].map(async (candidate) => {
6635
- if (!await pathExists(candidate))
6940
+ if (!await pathExists2(candidate))
6636
6941
  return null;
6637
6942
  if (previous && candidate === previous.installPath) {
6638
- return (await lstat3(candidate)).isDirectory() ? null : candidate;
6943
+ return (await lstat4(candidate)).isDirectory() ? null : candidate;
6639
6944
  }
6640
6945
  if (previous && previous.linkPaths.includes(candidate)) {
6641
- const stat = await lstat3(candidate);
6946
+ const stat = await lstat4(candidate);
6642
6947
  if (!stat.isSymbolicLink())
6643
6948
  return candidate;
6644
6949
  return path.resolve(path.dirname(candidate), await readlink(candidate)) === previous.installPath ? null : candidate;
@@ -6651,8 +6956,8 @@ async function reconcileLoadoutFavoriteSkills(payload, home = getHome(), env = p
6651
6956
  nextSkills.push(previous);
6652
6957
  continue;
6653
6958
  }
6654
- const allLinksExist = (await Promise.all(linkPaths.map(pathExists))).every(Boolean);
6655
- if (previous?.artifactVersionId === pkg.artifactVersionId && previous.displayName === pkg.displayName && previous.summary === pkg.summary && previous.installPath === installPath && previous.linkPaths.length === linkPaths.length && previous.linkPaths.every((linkPath) => linkPaths.includes(linkPath)) && await pathExists(installPath) && allLinksExist) {
6959
+ const allLinksExist = (await Promise.all(linkPaths.map(pathExists2))).every(Boolean);
6960
+ if (previous?.artifactVersionId === pkg.artifactVersionId && previous.displayName === pkg.displayName && previous.summary === pkg.summary && previous.installPath === installPath && previous.linkPaths.length === linkPaths.length && previous.linkPaths.every((linkPath) => linkPaths.includes(linkPath)) && await pathExists2(installPath) && allLinksExist) {
6656
6961
  result.unchanged.push(pkg.name);
6657
6962
  nextSkills.push(previous);
6658
6963
  continue;
@@ -6671,15 +6976,15 @@ async function reconcileLoadoutFavoriteSkills(payload, home = getHome(), env = p
6671
6976
  const createdLinkPaths = [];
6672
6977
  let backedUp = false;
6673
6978
  try {
6674
- if (await pathExists(installPath)) {
6675
- await rename2(installPath, backupPath);
6979
+ if (await pathExists2(installPath)) {
6980
+ await rename3(installPath, backupPath);
6676
6981
  backedUp = true;
6677
6982
  }
6678
- await rename2(temporaryPath, installPath);
6983
+ await rename3(temporaryPath, installPath);
6679
6984
  for (const linkPath of linkPaths) {
6680
6985
  await mkdir6(path.dirname(linkPath), { recursive: true });
6681
- if (!await pathExists(linkPath)) {
6682
- await symlink(installPath, linkPath, "dir");
6986
+ if (!await pathExists2(linkPath)) {
6987
+ await symlink2(installPath, linkPath, "dir");
6683
6988
  createdLinkPaths.push(linkPath);
6684
6989
  }
6685
6990
  }
@@ -6688,7 +6993,7 @@ async function reconcileLoadoutFavoriteSkills(payload, home = getHome(), env = p
6688
6993
  await Promise.all(createdLinkPaths.map((linkPath) => rm2(linkPath, { force: true })));
6689
6994
  await rm2(installPath, { recursive: true, force: true });
6690
6995
  if (backedUp)
6691
- await rename2(backupPath, installPath);
6996
+ await rename3(backupPath, installPath);
6692
6997
  await rm2(temporaryPath, { recursive: true, force: true });
6693
6998
  throw error;
6694
6999
  }
@@ -7251,8 +7556,8 @@ function errorMessage(error) {
7251
7556
  return error instanceof Error ? error.message : String(error);
7252
7557
  }
7253
7558
  export {
7254
- name,
7255
- inject,
7559
+ apply,
7256
7560
  applyDshPlugin,
7257
- apply
7561
+ inject,
7562
+ name
7258
7563
  };