From d8c50930e89c5074a0b8d5adb9ed960e106563bf Mon Sep 17 00:00:00 2001 From: GeminiVibe Date: Mon, 9 Nov 2026 12:56:46 +0000 Subject: [PATCH 1/2] Key a session by $TOKENECONOMIZER_REPO when its directory holds no git metadata A session in an export of a checkout (a container or sandbox that receives the working files without `.git`, a fresh folder per run) is keyed by its directory today, so every run starts a new repository and nothing learned carries over. `$TOKENECONOMIZER_REPO`, when set, is the repository's remote URL and takes the place of the one read from git, so such a session is keyed as a clone of that remote and shares what its clones learned. Unset or empty: no change. --- tests/test_repo_key_env.py | 50 +++++++++++++++++++++++++++++++++ tokeneconomizer/plugin/paths.py | 14 +++++++-- 2 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 tests/test_repo_key_env.py diff --git a/tests/test_repo_key_env.py b/tests/test_repo_key_env.py new file mode 100644 index 0000000..6bc08e5 --- /dev/null +++ b/tests/test_repo_key_env.py @@ -0,0 +1,50 @@ +"""`$TOKENECONOMIZER_REPO`: the repository of a session whose directory holds no git metadata.""" +import os + +from tokeneconomizer.plugin import paths + + +def git_repo(root, remote): + os.makedirs(os.path.join(root, ".git"), exist_ok=True) + with open(os.path.join(root, ".git", "HEAD"), "w") as fh: + fh.write("ref: refs/heads/main\n") + with open(os.path.join(root, ".git", "config"), "w") as fh: + fh.write(f'[core]\n\trepositoryformatversion = 0\n[remote "origin"]\n\turl = {remote}\n') + return root + + +def make_env(tmp_path, **extra): + home = tmp_path / "home" + home.mkdir(exist_ok=True) + return dict({"TOKENECONOMIZER_HOME": str(tmp_path / "te"), "HOME": str(home)}, **extra) + + +def test_a_named_remote_keys_an_export_without_git_metadata_as_its_clones(tmp_path): + """An export of a checkout in a container, or a new folder per run, holds no `.git`; the + variable names its repository, so it shares its clones' key.""" + env = make_env(tmp_path) + named = make_env(tmp_path, TOKENECONOMIZER_REPO="git@github.com:Microsoft/TokenEconomizer.git") + clone = git_repo(str(tmp_path / "TokenEconomizer"), "https://github.com/microsoft/TokenEconomizer") + export = tmp_path / "runs" / "job-1" / "work" + export.mkdir(parents=True) + r = paths.repo_identity(str(export), named) + assert r.key == paths.repo_identity(clone, env).key + assert r.how == paths.BY_REMOTE and r.root == str(export) + assert r.label == "microsoft/tokeneconomizer" and r.remote == "github.com/microsoft/tokeneconomizer" + # Another run's folder gets the same key; without the variable each folder is its own. + other = tmp_path / "runs" / "job-2" / "work" + other.mkdir(parents=True) + assert paths.repo_identity(str(other), named).key == r.key + plain = paths.repo_identity(str(other), env) + assert plain.how == paths.BY_DIR and plain.key != r.key + + +def test_an_empty_value_changes_nothing_and_a_set_one_names_the_repository(tmp_path): + env = make_env(tmp_path) + export = tmp_path / "work" + export.mkdir() + assert paths.repo_identity(str(export), make_env(tmp_path, TOKENECONOMIZER_REPO="")).how == paths.BY_DIR + named = make_env(tmp_path, TOKENECONOMIZER_REPO="https://github.com/microsoft/TokenEconomizer") + elsewhere = git_repo(str(tmp_path / "elsewhere"), "https://example.org/team/elsewhere.git") + assert paths.repo_identity(elsewhere, named).key == paths.repo_identity(str(export), named).key + assert paths.repo_identity(elsewhere, env).key != paths.repo_identity(elsewhere, named).key diff --git a/tokeneconomizer/plugin/paths.py b/tokeneconomizer/plugin/paths.py index 6c4a27c..1297299 100644 --- a/tokeneconomizer/plugin/paths.py +++ b/tokeneconomizer/plugin/paths.py @@ -21,6 +21,8 @@ from dataclasses import dataclass HOME_ENV = "TOKENECONOMIZER_HOME" +# Names the repository of a session whose directory holds no git metadata, by its remote URL. +REPO_ENV = "TOKENECONOMIZER_REPO" def state_root(env=None): @@ -234,10 +236,18 @@ def repo_identity(cwd, env=None): it has one (every clone, worktree and re-clone), else the real path of its main checkout (a linked worktree shares its clone's), else -- outside any checkout -- the directory itself. The key's readable part is the repository's name (the remote's last component, or the main - checkout's folder), not the folder one particular checkout sits in.""" + checkout's folder), not the folder one particular checkout sits in. + + `$TOKENECONOMIZER_REPO`, when set, is the repository's remote URL and takes the place of the + one read from git: a session in a directory that holds no git metadata -- an export of a + checkout in a container or a sandbox, a fresh folder per run -- is then keyed as a clone of + that remote is, and shares what was learned there.""" + env = os.environ if env is None else env found = find_repo_root(cwd, env) root = found or os.path.abspath(cwd or os.getcwd()) - remote = normalize_remote(origin_url(root)) if found else "" + remote = normalize_remote(env.get(REPO_ENV) or "") + if not remote and found: + remote = normalize_remote(origin_url(root)) if remote: how, canon, name = BY_REMOTE, remote, remote.rstrip("/").rsplit("/", 1)[-1] label = "/".join(remote.split("/")[-2:]) From 9327a6f96c29d33c6cecf2b86d116dabfe9510e2 Mon Sep 17 00:00:00 2001 From: Aaron Date: Tue, 10 Nov 2026 10:22:03 -0800 Subject: [PATCH 2/2] repo key: $TOKENECONOMIZER_REPO only where git names no remote A checkout's own origin wins, so a value left set in a shell never merges other repositories into one key. A checkout without an origin takes the named remote. Documented in docs/PLUGIN.md. --- docs/PLUGIN.md | 4 ++++ tests/test_repo_key_env.py | 16 +++++++++++----- tokeneconomizer/plugin/paths.py | 15 ++++++++------- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/docs/PLUGIN.md b/docs/PLUGIN.md index 2e09257..8de0510 100644 --- a/docs/PLUGIN.md +++ b/docs/PLUGIN.md @@ -703,6 +703,10 @@ Which repository a session belongs to (`plugin/paths.py`, `plugin/repos.py`): `gitdir:` file naming one that exists -- and the walk up from a session's directory stops at the home directory, so a versioned (or stray, empty) `~/.git` is the repository of sessions started in `~` and of nothing below it. `GIT_CEILING_DIRECTORIES` is honoured as git does. + `$TOKENECONOMIZER_REPO`, when set, is the repository's remote URL where git names none: a + session in a directory without git metadata (an export of a checkout in a container, a new + folder per run), or in a checkout without an `origin`, is keyed as a clone of that remote and + shares what was learned there. A checkout's own `origin` wins. * **One repository per session.** A hook's `cwd` is where the agent is now (Claude Code's follows its `cd`), so the first hook of a session pins it (`sessions//.json`) and every later hook, and the fold it hands off, uses the repository it started in -- where the diff --git a/tests/test_repo_key_env.py b/tests/test_repo_key_env.py index 6bc08e5..25fecf0 100644 --- a/tests/test_repo_key_env.py +++ b/tests/test_repo_key_env.py @@ -1,4 +1,4 @@ -"""`$TOKENECONOMIZER_REPO`: the repository of a session whose directory holds no git metadata.""" +"""`$TOKENECONOMIZER_REPO`: the repository of a session where git names none.""" import os from tokeneconomizer.plugin import paths @@ -9,7 +9,8 @@ def git_repo(root, remote): with open(os.path.join(root, ".git", "HEAD"), "w") as fh: fh.write("ref: refs/heads/main\n") with open(os.path.join(root, ".git", "config"), "w") as fh: - fh.write(f'[core]\n\trepositoryformatversion = 0\n[remote "origin"]\n\turl = {remote}\n') + fh.write("[core]\n\trepositoryformatversion = 0\n" + + (f'[remote "origin"]\n\turl = {remote}\n' if remote else "")) return root @@ -39,12 +40,17 @@ def test_a_named_remote_keys_an_export_without_git_metadata_as_its_clones(tmp_pa assert plain.how == paths.BY_DIR and plain.key != r.key -def test_an_empty_value_changes_nothing_and_a_set_one_names_the_repository(tmp_path): +def test_an_empty_value_changes_nothing_and_a_checkouts_own_remote_wins(tmp_path): env = make_env(tmp_path) export = tmp_path / "work" export.mkdir() assert paths.repo_identity(str(export), make_env(tmp_path, TOKENECONOMIZER_REPO="")).how == paths.BY_DIR named = make_env(tmp_path, TOKENECONOMIZER_REPO="https://github.com/microsoft/TokenEconomizer") + # A checkout keeps the repository its `origin` names: a value left set in a shell must not + # merge every repository the person opens into one. elsewhere = git_repo(str(tmp_path / "elsewhere"), "https://example.org/team/elsewhere.git") - assert paths.repo_identity(elsewhere, named).key == paths.repo_identity(str(export), named).key - assert paths.repo_identity(elsewhere, env).key != paths.repo_identity(elsewhere, named).key + assert paths.repo_identity(elsewhere, named) == paths.repo_identity(elsewhere, env) + # A checkout without an `origin` (a fresh `git init` in a sandbox) takes the named one. + fresh = git_repo(str(tmp_path / "fresh"), None) + assert paths.repo_identity(fresh, env).how == paths.BY_PATH + assert paths.repo_identity(fresh, named).key == paths.repo_identity(str(export), named).key diff --git a/tokeneconomizer/plugin/paths.py b/tokeneconomizer/plugin/paths.py index 1297299..d52ae56 100644 --- a/tokeneconomizer/plugin/paths.py +++ b/tokeneconomizer/plugin/paths.py @@ -238,16 +238,17 @@ def repo_identity(cwd, env=None): The key's readable part is the repository's name (the remote's last component, or the main checkout's folder), not the folder one particular checkout sits in. - `$TOKENECONOMIZER_REPO`, when set, is the repository's remote URL and takes the place of the - one read from git: a session in a directory that holds no git metadata -- an export of a - checkout in a container or a sandbox, a fresh folder per run -- is then keyed as a clone of - that remote is, and shares what was learned there.""" + `$TOKENECONOMIZER_REPO`, when set, is the repository's remote URL where git names none: a + session in a directory that holds no git metadata -- an export of a checkout in a container + or a sandbox, a fresh folder per run -- or in a checkout without an `origin` is then keyed + as a clone of that remote is, and shares what was learned there. A checkout's own `origin` + wins, so a value left set in a shell never merges another repository's state into it.""" env = os.environ if env is None else env found = find_repo_root(cwd, env) root = found or os.path.abspath(cwd or os.getcwd()) - remote = normalize_remote(env.get(REPO_ENV) or "") - if not remote and found: - remote = normalize_remote(origin_url(root)) + remote = normalize_remote(origin_url(root)) if found else "" + if not remote: + remote = normalize_remote(env.get(REPO_ENV) or "") if remote: how, canon, name = BY_REMOTE, remote, remote.rstrip("/").rsplit("/", 1)[-1] label = "/".join(remote.split("/")[-2:])