loom-code 0.1.1__py3-none-any.whl

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. loom_code/__init__.py +22 -0
  2. loom_code/_post_commit.py +119 -0
  3. loom_code/agent.py +544 -0
  4. loom_code/approval.py +616 -0
  5. loom_code/browse/__init__.py +291 -0
  6. loom_code/browse/act.py +467 -0
  7. loom_code/browse/observe.py +249 -0
  8. loom_code/browse/session.py +96 -0
  9. loom_code/browse/verify.py +194 -0
  10. loom_code/checkpoint.py +283 -0
  11. loom_code/cli.py +495 -0
  12. loom_code/code_index.py +703 -0
  13. loom_code/compact.py +143 -0
  14. loom_code/consent.py +47 -0
  15. loom_code/credentials.py +527 -0
  16. loom_code/edit_tool.py +635 -0
  17. loom_code/extensions.py +522 -0
  18. loom_code/file_history.py +322 -0
  19. loom_code/file_tools.py +93 -0
  20. loom_code/git_hook.py +200 -0
  21. loom_code/grep_tool.py +430 -0
  22. loom_code/hooks.py +297 -0
  23. loom_code/loominit/__init__.py +23 -0
  24. loom_code/loominit/_ast_walk.py +429 -0
  25. loom_code/loominit/_files.py +284 -0
  26. loom_code/loominit/_graph.py +141 -0
  27. loom_code/loominit/_resolve.py +392 -0
  28. loom_code/loominit/_tests_map.py +108 -0
  29. loom_code/loominit/extractor.py +332 -0
  30. loom_code/loominit/repomap.py +225 -0
  31. loom_code/loominit/schema.py +242 -0
  32. loom_code/lsp_tools.py +396 -0
  33. loom_code/mcp_host.py +79 -0
  34. loom_code/operator.py +449 -0
  35. loom_code/paste.py +97 -0
  36. loom_code/paths.py +52 -0
  37. loom_code/permissions.py +177 -0
  38. loom_code/project.py +104 -0
  39. loom_code/prompts.py +451 -0
  40. loom_code/render.py +783 -0
  41. loom_code/repl.py +4080 -0
  42. loom_code/rules.py +267 -0
  43. loom_code/sandboxed_bash.py +176 -0
  44. loom_code/scribe.py +88 -0
  45. loom_code/skills/__init__.py +16 -0
  46. loom_code/skills/graphify/SKILL.md +97 -0
  47. loom_code/skills/graphify/tools.py +570 -0
  48. loom_code/trust.py +216 -0
  49. loom_code/turn.py +169 -0
  50. loom_code/web_fetch.py +370 -0
  51. loom_code/workers.py +758 -0
  52. loom_code/worktree.py +134 -0
  53. loom_code-0.1.1.dist-info/METADATA +224 -0
  54. loom_code-0.1.1.dist-info/RECORD +58 -0
  55. loom_code-0.1.1.dist-info/WHEEL +5 -0
  56. loom_code-0.1.1.dist-info/entry_points.txt +2 -0
  57. loom_code-0.1.1.dist-info/licenses/LICENSE +21 -0
  58. loom_code-0.1.1.dist-info/top_level.txt +1 -0
