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