@eve-horizon/cli 0.2.51 → 0.2.53

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/index.js CHANGED
@@ -51284,97 +51284,58 @@ Requires Docker Desktop; k3d and kubectl are auto-managed by the CLI.`,
51284
51284
  "eve analytics env-health --org org_xxx"
51285
51285
  ]
51286
51286
  },
51287
- ollama: {
51288
- description: "Manage inference targets, installs, models, aliases, and platform managed availability.",
51289
- usage: "eve ollama <subcommand> [options]",
51287
+ endpoint: {
51288
+ description: "Manage private endpoints \u2014 Tailscale-connected services accessible from within the K8s cluster.",
51289
+ usage: "eve endpoint <subcommand> [options]",
51290
51290
  subcommands: {
51291
- targets: {
51292
- description: "List inference targets",
51293
- usage: "eve ollama targets [--scope-kind <platform|org|project>] [--scope-id <id>] [--json]"
51294
- },
51295
- target: {
51296
- description: "Manage a single target (add, rm, test, wake, pull, models)",
51297
- usage: "eve ollama target <add|rm|test|wake|pull|models> [options]",
51298
- options: [
51299
- "add: --name <name> --base-url <url> [--scope-kind <kind>] [--scope-id <id>] [--target-type <type>] [--transport-profile <profile>] [--api-key-ref <secret-ref>]",
51300
- "rm: <target-id>",
51301
- "test: <target-id>",
51302
- "wake: <target-id> [--wait true] [--timeout-ms <ms>] \u2014 Trigger GPU wake via ASG. Without --wait, returns immediately with retry_after_seconds (caller must poll). With --wait, server polls every 2.5s until target is healthy or timeout (default 120s, ~65s typical cold start).",
51303
- "pull: <target-id> --model-id <id> \u2014 Pull a model onto a remote Ollama target",
51304
- "models: <target-id> \u2014 List models currently loaded on a remote target"
51305
- ]
51306
- },
51307
- models: {
51308
- description: "List canonical inference models",
51309
- usage: "eve ollama models [--json]"
51310
- },
51311
- model: {
51312
- description: "Create canonical inference model",
51313
- usage: "eve ollama model add --canonical <id> --provider <name> --slug <provider-model-slug>"
51314
- },
51315
- aliases: {
51316
- description: "List alias routes",
51317
- usage: "eve ollama aliases [--scope-kind <kind>] [--scope-id <id>] [--json]"
51318
- },
51319
- alias: {
51320
- description: "Set or remove alias route",
51321
- usage: "eve ollama alias <set|rm> [options]",
51291
+ add: {
51292
+ description: "Register a private endpoint backed by Tailscale",
51293
+ usage: "eve endpoint add --name <name> --tailscale-hostname <fqdn> --port <port> --org <org_id> [--health-path <path>]",
51322
51294
  options: [
51323
- "set: --alias <name> --target-id <target-id> --model-id <model-id> [--scope-kind <kind>] [--scope-id <id>]",
51324
- "rm: --alias <name> [--scope-kind <kind>] [--scope-id <id>]"
51295
+ "--name <name> DNS-safe endpoint name",
51296
+ "--tailscale-hostname <fqdn> Tailscale MagicDNS hostname (e.g., mac-mini.tail12345.ts.net)",
51297
+ "--port <port> Service port (1-65535)",
51298
+ "--org <id> Organization ID or slug",
51299
+ '--health-path <path> HTTP health check path (default: /v1/models, "none" to disable)'
51300
+ ],
51301
+ examples: [
51302
+ "eve endpoint add --name lmstudio --tailscale-hostname mac-mini.tail12345.ts.net --port 1234 --org org_xxx"
51325
51303
  ]
51326
51304
  },
51327
- installs: {
51328
- description: "List target-model installs",
51329
- usage: "eve ollama installs [--target-id <id>] [--model-id <id>] [--json]"
51305
+ list: {
51306
+ description: "List registered endpoints for an org",
51307
+ usage: "eve endpoint list --org <org_id>",
51308
+ examples: ["eve endpoint list --org org_xxx"]
51330
51309
  },
51331
- install: {
51332
- description: "Install or remove model availability on a target",
51333
- usage: "eve ollama install <add|rm> --target-id <target-id> --model-id <model-id> [options]",
51310
+ show: {
51311
+ description: "Show endpoint details and optionally run a health check",
51312
+ usage: "eve endpoint show <name> --org <org_id> [--verbose]",
51334
51313
  options: [
51335
- "add: --target-id <target-id> --model-id <model-id> [--requires-warm-start true|false] [--min-target-capacity <n>]",
51336
- "rm: --target-id <target-id> --model-id <model-id>"
51337
- ]
51338
- },
51339
- assignments: {
51340
- description: "Inspect target assignment/load and queue depth",
51341
- usage: "eve ollama assignments [--scope-kind <platform|org|project>] [--scope-id <id>] [--json]"
51314
+ "--verbose Run and display a health check"
51315
+ ],
51316
+ examples: ["eve endpoint show lmstudio --org org_xxx --verbose"]
51342
51317
  },
51343
- "route-policies": {
51344
- description: "List route policies by scope",
51345
- usage: "eve ollama route-policies [--scope-kind <platform|org|project>] [--scope-id <id>] [--json]"
51318
+ remove: {
51319
+ description: "Remove a private endpoint and its K8s Service",
51320
+ usage: "eve endpoint remove <name> --org <org_id>",
51321
+ examples: ["eve endpoint remove lmstudio --org org_xxx"]
51346
51322
  },
51347
- "route-policy": {
51348
- description: "Set or remove a route policy",
51349
- usage: "eve ollama route-policy <set|rm> [options]",
51350
- options: [
51351
- "set: --scope-kind <kind> [--scope-id <id>] --preferred-target-id <target-id> [--fallback-to-alias-target true|false]",
51352
- "rm: --scope-kind <kind> [--scope-id <id>]"
51353
- ]
51323
+ health: {
51324
+ description: "Run a health check against a private endpoint",
51325
+ usage: "eve endpoint health <name> --org <org_id>",
51326
+ examples: ["eve endpoint health lmstudio --org org_xxx"]
51354
51327
  },
51355
- managed: {
51356
- description: "List, publish, and unpublish platform-managed catalog models",
51357
- usage: "eve ollama managed <list|publish|unpublish> [options]",
51358
- options: [
51359
- "list: [--json]",
51360
- "publish: --canonical <id> --provider <name> --slug <provider_model_slug> --target-id <id> [--requires-warm-start true|false] [--enabled true|false] [--json]",
51361
- "unpublish: --canonical <id> [--json]"
51362
- ]
51328
+ diagnose: {
51329
+ description: "Run diagnostic checks on a private endpoint",
51330
+ usage: "eve endpoint diagnose <name> --org <org_id>",
51331
+ examples: ["eve endpoint diagnose lmstudio --org org_xxx"]
51363
51332
  }
51364
51333
  },
51365
51334
  examples: [
51366
- "eve ollama target add --name local --base-url http://localhost:11434 --scope-kind platform --target-type external_ollama",
51367
- "eve ollama target wake itgt_xxx --wait true # Block until GPU target is healthy (~65s)",
51368
- "eve ollama target wake itgt_xxx --wait true --timeout-ms 180000 # Wait up to 3 minutes",
51369
- "eve ollama target wake itgt_xxx # Fire-and-forget (returns retry_after_seconds)",
51370
- "eve ollama target pull itgt_xxx --model-id imod_xxx # Pull model onto remote target",
51371
- "eve ollama target models itgt_xxx # List models on remote target",
51372
- "eve ollama model add --canonical gpt-oss:120b --provider ollama --slug gpt-oss:120b",
51373
- "eve ollama install add --target-id itgt_xxx --model-id imod_xxx --min-target-capacity 1",
51374
- "eve ollama assignments --scope-kind platform",
51375
- "eve ollama managed list",
51376
- "eve ollama managed publish --canonical deepseek-r1 --provider ollama --slug deepseek-r1:latest --target-id itgt_xxx",
51377
- "eve ollama managed unpublish --canonical deepseek-r1"
51335
+ "eve endpoint add --name lmstudio --tailscale-hostname mac-mini.tail12345.ts.net --port 1234 --org org_xxx",
51336
+ "eve endpoint list --org org_xxx",
51337
+ "eve endpoint show lmstudio --org org_xxx --verbose",
51338
+ "eve endpoint diagnose lmstudio --org org_xxx"
51378
51339
  ]
51379
51340
  },
51380
51341
  migrate: {
@@ -51482,7 +51443,7 @@ function showMainHelp() {
51482
51443
  console.log(" auth Authentication (login, logout, status)");
51483
51444
  console.log(" webhooks Manage outbound webhook subscriptions");
51484
51445
  console.log(" analytics Org analytics (jobs, pipelines, env health)");
51485
- console.log(" ollama Manage inference targets, aliases, and model routes");
51446
+ console.log(" endpoint Manage private endpoints (Tailscale-connected services)");
51486
51447
  console.log(" access Access control: permissions, roles, bindings, policy-as-code sync");
51487
51448
  console.log(" user Look up user profiles and memberships");
51488
51449
  console.log(" admin User and platform admin operations");
@@ -52546,7 +52507,7 @@ function buildQuery2(params) {
52546
52507
  }
52547
52508
 
52548
52509
  // src/commands/job.ts
52549
- var import_child_process2 = require("child_process");
52510
+ var import_child_process4 = require("child_process");
52550
52511
  var import_fs = require("fs");
52551
52512
  var import_path = require("path");
52552
52513
 
@@ -56674,6 +56635,8 @@ var configSchema = external_exports.object({
56674
56635
  EVE_SLACK_CLIENT_ID: external_exports.string().optional(),
56675
56636
  EVE_SLACK_CLIENT_SECRET: external_exports.string().optional(),
56676
56637
  EVE_INTERNAL_API_KEY: external_exports.string().optional(),
56638
+ EVE_GATEWAY_URL: external_exports.string().url().optional(),
56639
+ // Internal gateway URL for outbound delivery (e.g., http://eve-gateway.eve.svc.cluster.local:4820)
56677
56640
  EVE_ORG_FS_LINK_TOKEN_SECRET: external_exports.string().optional(),
56678
56641
  EVE_ORG_FS_LINK_TOKEN_TTL_SECONDS: external_exports.coerce.number().int().min(60).default(900),
56679
56642
  EVE_SECRETS_MASTER_KEY: external_exports.string().optional(),
@@ -57708,7 +57671,9 @@ var JobHintsSchema = external_exports.object({
57708
57671
  thread_id: external_exports.string(),
57709
57672
  dispatch_mode: external_exports.string().optional()
57710
57673
  }).optional(),
57711
- gates: external_exports.array(external_exports.string()).optional()
57674
+ gates: external_exports.array(external_exports.string()).optional(),
57675
+ // App API awareness: names of project APIs the agent should have access to
57676
+ app_apis: external_exports.array(external_exports.string()).optional()
57712
57677
  }).passthrough();
57713
57678
  var JobTargetSchema = external_exports.object({
57714
57679
  agent_slug: external_exports.string().optional(),
@@ -58872,10 +58837,17 @@ var WorkflowInvokeRequestSchema = external_exports.object({
58872
58837
  input: external_exports.record(external_exports.unknown()).optional()
58873
58838
  // User's workflow input payload
58874
58839
  }).optional();
58840
+ var WorkflowStepJobSchema = external_exports.object({
58841
+ job_id: external_exports.string(),
58842
+ step_name: external_exports.string(),
58843
+ depends_on: external_exports.array(external_exports.string()).optional()
58844
+ });
58875
58845
  var WorkflowInvokeResponseSchema = external_exports.object({
58876
58846
  job_id: external_exports.string(),
58877
- status: external_exports.string()
58878
- // Job phase
58847
+ status: external_exports.string(),
58848
+ // Job phase (root job)
58849
+ step_jobs: external_exports.array(WorkflowStepJobSchema).optional()
58850
+ // Child step jobs in the DAG
58879
58851
  });
58880
58852
  var WorkflowInvokeResultSchema = external_exports.object({
58881
58853
  job_id: external_exports.string(),
@@ -59034,6 +59006,7 @@ var EventListResponseSchema = external_exports.object({
59034
59006
  var AgentSummarySchema = external_exports.object({
59035
59007
  id: external_exports.string(),
59036
59008
  slug: external_exports.string().nullable().optional(),
59009
+ alias: external_exports.string().nullable().optional(),
59037
59010
  name: external_exports.string().nullable().optional(),
59038
59011
  description: external_exports.string().nullable().optional(),
59039
59012
  role: external_exports.string().nullable().optional(),
@@ -59057,6 +59030,7 @@ var OrgAgentDirectoryItemSchema = external_exports.object({
59057
59030
  project_name: external_exports.string(),
59058
59031
  agent_id: external_exports.string(),
59059
59032
  agent_slug: external_exports.string().nullable(),
59033
+ agent_alias: external_exports.string().nullable().optional(),
59060
59034
  agent_name: external_exports.string().nullable().optional(),
59061
59035
  agent_description: external_exports.string().nullable().optional(),
59062
59036
  role: external_exports.string().nullable().optional(),
@@ -59117,6 +59091,7 @@ var VALID_TOOLCHAINS = ["python", "media", "rust", "java", "kotlin"];
59117
59091
  var AgentEntrySchema = external_exports.object({
59118
59092
  name: external_exports.string().optional(),
59119
59093
  slug: AgentSlugSchema.optional(),
59094
+ alias: AgentSlugSchema.optional(),
59120
59095
  description: external_exports.string().optional(),
59121
59096
  role: external_exports.string().optional(),
59122
59097
  skill: external_exports.string().min(1),
@@ -59135,11 +59110,20 @@ var AgentsYamlSchema = external_exports.object({
59135
59110
  }).passthrough();
59136
59111
  var TeamDispatchSchema = external_exports.object({
59137
59112
  mode: external_exports.enum(["fanout", "council", "relay"]).optional(),
59113
+ staged: external_exports.boolean().optional(),
59138
59114
  max_parallel: external_exports.number().int().min(1).optional(),
59139
59115
  merge_strategy: external_exports.string().optional(),
59140
59116
  lead_timeout: external_exports.number().int().positive().optional(),
59141
59117
  member_timeout: external_exports.number().int().positive().optional()
59142
- }).passthrough();
59118
+ }).passthrough().superRefine((dispatch, ctx) => {
59119
+ if (dispatch.staged === true && dispatch.mode !== "council") {
59120
+ ctx.addIssue({
59121
+ code: "custom",
59122
+ path: ["staged"],
59123
+ message: "dispatch.staged=true is only valid when dispatch.mode is 'council'"
59124
+ });
59125
+ }
59126
+ });
59143
59127
  var TeamEntrySchema = external_exports.object({
59144
59128
  lead: external_exports.string().min(1),
59145
59129
  members: external_exports.array(external_exports.string()).optional(),
@@ -59173,6 +59157,7 @@ var AgentsSyncRequestSchema = external_exports.object({
59173
59157
  agents_yaml: external_exports.string().min(1, "agents yaml cannot be empty"),
59174
59158
  teams_yaml: external_exports.string().min(1, "teams yaml cannot be empty"),
59175
59159
  chat_yaml: external_exports.string().min(1, "chat yaml cannot be empty"),
59160
+ x_eve_yaml: external_exports.string().optional(),
59176
59161
  pack_refs: external_exports.array(PackRefSchema).optional(),
59177
59162
  git_sha: external_exports.string().optional(),
59178
59163
  branch: external_exports.string().optional(),
@@ -59255,6 +59240,9 @@ var ThreadMessageResponseSchema = external_exports.object({
59255
59240
  actor_id: external_exports.string().nullable().optional(),
59256
59241
  body: external_exports.string(),
59257
59242
  job_id: external_exports.string().nullable().optional(),
59243
+ delivery_status: external_exports.string().nullable().optional(),
59244
+ delivery_error: external_exports.string().nullable().optional(),
59245
+ delivered_at: external_exports.string().nullable().optional(),
59258
59246
  created_at: external_exports.string()
59259
59247
  });
59260
59248
  var ThreadMessageListResponseSchema = external_exports.object({
@@ -59370,6 +59358,15 @@ var ChatDispatchRequestSchema = ChatRouteRequestSchema.extend({
59370
59358
  var ChatDispatchResponseSchema = external_exports.object({
59371
59359
  job_ids: external_exports.array(external_exports.string())
59372
59360
  });
59361
+ var ChatDeliverRequestSchema = external_exports.object({
59362
+ job_id: external_exports.string().min(1).optional(),
59363
+ // optional for progress messages
59364
+ thread_id: external_exports.string().min(1),
59365
+ text: external_exports.string().min(1),
59366
+ agent_id: external_exports.string().optional(),
59367
+ progress: external_exports.boolean().optional()
59368
+ // marks this as a progress update (not final result)
59369
+ });
59373
59370
 
59374
59371
  // ../shared/dist/schemas/integrations.js
59375
59372
  var IntegrationResponseSchema = external_exports.object({
@@ -60339,201 +60336,105 @@ var BatchValidateResponseSchema = external_exports.object({
60339
60336
  errors: external_exports.array(BatchValidationErrorSchema)
60340
60337
  });
60341
60338
 
60342
- // ../shared/dist/schemas/managed-models.js
60343
- var ManagedModelCapabilitySchema = external_exports.object({
60344
- streaming: external_exports.boolean(),
60345
- tool_calling: external_exports.boolean(),
60346
- reasoning: external_exports.boolean()
60347
- });
60348
- var ManagedModelConfigV1Schema = external_exports.object({
60349
- display_name: external_exports.string().min(1),
60350
- inference_provider: external_exports.string().min(1),
60351
- harness: external_exports.string().optional(),
60352
- api_model_id: external_exports.string().min(1),
60353
- base_url: external_exports.string().min(1),
60354
- auth_header: external_exports.string().min(1),
60355
- auth_scheme: external_exports.string(),
60356
- secret_ref: external_exports.string().min(1),
60357
- extra_headers: external_exports.record(external_exports.string()),
60358
- capabilities: ManagedModelCapabilitySchema
60359
- }).passthrough();
60360
- var ManagedModelConfigV2Schema = external_exports.object({
60361
- display_name: external_exports.string().min(1),
60362
- provider: external_exports.string().min(1),
60363
- api_model_id: external_exports.string().min(1),
60364
- capabilities: ManagedModelCapabilitySchema,
60365
- harness: external_exports.string().optional(),
60366
- base_url: external_exports.string().optional(),
60367
- secret_ref: external_exports.string().optional(),
60368
- extra_headers: external_exports.record(external_exports.string()).optional()
60369
- }).passthrough();
60370
- var ManagedModelConfigSchema = external_exports.union([
60371
- ManagedModelConfigV1Schema,
60372
- ManagedModelConfigV2Schema
60373
- ]);
60374
- var ManagedModelRegistrySchema = external_exports.record(ManagedModelConfigSchema);
60375
-
60376
- // ../shared/dist/schemas/inference.js
60377
- var InferenceScopeKindSchema = external_exports.enum(["platform", "org", "project"]);
60378
- var InferenceTargetTypeSchema = external_exports.enum(["ollama_pool", "external_ollama", "openai_compat"]);
60379
- var InferenceTransportProfileSchema = external_exports.enum(["ollama_api", "openai_compat"]);
60380
- var InferenceTargetStatusSchema = external_exports.enum(["unknown", "healthy", "unhealthy", "waking", "draining", "disabled"]);
60381
- var InferenceTargetSchema = external_exports.object({
60339
+ // ../shared/dist/schemas/chat-file.js
60340
+ var ChatFileSchema = external_exports.object({
60341
+ /** Provider file ID */
60382
60342
  id: external_exports.string(),
60383
- scope_kind: InferenceScopeKindSchema,
60384
- scope_id: external_exports.string().nullable(),
60343
+ /** Original filename */
60385
60344
  name: external_exports.string(),
60386
- target_type: InferenceTargetTypeSchema,
60387
- transport_profile: InferenceTransportProfileSchema,
60388
- base_url: external_exports.string(),
60389
- health_probe_url: external_exports.string().nullable(),
60390
- capacity: external_exports.number().int(),
60391
- max_concurrent_inflight: external_exports.number().int(),
60392
- status: InferenceTargetStatusSchema,
60393
- transport_metadata: external_exports.record(external_exports.unknown()),
60394
- created_by: external_exports.string().nullable(),
60395
- updated_by: external_exports.string().nullable(),
60396
- created_at: external_exports.string(),
60397
- updated_at: external_exports.string()
60398
- });
60399
- var InferenceModelSchema = external_exports.object({
60400
- id: external_exports.string(),
60401
- canonical_model_id: external_exports.string(),
60402
- provider: external_exports.string(),
60403
- provider_model_slug: external_exports.string(),
60404
- max_context: external_exports.number().int().nullable(),
60405
- supports_json_schema: external_exports.boolean(),
60406
- metadata: external_exports.record(external_exports.unknown()),
60407
- created_at: external_exports.string(),
60408
- updated_at: external_exports.string()
60345
+ /** MIME type */
60346
+ mimetype: external_exports.string().optional(),
60347
+ /** URL — provider URL initially, then eve-storage:// after resolution */
60348
+ url: external_exports.string().optional(),
60349
+ /** File size in bytes */
60350
+ size: external_exports.number().optional(),
60351
+ /** Set after resolveFiles: original provider URL */
60352
+ source_url: external_exports.string().optional(),
60353
+ /** Set after resolveFiles: provider name */
60354
+ source_provider: external_exports.string().optional(),
60355
+ /** Set after resolveFiles: eve-storage key */
60356
+ storage_key: external_exports.string().optional(),
60357
+ /** Set when file resolution failed — reason code (e.g. 'auth_failed', 'content_mismatch') */
60358
+ error: external_exports.string().optional()
60409
60359
  });
60410
- var InferenceAliasSchema = external_exports.object({
60411
- id: external_exports.string(),
60412
- scope_kind: InferenceScopeKindSchema,
60413
- scope_id: external_exports.string().nullable(),
60414
- alias: external_exports.string(),
60415
- target_id: external_exports.string(),
60416
- model_id: external_exports.string(),
60417
- pin_model_id: external_exports.string().nullable(),
60418
- pinned_at: external_exports.string().nullable(),
60419
- created_by: external_exports.string().nullable(),
60420
- updated_by: external_exports.string().nullable(),
60421
- created_at: external_exports.string(),
60422
- updated_at: external_exports.string()
60360
+ var AttachmentIndexEntrySchema = external_exports.object({
60361
+ /** Provider attachment ID, when available */
60362
+ id: external_exports.string().optional(),
60363
+ /** Original filename */
60364
+ name: external_exports.string(),
60365
+ /** Relative path from workspace root */
60366
+ path: external_exports.string().nullable(),
60367
+ /** MIME type (e.g. application/pdf) */
60368
+ mimetype: external_exports.string().optional(),
60369
+ /** File size in bytes */
60370
+ size: external_exports.number().optional(),
60371
+ /** Original provider URL */
60372
+ source_url: external_exports.string().optional(),
60373
+ /** Provider that supplied this file */
60374
+ source_provider: external_exports.string().optional(),
60375
+ /** Storage key for re-download/debug */
60376
+ storage_key: external_exports.string().optional(),
60377
+ /** Error code if file could not be downloaded */
60378
+ error: external_exports.string().optional()
60423
60379
  });
60424
- var InferenceInstallSchema = external_exports.object({
60425
- id: external_exports.string(),
60426
- target_id: external_exports.string(),
60427
- model_id: external_exports.string(),
60428
- requires_warm_start: external_exports.boolean(),
60429
- min_target_capacity: external_exports.number().int(),
60430
- allowed_scopes: external_exports.record(external_exports.unknown()),
60431
- route_hints: external_exports.record(external_exports.unknown()),
60432
- created_at: external_exports.string(),
60433
- updated_at: external_exports.string()
60380
+ var AttachmentIndexSchema = external_exports.object({
60381
+ files: external_exports.array(AttachmentIndexEntrySchema)
60382
+ });
60383
+ var MAX_CHAT_FILE_SIZE = 50 * 1024 * 1024;
60384
+ var MAX_CHAT_TOTAL_SIZE = 100 * 1024 * 1024;
60385
+
60386
+ // ../shared/dist/schemas/private-endpoint.js
60387
+ var PrivateEndpointProviderSchema = external_exports.enum(["tailscale"]);
60388
+ var PrivateEndpointStatusSchema = external_exports.enum(["pending", "ready", "error"]);
60389
+ var DNS_SAFE_REGEX = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;
60390
+ var CreatePrivateEndpointRequestSchema = external_exports.object({
60391
+ name: external_exports.string().min(1).max(53).regex(DNS_SAFE_REGEX, "Name must be DNS-safe: lowercase alphanumeric and hyphens, cannot start or end with a hyphen"),
60392
+ provider: PrivateEndpointProviderSchema.optional().default("tailscale"),
60393
+ hostname: external_exports.string().min(1, "Tailscale hostname is required"),
60394
+ port: external_exports.number().int().min(1).max(65535),
60395
+ health_path: external_exports.string().nullable().optional().default("/v1/models"),
60396
+ metadata: external_exports.record(external_exports.unknown()).optional()
60434
60397
  });
60435
- var InferenceRoutePolicySchema = external_exports.object({
60398
+ var PrivateEndpointResponseSchema = external_exports.object({
60436
60399
  id: external_exports.string(),
60437
- scope_kind: InferenceScopeKindSchema,
60438
- scope_id: external_exports.string().nullable(),
60439
- preferred_target_id: external_exports.string(),
60440
- fallback_to_alias_target: external_exports.boolean(),
60441
- created_by: external_exports.string().nullable(),
60442
- updated_by: external_exports.string().nullable(),
60400
+ name: external_exports.string(),
60401
+ org_id: external_exports.string(),
60402
+ provider: external_exports.string(),
60403
+ hostname: external_exports.string(),
60404
+ port: external_exports.number(),
60405
+ protocol: external_exports.string(),
60406
+ status: PrivateEndpointStatusSchema,
60407
+ status_msg: external_exports.string().nullable(),
60408
+ k8s_svc_name: external_exports.string(),
60409
+ k8s_namespace: external_exports.string(),
60410
+ k8s_dns: external_exports.string().nullable(),
60411
+ health_path: external_exports.string().nullable(),
60412
+ cluster_url: external_exports.string().nullable(),
60443
60413
  created_at: external_exports.string(),
60444
60414
  updated_at: external_exports.string()
60445
60415
  });
60446
- var InferenceManagedModelSchema = external_exports.object({
60447
- canonical_model_id: external_exports.string(),
60448
- provider: external_exports.string(),
60449
- provider_model_slug: external_exports.string(),
60450
- target_id: external_exports.string(),
60451
- requires_warm_start: external_exports.boolean().default(false),
60452
- enabled: external_exports.boolean().default(true)
60453
- });
60454
- var InferenceManagedModelsSchema = external_exports.record(InferenceManagedModelSchema);
60455
- var UpsertInferenceManagedModelRequestSchema = external_exports.object({
60456
- canonical_model_id: external_exports.string(),
60457
- provider: external_exports.string(),
60458
- provider_model_slug: external_exports.string(),
60459
- target_id: external_exports.string(),
60460
- requires_warm_start: external_exports.boolean().optional().default(false),
60461
- enabled: external_exports.boolean().optional().default(true)
60462
- });
60463
- var InferenceManagedModelResponseSchema = external_exports.object({
60464
- canonical_model_id: external_exports.string(),
60465
- provider: external_exports.string(),
60466
- provider_model_slug: external_exports.string(),
60467
- target_id: external_exports.string(),
60468
- requires_warm_start: external_exports.boolean(),
60469
- enabled: external_exports.boolean()
60470
- });
60471
- var InferenceManagedModelListResponseSchema = external_exports.object({
60472
- data: external_exports.array(InferenceManagedModelResponseSchema)
60416
+ var PrivateEndpointListResponseSchema = external_exports.object({
60417
+ data: external_exports.array(PrivateEndpointResponseSchema),
60418
+ pagination: PaginationSchema
60473
60419
  });
60474
- var InferenceManagedModelUpsertResponseSchema = external_exports.object({
60475
- data: InferenceManagedModelResponseSchema,
60476
- created_install: external_exports.boolean()
60420
+ var PrivateEndpointHealthSchema = external_exports.object({
60421
+ endpoint: PrivateEndpointResponseSchema,
60422
+ health: external_exports.object({
60423
+ checked_at: external_exports.string(),
60424
+ reachable: external_exports.boolean(),
60425
+ http_status: external_exports.number().nullable(),
60426
+ response_time_ms: external_exports.number().nullable(),
60427
+ error: external_exports.string().nullable()
60428
+ })
60477
60429
  });
60478
- var CreateInferenceTargetRequestSchema = external_exports.object({
60479
- scope_kind: InferenceScopeKindSchema,
60480
- scope_id: external_exports.string().optional(),
60481
- name: external_exports.string().min(1),
60482
- target_type: InferenceTargetTypeSchema,
60483
- transport_profile: InferenceTransportProfileSchema.default("ollama_api"),
60484
- base_url: external_exports.string().min(1),
60485
- health_probe_url: external_exports.string().optional(),
60486
- capacity: external_exports.number().int().positive().optional(),
60487
- max_concurrent_inflight: external_exports.number().int().positive().optional(),
60488
- status: InferenceTargetStatusSchema.optional(),
60489
- transport_metadata: external_exports.record(external_exports.unknown()).optional()
60490
- });
60491
- var UpdateInferenceTargetRequestSchema = external_exports.object({
60492
- name: external_exports.string().min(1).optional(),
60493
- target_type: InferenceTargetTypeSchema.optional(),
60494
- transport_profile: InferenceTransportProfileSchema.optional(),
60495
- base_url: external_exports.string().min(1).optional(),
60496
- health_probe_url: external_exports.string().optional(),
60497
- capacity: external_exports.number().int().positive().optional(),
60498
- max_concurrent_inflight: external_exports.number().int().positive().optional(),
60499
- status: InferenceTargetStatusSchema.optional(),
60500
- transport_metadata: external_exports.record(external_exports.unknown()).optional()
60501
- });
60502
- var CreateInferenceModelRequestSchema = external_exports.object({
60503
- canonical_model_id: external_exports.string().min(1),
60504
- provider: external_exports.string().min(1),
60505
- provider_model_slug: external_exports.string().min(1),
60506
- max_context: external_exports.number().int().positive().optional(),
60507
- supports_json_schema: external_exports.boolean().optional(),
60508
- metadata: external_exports.record(external_exports.unknown()).optional()
60430
+ var PrivateEndpointDiagnoseSchema = external_exports.object({
60431
+ endpoint: PrivateEndpointResponseSchema,
60432
+ checks: external_exports.array(external_exports.object({
60433
+ name: external_exports.string(),
60434
+ passed: external_exports.boolean(),
60435
+ detail: external_exports.string().nullable()
60436
+ }))
60509
60437
  });
60510
- var CreateInferenceInstallRequestSchema = external_exports.object({
60511
- requires_warm_start: external_exports.boolean().optional(),
60512
- min_target_capacity: external_exports.number().int().positive().optional(),
60513
- allowed_scopes: external_exports.record(external_exports.unknown()).optional(),
60514
- route_hints: external_exports.record(external_exports.unknown()).optional()
60515
- });
60516
- var UpsertInferenceRoutePolicyRequestSchema = external_exports.object({
60517
- scope_kind: InferenceScopeKindSchema,
60518
- scope_id: external_exports.string().optional(),
60519
- preferred_target_id: external_exports.string().min(1),
60520
- fallback_to_alias_target: external_exports.boolean().optional()
60521
- });
60522
- var UpsertInferenceAliasRequestSchema = external_exports.object({
60523
- scope_kind: InferenceScopeKindSchema,
60524
- scope_id: external_exports.string().optional(),
60525
- alias: external_exports.string().min(1),
60526
- target_id: external_exports.string().min(1),
60527
- model_id: external_exports.string().min(1),
60528
- pin_model_id: external_exports.string().optional()
60529
- });
60530
- var InferenceChatCompletionsRequestSchema = external_exports.object({
60531
- model: external_exports.string().min(1),
60532
- messages: external_exports.array(external_exports.record(external_exports.unknown())).min(1),
60533
- stream: external_exports.boolean().optional(),
60534
- project_id: external_exports.string().optional(),
60535
- org_id: external_exports.string().optional()
60536
- }).passthrough();
60537
60438
 
60538
60439
  // ../shared/dist/observability.js
60539
60440
  var import_async_hooks = require("async_hooks");
@@ -60989,25 +60890,11 @@ for (const provider of PROVIDER_REGISTRY) {
60989
60890
  function getProvider(name) {
60990
60891
  return byName.get(name.trim().toLowerCase());
60991
60892
  }
60992
- function deriveHarnessEnvMap() {
60993
- const map = {};
60994
- for (const provider of PROVIDER_REGISTRY) {
60995
- for (const harness of provider.harnesses.all) {
60996
- if (!map[harness]) {
60997
- map[harness] = { ...provider.harnesses.env_map };
60998
- }
60999
- }
61000
- }
61001
- return map;
61002
- }
61003
60893
 
61004
60894
  // ../shared/dist/pricing/model-normalization.js
61005
60895
  function normalizeModelName(provider, model) {
61006
60896
  let m = model.trim();
61007
- if (m.startsWith("managed/")) {
61008
- m = m.slice("managed/".length);
61009
- }
61010
- if (m.includes("/") && !m.startsWith("managed/")) {
60897
+ if (m.includes("/")) {
61011
60898
  m = m.split("/").slice(1).join("/");
61012
60899
  }
61013
60900
  const providerDef = getProvider(provider);
@@ -62612,13 +62499,8 @@ var DEFAULT_RESOURCE_CLASSES_V1 = {
62612
62499
  }
62613
62500
  };
62614
62501
 
62615
- // ../shared/dist/pricing/managed-models.js
62616
- var HARNESS_ENV_MAP = deriveHarnessEnvMap();
62617
-
62618
62502
  // ../shared/dist/permissions.js
62619
62503
  var ALL_PERMISSIONS = [
62620
- // Inference
62621
- "inference:write",
62622
62504
  // Jobs
62623
62505
  "jobs:read",
62624
62506
  "jobs:write",
@@ -62672,6 +62554,9 @@ var ALL_PERMISSIONS = [
62672
62554
  "events:write",
62673
62555
  // Chat
62674
62556
  "chat:write",
62557
+ // Private Endpoints
62558
+ "endpoints:read",
62559
+ "endpoints:write",
62675
62560
  // System
62676
62561
  "system:read",
62677
62562
  "system:admin"
@@ -62761,6 +62646,16 @@ function normalizeLogLine(line) {
62761
62646
  return { type: kind || "log", raw: line };
62762
62647
  }
62763
62648
 
62649
+ // ../shared/dist/invoke/git-utils.js
62650
+ var import_child_process2 = require("child_process");
62651
+ var import_util5 = require("util");
62652
+ var execFileAsync2 = (0, import_util5.promisify)(import_child_process2.execFile);
62653
+
62654
+ // ../shared/dist/invoke/workspace-hooks.js
62655
+ var import_child_process3 = require("child_process");
62656
+ var import_util6 = require("util");
62657
+ var execFileAsync3 = (0, import_util6.promisify)(import_child_process3.execFile);
62658
+
62764
62659
  // src/commands/job.ts
62765
62660
  async function handleJob(subcommand, positionals, flags, context2) {
62766
62661
  const json = Boolean(flags.json);
@@ -63017,87 +62912,12 @@ async function handleCreate(flags, context2, json) {
63017
62912
  }
63018
62913
  if (withApis) {
63019
62914
  const apiNames = withApis.split(",").map((n) => n.trim()).filter(Boolean);
63020
- const apiListResponse = await requestJson(
63021
- context2,
63022
- `/projects/${resolvedProjectId}/apis`
63023
- );
63024
- const availableApis = new Map(
63025
- (apiListResponse.data || []).map((a) => [a.name, { type: a.type, base_url: a.base_url }])
63026
- );
63027
- const missing2 = apiNames.filter((name) => !availableApis.has(name));
63028
- if (missing2.length > 0) {
63029
- throw new Error(
63030
- `APIs not found in project: ${missing2.join(", ")}
63031
- Available APIs: ${[...availableApis.keys()].join(", ") || "(none)"}`
63032
- );
63033
- }
63034
- const contextArgs = [`--project ${resolvedProjectId}`];
63035
- if (envName) {
63036
- contextArgs.push(`--env ${envName}`);
63037
- }
63038
- const contextSuffix = contextArgs.join(" ");
63039
- const apiLines = apiNames.map((name) => {
63040
- const info = availableApis.get(name);
63041
- const type = info?.type ?? "openapi";
63042
- const baseUrl = info?.base_url || "<base_url>";
63043
- return `- \`${name}\` (${type})
63044
- - Use this runtime-safe Node helper for in-job API calls (no extra tools required).
63045
- \`\`\`bash
63046
- API_URL="${baseUrl}" node - <<'NODE'
63047
- const fs = require("fs");
63048
- const tokenFromJob = process.env.EVE_JOB_TOKEN;
63049
- const tokenFromCreds = () => {
63050
- const credsPath = \`\${process.env.HOME}/.eve/credentials.json\`;
63051
- if (!fs.existsSync(credsPath)) {
63052
- return undefined;
63053
- }
63054
- const creds = JSON.parse(fs.readFileSync(credsPath, "utf8"));
63055
- const apiKey = \`\${(process.env.EVE_API_URL || "").replace(/\\/+$/, "")}\`;
63056
- return creds.tokens?.[apiKey]?.access_token;
63057
- };
63058
- const token = tokenFromJob ?? tokenFromCreds();
63059
- const apiUrl = process.env.API_URL;
63060
- if (!apiUrl) {
63061
- throw new Error("Set API_URL before running the script.");
63062
- }
63063
- const method = process.env.EVE_APP_API_METHOD ?? "GET";
63064
- const path = process.env.EVE_APP_API_PATH ?? "/";
63065
- const bodyArg = process.env.EVE_APP_API_BODY;
63066
- if (!token) {
63067
- throw new Error("Missing token. Set EVE_JOB_TOKEN or keep ~/.eve/credentials.json for external shells.");
63068
- }
63069
- const options = {
63070
- method: method.toUpperCase(),
63071
- headers: {
63072
- Authorization: \`Bearer \${token}\`,
63073
- "Content-Type": "application/json",
63074
- },
63075
- };
63076
- if (bodyArg) {
63077
- options.body = bodyArg;
63078
- }
63079
- (async () => {
63080
- const response = await fetch(new URL(path, apiUrl).toString(), options);
63081
- const text = await response.text();
63082
- console.log(text);
63083
- if (!response.ok) {
63084
- process.exitCode = 1;
62915
+ if (apiNames.length > 0) {
62916
+ if (!body.hints || typeof body.hints !== "object") {
62917
+ body.hints = {};
63085
62918
  }
63086
- })().catch((error) => {
63087
- console.error(error);
63088
- process.exit(1);
63089
- });
63090
- NODE
63091
- # Example:
63092
- # API_URL="${baseUrl}" EVE_APP_API_METHOD=GET EVE_APP_API_PATH=/api/auth-config node - <<'NODE'
63093
- \`\`\`
63094
- - Discover endpoints with \`eve api spec ${name} ${contextSuffix}\` in your own shell (outside the job runtime).`;
63095
- });
63096
- body.description = body.description + `
63097
-
63098
- ---
63099
- **Available App APIs:**
63100
- ${apiLines.join("\n")}`;
62919
+ body.hints.app_apis = apiNames;
62920
+ }
63101
62921
  }
