@hasna/assistants 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -51203,7 +51203,8 @@ import {
51203
51203
  writeFileSync as writeFileSync7,
51204
51204
  readFileSync as readFileSync5,
51205
51205
  readdirSync as readdirSync4,
51206
- rmSync
51206
+ rmSync,
51207
+ renameSync
51207
51208
  } from "fs";
51208
51209
 
51209
51210
  class SharedWorkspaceManager {
@@ -51212,12 +51213,26 @@ class SharedWorkspaceManager {
51212
51213
  const envHome = process.env.HOME || process.env.USERPROFILE || homedir11();
51213
51214
  this.basePath = basePath || join19(envHome, ".assistants", "workspaces");
51214
51215
  this.ensureDir();
51216
+ this.migrateAgentsToAssistants();
51215
51217
  }
51216
51218
  ensureDir() {
51217
51219
  if (!existsSync10(this.basePath)) {
51218
51220
  mkdirSync6(this.basePath, { recursive: true });
51219
51221
  }
51220
51222
  }
51223
+ migrateAgentsToAssistants() {
51224
+ try {
51225
+ const dirs = readdirSync4(this.basePath, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
51226
+ for (const dir of dirs) {
51227
+ const wsPath = join19(this.basePath, dir);
51228
+ const oldAgentsDir = join19(wsPath, "agents");
51229
+ const newAssistantsDir = join19(wsPath, "assistants");
51230
+ if (existsSync10(oldAgentsDir) && !existsSync10(newAssistantsDir)) {
51231
+ renameSync(oldAgentsDir, newAssistantsDir);
51232
+ }
51233
+ }
51234
+ } catch {}
51235
+ }
51221
51236
  getWorkspacePath(id) {
51222
51237
  return join19(this.basePath, id);
51223
51238
  }
@@ -51238,8 +51253,8 @@ class SharedWorkspaceManager {
51238
51253
  };
51239
51254
  const wsPath = this.getWorkspacePath(id);
51240
51255
  mkdirSync6(join19(wsPath, "shared"), { recursive: true });
51241
- for (const agentId of workspace.participants) {
51242
- mkdirSync6(join19(wsPath, "agents", agentId), { recursive: true });
51256
+ for (const assistantId of workspace.participants) {
51257
+ mkdirSync6(join19(wsPath, "assistants", assistantId), { recursive: true });
51243
51258
  }
51244
51259
  writeFileSync7(this.getMetadataPath(id), JSON.stringify(workspace, null, 2));
51245
51260
  return workspace;
@@ -51254,9 +51269,9 @@ class SharedWorkspaceManager {
51254
51269
  workspace.updatedAt = Date.now();
51255
51270
  writeFileSync7(this.getMetadataPath(workspaceId), JSON.stringify(workspace, null, 2));
51256
51271
  }
51257
- const agentDir = join19(this.getWorkspacePath(workspaceId), "agents", assistantId);
51258
- if (!existsSync10(agentDir)) {
51259
- mkdirSync6(agentDir, { recursive: true });
51272
+ const assistantDir = join19(this.getWorkspacePath(workspaceId), "assistants", assistantId);
51273
+ if (!existsSync10(assistantDir)) {
51274
+ mkdirSync6(assistantDir, { recursive: true });
51260
51275
  }
51261
51276
  }
51262
51277
  get(workspaceId) {
@@ -51275,8 +51290,8 @@ class SharedWorkspaceManager {
51275
51290
  getSharedPath(workspaceId) {
51276
51291
  return join19(this.getWorkspacePath(workspaceId), "shared");
51277
51292
  }
51278
- getAgentPath(workspaceId, agentId) {
51279
- return join19(this.getWorkspacePath(workspaceId), "agents", agentId);
51293
+ getAssistantPath(workspaceId, assistantId) {
51294
+ return join19(this.getWorkspacePath(workspaceId), "assistants", assistantId);
51280
51295
  }
51281
51296
  list(includeArchived = false) {
51282
51297
  try {
@@ -133608,17 +133623,6 @@ async function saveSchedule(cwd, schedule) {
133608
133623
  }
133609
133624
  await writeFile2(path, JSON.stringify(schedule, null, 2), "utf-8");
133610
133625
  }
133611
- async function getSchedule(cwd, id) {
133612
- try {
133613
- const path = schedulePath(cwd, id);
133614
- if (!path)
133615
- return null;
133616
- const raw = await readFile3(path, "utf-8");
133617
- return JSON.parse(raw);
133618
- } catch {
133619
- return null;
133620
- }
133621
- }
133622
133626
  async function deleteSchedule(cwd, id) {
133623
133627
  try {
133624
133628
  const path = schedulePath(cwd, id);
@@ -136397,7 +136401,7 @@ async function cancelRecurringTask(cwd, id) {
136397
136401
  return task;
136398
136402
  }
136399
136403
  // packages/core/src/commands/builtin.ts
136400
- var VERSION = "1.1.0";
136404
+ var VERSION = "1.1.1";
136401
136405
  function resolveAuthTimeout(resolve5) {
136402
136406
  resolve5({ exitCode: 1, stdout: { toString: () => "{}" } });
136403
136407
  }
@@ -136477,7 +136481,6 @@ class BuiltinCommands {
136477
136481
  loader.register(this.assistantsCommand());
136478
136482
  loader.register(this.swarmCommand());
136479
136483
  loader.register(this.workspaceCommand());
136480
- loader.register(this.agentsCommand());
136481
136484
  loader.register(this.initCommand());
136482
136485
  loader.register(this.costCommand());
136483
136486
  loader.register(this.modelCommand());
@@ -136486,11 +136489,7 @@ class BuiltinCommands {
136486
136489
  loader.register(this.memoryCommand());
136487
136490
  loader.register(this.hooksCommand());
136488
136491
  loader.register(this.feedbackCommand());
136489
- loader.register(this.scheduleCommand());
136490
136492
  loader.register(this.schedulesCommand());
136491
- loader.register(this.unscheduleCommand());
136492
- loader.register(this.pauseScheduleCommand());
136493
- loader.register(this.resumeScheduleCommand());
136494
136493
  loader.register(this.connectorsCommand());
136495
136494
  loader.register(this.securityLogCommand());
136496
136495
  loader.register(this.guardrailsCommand());
@@ -136506,7 +136505,7 @@ class BuiltinCommands {
136506
136505
  voiceCommand() {
136507
136506
  return {
136508
136507
  name: "voice",
136509
- description: "Control voice mode (on/off/status/stop)",
136508
+ description: "Toggle voice mode, check status, or stop audio (on/off/status/stop)",
136510
136509
  builtin: true,
136511
136510
  selfHandled: true,
136512
136511
  content: "",
@@ -136547,6 +136546,13 @@ class BuiltinCommands {
136547
136546
  context.emit("done");
136548
136547
  return { handled: true };
136549
136548
  }
136549
+ context.emit("text", `
136550
+ ## Voice Mode
136551
+
136552
+ Speak and listen using text-to-speech and speech-to-text.
136553
+
136554
+ `);
136555
+ context.emit("text", "**Subcommands:** `/voice on` \xB7 `/voice off` \xB7 `/voice stop` \xB7 `/voice` (status)\n\n");
136550
136556
  const status = state.enabled ? "on" : "off";
136551
136557
  const activity = state.isSpeaking ? "speaking" : state.isListening ? "listening" : "idle";
136552
136558
  context.emit("text", `Voice mode: ${status} (${activity})
@@ -136563,14 +136569,19 @@ class BuiltinCommands {
136563
136569
  sayCommand() {
136564
136570
  return {
136565
136571
  name: "say",
136566
- description: "Speak text aloud with TTS",
136572
+ description: "Speak text aloud using text-to-speech (e.g. /say Hello world)",
136567
136573
  builtin: true,
136568
136574
  selfHandled: true,
136569
136575
  content: "",
136570
136576
  handler: async (args, context) => {
136571
136577
  const text = args.trim();
136572
136578
  if (!text) {
136573
- context.emit("text", `Usage: /say <text>
136579
+ context.emit("text", `
136580
+ ## Say
136581
+
136582
+ Speak text aloud using text-to-speech.
136583
+
136584
+ Usage: \`/say <text>\`
136574
136585
  `);
136575
136586
  context.emit("done");
136576
136587
  return { handled: true };
@@ -136594,7 +136605,7 @@ class BuiltinCommands {
136594
136605
  listenCommand() {
136595
136606
  return {
136596
136607
  name: "listen",
136597
- description: "Record audio and send transcription",
136608
+ description: "Record audio via microphone and transcribe to text (e.g. /listen 5)",
136598
136609
  builtin: true,
136599
136610
  selfHandled: true,
136600
136611
  content: "",
@@ -136605,6 +136616,12 @@ class BuiltinCommands {
136605
136616
  context.emit("done");
136606
136617
  return { handled: true };
136607
136618
  }
136619
+ context.emit("text", `
136620
+ ## Listen
136621
+
136622
+ Recording audio via microphone...
136623
+
136624
+ `);
136608
136625
  let durationSeconds;
136609
136626
  const trimmed = args.trim();
136610
136627
  if (trimmed) {
@@ -136632,7 +136649,6 @@ class BuiltinCommands {
136632
136649
  assistantCommand() {
136633
136650
  return {
136634
136651
  name: "assistants",
136635
- aliases: ["assistant"],
136636
136652
  description: "Manage assistants (list, create, switch, delete)",
136637
136653
  builtin: true,
136638
136654
  selfHandled: true,
@@ -136694,7 +136710,7 @@ Assistants:
136694
136710
  }
136695
136711
  if (action === "create") {
136696
136712
  if (!target) {
136697
- context.emit("text", `Usage: /assistant create <name>
136713
+ context.emit("text", `Usage: /assistants create <name>
136698
136714
  `);
136699
136715
  context.emit("done");
136700
136716
  return { handled: true };
@@ -136707,7 +136723,7 @@ Assistants:
136707
136723
  }
136708
136724
  if (action === "switch") {
136709
136725
  if (!target) {
136710
- context.emit("text", `Usage: /assistant switch <name|id>
136726
+ context.emit("text", `Usage: /assistants switch <name|id>
136711
136727
  `);
136712
136728
  context.emit("done");
136713
136729
  return { handled: true };
@@ -136728,7 +136744,7 @@ Assistants:
136728
136744
  }
136729
136745
  if (action === "delete") {
136730
136746
  if (!target) {
136731
- context.emit("text", `Usage: /assistant delete <name|id>
136747
+ context.emit("text", `Usage: /assistants delete <name|id>
136732
136748
  `);
136733
136749
  context.emit("done");
136734
136750
  return { handled: true };
@@ -136779,7 +136795,7 @@ Assistants:
136779
136795
  } else {
136780
136796
  context.emit("text", `No system prompt set for ${active.name}.
136781
136797
  `);
136782
- context.emit("text", `Usage: /assistant prompt <text>
136798
+ context.emit("text", `Usage: /assistants prompt <text>
136783
136799
  `);
136784
136800
  }
136785
136801
  context.emit("done");
@@ -136820,30 +136836,30 @@ Assistants:
136820
136836
  ## Assistant Commands
136821
136837
 
136822
136838
  `);
136823
- context.emit("text", `/assistant Open interactive assistant panel
136839
+ context.emit("text", `/assistants Open interactive assistant panel
136824
136840
  `);
136825
- context.emit("text", `/assistant show Show current assistant info
136841
+ context.emit("text", `/assistants show Show current assistant info
136826
136842
  `);
136827
- context.emit("text", `/assistant list List all assistants
136843
+ context.emit("text", `/assistants list List all assistants
136828
136844
  `);
136829
- context.emit("text", `/assistant create <name> Create new assistant
136845
+ context.emit("text", `/assistants create <name> Create new assistant
136830
136846
  `);
136831
- context.emit("text", `/assistant switch <name|id> Switch to assistant
136847
+ context.emit("text", `/assistants switch <name|id> Switch to assistant
136832
136848
  `);
136833
- context.emit("text", `/assistant delete <name|id> Delete assistant
136849
+ context.emit("text", `/assistants delete <name|id> Delete assistant
136834
136850
  `);
136835
- context.emit("text", `/assistant settings Show assistant settings
136851
+ context.emit("text", `/assistants settings Show assistant settings
136836
136852
  `);
136837
- context.emit("text", `/assistant prompt [text] Get/set assistant system prompt
136853
+ context.emit("text", `/assistants prompt [text] Get/set assistant system prompt
136838
136854
  `);
136839
- context.emit("text", `/assistant prompt-clear Clear assistant system prompt
136855
+ context.emit("text", `/assistants prompt-clear Clear assistant system prompt
136840
136856
  `);
136841
- context.emit("text", `/assistant help Show this help
136857
+ context.emit("text", `/assistants help Show this help
136842
136858
  `);
136843
136859
  context.emit("done");
136844
136860
  return { handled: true };
136845
136861
  }
136846
- context.emit("text", `Unknown /assistant command. Use /assistant help for options.
136862
+ context.emit("text", `Unknown /assistants command. Use /assistants help for options.
136847
136863
  `);
136848
136864
  context.emit("done");
136849
136865
  return { handled: true };
@@ -136853,7 +136869,7 @@ Assistants:
136853
136869
  hooksCommand() {
136854
136870
  return {
136855
136871
  name: "hooks",
136856
- description: "Manage hooks (view, enable, disable)",
136872
+ description: "View, enable, disable, and manage event hooks (pre/post tool use, etc.)",
136857
136873
  builtin: true,
136858
136874
  selfHandled: true,
136859
136875
  content: "",
@@ -137318,7 +137334,7 @@ To update fields, use the web UI or edit the identity file directly.
137318
137334
  whoamiCommand() {
137319
137335
  return {
137320
137336
  name: "whoami",
137321
- description: "Show active assistant and identity",
137337
+ description: "Show active assistant, identity profile, and current configuration",
137322
137338
  builtin: true,
137323
137339
  selfHandled: true,
137324
137340
  content: "",
@@ -137351,7 +137367,7 @@ To update fields, use the web UI or edit the identity file directly.
137351
137367
  helpCommand(loader) {
137352
137368
  return {
137353
137369
  name: "help",
137354
- description: "Show available slash commands",
137370
+ description: "Show all available slash commands and their descriptions",
137355
137371
  builtin: true,
137356
137372
  selfHandled: true,
137357
137373
  content: "",
@@ -137419,7 +137435,7 @@ To update fields, use the web UI or edit the identity file directly.
137419
137435
  clearCommand() {
137420
137436
  return {
137421
137437
  name: "clear",
137422
- description: "Clear conversation history and start fresh",
137438
+ description: "Clear current conversation history and reset context",
137423
137439
  builtin: true,
137424
137440
  selfHandled: true,
137425
137441
  content: "",
@@ -137440,7 +137456,7 @@ To update fields, use the web UI or edit the identity file directly.
137440
137456
  newCommand() {
137441
137457
  return {
137442
137458
  name: "new",
137443
- description: "Start a new conversation",
137459
+ description: "Start a new conversation session (preserves previous session)",
137444
137460
  builtin: true,
137445
137461
  selfHandled: true,
137446
137462
  content: "",
@@ -139574,7 +139590,7 @@ To enable:
139574
139590
  if (sub === "run") {
139575
139591
  const paused = await isPaused(context.cwd);
139576
139592
  if (paused) {
139577
- context.emit("text", `Task queue is paused. Use /tasks resume to enable auto-run.
139593
+ context.emit("text", `Note: Auto-run is paused. Running task manually.
139578
139594
  `);
139579
139595
  }
139580
139596
  const nextTask = await getNextTask(context.cwd);
@@ -139745,23 +139761,10 @@ Unknown workspace command. Use /workspace help for available commands.
139745
139761
  }
139746
139762
  };
139747
139763
  }
139748
- agentsCommand() {
139749
- return {
139750
- name: "agents",
139751
- description: "Open agent dashboard showing all sessions, budgets, and messages",
139752
- builtin: true,
139753
- selfHandled: true,
139754
- content: "",
139755
- handler: async (_args, context) => {
139756
- context.emit("done");
139757
- return { handled: true, showPanel: "agents" };
139758
- }
139759
- };
139760
- }
139761
139764
  exitCommand() {
139762
139765
  return {
139763
139766
  name: "exit",
139764
- description: "Exit assistants",
139767
+ description: "Exit the assistant session and return to shell",
139765
139768
  builtin: true,
139766
139769
  selfHandled: true,
139767
139770
  content: "",
@@ -139775,7 +139778,8 @@ Unknown workspace command. Use /workspace help for available commands.
139775
139778
  }
139776
139779
  sessionCommand() {
139777
139780
  return {
139778
- name: "session",
139781
+ name: "sessions",
139782
+ aliases: ["session"],
139779
139783
  description: "Manage sessions: list, create with agent, switch, assign agent",
139780
139784
  builtin: true,
139781
139785
  selfHandled: true,
@@ -139903,7 +139907,7 @@ Usage: /session assign <agent-name>
139903
139907
  tokensCommand() {
139904
139908
  return {
139905
139909
  name: "tokens",
139906
- description: "Show token usage",
139910
+ description: "Show token usage breakdown (input, output, cache, total)",
139907
139911
  builtin: true,
139908
139912
  selfHandled: true,
139909
139913
  content: "",
@@ -140816,7 +140820,7 @@ Not enough context to summarize yet.
140816
140820
  restCommand() {
140817
140821
  return {
140818
140822
  name: "rest",
140819
- description: "Recharge assistant energy",
140823
+ description: "Recharge assistant energy (optional: amount, e.g. /rest 5000)",
140820
140824
  builtin: true,
140821
140825
  selfHandled: true,
140822
140826
  content: "",
@@ -140850,7 +140854,7 @@ Energy restored.
140850
140854
  skillCommand() {
140851
140855
  return {
140852
140856
  name: "skill",
140853
- description: "Create or manage skills",
140857
+ description: "Create or manage skills (create, edit, invoke by name)",
140854
140858
  builtin: true,
140855
140859
  selfHandled: true,
140856
140860
  content: "",
@@ -141042,7 +141046,7 @@ Created skill "${result.name}" (${result.scope}).
141042
141046
  skillsCommand(loader) {
141043
141047
  return {
141044
141048
  name: "skills",
141045
- description: "List available skills",
141049
+ description: "List all available skills with descriptions and argument hints",
141046
141050
  builtin: true,
141047
141051
  selfHandled: true,
141048
141052
  content: "",
@@ -141082,7 +141086,7 @@ ${context.skills.length} skill(s) available.
141082
141086
  statusCommand() {
141083
141087
  return {
141084
141088
  name: "status",
141085
- description: "Show current session status, energy, identity, and token usage",
141089
+ description: "Show session overview: status, energy, identity, tokens, and runtime info",
141086
141090
  builtin: true,
141087
141091
  selfHandled: true,
141088
141092
  content: "",
@@ -141199,7 +141203,7 @@ ${context.skills.length} skill(s) available.
141199
141203
  compactCommand() {
141200
141204
  return {
141201
141205
  name: "compact",
141202
- description: "Summarize conversation to save context space",
141206
+ description: "Summarize conversation to save context space (auto-compaction)",
141203
141207
  builtin: true,
141204
141208
  selfHandled: false,
141205
141209
  content: `Please summarize our conversation so far into a concise format that preserves:
@@ -141214,7 +141218,7 @@ Format the summary as a brief bullet-point list. This summary will replace the c
141214
141218
  configCommand() {
141215
141219
  return {
141216
141220
  name: "config",
141217
- description: "View and edit configuration interactively",
141221
+ description: "View and edit configuration interactively (model, context, energy, etc.)",
141218
141222
  builtin: true,
141219
141223
  selfHandled: true,
141220
141224
  content: "",
@@ -141272,7 +141276,7 @@ Format the summary as a brief bullet-point list. This summary will replace the c
141272
141276
  budgetCommand() {
141273
141277
  return {
141274
141278
  name: "budget",
141275
- description: "View and manage resource usage budgets",
141279
+ description: "View and manage resource budgets (tokens, calls, duration limits)",
141276
141280
  builtin: true,
141277
141281
  selfHandled: true,
141278
141282
  content: "",
@@ -142086,7 +142090,7 @@ ${error instanceof Error ? error.message : String(error)}
142086
142090
  initCommand() {
142087
142091
  return {
142088
142092
  name: "init",
142089
- description: "Initialize assistants config and create example command",
142093
+ description: "Initialize .assistants/ config directory with example commands and hooks",
142090
142094
  builtin: true,
142091
142095
  selfHandled: true,
142092
142096
  content: "",
@@ -142137,18 +142141,22 @@ Please summarize the last interaction and suggest 2-3 next steps.
142137
142141
  costCommand() {
142138
142142
  return {
142139
142143
  name: "cost",
142140
- description: "Show estimated API cost for this session",
142144
+ description: "Show estimated API cost for this session (input + output pricing)",
142141
142145
  builtin: true,
142142
142146
  selfHandled: true,
142143
142147
  content: "",
142144
142148
  handler: async (args, context) => {
142145
142149
  const usage = this.tokenUsage;
142146
- const inputCostPer1M = 3;
142147
- const outputCostPer1M = 15;
142150
+ const { getModelById: getModelById3 } = await Promise.resolve().then(() => (init_models2(), exports_models));
142151
+ const activeModelId = context.getModel?.();
142152
+ const model = activeModelId ? getModelById3(activeModelId) : null;
142153
+ const inputCostPer1M = model?.inputCostPer1M ?? 3;
142154
+ const outputCostPer1M = model?.outputCostPer1M ?? 15;
142155
+ const modelName = model?.name ?? "Unknown model";
142148
142156
  const inputCost = usage.inputTokens / 1e6 * inputCostPer1M;
142149
142157
  const outputCost = usage.outputTokens / 1e6 * outputCostPer1M;
142150
142158
  const totalCost = inputCost + outputCost;
142151
- const cacheReadCostPer1M = 0.3;
142159
+ const cacheReadCostPer1M = inputCostPer1M * 0.1;
142152
142160
  const cacheSavings = usage.cacheReadTokens ? usage.cacheReadTokens / 1e6 * (inputCostPer1M - cacheReadCostPer1M) : 0;
142153
142161
  let message = `
142154
142162
  **Estimated Session Cost**
@@ -142166,7 +142174,7 @@ Cache savings: ~$${cacheSavings.toFixed(4)}
142166
142174
  `;
142167
142175
  }
142168
142176
  message += `
142169
- *Based on Claude 3.5 Sonnet pricing*
142177
+ *Based on ${modelName} pricing ($${inputCostPer1M}/1M in, $${outputCostPer1M}/1M out)*
142170
142178
  `;
142171
142179
  context.emit("text", message);
142172
142180
  context.emit("done");
@@ -142177,7 +142185,7 @@ Cache savings: ~$${cacheSavings.toFixed(4)}
142177
142185
  modelCommand() {
142178
142186
  return {
142179
142187
  name: "model",
142180
- description: "Show or switch models (list, <model-id>)",
142188
+ description: "Show current model or switch to another (e.g. /model claude-sonnet-4-5-20250929)",
142181
142189
  builtin: true,
142182
142190
  selfHandled: true,
142183
142191
  content: "",
@@ -142913,86 +142921,6 @@ Importing ${validMemories.length} valid entries (skipping ${errors.length} inval
142913
142921
  context.emit("text", `Unknown action: ${action}
142914
142922
  `);
142915
142923
  context.emit("text", `Use /memory for help.
142916
- `);
142917
- context.emit("done");
142918
- return { handled: true };
142919
- }
142920
- };
142921
- }
142922
- scheduleCommand() {
142923
- return {
142924
- name: "schedule",
142925
- description: "Schedule a command (ISO time or cron)",
142926
- builtin: true,
142927
- selfHandled: true,
142928
- content: "",
142929
- handler: async (args, context) => {
142930
- const parts = splitArgs(args);
142931
- if (parts.length < 2) {
142932
- context.emit("text", `Usage:
142933
- /schedule <ISO time> <command>
142934
- /schedule cron "<expr>" <command>
142935
- `);
142936
- context.emit("done");
142937
- return { handled: true };
142938
- }
142939
- const now2 = Date.now();
142940
- let kind = "once";
142941
- let at;
142942
- let cron;
142943
- let commandStart = 1;
142944
- if (parts[0] === "cron") {
142945
- kind = "cron";
142946
- cron = parts[1];
142947
- commandStart = 2;
142948
- } else {
142949
- at = parts[0];
142950
- }
142951
- if (kind === "cron" && !cron) {
142952
- context.emit("text", `Usage:
142953
- /schedule cron "<expr>" <command>
142954
- `);
142955
- context.emit("done");
142956
- return { handled: true };
142957
- }
142958
- const command = parts.slice(commandStart).join(" ").trim();
142959
- if (!command) {
142960
- context.emit("text", `Error: command is required.
142961
- `);
142962
- context.emit("done");
142963
- return { handled: true };
142964
- }
142965
- const schedule = {
142966
- id: generateId(),
142967
- createdAt: now2,
142968
- updatedAt: now2,
142969
- createdBy: "user",
142970
- sessionId: context.sessionId,
142971
- command,
142972
- status: "active",
142973
- schedule: {
142974
- kind,
142975
- at,
142976
- cron
142977
- }
142978
- };
142979
- schedule.nextRunAt = computeNextRun(schedule, now2);
142980
- if (!schedule.nextRunAt) {
142981
- context.emit("text", `Error: unable to compute next run time.
142982
- `);
142983
- context.emit("done");
142984
- return { handled: true };
142985
- }
142986
- if (schedule.nextRunAt <= now2) {
142987
- context.emit("text", `Error: scheduled time must be in the future.
142988
- `);
142989
- context.emit("done");
142990
- return { handled: true };
142991
- }
142992
- await saveSchedule(context.cwd, schedule);
142993
- context.emit("text", `Scheduled ${schedule.command}
142994
- id: ${schedule.id}
142995
- next: ${new Date(schedule.nextRunAt).toISOString()}
142996
142924
  `);
142997
142925
  context.emit("done");
142998
142926
  return { handled: true };
@@ -143002,7 +142930,7 @@ Importing ${validMemories.length} valid entries (skipping ${errors.length} inval
143002
142930
  schedulesCommand() {
143003
142931
  return {
143004
142932
  name: "schedules",
143005
- description: "Browse and manage scheduled commands",
142933
+ description: "Browse and manage all scheduled commands (active, paused, completed)",
143006
142934
  builtin: true,
143007
142935
  selfHandled: true,
143008
142936
  content: "",
@@ -143045,181 +142973,13 @@ Importing ${validMemories.length} valid entries (skipping ${errors.length} inval
143045
142973
  `);
143046
142974
  context.emit("text", `Usage:
143047
142975
  `);
143048
- context.emit("text", ` /schedules Open interactive panel
142976
+ context.emit("text", ` /schedules Open interactive panel (create, delete, pause, resume)
143049
142977
  `);
143050
- context.emit("text", ` /schedules ui Open interactive panel
142978
+ context.emit("text", ` /schedules ui Open interactive panel
143051
142979
  `);
143052
- context.emit("text", ` /schedules list Show text table (this session)
142980
+ context.emit("text", ` /schedules list Show text table (this session)
143053
142981
  `);
143054
142982
  context.emit("text", ` /schedules list --all Show all schedules
143055
- `);
143056
- context.emit("text", ` /schedule <time> <cmd> Create a schedule
143057
- `);
143058
- context.emit("text", ` /unschedule <id> Delete a schedule
143059
- `);
143060
- context.emit("text", ` /pause <id> Pause a schedule
143061
- `);
143062
- context.emit("text", ` /resume <id> Resume a schedule
143063
- `);
143064
- context.emit("done");
143065
- return { handled: true };
143066
- }
143067
- };
143068
- }
143069
- unscheduleCommand() {
143070
- return {
143071
- name: "unschedule",
143072
- description: "Delete a scheduled command",
143073
- builtin: true,
143074
- selfHandled: true,
143075
- content: "",
143076
- handler: async (args, context) => {
143077
- const id = args.trim();
143078
- if (!id) {
143079
- context.emit("text", `Usage: /unschedule <id>
143080
- `);
143081
- context.emit("done");
143082
- return { handled: true };
143083
- }
143084
- const schedule = await getSchedule(context.cwd, id);
143085
- if (!schedule) {
143086
- context.emit("text", `Schedule ${id} not found.
143087
- `);
143088
- context.emit("done");
143089
- return { handled: true };
143090
- }
143091
- if (schedule.sessionId && schedule.sessionId !== context.sessionId) {
143092
- context.emit("text", `Schedule ${id} belongs to another session. Cannot delete.
143093
- `);
143094
- context.emit("done");
143095
- return { handled: true };
143096
- }
143097
- const ok = await deleteSchedule(context.cwd, id);
143098
- context.emit("text", ok ? `Deleted schedule ${id}.
143099
- ` : `Schedule ${id} not found.
143100
- `);
143101
- context.emit("done");
143102
- return { handled: true };
143103
- }
143104
- };
143105
- }
143106
- pauseScheduleCommand() {
143107
- return {
143108
- name: "pause",
143109
- description: "Pause a scheduled command",
143110
- builtin: true,
143111
- selfHandled: true,
143112
- content: "",
143113
- handler: async (args, context) => {
143114
- const id = args.trim();
143115
- if (!id) {
143116
- const schedules = await listSchedules(context.cwd, { sessionId: context.sessionId });
143117
- if (schedules.length === 0) {
143118
- context.emit("text", `No schedules found for this session.
143119
- `);
143120
- } else {
143121
- const lines = schedules.sort((a, b) => (a.nextRunAt || 0) - (b.nextRunAt || 0)).map((schedule2) => `- ${schedule2.id} [${schedule2.status}] ${schedule2.command}`);
143122
- context.emit("text", `Usage: /pause <id>
143123
-
143124
- Available schedules:
143125
- ${lines.join(`
143126
- `)}
143127
- `);
143128
- }
143129
- context.emit("done");
143130
- return { handled: true };
143131
- }
143132
- const schedule = await getSchedule(context.cwd, id);
143133
- if (!schedule) {
143134
- context.emit("text", `Schedule ${id} not found.
143135
- `);
143136
- context.emit("done");
143137
- return { handled: true };
143138
- }
143139
- if (schedule.sessionId && schedule.sessionId !== context.sessionId) {
143140
- context.emit("text", `Schedule ${id} belongs to another session. Cannot pause.
143141
- `);
143142
- context.emit("done");
143143
- return { handled: true };
143144
- }
143145
- const updated = await updateSchedule(context.cwd, id, (s) => ({
143146
- ...s,
143147
- status: "paused",
143148
- updatedAt: Date.now()
143149
- }));
143150
- context.emit("text", updated ? `Paused schedule ${id}.
143151
- ` : `Schedule ${id} not found.
143152
- `);
143153
- context.emit("done");
143154
- return { handled: true };
143155
- }
143156
- };
143157
- }
143158
- resumeScheduleCommand() {
143159
- return {
143160
- name: "resume",
143161
- description: "Resume a scheduled command",
143162
- builtin: true,
143163
- selfHandled: true,
143164
- content: "",
143165
- handler: async (args, context) => {
143166
- const id = args.trim();
143167
- if (!id) {
143168
- const schedules = await listSchedules(context.cwd, { sessionId: context.sessionId });
143169
- if (schedules.length === 0) {
143170
- context.emit("text", `No schedules found for this session.
143171
- `);
143172
- } else {
143173
- const lines = schedules.sort((a, b) => (a.nextRunAt || 0) - (b.nextRunAt || 0)).map((schedule2) => `- ${schedule2.id} [${schedule2.status}] ${schedule2.command}`);
143174
- context.emit("text", `Usage: /resume <id>
143175
-
143176
- Available schedules:
143177
- ${lines.join(`
143178
- `)}
143179
- `);
143180
- }
143181
- context.emit("done");
143182
- return { handled: true };
143183
- }
143184
- const schedule = await getSchedule(context.cwd, id);
143185
- if (!schedule) {
143186
- context.emit("text", `Schedule ${id} not found.
143187
- `);
143188
- context.emit("done");
143189
- return { handled: true };
143190
- }
143191
- if (schedule.sessionId && schedule.sessionId !== context.sessionId) {
143192
- context.emit("text", `Schedule ${id} belongs to another session. Cannot resume.
143193
- `);
143194
- context.emit("done");
143195
- return { handled: true };
143196
- }
143197
- let computedNext;
143198
- const updated = await updateSchedule(context.cwd, id, (s) => {
143199
- computedNext = computeNextRun(s, Date.now());
143200
- if (!computedNext) {
143201
- return s;
143202
- }
143203
- return {
143204
- ...s,
143205
- status: "active",
143206
- updatedAt: Date.now(),
143207
- nextRunAt: computedNext
143208
- };
143209
- });
143210
- if (!updated) {
143211
- context.emit("text", `Schedule ${id} not found.
143212
- `);
143213
- context.emit("done");
143214
- return { handled: true };
143215
- }
143216
- if (!computedNext) {
143217
- context.emit("text", `Failed to compute next run for schedule ${id}.
143218
- `);
143219
- context.emit("done");
143220
- return { handled: true };
143221
- }
143222
- context.emit("text", `Resumed schedule ${id}.
143223
142983
  `);
143224
142984
  context.emit("done");
143225
142985
  return { handled: true };
@@ -143229,7 +142989,7 @@ ${lines.join(`
143229
142989
  connectorsCommand() {
143230
142990
  return {
143231
142991
  name: "connectors",
143232
- description: "Browse connectors interactively (refresh to re-discover)",
142992
+ description: "Browse and search connectors interactively (view commands, refresh)",
143233
142993
  builtin: true,
143234
142994
  selfHandled: true,
143235
142995
  content: "",
@@ -143470,7 +143230,7 @@ ${context.connectors.length} connector(s) available.
143470
143230
  securityLogCommand() {
143471
143231
  return {
143472
143232
  name: "security-log",
143473
- description: "Show recent security events (optional: limit, severity, type)",
143233
+ description: "Show recent security events with filtering (limit, severity, type)",
143474
143234
  builtin: true,
143475
143235
  selfHandled: true,
143476
143236
  content: "",
@@ -143527,7 +143287,7 @@ No security events recorded.
143527
143287
  feedbackCommand() {
143528
143288
  return {
143529
143289
  name: "feedback",
143530
- description: "Submit feedback or report an issue on GitHub",
143290
+ description: "Submit feedback (good/bad/bug/idea) or report an issue on GitHub",
143531
143291
  builtin: true,
143532
143292
  selfHandled: true,
143533
143293
  content: "",
@@ -168205,7 +167965,7 @@ class AssistantLoop {
168205
167965
  });
168206
167966
  this.emit({
168207
167967
  type: "show_panel",
168208
- panel: "agents",
167968
+ panel: "assistants",
168209
167969
  panelValue: `session:${payload}`
168210
167970
  });
168211
167971
  }
@@ -176664,6 +176424,7 @@ var import_react25 = __toESM(require_react(), 1);
176664
176424
  var import_react26 = __toESM(require_react(), 1);
176665
176425
  // packages/terminal/src/components/App.tsx
176666
176426
  var import_react53 = __toESM(require_react(), 1);
176427
+ import { spawn as spawn3 } from "child_process";
176667
176428
  init_src2();
176668
176429
 
176669
176430
  // packages/terminal/src/components/Input.tsx
@@ -176747,7 +176508,7 @@ var COMMANDS = [
176747
176508
  { name: "/clear", description: "clear the conversation" },
176748
176509
  { name: "/new", description: "start a new conversation" },
176749
176510
  { name: "/exit", description: "exit assistants" },
176750
- { name: "/session", description: "list/switch sessions (Ctrl+])" },
176511
+ { name: "/sessions", description: "list/switch sessions (Ctrl+])" },
176751
176512
  { name: "/status", description: "show session status" },
176752
176513
  { name: "/tokens", description: "show token usage" },
176753
176514
  { name: "/cost", description: "show estimated API cost" },
@@ -176763,17 +176524,13 @@ var COMMANDS = [
176763
176524
  { name: "/hooks", description: "manage hooks (list, add, remove, test)" },
176764
176525
  { name: "/projects", description: "manage projects in this folder" },
176765
176526
  { name: "/plans", description: "manage project plans" },
176766
- { name: "/schedule", description: "schedule a command" },
176767
- { name: "/schedules", description: "list scheduled commands" },
176768
- { name: "/unschedule", description: "delete a scheduled command" },
176769
- { name: "/pause", description: "pause a scheduled command" },
176770
- { name: "/resume", description: "resume a scheduled command" },
176527
+ { name: "/schedules", description: "manage scheduled commands" },
176771
176528
  { name: "/assistants", description: "switch or list assistants" },
176772
176529
  { name: "/identity", description: "manage assistant identity" },
176773
176530
  { name: "/whoami", description: "show current identity" },
176774
176531
  { name: "/voice", description: "toggle voice mode" },
176775
176532
  { name: "/say", description: "speak text aloud" },
176776
- { name: "/listen", description: "transcribe voice input" },
176533
+ { name: "/listen", description: "start dictation (pause 3s to send)" },
176777
176534
  { name: "/inbox", description: "view assistant messages" },
176778
176535
  { name: "/messages", description: "manage assistant-to-assistant messages" },
176779
176536
  { name: "/wallet", description: "manage assistant wallet" },
@@ -176807,7 +176564,7 @@ function isLargePaste(text, thresholds = DEFAULT_PASTE_THRESHOLDS) {
176807
176564
  const lineThreshold = thresholds.lines ?? DEFAULT_PASTE_THRESHOLDS.lines;
176808
176565
  return text.length > charThreshold || countWords(text) > wordThreshold || countLines(text) > lineThreshold;
176809
176566
  }
176810
- function Input({
176567
+ var Input = import_react27.default.forwardRef(function Input2({
176811
176568
  onSubmit,
176812
176569
  isProcessing,
176813
176570
  queueLength = 0,
@@ -176816,9 +176573,11 @@ function Input({
176816
176573
  isAskingUser = false,
176817
176574
  askPlaceholder,
176818
176575
  allowBlankAnswer = false,
176576
+ footerHints = [],
176577
+ assistantName,
176819
176578
  history: historyProp,
176820
176579
  pasteConfig
176821
- }) {
176580
+ }, ref) {
176822
176581
  const pasteEnabled = pasteConfig?.enabled !== false;
176823
176582
  const pasteThresholds = pasteConfig?.thresholds ?? DEFAULT_PASTE_THRESHOLDS;
176824
176583
  const pasteMode = pasteConfig?.mode ?? "placeholder";
@@ -176903,6 +176662,36 @@ function Input({
176903
176662
  historyRef.current.resetIndex(nextValue);
176904
176663
  }
176905
176664
  }, []);
176665
+ const clearLargePaste = import_react27.useCallback(() => {
176666
+ setLargePaste(null);
176667
+ setShowPastePreview(false);
176668
+ }, []);
176669
+ import_react27.useImperativeHandle(ref, () => ({
176670
+ setValue: (nextValue, nextCursor = nextValue.length, resetHistory = true) => {
176671
+ clearLargePaste();
176672
+ setValueAndCursor(nextValue, nextCursor, resetHistory);
176673
+ },
176674
+ appendValue: (text) => {
176675
+ if (!text)
176676
+ return;
176677
+ clearLargePaste();
176678
+ setInputState((prev) => {
176679
+ const newValue = prev.value + text;
176680
+ historyRef.current.resetIndex(newValue);
176681
+ return {
176682
+ value: newValue,
176683
+ cursor: newValue.length
176684
+ };
176685
+ });
176686
+ setPreferredColumn(null);
176687
+ setSelectedIndex(0);
176688
+ },
176689
+ clearValue: () => {
176690
+ clearLargePaste();
176691
+ setValueAndCursor("");
176692
+ },
176693
+ getValue: () => inputState.value
176694
+ }), [clearLargePaste, setValueAndCursor, inputState.value]);
176906
176695
  const handleSubmit = (submittedValue) => {
176907
176696
  const actualValue = largePaste ? largePaste.content : submittedValue;
176908
176697
  if (!actualValue.trim() && !allowBlankAnswer)
@@ -177188,12 +176977,39 @@ function Input({
177188
176977
  const lines = layout.displayLines;
177189
176978
  const lineCount = value.split(`
177190
176979
  `).length;
176980
+ const quickHints = [];
176981
+ if (isProcessing && !isAskingUser) {
176982
+ quickHints.push("[esc] stop");
176983
+ }
176984
+ if (footerHints.length > 0) {
176985
+ quickHints.push(...footerHints);
176986
+ }
177191
176987
  return /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
177192
176988
  flexDirection: "column",
177193
176989
  marginTop: 1,
177194
176990
  children: [
177195
176991
  /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
177196
- children: /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text3, {
176992
+ children: assistantName ? /* @__PURE__ */ jsx_dev_runtime.jsxDEV(jsx_dev_runtime.Fragment, {
176993
+ children: [
176994
+ /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text3, {
176995
+ color: "#666666",
176996
+ children: "\u2500".repeat(Math.max(0, terminalWidth - assistantName.length - 3))
176997
+ }, undefined, false, undefined, this),
176998
+ /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text3, {
176999
+ children: " "
177000
+ }, undefined, false, undefined, this),
177001
+ /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text3, {
177002
+ backgroundColor: "#4a8ba4",
177003
+ color: "white",
177004
+ bold: true,
177005
+ children: [
177006
+ " ",
177007
+ assistantName,
177008
+ " "
177009
+ ]
177010
+ }, undefined, true, undefined, this)
177011
+ ]
177012
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text3, {
177197
177013
  color: "#666666",
177198
177014
  children: "\u2500".repeat(terminalWidth)
177199
177015
  }, undefined, false, undefined, this)
@@ -177305,11 +177121,11 @@ function Input({
177305
177121
  children: "\u2500".repeat(terminalWidth)
177306
177122
  }, undefined, false, undefined, this)
177307
177123
  }, undefined, false, undefined, this),
177308
- isProcessing && !isAskingUser && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
177124
+ quickHints.length > 0 && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
177309
177125
  marginLeft: 2,
177310
177126
  children: /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text3, {
177311
177127
  dimColor: true,
177312
- children: "[esc] stop"
177128
+ children: quickHints.join(" \xB7 ")
177313
177129
  }, undefined, false, undefined, this)
177314
177130
  }, undefined, false, undefined, this),
177315
177131
  autocompleteMode === "skill" && filteredSkills.length > 0 && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
@@ -177396,7 +177212,8 @@ function Input({
177396
177212
  }, undefined, true, undefined, this)
177397
177213
  ]
177398
177214
  }, undefined, true, undefined, this);
177399
- }
177215
+ });
177216
+ Input.displayName = "Input";
177400
177217
 
177401
177218
  // packages/terminal/src/components/Messages.tsx
177402
177219
  var import_react28 = __toESM(require_react(), 1);
@@ -180392,7 +180209,7 @@ function truncatePath(path2, maxLen) {
180392
180209
  return ".../" + result;
180393
180210
  }
180394
180211
  function RecoveryPanel({ sessions, onRecover, onStartFresh }) {
180395
- const [selectedIndex, setSelectedIndex] = import_react33.useState(0);
180212
+ const [selectedIndex, setSelectedIndex] = import_react33.useState(sessions.length);
180396
180213
  const totalItems = sessions.length + 1;
180397
180214
  use_input_default((input, key) => {
180398
180215
  if (key.upArrow) {
@@ -181683,7 +181500,7 @@ function TasksPanel({
181683
181500
  });
181684
181501
  return;
181685
181502
  }
181686
- if (key.escape) {
181503
+ if (key.escape || input === "q" || input === "Q") {
181687
181504
  onClose();
181688
181505
  return;
181689
181506
  }
@@ -181780,7 +181597,7 @@ function TasksPanel({
181780
181597
  isFieldActive("description") ? /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(build_default2, {
181781
181598
  value: newDescription,
181782
181599
  onChange: setNewDescription,
181783
- onSubmit: handleCreateSubmit,
181600
+ onSubmit: () => setCreateField("priority"),
181784
181601
  placeholder: "What needs to be done..."
181785
181602
  }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text3, {
181786
181603
  dimColor: !newDescription,
@@ -181942,16 +181759,16 @@ function TasksPanel({
181942
181759
  children: newAssignee || "(unassigned)"
181943
181760
  }, undefined, false, undefined, this)
181944
181761
  ]
181945
- }, undefined, true, undefined, this)
181762
+ }, undefined, true, undefined, this),
181763
+ /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
181764
+ marginTop: 1,
181765
+ children: /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text3, {
181766
+ dimColor: true,
181767
+ children: createField === "assignee" ? "Enter: save task | Tab: cycle fields | Esc: cancel" : "Enter: next field | Tab: cycle fields | Esc: cancel"
181768
+ }, undefined, false, undefined, this)
181769
+ }, undefined, false, undefined, this)
181946
181770
  ]
181947
181771
  }, undefined, true, undefined, this),
181948
- /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
181949
- marginTop: 1,
181950
- children: /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text3, {
181951
- dimColor: true,
181952
- children: "Tab/Shift+Tab: switch field | Enter: add task | Esc: cancel"
181953
- }, undefined, false, undefined, this)
181954
- }, undefined, false, undefined, this),
181955
181772
  isSubmitting && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
181956
181773
  marginTop: 1,
181957
181774
  children: /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text3, {
@@ -182391,7 +182208,7 @@ function AssistantsPanel({
182391
182208
  }
182392
182209
  return;
182393
182210
  }
182394
- if (key.escape) {
182211
+ if (key.escape || input === "q" || input === "Q") {
182395
182212
  onClearError?.();
182396
182213
  onCancel();
182397
182214
  return;
@@ -185612,7 +185429,8 @@ var SECTIONS = [
185612
185429
  { id: "memory", name: "Memory", icon: "\uD83E\uDDE0" },
185613
185430
  { id: "subassistants", name: "Subassistants", icon: "\uD83D\uDC65" },
185614
185431
  { id: "voice", name: "Voice", icon: "\uD83C\uDFA4" },
185615
- { id: "energy", name: "Energy", icon: "\u26A1" }
185432
+ { id: "energy", name: "Energy", icon: "\u26A1" },
185433
+ { id: "statusLine", name: "Status Line", icon: "\uD83D\uDCCA" }
185616
185434
  ];
185617
185435
  function ConfigPanel({
185618
185436
  config,
@@ -185632,6 +185450,9 @@ function ConfigPanel({
185632
185450
  const [message, setMessage] = import_react41.useState(null);
185633
185451
  const [selectedModelIndex, setSelectedModelIndex] = import_react41.useState(ANTHROPIC_MODELS.findIndex((m5) => m5.id === config.llm?.model) || ANTHROPIC_MODELS.findIndex((m5) => m5.id === DEFAULT_MODEL));
185634
185452
  const [maxTokens, setMaxTokens] = import_react41.useState(config.llm?.maxTokens ?? 8192);
185453
+ const [selectedEnergyField, setSelectedEnergyField] = import_react41.useState(0);
185454
+ const [energyMaxEnergy, setEnergyMaxEnergy] = import_react41.useState(config.energy?.maxEnergy ?? 1e4);
185455
+ const [energyRegenRate, setEnergyRegenRate] = import_react41.useState(config.energy?.regenRate ?? 500);
185635
185456
  import_react41.useEffect(() => {
185636
185457
  if (message) {
185637
185458
  const timer = setTimeout(() => setMessage(null), 3000);
@@ -185661,7 +185482,7 @@ function ConfigPanel({
185661
185482
  }
185662
185483
  return;
185663
185484
  }
185664
- if (key.escape) {
185485
+ if (key.escape || input === "q" || input === "Q") {
185665
185486
  onCancel();
185666
185487
  return;
185667
185488
  }
@@ -185731,12 +185552,68 @@ function ConfigPanel({
185731
185552
  return;
185732
185553
  }
185733
185554
  if (section.id === "energy" && !editingField && input !== "t" && input !== "T") {
185555
+ if (key.upArrow) {
185556
+ setSelectedEnergyField((prev) => prev === 0 ? 1 : 0);
185557
+ return;
185558
+ }
185559
+ if (key.downArrow) {
185560
+ setSelectedEnergyField((prev) => prev === 1 ? 0 : 1);
185561
+ return;
185562
+ }
185563
+ if (key.leftArrow) {
185564
+ if (selectedEnergyField === 0) {
185565
+ setEnergyMaxEnergy((prev) => Math.max(1000, prev - 1000));
185566
+ } else {
185567
+ setEnergyRegenRate((prev) => Math.max(100, prev - 100));
185568
+ }
185569
+ return;
185570
+ }
185571
+ if (key.rightArrow) {
185572
+ if (selectedEnergyField === 0) {
185573
+ setEnergyMaxEnergy((prev) => Math.min(1e5, prev + 1000));
185574
+ } else {
185575
+ setEnergyRegenRate((prev) => Math.min(5000, prev + 100));
185576
+ }
185577
+ return;
185578
+ }
185579
+ if (key.return || input === "s" || input === "S") {
185580
+ setMode("location-select");
185581
+ return;
185582
+ }
185583
+ return;
185584
+ }
185585
+ if (section.id === "statusLine" && !editingField) {
185586
+ const sl2 = config.statusLine || {};
185587
+ const toggleField = (field, current) => {
185588
+ handleSaveField(`statusLine.${field}`, !(current ?? true));
185589
+ };
185734
185590
  if (input === "1") {
185735
- setEditingField("energy.maxEnergy");
185736
- setEditValue(String(config.energy?.maxEnergy ?? 1e4));
185737
- } else if (input === "2") {
185738
- setEditingField("energy.regenRate");
185739
- setEditValue(String(config.energy?.regenRate ?? 500));
185591
+ toggleField("showContext", sl2.showContext);
185592
+ return;
185593
+ }
185594
+ if (input === "2") {
185595
+ toggleField("showSession", sl2.showSession);
185596
+ return;
185597
+ }
185598
+ if (input === "3") {
185599
+ toggleField("showElapsed", sl2.showElapsed);
185600
+ return;
185601
+ }
185602
+ if (input === "4") {
185603
+ toggleField("showHeartbeat", sl2.showHeartbeat);
185604
+ return;
185605
+ }
185606
+ if (input === "5") {
185607
+ toggleField("showVoice", sl2.showVoice);
185608
+ return;
185609
+ }
185610
+ if (input === "6") {
185611
+ toggleField("showQueue", sl2.showQueue);
185612
+ return;
185613
+ }
185614
+ if (input === "7") {
185615
+ toggleField("showRecentTools", sl2.showRecentTools);
185616
+ return;
185740
185617
  }
185741
185618
  return;
185742
185619
  }
@@ -185808,6 +185685,15 @@ function ConfigPanel({
185808
185685
  }
185809
185686
  };
185810
185687
  }
185688
+ if (!saveUpdates && section.id === "energy") {
185689
+ saveUpdates = {
185690
+ energy: {
185691
+ ...config.energy,
185692
+ maxEnergy: energyMaxEnergy,
185693
+ regenRate: energyRegenRate
185694
+ }
185695
+ };
185696
+ }
185811
185697
  if (saveUpdates) {
185812
185698
  await onSave(location, saveUpdates);
185813
185699
  setMessage({ type: "success", text: `Saved to ${location} config` });
@@ -186417,59 +186303,43 @@ function ConfigPanel({
186417
186303
  }, undefined, true, undefined, this)
186418
186304
  ]
186419
186305
  }, undefined, true, undefined, this),
186420
- editingField === "energy.maxEnergy" ? /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
186421
- children: [
186422
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186423
- children: "1. Max Energy: "
186424
- }, undefined, false, undefined, this),
186425
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(build_default2, {
186426
- value: editValue,
186427
- onChange: setEditValue,
186428
- onSubmit: handleFieldSubmit
186429
- }, undefined, false, undefined, this)
186430
- ]
186431
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186306
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
186432
186307
  children: [
186433
- "1. Max Energy: ",
186434
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186435
- color: "cyan",
186436
- children: config.energy?.maxEnergy ?? 1e4
186437
- }, undefined, false, undefined, this),
186438
186308
  /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186439
- dimColor: true,
186309
+ inverse: selectedEnergyField === 0,
186440
186310
  children: [
186441
- " ",
186442
- getSource("energy.maxEnergy")
186311
+ selectedEnergyField === 0 ? ">" : " ",
186312
+ " Max Energy: ",
186313
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186314
+ color: "cyan",
186315
+ children: energyMaxEnergy
186316
+ }, undefined, false, undefined, this)
186443
186317
  ]
186444
- }, undefined, true, undefined, this)
186445
- ]
186446
- }, undefined, true, undefined, this),
186447
- editingField === "energy.regenRate" ? /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
186448
- children: [
186449
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186450
- children: "2. Regen Rate: "
186451
- }, undefined, false, undefined, this),
186452
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(build_default2, {
186453
- value: editValue,
186454
- onChange: setEditValue,
186455
- onSubmit: handleFieldSubmit
186318
+ }, undefined, true, undefined, this),
186319
+ selectedEnergyField === 0 && /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186320
+ dimColor: true,
186321
+ children: " (\u2190\u2192 adjust)"
186456
186322
  }, undefined, false, undefined, this)
186457
186323
  ]
186458
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186324
+ }, undefined, true, undefined, this),
186325
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
186459
186326
  children: [
186460
- "2. Regen Rate: ",
186461
186327
  /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186462
- color: "cyan",
186463
- children: config.energy?.regenRate ?? 500
186464
- }, undefined, false, undefined, this),
186465
- "/min",
186466
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186467
- dimColor: true,
186328
+ inverse: selectedEnergyField === 1,
186468
186329
  children: [
186469
- " ",
186470
- getSource("energy.regenRate")
186330
+ selectedEnergyField === 1 ? ">" : " ",
186331
+ " Regen Rate: ",
186332
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186333
+ color: "cyan",
186334
+ children: energyRegenRate
186335
+ }, undefined, false, undefined, this),
186336
+ "/min"
186471
186337
  ]
186472
- }, undefined, true, undefined, this)
186338
+ }, undefined, true, undefined, this),
186339
+ selectedEnergyField === 1 && /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186340
+ dimColor: true,
186341
+ children: " (\u2190\u2192 adjust)"
186342
+ }, undefined, false, undefined, this)
186473
186343
  ]
186474
186344
  }, undefined, true, undefined, this),
186475
186345
  /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
@@ -186526,11 +186396,101 @@ function ConfigPanel({
186526
186396
  marginTop: 1,
186527
186397
  children: /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186528
186398
  dimColor: true,
186529
- children: "Press t to toggle | 1-2 to edit | Esc to go back"
186399
+ children: "\u2191\u2193 select | \u2190\u2192 adjust | t toggle | Enter/s save | Esc back"
186530
186400
  }, undefined, false, undefined, this)
186531
186401
  }, undefined, false, undefined, this)
186532
186402
  ]
186533
186403
  }, undefined, true, undefined, this);
186404
+ case "statusLine": {
186405
+ const sl2 = config.statusLine || {};
186406
+ const showIcon = (v7) => v7 ?? true ? "Yes" : "No";
186407
+ const showColor = (v7) => v7 ?? true ? "green" : "red";
186408
+ return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
186409
+ flexDirection: "column",
186410
+ children: [
186411
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186412
+ bold: true,
186413
+ children: "Status Line Settings"
186414
+ }, undefined, false, undefined, this),
186415
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
186416
+ marginTop: 1,
186417
+ flexDirection: "column",
186418
+ children: [
186419
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186420
+ children: [
186421
+ "1. Context %: ",
186422
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186423
+ color: showColor(sl2.showContext),
186424
+ children: showIcon(sl2.showContext)
186425
+ }, undefined, false, undefined, this)
186426
+ ]
186427
+ }, undefined, true, undefined, this),
186428
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186429
+ children: [
186430
+ "2. Session: ",
186431
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186432
+ color: showColor(sl2.showSession),
186433
+ children: showIcon(sl2.showSession)
186434
+ }, undefined, false, undefined, this)
186435
+ ]
186436
+ }, undefined, true, undefined, this),
186437
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186438
+ children: [
186439
+ "3. Elapsed Time: ",
186440
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186441
+ color: showColor(sl2.showElapsed),
186442
+ children: showIcon(sl2.showElapsed)
186443
+ }, undefined, false, undefined, this)
186444
+ ]
186445
+ }, undefined, true, undefined, this),
186446
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186447
+ children: [
186448
+ "4. Heartbeat: ",
186449
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186450
+ color: showColor(sl2.showHeartbeat),
186451
+ children: showIcon(sl2.showHeartbeat)
186452
+ }, undefined, false, undefined, this)
186453
+ ]
186454
+ }, undefined, true, undefined, this),
186455
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186456
+ children: [
186457
+ "5. Voice: ",
186458
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186459
+ color: showColor(sl2.showVoice),
186460
+ children: showIcon(sl2.showVoice)
186461
+ }, undefined, false, undefined, this)
186462
+ ]
186463
+ }, undefined, true, undefined, this),
186464
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186465
+ children: [
186466
+ "6. Queue: ",
186467
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186468
+ color: showColor(sl2.showQueue),
186469
+ children: showIcon(sl2.showQueue)
186470
+ }, undefined, false, undefined, this)
186471
+ ]
186472
+ }, undefined, true, undefined, this),
186473
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186474
+ children: [
186475
+ "7. Recent Tools: ",
186476
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186477
+ color: showColor(sl2.showRecentTools),
186478
+ children: showIcon(sl2.showRecentTools)
186479
+ }, undefined, false, undefined, this)
186480
+ ]
186481
+ }, undefined, true, undefined, this)
186482
+ ]
186483
+ }, undefined, true, undefined, this),
186484
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
186485
+ marginTop: 1,
186486
+ children: /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
186487
+ dimColor: true,
186488
+ children: "1-7 toggle metric | Esc back"
186489
+ }, undefined, false, undefined, this)
186490
+ }, undefined, false, undefined, this)
186491
+ ]
186492
+ }, undefined, true, undefined, this);
186493
+ }
186534
186494
  default:
186535
186495
  return null;
186536
186496
  }
@@ -187914,6 +187874,15 @@ function GuardrailsPanel({
187914
187874
  // packages/terminal/src/components/BudgetPanel.tsx
187915
187875
  var import_react44 = __toESM(require_react(), 1);
187916
187876
  var jsx_dev_runtime22 = __toESM(require_jsx_dev_runtime(), 1);
187877
+ var EDIT_FIELDS = [
187878
+ { key: "maxTotalTokens", label: "Max Total Tokens", unit: "tokens", toStored: (v7) => v7, toDisplay: (v7) => v7 },
187879
+ { key: "maxInputTokens", label: "Max Input Tokens", unit: "tokens", toStored: (v7) => v7, toDisplay: (v7) => v7 },
187880
+ { key: "maxOutputTokens", label: "Max Output Tokens", unit: "tokens", toStored: (v7) => v7, toDisplay: (v7) => v7 },
187881
+ { key: "maxLlmCalls", label: "Max LLM Calls", unit: "calls", toStored: (v7) => v7, toDisplay: (v7) => v7 },
187882
+ { key: "maxToolCalls", label: "Max Tool Calls", unit: "calls", toStored: (v7) => v7, toDisplay: (v7) => v7 },
187883
+ { key: "maxDurationMs", label: "Max Duration", unit: "min", toStored: (v7) => v7 * 60 * 1000, toDisplay: (v7) => Math.round(v7 / 60000) }
187884
+ ];
187885
+ var ON_EXCEEDED_OPTIONS = ["warn", "pause", "stop"];
187917
187886
  var PRESET_LIMITS = {
187918
187887
  light: {
187919
187888
  name: "Light",
@@ -187950,7 +187919,7 @@ function formatDuration3(ms2) {
187950
187919
  return `${Math.round(ms2 / 60000)}m`;
187951
187920
  return `${Math.round(ms2 / 1000)}s`;
187952
187921
  }
187953
- function UsageBar({ used, limit: limit2, color }) {
187922
+ function UsageBar({ used, limit: limit2 }) {
187954
187923
  if (!limit2) {
187955
187924
  return /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text3, {
187956
187925
  dimColor: true,
@@ -187993,12 +187962,115 @@ function BudgetPanel({
187993
187962
  onToggleEnabled,
187994
187963
  onReset,
187995
187964
  onSetLimits,
187965
+ onSetOnExceeded,
187996
187966
  onCancel
187997
187967
  }) {
187998
187968
  const [mode, setMode] = import_react44.useState("overview");
187999
187969
  const [selectedPreset, setSelectedPreset] = import_react44.useState(0);
187970
+ const [editFieldIndex, setEditFieldIndex] = import_react44.useState(0);
187971
+ const [editValues, setEditValues] = import_react44.useState({});
187972
+ const [editOnExceeded, setEditOnExceeded] = import_react44.useState("warn");
187973
+ const [editingField, setEditingField] = import_react44.useState(false);
187974
+ const totalEditRows = EDIT_FIELDS.length + 1;
188000
187975
  const presetKeys = Object.keys(PRESET_LIMITS);
187976
+ function initEditValues() {
187977
+ const limits3 = config.session || {};
187978
+ const values = {};
187979
+ for (const field of EDIT_FIELDS) {
187980
+ const stored = limits3[field.key];
187981
+ values[field.key] = stored ? String(field.toDisplay(stored)) : "";
187982
+ }
187983
+ setEditValues(values);
187984
+ setEditOnExceeded(config.onExceeded || "warn");
187985
+ setEditFieldIndex(0);
187986
+ setEditingField(false);
187987
+ }
187988
+ function saveEditValues() {
187989
+ const newLimits = {};
187990
+ for (const field of EDIT_FIELDS) {
187991
+ const raw = editValues[field.key];
187992
+ if (raw && raw.trim() !== "") {
187993
+ const num = parseInt(raw, 10);
187994
+ if (!isNaN(num) && num > 0) {
187995
+ newLimits[field.key] = field.toStored(num);
187996
+ }
187997
+ }
187998
+ }
187999
+ onSetLimits("session", newLimits);
188000
+ if (onSetOnExceeded) {
188001
+ onSetOnExceeded(editOnExceeded);
188002
+ }
188003
+ setMode("overview");
188004
+ }
188001
188005
  use_input_default((input, key) => {
188006
+ if (mode === "edit-limits") {
188007
+ if (editingField) {
188008
+ if (key.return) {
188009
+ setEditingField(false);
188010
+ return;
188011
+ }
188012
+ if (key.escape) {
188013
+ setEditingField(false);
188014
+ return;
188015
+ }
188016
+ if (key.backspace || key.delete) {
188017
+ const fieldKey = editFieldIndex < EDIT_FIELDS.length ? EDIT_FIELDS[editFieldIndex].key : null;
188018
+ if (fieldKey) {
188019
+ setEditValues((prev) => ({
188020
+ ...prev,
188021
+ [fieldKey]: (prev[fieldKey] || "").slice(0, -1)
188022
+ }));
188023
+ }
188024
+ return;
188025
+ }
188026
+ if (editFieldIndex < EDIT_FIELDS.length && /^\d$/.test(input)) {
188027
+ const fieldKey = EDIT_FIELDS[editFieldIndex].key;
188028
+ setEditValues((prev) => ({
188029
+ ...prev,
188030
+ [fieldKey]: (prev[fieldKey] || "") + input
188031
+ }));
188032
+ return;
188033
+ }
188034
+ return;
188035
+ }
188036
+ if (key.upArrow) {
188037
+ setEditFieldIndex((prev) => prev === 0 ? totalEditRows - 1 : prev - 1);
188038
+ return;
188039
+ }
188040
+ if (key.downArrow) {
188041
+ setEditFieldIndex((prev) => prev >= totalEditRows - 1 ? 0 : prev + 1);
188042
+ return;
188043
+ }
188044
+ if (key.return || input === " ") {
188045
+ if (editFieldIndex < EDIT_FIELDS.length) {
188046
+ setEditingField(true);
188047
+ } else {
188048
+ const currentIdx = ON_EXCEEDED_OPTIONS.indexOf(editOnExceeded);
188049
+ setEditOnExceeded(ON_EXCEEDED_OPTIONS[(currentIdx + 1) % ON_EXCEEDED_OPTIONS.length]);
188050
+ }
188051
+ return;
188052
+ }
188053
+ if (input === "c" || input === "C") {
188054
+ if (editFieldIndex < EDIT_FIELDS.length) {
188055
+ const fieldKey = EDIT_FIELDS[editFieldIndex].key;
188056
+ setEditValues((prev) => ({ ...prev, [fieldKey]: "" }));
188057
+ }
188058
+ return;
188059
+ }
188060
+ if (input === "s" || input === "S") {
188061
+ saveEditValues();
188062
+ return;
188063
+ }
188064
+ if (key.escape || input === "b" || input === "B") {
188065
+ setMode("overview");
188066
+ return;
188067
+ }
188068
+ if (input === "q" || input === "Q") {
188069
+ onCancel();
188070
+ return;
188071
+ }
188072
+ return;
188073
+ }
188002
188074
  if (mode === "preset-select") {
188003
188075
  if (key.upArrow) {
188004
188076
  setSelectedPreset((prev) => prev === 0 ? presetKeys.length - 1 : prev - 1);
@@ -188019,7 +188091,7 @@ function BudgetPanel({
188019
188091
  setMode("overview");
188020
188092
  return;
188021
188093
  }
188022
- if (key.escape || input === "q" || input === "Q") {
188094
+ if (input === "q" || input === "Q") {
188023
188095
  onCancel();
188024
188096
  return;
188025
188097
  }
@@ -188046,8 +188118,18 @@ function BudgetPanel({
188046
188118
  setMode("preset-select");
188047
188119
  return;
188048
188120
  }
188121
+ if (key.return || input === "i" || input === "I") {
188122
+ initEditValues();
188123
+ setMode("edit-limits");
188124
+ return;
188125
+ }
188049
188126
  }
188050
188127
  if (mode === "limits") {
188128
+ if (input === "i" || input === "I" || key.return) {
188129
+ initEditValues();
188130
+ setMode("edit-limits");
188131
+ return;
188132
+ }
188051
188133
  if (key.escape || input === "b" || input === "B") {
188052
188134
  setMode("overview");
188053
188135
  return;
@@ -188058,6 +188140,120 @@ function BudgetPanel({
188058
188140
  return;
188059
188141
  }
188060
188142
  }, { isActive: true });
188143
+ if (mode === "edit-limits") {
188144
+ return /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
188145
+ flexDirection: "column",
188146
+ paddingY: 1,
188147
+ children: [
188148
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
188149
+ marginBottom: 1,
188150
+ children: [
188151
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text3, {
188152
+ bold: true,
188153
+ children: "Edit Budget Limits"
188154
+ }, undefined, false, undefined, this),
188155
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text3, {
188156
+ dimColor: true,
188157
+ children: " (session scope)"
188158
+ }, undefined, false, undefined, this)
188159
+ ]
188160
+ }, undefined, true, undefined, this),
188161
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
188162
+ flexDirection: "column",
188163
+ borderStyle: "round",
188164
+ borderColor: "gray",
188165
+ paddingX: 1,
188166
+ paddingY: 1,
188167
+ children: [
188168
+ EDIT_FIELDS.map((field, index) => {
188169
+ const isSelected = index === editFieldIndex;
188170
+ const value = editValues[field.key] || "";
188171
+ const isEditing = isSelected && editingField;
188172
+ return /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
188173
+ gap: 1,
188174
+ children: [
188175
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text3, {
188176
+ inverse: isSelected,
188177
+ children: isSelected ? ">" : " "
188178
+ }, undefined, false, undefined, this),
188179
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text3, {
188180
+ bold: isSelected,
188181
+ dimColor: !isSelected,
188182
+ children: field.label.padEnd(20)
188183
+ }, undefined, false, undefined, this),
188184
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
188185
+ minWidth: 15,
188186
+ children: isEditing ? /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text3, {
188187
+ children: [
188188
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text3, {
188189
+ color: "cyan",
188190
+ children: value
188191
+ }, undefined, false, undefined, this),
188192
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text3, {
188193
+ color: "cyan",
188194
+ bold: true,
188195
+ children: "_"
188196
+ }, undefined, false, undefined, this),
188197
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text3, {
188198
+ dimColor: true,
188199
+ children: [
188200
+ " ",
188201
+ field.unit
188202
+ ]
188203
+ }, undefined, true, undefined, this)
188204
+ ]
188205
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text3, {
188206
+ color: value ? undefined : "gray",
188207
+ children: [
188208
+ value || "unlimited",
188209
+ value ? /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text3, {
188210
+ dimColor: true,
188211
+ children: [
188212
+ " ",
188213
+ field.unit
188214
+ ]
188215
+ }, undefined, true, undefined, this) : null
188216
+ ]
188217
+ }, undefined, true, undefined, this)
188218
+ }, undefined, false, undefined, this)
188219
+ ]
188220
+ }, field.key, true, undefined, this);
188221
+ }),
188222
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
188223
+ gap: 1,
188224
+ marginTop: 1,
188225
+ children: [
188226
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text3, {
188227
+ inverse: editFieldIndex === EDIT_FIELDS.length,
188228
+ children: editFieldIndex === EDIT_FIELDS.length ? ">" : " "
188229
+ }, undefined, false, undefined, this),
188230
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text3, {
188231
+ bold: editFieldIndex === EDIT_FIELDS.length,
188232
+ dimColor: editFieldIndex !== EDIT_FIELDS.length,
188233
+ children: "On Exceeded".padEnd(20)
188234
+ }, undefined, false, undefined, this),
188235
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text3, {
188236
+ color: editOnExceeded === "stop" ? "red" : editOnExceeded === "pause" ? "yellow" : "cyan",
188237
+ children: editOnExceeded
188238
+ }, undefined, false, undefined, this),
188239
+ editFieldIndex === EDIT_FIELDS.length && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text3, {
188240
+ dimColor: true,
188241
+ children: " (Enter to cycle)"
188242
+ }, undefined, false, undefined, this)
188243
+ ]
188244
+ }, undefined, true, undefined, this)
188245
+ ]
188246
+ }, undefined, true, undefined, this),
188247
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
188248
+ marginTop: 1,
188249
+ children: /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text3, {
188250
+ dimColor: true,
188251
+ children: editingField ? "Type digits | Enter/Esc to confirm" : "\u2191\u2193 navigate | Enter to edit | [c]lear | [s]ave | [b]ack | [q]uit"
188252
+ }, undefined, false, undefined, this)
188253
+ }, undefined, false, undefined, this)
188254
+ ]
188255
+ }, undefined, true, undefined, this);
188256
+ }
188061
188257
  if (mode === "preset-select") {
188062
188258
  return /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
188063
188259
  flexDirection: "column",
@@ -188227,13 +188423,13 @@ function BudgetPanel({
188227
188423
  marginTop: 1,
188228
188424
  children: /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text3, {
188229
188425
  dimColor: true,
188230
- children: "[b]ack [q]uit"
188426
+ children: "[i] edit | [b]ack | [q]uit"
188231
188427
  }, undefined, false, undefined, this)
188232
188428
  }, undefined, false, undefined, this)
188233
188429
  ]
188234
188430
  }, undefined, true, undefined, this);
188235
188431
  }
188236
- const { usage, limits: limits2, checks, overallExceeded } = sessionStatus;
188432
+ const { usage, limits: limits2, overallExceeded } = sessionStatus;
188237
188433
  return /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
188238
188434
  flexDirection: "column",
188239
188435
  paddingY: 1,
@@ -188405,7 +188601,7 @@ function BudgetPanel({
188405
188601
  children: /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text3, {
188406
188602
  color: "yellow",
188407
188603
  children: [
188408
- "\u26A0 ",
188604
+ "! ",
188409
188605
  sessionStatus.warningsCount,
188410
188606
  " warning",
188411
188607
  sessionStatus.warningsCount !== 1 ? "s" : ""
@@ -188418,7 +188614,7 @@ function BudgetPanel({
188418
188614
  color: "red",
188419
188615
  bold: true,
188420
188616
  children: [
188421
- "\u26D4 Budget exceeded! Action: ",
188617
+ "Budget exceeded! Action: ",
188422
188618
  config.onExceeded || "warn"
188423
188619
  ]
188424
188620
  }, undefined, true, undefined, this)
@@ -188429,7 +188625,7 @@ function BudgetPanel({
188429
188625
  marginTop: 1,
188430
188626
  children: /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text3, {
188431
188627
  dimColor: true,
188432
- children: "[e]nable [d]isable [r]eset [l]imits [p]reset [q]uit"
188628
+ children: "[e]nable [d]isable [r]eset [l]imits [p]reset [i] edit | [q]uit"
188433
188629
  }, undefined, false, undefined, this)
188434
188630
  }, undefined, false, undefined, this)
188435
188631
  ]
@@ -189274,141 +189470,6 @@ function AssistantsRegistryPanel({
189274
189470
  // packages/terminal/src/components/SchedulesPanel.tsx
189275
189471
  var import_react46 = __toESM(require_react(), 1);
189276
189472
  var jsx_dev_runtime24 = __toESM(require_jsx_dev_runtime(), 1);
189277
- function MarkdownContent({ content, color }) {
189278
- if (!content)
189279
- return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189280
- dimColor: true,
189281
- children: "(empty)"
189282
- }, undefined, false, undefined, this);
189283
- const lines = content.split(`
189284
- `);
189285
- const elements = [];
189286
- for (let i5 = 0;i5 < lines.length; i5++) {
189287
- const line = lines[i5];
189288
- if (/^[-*]{3,}\s*$/.test(line.trim())) {
189289
- elements.push(/* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189290
- marginY: 0,
189291
- children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189292
- dimColor: true,
189293
- children: "\u2500".repeat(48)
189294
- }, undefined, false, undefined, this)
189295
- }, i5, false, undefined, this));
189296
- continue;
189297
- }
189298
- const headingMatch = line.match(/^(#{1,4})\s+(.+)$/);
189299
- if (headingMatch) {
189300
- const text = headingMatch[2];
189301
- elements.push(/* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189302
- marginTop: i5 > 0 ? 0 : 0,
189303
- children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189304
- bold: true,
189305
- color,
189306
- children: renderInlineFormatting(text)
189307
- }, undefined, false, undefined, this)
189308
- }, i5, false, undefined, this));
189309
- continue;
189310
- }
189311
- const bulletMatch = line.match(/^(\s*)([-*])\s+(.+)$/);
189312
- if (bulletMatch) {
189313
- const indent = bulletMatch[1].length;
189314
- const text = bulletMatch[3];
189315
- elements.push(/* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189316
- paddingLeft: indent > 0 ? 2 : 0,
189317
- children: [
189318
- /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189319
- dimColor: true,
189320
- children: [
189321
- " ",
189322
- "\u203A",
189323
- " "
189324
- ]
189325
- }, undefined, true, undefined, this),
189326
- /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189327
- color,
189328
- wrap: "wrap",
189329
- children: renderInlineFormatting(text)
189330
- }, undefined, false, undefined, this)
189331
- ]
189332
- }, i5, true, undefined, this));
189333
- continue;
189334
- }
189335
- const numberedMatch = line.match(/^(\s*)(\d+)[.)]\s+(.+)$/);
189336
- if (numberedMatch) {
189337
- const num = numberedMatch[2];
189338
- const text = numberedMatch[3];
189339
- elements.push(/* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189340
- children: [
189341
- /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189342
- dimColor: true,
189343
- children: [
189344
- " ",
189345
- num,
189346
- ". "
189347
- ]
189348
- }, undefined, true, undefined, this),
189349
- /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189350
- color,
189351
- wrap: "wrap",
189352
- children: renderInlineFormatting(text)
189353
- }, undefined, false, undefined, this)
189354
- ]
189355
- }, i5, true, undefined, this));
189356
- continue;
189357
- }
189358
- if (line.trim() === "") {
189359
- elements.push(/* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189360
- children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189361
- children: " "
189362
- }, undefined, false, undefined, this)
189363
- }, i5, false, undefined, this));
189364
- continue;
189365
- }
189366
- elements.push(/* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189367
- children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189368
- color,
189369
- wrap: "wrap",
189370
- children: renderInlineFormatting(line)
189371
- }, undefined, false, undefined, this)
189372
- }, i5, false, undefined, this));
189373
- }
189374
- return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189375
- flexDirection: "column",
189376
- children: elements
189377
- }, undefined, false, undefined, this);
189378
- }
189379
- function renderInlineFormatting(text) {
189380
- const parts = [];
189381
- const regex2 = /(\*\*(.+?)\*\*|\*(.+?)\*|`(.+?)`)/g;
189382
- let lastIndex = 0;
189383
- let match;
189384
- let key = 0;
189385
- while ((match = regex2.exec(text)) !== null) {
189386
- if (match.index > lastIndex) {
189387
- parts.push(text.slice(lastIndex, match.index));
189388
- }
189389
- if (match[2]) {
189390
- parts.push(/* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189391
- bold: true,
189392
- children: match[2]
189393
- }, key++, false, undefined, this));
189394
- } else if (match[3]) {
189395
- parts.push(/* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189396
- dimColor: true,
189397
- children: match[3]
189398
- }, key++, false, undefined, this));
189399
- } else if (match[4]) {
189400
- parts.push(/* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189401
- color: "cyan",
189402
- children: match[4]
189403
- }, key++, false, undefined, this));
189404
- }
189405
- lastIndex = match.index + match[0].length;
189406
- }
189407
- if (lastIndex < text.length) {
189408
- parts.push(text.slice(lastIndex));
189409
- }
189410
- return parts.length > 0 ? parts : [text];
189411
- }
189412
189473
  var STATUS_ICONS2 = {
189413
189474
  active: "\u25CF",
189414
189475
  paused: "\u25D0",
@@ -189428,8 +189489,8 @@ var KIND_LABELS = {
189428
189489
  interval: "Interval"
189429
189490
  };
189430
189491
  var ACTION_ICONS = {
189431
- command: "\u2318",
189432
- message: "\uD83D\uDCAC"
189492
+ command: "$",
189493
+ message: ">"
189433
189494
  };
189434
189495
  function getActionDisplay(schedule) {
189435
189496
  const actionType = schedule.actionType || "command";
@@ -189450,15 +189511,14 @@ function formatRelativeTime3(timestamp) {
189450
189511
  const hours = Math.floor(minutes / 60);
189451
189512
  const days = Math.floor(hours / 24);
189452
189513
  let timeStr;
189453
- if (days > 0) {
189514
+ if (days > 0)
189454
189515
  timeStr = `${days}d ${hours % 24}h`;
189455
- } else if (hours > 0) {
189516
+ else if (hours > 0)
189456
189517
  timeStr = `${hours}h ${minutes % 60}m`;
189457
- } else if (minutes > 0) {
189518
+ else if (minutes > 0)
189458
189519
  timeStr = `${minutes}m`;
189459
- } else {
189520
+ else
189460
189521
  timeStr = `${seconds}s`;
189461
- }
189462
189522
  return isPast ? `${timeStr} ago` : `in ${timeStr}`;
189463
189523
  }
189464
189524
  function formatAbsoluteTime2(timestamp) {
@@ -189481,32 +189541,178 @@ function getScheduleDescription(schedule) {
189481
189541
  return kind2;
189482
189542
  }
189483
189543
  }
189544
+ var KIND_OPTIONS = [
189545
+ { id: "once", label: "One-time", desc: "Run once at a specific ISO date/time" },
189546
+ { id: "cron", label: "Cron", desc: 'Run on a cron schedule (e.g. "0 9 * * *")' },
189547
+ { id: "interval", label: "Interval", desc: "Run every N minutes/hours" }
189548
+ ];
189549
+ var INTERVAL_UNITS = ["seconds", "minutes", "hours"];
189484
189550
  function SchedulesPanel({
189485
189551
  schedules,
189552
+ sessionId,
189486
189553
  onPause,
189487
189554
  onResume,
189488
189555
  onDelete,
189489
189556
  onRun,
189557
+ onCreate,
189490
189558
  onRefresh,
189491
189559
  onClose
189492
189560
  }) {
189493
189561
  const [selectedIndex, setSelectedIndex] = import_react46.useState(0);
189494
189562
  const [mode, setMode] = import_react46.useState("list");
189495
189563
  const [isSubmitting, setIsSubmitting] = import_react46.useState(false);
189564
+ const [createStep, setCreateStep] = import_react46.useState("kind");
189565
+ const [createKindIndex, setCreateKindIndex] = import_react46.useState(0);
189566
+ const [createCron, setCreateCron] = import_react46.useState("");
189567
+ const [createTime, setCreateTime] = import_react46.useState("");
189568
+ const [createInterval, setCreateInterval] = import_react46.useState("5");
189569
+ const [createIntervalUnitIndex, setCreateIntervalUnitIndex] = import_react46.useState(1);
189570
+ const [createCommand, setCreateCommand] = import_react46.useState("");
189571
+ const [createDescription, setCreateDescription] = import_react46.useState("");
189572
+ const [createError, setCreateError] = import_react46.useState(null);
189496
189573
  const sortedSchedules = [...schedules].sort((a5, b8) => {
189497
189574
  if (a5.status === "active" && b8.status !== "active")
189498
189575
  return -1;
189499
189576
  if (b8.status === "active" && a5.status !== "active")
189500
189577
  return 1;
189501
- const aNext = a5.nextRunAt || Infinity;
189502
- const bNext = b8.nextRunAt || Infinity;
189503
- return aNext - bNext;
189578
+ return (a5.nextRunAt || Infinity) - (b8.nextRunAt || Infinity);
189504
189579
  });
189505
189580
  import_react46.useEffect(() => {
189506
- setSelectedIndex((prev) => Math.min(prev, Math.max(0, sortedSchedules.length - 1)));
189581
+ setSelectedIndex((prev) => Math.min(prev, Math.max(0, sortedSchedules.length)));
189507
189582
  }, [sortedSchedules.length]);
189508
189583
  const selectedSchedule = sortedSchedules[selectedIndex];
189584
+ function resetCreateState() {
189585
+ setCreateStep("kind");
189586
+ setCreateKindIndex(0);
189587
+ setCreateCron("");
189588
+ setCreateTime("");
189589
+ setCreateInterval("5");
189590
+ setCreateIntervalUnitIndex(1);
189591
+ setCreateCommand("");
189592
+ setCreateDescription("");
189593
+ setCreateError(null);
189594
+ }
189595
+ async function handleCreateSubmit() {
189596
+ const kind2 = KIND_OPTIONS[createKindIndex].id;
189597
+ const command = createCommand.trim();
189598
+ if (!command) {
189599
+ setCreateError("Command is required");
189600
+ setCreateStep("command");
189601
+ return;
189602
+ }
189603
+ const schedule = {
189604
+ createdBy: "user",
189605
+ sessionId,
189606
+ command,
189607
+ description: createDescription.trim() || undefined,
189608
+ status: "active",
189609
+ schedule: { kind: kind2 }
189610
+ };
189611
+ if (kind2 === "once") {
189612
+ schedule.schedule.at = createTime.trim();
189613
+ } else if (kind2 === "cron") {
189614
+ schedule.schedule.cron = createCron.trim();
189615
+ } else if (kind2 === "interval") {
189616
+ const val = parseInt(createInterval, 10);
189617
+ if (isNaN(val) || val <= 0) {
189618
+ setCreateError("Interval must be a positive number");
189619
+ setCreateStep("interval");
189620
+ return;
189621
+ }
189622
+ schedule.schedule.kind = "interval";
189623
+ schedule.schedule.interval = val;
189624
+ schedule.schedule.unit = INTERVAL_UNITS[createIntervalUnitIndex];
189625
+ }
189626
+ setIsSubmitting(true);
189627
+ setCreateError(null);
189628
+ try {
189629
+ await onCreate(schedule);
189630
+ resetCreateState();
189631
+ setMode("list");
189632
+ } catch (err) {
189633
+ setCreateError(err instanceof Error ? err.message : String(err));
189634
+ } finally {
189635
+ setIsSubmitting(false);
189636
+ }
189637
+ }
189638
+ use_input_default((input, key) => {
189639
+ if (mode !== "create")
189640
+ return;
189641
+ if (createStep === "cron" || createStep === "time" || createStep === "command" || createStep === "description")
189642
+ return;
189643
+ if (key.escape) {
189644
+ if (createStep === "kind") {
189645
+ resetCreateState();
189646
+ setMode("list");
189647
+ } else {
189648
+ const stepOrder = ["kind", "cron", "time", "interval", "command", "description", "confirm"];
189649
+ const currentIdx = stepOrder.indexOf(createStep);
189650
+ if (currentIdx > 0) {
189651
+ setCreateStep(stepOrder[currentIdx - 1]);
189652
+ } else {
189653
+ resetCreateState();
189654
+ setMode("list");
189655
+ }
189656
+ }
189657
+ return;
189658
+ }
189659
+ if (createStep === "kind") {
189660
+ if (key.upArrow) {
189661
+ setCreateKindIndex((prev) => prev === 0 ? KIND_OPTIONS.length - 1 : prev - 1);
189662
+ return;
189663
+ }
189664
+ if (key.downArrow) {
189665
+ setCreateKindIndex((prev) => prev === KIND_OPTIONS.length - 1 ? 0 : prev + 1);
189666
+ return;
189667
+ }
189668
+ if (key.return) {
189669
+ const kind2 = KIND_OPTIONS[createKindIndex].id;
189670
+ if (kind2 === "once")
189671
+ setCreateStep("time");
189672
+ else if (kind2 === "cron")
189673
+ setCreateStep("cron");
189674
+ else if (kind2 === "interval")
189675
+ setCreateStep("interval");
189676
+ return;
189677
+ }
189678
+ }
189679
+ if (createStep === "interval") {
189680
+ if (key.upArrow) {
189681
+ setCreateInterval((prev) => String(Math.max(1, (parseInt(prev, 10) || 1) + 1)));
189682
+ return;
189683
+ }
189684
+ if (key.downArrow) {
189685
+ setCreateInterval((prev) => String(Math.max(1, (parseInt(prev, 10) || 1) - 1)));
189686
+ return;
189687
+ }
189688
+ if (key.leftArrow) {
189689
+ setCreateIntervalUnitIndex((prev) => prev === 0 ? INTERVAL_UNITS.length - 1 : prev - 1);
189690
+ return;
189691
+ }
189692
+ if (key.rightArrow) {
189693
+ setCreateIntervalUnitIndex((prev) => prev === INTERVAL_UNITS.length - 1 ? 0 : prev + 1);
189694
+ return;
189695
+ }
189696
+ if (key.return) {
189697
+ setCreateStep("command");
189698
+ return;
189699
+ }
189700
+ }
189701
+ if (createStep === "confirm") {
189702
+ if (key.return || input === "y" || input === "Y") {
189703
+ handleCreateSubmit();
189704
+ return;
189705
+ }
189706
+ if (input === "n" || input === "N") {
189707
+ resetCreateState();
189708
+ setMode("list");
189709
+ return;
189710
+ }
189711
+ }
189712
+ }, { isActive: mode === "create" && createStep !== "cron" && createStep !== "time" && createStep !== "command" && createStep !== "description" });
189509
189713
  use_input_default((input, key) => {
189714
+ if (mode === "create")
189715
+ return;
189510
189716
  if (mode === "delete-confirm") {
189511
189717
  if (input === "y" || input === "Y") {
189512
189718
  if (selectedSchedule) {
@@ -189525,7 +189731,7 @@ function SchedulesPanel({
189525
189731
  return;
189526
189732
  }
189527
189733
  if (mode === "detail") {
189528
- if (key.escape || input === "q") {
189734
+ if (key.escape || input === "q" || input === "Q") {
189529
189735
  setMode("list");
189530
189736
  return;
189531
189737
  }
@@ -189552,22 +189758,30 @@ function SchedulesPanel({
189552
189758
  }
189553
189759
  return;
189554
189760
  }
189555
- if (key.escape || input === "q") {
189761
+ if (key.escape || input === "q" || input === "Q") {
189556
189762
  onClose();
189557
189763
  return;
189558
189764
  }
189765
+ if (input === "n" || input === "N") {
189766
+ resetCreateState();
189767
+ setMode("create");
189768
+ return;
189769
+ }
189559
189770
  if (key.return) {
189560
- if (sortedSchedules.length > 0) {
189771
+ if (selectedIndex === sortedSchedules.length) {
189772
+ resetCreateState();
189773
+ setMode("create");
189774
+ } else if (sortedSchedules.length > 0) {
189561
189775
  setMode("detail");
189562
189776
  }
189563
189777
  return;
189564
189778
  }
189565
189779
  if (key.upArrow) {
189566
- setSelectedIndex((prev) => prev === 0 ? sortedSchedules.length - 1 : prev - 1);
189780
+ setSelectedIndex((prev) => prev === 0 ? sortedSchedules.length : prev - 1);
189567
189781
  return;
189568
189782
  }
189569
189783
  if (key.downArrow) {
189570
- setSelectedIndex((prev) => prev === sortedSchedules.length - 1 ? 0 : prev + 1);
189784
+ setSelectedIndex((prev) => prev === sortedSchedules.length ? 0 : prev + 1);
189571
189785
  return;
189572
189786
  }
189573
189787
  if (input === "p" || input === "P") {
@@ -189589,9 +189803,8 @@ function SchedulesPanel({
189589
189803
  return;
189590
189804
  }
189591
189805
  if (input === "d" || input === "D") {
189592
- if (selectedSchedule) {
189806
+ if (selectedSchedule)
189593
189807
  setMode("delete-confirm");
189594
- }
189595
189808
  return;
189596
189809
  }
189597
189810
  if (input === "f" || input === "F") {
@@ -189604,7 +189817,324 @@ function SchedulesPanel({
189604
189817
  setSelectedIndex(num - 1);
189605
189818
  return;
189606
189819
  }
189607
- });
189820
+ }, { isActive: mode !== "create" });
189821
+ if (mode === "create") {
189822
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189823
+ flexDirection: "column",
189824
+ paddingY: 1,
189825
+ children: [
189826
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189827
+ marginBottom: 1,
189828
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189829
+ bold: true,
189830
+ color: "cyan",
189831
+ children: "New Schedule"
189832
+ }, undefined, false, undefined, this)
189833
+ }, undefined, false, undefined, this),
189834
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189835
+ flexDirection: "column",
189836
+ borderStyle: "round",
189837
+ borderColor: "gray",
189838
+ paddingX: 1,
189839
+ paddingY: 1,
189840
+ children: [
189841
+ createStep === "kind" && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189842
+ flexDirection: "column",
189843
+ children: [
189844
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189845
+ bold: true,
189846
+ children: "Select schedule type:"
189847
+ }, undefined, false, undefined, this),
189848
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189849
+ flexDirection: "column",
189850
+ marginTop: 1,
189851
+ children: KIND_OPTIONS.map((opt, idx) => /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189852
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189853
+ inverse: idx === createKindIndex,
189854
+ children: [
189855
+ idx === createKindIndex ? ">" : " ",
189856
+ " ",
189857
+ opt.label.padEnd(12),
189858
+ " ",
189859
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189860
+ dimColor: true,
189861
+ children: opt.desc
189862
+ }, undefined, false, undefined, this)
189863
+ ]
189864
+ }, undefined, true, undefined, this)
189865
+ }, opt.id, false, undefined, this))
189866
+ }, undefined, false, undefined, this),
189867
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189868
+ marginTop: 1,
189869
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189870
+ dimColor: true,
189871
+ children: "\u2191\u2193 select | Enter confirm | Esc cancel"
189872
+ }, undefined, false, undefined, this)
189873
+ }, undefined, false, undefined, this)
189874
+ ]
189875
+ }, undefined, true, undefined, this),
189876
+ createStep === "cron" && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189877
+ flexDirection: "column",
189878
+ children: [
189879
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189880
+ bold: true,
189881
+ children: "Enter cron expression:"
189882
+ }, undefined, false, undefined, this),
189883
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189884
+ marginTop: 1,
189885
+ children: [
189886
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189887
+ children: "Cron: "
189888
+ }, undefined, false, undefined, this),
189889
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(build_default2, {
189890
+ value: createCron,
189891
+ onChange: setCreateCron,
189892
+ onSubmit: () => {
189893
+ if (createCron.trim())
189894
+ setCreateStep("command");
189895
+ },
189896
+ placeholder: 'e.g. "0 9 * * *" (daily at 9am)'
189897
+ }, undefined, false, undefined, this)
189898
+ ]
189899
+ }, undefined, true, undefined, this),
189900
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189901
+ marginTop: 1,
189902
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189903
+ dimColor: true,
189904
+ children: "Enter confirm | Esc back"
189905
+ }, undefined, false, undefined, this)
189906
+ }, undefined, false, undefined, this)
189907
+ ]
189908
+ }, undefined, true, undefined, this),
189909
+ createStep === "time" && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189910
+ flexDirection: "column",
189911
+ children: [
189912
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189913
+ bold: true,
189914
+ children: "Enter date/time (ISO 8601):"
189915
+ }, undefined, false, undefined, this),
189916
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189917
+ marginTop: 1,
189918
+ children: [
189919
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189920
+ children: "Time: "
189921
+ }, undefined, false, undefined, this),
189922
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(build_default2, {
189923
+ value: createTime,
189924
+ onChange: setCreateTime,
189925
+ onSubmit: () => {
189926
+ if (createTime.trim())
189927
+ setCreateStep("command");
189928
+ },
189929
+ placeholder: "e.g. 2026-02-08T09:00:00"
189930
+ }, undefined, false, undefined, this)
189931
+ ]
189932
+ }, undefined, true, undefined, this),
189933
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189934
+ marginTop: 1,
189935
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189936
+ dimColor: true,
189937
+ children: "Enter confirm | Esc back"
189938
+ }, undefined, false, undefined, this)
189939
+ }, undefined, false, undefined, this)
189940
+ ]
189941
+ }, undefined, true, undefined, this),
189942
+ createStep === "interval" && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189943
+ flexDirection: "column",
189944
+ children: [
189945
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189946
+ bold: true,
189947
+ children: "Configure interval:"
189948
+ }, undefined, false, undefined, this),
189949
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189950
+ marginTop: 1,
189951
+ children: [
189952
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189953
+ children: "Every "
189954
+ }, undefined, false, undefined, this),
189955
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189956
+ color: "cyan",
189957
+ bold: true,
189958
+ children: createInterval
189959
+ }, undefined, false, undefined, this),
189960
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189961
+ children: " "
189962
+ }, undefined, false, undefined, this),
189963
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189964
+ color: "cyan",
189965
+ bold: true,
189966
+ children: INTERVAL_UNITS[createIntervalUnitIndex]
189967
+ }, undefined, false, undefined, this)
189968
+ ]
189969
+ }, undefined, true, undefined, this),
189970
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189971
+ marginTop: 1,
189972
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189973
+ dimColor: true,
189974
+ children: "\u2191\u2193 change value | \u2190\u2192 change unit | Enter confirm | Esc back"
189975
+ }, undefined, false, undefined, this)
189976
+ }, undefined, false, undefined, this)
189977
+ ]
189978
+ }, undefined, true, undefined, this),
189979
+ createStep === "command" && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189980
+ flexDirection: "column",
189981
+ children: [
189982
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189983
+ bold: true,
189984
+ children: "Enter command to execute:"
189985
+ }, undefined, false, undefined, this),
189986
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189987
+ marginTop: 1,
189988
+ children: [
189989
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189990
+ children: "$ "
189991
+ }, undefined, false, undefined, this),
189992
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(build_default2, {
189993
+ value: createCommand,
189994
+ onChange: setCreateCommand,
189995
+ onSubmit: () => {
189996
+ if (createCommand.trim())
189997
+ setCreateStep("description");
189998
+ },
189999
+ placeholder: "e.g. /summarize or any slash command"
190000
+ }, undefined, false, undefined, this)
190001
+ ]
190002
+ }, undefined, true, undefined, this),
190003
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
190004
+ marginTop: 1,
190005
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190006
+ dimColor: true,
190007
+ children: "Enter next | Esc back"
190008
+ }, undefined, false, undefined, this)
190009
+ }, undefined, false, undefined, this)
190010
+ ]
190011
+ }, undefined, true, undefined, this),
190012
+ createStep === "description" && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
190013
+ flexDirection: "column",
190014
+ children: [
190015
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190016
+ bold: true,
190017
+ children: "Description (optional):"
190018
+ }, undefined, false, undefined, this),
190019
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
190020
+ marginTop: 1,
190021
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(build_default2, {
190022
+ value: createDescription,
190023
+ onChange: setCreateDescription,
190024
+ onSubmit: () => setCreateStep("confirm"),
190025
+ placeholder: "What does this schedule do?"
190026
+ }, undefined, false, undefined, this)
190027
+ }, undefined, false, undefined, this),
190028
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
190029
+ marginTop: 1,
190030
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190031
+ dimColor: true,
190032
+ children: "Enter next | Esc back"
190033
+ }, undefined, false, undefined, this)
190034
+ }, undefined, false, undefined, this)
190035
+ ]
190036
+ }, undefined, true, undefined, this),
190037
+ createStep === "confirm" && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
190038
+ flexDirection: "column",
190039
+ children: [
190040
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190041
+ bold: true,
190042
+ children: "Confirm new schedule:"
190043
+ }, undefined, false, undefined, this),
190044
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
190045
+ flexDirection: "column",
190046
+ marginTop: 1,
190047
+ marginLeft: 1,
190048
+ children: [
190049
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190050
+ children: [
190051
+ "Type: ",
190052
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190053
+ color: "cyan",
190054
+ children: KIND_OPTIONS[createKindIndex].label
190055
+ }, undefined, false, undefined, this)
190056
+ ]
190057
+ }, undefined, true, undefined, this),
190058
+ KIND_OPTIONS[createKindIndex].id === "cron" && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190059
+ children: [
190060
+ "Cron: ",
190061
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190062
+ color: "cyan",
190063
+ children: createCron
190064
+ }, undefined, false, undefined, this)
190065
+ ]
190066
+ }, undefined, true, undefined, this),
190067
+ KIND_OPTIONS[createKindIndex].id === "once" && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190068
+ children: [
190069
+ "Time: ",
190070
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190071
+ color: "cyan",
190072
+ children: createTime
190073
+ }, undefined, false, undefined, this)
190074
+ ]
190075
+ }, undefined, true, undefined, this),
190076
+ KIND_OPTIONS[createKindIndex].id === "interval" && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190077
+ children: [
190078
+ "Interval: ",
190079
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190080
+ color: "cyan",
190081
+ children: [
190082
+ "Every ",
190083
+ createInterval,
190084
+ " ",
190085
+ INTERVAL_UNITS[createIntervalUnitIndex]
190086
+ ]
190087
+ }, undefined, true, undefined, this)
190088
+ ]
190089
+ }, undefined, true, undefined, this),
190090
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190091
+ children: [
190092
+ "Command: ",
190093
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190094
+ color: "cyan",
190095
+ children: createCommand
190096
+ }, undefined, false, undefined, this)
190097
+ ]
190098
+ }, undefined, true, undefined, this),
190099
+ createDescription && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190100
+ children: [
190101
+ "Description: ",
190102
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190103
+ dimColor: true,
190104
+ children: createDescription
190105
+ }, undefined, false, undefined, this)
190106
+ ]
190107
+ }, undefined, true, undefined, this)
190108
+ ]
190109
+ }, undefined, true, undefined, this),
190110
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
190111
+ marginTop: 1,
190112
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190113
+ dimColor: true,
190114
+ children: "Enter/y create | n cancel | Esc back"
190115
+ }, undefined, false, undefined, this)
190116
+ }, undefined, false, undefined, this)
190117
+ ]
190118
+ }, undefined, true, undefined, this),
190119
+ createError && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
190120
+ marginTop: 1,
190121
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190122
+ color: "red",
190123
+ children: createError
190124
+ }, undefined, false, undefined, this)
190125
+ }, undefined, false, undefined, this)
190126
+ ]
190127
+ }, undefined, true, undefined, this),
190128
+ isSubmitting && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
190129
+ marginTop: 1,
190130
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190131
+ color: "yellow",
190132
+ children: "Creating schedule..."
190133
+ }, undefined, false, undefined, this)
190134
+ }, undefined, false, undefined, this)
190135
+ ]
190136
+ }, undefined, true, undefined, this);
190137
+ }
189608
190138
  if (mode === "delete-confirm") {
189609
190139
  const action = selectedSchedule ? getActionDisplay(selectedSchedule) : { type: "command", content: "" };
189610
190140
  const displayContent = action.content.slice(0, 50) + (action.content.length > 50 ? "..." : "");
@@ -189728,21 +190258,6 @@ function SchedulesPanel({
189728
190258
  }, undefined, false, undefined, this)
189729
190259
  ]
189730
190260
  }, undefined, true, undefined, this),
189731
- /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189732
- children: [
189733
- /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189734
- bold: true,
189735
- children: "Action Type: "
189736
- }, undefined, false, undefined, this),
189737
- /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189738
- children: [
189739
- ACTION_ICONS[s6.actionType || "command"],
189740
- " ",
189741
- s6.actionType || "command"
189742
- ]
189743
- }, undefined, true, undefined, this)
189744
- ]
189745
- }, undefined, true, undefined, this),
189746
190261
  s6.description && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189747
190262
  children: [
189748
190263
  /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
@@ -189754,39 +190269,35 @@ function SchedulesPanel({
189754
190269
  }, undefined, false, undefined, this)
189755
190270
  ]
189756
190271
  }, undefined, true, undefined, this),
189757
- (s6.actionType || "command") === "command" ? /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(jsx_dev_runtime24.Fragment, {
190272
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
190273
+ marginTop: 1,
190274
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190275
+ bold: true,
190276
+ children: "Command: "
190277
+ }, undefined, false, undefined, this)
190278
+ }, undefined, false, undefined, this),
190279
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
190280
+ marginLeft: 2,
190281
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190282
+ wrap: "wrap",
190283
+ color: "cyan",
190284
+ children: s6.command
190285
+ }, undefined, false, undefined, this)
190286
+ }, undefined, false, undefined, this),
190287
+ s6.message && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(jsx_dev_runtime24.Fragment, {
189758
190288
  children: [
189759
190289
  /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189760
190290
  marginTop: 1,
189761
190291
  children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189762
190292
  bold: true,
189763
- children: "Command: "
190293
+ children: "Message: "
189764
190294
  }, undefined, false, undefined, this)
189765
190295
  }, undefined, false, undefined, this),
189766
190296
  /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189767
190297
  marginLeft: 2,
189768
190298
  children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189769
190299
  wrap: "wrap",
189770
- color: "cyan",
189771
- children: s6.command
189772
- }, undefined, false, undefined, this)
189773
- }, undefined, false, undefined, this)
189774
- ]
189775
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(jsx_dev_runtime24.Fragment, {
189776
- children: [
189777
- /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189778
- marginTop: 1,
189779
- children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189780
- bold: true,
189781
- children: "Prompt:"
189782
- }, undefined, false, undefined, this)
189783
- }, undefined, false, undefined, this),
189784
- /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189785
- marginLeft: 1,
189786
- flexDirection: "column",
189787
- marginTop: 0,
189788
- children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(MarkdownContent, {
189789
- content: s6.message || ""
190300
+ children: s6.message
189790
190301
  }, undefined, false, undefined, this)
189791
190302
  }, undefined, false, undefined, this)
189792
190303
  ]
@@ -189856,7 +190367,7 @@ function SchedulesPanel({
189856
190367
  children: [
189857
190368
  s6.status === "active" ? "[p]ause" : s6.status === "paused" ? "[r]esume" : "",
189858
190369
  " ",
189859
- "[r]un now | [d]elete | Esc back"
190370
+ "[r]un now | [d]elete | Esc/q back"
189860
190371
  ]
189861
190372
  }, undefined, true, undefined, this)
189862
190373
  }, undefined, false, undefined, this),
@@ -189882,15 +190393,13 @@ function SchedulesPanel({
189882
190393
  marginBottom: 1,
189883
190394
  justifyContent: "space-between",
189884
190395
  children: [
189885
- /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189886
- children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189887
- bold: true,
189888
- children: "Schedules"
189889
- }, undefined, false, undefined, this)
190396
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190397
+ bold: true,
190398
+ children: "Schedules"
189890
190399
  }, undefined, false, undefined, this),
189891
190400
  /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189892
190401
  dimColor: true,
189893
- children: "[p]ause [r]esume [d]elete [f]refresh"
190402
+ children: "[n]ew [p]ause [r]esume [d]elete [f]refresh"
189894
190403
  }, undefined, false, undefined, this)
189895
190404
  ]
189896
190405
  }, undefined, true, undefined, this),
@@ -189915,82 +190424,75 @@ function SchedulesPanel({
189915
190424
  borderStyle: "round",
189916
190425
  borderColor: "gray",
189917
190426
  paddingX: 1,
189918
- children: sortedSchedules.length === 0 ? /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189919
- paddingY: 1,
189920
- children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189921
- dimColor: true,
189922
- children: "No schedules. Use /schedule to create one."
189923
- }, undefined, false, undefined, this)
189924
- }, undefined, false, undefined, this) : sortedSchedules.map((schedule, index) => {
189925
- const isSelected = index === selectedIndex;
189926
- const statusIcon = STATUS_ICONS2[schedule.status];
189927
- const statusColor = STATUS_COLORS2[schedule.status];
189928
- const nextRun = formatRelativeTime3(schedule.nextRunAt);
189929
- const action = getActionDisplay(schedule);
189930
- const actionIcon = ACTION_ICONS[action.type];
189931
- const content = action.content.slice(0, 30) + (action.content.length > 30 ? "..." : "");
189932
- const kindLabel = KIND_LABELS[schedule.schedule.kind] || schedule.schedule.kind;
189933
- return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189934
- paddingY: 0,
189935
- children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189936
- inverse: isSelected,
189937
- dimColor: !isSelected && schedule.status === "completed",
189938
- children: [
189939
- /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189940
- color: statusColor,
189941
- children: statusIcon
189942
- }, undefined, false, undefined, this),
189943
- " ",
189944
- actionIcon,
189945
- " ",
189946
- index + 1,
189947
- ". ",
189948
- content.padEnd(32),
189949
- " ",
189950
- kindLabel.padEnd(10),
189951
- " ",
189952
- nextRun
189953
- ]
189954
- }, undefined, true, undefined, this)
189955
- }, schedule.id, false, undefined, this);
189956
- })
189957
- }, undefined, false, undefined, this),
189958
- sortedSchedules.length > 0 && selectedSchedule && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189959
- marginTop: 1,
189960
- flexDirection: "column",
189961
190427
  children: [
189962
- (() => {
189963
- const action = getActionDisplay(selectedSchedule);
189964
- return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190428
+ sortedSchedules.length === 0 ? /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
190429
+ paddingY: 1,
190430
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189965
190431
  dimColor: true,
189966
- children: [
189967
- /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189968
- bold: true,
189969
- children: action.type === "message" ? "Message:" : "Command:"
189970
- }, undefined, false, undefined, this),
189971
- " ",
189972
- action.content
189973
- ]
189974
- }, undefined, true, undefined, this);
189975
- })(),
189976
- /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189977
- dimColor: true,
189978
- children: [
189979
- /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189980
- bold: true,
189981
- children: "Schedule:"
189982
- }, undefined, false, undefined, this),
189983
- " ",
189984
- getScheduleDescription(selectedSchedule)
189985
- ]
189986
- }, undefined, true, undefined, this)
190432
+ children: "No schedules. Press n to create one."
190433
+ }, undefined, false, undefined, this)
190434
+ }, undefined, false, undefined, this) : sortedSchedules.map((schedule, index) => {
190435
+ const isSelected = index === selectedIndex;
190436
+ const statusIcon = STATUS_ICONS2[schedule.status];
190437
+ const statusColor = STATUS_COLORS2[schedule.status];
190438
+ const nextRun = formatRelativeTime3(schedule.nextRunAt);
190439
+ const action = getActionDisplay(schedule);
190440
+ const actionIcon = ACTION_ICONS[action.type];
190441
+ const content = action.content.slice(0, 30) + (action.content.length > 30 ? "..." : "");
190442
+ const kindLabel = KIND_LABELS[schedule.schedule.kind] || schedule.schedule.kind;
190443
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
190444
+ paddingY: 0,
190445
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190446
+ inverse: isSelected,
190447
+ dimColor: !isSelected && schedule.status === "completed",
190448
+ children: [
190449
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190450
+ color: statusColor,
190451
+ children: statusIcon
190452
+ }, undefined, false, undefined, this),
190453
+ " ",
190454
+ actionIcon,
190455
+ " ",
190456
+ index + 1,
190457
+ ". ",
190458
+ content.padEnd(32),
190459
+ " ",
190460
+ kindLabel.padEnd(10),
190461
+ " ",
190462
+ nextRun
190463
+ ]
190464
+ }, undefined, true, undefined, this)
190465
+ }, schedule.id, false, undefined, this);
190466
+ }),
190467
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
190468
+ marginTop: 1,
190469
+ paddingY: 0,
190470
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190471
+ inverse: selectedIndex === sortedSchedules.length,
190472
+ dimColor: selectedIndex !== sortedSchedules.length,
190473
+ color: selectedIndex === sortedSchedules.length ? "cyan" : undefined,
190474
+ children: "+ New schedule (n)"
190475
+ }, undefined, false, undefined, this)
190476
+ }, undefined, false, undefined, this)
189987
190477
  ]
189988
190478
  }, undefined, true, undefined, this),
190479
+ sortedSchedules.length > 0 && selectedSchedule && selectedIndex < sortedSchedules.length && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
190480
+ marginTop: 1,
190481
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
190482
+ dimColor: true,
190483
+ children: [
190484
+ getScheduleDescription(selectedSchedule),
190485
+ " | ",
190486
+ selectedSchedule.status,
190487
+ " | Enter for details"
190488
+ ]
190489
+ }, undefined, true, undefined, this)
190490
+ }, undefined, false, undefined, this),
189989
190491
  /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
189990
190492
  marginTop: 1,
189991
190493
  children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
189992
190494
  dimColor: true,
189993
- children: "Enter view | \u2191/\u2193 navigate | Esc close"
190495
+ children: "Enter view | \u2191\u2193 navigate | q quit"
189994
190496
  }, undefined, false, undefined, this)
189995
190497
  }, undefined, false, undefined, this),
189996
190498
  isSubmitting && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
@@ -190087,7 +190589,7 @@ function ProjectsPanel({
190087
190589
  }
190088
190590
  return;
190089
190591
  }
190090
- if (key.escape) {
190592
+ if (key.escape || input === "q" || input === "Q") {
190091
190593
  onCancel();
190092
190594
  return;
190093
190595
  }
@@ -190497,7 +190999,7 @@ function PlansPanel({
190497
190999
  }
190498
191000
  return;
190499
191001
  }
190500
- if (key.escape) {
191002
+ if (key.escape || input === "q" || input === "Q") {
190501
191003
  onBack();
190502
191004
  return;
190503
191005
  }
@@ -192488,7 +192990,7 @@ function InboxPanel({
192488
192990
  }, undefined, true, undefined, this);
192489
192991
  }
192490
192992
 
192491
- // packages/terminal/src/components/AgentDashboard.tsx
192993
+ // packages/terminal/src/components/AssistantsDashboard.tsx
192492
192994
  var import_react52 = __toESM(require_react(), 1);
192493
192995
  var jsx_dev_runtime30 = __toESM(require_jsx_dev_runtime(), 1);
192494
192996
  function formatElapsed(startedAt) {
@@ -192516,7 +193018,7 @@ function StateIndicator({ isProcessing, isPaused: isPaused2 }) {
192516
193018
  children: "idle"
192517
193019
  }, undefined, false, undefined, this);
192518
193020
  }
192519
- function AgentDashboard({
193021
+ function AssistantsDashboard({
192520
193022
  sessions,
192521
193023
  projectBudget,
192522
193024
  projectName,
@@ -192529,6 +193031,12 @@ function AgentDashboard({
192529
193031
  }) {
192530
193032
  const [selectedIndex, setSelectedIndex] = import_react52.useState(0);
192531
193033
  use_input_default((input, key) => {
193034
+ if (sessions.length === 0) {
193035
+ if (key.escape || input === "q" || input === "Q") {
193036
+ onCancel();
193037
+ }
193038
+ return;
193039
+ }
192532
193040
  if (key.upArrow) {
192533
193041
  setSelectedIndex((prev) => Math.max(0, prev - 1));
192534
193042
  return;
@@ -192579,7 +193087,7 @@ function AgentDashboard({
192579
193087
  marginBottom: 1,
192580
193088
  children: /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text3, {
192581
193089
  bold: true,
192582
- children: "Agent Dashboard"
193090
+ children: "Assistants Dashboard"
192583
193091
  }, undefined, false, undefined, this)
192584
193092
  }, undefined, false, undefined, this),
192585
193093
  /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
@@ -192598,7 +193106,13 @@ function AgentDashboard({
192598
193106
  "):"
192599
193107
  ]
192600
193108
  }, undefined, true, undefined, this),
192601
- /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
193109
+ sessions.length === 0 ? /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
193110
+ marginTop: 1,
193111
+ children: /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text3, {
193112
+ dimColor: true,
193113
+ children: "No active sessions."
193114
+ }, undefined, false, undefined, this)
193115
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
192602
193116
  flexDirection: "column",
192603
193117
  marginTop: 1,
192604
193118
  children: sessions.map((session, i5) => {
@@ -193041,6 +193555,67 @@ function SwarmPanel({
193041
193555
  // packages/terminal/src/components/App.tsx
193042
193556
  var jsx_dev_runtime32 = __toESM(require_jsx_dev_runtime(), 1);
193043
193557
  var SHOW_ERROR_CODES = process.env.ASSISTANTS_DEBUG === "1";
193558
+ var MAX_SHELL_OUTPUT_BYTES = 64 * 1024;
193559
+ async function runShellCommand(command, cwd2) {
193560
+ return new Promise((resolve5, reject) => {
193561
+ const child = spawn3(command, { cwd: cwd2, shell: true, env: process.env });
193562
+ const stdoutChunks = [];
193563
+ const stderrChunks = [];
193564
+ let totalBytes = 0;
193565
+ let truncated = false;
193566
+ const collect = (chunk, target) => {
193567
+ if (totalBytes >= MAX_SHELL_OUTPUT_BYTES) {
193568
+ truncated = true;
193569
+ return;
193570
+ }
193571
+ const remaining = MAX_SHELL_OUTPUT_BYTES - totalBytes;
193572
+ if (chunk.length > remaining) {
193573
+ target.push(chunk.slice(0, remaining));
193574
+ totalBytes = MAX_SHELL_OUTPUT_BYTES;
193575
+ truncated = true;
193576
+ return;
193577
+ }
193578
+ target.push(chunk);
193579
+ totalBytes += chunk.length;
193580
+ };
193581
+ if (child.stdout) {
193582
+ child.stdout.on("data", (chunk) => collect(chunk, stdoutChunks));
193583
+ }
193584
+ if (child.stderr) {
193585
+ child.stderr.on("data", (chunk) => collect(chunk, stderrChunks));
193586
+ }
193587
+ child.on("error", (error2) => reject(error2));
193588
+ child.on("close", (code) => {
193589
+ resolve5({
193590
+ stdout: Buffer.concat(stdoutChunks).toString("utf8").trimEnd(),
193591
+ stderr: Buffer.concat(stderrChunks).toString("utf8").trimEnd(),
193592
+ exitCode: code,
193593
+ truncated
193594
+ });
193595
+ });
193596
+ });
193597
+ }
193598
+ function formatShellResult(command, result) {
193599
+ const sections = [
193600
+ "Local shell command executed:",
193601
+ "```bash\n$ " + command + "\n```",
193602
+ `Exit code: ${result.exitCode ?? "unknown"}`
193603
+ ];
193604
+ if (result.stdout) {
193605
+ sections.push("STDOUT:\n```\n" + result.stdout + "\n```");
193606
+ } else {
193607
+ sections.push("STDOUT: (empty)");
193608
+ }
193609
+ if (result.stderr) {
193610
+ sections.push("STDERR:\n```\n" + result.stderr + "\n```");
193611
+ }
193612
+ if (result.truncated) {
193613
+ sections.push("_Output truncated after 64KB._");
193614
+ }
193615
+ return sections.join(`
193616
+
193617
+ `);
193618
+ }
193044
193619
  function formatElapsedDuration(ms2) {
193045
193620
  const totalSeconds = Math.max(0, Math.floor(ms2 / 1000));
193046
193621
  if (totalSeconds === 0)
@@ -193129,7 +193704,7 @@ function App2({ cwd: cwd2, version: version3 }) {
193129
193704
  const [showInboxPanel, setShowInboxPanel] = import_react53.useState(false);
193130
193705
  const [inboxEmails, setInboxEmails] = import_react53.useState([]);
193131
193706
  const [inboxError, setInboxError] = import_react53.useState(null);
193132
- const [showAgentDashboard, setShowAgentDashboard] = import_react53.useState(false);
193707
+ const [showAssistantsDashboard, setShowAssistantsDashboard] = import_react53.useState(false);
193133
193708
  const [showSwarmPanel, setShowSwarmPanel] = import_react53.useState(false);
193134
193709
  const sessionUIStates = import_react53.useRef(new Map);
193135
193710
  const [messages2, setMessages] = import_react53.useState([]);
@@ -193150,6 +193725,7 @@ function App2({ cwd: cwd2, version: version3 }) {
193150
193725
  const [processingStartTime, setProcessingStartTime] = import_react53.useState();
193151
193726
  const [currentTurnTokens, setCurrentTurnTokens] = import_react53.useState(0);
193152
193727
  const [lastWorkedFor, setLastWorkedFor] = import_react53.useState();
193728
+ const [isListening, setIsListening] = import_react53.useState(false);
193153
193729
  const [skills, setSkills] = import_react53.useState([]);
193154
193730
  const [commands3, setCommands] = import_react53.useState([]);
193155
193731
  const lastCtrlCRef = import_react53.useRef(0);
@@ -193160,6 +193736,15 @@ function App2({ cwd: cwd2, version: version3 }) {
193160
193736
  const activityLogRef = import_react53.useRef([]);
193161
193737
  const skipNextDoneRef = import_react53.useRef(false);
193162
193738
  const isProcessingRef = import_react53.useRef(isProcessing);
193739
+ const inputRef = import_react53.useRef(null);
193740
+ const isListeningRef = import_react53.useRef(isListening);
193741
+ const listenLoopRef = import_react53.useRef({
193742
+ active: false,
193743
+ buffer: "",
193744
+ silenceMs: 0,
193745
+ manager: null
193746
+ });
193747
+ const sendListenMessageRef = import_react53.useRef(() => {});
193163
193748
  const processingStartTimeRef = import_react53.useRef(processingStartTime);
193164
193749
  const pendingSendsRef = import_react53.useRef([]);
193165
193750
  const askUserStateRef = import_react53.useRef(new Map);
@@ -193229,6 +193814,9 @@ function App2({ cwd: cwd2, version: version3 }) {
193229
193814
  import_react53.useEffect(() => {
193230
193815
  isProcessingRef.current = isProcessing;
193231
193816
  }, [isProcessing]);
193817
+ import_react53.useEffect(() => {
193818
+ isListeningRef.current = isListening;
193819
+ }, [isListening]);
193232
193820
  import_react53.useEffect(() => {
193233
193821
  processingStartTimeRef.current = processingStartTime;
193234
193822
  }, [processingStartTime]);
@@ -193334,6 +193922,105 @@ function App2({ cwd: cwd2, version: version3 }) {
193334
193922
  processingStartTimeRef.current = undefined;
193335
193923
  setCurrentTurnTokens(0);
193336
193924
  }, []);
193925
+ const appendTranscript = import_react53.useCallback((base2, chunk) => {
193926
+ const trimmed = chunk.trim();
193927
+ if (!trimmed)
193928
+ return base2;
193929
+ if (!base2)
193930
+ return trimmed;
193931
+ const lastChar = base2[base2.length - 1] || "";
193932
+ const needsSpace = lastChar !== " " && !/[.,!?;:]/.test(trimmed[0] || "");
193933
+ return `${base2}${needsSpace ? " " : ""}${trimmed}`;
193934
+ }, []);
193935
+ const updateListenDraft = import_react53.useCallback((next) => {
193936
+ inputRef.current?.setValue(next);
193937
+ }, []);
193938
+ const stopListening = import_react53.useCallback(() => {
193939
+ if (!listenLoopRef.current.active)
193940
+ return;
193941
+ listenLoopRef.current.active = false;
193942
+ listenLoopRef.current.silenceMs = 0;
193943
+ listenLoopRef.current.buffer = "";
193944
+ listenLoopRef.current.manager?.stopListening();
193945
+ listenLoopRef.current.manager = null;
193946
+ setIsListening(false);
193947
+ isListeningRef.current = false;
193948
+ }, []);
193949
+ const startListening = import_react53.useCallback(async () => {
193950
+ if (listenLoopRef.current.active)
193951
+ return;
193952
+ listenLoopRef.current.active = true;
193953
+ setIsListening(true);
193954
+ isListeningRef.current = true;
193955
+ let config;
193956
+ try {
193957
+ config = currentConfig ?? await loadConfig(cwd2);
193958
+ } catch (err) {
193959
+ setError(err instanceof Error ? err.message : "Failed to load config for voice");
193960
+ stopListening();
193961
+ return;
193962
+ }
193963
+ if (!listenLoopRef.current.active)
193964
+ return;
193965
+ const voiceConfig = config.voice;
193966
+ if (!voiceConfig) {
193967
+ setError("Voice configuration is missing. Add voice settings to config.json.");
193968
+ stopListening();
193969
+ return;
193970
+ }
193971
+ if (voiceConfig.stt.provider === "system") {
193972
+ setError('System speech-to-text is not available yet. Set voice.stt.provider to "whisper".');
193973
+ stopListening();
193974
+ return;
193975
+ }
193976
+ const manager = new VoiceManager({
193977
+ ...voiceConfig,
193978
+ enabled: true,
193979
+ stt: { ...voiceConfig.stt },
193980
+ tts: { ...voiceConfig.tts }
193981
+ });
193982
+ manager.enable();
193983
+ listenLoopRef.current.manager = manager;
193984
+ listenLoopRef.current.buffer = inputRef.current?.getValue() ?? "";
193985
+ listenLoopRef.current.silenceMs = 0;
193986
+ const chunkSeconds = 1;
193987
+ const silenceThresholdMs = 3500;
193988
+ while (listenLoopRef.current.active) {
193989
+ let transcript = "";
193990
+ try {
193991
+ transcript = await manager.listen({ durationSeconds: chunkSeconds });
193992
+ } catch (err) {
193993
+ if (!listenLoopRef.current.active)
193994
+ break;
193995
+ setError(err instanceof Error ? err.message : String(err));
193996
+ stopListening();
193997
+ break;
193998
+ }
193999
+ if (!listenLoopRef.current.active)
194000
+ break;
194001
+ const trimmed = transcript.trim();
194002
+ if (trimmed) {
194003
+ listenLoopRef.current.silenceMs = 0;
194004
+ const next = appendTranscript(listenLoopRef.current.buffer, trimmed);
194005
+ listenLoopRef.current.buffer = next;
194006
+ updateListenDraft(next);
194007
+ continue;
194008
+ }
194009
+ listenLoopRef.current.silenceMs += chunkSeconds * 1000;
194010
+ if (listenLoopRef.current.silenceMs >= silenceThresholdMs) {
194011
+ const payload = listenLoopRef.current.buffer.trim();
194012
+ listenLoopRef.current.buffer = "";
194013
+ listenLoopRef.current.silenceMs = 0;
194014
+ updateListenDraft("");
194015
+ if (payload) {
194016
+ sendListenMessageRef.current(payload);
194017
+ }
194018
+ }
194019
+ }
194020
+ }, [appendTranscript, cwd2, currentConfig, stopListening, updateListenDraft]);
194021
+ import_react53.useEffect(() => () => {
194022
+ stopListening();
194023
+ }, [stopListening]);
193337
194024
  const saveCurrentSessionState = import_react53.useCallback(() => {
193338
194025
  if (activeSessionId) {
193339
194026
  sessionUIStates.current.set(activeSessionId, {
@@ -193562,7 +194249,43 @@ function App2({ cwd: cwd2, version: version3 }) {
193562
194249
  setShowSchedulesPanel(true);
193563
194250
  });
193564
194251
  } else if (chunk.panel === "assistants") {
193565
- setShowAssistantsPanel(true);
194252
+ if (chunk.panelValue?.startsWith("session:")) {
194253
+ try {
194254
+ const payload = JSON.parse(chunk.panelValue.slice("session:".length));
194255
+ if (payload.action === "list") {
194256
+ setShowSessionSelector(true);
194257
+ } else if (payload.action === "new") {
194258
+ registry3.createSession({
194259
+ cwd: cwd2,
194260
+ label: payload.label,
194261
+ assistantId: payload.agent
194262
+ }).then((newSession) => {
194263
+ registry3.switchSession(newSession.id).then(() => {
194264
+ setActiveSessionId(newSession.id);
194265
+ });
194266
+ });
194267
+ } else if (payload.action === "assign" && payload.agent) {
194268
+ const active = registry3.getActiveSession();
194269
+ if (active) {
194270
+ registry3.assignAssistant(active.id, payload.agent);
194271
+ }
194272
+ } else if (payload.action === "switch" && payload.number) {
194273
+ const allSessions = registry3.listSessions();
194274
+ const target = allSessions[payload.number - 1];
194275
+ if (target) {
194276
+ registry3.switchSession(target.id).then(() => {
194277
+ setActiveSessionId(target.id);
194278
+ });
194279
+ }
194280
+ }
194281
+ } catch {
194282
+ setShowAssistantsDashboard(true);
194283
+ }
194284
+ } else if (chunk.panelValue === "dashboard") {
194285
+ setShowAssistantsDashboard(true);
194286
+ } else {
194287
+ setShowAssistantsPanel(true);
194288
+ }
193566
194289
  } else if (chunk.panel === "identity") {
193567
194290
  setShowIdentityPanel(true);
193568
194291
  } else if (chunk.panel === "hooks") {
@@ -193690,42 +194413,6 @@ function App2({ cwd: cwd2, version: version3 }) {
193690
194413
  setInboxError("Inbox not enabled. Configure inbox in config.json.");
193691
194414
  setShowInboxPanel(true);
193692
194415
  }
193693
- } else if (chunk.panel === "agents") {
193694
- if (chunk.panelValue?.startsWith("session:")) {
193695
- try {
193696
- const payload = JSON.parse(chunk.panelValue.slice("session:".length));
193697
- if (payload.action === "list") {
193698
- setShowSessionSelector(true);
193699
- } else if (payload.action === "new") {
193700
- registry3.createSession({
193701
- cwd: cwd2,
193702
- label: payload.label,
193703
- assistantId: payload.agent
193704
- }).then((newSession) => {
193705
- registry3.switchSession(newSession.id).then(() => {
193706
- setActiveSessionId(newSession.id);
193707
- });
193708
- });
193709
- } else if (payload.action === "assign" && payload.agent) {
193710
- const active = registry3.getActiveSession();
193711
- if (active) {
193712
- registry3.assignAssistant(active.id, payload.agent);
193713
- }
193714
- } else if (payload.action === "switch" && payload.number) {
193715
- const allSessions = registry3.listSessions();
193716
- const target = allSessions[payload.number - 1];
193717
- if (target) {
193718
- registry3.switchSession(target.id).then(() => {
193719
- setActiveSessionId(target.id);
193720
- });
193721
- }
193722
- }
193723
- } catch {
193724
- setShowAgentDashboard(true);
193725
- }
193726
- } else {
193727
- setShowAgentDashboard(true);
193728
- }
193729
194416
  } else if (chunk.panel === "swarm") {
193730
194417
  setShowSwarmPanel(true);
193731
194418
  } else if (chunk.panel === "workspace") {}
@@ -193966,6 +194653,11 @@ function App2({ cwd: cwd2, version: version3 }) {
193966
194653
  return false;
193967
194654
  }, [activityLog]);
193968
194655
  const isBusy = isProcessing || hasPendingTools;
194656
+ const listenHints = import_react53.useMemo(() => {
194657
+ if (!isListening)
194658
+ return [];
194659
+ return ["listening...", "pause 3s to send", "[ctrl+l] stop"];
194660
+ }, [isListening]);
193969
194661
  const showWelcome = messages2.length === 0 && !isProcessing;
193970
194662
  const renderWidth = columns ? Math.max(1, columns - 2) : undefined;
193971
194663
  const wrapChars = renderWidth ?? MESSAGE_WRAP_CHARS;
@@ -194054,6 +194746,10 @@ function App2({ cwd: cwd2, version: version3 }) {
194054
194746
  }
194055
194747
  }, [cwd2, registry3, saveCurrentSessionState, loadSessionState, beginAskUser]);
194056
194748
  use_input_default((input, key) => {
194749
+ if (isListeningRef.current && key.ctrl && input === "l") {
194750
+ stopListening();
194751
+ return;
194752
+ }
194057
194753
  if (key.ctrl && input === "]") {
194058
194754
  if (sessions.length > 0) {
194059
194755
  setShowSessionSelector(true);
@@ -194118,7 +194814,7 @@ function App2({ cwd: cwd2, version: version3 }) {
194118
194814
  }
194119
194815
  }
194120
194816
  if (key.ctrl && input === "a") {
194121
- setShowAgentDashboard(true);
194817
+ setShowAssistantsDashboard(true);
194122
194818
  return;
194123
194819
  }
194124
194820
  if (key.ctrl && input === "b") {
@@ -194174,12 +194870,35 @@ function App2({ cwd: cwd2, version: version3 }) {
194174
194870
  const skillInput = "/" + trimmedInput.slice(1);
194175
194871
  return handleSubmit(skillInput, mode);
194176
194872
  }
194177
- if (trimmedInput.startsWith("![") && trimmedInput.endsWith("]")) {
194178
- const bashCommand = trimmedInput.slice(2, -1).trim();
194179
- if (bashCommand) {
194180
- const bashInstruction = `Run this bash command: \`${bashCommand}\``;
194181
- return handleSubmit(bashInstruction, mode);
194873
+ if (trimmedInput.startsWith("!")) {
194874
+ const raw = trimmedInput.slice(1).trim();
194875
+ const shellCommand = raw.startsWith("[") && raw.endsWith("]") ? raw.slice(1, -1).trim() : raw;
194876
+ if (!shellCommand) {
194877
+ setError("Usage: !<command>");
194878
+ return;
194879
+ }
194880
+ try {
194881
+ const shellCwd = activeSession?.cwd || cwd2;
194882
+ const result = await runShellCommand(shellCommand, shellCwd);
194883
+ const payload = formatShellResult(shellCommand, result);
194884
+ return handleSubmit(payload, mode);
194885
+ } catch (err) {
194886
+ setError(err instanceof Error ? err.message : String(err));
194887
+ return;
194888
+ }
194889
+ }
194890
+ if (trimmedInput.startsWith("/listen")) {
194891
+ const arg = trimmedInput.slice(7).trim().toLowerCase();
194892
+ if (arg === "stop" || arg === "off") {
194893
+ stopListening();
194894
+ return;
194895
+ }
194896
+ if (listenLoopRef.current.active) {
194897
+ stopListening();
194898
+ return;
194182
194899
  }
194900
+ startListening();
194901
+ return;
194183
194902
  }
194184
194903
  if (trimmedInput.startsWith("/session")) {
194185
194904
  const arg = trimmedInput.slice(8).trim();
@@ -194382,8 +195101,16 @@ function App2({ cwd: cwd2, version: version3 }) {
194382
195101
  resetTurnState,
194383
195102
  activeSessionId,
194384
195103
  submitAskAnswer,
194385
- clearPendingSend
195104
+ clearPendingSend,
195105
+ startListening,
195106
+ stopListening
194386
195107
  ]);
195108
+ import_react53.useEffect(() => {
195109
+ sendListenMessageRef.current = (text) => {
195110
+ const mode = isProcessingRef.current ? "inline" : "normal";
195111
+ handleSubmit(text, mode);
195112
+ };
195113
+ }, [handleSubmit]);
194387
195114
  if (isInitializing && !showRecoveryPanel) {
194388
195115
  return /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Box_default, {
194389
195116
  flexDirection: "column",
@@ -194556,15 +195283,35 @@ When done, report the result.`);
194556
195283
  const handleScheduleRefresh = async () => {
194557
195284
  setSchedulesList(await listSchedules(cwd2, scheduleListOpts));
194558
195285
  };
195286
+ const handleScheduleCreate = async (schedule) => {
195287
+ const now2 = Date.now();
195288
+ const fullSchedule = {
195289
+ ...schedule,
195290
+ id: generateId(),
195291
+ createdAt: now2,
195292
+ updatedAt: now2
195293
+ };
195294
+ fullSchedule.nextRunAt = computeNextRun(fullSchedule, now2);
195295
+ if (!fullSchedule.nextRunAt) {
195296
+ throw new Error("Unable to compute next run time. Check your schedule configuration.");
195297
+ }
195298
+ if (fullSchedule.schedule.kind === "once" && fullSchedule.nextRunAt <= now2) {
195299
+ throw new Error("Scheduled time must be in the future.");
195300
+ }
195301
+ await saveSchedule(cwd2, fullSchedule);
195302
+ setSchedulesList(await listSchedules(cwd2, scheduleListOpts));
195303
+ };
194559
195304
  return /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Box_default, {
194560
195305
  flexDirection: "column",
194561
195306
  padding: 1,
194562
195307
  children: /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(SchedulesPanel, {
194563
195308
  schedules: schedulesList,
195309
+ sessionId: activeSessionId || "default",
194564
195310
  onPause: handleSchedulePause,
194565
195311
  onResume: handleScheduleResume,
194566
195312
  onDelete: handleScheduleDelete,
194567
195313
  onRun: handleScheduleRun,
195314
+ onCreate: handleScheduleCreate,
194568
195315
  onRefresh: handleScheduleRefresh,
194569
195316
  onClose: () => setShowSchedulesPanel(false)
194570
195317
  }, undefined, false, undefined, this)
@@ -194897,6 +195644,12 @@ When done, report the result.`);
194897
195644
  onToggleEnabled: handleBudgetToggleEnabled,
194898
195645
  onReset: handleBudgetReset,
194899
195646
  onSetLimits: handleBudgetSetLimits,
195647
+ onSetOnExceeded: (action) => {
195648
+ if (budgetTrackerRef.current) {
195649
+ budgetTrackerRef.current.updateConfig({ onExceeded: action });
195650
+ setBudgetConfig(budgetTrackerRef.current.getConfig());
195651
+ }
195652
+ },
194900
195653
  onCancel: () => setShowBudgetPanel(false)
194901
195654
  }, undefined, false, undefined, this)
194902
195655
  }, undefined, false, undefined, this);
@@ -195028,10 +195781,6 @@ When done, report the result.`);
195028
195781
  };
195029
195782
  const handleBack = () => {
195030
195783
  setShowPlansPanel(false);
195031
- listProjects(cwd2).then((projects2) => {
195032
- setProjectsList(projects2);
195033
- setShowProjectsPanel(true);
195034
- });
195035
195784
  };
195036
195785
  return /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Box_default, {
195037
195786
  flexDirection: "column",
@@ -195161,13 +195910,13 @@ When done, report the result.`);
195161
195910
  }, undefined, false, undefined, this)
195162
195911
  }, undefined, false, undefined, this);
195163
195912
  }
195164
- if (showAgentDashboard) {
195913
+ if (showAssistantsDashboard) {
195165
195914
  const sessions2 = registry3.listSessions();
195166
195915
  const sessionEntries = sessions2.map((s6, i5) => ({
195167
195916
  id: s6.id,
195168
195917
  label: s6.label,
195169
195918
  assistantId: s6.assistantId,
195170
- assistantName: s6.assistantId ? s6.label || `Agent ${i5 + 1}` : null,
195919
+ assistantName: s6.assistantId ? s6.label || `Assistant ${i5 + 1}` : null,
195171
195920
  isActive: s6.id === activeSessionId,
195172
195921
  isProcessing: s6.isProcessing,
195173
195922
  isPaused: false,
@@ -195181,7 +195930,7 @@ When done, report the result.`);
195181
195930
  return /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Box_default, {
195182
195931
  flexDirection: "column",
195183
195932
  padding: 1,
195184
- children: /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(AgentDashboard, {
195933
+ children: /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(AssistantsDashboard, {
195185
195934
  sessions: sessionEntries,
195186
195935
  projectBudget: projectBudgetStatus || undefined,
195187
195936
  projectName: budgetTrackerRef.current?.getActiveProject() || undefined,
@@ -195190,10 +195939,10 @@ When done, report the result.`);
195190
195939
  onSwitchSession: async (sessionId) => {
195191
195940
  await registry3.switchSession(sessionId);
195192
195941
  setActiveSessionId(sessionId);
195193
- setShowAgentDashboard(false);
195942
+ setShowAssistantsDashboard(false);
195194
195943
  },
195195
195944
  onMessageAgent: (assistantId) => {
195196
- setShowAgentDashboard(false);
195945
+ setShowAssistantsDashboard(false);
195197
195946
  activeSession?.client.send(`/messages send ${assistantId}`);
195198
195947
  },
195199
195948
  onPauseResume: (sessionId) => {
@@ -195205,7 +195954,7 @@ When done, report the result.`);
195205
195954
  }
195206
195955
  }
195207
195956
  },
195208
- onCancel: () => setShowAgentDashboard(false)
195957
+ onCancel: () => setShowAssistantsDashboard(false)
195209
195958
  }, undefined, false, undefined, this)
195210
195959
  }, undefined, false, undefined, this);
195211
195960
  }
@@ -195502,6 +196251,7 @@ ${msg.body || msg.preview}`);
195502
196251
  }, undefined, false, undefined, this)
195503
196252
  }, undefined, false, undefined, this),
195504
196253
  /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Input, {
196254
+ ref: inputRef,
195505
196255
  onSubmit: handleSubmit,
195506
196256
  isProcessing: isBusy,
195507
196257
  queueLength: activeQueue.length + inlineCount,
@@ -195509,7 +196259,9 @@ ${msg.body || msg.preview}`);
195509
196259
  skills,
195510
196260
  isAskingUser: Boolean(activeAskQuestion),
195511
196261
  askPlaceholder,
195512
- allowBlankAnswer: activeAskQuestion?.required === false
196262
+ allowBlankAnswer: activeAskQuestion?.required === false,
196263
+ footerHints: listenHints,
196264
+ assistantName: identityInfo?.assistant?.name || undefined
195513
196265
  }, undefined, false, undefined, this),
195514
196266
  /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Status, {
195515
196267
  isProcessing: isBusy,
@@ -195950,7 +196702,7 @@ Interactive Mode:
195950
196702
  // packages/terminal/src/index.tsx
195951
196703
  var jsx_dev_runtime33 = __toESM(require_jsx_dev_runtime(), 1);
195952
196704
  setRuntime(bunRuntime);
195953
- var VERSION4 = "1.1.0";
196705
+ var VERSION4 = "1.1.1";
195954
196706
  var SYNC_START = "\x1B[?2026h";
195955
196707
  var SYNC_END = "\x1B[?2026l";
195956
196708
  function enableSynchronizedOutput() {
@@ -196090,4 +196842,4 @@ export {
196090
196842
  main
196091
196843
  };
196092
196844
 
196093
- //# debugId=BC9526CB2A5CA7CE64756E2164756E21
196845
+ //# debugId=2D5C867C5E4F72F164756E2164756E21