loopat 0.1.0

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 (58) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +194 -0
  3. package/bin/loopat.mjs +65 -0
  4. package/package.json +52 -0
  5. package/server/package.json +22 -0
  6. package/server/src/api-tokens.ts +161 -0
  7. package/server/src/api-v1-openapi.ts +363 -0
  8. package/server/src/api-v1.ts +681 -0
  9. package/server/src/auth.ts +309 -0
  10. package/server/src/bootstrap.ts +113 -0
  11. package/server/src/chat.ts +390 -0
  12. package/server/src/claude-binary.ts +68 -0
  13. package/server/src/compose.ts +474 -0
  14. package/server/src/config.ts +783 -0
  15. package/server/src/files.ts +173 -0
  16. package/server/src/git-crypt-key.ts +36 -0
  17. package/server/src/git-host.ts +104 -0
  18. package/server/src/github.ts +161 -0
  19. package/server/src/index.ts +3204 -0
  20. package/server/src/kanban.ts +810 -0
  21. package/server/src/loop-stats.ts +225 -0
  22. package/server/src/loop-status.ts +67 -0
  23. package/server/src/loops.ts +1832 -0
  24. package/server/src/mcp-oauth.ts +516 -0
  25. package/server/src/onboarding.ts +105 -0
  26. package/server/src/paths.ts +190 -0
  27. package/server/src/personal-keys.ts +60 -0
  28. package/server/src/plugin-installer.ts +287 -0
  29. package/server/src/podman.ts +1216 -0
  30. package/server/src/presets.ts +30 -0
  31. package/server/src/profiles.ts +177 -0
  32. package/server/src/providers.ts +45 -0
  33. package/server/src/serve.ts +275 -0
  34. package/server/src/session.ts +1496 -0
  35. package/server/src/system-prompt.ts +90 -0
  36. package/server/src/term.ts +211 -0
  37. package/server/src/tiers.ts +762 -0
  38. package/server/src/vaults.ts +189 -0
  39. package/server/src/workspace.ts +501 -0
  40. package/server/templates/.claude-plugin/marketplace.json +13 -0
  41. package/server/templates/CLAUDE.md +78 -0
  42. package/server/templates/loop-kinds/distill/CLAUDE.md +46 -0
  43. package/server/templates/plugins/loopat/.claude-plugin/plugin.json +5 -0
  44. package/server/templates/plugins/loopat/skills/onboarding/SKILL.md +266 -0
  45. package/server/templates/plugins/loopat/skills/promote/SKILL.md +53 -0
  46. package/server/templates/sandbox/Containerfile +113 -0
  47. package/web/dist/assets/CodeEditor-BGODueTo.js +49 -0
  48. package/web/dist/assets/Editor-DMS25Vve.js +1 -0
  49. package/web/dist/assets/Markdown-CnHbW7WK.js +5 -0
  50. package/web/dist/assets/MilkdownEditor-nqo9_0v5.js +123 -0
  51. package/web/dist/assets/Terminal-BrP-ENHg.css +1 -0
  52. package/web/dist/assets/Terminal-CYWvxYam.js +174 -0
  53. package/web/dist/assets/index-DM5eO-Tv.js +163 -0
  54. package/web/dist/assets/index-DxIFezwv.css +1 -0
  55. package/web/dist/assets/w3c-keyname-BOAvb0qz.js +1 -0
  56. package/web/dist/favicon.svg +1 -0
  57. package/web/dist/index.html +14 -0
  58. package/web/dist/logo.png +0 -0
