agent.libx.js 0.94.3 → 0.94.5

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/README.md CHANGED
@@ -104,7 +104,7 @@ agentx --resume <id> "…" # resume a specific session
104
104
  ```
105
105
 
106
106
  - **Filesystem + Shell** — by default the CLI has **full real-filesystem access like Claude Code** (root `/` is the machine root, the launch dir is the working dir, absolute host paths and above-cwd reach both work) with a **real `/bin/sh`** (`Shell` tool) so the agent can run git, bun, node, curl, and any installed binary. Secrets (`.env`, `.ssh`, keys, `.git`) stay hidden by the jail; env secrets are scrubbed from the child shell. `--sandbox` instead operates over an in-memory copy of the working dir with a VFS-only `bash` — the real disk is never touched. `--boddb <dir>` runs over a **persistent database workspace** (a bod-db store at `<dir>` — `meta.db` tree + `files/` bytes) that survives across runs while the real disk stays untouched; DB-native by default, or add `--seed` to hydrate it from cwd on the first run. `--no-shell` forces the VFS bash in disk mode. (`/sandbox` shows the active mode.)
107
- - **Sessions** — every conversation persists to `./.agent/sessions/<id>.json`; `--continue`/`--resume` (and `/sessions`, `/resume`) pick it back up, *with memory across turns* — a REPL turn sees the previous one. A global symlink index at `~/.agent/sessions/` enables cross-project lookup: `--resume 090715-335` resolves from any directory, and `/sessions all` lists every project's sessions in one picker.
107
+ - **Sessions** — every conversation persists to `./.agent/sessions/<id>.json`; `--continue`/`--resume` (and `/sessions`, `/resume`) pick it back up, *with memory across turns* — a REPL turn sees the previous one. A global symlink index at `~/.agent/sessions/` enables cross-project lookup: `--resume 090715-myproject` resolves from any directory, and `/sessions all` lists every project's sessions in one picker.
108
108
  - **Diffs** — every `Edit`/`Write`/`MultiEdit` renders a colorized `+/-` diff (TTY-gated; plain when piped).
109
109
  - **Slash commands** — `/help /tools /model /compact /clear /sessions /resume /commands /init`; user-defined `./.agent/commands/<name>.md` are invokable directly as `/<name>` (the same registry the model's `SlashCommand` tool uses).
110
110
  - **Project instructions** — `./AGENTS.md` (or `CLAUDE.md`) auto-loads into every run; `/init` scaffolds one.
package/dist/cli.js CHANGED
@@ -6576,11 +6576,22 @@ var SessionStore = class {
6576
6576
  constructor(cwd) {
6577
6577
  this.dir = join6(cwd, ".agent", "sessions");
6578
6578
  }
6579
- /** Sortable, human-readable id: `YYYYMMDD-HHMMSS-mmm`. */
6580
- newId(now5 = Date.now()) {
6579
+ /** Sortable, human-readable id: `YYYYMMDD-HHMMSS-<folder>`. */
6580
+ newId(now5 = Date.now(), cwd) {
6581
6581
  const d = new Date(now5);
6582
6582
  const p = (n, w = 2) => String(n).padStart(w, "0");
6583
- return `${d.getFullYear()}${p(d.getMonth() + 1)}${p(d.getDate())}-${p(d.getHours())}${p(d.getMinutes())}${p(d.getSeconds())}-${p(d.getMilliseconds(), 3)}`;
6583
+ const slug2 = (cwd ?? process.cwd()).split("/").pop()?.replace(/[^A-Za-z0-9_-]/g, "") || "session";
6584
+ let id = `${d.getFullYear()}${p(d.getMonth() + 1)}${p(d.getDate())}-${p(d.getHours())}${p(d.getMinutes())}${p(d.getSeconds())}-${slug2}`;
6585
+ if (existsSync5(this.dir) && existsSync5(join6(this.dir, `${id}.json`))) {
6586
+ for (let i = 2; i <= 99; i++) {
6587
+ const c = `${id}-${i}`;
6588
+ if (!existsSync5(join6(this.dir, `${c}.json`))) {
6589
+ id = c;
6590
+ break;
6591
+ }
6592
+ }
6593
+ }
6594
+ return id;
6584
6595
  }
6585
6596
  /** A session id must be one safe path segment — blocks `../`-style traversal via --resume/load/save. */
6586
6597
  safeId(id) {
@@ -7770,7 +7781,7 @@ function applyKey(s, key, str) {
7770
7781
  }
7771
7782
  if (s.vim === "normal" && s.buf.length) return "none";
7772
7783
  if (s.buf.length) return "cancel";
7773
- if (wasEsc) return "rewind";
7784
+ if (wasEsc || key?.sequence === "\x1B\x1B") return "rewind";
7774
7785
  s.prevEsc = true;
7775
7786
  return "none";
7776
7787
  // first Esc on empty → arm double-Esc
@@ -9167,7 +9178,7 @@ async function runTurn(agent, store, session, task, cp, cwd = process.cwd(), sen
9167
9178
  const lastUser = res.messages.map((m2) => m2.role).lastIndexOf("user");
9168
9179
  const tools = res.messages.slice(lastUser).filter((m2) => m2.role === "tool").length;
9169
9180
  const ok = res.finishReason === "stop";
9170
- const shortId = session.meta.id.slice(-10);
9181
+ const shortId = session.meta.id.replace(/^\d{8}-/, "");
9171
9182
  const silentAbort = res.finishReason === "aborted" && !res.usage?.totalTokens;
9172
9183
  if (!silentAbort)
9173
9184
  err("\n" + (process.stderr.isTTY ? "\r\x1B[0J" : "") + (ok ? green(" \u2713 done") : red(` \u2717 ${res.finishReason}`)) + dim(` \xB7 ${res.steps} steps \xB7 ${tools} tools \xB7 ${tok}${secs}s \xB7 ${shortId}
@@ -9203,7 +9214,7 @@ function startSession(args, store, agent, cwd) {
9203
9214
  agent.transcript = data.messages;
9204
9215
  if (args.fork) {
9205
9216
  const now6 = Date.now();
9206
- const forked = { meta: { ...data.meta, id: args.sessionId ?? store.newId(now6), created: now6, updated: now6, turns: data.meta.turns }, messages: data.messages };
9217
+ const forked = { meta: { ...data.meta, id: args.sessionId ?? store.newId(now6, cwd), created: now6, updated: now6, turns: data.meta.turns }, messages: data.messages };
9207
9218
  err(dim(` forked ${data.meta.id} \u2192 ${forked.meta.id} (${data.meta.turns} turns)
9208
9219
  `));
9209
9220
  if (!args.task) printHistory(data.messages);
@@ -9218,7 +9229,7 @@ function startSession(args, store, agent, cwd) {
9218
9229
  `));
9219
9230
  }
9220
9231
  const now5 = Date.now();
9221
- const id = args.sessionId ?? store.newId(now5);
9232
+ const id = args.sessionId ?? store.newId(now5, cwd);
9222
9233
  if (!args.task) err(dim(` session ${id}
9223
9234
  `));
9224
9235
  return { meta: { id, created: now5, updated: now5, cwd, model: agent.options.model, turns: 0, title: "" }, messages: [] };