@rzx/ohs 1.1.23 → 1.1.25

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.
@@ -1054,6 +1054,7 @@ var init_auto_review = __esm(() => {
1054
1054
  "large_change",
1055
1055
  "many_files",
1056
1056
  "sensitive_path",
1057
+ "sensitive_content_path",
1057
1058
  "production_delete_or_rename",
1058
1059
  "patch_truncated",
1059
1060
  "not_git_repository",
@@ -1064,6 +1065,7 @@ var init_auto_review = __esm(() => {
1064
1065
  "review_output_invalid",
1065
1066
  "review_child_failed",
1066
1067
  "review_child_timed_out",
1068
+ "review_preempted_by_user",
1067
1069
  "parent_run_not_completed",
1068
1070
  "daemon_restarted"
1069
1071
  ];
@@ -3181,133 +3183,155 @@ var init_state = __esm(() => {
3181
3183
  init_session_sync_controller();
3182
3184
  });
3183
3185
 
3184
- // ../../packages/client/src/commands/plugin-presentation.ts
3185
- function formatPluginReload(result) {
3186
- const lines = [result.message];
3187
- if (!result.plugins.length)
3188
- lines.push("No plugins discovered.");
3189
- else {
3190
- lines.push("Plugin validation after reload (runtimes load on next use):");
3191
- for (const plugin of result.plugins) {
3192
- lines.push(`- ${plugin.identity.id} [${plugin.enabled ? "enabled" : "disabled"}/${plugin.installation}/${plugin.activation}]`);
3193
- for (const diagnostic of plugin.diagnostics)
3194
- lines.push(` ${diagnostic.severity}: ${diagnostic.code}: ${diagnostic.message}`);
3195
- if (plugin.permissions.missing.length)
3196
- lines.push(` Missing permissions: ${plugin.permissions.missing.join(", ")}`);
3197
- if (plugin.installation !== "installed" || plugin.permissions.missing.length || plugin.diagnostics.some((item) => item.code.includes("permission"))) {
3198
- lines.push(plugin.scope === "managed" ? " Ask your administrator to repair this managed plugin." : " Review the source and permissions, then run vk plugin install-local <source> or vk plugin link <source>, supplying --approve <permission> for each requested permission.");
3199
- }
3200
- }
3201
- }
3202
- lines.push(...result.warnings.map((warning) => `! ${warning}`));
3203
- return lines.join(`
3204
- `);
3205
- }
3206
-
3207
- // ../../packages/client/src/commands/session-commands.ts
3208
- function parseSlashLine(line) {
3209
- const trimmed = line.trim();
3210
- if (!trimmed.startsWith("/"))
3211
- return null;
3212
- const spaceIdx = trimmed.search(/\s/);
3213
- if (spaceIdx === -1)
3214
- return { name: trimmed, args: "" };
3215
- return { name: trimmed.slice(0, spaceIdx), args: trimmed.slice(spaceIdx + 1).trim() };
3216
- }
3217
- function mergeCommandDetails(catalog) {
3218
- const byName = new Map;
3219
- for (const entry of LOCAL_COMMAND_DETAILS)
3220
- byName.set(entry.name, entry);
3221
- for (const entry of catalog) {
3222
- if (byName.has(entry.name))
3223
- continue;
3224
- byName.set(entry.name, {
3225
- name: entry.name,
3226
- ...entry.description ? { description: entry.description } : {}
3186
+ // ../../packages/client/src/commands/diagnostic-commands.ts
3187
+ async function handleDiagnosticCommand(slash, host, emit, readPresentation) {
3188
+ const { client, sessionId, cwd, clientState, model, permissionMode, statusSessionId, busy } = host;
3189
+ if (slash.name === "/version") {
3190
+ await readPresentation("version", "Version", async () => {
3191
+ const health = await client.protocol.health();
3192
+ return `Vykor${health.version ? ` v${health.version}` : ""}`;
3227
3193
  });
3194
+ return "handled";
3228
3195
  }
3229
- return [...byName.values()].sort((a, b) => a.name.localeCompare(b.name));
3230
- }
3231
- function hasActiveRun(state, sessionId) {
3232
- if (!sessionId)
3233
- return false;
3234
- const bucket = state.buckets[sessionId];
3235
- if (!bucket)
3236
- return false;
3237
- return Object.values(bucket.runs).some((run) => run.status === "pending" || run.status === "running");
3238
- }
3239
- function resolveSessionCwd(input) {
3240
- if (typeof input.statusCwd === "string" && input.statusCwd)
3241
- return input.statusCwd;
3242
- if (input.daemonCwd)
3243
- return input.daemonCwd;
3244
- return input.fallback ?? ".";
3245
- }
3246
- function firstArg(args) {
3247
- return args.trim().split(/\s+/).filter(Boolean)[0];
3248
- }
3249
- function shouldPresentSlashOutput(slash) {
3250
- switch (slash.name) {
3251
- case "/help":
3252
- case "/version":
3253
- case "/status":
3254
- case "/mcp":
3255
- case "/context":
3256
- case "/stats":
3257
- case "/agents":
3258
- case "/doctor":
3259
- case "/usage":
3260
- case "/cost":
3261
- case "/hooks":
3262
- case "/subagents":
3263
- case "/diff":
3264
- case "/skills":
3265
- return true;
3266
- case "/config": {
3267
- const args = slash.args.trim();
3268
- return !args || args === "show";
3269
- }
3270
- case "/provider":
3271
- return !slash.args.trim();
3272
- case "/jobs": {
3273
- const sub = firstArg(slash.args);
3274
- return !sub || sub === "list" || sub === "show";
3275
- }
3276
- case "/memory": {
3277
- const sub = firstArg(slash.args);
3278
- return !sub || sub === "list" || sub === "show";
3279
- }
3280
- case "/facts": {
3281
- const sub = firstArg(slash.args);
3282
- return !sub || sub === "list";
3196
+ if (slash.name === "/status") {
3197
+ emit([
3198
+ "Session status:",
3199
+ ` session: ${statusSessionId ?? "(none)"}`,
3200
+ ` model: ${model ?? "(unknown)"}`,
3201
+ ` cwd: ${cwd || "(unknown)"}`,
3202
+ ` mode: ${permissionMode ?? "default"}`,
3203
+ ` busy: ${busy || hasActiveRun(clientState, sessionId) ? "yes" : "no"}`
3204
+ ].join(`
3205
+ `));
3206
+ return "handled";
3207
+ }
3208
+ if (slash.name === "/context") {
3209
+ const action = slash.args.trim().split(/\s+/).filter(Boolean)[0] ?? "preview";
3210
+ if (action === "status") {
3211
+ await readPresentation(`context:${cwd}:status`, "Context", async () => await client.system.getContextStatus({ cwd }));
3212
+ return "handled";
3283
3213
  }
3284
- case "/auth": {
3285
- const sub = firstArg(slash.args);
3286
- return !sub || sub === "status";
3214
+ if (action === "usage") {
3215
+ await readPresentation(`context:${cwd}:usage:${sessionId ?? "none"}`, "Context", async () => {
3216
+ const result = await client.system.getContextUsage({
3217
+ cwd,
3218
+ ...sessionId ? { sessionId } : {}
3219
+ });
3220
+ return result.report;
3221
+ });
3222
+ return "handled";
3287
3223
  }
3288
- case "/profile": {
3289
- const action = firstArg(slash.args) ?? "status";
3290
- return action === "status" || action === "show";
3224
+ if (action !== "preview") {
3225
+ emit("Usage: /context [preview|status|usage]");
3226
+ return "handled";
3291
3227
  }
3292
- case "/effort":
3293
- case "/turns":
3294
- return !slash.args.trim();
3295
- case "/output-style": {
3296
- const sub = firstArg(slash.args);
3297
- return !sub || sub === "show" || sub === "list";
3228
+ await readPresentation(`context:${cwd}`, "Context", async () => await client.system.getContextPreview({ cwd }));
3229
+ return "handled";
3230
+ }
3231
+ if (slash.name === "/stats") {
3232
+ if (!sessionId)
3233
+ return "handled";
3234
+ const bucket = clientState.buckets[sessionId];
3235
+ const messageCount = bucket?.messages.length ?? 0;
3236
+ const text = (bucket?.messages ?? []).flatMap((message) => bucket?.partsByMessageId[message.id] ?? []).map((part) => part.text ?? "").join(" ");
3237
+ const estimatedTokens = Math.max(1, Math.ceil(text.length / 4));
3238
+ const [memory, jobsResult, settings] = await Promise.all([
3239
+ client.system.listMemory({ cwd }).catch(() => ({ entries: [] })),
3240
+ client.jobs.list({ sessionId, includeFinished: true, limit: 100 }).then((jobs) => ({ jobs })).catch((error) => ({
3241
+ error: error instanceof Error ? error.message : String(error)
3242
+ })),
3243
+ client.system.getSettings().catch(() => ({}))
3244
+ ]);
3245
+ const jobsSummary = "jobs" in jobsResult ? String(jobsResult.jobs.length) : `unavailable (${jobsResult.error})`;
3246
+ emit([
3247
+ "Session stats:",
3248
+ `- messages: ${messageCount}`,
3249
+ `- estimated_tokens: ${estimatedTokens}`,
3250
+ `- memory_entries: ${memory.entries.length}`,
3251
+ `- jobs: ${jobsSummary}`,
3252
+ `- output_style: ${typeof settings.outputStyle === "string" ? settings.outputStyle : "default"}`
3253
+ ].join(`
3254
+ `));
3255
+ return "handled";
3256
+ }
3257
+ if (slash.name === "/agents") {
3258
+ if (!sessionId)
3259
+ return "handled";
3260
+ const agents = await client.jobs.list({
3261
+ sessionId,
3262
+ kinds: ["agent"],
3263
+ includeFinished: true,
3264
+ limit: 100
3265
+ });
3266
+ if (agents.length === 0) {
3267
+ emit("No Agent Jobs.");
3268
+ return "handled";
3298
3269
  }
3299
- case "/plugin": {
3300
- const sub = firstArg(slash.args);
3301
- return !sub || sub === "list";
3270
+ emit([
3271
+ `Agent Jobs (${agents.length}):`,
3272
+ "",
3273
+ ...agents.map((job) => ` ${job.id} [${job.status}] ${job.label}`)
3274
+ ].join(`
3275
+ `));
3276
+ return "handled";
3277
+ }
3278
+ const [settings, auth, memory, mcp, jobsResult] = await Promise.all([
3279
+ client.system.getSettings().catch(() => ({})),
3280
+ client.auth.getStatus().catch(() => null),
3281
+ client.system.listMemory({ cwd }).catch(() => ({ directory: "(unavailable)", entries: [] })),
3282
+ sessionId ? client.system.getSessionMcp(sessionId).catch(() => []) : Promise.resolve([]),
3283
+ sessionId ? client.jobs.list({ sessionId, includeFinished: true, limit: 100 }).then((jobs) => ({ jobs })).catch((error) => ({
3284
+ error: error instanceof Error ? error.message : String(error)
3285
+ })) : Promise.resolve({ jobs: [] })
3286
+ ]);
3287
+ const jobsSummary = "jobs" in jobsResult ? String(jobsResult.jobs.length) : `unavailable (${jobsResult.error})`;
3288
+ const bucket = sessionId ? clientState.buckets[sessionId] : undefined;
3289
+ const diagnostics = await host.getRuntimeDiagnostics?.();
3290
+ const runtime = diagnostics?.runtime ?? "(not provided by this host)";
3291
+ const platform = [diagnostics?.platform, diagnostics?.architecture].filter(Boolean).join(" ") || "(not provided by this host)";
3292
+ const lines = [
3293
+ "Vykor Environment Diagnostic",
3294
+ "\u2550".repeat(40),
3295
+ "",
3296
+ `CWD: ${cwd}`,
3297
+ `Runtime: ${runtime}`,
3298
+ `Platform: ${platform}`,
3299
+ `Model: ${model ?? String(settings.model ?? "(unknown)")}`,
3300
+ `API Format: ${String(settings.apiFormat ?? "(default)")}`,
3301
+ `Base URL: ${String(settings.baseUrl ?? "(default)")}`,
3302
+ `Permission: ${typeof settings.permission === "object" && settings.permission && "mode" in settings.permission ? String(settings.permission.mode ?? "default") : "default"}`,
3303
+ `Max Turns: ${String(settings.maxTurns ?? "(default)")}`,
3304
+ `Effort: ${String(settings.effort ?? "medium")}`,
3305
+ `Passes: ${String(settings.passes ?? 1)}`,
3306
+ `Fast Mode: ${settings.fastMode ? "on" : "off"}`,
3307
+ `Theme: ${String(settings.theme ?? "default")}`,
3308
+ "",
3309
+ `Messages: ${bucket?.messages.length ?? 0}`,
3310
+ `Jobs: ${jobsSummary}`,
3311
+ "",
3312
+ `Memory dir: ${memory.directory}`,
3313
+ `Memory entries: ${memory.entries.length}`
3314
+ ];
3315
+ if (auth) {
3316
+ lines.push("", `Codex auth: ${auth.codex.configured ? "ready" : auth.codex.state} (${auth.codex.source})`, `Stored keys: ${auth.storedProviders.length ? auth.storedProviders.join(", ") : "(none)"}`);
3317
+ }
3318
+ lines.push("", "MCP Servers:");
3319
+ if (mcp.length === 0)
3320
+ lines.push(" (none)");
3321
+ else {
3322
+ for (const server of mcp) {
3323
+ lines.push(` ${server.name}: ${server.status} (${server.toolCount} tools)`);
3302
3324
  }
3303
- case "/branch":
3304
- return !slash.args.trim() || slash.args.trim().split(/\s+/).includes("list");
3305
- case "/commit":
3306
- return !slash.args.trim();
3307
- default:
3308
- return false;
3309
3325
  }
3326
+ emit(lines.join(`
3327
+ `));
3328
+ return "handled";
3310
3329
  }
3330
+ var init_diagnostic_commands = __esm(() => {
3331
+ init_session_commands();
3332
+ });
3333
+
3334
+ // ../../packages/client/src/commands/job-commands.ts
3311
3335
  function formatJobReadResult(result) {
3312
3336
  const snapshot = result.snapshot;
3313
3337
  const capabilities = [
@@ -3337,214 +3361,66 @@ function formatJobReadResult(result) {
3337
3361
  ].join(`
3338
3362
  `);
3339
3363
  }
3340
- function slashOutputTitle(slash) {
3341
- const name = slash.name.startsWith("/") ? slash.name.slice(1) : slash.name;
3342
- return name ? name[0].toUpperCase() + name.slice(1) : "Output";
3343
- }
3344
- async function dispatchSessionCommand(slash, host) {
3345
- const {
3346
- client,
3347
- sessionId,
3348
- cwd,
3349
- model,
3350
- permissionMode,
3351
- statusSessionId,
3352
- commandCatalog,
3353
- clientState,
3354
- busy
3355
- } = host;
3356
- const emit = (text) => {
3357
- if (slash && host.present && shouldPresentSlashOutput(slash)) {
3358
- host.present(slashOutputTitle(slash), text);
3359
- return;
3360
- }
3361
- host.emit(text);
3362
- };
3363
- const readPresentation = async (key, title, load) => {
3364
- if (slash && host.cacheFirstRead && shouldPresentSlashOutput(slash)) {
3365
- host.cacheFirstRead({ key, title, load });
3366
- return;
3367
- }
3368
- emit(await load());
3369
- };
3370
- const patchStatus = (patch) => host.patchStatus?.(patch);
3371
- if (slash?.name === "/plan") {
3372
- const next = slash.args === "on" ? "plan" : slash.args === "off" ? "default" : undefined;
3373
- if (!next) {
3374
- emit("Usage: /plan [on|off]");
3375
- return "handled";
3376
- }
3377
- patchStatus({ permission_mode: next });
3378
- if (sessionId) {
3379
- await client.sessions.update(sessionId, {
3380
- metadata: patchSessionRuntimeMetadata({}, { permissionMode: next })
3381
- });
3382
- }
3383
- emit(`Permission mode: ${next}`);
3384
- return "handled";
3385
- }
3386
- if (slash?.name === "/skills") {
3387
- const templates = commandCatalog.filter((entry) => entry.kind === "template");
3388
- if (slash.args) {
3389
- const name = slash.args.startsWith("/") ? slash.args : `/${slash.args}`;
3390
- const match = templates.find((entry) => entry.name === name || entry.name === `/${slash.args}`);
3391
- if (!match) {
3392
- emit(`Unknown skill: ${slash.args}`);
3393
- return "handled";
3394
- }
3395
- emit(`${match.name}${match.description ? ` \u2014 ${match.description}` : ""}`);
3364
+ async function handleJobCommand(slash, host, emit, readPresentation) {
3365
+ const { client, sessionId } = host;
3366
+ if (slash.name === "/background") {
3367
+ const command = slash.args.trim();
3368
+ if (!command) {
3369
+ emit("Usage: /background <command>");
3396
3370
  return "handled";
3397
3371
  }
3398
- if (templates.length === 0) {
3399
- emit("No user-invocable skills available.");
3372
+ if (!sessionId)
3400
3373
  return "handled";
3401
- }
3402
- emit(["Skills:", ...templates.map((entry) => `- ${entry.name}${entry.description ? ` \u2014 ${entry.description}` : ""}`)].join(`
3403
- `));
3404
- return "handled";
3405
- }
3406
- if (slash?.name === "/help") {
3407
- const details = mergeCommandDetails(commandCatalog);
3408
- emit(["Available commands:", ...details.map((entry) => `${entry.name}${entry.description ? ` \u2014 ${entry.description}` : ""}`)].join(`
3409
- `));
3410
- return "handled";
3411
- }
3412
- if (slash?.name === "/version") {
3413
- await readPresentation("version", "Version", async () => {
3414
- const health = await client.protocol.health();
3415
- return `Vykor${health.version ? ` v${health.version}` : ""}`;
3416
- });
3417
- return "handled";
3418
- }
3419
- if (slash?.name === "/status") {
3420
- emit([
3421
- "Session status:",
3422
- ` session: ${statusSessionId ?? "(none)"}`,
3423
- ` model: ${model ?? "(unknown)"}`,
3424
- ` cwd: ${cwd || "(unknown)"}`,
3425
- ` mode: ${permissionMode ?? "default"}`,
3426
- ` busy: ${busy || hasActiveRun(clientState, sessionId) ? "yes" : "no"}`
3427
- ].join(`
3428
- `));
3374
+ const result = await client.jobs.createBackgroundShell({ sessionId, command });
3375
+ emit(`Background shell started: ${result.jobId}. Use /jobs to inspect it.`);
3429
3376
  return "handled";
3430
3377
  }
3431
- if (slash?.name === "/config") {
3432
- const args = slash.args.trim();
3433
- if (!args || args === "show") {
3434
- await readPresentation(`config:${cwd}`, "Config", async () => {
3435
- const settings = await client.system.getSettings();
3436
- return JSON.stringify(settings, null, 2);
3437
- });
3438
- return "handled";
3439
- }
3440
- const setMatch = args.match(/^set\s+(\S+)\s+([\s\S]+)$/);
3441
- if (!setMatch?.[1] || setMatch[2] === undefined) {
3442
- emit("Usage: /config [show | set KEY VALUE]");
3443
- return "handled";
3444
- }
3445
- await client.system.patchSettings({ path: setMatch[1], value: setMatch[2].trim() });
3446
- emit(`Set ${setMatch[1]} = ${setMatch[2].trim()}`);
3378
+ if (!sessionId)
3447
3379
  return "handled";
3448
- }
3449
- if (slash?.name === "/provider") {
3450
- if (!slash.args) {
3451
- await readPresentation("providers", "Provider", async () => {
3452
- const providers = await client.providers.listProviders();
3453
- const lines = ["Available providers:", ""];
3454
- for (const provider of providers) {
3455
- const marker = provider.active ? " (active)" : "";
3456
- const keyStatus = provider.local ? "[local]" : provider.hasKey ? "[key]" : "[no key]";
3457
- lines.push(` ${provider.name.padEnd(14)} ${provider.displayName.padEnd(14)} ${keyStatus}${marker}`);
3458
- }
3459
- return lines.join(`
3460
- `);
3380
+ const args = slash.args.trim();
3381
+ const [sub, id, ...extra] = args.split(/\s+/).filter(Boolean);
3382
+ if ((!sub || sub === "list") && !id) {
3383
+ await readPresentation(`jobs:${sessionId}`, "Jobs", async () => {
3384
+ const jobs = await client.jobs.list({
3385
+ sessionId,
3386
+ includeFinished: true,
3387
+ limit: 100
3461
3388
  });
3462
- return "handled";
3463
- }
3464
- const settings = await client.system.patchSettings(slash.args === "auto" ? { provider: "auto" } : { provider: slash.args });
3465
- if (typeof settings.model === "string") {
3466
- patchStatus({ model: settings.model });
3467
- }
3468
- emit(`Provider switched to: ${slash.args}`);
3469
- return "handled";
3470
- }
3471
- if (slash?.name === "/mcp") {
3472
- if (!sessionId)
3473
- return "handled";
3474
- await readPresentation(`mcp:${sessionId}`, "MCP", async () => {
3475
- const servers = await client.system.getSessionMcp(sessionId);
3476
- if (servers.length === 0)
3477
- return "No MCP servers connected.";
3389
+ if (jobs.length === 0)
3390
+ return "No Jobs.";
3478
3391
  return [
3479
- `MCP Servers (${servers.length}):`,
3392
+ `Jobs (${jobs.length}):`,
3480
3393
  "",
3481
- ...servers.flatMap((server) => [
3482
- ` ${server.name}: ${server.status}`,
3483
- ...server.command ? [` Command: ${server.command}`] : [],
3484
- ` Tools: ${server.toolCount} Resources: ${server.resourceCount}`,
3485
- ...server.error ? [` Error: ${server.error}`] : [],
3486
- ""
3487
- ])
3394
+ ...jobs.map((job) => ` ${job.id} [${job.status}] ${job.kind}: ${job.label}`)
3488
3395
  ].join(`
3489
3396
  `);
3490
3397
  });
3491
3398
  return "handled";
3492
3399
  }
3493
- if (slash?.name === "/jobs") {
3494
- if (!sessionId)
3495
- return "handled";
3496
- const args = slash.args.trim();
3497
- const [sub, id, ...extra] = args.split(/\s+/).filter(Boolean);
3498
- if ((!sub || sub === "list") && !id) {
3499
- await readPresentation(`jobs:${sessionId}`, "Jobs", async () => {
3500
- const jobs = await client.jobs.list({
3501
- sessionId,
3502
- includeFinished: true,
3503
- limit: 100
3504
- });
3505
- if (jobs.length === 0)
3506
- return "No Jobs.";
3507
- return [
3508
- `Jobs (${jobs.length}):`,
3509
- "",
3510
- ...jobs.map((job) => ` ${job.id} [${job.status}] ${job.kind}: ${job.label}`)
3511
- ].join(`
3512
- `);
3513
- });
3514
- return "handled";
3515
- }
3516
- if (sub === "show" && id && extra.length === 0) {
3517
- await readPresentation(`job:${sessionId}:${id}`, "Jobs", async () => {
3518
- const result = await client.jobs.read(id, { sessionId });
3519
- return formatJobReadResult(result);
3520
- });
3521
- return "handled";
3522
- }
3523
- if (sub === "cancel" && id && extra.length === 0) {
3524
- const snapshot = await client.jobs.cancel(id, {
3525
- sessionId,
3526
- reason: "Cancelled from slash command"
3527
- });
3528
- emit(`Job ${snapshot.id} status: ${snapshot.status}.`);
3529
- return "handled";
3530
- }
3531
- emit("Usage: /jobs [list | show ID | cancel ID]");
3400
+ if (sub === "show" && id && extra.length === 0) {
3401
+ await readPresentation(`job:${sessionId}:${id}`, "Jobs", async () => {
3402
+ const result = await client.jobs.read(id, { sessionId });
3403
+ return formatJobReadResult(result);
3404
+ });
3532
3405
  return "handled";
3533
3406
  }
3534
- if (slash?.name === "/background") {
3535
- const command = slash.args.trim();
3536
- if (!command) {
3537
- emit("Usage: /background <command>");
3538
- return "handled";
3539
- }
3540
- if (!sessionId)
3541
- return "handled";
3542
- const result = await client.jobs.createBackgroundShell({ sessionId, command });
3543
- emit(`Background shell started: ${result.jobId}. Use /jobs to inspect it.`);
3407
+ if (sub === "cancel" && id && extra.length === 0) {
3408
+ const snapshot = await client.jobs.cancel(id, {
3409
+ sessionId,
3410
+ reason: "Cancelled from slash command"
3411
+ });
3412
+ emit(`Job ${snapshot.id} status: ${snapshot.status}.`);
3544
3413
  return "handled";
3545
3414
  }
3546
- if (slash?.name === "/memory") {
3547
- const args = slash.args.trim();
3415
+ emit("Usage: /jobs [list | show ID | cancel ID]");
3416
+ return "handled";
3417
+ }
3418
+
3419
+ // ../../packages/client/src/commands/knowledge-commands.ts
3420
+ async function handleKnowledgeCommand(slash, host, emit, readPresentation) {
3421
+ const { client, cwd, sessionId } = host;
3422
+ const args = slash.args.trim();
3423
+ if (slash.name === "/memory") {
3548
3424
  const [sub, ...rest] = args.split(/\s+/).filter(Boolean);
3549
3425
  if (!sub || sub === "list") {
3550
3426
  await readPresentation(`memory:${cwd}:list`, "Memory", async () => {
@@ -3599,45 +3475,103 @@ No entries found.`;
3599
3475
  emit(`Memory removed: ${rest[0]}`);
3600
3476
  return "handled";
3601
3477
  }
3602
- emit("Usage: /memory [list | show ID | add CONTENT | remove ID]");
3478
+ emit("Usage: /memory [list | show ID | add CONTENT | remove ID]");
3479
+ return "handled";
3480
+ }
3481
+ const sub = args.split(/\s+/).filter(Boolean)[0];
3482
+ if (!sub || sub === "list") {
3483
+ await readPresentation(`facts:${cwd}:list`, "Environment facts", async () => {
3484
+ const { facts } = await client.system.listFacts({ cwd });
3485
+ if (!facts.length)
3486
+ return "No project environment facts found.";
3487
+ return ["Project environment facts:", "", ...facts.map((fact) => {
3488
+ const status = fact.status === "superseded" ? `superseded by ${fact.replacement?.byKey ?? "(unknown)"} (operation ${fact.replacement?.operationId ?? "unknown"})` : "active";
3489
+ const source = fact.manualSource ? `manual replacement ${fact.manualSource.operationId} of ${fact.manualSource.oldKey}` + ` at ${fact.manualSource.at}` + (fact.manualSource.sessionId ? ` in session ${fact.manualSource.sessionId}` : "") : `${fact.sourceSessionId ?? "?"}/${fact.sourceMessageId ?? "?"}`;
3490
+ return ` ${fact.key} [${status}] observed ${fact.observedAt?.slice(0, 10) ?? "unknown"}; source ${source}`;
3491
+ })].join(`
3492
+ `);
3493
+ });
3494
+ return "handled";
3495
+ }
3496
+ if (sub === "replace") {
3497
+ const body = args.slice("replace".length).trim();
3498
+ const separator = body.indexOf("=>");
3499
+ const oldKey = separator < 0 ? "" : body.slice(0, separator).trim();
3500
+ const newValue = separator < 0 ? "" : body.slice(separator + 2).trim();
3501
+ if (!oldKey || !newValue) {
3502
+ emit("Usage: /facts replace <old-key> => <new-value>");
3503
+ return "handled";
3504
+ }
3505
+ const result = await client.system.replaceFact({ cwd, oldKey, newValue, ...sessionId ? { sessionId } : {} });
3506
+ emit([
3507
+ `Environment fact replaced: ${result.oldKey} -> ${result.newKey} (operation ${result.operationId}).`,
3508
+ ...result.relatedActiveKeys.length ? [`Other active facts still mention the old address: ${result.relatedActiveKeys.join(", ")}`] : [],
3509
+ ...result.cacheWarning ? [`Warning: ${result.cacheWarning}`] : []
3510
+ ].join(`
3511
+ `));
3512
+ return "handled";
3513
+ }
3514
+ emit("Usage: /facts [list | replace <old-key> => <new-value>]");
3515
+ return "handled";
3516
+ }
3517
+
3518
+ // ../../packages/client/src/commands/settings-commands.ts
3519
+ async function handleSettingsCommand(slash, host, emit, readPresentation) {
3520
+ const { client, cwd, sessionId } = host;
3521
+ const patchStatus = (patch) => host.patchStatus?.(patch);
3522
+ if (slash?.name === "/plan") {
3523
+ const next = slash.args === "on" ? "plan" : slash.args === "off" ? "default" : undefined;
3524
+ if (!next) {
3525
+ emit("Usage: /plan [on|off]");
3526
+ return "handled";
3527
+ }
3528
+ patchStatus({ permission_mode: next });
3529
+ if (sessionId) {
3530
+ await client.sessions.update(sessionId, {
3531
+ metadata: patchSessionRuntimeMetadata({}, { permissionMode: next })
3532
+ });
3533
+ }
3534
+ emit(`Permission mode: ${next}`);
3535
+ return "handled";
3536
+ }
3537
+ if (slash?.name === "/config") {
3538
+ const args = slash.args.trim();
3539
+ if (!args || args === "show") {
3540
+ await readPresentation(`config:${cwd}`, "Config", async () => {
3541
+ const settings = await client.system.getSettings();
3542
+ return JSON.stringify(settings, null, 2);
3543
+ });
3544
+ return "handled";
3545
+ }
3546
+ const setMatch = args.match(/^set\s+(\S+)\s+([\s\S]+)$/);
3547
+ if (!setMatch?.[1] || setMatch[2] === undefined) {
3548
+ emit("Usage: /config [show | set KEY VALUE]");
3549
+ return "handled";
3550
+ }
3551
+ await client.system.patchSettings({ path: setMatch[1], value: setMatch[2].trim() });
3552
+ emit(`Set ${setMatch[1]} = ${setMatch[2].trim()}`);
3603
3553
  return "handled";
3604
3554
  }
3605
- if (slash?.name === "/facts") {
3606
- const args = slash.args.trim();
3607
- const sub = firstArg(args);
3608
- if (!sub || sub === "list") {
3609
- await readPresentation(`facts:${cwd}:list`, "Environment facts", async () => {
3610
- const { facts } = await client.system.listFacts({ cwd });
3611
- if (!facts.length)
3612
- return "No project environment facts found.";
3613
- return ["Project environment facts:", "", ...facts.map((fact) => {
3614
- const status = fact.status === "superseded" ? `superseded by ${fact.replacement?.byKey ?? "(unknown)"} (operation ${fact.replacement?.operationId ?? "unknown"})` : "active";
3615
- const source = fact.manualSource ? `manual replacement ${fact.manualSource.operationId} of ${fact.manualSource.oldKey}` + ` at ${fact.manualSource.at}` + (fact.manualSource.sessionId ? ` in session ${fact.manualSource.sessionId}` : "") : `${fact.sourceSessionId ?? "?"}/${fact.sourceMessageId ?? "?"}`;
3616
- return ` ${fact.key} [${status}] observed ${fact.observedAt?.slice(0, 10) ?? "unknown"}; source ${source}`;
3617
- })].join(`
3555
+ if (slash?.name === "/provider") {
3556
+ if (!slash.args) {
3557
+ await readPresentation("providers", "Provider", async () => {
3558
+ const providers = await client.providers.listProviders();
3559
+ const lines = ["Available providers:", ""];
3560
+ for (const provider of providers) {
3561
+ const marker = provider.active ? " (active)" : "";
3562
+ const keyStatus = provider.local ? "[local]" : provider.hasKey ? "[key]" : "[no key]";
3563
+ lines.push(` ${provider.name.padEnd(14)} ${provider.displayName.padEnd(14)} ${keyStatus}${marker}`);
3564
+ }
3565
+ return lines.join(`
3618
3566
  `);
3619
3567
  });
3620
3568
  return "handled";
3621
3569
  }
3622
- if (sub === "replace") {
3623
- const body = args.slice("replace".length).trim();
3624
- const separator = body.indexOf("=>");
3625
- const oldKey = separator < 0 ? "" : body.slice(0, separator).trim();
3626
- const newValue = separator < 0 ? "" : body.slice(separator + 2).trim();
3627
- if (!oldKey || !newValue) {
3628
- emit("Usage: /facts replace <old-key> => <new-value>");
3629
- return "handled";
3630
- }
3631
- const result = await client.system.replaceFact({ cwd, oldKey, newValue, ...sessionId ? { sessionId } : {} });
3632
- emit([
3633
- `Environment fact replaced: ${result.oldKey} -> ${result.newKey} (operation ${result.operationId}).`,
3634
- ...result.relatedActiveKeys.length ? [`Other active facts still mention the old address: ${result.relatedActiveKeys.join(", ")}`] : [],
3635
- ...result.cacheWarning ? [`Warning: ${result.cacheWarning}`] : []
3636
- ].join(`
3637
- `));
3638
- return "handled";
3570
+ const settings = await client.system.patchSettings(slash.args === "auto" ? { provider: "auto" } : { provider: slash.args });
3571
+ if (typeof settings.model === "string") {
3572
+ patchStatus({ model: settings.model });
3639
3573
  }
3640
- emit("Usage: /facts [list | replace <old-key> => <new-value>]");
3574
+ emit(`Provider switched to: ${slash.args}`);
3641
3575
  return "handled";
3642
3576
  }
3643
3577
  if (slash?.name === "/auth") {
@@ -3677,88 +3611,343 @@ No entries found.`;
3677
3611
  emit(result.message);
3678
3612
  return "handled";
3679
3613
  }
3680
- if (sub === "logout") {
3681
- if (!provider) {
3682
- emit("Usage: /auth logout <provider>");
3683
- return "handled";
3684
- }
3685
- const result = await client.auth.logout({ provider });
3686
- emit(result.message);
3687
- return "handled";
3614
+ if (sub === "logout") {
3615
+ if (!provider) {
3616
+ emit("Usage: /auth logout <provider>");
3617
+ return "handled";
3618
+ }
3619
+ const result = await client.auth.logout({ provider });
3620
+ emit(result.message);
3621
+ return "handled";
3622
+ }
3623
+ emit("Unknown subcommand. Use login, logout, or status.");
3624
+ return "handled";
3625
+ }
3626
+ if (slash?.name === "/profile") {
3627
+ const action = slash.args.trim().split(/\s+/).filter(Boolean)[0] ?? "status";
3628
+ if (action === "status" || action === "show") {
3629
+ emit(await client.system.getProfileStatus());
3630
+ return "handled";
3631
+ }
3632
+ if (action === "init") {
3633
+ emit(await client.system.initProfile());
3634
+ return "handled";
3635
+ }
3636
+ emit("Usage: /profile [status|init]");
3637
+ return "handled";
3638
+ }
3639
+ if (slash?.name === "/effort") {
3640
+ const level = slash.args.trim().split(/\s+/).filter(Boolean)[0];
3641
+ if (!level) {
3642
+ const settings = await client.system.getSettings();
3643
+ emit(`Current effort: ${String(settings.effort ?? "medium")}`);
3644
+ return "handled";
3645
+ }
3646
+ if (!level.trim()) {
3647
+ emit("Invalid effort. Provide a non-empty reasoning effort value");
3648
+ return "handled";
3649
+ }
3650
+ await client.system.patchSettings({ effort: level });
3651
+ emit(`Effort set to: ${level}`);
3652
+ return "handled";
3653
+ }
3654
+ if (slash?.name === "/fast") {
3655
+ const arg = slash.args.trim().split(/\s+/).filter(Boolean)[0];
3656
+ const settings = await client.system.getSettings();
3657
+ const current = settings.fastMode === true;
3658
+ let next;
3659
+ if (arg === "on")
3660
+ next = true;
3661
+ else if (arg === "off")
3662
+ next = false;
3663
+ else
3664
+ next = !current;
3665
+ await client.system.patchSettings({ fastMode: next });
3666
+ emit(`Fast mode: ${next ? "ON" : "OFF"}`);
3667
+ return "handled";
3668
+ }
3669
+ if (slash?.name === "/reasoning") {
3670
+ const arg = slash.args.trim().split(/\s+/).filter(Boolean)[0];
3671
+ const settings = await client.system.getSettings();
3672
+ const current = settings.showReasoning !== false;
3673
+ let next;
3674
+ if (arg === "on")
3675
+ next = true;
3676
+ else if (arg === "off")
3677
+ next = false;
3678
+ else
3679
+ next = !current;
3680
+ await client.system.patchSettings({ showReasoning: next });
3681
+ emit(`Reasoning: ${next ? "ON" : "OFF"}`);
3682
+ return "handled";
3683
+ }
3684
+ if (slash?.name === "/turns") {
3685
+ const value = slash.args.trim().split(/\s+/).filter(Boolean)[0];
3686
+ if (!value) {
3687
+ const settings = await client.system.getSettings();
3688
+ emit(`Current max turns: ${String(settings.maxTurns ?? "(default)")}`);
3689
+ return "handled";
3690
+ }
3691
+ const n = Number.parseInt(value, 10);
3692
+ if (!Number.isFinite(n) || n < 1 || n > 512) {
3693
+ emit("Value must be between 1 and 512");
3694
+ return "handled";
3695
+ }
3696
+ await client.system.patchSettings({ maxTurns: n });
3697
+ emit(`Max turns set to: ${n}`);
3698
+ return "handled";
3699
+ }
3700
+ if (slash?.name === "/output-style") {
3701
+ const args = slash.args.trim();
3702
+ const styles = await client.system.listOutputStyles();
3703
+ const settings = await client.system.getSettings();
3704
+ const current = typeof settings.outputStyle === "string" ? settings.outputStyle : "default";
3705
+ const firstSpace = args.search(/\s/);
3706
+ const first = firstSpace === -1 ? args : args.slice(0, firstSpace);
3707
+ const rest = firstSpace === -1 ? "" : args.slice(firstSpace + 1).trim();
3708
+ if (!first || first === "show") {
3709
+ emit(`Output style: ${current}`);
3710
+ return "handled";
3711
+ }
3712
+ if (first === "list") {
3713
+ emit(styles.map((style) => `${style.name === current ? "* " : " "}${style.name} [${style.source}]`).join(`
3714
+ `));
3715
+ return "handled";
3716
+ }
3717
+ const styleName = first === "set" && rest ? rest : rest === "" ? first : undefined;
3718
+ if (!styleName) {
3719
+ emit("Usage: /output-style [show|list|NAME]");
3720
+ return "handled";
3721
+ }
3722
+ if (!styles.some((style) => style.name === styleName)) {
3723
+ emit(`Unknown output style: ${styleName}`);
3724
+ return "handled";
3725
+ }
3726
+ await client.system.patchSettings({ outputStyle: styleName });
3727
+ emit(`Output style set to ${styleName}`);
3728
+ return "handled";
3729
+ }
3730
+ return "handled";
3731
+ }
3732
+ var init_settings_commands = __esm(() => {
3733
+ init_src();
3734
+ });
3735
+
3736
+ // ../../packages/client/src/commands/plugin-presentation.ts
3737
+ function formatPluginReload(result) {
3738
+ const lines = [result.message];
3739
+ if (!result.plugins.length)
3740
+ lines.push("No plugins discovered.");
3741
+ else {
3742
+ lines.push("Plugin validation after reload (runtimes load on next use):");
3743
+ for (const plugin of result.plugins) {
3744
+ lines.push(`- ${plugin.identity.id} [${plugin.enabled ? "enabled" : "disabled"}/${plugin.installation}/${plugin.activation}]`);
3745
+ for (const diagnostic of plugin.diagnostics)
3746
+ lines.push(` ${diagnostic.severity}: ${diagnostic.code}: ${diagnostic.message}`);
3747
+ if (plugin.permissions.missing.length)
3748
+ lines.push(` Missing permissions: ${plugin.permissions.missing.join(", ")}`);
3749
+ if (plugin.installation !== "installed" || plugin.permissions.missing.length || plugin.diagnostics.some((item) => item.code.includes("permission"))) {
3750
+ lines.push(plugin.scope === "managed" ? " Ask your administrator to repair this managed plugin." : " Review the source and permissions, then run vk plugin install-local <source> or vk plugin link <source>, supplying --approve <permission> for each requested permission.");
3751
+ }
3752
+ }
3753
+ }
3754
+ lines.push(...result.warnings.map((warning) => `! ${warning}`));
3755
+ return lines.join(`
3756
+ `);
3757
+ }
3758
+
3759
+ // ../../packages/client/src/commands/session-commands.ts
3760
+ function parseSlashLine(line) {
3761
+ const trimmed = line.trim();
3762
+ if (!trimmed.startsWith("/"))
3763
+ return null;
3764
+ const spaceIdx = trimmed.search(/\s/);
3765
+ if (spaceIdx === -1)
3766
+ return { name: trimmed, args: "" };
3767
+ return { name: trimmed.slice(0, spaceIdx), args: trimmed.slice(spaceIdx + 1).trim() };
3768
+ }
3769
+ function mergeCommandDetails(catalog) {
3770
+ const byName = new Map;
3771
+ for (const entry of LOCAL_COMMAND_DETAILS)
3772
+ byName.set(entry.name, entry);
3773
+ for (const entry of catalog) {
3774
+ if (byName.has(entry.name))
3775
+ continue;
3776
+ byName.set(entry.name, {
3777
+ name: entry.name,
3778
+ ...entry.description ? { description: entry.description } : {}
3779
+ });
3780
+ }
3781
+ return [...byName.values()].sort((a, b) => a.name.localeCompare(b.name));
3782
+ }
3783
+ function hasActiveRun(state, sessionId) {
3784
+ if (!sessionId)
3785
+ return false;
3786
+ const bucket = state.buckets[sessionId];
3787
+ if (!bucket)
3788
+ return false;
3789
+ return Object.values(bucket.runs).some((run) => run.status === "pending" || run.status === "running");
3790
+ }
3791
+ function resolveSessionCwd(input) {
3792
+ if (typeof input.statusCwd === "string" && input.statusCwd)
3793
+ return input.statusCwd;
3794
+ if (input.daemonCwd)
3795
+ return input.daemonCwd;
3796
+ return input.fallback ?? ".";
3797
+ }
3798
+ function firstArg(args) {
3799
+ return args.trim().split(/\s+/).filter(Boolean)[0];
3800
+ }
3801
+ function shouldPresentSlashOutput(slash) {
3802
+ switch (slash.name) {
3803
+ case "/help":
3804
+ case "/version":
3805
+ case "/status":
3806
+ case "/mcp":
3807
+ case "/context":
3808
+ case "/stats":
3809
+ case "/agents":
3810
+ case "/doctor":
3811
+ case "/usage":
3812
+ case "/cost":
3813
+ case "/hooks":
3814
+ case "/subagents":
3815
+ case "/diff":
3816
+ case "/skills":
3817
+ return true;
3818
+ case "/config": {
3819
+ const args = slash.args.trim();
3820
+ return !args || args === "show";
3821
+ }
3822
+ case "/provider":
3823
+ return !slash.args.trim();
3824
+ case "/jobs": {
3825
+ const sub = firstArg(slash.args);
3826
+ return !sub || sub === "list" || sub === "show";
3827
+ }
3828
+ case "/memory": {
3829
+ const sub = firstArg(slash.args);
3830
+ return !sub || sub === "list" || sub === "show";
3831
+ }
3832
+ case "/facts": {
3833
+ const sub = firstArg(slash.args);
3834
+ return !sub || sub === "list";
3835
+ }
3836
+ case "/auth": {
3837
+ const sub = firstArg(slash.args);
3838
+ return !sub || sub === "status";
3839
+ }
3840
+ case "/profile": {
3841
+ const action = firstArg(slash.args) ?? "status";
3842
+ return action === "status" || action === "show";
3843
+ }
3844
+ case "/effort":
3845
+ case "/turns":
3846
+ return !slash.args.trim();
3847
+ case "/output-style": {
3848
+ const sub = firstArg(slash.args);
3849
+ return !sub || sub === "show" || sub === "list";
3688
3850
  }
3689
- emit("Unknown subcommand. Use login, logout, or status.");
3690
- return "handled";
3851
+ case "/plugin": {
3852
+ const sub = firstArg(slash.args);
3853
+ return !sub || sub === "list";
3854
+ }
3855
+ case "/branch":
3856
+ return !slash.args.trim() || slash.args.trim().split(/\s+/).includes("list");
3857
+ case "/commit":
3858
+ return !slash.args.trim();
3859
+ default:
3860
+ return false;
3691
3861
  }
3692
- if (slash?.name === "/context") {
3693
- const action = slash.args.trim().split(/\s+/).filter(Boolean)[0] ?? "preview";
3694
- if (action === "status") {
3695
- await readPresentation(`context:${cwd}:status`, "Context", async () => await client.system.getContextStatus({ cwd }));
3696
- return "handled";
3862
+ }
3863
+ function slashOutputTitle(slash) {
3864
+ const name = slash.name.startsWith("/") ? slash.name.slice(1) : slash.name;
3865
+ return name ? name[0].toUpperCase() + name.slice(1) : "Output";
3866
+ }
3867
+ async function dispatchSessionCommand(slash, host) {
3868
+ const {
3869
+ client,
3870
+ sessionId,
3871
+ cwd,
3872
+ commandCatalog
3873
+ } = host;
3874
+ const emit = (text) => {
3875
+ if (slash && host.present && shouldPresentSlashOutput(slash)) {
3876
+ host.present(slashOutputTitle(slash), text);
3877
+ return;
3697
3878
  }
3698
- if (action === "usage") {
3699
- await readPresentation(`context:${cwd}:usage:${sessionId ?? "none"}`, "Context", async () => {
3700
- const result = await client.system.getContextUsage({
3701
- cwd,
3702
- ...sessionId ? { sessionId } : {}
3703
- });
3704
- return result.report;
3705
- });
3879
+ host.emit(text);
3880
+ };
3881
+ const readPresentation = async (key, title, load) => {
3882
+ if (slash && host.cacheFirstRead && shouldPresentSlashOutput(slash)) {
3883
+ host.cacheFirstRead({ key, title, load });
3884
+ return;
3885
+ }
3886
+ emit(await load());
3887
+ };
3888
+ if (slash && ["/plan", "/config", "/provider", "/auth", "/profile", "/effort", "/fast", "/reasoning", "/turns", "/output-style"].includes(slash.name)) {
3889
+ return handleSettingsCommand(slash, host, emit, readPresentation);
3890
+ }
3891
+ if (slash?.name === "/skills") {
3892
+ const templates = commandCatalog.filter((entry) => entry.kind === "template");
3893
+ if (slash.args) {
3894
+ const name = slash.args.startsWith("/") ? slash.args : `/${slash.args}`;
3895
+ const match = templates.find((entry) => entry.name === name || entry.name === `/${slash.args}`);
3896
+ if (!match) {
3897
+ emit(`Unknown skill: ${slash.args}`);
3898
+ return "handled";
3899
+ }
3900
+ emit(`${match.name}${match.description ? ` \u2014 ${match.description}` : ""}`);
3706
3901
  return "handled";
3707
3902
  }
3708
- if (action !== "preview") {
3709
- emit("Usage: /context [preview|status|usage]");
3903
+ if (templates.length === 0) {
3904
+ emit("No user-invocable skills available.");
3710
3905
  return "handled";
3711
3906
  }
3712
- await readPresentation(`context:${cwd}`, "Context", async () => await client.system.getContextPreview({ cwd }));
3907
+ emit(["Skills:", ...templates.map((entry) => `- ${entry.name}${entry.description ? ` \u2014 ${entry.description}` : ""}`)].join(`
3908
+ `));
3713
3909
  return "handled";
3714
3910
  }
3715
- if (slash?.name === "/stats") {
3716
- if (!sessionId)
3717
- return "handled";
3718
- const bucket = clientState.buckets[sessionId];
3719
- const messageCount = bucket?.messages.length ?? 0;
3720
- const text = (bucket?.messages ?? []).flatMap((message) => bucket?.partsByMessageId[message.id] ?? []).map((part) => part.text ?? "").join(" ");
3721
- const estimatedTokens = Math.max(1, Math.ceil(text.length / 4));
3722
- const [memory, jobsResult, settings] = await Promise.all([
3723
- client.system.listMemory({ cwd }).catch(() => ({ entries: [] })),
3724
- client.jobs.list({ sessionId, includeFinished: true, limit: 100 }).then((jobs) => ({ jobs })).catch((error) => ({
3725
- error: error instanceof Error ? error.message : String(error)
3726
- })),
3727
- client.system.getSettings().catch(() => ({}))
3728
- ]);
3729
- const jobsSummary = "jobs" in jobsResult ? String(jobsResult.jobs.length) : `unavailable (${jobsResult.error})`;
3730
- emit([
3731
- "Session stats:",
3732
- `- messages: ${messageCount}`,
3733
- `- estimated_tokens: ${estimatedTokens}`,
3734
- `- memory_entries: ${memory.entries.length}`,
3735
- `- jobs: ${jobsSummary}`,
3736
- `- output_style: ${typeof settings.outputStyle === "string" ? settings.outputStyle : "default"}`
3737
- ].join(`
3911
+ if (slash?.name === "/help") {
3912
+ const details = mergeCommandDetails(commandCatalog);
3913
+ emit(["Available commands:", ...details.map((entry) => `${entry.name}${entry.description ? ` \u2014 ${entry.description}` : ""}`)].join(`
3738
3914
  `));
3739
3915
  return "handled";
3740
3916
  }
3741
- if (slash?.name === "/agents") {
3917
+ if (slash && (slash.name === "/version" || slash.name === "/status")) {
3918
+ return handleDiagnosticCommand(slash, host, emit, readPresentation);
3919
+ }
3920
+ if (slash?.name === "/mcp") {
3742
3921
  if (!sessionId)
3743
3922
  return "handled";
3744
- const agents = await client.jobs.list({
3745
- sessionId,
3746
- kinds: ["agent"],
3747
- includeFinished: true,
3748
- limit: 100
3923
+ await readPresentation(`mcp:${sessionId}`, "MCP", async () => {
3924
+ const servers = await client.system.getSessionMcp(sessionId);
3925
+ if (servers.length === 0)
3926
+ return "No MCP servers connected.";
3927
+ return [
3928
+ `MCP Servers (${servers.length}):`,
3929
+ "",
3930
+ ...servers.flatMap((server) => [
3931
+ ` ${server.name}: ${server.status}`,
3932
+ ...server.command ? [` Command: ${server.command}`] : [],
3933
+ ` Tools: ${server.toolCount} Resources: ${server.resourceCount}`,
3934
+ ...server.error ? [` Error: ${server.error}`] : [],
3935
+ ""
3936
+ ])
3937
+ ].join(`
3938
+ `);
3749
3939
  });
3750
- if (agents.length === 0) {
3751
- emit("No Agent Jobs.");
3752
- return "handled";
3753
- }
3754
- emit([
3755
- `Agent Jobs (${agents.length}):`,
3756
- "",
3757
- ...agents.map((job) => ` ${job.id} [${job.status}] ${job.label}`)
3758
- ].join(`
3759
- `));
3760
3940
  return "handled";
3761
3941
  }
3942
+ if (slash?.name === "/jobs" || slash?.name === "/background") {
3943
+ return handleJobCommand(slash, host, emit, readPresentation);
3944
+ }
3945
+ if (slash?.name === "/memory" || slash?.name === "/facts") {
3946
+ return handleKnowledgeCommand(slash, host, emit, readPresentation);
3947
+ }
3948
+ if (slash && (slash.name === "/context" || slash.name === "/stats" || slash.name === "/agents")) {
3949
+ return handleDiagnosticCommand(slash, host, emit, readPresentation);
3950
+ }
3762
3951
  if (slash?.name === "/rewind") {
3763
3952
  if (!sessionId)
3764
3953
  return "handled";
@@ -3800,132 +3989,8 @@ No entries found.`;
3800
3989
  emit(`Dream started as Job ${result.taskId}. Use /jobs to inspect it.`);
3801
3990
  return "handled";
3802
3991
  }
3803
- if (slash?.name === "/profile") {
3804
- const action = slash.args.trim().split(/\s+/).filter(Boolean)[0] ?? "status";
3805
- if (action === "status" || action === "show") {
3806
- emit(await client.system.getProfileStatus());
3807
- return "handled";
3808
- }
3809
- if (action === "init") {
3810
- emit(await client.system.initProfile());
3811
- return "handled";
3812
- }
3813
- emit("Usage: /profile [status|init]");
3814
- return "handled";
3815
- }
3816
3992
  if (slash?.name === "/doctor") {
3817
- const [settings, auth, memory, mcp, jobsResult] = await Promise.all([
3818
- client.system.getSettings().catch(() => ({})),
3819
- client.auth.getStatus().catch(() => null),
3820
- client.system.listMemory({ cwd }).catch(() => ({ directory: "(unavailable)", entries: [] })),
3821
- sessionId ? client.system.getSessionMcp(sessionId).catch(() => []) : Promise.resolve([]),
3822
- sessionId ? client.jobs.list({ sessionId, includeFinished: true, limit: 100 }).then((jobs) => ({ jobs })).catch((error) => ({
3823
- error: error instanceof Error ? error.message : String(error)
3824
- })) : Promise.resolve({ jobs: [] })
3825
- ]);
3826
- const jobsSummary = "jobs" in jobsResult ? String(jobsResult.jobs.length) : `unavailable (${jobsResult.error})`;
3827
- const bucket = sessionId ? clientState.buckets[sessionId] : undefined;
3828
- const diagnostics = await host.getRuntimeDiagnostics?.();
3829
- const runtime = diagnostics?.runtime ?? "(not provided by this host)";
3830
- const platform = [diagnostics?.platform, diagnostics?.architecture].filter(Boolean).join(" ") || "(not provided by this host)";
3831
- const lines = [
3832
- "Vykor Environment Diagnostic",
3833
- "\u2550".repeat(40),
3834
- "",
3835
- `CWD: ${cwd}`,
3836
- `Runtime: ${runtime}`,
3837
- `Platform: ${platform}`,
3838
- `Model: ${model ?? String(settings.model ?? "(unknown)")}`,
3839
- `API Format: ${String(settings.apiFormat ?? "(default)")}`,
3840
- `Base URL: ${String(settings.baseUrl ?? "(default)")}`,
3841
- `Permission: ${typeof settings.permission === "object" && settings.permission && "mode" in settings.permission ? String(settings.permission.mode ?? "default") : "default"}`,
3842
- `Max Turns: ${String(settings.maxTurns ?? "(default)")}`,
3843
- `Effort: ${String(settings.effort ?? "medium")}`,
3844
- `Passes: ${String(settings.passes ?? 1)}`,
3845
- `Fast Mode: ${settings.fastMode ? "on" : "off"}`,
3846
- `Theme: ${String(settings.theme ?? "default")}`,
3847
- "",
3848
- `Messages: ${bucket?.messages.length ?? 0}`,
3849
- `Jobs: ${jobsSummary}`,
3850
- "",
3851
- `Memory dir: ${memory.directory}`,
3852
- `Memory entries: ${memory.entries.length}`
3853
- ];
3854
- if (auth) {
3855
- lines.push("", `Codex auth: ${auth.codex.configured ? "ready" : auth.codex.state} (${auth.codex.source})`, `Stored keys: ${auth.storedProviders.length ? auth.storedProviders.join(", ") : "(none)"}`);
3856
- }
3857
- lines.push("", "MCP Servers:");
3858
- if (mcp.length === 0)
3859
- lines.push(" (none)");
3860
- else {
3861
- for (const server of mcp) {
3862
- lines.push(` ${server.name}: ${server.status} (${server.toolCount} tools)`);
3863
- }
3864
- }
3865
- emit(lines.join(`
3866
- `));
3867
- return "handled";
3868
- }
3869
- if (slash?.name === "/effort") {
3870
- const level = slash.args.trim().split(/\s+/).filter(Boolean)[0];
3871
- if (!level) {
3872
- const settings = await client.system.getSettings();
3873
- emit(`Current effort: ${String(settings.effort ?? "medium")}`);
3874
- return "handled";
3875
- }
3876
- if (!level.trim()) {
3877
- emit("Invalid effort. Provide a non-empty reasoning effort value");
3878
- return "handled";
3879
- }
3880
- await client.system.patchSettings({ effort: level });
3881
- emit(`Effort set to: ${level}`);
3882
- return "handled";
3883
- }
3884
- if (slash?.name === "/fast") {
3885
- const arg = slash.args.trim().split(/\s+/).filter(Boolean)[0];
3886
- const settings = await client.system.getSettings();
3887
- const current = settings.fastMode === true;
3888
- let next;
3889
- if (arg === "on")
3890
- next = true;
3891
- else if (arg === "off")
3892
- next = false;
3893
- else
3894
- next = !current;
3895
- await client.system.patchSettings({ fastMode: next });
3896
- emit(`Fast mode: ${next ? "ON" : "OFF"}`);
3897
- return "handled";
3898
- }
3899
- if (slash?.name === "/reasoning") {
3900
- const arg = slash.args.trim().split(/\s+/).filter(Boolean)[0];
3901
- const settings = await client.system.getSettings();
3902
- const current = settings.showReasoning !== false;
3903
- let next;
3904
- if (arg === "on")
3905
- next = true;
3906
- else if (arg === "off")
3907
- next = false;
3908
- else
3909
- next = !current;
3910
- await client.system.patchSettings({ showReasoning: next });
3911
- emit(`Reasoning: ${next ? "ON" : "OFF"}`);
3912
- return "handled";
3913
- }
3914
- if (slash?.name === "/turns") {
3915
- const value = slash.args.trim().split(/\s+/).filter(Boolean)[0];
3916
- if (!value) {
3917
- const settings = await client.system.getSettings();
3918
- emit(`Current max turns: ${String(settings.maxTurns ?? "(default)")}`);
3919
- return "handled";
3920
- }
3921
- const n = Number.parseInt(value, 10);
3922
- if (!Number.isFinite(n) || n < 1 || n > 512) {
3923
- emit("Value must be between 1 and 512");
3924
- return "handled";
3925
- }
3926
- await client.system.patchSettings({ maxTurns: n });
3927
- emit(`Max turns set to: ${n}`);
3928
- return "handled";
3993
+ return handleDiagnosticCommand(slash, host, emit, readPresentation);
3929
3994
  }
3930
3995
  if (slash?.name === "/usage" || slash?.name === "/cost") {
3931
3996
  if (!sessionId)
@@ -3975,36 +4040,6 @@ No entries found.`;
3975
4040
  emit(`Exported ${result.format === "json" ? "JSON" : "Markdown"} to: ${result.filepath}`);
3976
4041
  return "handled";
3977
4042
  }
3978
- if (slash?.name === "/output-style") {
3979
- const args = slash.args.trim();
3980
- const styles = await client.system.listOutputStyles();
3981
- const settings = await client.system.getSettings();
3982
- const current = typeof settings.outputStyle === "string" ? settings.outputStyle : "default";
3983
- const firstSpace = args.search(/\s/);
3984
- const first = firstSpace === -1 ? args : args.slice(0, firstSpace);
3985
- const rest = firstSpace === -1 ? "" : args.slice(firstSpace + 1).trim();
3986
- if (!first || first === "show") {
3987
- emit(`Output style: ${current}`);
3988
- return "handled";
3989
- }
3990
- if (first === "list") {
3991
- emit(styles.map((style) => `${style.name === current ? "* " : " "}${style.name} [${style.source}]`).join(`
3992
- `));
3993
- return "handled";
3994
- }
3995
- const styleName = first === "set" && rest ? rest : rest === "" ? first : undefined;
3996
- if (!styleName) {
3997
- emit("Usage: /output-style [show|list|NAME]");
3998
- return "handled";
3999
- }
4000
- if (!styles.some((style) => style.name === styleName)) {
4001
- emit(`Unknown output style: ${styleName}`);
4002
- return "handled";
4003
- }
4004
- await client.system.patchSettings({ outputStyle: styleName });
4005
- emit(`Output style set to ${styleName}`);
4006
- return "handled";
4007
- }
4008
4043
  if (slash?.name === "/init") {
4009
4044
  emit(await client.projects.init({ cwd }));
4010
4045
  return "handled";
@@ -4110,7 +4145,8 @@ No entries found.`;
4110
4145
  }
4111
4146
  var LOCAL_COMMAND_DETAILS, LOCAL_COMMAND_NAMES;
4112
4147
  var init_session_commands = __esm(() => {
4113
- init_src();
4148
+ init_diagnostic_commands();
4149
+ init_settings_commands();
4114
4150
  LOCAL_COMMAND_DETAILS = [
4115
4151
  { name: "/new", description: "Start a new session" },
4116
4152
  { name: "/sessions", description: "List and switch sessions" },
@@ -9458,4 +9494,4 @@ try {
9458
9494
  process.exit(1);
9459
9495
  }
9460
9496
 
9461
- //# debugId=8AD6F6EBE8544AE364756E2164756E21
9497
+ //# debugId=8AAF49FB8D8C464364756E2164756E21