arctx-cli 0.2.0b3__tar.gz → 0.2.0b4__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.
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/PKG-INFO +2 -2
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/pyproject.toml +2 -2
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/ext/git/commit.py +22 -1
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_commit.py +58 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/.gitignore +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/README.md +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/__init__.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/alias.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/append_batch.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/__init__.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/alias_cmd.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/anchor.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/current.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/cut.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/dump.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/export.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/ext.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/git.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/graph.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/guide.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/init.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/list.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/migrate.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/node.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/outcomes.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/payload.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/reachable.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/show.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/sync.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/trace.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/transition.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/use.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/view.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/commands/work_session.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/context.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/ext/__init__.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/ext/command/__init__.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/ext/git/__init__.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/ext/git/branch.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/ext/git/cherry_pick.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/ext/git/hook.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/ext/git/merge.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/ext/git/repo.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/ext/git/reset.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/ext/git/revert.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/ext/git/verify.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/ext/git/worktree.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/ext_registry.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/main.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/paths.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/payload_builder.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/src/arctx_cli/workspace.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/__init__.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/__init__.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_alias_cli.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_alias_resolve.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_basic.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_branch.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_cherry_pick.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_command_extension.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_commit_guard.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_ext_cli.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_git_namespace_cli.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_git_repo.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_git_worktree.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_hook_install.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_hook_post_merge.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_hook_post_rewrite.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_init_extension.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_init_hooks.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_init_stag_id.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_merge.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_paths.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_reset.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_revert.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_show_history.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_verify.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/cli/test_work_session.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/fixtures/__init__.py +0 -0
- {arctx_cli-0.2.0b3 → arctx_cli-0.2.0b4}/tests/fixtures/dummy_ext.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: arctx-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.0b4
|
|
4
4
|
Summary: CLI for ARCTX — append-only DAG for reasoning history and parallel agent work
|
|
5
5
|
Project-URL: Homepage, https://github.com/takumiecd/arctx
|
|
6
6
|
Project-URL: Repository, https://github.com/takumiecd/arctx
|
|
@@ -17,7 +17,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
17
17
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
18
|
Classifier: Topic :: Utilities
|
|
19
19
|
Requires-Python: >=3.10
|
|
20
|
-
Requires-Dist: arctx>=0.2.
|
|
20
|
+
Requires-Dist: arctx>=0.2.0b4
|
|
21
21
|
Provides-Extra: dev
|
|
22
22
|
Requires-Dist: black>=23.0; extra == 'dev'
|
|
23
23
|
Requires-Dist: mypy>=1.0; extra == 'dev'
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "arctx-cli"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.0b4"
|
|
8
8
|
description = "CLI for ARCTX — append-only DAG for reasoning history and parallel agent work"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -25,7 +25,7 @@ classifiers = [
|
|
|
25
25
|
"Topic :: Utilities",
|
|
26
26
|
]
|
|
27
27
|
dependencies = [
|
|
28
|
-
"arctx>=0.2.
|
|
28
|
+
"arctx>=0.2.0b4",
|
|
29
29
|
]
|
|
30
30
|
|
|
31
31
|
[project.optional-dependencies]
|
|
@@ -26,6 +26,18 @@ def add_parser(subparsers) -> argparse.ArgumentParser:
|
|
|
26
26
|
help="Drive a git commit and record a arctx transition",
|
|
27
27
|
)
|
|
28
28
|
p.add_argument("-m", "--message", required=True, help="Commit message")
|
|
29
|
+
p.add_argument(
|
|
30
|
+
"--from",
|
|
31
|
+
dest="from_nodes",
|
|
32
|
+
action="append",
|
|
33
|
+
default=None,
|
|
34
|
+
metavar="NODE",
|
|
35
|
+
help=(
|
|
36
|
+
"Branch this commit off the given node instead of the session / "
|
|
37
|
+
"branch tip. Repeat for a fan-in. This is how sibling experiments "
|
|
38
|
+
"fan out from a shared baseline node."
|
|
39
|
+
),
|
|
40
|
+
)
|
|
29
41
|
p.add_argument(
|
|
30
42
|
"--branch",
|
|
31
43
|
default=None,
|
|
@@ -82,6 +94,7 @@ def run_commit_command(
|
|
|
82
94
|
work_session_id: str | None,
|
|
83
95
|
merge: str | None = None,
|
|
84
96
|
join: bool = False,
|
|
97
|
+
from_node_ids: tuple[str, ...] | None = None,
|
|
85
98
|
# Test-only parameters; not exposed in the CLI parser.
|
|
86
99
|
dry_run: bool = False,
|
|
87
100
|
head_commit: str | None = None,
|
|
@@ -136,6 +149,7 @@ def run_commit_command(
|
|
|
136
149
|
branch=branch,
|
|
137
150
|
user_id=user_id,
|
|
138
151
|
work_session_id=work_session_id,
|
|
152
|
+
from_node_ids=from_node_ids,
|
|
139
153
|
dry_run=dry_run,
|
|
140
154
|
head_commit=head_commit,
|
|
141
155
|
)
|
|
@@ -178,6 +192,12 @@ def cli_commit(args) -> int:
|
|
|
178
192
|
user_id = resolve_user_id_from_args(args)
|
|
179
193
|
work_session_id = resolve_work_session_id_from_args(args)
|
|
180
194
|
|
|
195
|
+
from_nodes = getattr(args, "from_nodes", None)
|
|
196
|
+
merge = getattr(args, "merge", None)
|
|
197
|
+
if from_nodes and merge is not None:
|
|
198
|
+
print("error: --from cannot be combined with --merge", file=sys.stderr)
|
|
199
|
+
return 1
|
|
200
|
+
|
|
181
201
|
try:
|
|
182
202
|
result = run_commit_command(
|
|
183
203
|
message=args.message,
|
|
@@ -186,8 +206,9 @@ def cli_commit(args) -> int:
|
|
|
186
206
|
store_dir=args.store_dir,
|
|
187
207
|
user_id=user_id,
|
|
188
208
|
work_session_id=work_session_id,
|
|
189
|
-
merge=
|
|
209
|
+
merge=merge,
|
|
190
210
|
join=getattr(args, "join", False),
|
|
211
|
+
from_node_ids=tuple(from_nodes) if from_nodes else None,
|
|
191
212
|
)
|
|
192
213
|
except ParallelSessionConflict as exc:
|
|
193
214
|
print(f"error: {exc}", file=sys.stderr)
|
|
@@ -146,3 +146,61 @@ class TestCommitCLIIntegration:
|
|
|
146
146
|
|
|
147
147
|
t2 = handle.run_graph.transitions[r2["transition_id"]]
|
|
148
148
|
assert r1["output_node_id"] in t2.input_node_ids
|
|
149
|
+
|
|
150
|
+
def test_from_branches_siblings_off_baseline(self, tmp_path, monkeypatch):
|
|
151
|
+
"""--from anchors the input node, so experiments fan out from a baseline."""
|
|
152
|
+
repo = _init_git_repo(tmp_path / "repo")
|
|
153
|
+
monkeypatch.setenv("ARCTX_HOME", str(_arctx_home(tmp_path)))
|
|
154
|
+
monkeypatch.chdir(repo)
|
|
155
|
+
|
|
156
|
+
_init_arctx(repo, tmp_path, run_id="run_from")
|
|
157
|
+
|
|
158
|
+
from arctx_cli.ext.git.commit import run_commit_command
|
|
159
|
+
|
|
160
|
+
# Baseline commit.
|
|
161
|
+
(repo / "base.txt").write_text("base\n")
|
|
162
|
+
subprocess.run(["git", "add", "base.txt"], cwd=str(repo), check=True, capture_output=True)
|
|
163
|
+
base = run_commit_command(
|
|
164
|
+
message="baseline",
|
|
165
|
+
branch="main",
|
|
166
|
+
run_id="run_from",
|
|
167
|
+
store_dir=_store_dir(tmp_path),
|
|
168
|
+
user_id="user",
|
|
169
|
+
work_session_id="ws_a",
|
|
170
|
+
)
|
|
171
|
+
base_node = base["output_node_id"]
|
|
172
|
+
|
|
173
|
+
# Two experiments, each explicitly branched off the baseline node.
|
|
174
|
+
(repo / "exp.txt").write_text("a\n")
|
|
175
|
+
subprocess.run(["git", "add", "exp.txt"], cwd=str(repo), check=True, capture_output=True)
|
|
176
|
+
a = run_commit_command(
|
|
177
|
+
message="hypothesis A",
|
|
178
|
+
branch="try/a",
|
|
179
|
+
run_id="run_from",
|
|
180
|
+
store_dir=_store_dir(tmp_path),
|
|
181
|
+
user_id="user",
|
|
182
|
+
work_session_id="ws_a",
|
|
183
|
+
from_node_ids=(base_node,),
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
(repo / "exp.txt").write_text("b\n")
|
|
187
|
+
subprocess.run(["git", "add", "exp.txt"], cwd=str(repo), check=True, capture_output=True)
|
|
188
|
+
b = run_commit_command(
|
|
189
|
+
message="hypothesis B",
|
|
190
|
+
branch="try/b",
|
|
191
|
+
run_id="run_from",
|
|
192
|
+
store_dir=_store_dir(tmp_path),
|
|
193
|
+
user_id="user",
|
|
194
|
+
work_session_id="ws_a",
|
|
195
|
+
from_node_ids=(base_node,),
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
store = resolve_store(_store_dir(tmp_path))
|
|
199
|
+
handle = store.load_run("run_from")
|
|
200
|
+
|
|
201
|
+
ta = handle.run_graph.transitions[a["transition_id"]]
|
|
202
|
+
tb = handle.run_graph.transitions[b["transition_id"]]
|
|
203
|
+
# Both experiments hang off the same baseline node — true siblings.
|
|
204
|
+
assert ta.input_node_ids == (base_node,)
|
|
205
|
+
assert tb.input_node_ids == (base_node,)
|
|
206
|
+
assert a["output_node_id"] != b["output_node_id"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|