@captain_z/zsk 1.0.2 → 1.2.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.
Files changed (45) hide show
  1. package/README.md +38 -3
  2. package/dist/bin.js +40 -1
  3. package/dist/bin.js.map +1 -1
  4. package/dist/commands/add-flow.d.ts +5 -2
  5. package/dist/commands/add-flow.js +83 -24
  6. package/dist/commands/add-flow.js.map +1 -1
  7. package/dist/commands/add.js +43 -19
  8. package/dist/commands/add.js.map +1 -1
  9. package/dist/commands/check.d.ts +4 -0
  10. package/dist/commands/check.js +157 -0
  11. package/dist/commands/check.js.map +1 -0
  12. package/dist/commands/config.d.ts +4 -0
  13. package/dist/commands/config.js +18 -0
  14. package/dist/commands/config.js.map +1 -0
  15. package/dist/commands/prep.d.ts +4 -0
  16. package/dist/commands/prep.js +27 -0
  17. package/dist/commands/prep.js.map +1 -0
  18. package/dist/commands/project-init.js +12 -11
  19. package/dist/commands/project-init.js.map +1 -1
  20. package/dist/commands/remove.js +5 -3
  21. package/dist/commands/remove.js.map +1 -1
  22. package/dist/core/config.d.ts +35 -0
  23. package/dist/core/config.js +191 -0
  24. package/dist/core/config.js.map +1 -0
  25. package/dist/core/raw-manifest.d.ts +21 -0
  26. package/dist/core/raw-manifest.js +53 -0
  27. package/dist/core/raw-manifest.js.map +1 -0
  28. package/dist/ui/prompts.d.ts +1 -0
  29. package/dist/ui/prompts.js +12 -1
  30. package/dist/ui/prompts.js.map +1 -1
  31. package/package.json +3 -2
  32. package/templates/project-init/.issues/README.md +26 -0
  33. package/templates/project-init/.issues/_templates/issue.md +44 -0
  34. package/templates/project-init/.raws/README.md +15 -12
  35. package/templates/project-init/.raws/api-contracts/README.md +13 -0
  36. package/templates/project-init/.raws/design-assets/README.md +16 -0
  37. package/templates/project-init/.raws/manifest.json +4 -0
  38. package/templates/project-init/.raws/testing/README.md +10 -0
  39. package/templates/project-init/.zsk/schemas/module.schema.json +203 -0
  40. package/templates/project-init/.zsk/schemas/zsk-config.schema.json +246 -0
  41. package/templates/project-init/SYSTEM-SPEC.md +55 -0
  42. package/templates/project-init/docs/_module-index.md +7 -0
  43. package/templates/project-init/docs/_module-template/module.yaml +32 -0
  44. package/templates/project-init/docs/system/README.md +12 -0
  45. package/templates/project-init/zsk.config.yaml +50 -0
@@ -0,0 +1,53 @@
1
+ import { createHash } from "node:crypto";
2
+ import { readFile, writeFile, mkdir, stat } from "node:fs/promises";
3
+ import { dirname, isAbsolute, resolve } from "node:path";
4
+ export async function updateRawManifest(file, records) {
5
+ await mkdir(dirname(file), { recursive: true });
6
+ const manifest = {
7
+ version: 1,
8
+ resources: records,
9
+ };
10
+ await writeFile(file, `${JSON.stringify(manifest, null, 2)}\n`, "utf8");
11
+ }
12
+ export async function describeResource(root, provider, source) {
13
+ const ref = source.path ?? source.output;
14
+ const fullPath = ref ? resolvePath(root, ref) : null;
15
+ const info = fullPath ? await safeStat(fullPath) : null;
16
+ return {
17
+ provider,
18
+ kind: source.kind ?? "local",
19
+ path: source.path,
20
+ output: source.output,
21
+ exists: Boolean(info),
22
+ size: info?.size ?? null,
23
+ hash: info && info.isFile ? await sha256(fullPath) : null,
24
+ syncedAt: new Date().toISOString(),
25
+ method: toMethod(source.kind),
26
+ };
27
+ }
28
+ function toMethod(kind) {
29
+ if (kind === "script")
30
+ return "script";
31
+ if (kind === "skill")
32
+ return "skill";
33
+ if (kind === "manual")
34
+ return "manual";
35
+ return "local";
36
+ }
37
+ async function safeStat(path) {
38
+ try {
39
+ const info = await stat(path);
40
+ return { size: info.size, isFile: info.isFile() };
41
+ }
42
+ catch {
43
+ return null;
44
+ }
45
+ }
46
+ async function sha256(path) {
47
+ const content = await readFile(path);
48
+ return createHash("sha256").update(content).digest("hex");
49
+ }
50
+ function resolvePath(root, value) {
51
+ return isAbsolute(value) ? value : resolve(root, value);
52
+ }
53
+ //# sourceMappingURL=raw-manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"raw-manifest.js","sourceRoot":"","sources":["../../src/core/raw-manifest.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import { intro as clackIntro, outro as clackOutro, spinner as clackSpinner, note
2
2
  type Primitive = Readonly<string | boolean | number>;
