offsite 0.0.41 → 0.0.43

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.
@@ -5,7 +5,7 @@ import path from "node:path";
5
5
  import { consola } from "consola";
6
6
  import { WebSocketServer } from "ws";
7
7
  import { z } from "zod";
8
- import os, { homedir } from "node:os";
8
+ import os from "node:os";
9
9
  import { deleteSession, forkSession, getSessionInfo, getSessionMessages, getSubagentMessages, listSessions, query, renameSession } from "@anthropic-ai/claude-agent-sdk";
10
10
  import { execFile, spawn } from "node:child_process";
11
11
  import readline from "node:readline";
@@ -955,6 +955,10 @@ function platform() {
955
955
  function claudeBaseDir() {
956
956
  return readConfig().claudeBaseDir[platform()] ?? path.join(os.homedir(), ".claude");
957
957
  }
958
+ function workingDirectory() {
959
+ const dir = readConfig().workingDir[platform()] ?? "~";
960
+ return dir.startsWith("~") ? path.join(os.homedir(), dir.slice(1)) : dir;
961
+ }
958
962
  function defaultShell() {
959
963
  if (process.platform === "win32") return process.env.COMSPEC ?? "cmd.exe";
960
964
  return os.userInfo().shell ?? "/bin/sh";
@@ -1003,8 +1007,11 @@ function activity() {
1003
1007
  for (const run of runs.values()) result[run.sessionId] = {
1004
1008
  running: run.running,
1005
1009
  waiting: run.pending.size > 0,
1010
+ approval: [...run.pending.values()].some((pending) => pending.request.kind === "approval" || pending.request.kind === "plan"),
1011
+ question: [...run.pending.values()].some((pending) => pending.request.kind === "question"),
1006
1012
  prompted: run.prompted,
1007
1013
  compacting: run.compacting,
1014
+ backgroundAgent: run.backgroundAgents > 0,
1008
1015
  tasks: run.tasks
1009
1016
  };
1010
1017
  return result;
@@ -1191,6 +1198,7 @@ var CodexRun = class CodexRun {
1191
1198
  prompted = false;
1192
1199
  compacting = false;
1193
1200
  backgroundTasks = 0;
1201
+ backgroundAgents = 0;
1194
1202
  tasks = {};
1195
1203
  activeAt = Date.now();
1196
1204
  model;
@@ -2205,6 +2213,7 @@ var OpenCodeRun = class OpenCodeRun {
2205
2213
  prompted = false;
2206
2214
  compacting = false;
2207
2215
  backgroundTasks = 0;
2216
+ backgroundAgents = 0;
2208
2217
  tasks = {};
2209
2218
  close;
2210
2219
  applied;
@@ -3309,6 +3318,7 @@ const CAN = 24;
3309
3318
  const SUB = 26;
3310
3319
  var Scanner = class {
3311
3320
  title = "";
3321
+ directory = null;
3312
3322
  state = "ground";
3313
3323
  payload = [];
3314
3324
  scan(bytes) {
@@ -3385,6 +3395,10 @@ var Scanner = class {
3385
3395
  this.title = text.slice(2);
3386
3396
  return null;
3387
3397
  }
3398
+ if (text.startsWith("9;9;")) {
3399
+ this.directory = text.slice(4).replace(/^"(.*)"$/, "$1");
3400
+ return null;
3401
+ }
3388
3402
  if (text.startsWith("9;")) {
3389
3403
  const body = text.slice(2);
3390
3404
  const digits = /^\d*/.exec(body)?.[0].length ?? 0;
@@ -3705,7 +3719,7 @@ function startShell(cwd) {
3705
3719
  encoding: null
3706
3720
  });
3707
3721
  }
3708
- async function currentDirectory(pid) {
3722
+ async function currentDirectory(pid, reported) {
3709
3723
  if (process.platform === "linux") return readlink(`/proc/${pid}/cwd`);
3710
3724
  if (process.platform === "darwin") {
3711
3725
  const { stdout } = await run("lsof", [
@@ -3720,6 +3734,10 @@ async function currentDirectory(pid) {
3720
3734
  if (line === void 0) throw new Error(`lsof found no folder for ${pid}`);
3721
3735
  return line.slice(1);
3722
3736
  }
3737
+ if (process.platform === "win32") {
3738
+ if (reported === null || !statSync(reported, { throwIfNoEntry: false })?.isDirectory()) throw new Error(`the shell reported no existing folder, it reported ${reported}`);
3739
+ return reported;
3740
+ }
3723
3741
  throw new Error("reading the directory of another process is not supported on this platform");
3724
3742
  }
3725
3743
  async function busyProgram(pid) {
@@ -3830,12 +3848,6 @@ const OUTPUT_LIMIT$1 = 1048576;
3830
3848
  const STALL_LIMIT = 1e4;
3831
3849
  const SILENCE_LIMIT$1 = 9e4;
3832
3850
  const KILL_DELAY = 3e3;
3833
- const pasteTypes = {
3834
- "image/png": "png",
3835
- "image/jpeg": "jpg",
3836
- "image/gif": "gif",
3837
- "image/webp": "webp"
3838
- };
3839
3851
  const instance = `${Date.now()}-${randomUUID()}`;
3840
3852
  const projects = /* @__PURE__ */ new Map();
3841
3853
  const terminals = /* @__PURE__ */ new Map();
@@ -3889,15 +3901,6 @@ function closeProjectTabs(projectId) {
3889
3901
  for (const tab of [...project.tabs]) closeTab(tab.id);
3890
3902
  publish();
3891
3903
  }
3892
- function savePastedImage(type, data) {
3893
- const extension = pasteTypes[type];
3894
- if (extension === void 0) throw new Error("pasted image must be a PNG, JPEG, GIF or WebP image");
3895
- const directory = path.join(home, "paste");
3896
- mkdirSync(directory, { recursive: true });
3897
- const file = path.join(directory, `${Date.now()}-${randomUUID()}.${extension}`);
3898
- writeFileSync(file, data);
3899
- return file;
3900
- }
3901
3904
  function attach(client) {
3902
3905
  detachTerminal(client);
3903
3906
  const connection = {
@@ -3994,7 +3997,7 @@ function input(connection, bytes) {
3994
3997
  terminal.pty.write(Buffer.from(frame.data));
3995
3998
  }
3996
3999
  async function createTab(projectId) {
3997
- const cwd = projectId === "global" ? homedir() : projectPath(projectId);
4000
+ const cwd = projectId === "global" ? workingDirectory() : projectPath(projectId);
3998
4001
  if (!statSync(cwd, { throwIfNoEntry: false })?.isDirectory()) {
3999
4002
  console.error(`${cwd} is not a folder, terminal not created`);
4000
4003
  return;
@@ -4007,7 +4010,7 @@ async function createTab(projectId) {
4007
4010
  const active = project.activeTab === null ? void 0 : terminals.get(project.activeTab);
4008
4011
  let directory = cwd;
4009
4012
  if (active !== void 0) try {
4010
- directory = await currentDirectory(active.pty.pid);
4013
+ directory = await currentDirectory(active.pty.pid, active.scanner.directory);
4011
4014
  } catch (error) {
4012
4015
  console.warn(`starting in the project folder, could not read the folder of the active terminal: ${error}`);
4013
4016
  }
@@ -4035,7 +4038,7 @@ async function createTab(projectId) {
4035
4038
  minimized: false
4036
4039
  });
4037
4040
  project.activeTab = id;
4038
- pty.onData((data) => output(id, terminal, data));
4041
+ pty.onData((data) => output(id, terminal, Buffer.from(data)));
4039
4042
  pty.onExit(() => {
4040
4043
  terminals.delete(id);
4041
4044
  paused.delete(pty);
@@ -4106,12 +4109,8 @@ function drain() {
4106
4109
  }, 10);
4107
4110
  }
4108
4111
  function scan(id, terminal, data) {
4109
- if (!pushActive()) {
4110
- terminal.scanner = new Scanner();
4111
- return;
4112
- }
4113
4112
  const alert = terminal.scanner.scan(data);
4114
- if (alert === null || notifierWatching()) return;
4113
+ if (!pushActive() || alert === null || notifierWatching()) return;
4115
4114
  if (!(alert.type === "bell" ? terminal.alerts.startBell() : terminal.alerts.startNotification())) return;
4116
4115
  const windowTitle = terminal.scanner.title;
4117
4116
  setTimeout(() => push(id, alert, windowTitle), 500);
@@ -5616,6 +5615,7 @@ var Run = class {
5616
5615
  prompted = false;
5617
5616
  compacting = false;
5618
5617
  backgroundTasks = 0;
5618
+ backgroundAgents = 0;
5619
5619
  tasks = {};
5620
5620
  inbox = [];
5621
5621
  wake = null;
@@ -5830,6 +5830,7 @@ var Run = class {
5830
5830
  case "background_tasks_changed": {
5831
5831
  const live = message.tasks.filter((task) => task.ambient !== true);
5832
5832
  this.backgroundTasks = live.length;
5833
+ this.backgroundAgents = live.filter((task) => task.task_type === "local_agent").length;
5833
5834
  this.tasks = {
5834
5835
  ...Object.fromEntries(Object.entries(this.tasks).filter(([, status]) => status !== "running")),
5835
5836
  ...Object.fromEntries(live.map((task) => [task.task_id, "running"]))
@@ -6397,6 +6398,23 @@ async function changedElsewhere(run, cwd) {
6397
6398
  return last !== void 0 && !run.messages.some((item) => item.uuid === last);
6398
6399
  }
6399
6400
  //#endregion
6401
+ //#region src/services/terminal/paste.ts
6402
+ const pasteTypes = {
6403
+ "image/png": "png",
6404
+ "image/jpeg": "jpg",
6405
+ "image/gif": "gif",
6406
+ "image/webp": "webp"
6407
+ };
6408
+ function savePastedImage(type, data) {
6409
+ const extension = pasteTypes[type];
6410
+ if (extension === void 0) throw new Error("pasted image must be a PNG, JPEG, GIF or WebP image");
6411
+ const directory = path.join(home, "paste");
6412
+ mkdirSync(directory, { recursive: true });
6413
+ const file = path.join(directory, `${Date.now()}-${randomUUID()}.${extension}`);
6414
+ writeFileSync(file, data);
6415
+ return file;
6416
+ }
6417
+ //#endregion
6400
6418
  //#region src/storage/state.ts
6401
6419
  const stateFile = path.join(home, "state.json");
6402
6420
  const stateSchema = z.strictObject({ composer: z.strictObject({