mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-11-14 10:39:32 +01:00
fix(worktrees): the injected agent skill no longer blocks removal
With Codeman Agent Skill on (agentSkillEnabled), every session create writes the skill into the folder the session runs in, so a session in a worktree leaves an untracked .claude/skills/codeman/ (claude) or .agents/skills/codeman/ (codex, gemini and the rest) behind. git then refuses `git worktree remove` for that worktree forever, and an agent running `git add -A` there would commit Codeman's skill into its branch (reproduced: the worktree's status showed "?? .agents/" and "?? .claude/"). A create now excludes <skills dir>/codeman/ next to the hooks file, for every skills folder the registry names (capabilities.agentSkillDir, read at call time by the route and passed in as data, so no CLI id is branched on). Like the other lines it is only added when git does not already ignore the path, and only to the repository's local info/exclude. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
64fea4ff84
commit
28cbbad591
7 files changed
+90
-8
No files matched your search
@@ -29,6 +29,8 @@ import { readDockerCases } from '../../docker-hosts.js';
|
||||
import { readRemoteCases } from '../../remote-hosts.js';
|
||||
import { dataPath, getDataDir } from '../../config/instance.js';
|
||||
import { isMultiUserMode } from '../../config/multiuser.js';
|
||||
import { listClis } from '../../config/cli-registry/registry.js';
|
||||
import { agentSkillDir } from '../../hooks-config.js';
|
||||
import { describeUnknownPath, probePathKind } from '../../utils/index.js';
|
||||
import {
|
||||
createCaseWorktree,
|
||||
@@ -65,6 +67,19 @@ const SAFE_CASE_NAME = /^[a-zA-Z0-9_-]+$/;
|
||||
const defaultDockerWorkspaces = async (): Promise<string[]> =>
|
||||
(await readDockerCases(getDataDir()).catch(() => [])).map((c) => c.hostWorkspacePath).filter(Boolean);
|
||||
|
||||
/**
|
||||
* Every workspace skills folder a session of some registry CLI gets Codeman's agent skill in
|
||||
* (`capabilities.agentSkillDir`), read from the registry at call time as data, never by CLI id.
|
||||
*/
|
||||
const registryAgentSkillDirs = (): string[] => {
|
||||
const dirs = new Set<string>();
|
||||
for (const cli of listClis()) {
|
||||
const dir = agentSkillDir(cli.capabilities);
|
||||
if (dir) dirs.add(dir);
|
||||
}
|
||||
return [...dirs];
|
||||
};
|
||||
|
||||
/** A live session in a worktree, as the list reports it to a caller who may see it. */
|
||||
export interface WorktreeSessionRef {
|
||||
id: string;
|
||||
@@ -239,7 +254,10 @@ export function registerWorktreeRoutes(
|
||||
if (nameError) return failWith(reply, ApiErrorCode.INVALID_INPUT, nameError);
|
||||
const resolved = await caseRepository(req, reply, name);
|
||||
if (!resolved.ok) return resolved.fail;
|
||||
const created = await createCaseWorktree(resolved.repo, body, { git: deps.git });
|
||||
const created = await createCaseWorktree(resolved.repo, body, {
|
||||
git: deps.git,
|
||||
agentSkillDirs: registryAgentSkillDirs(),
|
||||
});
|
||||
if (!created.ok) return failFrom(reply, created);
|
||||
reply.code(201);
|
||||
return { success: true, data: { worktree: created.worktree } };
|
||||
|
||||
Reference in new issue
Block a user