Repository navigation
Aggregate one .basou/ across multiple source repos - #44
Merged
Merged
Conversation
A single logical project often spans several checkouts -- an implementation repo, a planning repo, and a shared working directory the AI is launched from. Each AI session is recorded under whichever directory it ran in (Codex keys each rollout by its session cwd; Claude Code stores transcripts per project directory), but the provenance belongs to one workspace. Until now import discovery keyed on a single exact source path, so a multi-repo project captured only the slice whose cwd matched the workspace's own repo root and silently dropped the rest. Let one .basou/ aggregate the native logs of multiple source roots, applied symmetrically to the claude-code and codex importers and to basou refresh: - --project <path> is now repeatable on import claude-code, import codex, and refresh. Each path is a source root; several paths union their sessions into the workspace, de-duplicated (a root listed twice, or equal to the repo root, is scanned once). - manifest.import.source_roots: an optional, ordered list of roots relative to the repository root (e.g. ["." , "../basou-workspace"]), so refresh with no arguments aggregates every listed repo. The list is complete -- include "." to keep the host repo. Absent means the host repo only (prior behaviour, unchanged). Entries are validated by a regex that rejects absolute paths, '~' expansion, backslashes, and drive letters, so the committed manifest stays path-clean and portable; the constraint is emitted into the JSON Schema 'pattern' too. - init --source-root <path> (repeatable) seeds source_roots for a new workspace, normalizing each value to a repo-root-relative path. Resolution precedence: explicit --project flags, else the manifest's source_roots, else the repository root alone. The path sanitizer is unchanged: each session is sanitized against its own working_directory, so aggregating siblings never relativizes a path across repositories or leaks an absolute host path. The basou view project field no longer pre-fills the repo root, so a GUI refresh honors source_roots instead of overriding them. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
takashi-matsuyama
force-pushed
the
import/multi-root-source-roots
branch
from
June 7, 2026 03:13
c4abee1 to
721672a
Compare
takashi-matsuyama
added a commit
that referenced
this pull request
Jun 7, 2026
Import is a pull, so the corpus only advances when 'basou refresh' runs. After multi-root capture (#44) fixed which repos are scanned, this closes the currency half: keep the workspace current without a manual step. 'basou refresh --watch [--interval <seconds>]' runs a catch-up refresh on start, then polls the native-log stores (~/.codex/sessions, ~/.claude/projects) and re-imports + regenerates only when they have settled (unchanged since the previous poll, so nothing is captured mid-write) AND changed since the last import. Handoff / decisions regenerate only when something was imported, so AI work in unrelated projects never rewrites this workspace's files. Polling is dependency-free and cross-platform; latency is the interval (default 30s, min 5, max 86400), not real-time. Ctrl-C / SIGTERM stops after the in-flight cycle. --watch rejects --dry-run / --json / --force. The baseline scan is taken before the initial import so a session that appears during the import window is not missed; a pending-regenerate flag retries a failed regeneration; scan errors are pathless and a missing / non-directory root contributes nothing; the abortable sleep leaves no listener behind. A session active at start-up or resumed after settling is recorded only up to that point -- 'basou refresh --force' rebuilds those. Event-driven watching and vendor hooks are deferred. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
6 tasks done
takashi-matsuyama
added a commit
that referenced
this pull request
Jun 8, 2026
Promote the Unreleased changelog to 0.7.0 and bump @basou/core, @basou/cli, @basou/sdk, and the bare `basou` installer to 0.7.0 in lockstep. Publishes two dogfood-proven features already on main plus two folded-in fixes. Features since 0.6.0: - Multi-root capture: one .basou/ workspace can aggregate the native logs of several sibling repositories (#44). - `basou refresh --watch`: keep the workspace current automatically by polling the native-log stores and re-importing only settled, changed sessions (#45). Fixes: - Reject --session combined with --all on import (both adapters). - Drop a reference to a nonexistent `basou session export` from the session-import JSON Schema. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Let one
.basou/workspace aggregate the native logs of multiple sourcerepositories. A single logical project often spans several checkouts (an
implementation repo, a planning repo, and a shared working directory the AI is
launched from). Each session is recorded under whichever directory the AI ran
in, but the provenance belongs to one workspace. Import discovery previously
keyed on a single exact source path, so a multi-repo project captured only the
slice whose
cwdmatched the workspace's own repo root and silently dropped therest.
Why
This is a real coverage gap for any monorepo-of-repos / workspace layout. The
fix is vendor-neutral (both the
claude-codeandcodeximporters) and matchesthe project's stance that cross-tool, cross-checkout capture is the point.
What changed
Applied symmetrically to
basou import claude-code,basou import codex, andbasou refresh:--project <path>— each path is a source root; several pathsunion their sessions into the current workspace, de-duplicated (a root listed
twice, or equal to the repo root, is scanned once).
manifest.import.source_roots— an optional, ordered list of rootsrelative to the repository root (e.g.
[".", "../basou-workspace"]), sobasou refreshwith no arguments aggregates every listed repo. The list iscomplete: include
"."to keep the host repo. Absent means the host repo only(prior behaviour, unchanged). A regex validates entries (rejects absolute
paths,
~-expansion, backslashes, drive letters) and is emitted into the JSONSchema
pattern, so cross-language validators enforce it too.basou init --source-root <path>(repeatable) seedssource_rootsfor anew workspace, normalizing each value to a repo-root-relative path.
Resolution precedence: explicit
--projectflags, else the manifest'ssource_roots, else the repository root alone.Notes on correctness
working_directory, so aggregating siblings never relativizes a path acrossrepositories or leaks an absolute host path beyond the existing pathless
contract.
basou view's project field no longer pre-fills the repo root, so a GUIrefresh honors
source_rootsinstead of silently overriding them.Testing
pnpm -r build && pnpm typecheck && pnpm test && pnpm lintall green(core 743, sdk 17, cli 433; lint 0 errors).
resolved relative to the repo root, de-dup, partial presence (one absent
root),
--sessionacross roots, "not found in any root" errors, schemarejection of absolute/
~/backslash/drive-letter/empty source roots,init --source-rootnormalization, and arefreshmanifest aggregation case.@basou/coreJSON Schema artifacts; the drift-guard test passes.Out of scope
Capture currency / automation (a
refresh --watch/ cron / editor hooks),per-source-root session tagging, and the
--session+--allmutual-exclusionguard are intentionally left as follow-ups.