CommandCodeAI / CommandCodeAI/command-code

Project root is resolved inconsistently across surfaces (git root vs. cwd) — a project's .commandcode/mods/ can be silently unscanned, with no project-scoped override

Open
#861 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
No language data
Stars
4k
Forks
350
PR merge metrics
No merged PRs in 30d

Description

Authorship note: This issue was written by an AI assistant (Command Code) on behalf of a human user who reported the problem and explicitly asked that it be filed. The human reproduced the behavior and directed the diagnosis; the AI wrote this text. No personal, machine, or project-identifying information is included, at the reporter's explicit request — so some template fields below are intentionally left blank rather than partially filled.

The reporter also asked that the point of this issue not be diluted: the project root is not the directory the user started from, and that mismatch is disruptive.

Summary

Project-scoped mods are discovered from the project's .commandcode/mods/ directory. "The project" there is not the directory cmd was launched from — it is a resolved project root, and which directory that resolves to is not only undocumented for mods, it is defined inconsistently across the product's own documentation. When the directory a user considers "the project" is not the one the resolver picks, their mod files live in a place that looks correct, is documented as correct, and is never scanned. /reload does not help, because it re-discovers from the same derived root. There is no project-scoped way to point discovery at the directory the user is actually in.

The root is not even consistent across surfaces

Different surfaces define "the project" differently in the shipped reference documentation:

Surface What the docs say the root is
Skills / settings paths "the git root, or the working directory outside a repo"
${COMMANDCODE_PROJECT_DIR} (skills reference) "The project root (git root, otherwise the current directory)"
COMMANDCODE_PROJECT_DIR (hooks reference) "Absolute path to the project (same as cwd)" — and COMMANDCODE_CWD is documented as an alias with the identical value
Memory (AGENTS.md) "project root" for the project tier; subdirectory memory "walks from that file's directory up to the project root" — the root itself is never defined
Slash commands (.commandcode/commands/) "This project only" — root never defined
Agents (.commandcode/agents/) "This project" — root never defined
Mods (.commandcode/mods/) "<project>" — root never defined

The skills reference and the hooks reference directly contradict each other: one states the project directory is the git root, the other states it is the same as cwd. These are not compatible when the working directory is a subdirectory of a repository.

Reporter's observation, from live use: AGENTS.md is picked up from the working directory, not the git root. That is consistent with the hooks definition and inconsistent with the skills definition — which suggests the two definitions are both real at runtime and applied by different subsystems, rather than one being a documentation error.

Net effect: each surface resolves its own notion of "the project", the definitions disagree, several are undocumented, and nothing tells the user which one was applied. For a user whose working layout does not align with a single repository root, this makes file placement guesswork.

Actual behavior

  • A mod file placed at a .commandcode/mods/ directory that is not the resolved project root is not discovered.
  • /reload restarts and re-discovers mods, but from the same derived root — so a mod written to a different directory stays invisible across reloads.
  • There is no diagnostic. A directory skipped because it falls outside the resolved root and a directory that was never created look identical from the outside.
  • The user's mental model ("I started cmd here, so here is the project") and the resolver's model silently disagree — and per the table above, the resolver's own model is not self-consistent.

Expected behavior

Any one of the first three would resolve the reported problem; a consistent definition would resolve the class of problems.

  1. Resolve from the launch directory, or make that selectable. If two directories can both plausibly be called "the project", the one the user actually cd-ed into should win, or the user should be able to choose.
  2. Add a project-scoped override. Something that points discovery at a directory for this project only — a flag (--project-root, --mods-dir) or a project-scope settings key. A user-global entry is not an equivalent substitute, because it applies the mod in every unrelated repo.
  3. Warn on a near-miss. If a relevant directory exists in the launch directory (or a parent/child) but was not scanned because it falls outside the resolved project root, say so. Silence here is what turns this from an annoyance into a long debugging session.
  4. Pick one definition and apply it everywhere. Define "the project root" once, use it for memory, commands, agents, skills, settings, and mods, and document it on each surface. If a surface genuinely must differ, say so explicitly and say why.
  5. Surface the resolved root. /status already reports environment information — the resolved project root belongs there, and near-miss warnings should name it.

Current workarounds and why they are not equivalent

  • --mod /abs/path/<name>.ts — works, explicit, always loads. Per-session only, so it needs a wrapper/alias to be durable, and it does not fix discovery for anything else in that directory.
  • ~/.commandcode/mods/ — user-scope mods always load and never consult the root. Gives up project locality entirely: a mod that hardcodes one project's commands then surfaces in every unrelated repo.
  • mods.paths with an absolute path — no root to derive, so it works, but it is documented at user scope, so it leaks the same way.

None of these give "this directory is the project, for this project only."

Why this matters more than it looks

Nested repositories, a repository above a directory the user treats as standalone, or a git directory several levels up are all ordinary layouts. In each of them the repository boundary and the user's intent genuinely disagree, and the resolver silently picks one — possibly a different one per surface. The user cannot see which directory was chosen without going looking for it.

This is also not a mods-only issue: AGENTS.md is the highest-traffic instance, since it changes what the model is told about the project on every request. If memory and skills disagree about which AGENTS.md applies, the model's context and the user's intent diverge with no visible signal.

Confidence / what was not verified

Stating this plainly so the report is not overclaimed:

  • The observed symptoms — project mods not detected after reload with no warning, and AGENTS.md being read from the working directory rather than the git root — are the report.
  • The table above is quoted from the shipped reference documentation, not inferred.
  • However, I could not confirm which resolver mods, commands, or agents actually use at runtime, because none of those pages define the root. The mods-relevant diagnosis is inferred from the documented project-root behavior on other surfaces.
  • Other causes can produce a similar mods symptom and were not ruled out: a duplicate tool/mod name (skipped as mod_error), a factory or import that throws, and simply never being scanned by cmd mods list.
  • Request: please state the intended resolution order for mods, commands, agents, and memory, and whether it is meant to be identical to skills/settings.

Documentation asks

  • State the project-root derivation explicitly wherever a project-scoped path is documented, the way the skills reference does — not only on the skills page.
  • Reconcile the hooks reference (COMMANDCODE_PROJECT_DIR == cwd) with the skills reference (project root == git root), or document why they differ.
  • Document cmd mods open --path, which prints the directory actually being scanned — it is the single command that settles this class of question, and it is not obvious that it exists.
  • Consider documenting cmd --debug + ~/.commandcode/logs/command.log alongside it, since the log records discovery and config-load decisions.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with cmd mods open --path to see the directory currently scanned, then use cmd --debug and ~/.commandcode/logs/command.log to trace discovery and config-load decisions. Compare the documented root behavior for skills, hooks, memory, commands, agents, and mods. Done means the root derivation and resolution order are consistent or explicitly documented, with the reported project-scoped discovery case and diagnostics addressed.

Written by the indexing model from the issue text.

Assessment

Tech stack
git
Domain
cli, developer-experience
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.