phasegate 0.160.2 → 0.160.4
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/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.160.4] - 2026-05-14
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **WI-184 — skill catalog CLI** — fixes `phasegate skills list` so guidance-category skills no longer crash an undefined accumulator, shares the `SKILL.md` catalog path with `skills info`, and covers empty skill catalogs.
|
|
15
|
+
|
|
16
|
+
## [0.160.3] - 2026-05-14
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- **WI-187 — doctor no-op repair semantics** — stops `phasegate doctor` from advertising `migrate work-items --apply` as a mechanical repair for `_shared` ad-hoc plan drift, marks the finding manual with `repairHint: null`, and adds a regression flow proving the migration command would apply zero candidates and leave the doctor finding unresolved.
|
|
21
|
+
|
|
10
22
|
## [0.160.2] - 2026-05-14
|
|
11
23
|
|
|
12
24
|
### Fixed
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// @unit installation
|
|
2
2
|
// @layer application
|
|
3
3
|
// @work-item-id WI-143
|
|
4
|
+
// @work-item-id WI-187
|
|
4
5
|
|
|
5
6
|
import { join, relative, sep } from "node:path";
|
|
6
7
|
import { DiagnosticFinding } from "../../domain/diagnostic-finding.js";
|
|
@@ -37,8 +38,8 @@ export class WiWorkflowDriftCheck implements HeuristicCheck {
|
|
|
37
38
|
severity: "red",
|
|
38
39
|
target: "docs/inception",
|
|
39
40
|
message,
|
|
40
|
-
repairMode: "
|
|
41
|
-
repairHint:
|
|
41
|
+
repairMode: "manual",
|
|
42
|
+
repairHint: null,
|
|
42
43
|
suggestedSkill: null,
|
|
43
44
|
});
|
|
44
45
|
}
|
package/scripts/harness/main.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* @work-item-id WI-171 / WI-172 / WI-173
|
|
7
7
|
* @work-item-id WI-175
|
|
8
8
|
* @work-item-id WI-176
|
|
9
|
+
* @work-item-id WI-184
|
|
9
10
|
*
|
|
10
11
|
* Phasegate CLI エントリポイント。
|
|
11
12
|
* 各Unitの Composition Root からハンドラーを取得し、コマンドに応じてディスパッチする。
|
|
@@ -64,7 +65,9 @@ import {
|
|
|
64
65
|
deploySkills,
|
|
65
66
|
getCategoryForSkill,
|
|
66
67
|
getHarnessVersion,
|
|
68
|
+
getSkillMarkdownPath,
|
|
67
69
|
initHarnessConfig,
|
|
70
|
+
listAvailableSkillNames,
|
|
68
71
|
} from "./setup/skill-deployer.js";
|
|
69
72
|
import { createSkillQualityHandlers } from "./skill-quality/composition-root.js";
|
|
70
73
|
import { createTraceabilityModelModule } from "./traceability-model/composition-root.js";
|
|
@@ -2753,25 +2756,16 @@ Examples:
|
|
|
2753
2756
|
// ── skills ──
|
|
2754
2757
|
case "skills": {
|
|
2755
2758
|
const subCommand = args[1];
|
|
2756
|
-
const skillsRoot = join(harnessRoot, "skills");
|
|
2757
2759
|
|
|
2758
2760
|
if (subCommand === "list") {
|
|
2759
|
-
const
|
|
2760
|
-
const
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
} catch {
|
|
2768
|
-
// skip directories without SKILL.md
|
|
2769
|
-
}
|
|
2770
|
-
}
|
|
2771
|
-
}
|
|
2772
|
-
skills.sort();
|
|
2773
|
-
|
|
2774
|
-
const grouped: Record<string, string[]> = { core: [], aidlc: [], utility: [], unknown: [] };
|
|
2761
|
+
const skills = await listAvailableSkillNames(harnessRoot);
|
|
2762
|
+
const grouped: Record<"core" | "aidlc" | "utility" | "guidance" | "unknown", string[]> = {
|
|
2763
|
+
core: [],
|
|
2764
|
+
aidlc: [],
|
|
2765
|
+
utility: [],
|
|
2766
|
+
guidance: [],
|
|
2767
|
+
unknown: [],
|
|
2768
|
+
};
|
|
2775
2769
|
for (const name of skills) {
|
|
2776
2770
|
const cat = getCategoryForSkill(name) ?? "unknown";
|
|
2777
2771
|
grouped[cat].push(name);
|
|
@@ -2783,8 +2777,9 @@ Examples:
|
|
|
2783
2777
|
core: "Core — Quality Defense",
|
|
2784
2778
|
aidlc: "AIDLC — Development Workflow",
|
|
2785
2779
|
utility: "Utility",
|
|
2780
|
+
guidance: "Guidance",
|
|
2786
2781
|
};
|
|
2787
|
-
for (const cat of ["core", "aidlc", "utility", "unknown"] as const) {
|
|
2782
|
+
for (const cat of ["core", "aidlc", "utility", "guidance", "unknown"] as const) {
|
|
2788
2783
|
if (grouped[cat].length === 0) continue;
|
|
2789
2784
|
const label = labels[cat] ?? "Other";
|
|
2790
2785
|
console.log(` [${label}] (${grouped[cat].length})`);
|
|
@@ -2803,7 +2798,7 @@ Examples:
|
|
|
2803
2798
|
process.exit(2);
|
|
2804
2799
|
}
|
|
2805
2800
|
const { promises: fs } = await import("node:fs");
|
|
2806
|
-
const skillMdPath =
|
|
2801
|
+
const skillMdPath = getSkillMarkdownPath(harnessRoot, skillName);
|
|
2807
2802
|
try {
|
|
2808
2803
|
const content = await fs.readFile(skillMdPath, "utf-8");
|
|
2809
2804
|
console.log(content);
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// @layer infrastructure
|
|
3
3
|
// @work-item-id WI-086 / WI-087
|
|
4
4
|
// @work-item-id WI-127
|
|
5
|
+
// @work-item-id WI-184
|
|
5
6
|
// Note: import.meta.url を使わず、呼び出し元 (main.ts) がパスを解決して渡す設計。
|
|
6
7
|
|
|
7
8
|
import { promises as fs } from "node:fs";
|
|
@@ -78,6 +79,33 @@ export function getCategoryForSkill(skillName: string): SkillCategory | null {
|
|
|
78
79
|
return null;
|
|
79
80
|
}
|
|
80
81
|
|
|
82
|
+
export function getSkillMarkdownPath(harnessRoot: string, skillName: string): string {
|
|
83
|
+
return join(harnessRoot, SKILLS_SOURCE_DIR, skillName, "SKILL.md");
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export async function listAvailableSkillNames(harnessRoot: string): Promise<string[]> {
|
|
87
|
+
const skillsRoot = join(harnessRoot, SKILLS_SOURCE_DIR);
|
|
88
|
+
let entries;
|
|
89
|
+
try {
|
|
90
|
+
entries = await fs.readdir(skillsRoot, { withFileTypes: true });
|
|
91
|
+
} catch {
|
|
92
|
+
return [];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const skills: string[] = [];
|
|
96
|
+
for (const entry of entries) {
|
|
97
|
+
if (!entry.isDirectory()) continue;
|
|
98
|
+
try {
|
|
99
|
+
await fs.access(getSkillMarkdownPath(harnessRoot, entry.name));
|
|
100
|
+
skills.push(entry.name);
|
|
101
|
+
} catch {
|
|
102
|
+
// Directories without SKILL.md are not catalog entries.
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return skills.sort();
|
|
107
|
+
}
|
|
108
|
+
|
|
81
109
|
export interface DeployResult {
|
|
82
110
|
deployedSkills: string[];
|
|
83
111
|
targetDir: string;
|