create-op-node 0.14.0 → 0.15.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.
package/dist/cli.js CHANGED
@@ -4014,7 +4014,12 @@ async function runVerify(input, deps = DEFAULT_DEPS2) {
4014
4014
  await verifyCosignPhase(input, deps, push);
4015
4015
  return { phases };
4016
4016
  }
4017
+ function skipLocalOnly(name, detail, push) {
4018
+ push({ name, status: "skipped", detail });
4019
+ }
4020
+ var LOCAL_ONLY_NO_ENDPOINT = "local-only node \u2014 no public endpoint to probe";
4017
4021
  async function verifyTlsPhase(input, deps, push) {
4022
+ if (input.localOnly) return skipLocalOnly("TLS handshake", LOCAL_ONLY_NO_ENDPOINT, push);
4018
4023
  const tls2 = await deps.tls({ host: input.apiHost });
4019
4024
  if (!tls2.ok) {
4020
4025
  push({ name: "TLS handshake", status: "fail", detail: tls2.reason });
@@ -4032,6 +4037,7 @@ async function verifyTlsPhase(input, deps, push) {
4032
4037
  push({ name: "TLS handshake", status: "ok", detail: line });
4033
4038
  }
4034
4039
  async function verifyHealthPhase(input, deps, push) {
4040
+ if (input.localOnly) return skipLocalOnly("GET /health", LOCAL_ONLY_NO_ENDPOINT, push);
4035
4041
  const health = await deps.http({ url: `https://${input.apiHost}/health` });
4036
4042
  if (health.ok) {
4037
4043
  push({ name: "GET /health", status: "ok", detail: `HTTP ${health.status}` });
@@ -4040,6 +4046,7 @@ async function verifyHealthPhase(input, deps, push) {
4040
4046
  }
4041
4047
  }
4042
4048
  async function verifyGraphqlPhase(input, deps, push) {
4049
+ if (input.localOnly) return skipLocalOnly("GraphQL { __typename }", LOCAL_ONLY_NO_ENDPOINT, push);
4043
4050
  const gql = await deps.graphql({ url: `https://${input.apiHost}/api` });
4044
4051
  if (gql.ok) {
4045
4052
  push({ name: "GraphQL { __typename }", status: "ok", detail: `typename=${gql.typename}` });
@@ -4081,6 +4088,7 @@ async function verifyOllamaModelsPhase(input, deps, push) {
4081
4088
  push({ name: "Ollama models", status: "ok", detail: `${required.join(", ")} present` });
4082
4089
  }
4083
4090
  async function verifyCloudflarePhase(input, deps, push) {
4091
+ if (input.localOnly) return skipLocalOnly("Cloudflare Tunnel", "local-only node \u2014 no tunnel", push);
4084
4092
  const cfFields = [
4085
4093
  ["--cf-token", input.cf?.token],
4086
4094
  ["--cf-account-id", input.cf?.accountId],
@@ -4150,6 +4158,9 @@ function readTokenFile(path) {
4150
4158
  if (!raw) throw new Error(`--cf-token-file ${path} was empty`);
4151
4159
  return raw;
4152
4160
  }
4161
+ function collectImage(value, previous) {
4162
+ return [...previous ?? [], value];
4163
+ }
4153
4164
  var verifyCommand = new Command("verify").description(
4154
4165
  "Off-LAN health probe of a live node \u2014 TLS, Apollo Federation reachability, GraphQL smoke. Run from anywhere with internet access."
4155
4166
  ).addOption(
@@ -4159,9 +4170,7 @@ var verifyCommand = new Command("verify").description(
4159
4170
  ).addOption(new Option("--cf-account-id <id>", "Cloudflare account ID (required with --cf-token)")).addOption(
4160
4171
  new Option("--tunnel-id <id>", "Cloudflare Tunnel ID to query (required with --cf-token)")
4161
4172
  ).addOption(
4162
- new Option("--image <ref>", "Repeatable. Image to cosign-verify (e.g. ghcr.io/opuspopuli/api:tag)").default(
4163
- []
4164
- )
4173
+ new Option("--image <ref>", "Repeatable. Image to cosign-verify (e.g. ghcr.io/opuspopuli/api:tag)").default([]).argParser(collectImage)
4165
4174
  ).addOption(
4166
4175
  new Option("--cert-warn-days <n>", "Warn if cert expires within N days").default("14")
4167
4176
  ).addOption(
@@ -4175,14 +4184,20 @@ var verifyCommand = new Command("verify").description(
4175
4184
  new Option("--embeddings-provider <provider>", "Embeddings provider the node runs; the embedding model is only asserted for `ollama`.").choices(["xenova", "ollama"])
4176
4185
  ).addOption(
4177
4186
  new Option("--repo-dir <path>", "Node repo dir whose .env supplies the model config when --llm-model is omitted (default: cwd).")
4187
+ ).addOption(
4188
+ new Option(
4189
+ "--local-only",
4190
+ "Node has no public domain/tunnel \u2014 skip the TLS/health/GraphQL/tunnel probes (no domain prompt) and run only the node-local checks (Ollama model presence, cosign)."
4191
+ ).default(false)
4178
4192
  ).addOption(
4179
4193
  new Option("--show-skipped", "Include skipped phases in the summary").default(false)
4180
4194
  ).action(async (opts) => {
4181
4195
  p3.intro(pc2.bgCyan(pc2.black(" create-op-node verify ")));
4182
- const domain = await resolveDomain(opts);
4196
+ const localOnly = opts.localOnly ?? false;
4197
+ const domain = localOnly ? void 0 : await resolveDomain(opts);
4183
4198
  const certWarnDays = resolveCertWarnDays(opts);
4184
4199
  const cfToken = resolveCfToken(opts);
4185
- const apiHost = opts.apiHost ?? `api.${domain}`;
4200
+ const apiHost = localOnly ? "" : opts.apiHost ?? `api.${domain}`;
4186
4201
  const images = opts.image ?? [];
4187
4202
  const ollama = await resolveOllamaVerifyInput(opts);
4188
4203
  const totalPhases = 5 + (images.length === 0 ? 1 : images.length);
@@ -4193,6 +4208,7 @@ var verifyCommand = new Command("verify").description(
4193
4208
  opts,
4194
4209
  images,
4195
4210
  totalPhases,
4211
+ localOnly,
4196
4212
  ...ollama ? { ollama } : {}
4197
4213
  });
4198
4214
  renderVerifySummary(report, { opts, totalPhases });
@@ -4291,7 +4307,7 @@ async function resolveOllamaVerifyInput(opts) {
4291
4307
  return mergeOllamaModelConfig(opts, envCfg);
4292
4308
  }
4293
4309
  async function runVerifyWithSpinner(args) {
4294
- const { apiHost, certWarnDays, cfToken, opts, images, totalPhases, ollama } = args;
4310
+ const { apiHost, certWarnDays, cfToken, opts, images, totalPhases, localOnly, ollama } = args;
4295
4311
  let phaseIndex = 0;
4296
4312
  let activeSpin = null;
4297
4313
  const renderPhase = (ph) => {
@@ -4313,6 +4329,7 @@ async function runVerifyWithSpinner(args) {
4313
4329
  ...opts.tunnelId ? { tunnelId: opts.tunnelId } : {}
4314
4330
  },
4315
4331
  images,
4332
+ localOnly,
4316
4333
  ...ollama ? { ollama } : {}
4317
4334
  },
4318
4335
  deps
@@ -5428,7 +5445,7 @@ function withDefaultSubcommand(argv, known) {
5428
5445
  }
5429
5446
 
5430
5447
  // src/cli.ts
5431
- var VERSION = "0.14.0";
5448
+ var VERSION = "0.15.0";
5432
5449
  var program = new Command();
5433
5450
  program.name("create-op-node").description(
5434
5451
  "Interactive bootstrap for an Opus Populi federation node.\nCloudflare infrastructure \u2192 Mac Studio \u2192 live public API."