create-op-node 0.12.2 → 0.12.4

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/cli.js CHANGED
@@ -1335,8 +1335,6 @@ async function waitForApplyAndFetchTunnelToken(input) {
1335
1335
  return null;
1336
1336
  }
1337
1337
  }
1338
-
1339
- // src/lib/homebrew.ts
1340
1338
  var STUDIO_PACKAGES = [
1341
1339
  { name: "git", kind: "formula" },
1342
1340
  { name: "gh", kind: "formula" },
@@ -1347,8 +1345,11 @@ var STUDIO_PACKAGES = [
1347
1345
  { name: "ollama", kind: "formula" },
1348
1346
  // Required for the fail-closed image-signature gate in `bootstrap` (#34).
1349
1347
  { name: "cosign", kind: "formula" },
1350
- { name: "docker", kind: "cask" },
1351
- { name: "tailscale", kind: "cask" }
1348
+ // Homebrew renamed the `docker` cask to `docker-desktop`. The appPath skip
1349
+ // means a directly-installed Docker Desktop (the common case) is treated as
1350
+ // present rather than tripping `brew install` on the existing app. (#89)
1351
+ { name: "docker-desktop", kind: "cask", appPath: "/Applications/Docker.app" },
1352
+ { name: "tailscale", kind: "cask", appPath: "/Applications/Tailscale.app" }
1352
1353
  ];
1353
1354
  async function detectBrew() {
1354
1355
  const res = await safeExeca("brew", ["--version"]);
@@ -1359,7 +1360,18 @@ async function detectBrew() {
1359
1360
  return { installed: true, ...version ? { version } : {} };
1360
1361
  }
1361
1362
  var HOMEBREW_INSTALL_COMMAND = '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"';
1363
+ async function pathExists(path) {
1364
+ try {
1365
+ await access(path);
1366
+ return true;
1367
+ } catch {
1368
+ return false;
1369
+ }
1370
+ }
1362
1371
  async function isPackageInstalled(pkg) {
1372
+ if (pkg.appPath && await pathExists(pkg.appPath)) {
1373
+ return true;
1374
+ }
1363
1375
  const flag = pkg.kind === "cask" ? "--cask" : "--formula";
1364
1376
  const res = await safeExeca("brew", ["list", flag, pkg.name]);
1365
1377
  return res !== null && res.exitCode === 0;
@@ -1481,6 +1493,7 @@ async function writePgsodiumKeyFile(key, keyFile) {
1481
1493
  try {
1482
1494
  const dir = dirname(keyFile);
1483
1495
  await mkdir(dir, { recursive: true, mode: 448 });
1496
+ await rm(keyFile, { force: true });
1484
1497
  await writeFile(keyFile, key, { mode: 256 });
1485
1498
  await chmod(dir, 448);
1486
1499
  await chmod(keyFile, 256);
@@ -2061,7 +2074,7 @@ function assessAllRunning(snapshots) {
2061
2074
 
2062
2075
  // src/lib/cosign.ts
2063
2076
  var COSIGN_OIDC_ISSUER = "https://token.actions.githubusercontent.com";
2064
- var DEFAULT_IDENTITY_REGEXP = "^https://github\\.com/OpusPopuli/opuspopuli/\\.github/workflows/release\\.yml@refs/heads/.*$";
2077
+ var DEFAULT_IDENTITY_REGEXP = "^https://github\\.com/OpusPopuli/(?:opuspopuli|prompt-service)/\\.github/workflows/release\\.yml@refs/heads/.*$";
2065
2078
  async function cosignVerifyImage(input) {
2066
2079
  const idRegex = input.certificateIdentityRegexp ?? DEFAULT_IDENTITY_REGEXP;
2067
2080
  const issuer = input.certificateOidcIssuer ?? COSIGN_OIDC_ISSUER;
@@ -2615,15 +2628,18 @@ async function collectCoreSecrets(args) {
2615
2628
  }
2616
2629
  async function collectPromptServiceSecrets(args) {
2617
2630
  const { region, nodeType, opts } = args;
2631
+ let promptsDbPassword;
2632
+ let promptServiceApiKey;
2633
+ let promptServiceAdminApiKeys;
2618
2634
  if (nodeType === "region-with-prompts") {
2619
- await loadSecret({
2635
+ promptsDbPassword = await loadSecret({
2620
2636
  region,
2621
2637
  account: "prompts-db-password",
2622
2638
  label: "prompt-service Postgres password",
2623
2639
  validate: (v) => URL_SAFE_PASSWORD_RE.test(v) ? void 0 : "must be base64url chars only (no + / =)",
2624
2640
  generate: generatePostgresPassword
2625
2641
  });
2626
- await loadSecret({
2642
+ promptServiceApiKey = await loadSecret({
2627
2643
  region,
2628
2644
  account: "prompt-service-api-key",
2629
2645
  label: "prompt-service HMAC API key",
@@ -2632,7 +2648,7 @@ async function collectPromptServiceSecrets(args) {
2632
2648
  validate: (v) => URL_SAFE_PASSWORD_RE.test(v) ? void 0 : "must be base64url chars only (no + / =)",
2633
2649
  generate: generateHmacApiKey
2634
2650
  });
2635
- await loadSecret({
2651
+ promptServiceAdminApiKeys = await loadSecret({
2636
2652
  region,
2637
2653
  account: "prompt-service-admin-api-key",
2638
2654
  label: "prompt-service admin API key",
@@ -2640,7 +2656,7 @@ async function collectPromptServiceSecrets(args) {
2640
2656
  generate: generateHmacApiKey
2641
2657
  });
2642
2658
  } else {
2643
- await loadSecret({
2659
+ promptServiceApiKey = await loadSecret({
2644
2660
  region,
2645
2661
  account: "prompt-service-api-key",
2646
2662
  label: "prompt-service HMAC API key (issued by the prompts team)",
@@ -2658,7 +2674,15 @@ async function collectPromptServiceSecrets(args) {
2658
2674
  );
2659
2675
  process.exit(1);
2660
2676
  }
2661
- return promptServiceUrl;
2677
+ return {
2678
+ url: promptServiceUrl,
2679
+ ...promptsDbPassword !== void 0 ? { promptsDbPassword } : {},
2680
+ // PROMPT_SERVICE_API_KEY is the raw key; PROMPT_SERVICE_API_KEYS is the
2681
+ // `<region>:<key>` list prompt-service validates against — same derivation
2682
+ // the op-compose wrapper does.
2683
+ ...promptServiceApiKey !== void 0 ? { promptServiceApiKey, promptServiceApiKeys: `${region}:${promptServiceApiKey}` } : {},
2684
+ ...promptServiceAdminApiKeys !== void 0 ? { promptServiceAdminApiKeys } : {}
2685
+ };
2662
2686
  }
2663
2687
  async function resolveSupabaseUrl(opts) {
2664
2688
  let supabaseUrl;
@@ -2688,9 +2712,9 @@ async function resolveSupabaseUrl(opts) {
2688
2712
  }
2689
2713
  async function collectSecretsPhase(args) {
2690
2714
  const core = await collectCoreSecrets({ region: args.region, opts: args.opts });
2691
- const promptServiceUrl = await collectPromptServiceSecrets(args);
2715
+ const { url: promptServiceUrl, ...promptSecrets } = await collectPromptServiceSecrets(args);
2692
2716
  const supabaseUrl = await resolveSupabaseUrl(args.opts);
2693
- return { ...core, promptServiceUrl, supabaseUrl };
2717
+ return { ...core, ...promptSecrets, promptServiceUrl, supabaseUrl };
2694
2718
  }
2695
2719
  async function runLaunchAgentPhase(args) {
2696
2720
  const { opts, secrets, llmModel, embeddingModel } = args;
@@ -2806,6 +2830,16 @@ function buildComposeEnv(args) {
2806
2830
  SUPABASE_URL: secrets.supabaseUrl,
2807
2831
  AUTH_JWT_SECRET: process.env["AUTH_JWT_SECRET"] ?? secrets.jwtSecret,
2808
2832
  ...secrets.tunnelToken !== void 0 ? { TUNNEL_TOKEN: secrets.tunnelToken } : {},
2833
+ // prompt-service wiring — mirrors the op-compose wrapper so bootstrap's OWN
2834
+ // compose calls can process the region-with-prompts overlay instead of
2835
+ // aborting on `${PROMPTS_DB_PASSWORD:?}`. PROMPT_SERVICE_URL is always set
2836
+ // (in-network for colocated, remote otherwise); the rest are present only
2837
+ // when the node runs or calls a prompt-service. (#90)
2838
+ PROMPT_SERVICE_URL: secrets.promptServiceUrl,
2839
+ ...secrets.promptsDbPassword !== void 0 ? { PROMPTS_DB_PASSWORD: secrets.promptsDbPassword } : {},
2840
+ ...secrets.promptServiceApiKey !== void 0 ? { PROMPT_SERVICE_API_KEY: secrets.promptServiceApiKey } : {},
2841
+ ...secrets.promptServiceApiKeys !== void 0 ? { PROMPT_SERVICE_API_KEYS: secrets.promptServiceApiKeys } : {},
2842
+ ...secrets.promptServiceAdminApiKeys !== void 0 ? { PROMPT_SERVICE_ADMIN_API_KEYS: secrets.promptServiceAdminApiKeys } : {},
2809
2843
  ...llmModel ? { LLM_MODEL: llmModel } : {},
2810
2844
  ...embeddingModel ? { EMBEDDINGS_MODEL: embeddingModel } : {}
2811
2845
  };
@@ -5121,7 +5155,7 @@ function withDefaultSubcommand(argv, known) {
5121
5155
  }
5122
5156
 
5123
5157
  // src/cli.ts
5124
- var VERSION = "0.12.2";
5158
+ var VERSION = "0.12.4";
5125
5159
  var program = new Command();
5126
5160
  program.name("create-op-node").description(
5127
5161
  "Interactive bootstrap for an Opus Populi federation node.\nCloudflare infrastructure \u2192 Mac Studio \u2192 live public API."