phasegate 0.73.0 → 0.74.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/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.74.0] - 2026-04-22
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- ISSUE-007 Wave 9 — phase-gate ブロック時に出力される `scaffold:` 行に含まれる `<unit-id>` プレースホルダを、実 unit ID に置換するようにした。従来は L2-001 registry (`l2-error-definitions.ts`) の `defaultScaffoldCommand` が静的文字列 `npx phasegate scaffold-design --unit <unit-id> --phase logical` のまま出力されていたため、ユーザーが手で unit 名に書き換える必要があった。PHASE_GATE の場合は `metadata.unitId`、FULL_MODE_REQUIRED の場合は `targetFilePaths` から `WriteTargetScope.fromPath` で導出した unit ID を使って置換する。
|
|
15
|
+
- IT-AI-GUIDE-UID-001 / IT-AI-GUIDE-UID-002 を追加(PHASE_GATE と FULL_MODE_REQUIRED の両経路で `<unit-id>` が実 unit に置換されることを検証)。
|
|
16
|
+
|
|
10
17
|
## [0.73.0] - 2026-04-22
|
|
11
18
|
|
|
12
19
|
### Added
|
package/package.json
CHANGED
package/scripts/harness/agent-integration/application/usecases/handle-pre-tool-use-usecase.ts
CHANGED
|
@@ -103,7 +103,14 @@ export class HandlePreToolUseUseCase {
|
|
|
103
103
|
// fallthrough: continue to full-mode / story-reflection checks (which may also grandfather)
|
|
104
104
|
} else {
|
|
105
105
|
const guidance = await this.resolveGuidance('L2-001');
|
|
106
|
-
|
|
106
|
+
const unitIdForGuidance =
|
|
107
|
+
metadata?.unitId ?? this.deriveUnitIdFromPaths(input.targetFilePaths);
|
|
108
|
+
return HandlePreToolUseUseCase.buildPhaseGateBlockOutput(
|
|
109
|
+
blockedFilePath,
|
|
110
|
+
metadata,
|
|
111
|
+
guidance,
|
|
112
|
+
unitIdForGuidance,
|
|
113
|
+
);
|
|
107
114
|
}
|
|
108
115
|
} else {
|
|
109
116
|
return {
|
|
@@ -125,10 +132,12 @@ export class HandlePreToolUseUseCase {
|
|
|
125
132
|
const fullModeResult = await this.fullModeRequirementQueryPort.check(input.targetFilePaths);
|
|
126
133
|
if (fullModeResult.requiresFullMode) {
|
|
127
134
|
const guidance = await this.resolveGuidance('L2-001');
|
|
135
|
+
const unitIdForGuidance = this.deriveUnitIdFromPaths(input.targetFilePaths);
|
|
128
136
|
return HandlePreToolUseUseCase.buildFullModeRequiredBlockOutput(
|
|
129
137
|
input.targetFilePaths[0],
|
|
130
138
|
fullModeResult,
|
|
131
139
|
guidance,
|
|
140
|
+
unitIdForGuidance,
|
|
132
141
|
);
|
|
133
142
|
}
|
|
134
143
|
}
|
|
@@ -198,6 +207,7 @@ export class HandlePreToolUseUseCase {
|
|
|
198
207
|
dominantCategory?: string;
|
|
199
208
|
},
|
|
200
209
|
guidance: ErrorGuidance | null,
|
|
210
|
+
unitId: string | undefined,
|
|
201
211
|
): HandlePreToolUseOutput {
|
|
202
212
|
const fp = blockedFilePath ?? '不明なファイル';
|
|
203
213
|
const lines: string[] = [
|
|
@@ -214,7 +224,7 @@ export class HandlePreToolUseUseCase {
|
|
|
214
224
|
}
|
|
215
225
|
const suggestedSkill = guidance?.suggestedSkill ?? '/story-implementor';
|
|
216
226
|
lines.push(`次のアクション: ${suggestedSkill} スキルを使用して設計フェーズから開始してください。`);
|
|
217
|
-
HandlePreToolUseUseCase.appendGuidanceLines(lines, guidance);
|
|
227
|
+
HandlePreToolUseUseCase.appendGuidanceLines(lines, guidance, unitId);
|
|
218
228
|
|
|
219
229
|
return {
|
|
220
230
|
shouldBlock: true,
|
|
@@ -227,16 +237,34 @@ export class HandlePreToolUseUseCase {
|
|
|
227
237
|
};
|
|
228
238
|
}
|
|
229
239
|
|
|
230
|
-
private static appendGuidanceLines(
|
|
240
|
+
private static appendGuidanceLines(
|
|
241
|
+
lines: string[],
|
|
242
|
+
guidance: ErrorGuidance | null,
|
|
243
|
+
unitId?: string,
|
|
244
|
+
): void {
|
|
231
245
|
if (guidance === null) return;
|
|
232
246
|
if (guidance.scaffoldCommand !== null) {
|
|
233
|
-
|
|
247
|
+
const command = unitId !== undefined && unitId !== ''
|
|
248
|
+
? guidance.scaffoldCommand.replaceAll('<unit-id>', unitId)
|
|
249
|
+
: guidance.scaffoldCommand;
|
|
250
|
+
lines.push(` scaffold: ${command}`);
|
|
234
251
|
}
|
|
235
252
|
if (guidance.templatePath !== null) {
|
|
236
253
|
lines.push(` テンプレ: ${guidance.templatePath}`);
|
|
237
254
|
}
|
|
238
255
|
}
|
|
239
256
|
|
|
257
|
+
private deriveUnitIdFromPaths(targetFilePaths: readonly string[]): string | undefined {
|
|
258
|
+
const projectPaths = this.configQueryPort.getProjectPaths();
|
|
259
|
+
for (const targetFilePath of targetFilePaths) {
|
|
260
|
+
const scope = WriteTargetScope.fromPath(targetFilePath, projectPaths);
|
|
261
|
+
if (scope?.unitId !== undefined) {
|
|
262
|
+
return scope.unitId;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return undefined;
|
|
266
|
+
}
|
|
267
|
+
|
|
240
268
|
private resolveStoryReflectionScope(input: HandlePreToolUseInput): WriteTargetScope | null {
|
|
241
269
|
if (!HandlePreToolUseUseCase.WRITE_TOOLS.has(input.toolName)) {
|
|
242
270
|
return null;
|
|
@@ -264,6 +292,7 @@ export class HandlePreToolUseUseCase {
|
|
|
264
292
|
blockedFilePath: string | undefined,
|
|
265
293
|
metadata: BlockMetadata,
|
|
266
294
|
guidance: ErrorGuidance | null,
|
|
295
|
+
unitId: string | undefined,
|
|
267
296
|
): HandlePreToolUseOutput {
|
|
268
297
|
const levelLabel = metadata.scopeLevel
|
|
269
298
|
? HandlePreToolUseUseCase.LEVEL_LABELS[metadata.scopeLevel] ?? `Level ${metadata.scopeLevel}`
|
|
@@ -286,7 +315,7 @@ export class HandlePreToolUseUseCase {
|
|
|
286
315
|
if (metadata.unitId) {
|
|
287
316
|
lines.push(` 実行例: ${suggestedSkill} --unit ${metadata.unitId}`);
|
|
288
317
|
}
|
|
289
|
-
HandlePreToolUseUseCase.appendGuidanceLines(lines, guidance);
|
|
318
|
+
HandlePreToolUseUseCase.appendGuidanceLines(lines, guidance, unitId);
|
|
290
319
|
|
|
291
320
|
return {
|
|
292
321
|
shouldBlock: true,
|