tote: Instructions file for Codex

AGENTS.md

tote AGENTS.md is an instructions file for Codex, OpenCode from yusufkaraaslan/tote. It costs 3,510 tokens per session, scanned A, original, MIT.

Development instructions for Tote, an Electron desktop app that combines web-based AI tabs, shared project folders, and terminal sessions. Electron is a framework for building desktop apps with web technologies.

In plain words
What is it for?
Use them when changing Tote's setup wizard, workspace management, file handling, provider sessions, terminal support, settings, or its vanilla JavaScript interface.
Why use it?
They document how the app's workspaces, downloads, settings, terminal sessions, and installer behave. This helps prevent changes from using the wrong project folder or breaking communication between the app's parts.

Instructions file for CodexOpenCode

Written for Codex and OpenCode: the file is AGENTS.md. Also seen: mentions Claude Code; mentions Codex.

This is yusufkaraaslan/tote's own configuration. It tells Codex and OpenCode how to work on tote itself, so it is not a mod to install elsewhere. Copy it as a starting point and replace the rules that are about this project. Everything tote configures →

Reuse

Borrowing it

Nothing to install: this file belongs to yusufkaraaslan/tote. Take a copy, put it at the same path in your own repository, and replace the rules that are about this project with yours.

Copy the file
curl -O https://raw.githubusercontent.com/yusufkaraaslan/tote/main/AGENTS.md
Clone the repo
git clone --depth 1 https://github.com/yusufkaraaslan/tote

Made for: Codex, OpenCode.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for tote AGENTS.md

