buddy-agent-harness 0.5.0 → 0.6.0
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.
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor-plugin/plugin.json +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +129 -13
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/{init.command-c0fBv15T.mjs → init.command-zbntulIq.mjs} +347 -45
- package/dist/init.command-zbntulIq.mjs.map +1 -0
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/skills/doctor/SKILL.md +24 -6
- package/skills/init/SKILL.md +6 -3
- package/skills/init/references/harnesses/claude-code.md +2 -0
- package/skills/init/references/harnesses/gemini-cli.md +6 -9
- package/src/diagnose-bridges/agents-files.ts +34 -0
- package/src/diagnose-bridges/diagnose-bridges.ts +18 -8
- package/src/diagnose-bridges/diagnose-instructions.ts +140 -0
- package/src/diagnose-bridges/doctor-guidance.ts +81 -13
- package/src/diagnose-bridges/doctor.command.ts +8 -2
- package/src/diagnose-bridges/json-with-comments.ts +60 -0
- package/src/harness-registry/harness-registry.ts +71 -14
- package/src/harness-registry/instruction-bridge.ts +31 -0
- package/src/index.ts +16 -3
- package/src/initialize-harnesses/initialize-harnesses.ts +1 -1
- package/src/skill-projection/skill-projection.ts +2 -2
- package/dist/init.command-c0fBv15T.mjs.map +0 -1
package/dist/cli.mjs
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -1,20 +1,84 @@
|
|
|
1
1
|
import { cli as cli$1 } from "clibuilder";
|
|
2
|
+
//#region src/harness-registry/instruction-bridge.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* What a harness needs in order to read the repository's `AGENTS.md`.
|
|
5
|
+
*
|
|
6
|
+
* A skills projection is one shape — a directory pointing at `.agents/skills` — so the registry
|
|
7
|
+
* models it as a path. Instruction bridges are not one shape: Claude Code needs a Markdown file
|
|
8
|
+
* whose body imports `AGENTS.md`, and Gemini CLI needs `AGENTS.md` added to an array inside a JSON
|
|
9
|
+
* settings file. A second bare path field would describe the first and lie about the second, so the
|
|
10
|
+
* variant carries what its own check needs.
|
|
11
|
+
*
|
|
12
|
+
* The `init` command writes none of these. They are the `init` skill's work, which is why every
|
|
13
|
+
* finding against one names the skill rather than a flag.
|
|
14
|
+
*/
|
|
15
|
+
type InstructionBridge = {
|
|
16
|
+
/**
|
|
17
|
+
* A Markdown file whose body is an `@AGENTS.md` import, or a symlink to `AGENTS.md`. One is
|
|
18
|
+
* needed beside every `AGENTS.md` in the tree, not only the root file: an import bridges the
|
|
19
|
+
* one file next to it, so a nested `AGENTS.md` is invisible until it has its own.
|
|
20
|
+
*/
|
|
21
|
+
kind: "import";
|
|
22
|
+
/** Repository-relative name, the same in every directory that holds an `AGENTS.md`. */
|
|
23
|
+
path: string;
|
|
24
|
+
} | {
|
|
25
|
+
/** An `AGENTS.md` entry in an array inside a JSON settings file. */
|
|
26
|
+
kind: "settings-entry";
|
|
27
|
+
/** Repository-relative path of the settings file. */
|
|
28
|
+
path: string;
|
|
29
|
+
/** Dotted path to the array within it, as the harness documents it. */
|
|
30
|
+
key: string;
|
|
31
|
+
};
|
|
32
|
+
//#endregion
|
|
2
33
|
//#region src/harness-registry/harness-registry.d.ts
|
|
3
34
|
type HarnessName = "claude-code" | "cursor" | "codex" | "copilot-cli" | "gemini-cli" | "devin-desktop" | "windsurf";
|
|
35
|
+
/** The two scopes a harness reads configuration at. Their roots differ; their shape does not. */
|
|
36
|
+
type HarnessScopeName = "project" | "user";
|
|
4
37
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
38
|
+
* What one harness does at one scope. Paths are relative to that scope's root: the repository root
|
|
39
|
+
* at project scope, the user's home directory at user scope.
|
|
40
|
+
*
|
|
41
|
+
* `detect` is the directory whose presence means this harness is configured at this scope — a
|
|
42
|
+
* different question per scope, which is why it is recorded per scope rather than once.
|
|
43
|
+
*
|
|
44
|
+
* `skillsDirectory` is the projection target the harness needs to see `.agents/skills` at this
|
|
45
|
+
* scope. A harness that reads `.agents/skills` natively there has none, and is never projected into.
|
|
46
|
+
*
|
|
47
|
+
* `instructionBridge` is the same question for `AGENTS.md`: what the harness needs at this scope in
|
|
48
|
+
* order to read it. It belongs per scope for the same reason `skillsDirectory` does — the file
|
|
49
|
+
* differs. Unlike `skillsDirectory`, the `init` command does not write it; the `init` skill does. It
|
|
50
|
+
* is recorded here to be diagnosed and gated per harness, not to be projected.
|
|
7
51
|
*/
|
|
8
|
-
type
|
|
9
|
-
name: HarnessName;
|
|
52
|
+
type HarnessScope = {
|
|
10
53
|
detect: string;
|
|
11
54
|
skillsDirectory?: string;
|
|
55
|
+
instructionBridge?: InstructionBridge;
|
|
56
|
+
};
|
|
57
|
+
type Harness = {
|
|
58
|
+
name: HarnessName;
|
|
59
|
+
/** What this harness does inside a repository. `init` and `doctor` act only here. */
|
|
60
|
+
project: HarnessScope;
|
|
61
|
+
/**
|
|
62
|
+
* What this harness does for the user, outside any repository. Absent when no user-scope path is
|
|
63
|
+
* primary-sourced — Devin documents none. Described and diagnosable; never written to.
|
|
64
|
+
*/
|
|
65
|
+
user?: HarnessScope;
|
|
12
66
|
/** Set when this name has been superseded; the value is the name that replaces it. */
|
|
13
67
|
deprecated?: HarnessName;
|
|
14
68
|
};
|
|
15
69
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
70
|
+
* The two scopes disagree in general, and a single answer per harness could only record one of them:
|
|
71
|
+
* Copilot CLI is `.github/skills` in a repository and `~/.copilot` for the user. Claude Code is the
|
|
72
|
+
* only harness that needs a skills projection, and it needs one at both scopes. Codex, Cursor,
|
|
73
|
+
* Copilot CLI, Gemini CLI, and Devin Desktop read `.agents/skills` themselves and are never
|
|
74
|
+
* projected into.
|
|
75
|
+
*
|
|
76
|
+
* Gemini CLI carried a `.gemini/skills` projection until E-GEM-02: it reads the `.agents/skills`
|
|
77
|
+
* alias at project scope too, where that alias takes precedence over `.gemini/skills`. It still
|
|
78
|
+
* needs an instruction bridge, which is a separate axis and unaffected.
|
|
79
|
+
*
|
|
80
|
+
* Instruction bridges are recorded at project scope only. The user-scope equivalents exist, but
|
|
81
|
+
* nothing writes or reads them yet: `init` works inside a repository, and so does `doctor`.
|
|
18
82
|
*
|
|
19
83
|
* `windsurf` is the former name of Devin Desktop, rebranded 2026-06-02. It is retained as a
|
|
20
84
|
* deprecated alias: Devin still scans the legacy `.windsurf/skills` path, so its projection keeps
|
|
@@ -24,6 +88,35 @@ type Harness = {
|
|
|
24
88
|
*/
|
|
25
89
|
declare const harnessRegistry: readonly Harness[];
|
|
26
90
|
//#endregion
|
|
91
|
+
//#region src/diagnose-bridges/diagnose-instructions.d.ts
|
|
92
|
+
/** What is on disk where an instruction bridge belongs. */
|
|
93
|
+
type InstructionKind = "import" | "symlink" | "settings-entry" | "file" | "none";
|
|
94
|
+
/**
|
|
95
|
+
* `unbridged` is the case a skills bridge has no equivalent of: the file is there, so nothing looks
|
|
96
|
+
* wrong, and it names `AGENTS.md` nowhere — a `CLAUDE.md` overwritten with real content, or a
|
|
97
|
+
* settings file another tool rewrote.
|
|
98
|
+
*/
|
|
99
|
+
type InstructionStatus = "ok" | "missing" | "unbridged" | "unreadable";
|
|
100
|
+
type InstructionReport = {
|
|
101
|
+
harness: HarnessName;
|
|
102
|
+
/** Repository-relative path of the file that carries the bridge. */
|
|
103
|
+
path: string;
|
|
104
|
+
kind: InstructionKind;
|
|
105
|
+
status: InstructionStatus;
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* Reports whether every enabled harness can still read `AGENTS.md`.
|
|
109
|
+
*
|
|
110
|
+
* Losing one of these is quieter than losing a skills bridge and costs more: a harness with no
|
|
111
|
+
* instruction bridge reads none of the repository's instructions, and says nothing about it. The
|
|
112
|
+
* checks are read-only, and no repair is a command — rewriting an instruction file is the `init`
|
|
113
|
+
* skill's judgment.
|
|
114
|
+
*/
|
|
115
|
+
declare function diagnoseInstructions(root: string, harnesses: readonly Harness[], cli: string): {
|
|
116
|
+
instructions: InstructionReport[];
|
|
117
|
+
findings: BridgeFinding[];
|
|
118
|
+
};
|
|
119
|
+
//#endregion
|
|
27
120
|
//#region src/diagnose-bridges/git-bridge-state.d.ts
|
|
28
121
|
/** Which side of a diverged bridge moved since the last commit where the two agreed. */
|
|
29
122
|
type DivergenceDirection = "bridge" | "canonical" | "both" | "unknown";
|
|
@@ -56,13 +149,18 @@ type DiagnoseOptions = {
|
|
|
56
149
|
};
|
|
57
150
|
type DiagnoseResult = {
|
|
58
151
|
bridges: BridgeReport[];
|
|
152
|
+
/**
|
|
153
|
+
* The instruction bridges into `AGENTS.md`, kept out of `bridges` on purpose: a different `kind`
|
|
154
|
+
* and `status` vocabulary, and a repair that is the `init` skill rather than a command.
|
|
155
|
+
*/
|
|
156
|
+
instructions: InstructionReport[];
|
|
59
157
|
divergence: DivergenceReport[];
|
|
60
158
|
findings: BridgeFinding[];
|
|
61
159
|
};
|
|
62
160
|
/**
|
|
63
|
-
* Reports whether every bridge
|
|
64
|
-
* `.agents/skills`. Read-only: nothing is created,
|
|
65
|
-
* to run from the repair each finding carries.
|
|
161
|
+
* Reports whether every bridge this repository needs still resolves: the skills bridges into
|
|
162
|
+
* `.agents/skills`, and the instruction bridges into `AGENTS.md`. Read-only: nothing is created,
|
|
163
|
+
* moved, or repaired, so the caller decides what to run from the repair each finding carries.
|
|
66
164
|
*/
|
|
67
165
|
declare function diagnoseBridges({ root, harnesses: preferred, cli }: DiagnoseOptions): DiagnoseResult;
|
|
68
166
|
//#endregion
|
|
@@ -75,10 +173,18 @@ declare const doctorCommand: cli$1.Command;
|
|
|
75
173
|
* `findings` and `help` sections; `skills/doctor/SKILL.md` is generated from the same table by
|
|
76
174
|
* `scripts/generate-skills.ts`, so the shipped skill cannot drift from what the command says.
|
|
77
175
|
*/
|
|
78
|
-
/** Every way a bridge can fail, in the order `doctor` reports them. */
|
|
176
|
+
/** Every way a skills bridge can fail, in the order `doctor` reports them. */
|
|
79
177
|
type BridgeProblem = "no-canonical" | "missing" | "degraded" | "stale" | "diverged-bridge" | "diverged-canonical" | "diverged-both" | "diverged-unknown" | "unpinned-copy";
|
|
178
|
+
/**
|
|
179
|
+
* Every way an instruction bridge can fail. Separate from `BridgeProblem` because the two share no
|
|
180
|
+
* repair: a skills bridge is rebuilt with `init` flags, and an instruction bridge is a file whose
|
|
181
|
+
* content is the user's, so every repair here goes back to the `init` skill.
|
|
182
|
+
*/
|
|
183
|
+
type InstructionProblem = "no-instructions" | "instructions-missing" | "instructions-unbridged" | "instructions-unreadable";
|
|
184
|
+
/** Everything `doctor` can report against, across both sections. */
|
|
185
|
+
type DoctorProblem = BridgeProblem | InstructionProblem;
|
|
80
186
|
type Repair = {
|
|
81
|
-
problem:
|
|
187
|
+
problem: DoctorProblem;
|
|
82
188
|
/** What `doctor` prints in the `findings` row for this problem. */
|
|
83
189
|
detail: string;
|
|
84
190
|
/**
|
|
@@ -93,10 +199,20 @@ type Repair = {
|
|
|
93
199
|
*/
|
|
94
200
|
skillRepair(path: string): string;
|
|
95
201
|
};
|
|
202
|
+
/** The skills bridges, reported in `bridges`. */
|
|
203
|
+
declare const bridgeRepairs: readonly Repair[];
|
|
204
|
+
/**
|
|
205
|
+
* The instruction bridges, reported in `instructions`. Every repair is the `init` skill: these are
|
|
206
|
+
* files a person wrote, or files carrying content beside the bridge, and deciding what to preserve
|
|
207
|
+
* while restoring the bridge is judgment no flag carries. `repair` therefore names the skill in
|
|
208
|
+
* both places rather than pretending a shell command exists.
|
|
209
|
+
*/
|
|
210
|
+
declare const instructionRepairs: readonly Repair[];
|
|
211
|
+
/** Both sections, in the order `doctor` reports them. */
|
|
96
212
|
declare const doctorRepairs: readonly Repair[];
|
|
97
213
|
declare const doctorSkill: {
|
|
98
214
|
readonly name: "doctor";
|
|
99
|
-
readonly description: "Use this skill when a repository loads no project skills, when skills are missing after a clone, or when checking whether the agent configuration bridges into .claude/skills and the other harness
|
|
215
|
+
readonly description: "Use this skill when a repository loads no project skills, when skills are missing after a clone, when a harness appears to be ignoring AGENTS.md, or when checking whether the agent configuration bridges into .claude/skills, CLAUDE.md, and the other harness files still resolve.";
|
|
100
216
|
};
|
|
101
217
|
/**
|
|
102
218
|
* The shipped `doctor` skill, rendered from the same table the command prints. `version` is the
|
|
@@ -134,5 +250,5 @@ type InitializeResult = {
|
|
|
134
250
|
};
|
|
135
251
|
declare function initializeHarnesses({ root, harnesses: preferred, copy, force }: InitializeOptions): InitializeResult;
|
|
136
252
|
//#endregion
|
|
137
|
-
export { type BridgeFinding, type BridgeKind, type BridgeProblem, type BridgeReport, type BridgeStatus, type DiagnoseOptions, type DiagnoseResult, type DivergenceDirection, type DivergenceReport, type HarnessName, type InitializeOptions, type InitializeResult, type Repair, activate, diagnoseBridges, doctorCommand, doctorRepairs, doctorSkill, harnessCommand, harnessRegistry, initCommand, initializeHarnesses, renderDoctorSkill };
|
|
253
|
+
export { type BridgeFinding, type BridgeKind, type BridgeProblem, type BridgeReport, type BridgeStatus, type DiagnoseOptions, type DiagnoseResult, type DivergenceDirection, type DivergenceReport, type DoctorProblem, type Harness, type HarnessName, type HarnessScope, type HarnessScopeName, type InitializeOptions, type InitializeResult, type InstructionBridge, type InstructionKind, type InstructionProblem, type InstructionReport, type InstructionStatus, type Repair, activate, bridgeRepairs, diagnoseBridges, diagnoseInstructions, doctorCommand, doctorRepairs, doctorSkill, harnessCommand, harnessRegistry, initCommand, initializeHarnesses, instructionRepairs, renderDoctorSkill };
|
|
138
254
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/harness-registry/harness-registry.ts","../src/diagnose-bridges/git-bridge-state.ts","../src/diagnose-bridges/diagnose-bridges.ts","../src/diagnose-bridges/doctor.command.ts","../src/diagnose-bridges/doctor-guidance.ts","../src/initialize-harnesses/init.command.ts","../src/initialize-harnesses/initialize-harnesses.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/harness-registry/instruction-bridge.ts","../src/harness-registry/harness-registry.ts","../src/diagnose-bridges/diagnose-instructions.ts","../src/diagnose-bridges/git-bridge-state.ts","../src/diagnose-bridges/diagnose-bridges.ts","../src/diagnose-bridges/doctor.command.ts","../src/diagnose-bridges/doctor-guidance.ts","../src/initialize-harnesses/init.command.ts","../src/initialize-harnesses/initialize-harnesses.ts"],"mappings":";;;;;;;;;;;;;;KAYY;;;;;;EAOT;;EAEA;;;EAIA;;EAEA;;EAEA;;;;KCzBS;;KAUA;;;;;;;;;;;;;;;;KAiBA;EACX;EACA;EACA,oBAAoB;;KAGT;EACX,MAAM;;EAEN,SAAS;;;;;EAKT,OAAO;;EAEP,aAAa;;;;;;;;;;;;;;;;;;;;;;cAuBD,0BAA0B;;;;KC5D3B;;;;;;KAMA;KAEA;EACX,SAAS;;EAET;EACA,MAAM;EACN,QAAQ;;;;;;;;;;iBAkFO,qBACf,cACA,oBAAoB,WACpB;EACI,cAAc;EAAqB,UAAU;;;;;KCxGtC;;;KCGA;KACA;KAEA;EACX,SAAS;;EAET;EACA,MAAM;EACN,QAAQ;;KAGG;EACX;EACA;;EAEA;;KAGW;EACX;EACA,WAAW;;KAGA;EACX;EACA,YAAY;;EAEZ;;KAGW;EACX,SAAS;;;;;EAKT,cAAc;EACd,YAAY;EACZ,UAAU;;;;;;;iBA8EK,kBAAkB,MAAM,WAAW,WAAgB,OAAO,kBAAkB;;;cC9E/E,eAAe,MAAI;;;;;;;;;KCvCpB;;;;;;KAgBA;;KAOA,gBAAgB,gBAAgB;KAEhC;EACX,SAAS;;EAET;;;;;EAKA,OAAO,cAAc;;;;;;EAMrB,YAAY;;;cAsDA,wBAAwB;;;;;;;cAmExB,6BAA6B;;cA6B7B,wBAAwB;cAQxB;WACZ;WACA;;;;;;;iBAae,kBAAkB;;;cCpNrB,aAAa,MAAI;cA0DjB,gBAAgB,MAAI;iBAMjB,WAAW;EAAgB,WAAW,gBAAgB;;;;KCnE1D;EACX;EACA,YAAY;EACZ;EACA;;KAEW;EACX;EACA,WAAW;EACX,QAAQ;EACR,QAAQ;;EAER;IAAc,MAAM;IAAa,YAAY;;EAC7C;EACA;;iBAGe,sBACf,MACA,WAAW,WACX,MACA,SACE,oBAAoB"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as doctorCommand, c as
|
|
2
|
-
export { activate, diagnoseBridges, doctorCommand, doctorRepairs, doctorSkill, harnessCommand, harnessRegistry, initCommand, initializeHarnesses, renderDoctorSkill };
|
|
1
|
+
import { a as doctorCommand, c as bridgeRepairs, d as instructionRepairs, f as renderDoctorSkill, i as initializeHarnesses, l as doctorRepairs, n as harnessCommand, o as diagnoseBridges, p as harnessRegistry, r as initCommand, s as diagnoseInstructions, t as activate, u as doctorSkill } from "./init.command-zbntulIq.mjs";
|
|
2
|
+
export { activate, bridgeRepairs, diagnoseBridges, diagnoseInstructions, doctorCommand, doctorRepairs, doctorSkill, harnessCommand, harnessRegistry, initCommand, initializeHarnesses, instructionRepairs, renderDoctorSkill };
|