inscript 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.
- inscript-0.1.0/LICENSE +21 -0
- inscript-0.1.0/PKG-INFO +79 -0
- inscript-0.1.0/README.md +59 -0
- inscript-0.1.0/inscript.egg-info/PKG-INFO +79 -0
- inscript-0.1.0/inscript.egg-info/SOURCES.txt +10 -0
- inscript-0.1.0/inscript.egg-info/dependency_links.txt +1 -0
- inscript-0.1.0/inscript.egg-info/entry_points.txt +3 -0
- inscript-0.1.0/inscript.egg-info/top_level.txt +1 -0
- inscript-0.1.0/pyproject.toml +34 -0
- inscript-0.1.0/setup.cfg +4 -0
- inscript-0.1.0/trace_pkg/__init__.py +60 -0
- inscript-0.1.0/trace_pkg/hook.py +78 -0
inscript-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Andrew Park
|
|
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.
|
inscript-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: inscript
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Universal agent context tracking. Know what codebase the agent is working in.
|
|
5
|
+
Author: Andrew Park
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/aardpark/trace
|
|
8
|
+
Keywords: ai,agent,context,mcp,claude
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# trace
|
|
22
|
+
|
|
23
|
+
Universal agent context tracking.
|
|
24
|
+
|
|
25
|
+
When an AI agent works on code, **trace** records which project it's in. Any tool — MCP servers, hooks, scripts — can read `~/.trace/active_project` to know the current context.
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install trace
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## How it works
|
|
34
|
+
|
|
35
|
+
A Claude Code hook fires on every file operation (Read, Edit, Write). It extracts the git root from the file path and writes it to `~/.trace/active_project`. That's it.
|
|
36
|
+
|
|
37
|
+
Any tool can read this file. No coordination needed.
|
|
38
|
+
|
|
39
|
+
## Python API
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
from trace_pkg import active_project
|
|
43
|
+
|
|
44
|
+
project = active_project() # Path("/Users/you/your-project") or None
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## CLI
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
trace # print active project
|
|
51
|
+
trace set . # manually set active project
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Claude Code setup
|
|
55
|
+
|
|
56
|
+
Add to `~/.claude/settings.json`:
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"hooks": {
|
|
61
|
+
"PostToolUse": [
|
|
62
|
+
{
|
|
63
|
+
"matcher": "Read|Edit|Write|Glob|Grep",
|
|
64
|
+
"hooks": [
|
|
65
|
+
{
|
|
66
|
+
"type": "command",
|
|
67
|
+
"command": "trace-hook",
|
|
68
|
+
"async": true
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Why
|
|
78
|
+
|
|
79
|
+
MCP servers need to know what project the agent is working in. Without trace, each server has to guess from cwd, env vars, or explicit configuration. With trace, there's one source of truth that updates automatically.
|
inscript-0.1.0/README.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# trace
|
|
2
|
+
|
|
3
|
+
Universal agent context tracking.
|
|
4
|
+
|
|
5
|
+
When an AI agent works on code, **trace** records which project it's in. Any tool — MCP servers, hooks, scripts — can read `~/.trace/active_project` to know the current context.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install trace
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## How it works
|
|
14
|
+
|
|
15
|
+
A Claude Code hook fires on every file operation (Read, Edit, Write). It extracts the git root from the file path and writes it to `~/.trace/active_project`. That's it.
|
|
16
|
+
|
|
17
|
+
Any tool can read this file. No coordination needed.
|
|
18
|
+
|
|
19
|
+
## Python API
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from trace_pkg import active_project
|
|
23
|
+
|
|
24
|
+
project = active_project() # Path("/Users/you/your-project") or None
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## CLI
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
trace # print active project
|
|
31
|
+
trace set . # manually set active project
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Claude Code setup
|
|
35
|
+
|
|
36
|
+
Add to `~/.claude/settings.json`:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"hooks": {
|
|
41
|
+
"PostToolUse": [
|
|
42
|
+
{
|
|
43
|
+
"matcher": "Read|Edit|Write|Glob|Grep",
|
|
44
|
+
"hooks": [
|
|
45
|
+
{
|
|
46
|
+
"type": "command",
|
|
47
|
+
"command": "trace-hook",
|
|
48
|
+
"async": true
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Why
|
|
58
|
+
|
|
59
|
+
MCP servers need to know what project the agent is working in. Without trace, each server has to guess from cwd, env vars, or explicit configuration. With trace, there's one source of truth that updates automatically.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: inscript
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Universal agent context tracking. Know what codebase the agent is working in.
|
|
5
|
+
Author: Andrew Park
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/aardpark/trace
|
|
8
|
+
Keywords: ai,agent,context,mcp,claude
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# trace
|
|
22
|
+
|
|
23
|
+
Universal agent context tracking.
|
|
24
|
+
|
|
25
|
+
When an AI agent works on code, **trace** records which project it's in. Any tool — MCP servers, hooks, scripts — can read `~/.trace/active_project` to know the current context.
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install trace
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## How it works
|
|
34
|
+
|
|
35
|
+
A Claude Code hook fires on every file operation (Read, Edit, Write). It extracts the git root from the file path and writes it to `~/.trace/active_project`. That's it.
|
|
36
|
+
|
|
37
|
+
Any tool can read this file. No coordination needed.
|
|
38
|
+
|
|
39
|
+
## Python API
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
from trace_pkg import active_project
|
|
43
|
+
|
|
44
|
+
project = active_project() # Path("/Users/you/your-project") or None
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## CLI
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
trace # print active project
|
|
51
|
+
trace set . # manually set active project
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Claude Code setup
|
|
55
|
+
|
|
56
|
+
Add to `~/.claude/settings.json`:
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"hooks": {
|
|
61
|
+
"PostToolUse": [
|
|
62
|
+
{
|
|
63
|
+
"matcher": "Read|Edit|Write|Glob|Grep",
|
|
64
|
+
"hooks": [
|
|
65
|
+
{
|
|
66
|
+
"type": "command",
|
|
67
|
+
"command": "trace-hook",
|
|
68
|
+
"async": true
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Why
|
|
78
|
+
|
|
79
|
+
MCP servers need to know what project the agent is working in. Without trace, each server has to guess from cwd, env vars, or explicit configuration. With trace, there's one source of truth that updates automatically.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
trace_pkg
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "inscript"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Universal agent context tracking. Know what codebase the agent is working in."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [
|
|
13
|
+
{name = "Andrew Park"},
|
|
14
|
+
]
|
|
15
|
+
keywords = ["ai", "agent", "context", "mcp", "claude"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 3 - Alpha",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.10",
|
|
21
|
+
"Programming Language :: Python :: 3.11",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Topic :: Software Development :: Libraries",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[project.urls]
|
|
27
|
+
Homepage = "https://github.com/aardpark/trace"
|
|
28
|
+
|
|
29
|
+
[project.scripts]
|
|
30
|
+
trace = "trace_pkg:cli"
|
|
31
|
+
trace-hook = "trace_pkg.hook:main"
|
|
32
|
+
|
|
33
|
+
[tool.setuptools.packages.find]
|
|
34
|
+
include = ["trace_pkg*"]
|
inscript-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""Trace — universal agent context tracking.
|
|
2
|
+
|
|
3
|
+
Tracks what codebase an AI agent is working in. Any tool can read
|
|
4
|
+
~/.trace/active_project to know the current project context.
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
from trace_pkg import active_project, set_active_project
|
|
8
|
+
|
|
9
|
+
# Read current project
|
|
10
|
+
project = active_project() # Path or None
|
|
11
|
+
|
|
12
|
+
# Set current project (usually done by the hook)
|
|
13
|
+
set_active_project("/path/to/project")
|
|
14
|
+
"""
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
__version__ = "0.1.0"
|
|
20
|
+
|
|
21
|
+
TRACE_DIR = Path.home() / ".trace"
|
|
22
|
+
ACTIVE_PROJECT_FILE = TRACE_DIR / "active_project"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def active_project() -> Path | None:
|
|
26
|
+
"""Read the currently active project path."""
|
|
27
|
+
try:
|
|
28
|
+
text = ACTIVE_PROJECT_FILE.read_text().strip()
|
|
29
|
+
if text:
|
|
30
|
+
p = Path(text)
|
|
31
|
+
if p.is_dir():
|
|
32
|
+
return p
|
|
33
|
+
except (OSError, ValueError):
|
|
34
|
+
pass
|
|
35
|
+
return None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def set_active_project(path: str | Path) -> None:
|
|
39
|
+
"""Set the active project path."""
|
|
40
|
+
TRACE_DIR.mkdir(parents=True, exist_ok=True)
|
|
41
|
+
ACTIVE_PROJECT_FILE.write_text(str(Path(path).resolve()) + "\n")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def cli() -> None:
|
|
45
|
+
"""CLI entry point."""
|
|
46
|
+
import sys
|
|
47
|
+
|
|
48
|
+
if len(sys.argv) > 1 and sys.argv[1] == "set":
|
|
49
|
+
if len(sys.argv) < 3:
|
|
50
|
+
print("Usage: trace set <path>", file=sys.stderr)
|
|
51
|
+
sys.exit(1)
|
|
52
|
+
set_active_project(sys.argv[2])
|
|
53
|
+
print(f"Active project: {Path(sys.argv[2]).resolve()}")
|
|
54
|
+
else:
|
|
55
|
+
project = active_project()
|
|
56
|
+
if project:
|
|
57
|
+
print(project)
|
|
58
|
+
else:
|
|
59
|
+
print("No active project", file=sys.stderr)
|
|
60
|
+
sys.exit(1)
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"""Claude Code PostToolUse hook — tracks the active project.
|
|
2
|
+
|
|
3
|
+
Reads tool input JSON from stdin, extracts file paths, finds the git root,
|
|
4
|
+
and writes to ~/.trace/active_project.
|
|
5
|
+
|
|
6
|
+
Install as a hook or run directly:
|
|
7
|
+
echo '{"tool_input":{"file_path":"/some/repo/file.py"}}' | trace-hook
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import json
|
|
12
|
+
import re
|
|
13
|
+
import sys
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
from . import TRACE_DIR, ACTIVE_PROJECT_FILE
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _extract_path(data: dict) -> str | None:
|
|
20
|
+
"""Extract a file path from hook input JSON."""
|
|
21
|
+
inp = data.get("tool_input", {})
|
|
22
|
+
|
|
23
|
+
# Direct file_path field (Read, Edit, Write)
|
|
24
|
+
path = inp.get("file_path") or inp.get("path")
|
|
25
|
+
if path and path.startswith("/"):
|
|
26
|
+
return path
|
|
27
|
+
|
|
28
|
+
# Bash command — extract first absolute path
|
|
29
|
+
command = inp.get("command", "")
|
|
30
|
+
if command:
|
|
31
|
+
matches = re.findall(r"(/[^\s;|&\"']+)", command)
|
|
32
|
+
if matches:
|
|
33
|
+
return matches[0]
|
|
34
|
+
|
|
35
|
+
return None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _find_git_root(path: str) -> Path | None:
|
|
39
|
+
"""Walk up from path to find the git root."""
|
|
40
|
+
p = Path(path)
|
|
41
|
+
if p.is_file():
|
|
42
|
+
p = p.parent
|
|
43
|
+
while p != p.parent:
|
|
44
|
+
if (p / ".git").exists():
|
|
45
|
+
return p
|
|
46
|
+
p = p.parent
|
|
47
|
+
return None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def main() -> None:
|
|
51
|
+
"""Entry point for the hook."""
|
|
52
|
+
try:
|
|
53
|
+
data = json.load(sys.stdin)
|
|
54
|
+
except (json.JSONDecodeError, EOFError):
|
|
55
|
+
return
|
|
56
|
+
|
|
57
|
+
path = _extract_path(data)
|
|
58
|
+
if not path:
|
|
59
|
+
return
|
|
60
|
+
|
|
61
|
+
root = _find_git_root(path)
|
|
62
|
+
if not root:
|
|
63
|
+
return
|
|
64
|
+
|
|
65
|
+
# Only write if changed
|
|
66
|
+
try:
|
|
67
|
+
current = ACTIVE_PROJECT_FILE.read_text().strip()
|
|
68
|
+
if current == str(root):
|
|
69
|
+
return
|
|
70
|
+
except OSError:
|
|
71
|
+
pass
|
|
72
|
+
|
|
73
|
+
TRACE_DIR.mkdir(parents=True, exist_ok=True)
|
|
74
|
+
ACTIVE_PROJECT_FILE.write_text(str(root) + "\n")
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
if __name__ == "__main__":
|
|
78
|
+
main()
|