@hasna/assistants 1.1.86 → 1.1.87

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
@@ -740,7 +740,8 @@ var init_config = __esm(async () => {
740
740
  customPath: null
741
741
  },
742
742
  permissions: {
743
- bash: "readonly"
743
+ bash: "readonly",
744
+ mode: "normal"
744
745
  },
745
746
  backgroundModel: "claude-haiku-4-5-20251001"
746
747
  };
@@ -54652,10 +54653,143 @@ var init_loader3 = __esm(() => {
54652
54653
  init_src2();
54653
54654
  import_fast_glob = __toESM(require_out4(), 1);
54654
54655
  });
54656
+
54657
+ // packages/core/src/extensions/loader.ts
54658
+ import { join as join22 } from "path";
54659
+ import { homedir as homedir19 } from "os";
54660
+ import { stat as stat6, readdir } from "fs/promises";
54661
+
54662
+ class ExtensionLoader {
54663
+ extensions = new Map;
54664
+ loadResults = [];
54665
+ async loadAll(cwd, toolRegistry, commandLoader, config) {
54666
+ this.extensions.clear();
54667
+ this.loadResults = [];
54668
+ const envHome = process.env.HOME || process.env.USERPROFILE;
54669
+ const userHome = envHome && envHome.trim().length > 0 ? envHome : homedir19();
54670
+ const globalDir = join22(userHome, ".assistants", "extensions");
54671
+ const projectDir = join22(cwd, ".assistants", "extensions");
54672
+ await this.discoverExtensions(globalDir);
54673
+ await this.discoverExtensions(projectDir);
54674
+ const results = [];
54675
+ for (const extension2 of this.extensions.values()) {
54676
+ const result = await this.setupExtension(extension2, toolRegistry, commandLoader, config, cwd);
54677
+ results.push(result);
54678
+ }
54679
+ this.loadResults = results;
54680
+ return results;
54681
+ }
54682
+ async discoverExtensions(dir) {
54683
+ try {
54684
+ const stats = await stat6(dir);
54685
+ if (!stats.isDirectory())
54686
+ return;
54687
+ } catch {
54688
+ return;
54689
+ }
54690
+ let entries;
54691
+ try {
54692
+ entries = await readdir(dir);
54693
+ } catch {
54694
+ return;
54695
+ }
54696
+ for (const entry of entries) {
54697
+ if (entry.startsWith(".") || entry === "node_modules")
54698
+ continue;
54699
+ const extDir = join22(dir, entry);
54700
+ try {
54701
+ const extStats = await stat6(extDir);
54702
+ if (!extStats.isDirectory())
54703
+ continue;
54704
+ } catch {
54705
+ continue;
54706
+ }
54707
+ const extension2 = await this.loadExtensionModule(extDir, entry);
54708
+ if (extension2) {
54709
+ this.extensions.set(extension2.name, extension2);
54710
+ }
54711
+ }
54712
+ }
54713
+ async loadExtensionModule(dir, fallbackName) {
54714
+ const candidates = ["index.ts", "index.js"];
54715
+ for (const filename of candidates) {
54716
+ const filePath = join22(dir, filename);
54717
+ try {
54718
+ const fileStats = await stat6(filePath);
54719
+ if (!fileStats.isFile())
54720
+ continue;
54721
+ } catch {
54722
+ continue;
54723
+ }
54724
+ try {
54725
+ const mod = await import(filePath);
54726
+ const ext = mod.default ?? mod;
54727
+ if (!ext || typeof ext.name !== "string" || typeof ext.version !== "string" || typeof ext.setup !== "function") {
54728
+ this.loadResults.push({
54729
+ name: fallbackName,
54730
+ version: "0.0.0",
54731
+ success: false,
54732
+ error: `Extension at ${filePath} does not export a valid Extension (requires name, version, setup)`
54733
+ });
54734
+ return null;
54735
+ }
54736
+ return ext;
54737
+ } catch (error2) {
54738
+ const message = error2 instanceof Error ? error2.message : String(error2);
54739
+ this.loadResults.push({
54740
+ name: fallbackName,
54741
+ version: "0.0.0",
54742
+ success: false,
54743
+ error: `Failed to import ${filePath}: ${message}`
54744
+ });
54745
+ return null;
54746
+ }
54747
+ }
54748
+ return null;
54749
+ }
54750
+ async setupExtension(extension2, toolRegistry, commandLoader, config, cwd) {
54751
+ const context = {
54752
+ registerTool: (tool, executor2) => {
54753
+ toolRegistry.register(tool, executor2);
54754
+ },
54755
+ registerCommand: (command) => {
54756
+ commandLoader.register(command);
54757
+ },
54758
+ config,
54759
+ cwd
54760
+ };
54761
+ try {
54762
+ await extension2.setup(context);
54763
+ return {
54764
+ name: extension2.name,
54765
+ version: extension2.version,
54766
+ success: true
54767
+ };
54768
+ } catch (error2) {
54769
+ const message = error2 instanceof Error ? error2.message : String(error2);
54770
+ return {
54771
+ name: extension2.name,
54772
+ version: extension2.version,
54773
+ success: false,
54774
+ error: `setup() failed: ${message}`
54775
+ };
54776
+ }
54777
+ }
54778
+ getExtensions() {
54779
+ return Array.from(this.extensions.values());
54780
+ }
54781
+ getExtension(name) {
54782
+ return this.extensions.get(name);
54783
+ }
54784
+ getLoadResults() {
54785
+ return this.loadResults;
54786
+ }
54787
+ }
54788
+ var init_loader4 = () => {};
54655
54789
  // packages/core/src/commands/loader.ts
54656
54790
  import { existsSync as existsSync15, readdirSync as readdirSync6, statSync as statSync4 } from "fs";
54657
- import { join as join22, basename as basename6, extname as extname3 } from "path";
54658
- import { homedir as homedir19 } from "os";
54791
+ import { join as join23, basename as basename6, extname as extname3 } from "path";
54792
+ import { homedir as homedir20 } from "os";
54659
54793
 
