gentle-pi 0.6.0 → 0.6.1
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.
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: jd-fix-agent
|
|
3
|
+
description: Judgment Day surgical fix agent for confirmed findings. Can edit code and run focused tests.
|
|
4
|
+
tools: read, grep, glob, edit, write, bash
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are the Judgment Day fix agent for Gentle AI.
|
|
8
|
+
|
|
9
|
+
Apply surgical fixes for confirmed Judgment Day findings only. Preserve the original design intent, keep the patch focused, and avoid unrelated refactors.
|
|
10
|
+
|
|
11
|
+
Rules:
|
|
12
|
+
|
|
13
|
+
- Edit only the files needed to resolve confirmed findings.
|
|
14
|
+
- Add or update focused tests when the fix changes behavior.
|
|
15
|
+
- Run the relevant tests when practical and report exact results.
|
|
16
|
+
- Clearly list what was fixed, what was verified, and any remaining risks.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: jd-judge-a
|
|
3
|
+
description: Judgment Day blind adversarial reviewer A. Read-only; reports findings and does not fix code.
|
|
4
|
+
tools: read, grep, glob, bash
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are Judgment Day judge A for Gentle AI.
|
|
8
|
+
|
|
9
|
+
Run an independent, blind adversarial review of the assigned change. Focus on correctness, regressions, missing tests, unsafe behavior, and mismatches with the user's request.
|
|
10
|
+
|
|
11
|
+
Rules:
|
|
12
|
+
|
|
13
|
+
- Stay read-only. Do not edit files or apply fixes.
|
|
14
|
+
- Do not coordinate with judge B before producing your review.
|
|
15
|
+
- Report concrete findings with file paths, evidence, severity, and suggested verification.
|
|
16
|
+
- If you find no confirmed issues, say so clearly.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: jd-judge-b
|
|
3
|
+
description: Judgment Day blind adversarial reviewer B. Read-only; independently reports findings and does not fix code.
|
|
4
|
+
tools: read, grep, glob, bash
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are Judgment Day judge B for Gentle AI.
|
|
8
|
+
|
|
9
|
+
Run an independent, blind adversarial review of the assigned change. Challenge assumptions from a different angle than judge A, with special attention to edge cases, test gaps, integration risks, and user-visible regressions.
|
|
10
|
+
|
|
11
|
+
Rules:
|
|
12
|
+
|
|
13
|
+
- Stay read-only. Do not edit files or apply fixes.
|
|
14
|
+
- Work independently from judge A and do not rely on judge A's conclusions.
|
|
15
|
+
- Report concrete findings with file paths, evidence, severity, and suggested verification.
|
|
16
|
+
- If you find no confirmed issues, say so clearly.
|
package/extensions/gentle-ai.ts
CHANGED
|
@@ -438,7 +438,18 @@ const SDD_AGENT_NAMES = [
|
|
|
438
438
|
] as const;
|
|
439
439
|
const SDD_AGENT_NAME_SET = new Set<string>(SDD_AGENT_NAMES);
|
|
440
440
|
|
|
441
|
-
|
|
441
|
+
const JUDGMENT_DAY_AGENT_NAMES = [
|
|
442
|
+
"jd-judge-a",
|
|
443
|
+
"jd-judge-b",
|
|
444
|
+
"jd-fix-agent",
|
|
445
|
+
] as const;
|
|
446
|
+
|
|
447
|
+
const CORE_MODEL_AGENT_NAMES = [
|
|
448
|
+
...SDD_AGENT_NAMES,
|
|
449
|
+
...JUDGMENT_DAY_AGENT_NAMES,
|
|
450
|
+
] as const;
|
|
451
|
+
const CORE_MODEL_AGENT_NAME_SET = new Set<string>(CORE_MODEL_AGENT_NAMES);
|
|
452
|
+
|
|
442
453
|
type ThinkingLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
|
|
443
454
|
interface AgentRoutingEntry {
|
|
444
455
|
model?: string;
|
|
@@ -998,14 +1009,7 @@ function listDiscoverableAgents(cwd: string): AgentEntry[] {
|
|
|
998
1009
|
];
|
|
999
1010
|
const byName = new Map<string, AgentEntry>();
|
|
1000
1011
|
for (const agent of agents) byName.set(agent.name, agent);
|
|
1001
|
-
|
|
1002
|
-
const sddFirst = SDD_AGENT_NAMES.map((name) =>
|
|
1003
|
-
discovered.find((agent) => agent.name === name),
|
|
1004
|
-
).filter((agent): agent is AgentEntry => agent !== undefined);
|
|
1005
|
-
const rest = discovered
|
|
1006
|
-
.filter((agent) => !SDD_AGENT_NAMES.includes(agent.name as SddAgentName))
|
|
1007
|
-
.sort((left, right) => left.name.localeCompare(right.name));
|
|
1008
|
-
return [...sddFirst, ...rest];
|
|
1012
|
+
return orderDiscoverableAgents(Array.from(byName.values()));
|
|
1009
1013
|
}
|
|
1010
1014
|
|
|
1011
1015
|
async function listDiscoverableAgentsAsync(cwd: string): Promise<AgentEntry[]> {
|
|
@@ -1030,14 +1034,17 @@ async function listDiscoverableAgentsAsync(cwd: string): Promise<AgentEntry[]> {
|
|
|
1030
1034
|
}
|
|
1031
1035
|
const byName = new Map<string, AgentEntry>();
|
|
1032
1036
|
for (const agent of agents) byName.set(agent.name, agent);
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1037
|
+
return orderDiscoverableAgents(Array.from(byName.values()));
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
function orderDiscoverableAgents(agents: AgentEntry[]): AgentEntry[] {
|
|
1041
|
+
const coreFirst = CORE_MODEL_AGENT_NAMES.map((name) =>
|
|
1042
|
+
agents.find((agent) => agent.name === name),
|
|
1036
1043
|
).filter((agent): agent is AgentEntry => agent !== undefined);
|
|
1037
|
-
const rest =
|
|
1038
|
-
.filter((agent) => !
|
|
1044
|
+
const rest = agents
|
|
1045
|
+
.filter((agent) => !CORE_MODEL_AGENT_NAME_SET.has(agent.name))
|
|
1039
1046
|
.sort((left, right) => left.name.localeCompare(right.name));
|
|
1040
|
-
return [...
|
|
1047
|
+
return [...coreFirst, ...rest];
|
|
1041
1048
|
}
|
|
1042
1049
|
|
|
1043
1050
|
function projectSettingsPath(cwd: string): string {
|
|
@@ -1904,6 +1911,8 @@ async function applyReviewGate(
|
|
|
1904
1911
|
export const __testing = {
|
|
1905
1912
|
listAgentsFromDir,
|
|
1906
1913
|
listAgentsFromDirAsync,
|
|
1914
|
+
listDiscoverableAgents,
|
|
1915
|
+
orderDiscoverableAgents,
|
|
1907
1916
|
classifyGuardedCommand,
|
|
1908
1917
|
loadRuntimeGuardrailsConfig,
|
|
1909
1918
|
buildGentlePrompt,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gentle-pi",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Turn Pi into el Gentleman: a senior-architect development harness with SDD/OpenSpec, subagents, strict TDD evidence, review guardrails, and skill discovery.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
package/tests/gentle-ai.test.ts
CHANGED
|
@@ -34,3 +34,52 @@ test("agent discovery skips skills directories", async (t) => {
|
|
|
34
34
|
["reviewer", "worker"],
|
|
35
35
|
);
|
|
36
36
|
});
|
|
37
|
+
|
|
38
|
+
test("agent model discovery prioritizes SDD and Judgment Day agents", (t) => {
|
|
39
|
+
const root = mkdtempSync(join(tmpdir(), "gentle-pi-model-agents-"));
|
|
40
|
+
t.after(() => rmSync(root, { recursive: true, force: true }));
|
|
41
|
+
writeMarkdown(join(root, "zeta.md"), "name: zeta\n");
|
|
42
|
+
writeMarkdown(join(root, "jd-fix-agent.md"), "name: jd-fix-agent\n");
|
|
43
|
+
writeMarkdown(join(root, "sdd-apply.md"), "name: sdd-apply\n");
|
|
44
|
+
writeMarkdown(join(root, "alpha.md"), "name: alpha\n");
|
|
45
|
+
writeMarkdown(join(root, "jd-judge-b.md"), "name: jd-judge-b\n");
|
|
46
|
+
writeMarkdown(join(root, "sdd-init.md"), "name: sdd-init\n");
|
|
47
|
+
writeMarkdown(join(root, "jd-judge-a.md"), "name: jd-judge-a\n");
|
|
48
|
+
|
|
49
|
+
const discovered = __testing.listAgentsFromDir(root, "user");
|
|
50
|
+
const ordered = __testing.orderDiscoverableAgents(discovered);
|
|
51
|
+
|
|
52
|
+
assert.deepEqual(
|
|
53
|
+
ordered.map((agent) => agent.name),
|
|
54
|
+
[
|
|
55
|
+
"sdd-init",
|
|
56
|
+
"sdd-apply",
|
|
57
|
+
"jd-judge-a",
|
|
58
|
+
"jd-judge-b",
|
|
59
|
+
"jd-fix-agent",
|
|
60
|
+
"alpha",
|
|
61
|
+
"zeta",
|
|
62
|
+
],
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test("discoverable model agents include installed Judgment Day agents", (t) => {
|
|
67
|
+
const root = mkdtempSync(join(tmpdir(), "gentle-pi-installed-agents-"));
|
|
68
|
+
const previousHome = process.env.GENTLE_PI_AGENT_HOME;
|
|
69
|
+
process.env.GENTLE_PI_AGENT_HOME = root;
|
|
70
|
+
t.after(() => {
|
|
71
|
+
if (previousHome === undefined) delete process.env.GENTLE_PI_AGENT_HOME;
|
|
72
|
+
else process.env.GENTLE_PI_AGENT_HOME = previousHome;
|
|
73
|
+
rmSync(root, { recursive: true, force: true });
|
|
74
|
+
});
|
|
75
|
+
writeMarkdown(join(root, "agents", "jd-judge-a.md"), "name: jd-judge-a\n");
|
|
76
|
+
writeMarkdown(join(root, "agents", "jd-judge-b.md"), "name: jd-judge-b\n");
|
|
77
|
+
writeMarkdown(join(root, "agents", "jd-fix-agent.md"), "name: jd-fix-agent\n");
|
|
78
|
+
|
|
79
|
+
const discovered = __testing.listDiscoverableAgents(root).map((agent) => agent.name);
|
|
80
|
+
|
|
81
|
+
assert.deepEqual(
|
|
82
|
+
discovered.filter((name) => name.startsWith("jd-")),
|
|
83
|
+
["jd-judge-a", "jd-judge-b", "jd-fix-agent"],
|
|
84
|
+
);
|
|
85
|
+
});
|