agentsquid 0.1.0__tar.gz

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.
Files changed (151) hide show
  1. agentsquid-0.1.0/.gitignore +21 -0
  2. agentsquid-0.1.0/LICENSE +21 -0
  3. agentsquid-0.1.0/PKG-INFO +234 -0
  4. agentsquid-0.1.0/README.md +211 -0
  5. agentsquid-0.1.0/activate.sh +1 -0
  6. agentsquid-0.1.0/agent/__init__.py +0 -0
  7. agentsquid-0.1.0/agent/config.py +137 -0
  8. agentsquid-0.1.0/agent/context_sync.py +163 -0
  9. agentsquid-0.1.0/agent/creds.py +130 -0
  10. agentsquid-0.1.0/agent/flow.py +806 -0
  11. agentsquid-0.1.0/agent/git_changes.py +399 -0
  12. agentsquid-0.1.0/agent/harnesses.py +344 -0
  13. agentsquid-0.1.0/agent/history.py +16 -0
  14. agentsquid-0.1.0/agent/journal.py +323 -0
  15. agentsquid-0.1.0/agent/memory.py +247 -0
  16. agentsquid-0.1.0/agent/providers.py +275 -0
  17. agentsquid-0.1.0/agent/resolve.py +199 -0
  18. agentsquid-0.1.0/agent/runners.py +1841 -0
  19. agentsquid-0.1.0/agent/server.py +2879 -0
  20. agentsquid-0.1.0/agent/stats_db.py +3577 -0
  21. agentsquid-0.1.0/agent/topic_queue.py +666 -0
  22. agentsquid-0.1.0/agent/topics.py +14 -0
  23. agentsquid-0.1.0/agent/worktree.py +717 -0
  24. agentsquid-0.1.0/benchmarks/__init__.py +1 -0
  25. agentsquid-0.1.0/benchmarks/claude_session_continuity/README.md +153 -0
  26. agentsquid-0.1.0/benchmarks/claude_session_continuity/__init__.py +1 -0
  27. agentsquid-0.1.0/benchmarks/claude_session_continuity/benchmark.py +1214 -0
  28. agentsquid-0.1.0/benchmarks/claude_session_continuity/prompts.example.yaml +127 -0
  29. agentsquid-0.1.0/bin/install.sh +147 -0
  30. agentsquid-0.1.0/bin/start.sh +116 -0
  31. agentsquid-0.1.0/bin/stop.sh +27 -0
  32. agentsquid-0.1.0/config/squid.yaml.example +206 -0
  33. agentsquid-0.1.0/context/.gitkeep +0 -0
  34. agentsquid-0.1.0/context/README.md +89 -0
  35. agentsquid-0.1.0/context/roles/review/AGENTS.md +52 -0
  36. agentsquid-0.1.0/context/roles/review/claude/CLAUDE.md +3 -0
  37. agentsquid-0.1.0/context/topics/default/memory.md +4 -0
  38. agentsquid-0.1.0/docs/adding-harness-checklist.md +102 -0
  39. agentsquid-0.1.0/docs/data-model-and-api.md +1107 -0
  40. agentsquid-0.1.0/docs/db-schema-target.md +297 -0
  41. agentsquid-0.1.0/docs/decisions/0001-resumable-sessions-as-primary-flow.md +167 -0
  42. agentsquid-0.1.0/docs/decisions/0002-session-identity-topic-agent.md +37 -0
  43. agentsquid-0.1.0/docs/decisions/0003-cwd-locked-at-session-creation.md +81 -0
  44. agentsquid-0.1.0/docs/decisions/0004-agent-required-no-auto-detect.md +35 -0
  45. agentsquid-0.1.0/docs/decisions/0005-sticky-topic-agent.md +37 -0
  46. agentsquid-0.1.0/docs/decisions/0006-adhoc-notation.md +38 -0
  47. agentsquid-0.1.0/docs/decisions/0007-cross-session-injection-tracking.md +80 -0
  48. agentsquid-0.1.0/docs/decisions/0008-filter-ui-topic-agent-colors.md +89 -0
  49. agentsquid-0.1.0/docs/decisions/0009-pinned-message-injection-scoping.md +100 -0
  50. agentsquid-0.1.0/docs/decisions/0010-adhoc-parallel-execution.md +95 -0
  51. agentsquid-0.1.0/docs/decisions/0011-response-surfaces-at-bottom-on-done.md +60 -0
  52. agentsquid-0.1.0/docs/decisions/0012-context-sync-tmp-squid.md +74 -0
  53. agentsquid-0.1.0/docs/decisions/0013-slash-command-system.md +96 -0
  54. agentsquid-0.1.0/docs/decisions/0014-yaml-config-single-file.md +82 -0
  55. agentsquid-0.1.0/docs/decisions/0015-topic-journals.md +112 -0
  56. agentsquid-0.1.0/docs/decisions/0016-security-model.md +114 -0
  57. agentsquid-0.1.0/docs/decisions/0017-token-counting-semantics.md +99 -0
  58. agentsquid-0.1.0/docs/decisions/0018-cli-process-group-isolation.md +235 -0
  59. agentsquid-0.1.0/docs/decisions/0019-oneshot-cli-over-tmux-session-reading.md +107 -0
  60. agentsquid-0.1.0/docs/decisions/0020-topic-code-roots-for-cross-agent-diffs.md +138 -0
  61. agentsquid-0.1.0/docs/decisions/0021-keyword-search-model.md +220 -0
  62. agentsquid-0.1.0/docs/decisions/0022-multi-protocol-agent-execution.md +192 -0
  63. agentsquid-0.1.0/docs/decisions/0023-quota-deltas-are-observational.md +57 -0
  64. agentsquid-0.1.0/docs/decisions/0024-configurable-backends-and-coded-drivers.md +103 -0
  65. agentsquid-0.1.0/docs/decisions/0025-per-turn-worktree-isolation.md +857 -0
  66. agentsquid-0.1.0/docs/decisions/0026-stats-breakdown-filter-semantics.md +495 -0
  67. agentsquid-0.1.0/docs/decisions/0027-backend-naming-convention.md +171 -0
  68. agentsquid-0.1.0/docs/decisions/0028-harness-provider-separation.md +277 -0
  69. agentsquid-0.1.0/docs/decisions/0029-retain-stats-on-topic-delete.md +44 -0
  70. agentsquid-0.1.0/docs/decisions/0030-update-mechanism-notify-only.md +191 -0
  71. agentsquid-0.1.0/docs/decisions/0031-central-comms-insights-json.md +263 -0
  72. agentsquid-0.1.0/docs/decisions/0032-route-chains-with-cwd-profile-agents.md +1009 -0
  73. agentsquid-0.1.0/docs/decisions/0033-cancelled-and-error-turn-capture.md +139 -0
  74. agentsquid-0.1.0/docs/decisions/0034-pypi-pipx-distribution.md +148 -0
  75. agentsquid-0.1.0/docs/squid-flow-whitepaper.md +389 -0
  76. agentsquid-0.1.0/preview-icons.html +144 -0
  77. agentsquid-0.1.0/pyproject.toml +60 -0
  78. agentsquid-0.1.0/test-results/.last-run.json +4 -0
  79. agentsquid-0.1.0/tests/__init__.py +0 -0
  80. agentsquid-0.1.0/tests/conftest.py +14 -0
  81. agentsquid-0.1.0/tests/e2e/README.md +57 -0
  82. agentsquid-0.1.0/tests/e2e/agents-mobile.spec.js +152 -0
  83. agentsquid-0.1.0/tests/e2e/boot-logo.spec.js +119 -0
  84. agentsquid-0.1.0/tests/e2e/branding.spec.js +18 -0
  85. agentsquid-0.1.0/tests/e2e/chat.spec.js +1626 -0
  86. agentsquid-0.1.0/tests/e2e/close-affordance-colors.spec.js +87 -0
  87. agentsquid-0.1.0/tests/e2e/community.spec.js +16 -0
  88. agentsquid-0.1.0/tests/e2e/compact-passthrough.spec.js +61 -0
  89. agentsquid-0.1.0/tests/e2e/composer-route-override.spec.js +151 -0
  90. agentsquid-0.1.0/tests/e2e/composer-tooltips.spec.js +74 -0
  91. agentsquid-0.1.0/tests/e2e/config.spec.js +1521 -0
  92. agentsquid-0.1.0/tests/e2e/deep-dive-button.spec.js +424 -0
  93. agentsquid-0.1.0/tests/e2e/files.spec.js +925 -0
  94. agentsquid-0.1.0/tests/e2e/filter.spec.js +601 -0
  95. agentsquid-0.1.0/tests/e2e/flow-view.spec.js +291 -0
  96. agentsquid-0.1.0/tests/e2e/history-pagination.spec.js +94 -0
  97. agentsquid-0.1.0/tests/e2e/linear-route-chain.spec.js +950 -0
  98. agentsquid-0.1.0/tests/e2e/mobile-navigation-history.spec.js +38 -0
  99. agentsquid-0.1.0/tests/e2e/origin-broadcast.spec.js +199 -0
  100. agentsquid-0.1.0/tests/e2e/package-lock.json +1119 -0
  101. agentsquid-0.1.0/tests/e2e/package.json +13 -0
  102. agentsquid-0.1.0/tests/e2e/pin.spec.js +824 -0
  103. agentsquid-0.1.0/tests/e2e/playwright.config.js +24 -0
  104. agentsquid-0.1.0/tests/e2e/process-status.spec.js +492 -0
  105. agentsquid-0.1.0/tests/e2e/prompt-autocomplete.spec.js +1066 -0
  106. agentsquid-0.1.0/tests/e2e/quota.spec.js +667 -0
  107. agentsquid-0.1.0/tests/e2e/search.spec.js +512 -0
  108. agentsquid-0.1.0/tests/e2e/session-advisory.spec.js +116 -0
  109. agentsquid-0.1.0/tests/e2e/stats-aggregates.spec.js +870 -0
  110. agentsquid-0.1.0/tests/e2e/stats-by-turn.spec.js +266 -0
  111. agentsquid-0.1.0/tests/e2e/stats-mobile.spec.js +85 -0
  112. agentsquid-0.1.0/tests/e2e/stats-presets.spec.js +351 -0
  113. agentsquid-0.1.0/tests/e2e/stats-system-views.spec.js +448 -0
  114. agentsquid-0.1.0/tests/e2e/stats-terminal-turns.spec.js +54 -0
  115. agentsquid-0.1.0/tests/e2e/stop.spec.js +340 -0
  116. agentsquid-0.1.0/tests/e2e/topics.spec.js +162 -0
  117. agentsquid-0.1.0/tests/e2e/update-notice.spec.js +89 -0
  118. agentsquid-0.1.0/tests/manual/verify_ask_followup_real.py +108 -0
  119. agentsquid-0.1.0/tests/test_claude_session_continuity_benchmark.py +690 -0
  120. agentsquid-0.1.0/tests/test_context_sync.py +82 -0
  121. agentsquid-0.1.0/tests/test_creds.py +31 -0
  122. agentsquid-0.1.0/tests/test_flow.py +814 -0
  123. agentsquid-0.1.0/tests/test_git_changes.py +252 -0
  124. agentsquid-0.1.0/tests/test_harnesses.py +189 -0
  125. agentsquid-0.1.0/tests/test_journal.py +19 -0
  126. agentsquid-0.1.0/tests/test_memory.py +172 -0
  127. agentsquid-0.1.0/tests/test_runners.py +1839 -0
  128. agentsquid-0.1.0/tests/test_server.py +1477 -0
  129. agentsquid-0.1.0/tests/test_stats_db.py +1797 -0
  130. agentsquid-0.1.0/tests/test_topic_queue.py +806 -0
  131. agentsquid-0.1.0/tests/test_worktree.py +633 -0
  132. agentsquid-0.1.0/ui/app.js +14381 -0
  133. agentsquid-0.1.0/ui/favicon.png +0 -0
  134. agentsquid-0.1.0/ui/flow-lang.js +727 -0
  135. agentsquid-0.1.0/ui/flow-playground.html +306 -0
  136. agentsquid-0.1.0/ui/icons/icon-192.png +0 -0
  137. agentsquid-0.1.0/ui/icons/icon-512.png +0 -0
  138. agentsquid-0.1.0/ui/icons/maskable-192.png +0 -0
  139. agentsquid-0.1.0/ui/icons/maskable-512.png +0 -0
  140. agentsquid-0.1.0/ui/index.html +755 -0
  141. agentsquid-0.1.0/ui/manifest.webmanifest +39 -0
  142. agentsquid-0.1.0/ui/squid.jpg +0 -0
  143. agentsquid-0.1.0/ui/squid.png +0 -0
  144. agentsquid-0.1.0/ui/squid_white.png +0 -0
  145. agentsquid-0.1.0/ui/style.css +5071 -0
  146. agentsquid-0.1.0/ui/sw.js +66 -0
  147. agentsquid-0.1.0/ui/vendor/atom-one-dark.min.css +1 -0
  148. agentsquid-0.1.0/ui/vendor/highlight.min.js +1213 -0
  149. agentsquid-0.1.0/ui/vendor/marked.min.js +69 -0
  150. agentsquid-0.1.0/ui/vendor/qrcode.min.js +1 -0
  151. agentsquid-0.1.0/uv.lock +1596 -0