54660
54794
  class CommandLoader {
54661
54795
  commands = new Map;
@@ -54666,10 +54800,10 @@ class CommandLoader {
54666
54800
  async loadAll() {
54667
54801
  this.commands.clear();
54668
54802
  const envHome = process.env.HOME || process.env.USERPROFILE;
54669
- const homeDir = envHome && envHome.trim().length > 0 ? envHome : homedir19();
54670
- const globalDir = join22(homeDir, ".assistants", "commands");
54803
+ const homeDir = envHome && envHome.trim().length > 0 ? envHome : homedir20();
54804
+ const globalDir = join23(homeDir, ".assistants", "commands");
54671
54805
  await this.loadFromDirectory(globalDir, "global");
54672
- const projectDir = join22(this.cwd, ".assistants", "commands");
54806
+ const projectDir = join23(this.cwd, ".assistants", "commands");
54673
54807
  await this.loadFromDirectory(projectDir, "project");
54674
54808
  }
54675
54809
  async loadFromDirectory(dir, source, prefix = "") {
@@ -54677,12 +54811,12 @@ class CommandLoader {
54677
54811
  return;
54678
54812
  const entries = readdirSync6(dir);
54679
54813
  for (const entry of entries) {
54680
- const fullPath = join22(dir, entry);
54681
- const stat6 = statSync4(fullPath);
54682
- if (stat6.isDirectory()) {
54814
+ const fullPath = join23(dir, entry);
54815
+ const stat7 = statSync4(fullPath);
54816
+ if (stat7.isDirectory()) {
54683
54817
  const newPrefix = prefix ? `${prefix}:${entry}` : entry;
54684
54818
  await this.loadFromDirectory(fullPath, source, newPrefix);
54685
- } else if (stat6.isFile() && extname3(entry) === ".md") {
54819
+ } else if (stat7.isFile() && extname3(entry) === ".md") {
54686
54820
  const command = await this.loadCommandFile(fullPath, prefix);
54687
54821
  if (command) {
54688
54822
  this.commands.set(command.name, command);
@@ -54800,7 +54934,7 @@ class CommandLoader {
54800
54934
  return this.getCommands().filter((cmd) => cmd.name.toLowerCase().startsWith(lower) || cmd.description.toLowerCase().includes(lower) || cmd.aliases?.some((alias) => alias.toLowerCase().startsWith(lower)));
54801
54935
  }
54802
54936
  }
54803
- var init_loader4 = __esm(async () => {
54937
+ var init_loader5 = __esm(async () => {
54804
54938
  await init_runtime();
54805
54939
  });
54806
54940
 
@@ -55745,7 +55879,7 @@ var init_types4 = __esm(() => {
55745
55879
  // node_modules/.pnpm/@hasna+todos@0.9.23_@types+react@19.2.14/node_modules/@hasna/todos/dist/index.js
55746
55880
  import { Database as Database2 } from "bun:sqlite";
55747
55881
  import { existsSync as existsSync16, mkdirSync as mkdirSync8 } from "fs";
55748
- import { dirname as dirname11, join as join23, resolve as resolve10 } from "path";
55882
+ import { dirname as dirname11, join as join24, resolve as resolve10 } from "path";
55749
55883
  import { existsSync as existsSync32 } from "fs";
55750
55884
  import { join as join32 } from "path";
55751
55885
  import { existsSync as existsSync22, mkdirSync as mkdirSync22, readFileSync as readFileSync8, readdirSync as readdirSync7, statSync as statSync5, writeFileSync as writeFileSync7 } from "fs";
@@ -55755,7 +55889,7 @@ function isInMemoryDb(path3) {
55755
55889
  function findNearestTodosDb(startDir) {
55756
55890
  let dir = resolve10(startDir);
55757
55891
  while (true) {
55758
- const candidate = join23(dir, ".todos", "todos.db");
55892
+ const candidate = join24(dir, ".todos", "todos.db");
55759
55893
  if (existsSync16(candidate))
55760
55894
  return candidate;
55761
55895
  const parent = dirname11(dir);
@@ -55768,7 +55902,7 @@ function findNearestTodosDb(startDir) {
55768
55902
  function findGitRoot(startDir) {
55769
55903
  let dir = resolve10(startDir);
55770
55904
  while (true) {
55771
- if (existsSync16(join23(dir, ".git")))
55905
+ if (existsSync16(join24(dir, ".git")))
55772
55906
  return dir;
55773
55907
  const parent = dirname11(dir);
55774
55908
  if (parent === dir)
@@ -55788,11 +55922,11 @@ function getDbPath() {
55788
55922
  if (process.env["TODOS_DB_SCOPE"] === "project") {
55789
55923
  const gitRoot = findGitRoot(cwd);
55790
55924
  if (gitRoot) {
55791
- return join23(gitRoot, ".todos", "todos.db");
55925
+ return join24(gitRoot, ".todos", "todos.db");
55792
55926
  }
55793
55927
  }
55794
55928
  const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
55795
- return join23(home, ".todos", "todos.db");
55929
+ return join24(home, ".todos", "todos.db");
55796
55930
  }
55797
55931
  function ensureDir(filePath) {
55798
55932
  if (isInMemoryDb(filePath))
@@ -86761,8 +86895,8 @@ var require_core4 = __commonJS((exports) => {
86761
86895
  function many1(p) {
86762
86896
  return ab(p, many(p), (head, tail) => [head, ...tail]);
86763
86897
  }
86764
- function ab(pa, pb, join24) {
86765
- return (data, i) => mapOuter(pa(data, i), (ma) => mapInner(pb(data, ma.position), (vb, j) => join24(ma.value, vb, data, i, j)));
86898
+ function ab(pa, pb, join25) {
86899
+ return (data, i) => mapOuter(pa(data, i), (ma) => mapInner(pb(data, ma.position), (vb, j) => join25(ma.value, vb, data, i, j)));
86766
86900
  }
86767
86901
  function left(pa, pb) {
86768
86902
  return ab(pa, pb, (va) => va);
@@ -86770,8 +86904,8 @@ var require_core4 = __commonJS((exports) => {
86770
86904
  function right(pa, pb) {
86771
86905
  return ab(pa, pb, (va, vb) => vb);
86772
86906
  }
86773
- function abc(pa, pb, pc, join24) {
86774
- return (data, i) => mapOuter(pa(data, i), (ma) => mapOuter(pb(data, ma.position), (mb) => mapInner(pc(data, mb.position), (vc, j) => join24(ma.value, mb.value, vc, data, i, j))));
86907
+ function abc(pa, pb, pc, join25) {
86908
+ return (data, i) => mapOuter(pa(data, i), (ma) => mapOuter(pb(data, ma.position), (mb) => mapInner(pc(data, mb.position), (vc, j) => join25(ma.value, mb.value, vc, data, i, j))));
86775
86909
  }
86776
86910
  function middle(pa, pb, pc) {
86777
86911
  return abc(pa, pb, pc, (ra, rb) => rb);
@@ -95485,7 +95619,7 @@ var init_email_parser = __esm(() => {
95485
95619
  });
95486
95620
 
95487
95621
  // packages/core/src/workspace/shared.ts
95488
- import { join as join24 } from "path";
95622
+ import { join as join25 } from "path";
95489
95623
  import {
95490
95624
  existsSync as existsSync17,
95491
95625
  mkdirSync as mkdirSync9,
@@ -95519,7 +95653,7 @@ class SharedWorkspaceManager {
95519
95653
  basePath;
95520
95654
  db;
95521
95655
  constructor(basePath, db) {
95522
- this.basePath = basePath || join24(getConfigDir(), "workspaces");
95656
+ this.basePath = basePath || join25(getConfigDir(), "workspaces");
95523
95657
  this.db = db || getDb6();
95524
95658
  this.ensureDir();
95525
95659
  this.migrateAgentsToAssistants();
@@ -95533,9 +95667,9 @@ class SharedWorkspaceManager {
95533
95667
  try {
95534
95668
  const dirs = readdirSync8(this.basePath, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
95535
95669
  for (const dir of dirs) {
95536
- const wsPath = join24(this.basePath, dir);
95537
- const oldAgentsDir = join24(wsPath, "agents");
95538
- const newAssistantsDir = join24(wsPath, "assistants");
95670
+ const wsPath = join25(this.basePath, dir);
95671
+ const oldAgentsDir = join25(wsPath, "agents");
95672
+ const newAssistantsDir = join25(wsPath, "assistants");
95539
95673
  if (existsSync17(oldAgentsDir) && !existsSync17(newAssistantsDir)) {
95540
95674
  renameSync(oldAgentsDir, newAssistantsDir);
95541
95675
  }
@@ -95543,7 +95677,7 @@ class SharedWorkspaceManager {
95543
95677
  } catch {}
95544
95678
  }
95545
95679
  getWorkspacePath(id) {
95546
- return join24(this.basePath, id);
95680
+ return join25(this.basePath, id);
95547
95681
  }
95548
95682
  create(name, createdBy, participants, description) {
95549
95683
  const id = `ws_${generateId().slice(0, 8)}`;
@@ -95561,9 +95695,9 @@ class SharedWorkspaceManager {
95561
95695
  status: "active"
95562
95696
  };
95563
95697
  const wsPath = this.getWorkspacePath(id);
95564
- mkdirSync9(join24(wsPath, "shared"), { recursive: true });
95698
+ mkdirSync9(join25(wsPath, "shared"), { recursive: true });
95565
95699
  for (const assistantId of allParticipants) {
95566
- mkdirSync9(join24(wsPath, "assistants", assistantId), { recursive: true });
95700
+ mkdirSync9(join25(wsPath, "assistants", assistantId), { recursive: true });
95567
95701
  }
95568
95702
  this.db.prepare(`INSERT INTO workspaces (id, name, description, creator_id, creator_name, status, participants, created_at, updated_at)
95569
95703
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, name, description || null, createdBy, createdBy, "active", JSON.stringify(allParticipants), nowIso, nowIso);
@@ -95579,7 +95713,7 @@ class SharedWorkspaceManager {
95579
95713
  workspace.updatedAt = Date.now();
95580
95714
  this.db.prepare("UPDATE workspaces SET participants = ?, updated_at = ? WHERE id = ?").run(JSON.stringify(workspace.participants), new Date(workspace.updatedAt).toISOString(), workspaceId);
95581
95715
  }
95582
- const assistantDir = join24(this.getWorkspacePath(workspaceId), "assistants", assistantId);
95716
+ const assistantDir = join25(this.getWorkspacePath(workspaceId), "assistants", assistantId);
95583
95717
  if (!existsSync17(assistantDir)) {
95584
95718
  mkdirSync9(assistantDir, { recursive: true });
95585
95719
  }
@@ -95594,10 +95728,10 @@ class SharedWorkspaceManager {
95594
95728
  return this.getWorkspacePath(workspaceId);
95595
95729
  }
95596
95730
  getSharedPath(workspaceId) {
95597
- return join24(this.getWorkspacePath(workspaceId), "shared");
95731
+ return join25(this.getWorkspacePath(workspaceId), "shared");
95598
95732
  }
95599
95733
  getAssistantPath(workspaceId, assistantId) {
95600
- return join24(this.getWorkspacePath(workspaceId), "assistants", assistantId);
95734
+ return join25(this.getWorkspacePath(workspaceId), "assistants", assistantId);
95601
95735
  }
95602
95736
  list(includeArchived = false) {
95603
95737
  const query = includeArchived ? "SELECT * FROM workspaces ORDER BY updated_at DESC" : "SELECT * FROM workspaces WHERE status = 'active' ORDER BY updated_at DESC";
@@ -95630,7 +95764,7 @@ var init_shared2 = __esm(async () => {
95630
95764
  });
95631
95765
 
95632
95766
  // packages/core/src/workspace/active.ts
95633
- import { join as join25 } from "path";
95767
+ import { join as join26 } from "path";
95634
95768
  import { existsSync as existsSync18, mkdirSync as mkdirSync10 } from "fs";
95635
95769
  function getDb7() {
95636
95770
  return getDatabase();
@@ -95639,7 +95773,7 @@ function isValidId2(id) {
95639
95773
  return typeof id === "string" && id.length > 0 && SAFE_ID_PATTERN3.test(id);
95640
95774
  }
95641
95775
  function getWorkspaceRoot(baseDir) {
95642
- return join25(baseDir ?? getConfigDir(), "workspaces");
95776
+ return join26(baseDir ?? getConfigDir(), "workspaces");
95643
95777
  }
95644
95778
  function getActiveWorkspaceId(baseDir, db) {
95645
95779
  try {
@@ -95669,7 +95803,7 @@ function getWorkspaceDataDir(workspaceId, baseDir) {
95669
95803
  if (!isValidId2(workspaceId)) {
95670
95804
  throw new Error(`Invalid workspace id: "${workspaceId}"`);
95671
95805
  }
95672
- return join25(getWorkspaceRoot(baseDir), workspaceId, ".assistants");
95806
+ return join26(getWorkspaceRoot(baseDir), workspaceId, ".assistants");
95673
95807
  }
95674
95808
  function ensureWorkspaceDataDir(workspaceId, baseDir) {
95675
95809
  const dir = getWorkspaceDataDir(workspaceId, baseDir);
@@ -100021,7 +100155,7 @@ var init_dispatcher = __esm(() => {
100021
100155
  maxQueueSize: 50,
100022
100156
  forbiddenTools: ["swarm_execute", "assistant_spawn"],
100023
100157
  defaultWorkerTools: ["bash", "read", "write", "edit", "glob", "grep"],
100024
- maxTurnsPerTask: 15
100158
+ maxTurnsPerTask: 25
100025
100159
  };
100026
100160
  });
100027
100161
 
@@ -101506,8 +101640,8 @@ var init_swarm = __esm(() => {
101506
101640
  });
101507
101641
 
101508
101642
  // packages/core/src/commands/builtin.ts
101509
- import { join as join26 } from "path";
101510
- import { homedir as homedir20, platform as platform2, release, arch as arch2 } from "os";
101643
+ import { join as join27 } from "path";
101644
+ import { homedir as homedir21, platform as platform2, release, arch as arch2 } from "os";
101511
101645
  import { existsSync as existsSync19, mkdirSync as mkdirSync11, writeFileSync as writeFileSync8 } from "fs";
101512
101646
  function resolveAuthTimeout(resolve11) {
101513
101647
  resolve11({ exitCode: 1, stdout: { toString: () => "{}" } });
@@ -101614,11 +101748,14 @@ class BuiltinCommands {
101614
101748
  loader.register(this.callCommand());
101615
101749
  loader.register(this.ordersCommand());
101616
101750
  loader.register(this.tasksCommand());
101751
+ loader.register(this.renameCommand());
101617
101752
  loader.register(this.setupCommand());
101618
101753
  loader.register(this.scriptsCommand());
101619
101754
  loader.register(this.exitCommand());
101620
101755
  loader.register(this.diffCommand());
101621
101756
  loader.register(this.undoCommand());
101757
+ loader.register(this.treeCommand());
101758
+ loader.register(this.modeCommand());
101622
101759
  }
101623
101760
  aboutCommand() {
101624
101761
  return {
@@ -106339,6 +106476,32 @@ Unknown workspace command. Use /workspace help for available commands.
106339
106476
  }
106340
106477
  };
106341
106478
  }
106479
+ renameCommand() {
106480
+ return {
106481
+ name: "rename",
106482
+ description: "Rename the current session (shortcut for /session rename)",
106483
+ builtin: true,
106484
+ selfHandled: true,
106485
+ content: "",
106486
+ handler: async (args, context) => {
106487
+ const label = args.trim();
106488
+ if (!label) {
106489
+ context.emit("text", `
106490
+ Usage: /rename <name>
106491
+ Example: /rename auth-refactor
106492
+ `);
106493
+ context.emit("done");
106494
+ return { handled: true };
106495
+ }
106496
+ context.emit("done");
106497
+ return {
106498
+ handled: true,
106499
+ sessionAction: "rename",
106500
+ sessionLabel: label
106501
+ };
106502
+ }
106503
+ };
106504
+ }
106342
106505
  exitCommand() {
106343
106506
  return {
106344
106507
  name: "exit",
@@ -107885,8 +108048,8 @@ Options for install/uninstall:
107885
108048
  `;
107886
108049
  message += `| --- | --- | --- |
107887
108050
  `;
107888
- for (const stat6 of errorStats.slice(0, 5)) {
107889
- message += `| ${stat6.code} | ${stat6.count} | ${stat6.lastOccurrence} |
108051
+ for (const stat7 of errorStats.slice(0, 5)) {
108052
+ message += `| ${stat7.code} | ${stat7.count} | ${stat7.lastOccurrence} |
107890
108053
  `;
107891
108054
  }
107892
108055
  }
@@ -107937,9 +108100,9 @@ Format the summary as a brief bullet-point list. This summary will replace the c
107937
108100
  if (action === "show" || action === "paths") {
107938
108101
  const storageDir = context.getStorageDir?.() || getConfigDir();
107939
108102
  const configPaths = [
107940
- join26(context.cwd, ".assistants", "config.json"),
107941
- join26(context.cwd, ".assistants", "config.local.json"),
107942
- join26(storageDir, "config.json")
108103
+ join27(context.cwd, ".assistants", "config.json"),
108104
+ join27(context.cwd, ".assistants", "config.local.json"),
108105
+ join27(storageDir, "config.json")
107943
108106
  ];
107944
108107
  let message = `
107945
108108
  **Configuration**
@@ -107953,16 +108116,16 @@ Format the summary as a brief bullet-point list. This summary will replace the c
107953
108116
  `;
107954
108117
  }
107955
108118
  const envHome = process.env.HOME || process.env.USERPROFILE;
107956
- const homeDir = envHome && envHome.trim().length > 0 ? envHome : homedir20();
108119
+ const homeDir = envHome && envHome.trim().length > 0 ? envHome : homedir21();
107957
108120
  message += `
107958
108121
  **Commands Directories:**
107959
108122
  `;
107960
- message += ` - Project: ${join26(context.cwd, ".assistants", "commands")}
108123
+ message += ` - Project: ${join27(context.cwd, ".assistants", "commands")}
107961
108124
  `;
107962
- message += ` - User/Workspace: ${join26(storageDir, "commands")}
108125
+ message += ` - User/Workspace: ${join27(storageDir, "commands")}
107963
108126
  `;
107964
- if (storageDir !== join26(homeDir, ".assistants")) {
107965
- message += ` - Global fallback: ${join26(homeDir, ".assistants", "commands")}
108127
+ if (storageDir !== join27(homeDir, ".assistants")) {
108128
+ message += ` - Global fallback: ${join27(homeDir, ".assistants", "commands")}
107966
108129
  `;
107967
108130
  }
107968
108131
  context.emit("text", message);
@@ -108878,7 +109041,7 @@ ${error2 instanceof Error ? error2.message : String(error2)}
108878
109041
  selfHandled: true,
108879
109042
  content: "",
108880
109043
  handler: async (args, context) => {
108881
- const commandsDir = join26(context.cwd, ".assistants", "commands");
109044
+ const commandsDir = join27(context.cwd, ".assistants", "commands");
108882
109045
  mkdirSync11(commandsDir, { recursive: true });
108883
109046
  const exampleCommand = `---
108884
109047
  name: reflect
@@ -108894,7 +109057,7 @@ Please summarize the last interaction and suggest 2-3 next steps.
108894
109057
  - Focus on clarity
108895
109058
  - Ask a follow-up question if needed
108896
109059
  `;
108897
- const examplePath = join26(commandsDir, "reflect.md");
109060
+ const examplePath = join27(commandsDir, "reflect.md");
108898
109061
  if (!existsSync19(examplePath)) {
108899
109062
  writeFileSync8(examplePath, exampleCommand);
108900
109063
  }
@@ -109625,7 +109788,7 @@ Memory Statistics
109625
109788
  return { handled: true };
109626
109789
  }
109627
109790
  if (action === "export") {
109628
- const filePath = rest[0] || join26(context.getStorageDir?.() || getConfigDir(), "memories-export.json");
109791
+ const filePath = rest[0] || join27(context.getStorageDir?.() || getConfigDir(), "memories-export.json");
109629
109792
  const memories = await manager.export();
109630
109793
  try {
109631
109794
  const content3 = JSON.stringify(memories, null, 2);
@@ -109843,7 +110006,7 @@ Importing ${validMemories.length} valid entries (skipping ${errors.length} inval
109843
110006
  const heartbeatConfig = context.getHeartbeatConfig?.() ?? null;
109844
110007
  const historyPathTemplate = heartbeatConfig?.historyPath;
109845
110008
  const storageDir = context.getStorageDir?.();
109846
- const runsDir = storageDir ? join26(storageDir, "heartbeats", "runs") : undefined;
110009
+ const runsDir = storageDir ? join27(storageDir, "heartbeats", "runs") : undefined;
109847
110010
  if (!cleanedArgs || cleanedArgs === "ui") {
109848
110011
  context.emit("done");
109849
110012
  return { handled: true, showPanel: "heartbeat" };
@@ -110455,7 +110618,7 @@ Not a git repository or git not available.
110455
110618
  handler: async (_args, context) => {
110456
110619
  const { getProjectDataDir: getDataDir } = await init_config().then(() => exports_config);
110457
110620
  const { readdirSync: readdirSync9, statSync: statSync6 } = await import("fs");
110458
- const scriptsRoot = join26(getDataDir(context.cwd), "scripts", context.sessionId);
110621
+ const scriptsRoot = join27(getDataDir(context.cwd), "scripts", context.sessionId);
110459
110622
  let entries = [];
110460
110623
  const walk = (dir, prefix) => {
110461
110624
  let items;
@@ -110465,15 +110628,15 @@ Not a git repository or git not available.
110465
110628
  return;
110466
110629
  }
110467
110630
  for (const item of items) {
110468
- const fullPath = join26(dir, item);
110631
+ const fullPath = join27(dir, item);
110469
110632
  try {
110470
- const stat6 = statSync6(fullPath);
110471
- if (stat6.isDirectory()) {
110633
+ const stat7 = statSync6(fullPath);
110634
+ if (stat7.isDirectory()) {
110472
110635
  walk(fullPath, prefix ? `${prefix}/${item}` : item);
110473
110636
  } else {
110474
110637
  entries.push({
110475
110638
  relativePath: prefix ? `${prefix}/${item}` : item,
110476
- size: stat6.size
110639
+ size: stat7.size
110477
110640
  });
110478
110641
  }
110479
110642
  } catch {}
@@ -110582,6 +110745,136 @@ Not a git repository or git not available.
110582
110745
  }
110583
110746
  };
110584
110747
  }
110748
+ modeCommand() {
110749
+ return {
110750
+ name: "mode",
110751
+ description: "Show or switch permission mode: normal, plan (read-only), auto (auto-accept)",
110752
+ builtin: true,
110753
+ selfHandled: true,
110754
+ content: "",
110755
+ handler: async (args, context) => {
110756
+ const trimmedArgs = args.trim().toLowerCase();
110757
+ if (!trimmedArgs) {
110758
+ const current = context.getPermissionMode?.() ?? "normal";
110759
+ let message = `
110760
+ **Permission Mode:** ${current}
110761
+
110762
+ `;
110763
+ message += `**Available modes:**
110764
+ `;
110765
+ message += " `normal` \u2014 Standard behavior with per-tool permission checks\n";
110766
+ message += " `plan` \u2014 Read-only mode. Only analysis tools allowed (read, glob, grep, web_search, etc.)\n";
110767
+ message += " `auto` \u2014 Auto-accept all tool calls without confirmation\n\n";
110768
+ message += "Switch with: `/mode plan`, `/mode normal`, or `/mode auto`\n";
110769
+ context.emit("text", message);
110770
+ context.emit("done");
110771
+ return { handled: true };
110772
+ }
110773
+ const modeMap = {
110774
+ normal: "normal",
110775
+ plan: "plan",
110776
+ auto: "auto-accept",
110777
+ "auto-accept": "auto-accept"
110778
+ };
110779
+ const newMode = modeMap[trimmedArgs];
110780
+ if (!newMode) {
110781
+ context.emit("text", `
110782
+ Unknown mode "${trimmedArgs}". Valid modes: normal, plan, auto
110783
+ `);
110784
+ context.emit("done");
110785
+ return { handled: true };
110786
+ }
110787
+ context.setPermissionMode?.(newMode);
110788
+ const labels = {
110789
+ normal: "normal \u2014 standard tool permissions",
110790
+ plan: "plan \u2014 read-only mode (write tools blocked)",
110791
+ "auto-accept": "auto \u2014 all tool calls auto-accepted"
110792
+ };
110793
+ context.emit("text", `
110794
+ Switched to **${labels[newMode]}**
110795
+ `);
110796
+ context.emit("done");
110797
+ return { handled: true };
110798
+ }
110799
+ };
110800
+ }
110801
+ treeCommand() {
110802
+ return {
110803
+ name: "tree",
110804
+ description: "Show session message history as a navigable tree",
110805
+ builtin: true,
110806
+ selfHandled: true,
110807
+ content: "",
110808
+ handler: async (_args, context) => {
110809
+ const messages = context.messages;
110810
+ if (!messages || messages.length === 0) {
110811
+ context.emit("text", `
110812
+ No messages in the current session.
110813
+ `);
110814
+ context.emit("done");
110815
+ return { handled: true };
110816
+ }
110817
+ let output = `
110818
+ ## Session Tree
110819
+
110820
+ `;
110821
+ const formatTimeAgo = (ts) => {
110822
+ const diff = Date.now() - ts;
110823
+ const seconds = Math.floor(diff / 1000);
110824
+ if (seconds < 60)
110825
+ return `${seconds}s ago`;
110826
+ const minutes = Math.floor(seconds / 60);
110827
+ if (minutes < 60)
110828
+ return `${minutes}m ago`;
110829
+ const hours = Math.floor(minutes / 60);
110830
+ if (hours < 24)
110831
+ return `${hours}h ago`;
110832
+ const days = Math.floor(hours / 24);
110833
+ return `${days}d ago`;
110834
+ };
110835
+ const preview = (text5) => {
110836
+ const clean = text5.replace(/\n/g, " ").trim();
110837
+ return clean.length > 50 ? clean.slice(0, 50) + "..." : clean;
110838
+ };
110839
+ for (let i = 0;i < messages.length; i++) {
110840
+ const msg = messages[i];
110841
+ const isLast = i === messages.length - 1;
110842
+ const timeStr = msg.timestamp ? ` (${formatTimeAgo(msg.timestamp)})` : "";
110843
+ if (msg.role === "user") {
110844
+ const connector = isLast ? "\u2514\u2500" : "\u251C\u2500";
110845
+ output += `${connector} [user] "${preview(msg.content)}"${timeStr}
110846
+ `;
110847
+ let j = i + 1;
110848
+ while (j < messages.length && messages[j].role === "assistant") {
110849
+ const aMsg = messages[j];
110850
+ const aTimeStr = aMsg.timestamp ? ` (${formatTimeAgo(aMsg.timestamp)})` : "";
110851
+ const isLastAssistant = j + 1 >= messages.length || messages[j + 1].role !== "assistant";
110852
+ const prefix = isLast ? " " : "\u2502 ";
110853
+ const aConnector = isLastAssistant ? "\u2514\u2500" : "\u251C\u2500";
110854
+ output += `${prefix}${aConnector} [assistant] "${preview(aMsg.content)}"${aTimeStr}
110855
+ `;
110856
+ j++;
110857
+ }
110858
+ i = j - 1;
110859
+ } else if (msg.role === "system") {
110860
+ const connector = isLast ? "\u2514\u2500" : "\u251C\u2500";
110861
+ output += `${connector} [system] "${preview(msg.content)}"${timeStr}
110862
+ `;
110863
+ } else {
110864
+ const connector = isLast ? "\u2514\u2500" : "\u251C\u2500";
110865
+ output += `${connector} [assistant] "${preview(msg.content)}"${timeStr}
110866
+ `;
110867
+ }
110868
+ }
110869
+ output += `
110870
+ **Total messages:** ${messages.length}
110871
+ `;
110872
+ context.emit("text", output);
110873
+ context.emit("done");
110874
+ return { handled: true };
110875
+ }
110876
+ };
110877
+ }
110585
110878
  async resolveProject(context, target) {
110586
110879
  const byId = await readProject(context.cwd, target);
110587
110880
  if (byId)
@@ -110612,7 +110905,7 @@ Not a git repository or git not available.
110612
110905
  context.setProjectContext(projectContext);
110613
110906
  }
110614
110907
  }
110615
- var VERSION2 = "1.1.86";
110908
+ var VERSION2 = "1.1.87";
110616
110909
  var init_builtin = __esm(async () => {
110617
110910
  init_src2();
110618
110911
  init_context3();
@@ -110637,7 +110930,7 @@ var init_builtin = __esm(async () => {
110637
110930
  // packages/core/src/commands/index.ts
110638
110931
  var init_commands = __esm(async () => {
110639
110932
  await __promiseAll([
110640
- init_loader4(),
110933
+ init_loader5(),
110641
110934
  init_executor4(),
110642
110935
  init_builtin()
110643
110936
  ]);
@@ -116001,12 +116294,12 @@ var init_watchdog = __esm(async () => {
116001
116294
  });
116002
116295
 
116003
116296
  // packages/core/src/heartbeat/install-skills.ts
116004
- import { join as join27 } from "path";
116005
- import { homedir as homedir21 } from "os";
116297
+ import { join as join28 } from "path";
116298
+ import { homedir as homedir22 } from "os";
116006
116299
  async function writeSkillIfNeeded(dir, skillName, content3) {
116007
116300
  const { mkdir: mkdir7, writeFile: writeFile6, readFile: readFile7 } = await import("fs/promises");
116008
- const skillDir = join27(dir, `skill-${skillName}`);
116009
- const skillFile = join27(skillDir, "SKILL.md");
116301
+ const skillDir = join28(dir, `skill-${skillName}`);
116302
+ const skillFile = join28(skillDir, "SKILL.md");
116010
116303
  await mkdir7(skillDir, { recursive: true });
116011
116304
  try {
116012
116305
  const existing = await readFile7(skillFile, "utf-8");
@@ -116025,7 +116318,7 @@ async function writeSkillIfNeeded(dir, skillName, content3) {
116025
116318
  }
116026
116319
  }
116027
116320
  async function installHeartbeatSkills() {
116028
- const sharedSkillsDir = join27(homedir21(), ".skill");
116321
+ const sharedSkillsDir = join28(homedir22(), ".skill");
116029
116322
  const installed = [];
116030
116323
  const results = await Promise.all([
116031
116324
  writeSkillIfNeeded(sharedSkillsDir, "main-loop", MAIN_LOOP_SKILL),
@@ -116188,7 +116481,7 @@ var init_llm_response = __esm(() => {
116188
116481
  // packages/core/src/voice/tts.ts
116189
116482
  import { spawnSync as spawnSync2 } from "child_process";
116190
116483
  import { tmpdir as tmpdir2 } from "os";
116191
- import { join as join28 } from "path";
116484
+ import { join as join29 } from "path";
116192
116485
  import { readFileSync as readFileSync9, unlinkSync as unlinkSync3 } from "fs";
116193
116486
 
116194
116487
  class ElevenLabsTTS {
@@ -116380,7 +116673,7 @@ class SystemTTS {
116380
116673
  if (!say) {
116381
116674
  throw new Error('System TTS not available: missing "say" command.');
116382
116675
  }
116383
- const output = join28(tmpdir2(), `assistants-tts-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.aiff`);
116676
+ const output = join29(tmpdir2(), `assistants-tts-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.aiff`);
116384
116677
  const args = [];
116385
116678
  if (this.voiceId) {
116386
116679
  args.push("-v", this.voiceId);
@@ -116402,7 +116695,7 @@ class SystemTTS {
116402
116695
  }
116403
116696
  const espeak = findExecutable("espeak") || findExecutable("espeak-ng");
116404
116697
  if (espeak) {
116405
- const output = join28(tmpdir2(), `assistants-tts-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.wav`);
116698
+ const output = join29(tmpdir2(), `assistants-tts-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.wav`);
116406
116699
  const args = ["-w", output];
116407
116700
  if (this.voiceId) {
116408
116701
  args.push("-v", this.voiceId);
@@ -116432,7 +116725,7 @@ var init_tts = __esm(() => {
116432
116725
  // packages/core/src/voice/player.ts
116433
116726
  import { spawn as spawn2 } from "child_process";
116434
116727
  import { tmpdir as tmpdir3 } from "os";
116435
- import { join as join29 } from "path";
116728
+ import { join as join30 } from "path";
116436
116729
  import { unlink as unlink2, writeFileSync as writeFileSync9, appendFileSync as appendFileSync3 } from "fs";
116437
116730
 
116438
116731
  class AudioPlayer {
@@ -116440,7 +116733,7 @@ class AudioPlayer {
116440
116733
  playing = false;
116441
116734
  async play(audio, options2 = {}) {
116442
116735
  const format = options2.format ?? "mp3";
116443
- const tempFile = join29(tmpdir3(), `assistants-audio-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.${format}`);
116736
+ const tempFile = join30(tmpdir3(), `assistants-audio-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.${format}`);
116444
116737
  writeFileSync9(tempFile, Buffer.from(audio));
116445
116738
  const player = this.resolvePlayer(format);
116446
116739
  if (!player) {
@@ -116468,7 +116761,7 @@ class AudioPlayer {
116468
116761
  }
116469
116762
  async playStream(chunks, options2 = {}) {
116470
116763
  const format = options2.format ?? "mp3";
116471
- const tempFile = join29(tmpdir3(), `assistants-stream-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.${format}`);
116764
+ const tempFile = join30(tmpdir3(), `assistants-stream-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.${format}`);
116472
116765
  writeFileSync9(tempFile, Buffer.alloc(0));
116473
116766
  for await (const chunk of chunks) {
116474
116767
  appendFileSync3(tempFile, Buffer.from(chunk));
@@ -116537,7 +116830,7 @@ var init_player = __esm(() => {
116537
116830
  // packages/core/src/voice/recorder.ts
116538
116831
  import { spawn as spawn3 } from "child_process";
116539
116832
  import { tmpdir as tmpdir4 } from "os";
116540
- import { join as join30 } from "path";
116833
+ import { join as join31 } from "path";
116541
116834
  import { readFileSync as readFileSync10, existsSync as existsSync20, unlink as unlink3 } from "fs";
116542
116835
 
116543
116836
  class AudioRecorder {
@@ -116551,7 +116844,7 @@ class AudioRecorder {
116551
116844
  const duration = options2.durationSeconds ?? 5;
116552
116845
  const sampleRate = options2.sampleRate ?? 16000;
116553
116846
  const channels = options2.channels ?? 1;
116554
- const output = join30(tmpdir4(), `assistants-record-${Date.now()}.wav`);
116847
+ const output = join31(tmpdir4(), `assistants-record-${Date.now()}.wav`);
116555
116848
  this.currentOutputPath = output;
116556
116849
  this.stoppedIntentionally = false;
116557
116850
  const recorder = this.resolveRecorder(sampleRate, channels, duration, output);
@@ -116589,7 +116882,7 @@ class AudioRecorder {
116589
116882
  const sampleRate = options2.sampleRate ?? 16000;
116590
116883
  const channels = options2.channels ?? 1;
116591
116884
  const maxDuration = options2.durationSeconds ?? 30;
116592
- const output = join30(tmpdir4(), `assistants-record-${Date.now()}.wav`);
116885
+ const output = join31(tmpdir4(), `assistants-record-${Date.now()}.wav`);
116593
116886
  this.currentOutputPath = output;
116594
116887
  this.stoppedIntentionally = false;
116595
116888
  const recorder = this.resolveVadRecorder(sampleRate, channels, maxDuration, output);
@@ -117009,7 +117302,7 @@ var init_manager3 = __esm(() => {
117009
117302
  // packages/core/src/identity/identity-manager.ts
117010
117303
  import { existsSync as existsSync21 } from "fs";
117011
117304
  import { mkdir as mkdir7, readFile as readFile7, writeFile as writeFile6, rm as rm2 } from "fs/promises";
117012
- import { join as join31 } from "path";
117305
+ import { join as join33 } from "path";
117013
117306
  function isValidId3(id) {
117014
117307
  return typeof id === "string" && id.length > 0 && SAFE_ID_PATTERN4.test(id);
117015
117308
  }
@@ -117030,20 +117323,20 @@ class IdentityManager {
117030
117323
  this.basePath = basePath;
117031
117324
  }
117032
117325
  get identitiesRoot() {
117033
- return join31(this.basePath, "assistants", this.assistantId, "identities");
117326
+ return join33(this.basePath, "assistants", this.assistantId, "identities");
117034
117327
  }
117035
117328
  get indexPath() {
117036
- return join31(this.identitiesRoot, "index.json");
117329
+ return join33(this.identitiesRoot, "index.json");
117037
117330
  }
117038
117331
  get activePath() {
117039
- return join31(this.identitiesRoot, "active.json");
117332
+ return join33(this.identitiesRoot, "active.json");
117040
117333
  }
117041
117334
  identityPath(id) {
117042
117335
  validateId(id, "identityId");
117043
- return join31(this.identitiesRoot, `${id}.json`);
117336
+ return join33(this.identitiesRoot, `${id}.json`);
117044
117337
  }
117045
117338
  assistantConfigPath() {
117046
- return join31(this.basePath, "assistants", this.assistantId, "config.json");
117339
+ return join33(this.basePath, "assistants", this.assistantId, "config.json");
117047
117340
  }
117048
117341
  async initialize() {
117049
117342
  await mkdir7(this.identitiesRoot, { recursive: true });
@@ -145124,8 +145417,8 @@ var require_signin = __commonJS((exports) => {
145124
145417
  // node_modules/.pnpm/@aws-sdk+credential-provider-login@3.972.8/node_modules/@aws-sdk/credential-provider-login/dist-es/LoginCredentialsFetcher.js
145125
145418
  import { createHash as createHash5, createPrivateKey, createPublicKey, sign } from "crypto";
145126
145419
  import { promises as fs2 } from "fs";
145127
- import { homedir as homedir22 } from "os";
145128
- import { dirname as dirname13, join as join33 } from "path";
145420
+ import { homedir as homedir23 } from "os";
145421
+ import { dirname as dirname13, join as join35 } from "path";
145129
145422
  var import_property_provider18, import_protocol_http11, import_shared_ini_file_loader6, LoginCredentialsFetcher;
145130
145423
  var init_LoginCredentialsFetcher = __esm(() => {
145131
145424
  import_property_provider18 = __toESM(require_dist_cjs17(), 1);
@@ -145285,10 +145578,10 @@ var init_LoginCredentialsFetcher = __esm(() => {
145285
145578
  await fs2.writeFile(tokenFilePath, JSON.stringify(token, null, 2), "utf8");
145286
145579
  }
145287
145580
  getTokenFilePath() {
145288
- const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ?? join33(homedir22(), ".aws", "login", "cache");
145581
+ const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ?? join35(homedir23(), ".aws", "login", "cache");
145289
145582
  const loginSessionBytes = Buffer.from(this.loginSession, "utf8");
145290
145583
  const loginSessionSha256 = createHash5("sha256").update(loginSessionBytes).digest("hex");
145291
- return join33(directory, `${loginSessionSha256}.json`);
145584
+ return join35(directory, `${loginSessionSha256}.json`);
145292
145585
  }
145293
145586
  derToRawSignature(derSignature) {
145294
145587
  let offset = 2;
@@ -149945,8 +150238,8 @@ var init_s3_client = __esm(() => {
149945
150238
  });
149946
150239
 
149947
150240
  // packages/core/src/inbox/storage/local-cache.ts
149948
- import { join as join35, basename as basename7 } from "path";
149949
- import { mkdir as mkdir8, readFile as readFile9, writeFile as writeFile8, rm as rm3, readdir, stat as stat6 } from "fs/promises";
150241
+ import { join as join36, basename as basename7 } from "path";
150242
+ import { mkdir as mkdir8, readFile as readFile9, writeFile as writeFile8, rm as rm3, readdir as readdir2, stat as stat7 } from "fs/promises";
149950
150243
  import { createHash as createHash6 } from "crypto";
149951
150244
  function isValidAssistantId(id) {
149952
150245
  return typeof id === "string" && id.length > 0 && STRICT_ID_PATTERN.test(id);
@@ -149986,15 +150279,15 @@ class LocalInboxCache {
149986
150279
  validateAssistantId(options2.assistantId);
149987
150280
  this.assistantId = options2.assistantId;
149988
150281
  this.basePath = options2.basePath;
149989
- this.cacheDir = join35(this.basePath, this.assistantId);
150282
+ this.cacheDir = join36(this.basePath, this.assistantId);
149990
150283
  this.injectedDb = options2.db;
149991
150284
  }
149992
150285
  db() {
149993
150286
  return getDb11(this.injectedDb);
149994
150287
  }
149995
150288
  async ensureDirectories() {
149996
- await mkdir8(join35(this.cacheDir, "emails"), { recursive: true });
149997
- await mkdir8(join35(this.cacheDir, "attachments"), { recursive: true });
150289
+ await mkdir8(join36(this.cacheDir, "emails"), { recursive: true });
150290
+ await mkdir8(join36(this.cacheDir, "attachments"), { recursive: true });
149998
150291
  }
149999
150292
  async loadIndex() {
150000
150293
  const rows = this.db().query("SELECT * FROM inbox_cache WHERE assistant_id = ? ORDER BY date DESC").all(this.assistantId);
@@ -150022,7 +150315,7 @@ class LocalInboxCache {
150022
150315
  throw new Error(`Failed to create safe filename for email ID: "${email.id}"`);
150023
150316
  }
150024
150317
  await this.ensureDirectories();
150025
- const emailPath = join35(this.cacheDir, "emails", `${filename}.json`);
150318
+ const emailPath = join36(this.cacheDir, "emails", `${filename}.json`);
150026
150319
  await writeFile8(emailPath, JSON.stringify(email, null, 2));
150027
150320
  const existing = this.db().query("SELECT * FROM inbox_cache WHERE id = ? AND assistant_id = ?").get(email.id, this.assistantId);
150028
150321
  if (existing) {
@@ -150041,7 +150334,7 @@ class LocalInboxCache {
150041
150334
  if (!isValidMappedFilename(filename))
150042
150335
  return null;
150043
150336
  try {
150044
- const emailPath = join35(this.cacheDir, "emails", `${filename}.json`);
150337
+ const emailPath = join36(this.cacheDir, "emails", `${filename}.json`);
150045
150338
  const content3 = await readFile9(emailPath, "utf-8");
150046
150339
  return JSON.parse(content3);
150047
150340
  } catch {
@@ -150093,9 +150386,9 @@ class LocalInboxCache {
150093
150386
  if (!safeFilename) {
150094
150387
  throw new Error("Invalid attachment filename");
150095
150388
  }
150096
- const attachmentDir = join35(this.cacheDir, "attachments", emailFilename);
150389
+ const attachmentDir = join36(this.cacheDir, "attachments", emailFilename);
150097
150390
  await mkdir8(attachmentDir, { recursive: true });
150098
- const attachmentPath = join35(attachmentDir, safeFilename);
150391
+ const attachmentPath = join36(attachmentDir, safeFilename);
150099
150392
  await writeFile8(attachmentPath, content3);
150100
150393
  return attachmentPath;
150101
150394
  }
@@ -150109,8 +150402,8 @@ class LocalInboxCache {
150109
150402
  return null;
150110
150403
  }
150111
150404
  try {
150112
- const attachmentPath = join35(this.cacheDir, "attachments", emailFilename, safeFilename);
150113
- await stat6(attachmentPath);
150405
+ const attachmentPath = join36(this.cacheDir, "attachments", emailFilename, safeFilename);
150406
+ await stat7(attachmentPath);
150114
150407
  return attachmentPath;
150115
150408
  } catch {
150116
150409
  return null;
@@ -150132,10 +150425,10 @@ class LocalInboxCache {
150132
150425
  const filename = row.filename || emailIdToFilename(row.id);
150133
150426
  if (isValidMappedFilename(filename)) {
150134
150427
  try {
150135
- await rm3(join35(this.cacheDir, "emails", `${filename}.json`));
150428
+ await rm3(join36(this.cacheDir, "emails", `${filename}.json`));
150136
150429
  } catch {}
150137
150430
  try {
150138
- await rm3(join35(this.cacheDir, "attachments", filename), { recursive: true });
150431
+ await rm3(join36(this.cacheDir, "attachments", filename), { recursive: true });
150139
150432
  } catch {}
150140
150433
  }
150141
150434
  }
@@ -150147,20 +150440,20 @@ class LocalInboxCache {
150147
150440
  async getCacheSize() {
150148
150441
  let totalSize = 0;
150149
150442
  try {
150150
- const emailsDir = join35(this.cacheDir, "emails");
150151
- const files = await readdir(emailsDir);
150443
+ const emailsDir = join36(this.cacheDir, "emails");
150444
+ const files = await readdir2(emailsDir);
150152
150445
  for (const file of files) {
150153
- const fileStat = await stat6(join35(emailsDir, file));
150446
+ const fileStat = await stat7(join36(emailsDir, file));
150154
150447
  totalSize += fileStat.size;
150155
150448
  }
150156
150449
  } catch {}
150157
150450
  try {
150158
- const attachmentsDir = join35(this.cacheDir, "attachments");
150159
- const dirs = await readdir(attachmentsDir);
150451
+ const attachmentsDir = join36(this.cacheDir, "attachments");
150452
+ const dirs = await readdir2(attachmentsDir);
150160
150453
  for (const dir of dirs) {
150161
- const files = await readdir(join35(attachmentsDir, dir));
150454
+ const files = await readdir2(join36(attachmentsDir, dir));
150162
150455
  for (const file of files) {
150163
- const fileStat = await stat6(join35(attachmentsDir, dir, file));
150456
+ const fileStat = await stat7(join36(attachmentsDir, dir, file));
150164
150457
  totalSize += fileStat.size;
150165
150458
  }
150166
150459
  }
@@ -167751,7 +168044,7 @@ var init_providers = __esm(() => {
167751
168044
  });
167752
168045
 
167753
168046
  // packages/core/src/inbox/inbox-manager.ts
167754
- import { join as join36 } from "path";
168047
+ import { join as join37 } from "path";
167755
168048
 
167756
168049
  class InboxManager {
167757
168050
  assistantId;
@@ -167925,7 +168218,7 @@ class InboxManager {
167925
168218
  }
167926
168219
  }
167927
168220
  function createInboxManager(assistantId, assistantName, config, configDir) {
167928
- const basePath = join36(configDir, "messages");
168221
+ const basePath = join37(configDir, "messages");
167929
168222
  return new InboxManager({
167930
168223
  assistantId,
167931
168224
  assistantName,
@@ -171958,7 +172251,7 @@ var init_local_storage = __esm(async () => {
171958
172251
 
171959
172252
  // packages/core/src/messages/watcher.ts
171960
172253
  import { watch, existsSync as existsSync23, readdirSync as readdirSync9 } from "fs";
171961
- import { join as join37 } from "path";
172254
+ import { join as join38 } from "path";
171962
172255
 
171963
172256
  class InboxWatcher {
171964
172257
  assistantId;
@@ -171970,7 +172263,7 @@ class InboxWatcher {
171970
172263
  constructor(assistantId, basePath) {
171971
172264
  this.assistantId = assistantId;
171972
172265
  const base = basePath || getMessagesBasePath();
171973
- this.inboxPath = join37(base, assistantId, "messages");
172266
+ this.inboxPath = join38(base, assistantId, "messages");
171974
172267
  }
171975
172268
  start() {
171976
172269
  if (this.running)
@@ -172948,7 +173241,7 @@ var init_local_storage2 = __esm(async () => {
172948
173241
 
172949
173242
  // packages/core/src/webhooks/watcher.ts
172950
173243
  import { watch as watch2, existsSync as existsSync25, readdirSync as readdirSync10 } from "fs";
172951
- import { join as join38 } from "path";
173244
+ import { join as join39 } from "path";
172952
173245
 
172953
173246
  class WebhookEventWatcher {
172954
173247
  basePath;
@@ -172960,7 +173253,7 @@ class WebhookEventWatcher {
172960
173253
  directoryWatcher = null;
172961
173254
  constructor(basePath) {
172962
173255
  this.basePath = basePath || getWebhooksBasePath();
172963
- this.eventsPath = join38(this.basePath, "events");
173256
+ this.eventsPath = join39(this.basePath, "events");
172964
173257
  }
172965
173258
  start() {
172966
173259
  if (this.running)
@@ -172999,7 +173292,7 @@ class WebhookEventWatcher {
172999
173292
  this.directoryWatcher = watch2(this.eventsPath, (eventType, filename) => {
173000
173293
  if (!filename || eventType !== "rename")
173001
173294
  return;
173002
- const dirPath = join38(this.eventsPath, filename);
173295
+ const dirPath = join39(this.eventsPath, filename);
173003
173296
  if (existsSync25(dirPath) && !this.watchers.has(filename)) {
173004
173297
  this.watchWebhookDir(filename);
173005
173298
  }
@@ -173025,7 +173318,7 @@ class WebhookEventWatcher {
173025
173318
  watchWebhookDir(webhookId) {
173026
173319
  if (this.watchers.has(webhookId))
173027
173320
  return;
173028
- const dirPath = join38(this.eventsPath, webhookId);
173321
+ const dirPath = join39(this.eventsPath, webhookId);
173029
173322
  if (!existsSync25(dirPath))
173030
173323
  return;
173031
173324
  const known = new Set;
@@ -174392,8 +174685,8 @@ import { spawn as spawn4 } from "child_process";
174392
174685
  import { createInterface } from "readline";
174393
174686
  import * as fs3 from "fs";
174394
174687
  import { stat as statPromise, open as open2 } from "fs/promises";
174395
- import { join as join39 } from "path";
174396
- import { homedir as homedir23 } from "os";
174688
+ import { join as join40 } from "path";
174689
+ import { homedir as homedir24 } from "os";
174397
174690
  import { dirname as dirname14, join as join210 } from "path";
174398
174691
  import { cwd } from "process";
174399
174692
  import { realpathSync as realpathSync2 } from "fs";
@@ -174677,7 +174970,7 @@ function shouldShowDebugMessage(message, filter) {
174677
174970
  return shouldShowDebugCategories(categories, filter);
174678
174971
  }
174679
174972
  function getClaudeConfigHomeDir() {
174680
- return process.env.CLAUDE_CONFIG_DIR ?? join39(homedir23(), ".claude");
174973
+ return process.env.CLAUDE_CONFIG_DIR ?? join40(homedir24(), ".claude");
174681
174974
  }
174682
174975
  function isEnvTruthy(envVar) {
174683
174976
  if (!envVar)
@@ -202013,6 +202306,14 @@ class SessionStore {
202013
202306
  this.db.prepare("DELETE FROM persisted_sessions WHERE id = ?").run(id);
202014
202307
  } catch {}
202015
202308
  }
202309
+ findByLabel(label) {
202310
+ try {
202311
+ const row = this.db.query("SELECT * FROM persisted_sessions WHERE LOWER(label) = LOWER(?) ORDER BY updated_at DESC LIMIT 1").get(label);
202312
+ return row ? rowToSession2(row) : null;
202313
+ } catch {
202314
+ return null;
202315
+ }
202316
+ }
202016
202317
  listRecoverable() {
202017
202318
  try {
202018
202319
  const rows = this.db.query(`SELECT * FROM persisted_sessions WHERE status != 'closed' ORDER BY updated_at DESC`).all();
@@ -203638,9 +203939,9 @@ function createSelfAwarenessToolExecutors(context) {
203638
203939
  return JSON.stringify(response, null, 2);
203639
203940
  },
203640
203941
  workspace_map: async (input) => {
203641
- const { readdir: readdir2, stat: stat7, access } = await import("fs/promises");
203942
+ const { readdir: readdir3, stat: stat8, access } = await import("fs/promises");
203642
203943
  const { execSync } = await import("child_process");
203643
- const { join: join40, basename: basename8 } = await import("path");
203944
+ const { join: join41, basename: basename8 } = await import("path");
203644
203945
  const depth = input.depth ?? 3;
203645
203946
  const includeGitStatus = input.include_git_status !== false;
203646
203947
  const includeRecentFiles = input.include_recent_files !== false;
@@ -203675,7 +203976,7 @@ function createSelfAwarenessToolExecutors(context) {
203675
203976
  if (currentDepth > depth)
203676
203977
  return [];
203677
203978
  try {
203678
- const entries = await readdir2(dir, { withFileTypes: true });
203979
+ const entries = await readdir3(dir, { withFileTypes: true });
203679
203980
  const nodes = [];
203680
203981
  let fileCount = 0;
203681
203982
  for (const entry of entries) {
@@ -203686,7 +203987,7 @@ function createSelfAwarenessToolExecutors(context) {
203686
203987
  break;
203687
203988
  }
203688
203989
  if (entry.isDirectory()) {
203689
- const children2 = await buildTree(join40(dir, entry.name), currentDepth + 1);
203990
+ const children2 = await buildTree(join41(dir, entry.name), currentDepth + 1);
203690
203991
  nodes.push({
203691
203992
  name: entry.name,
203692
203993
  type: "directory",
@@ -203712,7 +204013,7 @@ function createSelfAwarenessToolExecutors(context) {
203712
204013
  };
203713
204014
  if (includeGitStatus) {
203714
204015
  try {
203715
- await access(join40(cwd2, ".git"));
204016
+ await access(join41(cwd2, ".git"));
203716
204017
  gitStatus.isRepo = true;
203717
204018
  try {
203718
204019
  const branch = execSync("git branch --show-current", { cwd: cwd2, encoding: "utf-8" }).trim();
@@ -203739,15 +204040,15 @@ function createSelfAwarenessToolExecutors(context) {
203739
204040
  if (recentFiles.length >= 10)
203740
204041
  return;
203741
204042
  try {
203742
- const entries = await readdir2(dir, { withFileTypes: true });
204043
+ const entries = await readdir3(dir, { withFileTypes: true });
203743
204044
  for (const entry of entries) {
203744
204045
  if (shouldIgnore(entry.name))
203745
204046
  continue;
203746
- const fullPath = join40(dir, entry.name);
204047
+ const fullPath = join41(dir, entry.name);
203747
204048
  const relPath = relativePath ? `${relativePath}/${entry.name}` : entry.name;
203748
204049
  if (entry.isFile()) {
203749
204050
  try {
203750
- const stats = await stat7(fullPath);
204051
+ const stats = await stat8(fullPath);
203751
204052
  recentFiles.push({
203752
204053
  path: relPath,
203753
204054
  mtime: stats.mtime.toISOString()
@@ -203777,12 +204078,12 @@ function createSelfAwarenessToolExecutors(context) {
203777
204078
  let projectName = basename8(cwd2);
203778
204079
  for (const indicator of projectIndicators) {
203779
204080
  try {
203780
- await access(join40(cwd2, indicator.file));
204081
+ await access(join41(cwd2, indicator.file));
203781
204082
  projectType = indicator.type;
203782
204083
  if (indicator.file === "package.json") {
203783
204084
  try {
203784
204085
  const { readFile: readFile10 } = await import("fs/promises");
203785
- const pkg = JSON.parse(await readFile10(join40(cwd2, indicator.file), "utf-8"));
204086
+ const pkg = JSON.parse(await readFile10(join41(cwd2, indicator.file), "utf-8"));
203786
204087
  projectName = pkg.name || projectName;
203787
204088
  } catch {}
203788
204089
  }
@@ -204777,12 +205078,16 @@ function createAssistantToolExecutors2(context) {
204777
205078
  const tools = Array.isArray(input.tools) ? input.tools.map(String) : undefined;
204778
205079
  const contextStr = typeof input.context === "string" ? input.context : undefined;
204779
205080
  const maxTurns = typeof input.maxTurns === "number" ? input.maxTurns : undefined;
205081
+ const minTurns = typeof input.minTurns === "number" ? input.minTurns : undefined;
205082
+ const workUntilDone = input.workUntilDone === true;
204780
205083
  const async = input.async === true;
204781
205084
  const config2 = {
204782
205085
  task,
204783
205086
  tools,
204784
205087
  context: contextStr,
204785
205088
  maxTurns,
205089
+ minTurns,
205090
+ workUntilDone,
204786
205091
  async,
204787
205092
  parentSessionId: context.getSessionId(),
204788
205093
  depth: context.getDepth(),
@@ -205070,7 +205375,15 @@ The subassistant has no memory of the parent conversation - provide all needed c
205070
205375
  },
205071
205376
  maxTurns: {
205072
205377
  type: "number",
205073
- description: "Maximum turns the subassistant can take (default: 10, max: 25)"
205378
+ description: "Maximum turns the subassistant can take (default: 25, max: 50)"
205379
+ },
205380
+ minTurns: {
205381
+ type: "number",
205382
+ description: "Minimum turns the subassistant must take before returning (default: 3). Prevents superficial results."
205383
+ },
205384
+ workUntilDone: {
205385
+ type: "boolean",
205386
+ description: "If true, subassistant keeps working until the task is fully complete instead of returning early (default: false)"
205074
205387
  },
205075
205388
  async: {
205076
205389
  type: "boolean",
@@ -206662,9 +206975,9 @@ var init_types11 = __esm(() => {
206662
206975
  // node_modules/.pnpm/@hasna+mementos@0.3.9_@types+react@19.2.14/node_modules/@hasna/mementos/dist/index.js
206663
206976
  import { Database as Database3 } from "bun:sqlite";
206664
206977
  import { existsSync as existsSync27, mkdirSync as mkdirSync14 } from "fs";
206665
- import { dirname as dirname15, join as join40, resolve as resolve11 } from "path";
206978
+ import { dirname as dirname15, join as join41, resolve as resolve11 } from "path";
206666
206979
  import { existsSync as existsSync28, mkdirSync as mkdirSync24, readFileSync as readFileSync13 } from "fs";
206667
- import { homedir as homedir24 } from "os";
206980
+ import { homedir as homedir25 } from "os";
206668
206981
  import { dirname as dirname22, join as join212, resolve as resolve22 } from "path";
206669
206982
  function isInMemoryDb2(path5) {
206670
206983
  return path5 === ":memory:" || path5.startsWith("file::memory:");
@@ -206672,7 +206985,7 @@ function isInMemoryDb2(path5) {
206672
206985
  function findNearestMementosDb(startDir) {
206673
206986
  let dir = resolve11(startDir);
206674
206987
  while (true) {
206675
- const candidate = join40(dir, ".mementos", "mementos.db");
206988
+ const candidate = join41(dir, ".mementos", "mementos.db");
206676
206989
  if (existsSync27(candidate))
206677
206990
  return candidate;
206678
206991
  const parent = dirname15(dir);
@@ -206685,7 +206998,7 @@ function findNearestMementosDb(startDir) {
206685
206998
  function findGitRoot2(startDir) {
206686
206999
  let dir = resolve11(startDir);
206687
207000
  while (true) {
206688
- if (existsSync27(join40(dir, ".git")))
207001
+ if (existsSync27(join41(dir, ".git")))
206689
207002
  return dir;
206690
207003
  const parent = dirname15(dir);
206691
207004
  if (parent === dir)
@@ -206705,11 +207018,11 @@ function getDbPath2() {
206705
207018
  if (process.env["MEMENTOS_DB_SCOPE"] === "project") {
206706
207019
  const gitRoot = findGitRoot2(cwd2);
206707
207020
  if (gitRoot) {
206708
- return join40(gitRoot, ".mementos", "mementos.db");
207021
+ return join41(gitRoot, ".mementos", "mementos.db");
206709
207022
  }
206710
207023
  }
206711
207024
  const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
206712
- return join40(home, ".mementos", "mementos.db");
207025
+ return join41(home, ".mementos", "mementos.db");
206713
207026
  }
206714
207027
  function ensureDir2(filePath) {
206715
207028
  if (isInMemoryDb2(filePath))
@@ -207017,7 +207330,7 @@ function isValidCategory(value2) {
207017
207330
  return VALID_CATEGORIES2.includes(value2);
207018
207331
  }
207019
207332
  function loadConfig5() {
207020
- const configPath = join212(homedir24(), ".mementos", "config.json");
207333
+ const configPath = join212(homedir25(), ".mementos", "config.json");
207021
207334
  let fileConfig = {};
207022
207335
  if (existsSync28(configPath)) {
207023
207336
  try {
@@ -208188,6 +208501,7 @@ class SubassistantManager {
208188
208501
  maxDepth: config2.maxDepth ?? DEFAULT_MAX_DEPTH,
208189
208502
  maxConcurrent: config2.maxConcurrent ?? DEFAULT_MAX_CONCURRENT,
208190
208503
  maxTurns: config2.maxTurns ?? DEFAULT_MAX_TURNS,
208504
+ minTurns: config2.minTurns ?? DEFAULT_MIN_TURNS,
208191
208505
  defaultTimeoutMs: config2.defaultTimeoutMs ?? DEFAULT_TIMEOUT_MS3,
208192
208506
  defaultTools: config2.defaultTools ?? DEFAULT_SUBASSISTANT_TOOLS,
208193
208507
  forbiddenTools: config2.forbiddenTools ?? FORBIDDEN_SUBASSISTANT_TOOLS
@@ -208315,11 +208629,15 @@ ${hookResult.additionalContext}` : hookResult.additionalContext
208315
208629
  try {
208316
208630
  const tools = this.filterToolsForSubassistant(config2.tools, config2.depth);
208317
208631
  const maxTurns = Math.min(config2.maxTurns ?? this.config.maxTurns, MAX_ALLOWED_TURNS);
208632
+ const minTurns = Math.min(config2.minTurns ?? this.config.minTurns, maxTurns);
208633
+ const workUntilDone = config2.workUntilDone ?? false;
208318
208634
  const runner = await this.context.createSubassistantLoop({
208319
208635
  task: config2.task,
208320
208636
  tools,
208321
208637
  context: config2.context,
208322
208638
  maxTurns,
208639
+ minTurns,
208640
+ workUntilDone,
208323
208641
  cwd: config2.cwd,
208324
208642
  sessionId: `subassistant-${subassistantId}`,
208325
208643
  depth: config2.depth + 1
@@ -208527,7 +208845,7 @@ ${hookResult.additionalContext}` : hookResult.additionalContext
208527
208845
  return new Promise((resolve12) => setTimeout(resolve12, ms));
208528
208846
  }
208529
208847
  }
208530
- var DEFAULT_MAX_DEPTH = 3, DEFAULT_MAX_CONCURRENT = 5, DEFAULT_MAX_TURNS = 10, MAX_ALLOWED_TURNS = 25, DEFAULT_TIMEOUT_MS3 = 120000, DEFAULT_SUBASSISTANT_TOOLS, FORBIDDEN_SUBASSISTANT_TOOLS;
208848
+ var DEFAULT_MAX_DEPTH = 3, DEFAULT_MAX_CONCURRENT = 5, DEFAULT_MAX_TURNS = 25, DEFAULT_MIN_TURNS = 3, MAX_ALLOWED_TURNS = 50, DEFAULT_TIMEOUT_MS3 = 120000, DEFAULT_SUBASSISTANT_TOOLS, FORBIDDEN_SUBASSISTANT_TOOLS;
208531
208849
  var init_subagent_manager = __esm(() => {
208532
208850
  init_src2();
208533
208851
  DEFAULT_SUBASSISTANT_TOOLS = [
@@ -209533,8 +209851,8 @@ __export(exports_dist2, {
209533
209851
  AGENT_TARGETS: () => AGENT_TARGETS
209534
209852
  });
209535
209853
  import { existsSync as existsSync29, cpSync, mkdirSync as mkdirSync15, writeFileSync as writeFileSync10, rmSync as rmSync3, readdirSync as readdirSync12, statSync as statSync7, readFileSync as readFileSync14 } from "fs";
209536
- import { join as join41, dirname as dirname16 } from "path";
209537
- import { homedir as homedir25 } from "os";
209854
+ import { join as join43, dirname as dirname16 } from "path";
209855
+ import { homedir as homedir26 } from "os";
209538
209856
  import { fileURLToPath as fileURLToPath6 } from "url";
209539
209857
  import { existsSync as existsSync210, readFileSync as readFileSync22, readdirSync as readdirSync22 } from "fs";
209540
209858
  import { join as join213 } from "path";
@@ -209642,17 +209960,17 @@ function normalizeSkillName(name) {
209642
209960
  function findSkillsDir() {
209643
209961
  let dir = __dirname2;
209644
209962
  for (let i6 = 0;i6 < 5; i6++) {
209645
- const candidate = join41(dir, "skills");
209963
+ const candidate = join43(dir, "skills");
209646
209964
  if (existsSync29(candidate)) {
209647
209965
  return candidate;
209648
209966
  }
209649
209967
  dir = dirname16(dir);
209650
209968
  }
209651
- return join41(__dirname2, "..", "skills");
209969
+ return join43(__dirname2, "..", "skills");
209652
209970
  }
209653
209971
  function getSkillPath(name) {
209654
209972
  const skillName = normalizeSkillName(name);
209655
- return join41(SKILLS_DIR, skillName);
209973
+ return join43(SKILLS_DIR, skillName);
209656
209974
  }
209657
209975
  function skillExists(name) {
209658
209976
  return existsSync29(getSkillPath(name));
@@ -209661,8 +209979,8 @@ function installSkill(name, options2 = {}) {
209661
209979
  const { targetDir = process.cwd(), overwrite = false } = options2;
209662
209980
  const skillName = normalizeSkillName(name);
209663
209981
  const sourcePath = getSkillPath(name);
209664
- const destDir = join41(targetDir, ".skills");
209665
- const destPath = join41(destDir, skillName);
209982
+ const destDir = join43(targetDir, ".skills");
209983
+ const destPath = join43(destDir, skillName);
209666
209984
  if (!existsSync29(sourcePath)) {
209667
209985
  return {
209668
209986
  skill: name,
@@ -209720,7 +210038,7 @@ function installSkills(names, options2 = {}) {
209720
210038
  return names.map((name) => installSkill(name, options2));
209721
210039
  }
209722
210040
  function updateSkillsIndex(skillsDir) {
209723
- const indexPath = join41(skillsDir, "index.ts");
210041
+ const indexPath = join43(skillsDir, "index.ts");
209724
210042
  const skills = readdirSync12(skillsDir).filter((f5) => f5.startsWith("skill-") && !f5.includes("."));
209725
210043
  const exports = skills.map((s5) => {
209726
210044
  const name = s5.replace("skill-", "").replace(/-/g, "_");
@@ -209737,19 +210055,19 @@ ${exports}
209737
210055
  writeFileSync10(indexPath, content3);
209738
210056
  }
209739
210057
  function getInstalledSkills(targetDir = process.cwd()) {
209740
- const skillsDir = join41(targetDir, ".skills");
210058
+ const skillsDir = join43(targetDir, ".skills");
209741
210059
  if (!existsSync29(skillsDir)) {
209742
210060
  return [];
209743
210061
  }
209744
210062
  return readdirSync12(skillsDir).filter((f5) => {
209745
- const fullPath = join41(skillsDir, f5);
210063
+ const fullPath = join43(skillsDir, f5);
209746
210064
  return f5.startsWith("skill-") && statSync7(fullPath).isDirectory();
209747
210065
  }).map((f5) => f5.replace("skill-", ""));
209748
210066
  }
209749
210067
  function removeSkill(name, targetDir = process.cwd()) {
209750
210068
  const skillName = normalizeSkillName(name);
209751
- const skillsDir = join41(targetDir, ".skills");
209752
- const skillPath = join41(skillsDir, skillName);
210069
+ const skillsDir = join43(targetDir, ".skills");
210070
+ const skillPath = join43(skillsDir, skillName);
209753
210071
  if (!existsSync29(skillPath)) {
209754
210072
  return false;
209755
210073
  }
@@ -209760,13 +210078,13 @@ function removeSkill(name, targetDir = process.cwd()) {
209760
210078
  function getAgentSkillsDir(agent, scope = "global", projectDir) {
209761
210079
  const agentDir = `.${agent}`;
209762
210080
  if (scope === "project") {
209763
- return join41(projectDir || process.cwd(), agentDir, "skills");
210081
+ return join43(projectDir || process.cwd(), agentDir, "skills");
209764
210082
  }
209765
- return join41(homedir25(), agentDir, "skills");
210083
+ return join43(homedir26(), agentDir, "skills");
209766
210084
  }
209767
210085
  function getAgentSkillPath(name, agent, scope = "global", projectDir) {
209768
210086
  const skillName = normalizeSkillName(name);
209769
- return join41(getAgentSkillsDir(agent, scope, projectDir), skillName);
210087
+ return join43(getAgentSkillsDir(agent, scope, projectDir), skillName);
209770
210088
  }
209771
210089
  function installSkillForAgent(name, options2, generateSkillMd) {
209772
210090
  const { agent, scope = "global", projectDir } = options2;
@@ -209776,7 +210094,7 @@ function installSkillForAgent(name, options2, generateSkillMd) {
209776
210094
  return { skill: name, success: false, error: `Skill '${name}' not found` };
209777
210095
  }
209778
210096
  let skillMdContent = null;
209779
- const skillMdPath = join41(sourcePath, "SKILL.md");
210097
+ const skillMdPath = join43(sourcePath, "SKILL.md");
209780
210098
  if (existsSync29(skillMdPath)) {
209781
210099
  skillMdContent = readFileSync14(skillMdPath, "utf-8");
209782
210100
  } else if (generateSkillMd) {
@@ -209788,7 +210106,7 @@ function installSkillForAgent(name, options2, generateSkillMd) {
209788
210106
  const destDir = getAgentSkillPath(name, agent, scope, projectDir);
209789
210107
  try {
209790
210108
  mkdirSync15(destDir, { recursive: true });
209791
- writeFileSync10(join41(destDir, "SKILL.md"), skillMdContent);
210109
+ writeFileSync10(join43(destDir, "SKILL.md"), skillMdContent);
209792
210110
  return { skill: name, success: true, path: destDir };
209793
210111
  } catch (error4) {
209794
210112
  return {
@@ -211694,7 +212012,7 @@ __export(exports_dist3, {
211694
212012
  CATEGORIES: () => CATEGORIES2
211695
212013
  });
211696
212014
  import { existsSync as existsSync31, readFileSync as readFileSync15 } from "fs";
211697
- import { join as join43, dirname as dirname17 } from "path";
212015
+ import { join as join45, dirname as dirname17 } from "path";
211698
212016
  import { fileURLToPath as fileURLToPath7 } from "url";
211699
212017
  import { existsSync as existsSync211, cpSync as cpSync2, mkdirSync as mkdirSync16, readFileSync as readFileSync23, writeFileSync as writeFileSync11, readdirSync as readdirSync13, statSync as statSync8, rmSync as rmSync4 } from "fs";
211700
212018
  import { join as join214, dirname as dirname23 } from "path";
@@ -211715,15 +212033,15 @@ function loadConnectorVersions() {
211715
212033
  versionsLoaded = true;
211716
212034
  const thisDir = dirname17(fileURLToPath7(import.meta.url));
211717
212035
  const candidates = [
211718
- join43(thisDir, "..", "connectors"),
211719
- join43(thisDir, "..", "..", "connectors")
212036
+ join45(thisDir, "..", "connectors"),
212037
+ join45(thisDir, "..", "..", "connectors")
211720
212038
  ];
211721
212039
  const connectorsDir = candidates.find((d5) => existsSync31(d5));
211722
212040
  if (!connectorsDir)
211723
212041
  return;
211724
212042
  for (const connector of CONNECTORS) {
211725
212043
  try {
211726
- const pkgPath = join43(connectorsDir, `connect-${connector.name}`, "package.json");
212044
+ const pkgPath = join45(connectorsDir, `connect-${connector.name}`, "package.json");
211727
212045
  if (existsSync31(pkgPath)) {
211728
212046
  const pkg = JSON.parse(readFileSync15(pkgPath, "utf-8"));
211729
212047
  connector.version = pkg.version || "0.0.0";
@@ -212515,6 +212833,7 @@ var init_loop = __esm(async () => {
212515
212833
  init_wait();
212516
212834
  init_notify();
212517
212835
  init_loader3();
212836
+ init_loader4();
212518
212837
  init_client3();
212519
212838
  init_errors();
212520
212839
  init_limits();
@@ -212599,6 +212918,7 @@ var init_loop = __esm(async () => {
212599
212918
  connectorBridge;
212600
212919
  skillLoader;
212601
212920
  skillExecutor;
212921
+ extensionLoader;
212602
212922
  hookLoader;
212603
212923
  hookExecutor;
212604
212924
  scopeContextManager;
@@ -212678,6 +212998,7 @@ var init_loop = __esm(async () => {
212678
212998
  statsTracker;
212679
212999
  paused = false;
212680
213000
  pauseResolve = null;
213001
+ pendingPermissionMode = null;
212681
213002
  maxTurnsPerRun = 50;
212682
213003
  onChunk;
212683
213004
  onToolStart;
@@ -212699,6 +213020,7 @@ var init_loop = __esm(async () => {
212699
213020
  this.connectorBridge = new ConnectorBridge(this.cwd);
212700
213021
  this.skillLoader = new SkillLoader;
212701
213022
  this.skillExecutor = new SkillExecutor;
213023
+ this.extensionLoader = new ExtensionLoader;
212702
213024
  this.hookLoader = new HookLoader;
212703
213025
  this.hookExecutor = new HookExecutor;
212704
213026
  this.scopeContextManager = new ScopeContextManager;
@@ -213138,6 +213460,9 @@ var init_loop = __esm(async () => {
213138
213460
  }
213139
213461
  this.connectorBridge.registerAll(this.toolRegistry);
213140
213462
  this.builtinCommands.registerAll(this.commandLoader);
213463
+ try {
213464
+ await this.extensionLoader.loadAll(this.cwd, this.toolRegistry, this.commandLoader, this.config);
213465
+ } catch {}
213141
213466
  this.hookLoader.load(hooksConfig);
213142
213467
  const hookCliBridge = new HookCliBridge(this.cwd);
213143
213468
  this.hookExecutor.setCliBridge(hookCliBridge);
@@ -213765,6 +214090,25 @@ You are running in **autonomous mode**. You manage your own wakeup schedule.
213765
214090
  results.push(blockedResult);
213766
214091
  continue;
213767
214092
  }
214093
+ if (this.config?.permissions?.mode === "plan" && !this.isToolAllowedInPlanMode(toolCall.name)) {
214094
+ const blockedResult = {
214095
+ toolCallId: toolCall.id,
214096
+ content: `Blocked in plan mode: "${toolCall.name}" is not available. Only read-only tools are allowed. Switch to normal mode with /mode normal`,
214097
+ isError: true,
214098
+ toolName: toolCall.name
214099
+ };
214100
+ this.emit({ type: "tool_result", toolResult: blockedResult });
214101
+ await this.hookExecutor.execute(this.hookLoader.getHooks("PostToolUseFailure"), {
214102
+ session_id: this.sessionId,
214103
+ hook_event_name: "PostToolUseFailure",
214104
+ cwd: this.cwd,
214105
+ tool_name: toolCall.name,
214106
+ tool_input: toolCall.input,
214107
+ tool_result: blockedResult.content
214108
+ });
214109
+ results.push(blockedResult);
214110
+ continue;
214111
+ }
213768
214112
  if (this.policyEvaluator?.isEnabled()) {
213769
214113
  const policyResult = this.policyEvaluator.evaluateToolUse({
213770
214114
  toolName: toolCall.name,
@@ -214272,7 +214616,9 @@ You are running in **autonomous mode**. You manage your own wakeup schedule.
214272
214616
  this.policyEvaluator.updateConfig({ ...config2, defaultAction: action });
214273
214617
  }
214274
214618
  },
214275
- getSwarmCoordinator: () => this.getOrCreateSwarmCoordinator()
214619
+ getSwarmCoordinator: () => this.getOrCreateSwarmCoordinator(),
214620
+ getPermissionMode: () => this.getPermissionMode(),
214621
+ setPermissionMode: (mode) => this.setPermissionMode(mode)
214276
214622
  };
214277
214623
  const result = await this.commandExecutor.execute(message, context);
214278
214624
  if (!result.handled && result.prompt) {
@@ -215303,6 +215649,14 @@ Current state: ${voiceState.enabled ? "enabled" : "disabled"}, STT: ${voiceState
215303
215649
  let turns = 0;
215304
215650
  let toolCalls = 0;
215305
215651
  let stopped = false;
215652
+ const thoroughnessInstructions = [
215653
+ "Work thoroughly on this task. Don't return after minimal effort.",
215654
+ "Verify your work before completing.",
215655
+ "If the task requires multiple steps, complete ALL steps.",
215656
+ config2.minTurns > 1 ? `You must take at least ${config2.minTurns} turns before returning \u2014 do not give a superficial answer.` : null,
215657
+ config2.workUntilDone ? "Keep working until the task is fully complete. Do not stop early or return partial results." : null
215658
+ ].filter(Boolean).join(`
215659
+ `);
215306
215660
  const subassistant = new AssistantLoop({
215307
215661
  cwd: config2.cwd,
215308
215662
  sessionId: config2.sessionId,
@@ -215317,7 +215671,8 @@ Task: ${config2.task}
215317
215671
  ${config2.context ? `Context:
215318
215672
  ${config2.context}
215319
215673
 
215320
- ` : ""}
215674
+ ` : ""}${thoroughnessInstructions}
215675
+
215321
215676
  Complete this task and provide a clear summary of what you found or accomplished.
215322
215677
  Be concise but thorough. Focus only on this task.`,
215323
215678
  onChunk: (chunk) => {
@@ -215450,12 +215805,42 @@ Be concise but thorough. Focus only on this task.`,
215450
215805
  return true;
215451
215806
  return allowed.has(name.toLowerCase());
215452
215807
  }
215808
+ static PLAN_MODE_ALLOWED_TOOLS = new Set([
215809
+ "read",
215810
+ "glob",
215811
+ "grep",
215812
+ "web_search",
215813
+ "web_fetch",
215814
+ "memory_list",
215815
+ "memory_search",
215816
+ "memory_recall",
215817
+ "memory_context",
215818
+ "memory_stats",
215819
+ "tasks_list",
215820
+ "tasks_get",
215821
+ "ask_user",
215822
+ "diff"
215823
+ ]);
215824
+ isToolAllowedInPlanMode(name) {
215825
+ return AssistantLoop.PLAN_MODE_ALLOWED_TOOLS.has(name.toLowerCase());
215826
+ }
215827
+ setPermissionMode(mode) {
215828
+ if (!this.config)
215829
+ return;
215830
+ if (!this.config.permissions) {
215831
+ this.config.permissions = {};
215832
+ }
215833
+ this.config.permissions.mode = mode;
215834
+ }
215835
+ getPermissionMode() {
215836
+ return this.config?.permissions?.mode ?? "normal";
215837
+ }
215453
215838
  };
215454
215839
  });
215455
215840
 
215456
215841
  // packages/core/src/tools/connector-index.ts
215457
- import { join as join45, dirname as dirname18 } from "path";
215458
- import { homedir as homedir26 } from "os";
215842
+ import { join as join46, dirname as dirname18 } from "path";
215843
+ import { homedir as homedir27 } from "os";
215459
215844
  import { existsSync as existsSync33, mkdirSync as mkdirSync17, writeFileSync as writeFileSync12, readFileSync as readFileSync16 } from "fs";
215460
215845
  var TAG_KEYWORDS, INDEX_VERSION = 1, INDEX_TTL_MS, ConnectorIndex;
215461
215846
  var init_connector_index = __esm(() => {
@@ -215490,10 +215875,10 @@ var init_connector_index = __esm(() => {
215490
215875
  }
215491
215876
  getHomeDir() {
215492
215877
  const envHome = process.env.HOME || process.env.USERPROFILE;
215493
- return envHome && envHome.trim().length > 0 ? envHome : homedir26();
215878
+ return envHome && envHome.trim().length > 0 ? envHome : homedir27();
215494
215879
  }
215495
215880
  getCachePath() {
215496
- return join45(this.getHomeDir(), ".assistants", "cache", "connector-index.json");
215881
+ return join46(this.getHomeDir(), ".assistants", "cache", "connector-index.json");
215497
215882
  }
215498
215883
  loadDiskCache() {
215499
215884
  ConnectorIndex.indexLoaded = true;
@@ -216011,6 +216396,275 @@ var init_search = __esm(() => {
216011
216396
  };
216012
216397
  });
216013
216398
 
216399
+ // packages/core/src/extensions/index.ts
216400
+ var init_extensions = __esm(() => {
216401
+ init_loader4();
216402
+ });
216403
+
216404
+ // packages/core/src/packages/installer.ts
216405
+ import { join as join47 } from "path";
216406
+ import { homedir as homedir28 } from "os";
216407
+ import { mkdir as mkdir9, readFile as readFile10, writeFile as writeFile9, readdir as readdir3, rm as rm4, stat as stat8 } from "fs/promises";
216408
+ function parseSource(source) {
216409
+ if (source.startsWith("npm:")) {
216410
+ return { source: "npm", identifier: source.slice(4) };
216411
+ }
216412
+ if (source.startsWith("git:")) {
216413
+ let url = source.slice(4);
216414
+ if (!url.startsWith("http") && !url.startsWith("git@")) {
216415
+ url = `https://${url}`;
216416
+ }
216417
+ return { source: "git", identifier: url };
216418
+ }
216419
+ return { source: "npm", identifier: source };
216420
+ }
216421
+ function resolvePackagesDir(scope, cwd2) {
216422
+ if (scope === "global") {
216423
+ return join47(homedir28(), ".assistants", "packages");
216424
+ }
216425
+ return join47(cwd2 || process.cwd(), ".assistants", "packages");
216426
+ }
216427
+ async function ensurePackagesDir(dir) {
216428
+ await mkdir9(dir, { recursive: true });
216429
+ const pkgPath = join47(dir, "package.json");
216430
+ try {
216431
+ await stat8(pkgPath);
216432
+ } catch {
216433
+ await writeFile9(pkgPath, JSON.stringify({ name: "assistants-packages", private: true, dependencies: {} }, null, 2) + `
216434
+ `);
216435
+ }
216436
+ const gitignorePath = join47(dir, ".gitignore");
216437
+ try {
216438
+ await stat8(gitignorePath);
216439
+ } catch {
216440
+ await writeFile9(gitignorePath, `node_modules/
216441
+ `);
216442
+ }
216443
+ }
216444
+ function deriveName(source, identifier) {
216445
+ if (source === "npm") {
216446
+ return identifier;
216447
+ }
216448
+ const parts = identifier.replace(/\.git$/, "").split("/");
216449
+ return parts[parts.length - 1] || identifier;
216450
+ }
216451
+ async function installPackage(source, options2) {
216452
+ const { source: srcType, identifier } = parseSource(source);
216453
+ const scope = options2?.local ? "local" : "global";
216454
+ const dir = resolvePackagesDir(scope);
216455
+ if (srcType === "npm") {
216456
+ await ensurePackagesDir(dir);
216457
+ const result2 = Bun.spawnSync(["bun", "add", identifier], {
216458
+ cwd: dir,
216459
+ stdout: "pipe",
216460
+ stderr: "pipe"
216461
+ });
216462
+ if (result2.exitCode !== 0) {
216463
+ const stderr = result2.stderr.toString().trim();
216464
+ throw new Error(`Failed to install ${identifier}: ${stderr || "unknown error"}`);
216465
+ }
216466
+ let version4 = "unknown";
216467
+ try {
216468
+ const pkgJsonPath = join47(dir, "node_modules", identifier, "package.json");
216469
+ const pkgJson = JSON.parse(await readFile10(pkgJsonPath, "utf-8"));
216470
+ version4 = pkgJson.version || "unknown";
216471
+ } catch {}
216472
+ return {
216473
+ name: identifier,
216474
+ source: "npm",
216475
+ version: version4,
216476
+ path: join47(dir, "node_modules", identifier)
216477
+ };
216478
+ }
216479
+ const repoName = deriveName("git", identifier);
216480
+ const targetDir = join47(dir, repoName);
216481
+ await mkdir9(dir, { recursive: true });
216482
+ try {
216483
+ const stats = await stat8(targetDir);
216484
+ if (stats.isDirectory()) {
216485
+ throw new Error(`Package "${repoName}" already exists at ${targetDir}. Remove it first or use update.`);
216486
+ }
216487
+ } catch (err) {
216488
+ if (err instanceof Error && err.message.includes("already exists")) {
216489
+ throw err;
216490
+ }
216491
+ }
216492
+ const result = Bun.spawnSync(["git", "clone", identifier, repoName], {
216493
+ cwd: dir,
216494
+ stdout: "pipe",
216495
+ stderr: "pipe"
216496
+ });
216497
+ if (result.exitCode !== 0) {
216498
+ const stderr = result.stderr.toString().trim();
216499
+ throw new Error(`Failed to clone ${identifier}: ${stderr || "unknown error"}`);
216500
+ }
216501
+ let version3 = "unknown";
216502
+ try {
216503
+ const pkgJson = JSON.parse(await readFile10(join47(targetDir, "package.json"), "utf-8"));
216504
+ version3 = pkgJson.version || "unknown";
216505
+ } catch {}
216506
+ return {
216507
+ name: repoName,
216508
+ source: "git",
216509
+ version: version3,
216510
+ path: targetDir
216511
+ };
216512
+ }
216513
+ async function removePackage(name, options2) {
216514
+ const scope = options2?.local ? "local" : "global";
216515
+ const dir = resolvePackagesDir(scope);
216516
+ const pkgPath = join47(dir, "package.json");
216517
+ let isNpm = false;
216518
+ try {
216519
+ const pkgJson = JSON.parse(await readFile10(pkgPath, "utf-8"));
216520
+ const deps = pkgJson.dependencies || {};
216521
+ if (deps[name]) {
216522
+ isNpm = true;
216523
+ }
216524
+ } catch {}
216525
+ if (isNpm) {
216526
+ const result = Bun.spawnSync(["bun", "remove", name], {
216527
+ cwd: dir,
216528
+ stdout: "pipe",
216529
+ stderr: "pipe"
216530
+ });
216531
+ if (result.exitCode !== 0) {
216532
+ const stderr = result.stderr.toString().trim();
216533
+ throw new Error(`Failed to remove ${name}: ${stderr || "unknown error"}`);
216534
+ }
216535
+ return;
216536
+ }
216537
+ const targetDir = join47(dir, name);
216538
+ try {
216539
+ const stats = await stat8(targetDir);
216540
+ if (stats.isDirectory()) {
216541
+ await rm4(targetDir, { recursive: true, force: true });
216542
+ return;
216543
+ }
216544
+ } catch {}
216545
+ throw new Error(`Package "${name}" not found in ${scope} scope.`);
216546
+ }
216547
+ async function listPackages(options2) {
216548
+ const scope = options2?.local ? "local" : "global";
216549
+ const dir = resolvePackagesDir(scope);
216550
+ const results = [];
216551
+ const pkgPath = join47(dir, "package.json");
216552
+ try {
216553
+ const pkgJson = JSON.parse(await readFile10(pkgPath, "utf-8"));
216554
+ const deps = pkgJson.dependencies || {};
216555
+ for (const [depName, depVersion] of Object.entries(deps)) {
216556
+ results.push({
216557
+ name: depName,
216558
+ source: "npm",
216559
+ version: String(depVersion),
216560
+ path: join47(dir, "node_modules", depName)
216561
+ });
216562
+ }
216563
+ } catch {}
216564
+ try {
216565
+ const entries = await readdir3(dir);
216566
+ for (const entry of entries) {
216567
+ if (entry === "node_modules" || entry.startsWith(".") || entry === "package.json" || entry === "bun.lockb" || entry === "bun.lock") {
216568
+ continue;
216569
+ }
216570
+ const entryPath = join47(dir, entry);
216571
+ try {
216572
+ const stats = await stat8(entryPath);
216573
+ if (!stats.isDirectory())
216574
+ continue;
216575
+ } catch {
216576
+ continue;
216577
+ }
216578
+ try {
216579
+ await stat8(join47(entryPath, ".git"));
216580
+ } catch {
216581
+ continue;
216582
+ }
216583
+ let version3 = "unknown";
216584
+ try {
216585
+ const pkgJson = JSON.parse(await readFile10(join47(entryPath, "package.json"), "utf-8"));
216586
+ version3 = pkgJson.version || "unknown";
216587
+ } catch {}
216588
+ results.push({
216589
+ name: entry,
216590
+ source: "git",
216591
+ version: version3,
216592
+ path: entryPath
216593
+ });
216594
+ }
216595
+ } catch {}
216596
+ return results;
216597
+ }
216598
+ async function updatePackages(options2) {
216599
+ const scope = options2?.local ? "local" : "global";
216600
+ const dir = resolvePackagesDir(scope);
216601
+ const updated = [];
216602
+ const errors5 = [];
216603
+ const pkgPath = join47(dir, "package.json");
216604
+ try {
216605
+ const pkgJson = JSON.parse(await readFile10(pkgPath, "utf-8"));
216606
+ const deps = pkgJson.dependencies || {};
216607
+ if (Object.keys(deps).length > 0) {
216608
+ const result = Bun.spawnSync(["bun", "update"], {
216609
+ cwd: dir,
216610
+ stdout: "pipe",
216611
+ stderr: "pipe"
216612
+ });
216613
+ if (result.exitCode === 0) {
216614
+ for (const name of Object.keys(deps)) {
216615
+ updated.push(name);
216616
+ }
216617
+ } else {
216618
+ const stderr = result.stderr.toString().trim();
216619
+ errors5.push(`npm update failed: ${stderr || "unknown error"}`);
216620
+ }
216621
+ }
216622
+ } catch {}
216623
+ try {
216624
+ const entries = await readdir3(dir);
216625
+ for (const entry of entries) {
216626
+ if (entry === "node_modules" || entry.startsWith(".") || entry === "package.json" || entry === "bun.lockb" || entry === "bun.lock") {
216627
+ continue;
216628
+ }
216629
+ const entryPath = join47(dir, entry);
216630
+ try {
216631
+ await stat8(join47(entryPath, ".git"));
216632
+ } catch {
216633
+ continue;
216634
+ }
216635
+ const result = Bun.spawnSync(["git", "pull"], {
216636
+ cwd: entryPath,
216637
+ stdout: "pipe",
216638
+ stderr: "pipe"
216639
+ });
216640
+ if (result.exitCode === 0) {
216641
+ updated.push(entry);
216642
+ } else {
216643
+ const stderr = result.stderr.toString().trim();
216644
+ errors5.push(`${entry}: git pull failed: ${stderr || "unknown error"}`);
216645
+ }
216646
+ }
216647
+ } catch {}
216648
+ return { updated, errors: errors5 };
216649
+ }
216650
+ var PackageInstaller;
216651
+ var init_installer2 = __esm(() => {
216652
+ PackageInstaller = {
216653
+ parseSource,
216654
+ resolvePackagesDir,
216655
+ installPackage,
216656
+ removePackage,
216657
+ listPackages,
216658
+ updatePackages
216659
+ };
216660
+ });
216661
+
216662
+ // packages/core/src/packages/index.ts
216663
+ var init_packages = __esm(() => {
216664
+ init_installer2();
216665
+ init_installer2();
216666
+ });
216667
+
216014
216668
  // packages/core/src/interviews/store.ts
216015
216669
  class InterviewStore {
216016
216670
  db;
@@ -216096,14 +216750,14 @@ var init_interviews = __esm(async () => {
216096
216750
  });
216097
216751
 
216098
216752
  // packages/core/src/memory/sessions.ts
216099
- import { join as join46, dirname as dirname19 } from "path";
216753
+ import { join as join48, dirname as dirname19 } from "path";
216100
216754
  import { existsSync as existsSync35, mkdirSync as mkdirSync18 } from "fs";
216101
216755
 
216102
216756
  class SessionManager {
216103
216757
  db;
216104
216758
  constructor(dbPath, assistantId) {
216105
216759
  const baseDir = getConfigDir();
216106
- const path5 = dbPath || (assistantId ? join46(baseDir, "assistants", assistantId, "memory.db") : join46(baseDir, "memory.db"));
216760
+ const path5 = dbPath || (assistantId ? join48(baseDir, "assistants", assistantId, "memory.db") : join48(baseDir, "memory.db"));
216107
216761
  const dir = dirname19(path5);
216108
216762
  if (!existsSync35(dir)) {
216109
216763
  mkdirSync18(dir, { recursive: true });
@@ -216761,6 +217415,7 @@ __export(exports_src3, {
216761
217415
  updateTask: () => updateTask2,
216762
217416
  updateSchedule: () => updateSchedule,
216763
217417
  updateProject: () => updateProject,
217418
+ updatePackages: () => updatePackages,
216764
217419
  updateJob: () => updateJob,
216765
217420
  twilioToElevenLabs: () => twilioToElevenLabs,
216766
217421
  toolsSearchTool: () => toolsSearchTool,
@@ -216832,6 +217487,7 @@ __export(exports_src3, {
216832
217487
  resourceLimitsTool: () => resourceLimitsTool,
216833
217488
  resolveWorkspaceBaseDir: () => resolveWorkspaceBaseDir,
216834
217489
  resolveTaskId: () => resolveTaskId,
217490
+ resolvePackagesDir: () => resolvePackagesDir,
216835
217491
  resolveNameToKnown: () => resolveNameToKnown,
216836
217492
  resolveMentions: () => resolveMentions,
216837
217493
  resolveHeartbeatPersistPath: () => resolveHeartbeatPersistPath,
@@ -216841,6 +217497,7 @@ __export(exports_src3, {
216841
217497
  resetGlobalCapabilityStorage: () => resetGlobalCapabilityStorage,
216842
217498
  resetGlobalCapabilityEnforcer: () => resetGlobalCapabilityEnforcer,
216843
217499
  resetDatabaseSingleton: () => resetDatabaseSingleton,
217500
+ removePackage: () => removePackage,
216844
217501
  registryStatsTool: () => registryStatsTool,
216845
217502
  registryQueryTool: () => registryQueryTool,
216846
217503
  registryListTool: () => registryListTool,
@@ -216894,6 +217551,7 @@ __export(exports_src3, {
216894
217551
  peopleDeleteTool: () => peopleDeleteTool,
216895
217552
  peopleCreateTool: () => peopleCreateTool,
216896
217553
  pcmToMulaw: () => pcmToMulaw,
217554
+ parseSource: () => parseSource,
216897
217555
  parseMentions: () => parseMentions,
216898
217556
  parseCronExpression: () => parseCronExpression,
216899
217557
  ordersUpdateTool: () => ordersUpdateTool,
@@ -216937,6 +217595,7 @@ __export(exports_src3, {
216937
217595
  listTemplates: () => listTemplates,
216938
217596
  listSchedules: () => listSchedules,
216939
217597
  listProjects: () => listProjects,
217598
+ listPackages: () => listPackages,
216940
217599
  listJobsForSession: () => listJobsForSession,
216941
217600
  listJobsByStatus: () => listJobsByStatus,
216942
217601
  listJobs: () => listJobs,
@@ -216963,6 +217622,7 @@ __export(exports_src3, {
216963
217622
  isAssistantError: () => isAssistantError,
216964
217623
  isAnyLLMConfigured: () => isAnyLLMConfigured,
216965
217624
  isAWSConfigured: () => isAWSConfigured,
217625
+ installPackage: () => installPackage,
216966
217626
  installHeartbeatSkills: () => installHeartbeatSkills,
216967
217627
  initAssistantsDir: () => initAssistantsDir,
216968
217628
  inboxTools: () => inboxTools,
@@ -217242,6 +217902,7 @@ __export(exports_src3, {
217242
217902
  PolicyEvaluator: () => PolicyEvaluator,
217243
217903
  PeopleStore: () => PeopleStore,
217244
217904
  PeopleManager: () => PeopleManager,
217905
+ PackageInstaller: () => PackageInstaller,
217245
217906
  PRIORITY_ORDER: () => PRIORITY_ORDER,
217246
217907
  POLICY_SCOPE_PRECEDENCE: () => POLICY_SCOPE_PRECEDENCE,
217247
217908
  PERMISSIVE_POLICY: () => PERMISSIVE_POLICY,
@@ -217285,6 +217946,7 @@ __export(exports_src3, {
217285
217946
  GlobalMemoryManager: () => GlobalMemoryManager,
217286
217947
  FilesystemTools: () => FilesystemTools,
217287
217948
  FeedbackTool: () => FeedbackTool,
217949
+ ExtensionLoader: () => ExtensionLoader,
217288
217950
  ErrorCodes: () => ErrorCodes,
217289
217951
  ErrorAggregator: () => ErrorAggregator,
217290
217952
  EmbeddedClient: () => EmbeddedClient,
@@ -217370,6 +218032,9 @@ var init_src3 = __esm(async () => {
217370
218032
  init_agent_registry();
217371
218033
  init_capabilities();
217372
218034
  init_swarm2();
218035
+ init_extensions();
218036
+ init_packages();
218037
+ init_packages();
217373
218038
  init_loader3();
217374
218039
  init_create();
217375
218040
  init_installer();
@@ -236887,7 +237552,7 @@ var require_filesystem = __commonJS((exports, module) => {
236887
237552
  fs7.close(fd, () => {});
236888
237553
  return buffer.subarray(0, bytesRead);
236889
237554
  };
236890
- var readFile10 = (path5) => new Promise((resolve12, reject) => {
237555
+ var readFile11 = (path5) => new Promise((resolve12, reject) => {
236891
237556
  fs7.open(path5, "r", (err, fd) => {
236892
237557
  if (err) {
236893
237558
  reject(err);
@@ -236904,7 +237569,7 @@ var require_filesystem = __commonJS((exports, module) => {
236904
237569
  LDD_PATH,
236905
237570
  SELF_PATH,
236906
237571
  readFileSync: readFileSync18,
236907
- readFile: readFile10
237572
+ readFile: readFile11
236908
237573
  };
236909
237574
  });
236910
237575
 
@@ -236946,7 +237611,7 @@ var require_elf = __commonJS((exports, module) => {
236946
237611
  var require_detect_libc = __commonJS((exports, module) => {
236947
237612
  var childProcess = __require("child_process");
236948
237613
  var { isLinux: isLinux2, getReport } = require_process();
236949
- var { LDD_PATH, SELF_PATH, readFile: readFile10, readFileSync: readFileSync18 } = require_filesystem();
237614
+ var { LDD_PATH, SELF_PATH, readFile: readFile11, readFileSync: readFileSync18 } = require_filesystem();
236950
237615
  var { interpreterPath } = require_elf();
236951
237616
  var cachedFamilyInterpreter;
236952
237617
  var cachedFamilyFilesystem;
@@ -237026,7 +237691,7 @@ var require_detect_libc = __commonJS((exports, module) => {
237026
237691
  }
237027
237692
  cachedFamilyFilesystem = null;
237028
237693
  try {
237029
- const lddContent = await readFile10(LDD_PATH);
237694
+ const lddContent = await readFile11(LDD_PATH);
237030
237695
  cachedFamilyFilesystem = getFamilyFromLddContent(lddContent);
237031
237696
  } catch (e5) {}
237032
237697
  return cachedFamilyFilesystem;
@@ -237048,7 +237713,7 @@ var require_detect_libc = __commonJS((exports, module) => {
237048
237713
  }
237049
237714
  cachedFamilyInterpreter = null;
237050
237715
  try {
237051
- const selfContent = await readFile10(SELF_PATH);
237716
+ const selfContent = await readFile11(SELF_PATH);
237052
237717
  const path5 = interpreterPath(selfContent);
237053
237718
  cachedFamilyInterpreter = familyFromInterpreterPath(path5);
237054
237719
  } catch (e5) {}
@@ -237108,7 +237773,7 @@ var require_detect_libc = __commonJS((exports, module) => {
237108
237773
  }
237109
237774
  cachedVersionFilesystem = null;
237110
237775
  try {
237111
- const lddContent = await readFile10(LDD_PATH);
237776
+ const lddContent = await readFile11(LDD_PATH);
237112
237777
  const versionMatch = lddContent.match(RE_GLIBC_VERSION);
237113
237778
  if (versionMatch) {
237114
237779
  cachedVersionFilesystem = versionMatch[1];
@@ -243474,15 +244139,15 @@ var require_windows = __commonJS((exports, module) => {
243474
244139
  }
243475
244140
  return false;
243476
244141
  }
243477
- function checkStat(stat7, path5, options2) {
243478
- if (!stat7.isSymbolicLink() && !stat7.isFile()) {
244142
+ function checkStat(stat9, path5, options2) {
244143
+ if (!stat9.isSymbolicLink() && !stat9.isFile()) {
243479
244144
  return false;
243480
244145
  }
243481
244146
  return checkPathExt(path5, options2);
243482
244147
  }
243483
244148
  function isexe(path5, options2, cb2) {
243484
- fs7.stat(path5, function(er, stat7) {
243485
- cb2(er, er ? false : checkStat(stat7, path5, options2));
244149
+ fs7.stat(path5, function(er, stat9) {
244150
+ cb2(er, er ? false : checkStat(stat9, path5, options2));
243486
244151
  });
243487
244152
  }
243488
244153
  function sync(path5, options2) {
@@ -243496,20 +244161,20 @@ var require_mode = __commonJS((exports, module) => {
243496
244161
  isexe.sync = sync;
243497
244162
  var fs7 = __require("fs");
243498
244163
  function isexe(path5, options2, cb2) {
243499
- fs7.stat(path5, function(er, stat7) {
243500
- cb2(er, er ? false : checkStat(stat7, options2));
244164
+ fs7.stat(path5, function(er, stat9) {
244165
+ cb2(er, er ? false : checkStat(stat9, options2));
243501
244166
  });
243502
244167
  }
243503
244168
  function sync(path5, options2) {
243504
244169
  return checkStat(fs7.statSync(path5), options2);
243505
244170
  }
243506
- function checkStat(stat7, options2) {
243507
- return stat7.isFile() && checkMode(stat7, options2);
244171
+ function checkStat(stat9, options2) {
244172
+ return stat9.isFile() && checkMode(stat9, options2);
243508
244173
  }
243509
- function checkMode(stat7, options2) {
243510
- var mod = stat7.mode;
243511
- var uid = stat7.uid;
243512
- var gid = stat7.gid;
244174
+ function checkMode(stat9, options2) {
244175
+ var mod = stat9.mode;
244176
+ var uid = stat9.uid;
244177
+ var gid = stat9.gid;
243513
244178
  var myUid = options2.uid !== undefined ? options2.uid : process.getuid && process.getuid();
243514
244179
  var myGid = options2.gid !== undefined ? options2.gid : process.getgid && process.getgid();
243515
244180
  var u5 = parseInt("100", 8);
@@ -258419,8 +259084,8 @@ await __promiseAll([
258419
259084
  ]);
258420
259085
  var import_react86 = __toESM(require_react(), 1);
258421
259086
  import { spawn as spawn6 } from "child_process";
258422
- import { join as join48 } from "path";
258423
- import { homedir as homedir27 } from "os";
259087
+ import { join as join50 } from "path";
259088
+ import { homedir as homedir29 } from "os";
258424
259089
 
258425
259090
  // packages/terminal/src/components/Input.tsx
258426
259091
  await init_build2();
@@ -289795,7 +290460,7 @@ function handleHistory(query2) {
289795
290460
  ${lines.join(`
289796
290461
  `)}
289797
290462
 
289798
- Resume with: \`assistants --resume <id>\``);
290463
+ Resume with: \`assistants --resume <id or name>\``);
289799
290464
  }
289800
290465
  function handleTemplates() {
289801
290466
  const templates = [
@@ -289848,7 +290513,11 @@ function printExitSummary(stats) {
289848
290513
  const lines = [];
289849
290514
  lines.push("");
289850
290515
  lines.push(`\x1B[1mResume this session:\x1B[0m`);
289851
- lines.push(` assistants --resume ${stats.sessionId}`);
290516
+ if (stats.sessionLabel) {
290517
+ lines.push(` assistants --resume ${stats.sessionLabel}`);
290518
+ } else {
290519
+ lines.push(` assistants --resume ${stats.sessionId}`);
290520
+ }
289852
290521
  lines.push("");
289853
290522
  const durationLabel = "Total duration (wall):";
289854
290523
  const messagesLabel = "Total messages:";
@@ -289888,8 +290557,8 @@ await init_src3();
289888
290557
  // packages/terminal/src/lib/budgets.ts
289889
290558
  init_src2();
289890
290559
  await init_src3();
289891
- import { join as join47 } from "path";
289892
- import { mkdir as mkdir9, readFile as readFile10, writeFile as writeFile9 } from "fs/promises";
290560
+ import { join as join49 } from "path";
290561
+ import { mkdir as mkdir10, readFile as readFile11, writeFile as writeFile10 } from "fs/promises";
289893
290562
  var PROFILES_FILE = "budgets.json";
289894
290563
  var SESSION_MAP_FILE = "budget-sessions.json";
289895
290564
  var DEFAULT_PROFILE_ID = "default";
@@ -289897,22 +290566,22 @@ function cloneConfig2(config2) {
289897
290566
  return JSON.parse(JSON.stringify(config2 || DEFAULT_BUDGET_CONFIG));
289898
290567
  }
289899
290568
  async function ensureDir3(baseDir) {
289900
- await mkdir9(baseDir, { recursive: true });
290569
+ await mkdir10(baseDir, { recursive: true });
289901
290570
  }
289902
290571
  async function readJsonFile2(path7) {
289903
290572
  try {
289904
- const raw = await readFile10(path7, "utf-8");
290573
+ const raw = await readFile11(path7, "utf-8");
289905
290574
  return JSON.parse(raw);
289906
290575
  } catch {
289907
290576
  return null;
289908
290577
  }
289909
290578
  }
289910
290579
  async function writeJsonFile(path7, data) {
289911
- await writeFile9(path7, JSON.stringify(data, null, 2), "utf-8");
290580
+ await writeFile10(path7, JSON.stringify(data, null, 2), "utf-8");
289912
290581
  }
289913
290582
  async function loadBudgetProfiles(baseDir, seedConfig) {
289914
290583
  await ensureDir3(baseDir);
289915
- const path7 = join47(baseDir, PROFILES_FILE);
290584
+ const path7 = join49(baseDir, PROFILES_FILE);
289916
290585
  const data = await readJsonFile2(path7);
289917
290586
  const profiles = Array.isArray(data?.profiles) ? data.profiles : [];
289918
290587
  if (profiles.length === 0) {
@@ -289932,7 +290601,7 @@ async function loadBudgetProfiles(baseDir, seedConfig) {
289932
290601
  }
289933
290602
  async function saveBudgetProfiles(baseDir, profiles) {
289934
290603
  await ensureDir3(baseDir);
289935
- const path7 = join47(baseDir, PROFILES_FILE);
290604
+ const path7 = join49(baseDir, PROFILES_FILE);
289936
290605
  await writeJsonFile(path7, { profiles });
289937
290606
  }
289938
290607
  async function createBudgetProfile(baseDir, name, config2, description) {
@@ -289970,13 +290639,13 @@ async function deleteBudgetProfile(baseDir, id) {
289970
290639
  }
289971
290640
  async function loadSessionBudgetMap(baseDir) {
289972
290641
  await ensureDir3(baseDir);
289973
- const path7 = join47(baseDir, SESSION_MAP_FILE);
290642
+ const path7 = join49(baseDir, SESSION_MAP_FILE);
289974
290643
  const data = await readJsonFile2(path7);
289975
290644
  return data || {};
289976
290645
  }
289977
290646
  async function saveSessionBudgetMap(baseDir, map3) {
289978
290647
  await ensureDir3(baseDir);
289979
- const path7 = join47(baseDir, SESSION_MAP_FILE);
290648
+ const path7 = join49(baseDir, SESSION_MAP_FILE);
289980
290649
  await writeJsonFile(path7, map3);
289981
290650
  }
289982
290651
 
@@ -290135,7 +290804,7 @@ function CloseOnAnyKeyPanel({ message, onClose }) {
290135
290804
  ]
290136
290805
  }, undefined, true, undefined, this);
290137
290806
  }
290138
- function App2({ cwd: cwd3, version: version4 }) {
290807
+ function App2({ cwd: cwd3, version: version4, permissionMode: initialPermissionMode }) {
290139
290808
  const { exit: exit3 } = use_app_default();
290140
290809
  const { stdout } = use_stdout_default();
290141
290810
  const rows = stdout?.rows ?? 24;
@@ -291008,6 +291677,10 @@ function App2({ cwd: cwd3, version: version4 }) {
291008
291677
  const profiles = budgetProfiles.length > 0 ? budgetProfiles : await loadBudgetData();
291009
291678
  const profileId = getSessionBudgetProfileId(newSession.id, profiles);
291010
291679
  await applyBudgetProfileToSession(newSession, profileId, profiles);
291680
+ if (initialPermissionMode) {
291681
+ const loop = newSession.client.getAssistantLoop?.();
291682
+ loop?.setPermissionMode(initialPermissionMode);
291683
+ }
291011
291684
  return newSession;
291012
291685
  }, [
291013
291686
  registry3,
@@ -291020,7 +291693,8 @@ function App2({ cwd: cwd3, version: version4 }) {
291020
291693
  budgetProfiles,
291021
291694
  loadBudgetData,
291022
291695
  getSessionBudgetProfileId,
291023
- applyBudgetProfileToSession
291696
+ applyBudgetProfileToSession,
291697
+ initialPermissionMode
291024
291698
  ]);
291025
291699
  const seedSessionState = import_react86.useCallback((sessionId, seededMessages) => {
291026
291700
  sessionUIStates.current.set(sessionId, {
@@ -291324,6 +291998,7 @@ function App2({ cwd: cwd3, version: version4 }) {
291324
291998
  if (active) {
291325
291999
  setExitStats({
291326
292000
  sessionId: active.id,
292001
+ sessionLabel: active.label,
291327
292002
  startedAt: active.startedAt,
291328
292003
  tokenUsage: tokenUsageRef.current,
291329
292004
  messageCount: messagesLengthRef.current,
@@ -291661,12 +292336,12 @@ function App2({ cwd: cwd3, version: version4 }) {
291661
292336
  try {
291662
292337
  const config2 = await loadConfig(cwd3, workspaceBaseDir);
291663
292338
  setCurrentConfig(config2);
291664
- const { readFile: readFile11, access } = await import("fs/promises");
292339
+ const { readFile: readFile12, access } = await import("fs/promises");
291665
292340
  const configBaseDir = workspaceBaseDir || getConfigDir();
291666
292341
  const userPath = `${configBaseDir}/config.json`;
291667
292342
  try {
291668
292343
  await access(userPath);
291669
- const content3 = await readFile11(userPath, "utf-8");
292344
+ const content3 = await readFile12(userPath, "utf-8");
291670
292345
  setUserConfig(JSON.parse(content3));
291671
292346
  } catch {
291672
292347
  setUserConfig(null);
@@ -291674,7 +292349,7 @@ function App2({ cwd: cwd3, version: version4 }) {
291674
292349
  const projectPath = `${getProjectConfigDir(cwd3)}/config.json`;
291675
292350
  try {
291676
292351
  await access(projectPath);
291677
- const content3 = await readFile11(projectPath, "utf-8");
292352
+ const content3 = await readFile12(projectPath, "utf-8");
291678
292353
  setProjectConfig(JSON.parse(content3));
291679
292354
  } catch {
291680
292355
  setProjectConfig(null);
@@ -291682,7 +292357,7 @@ function App2({ cwd: cwd3, version: version4 }) {
291682
292357
  const localPath = `${getProjectConfigDir(cwd3)}/config.local.json`;
291683
292358
  try {
291684
292359
  await access(localPath);
291685
- const content3 = await readFile11(localPath, "utf-8");
292360
+ const content3 = await readFile12(localPath, "utf-8");
291686
292361
  setLocalConfig(JSON.parse(content3));
291687
292362
  } catch {
291688
292363
  setLocalConfig(null);
@@ -291784,7 +292459,7 @@ function App2({ cwd: cwd3, version: version4 }) {
291784
292459
  }, [recoverableSessions, createSessionFromRecovery, workspaceBaseDir]);
291785
292460
  const handleOnboardingComplete = import_react86.useCallback(async (result) => {
291786
292461
  const { existsSync: existsSync30, mkdirSync: mkdirSync19, readFileSync: readFileSync18, writeFileSync: writeFileSync13, appendFileSync: appendFileSync5 } = await import("fs");
291787
- const secretsPath = join48(homedir27(), ".secrets");
292462
+ const secretsPath = join50(homedir29(), ".secrets");
291788
292463
  const providerInfo = getProviderInfo(result.provider);
291789
292464
  const envName = providerInfo?.apiKeyEnv || "ANTHROPIC_API_KEY";
291790
292465
  const keyExport = `export ${envName}="${result.apiKey}"`;
@@ -291818,7 +292493,7 @@ function App2({ cwd: cwd3, version: version4 }) {
291818
292493
  if (!existsSync30(configDir)) {
291819
292494
  mkdirSync19(configDir, { recursive: true });
291820
292495
  }
291821
- const configPath = join48(configDir, "config.json");
292496
+ const configPath = join50(configDir, "config.json");
291822
292497
  let existingConfig = {};
291823
292498
  if (existsSync30(configPath)) {
291824
292499
  try {
@@ -291874,7 +292549,7 @@ function App2({ cwd: cwd3, version: version4 }) {
291874
292549
  if (isOnboardingCompleted()) {
291875
292550
  needsOnboarding = false;
291876
292551
  } else {
291877
- const configPath = join48(workspaceBaseDir || getConfigDir(), "config.json");
292552
+ const configPath = join50(workspaceBaseDir || getConfigDir(), "config.json");
291878
292553
  const { existsSync: existsSync30, readFileSync: readFileSync18 } = await import("fs");
291879
292554
  if (!existsSync30(configPath)) {
291880
292555
  needsOnboarding = true;
@@ -292148,6 +292823,7 @@ function App2({ cwd: cwd3, version: version4 }) {
292148
292823
  if (active) {
292149
292824
  setExitStats({
292150
292825
  sessionId: active.id,
292826
+ sessionLabel: active.label,
292151
292827
  startedAt: active.startedAt,
292152
292828
  tokenUsage,
292153
292829
  messageCount: messages2.length,
@@ -294146,7 +294822,7 @@ When done, report the result.`);
294146
294822
  }
294147
294823
  if (showConfigPanel && currentConfig) {
294148
294824
  const handleConfigSave = async (location, updates) => {
294149
- const { writeFile: writeFile10, mkdir: mkdir10 } = await import("fs/promises");
294825
+ const { writeFile: writeFile11, mkdir: mkdir11 } = await import("fs/promises");
294150
294826
  const { dirname: dirname21 } = await import("path");
294151
294827
  let configPath;
294152
294828
  let existingConfig;
@@ -294165,8 +294841,8 @@ When done, report the result.`);
294165
294841
  break;
294166
294842
  }
294167
294843
  const newConfig = deepMerge3(existingConfig || {}, updates);
294168
- await mkdir10(dirname21(configPath), { recursive: true });
294169
- await writeFile10(configPath, JSON.stringify(newConfig, null, 2));
294844
+ await mkdir11(dirname21(configPath), { recursive: true });
294845
+ await writeFile11(configPath, JSON.stringify(newConfig, null, 2));
294170
294846
  await loadConfigFiles();
294171
294847
  };
294172
294848
  return /* @__PURE__ */ jsx_dev_runtime51.jsxDEV(Box_default, {
@@ -294658,11 +295334,20 @@ async function runHeadless(options2) {
294658
295334
  } = options2;
294659
295335
  let sessionData = null;
294660
295336
  if (resume) {
294661
- const data = SessionStorage.loadSession(resume);
295337
+ let resolvedId = resume;
295338
+ let data = SessionStorage.loadSession(resume);
294662
295339
  if (!data) {
294663
- throw new Error(`Session ${resume} not found`);
295340
+ const store2 = new SessionStore;
295341
+ const match = store2.findByLabel(resume);
295342
+ if (match) {
295343
+ resolvedId = match.id;
295344
+ data = SessionStorage.loadSession(match.id);
295345
+ }
294664
295346
  }
294665
- sessionData = { id: resume, data };
295347
+ if (!data) {
295348
+ throw new Error(`Session "${resume}" not found (tried ID and label lookup)`);
295349
+ }
295350
+ sessionData = { id: resolvedId, data };
294666
295351
  } else if (shouldContinue) {
294667
295352
  const latest = SessionStorage.getLatestSession();
294668
295353
  if (latest) {
@@ -294680,6 +295365,10 @@ async function runHeadless(options2) {
294680
295365
  allowedTools: options2.allowedTools,
294681
295366
  startedAt: sessionData?.data?.startedAt
294682
295367
  });
295368
+ if (options2.permissionMode) {
295369
+ const loop = client.getAssistantLoop?.();
295370
+ loop?.setPermissionMode(options2.permissionMode);
295371
+ }
294683
295372
  let result = "";
294684
295373
  const toolCalls = [];
294685
295374
  let hadError = false;
@@ -294859,6 +295548,7 @@ function parseArgs(argv) {
294859
295548
  continue: false,
294860
295549
  resume: null,
294861
295550
  cwdProvided: false,
295551
+ permissionMode: null,
294862
295552
  errors: []
294863
295553
  };
294864
295554
  let endOfOptions = false;
@@ -294962,7 +295652,7 @@ function parseArgs(argv) {
294962
295652
  if (arg === "--resume" || arg === "-r") {
294963
295653
  const nextArg = args[i6 + 1];
294964
295654
  if (nextArg === undefined || isFlag(nextArg)) {
294965
- options2.errors.push(`${arg} requires a session ID`);
295655
+ options2.errors.push(`${arg} requires a session ID or name`);
294966
295656
  } else {
294967
295657
  options2.resume = nextArg;
294968
295658
  i6++;
@@ -294980,6 +295670,27 @@ function parseArgs(argv) {
294980
295670
  }
294981
295671
  continue;
294982
295672
  }
295673
+ if (arg === "--permission-mode" || arg === "--mode") {
295674
+ const nextArg = args[i6 + 1];
295675
+ if (nextArg === undefined || isFlag(nextArg)) {
295676
+ options2.errors.push(`${arg} requires a value (normal, plan, or auto-accept)`);
295677
+ } else {
295678
+ const modeMap = {
295679
+ normal: "normal",
295680
+ plan: "plan",
295681
+ auto: "auto-accept",
295682
+ "auto-accept": "auto-accept"
295683
+ };
295684
+ const mode = modeMap[nextArg.toLowerCase()];
295685
+ if (!mode) {
295686
+ options2.errors.push(`Invalid permission mode "${nextArg}". Valid options: normal, plan, auto-accept`);
295687
+ } else {
295688
+ options2.permissionMode = mode;
295689
+ }
295690
+ i6++;
295691
+ }
295692
+ continue;
295693
+ }
294983
295694
  if (!arg.startsWith("-")) {
294984
295695
  positionalArgs.push(arg);
294985
295696
  }
@@ -295027,8 +295738,9 @@ Headless Mode:
295027
295738
  --json-schema <schema> JSON Schema for structured output (use with --output-format json)
295028
295739
  --headless-timeout-ms <ms> Abort headless run after the given timeout (ms)
295029
295740
  -c, --continue Continue the most recent conversation
295030
- -r, --resume <session_id> Resume a specific session by ID
295741
+ -r, --resume <id_or_name> Resume a session by ID or name
295031
295742
  --cwd <path> Set working directory
295743
+ --permission-mode <mode> Permission mode: normal, plan (read-only), auto-accept
295032
295744
 
295033
295745
  Examples:
295034
295746
  # Ask a question
@@ -295106,7 +295818,7 @@ process.on("unhandledRejection", (reason) => {
295106
295818
  cleanup();
295107
295819
  process.exit(1);
295108
295820
  });
295109
- var VERSION4 = "1.1.86";
295821
+ var VERSION4 = "1.1.87";
295110
295822
  var SYNC_START = "\x1B[?2026h";
295111
295823
  var SYNC_END = "\x1B[?2026l";
295112
295824
  function enableSynchronizedOutput() {
@@ -295172,7 +295884,7 @@ Headless Mode:
295172
295884
  --json-schema <schema> JSON Schema for structured output (use with --output-format json)
295173
295885
  --headless-timeout-ms <ms> Abort headless run after the given timeout (ms)
295174
295886
  -c, --continue Continue the most recent conversation
295175
- -r, --resume <session_id> Resume a specific session by ID
295887
+ -r, --resume <id_or_name> Resume a session by ID or name
295176
295888
  --cwd <path> Set working directory
295177
295889
 
295178
295890
  Examples:
@@ -295218,7 +295930,8 @@ if (options2.print !== null) {
295218
295930
  continue: options2.continue,
295219
295931
  resume: options2.resume,
295220
295932
  cwdProvided: options2.cwdProvided,
295221
- timeoutMs: options2.headlessTimeoutMs
295933
+ timeoutMs: options2.headlessTimeoutMs,
295934
+ permissionMode: options2.permissionMode ?? undefined
295222
295935
  }).then((result) => {
295223
295936
  process.exit(result.success ? 0 : 1);
295224
295937
  }).catch((error4) => {
@@ -295230,7 +295943,8 @@ if (options2.print !== null) {
295230
295943
  const disableSyncOutput = useSyncOutput ? enableSynchronizedOutput() : () => {};
295231
295944
  const appElement = /* @__PURE__ */ jsx_dev_runtime52.jsxDEV(App2, {
295232
295945
  cwd: options2.cwd,
295233
- version: VERSION4
295946
+ version: VERSION4,
295947
+ permissionMode: options2.permissionMode ?? undefined
295234
295948
  }, undefined, false, undefined, this);
295235
295949
  const { waitUntilExit } = render_default(appElement, {
295236
295950
  patchConsole: true,
@@ -295251,4 +295965,4 @@ export {
295251
295965
  main
295252
295966
  };
295253
295967
 
295254
- //# debugId=27FD559CEE6360B064756E2164756E21
295968
+ //# debugId=B1DCE952AC4F269164756E2164756E21