README.md
[![agentmods](https://agentmods.dev/badge/instructions/yusufkaraaslan/tote/agents-md/github.svg)](https://agentmods.dev/instructions/yusufkaraaslan/tote/agents-md)
Your own site
<a href="https://agentmods.dev/instructions/yusufkaraaslan/tote/agents-md"><img src="https://agentmods.dev/badge/instructions/yusufkaraaslan/tote/agents-md/github.svg" alt="Measured on agentmods" height="20"></a>

Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.

agentmods 80×15 button for tote AGENTS.md

Your own site · 80×15
<a href="https://agentmods.dev/instructions/yusufkaraaslan/tote/agents-md"><img src="https://agentmods.dev/badge/instructions/yusufkaraaslan/tote/agents-md.svg" alt="Reviewed on agentmods" width="80" height="20"></a>
Per session 3,510 This file is loaded in full into every session.
When invoked 3,510 The same file — it is already loaded in full.
Security scan A 1 finding. A grade says what 26 rules found in the file — not that it is safe.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.03510 $0.03510
Opus 5.5 $0.01404 $0.01404
Sonnet 5.5 $0.00702 $0.00702
Haiku 4.5 $0.00351 $0.00351

Measured 8d ago against content hash 70b020bc5998, method: parsed. Prices are Anthropic first-party input rates as of 2026-10-07, from the pricing page.

Security

Grade A, and why

tote AGENTS.md scanned grade A with 1 finding against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 8d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Runs shell commandslowCapability

Expected in a hook, worth knowing in a rule or an instructions file.

- Terminals must stay real PTYs (node-pty) — piping through child_process breaks TUI agents. A remote terminal is still a real local pty with `ssh -tt` inside it, riding the space's master socket through the *remote* log
AGENTS.md · 39 lines

How it starts

The opening of the file, as written. The whole thing — 39 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Tote — agent notes

Electron hub app: web LLM tabs + shared workspace folder + docked CLI-agent terminals.

  • Run: npm install && npm start (postinstall copies xterm assets to src/renderer/vendor).
  • Host / viewer split (devices design, docs/superpowers/specs/2026-10-12-devices-design.md): src/host/ owns the device — spaces, files, views.json, terminals, watchers — and never requires electron (npm test enforces it). Every window is a viewer with its own active space; host.call(name, viewerId, args) runs a method from host.js's table with ctx = { viewer, wsId }, and file ops go through workspace.scoped(wsId). Terminals are host sessions (src/host/sessions.js): a pty plus an @xterm/headless mirror that replays to a late window, answers terminal queries once (windows drop their own replies via src/renderer/termreports.js), and survives its window closing. src/host/channels.js classifies every IPC channel as host / viewer / split.
  • Devices (phase 3): with settings.shareDevice on, src/host/server.js listens on this node's Tailscale IP only and admits a caller only when tailscale whois says it is one of the same owner's own nodes (not shared in). Another machine's Tote then calls host methods over JSON-over-WebSocket (src/host/protocol.js) exactly as a window does over IPC; src/main/devices.js is the client, and route() in main.js sends a window's host calls to whichever device it is viewing. The device chip at the top of the sidebar lists your devices and switches without reloading — the renderer keeps one slice of state per device (SLICE, switchDevice), events carry the device key, a dropped device keeps its panes under a banner and reconnects by itself, downloads and PDFs cross between machines in slices; things that need this machine's disk or apps refuse while viewing another.
  • Main process: src/main/ (sessions per provider partition, downloads → the inbox of the space the downloading window is in, Downloads-folder bridge for native apps (macOS only; copies, and only files the quarantine xattr attributes to a known LLM app), app launcher, IPC, node-pty). Setup wizard logic lives in src/main/installer.js (system checks, Claude Desktop MCP binding, MCP snippet) + the #wizard-* section of src/renderer/app.js.
  • CLI profiles carry an install command (npm -g) used by the wizard; keep package names accurate when adding profiles. Wizard installs self-heal: the run's output is buffered and src/renderer/npmfix.js (pure, npm test covers it) detects npm's blocked-install-scripts warning (retry with --allow-scripts=…) and EACCES on a root-owned global prefix (setup:fixNpmPrefix points npm at ~/.local only when prefixPlan says that's safe); each mend runs at most once.
  • Remote spaces: a space with a host field lives on another machine over ssh (typically Tailscale SSH). New remote space in the sidebar creates one; src/main/sshfix.js is pure (quoting, every remote command, containment, the ssh/Tailscale detectors — npm test covers it) and src/main/remote.js holds RemoteConn + RemoteFs. Rules that matter: never expandTilde a remote path or mkdir its inbox locally; discardTemp() refuses remote outright; shq() is the only thing that puts a path into a remote command; every non-interactive op sets BatchMode=yes and hands failure to the connection actor, which owns the one interactive pty allowed to authenticate; BatchMode alone does NOT prevent a hang (Tailscale's check is served after the connection is up, so ssh holds the session open) -- exec() in remote.js bounds every op with a timeout plus a stderr sniffer (needsHuman) that aborts the instant the auth banner appears; the master socket uses ControlPersist=yes and deliberately outlives Tote, because its lifetime is what sets how often Tailscale's periodic check makes the user re-authenticate. Re-auth is ambient, not a setup step — it surfaces as a banner in the files pane and a connect pane, never a modal. A remote space polls a remote-hashed fingerprint instead of binding chokidar.
  • Workspaces are two-level: one global + project spaces in config/workspaces.json. All file ops resolve the CALLING WINDOW's space at call time via host.ws(ctx) (a workspace.scoped(wsId) view) — never cache the root; the registry's active is only where a fresh window opens. Spaces are managed from the sidebar's right-click menu and the Workspaces section of Settings (add / rename / change folder / remove → workspaces:* IPC); ids are stable across rename/re-point.
  • Renderer: src/renderer/ vanilla JS, no bundler. Bridge surface = window.tote (see src/preload/preload.js).
  • Providers, CLI profiles, workspaces and apps are data, not code: defaults in config/*.json, runtime copies in userData. Prefer adding entries there over hardcoding.
  • Never give the renderer nodeIntegration. New capabilities: classify the channel in src/host/channels.js, then a host method in host.js (forwarded by name) or an ipcMain handler in main.js (viewer/split), then a preload wrapper.
  • Keep all workspace file access inside WorkspaceManager.resolveSafe (path-escape guard).
  • The tree watcher has a file-descriptor budget and blowing it breaks terminals, not the tree (chokidar 4 has no fsevents, so it opens one fd per watched path). A terminal that prints [process exited with code 0] and nothing else means the main process is out of descriptors, not that the shell failed. Defences: IGNORE by name, IGNORE_UNITY + skipper() by context (Library/Temp/Logs/obj are pruned only inside a real Unity project, since those names are also real source dirs), watchPlan() lowering the depth to fit WATCH_BUDGET, and watch() awaiting the previous watcher's close() before binding the new one — it re-arms on every space switch.
  • Terminals must stay real PTYs (node-pty) — piping through child_process breaks TUI agents. A remote terminal is still a real local pty with ssh -tt inside it, riding the space's master socket through the remote login shell, so xterm, resize and the key handlers are untouched. node-pty's prebuilt spawn-helper must be executable (postinstall chmods it; asarUnpack for packaged builds) or spawns fail with posix_spawnp failed.
  • Tote hands process.env to every child (ptys, wizard installs, cli:check, local services), so dropInheritedAgentSession() in main.js strips inherited agent-session markers (CLAUDE_CODE_CHILD_SESSION, CLAUDECODE, …) once at startup — an upgrade reopened from a docked agent terminal otherwise makes every new terminal look like a nested child session (Claude Code then disables transcript saving). Keep that list explicit; CLAUDE_CONFIG_DIR and the Bedrock/Vertex vars share the prefix and must survive.
  • A GUI launch (Finder/Dock/.desktop) gives the app a minimal PATH, so codex/claude/npm are missing even though they work in a terminal. ptyManager.js runs every CLI profile through $SHELL -l -i -c 'exec …', and adoptLoginShellPath() in main.js adopts the login shell's PATH at startup for the wizard checks and local services. Don't exec profile commands directly on POSIX.
  • Webview popups (OAuth) must open in-app so they share the provider partition; only non-http schemes go to the system browser. UA = Electron's real UA minus Electron/Tote tokens — never a hardcoded foreign UA.
  • Views are per-workspace: web tabs are instances stored in views.json (+ menu opens providers, duplicates allowed), terminals tagged with wsId and referenced by host session id (random, chosen by the renderer); showWorkspaceViews() restores a space's setup on switch. Another window's views:save arrives as views:changed and adoptViews() applies it (last edit wins).
  • Layout: a tiling tree of panes, not docks. Web views, terminals and the files tree are equal leaves in one binary tree; the pure engine is src/renderer/layout.js (window.TileTree, covered by npm test) and applyTiles() in app.js turns the tree into rects. #tiles is flat: a pane element is created once per content instance and never reparented — reparenting a <webview> reloads the guest and loses page state.
  • Sidebar order is the registry list order; a tab drag calls workspaces:reorder → WorkspaceManager.reorder(ids), which only rewrites the order in workspaces.json (active space, entry fields and watchers untouched) and re-appends any id the renderer omitted.
  • Temp spaces carry temp: true + lastUsed and live under settings.scratchRoot (default ~/tote/scratch). discardTemp() is the only function in Tote that deletes user files — temp-only, inside-the-root-only, never the last space — and remove() still never touches the disk. promote() moves the folder and keeps the id so views.json survives; the sweep runs at launch only. Pure parts are in src/main/scratch.js, tested by scripts/test-scratch.js (run by npm test).
  • Each space holds groups — virtual desktops with their own tree (views.json: groups[] + activeGroup), switched from #group-bar or Cmd/Ctrl+Alt+1…9; moveToGroup() moves a pane between them (drag the head onto a chip, right-click the head, or Cmd/Ctrl+Alt+Shift+1…9) by editing trees only — nothing is reparented. Other groups' webviews and PTYs stay alive and hidden. Walk persisted trees with groupsOf(V), never V.tiling.
  • The files tree is a dock: insertRoot pins it to the whole left edge at the width it had when closed (filesRatio, per space); splitTarget() and openPane keep content panes out of it.
  • Files dropped on a terminal pane are typed in as shell-escaped paths (acceptFileDrop), never sent — and every other drop is swallowed, because Chromium's default is to navigate the window to the file. Paths come from webUtils.getPathForFile (File.path is gone since Electron 32), with will-navigate in main.js as the backstop.
  • Files are panes: clicking one opens leaf kind doc, whose ref is an instance (views.json: docs: [{id, path, mode}]), not a path — a click retargets the pane you have, Cmd/Ctrl-click opens a second. Only those three fields persist; unsaved buffers never reach disk. Text and code are editable with Cmd/Ctrl+S, markdown, HTML and SVG render with a src|view toggle (MOD+E) — HTML in its own <webview>, so the page's own CSS/JS/images load — images and PDFs are read-only, and anything else still goes to the system app. readDoc in workspace.js is the single classify-and-read channel; docKind also stamps every tree node.
  • Rendered markdown comes from src/renderer/markdown.js (pure, npm test covers it) and is built with createElement — never innerHTML. The parser keeps raw HTML literal and filters hrefs to http(s)/mailto/relative, which is what makes that safe; keep both rules if you ever swap the parser out.
  • A doc pane re-reads its own file on workspace:changed (the ping has no path): clean panes reload silently, dirty ones show the changed on disk bar, and "keep mine" lets the next save overwrite.
  • The focused class is only a border: focusPaneContent() puts real keyboard focus inside the focused pane (xterm, the webview host — blurred first if it already is the active element, or Electron's guest stays unfocused — or a doc textarea). It runs from focusPane even when the leaf is unchanged, after every space/group switch, and on win:focus from main; drop any of those and the user needs a second click before typing works. Clicks inside a webview never reach the pane, so the host's focus event is what moves the logical focus there.
  • Any splitter or pane drag must toggle body.dragging so webviews don't eat mouse events. Fit xterm before ptySpawn and ptyResize after, or TUIs render at 80×24. Shift+Enter needs the attachCustomKeyEventHandler in spawnTerm that sends LF (\n, the Ctrl+J byte) — xterm's default CR is indistinguishable from Enter, so agents submit instead of adding a line. That handler also maps Shift+arrows/Home/End to xterm's scrollback (bare arrows belong to the agent's history), passing them through on the alternate screen. It also sends Alt+Up/Down as ESC[1;3A/B itself — xterm turns them into Ctrl+arrow on non-macOS, which hid Codex's "alt + ↑ to answer" prompt.

Read the full file on GitHub · 39 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 8d ago Changed · +4 lines · +358 tokens per session 70b020bc5998
  2. 13d ago Changed · +2 lines · +101 tokens per session 3e77673c7b1e
  3. 26d ago Changed · +2 lines · +521 tokens per session b9e6691636a1
  4. 27d ago Changed · +47 tokens per session f7b3015079a6
  5. 1mo ago Changed · +23 tokens per session 7f988da6d65f
  6. 1mo ago Changed · +1 lines · +176 tokens per session 891a77847d76
  7. 1mo ago Changed · +2 lines · +288 tokens per session 069961ceeb07
  8. 2mo ago Changed · +1 lines · +354 tokens per session bf32270e9e11
  9. 2mo ago Changed · +1 lines · +156 tokens per session 40a601205d9a
  10. 2mo ago First seen · 26 lines · 1,486 tokens per session scan A 2e79b1b39a51

Subscribe to this mod's changes

tote AGENTS.md is an instructions file published in the GitHub repository yusufkaraaslan/tote (6 stars, last pushed 8d ago), licensed MIT. It adds 3,510 tokens to every session, about $0.0140 per session on Opus 5.5. A static security scan graded it A with 1 finding (runs shell commands). No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.

Related

tote AGENTS.md compared with instructions from other repositories

tote AGENTS.md next to 6 instructions from other repositories
ModTypeStarsLast pushLicenceScanTokensWorks with
tote AGENTS.mdyusufkaraaslan/toteInstructions file68d agoMITA3,510Codex, OpenCode
vscode buildNext.instructions.mdmicrosoft/vscodeInstructions file195ktodayMITA9,719GitHub Copilot
next.js AGENTS.mdvercel/next.jsInstructions file143kyesterdayMITA7,461Codex, OpenCode
vscode oss-third-party-notices.instructions.mdmicrosoft/vscodeInstructions file195ktodayMITA5,649GitHub Copilot
langchain AGENTS.mdlangchain-ai/langchainInstructions file149ktodayMITA4,680Codex, OpenCode
vscode copilot-instructions.mdmicrosoft/vscodeInstructions file195ktodayMITA3,093GitHub Copilot
vscode ai-customization.instructions.mdmicrosoft/vscodeInstructions file195ktodayMITA1,907GitHub Copilot