@@ -0,0 +1,21 @@
1
+ __pycache__
2
+ *.py[cod]
3
+ *.egg-info/
4
+ .venv
5
+ dist/
6
+ .env
7
+ *.log
8
+ squid.db
9
+ .squid.pid
10
+ tests/e2e/node_modules
11
+ tests/e2e/playwright-report/
12
+ tests/e2e/test-results/
13
+ context/journals/
14
+ context/topics/*
15
+ !context/topics/default
16
+ context/topics/default/*
17
+ !context/topics/default/memory.md
18
+ logs/
19
+ .claude/
20
+ benchmarks/claude_session_continuity/results
21
+ config/squid.yaml
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Haebin Na
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,234 @@
1
+ Metadata-Version: 2.4
2
+ Name: agentsquid
3
+ Version: 0.1.0
4
+ Summary: Locally running chat agent with access to Claude Code, Codex, and bash
5
+ Project-URL: Homepage, https://agentsquid.ai
6
+ Project-URL: Repository, https://github.com/agent-squid/squid
7
+ Author: Haebin Na
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Topic :: Software Development :: Build Tools
15
+ Requires-Python: >=3.9
16
+ Requires-Dist: browser-cookie3>=0.19.0
17
+ Requires-Dist: curl-cffi>=0.7.0
18
+ Requires-Dist: fastapi>=0.111.0
19
+ Requires-Dist: httpx>=0.27.0
20
+ Requires-Dist: pyyaml>=6.0
21
+ Requires-Dist: uvicorn[standard]>=0.29.0
22
+ Description-Content-Type: text/markdown
23
+
24
+ # 🦑 AgentSquid
25
+ ```
26
+ 🦑 AGENT
27
+ ██████╗ ██████╗ ██╗ ██╗██╗██████╗
28
+ ██╔════╝██╔═══██╗██║ ██║██║██╔══██╗
29
+ ╚█████╗ ██║ ██║██║ ██║██║██║ ██║
30
+ ╚═══██╗██║▄▄ ██║██║ ██║██║██║ ██║
31
+ ██████╔╝╚██████╔╝╚██████╔╝██║██████╔╝
32
+ ╚═════╝ ╚══▀▀═╝ ╚═════╝ ╚═╝╚═════╝
33
+ ```
34
+ ## Quick Start
35
+
36
+ 1. Install at least one supported CLI and check whether you can use it (/login):
37
+
38
+ | Backend | CLI | Install |
39
+ |---|---|---|
40
+ | Claude Code | `claude` | `curl -fsSL https://claude.ai/install.sh \| bash` |
41
+ | OpenAI Codex | `codex` | `curl -fsSL https://chatgpt.com/codex/install.sh \| sh` |
42
+ | Cursor Agent | `cursor-agent` | `curl -fsS https://cursor.com/install \| bash` |
43
+ | OpenCode | `opencode` | `curl -fsSL https://opencode.ai/install \| bash` |
44
+ | Pi | `pi` | `curl -fsSL https://pi.dev/install.sh \| sh` |
45
+
46
+ 2. Install and run AgentSquid!
47
+
48
+ ```bash
49
+ curl -fsSL https://agentsquid.ai/install.sh | sh
50
+ agentsquid
51
+ ```
52
+
53
+ 3. Open in your browser:
54
+ ```text
55
+ http://127.0.0.1:8000
56
+ ```
57
+
58
+ Create agents in the UI. An agent is a named config:
59
+ ```text
60
+ agent name (@agent) = harness (Claude Code) + provider (Claude) + model (claude-sonnet-5) + working directory (CLAUDE.md, etc.)
61
+ ```
62
+
63
+ ## The Squid Manifesto: EVERY. TOKEN. COUNTS!
64
+
65
+ * COUNT every token, every prompt!
66
+ * UNIFY your subscriptions, free tiers, and local models into one workplace.
67
+ * SHARE context explicitly across models, topics, sessions; no waste!
68
+ * CLEAR old context without fear; AgentSquid alerts you to clear and let you choose exactly what stays!
69
+ * PARALLELIZE your prompts, no more waiting!
70
+
71
+ ## Your Local Coding Agents, Unified
72
+
73
+ Agent-Squid is a **meta harness orchestrator** which lets you run Claude Code, OpenAI Codex, Cursor Agent, OpenCode, Pi **coding agents** with **multiple providers**, such as, Claude, GPT, Cursor, OpenCode, NVIDIA, DeepSeek, local LLMs via **one browser UI**. Your agents still run on your own machine, with your repo, shell tools, credentials, and native CLI sessions. Squid gives those sessions names, history, queues, controls, and phone/tablet access.
74
+
75
+ Use it when your workflow has become a wall of unnamed terminal tabs or you need to use multiple coding agents; a couple of $20 agents alongside a free coding agent.
76
+
77
+ ```text
78
+ #launch@claude write the release notes
79
+ #launch@codex! review the diff for regressions
80
+ #bug@cursor reproduce the auth failure
81
+ #ops@opencode summarize the incident notes
82
+ #research@pi compare the implementation options
83
+ ```
84
+ NOTE: These topics are sticky. Once you are in the topic, no need to type it. :)
85
+
86
+ ## Why
87
+
88
+ CLI agents are useful, but the workflow gets messy quickly:
89
+
90
+ - You have ten Claude Code terminals open and cannot remember which one is doing what.
91
+ - A terminal closes or the machine reboots, and reviving the right session becomes a hunt through resume pickers, session IDs, cwd-sensitive history, and shell scrollback.
92
+ - Long-running sessions grow, drift, stall, and need compaction or reset but afraid to lose details.
93
+ - There is no way to select responses as context for the next new session, so you have to tell it again.
94
+ - Different agent CLIs have different commands, resume flags, slash commands, output formats, and UI assumptions.
95
+ - Token usage is usually hidden in the flow instead of attached clearly to each prompt and response.
96
+ - You want to do couch coding, but /remote doesn't cut it because not optimized for mobile.
97
+
98
+ Squid turns those local agents into named, durable lanes you can control from a single chat thread with filter support.
99
+
100
+ Topics and agents are not a rigid setup step. You can create a new `#topic` the moment you type it, switch agents with `@agent`, and clean up old workstreams when they are done. Squid treats tags as the UI for your agent work: lightweight enough to create dynamically, durable enough to recover later, and visible enough that you are not guessing which terminal was doing what.
101
+
102
+ ## What You Get
103
+
104
+ - **Named agent lanes:** `#topic@agent` gives every workstream a durable identity.
105
+ - **Dynamic tags:** create topics as you type, reuse sticky agents, filter by tag, and delete stale topics when the work is done.
106
+ - **Native resumable sessions:** Squid tracks session handles while the CLI owns its real context.
107
+ - **Parallel work:** different topics and agents run independently.
108
+ - **Adhoc (Goldfish) mode:** `#topic@agent!` runs a fresh one-off job immediately without polluting the main session. You can add the adhoc output to session context easily. (merging context)
109
+ - **Session vs. limited-context comparison:** compare a session lane against an adhoc prompt that includes only the last N exchanges.
110
+ - **Live progress bubble:** watch queued state, tool/status output, and partial response progress while the CLI is working.
111
+ - **Auto-compaction hint:** alerts you to /clear the session if it's stale or too many turns.
112
+ - **Context pin:** pin a useful answer and inject it into another session or adhoc turn.
113
+ - **Context bookmark:** bookmark a useful answer and use it later for context.
114
+ - **Process controls:** stop one process from the UI, stop by command, stop a topic, drain queues, clear sessions, and compact/reset context.
115
+ - **History and filtering:** scan past work by topic, agent, or adhoc lane.
116
+ - **Analytics:** review usage by time, topic, or agent, plus live process state.
117
+ - **Per-prompt usage:** every completed prompt can show input, output, cache, reasoning, cost, duration, and quota signals when the backend exposes them.
118
+ - **Phone/tablet access:** lie on the couch while your local machine keeps coding.
119
+
120
+ ## Basic Usage
121
+
122
+ | Syntax | Meaning |
123
+ |---|---|
124
+ | `#topic@agent message` | Continue that topic/agent session |
125
+ | `#topic@agent! message` | Run a parallel adhoc turn with no session history |
126
+ | `#topic@agent!3 message` | Run adhoc with only the last 3 exchanges (normal, searched, filtered) as context |
127
+ | `/stop` | Stop the current process scope |
128
+ | `/stopall` | Stop and drain the current topic |
129
+ | `/clear` | Create new session |
130
+ | `/f`, `/filter` | Filter history to the current topic/agent lane |
131
+ | `/s`, `/search` | Search history to the current topic/agent lane |
132
+ | `/remote` | Show QR code for mobile/tablet access via Tailscale |
133
+
134
+ Session turns are queued per `#topic@agent` for the tasks with order matters. Adhoc `!` turns are independent and run immediately.
135
+
136
+ This makes comparison easy. Ask the session with `#topic@agent`, then ask a limited-context version with `#topic@agent!3`, `#topic@agent!1`, or `#topic@agent!`. You can see whether the long session is helping, whether stale context is hurting, and how much token usage each path costs.
137
+
138
+ Tags are created dynamically. If you send `#release@claude ...`, Squid creates or updates the `release` topic and remembers `claude` as its sticky agent. Later, `#release ...` continues that lane without retyping the agent. Topic autocomplete lets you browse existing tags, and old topics can be hidden or deleted when they are no longer useful.
139
+
140
+ While an agent is running, Squid shows progress in a thought bubble instead of leaving you staring at a frozen terminal. You can see queue position, status output, tool activity, and streamed partial content. If the job is going in the wrong direction, stop it from the bubble’s UI control or type `/stop`, `/stopall`, or `deq` just like you would use CLI control commands, but with clearer scope and feedback.
141
+
142
+ After completion, the response carries usage metadata. Instead of guessing what a turn cost, you can inspect tokens, cache reads/writes, reasoning tokens where available, duration, cost, and quota deltas. The analytics view rolls this up by time, topic, and agent so you can see which lanes are expensive and which models are doing the most work.
143
+
144
+ ## Couch Coding With Tailscale
145
+
146
+ Squid is most useful when your local machine can keep working while you are away from the desk.
147
+
148
+ Tailscale is a good fit for this. Its Personal plan is free for non-commercial personal use, and it creates a private WireGuard-based network across your own devices. Your phone, tablet, laptop, Mac mini, and workstation can talk inside the tailnet without opening a public port.
149
+
150
+ Squid always binds to `127.0.0.1`, it never exposes itself directly on the network. Starting squid automatically configures Tailscale's HTTPS proxy if Tailscale is installed:
151
+
152
+ ```bash
153
+ agentsquid # configures tailscale serve automatically
154
+ ```
155
+
156
+ Type `/remote` in the chat to get a QR code with the full HTTPS URL and your
157
+ token already included — point your phone camera at it to open squid in one tap:
158
+
159
+ ```text
160
+ https://<machine-name>.<tailnet>.ts.net/?token=<your-token>
161
+ ```
162
+
163
+ The full domain is required — the short hostname alone (`https://<machine-name>/`)
164
+ won't work because Tailscale's TLS cert is scoped to `*.ts.net` and browsers
165
+ enforce an exact match.
166
+
167
+ ## How Squid Is Different
168
+
169
+ Squid is not another general AI chat app. Open WebUI and LibreChat are broad self-hosted chat platforms for many providers, RAG, plugins, users, memory, and web search.
170
+
171
+ Squid is narrower: it controls real local coding-agent CLIs and preserves their session behavior.
172
+
173
+ Most chat UIs send messages to a model API and render text back. Even when they support tools or agents, the chat app is usually the runtime. Squid is different: the runtime is still the local CLI agent. Claude Code, Codex, Cursor Agent, OpenCode, and Pi are the process doing the work on your machine. Squid is the interactive control layer around those processes.
174
+
175
+ That difference matters:
176
+
177
+ - **Real CLI sessions, not copied chat history:** Squid uses the agent’s native session instead of pretending to be the agent with a replayed transcript.
178
+ - **Working-directory awareness:** sessions are tied to the cwd where the CLI actually runs, which matters for local project context and resume behavior. You can change it to your local home to inherit all the settings. (note: this will burn a bit more tokens for additional context)
179
+ - **Process ownership:** Squid can show live processes, kill the exact running job, drain queued jobs, and recover after disconnects.
180
+ - **Topic and agent lanes:** `#topic@agent` is closer to a named terminal workspace than a chat room. You can easily filter it to look like a chat room.
181
+ - **Progress while work happens:** the thought bubble surfaces status, queued state, tool activity, and partial output before the final answer lands.
182
+ - **UI plus command control:** click to stop a specific run, or type commands like `/stop`, `/stopall`, `/clear`, `/compact`, and `/filter`.
183
+ - **Analytics attached to real work:** token usage is tied to each prompt and can be rolled up by topic, agent, or time.
184
+ - **Built-in context experiments:** compare a native resumed session against an adhoc turn with only selected recent context.
185
+ - **Local machine as the backend:** your Mac mini or workstation stays the execution environment, so the agent has the same filesystem, shell, credentials, and installed tools it would have in a terminal.
186
+
187
+ | Category | Examples | Squid's difference |
188
+ |---|---|---|
189
+ | Self-hosted AI chat | Open WebUI, LibreChat | Squid runs local CLI coding agents instead of replacing them with a provider chat UI. |
190
+ | Single-agent CLIs | Claude Code, Codex CLI, Cursor Agent, OpenCode, Pi | Squid gives them shared browser/mobile UI, topics, queues, history, controls, and analytics. |
191
+ | IDE agents | Cursor, Cline, VS Code Copilot | Squid is editor-agnostic and works even when the IDE is not open. |
192
+ | Terminal pair programmers | Aider, OpenCode | Squid is an orchestration layer, not a coding engine. |
193
+
194
+ Use the agent directly when one terminal is enough. Use Squid when you want several local agents, named sessions, mobile access, process control, recoverable long-running work, and analytics that explain what each lane is costing you.
195
+
196
+ ## Architecture
197
+
198
+ ```text
199
+ Browser / phone / tablet
200
+ |
201
+ | HTTP + SSE
202
+ v
203
+ FastAPI Squid server
204
+ |
205
+ +-- SQLite history, stats, topics, session handles
206
+ |
207
+ +-- TopicDispatcher
208
+ |
209
+ +-- FIFO worker per #topic@agent session lane
210
+ +-- ephemeral worker per adhoc ! turn
211
+ |
212
+ +-- local CLI subprocesses
213
+ claude / codex / cursor-agent / opencode / pi
214
+ ```
215
+
216
+ The CLI owns the real conversation context. Squid stores history, stats, topics, active session IDs, cwd locks, and UI state needed to make the workflow manageable. Session turns use native resume. Adhoc turns build an explicit limited-context prompt, which makes the two modes easy to compare.
217
+
218
+ ## Good Fit
219
+
220
+ Squid is a good fit if:
221
+
222
+ - You run multiple coding-agent terminals at once.
223
+ - You want to recover and operate sessions by name.
224
+ - You use a local Mac mini, workstation, or always-on machine for agent work.
225
+ - You want phone/tablet control without moving execution to the cloud.
226
+ - You compare or combine several agent CLIs.
227
+ - You want to compare full-session context against limited-history prompts.
228
+ - You care about token usage, cost, cache behavior, and per-topic or per-agent analytics.
229
+
230
+ It may be overkill if:
231
+
232
+ - You only ever use one agent in one terminal.
233
+ - You want a hosted team chat product.
234
+ - You want Squid to be the coding agent itself.
@@ -0,0 +1,211 @@
1
+ # 🦑 AgentSquid
2
+ ```
3
+ 🦑 AGENT
4
+ ██████╗ ██████╗ ██╗ ██╗██╗██████╗
5
+ ██╔════╝██╔═══██╗██║ ██║██║██╔══██╗
6
+ ╚█████╗ ██║ ██║██║ ██║██║██║ ██║
7
+ ╚═══██╗██║▄▄ ██║██║ ██║██║██║ ██║
8
+ ██████╔╝╚██████╔╝╚██████╔╝██║██████╔╝
9
+ ╚═════╝ ╚══▀▀═╝ ╚═════╝ ╚═╝╚═════╝
10
+ ```
11
+ ## Quick Start
12
+
13
+ 1. Install at least one supported CLI and check whether you can use it (/login):
14
+
15
+ | Backend | CLI | Install |
16
+ |---|---|---|
17
+ | Claude Code | `claude` | `curl -fsSL https://claude.ai/install.sh \| bash` |
18
+ | OpenAI Codex | `codex` | `curl -fsSL https://chatgpt.com/codex/install.sh \| sh` |
19
+ | Cursor Agent | `cursor-agent` | `curl -fsS https://cursor.com/install \| bash` |
20
+ | OpenCode | `opencode` | `curl -fsSL https://opencode.ai/install \| bash` |
21
+ | Pi | `pi` | `curl -fsSL https://pi.dev/install.sh \| sh` |
22
+
23
+ 2. Install and run AgentSquid!
24
+
25
+ ```bash
26
+ curl -fsSL https://agentsquid.ai/install.sh | sh
27
+ agentsquid
28
+ ```
29
+
30
+ 3. Open in your browser:
31
+ ```text
32
+ http://127.0.0.1:8000
33
+ ```
34
+
35
+ Create agents in the UI. An agent is a named config:
36
+ ```text
37
+ agent name (@agent) = harness (Claude Code) + provider (Claude) + model (claude-sonnet-5) + working directory (CLAUDE.md, etc.)
38
+ ```
39
+
40
+ ## The Squid Manifesto: EVERY. TOKEN. COUNTS!
41
+
42
+ * COUNT every token, every prompt!
43
+ * UNIFY your subscriptions, free tiers, and local models into one workplace.
44
+ * SHARE context explicitly across models, topics, sessions; no waste!
45
+ * CLEAR old context without fear; AgentSquid alerts you to clear and let you choose exactly what stays!
46
+ * PARALLELIZE your prompts, no more waiting!
47
+
48
+ ## Your Local Coding Agents, Unified
49
+
50
+ Agent-Squid is a **meta harness orchestrator** which lets you run Claude Code, OpenAI Codex, Cursor Agent, OpenCode, Pi **coding agents** with **multiple providers**, such as, Claude, GPT, Cursor, OpenCode, NVIDIA, DeepSeek, local LLMs via **one browser UI**. Your agents still run on your own machine, with your repo, shell tools, credentials, and native CLI sessions. Squid gives those sessions names, history, queues, controls, and phone/tablet access.
51
+
52
+ Use it when your workflow has become a wall of unnamed terminal tabs or you need to use multiple coding agents; a couple of $20 agents alongside a free coding agent.
53
+
54
+ ```text
55
+ #launch@claude write the release notes
56
+ #launch@codex! review the diff for regressions
57
+ #bug@cursor reproduce the auth failure
58
+ #ops@opencode summarize the incident notes
59
+ #research@pi compare the implementation options
60
+ ```
61
+ NOTE: These topics are sticky. Once you are in the topic, no need to type it. :)
62
+
63
+ ## Why
64
+
65
+ CLI agents are useful, but the workflow gets messy quickly:
66
+
67
+ - You have ten Claude Code terminals open and cannot remember which one is doing what.
68
+ - A terminal closes or the machine reboots, and reviving the right session becomes a hunt through resume pickers, session IDs, cwd-sensitive history, and shell scrollback.
69
+ - Long-running sessions grow, drift, stall, and need compaction or reset but afraid to lose details.
70
+ - There is no way to select responses as context for the next new session, so you have to tell it again.
71
+ - Different agent CLIs have different commands, resume flags, slash commands, output formats, and UI assumptions.
72
+ - Token usage is usually hidden in the flow instead of attached clearly to each prompt and response.
73
+ - You want to do couch coding, but /remote doesn't cut it because not optimized for mobile.
74
+
75
+ Squid turns those local agents into named, durable lanes you can control from a single chat thread with filter support.
76
+
77
+ Topics and agents are not a rigid setup step. You can create a new `#topic` the moment you type it, switch agents with `@agent`, and clean up old workstreams when they are done. Squid treats tags as the UI for your agent work: lightweight enough to create dynamically, durable enough to recover later, and visible enough that you are not guessing which terminal was doing what.
78
+
79
+ ## What You Get
80
+
81
+ - **Named agent lanes:** `#topic@agent` gives every workstream a durable identity.
82
+ - **Dynamic tags:** create topics as you type, reuse sticky agents, filter by tag, and delete stale topics when the work is done.
83
+ - **Native resumable sessions:** Squid tracks session handles while the CLI owns its real context.
84
+ - **Parallel work:** different topics and agents run independently.
85
+ - **Adhoc (Goldfish) mode:** `#topic@agent!` runs a fresh one-off job immediately without polluting the main session. You can add the adhoc output to session context easily. (merging context)
86
+ - **Session vs. limited-context comparison:** compare a session lane against an adhoc prompt that includes only the last N exchanges.
87
+ - **Live progress bubble:** watch queued state, tool/status output, and partial response progress while the CLI is working.
88
+ - **Auto-compaction hint:** alerts you to /clear the session if it's stale or too many turns.
89
+ - **Context pin:** pin a useful answer and inject it into another session or adhoc turn.
90
+ - **Context bookmark:** bookmark a useful answer and use it later for context.
91
+ - **Process controls:** stop one process from the UI, stop by command, stop a topic, drain queues, clear sessions, and compact/reset context.
92
+ - **History and filtering:** scan past work by topic, agent, or adhoc lane.
93
+ - **Analytics:** review usage by time, topic, or agent, plus live process state.
94
+ - **Per-prompt usage:** every completed prompt can show input, output, cache, reasoning, cost, duration, and quota signals when the backend exposes them.
95
+ - **Phone/tablet access:** lie on the couch while your local machine keeps coding.
96
+
97
+ ## Basic Usage
98
+
99
+ | Syntax | Meaning |
100
+ |---|---|
101
+ | `#topic@agent message` | Continue that topic/agent session |
102
+ | `#topic@agent! message` | Run a parallel adhoc turn with no session history |
103
+ | `#topic@agent!3 message` | Run adhoc with only the last 3 exchanges (normal, searched, filtered) as context |
104
+ | `/stop` | Stop the current process scope |
105
+ | `/stopall` | Stop and drain the current topic |
106
+ | `/clear` | Create new session |
107
+ | `/f`, `/filter` | Filter history to the current topic/agent lane |
108
+ | `/s`, `/search` | Search history to the current topic/agent lane |
109
+ | `/remote` | Show QR code for mobile/tablet access via Tailscale |
110
+
111
+ Session turns are queued per `#topic@agent` for the tasks with order matters. Adhoc `!` turns are independent and run immediately.
112
+
113
+ This makes comparison easy. Ask the session with `#topic@agent`, then ask a limited-context version with `#topic@agent!3`, `#topic@agent!1`, or `#topic@agent!`. You can see whether the long session is helping, whether stale context is hurting, and how much token usage each path costs.
114
+
115
+ Tags are created dynamically. If you send `#release@claude ...`, Squid creates or updates the `release` topic and remembers `claude` as its sticky agent. Later, `#release ...` continues that lane without retyping the agent. Topic autocomplete lets you browse existing tags, and old topics can be hidden or deleted when they are no longer useful.
116
+
117
+ While an agent is running, Squid shows progress in a thought bubble instead of leaving you staring at a frozen terminal. You can see queue position, status output, tool activity, and streamed partial content. If the job is going in the wrong direction, stop it from the bubble’s UI control or type `/stop`, `/stopall`, or `deq` just like you would use CLI control commands, but with clearer scope and feedback.
118
+
119
+ After completion, the response carries usage metadata. Instead of guessing what a turn cost, you can inspect tokens, cache reads/writes, reasoning tokens where available, duration, cost, and quota deltas. The analytics view rolls this up by time, topic, and agent so you can see which lanes are expensive and which models are doing the most work.
120
+
121
+ ## Couch Coding With Tailscale
122
+
123
+ Squid is most useful when your local machine can keep working while you are away from the desk.
124
+
125
+ Tailscale is a good fit for this. Its Personal plan is free for non-commercial personal use, and it creates a private WireGuard-based network across your own devices. Your phone, tablet, laptop, Mac mini, and workstation can talk inside the tailnet without opening a public port.
126
+
127
+ Squid always binds to `127.0.0.1`, it never exposes itself directly on the network. Starting squid automatically configures Tailscale's HTTPS proxy if Tailscale is installed:
128
+
129
+ ```bash
130
+ agentsquid # configures tailscale serve automatically
131
+ ```
132
+
133
+ Type `/remote` in the chat to get a QR code with the full HTTPS URL and your
134
+ token already included — point your phone camera at it to open squid in one tap:
135
+
136
+ ```text
137
+ https://<machine-name>.<tailnet>.ts.net/?token=<your-token>
138
+ ```
139
+
140
+ The full domain is required — the short hostname alone (`https://<machine-name>/`)
141
+ won't work because Tailscale's TLS cert is scoped to `*.ts.net` and browsers
142
+ enforce an exact match.
143
+
144
+ ## How Squid Is Different
145
+
146
+ Squid is not another general AI chat app. Open WebUI and LibreChat are broad self-hosted chat platforms for many providers, RAG, plugins, users, memory, and web search.
147
+
148
+ Squid is narrower: it controls real local coding-agent CLIs and preserves their session behavior.
149
+
150
+ Most chat UIs send messages to a model API and render text back. Even when they support tools or agents, the chat app is usually the runtime. Squid is different: the runtime is still the local CLI agent. Claude Code, Codex, Cursor Agent, OpenCode, and Pi are the process doing the work on your machine. Squid is the interactive control layer around those processes.
151
+
152
+ That difference matters:
153
+
154
+ - **Real CLI sessions, not copied chat history:** Squid uses the agent’s native session instead of pretending to be the agent with a replayed transcript.
155
+ - **Working-directory awareness:** sessions are tied to the cwd where the CLI actually runs, which matters for local project context and resume behavior. You can change it to your local home to inherit all the settings. (note: this will burn a bit more tokens for additional context)
156
+ - **Process ownership:** Squid can show live processes, kill the exact running job, drain queued jobs, and recover after disconnects.
157
+ - **Topic and agent lanes:** `#topic@agent` is closer to a named terminal workspace than a chat room. You can easily filter it to look like a chat room.
158
+ - **Progress while work happens:** the thought bubble surfaces status, queued state, tool activity, and partial output before the final answer lands.
159
+ - **UI plus command control:** click to stop a specific run, or type commands like `/stop`, `/stopall`, `/clear`, `/compact`, and `/filter`.
160
+ - **Analytics attached to real work:** token usage is tied to each prompt and can be rolled up by topic, agent, or time.
161
+ - **Built-in context experiments:** compare a native resumed session against an adhoc turn with only selected recent context.
162
+ - **Local machine as the backend:** your Mac mini or workstation stays the execution environment, so the agent has the same filesystem, shell, credentials, and installed tools it would have in a terminal.
163
+
164
+ | Category | Examples | Squid's difference |
165
+ |---|---|---|
166
+ | Self-hosted AI chat | Open WebUI, LibreChat | Squid runs local CLI coding agents instead of replacing them with a provider chat UI. |
167
+ | Single-agent CLIs | Claude Code, Codex CLI, Cursor Agent, OpenCode, Pi | Squid gives them shared browser/mobile UI, topics, queues, history, controls, and analytics. |
168
+ | IDE agents | Cursor, Cline, VS Code Copilot | Squid is editor-agnostic and works even when the IDE is not open. |
169
+ | Terminal pair programmers | Aider, OpenCode | Squid is an orchestration layer, not a coding engine. |
170
+
171
+ Use the agent directly when one terminal is enough. Use Squid when you want several local agents, named sessions, mobile access, process control, recoverable long-running work, and analytics that explain what each lane is costing you.
172
+
173
+ ## Architecture
174
+
175
+ ```text
176
+ Browser / phone / tablet
177
+ |
178
+ | HTTP + SSE
179
+ v
180
+ FastAPI Squid server
181
+ |
182
+ +-- SQLite history, stats, topics, session handles
183
+ |
184
+ +-- TopicDispatcher
185
+ |
186
+ +-- FIFO worker per #topic@agent session lane
187
+ +-- ephemeral worker per adhoc ! turn
188
+ |
189
+ +-- local CLI subprocesses
190
+ claude / codex / cursor-agent / opencode / pi
191
+ ```
192
+
193
+ The CLI owns the real conversation context. Squid stores history, stats, topics, active session IDs, cwd locks, and UI state needed to make the workflow manageable. Session turns use native resume. Adhoc turns build an explicit limited-context prompt, which makes the two modes easy to compare.
194
+
195
+ ## Good Fit
196
+
197
+ Squid is a good fit if:
198
+
199
+ - You run multiple coding-agent terminals at once.
200
+ - You want to recover and operate sessions by name.
201
+ - You use a local Mac mini, workstation, or always-on machine for agent work.
202
+ - You want phone/tablet control without moving execution to the cloud.
203
+ - You compare or combine several agent CLIs.
204
+ - You want to compare full-session context against limited-history prompts.
205
+ - You care about token usage, cost, cache behavior, and per-topic or per-agent analytics.
206
+
207
+ It may be overkill if:
208
+
209
+ - You only ever use one agent in one terminal.
210
+ - You want a hosted team chat product.
211
+ - You want Squid to be the coding agent itself.
@@ -0,0 +1 @@
1
+ source .venv/bin/activate
File without changes
@@ -0,0 +1,137 @@
1
+ import getpass
2
+ import hashlib
3
+ import os
4
+ import shutil
5
+ import tempfile
6
+ from pathlib import Path
7
+ from typing import Optional
8
+ import yaml
9
+
10
+ _USER_CONFIG = Path.home() / ".squid" / "squid.yaml"
11
+ _EXAMPLE_CONFIG = Path(__file__).parent.parent / "config" / "squid.yaml.example"
12
+
13
+
14
+ def _bootstrap_config() -> None:
15
+ """Create ~/.squid/squid.yaml from the bundled example on first run.
16
+
17
+ bin/install.sh and bin/start.sh do this same substitution for a source
18
+ checkout, but a pip/pipx install never runs either script, so this has
19
+ to also happen here — otherwise a fresh pipx install has no config file
20
+ and _load_config() below crashes on the very first launch.
21
+ """
22
+ if _USER_CONFIG.exists() or not _EXAMPLE_CONFIG.exists():
23
+ return
24
+ _USER_CONFIG.parent.mkdir(parents=True, exist_ok=True)
25
+ text = _EXAMPLE_CONFIG.read_text(encoding="utf-8")
26
+ text = text.replace("/tmp/squid", f"/tmp/{getpass.getuser()}/squid")
27
+ _USER_CONFIG.write_text(text, encoding="utf-8")
28
+
29
+
30
+ def _load_config() -> dict:
31
+ _bootstrap_config()
32
+ return yaml.safe_load(_USER_CONFIG.read_text())
33
+
34
+
35
+ def config_text() -> str:
36
+ return _USER_CONFIG.read_text(encoding="utf-8")
37
+
38
+
39
+ def config_revision(content: Optional[str] = None) -> str:
40
+ raw = config_text() if content is None else content
41
+ return hashlib.sha256(raw.encode("utf-8")).hexdigest()[:16]
42
+
43
+
44
+ def write_config_text(content: str, expected_revision: Optional[str] = None) -> str:
45
+ """Atomically replace squid.yaml, retaining the previous version as .bak."""
46
+ if expected_revision is not None and config_revision() != expected_revision:
47
+ raise RuntimeError("configuration changed since it was loaded")
48
+
49
+ mode = _USER_CONFIG.stat().st_mode & 0o777
50
+ backup = _USER_CONFIG.with_suffix(_USER_CONFIG.suffix + ".bak")
51
+ shutil.copy2(_USER_CONFIG, backup)
52
+ fd, tmp_name = tempfile.mkstemp(prefix=".squid.yaml.", dir=_USER_CONFIG.parent)
53
+ try:
54
+ with os.fdopen(fd, "w", encoding="utf-8") as handle:
55
+ handle.write(content)
56
+ handle.flush()
57
+ os.fsync(handle.fileno())
58
+ os.chmod(tmp_name, mode)
59
+ os.replace(tmp_name, _USER_CONFIG)
60
+ finally:
61
+ if os.path.exists(tmp_name):
62
+ os.unlink(tmp_name)
63
+ return config_revision(content)
64
+
65
+ _cfg = _load_config()
66
+
67
+ # CLI executable names — override via env if installed elsewhere
68
+ CLAUDE_CLI = "claude"
69
+ CODEX_CLI = "codex"
70
+ CURSOR_CLI = "cursor-agent"
71
+ OPENCODE_CLI = "opencode"
72
+ PI_CLI = "pi"
73
+
74
+ # Experimental runners exist for these CLIs but they are not configurable harnesses.
75
+ COPILOT_CLI = "copilot"
76
+ AGY_CLI = "agy"
77
+
78
+ # Squid Echo: a no-op harness (agent/runners.py's run_echo) that echoes the
79
+ # prompt straight back with no subprocess and no network call — for fast,
80
+ # free previews of how a Squid Flow route actually dispatches/executes
81
+ # (joins, round-trips, broadcasts, ...) without a real coding-agent CLI in
82
+ # the loop. Opt-in only (absent/false by default), so it never shows up for
83
+ # a user who hasn't asked for it; harnesses.py and providers.py both gate on
84
+ # this flag. Settable either way — `test_harness_enabled: true` in
85
+ # squid.yaml (picked up on every restart, since /restart re-execs and
86
+ # re-reads the file) or the SQUID_TEST_HARNESS env var (for CI/one-offs).
87
+ TEST_HARNESS_ENABLED: bool = bool(_cfg.get("test_harness_enabled")) or bool(os.environ.get("SQUID_TEST_HARNESS"))
88
+
89
+ # How long to wait for a CLI to produce its first byte before giving up
90
+ FIRST_BYTE_TIMEOUT: int = _cfg["agent"]["first_byte_timeout"]
91
+
92
+ # Hard cap on total response time per request
93
+ RESPONSE_TIMEOUT: int = _cfg["agent"]["response_timeout"]
94
+
95
+ def find_cli(name: str) -> Optional[str]:
96
+ return shutil.which(name)
97
+
98
+ CLAUDE_PATH = find_cli(CLAUDE_CLI)
99
+ CODEX_PATH = find_cli(CODEX_CLI)
100
+ COPILOT_PATH = find_cli(COPILOT_CLI)
101
+ CURSOR_PATH = find_cli(CURSOR_CLI)
102
+ OPENCODE_PATH = find_cli(OPENCODE_CLI)
103
+ PI_PATH = find_cli(PI_CLI)
104
+ AGY_PATH = find_cli(AGY_CLI)
105
+
106
+ # OpenCode free provider — no API key required
107
+ OPENCODE_DEFAULT_MODEL = "opencode/deepseek-v4-flash-free"
108
+
109
+ # Per-user tmp dir for context sync — avoids cross-user permission conflicts
110
+ SQUID_HOME = f"/tmp/{os.getlogin()}/squid"
111
+
112
+ # Per-turn Git worktree isolation (see ADR-0025). On by default; set
113
+ # `worktree.enabled: false` in squid.yaml to use direct working-tree writes.
114
+ _worktree_cfg = _cfg.get("worktree", {})
115
+ WORKTREE_ISOLATION_ENABLED: bool = bool(_worktree_cfg.get("enabled", True))
116
+ WORKTREE_TRACK_DIRTY_CHANGES: bool = bool(_worktree_cfg.get("track_dirty_changes", False))
117
+
118
+ # Dependency/cache directory names to symlink from a code root into each fresh
119
+ # per-turn worktree. auto_link_ignored_dirs only links ignored dirs whose
120
+ # basename appears in this allowlist.
121
+ WORKTREE_AUTO_LINK_IGNORED_DIRS: bool = bool(_worktree_cfg.get("auto_link_ignored_dirs", True))
122
+ DEPENDENCY_DIRS: list[str] = _worktree_cfg.get("dependency_dirs", [
123
+ "node_modules", ".venv", "venv", "env", ".tox", "__pypackages__",
124
+ "vendor", "target", ".bundle", "Pods", ".cargo", ".stack-work", "elm-stuff",
125
+ ])
126
+
127
+ # Proxy environment to inject into every CLI subprocess, or None if disabled.
128
+ _proxy_cfg = _cfg.get("proxy", {})
129
+ PROXY_ENV: Optional[dict] = None
130
+ if _proxy_cfg.get("enabled"):
131
+ _proxy_url = _proxy_cfg.get("url", "http://127.0.0.1:8080")
132
+ _cert = os.path.expanduser(_proxy_cfg.get("ssl_cert_file", "~/.mitmproxy/mitmproxy-ca-cert.pem"))
133
+ PROXY_ENV = {
134
+ "HTTP_PROXY": _proxy_url,
135
+ "HTTPS_PROXY": _proxy_url,
136
+ "SSL_CERT_FILE": _cert,
137
+ }