package/LICENSE ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for describing the origin of the Work and
141
+ reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may accept and charge a
167
+ fee for, acceptance of support, warranty, indemnity, or other
168
+ liability obligations and/or rights consistent with this License.
169
+ However, in accepting such obligations, You may act only on Your
170
+ own behalf and on Your sole responsibility, not on behalf of any
171
+ other Contributor, and only if You agree to indemnify, defend,
172
+ and hold each Contributor harmless for any liability incurred by,
173
+ or claims asserted against, such Contributor by reason of your
174
+ accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright 2026 simpx and loopat contributors
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
200
+ implied. See the License for the specific language governing
201
+ permissions and limitations under the License.
package/README.md ADDED
@@ -0,0 +1,194 @@
1
+ # 🧶 loopat
2
+
3
+ > **Self-hosted AI workspace built around context management — works solo, scales to teams**
4
+
5
+ <p align="center">
6
+ <img src="docs/screenshot.png" alt="loopat — Loop view with chat, workdir, terminal, and team DM" width="100%">
7
+ </p>
8
+
9
+ ⭐ [Star on GitHub](https://github.com/simpx/loopat) ·
10
+ 🚀 [Quick start](#quick-start) ·
11
+ 📖 [Architecture](docs/architecture.md)
12
+
13
+ ---
14
+
15
+ When humans collaborate with AI, three things only humans can bring:
16
+
17
+ - **Drive** — pushing the work forward. AI has no desires, no
18
+ ambition of its own; momentum has to come from a human.
19
+ - **Attention** — what matters now, what to ignore. AI doesn't know
20
+ what's worth your time.
21
+ - **Entropy reduction** — turning noise into structured knowledge.
22
+ AI generates tokens but won't spontaneously simplify.
23
+
24
+ loopat is built around managing these three as first-class concepts:
25
+ **Loop** (drive) · **Focus** (attention) · **Context** (entropy
26
+ reduction). A fourth concept — **Chat** — coordinates the team on the
27
+ sync axis.
28
+
29
+ <p align="center">
30
+ <img src="docs/overview.svg" alt="loopat architecture" width="100%">
31
+ </p>
32
+
33
+ The agent itself is the [Claude Agent SDK][sdk]; what makes loopat
34
+ distinct is the **context architecture around it** — how chat, code,
35
+ memory, and knowledge interlock so context doesn't get lost across
36
+ sessions or teammates.
37
+
38
+ [sdk]: https://github.com/anthropics/claude-agent-sdk
39
+
40
+ ---
41
+
42
+ ## What makes loopat different
43
+
44
+ - **End-to-end context management.** Team chat (IM) threads, code
45
+ edits, agent decisions, memory — all live in the same context graph
46
+ and all flow into the next loop. Most AI tools make you copy-paste
47
+ from Slack into the AI to give it situational context; loopat treats
48
+ team chat as **a first-class context source** — spawn a loop from
49
+ any chat thread and that thread becomes part of the loop's context
50
+ automatically.
51
+ - **Works solo, scales to teams.** Same workspace whether you're
52
+ alone or onboarding teammates. Solo, it's a personal AI workspace;
53
+ with a team, shared `knowledge/` and `notes/` git repos sync across
54
+ members, loops auto-commit their work, and observations promote
55
+ upward through a distillation pipeline. Most AI tools force you to
56
+ pick between solo CLI and team SaaS — loopat is one tool at any scale.
57
+ - **Reproducible loops.** Every loop runs in its own sandbox with a
58
+ versioned toolchain and a pinned credential vault. Spawn the same
59
+ loop tomorrow on a different machine and get the same starting
60
+ state. No "works on my machine" for AI sessions.
61
+ - **Self-hosted, data you own.** All artifacts live in plain git
62
+ repos you fully control; vault secrets are git-crypt encrypted.
63
+ BYO API key — nothing leaves your machine except the model API call
64
+ itself.
65
+
66
+ ## How loopat compares
67
+
68
+ | | Claude Code | Cursor | opencode | Codex | **loopat** |
69
+ |---|---|---|---|---|---|
70
+ | Form factor | CLI | IDE | TUI | Web (hosted) | **Web (self-hosted)** |
71
+ | License | proprietary | proprietary | MIT | proprietary | **Apache 2.0** |
72
+ | Team IM integration | external (manual paste) | external (manual paste) | external (manual paste) | external (manual paste) | **built-in, threads ingested into loop context** |
73
+ | Memory management | personal (`CLAUDE.md`) | personal (rules + memories) | personal (`AGENTS.md`) | none | **personal + team-shared, with distillation pipeline** |
74
+ | Multi-user | single user | per-seat | single user | per-account | **shared workspace** |
75
+ | Shared team knowledge | individual config | individual config | individual config | individual config | **git-synced across team** |
76
+ | Per-session sandbox | process-level | process-level | process-level | OpenAI-managed | **bwrap (default) · Docker (planned)** |
77
+ | Toolchain pinning | host runtime | host runtime | host runtime | fixed (hosted env) | **per-loop versioned** |
78
+ | Per-task credential isolation | shared (env vars) | shared (subscription) | shared (env vars) | account-managed | **per-loop vault overlay** |
79
+ | Data location | local files | cloud | local files | OpenAI servers | **git repos you control** |
80
+ | Secrets storage | env vars (plaintext) | cloud-managed | env vars (plaintext) | platform-managed | **git-crypt encrypted vault** |
81
+ | Agent engine | proprietary (Anthropic) | proprietary (multi-model) | pluggable | proprietary (OpenAI) | **Claude Agent SDK** |
82
+
83
+ ---
84
+
85
+ ## Quick start
86
+
87
+ ```sh
88
+ git clone https://github.com/simpx/loopat.git
89
+ cd loopat && bun install
90
+ bun run dev
91
+ ```
92
+
93
+ Open <http://localhost:7787>. The first run bootstraps `~/.loopat/`,
94
+ prints a checklist, and prompts you to set your API key in
95
+ `~/.loopat/config.json`. Restart — done.
96
+
97
+ > **Needs:** Linux + [bubblewrap][bwrap] + [mise][mise] + [bun][bun] on
98
+ > the host. macOS / Windows is via Docker (see below). For team setups
99
+ > with shared knowledge/notes git repos and full bootstrap details, see
100
+ > the [installation guide](docs/install.md).
101
+
102
+ ### Setup guides
103
+
104
+ Loopat splits configuration along role lines — read whichever applies:
105
+
106
+ - **[Admin setup](docs/setup-admin.md)** — provision the workspace:
107
+ knowledge / notes repos, team sandboxes, MCP, operator mounts. Run
108
+ this once per workspace.
109
+ - **[User setup](docs/setup-user.md)** — join an existing workspace:
110
+ personal credential repo, providers, vaults, sandbox mounts. Run
111
+ this once per member, per machine.
112
+
113
+ [bwrap]: https://github.com/containers/bubblewrap
114
+ [mise]: https://mise.jdx.dev/
115
+ [bun]: https://bun.sh/
116
+
117
+ ## Deployment
118
+
119
+ ### Docker (recommended)
120
+
121
+ ```sh
122
+ docker compose up -d
123
+ ```
124
+
125
+ Open <http://localhost:17787> (note: **17787**, not 7787 — the host
126
+ port is remapped to avoid collision with a local dev server; see
127
+ [`docker-compose.yml`](docker-compose.yml)). Workspace persists in
128
+ the `loopat-data` volume. Needs `SYS_ADMIN` + unconfined AppArmor for
129
+ bwrap mount namespaces.
130
+
131
+ ### From source (Linux)
132
+
133
+ ```sh
134
+ bun run build # installs deps + builds frontend → web/dist/
135
+ PORT=7787 bun run server/src/index.ts
136
+ ```
137
+
138
+ Single Hono process serves API + static SPA + websocket on one port.
139
+ Put a reverse proxy in front and proxy `/api` + `/ws` to the server.
140
+
141
+ ## Documentation
142
+
143
+ - **[Admin setup](docs/setup-admin.md)** — workspace config, knowledge /
144
+ notes repos, sandboxes, MCP, operator mounts.
145
+ - **[User setup](docs/setup-user.md)** — personal repo, providers,
146
+ vaults, sandbox mounts.
147
+ - **[Installation guide](docs/install.md)** — host install, system deps,
148
+ environment variables.
149
+ - **[Architecture](docs/architecture.md)** — the read/write path, layered
150
+ context model, distillation pipeline, Claude config injection paths.
151
+ - **[Context flow](docs/context-flow.md)** — the horizontal working model: a
152
+ loop is a git worktree, shared context is `main`, and loops exchange it over
153
+ two edges — pull and promote.
154
+ - **[Identity](docs/identity.md)** — who a loop acts as: the credential chain
155
+ (deploy key → git-crypt → vault), and how loopat integrates with your git
156
+ host so onboarding is one authorization.
157
+ - **[.claude composition](docs/composition.md)** — how team / profile /
158
+ personal / repo `.claude/` tiers merge into the loop runtime, and what
159
+ you can put in each tier.
160
+ - **[Sandbox](docs/sandbox.md)** — bwrap mount mechanics, three-tier mount
161
+ authority, what stops the agent from escaping.
162
+ - **[Troubleshooting](docs/troubleshoot.md)** — chat won't start, banner
163
+ errors, common pitfalls.
164
+
165
+ ## Contributing
166
+
167
+ Issues and PRs welcome. Before opening a non-trivial PR, please skim
168
+ [`docs/architecture.md`](docs/architecture.md) so the change lands in the
169
+ right layer (sandbox / vault / loop / chat).
170
+
171
+ Contributors are asked to sign the [Contributor License Agreement](CLA.md)
172
+ on their first PR — the [CLA Assistant][cla-assistant] bot prompts you
173
+ with a one-click link. This keeps future licensing options open (e.g.
174
+ moving to a business-friendly license) without having to re-collect
175
+ permission from every contributor.
176
+
177
+ [cla-assistant]: https://cla-assistant.io/
178
+
179
+ ## Acknowledgments
180
+
181
+ loopat is built on top of:
182
+
183
+ - [Claude Agent SDK][sdk] — the agent runtime
184
+ - [assistant-ui](https://github.com/assistant-ui/assistant-ui) — React
185
+ components for the chat interface
186
+ - [Hono](https://hono.dev/) — the HTTP + WebSocket server
187
+ - [bubblewrap](https://github.com/containers/bubblewrap) — sandbox mount
188
+ namespaces
189
+ - [mise](https://mise.jdx.dev/) — per-loop toolchain installs
190
+
191
+ ## License
192
+
193
+ [Apache License 2.0](LICENSE). See [`NOTICE`](NOTICE) for required
194
+ attributions and [`CLA.md`](CLA.md) for contribution terms.
package/bin/loopat.mjs ADDED
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env node
2
+ // loopat launcher — runs the Bun server bundled in this package.
3
+ //
4
+ // loopat's server is written against the Bun runtime (bun:sqlite, Bun.serve,
5
+ // bun-pty FFI, …), so it cannot run on plain Node. We depend on the `bun` npm
6
+ // package, which downloads a platform Bun binary at install time; this Node
7
+ // shim locates that binary and hands off to `bun server/src/index.ts`.
8
+ //
9
+ // `npx loopat` therefore works on any machine that has Node — the user never
10
+ // has to install Bun themselves.
11
+ import { spawn } from "node:child_process"
12
+ import { createRequire } from "node:module"
13
+ import { existsSync } from "node:fs"
14
+ import { fileURLToPath } from "node:url"
15
+ import { dirname, join } from "node:path"
16
+
17
+ const require = createRequire(import.meta.url)
18
+ const here = dirname(fileURLToPath(import.meta.url))
19
+ const pkgRoot = join(here, "..")
20
+ const serverEntry = join(pkgRoot, "server", "src", "index.ts")
21
+
22
+ function resolveBun() {
23
+ // 1. Explicit override.
24
+ if (process.env.LOOPAT_BUN && existsSync(process.env.LOOPAT_BUN)) {
25
+ return process.env.LOOPAT_BUN
26
+ }
27
+ // 2. The `bun` dependency's installed binary. The package ships bin/bun.exe
28
+ // (a cross-platform shim) and, after its postinstall, the real binary.
29
+ try {
30
+ const bunPkg = dirname(require.resolve("bun/package.json"))
31
+ for (const candidate of [
32
+ join(bunPkg, "bin", "bun"),
33
+ join(bunPkg, "bin", "bun.exe"),
34
+ ]) {
35
+ if (existsSync(candidate)) return candidate
36
+ }
37
+ } catch {
38
+ /* bun package not resolvable from here — fall through */
39
+ }
40
+ // 3. npm-created bin shim alongside our package.
41
+ for (const candidate of [
42
+ join(pkgRoot, "..", ".bin", "bun"),
43
+ join(pkgRoot, "node_modules", ".bin", "bun"),
44
+ ]) {
45
+ if (existsSync(candidate)) return candidate
46
+ }
47
+ // 4. A bun already on PATH.
48
+ return "bun"
49
+ }
50
+
51
+ const bun = resolveBun()
52
+ const child = spawn(bun, [serverEntry, ...process.argv.slice(2)], {
53
+ stdio: "inherit",
54
+ env: process.env,
55
+ })
56
+
57
+ child.on("error", (err) => {
58
+ console.error(`[loopat] failed to launch bun (${bun}): ${err.message}`)
59
+ console.error("[loopat] set LOOPAT_BUN to a bun binary, or install bun: https://bun.sh")
60
+ process.exit(1)
61
+ })
62
+ child.on("exit", (code, signal) => {
63
+ if (signal) process.kill(process.pid, signal)
64
+ else process.exit(code ?? 0)
65
+ })
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "loopat",
3
+ "version": "0.1.0",
4
+ "description": "Self-hosted AI workspace built around context management — works solo, scales to teams",
5
+ "license": "Apache-2.0",
6
+ "homepage": "https://github.com/simpx/loopat",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/simpx/loopat.git"
10
+ },
11
+ "type": "module",
12
+ "bin": {
13
+ "loopat": "bin/loopat.mjs"
14
+ },
15
+ "files": [
16
+ "bin/",
17
+ "server/src/",
18
+ "!server/src/serve-rs",
19
+ "!server/src/port-proxy-rs",
20
+ "server/templates/",
21
+ "server/package.json",
22
+ "web/dist/"
23
+ ],
24
+ "workspaces": [
25
+ "server",
26
+ "web"
27
+ ],
28
+ "scripts": {
29
+ "dev": "HOST=${HOST:-127.0.0.1} LOOPAT_SERVE_HOST=${LOOPAT_SERVE_HOST:-127.0.0.1} bun run --filter '*' dev",
30
+ "dev:host": "HOST=0.0.0.0 LOOPAT_SERVE_HOST=0.0.0.0 bun run --filter '*' dev",
31
+ "dev:server": "bun --cwd server run dev",
32
+ "dev:web": "bun --cwd web run dev",
33
+ "dev:serve": "bun --cwd server run serve",
34
+ "build": "bun install && (cd web && bun run build)",
35
+ "build:web": "cd web && bunx tsc -b && bunx vite build",
36
+ "prepublishOnly": "bun install && bun run build:web",
37
+ "test:e2e": "playwright test",
38
+ "test:e2e:ui": "playwright test --ui"
39
+ },
40
+ "dependencies": {
41
+ "@anthropic-ai/claude-agent-sdk": "^0.3.150",
42
+ "@anthropic-ai/sandbox-runtime": "^0.0.52",
43
+ "@scalar/hono-api-reference": "^0.10.19",
44
+ "bun": "^1.3.14",
45
+ "bun-pty": "^0.4.8",
46
+ "hono": "^4.12.18",
47
+ "smol-toml": "^1.6.1"
48
+ },
49
+ "devDependencies": {
50
+ "@playwright/test": "^1.60.0"
51
+ }
52
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@loopat/server",
3
+ "private": true,
4
+ "type": "module",
5
+ "scripts": {
6
+ "dev": "bun run --hot src/index.ts",
7
+ "serve": "bun run --hot src/serve.ts",
8
+ "test": "bun test"
9
+ },
10
+ "dependencies": {
11
+ "@anthropic-ai/claude-agent-sdk": "^0.3.150",
12
+ "@anthropic-ai/sandbox-runtime": "^0.0.52",
13
+ "@scalar/hono-api-reference": "^0.10.19",
14
+ "bun-pty": "^0.4.8",
15
+ "hono": "^4.12.18",
16
+ "smol-toml": "^1.6.1"
17
+ },
18
+ "devDependencies": {
19
+ "@types/bun": "latest",
20
+ "typescript": "^5.6.0"
21
+ }
22
+ }