phasegate 0.74.0 → 0.83.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 +123 -0
- package/package.json +1 -1
- package/scripts/harness/agent-integration/{infrastructure → application}/ports/cli-executor-port.ts +2 -2
- package/scripts/harness/agent-integration/application/usecases/handle-post-tool-use-usecase.ts +2 -2
- package/scripts/harness/agent-integration/application/usecases/handle-pre-tool-use-usecase.ts +28 -8
- package/scripts/harness/agent-integration/application/usecases/handle-stop-usecase.ts +1 -1
- package/scripts/harness/agent-integration/domain/ports/phase-gate-query-port.ts +6 -0
- package/scripts/harness/agent-integration/domain/services/fallback-verification-service.ts +2 -17
- package/scripts/harness/agent-integration/index.ts +3 -4
- package/scripts/harness/agent-integration/infrastructure/adapters/child-process-cli-executor-adapter.ts +2 -2
- package/scripts/harness/agent-integration/infrastructure/adapters/env-file-reentry-guard-state-adapter.ts +2 -10
- package/scripts/harness/agent-integration/infrastructure/adapters/phase-gate-query-adapter.ts +30 -0
- package/scripts/harness/agent-integration/presentation/session-start-hook.ts +2 -17
- package/scripts/harness/agent-integration/presentation/user-prompt-submit-hook.ts +2 -21
- package/scripts/harness/biome-ast-engine/composition-root.ts +2 -18
- package/scripts/harness/biome-ast-engine/domain/services/lint-runner.ts +19 -3
- package/scripts/harness/biome-ast-engine/domain/services/rule-definition-registry.ts +28 -3
- package/scripts/harness/biome-ast-engine/domain/value-objects/import-graph.ts +22 -6
- package/scripts/harness/biome-ast-engine/infrastructure/adapters/typescript-source-module-analyzer-adapter.ts +38 -48
- package/scripts/harness/biome-ast-engine/infrastructure/parsers/layer-comment-parser.ts +2 -8
- package/scripts/harness/biome-ast-engine/infrastructure/parsers/unit-comment-parser.ts +3 -10
- package/scripts/harness/ci-governance/application/usecases/generate-ci-template-usecase.ts +2 -2
- package/scripts/harness/ci-governance/domain/types/lesson-artifact.ts +5 -13
- package/scripts/harness/ci-governance/domain/types/template-type.ts +2 -6
- package/scripts/harness/ci-governance/domain/types/trigger-condition.ts +2 -6
- package/scripts/harness/ci-governance/infrastructure/adapters/harness-api-command-existence-adapter.ts +2 -6
- package/scripts/harness/ci-governance/infrastructure/adapters/validator-id-registry-adapter.ts +2 -6
- package/scripts/harness/ci-governance/infrastructure/schema/error-history-schema.ts +2 -6
- package/scripts/harness/ci-governance/presentation/handlers/migrate-agents-md-handler.ts +1 -1
- package/scripts/harness/config-foundation/domain/errors/config-foundation-domain-error.ts +3 -6
- package/scripts/harness/config-foundation/domain/errors/invalid-preset-error.ts +3 -6
- package/scripts/harness/config-foundation/domain/harness-config.ts +2 -1
- package/scripts/harness/config-foundation/domain/value-objects/phase-dependencies-config.ts +2 -1
- package/scripts/harness/config-foundation/index.ts +2 -11
- package/scripts/harness/harness-error/application/dto/error-definition-summary.ts +3 -6
- package/scripts/harness/harness-error/application/dto/harness-error-contract.ts +3 -6
- package/scripts/harness/harness-error/application/dto/validator-issue-draft.ts +3 -6
- package/scripts/harness/harness-error/domain/errors/adr-reference-not-found-error.ts +3 -6
- package/scripts/harness/harness-error/domain/errors/duplicate-error-code-error.ts +3 -6
- package/scripts/harness/harness-error/domain/errors/invalid-adr-ref-error.ts +3 -6
- package/scripts/harness/harness-error/domain/errors/invalid-error-code-error.ts +3 -6
- package/scripts/harness/harness-error/domain/errors/invalid-severity-error.ts +3 -6
- package/scripts/harness/harness-error/domain/errors/missing-adr-ref-error.ts +3 -6
- package/scripts/harness/harness-error/domain/errors/missing-fix-example-error.ts +3 -6
- package/scripts/harness/harness-error/domain/errors/severity-downgrade-violation-error.ts +3 -6
- package/scripts/harness/harness-error/domain/errors/unknown-error-definition-error.ts +3 -6
- package/scripts/harness/harness-error/domain/ports/fix-example-validator-port.ts +3 -7
- package/scripts/harness/nyquist-validation/application/dto/analyze-impact-output.ts +2 -6
- package/scripts/harness/nyquist-validation/infrastructure/adapters/ajv-json-schema-validator-adapter.ts +7 -19
- package/scripts/harness/nyquist-validation/infrastructure/adapters/traceability-model-story-registry-adapter.ts +4 -8
- package/scripts/harness/phase-dependency-model/application/usecases/check-story-reflection-usecase.ts +2 -13
- package/scripts/harness/phase-dependency-model/domain/ports/story-reflection-file-system-port.ts +2 -6
- package/scripts/harness/quick-mode/application/dto/change-category-classification-contract.ts +3 -7
- package/scripts/harness/quick-mode/index.ts +2 -13
- package/scripts/harness/setup/skill-deployer.ts +3 -58
- package/scripts/harness/skill-quality/infrastructure/adapters/ajv-lesson-artifact-schema-adapter.ts +3 -3
- package/scripts/harness/validator-system/application/dto/run-full-validation-input.ts +4 -10
- package/scripts/harness/validator-system/domain/ports/adr-reference-port.ts +2 -6
- package/scripts/harness/validator-system/domain/ports/it-test-file-analyzer-port.ts +2 -10
- package/scripts/harness/validator-system/domain/ports/metadata-policy-port.ts +3 -6
- package/scripts/harness/validator-system/domain/ports/source-analysis-port.ts +2 -7
- package/scripts/harness/validator-system/domain/ports/source-code-analyzer-port.ts +2 -7
- package/scripts/harness/validator-system/domain/ports/source-file-text-scanner-port.ts +2 -9
- package/scripts/harness/validator-system/domain/ports/test-quality-analyzer-port.ts +3 -6
- package/scripts/harness/validator-system/domain/services/cli-e2e-test-existence-service.ts +3 -11
- package/scripts/harness/validator-system/domain/services/stub-comment-detection-service.ts +3 -8
- package/scripts/harness/validator-system/infrastructure/adapters/cli-command-registry-adapter.ts +3 -7
- package/scripts/harness/agent-integration/domain/ports/import-analyzer-port.ts +0 -13
- package/scripts/harness/agent-integration/infrastructure/adapters/regex-import-analyzer-adapter.ts +0 -69
- package/scripts/harness/ci-governance/application/dto/validate-pointers-input.ts +0 -8
- package/scripts/harness/ci-governance/presentation/dto/ci-governance-render-options.ts +0 -9
- package/scripts/harness/ci-governance/presentation/formatters/error-repetition-formatter.ts +0 -26
- package/scripts/harness/config-foundation/infrastructure/registries/composite-feature-registry-adapter.ts +0 -22
- package/scripts/harness/nyquist-validation/domain/errors/story-not-found-error.ts +0 -14
- package/scripts/harness/nyquist-validation/presentation/dto/cli-render-options.ts +0 -12
- package/scripts/harness/quick-mode/application/dto/build-relaxation-profile-input.ts +0 -12
- package/scripts/harness/quick-mode/application/dto/execute-quick-ci-check-input.ts +0 -11
- package/scripts/harness/quick-mode/application/dto/judge-quick-mode-eligibility-input.ts +0 -10
- package/scripts/harness/quick-mode/domain/ports/quick-mode-config-port.ts +0 -12
- package/scripts/harness/quick-mode/domain/ports/validator-id-registry-port.ts +0 -10
- package/scripts/harness/shared-kernel/harness-api.ts +0 -6
- package/scripts/harness/shared-kernel/quick-mode.ts +0 -15
- package/scripts/harness/shared-kernel/validator-system.ts +0 -14
- package/scripts/harness/skill-quality/application/mappers/cascade-update-result-mapper.ts +0 -16
- package/scripts/harness/skill-quality/application/mappers/coverage-report-mapper.ts +0 -37
- package/scripts/harness/skill-quality/application/mappers/lesson-artifact-mapper.ts +0 -11
- package/scripts/harness/skill-quality/domain/types/unit-name.ts +0 -5
- package/scripts/harness/traceability-model/application/dto/metadata-validation-input.ts +0 -12
- package/scripts/harness/traceability-model/domain/constants/traceability-link-types.ts +0 -14
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*
|
|
5
|
-
* FixExample検証ポート
|
|
6
|
-
* Infrastructure層が実装し、構文妥当性確認と適用後のvalidator通過を検証する
|
|
7
|
-
*/
|
|
1
|
+
// @unit harness-error
|
|
2
|
+
// @layer domain
|
|
3
|
+
|
|
8
4
|
import type { ErrorCode } from '../value-objects/error-code.js';
|
|
9
5
|
import type { FixExample } from '../value-objects/fix-example.js';
|
|
10
6
|
import type { FixExampleValidationResult } from '../value-objects/fix-example-validation-result.js';
|
|
@@ -4,20 +4,13 @@
|
|
|
4
4
|
*
|
|
5
5
|
* JSONスキーマバリデーション実装: Ajv
|
|
6
6
|
*/
|
|
7
|
-
import
|
|
7
|
+
import AjvModule, { type ErrorObject, type ValidateFunction } from 'ajv';
|
|
8
|
+
const Ajv = AjvModule.default ?? AjvModule;
|
|
8
9
|
import type { NyquistHarnessError } from '../../domain/services/ac-coverage-gate-policy.js';
|
|
9
10
|
import type { AjvValidatorPort } from '../../application/usecases/validate-matrix-usecase.js';
|
|
10
11
|
import { loadMatrixSchema } from '../schema/matrix-schema-loader.js';
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
keyword: string;
|
|
14
|
-
instancePath: string;
|
|
15
|
-
schemaPath: string;
|
|
16
|
-
params: Record<string, unknown>;
|
|
17
|
-
message?: string;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function convertAjvError(err: AjvErrorObject): NyquistHarnessError {
|
|
13
|
+
function convertAjvError(err: ErrorObject): NyquistHarnessError {
|
|
21
14
|
let message: string;
|
|
22
15
|
|
|
23
16
|
switch (err.keyword) {
|
|
@@ -41,27 +34,22 @@ function convertAjvError(err: AjvErrorObject): NyquistHarnessError {
|
|
|
41
34
|
}
|
|
42
35
|
|
|
43
36
|
export class AjvJsonSchemaValidatorAdapter implements AjvValidatorPort {
|
|
44
|
-
|
|
45
|
-
private readonly ajv: any;
|
|
37
|
+
private readonly ajv: InstanceType<typeof Ajv>;
|
|
46
38
|
|
|
47
39
|
constructor() {
|
|
48
|
-
|
|
49
|
-
this.ajv = new (Ajv as any)({ allErrors: true });
|
|
40
|
+
this.ajv = new Ajv({ allErrors: true });
|
|
50
41
|
}
|
|
51
42
|
|
|
52
43
|
async validate(data: unknown): Promise<{ valid: boolean; errors: NyquistHarnessError[] }> {
|
|
53
44
|
const schema = await loadMatrixSchema();
|
|
54
|
-
const validateFn = this.ajv.compile(schema as object);
|
|
45
|
+
const validateFn: ValidateFunction = this.ajv.compile(schema as object);
|
|
55
46
|
const valid = validateFn(data);
|
|
56
47
|
|
|
57
48
|
if (valid) {
|
|
58
49
|
return { valid: true, errors: [] };
|
|
59
50
|
}
|
|
60
51
|
|
|
61
|
-
|
|
62
|
-
const errors: NyquistHarnessError[] = (validateFn.errors ?? []).map((e: any) =>
|
|
63
|
-
convertAjvError(e as AjvErrorObject)
|
|
64
|
-
);
|
|
52
|
+
const errors: NyquistHarnessError[] = (validateFn.errors ?? []).map((e) => convertAjvError(e));
|
|
65
53
|
return { valid: false, errors };
|
|
66
54
|
}
|
|
67
55
|
}
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* StoryRegistryPort 実装: traceability-model アダプタ
|
|
6
|
-
* @stub wave2-pending
|
|
7
|
-
*/
|
|
1
|
+
// @unit nyquist-validation
|
|
2
|
+
// @layer infrastructure
|
|
3
|
+
// @stub wave2-pending
|
|
4
|
+
|
|
8
5
|
import type { StoryRegistryPort } from '../../domain/ports/story-registry-port.js';
|
|
9
6
|
|
|
10
7
|
export interface TraceabilityModelStoryRegistryAdapterDeps {
|
|
11
|
-
/** traceability-model から有効なstoryIdを取得するコールバック(Wave2暫定) */
|
|
12
8
|
getStoryIds: () => Promise<readonly string[]>;
|
|
13
9
|
}
|
|
14
10
|
|
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* @unit phase-dependency-model
|
|
4
|
-
*
|
|
5
|
-
* CheckStoryReflectionUseCase
|
|
6
|
-
* StoryReflectionChecker をオーケストレーションし、inception → product への
|
|
7
|
-
* storyId 反映状況を検証するユースケース。
|
|
8
|
-
*
|
|
9
|
-
* 入力: unitId, StoryReflectionConfig
|
|
10
|
-
* 出力: StoryReflectionResult(pass/fail + violations/warnings)
|
|
11
|
-
*
|
|
12
|
-
* enabled=false の場合は即座に pass を返す。
|
|
13
|
-
*/
|
|
1
|
+
// @unit phase-dependency-model
|
|
2
|
+
// @layer application
|
|
14
3
|
|
|
15
4
|
import type { StoryReflectionChecker } from '../../domain/services/story-reflection-checker.js';
|
|
16
5
|
import type { StoryReflectionConfig } from '../../domain/values/story-reflection-config.js';
|
package/scripts/harness/phase-dependency-model/domain/ports/story-reflection-file-system-port.ts
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* @unit phase-dependency-model
|
|
4
|
-
*/
|
|
1
|
+
// @unit phase-dependency-model
|
|
2
|
+
// @layer domain
|
|
5
3
|
|
|
6
4
|
export interface StoryReflectionFileSystemPort {
|
|
7
|
-
/** inception/{unit}/ 配下の storyId ディレクトリ名一覧を返す */
|
|
8
5
|
listStoryDirectories(unitId: string): Promise<readonly string[]>;
|
|
9
|
-
/** ファイルの存在チェック */
|
|
10
6
|
fileExists(path: string): Promise<boolean>;
|
|
11
7
|
/** product 文書内に @story-id {storyId} アノテーションが含まれているか */
|
|
12
8
|
fileContainsStoryAnnotation(
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* @unit quick-mode
|
|
4
|
-
*
|
|
5
|
-
* quick-mode ユニットの公開エントリポイント
|
|
6
|
-
*/
|
|
1
|
+
// @unit quick-mode
|
|
2
|
+
// @layer application
|
|
7
3
|
|
|
8
|
-
// Domain Value Objects
|
|
9
4
|
export { ChangeCategory, UnknownChangeCategoryError } from './domain/value-objects/change-category.js';
|
|
10
5
|
export { ChangedFile } from './domain/value-objects/changed-file.js';
|
|
11
6
|
export { ChangeClassification } from './domain/value-objects/change-classification.js';
|
|
@@ -14,29 +9,23 @@ export { QuickModeDecision } from './domain/value-objects/quick-mode-decision.js
|
|
|
14
9
|
export { QuickModeEligibility } from './domain/value-objects/quick-mode-eligibility.js';
|
|
15
10
|
export { ValidatorRelaxationProfile } from './domain/value-objects/validator-relaxation-profile.js';
|
|
16
11
|
|
|
17
|
-
// Domain Services
|
|
18
12
|
export { QuickModeJudgmentEngine } from './domain/services/quick-mode-judgment-engine.js';
|
|
19
13
|
export { ValidatorRelaxationService } from './domain/services/validator-relaxation-service.js';
|
|
20
14
|
|
|
21
|
-
// Application DTOs
|
|
22
15
|
export type { QuickModeDecisionContract } from './application/dto/quick-mode-decision-contract.js';
|
|
23
16
|
export type { QuickModeEligibilityContract } from './application/dto/quick-mode-eligibility-contract.js';
|
|
24
17
|
export type { ValidatorRelaxationProfileContract } from './application/dto/validator-relaxation-profile-contract.js';
|
|
25
18
|
|
|
26
|
-
// Application UseCases
|
|
27
19
|
export { JudgeQuickModeEligibilityUseCase } from './application/usecases/judge-quick-mode-eligibility-usecase.js';
|
|
28
20
|
export { BuildRelaxationProfileUseCase, QuickModeNotEligibleError } from './application/usecases/build-relaxation-profile-usecase.js';
|
|
29
21
|
export { ExecuteQuickCiCheckUseCase } from './application/usecases/execute-quick-ci-check-usecase.js';
|
|
30
22
|
|
|
31
|
-
// Application Mappers
|
|
32
23
|
export { QuickModeDecisionContractMapper } from './application/mappers/quick-mode-decision-contract-mapper.js';
|
|
33
24
|
|
|
34
|
-
// Infrastructure Adapters
|
|
35
25
|
export { GitDiffChangedFilesAdapter, GitNotAvailableError, GitCommandError } from './infrastructure/adapters/git-diff-changed-files-adapter.js';
|
|
36
26
|
export { HarnessConfigQuickModeConfigAdapter, HarnessConfigNotFoundError, HarnessConfigParseError } from './infrastructure/adapters/harness-config-quick-mode-config-adapter.js';
|
|
37
27
|
export { ValidatorSystemValidatorIdRegistryAdapter } from './infrastructure/adapters/validator-system-validator-id-registry-adapter.js';
|
|
38
28
|
|
|
39
|
-
// Presentation
|
|
40
29
|
export { CiCheckQuickModeHandler } from './presentation/handlers/ci-check-quick-mode-handler.js';
|
|
41
30
|
export { HumanQuickModeFormatter } from './presentation/formatters/human-quick-mode-formatter.js';
|
|
42
31
|
export { AgentQuickModeFormatter } from './presentation/formatters/agent-quick-mode-formatter.js';
|
|
@@ -1,12 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
* Harnessスキルのデプロイメントインフラ。
|
|
5
|
-
* パッケージルートの skills/ を対象プロジェクトの .claude/skills/ にコピーする。
|
|
6
|
-
* harness init / harness update-skills コマンドから呼び出される。
|
|
7
|
-
*
|
|
8
|
-
* Note: import.meta.url を使わず、呼び出し元 (main.ts) がパスを解決して渡す設計。
|
|
9
|
-
*/
|
|
1
|
+
// @layer infrastructure
|
|
2
|
+
// Note: import.meta.url を使わず、呼び出し元 (main.ts) がパスを解決して渡す設計。
|
|
10
3
|
|
|
11
4
|
import { join } from 'node:path';
|
|
12
5
|
import { promises as fs } from 'node:fs';
|
|
@@ -60,9 +53,6 @@ export const SKILL_CATEGORIES: Record<SkillCategory, readonly string[]> = {
|
|
|
60
53
|
],
|
|
61
54
|
} as const;
|
|
62
55
|
|
|
63
|
-
/**
|
|
64
|
-
* 指定された SkillSet に含まれるスキル名の一覧を返す。
|
|
65
|
-
*/
|
|
66
56
|
export function getSkillsForSet(skillSet: SkillSet): string[] {
|
|
67
57
|
if (skillSet === 'core') {
|
|
68
58
|
return [...SKILL_CATEGORIES.core];
|
|
@@ -74,9 +64,6 @@ export function getSkillsForSet(skillSet: SkillSet): string[] {
|
|
|
74
64
|
];
|
|
75
65
|
}
|
|
76
66
|
|
|
77
|
-
/**
|
|
78
|
-
* スキル名からカテゴリを逆引きする。未知のスキルは null を返す。
|
|
79
|
-
*/
|
|
80
67
|
export function getCategoryForSkill(skillName: string): SkillCategory | null {
|
|
81
68
|
for (const [category, skills] of Object.entries(SKILL_CATEGORIES)) {
|
|
82
69
|
if ((skills as readonly string[]).includes(skillName)) {
|
|
@@ -128,13 +115,6 @@ async function copyDirectory(src: string, dest: string): Promise<number> {
|
|
|
128
115
|
return count;
|
|
129
116
|
}
|
|
130
117
|
|
|
131
|
-
/**
|
|
132
|
-
* skills/ ディレクトリを対象プロジェクトの .claude/skills/ にデプロイする。
|
|
133
|
-
* 既存ファイルは上書きされる(update-skills でも同じ関数を使う)。
|
|
134
|
-
*
|
|
135
|
-
* @param harnessRoot - harnessパッケージのルートディレクトリ(skills/がある場所)
|
|
136
|
-
* @param projectRoot - デプロイ先プロジェクトのルートディレクトリ
|
|
137
|
-
*/
|
|
138
118
|
export async function deploySkills(
|
|
139
119
|
harnessRoot: string,
|
|
140
120
|
projectRoot: string,
|
|
@@ -168,10 +148,6 @@ export async function deploySkills(
|
|
|
168
148
|
return { deployedSkills: skills, targetDir: skillsTarget, version, deployedAt, skillSet };
|
|
169
149
|
}
|
|
170
150
|
|
|
171
|
-
/**
|
|
172
|
-
* デプロイ済みバージョン情報を読み取る。
|
|
173
|
-
* .harness-version ファイルが存在しない場合は null を返す。
|
|
174
|
-
*/
|
|
175
151
|
export async function getDeployedVersion(projectRoot: string): Promise<VersionInfo | null> {
|
|
176
152
|
const versionFile = join(projectRoot, SKILLS_TARGET_DIR, HARNESS_VERSION_FILE);
|
|
177
153
|
try {
|
|
@@ -188,14 +164,6 @@ export interface DeployHooksResult {
|
|
|
188
164
|
settingsCreated: boolean;
|
|
189
165
|
}
|
|
190
166
|
|
|
191
|
-
/**
|
|
192
|
-
* templates/.claude/scripts/ を対象プロジェクトの .claude/scripts/ にデプロイする。
|
|
193
|
-
* templates/.claude/settings.json も存在しなければ作成する。
|
|
194
|
-
* 既存のスクリプトは上書き、settings.json は既存があればスキップ。
|
|
195
|
-
*
|
|
196
|
-
* @param harnessRoot - harnessパッケージのルートディレクトリ
|
|
197
|
-
* @param projectRoot - デプロイ先プロジェクトのルートディレクトリ
|
|
198
|
-
*/
|
|
199
167
|
export async function deployHookScripts(
|
|
200
168
|
harnessRoot: string,
|
|
201
169
|
projectRoot: string,
|
|
@@ -220,7 +188,6 @@ export async function deployHookScripts(
|
|
|
220
188
|
}
|
|
221
189
|
}
|
|
222
190
|
} catch {
|
|
223
|
-
// テンプレートが存在しない場合はスキップ
|
|
224
191
|
}
|
|
225
192
|
|
|
226
193
|
// settings.json を作成(既存があればスキップ)
|
|
@@ -238,17 +205,12 @@ export async function deployHookScripts(
|
|
|
238
205
|
await fs.copyFile(settingsSource, settingsTarget);
|
|
239
206
|
settingsCreated = true;
|
|
240
207
|
} catch {
|
|
241
|
-
|
|
242
|
-
}
|
|
208
|
+
}
|
|
243
209
|
}
|
|
244
210
|
|
|
245
211
|
return { scriptsDeployed, settingsCreated };
|
|
246
212
|
}
|
|
247
213
|
|
|
248
|
-
/**
|
|
249
|
-
* phasegate.config.json のデフォルトテンプレートを生成する。
|
|
250
|
-
* 対象プロジェクトに phasegate.config.json が存在しない場合のみ作成する。
|
|
251
|
-
*/
|
|
252
214
|
export async function initHarnessConfig(
|
|
253
215
|
projectRoot: string,
|
|
254
216
|
projectName: string,
|
|
@@ -298,12 +260,6 @@ export interface DeployDesignDocsResult {
|
|
|
298
260
|
skippedFiles: string[];
|
|
299
261
|
}
|
|
300
262
|
|
|
301
|
-
/**
|
|
302
|
-
* 設計原則ドキュメントを対象プロジェクトの docs/ にデプロイする。
|
|
303
|
-
* - docs/folder_management_rules.md → <projectRoot>/docs/folder_management_rules.md
|
|
304
|
-
* - docs/principles/*.md → <projectRoot>/docs/principles/*.md
|
|
305
|
-
* 既存ファイルは上書きせずスキップする。
|
|
306
|
-
*/
|
|
307
263
|
export async function deployDesignDocs(
|
|
308
264
|
harnessRoot: string,
|
|
309
265
|
projectRoot: string,
|
|
@@ -367,10 +323,6 @@ export interface DeployHuskyHookResult {
|
|
|
367
323
|
path: string;
|
|
368
324
|
}
|
|
369
325
|
|
|
370
|
-
/**
|
|
371
|
-
* husky pre-commit フックを対象プロジェクトの .husky/ にデプロイする。
|
|
372
|
-
* 既存があればスキップする。実行権限 0o755 を付与する。
|
|
373
|
-
*/
|
|
374
326
|
export async function deployHuskyHook(
|
|
375
327
|
harnessRoot: string,
|
|
376
328
|
projectRoot: string,
|
|
@@ -381,7 +333,6 @@ export async function deployHuskyHook(
|
|
|
381
333
|
await fs.access(targetPath);
|
|
382
334
|
return { created: false, path: targetPath };
|
|
383
335
|
} catch {
|
|
384
|
-
// 配置先が存在しない場合は新規作成
|
|
385
336
|
}
|
|
386
337
|
|
|
387
338
|
const sourcePath = join(harnessRoot, 'templates', '.husky', 'pre-commit');
|
|
@@ -397,11 +348,6 @@ export interface DeployCodexHooksResult {
|
|
|
397
348
|
path: string;
|
|
398
349
|
}
|
|
399
350
|
|
|
400
|
-
/**
|
|
401
|
-
* Codex CLI 向け hooks.json を対象プロジェクトの .codex/ にデプロイする。
|
|
402
|
-
* 既存があればスキップする (ユーザー定義 hooks を上書きしない)。
|
|
403
|
-
* ISSUE-013 Wave 2: --agent codex フラグ経由で init から呼び出される。
|
|
404
|
-
*/
|
|
405
351
|
export async function deployCodexHooks(
|
|
406
352
|
harnessRoot: string,
|
|
407
353
|
projectRoot: string,
|
|
@@ -412,7 +358,6 @@ export async function deployCodexHooks(
|
|
|
412
358
|
await fs.access(targetPath);
|
|
413
359
|
return { created: false, path: targetPath };
|
|
414
360
|
} catch {
|
|
415
|
-
// 配置先が存在しない場合は新規作成
|
|
416
361
|
}
|
|
417
362
|
|
|
418
363
|
const sourcePath = join(harnessRoot, 'templates', '.codex', 'hooks.json');
|
package/scripts/harness/skill-quality/infrastructure/adapters/ajv-lesson-artifact-schema-adapter.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* @layer infrastructure
|
|
3
3
|
* @unit skill-quality
|
|
4
4
|
*/
|
|
5
|
-
import AjvModule from 'ajv';
|
|
6
|
-
const Ajv =
|
|
5
|
+
import AjvModule, { type ErrorObject } from 'ajv';
|
|
6
|
+
const Ajv = AjvModule.default ?? AjvModule;
|
|
7
7
|
import type { LessonArtifactSchemaPort } from '../../domain/ports/lesson-artifact-schema-port.js';
|
|
8
8
|
import type { ValidationViolation } from '../../domain/types/validation-violation.js';
|
|
9
9
|
|
|
@@ -29,7 +29,7 @@ export class AjvLessonArtifactSchemaAdapter implements LessonArtifactSchemaPort
|
|
|
29
29
|
async validate(json: unknown): Promise<readonly ValidationViolation[]> {
|
|
30
30
|
const valid = this.compiledValidator(json);
|
|
31
31
|
if (valid) return [];
|
|
32
|
-
return (this.compiledValidator.errors ?? []).map((err:
|
|
32
|
+
return (this.compiledValidator.errors ?? []).map((err: ErrorObject) => ({
|
|
33
33
|
ruleId: 'SCHEMA_VIOLATION',
|
|
34
34
|
message: err.message ?? 'Schema validation error',
|
|
35
35
|
location: err.instancePath,
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*
|
|
5
|
-
* RunFullValidationInput — H08-06 UseCase入力DTO
|
|
6
|
-
*/
|
|
1
|
+
// @unit validator-system
|
|
2
|
+
// @layer application
|
|
3
|
+
|
|
7
4
|
export interface RunFullValidationInput {
|
|
8
5
|
readonly targetPaths: readonly string[];
|
|
9
6
|
readonly unitName: string;
|
|
@@ -13,9 +10,6 @@ export interface RunFullValidationInput {
|
|
|
13
10
|
readonly failOnWarning?: boolean;
|
|
14
11
|
readonly coverageReportPath?: string;
|
|
15
12
|
readonly requirementMatrixPath?: string;
|
|
16
|
-
/**
|
|
17
|
-
* ISSUE-005 P1-4: 実行レイヤー絞り込み。未指定は全レイヤー実行。
|
|
18
|
-
* 指定された場合、`includeL4` より優先される。
|
|
19
|
-
*/
|
|
13
|
+
/** 指定時は includeL4 より優先。未指定は全レイヤー実行。 */
|
|
20
14
|
readonly targetLayers?: readonly ('L2' | 'L3' | 'L4')[];
|
|
21
15
|
}
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* @unit validator-system
|
|
4
|
-
*
|
|
5
|
-
* ItTestFileAnalyzerPort — ITテストファイルのvi.mock解析ポート
|
|
6
|
-
*/
|
|
1
|
+
// @unit validator-system
|
|
2
|
+
// @layer domain
|
|
7
3
|
|
|
8
4
|
export interface ItTestMockCall {
|
|
9
5
|
readonly filePath: string;
|
|
@@ -11,10 +7,6 @@ export interface ItTestMockCall {
|
|
|
11
7
|
}
|
|
12
8
|
|
|
13
9
|
export interface ItTestFileAnalyzerPort {
|
|
14
|
-
/**
|
|
15
|
-
* 指定ファイル群のITテストファイルをスキャンし、vi.mockで内部モジュールを
|
|
16
|
-
* モックしている箇所を返す。
|
|
17
|
-
*/
|
|
18
10
|
findMockCallsInItTests(targetPaths?: readonly string[]): Promise<readonly ItTestMockCall[]>;
|
|
19
11
|
}
|
|
20
12
|
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*
|
|
5
|
-
* MetadataPolicyPort — traceability-model メタデータ検証仕様
|
|
6
|
-
*/
|
|
1
|
+
// @unit validator-system
|
|
2
|
+
// @layer domain
|
|
3
|
+
|
|
7
4
|
import type { HarnessErrorLike } from '../value-objects/validation-result.js';
|
|
8
5
|
|
|
9
6
|
export interface MetadataPolicyPort {
|
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* @unit validator-system
|
|
4
|
-
*
|
|
5
|
-
* SourceAnalysisPort — biome-ast-engine ImportGraph相当データ(L4-003)
|
|
6
|
-
*/
|
|
1
|
+
// @unit validator-system
|
|
2
|
+
// @layer domain
|
|
7
3
|
|
|
8
4
|
export interface ImportGraphData {
|
|
9
5
|
readonly nodes: readonly { filePath: string; exports: readonly string[] }[];
|
|
10
6
|
readonly edges: readonly { from: string; to: string; importedNames: readonly string[] }[];
|
|
11
|
-
/** DeadCodeDetectionService用: 未使用エクスポート・到達不能コード */
|
|
12
7
|
readonly unusedExports?: readonly string[];
|
|
13
8
|
readonly unreachableCode?: readonly { filePath: string; range: { startLine: number; endLine: number } }[];
|
|
14
9
|
}
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* @unit validator-system
|
|
4
|
-
*
|
|
5
|
-
* SourceCodeAnalyzerPort — AST解析結果取得(L4-001, L4-003)
|
|
6
|
-
*/
|
|
1
|
+
// @unit validator-system
|
|
2
|
+
// @layer domain
|
|
7
3
|
|
|
8
4
|
export interface SourceAnalysisResult {
|
|
9
5
|
readonly unitName: string;
|
|
@@ -14,6 +10,5 @@ export interface SourceAnalysisResult {
|
|
|
14
10
|
|
|
15
11
|
export interface SourceCodeAnalyzerPort {
|
|
16
12
|
analyzeExports(targetUnits?: readonly string[]): Promise<readonly SourceAnalysisResult[]>;
|
|
17
|
-
/** DriftDetectionService用: 要素名一覧取得 */
|
|
18
13
|
getElements?(targetUnits?: readonly string[]): Promise<string[]>;
|
|
19
14
|
}
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* @unit validator-system
|
|
4
|
-
*
|
|
5
|
-
* SourceFileTextScannerPort — ソースファイルテキストスキャンポート
|
|
6
|
-
*/
|
|
1
|
+
// @unit validator-system
|
|
2
|
+
// @layer domain
|
|
7
3
|
|
|
8
4
|
export interface TextScanMatch {
|
|
9
5
|
readonly filePath: string;
|
|
@@ -12,9 +8,6 @@ export interface TextScanMatch {
|
|
|
12
8
|
}
|
|
13
9
|
|
|
14
10
|
export interface SourceFileTextScannerPort {
|
|
15
|
-
/**
|
|
16
|
-
* 指定ファイル群のソースファイルをスキャンし、パターンに一致する行を返す。
|
|
17
|
-
*/
|
|
18
11
|
scanForPattern(pattern: RegExp, targetPaths?: readonly string[]): Promise<readonly TextScanMatch[]>;
|
|
19
12
|
}
|
|
20
13
|
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*
|
|
5
|
-
* TestQualityAnalyzerPort — AAAパターン・命名規約解析(L2-003)
|
|
6
|
-
*/
|
|
1
|
+
// @unit validator-system
|
|
2
|
+
// @layer domain
|
|
3
|
+
|
|
7
4
|
import type { HarnessErrorLike } from '../value-objects/validation-result.js';
|
|
8
5
|
|
|
9
6
|
export interface TestQualityAnalyzerPort {
|
|
@@ -1,17 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*
|
|
5
|
-
* CliE2eTestExistenceService — H08-09: CLIコマンドE2Eテスト存在チェックドメインサービス
|
|
6
|
-
* CLIハンドラー定義とE2Eテストファイルの突合検証を行う。
|
|
7
|
-
*/
|
|
1
|
+
// @unit validator-system
|
|
2
|
+
// @layer domain
|
|
3
|
+
|
|
8
4
|
import { CliE2eTestCoverageReport, type CliCommandCoverageEntry } from '../value-objects/cli-e2e-test-coverage-report.js';
|
|
9
5
|
|
|
10
6
|
export class CliE2eTestExistenceService {
|
|
11
|
-
/**
|
|
12
|
-
* 登録済みCLIコマンドとE2Eテストファイル一覧を突合し、カバレッジレポートを生成する。
|
|
13
|
-
* E2Eテストファイルのパスまたは内容にコマンド名が含まれていればカバー済みとみなす。
|
|
14
|
-
*/
|
|
15
7
|
check(commands: readonly string[], e2eTestFiles: readonly string[]): CliE2eTestCoverageReport {
|
|
16
8
|
const e2eContent = e2eTestFiles.join('\n').toLowerCase();
|
|
17
9
|
|
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*
|
|
5
|
-
* StubCommentDetectionService — H08-08: スタブコメント残存検出ドメインサービス
|
|
6
|
-
* ソースファイル内の stub 実装コメントパターンを検出する。
|
|
7
|
-
*/
|
|
1
|
+
// @unit validator-system
|
|
2
|
+
// @layer domain
|
|
3
|
+
|
|
8
4
|
import type { TextScanMatch } from '../ports/source-file-text-scanner-port.js';
|
|
9
5
|
import { StubCommentReport, type StubCommentEntry } from '../value-objects/stub-comment-report.js';
|
|
10
6
|
|
|
11
7
|
export class StubCommentDetectionService {
|
|
12
|
-
/** スタブコメント検出パターン */
|
|
13
8
|
static readonly STUB_COMMENT_PATTERN = /\/\/\s*(stub実装|Stub implementation|stub implementation|TODO.*stub|STUB)/i;
|
|
14
9
|
|
|
15
10
|
detect(matches: readonly TextScanMatch[]): StubCommentReport {
|
package/scripts/harness/validator-system/infrastructure/adapters/cli-command-registry-adapter.ts
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*
|
|
5
|
-
* CliCommandRegistryAdapter — CliCommandRegistryPort実装
|
|
6
|
-
* 登録済みCLIコマンド名一覧を提供する。
|
|
7
|
-
*/
|
|
1
|
+
// @unit validator-system
|
|
2
|
+
// @layer infrastructure
|
|
3
|
+
|
|
8
4
|
import type { CliCommandRegistryPort } from '../../domain/ports/cli-command-registry-port.js';
|
|
9
5
|
|
|
10
6
|
export interface CliCommandRegistryAdapterOptions {
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @layer domain
|
|
3
|
-
* @unit agent-integration
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export interface ImportAnalysisResult {
|
|
7
|
-
filePath: string;
|
|
8
|
-
agentApiImports: string[];
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface ImportAnalyzerPort {
|
|
12
|
-
analyzeAgentApiImports(targetFilePaths: string[]): Promise<ImportAnalysisResult[]>;
|
|
13
|
-
}
|
package/scripts/harness/agent-integration/infrastructure/adapters/regex-import-analyzer-adapter.ts
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @layer infrastructure
|
|
3
|
-
* @unit agent-integration
|
|
4
|
-
*
|
|
5
|
-
* RegexImportAnalyzerAdapter (TsMorphImportAnalyzerAdapter の代替実装)
|
|
6
|
-
* ts-morph が利用不可のため、正規表現ベースの import 解析を実装する
|
|
7
|
-
*
|
|
8
|
-
* 設計注意: ts-morph は package.json に含まれていないため、
|
|
9
|
-
* node:fs/promises + 正規表現で @anthropic-ai/claude-code の import を検出する
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import * as fs from 'node:fs/promises';
|
|
13
|
-
import type { ImportAnalyzerPort, ImportAnalysisResult } from '../../domain/ports/import-analyzer-port.js';
|
|
14
|
-
|
|
15
|
-
/** エージェント固有APIのパターン */
|
|
16
|
-
const AGENT_API_PATTERNS = [
|
|
17
|
-
'@anthropic-ai/claude-code',
|
|
18
|
-
'claude-code',
|
|
19
|
-
];
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* TypeScript ファイルから import 文を解析し、
|
|
23
|
-
* エージェント固有APIの import を検出する
|
|
24
|
-
*/
|
|
25
|
-
function detectAgentImportsInContent(content: string): string[] {
|
|
26
|
-
const detected: string[] = [];
|
|
27
|
-
// import { ... } from '...' または import ... from '...' のパターン
|
|
28
|
-
const importRegex = /import\s+(?:[^'"]*from\s+)?['"]([^'"]+)['"]/g;
|
|
29
|
-
let match: RegExpExecArray | null;
|
|
30
|
-
|
|
31
|
-
while ((match = importRegex.exec(content)) !== null) {
|
|
32
|
-
const modulePath = match[1];
|
|
33
|
-
if (modulePath && AGENT_API_PATTERNS.some((pattern) => modulePath === pattern || modulePath.startsWith(`${pattern}/`))) {
|
|
34
|
-
if (!detected.includes(modulePath)) {
|
|
35
|
-
detected.push(modulePath);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return detected;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export class RegexImportAnalyzerAdapter implements ImportAnalyzerPort {
|
|
44
|
-
async analyzeAgentApiImports(targetFilePaths: string[]): Promise<ImportAnalysisResult[]> {
|
|
45
|
-
if (targetFilePaths.length === 0) {
|
|
46
|
-
return [];
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const results: ImportAnalysisResult[] = [];
|
|
50
|
-
|
|
51
|
-
for (const filePath of targetFilePaths) {
|
|
52
|
-
let content: string;
|
|
53
|
-
try {
|
|
54
|
-
content = await fs.readFile(filePath, 'utf8');
|
|
55
|
-
} catch (error) {
|
|
56
|
-
// ファイルが存在しない場合はエラーを再スロー
|
|
57
|
-
throw new Error(`ファイルの読み取りに失敗しました: ${filePath}: ${String(error)}`);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const agentApiImports = detectAgentImportsInContent(content);
|
|
61
|
-
results.push({ filePath, agentApiImports });
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return results;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// TsMorphImportAnalyzerAdapter として同じクラスを re-export
|
|
69
|
-
export { RegexImportAnalyzerAdapter as TsMorphImportAnalyzerAdapter };
|