@penvhq/launcher 0.9.4 → 0.9.5

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/dist/bin.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  httpFetcher,
6
6
  nodeSpawner,
7
7
  runLauncher
8
- } from "./chunk-Q27F7QYT.js";
8
+ } from "./chunk-4YZYBC5T.js";
9
9
 
10
10
  // src/bin.ts
11
11
  function readLine() {
@@ -164,6 +164,7 @@ function setProviderType(source, environment, type) {
164
164
  import {
165
165
  ENGINE_PACKAGE,
166
166
  EXTENSIONS_PATH,
167
+ LOCAL_EXTENSIONS_PATH,
167
168
  MANIFEST_PATH,
168
169
  OFFICIAL_SCOPE,
169
170
  PenvError
@@ -271,7 +272,38 @@ var AddFlagError = class extends PenvError {
271
272
  super(
272
273
  "PENV_ADD_FLAG",
273
274
  `\`penv add\` does not understand \`${flag}\``,
274
- `Run \`penv add <package>\` with \`${TRUST_YOUNG_FLAG}\` or \`--registry <url>\` \u2014 those are the two it takes.`
275
+ `Run \`penv add <package>\` with \`${TRUST_YOUNG_FLAG}\`, \`--registry <url>\`, or \`${LOCAL_FLAG}\` \u2014 those are the three it takes.`
276
+ );
277
+ }
278
+ };
279
+ var LOCAL_FLAG = "--local";
280
+ var AddLocalFlagError = class extends PenvError {
281
+ name = "AddLocalFlagError";
282
+ constructor(subject) {
283
+ super(
284
+ "PENV_ADD_LOCAL_FLAG",
285
+ `\`penv add ${LOCAL_FLAG}\` cannot take ${subject}`,
286
+ `${LOCAL_FLAG} adds the package this project already builds, so there is no release to name and nothing to pin. Publish it and run \`penv add <package>\` to pin one.`
287
+ );
288
+ }
289
+ };
290
+ var LocalExtensionUnresolvedError = class extends PenvError {
291
+ name = "LocalExtensionUnresolvedError";
292
+ constructor(name, root) {
293
+ super(
294
+ "PENV_LOCAL_EXTENSION_UNRESOLVED",
295
+ `${name} does not resolve from ${root}`,
296
+ `${LOCAL_FLAG} records that penv should read this package out of the project, so the project has to have it \u2014 add it as a dependency of the root (a workspace link is one), then run this again.`
297
+ );
298
+ }
299
+ };
300
+ var AddLocalInCiError = class extends PenvError {
301
+ name = "AddLocalInCiError";
302
+ constructor(name) {
303
+ super(
304
+ "PENV_ADD_LOCAL_IN_CI",
305
+ `Adding ${name} writes ${LOCAL_EXTENSIONS_PATH}, and CI does not decide what a project develops`,
306
+ `Run \`penv add ${LOCAL_FLAG} ${name}\` from a terminal and commit what it writes.`
275
307
  );
276
308
  }
277
309
  };
@@ -474,14 +506,20 @@ function readExtensionPackage(dir) {
474
506
  try {
475
507
  parsed = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
476
508
  } catch {
477
- return { types: void 0, onboard: void 0 };
509
+ return { name: void 0, version: void 0, types: void 0, onboard: void 0 };
478
510
  }
479
511
  const penv = field(parsed, "penv");
480
- return { types: text(field(penv, "types")), onboard: text(field(penv, "onboard")) };
512
+ return {
513
+ name: text(field(parsed, "name")),
514
+ version: text(field(parsed, "version")),
515
+ types: text(field(penv, "types")),
516
+ onboard: text(field(penv, "onboard"))
517
+ };
481
518
  }
482
519
  function header(subject) {
483
- const provenance = subject.attested ? "npm records a provenance attestation for it" : "npm records no provenance attestation for it";
484
- return `// Written by \`penv add ${subject.name}\`, and committed.
520
+ const local = subject.local === true;
521
+ const provenance = local ? "resolved from this project, not from a published release" : subject.attested ? "npm records a provenance attestation for it" : "npm records no provenance attestation for it";
522
+ return `// Written by \`penv add ${local ? "--local " : ""}${subject.name}\`, and committed.
485
523
  // ${subject.name} ${subject.version} \u2014 ${provenance}.
486
524
  //
487
525
  // Types only: this declares the shape of the provider's \`penv.config.ts\`
@@ -819,9 +857,19 @@ async function fetchRelease(query) {
819
857
  }
820
858
 
821
859
  // src/add.ts
822
- import { readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
823
- import { relative, sep as sep3 } from "path";
824
- import { findConfigFile, MANIFEST_PATH as MANIFEST_PATH2, OFFICIAL_SCOPE as OFFICIAL_SCOPE2, serializeManifest } from "@penvhq/core";
860
+ import { mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
861
+ import { createRequire } from "module";
862
+ import { dirname as dirname3, relative, resolve as resolve3, sep as sep3 } from "path";
863
+ import {
864
+ findConfigFile,
865
+ LOCAL_EXTENSIONS_PATH as LOCAL_EXTENSIONS_PATH2,
866
+ localExtensionsFile,
867
+ MANIFEST_PATH as MANIFEST_PATH2,
868
+ OFFICIAL_SCOPE as OFFICIAL_SCOPE2,
869
+ parseLocalExtensions,
870
+ serializeLocalExtensions,
871
+ serializeManifest
872
+ } from "@penvhq/core";
825
873
 
826
874
  // src/repair.ts
827
875
  import { parseManifest } from "@penvhq/core";
@@ -885,8 +933,13 @@ function parseRequest(argv) {
885
933
  let spec;
886
934
  let registry;
887
935
  let trustYoung = false;
936
+ let local = false;
888
937
  for (let index = 0; index < argv.length; index += 1) {
889
938
  const token = argv[index] ?? "";
939
+ if (token === LOCAL_FLAG) {
940
+ local = true;
941
+ continue;
942
+ }
890
943
  if (token === TRUST_YOUNG_FLAG) {
891
944
  trustYoung = true;
892
945
  continue;
@@ -915,7 +968,18 @@ function parseRequest(argv) {
915
968
  if (!PACKAGE_NAME.test(name) || version === "") {
916
969
  throw new AddPackageNameError(spec);
917
970
  }
918
- return { name, version, registry, trustYoung };
971
+ if (local) {
972
+ if (version !== void 0) {
973
+ throw new AddLocalFlagError("a version");
974
+ }
975
+ if (registry !== void 0) {
976
+ throw new AddLocalFlagError(`\`${REGISTRY_FLAG}\``);
977
+ }
978
+ if (trustYoung) {
979
+ throw new AddLocalFlagError(`\`${TRUST_YOUNG_FLAG}\``);
980
+ }
981
+ }
982
+ return { name, version, registry, trustYoung, local };
919
983
  }
920
984
  function tierOf(request) {
921
985
  if (request.name.startsWith(OFFICIAL_SCOPE2)) {
@@ -1048,9 +1112,69 @@ async function offerOnboarding(io, name, onboard) {
1048
1112
  io.out(`Run \`${command}\` to finish setting ${name} up.`);
1049
1113
  return void 0;
1050
1114
  }
1115
+ function resolvePackageDir(name, root) {
1116
+ const require2 = createRequire(resolve3(root, "noop.js"));
1117
+ try {
1118
+ return dirname3(require2.resolve(`${name}/package.json`));
1119
+ } catch {
1120
+ let dir;
1121
+ try {
1122
+ dir = dirname3(require2.resolve(name));
1123
+ } catch {
1124
+ return void 0;
1125
+ }
1126
+ for (let current = dir, parent = dirname3(dir); current !== parent; parent = dirname3(current)) {
1127
+ if (readExtensionPackage(current).name === name) {
1128
+ return current;
1129
+ }
1130
+ current = parent;
1131
+ }
1132
+ return void 0;
1133
+ }
1134
+ }
1135
+ function recordLocalExtension(root, name) {
1136
+ const file = localExtensionsFile(root);
1137
+ let current;
1138
+ try {
1139
+ current = readFileSync4(file, "utf8");
1140
+ } catch {
1141
+ current = "[]";
1142
+ }
1143
+ mkdirSync3(dirname3(file), { recursive: true });
1144
+ writeFileSync3(file, serializeLocalExtensions([...parseLocalExtensions(current), name]));
1145
+ }
1146
+ async function addLocal(options, request) {
1147
+ const { io, root } = options;
1148
+ if (options.ci === true) {
1149
+ throw new AddLocalInCiError(request.name);
1150
+ }
1151
+ const dir = resolvePackageDir(request.name, root);
1152
+ if (dir === void 0) {
1153
+ throw new LocalExtensionUnresolvedError(request.name, root);
1154
+ }
1155
+ const installed = readExtensionPackage(dir);
1156
+ const declaration = writeDeclaration({
1157
+ root,
1158
+ dir,
1159
+ name: request.name,
1160
+ version: installed.version ?? "unpublished",
1161
+ attested: false,
1162
+ local: true,
1163
+ types: installed.types
1164
+ });
1165
+ recordLocalExtension(root, request.name);
1166
+ io.out(`\u2713 ${request.name} resolves from this project \u2014 nothing is pinned`);
1167
+ io.out(`\u2713 ${LOCAL_EXTENSIONS_PATH2} records it`);
1168
+ io.out(`\u2713 ${declaration} declares its config type`);
1169
+ await offerConfigEdit(options, request.name);
1170
+ return { onboard: await offerOnboarding(io, request.name, installed.onboard) };
1171
+ }
1051
1172
  async function add(options) {
1052
1173
  const { io, fetcher, home, root, manifestFile } = options;
1053
1174
  const request = parseRequest(options.argv);
1175
+ if (request.local) {
1176
+ return addLocal(options, request);
1177
+ }
1054
1178
  const tier = tierOf(request);
1055
1179
  const now = (options.now ?? (() => /* @__PURE__ */ new Date()))();
1056
1180
  if (options.noDownload === true) {
@@ -1147,13 +1271,13 @@ function nodeSpawner() {
1147
1271
 
1148
1272
  // src/engine.ts
1149
1273
  import { existsSync as existsSync2, readFileSync as readFileSync5 } from "fs";
1150
- import { createRequire } from "module";
1151
- import { dirname as dirname3, join as join4, resolve as resolve3, sep as sep4 } from "path";
1274
+ import { createRequire as createRequire2 } from "module";
1275
+ import { dirname as dirname4, join as join5, resolve as resolve4, sep as sep4 } from "path";
1152
1276
  import { ENGINE_PACKAGE as ENGINE_PACKAGE2, PenvError as PenvError3 } from "@penvhq/core";
1153
1277
  var ENGINE_BIN = "penv-engine";
1154
1278
  function readPackageManifest(dir) {
1155
1279
  try {
1156
- return JSON.parse(readFileSync5(join4(dir, "package.json"), "utf8"));
1280
+ return JSON.parse(readFileSync5(join5(dir, "package.json"), "utf8"));
1157
1281
  } catch {
1158
1282
  return void 0;
1159
1283
  }
@@ -1175,15 +1299,15 @@ function binPath(bin) {
1175
1299
  function engineAt(dir, name, version) {
1176
1300
  const manifest = readPackageManifest(dir);
1177
1301
  const bin = manifest === void 0 ? void 0 : binPath(manifest.bin);
1178
- const root = resolve3(dir);
1179
- const entry = bin === void 0 ? void 0 : resolve3(root, bin);
1302
+ const root = resolve4(dir);
1303
+ const entry = bin === void 0 ? void 0 : resolve4(root, bin);
1180
1304
  if (entry === void 0 || !entry.startsWith(root + sep4) || !existsSync2(entry)) {
1181
1305
  throw new EngineEntryError(name, version, dir);
1182
1306
  }
1183
1307
  return { name, version, dir, entry };
1184
1308
  }
1185
1309
  function bundledEngine() {
1186
- const require2 = createRequire(import.meta.url);
1310
+ const require2 = createRequire2(import.meta.url);
1187
1311
  let manifestFile;
1188
1312
  try {
1189
1313
  manifestFile = require2.resolve(`${ENGINE_PACKAGE2}/package.json`);
@@ -1194,7 +1318,7 @@ function bundledEngine() {
1194
1318
  "Reinstall the launcher with `npm install -g @penvhq/launcher`."
1195
1319
  );
1196
1320
  }
1197
- const dir = dirname3(manifestFile);
1321
+ const dir = dirname4(manifestFile);
1198
1322
  const version = readPackageManifest(dir)?.version;
1199
1323
  return engineAt(dir, ENGINE_PACKAGE2, typeof version === "string" ? version : "unknown");
1200
1324
  }
@@ -1218,8 +1342,8 @@ var DEV_PIN_INTEGRITY = "sha512-development-build-not-a-published-release";
1218
1342
  var DEV_PIN_VERSION = "0.0.0-dev";
1219
1343
  var BUNDLED_ENGINE_PIN = {
1220
1344
  package: ENGINE_PACKAGE3,
1221
- version: "0.9.4",
1222
- integrity: "sha512-XnG+KlEAZyUaaKUfANPiyhY1dfYZ9KgnkF2R+5A0OskRgfYPSpBRN0i1UPtq8RnwMJaPxfSNDNdqfiiESz6kRw=="
1345
+ version: "0.9.5",
1346
+ integrity: "sha512-cacsvynscs6G0NThpGaK1BfKy3POQSoogI/vvQNZ5sTZaftzwg4mPtUpT+i2GSc3KbYAHQu4Kq9MpYLOvSvulA=="
1223
1347
  };
1224
1348
  function assertReleasePin(pin) {
1225
1349
  if (pin.integrity === DEV_PIN_INTEGRITY || pin.version === DEV_PIN_VERSION) {
@@ -1236,16 +1360,16 @@ function releaseEnginePin(pin, ranVersion) {
1236
1360
 
1237
1361
  // src/project.ts
1238
1362
  import { existsSync as existsSync3 } from "fs";
1239
- import { dirname as dirname4, join as join5, resolve as resolve4 } from "path";
1363
+ import { dirname as dirname5, join as join6, resolve as resolve5 } from "path";
1240
1364
  import { MANIFEST_PATH as MANIFEST_PATH3, stateDir } from "@penvhq/core";
1241
1365
  var MANIFEST_SEGMENTS = MANIFEST_PATH3.split("/");
1242
1366
  function findUp(cwd, matches) {
1243
- let dir = resolve4(cwd);
1367
+ let dir = resolve5(cwd);
1244
1368
  for (; ; ) {
1245
1369
  if (matches(dir)) {
1246
1370
  return dir;
1247
1371
  }
1248
- const parent = dirname4(dir);
1372
+ const parent = dirname5(dir);
1249
1373
  if (parent === dir) {
1250
1374
  return void 0;
1251
1375
  }
@@ -1253,8 +1377,8 @@ function findUp(cwd, matches) {
1253
1377
  }
1254
1378
  }
1255
1379
  function findProject(cwd) {
1256
- const root = findUp(cwd, (dir) => existsSync3(join5(dir, ...MANIFEST_SEGMENTS)));
1257
- return root === void 0 ? void 0 : { root, manifestFile: join5(root, ...MANIFEST_SEGMENTS) };
1380
+ const root = findUp(cwd, (dir) => existsSync3(join6(dir, ...MANIFEST_SEGMENTS)));
1381
+ return root === void 0 ? void 0 : { root, manifestFile: join6(root, ...MANIFEST_SEGMENTS) };
1258
1382
  }
1259
1383
  function findAdoptedRoot(cwd) {
1260
1384
  return findUp(cwd, (dir) => existsSync3(stateDir(dir)));
@@ -1262,7 +1386,7 @@ function findAdoptedRoot(cwd) {
1262
1386
 
1263
1387
  // src/launcher.ts
1264
1388
  import { existsSync as existsSync4, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
1265
- import { join as join6 } from "path";
1389
+ import { join as join7 } from "path";
1266
1390
  import {
1267
1391
  MANIFEST_FORMAT,
1268
1392
  MANIFEST_PATH as MANIFEST_PATH4,
@@ -1403,7 +1527,7 @@ async function adopt(options, forwarded, home, cwd, noDownload) {
1403
1527
  if (root === void 0) {
1404
1528
  return 0;
1405
1529
  }
1406
- const manifestFile = join6(root, ...MANIFEST_PATH4.split("/"));
1530
+ const manifestFile = join7(root, ...MANIFEST_PATH4.split("/"));
1407
1531
  if (existsSync4(manifestFile)) {
1408
1532
  return 0;
1409
1533
  }
@@ -1516,6 +1640,10 @@ export {
1516
1640
  AddSubjectError,
1517
1641
  AddPackageNameError,
1518
1642
  AddFlagError,
1643
+ LOCAL_FLAG,
1644
+ AddLocalFlagError,
1645
+ LocalExtensionUnresolvedError,
1646
+ AddLocalInCiError,
1519
1647
  AddRegistryError,
1520
1648
  OfficialRegistryError,
1521
1649
  RegistryUnreadableError,
@@ -1567,4 +1695,4 @@ export {
1567
1695
  findAdoptedRoot,
1568
1696
  runLauncher
1569
1697
  };
1570
- //# sourceMappingURL=chunk-Q27F7QYT.js.map
1698
+ //# sourceMappingURL=chunk-4YZYBC5T.js.map