3
3
  export declare function select<T extends Primitive>(message: string, options: Option<T>[], initialValue?: T): Promise<T>;
4
4
  export declare function groupMultiselect<T extends Primitive>(message: string, options: Record<string, Option<T>[]>, initialValues?: T[]): Promise<T[]>;
5
+ export declare function multiselect<T extends Primitive>(message: string, options: Option<T>[], initialValues?: T[], maxItems?: number): Promise<T[]>;
5
6
  export declare function text(message: string, opts?: {
6
7
  placeholder?: string;
7
8
  validate?: (v: string) => string | undefined;
@@ -1,6 +1,6 @@
1
1
  // @clack/prompts wrappers with centralized isCancel handling.
2
2
  // All CLI interactive prompts go through this module so Ctrl+C is handled once.
3
- import { intro as clackIntro, outro as clackOutro, select as clackSelect, groupMultiselect as clackGroupMultiselect, confirm as clackConfirm, text as clackText, spinner as clackSpinner, note as clackNote, log, cancel, isCancel, } from "@clack/prompts";
3
+ import { intro as clackIntro, outro as clackOutro, select as clackSelect, multiselect as clackMultiselect, groupMultiselect as clackGroupMultiselect, confirm as clackConfirm, text as clackText, spinner as clackSpinner, note as clackNote, log, cancel, isCancel, } from "@clack/prompts";
4
4
  function exitIfCancel(value) {
5
5
  if (isCancel(value)) {
6
6
  cancel("已取消");
@@ -22,6 +22,17 @@ export async function groupMultiselect(message, options, initialValues = []) {
22
22
  exitIfCancel(v);
23
23
  return v;
24
24
  }
25
+ export async function multiselect(message, options, initialValues = [], maxItems = 12) {
26
+ const v = await clackMultiselect({
27
+ message,
28
+ options,
29
+ initialValues,
30
+ maxItems,
31
+ required: false,
32
+ });
33
+ exitIfCancel(v);
34
+ return v;
35
+ }
25
36
  export async function text(message, opts = {}) {
26
37
  const v = await clackText({
27
38
  message,
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/ui/prompts.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,gFAAgF;AAEhF,OAAO,EACL,KAAK,IAAI,UAAU,EACnB,KAAK,IAAI,UAAU,EACnB,MAAM,IAAI,WAAW,EACrB,gBAAgB,IAAI,qBAAqB,EACzC,OAAO,IAAI,YAAY,EACvB,IAAI,IAAI,SAAS,EACjB,OAAO,IAAI,YAAY,EACvB,IAAI,IAAI,SAAS,EACjB,GAAG,EACH,MAAM,EACN,QAAQ,GAET,MAAM,gBAAgB,CAAC;AAIxB,SAAS,YAAY,CAAI,KAAiB;IACxC,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACpB,MAAM,CAAC,KAAK,CAAC,CAAC;QACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,OAAe,EACf,OAAoB,EACpB,YAAgB;IAEhB,MAAM,CAAC,GAAG,MAAM,WAAW,CAAI,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC;IACnE,YAAY,CAAC,CAAC,CAAC,CAAC;IAChB,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAe,EACf,OAAoC,EACpC,gBAAqB,EAAE;IAEvB,MAAM,CAAC,GAAG,MAAM,qBAAqB,CAAI;QACvC,OAAO;QACP,OAAO;QACP,aAAa;QACb,QAAQ,EAAE,KAAK;KAChB,CAAC,CAAC;IACH,YAAY,CAAC,CAAC,CAAC,CAAC;IAChB,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,OAAe,EACf,OAGI,EAAE;IAEN,MAAM,CAAC,GAAG,MAAM,SAAS,CAAC;QACxB,OAAO;QACP,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,QAAQ,EAAE,IAAI,CAAC,QAAQ;KACxB,CAAC,CAAC;IACH,YAAY,CAAC,CAAC,CAAC,CAAC;IAChB,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,OAAe,EACf,YAAY,GAAG,IAAI;IAEnB,MAAM,CAAC,GAAG,MAAM,YAAY,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC;IACxD,YAAY,CAAC,CAAC,CAAC,CAAC;IAChB,OAAO,CAAC,CAAC;AACX,CAAC;AAED,OAAO,EACL,UAAU,IAAI,KAAK,EACnB,UAAU,IAAI,KAAK,EACnB,YAAY,IAAI,OAAO,EACvB,SAAS,IAAI,IAAI,EACjB,GAAG,GACJ,CAAC"}
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/ui/prompts.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,gFAAgF;AAEhF,OAAO,EACL,KAAK,IAAI,UAAU,EACnB,KAAK,IAAI,UAAU,EACnB,MAAM,IAAI,WAAW,EACrB,WAAW,IAAI,gBAAgB,EAC/B,gBAAgB,IAAI,qBAAqB,EACzC,OAAO,IAAI,YAAY,EACvB,IAAI,IAAI,SAAS,EACjB,OAAO,IAAI,YAAY,EACvB,IAAI,IAAI,SAAS,EACjB,GAAG,EACH,MAAM,EACN,QAAQ,GAET,MAAM,gBAAgB,CAAC;AAIxB,SAAS,YAAY,CAAI,KAAiB;IACxC,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACpB,MAAM,CAAC,KAAK,CAAC,CAAC;QACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,OAAe,EACf,OAAoB,EACpB,YAAgB;IAEhB,MAAM,CAAC,GAAG,MAAM,WAAW,CAAI,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC;IACnE,YAAY,CAAC,CAAC,CAAC,CAAC;IAChB,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAe,EACf,OAAoC,EACpC,gBAAqB,EAAE;IAEvB,MAAM,CAAC,GAAG,MAAM,qBAAqB,CAAI;QACvC,OAAO;QACP,OAAO;QACP,aAAa;QACb,QAAQ,EAAE,KAAK;KAChB,CAAC,CAAC;IACH,YAAY,CAAC,CAAC,CAAC,CAAC;IAChB,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,OAAe,EACf,OAAoB,EACpB,gBAAqB,EAAE,EACvB,QAAQ,GAAG,EAAE;IAEb,MAAM,CAAC,GAAG,MAAM,gBAAgB,CAAI;QAClC,OAAO;QACP,OAAO;QACP,aAAa;QACb,QAAQ;QACR,QAAQ,EAAE,KAAK;KAChB,CAAC,CAAC;IACH,YAAY,CAAC,CAAC,CAAC,CAAC;IAChB,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,OAAe,EACf,OAGI,EAAE;IAEN,MAAM,CAAC,GAAG,MAAM,SAAS,CAAC;QACxB,OAAO;QACP,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,QAAQ,EAAE,IAAI,CAAC,QAAQ;KACxB,CAAC,CAAC;IACH,YAAY,CAAC,CAAC,CAAC,CAAC;IAChB,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,OAAe,EACf,YAAY,GAAG,IAAI;IAEnB,MAAM,CAAC,GAAG,MAAM,YAAY,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC;IACxD,YAAY,CAAC,CAAC,CAAC,CAAC;IAChB,OAAO,CAAC,CAAC;AACX,CAAC;AAED,OAAO,EACL,UAAU,IAAI,KAAK,EACnB,UAAU,IAAI,KAAK,EACnB,YAAY,IAAI,OAAO,EACvB,SAAS,IAAI,IAAI,EACjB,GAAG,GACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@captain_z/zsk",
3
- "version": "1.0.2",
3
+ "version": "1.2.0",
4
4
  "description": "ZNorth Standard Kit — CLI installer for zsk skill bundles (npx @captain_z/zsk add)",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -15,10 +15,11 @@
15
15
  ],
16
16
  "dependencies": {
17
17
  "@clack/prompts": "^0.9.0",
18
+ "ajv": "^8.17.1",
18
19
  "commander": "^12.1.0",
19
20
  "picocolors": "^1.1.1",
20
21
  "yaml": "^2.7.0",
21
- "@captain_z/zsk-skills": "1.0.2"
22
+ "@captain_z/zsk-skills": "1.2.0"
22
23
  },
23
24
  "devDependencies": {
24
25
  "@types/node": "^22.10.0",
@@ -0,0 +1,26 @@
1
+ # Issues
2
+
3
+ `.issues/` stores local review findings, bug reports, screenshots, logs, reproduction evidence, and verification records created during project work.
4
+
5
+ ## Layout
6
+
7
+ ```text
8
+ .issues/
9
+ ├── README.md
10
+ ├── _templates/
11
+ │ └── issue.md
12
+ └── {module}/
13
+ └── BUG-0001-short-slug/
14
+ ├── issue.md
15
+ ├── assets/
16
+ └── debug-logs/
17
+ ```
18
+
19
+ ## Rules
20
+
21
+ - Keep one confirmed bug per `BUG-xxxx-short-slug/` directory.
22
+ - Group related bugs under the same module directory.
23
+ - Put bug-specific screenshots and runtime evidence under that bug's `assets/`.
24
+ - Put bug-specific console logs, test output, and investigation logs under that bug's `debug-logs/`.
25
+ - Do not place runtime screenshots, debug logs, or failed verification artifacts under `docs/`.
26
+ - Do not place local verification artifacts under `.raws/`.
@@ -0,0 +1,44 @@
1
+ # BUG-0000-short-description
2
+
3
+ ## Priority
4
+
5
+ P1
6
+
7
+ ## Module
8
+
9
+ `<module-id>`
10
+
11
+ ## Environment
12
+
13
+ - Date: YYYY-MM-DD
14
+ - Branch:
15
+ - URL:
16
+ - Command:
17
+ - Browser:
18
+ - Data source:
19
+
20
+ ## Reproduction Steps
21
+
22
+ 1.
23
+
24
+ ## Actual Result
25
+
26
+
27
+ ## Expected Result
28
+
29
+
30
+ ## Logs And Evidence
31
+
32
+ - `assets/<file>`:
33
+ - `debug-logs/<file>`:
34
+
35
+ ## Impact
36
+
37
+
38
+ ## Root Cause / Hypothesis
39
+
40
+
41
+ ## Status
42
+
43
+ - Status: Open
44
+ - Retest:
@@ -4,24 +4,26 @@
4
4
 
5
5
  ## 推荐内容
6
6
 
7
- | 文件 / 子目录 | 用途 | zsk skill 引用 |
7
+ | 文件 / 子目录 | 用途 | zsk 配置入口 |
8
8
  | --- | --- | --- |
9
- | `SRS.md` | 原始需求文档(Software Requirements Spec) | `{{config.paths.srs}}` |
10
- | `FIGMA-INDEX.md` | 模块 → Figma URL / node-id 索引 | `{{config.paths.figma_index}}` |
11
- | `api-contracts/` | 后端 API 契约(OpenAPI / GraphQL schema) | `{{config.paths.api_contracts}}` |
12
- | `design-assets/{module}/{snapshot}/` | Figma 快照(由 `zsk:ue-mcp` 产出) | `{{config.paths.design_assets}}` |
9
+ | `SRS.md` | 原始需求文档(Software Requirements Spec) | `zsk.config.yaml#sources.srs.path` |
10
+ | `FIGMA-INDEX.md` | 模块 → Figma URL / node-id 索引 | `zsk.config.yaml#sources.figma_index.path` |
11
+ | `api-contracts/` | 后端 API 契约(OpenAPI / GraphQL schema) | `zsk.config.yaml#sources.api_contracts.path` |
12
+ | `design-assets/{module}/{snapshot}/` | Figma 快照(由 `zsk:ue-mcp` 产出) | `zsk.config.yaml#sources.design_assets.path` |
13
+ | `testing/` | 原始测试用例、验收用例、提测测试包 | `docs/{module}/module.yaml` 的 `tests.raw_cases` |
14
+ | `manifest.json` | 资源同步清单,由 `zsk prep` / `zsk sync` 维护 | N/A |
13
15
 
14
16
  ## 消费路径
15
17
 
16
- skill 通过 `project-config.md` frontmatter `paths.*` 键找到本目录文件:
18
+ skill 通过 `zsk.config.yaml` `docs/{module}/module.yaml` 找到本目录文件:
17
19
 
18
20
  ```
19
- project-config.md:
20
- paths:
21
- srs: .raws/SRS.md
22
- figma_index: .raws/FIGMA-INDEX.md
23
- api_contracts: .raws/api-contracts
24
- design_assets: .raws/design-assets
21
+ zsk.config.yaml:
22
+ sources:
23
+ srs:
24
+ path: .raws/SRS.md
25
+ testing:
26
+ path: .raws/testing
25
27
  ```
26
28
 
27
29
  ## Git 状态建议
@@ -35,3 +37,4 @@ project-config.md:
35
37
  - **源文件不被 LLM 随意改写**:变更走人工/流程
36
38
  - **变更即新 snapshot**:Figma 更新→新 snapshot 目录,不覆盖历史
37
39
  - **编号锚稳定**:SRS 中的 `FR-001` / `US-001` / `AC-001` 一旦发布不改(仅废弃,合并/拆分留追踪)
40
+ - **测试用例是一等资产**:原始测试用例保存在 `.raws/testing/`,派生测试矩阵和自动化映射写入 `docs/{module}/`
@@ -0,0 +1,13 @@
1
+ # API Contracts
2
+
3
+ Store upstream API contracts here, grouped by service or provider.
4
+
5
+ Recommended layout:
6
+
7
+ ```text
8
+ .raws/api-contracts/
9
+ └── {service}/
10
+ └── contracts/
11
+ ```
12
+
13
+ Do not edit generated or upstream-owned contracts to match frontend assumptions. If a contract conflicts with SRS, test cases, or design assets, record an issue and resolve the decision in `docs/{module}/`.
@@ -0,0 +1,16 @@
1
+ # Design Assets
2
+
3
+ Store Figma, MCP, and design-source snapshots here.
4
+
5
+ Recommended layout:
6
+
7
+ ```text
8
+ .raws/design-assets/
9
+ └── {module}/
10
+ └── {snapshot}/
11
+ ├── description.md
12
+ ├── screenshot-*.png
13
+ └── raw/
14
+ ```
15
+
16
+ Treat each sync as a snapshot. Prefer adding a new snapshot over overwriting historical evidence.
@@ -0,0 +1,4 @@
1
+ {
2
+ "version": 1,
3
+ "resources": []
4
+ }
@@ -0,0 +1,10 @@
1
+ # Testing Sources
2
+
3
+ Store original test assets here:
4
+
5
+ - QA test cases
6
+ - acceptance spreadsheets or exports
7
+ - release test packs
8
+ - manually supplied validation scenarios
9
+
10
+ These are raw source facts. Derived scenario matrices and automated test mappings belong under `docs/{module}/`.
@@ -0,0 +1,203 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://zsk.dev/schemas/module.schema.json",
4
+ "title": "ZSK Module Config",
5
+ "description": "Module-level resource, runtime, test, and output mapping for ZSK workflows.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["module", "sources", "tests", "outputs"],
9
+ "properties": {
10
+ "module": {
11
+ "description": "Module identity.",
12
+ "type": "object",
13
+ "additionalProperties": false,
14
+ "required": ["id", "name"],
15
+ "properties": {
16
+ "id": {
17
+ "description": "Stable module slug.",
18
+ "type": "string",
19
+ "minLength": 1,
20
+ "pattern": "^[a-z0-9][a-z0-9-]*$"
21
+ },
22
+ "name": {
23
+ "description": "Human-readable module name.",
24
+ "type": "string",
25
+ "minLength": 1
26
+ },
27
+ "metadata": {
28
+ "$ref": "#/$defs/metadata"
29
+ }
30
+ }
31
+ },
32
+ "sources": {
33
+ "description": "Raw and derived resource inputs consumed by this module.",
34
+ "type": "object",
35
+ "additionalProperties": false,
36
+ "required": ["testing"],
37
+ "properties": {
38
+ "srs": {
39
+ "$ref": "#/$defs/srsSource"
40
+ },
41
+ "api_contracts": {
42
+ "$ref": "#/$defs/pathList"
43
+ },
44
+ "testing": {
45
+ "$ref": "#/$defs/pathList"
46
+ },
47
+ "design_assets": {
48
+ "$ref": "#/$defs/pathList"
49
+ },
50
+ "figma": {
51
+ "$ref": "#/$defs/pathList"
52
+ },
53
+ "metadata": {
54
+ "$ref": "#/$defs/metadata"
55
+ }
56
+ }
57
+ },
58
+ "runtime": {
59
+ "description": "Optional runtime verification target.",
60
+ "type": "object",
61
+ "additionalProperties": false,
62
+ "required": ["url"],
63
+ "properties": {
64
+ "url": {
65
+ "description": "Local or deployed URL used for runtime verification.",
66
+ "type": "string",
67
+ "minLength": 1
68
+ },
69
+ "tools": {
70
+ "description": "Preferred runtime verification tools.",
71
+ "type": "array",
72
+ "items": {
73
+ "$ref": "#/$defs/toolName"
74
+ },
75
+ "uniqueItems": true
76
+ },
77
+ "metadata": {
78
+ "$ref": "#/$defs/metadata"
79
+ }
80
+ }
81
+ },
82
+ "tests": {
83
+ "description": "Test asset mapping and TDD policy for this module.",
84
+ "type": "object",
85
+ "additionalProperties": false,
86
+ "required": ["raw_cases", "derived_cases", "automated", "tdd_required"],
87
+ "properties": {
88
+ "raw_cases": {
89
+ "$ref": "#/$defs/pathList"
90
+ },
91
+ "derived_cases": {
92
+ "$ref": "#/$defs/pathList"
93
+ },
94
+ "automated": {
95
+ "description": "Executable test locations grouped by test level.",
96
+ "type": "object",
97
+ "additionalProperties": false,
98
+ "required": ["unit", "integration", "e2e"],
99
+ "properties": {
100
+ "unit": {
101
+ "$ref": "#/$defs/pathList"
102
+ },
103
+ "integration": {
104
+ "$ref": "#/$defs/pathList"
105
+ },
106
+ "e2e": {
107
+ "$ref": "#/$defs/pathList"
108
+ },
109
+ "metadata": {
110
+ "$ref": "#/$defs/metadata"
111
+ }
112
+ }
113
+ },
114
+ "tdd_required": {
115
+ "description": "Whether AI coding must create/update failing tests before implementation.",
116
+ "type": "boolean"
117
+ },
118
+ "metadata": {
119
+ "$ref": "#/$defs/metadata"
120
+ }
121
+ }
122
+ },
123
+ "outputs": {
124
+ "description": "Module output locations for docs and issues.",
125
+ "type": "object",
126
+ "additionalProperties": false,
127
+ "required": ["docs", "issues"],
128
+ "properties": {
129
+ "docs": {
130
+ "$ref": "#/$defs/pathRef"
131
+ },
132
+ "issues": {
133
+ "$ref": "#/$defs/pathRef"
134
+ },
135
+ "metadata": {
136
+ "$ref": "#/$defs/metadata"
137
+ }
138
+ }
139
+ },
140
+ "metadata": {
141
+ "$ref": "#/$defs/metadata"
142
+ }
143
+ },
144
+ "$defs": {
145
+ "pathRef": {
146
+ "description": "Project-relative path unless the value is intentionally absolute.",
147
+ "type": "string",
148
+ "minLength": 1
149
+ },
150
+ "pathList": {
151
+ "description": "List of project-relative paths or glob-like path patterns.",
152
+ "type": "array",
153
+ "items": {
154
+ "$ref": "#/$defs/pathRef"
155
+ },
156
+ "uniqueItems": true
157
+ },
158
+ "srsSource": {
159
+ "description": "SRS source path with optional section anchors.",
160
+ "type": "object",
161
+ "additionalProperties": false,
162
+ "required": ["path"],
163
+ "properties": {
164
+ "path": {
165
+ "$ref": "#/$defs/pathRef"
166
+ },
167
+ "sections": {
168
+ "description": "Relevant SRS sections for this module.",
169
+ "type": "array",
170
+ "items": {
171
+ "type": "string",
172
+ "minLength": 1
173
+ },
174
+ "uniqueItems": true
175
+ },
176
+ "anchors": {
177
+ "description": "Stable raw-source anchors such as FR/AC IDs.",
178
+ "type": "array",
179
+ "items": {
180
+ "type": "string",
181
+ "minLength": 1
182
+ },
183
+ "uniqueItems": true
184
+ },
185
+ "metadata": {
186
+ "$ref": "#/$defs/metadata"
187
+ }
188
+ }
189
+ },
190
+ "toolName": {
191
+ "description": "Known runtime/design verification tool.",
192
+ "type": "string",
193
+ "enum": ["computer_use", "browser_use", "figma_mcp", "script", "manual", "skill"]
194
+ },
195
+ "metadata": {
196
+ "description": "Explicit extension point for project-specific metadata.",
197
+ "type": "object",
198
+ "additionalProperties": {
199
+ "type": ["string", "number", "integer", "boolean", "null"]
200
+ }
201
+ }
202
+ }
203
+ }