Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
589 commits
Select commit Hold shift + click to select a range
49531d2
feat: simplify file picker UI and enhance file search functionality; …
panlilu May 25, 2026
1f1864d
feat: implement goal management system; add commands to set, complete…
panlilu May 25, 2026
8441e08
feat: add production_start.sh script for infinite-loop server launche…
panlilu May 25, 2026
c158803
fix: update default host addresses in production_start.sh to 127.0.0.1
panlilu May 25, 2026
943f827
feat: add recursive file listing functionality; implement listDirRecu…
panlilu May 25, 2026
037871c
refactor: de-special-case MCP tokens as plain vault envs
simpx May 25, 2026
e5adb42
feat: add scripts/stop_all.sh to kill all loopat processes
simpx May 25, 2026
3181ea1
feat: add chimp gateway sse
simpx May 25, 2026
125454e
refactor: generalize runtime gateway
simpx May 25, 2026
891c749
feat: generic per-user runtime gateway with token management UI
simpx May 25, 2026
c8ede46
feat(api): v1 Loop API + token store; migrate web create flow
simpx May 25, 2026
8ff62a5
feat(api): chat receive/send goes through v1 (WS retained for operato…
simpx May 25, 2026
b573d51
docs(api-v1): add /me/tokens endpoint section + Implementation Status
simpx May 25, 2026
84c7e93
feat(api): serve OpenAPI 3 spec + Scalar interactive docs; rename Gat…
simpx May 25, 2026
29537b4
docs: account-model.md — multi-account identity model (the "agent" qu…
simpx May 26, 2026
987161b
feat(api): add mise-config endpoints for tier management; implement M…
panlilu May 26, 2026
5ee494f
docs(account-model): reframe with OA-system "multi-account / 公共账号" te…
simpx May 26, 2026
f76a7bd
Refactor code structure for improved readability and maintainability
panlilu May 26, 2026
56df232
feat(account): public accounts (公共账号) — step 1-5 server impl
simpx May 26, 2026
bf588ff
feat(ui): add fullscreen toggle functionality to editor components
panlilu May 26, 2026
27597af
feat(web): Settings → Agents tab — create/list/delete public accounts
simpx May 26, 2026
c52fc2f
fix(web): rename Agents tab → Accounts (no agent terminology in UI)
simpx May 26, 2026
9642eaf
feat(presets): implement admin presets management for providers and m…
panlilu May 26, 2026
77bc9f5
fix: prevent submit actions during composition in input fields
panlilu May 26, 2026
dafae9f
feat(kanban): add refresh functionality to KanbanBoard component
panlilu May 26, 2026
c58aa7f
feat(kanban): add loading indicators to action buttons in CardDetailD…
panlilu May 26, 2026
33048ae
feat(dialog): add success message for save actions in WorkspacePanel …
panlilu May 26, 2026
52ca9cf
fix(session): auto-complete goal when stopping model without backgrou…
panlilu May 26, 2026
8245373
feat(pull): add force option to discard local changes during pull
panlilu May 26, 2026
b93b731
fix(pull): update error handling for merge failures and improve user …
panlilu May 26, 2026
e96f280
fix(pull): enhance force pull operation to handle merge aborts and su…
panlilu May 26, 2026
57d35dc
fix(pull): improve force pull operation to handle stuck merges and en…
panlilu May 26, 2026
203b94e
feat(web): account row expansion — tokens + personal repo URL inline
simpx May 26, 2026
3ef23f9
revert: drop multi-account / public-account implementation (keep desi…
simpx May 26, 2026
ec20ca5
feat(sandbox): switch from bwrap to rootless podman with shared conta…
simpx May 26, 2026
e56f0eb
fix(sandbox): drop extraEnv from container config-hash to stop spurio…
simpx May 26, 2026
0a8cc60
fix(sandbox): pass -i to podman exec for SDK so claude receives stdin
simpx May 26, 2026
4ace3c9
fix(sandbox): suppress post-result SDK exit-137 cleanup noise
simpx May 26, 2026
065be8b
test+fix(api-v1): chat-integration E2E catches the bugs the API tests…
simpx May 27, 2026
8735e24
feat(terminal): enhance terminal functionality with additional xterm …
panlilu May 27, 2026
235a377
feat(loop): implement user-specific loop navigation and storage of la…
panlilu May 27, 2026
ba4e16f
fix(term): remove scrollback replay in attachTerm to prevent cursor m…
panlilu May 27, 2026
939d2fb
feat(term): enhance terminal resizing by reading client dimensions fr…
panlilu May 27, 2026
0bbdd58
feat(docker): update Dockerfile to include podman and subuid/subgid m…
panlilu May 27, 2026
460a42d
fix(ui): adjust overflow behavior in NewLoopDialog and RightPanel for…
panlilu May 27, 2026
0682e2d
feat(loop): add mobile quick-access buttons and drag functionality fo…
panlilu May 27, 2026
f9a7748
refactor(loop): remove unused SSE implementation from useLoopRuntime
panlilu May 27, 2026
0d6d0f8
feat(terminal): add name attribute to xterm.js helper textarea for ac…
panlilu May 27, 2026
920c3d1
feat(term): integrate mise toolchain activation and surface warnings …
panlilu May 27, 2026
ed80afa
test(api-e2e): real CC + mock Anthropic API drives v1 loop API e2e
simpx May 27, 2026
f618307
test(api-e2e): 7 more user-journey scenarios — choice / queue / recon…
simpx May 27, 2026
62929d6
feat(sandbox): per-loop podman image with mise toolchain baked in
simpx May 27, 2026
48c38eb
feat(sandbox): fix container user to `loopat` (uid 2000) regardless o…
simpx May 27, 2026
1971d24
feat(sandbox): graceful toolchain build failure + PTY warning
simpx May 27, 2026
8f1736b
feat(podman): enhance runPodman and ensureSandboxImage with progress …
panlilu May 27, 2026
e23d2bb
Refactor workspace serve to run in a Podman container
panlilu May 27, 2026
dd435ba
feat(sandbox): enable nested rootless podman in every loop
simpx May 27, 2026
2dd50fb
feat: enhance sharing capabilities with external port and protocol op…
panlilu May 27, 2026
dd8294a
fix(port-proxy): use `ss` instead of `lsof` to scan occupied ports
simpx May 28, 2026
0079206
feat(share): Ephemeral Port mode — kernel-assigned per-restart host port
simpx May 28, 2026
11cec58
fix(share): show Share Artifact button when only Ephemeral mode is en…
simpx May 28, 2026
cc01b76
fix(sandbox): cascade base-image changes into per-loop child images
simpx May 28, 2026
925aad6
docs: add context-flow — the loopat working model
simpx May 29, 2026
d64cc37
docs: link context-flow from README
simpx May 30, 2026
56a4d75
feat(context-flow): loops pull from origin/main + /promote skill
simpx May 30, 2026
f0d2d35
feat(context-flow): personal worktree + clone-on-demand repos + unifi…
simpx May 30, 2026
daf1afc
docs: add identity — who a loop acts as
simpx May 30, 2026
b02d8f8
docs: add identity diagram (overview-style)
simpx May 30, 2026
aa1f920
feat(local-hosting): loopat-hosted bare origin for notes/knowledge
simpx May 30, 2026
e60aa23
feat(local-hosting): personal also gets a loopat-hosted bare origin
simpx May 30, 2026
7aa17dd
feat(github): REST client for the five-capability integration contract
simpx May 30, 2026
e059982
feat(github): setupPersonalViaGithub — PAT onboarding orchestration
simpx May 30, 2026
14844a5
fix(personal): ensure personal/ parent dir before swap
simpx May 30, 2026
7539339
feat(github): /api/personal/github endpoint for PAT onboarding
simpx May 30, 2026
dc8e7b2
feat(github): personal onboarding via GitHub token in the UI
simpx May 30, 2026
99abb24
refactor(git-host): pluggable GitHostProvider — add a platform = one …
simpx May 30, 2026
cb9825d
docs(identity): point the integration contract at GitHostProvider / p…
simpx May 30, 2026
684c44f
chore: drop dead code superseded by bare-origin local hosting
simpx May 30, 2026
3484bed
feat(git-host): provider extensions + https-token auth mode
simpx May 30, 2026
f86e863
feat(git-host): platform-level provider config + provider-aware onboa…
simpx May 30, 2026
a6323e2
feat(git-host): repo picker (personal-first) + configurable default repo
simpx May 30, 2026
f4e1c29
docs(context-flow): origin-as-SoT sync model; the UI as a no-AI loop
simpx May 30, 2026
cc07ae3
feat(personal): provider-driven onboarding + origin-as-SoT sync
simpx May 30, 2026
1325a03
docs(context-flow): generalize the UI loop — browser session = worktree
simpx May 31, 2026
50945bd
feat(notes): git-as-database stage 0 — per-user UI-loop worktree + ex…
simpx May 31, 2026
0007e8c
docs(notes-realtime): git-as-database design — git as SoT, realtime b…
simpx May 31, 2026
86e2783
feat(notes): MVP refresh + "remote updated" hint (no realtime push)
simpx May 31, 2026
96058d2
fix(notes): kanban writes go through the per-user worktree + push
simpx May 31, 2026
c229095
feat(dist): publishable npm package + npx launcher; default port → 10001
simpx May 31, 2026
5aff83c
fix(notes): detect the remote's default branch (master vs main)
simpx May 31, 2026
669d535
fix(worktree): rebuild via -B + prune so a removed worktree re-opens …
simpx May 31, 2026
01e75cd
ci: auto-publish to npm on version tag (GitHub Actions)
simpx May 31, 2026
7cb740a
ci: read NPM_TOKEN from the 'release' environment
simpx May 31, 2026
7d8a726
0.1.2
simpx May 31, 2026
c2b9c67
fix(mac): platform-aware preflight for npx loopat on macOS
simpx May 31, 2026
b5cd2f0
feat(host-exec): POC host-cli proxy — run host-only clis on behalf of…
simpx May 31, 2026
4121c63
feat(docker): GHCR auto-publish + buildable image (cargo-free build, …
simpx May 31, 2026
75f9ec8
feat(host-exec): unix-socket channel + sandbox forwarder
simpx May 31, 2026
db71ca7
refactor(host-exec): bake the forwarder into the image — it's native
simpx May 31, 2026
f86625d
feat(host-cli): wire host-cli proxy into podman — no whitelist, mise-…
simpx May 31, 2026
821a308
ci+docs: Node 24 actions, drop provenance attestations, add README ba…
simpx May 31, 2026
d98c187
feat(cli): `loopat uninstall` — clean removal of loopat's own resources
simpx May 31, 2026
ed25241
0.1.3
simpx May 31, 2026
cfd3ba6
feat(podman): per-workspace images + network so uninstall never touch…
simpx May 31, 2026
eb18b96
0.1.4
simpx May 31, 2026
8a35aed
test(e2e): scenario #1 — install → uninstall lifecycle + workspace is…
simpx May 31, 2026
49037a6
test(e2e): scenario #2 — basic context flow (promote → next loop sees…
simpx May 31, 2026
0637914
feat(context): personal repo self-describes kn/notes; loop connects w…
simpx May 31, 2026
724582e
feat(context): every loop git op authenticates as the user via the va…
simpx May 31, 2026
1039efb
test(behavior): add behavior/ case specs; tighten loop git to vault-k…
simpx May 31, 2026
3beea9b
test(behavior): case 02 e2e — per-repo personal permissions over ssh
simpx May 31, 2026
54061b1
0.1.5
simpx May 31, 2026
445b29a
fix(context): sandbox-side promote authenticates with the vault key
simpx May 31, 2026
f95412a
0.1.6
simpx May 31, 2026
e4cb4b9
fix(npx): bind the claude binary into the sandbox when it's outside t…
simpx May 31, 2026
3fd27f8
0.1.7
simpx May 31, 2026
3303500
test(behavior): case 03 e2e — real-AI context flow over ssh (npx + v1…
simpx May 31, 2026
57880c7
test(e2e): cross-platform host ip in context-flow-ai (macOS ipconfig …
simpx May 31, 2026
010de43
docs(behavior): note the corporate-intranet macOS docker-mirror prere…
simpx May 31, 2026
eead9b8
fix(ux): honest bootstrap banner — colors, repos-on-demand, serve ava…
simpx May 31, 2026
f47b022
0.1.8
simpx May 31, 2026
d44f1d8
fix: loop-create git-crypt crash + permanent personal deploy-key + bo…
simpx May 31, 2026
94502f8
0.1.9
simpx May 31, 2026
7f99723
fix(chat): surface errors instead of hanging on "Reasoning…"
simpx May 31, 2026
f8398e2
0.1.10
simpx May 31, 2026
1083922
refactor: remove onboarding mechanism + per-user shell config
simpx May 31, 2026
bcaa8bf
0.1.11
simpx May 31, 2026
f921cdb
feat(personal-repo): add "Show SSH public key" action to imported panel
simpx May 31, 2026
0252c65
0.1.12
simpx May 31, 2026
c4a4bd2
fix(personal-repo): land on ImportedPanel after backing up git-crypt key
simpx May 31, 2026
6984604
0.1.13
simpx May 31, 2026
f34ea14
refactor(context): per-user knowledge/notes/repos — personal wins, no…
simpx May 31, 2026
86209a8
0.1.14
simpx May 31, 2026
7e87a9a
fix(serve): 404 missing build assets instead of SPA-falling-back to i…
simpx May 31, 2026
0845a4e
feat(loops): surface per-user context clone failures as a loop banner
simpx May 31, 2026
dad6dbe
0.1.15
simpx May 31, 2026
47b2425
fix(loops): pick the meaningful clone-failure line for the context wa…
simpx May 31, 2026
4566bd9
docs: record known issues (todo.md) + mac dual-platform test results
simpx May 31, 2026
e9a7324
feat(context): batch4b — declarative /context/repos roster editor + c…
simpx Jun 1, 2026
2ddc498
0.1.16
simpx Jun 1, 2026
47f9286
fix(personal-repo): show VAULT keys (team repos), not the deploy key
simpx Jun 1, 2026
e09cfbb
0.1.17
simpx Jun 1, 2026
2acd5d1
feat(context): background-sync knowledge on open — instant view, fres…
simpx Jun 1, 2026
1bb8b51
0.1.18
simpx Jun 1, 2026
08695d9
feat(context): unify knowledge/notes/personal sync + fix notes per-re…
simpx Jun 1, 2026
b3545de
0.1.19
simpx Jun 1, 2026
6f1edf9
fix(context): personal save pushes to remote (was commit-only, like n…
simpx Jun 1, 2026
8269511
0.1.20
simpx Jun 1, 2026
3ee4a20
feat(sandbox): fetch linux claude on non-linux hosts (postinstall) fo…
simpx Jun 1, 2026
7b9b03d
0.1.21
simpx Jun 1, 2026
7459dfe
fix(sandbox): fetch linux claude at BOOT (npx skips postinstall) via …
simpx Jun 1, 2026
1d6260d
0.1.22
simpx Jun 1, 2026
a6da77d
docs(todo): mark mac linux-claude blocker solved (0.1.22, sandbox exe…
simpx Jun 1, 2026
65ab808
docs: mac real-AI loop verified end-to-end (sandbox linux claude → id…
simpx Jun 1, 2026
80049f5
feat(sandbox): base image from Aliyun AC2 registry (China-reachable U…
simpx Jun 2, 2026
658b937
0.1.23
simpx Jun 2, 2026
68f2dcd
feat(sandbox): prepare base image at startup + fix AC2 apt mirror
simpx Jun 2, 2026
5026dd9
0.1.24
simpx Jun 2, 2026
e2d8fd6
feat(sandbox): pull prebuilt base image from GHCR, fall back to local…
simpx Jun 2, 2026
11a05f0
0.1.25
simpx Jun 2, 2026
fc63b39
fix(boot): print 'ready. open' only after port is listening + image r…
simpx Jun 2, 2026
5b59aaa
0.1.26
simpx Jun 2, 2026
8c15cd9
fix(log): stop leaking 'fatal: not a git repository' + quiet debug sp…
simpx Jun 2, 2026
0f246b7
0.1.27
simpx Jun 2, 2026
9c08b4a
feat(git-host): a dropped-in provider extension auto-activates (no co…
simpx Jun 2, 2026
d067fd5
0.1.28
simpx Jun 2, 2026
b38469d
feat(git-host): provider fully file-driven, config.json no longer con…
simpx Jun 2, 2026
81f606b
0.1.29
simpx Jun 2, 2026
c117f91
fix(context): serialize per-user context + worktree builds (no more c…
simpx Jun 2, 2026
df0f661
0.1.30
simpx Jun 2, 2026
d34c641
feat(onboarding): provider-driven mandatory onboarding gate
simpx Jun 2, 2026
9839e63
0.1.31
simpx Jun 2, 2026
876f19c
chore(gitignore): never commit the internal provider extension / inst…
simpx Jun 2, 2026
5005900
feat(onboarding): provider fully owns the flow (check -> remediation)
simpx Jun 2, 2026
1cb7a99
0.1.32
simpx Jun 2, 2026
9e2e8a4
fix(profiles): source profiles from the user's per-user knowledge repo
simpx Jun 2, 2026
7f8a3f4
0.1.33
simpx Jun 2, 2026
dcc074d
fix(profiles): loop-stats counts from per-user knowledge too
simpx Jun 2, 2026
61042c6
0.1.34
simpx Jun 2, 2026
cc9cd3b
perf(loop): blobless partial clone for the workdir repo
simpx Jun 2, 2026
9ac9c5f
0.1.35
simpx Jun 2, 2026
a21cabb
perf(loop): shallow (depth=1) workdir clone, not blobless
simpx Jun 2, 2026
36bb9a6
0.1.36
simpx Jun 2, 2026
62f43fe
feat(repo): bare mirror cache + worktree for loop workdirs
simpx Jun 2, 2026
a382c93
0.1.37
simpx Jun 2, 2026
1dc55c7
feat(mcp): generalized auth + paste-URL setup flow for url-keyed servers
simpx Jun 2, 2026
94d32df
0.1.38
simpx Jun 2, 2026
12f247a
feat(a2a): in-process A2A (Agent-to-Agent) adapter
simpx Jun 2, 2026
2fb75ea
feat(a2a): standard A2A, per-user agents, editable card + key
simpx Jun 2, 2026
d56a496
0.1.39
simpx Jun 2, 2026
1131c25
fix(personal-repo): show the crypt-key field when importing an encryp…
simpx Jun 2, 2026
6d5ae55
0.1.40
simpx Jun 2, 2026
6394b1d
fix(personal): push the personal repo after a vault write
simpx Jun 2, 2026
f7d6f6f
0.1.41
simpx Jun 2, 2026
adc92a1
feat(onboarding): add 'info' remediation kind for out-of-loopat steps
simpx Jun 2, 2026
df3c7ba
0.1.42
simpx Jun 2, 2026
3c79f03
feat(loop): block terminal+chat while the sandbox toolchain installs
simpx Jun 2, 2026
988385b
0.1.43
simpx Jun 2, 2026
9238596
fix(ssh): force 0600 on the vault ssh key at point-of-use
simpx Jun 2, 2026
22cbfdc
0.1.44
simpx Jun 2, 2026
7776f07
fix(loop-status): broadcast live updates — stop prev-aliasing eating …
simpx Jun 2, 2026
7d0bfc7
0.1.45
simpx Jun 2, 2026
6764524
feat(context): personal repo roster + standard vault ssh key
simpx Jun 2, 2026
e37813f
0.1.46
simpx Jun 2, 2026
fbd493a
fix(sandbox): bind roster repo's bare mirror into the sandbox
simpx Jun 2, 2026
dc5751a
0.1.47
simpx Jun 2, 2026
30f735f
docs: critical-path e2e design (sshd fixture + browser + container + …
simpx Jun 2, 2026
2f4f075
docs: fixture git server is a podman sshd container (isolated, repro)
simpx Jun 2, 2026
0bc5488
docs: drop AI dual-mode — real AI only, simulates a real user
simpx Jun 2, 2026
8bd5c95
docs: dogfood/ dir, first journey = first-5-minutes
simpx Jun 2, 2026
91b759e
docs: implementation plan for dogfood/first-5-minutes
simpx Jun 2, 2026
670269b
test(dogfood): fixture sshd git server image (verified ssh clone)
simpx Jun 2, 2026
454aed6
docs: backfill Task1 findings (pickPort, unlock git account)
simpx Jun 2, 2026
6742067
test(dogfood): playwright config + setup/teardown for first-5-minutes…
simpx Jun 2, 2026
702143d
test(dogfood): self-contained vault — generate fresh ssh key, IDEALAB…
simpx Jun 2, 2026
bf5eb6c
test(dogfood): first-5-minutes Task 3 — create loop from roster1, ass…
simpx Jun 2, 2026
1041e06
test(dogfood): fix notes git url to loopat-fixture Host alias
simpx Jun 2, 2026
a416add
docs: note remote/pre-prod testing as future extension (target-host a…
simpx Jun 2, 2026
a7609d5
test(dogfood): add bun run dogfood script
simpx Jun 2, 2026
82d8cf5
feat(podman): content-hash image tag (drop workspace prefix) — reuse …
simpx Jun 2, 2026
23aef71
fix(sandbox): $HOME = image passwd home (/home/loopat) so ssh resolve…
simpx Jun 2, 2026
ed42d0d
test(dogfood): complete first-5-minutes journey — chat→real AI→termin…
simpx Jun 2, 2026
895de2a
test(dogfood): repos-page journey — roster add persists to personal c…
simpx Jun 2, 2026
264ce27
test(dogfood): second-loop-warm journey — regress content-hash image …
simpx Jun 2, 2026
31f819d
test(dogfood): attach-detach journey — guard config-hash-drift contai…
simpx Jun 2, 2026
83eb935
test(dogfood): context-notes-sync journey — loop pushes notes worktre…
simpx Jun 2, 2026
db44ade
test(dogfood): multi-turn-task journey — real AI tool-use turn verifi…
simpx Jun 2, 2026
6d03d59
test(dogfood): run cases serially (workers=1) — all share one backend…
simpx Jun 2, 2026
37f5d1f
test(dogfood): suite isolation — loopId from create response + per-ca…
simpx Jun 2, 2026
0eb23d5
test(dogfood): de-flake first-5-minutes — chat is reply-only (no git …
simpx Jun 3, 2026
2dba74d
0.1.48
simpx Jun 3, 2026
fffc83a
docs: spec for first-run journey redesign (real onboarding via fixtur…
simpx Jun 3, 2026
4323c99
docs: first-run spec — fixture provider mirrors code.ts (token→list→c…
simpx Jun 3, 2026
d2ebf6d
test(dogfood): first-run journey — real onboarding via fixture provid…
simpx Jun 3, 2026
f315176
0.1.49
simpx Jun 3, 2026
db0be2c
test(dogfood): first-run drives UI terminal + reads pubkey from UI
simpx Jun 3, 2026
b4dce1f
test(dogfood): unify fixture notes url (absolute ssh) + first-run ass…
simpx Jun 3, 2026
133d962
fix(sandbox): deterministic vault ssh-key perms at container spawn — …
simpx Jun 3, 2026
fb69f99
0.1.50
simpx Jun 3, 2026
0c8defb
test(dogfood): concurrent-push — non-ff rejection + fetch/rebase/re-p…
simpx Jun 3, 2026
07381b1
fix(sandbox): standard origin/<def> tracking ref — ordinary worktree …
simpx Jun 3, 2026
4ac57e3
0.1.51
simpx Jun 3, 2026
fd319e1
test(dogfood): first-run ends with real AI-push + human-push to origi…
simpx Jun 3, 2026
bf2f4a4
test(dogfood): sync tier — context flow across two independent server…
simpx Jun 4, 2026
98af199
test(dogfood): S2 — assert only UI-exposed truth (kn read needs a loo…
simpx Jun 4, 2026
29766fd
test(dogfood): sync S2/S3 — B sees kn+notes at loop level (sandbox cl…
simpx Jun 4, 2026
f157aef
test(dogfood): sync S6 held-back recovery + S7 deletion propagation
simpx Jun 4, 2026
5702dfc
feat(notes): take-remote discard endpoint — escape hatch from held-ba…
simpx Jun 4, 2026
fc71f9f
0.1.52
simpx Jun 4, 2026
917918c
ci: add test workflow for PR gate
Mingholy Jun 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
23 changes: 23 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
node_modules
node_modules/
*/node_modules
*/node_modules/
*/*/node_modules
*/*/node_modules/
*/*/*/node_modules
*/*/*/node_modules/
.git/
.git
dist/
dist
.vite/
.vite
*.tsbuildinfo
*.log
.env
.env.local
.DS_Store
loopat-data/
loopat-data
server/src/*.js
server/src/*.js.map
20 changes: 20 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- run: bun install
- run: cd server && bun test
52 changes: 52 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Publish Docker image

# Build and push the Docker image to GHCR on a version tag (same v* tags
# that trigger the npm publish). Manually runnable via workflow_dispatch.
#
# Uses the built-in GITHUB_TOKEN — no extra secret needed. The image lands
# at ghcr.io/<owner>/<repo>, e.g. ghcr.io/simpx/loopat.

# Opt all JS actions into the Node 24 runtime (Node 20 is deprecated).
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

on:
push:
tags:
- "v*"
workflow_dispatch:

jobs:
docker:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v5

- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3

- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=semver,pattern={{version}}
type=raw,value=latest

- uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
provenance: false
40 changes: 40 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Publish to npm

# Publish loopat to npm when a version tag is pushed.
#
# Release flow:
# npm version patch # bumps package.json, commits, tags vX.Y.Z
# git push origin main --tags
#
# Setup (one time): add the npm Automation token (bypasses 2FA) as a repo
# secret named NPM_TOKEN — Settings -> Secrets and variables -> Actions.

# Opt all JS actions into the Node 24 runtime (Node 20 is deprecated).
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

on:
push:
tags:
- "v*"

jobs:
publish:
runs-on: ubuntu-latest
environment: release
steps:
- uses: actions/checkout@v5

# Bun is needed to build web/dist (vite) during prepublishOnly.
- uses: oven-sh/setup-bun@v2

# Node provides npm and wires NODE_AUTH_TOKEN into the registry.
- uses: actions/setup-node@v5
with:
node-version: 24
registry-url: https://registry.npmjs.org

# prepublishOnly runs `bun install && bun run build:web` for us.
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
72 changes: 72 additions & 0 deletions .github/workflows/sandbox-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: Publish sandbox image to GHCR

# Build the loopat sandbox base image and push it to GHCR so end users pull a
# ready 700MB+ image instead of apt-installing ~150 packages over a flaky China
# mirror at first run. Tagged by the Containerfile content hash (must match
# baseContainerfileHash() in server/src/podman.ts) so loopat can pull the exact
# image its Containerfile describes; also tagged :<version> and :latest.
#
# Multi-arch (amd64 + arm64): macs are arm64, most linux servers amd64. The
# arm64 leg builds under QEMU emulation — slow (apt + mise can take 10-20 min),
# but this only runs at release time.
#
# One-time setup: after the first successful run, make the GHCR package PUBLIC
# (GitHub -> repo -> Packages -> loopat-sandbox -> Package settings -> Change
# visibility -> Public). Anonymous pulls fail until then, and loopat silently
# falls back to a local build.

on:
push:
tags:
- "v*"
workflow_dispatch:

env:
IMAGE: ghcr.io/${{ github.repository_owner }}/loopat-sandbox

jobs:
publish-sandbox:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4

- name: Compute Containerfile content hash
id: hash
run: |
cd server/templates/sandbox
# Must match baseContainerfileHash(): sha256(Containerfile || loopat-host), first 16 hex.
H=$(cat Containerfile loopat-host | sha256sum | cut -c1-16)
echo "hash=$H" >> "$GITHUB_OUTPUT"
echo "sandbox content hash: $H"

- name: Derive version tag
id: ver
env:
REF_NAME: ${{ github.ref_name }}
run: echo "version=${REF_NAME#v}" >> "$GITHUB_OUTPUT"

- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3

- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push (amd64 + arm64)
uses: docker/build-push-action@v6
with:
context: server/templates/sandbox
file: server/templates/sandbox/Containerfile
platforms: linux/amd64,linux/arm64
push: true
provenance: false
tags: |
${{ env.IMAGE }}:${{ steps.hash.outputs.hash }}
${{ env.IMAGE }}:${{ steps.ver.outputs.version }}
${{ env.IMAGE }}:latest
46 changes: 37 additions & 9 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,15 +1,43 @@
# Nested repos with their own histories
claw-code/
loop/
opencode/
loopat-ts/
node_modules/
dist/
.vite/
.run/
.env
.env.local
*.log
.DS_Store
bun.lock
*.tsbuildinfo
test-results/
playwright-report/
e2e/.auth.json
e2e/.test-meta.json
dogfood/.auth.json
dogfood/.test-meta.json
dogfood/first-run/.test-meta.json
dogfood/sync/.test-meta.json
dogfood/sync/.authA.json
dogfood/sync/.authB.json
server/src/*.js
server/src/*.js.map

# Rust
**/target/

# Python
__pycache__/
*.pyc

# Editor swap / temp files
.*.swp
.*.swo
*~

# JS build artifacts
node_modules/
dist/
.vite/
# Misc
*.tmp

# Internal git-host provider extension + its installer — NOT open-source.
# They carry internal hosts/URLs and are distributed out-of-band (OSS), so they
# must never land in this repo. (Drop into LOOPAT_HOME/extensions/providers/.)
/code.ts
/install.sh
114 changes: 114 additions & 0 deletions CLA.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# loopat Individual Contributor License Agreement

Thank you for your interest in contributing to loopat (the "Project"),
maintained by simpx ("we", "us", or the "Project Maintainer").

This Contributor License Agreement ("Agreement") sets out the terms under
which You ("You" or "Contributor") license Your Contributions to us. It is
modeled on the [Apache Software Foundation Individual CLA v2.2][apache-icla]
and uses the same definitions and structure, simplified for an
individual-maintainer project that may, in the future, transfer ownership to
a successor entity (such as a company or foundation).

By submitting a Contribution to the Project (for example, by opening a
pull request on GitHub and signing the CLA via [CLA Assistant][cla-assistant]),
You accept and agree to the following terms for Your present and future
Contributions.

[apache-icla]: https://www.apache.org/licenses/contributor-agreements.html
[cla-assistant]: https://cla-assistant.io/

---

## 1. Definitions

- **"You"** means the individual who Submits a Contribution to Us.
- **"Contribution"** means any original work of authorship, including any
modifications or additions to existing work, that You intentionally Submit
to Us for inclusion in the Project.
- **"Submit"** means any form of communication sent to Us or our
representatives — including but not limited to pull requests, patches,
issues, mailing lists, and chat — for the purpose of discussing or
improving the Project, except communication that You conspicuously mark
as "Not a Contribution".
- **"Successor"** means any individual or legal entity to whom We assign or
transfer ownership of the Project, in whole or in part. The rights granted
in this Agreement extend to Us and any Successor.

## 2. Grant of Copyright License

You grant to Us and to any Successor a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable copyright license to reproduce, prepare
derivative works of, publicly display, publicly perform, sublicense, and
distribute Your Contributions and such derivative works **under any license
terms We choose**, including but not limited to the Apache License 2.0 and
any later commercial, copyleft, or source-available license.

This sublicensing right is the key purpose of this Agreement: it allows Us
(or any Successor) to relicense the Project as a whole in the future without
having to re-collect permission from every Contributor.

## 3. Grant of Patent License

You grant to Us, to any Successor, and to recipients of the Project
distributed by Us, a perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable (except as stated in this section) patent license
to make, have made, use, offer to sell, sell, import, and otherwise transfer
the Project. This license applies only to those patent claims licensable by
You that are necessarily infringed by Your Contribution alone or by
combination of Your Contribution with the Project.

If any entity institutes patent litigation against You or any other entity
(including a cross-claim or counterclaim in a lawsuit) alleging that Your
Contribution, or the Project to which You have Contributed, constitutes
direct or contributory patent infringement, then any patent licenses
granted to that entity under this Agreement for that Contribution or
Project shall terminate as of the date such litigation is filed.

## 4. You Are Legally Entitled to Grant These Licenses

You represent that:

- Each of Your Contributions is Your original creation, **or**
- Your Contribution includes complete details of any third-party license or
other restriction (including, but not limited to, related patents and
trademarks) of which You are personally aware and which are associated
with any part of Your Contribution.
- If Your employer has rights to intellectual property You create that
includes Your Contributions, You have received permission to make
Contributions on behalf of that employer, or Your employer has waived such
rights for Your Contributions to the Project.

## 5. No Warranty

You provide Your Contributions on an "AS IS" basis, without warranties or
conditions of any kind, either express or implied, including, without
limitation, any warranties of title, non-infringement, merchantability, or
fitness for a particular purpose. You are not expected to provide support
for Your Contributions, except to the extent You desire to provide support.

## 6. Notification of Changes

You agree to notify Us of any facts or circumstances of which You become
aware that would make the representations in Section 4 inaccurate in any
respect.

## 7. Public Record

You acknowledge that We will publicly record the fact that You have signed
this Agreement (typically via [CLA Assistant][cla-assistant]) alongside
Your GitHub username, so that other Contributors and users can verify that
Your Contributions are properly licensed.

---

## How to sign

Open any pull request against <https://github.com/simpx/loopat>. The
CLA Assistant bot will comment with a one-click link to sign this
Agreement. Once signed, all Your present and future Contributions to the
Project are covered — You only need to sign once.

If You prefer, You may also sign by sending an email to
**simpxx@gmail.com** with the subject `loopat CLA: <your-github-username>`
and the text "I agree to the loopat CLA, version 1.0" in the body.
Loading
Loading