63102
62922
  const response = await requestJson(context2, `/projects/${resolvedProjectId}/jobs`, {
63103
62923
  method: "POST",
@@ -65370,7 +65190,7 @@ async function handleRunnerLogs(positionals, flags, context2) {
65370
65190
  console.log(`No pod_name in runtime_meta, using label selector: job-id=${jobId}`);
65371
65191
  kubectlArgs = ["-n", "eve", "logs", "-f", "-l", `job-id=${jobId}`];
65372
65192
  }
65373
- const kubectl = (0, import_child_process2.spawn)("kubectl", kubectlArgs, {
65193
+ const kubectl = (0, import_child_process4.spawn)("kubectl", kubectlArgs, {
65374
65194
  stdio: "inherit"
65375
65195
  });
65376
65196
  return new Promise((resolve8, reject) => {
@@ -74745,27 +74565,27 @@ async function handleUsers(flags, context2, json) {
74745
74565
  role: col("role", "Role"),
74746
74566
  created: col("created", "Created")
74747
74567
  };
74748
- const pad3 = (s, n) => s + " ".repeat(Math.max(0, n - s.length));
74568
+ const pad2 = (s, n) => s + " ".repeat(Math.max(0, n - s.length));
74749
74569
  const header = [
74750
- pad3("Email", w.email),
74751
- pad3("Name", w.name),
74752
- pad3("Admin", w.admin),
74753
- pad3("Scope", w.scope),
74754
- pad3("Target", w.target),
74755
- pad3("Role", w.role),
74756
- pad3("Created", w.created)
74570
+ pad2("Email", w.email),
74571
+ pad2("Name", w.name),
74572
+ pad2("Admin", w.admin),
74573
+ pad2("Scope", w.scope),
74574
+ pad2("Target", w.target),
74575
+ pad2("Role", w.role),
74576
+ pad2("Created", w.created)
74757
74577
  ].join(" ");
74758
74578
  console.log(header);
74759
74579
  console.log("-".repeat(header.length));
74760
74580
  for (const row of rows) {
74761
74581
  console.log([
74762
- pad3(row.email, w.email),
74763
- pad3(row.name, w.name),
74764
- pad3(row.admin, w.admin),
74765
- pad3(row.scope, w.scope),
74766
- pad3(row.target, w.target),
74767
- pad3(row.role, w.role),
74768
- pad3(row.created, w.created)
74582
+ pad2(row.email, w.email),
74583
+ pad2(row.name, w.name),
74584
+ pad2(row.admin, w.admin),
74585
+ pad2(row.scope, w.scope),
74586
+ pad2(row.target, w.target),
74587
+ pad2(row.role, w.role),
74588
+ pad2(row.created, w.created)
74769
74589
  ].join(" "));
74770
74590
  }
74771
74591
  console.log("");
@@ -74958,7 +74778,7 @@ async function resolvePacksAndMerge(repoRoot, manifest, projectSlug) {
74958
74778
  agents_count: Object.keys(extractInnerMap(mergedAgents, "agents")).length,
74959
74779
  teams_count: Object.keys(extractInnerMap(mergedTeams, "teams")).length,
74960
74780
  routes_count: (mergedChat.routes ?? []).length,
74961
- profiles_count: Object.keys(mergedXEve?.profiles ?? {}).length,
74781
+ profiles_count: Object.keys(mergedXEve?.agents?.profiles ?? {}).length,
74962
74782
  agents_hash: simpleHash(JSON.stringify(mergedAgents)),
74963
74783
  teams_hash: simpleHash(JSON.stringify(mergedTeams)),
74964
74784
  chat_hash: simpleHash(JSON.stringify(mergedChat))
@@ -74974,6 +74794,7 @@ async function resolvePacksAndMerge(repoRoot, manifest, projectSlug) {
74974
74794
  agentsYaml: (0, import_yaml3.stringify)(mergedAgents),
74975
74795
  teamsYaml: (0, import_yaml3.stringify)(mergedTeams),
74976
74796
  chatYaml: (0, import_yaml3.stringify)(mergedChat),
74797
+ xEveYaml: Object.keys(mergedXEve).length > 0 ? (0, import_yaml3.stringify)(mergedXEve) : null,
74977
74798
  workflowsYaml: mergedWorkflows ? (0, import_yaml3.stringify)({
74978
74799
  workflows: mergedWorkflows,
74979
74800
  ...Object.keys(mergedXEve).length > 0 ? { x_eve: mergedXEve } : {}
@@ -75135,11 +74956,13 @@ async function handleAgents(subcommand, positionals, flags, context2) {
75135
74956
  let agentsYaml;
75136
74957
  let teamsYaml;
75137
74958
  let chatYaml;
74959
+ let xEveYaml;
75138
74960
  let packRefs;
75139
74961
  if (packResult) {
75140
74962
  agentsYaml = packResult.agentsYaml;
75141
74963
  teamsYaml = packResult.teamsYaml;
75142
74964
  chatYaml = packResult.chatYaml;
74965
+ xEveYaml = packResult.xEveYaml ?? void 0;
75143
74966
  packRefs = packResult.packRefs;
75144
74967
  if (packResult.workflowsYaml) {
75145
74968
  await requestJson(
@@ -75180,6 +75003,7 @@ async function handleAgents(subcommand, positionals, flags, context2) {
75180
75003
  agents_yaml: agentsYaml,
75181
75004
  teams_yaml: teamsYaml,
75182
75005
  chat_yaml: chatYaml,
75006
+ ...xEveYaml ? { x_eve_yaml: xEveYaml } : {},
75183
75007
  git_sha: gitSha,
75184
75008
  branch,
75185
75009
  git_ref: gitRef,
@@ -76587,7 +76411,8 @@ async function handleThread(subcommand, positionals, flags, context2) {
76587
76411
  const dir = msg.direction === "outbound" ? "\u2192" : "\u2190";
76588
76412
  const time = new Date(msg.created_at).toLocaleTimeString();
76589
76413
  const jobRef = msg.job_id ? ` [job:${msg.job_id}]` : "";
76590
- console.log(` ${dir} ${time} ${actor}${jobRef}`);
76414
+ const delivery = msg.delivery_status === "delivered" ? " \u2713 delivered" : msg.delivery_status === "failed" ? ` \u2717 ${msg.delivery_error ?? "delivery failed"}` : msg.delivery_status === "pending" ? " \u23F3 pending" : "";
76415
+ console.log(` ${dir} ${time} ${actor}${jobRef}${delivery}`);
76591
76416
  try {
76592
76417
  const parsed = JSON.parse(msg.body);
76593
76418
  if (parsed.kind && parsed.body) {
@@ -76659,7 +76484,8 @@ async function handleThread(subcommand, positionals, flags, context2) {
76659
76484
  const dir = msg.direction === "outbound" ? "\u2192" : "\u2190";
76660
76485
  const time = new Date(msg.created_at).toLocaleTimeString();
76661
76486
  const jobRef = msg.job_id ? ` [job:${msg.job_id}]` : "";
76662
- process.stdout.write(`${dir} ${time} ${actor}${jobRef}: `);
76487
+ const delivery = msg.delivery_status === "delivered" ? " \u2713" : msg.delivery_status === "failed" ? " \u2717" : "";
76488
+ process.stdout.write(`${dir} ${time} ${actor}${jobRef}${delivery}: `);
76663
76489
  try {
76664
76490
  const parsed = JSON.parse(msg.body);
76665
76491
  if (parsed.kind && parsed.body) {
@@ -76880,70 +76706,6 @@ function normalizeRemoteSource(source) {
76880
76706
  return source;
76881
76707
  }
76882
76708
 
76883
- // src/commands/models.ts
76884
- async function handleModels(subcommand, positionals, flags, context2) {
76885
- const json = Boolean(flags.json);
76886
- switch (subcommand) {
76887
- case "list":
76888
- case void 0:
76889
- return handleList8(context2, json);
76890
- default:
76891
- throw new Error("Usage: eve models list [--json]");
76892
- }
76893
- }
76894
- async function handleList8(context2, json) {
76895
- const response = await requestJson(context2, "/models");
76896
- if (json) {
76897
- outputJson(response, json);
76898
- return;
76899
- }
76900
- if (response.byok) {
76901
- console.log("BYOK (Bring Your Own Key)");
76902
- console.log("========================");
76903
- console.log(` ${response.byok.description}`);
76904
- console.log("");
76905
- }
76906
- if (response.managed.length === 0) {
76907
- console.log("No managed models available.");
76908
- return;
76909
- }
76910
- console.log("Managed Models (Platform-Hosted)");
76911
- console.log("================================");
76912
- console.log("");
76913
- const specWidth = Math.max(10, ...response.managed.map((m) => m.model_spec.length));
76914
- const nameWidth = Math.max(12, ...response.managed.map((m) => m.display_name.length));
76915
- const providerWidth = Math.max(8, ...response.managed.map((m) => m.inference_provider.length));
76916
- const header = [
76917
- padRight9("Model Spec", specWidth),
76918
- padRight9("Display Name", nameWidth),
76919
- padRight9("Provider", providerWidth),
76920
- "Capabilities"
76921
- ].join(" ");
76922
- console.log(header);
76923
- console.log("-".repeat(header.length));
76924
- for (const model of response.managed) {
76925
- const caps = [];
76926
- if (model.capabilities.streaming) caps.push("stream");
76927
- if (model.capabilities.tool_calling) caps.push("tools");
76928
- if (model.capabilities.reasoning) caps.push("reason");
76929
- const row = [
76930
- padRight9(model.model_spec, specWidth),
76931
- padRight9(model.display_name, nameWidth),
76932
- padRight9(model.inference_provider, providerWidth),
76933
- caps.join(", ")
76934
- ].join(" ");
76935
- console.log(row);
76936
- }
76937
- console.log("");
76938
- console.log(`Total: ${response.managed.length} managed model(s)`);
76939
- console.log("");
76940
- console.log('Usage: Set harness_options.model to the model spec (e.g. "managed/deepseek-r1")');
76941
- }
76942
- function padRight9(str, width) {
76943
- if (str.length >= width) return str;
76944
- return str + " ".repeat(width - str.length);
76945
- }
76946
-
76947
76709
  // src/commands/access.ts
76948
76710
  var import_node_fs16 = require("node:fs");
76949
76711
  var import_node_path16 = require("node:path");
@@ -79694,539 +79456,6 @@ async function handleAnalytics(subcommand, _positionals, flags, context2) {
79694
79456
  }
79695
79457
  }
79696
79458
 
79697
- // src/commands/ollama.ts
79698
- function asString(flags, key) {
79699
- const value = flags[key];
79700
- return typeof value === "string" ? value : void 0;
79701
- }
79702
- function requireString(flags, key) {
79703
- const value = asString(flags, key);
79704
- if (!value) throw new Error(`Missing required flag --${key}`);
79705
- return value;
79706
- }
79707
- function asBoolean(flags, key) {
79708
- const value = asString(flags, key);
79709
- if (value === void 0) return void 0;
79710
- return value === "true" || value === "1";
79711
- }
79712
- function normalizeManagedModelRows(payload) {
79713
- return Array.isArray(payload) ? payload : payload.data;
79714
- }
79715
- function looksLikeGatewayPath(baseUrl) {
79716
- try {
79717
- const parsed = new URL(baseUrl);
79718
- const path8 = parsed.pathname.toLowerCase();
79719
- return path8.includes("/inference/v1") || path8.endsWith("/v1");
79720
- } catch {
79721
- return false;
79722
- }
79723
- }
79724
- function printTable(headers, rows) {
79725
- const widths = headers.map((header, idx) => Math.max(header.length, ...rows.map((row) => row[idx]?.length ?? 0)));
79726
- const line = `+${widths.map((w) => "-".repeat(w + 2)).join("+")}+`;
79727
- console.log(line);
79728
- console.log(formatRow3(headers, widths));
79729
- console.log(line);
79730
- for (const row of rows) {
79731
- console.log(formatRow3(row, widths));
79732
- }
79733
- console.log(line);
79734
- }
79735
- function formatRow3(columns, widths) {
79736
- const padded = columns.map((value, idx) => ` ${pad2(value, widths[idx])} `);
79737
- return `|${padded.join("|")}|`;
79738
- }
79739
- function pad2(value, width) {
79740
- return value.length >= width ? value : `${value}${" ".repeat(width - value.length)}`;
79741
- }
79742
- async function handleOllama(subcommand, positionals, flags, context2) {
79743
- const json = Boolean(flags.json);
79744
- switch (subcommand) {
79745
- case "targets": {
79746
- const scopeKind = asString(flags, "scope-kind");
79747
- const scopeId = asString(flags, "scope-id");
79748
- const query = new URLSearchParams();
79749
- if (scopeKind) query.set("scope_kind", scopeKind);
79750
- if (scopeId) query.set("scope_id", scopeId);
79751
- const suffix = query.toString() ? `?${query.toString()}` : "";
79752
- const targets = await requestJson(context2, `/inference/targets${suffix}`);
79753
- if (json) {
79754
- outputJson(targets, json);
79755
- return;
79756
- }
79757
- if (targets.length === 0) {
79758
- console.log("No inference targets found.");
79759
- return;
79760
- }
79761
- printTable(
79762
- ["ID", "Name", "Scope", "Type", "Transport", "Status", "Base URL"],
79763
- targets.map((item) => [
79764
- item.id,
79765
- item.name,
79766
- item.scope_id ? `${item.scope_kind}:${item.scope_id}` : item.scope_kind,
79767
- item.target_type,
79768
- item.transport_profile,
79769
- item.status,
79770
- item.base_url
79771
- ])
79772
- );
79773
- return;
79774
- }
79775
- case "target": {
79776
- const action = positionals[0];
79777
- if (action === "add") {
79778
- const body = {
79779
- scope_kind: asString(flags, "scope-kind") ?? "platform",
79780
- name: requireString(flags, "name"),
79781
- target_type: asString(flags, "target-type") ?? "external_ollama",
79782
- transport_profile: asString(flags, "transport-profile") ?? "ollama_api",
79783
- base_url: requireString(flags, "base-url")
79784
- };
79785
- const scopeId = asString(flags, "scope-id");
79786
- if (scopeId) body.scope_id = scopeId;
79787
- const apiKeyRef = asString(flags, "api-key-ref");
79788
- if (apiKeyRef) {
79789
- body.transport_metadata = {
79790
- api_key_ref: apiKeyRef,
79791
- auth_header: asString(flags, "auth-header") ?? "Authorization",
79792
- auth_scheme: asString(flags, "auth-scheme") ?? "Bearer"
79793
- };
79794
- }
79795
- const created = await requestJson(context2, "/inference/targets", {
79796
- method: "POST",
79797
- body
79798
- });
79799
- outputJson(created, json);
79800
- if (!json) console.log(`Created target ${created.id}`);
79801
- return;
79802
- }
79803
- if (action === "rm") {
79804
- const targetId = positionals[1];
79805
- if (!targetId) throw new Error("Usage: eve ollama target rm <target-id>");
79806
- await requestJson(context2, `/inference/targets/${targetId}`, {
79807
- method: "DELETE"
79808
- });
79809
- if (!json) console.log(`Deleted target ${targetId}`);
79810
- return;
79811
- }
79812
- if (action === "test") {
79813
- const targetId = positionals[1];
79814
- if (!targetId) throw new Error("Usage: eve ollama target test <target-id>");
79815
- const result = await requestJson(context2, `/inference/targets/${targetId}/test`, {
79816
- method: "POST"
79817
- });
79818
- outputJson(result, json);
79819
- if (!json) console.log("Target test completed");
79820
- return;
79821
- }
79822
- if (action === "wake") {
79823
- const targetId = positionals[1];
79824
- if (!targetId) throw new Error("Usage: eve ollama target wake <target-id> [--wait=true] [--timeout-ms <ms>]");
79825
- const query = new URLSearchParams();
79826
- const wait = asString(flags, "wait");
79827
- const timeoutMs = asString(flags, "timeout-ms");
79828
- if (wait === "true" || wait === "1") query.set("wait", "true");
79829
- if (timeoutMs) query.set("timeout_ms", timeoutMs);
79830
- const suffix = query.toString() ? `?${query.toString()}` : "";
79831
- const result = await requestJson(context2, `/inference/targets/${targetId}/wake${suffix}`, {
79832
- method: "POST"
79833
- });
79834
- outputJson(result, json);
79835
- if (!json) {
79836
- const nextState = result.ready ? "ready" : result.state;
79837
- console.log(`Wake request state: ${result.state}`);
79838
- console.log(`Target: ${result.target_id}`);
79839
- if (result.waited_ms !== void 0) {
79840
- console.log(`Waited: ${result.waited_ms}ms`);
79841
- } else {
79842
- console.log(`Retry after: ${result.retry_after_seconds}s`);
79843
- }
79844
- console.log(`Message: ${result.message}`);
79845
- if (result.ready) {
79846
- console.log(`Wake result: ${nextState}`);
79847
- }
79848
- }
79849
- return;
79850
- }
79851
- if (action === "pull") {
79852
- const targetId = positionals[1];
79853
- if (!targetId) throw new Error("Usage: eve ollama target pull <target-id> --model-id <id>");
79854
- const modelId = requireString(flags, "model-id");
79855
- const query = new URLSearchParams();
79856
- query.set("model_id", modelId);
79857
- const result = await requestJson(
79858
- context2,
79859
- `/inference/targets/${targetId}/pull?${query.toString()}`,
79860
- { method: "POST" }
79861
- );
79862
- outputJson(result, json);
79863
- if (!json) {
79864
- if (result.ok) {
79865
- console.log(`Pull complete: ${result.model} on ${result.target}`);
79866
- } else {
79867
- console.error(`Pull failed: ${result.message}`);
79868
- process.exitCode = 1;
79869
- }
79870
- }
79871
- return;
79872
- }
79873
- if (action === "models") {
79874
- const targetId = positionals[1];
79875
- if (!targetId) throw new Error("Usage: eve ollama target models <target-id>");
79876
- const result = await requestJson(
79877
- context2,
79878
- `/inference/targets/${targetId}/remote-models`
79879
- );
79880
- if (json) {
79881
- outputJson(result, json);
79882
- return;
79883
- }
79884
- console.log(`Models on target "${result.target}":`);
79885
- if (result.models.length === 0) {
79886
- console.log(" (none)");
79887
- return;
79888
- }
79889
- printTable(
79890
- ["Name", "Size (GB)", "Modified"],
79891
- result.models.map((m) => [
79892
- m.name,
79893
- (m.size / 1e9).toFixed(1),
79894
- m.modified_at
79895
- ])
79896
- );
79897
- return;
79898
- }
79899
- throw new Error(
79900
- "Usage: eve ollama target <add|rm|test|wake|pull|models> ...\n wake: <target-id> [--wait true] [--timeout-ms <ms>] Trigger GPU wake (default timeout 120s with --wait)"
79901
- );
79902
- }
79903
- case "models": {
79904
- const models = await requestJson(context2, "/inference/models");
79905
- if (json) {
79906
- outputJson(models, json);
79907
- return;
79908
- }
79909
- if (models.length === 0) {
79910
- console.log("No inference models found.");
79911
- return;
79912
- }
79913
- printTable(
79914
- ["ID", "Canonical", "Provider", "Provider Slug"],
79915
- models.map((item) => [item.id, item.canonical_model_id, item.provider, item.provider_model_slug])
79916
- );
79917
- return;
79918
- }
79919
- case "model": {
79920
- const action = positionals[0];
79921
- if (action !== "add") throw new Error("Usage: eve ollama model add --canonical <id> --provider <name> --slug <provider-model-slug>");
79922
- const created = await requestJson(context2, "/inference/models", {
79923
- method: "POST",
79924
- body: {
79925
- canonical_model_id: requireString(flags, "canonical"),
79926
- provider: requireString(flags, "provider"),
79927
- provider_model_slug: requireString(flags, "slug")
79928
- }
79929
- });
79930
- outputJson(created, json);
79931
- if (!json) console.log(`Model available as ${created.id}`);
79932
- return;
79933
- }
79934
- case "aliases": {
79935
- const scopeKind = asString(flags, "scope-kind");
79936
- const scopeId = asString(flags, "scope-id");
79937
- const query = new URLSearchParams();
79938
- if (scopeKind) query.set("scope_kind", scopeKind);
79939
- if (scopeId) query.set("scope_id", scopeId);
79940
- const suffix = query.toString() ? `?${query.toString()}` : "";
79941
- const aliases = await requestJson(context2, `/inference/aliases${suffix}`);
79942
- if (json) {
79943
- outputJson(aliases, json);
79944
- return;
79945
- }
79946
- if (aliases.length === 0) {
79947
- console.log("No inference aliases found.");
79948
- return;
79949
- }
79950
- printTable(
79951
- ["Alias", "Scope", "Target ID", "Model ID"],
79952
- aliases.map((item) => [
79953
- item.alias,
79954
- item.scope_id ? `${item.scope_kind}:${item.scope_id}` : item.scope_kind,
79955
- item.target_id,
79956
- item.model_id
79957
- ])
79958
- );
79959
- return;
79960
- }
79961
- case "alias": {
79962
- const action = positionals[0];
79963
- if (action === "set") {
79964
- const alias = requireString(flags, "alias");
79965
- const targetId = requireString(flags, "target-id");
79966
- const modelId = requireString(flags, "model-id");
79967
- const scopeKind = asString(flags, "scope-kind") ?? "platform";
79968
- const scopeId = asString(flags, "scope-id");
79969
- const body = {
79970
- alias,
79971
- target_id: targetId,
79972
- model_id: modelId,
79973
- scope_kind: scopeKind
79974
- };
79975
- if (scopeId) body.scope_id = scopeId;
79976
- const saved = await requestJson(context2, "/inference/aliases", {
79977
- method: "POST",
79978
- body
79979
- });
79980
- outputJson(saved, json);
79981
- if (!json) console.log(`Alias ${alias} saved`);
79982
- return;
79983
- }
79984
- if (action === "rm") {
79985
- const scopeKind = asString(flags, "scope-kind") ?? "platform";
79986
- const alias = requireString(flags, "alias");
79987
- const scopeId = asString(flags, "scope-id");
79988
- const query = new URLSearchParams();
79989
- if (scopeId) query.set("scope_id", scopeId);
79990
- const suffix = query.toString() ? `?${query.toString()}` : "";
79991
- await requestJson(context2, `/inference/aliases/${scopeKind}/${alias}${suffix}`, {
79992
- method: "DELETE"
79993
- });
79994
- if (!json) console.log(`Alias ${alias} deleted`);
79995
- return;
79996
- }
79997
- throw new Error("Usage: eve ollama alias <set|rm> ...");
79998
- }
79999
- case "installs": {
80000
- const targetId = asString(flags, "target-id");
80001
- const modelId = asString(flags, "model-id");
80002
- const query = new URLSearchParams();
80003
- if (targetId) query.set("target_id", targetId);
80004
- if (modelId) query.set("model_id", modelId);
80005
- const suffix = query.toString() ? `?${query.toString()}` : "";
80006
- const installs = await requestJson(context2, `/inference/installs${suffix}`);
80007
- if (json) {
80008
- outputJson(installs, json);
80009
- return;
80010
- }
80011
- if (installs.length === 0) {
80012
- console.log("No inference installs found.");
80013
- return;
80014
- }
80015
- printTable(
80016
- ["ID", "Target ID", "Model ID", "Warm Start", "Min Capacity"],
80017
- installs.map((item) => [
80018
- item.id,
80019
- item.target_id,
80020
- item.model_id,
80021
- item.requires_warm_start ? "yes" : "no",
80022
- String(item.min_target_capacity)
80023
- ])
80024
- );
80025
- return;
80026
- }
80027
- case "assignments": {
80028
- const scopeKind = asString(flags, "scope-kind");
80029
- const scopeId = asString(flags, "scope-id");
80030
- const query = new URLSearchParams();
80031
- if (scopeKind) query.set("scope_kind", scopeKind);
80032
- if (scopeId) query.set("scope_id", scopeId);
80033
- const suffix = query.toString() ? `?${query.toString()}` : "";
80034
- const assignments = await requestJson(context2, `/inference/assignments${suffix}`);
80035
- if (json) {
80036
- outputJson(assignments, json);
80037
- return;
80038
- }
80039
- if (assignments.length === 0) {
80040
- console.log("No inference assignments found.");
80041
- return;
80042
- }
80043
- printTable(
80044
- ["Target", "Scope", "Inflight", "Queue", "Max Inflight", "Status"],
80045
- assignments.map((item) => [
80046
- item.target_name,
80047
- item.scope_id ? `${item.scope_kind}:${item.scope_id}` : item.scope_kind,
80048
- String(item.inflight),
80049
- String(item.queue_depth),
80050
- String(item.max_concurrent_inflight),
80051
- item.status
80052
- ])
80053
- );
80054
- return;
80055
- }
80056
- case "route-policies": {
80057
- const scopeKind = asString(flags, "scope-kind");
80058
- const scopeId = asString(flags, "scope-id");
80059
- const query = new URLSearchParams();
80060
- if (scopeKind) query.set("scope_kind", scopeKind);
80061
- if (scopeId) query.set("scope_id", scopeId);
80062
- const suffix = query.toString() ? `?${query.toString()}` : "";
80063
- const policies = await requestJson(context2, `/inference/route-policies${suffix}`);
80064
- if (json) {
80065
- outputJson(policies, json);
80066
- return;
80067
- }
80068
- if (policies.length === 0) {
80069
- console.log("No inference route policies found.");
80070
- return;
80071
- }
80072
- printTable(
80073
- ["Scope", "Preferred Target", "Fallback"],
80074
- policies.map((item) => [
80075
- item.scope_id ? `${item.scope_kind}:${item.scope_id}` : item.scope_kind,
80076
- item.preferred_target_id,
80077
- item.fallback_to_alias_target ? "yes" : "no"
80078
- ])
80079
- );
80080
- return;
80081
- }
80082
- case "route-policy": {
80083
- const action = positionals[0];
80084
- if (action === "set") {
80085
- const scopeKind = asString(flags, "scope-kind") ?? "platform";
80086
- const scopeId = asString(flags, "scope-id");
80087
- const preferredTargetId = requireString(flags, "preferred-target-id");
80088
- const fallback = asString(flags, "fallback-to-alias-target");
80089
- const body = {
80090
- scope_kind: scopeKind,
80091
- preferred_target_id: preferredTargetId
80092
- };
80093
- if (scopeId) body.scope_id = scopeId;
80094
- if (fallback !== void 0) body.fallback_to_alias_target = fallback === "true" || fallback === "1";
80095
- const saved = await requestJson(context2, "/inference/route-policies", {
80096
- method: "POST",
80097
- body
80098
- });
80099
- outputJson(saved, json);
80100
- if (!json) console.log("Route policy saved");
80101
- return;
80102
- }
80103
- if (action === "rm") {
80104
- const scopeKind = asString(flags, "scope-kind") ?? "platform";
80105
- const scopeId = asString(flags, "scope-id");
80106
- const query = new URLSearchParams();
80107
- if (scopeId) query.set("scope_id", scopeId);
80108
- const suffix = query.toString() ? `?${query.toString()}` : "";
80109
- await requestJson(context2, `/inference/route-policies/${scopeKind}${suffix}`, {
80110
- method: "DELETE"
80111
- });
80112
- if (!json) console.log("Route policy deleted");
80113
- return;
80114
- }
80115
- throw new Error("Usage: eve ollama route-policy <set|rm> [options]");
80116
- }
80117
- case "install": {
80118
- const action = positionals[0];
80119
- if (action === "add") {
80120
- const targetId = requireString(flags, "target-id");
80121
- const modelId = requireString(flags, "model-id");
80122
- const body = {};
80123
- const requiresWarmStart = asString(flags, "requires-warm-start");
80124
- if (requiresWarmStart !== void 0) {
80125
- body.requires_warm_start = requiresWarmStart === "true" || requiresWarmStart === "1";
80126
- }
80127
- const minTargetCapacity = asString(flags, "min-target-capacity");
80128
- if (minTargetCapacity) {
80129
- body.min_target_capacity = Number(minTargetCapacity);
80130
- }
80131
- const saved = await requestJson(context2, `/inference/targets/${targetId}/models/${modelId}`, {
80132
- method: "POST",
80133
- body
80134
- });
80135
- outputJson(saved, json);
80136
- if (!json) console.log(`Installed model ${modelId} on target ${targetId}`);
80137
- return;
80138
- }
80139
- if (action === "rm") {
80140
- const targetId = requireString(flags, "target-id");
80141
- const modelId = requireString(flags, "model-id");
80142
- await requestJson(context2, `/inference/targets/${targetId}/models/${modelId}`, {
80143
- method: "DELETE"
80144
- });
80145
- if (!json) console.log(`Removed model ${modelId} from target ${targetId}`);
80146
- return;
80147
- }
80148
- throw new Error("Usage: eve ollama install <add|rm> --target-id <id> --model-id <id>");
80149
- }
80150
- case "managed": {
80151
- const action = positionals[0];
80152
- if (action === "list") {
80153
- const response = await requestJson(
80154
- context2,
80155
- "/inference/managed-models"
80156
- );
80157
- const managed = normalizeManagedModelRows(response);
80158
- outputJson(managed, json);
80159
- if (json) return;
80160
- if (managed.length === 0) {
80161
- console.log("No managed models published.");
80162
- return;
80163
- }
80164
- printTable(
80165
- ["Canonical", "Provider", "Slug", "Target ID", "Warm Start", "Enabled"],
80166
- managed.map((item) => [
80167
- item.canonical_model_id,
80168
- item.provider,
80169
- item.provider_model_slug,
80170
- item.target_id,
80171
- item.requires_warm_start ? "yes" : "no",
80172
- item.enabled ? "yes" : "no"
80173
- ])
80174
- );
80175
- return;
80176
- }
80177
- if (action === "publish") {
80178
- const body = {
80179
- canonical_model_id: requireString(flags, "canonical"),
80180
- provider: requireString(flags, "provider"),
80181
- provider_model_slug: requireString(flags, "slug"),
80182
- target_id: requireString(flags, "target-id")
80183
- };
80184
- const requiresWarmStart = asBoolean(flags, "requires-warm-start");
80185
- const enabled = asBoolean(flags, "enabled");
80186
- const targetId = body.target_id;
80187
- const target = await requestJson(context2, `/inference/targets/${targetId}`);
80188
- if (target.transport_profile === "openai_compat" && looksLikeGatewayPath(target.base_url)) {
80189
- console.log("warning: openai_compat target base_url appears to include /v1-like gateway path.");
80190
- }
80191
- if (requiresWarmStart !== void 0) {
80192
- body.requires_warm_start = requiresWarmStart;
80193
- }
80194
- if (enabled !== void 0) {
80195
- body.enabled = enabled;
80196
- }
80197
- const result = await requestJson(context2, "/inference/managed-models", {
80198
- method: "POST",
80199
- body
80200
- });
80201
- outputJson(result, json);
80202
- if (!json) {
80203
- console.log(
80204
- `Published managed model ${result.data.canonical_model_id} (install ${result.created_install ? "created" : "already present"}), target ${result.data.target_id}`
80205
- );
80206
- }
80207
- return;
80208
- }
80209
- if (action === "unpublish") {
80210
- const canonicalModelId = requireString(flags, "canonical");
80211
- await requestJson(context2, `/inference/managed-models/${encodeURIComponent(canonicalModelId)}`, {
80212
- method: "DELETE"
80213
- });
80214
- const payload = { canonical_model_id: canonicalModelId };
80215
- outputJson(payload, json);
80216
- if (!json) {
80217
- console.log(`Unpublished managed model ${canonicalModelId}`);
80218
- }
80219
- return;
80220
- }
80221
- throw new Error("Usage: eve ollama managed <list|publish|unpublish> ...");
80222
- }
80223
- default:
80224
- throw new Error(
80225
- "Usage: eve ollama <targets|target|models|model|aliases|alias|installs|install|assignments|route-policies|route-policy|managed>"
80226
- );
80227
- }
80228
- }
80229
-
80230
79459
  // src/commands/ingest.ts
80231
79460
  var import_node_fs19 = require("node:fs");
80232
79461
  var import_node_path19 = require("node:path");
@@ -82234,6 +81463,170 @@ async function handleUser(subcommand, positionals, flags, context2) {
82234
81463
  }
82235
81464
  }
82236
81465
 
81466
+ // src/commands/endpoint.ts
81467
+ async function handleEndpoint(subcommand, positionals, flags, context2) {
81468
+ const json = Boolean(flags.json);
81469
+ const orgId = getStringFlag(flags, ["org"]) ?? context2.orgId;
81470
+ if (!orgId) {
81471
+ throw new Error("Missing --org flag or profile default org.");
81472
+ }
81473
+ const basePath = `/orgs/${orgId}/endpoints`;
81474
+ switch (subcommand) {
81475
+ case "add": {
81476
+ const name = getStringFlag(flags, ["name"]) ?? positionals[0];
81477
+ const hostname2 = getStringFlag(flags, ["tailscale-hostname", "hostname"]);
81478
+ const portStr = getStringFlag(flags, ["port"]);
81479
+ const healthPath = getStringFlag(flags, ["health-path"]);
81480
+ if (!name || !hostname2 || !portStr) {
81481
+ throw new Error(
81482
+ "Usage: eve endpoint add --name <name> --tailscale-hostname <fqdn> --port <port> --org <org_id> [--health-path <path>]"
81483
+ );
81484
+ }
81485
+ const port = parseInt(portStr, 10);
81486
+ if (isNaN(port) || port < 1 || port > 65535) {
81487
+ throw new Error("--port must be a valid port number (1-65535)");
81488
+ }
81489
+ const body = {
81490
+ name,
81491
+ provider: "tailscale",
81492
+ hostname: hostname2,
81493
+ port
81494
+ };
81495
+ if (healthPath !== void 0) {
81496
+ body.health_path = healthPath === "none" ? null : healthPath;
81497
+ }
81498
+ const response = await requestJson(context2, basePath, {
81499
+ method: "POST",
81500
+ body
81501
+ });
81502
+ if (json) {
81503
+ outputJson(response, true);
81504
+ } else {
81505
+ const clusterUrl = response.cluster_url ?? "unknown";
81506
+ const status = response.status ?? "unknown";
81507
+ console.log(`\u2713 Endpoint registered: ${name}`);
81508
+ console.log(` Status: ${status}`);
81509
+ console.log(` Cluster URL: ${clusterUrl}`);
81510
+ console.log(` K8s Service: ${response.k8s_svc_name}.${response.k8s_namespace}`);
81511
+ if (status === "error" && response.status_msg) {
81512
+ console.log(` Error: ${response.status_msg}`);
81513
+ }
81514
+ console.log("");
81515
+ console.log(`Use this URL in your secrets:`);
81516
+ console.log(` eve secrets set LLM_BASE_URL "${clusterUrl}/v1" --scope org --org ${orgId}`);
81517
+ }
81518
+ return;
81519
+ }
81520
+ case "list": {
81521
+ const response = await requestJson(context2, basePath);
81522
+ if (json) {
81523
+ outputJson(response, true);
81524
+ } else {
81525
+ const data = response.data ?? [];
81526
+ if (data.length === 0) {
81527
+ console.log("No private endpoints registered.");
81528
+ } else {
81529
+ console.log(`Private endpoints for org ${orgId}:
81530
+ `);
81531
+ for (const ep of data) {
81532
+ const status = ep.status === "ready" ? "\u2713" : ep.status === "error" ? "\u2717" : "\u2026";
81533
+ console.log(` ${status} ${ep.name} (${ep.hostname}:${ep.port}) [${ep.status}]`);
81534
+ console.log(` URL: ${ep.cluster_url ?? "pending"}`);
81535
+ }
81536
+ }
81537
+ }
81538
+ return;
81539
+ }
81540
+ case "show": {
81541
+ const name = positionals[0] ?? getStringFlag(flags, ["name"]);
81542
+ if (!name) {
81543
+ throw new Error("Usage: eve endpoint show <name> --org <org_id>");
81544
+ }
81545
+ const verbose = Boolean(flags.verbose);
81546
+ const response = await requestJson(context2, `${basePath}/${name}`);
81547
+ if (json) {
81548
+ outputJson(response, true);
81549
+ } else {
81550
+ console.log(`Name: ${response.name}`);
81551
+ console.log(`Org: ${orgId}`);
81552
+ console.log(`Provider: ${response.provider}`);
81553
+ console.log(`Hostname: ${response.hostname}`);
81554
+ console.log(`Port: ${response.port}`);
81555
+ console.log(`Status: ${response.status}`);
81556
+ console.log(`Cluster DNS: ${response.k8s_dns}:${response.port}`);
81557
+ console.log(`Cluster URL: ${response.cluster_url}`);
81558
+ if (response.status_msg) {
81559
+ console.log(`Status Msg: ${response.status_msg}`);
81560
+ }
81561
+ if (verbose && response.health_path) {
81562
+ console.log("");
81563
+ console.log("Running health check...");
81564
+ try {
81565
+ const health = await requestJson(
81566
+ context2,
81567
+ `${basePath}/${name}/health`
81568
+ );
81569
+ const h = health.health;
81570
+ console.log(` Last checked: ${h.checked_at}`);
81571
+ if (h.reachable) {
81572
+ console.log(` HTTP GET ${response.health_path} \u2192 ${h.http_status} OK (${h.response_time_ms}ms)`);
81573
+ } else {
81574
+ console.log(` Unreachable: ${h.error}`);
81575
+ }
81576
+ } catch (err) {
81577
+ console.log(` Health check failed: ${err instanceof Error ? err.message : err}`);
81578
+ }
81579
+ }
81580
+ }
81581
+ return;
81582
+ }
81583
+ case "remove": {
81584
+ const name = positionals[0] ?? getStringFlag(flags, ["name"]);
81585
+ if (!name) {
81586
+ throw new Error("Usage: eve endpoint remove <name> --org <org_id>");
81587
+ }
81588
+ await requestJson(context2, `${basePath}/${name}`, { method: "DELETE" });
81589
+ outputJson({ ok: true }, json, `\u2713 Endpoint '${name}' removed`);
81590
+ return;
81591
+ }
81592
+ case "health": {
81593
+ const name = positionals[0] ?? getStringFlag(flags, ["name"]);
81594
+ if (!name) {
81595
+ throw new Error("Usage: eve endpoint health <name> --org <org_id>");
81596
+ }
81597
+ const response = await requestJson(context2, `${basePath}/${name}/health`);
81598
+ outputJson(response, json);
81599
+ return;
81600
+ }
81601
+ case "diagnose": {
81602
+ const name = positionals[0] ?? getStringFlag(flags, ["name"]);
81603
+ if (!name) {
81604
+ throw new Error("Usage: eve endpoint diagnose <name> --org <org_id>");
81605
+ }
81606
+ const response = await requestJson(
81607
+ context2,
81608
+ `${basePath}/${name}/diagnose`
81609
+ );
81610
+ if (json) {
81611
+ outputJson(response, true);
81612
+ } else {
81613
+ console.log(`Diagnostics for endpoint '${name}':
81614
+ `);
81615
+ for (const check of response.checks) {
81616
+ const icon = check.passed ? "\u2713" : "\u2717";
81617
+ const detail = check.detail ? ` \u2014 ${check.detail}` : "";
81618
+ console.log(` ${icon} ${check.name}${detail}`);
81619
+ }
81620
+ }
81621
+ return;
81622
+ }
81623
+ default:
81624
+ throw new Error(
81625
+ "Usage: eve endpoint <add|list|show|remove|health|diagnose>\n\n add Register a private endpoint backed by Tailscale\n list List endpoints for an org\n show Show endpoint details\n remove Remove an endpoint\n health Run a health check\n diagnose Run diagnostics on an endpoint"
81626
+ );
81627
+ }
81628
+ }
81629
+
82237
81630
  // src/index.ts
82238
81631
  function getCliVersion() {
82239
81632
  try {
@@ -82388,9 +81781,6 @@ async function main2() {
82388
81781
  case "migrate":
82389
81782
  await handleMigrate2(subcommand, rest, flags);
82390
81783
  return;
82391
- case "models":
82392
- await handleModels(subcommand, rest, flags, context2);
82393
- return;
82394
81784
  case "access":
82395
81785
  await handleAccess(subcommand, rest, flags, context2);
82396
81786
  return;
@@ -82417,9 +81807,6 @@ async function main2() {
82417
81807
  case "analytics":
82418
81808
  await handleAnalytics(subcommand, rest, flags, context2);
82419
81809
  return;
82420
- case "ollama":
82421
- await handleOllama(subcommand, rest, flags, context2);
82422
- return;
82423
81810
  case "ingest":
82424
81811
  await handleIngest(subcommand, rest, flags, context2);
82425
81812
  return;
@@ -82438,6 +81825,9 @@ async function main2() {
82438
81825
  case "user":
82439
81826
  await handleUser(subcommand, rest, flags, context2);
82440
81827
  return;
81828
+ case "endpoint":
81829
+ await handleEndpoint(subcommand, rest, flags, context2);
81830
+ return;
82441
81831
  default:
82442
81832
  showMainHelp();
82443
81833
  }