loom_code/worktree.py ADDED
@@ -0,0 +1,134 @@
1
+ """Git worktree lifecycle for session isolation.
2
+
3
+ An *isolated* session edits in its own git worktree on branch
4
+ ``loom/<session_id>`` — a separate working copy of the same repo — so
5
+ two concurrent sessions on one repo (two ``loom-code`` terminals, two
6
+ desktop chat tabs) can't collide on disk. When done, the branch is
7
+ either merged into the base branch or discarded, and the worktree is
8
+ removed.
9
+
10
+ This is the SHARED lifecycle: the loom-code CLI drives it via
11
+ ``/isolate`` `/review` `/merge` `/discard`, and the desktop sidecar can
12
+ use the same functions instead of its own copy.
13
+
14
+ Git-only. Every function degrades gracefully — git failures come back
15
+ as ``(None, error)`` / ``(False, error)`` rather than raising, so a
16
+ bad git state never crashes the REPL.
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ import subprocess
22
+ from dataclasses import dataclass
23
+ from pathlib import Path
24
+
25
+
26
+ @dataclass(frozen=True)
27
+ class WorktreeInfo:
28
+ """A live session worktree: where it is, its branch, and the base
29
+ branch it was forked from (and will merge back into)."""
30
+
31
+ path: Path
32
+ branch: str
33
+ base: str
34
+
35
+
36
+ def _git(
37
+ cwd: Path | str, args: list[str], *, timeout: int = 60
38
+ ) -> tuple[int, str, str]:
39
+ """Run a git subcommand in ``cwd``. Returns (returncode, out, err);
40
+ never raises on a non-zero exit — callers inspect the code."""
41
+ try:
42
+ proc = subprocess.run(
43
+ ["git", *args],
44
+ cwd=str(cwd),
45
+ capture_output=True,
46
+ text=True,
47
+ timeout=timeout,
48
+ )
49
+ except (OSError, subprocess.SubprocessError) as exc:
50
+ return 1, "", str(exc)
51
+ return proc.returncode, proc.stdout, proc.stderr
52
+
53
+
54
+ def is_git_repo(root: Path | str) -> bool:
55
+ return (Path(root) / ".git").exists()
56
+
57
+
58
+ def worktree_path(root: Path | str, session_id: str) -> Path:
59
+ return Path(root) / ".loom" / "worktrees" / session_id
60
+
61
+
62
+ def branch_name(session_id: str) -> str:
63
+ # session ids (chat-<...> / ULIDs) are ref-safe; "loom/" namespaces
64
+ # them so they're easy to spot + bulk-clean.
65
+ return f"loom/{session_id}"
66
+
67
+
68
+ def current_branch(root: Path | str) -> str:
69
+ rc, out, _ = _git(root, ["symbolic-ref", "--short", "HEAD"])
70
+ return out.strip() if rc == 0 and out.strip() else "HEAD"
71
+
72
+
73
+ def create(
74
+ root: Path | str, session_id: str
75
+ ) -> tuple[WorktreeInfo | None, str]:
76
+ """Create a worktree for ``session_id``. Returns ``(info, "")`` or
77
+ ``(None, error)``. Idempotent-ish: if the branch already exists
78
+ (re-isolate after a discard) it's reused."""
79
+ root = Path(root)
80
+ if not is_git_repo(root):
81
+ return None, "not a git repository"
82
+ wt = worktree_path(root, session_id)
83
+ branch = branch_name(session_id)
84
+ base = current_branch(root)
85
+ try:
86
+ wt.parent.mkdir(parents=True, exist_ok=True)
87
+ except OSError as exc:
88
+ return None, f"mkdir failed: {exc}"
89
+ rc, _out, err = _git(root, ["worktree", "add", str(wt), "-b", branch])
90
+ if rc != 0:
91
+ rc2, _o2, err2 = _git(root, ["worktree", "add", str(wt), branch])
92
+ if rc2 != 0:
93
+ return None, (err or err2).strip()
94
+ return WorktreeInfo(path=wt, branch=branch, base=base), ""
95
+
96
+
97
+ def diff(info: WorktreeInfo) -> tuple[str, str]:
98
+ """Unified diff of the worktree (committed-on-branch + uncommitted)
99
+ vs the base branch. Returns ``(diff_text, error)``."""
100
+ rc, out, err = _git(info.path, ["diff", info.base])
101
+ if rc != 0:
102
+ return "", err.strip()
103
+ return out, ""
104
+
105
+
106
+ def merge(root: Path | str, info: WorktreeInfo) -> tuple[bool, str]:
107
+ """Commit the worktree's uncommitted edits (only when dirty), then
108
+ merge its branch into the base branch from the MAIN tree. Returns
109
+ ``(ok, error)``. Refuses if the main tree isn't on the base branch
110
+ (to avoid merging into the wrong branch); aborts on conflict."""
111
+ root = Path(root)
112
+ rc, out, _ = _git(info.path, ["status", "--porcelain"])
113
+ if rc == 0 and out.strip():
114
+ _git(info.path, ["add", "-A"])
115
+ _git(info.path, ["commit", "-m", f"loom session {info.branch}"])
116
+ cur = current_branch(root)
117
+ if cur != info.base:
118
+ return False, (
119
+ f"the main working tree is on '{cur}', not the session's "
120
+ f"base '{info.base}' — switch back before merging"
121
+ )
122
+ rc, _o, err = _git(root, ["merge", "--no-edit", info.branch])
123
+ if rc != 0:
124
+ _git(root, ["merge", "--abort"])
125
+ return False, f"merge conflict: {err.strip()}"
126
+ return True, ""
127
+
128
+
129
+ def remove(root: Path | str, info: WorktreeInfo) -> None:
130
+ """Remove the worktree + delete its branch. Best-effort — used on
131
+ both discard and post-merge cleanup."""
132
+ root = Path(root)
133
+ _git(root, ["worktree", "remove", "--force", str(info.path)])
134
+ _git(root, ["branch", "-D", info.branch])
@@ -0,0 +1,224 @@
1
+ Metadata-Version: 2.4
2
+ Name: loom-code
3
+ Version: 0.1.1
4
+ Summary: loom-code — a loomflow-native terminal coding agent
5
+ Author: Anupam Nautiyal
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 Anupam Nautiyal
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/Anurich/loomflow-cli
29
+ Project-URL: Repository, https://github.com/Anurich/loomflow-cli
30
+ Project-URL: Issues, https://github.com/Anurich/loomflow-cli/issues
31
+ Keywords: ai,agent,cli,coding-assistant,llm,loomflow
32
+ Classifier: Development Status :: 4 - Beta
33
+ Classifier: Environment :: Console
34
+ Classifier: Intended Audience :: Developers
35
+ Classifier: Programming Language :: Python :: 3.11
36
+ Classifier: Programming Language :: Python :: 3.12
37
+ Classifier: Programming Language :: Python :: 3.13
38
+ Classifier: Topic :: Software Development :: Code Generators
39
+ Requires-Python: >=3.11
40
+ Description-Content-Type: text/markdown
41
+ License-File: LICENSE
42
+ Requires-Dist: loomflow[litellm,mcp,web]<0.11,>=0.10.23
43
+ Requires-Dist: rich>=13
44
+ Requires-Dist: prompt-toolkit>=3.0
45
+ Requires-Dist: anthropic
46
+ Requires-Dist: openai
47
+ Requires-Dist: graphifyy<0.9,>=0.8.11
48
+ Requires-Dist: jedi>=0.19
49
+ Provides-Extra: dev
50
+ Requires-Dist: pytest; extra == "dev"
51
+ Requires-Dist: ruff; extra == "dev"
52
+ Requires-Dist: bump-my-version>=0.30; extra == "dev"
53
+ Dynamic: license-file
54
+
55
+ # loom-code
56
+
57
+ **A terminal coding agent built on [loomflow](https://github.com/Anurich/LoomFlow).**
58
+ Plans before it codes, asks before it breaks things, works with any model —
59
+ including free ones.
60
+
61
+ ```
62
+ › add a retry decorator to the http client
63
+
64
+ ● loom
65
+ Added `retry(max_attempts=3, backoff=2.0)` to http/client.py and wired it
66
+ onto get() and post(). Tests pass (14/14).
67
+ ───────────────────────────────────────────── 12,431 in · 217 out · $0.0043
68
+ ```
69
+
70
+ loom-code is a thin terminal shell — the brain is loomflow. The CLI detects
71
+ your project, builds a loomflow `Agent`, streams the run to your terminal,
72
+ and gates destructive tool calls behind an approval prompt. Everything
73
+ load-bearing — the agent loop, tools, planning, memory — is loomflow.
74
+
75
+ ## Highlights
76
+
77
+ - **Plans before it codes.** Every task gets a living plan
78
+ (TodoWrite-style), visible as it progresses, hard to drift from.
79
+ - **Any model, including free ones.** OpenAI, Anthropic, NVIDIA's free
80
+ NIM tier, local Ollama, or anything LiteLLM routes (Groq, Together,
81
+ Azure, Bedrock, Vertex…). `/set_model` walks you through provider →
82
+ API key → model with arrow-key menus.
83
+ - **Claude-Code-style permissions.** Reads are lenient, writes are
84
+ strict. Every write/edit/shell command routes through an approval
85
+ gate with a unified-diff preview. Allow/ask/deny rules, approval
86
+ modes (`default` / `accept-edits` / `plan` / `yolo`), and an
87
+ optional OS-level bash sandbox (`--sandbox`).
88
+ - **Specialist sub-agents on demand.** The main loop can call
89
+ `explore` (read-only investigation) and `review` (independent
90
+ verification) as tools — one coherent thread, specialists when they
91
+ earn their keep.
92
+ - **Session isolation.** `/isolate` runs the session in its own git
93
+ worktree; `/review` shows the diff, `/merge` or `/discard` ends it.
94
+ Auto-checkpoints before every edit; `/undo` restores.
95
+ - **Gets sharper at your repo.** A per-project notebook plus episode
96
+ memory (`.loom/`) — notes the agent used get credited when a turn
97
+ goes well, so future runs surface what worked. `/good` and `/bad`
98
+ train it.
99
+ - **Cost you can see.** Every response closes with that turn's tokens
100
+ and dollar cost (`free` on free tiers). `/cost` has session totals.
101
+ - **MCP out of the box.** Connect Linear, Sentry, Postgres,
102
+ Playwright, or any MCP server; `/mcp` lists what's live.
103
+ - **Goal mode.** `/goal make all tests pass` keeps working until the
104
+ condition is verifiably met.
105
+
106
+ ## Install
107
+
108
+ ```bash
109
+ pipx install git+https://github.com/Anurich/loomflow-cli
110
+ ```
111
+
112
+ (`pip install` works too; `pipx` keeps CLI tools in their own venvs.
113
+ No pipx? `brew install pipx` or `python -m pip install --user pipx`.)
114
+
115
+ Requires Python 3.11+. To update: `pipx upgrade loom-code`.
116
+
117
+ ## Quickstart
118
+
119
+ ```bash
120
+ cd ~/your-project
121
+ loom-code
122
+ ```
123
+
124
+ First run: type `/set_model`, pick a provider with the arrow keys,
125
+ paste your API key once (it's saved for future sessions), pick a
126
+ model. **No paid key?** Pick NVIDIA — free at
127
+ [build.nvidia.com](https://build.nvidia.com).
128
+
129
+ Then just type what you want:
130
+
131
+ ```
132
+ › fix the failing test in tests/test_auth.py
133
+ › add a /users endpoint with pagination
134
+ › why is startup slow? profile it
135
+ ```
136
+
137
+ One-shot mode (does the task, prints a summary, exits):
138
+
139
+ ```bash
140
+ loom-code "add a retry decorator to the http client"
141
+ loom-code --yes "scaffold a FastAPI backend" # skip approval prompts
142
+ ```
143
+
144
+ Works on existing code and empty directories alike — scaffolding new
145
+ projects is a first-class path.
146
+
147
+ ## Models
148
+
149
+ | model string | provider | env key |
150
+ |---|---|---|
151
+ | `claude-opus-4-8`, `claude-sonnet-4-6`, … | Anthropic | `ANTHROPIC_API_KEY` |
152
+ | `gpt-4.1`, `gpt-4.1-mini`, `o4-mini`, … | OpenAI | `OPENAI_API_KEY` |
153
+ | `nvidia/…` (Nemotron, Llama, DeepSeek) | NVIDIA NIM — **free tier** | `NVIDIA_NIM_API_KEY` |
154
+ | `ollama/llama3`, `ollama/qwen2.5-coder`, … | local [Ollama](https://ollama.com) — free, offline | — |
155
+ | `litellm/<provider>/<model>` | anything LiteLLM routes | provider's own |
156
+
157
+ Switch anytime with `/model <name>` or the guided `/set_model`.
158
+ Reasoning models support `/effort low|medium|high`.
159
+
160
+ > Tip: tool-heavy agent work needs a model with solid function
161
+ > calling. On the free NVIDIA tier, `deepseek-v4-pro` and
162
+ > `nemotron-super-49b` hold up well; tiny models fumble tool calls.
163
+
164
+ ## Safety & permissions
165
+
166
+ The permission layer is the boundary, not the working directory:
167
+
168
+ - **Reads** anywhere are allowed; **writes outside the project** are
169
+ only possible for files *you* referenced, and always show a diff
170
+ prompt — in every mode, even `--yes`.
171
+ - **Approval modes** (`/mode`): `default` asks for writes and shell;
172
+ `accept-edits` auto-approves in-project edits; `plan` is read-only;
173
+ `yolo` approves everything except your deny rules.
174
+ - **Rules** live in `.loom/settings.toml` — glob-based
175
+ `allow` / `ask` / `deny` per tool (e.g. `deny = ["edit(*.env)"]`).
176
+ Deny always wins, even in yolo.
177
+ - **Sandbox**: `--sandbox` runs bash under OS-level isolation
178
+ (writes limited to the repo, network off unless
179
+ `--sandbox-allow-network`).
180
+ - Irreversible commands (`git push --force`, `rm -rf`, …) always
181
+ get an explicit prompt.
182
+
183
+ ## Commands
184
+
185
+ Type `/` in the REPL — the menu autocompletes. Highlights:
186
+
187
+ | | |
188
+ |---|---|
189
+ | `/plan` | show or start the living plan |
190
+ | `/goal <condition>` | work until the condition is met |
191
+ | `/undo` · `/checkpoints` | restore / list auto-checkpoints |
192
+ | `/isolate` · `/review` · `/merge` · `/discard` | worktree-isolated sessions |
193
+ | `/model` · `/set_model` · `/effort` · `/mode` | model + approval setup |
194
+ | `/set_web` | web search (Serper / DuckDuckGo) |
195
+ | `/mcp` | list connected MCP servers |
196
+ | `/cost` · `/compact` · `/export` | session accounting + history |
197
+ | `/resume` | pick up the last session for this project |
198
+ | `/good` · `/bad` | credit / debit the agent's notes |
199
+
200
+ ## Project context
201
+
202
+ loom-code reads `LOOM.md` / `CLAUDE.md` / `AGENTS.md` /
203
+ `.loom/context.md` at the project root and treats it as binding house
204
+ rules. `/init-loom` creates a starter file.
205
+
206
+ ## Development
207
+
208
+ ```bash
209
+ git clone https://github.com/Anurich/loomflow-cli
210
+ cd loomflow-cli
211
+ python -m venv .venv && source .venv/bin/activate
212
+ pip install -e ".[dev]"
213
+ pytest -q # 465 tests
214
+ ruff check .
215
+ ```
216
+
217
+ Architecture in one line: **loom-code is deliberately thin** — if a
218
+ capability belongs in the agent loop, it goes in
219
+ [loomflow](https://github.com/Anurich/LoomFlow), not here. See
220
+ `DESIGN.md` for the boundary.
221
+
222
+ ## License
223
+
224
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,58 @@
1
+ loom_code/__init__.py,sha256=am0nt0omKYSWlzGtoVZC2JScZoNy1ncT2SCCIraw5XY,949
2
+ loom_code/_post_commit.py,sha256=wM1E9T-52dXbTF_eHzb6Ve_F02yPTOU1OXGUf1C7hu4,4239
3
+ loom_code/agent.py,sha256=DslJCjfO1P5LrMVBFjCjTrebB1_AMM3GxDuqqrDMjVU,24809
4
+ loom_code/approval.py,sha256=2lNZC4inyF_qggySVxlnJVlZwQgM9GGHFHyWR0E547k,22791
5
+ loom_code/checkpoint.py,sha256=9lCSo88PVfK9_KquX6EqO5nQbIuDdM5Ip2asTNHFDng,10282
6
+ loom_code/cli.py,sha256=GPy5nrXnShfgMtEg0JG7dBn6UCiVhVzPAZ1CKQomic0,17570
7
+ loom_code/code_index.py,sha256=nlUfIXKZ6xMRoMPGl_Scu93i52OZSapBI3_BGqYYMD4,27553
8
+ loom_code/compact.py,sha256=45-iCdMAJ5wcX6lWab8_NZZ_z3VfJO3mAZwNHFsAyUY,5456
9
+ loom_code/consent.py,sha256=Qnyo6TymAmOUxv8JAdv3Px74CJvcF_dXv0xUb3vuGOQ,1721
10
+ loom_code/credentials.py,sha256=0cUjElx6hLBYieeucqzlZAe_ey-nMXpJw1K17nljOn8,21404
11
+ loom_code/edit_tool.py,sha256=34cB9TRpTSfMnD7vFX5kMCrJ9i4SPbUoMOBBEOtmDio,25703
12
+ loom_code/extensions.py,sha256=ClCbZ-anomkTKXUMDrpBdZRp4t07eBXv4zvR8XEPO7A,19031
13
+ loom_code/file_history.py,sha256=6MRi6khIVLt-oF6F4M4OgtaIhPpWs6MeC4GOz0AfAoI,11574
14
+ loom_code/file_tools.py,sha256=08c1jrc9nDxL_jgvWInO-uqhXOscY6exZdUwzBFVGK0,4016
15
+ loom_code/git_hook.py,sha256=gx556a385-dEsctz-HqBj4m-3273PIUT-48x8puH8mM,7415
16
+ loom_code/grep_tool.py,sha256=wtQYRkE6OpY_EeUdd8geLuj4MWt8C2iKFv96ZqLjat0,16593
17
+ loom_code/hooks.py,sha256=x-LX92jOn--uBmDPNcsW1K1h5nqxAGJrfDQZH6FXPow,10992
18
+ loom_code/lsp_tools.py,sha256=R73TSwRs9ZgiKgfJ5xP4sUiBvm5tYlyJjDZhJ8Qq8ss,14739
19
+ loom_code/mcp_host.py,sha256=a-JrPfJKE7s8YuZJFNIAGoH73UwUdFT8zzGtNe0YepU,3165
20
+ loom_code/operator.py,sha256=Qbhnz8CSdZBGi-7DGggP1xbOy4n_8Fd0qqy20vLs3Kc,20773
21
+ loom_code/paste.py,sha256=o7Zq70aCU6HQB6Gziez8jNP8KBVBTbnqAIfeVOnXFww,3437
22
+ loom_code/paths.py,sha256=HHFbDkpXgIQWND1XGWSao_9RVpF9HyZ2fCEpOWDcY2E,2044
23
+ loom_code/permissions.py,sha256=RkxqiHu1eqwaVyaLGHinW4amz69S9i8zC9lW0OTH1h8,6314
24
+ loom_code/project.py,sha256=iEUQOYUA23d06ZlaAcNouei635t5K-B_E-Ri0DPZEB0,3639
25
+ loom_code/prompts.py,sha256=i0NoblhIk58UhQTkHuOFi3yqenDs9C60KpFPLP-P7iQ,21892
26
+ loom_code/render.py,sha256=6fuGpC74WBAw-31qrqwa5XEfMVw_ZZqYEI0eqJ9jYm0,33756
27
+ loom_code/repl.py,sha256=Tja7idGyeAOOsdAmLkTA0wVbKSwBQieGhPyEUe4Emkw,174054
28
+ loom_code/rules.py,sha256=pdy1t8L7ic9nE5bSJPs_FoHxfKdhK0A6-c8JIws7ZMM,9778
29
+ loom_code/sandboxed_bash.py,sha256=kfDfKwgTj7MUjUPutxRUykytjgY8qOjih2OZlRnL88g,6438
30
+ loom_code/scribe.py,sha256=Lz4pT4Xu9RquoQafgaOmkIaodFI252Dttr_6ycKgmMI,3145
31
+ loom_code/trust.py,sha256=Eimvs0OwE9rr8Ve3c3if4wiQaRB6kfgIi0XA_23Hmsc,7655
32
+ loom_code/turn.py,sha256=vl3dZkFVAoiBYpAfsXB5RUSjFcuqHTpxgzwK0MWV1nE,5773
33
+ loom_code/web_fetch.py,sha256=IfMua8sTmCB61T0gpWxe3oC1yst0Ul4tEXmzy1rIaZU,15386
34
+ loom_code/workers.py,sha256=e_mZx-bg5M6g4vEnGxgReJiDivGLYqa_cSZ7Opa4s9w,31333
35
+ loom_code/worktree.py,sha256=CKbiYAvVd6OS3eX89NIeB2KJ1O_rNfUlIuLNu1uZXO8,4782
36
+ loom_code/browse/__init__.py,sha256=nYi8jQBzLGDCZb0W0s6IYX4EV0K2pgJTz304j6tdk2s,12741
37
+ loom_code/browse/act.py,sha256=5h3DeBKJkDbUjniXPBSbqq1vEg23QRlwGwi8HpBtKSM,17015
38
+ loom_code/browse/observe.py,sha256=PJi6OmrIX93MO1Ri5R9qp5kFjs6RhKJmpF5beE0il6E,9337
39
+ loom_code/browse/session.py,sha256=RNPA39oNrhYN_ZTK1dIl2hGL3BNSDkvRI6dmD3jhb-g,3778
40
+ loom_code/browse/verify.py,sha256=zuJhy17BR6iLPu2EZ0bqklxIV72NCrJQY9EHsOj1zG4,7660
41
+ loom_code/loominit/__init__.py,sha256=R4UDbwhmwAOg9QD24zbxeqG4vbdIIrfsFST9FxSzgrM,1166
42
+ loom_code/loominit/_ast_walk.py,sha256=4iSF0SUxSp3gDGVqqeB8TyDrOes3SaLpUu6554qcHTA,15784
43
+ loom_code/loominit/_files.py,sha256=CQWiMf25RRWrePpHlAkwbz95T1T7xJ9bz7hojA0mcTY,9212
44
+ loom_code/loominit/_graph.py,sha256=vtZBdIEyFeXjf9XLrnS0l2p0lMqw09os4_5MMFnmHfA,5184
45
+ loom_code/loominit/_resolve.py,sha256=f-zPHDvSAEn5uw30I9UEIE-OMYo1UYPKWSPlJHqQiFc,14035
46
+ loom_code/loominit/_tests_map.py,sha256=Na6bfsj5gpG-_y1_jT0smRIvs7i3LeSrs_c6e-UkJiI,3604
47
+ loom_code/loominit/extractor.py,sha256=WmMEXAVadPw6vYIB0PiBZwofr_x647T8GFfMP1CzYZY,11803
48
+ loom_code/loominit/repomap.py,sha256=gyyDgfMmo8mNNwWsj4aZPLJxJfJSkz-P65ijluM6C1s,8307
49
+ loom_code/loominit/schema.py,sha256=WVHREn_xXjGtafmMBPkQUeeSFplnkj0ZNTTzw37gl70,9037
50
+ loom_code/skills/__init__.py,sha256=_CeYfPjc82C6AXOIJ8gvhdB-2YbYqx9OwPoZ0_k1U9A,641
51
+ loom_code/skills/graphify/SKILL.md,sha256=sCsZ_J3i1mSCM6IV_WsYVu84LbYOXXbQmF5hy5alSPg,4424
52
+ loom_code/skills/graphify/tools.py,sha256=67LVXOzYE2cM3T061xxuQaQLDXjR810GX_wMoUG1hUM,23316
53
+ loom_code-0.1.1.dist-info/licenses/LICENSE,sha256=Qw2tq9Jw4fNrucoVwMew3TJv281S77WxU4pWvlf9YUk,1072
54
+ loom_code-0.1.1.dist-info/METADATA,sha256=xoztBTcjQiIjfs5qT1fxmVgZnfG_1yKjkVGGAapLq4o,9062
55
+ loom_code-0.1.1.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
56
+ loom_code-0.1.1.dist-info/entry_points.txt,sha256=yRqKU6PZCzbkM3bdbNK3uLEzjkIhTTP3YO5I30H3cPY,49
57
+ loom_code-0.1.1.dist-info/top_level.txt,sha256=scpQuHtufFFRPlPQjrCqkCPWpH-vdjlwZ_H6pH_AbvE,10
58
+ loom_code-0.1.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ loom-code = loom_code.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Anupam Nautiyal
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 @@
1
+ loom_code