@konstantdotcloud/boombox 0.1.1 → 0.2.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/README.md +3 -2
- package/dist/boombox.js +141 -21
- package/dist/index.js +32 -18
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ boombox admin # opens the VM admin UI through a short-lived cloud grant
|
|
|
21
21
|
boombox run bd_pre_meeting_brief --input meeting_uid=sample --input organizer=user@example.com --input attendees='["user@example.com"]' --input start_time=2026-06-02T15:00:00Z --input summary=Sample
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
For MCP clients, add `boombox serve --mcp` after `boombox login` succeeds.
|
|
24
|
+
For MCP clients, add `boombox serve --mcp` after `boombox login` succeeds. The MCP server defaults to the `advanced` profile (cassette authoring + rack verbs included); set `GARY_MCP_PROFILE=andrew` or pass `--profile` to narrow or change it.
|
|
25
25
|
|
|
26
26
|
## Commands
|
|
27
27
|
|
|
@@ -33,6 +33,7 @@ For MCP clients, add `boombox serve --mcp` after `boombox login` succeeds.
|
|
|
33
33
|
| `boombox run <cassette_name> [--input key=value ...] [--no-tail] [--json]` | Manually triggers a cassette through `/gateway/rack/run`, prompts for required missing inputs, then polls to a terminal state unless `--no-tail` is set. |
|
|
34
34
|
| `boombox cassettes list` | Lists active cassettes available to the tenant. |
|
|
35
35
|
| `boombox cassettes show <id> [--draft]` | Prints a cassette YAML projection. |
|
|
36
|
+
| `boombox cassettes publish <draft_id> --name <name> [--version <n>] [--json]` | Publishes a dry-run-approved cassette draft to the tenant tier via `POST /gateway/cassette/publish`; renders gate rejections (e.g. `dry-run-not-green`) with fix guidance. |
|
|
36
37
|
| `boombox runs list [--cassette=X] [--since=24h] [--actor=Y] [--status=completed] [--limit=20]` | Lists recent runs with run id, cassette, actor, status, duration, and start time. |
|
|
37
38
|
| `boombox runs show <run_id>` | Shows one run: spec hash, inputs, step trace, delivery receipts, error summary, and replay ref. |
|
|
38
39
|
| `boombox logs tail [--cassette=X]` | Tails run/step events from the VM SSE stream. |
|
|
@@ -57,7 +58,7 @@ For MCP clients, add `boombox serve --mcp` after `boombox login` succeeds.
|
|
|
57
58
|
[konstant]
|
|
58
59
|
tenant_id = "example"
|
|
59
60
|
api_key = "kn_example_***"
|
|
60
|
-
gateway_url = "https://boombox.
|
|
61
|
+
gateway_url = "https://boombox-example.exe.xyz"
|
|
61
62
|
|
|
62
63
|
[runtime]
|
|
63
64
|
default_kind = "vm"
|
package/dist/boombox.js
CHANGED
|
@@ -36148,7 +36148,7 @@ var init_ask_gary = __esm({
|
|
|
36148
36148
|
thread_id: external_exports2.string().optional().describe("Concrete thread_id to use instead of resolving a named alias. Useful when continuing an artifact discussion thread."),
|
|
36149
36149
|
artifact_ref: external_exports2.string().optional().describe("Artifact id to pin as Gary context. Gary loads the artifact body and tags the resulting thread with artifact_ref."),
|
|
36150
36150
|
fresh: external_exports2.boolean().optional().describe("If true, rotate the thread alias to a brand-new conversation, discarding prior history under that alias."),
|
|
36151
|
-
model_tier: external_exports2.enum(["auto", "fast", "nano", "mini", "reason", "mid", "explore", "premium", "opus"]).optional().describe("Model tier override. Default 'explore' (Sonnet 4.6). Use 'premium' for
|
|
36151
|
+
model_tier: external_exports2.enum(["auto", "fast", "nano", "mini", "reason", "mid", "explore", "premium", "opus"]).optional().describe("Model tier override. Default 'explore' (Sonnet 4.6). Use 'premium' for Opus 4.8 at max thinking, 'opus' for Opus 4.8 standard."),
|
|
36152
36152
|
thinking_level: external_exports2.enum(["off", "minimal", "low", "medium", "high", "xhigh"]).optional().describe("Reasoning effort override. Default 'medium'."),
|
|
36153
36153
|
intent: external_exports2.enum(["cassette_author"]).optional().describe("Set to cassette_author to load Gary cassette-authoring mode prompt/doctrine.")
|
|
36154
36154
|
};
|
|
@@ -37341,12 +37341,6 @@ function registerCassetteAuthoringVerbs(server, gateway) {
|
|
|
37341
37341
|
publishSchema,
|
|
37342
37342
|
async (input) => renderGatewayResult("cassette_publish", await gateway.call("/gateway/cassette/publish", input))
|
|
37343
37343
|
);
|
|
37344
|
-
server.tool(
|
|
37345
|
-
"cassette_request_publish",
|
|
37346
|
-
"Request tenant_admin approval to publish a cassette draft when the caller lacks cassette.publish.",
|
|
37347
|
-
requestPublishSchema,
|
|
37348
|
-
async (input) => renderGatewayResult("cassette_request_publish", await gateway.call("/gateway/cassette/request-publish", input))
|
|
37349
|
-
);
|
|
37350
37344
|
server.tool(
|
|
37351
37345
|
"cassette_get",
|
|
37352
37346
|
"Get a cassette draft or published cassette as YAML plus describe payload.",
|
|
@@ -37399,7 +37393,7 @@ ${JSON.stringify(record2, null, 2)}`;
|
|
|
37399
37393
|
function isRecord(value) {
|
|
37400
37394
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
37401
37395
|
}
|
|
37402
|
-
var recordSchema, draftSchema, refineSchema, dryRunSchema, publishSchema,
|
|
37396
|
+
var recordSchema, draftSchema, refineSchema, dryRunSchema, publishSchema, getSchema, listDraftsSchema, listCapabilitiesSchema;
|
|
37403
37397
|
var init_cassette_authoring = __esm({
|
|
37404
37398
|
"../../lib/gary-mcp/verbs/cassette-authoring.ts"() {
|
|
37405
37399
|
"use strict";
|
|
@@ -37427,10 +37421,6 @@ var init_cassette_authoring = __esm({
|
|
|
37427
37421
|
name: external_exports2.string().min(1),
|
|
37428
37422
|
version: external_exports2.number().int().min(1).optional()
|
|
37429
37423
|
};
|
|
37430
|
-
requestPublishSchema = {
|
|
37431
|
-
draft_id: external_exports2.string().min(1),
|
|
37432
|
-
reason: external_exports2.string().min(1).optional()
|
|
37433
|
-
};
|
|
37434
37424
|
getSchema = {
|
|
37435
37425
|
id: external_exports2.string().min(1).optional(),
|
|
37436
37426
|
draft_id: external_exports2.string().min(1).optional()
|
|
@@ -37480,7 +37470,10 @@ function normalizeProfile(value) {
|
|
|
37480
37470
|
}
|
|
37481
37471
|
function guessPathPrefix(baseUrl) {
|
|
37482
37472
|
if (!baseUrl) return "/api";
|
|
37483
|
-
if (/\.
|
|
37473
|
+
if (/\.exe\.(xyz|dev)/i.test(baseUrl)) {
|
|
37474
|
+
return /\/v2\/?$/.test(baseUrl) ? "/api" : "/v2/api";
|
|
37475
|
+
}
|
|
37476
|
+
if (/\.fly\.dev/i.test(baseUrl)) return "/api";
|
|
37484
37477
|
if (/\.konstant\.cloud/i.test(baseUrl)) return "/api";
|
|
37485
37478
|
if (/\.vercel\.app/i.test(baseUrl)) return "/api";
|
|
37486
37479
|
return "";
|
|
@@ -37606,7 +37599,7 @@ var {
|
|
|
37606
37599
|
init_esm_shims();
|
|
37607
37600
|
|
|
37608
37601
|
// package.json
|
|
37609
|
-
var version = "0.
|
|
37602
|
+
var version = "0.2.0";
|
|
37610
37603
|
|
|
37611
37604
|
// src/lib/version.ts
|
|
37612
37605
|
var BOOMBOX_VERSION = version;
|
|
@@ -42579,10 +42572,21 @@ function resolveGatewayTarget(config2) {
|
|
|
42579
42572
|
function normalizeUrl(url) {
|
|
42580
42573
|
return url.replace(/\/+$/, "");
|
|
42581
42574
|
}
|
|
42575
|
+
function gatewayApiPrefix(baseUrl) {
|
|
42576
|
+
if (!baseUrl) return "/api";
|
|
42577
|
+
if (/\.exe\.(xyz|dev)/i.test(baseUrl)) {
|
|
42578
|
+
return /\/v2\/?$/.test(baseUrl) ? "/api" : "/v2/api";
|
|
42579
|
+
}
|
|
42580
|
+
return "/api";
|
|
42581
|
+
}
|
|
42582
|
+
function resolveGatewayApiBase(config2) {
|
|
42583
|
+
const origin = resolveGatewayTarget(config2).url;
|
|
42584
|
+
return `${origin}${gatewayApiPrefix(origin)}`;
|
|
42585
|
+
}
|
|
42582
42586
|
|
|
42583
42587
|
// src/cli/_verify.ts
|
|
42584
42588
|
async function verifyAuth(config2, fetchImpl = fetch) {
|
|
42585
|
-
const url = `${
|
|
42589
|
+
const url = `${resolveGatewayApiBase(config2)}/gateway/rack/list`;
|
|
42586
42590
|
let res;
|
|
42587
42591
|
try {
|
|
42588
42592
|
res = await fetchImpl(url, {
|
|
@@ -42634,7 +42638,7 @@ async function runInit(options = {}) {
|
|
|
42634
42638
|
const preset = {
|
|
42635
42639
|
tenant_id: options.tenantId ?? enrollPayload?.tenant_id ?? existing?.konstant.tenant_id ?? "",
|
|
42636
42640
|
api_key: options.tenantApiKey ?? options.apiKey ?? enrollPayload?.tenant_api_key ?? enrollPayload?.api_key ?? existing?.konstant.api_key ?? "",
|
|
42637
|
-
gateway_url: options.gatewayUrl ?? enrollPayload?.gateway_url ?? existing?.konstant.gateway_url ??
|
|
42641
|
+
gateway_url: options.gatewayUrl ?? enrollPayload?.gateway_url ?? existing?.konstant.gateway_url ?? options.vmUrl ?? enrollPayload?.vm_url ?? existing?.runtime.vm_url ?? "",
|
|
42638
42642
|
vm_url: options.vmUrl ?? enrollPayload?.vm_url ?? existing?.runtime.vm_url ?? ""
|
|
42639
42643
|
};
|
|
42640
42644
|
log("Welcome to Konstant Boombox.");
|
|
@@ -43299,7 +43303,6 @@ var open_default = open;
|
|
|
43299
43303
|
|
|
43300
43304
|
// src/cli/enroll.ts
|
|
43301
43305
|
var DEFAULT_AUTH_BASE = "https://boombox.konstant.cloud";
|
|
43302
|
-
var DEFAULT_GATEWAY_BASE = "https://boombox.konstant.cloud/v2";
|
|
43303
43306
|
var DEFAULT_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
43304
43307
|
async function runEnroll(options = {}) {
|
|
43305
43308
|
const log = options.log ?? ((m) => console.log(m));
|
|
@@ -43325,8 +43328,13 @@ async function runEnroll(options = {}) {
|
|
|
43325
43328
|
log,
|
|
43326
43329
|
openBrowser: options.openBrowser
|
|
43327
43330
|
});
|
|
43328
|
-
const gatewayUrl = (options.gatewayUrl ?? payload.gateway_url ?? DEFAULT_GATEWAY_BASE).replace(/\/+$/, "");
|
|
43329
43331
|
const vmUrl = (options.vmUrl ?? payload.vm_url)?.replace(/\/+$/, "");
|
|
43332
|
+
const gatewayUrl = (options.gatewayUrl ?? payload.gateway_url ?? vmUrl ?? "").replace(/\/+$/, "");
|
|
43333
|
+
if (!gatewayUrl) {
|
|
43334
|
+
throw new Error(
|
|
43335
|
+
"Enrollment returned no gateway: neither gateway_url nor vm_url present. Provision a tenant VM (Mode 2) \u2014 the shared cloud gateway (Mode 1) is retired."
|
|
43336
|
+
);
|
|
43337
|
+
}
|
|
43330
43338
|
const apiKey = payload.tenant_api_key ?? payload.api_key;
|
|
43331
43339
|
const httpPort = existing?.boombox.http_port ?? DEFAULT_HTTP_PORT;
|
|
43332
43340
|
const config2 = BoomboxConfigSchema.parse({
|
|
@@ -47032,12 +47040,20 @@ function relativeToCwd(absPath) {
|
|
|
47032
47040
|
|
|
47033
47041
|
// src/server/mcp-stdio.ts
|
|
47034
47042
|
init_esm_shims();
|
|
47043
|
+
var DEFAULT_MCP_PROFILE = "advanced";
|
|
47044
|
+
function resolveMcpProfileSelection(flag) {
|
|
47045
|
+
if (flag === void 0) return void 0;
|
|
47046
|
+
return flag === "default" ? DEFAULT_MCP_PROFILE : flag;
|
|
47047
|
+
}
|
|
47035
47048
|
async function startStdioMcp(config2) {
|
|
47036
47049
|
process.env.GARY_MCP_GATEWAY_URL = resolveGateway(config2);
|
|
47037
47050
|
process.env.GARY_MCP_API_KEY = config2.konstant.api_key;
|
|
47038
47051
|
if (!process.env.KONSTANT_API_KEY) {
|
|
47039
47052
|
process.env.KONSTANT_API_KEY = config2.konstant.api_key;
|
|
47040
47053
|
}
|
|
47054
|
+
if (!(process.env.GARY_MCP_PROFILE ?? "").trim()) {
|
|
47055
|
+
process.env.GARY_MCP_PROFILE = DEFAULT_MCP_PROFILE;
|
|
47056
|
+
}
|
|
47041
47057
|
const mod = await Promise.resolve().then(() => (init_gary_mcp(), gary_mcp_exports));
|
|
47042
47058
|
await mod.startGaryMcpServer();
|
|
47043
47059
|
}
|
|
@@ -47112,8 +47128,10 @@ async function runServe(options = {}) {
|
|
|
47112
47128
|
log("Note: mcp_enabled=false in config; enabling for this session.");
|
|
47113
47129
|
}
|
|
47114
47130
|
if (enableMcp) {
|
|
47115
|
-
const
|
|
47116
|
-
|
|
47131
|
+
const selectedProfile = resolveMcpProfileSelection(options.profile);
|
|
47132
|
+
if (selectedProfile !== void 0) {
|
|
47133
|
+
process.env.GARY_MCP_PROFILE = selectedProfile;
|
|
47134
|
+
}
|
|
47117
47135
|
process.env.GARY_MCP_TENANT_ID = config2.konstant.tenant_id;
|
|
47118
47136
|
}
|
|
47119
47137
|
const handle = await serve2({
|
|
@@ -48246,6 +48264,7 @@ function createOpsContext(options = {}) {
|
|
|
48246
48264
|
return {
|
|
48247
48265
|
config: config2,
|
|
48248
48266
|
gateway: resolveGateway(config2),
|
|
48267
|
+
gatewayApi: resolveGatewayApiBase(config2),
|
|
48249
48268
|
apiKey: config2.konstant.api_key,
|
|
48250
48269
|
tenant_id: config2.konstant.tenant_id,
|
|
48251
48270
|
fetchImpl: options.fetchImpl ?? fetch,
|
|
@@ -48265,7 +48284,8 @@ function joinUrl(base, path4) {
|
|
|
48265
48284
|
return `${cleanBase}${cleanPath}`;
|
|
48266
48285
|
}
|
|
48267
48286
|
async function fetchText(ctx, path4, options = {}) {
|
|
48268
|
-
const
|
|
48287
|
+
const base = path4.startsWith("/gateway") ? ctx.gatewayApi : ctx.gateway;
|
|
48288
|
+
const url = joinUrl(base, path4);
|
|
48269
48289
|
const headers = {
|
|
48270
48290
|
...options.auth === false ? {} : authHeaders(ctx, options.accept ?? "application/json"),
|
|
48271
48291
|
...options.headers ?? {}
|
|
@@ -49179,6 +49199,96 @@ async function runCassettesDryRun(options) {
|
|
|
49179
49199
|
}
|
|
49180
49200
|
printSimulation(body, ctx);
|
|
49181
49201
|
}
|
|
49202
|
+
async function runCassettesPublish(options) {
|
|
49203
|
+
const ctx = createOpsContext(options);
|
|
49204
|
+
const payload = {
|
|
49205
|
+
draft_id: options.draftId,
|
|
49206
|
+
name: options.name
|
|
49207
|
+
};
|
|
49208
|
+
if (options.version !== void 0) payload.version = options.version;
|
|
49209
|
+
let body;
|
|
49210
|
+
try {
|
|
49211
|
+
body = (await fetchJson(ctx, "/gateway/cassette/publish", { method: "POST", body: payload })).body;
|
|
49212
|
+
} catch (error2) {
|
|
49213
|
+
if (error2 instanceof OpsHttpError) {
|
|
49214
|
+
renderPublishRejection(error2.body, ctx, options, `HTTP ${error2.status}`);
|
|
49215
|
+
return 1;
|
|
49216
|
+
}
|
|
49217
|
+
throw error2;
|
|
49218
|
+
}
|
|
49219
|
+
const record2 = asRecord(body);
|
|
49220
|
+
if (record2 && (record2.ok === false || typeof record2.code === "string" && record2.ok !== true)) {
|
|
49221
|
+
renderPublishRejection(body, ctx, options, "rejected");
|
|
49222
|
+
return 1;
|
|
49223
|
+
}
|
|
49224
|
+
if (options.json) {
|
|
49225
|
+
ctx.log(JSON.stringify(body ?? null, null, 2));
|
|
49226
|
+
return 0;
|
|
49227
|
+
}
|
|
49228
|
+
const published = recordField(record2, "workflow") ?? recordField(record2, "published") ?? recordField(record2, "cassette") ?? record2 ?? {};
|
|
49229
|
+
printKeyValues([
|
|
49230
|
+
["draft", options.draftId],
|
|
49231
|
+
["workflow", field2(published, ["workflow_id", "id", "cassette_id"])],
|
|
49232
|
+
["version", field2(published, ["version", "workflow_version"])],
|
|
49233
|
+
["tier", field2(published, ["tier"])],
|
|
49234
|
+
["status", field2(published, ["status"])]
|
|
49235
|
+
], ctx.log);
|
|
49236
|
+
ctx.log("Published to the tenant tier.");
|
|
49237
|
+
return 0;
|
|
49238
|
+
}
|
|
49239
|
+
function publishRejectionHint(code, draftId) {
|
|
49240
|
+
switch (code.toLowerCase().replace(/_/g, "-")) {
|
|
49241
|
+
case "publish-blocked-draft-required":
|
|
49242
|
+
return `Publish requires a saved draft, not raw YAML. Save the draft first (cassette_draft / cassette_refine via MCP), then publish by draft_id (\`${draftId}\`).`;
|
|
49243
|
+
case "publish-blocked-dry-run-missing":
|
|
49244
|
+
return `This draft has no dry-run yet. Run one (cassette_dry_run via MCP, or \`boombox cassettes dry-run ${draftId} --draft\`) and get a ready_to_publish verdict before publishing.`;
|
|
49245
|
+
case "publish-blocked-dry-run-not-ready":
|
|
49246
|
+
case "dry-run-not-green":
|
|
49247
|
+
return `The draft's latest dry-run is not green. Re-run it (cassette_dry_run via MCP, or \`boombox cassettes dry-run ${draftId} --draft\`) until the verdict is ready_to_publish, then publish again.`;
|
|
49248
|
+
case "publish-blocked-dry-run-stale":
|
|
49249
|
+
case "dry-run-stale":
|
|
49250
|
+
// legacy aliases
|
|
49251
|
+
case "stale-dry-run":
|
|
49252
|
+
case "spec-hash-mismatch":
|
|
49253
|
+
return "The draft changed after its last green dry-run. Re-run the dry-run against the current draft revision, then publish again.";
|
|
49254
|
+
case "forbidden-authority":
|
|
49255
|
+
case "missing-authority":
|
|
49256
|
+
return "This API key lacks the cassette.publish grant. Use cassette_request_publish (MCP) to ask a tenant admin to publish, or have an admin add cassette.publish to your key.";
|
|
49257
|
+
case "publish-blocked-not-owner":
|
|
49258
|
+
case "forbidden-not-owner":
|
|
49259
|
+
case "forbidden":
|
|
49260
|
+
// legacy aliases
|
|
49261
|
+
case "draft-not-owned":
|
|
49262
|
+
return "This draft is not owned by your API key actor. Publish from the key that created the draft, or ask a tenant admin to publish it.";
|
|
49263
|
+
case "not-found":
|
|
49264
|
+
return `No draft "${draftId}" is visible to this key. Check \`boombox cassettes list --status draft\` (or cassette_list_drafts via MCP).`;
|
|
49265
|
+
case "publish-blocked-master-shadow":
|
|
49266
|
+
case "master-shadowing":
|
|
49267
|
+
// legacy aliases
|
|
49268
|
+
case "master-collision":
|
|
49269
|
+
return "The cassette id collides with a master/builtin cassette, which tenant publishes are not allowed to shadow. Rename the cassette and publish again.";
|
|
49270
|
+
case "publish-blocked-event-trigger":
|
|
49271
|
+
return "Tenant cassettes cannot publish with event triggers (those are reserved for master-tier cassettes). Remove the event trigger, or request an admin publish.";
|
|
49272
|
+
case "cassette-yaml-invalid":
|
|
49273
|
+
return "The draft YAML failed validation. Fix the reported errors (cassette_refine via MCP) and re-run a dry-run before publishing.";
|
|
49274
|
+
case "validation-error":
|
|
49275
|
+
return "The publish payload was rejected. Check the draft_id and --name values, then re-validate the draft before publishing.";
|
|
49276
|
+
default:
|
|
49277
|
+
return void 0;
|
|
49278
|
+
}
|
|
49279
|
+
}
|
|
49280
|
+
function renderPublishRejection(body, ctx, options, fallbackLabel) {
|
|
49281
|
+
if (options.json) {
|
|
49282
|
+
ctx.errLog(JSON.stringify(body ?? { code: fallbackLabel }, null, 2));
|
|
49283
|
+
return;
|
|
49284
|
+
}
|
|
49285
|
+
const record2 = asRecord(body);
|
|
49286
|
+
const code = stringField4(record2, "code") ?? fallbackLabel;
|
|
49287
|
+
const message = stringField4(record2, "message") ?? stringField4(record2, "error") ?? "no detail from gateway";
|
|
49288
|
+
ctx.errLog(`publish rejected (${code}): ${message}`);
|
|
49289
|
+
const hint = publishRejectionHint(code, options.draftId);
|
|
49290
|
+
if (hint) ctx.errLog(` fix: ${hint}`);
|
|
49291
|
+
}
|
|
49182
49292
|
function extractCassettes(body) {
|
|
49183
49293
|
const record2 = asRecord(body);
|
|
49184
49294
|
const list = arrayField2(record2, "cassettes") ?? arrayField2(record2, "items") ?? arrayField2(record2, "drafts") ?? (Array.isArray(body) ? body : []);
|
|
@@ -49584,6 +49694,16 @@ cassettes.command("validate <id>").description("Run cassette oracle readiness ch
|
|
|
49584
49694
|
cassettes.command("dry-run <id>").description("Run cassette v2 preview simulation with no durable side effects.").option("--draft", "load from cassette_drafts instead of published records").option("--json", "print raw JSON report").option("--config <path>", "override config path").action(async (id, opts) => {
|
|
49585
49695
|
await runCassettesDryRun({ id, draft: opts.draft, json: opts.json, configPath: opts.config });
|
|
49586
49696
|
});
|
|
49697
|
+
cassettes.command("publish <draft_id>").description("Publish a dry-run-approved cassette draft to the tenant tier.").requiredOption("--name <name>", "name for the published cassette").option("--version <n>", "explicit version (server assigns the next one when omitted)", parsePositiveIntFlag).option("--json", "print the raw JSON response").option("--config <path>", "override config path").action(async (draftId, opts) => {
|
|
49698
|
+
const code = await runCassettesPublish({
|
|
49699
|
+
draftId,
|
|
49700
|
+
name: opts.name,
|
|
49701
|
+
version: opts.version,
|
|
49702
|
+
json: opts.json,
|
|
49703
|
+
configPath: opts.config
|
|
49704
|
+
});
|
|
49705
|
+
if (code !== 0) process.exit(code);
|
|
49706
|
+
});
|
|
49587
49707
|
var artifacts = program2.command("artifacts").description("Operate on artifacts.");
|
|
49588
49708
|
artifacts.command("open <artifact_id>").description("Open an artifact URL in the system browser.").option("--config <path>", "override config path").action(async (artifactId, opts) => {
|
|
49589
49709
|
await runArtifactsOpen({ artifactId, configPath: opts.config });
|
package/dist/index.js
CHANGED
|
@@ -28219,7 +28219,7 @@ var init_ask_gary = __esm({
|
|
|
28219
28219
|
thread_id: external_exports2.string().optional().describe("Concrete thread_id to use instead of resolving a named alias. Useful when continuing an artifact discussion thread."),
|
|
28220
28220
|
artifact_ref: external_exports2.string().optional().describe("Artifact id to pin as Gary context. Gary loads the artifact body and tags the resulting thread with artifact_ref."),
|
|
28221
28221
|
fresh: external_exports2.boolean().optional().describe("If true, rotate the thread alias to a brand-new conversation, discarding prior history under that alias."),
|
|
28222
|
-
model_tier: external_exports2.enum(["auto", "fast", "nano", "mini", "reason", "mid", "explore", "premium", "opus"]).optional().describe("Model tier override. Default 'explore' (Sonnet 4.6). Use 'premium' for
|
|
28222
|
+
model_tier: external_exports2.enum(["auto", "fast", "nano", "mini", "reason", "mid", "explore", "premium", "opus"]).optional().describe("Model tier override. Default 'explore' (Sonnet 4.6). Use 'premium' for Opus 4.8 at max thinking, 'opus' for Opus 4.8 standard."),
|
|
28223
28223
|
thinking_level: external_exports2.enum(["off", "minimal", "low", "medium", "high", "xhigh"]).optional().describe("Reasoning effort override. Default 'medium'."),
|
|
28224
28224
|
intent: external_exports2.enum(["cassette_author"]).optional().describe("Set to cassette_author to load Gary cassette-authoring mode prompt/doctrine.")
|
|
28225
28225
|
};
|
|
@@ -29412,12 +29412,6 @@ function registerCassetteAuthoringVerbs(server, gateway) {
|
|
|
29412
29412
|
publishSchema,
|
|
29413
29413
|
async (input) => renderGatewayResult("cassette_publish", await gateway.call("/gateway/cassette/publish", input))
|
|
29414
29414
|
);
|
|
29415
|
-
server.tool(
|
|
29416
|
-
"cassette_request_publish",
|
|
29417
|
-
"Request tenant_admin approval to publish a cassette draft when the caller lacks cassette.publish.",
|
|
29418
|
-
requestPublishSchema,
|
|
29419
|
-
async (input) => renderGatewayResult("cassette_request_publish", await gateway.call("/gateway/cassette/request-publish", input))
|
|
29420
|
-
);
|
|
29421
29415
|
server.tool(
|
|
29422
29416
|
"cassette_get",
|
|
29423
29417
|
"Get a cassette draft or published cassette as YAML plus describe payload.",
|
|
@@ -29470,7 +29464,7 @@ ${JSON.stringify(record2, null, 2)}`;
|
|
|
29470
29464
|
function isRecord(value) {
|
|
29471
29465
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
29472
29466
|
}
|
|
29473
|
-
var recordSchema, draftSchema, refineSchema, dryRunSchema, publishSchema,
|
|
29467
|
+
var recordSchema, draftSchema, refineSchema, dryRunSchema, publishSchema, getSchema, listDraftsSchema, listCapabilitiesSchema;
|
|
29474
29468
|
var init_cassette_authoring = __esm({
|
|
29475
29469
|
"../../lib/gary-mcp/verbs/cassette-authoring.ts"() {
|
|
29476
29470
|
"use strict";
|
|
@@ -29498,10 +29492,6 @@ var init_cassette_authoring = __esm({
|
|
|
29498
29492
|
name: external_exports2.string().min(1),
|
|
29499
29493
|
version: external_exports2.number().int().min(1).optional()
|
|
29500
29494
|
};
|
|
29501
|
-
requestPublishSchema = {
|
|
29502
|
-
draft_id: external_exports2.string().min(1),
|
|
29503
|
-
reason: external_exports2.string().min(1).optional()
|
|
29504
|
-
};
|
|
29505
29495
|
getSchema = {
|
|
29506
29496
|
id: external_exports2.string().min(1).optional(),
|
|
29507
29497
|
draft_id: external_exports2.string().min(1).optional()
|
|
@@ -29551,7 +29541,10 @@ function normalizeProfile(value) {
|
|
|
29551
29541
|
}
|
|
29552
29542
|
function guessPathPrefix(baseUrl) {
|
|
29553
29543
|
if (!baseUrl) return "/api";
|
|
29554
|
-
if (/\.
|
|
29544
|
+
if (/\.exe\.(xyz|dev)/i.test(baseUrl)) {
|
|
29545
|
+
return /\/v2\/?$/.test(baseUrl) ? "/api" : "/v2/api";
|
|
29546
|
+
}
|
|
29547
|
+
if (/\.fly\.dev/i.test(baseUrl)) return "/api";
|
|
29555
29548
|
if (/\.konstant\.cloud/i.test(baseUrl)) return "/api";
|
|
29556
29549
|
if (/\.vercel\.app/i.test(baseUrl)) return "/api";
|
|
29557
29550
|
return "";
|
|
@@ -34581,7 +34574,7 @@ init_esm_shims();
|
|
|
34581
34574
|
init_esm_shims();
|
|
34582
34575
|
|
|
34583
34576
|
// package.json
|
|
34584
|
-
var version = "0.
|
|
34577
|
+
var version = "0.2.0";
|
|
34585
34578
|
|
|
34586
34579
|
// src/lib/version.ts
|
|
34587
34580
|
var BOOMBOX_VERSION = version;
|
|
@@ -42608,6 +42601,17 @@ function resolveGatewayTarget(config2) {
|
|
|
42608
42601
|
function normalizeUrl(url) {
|
|
42609
42602
|
return url.replace(/\/+$/, "");
|
|
42610
42603
|
}
|
|
42604
|
+
function gatewayApiPrefix(baseUrl) {
|
|
42605
|
+
if (!baseUrl) return "/api";
|
|
42606
|
+
if (/\.exe\.(xyz|dev)/i.test(baseUrl)) {
|
|
42607
|
+
return /\/v2\/?$/.test(baseUrl) ? "/api" : "/v2/api";
|
|
42608
|
+
}
|
|
42609
|
+
return "/api";
|
|
42610
|
+
}
|
|
42611
|
+
function resolveGatewayApiBase(config2) {
|
|
42612
|
+
const origin = resolveGatewayTarget(config2).url;
|
|
42613
|
+
return `${origin}${gatewayApiPrefix(origin)}`;
|
|
42614
|
+
}
|
|
42611
42615
|
|
|
42612
42616
|
// src/server/proxy.ts
|
|
42613
42617
|
init_esm_shims();
|
|
@@ -42880,12 +42884,20 @@ function relativeToCwd(absPath) {
|
|
|
42880
42884
|
|
|
42881
42885
|
// src/server/mcp-stdio.ts
|
|
42882
42886
|
init_esm_shims();
|
|
42887
|
+
var DEFAULT_MCP_PROFILE = "advanced";
|
|
42888
|
+
function resolveMcpProfileSelection(flag) {
|
|
42889
|
+
if (flag === void 0) return void 0;
|
|
42890
|
+
return flag === "default" ? DEFAULT_MCP_PROFILE : flag;
|
|
42891
|
+
}
|
|
42883
42892
|
async function startStdioMcp(config2) {
|
|
42884
42893
|
process.env.GARY_MCP_GATEWAY_URL = resolveGateway(config2);
|
|
42885
42894
|
process.env.GARY_MCP_API_KEY = config2.konstant.api_key;
|
|
42886
42895
|
if (!process.env.KONSTANT_API_KEY) {
|
|
42887
42896
|
process.env.KONSTANT_API_KEY = config2.konstant.api_key;
|
|
42888
42897
|
}
|
|
42898
|
+
if (!(process.env.GARY_MCP_PROFILE ?? "").trim()) {
|
|
42899
|
+
process.env.GARY_MCP_PROFILE = DEFAULT_MCP_PROFILE;
|
|
42900
|
+
}
|
|
42889
42901
|
const mod = await Promise.resolve().then(() => (init_gary_mcp(), gary_mcp_exports));
|
|
42890
42902
|
await mod.startGaryMcpServer();
|
|
42891
42903
|
}
|
|
@@ -42925,7 +42937,7 @@ import { readFileSync as readFileSync3 } from "fs";
|
|
|
42925
42937
|
// src/cli/_verify.ts
|
|
42926
42938
|
init_esm_shims();
|
|
42927
42939
|
async function verifyAuth(config2, fetchImpl = fetch) {
|
|
42928
|
-
const url = `${
|
|
42940
|
+
const url = `${resolveGatewayApiBase(config2)}/gateway/rack/list`;
|
|
42929
42941
|
let res;
|
|
42930
42942
|
try {
|
|
42931
42943
|
res = await fetchImpl(url, {
|
|
@@ -42977,7 +42989,7 @@ async function runInit(options = {}) {
|
|
|
42977
42989
|
const preset = {
|
|
42978
42990
|
tenant_id: options.tenantId ?? enrollPayload?.tenant_id ?? existing?.konstant.tenant_id ?? "",
|
|
42979
42991
|
api_key: options.tenantApiKey ?? options.apiKey ?? enrollPayload?.tenant_api_key ?? enrollPayload?.api_key ?? existing?.konstant.api_key ?? "",
|
|
42980
|
-
gateway_url: options.gatewayUrl ?? enrollPayload?.gateway_url ?? existing?.konstant.gateway_url ??
|
|
42992
|
+
gateway_url: options.gatewayUrl ?? enrollPayload?.gateway_url ?? existing?.konstant.gateway_url ?? options.vmUrl ?? enrollPayload?.vm_url ?? existing?.runtime.vm_url ?? "",
|
|
42981
42993
|
vm_url: options.vmUrl ?? enrollPayload?.vm_url ?? existing?.runtime.vm_url ?? ""
|
|
42982
42994
|
};
|
|
42983
42995
|
log("Welcome to Konstant Boombox.");
|
|
@@ -43339,8 +43351,10 @@ async function runServe(options = {}) {
|
|
|
43339
43351
|
log("Note: mcp_enabled=false in config; enabling for this session.");
|
|
43340
43352
|
}
|
|
43341
43353
|
if (enableMcp) {
|
|
43342
|
-
const
|
|
43343
|
-
|
|
43354
|
+
const selectedProfile = resolveMcpProfileSelection(options.profile);
|
|
43355
|
+
if (selectedProfile !== void 0) {
|
|
43356
|
+
process.env.GARY_MCP_PROFILE = selectedProfile;
|
|
43357
|
+
}
|
|
43344
43358
|
process.env.GARY_MCP_TENANT_ID = config2.konstant.tenant_id;
|
|
43345
43359
|
}
|
|
43346
43360
|
const handle = await serve2({
|
package/package.json
CHANGED