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 +47 -13
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
1351
|
-
|
|
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
|
|
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.
|
|
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."
|