@shepai/cli 1.120.0 → 1.121.0-pr387.781b61f

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 (164) hide show
  1. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/evidence-output-parser.d.ts +21 -0
  2. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/evidence-output-parser.d.ts.map +1 -1
  3. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/evidence-output-parser.js +71 -0
  4. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/evidence.node.d.ts.map +1 -1
  5. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/evidence.node.js +11 -1
  6. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/evidence-prompts.d.ts.map +1 -1
  7. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/evidence-prompts.js +18 -6
  8. package/dist/src/presentation/web/components/common/feature-list-item/feature-list-item.stories.d.ts +1 -0
  9. package/dist/src/presentation/web/components/common/feature-list-item/feature-list-item.stories.d.ts.map +1 -1
  10. package/dist/src/presentation/web/components/common/feature-list-item/feature-list-item.stories.js +8 -0
  11. package/dist/src/presentation/web/components/common/feature-status-badges/feature-status-badges.stories.js +6 -6
  12. package/dist/src/presentation/web/components/common/feature-status-config.d.ts +1 -1
  13. package/dist/src/presentation/web/components/common/feature-status-config.d.ts.map +1 -1
  14. package/dist/src/presentation/web/components/common/feature-status-config.js +8 -1
  15. package/dist/src/presentation/web/components/common/feature-status-group/feature-status-group.stories.d.ts +1 -0
  16. package/dist/src/presentation/web/components/common/feature-status-group/feature-status-group.stories.d.ts.map +1 -1
  17. package/dist/src/presentation/web/components/common/feature-status-group/feature-status-group.stories.js +7 -0
  18. package/dist/src/presentation/web/hooks/sidebar-features-context.js +1 -1
  19. package/dist/tsconfig.build.tsbuildinfo +1 -1
  20. package/package.json +1 -1
  21. package/web/.next/BUILD_ID +1 -1
  22. package/web/.next/build-manifest.json +2 -2
  23. package/web/.next/fallback-build-manifest.json +2 -2
  24. package/web/.next/prerender-manifest.json +3 -3
  25. package/web/.next/required-server-files.js +3 -3
  26. package/web/.next/required-server-files.json +3 -3
  27. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +21 -21
  28. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  29. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  30. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +27 -27
  31. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  32. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  33. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +27 -27
  34. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  35. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  36. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +19 -19
  37. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  38. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  39. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +21 -21
  40. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  41. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  42. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +27 -27
  43. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  44. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  45. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +27 -27
  46. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  47. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  48. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +19 -19
  49. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  50. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  51. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +19 -19
  52. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  53. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  54. package/web/.next/server/app/_global-error.html +2 -2
  55. package/web/.next/server/app/_global-error.rsc +1 -1
  56. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  57. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  58. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  59. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  60. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  61. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  62. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  63. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  64. package/web/.next/server/app/api/cli-upgrade/route.js +2 -2
  65. package/web/.next/server/app/settings/page/server-reference-manifest.json +6 -6
  66. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  67. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  68. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  69. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  70. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  71. package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  72. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  73. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  74. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  75. package/web/.next/server/app/version/page.js.nft.json +1 -1
  76. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  77. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  78. package/web/.next/server/chunks/[root-of-the-server]__d2c18946._.js +2 -2
  79. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  80. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  81. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_ed372306.js +1 -1
  82. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_ed372306.js.map +1 -1
  83. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_32e26434.js +1 -1
  84. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_32e26434.js.map +1 -1
  85. package/web/.next/server/chunks/ssr/[root-of-the-server]__06fef644._.js +1 -1
  86. package/web/.next/server/chunks/ssr/[root-of-the-server]__3b14e5a0._.js +1 -1
  87. package/web/.next/server/chunks/ssr/[root-of-the-server]__3b14e5a0._.js.map +1 -1
  88. package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js +1 -1
  89. package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js.map +1 -1
  90. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  91. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
  92. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js +2 -2
  93. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js.map +1 -1
  94. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  95. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
  96. package/web/.next/server/chunks/ssr/[root-of-the-server]__8b59c03e._.js +1 -1
  97. package/web/.next/server/chunks/ssr/[root-of-the-server]__8b59c03e._.js.map +1 -1
  98. package/web/.next/server/chunks/ssr/[root-of-the-server]__8c553503._.js +2 -2
  99. package/web/.next/server/chunks/ssr/[root-of-the-server]__994ad9fe._.js +1 -1
  100. package/web/.next/server/chunks/ssr/[root-of-the-server]__994ad9fe._.js.map +1 -1
  101. package/web/.next/server/chunks/ssr/[root-of-the-server]__a022445f._.js +2 -2
  102. package/web/.next/server/chunks/ssr/[root-of-the-server]__a7de2711._.js +2 -2
  103. package/web/.next/server/chunks/ssr/[root-of-the-server]__c9c1cfee._.js +1 -1
  104. package/web/.next/server/chunks/ssr/[root-of-the-server]__c9c1cfee._.js.map +1 -1
  105. package/web/.next/server/chunks/ssr/_0dc2cfd3._.js +3 -0
  106. package/web/.next/server/chunks/ssr/_0dc2cfd3._.js.map +1 -0
  107. package/web/.next/server/chunks/ssr/_135edb9c._.js +1 -1
  108. package/web/.next/server/chunks/ssr/_135edb9c._.js.map +1 -1
  109. package/web/.next/server/chunks/ssr/{_16e2ff25._.js → _20f495c0._.js} +2 -2
  110. package/web/.next/server/chunks/ssr/{_16e2ff25._.js.map → _20f495c0._.js.map} +1 -1
  111. package/web/.next/server/chunks/ssr/_2f6f48b8._.js +1 -1
  112. package/web/.next/server/chunks/ssr/_2f6f48b8._.js.map +1 -1
  113. package/web/.next/server/chunks/ssr/{_c93f4352._.js → _64380792._.js} +2 -2
  114. package/web/.next/server/chunks/ssr/{_c93f4352._.js.map → _64380792._.js.map} +1 -1
  115. package/web/.next/server/chunks/ssr/{_503b26e9._.js → _88bbb656._.js} +2 -2
  116. package/web/.next/server/chunks/ssr/{_503b26e9._.js.map → _88bbb656._.js.map} +1 -1
  117. package/web/.next/server/chunks/ssr/_cc77a143._.js +1 -1
  118. package/web/.next/server/chunks/ssr/_cc77a143._.js.map +1 -1
  119. package/web/.next/server/chunks/ssr/{_f605354c._.js → _f1a649e3._.js} +3 -3
  120. package/web/.next/server/chunks/ssr/_f1a649e3._.js.map +1 -0
  121. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  122. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  123. package/web/.next/server/chunks/ssr/src_presentation_web_0835b28e._.js +2 -2
  124. package/web/.next/server/chunks/ssr/src_presentation_web_0835b28e._.js.map +1 -1
  125. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_e99d78dd.js +1 -1
  126. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_e99d78dd.js.map +1 -1
  127. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
  128. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
  129. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
  130. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
  131. package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +1 -1
  132. package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +1 -1
  133. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  134. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  135. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  136. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  137. package/web/.next/server/chunks/ssr/src_presentation_web_e8034a29._.js +2 -2
  138. package/web/.next/server/chunks/ssr/src_presentation_web_e8034a29._.js.map +1 -1
  139. package/web/.next/server/pages/500.html +2 -2
  140. package/web/.next/server/server-reference-manifest.js +1 -1
  141. package/web/.next/server/server-reference-manifest.json +33 -33
  142. package/web/.next/static/chunks/0abe87bdcd7c51d8.js +1 -0
  143. package/web/.next/static/chunks/0d2af96e64960ef5.css +1 -0
  144. package/web/.next/static/chunks/1ff208053b7fb006.js +1 -0
  145. package/web/.next/static/chunks/256e536a9e8cd2c9.js +11 -0
  146. package/web/.next/static/chunks/{abb2b485cb0da264.js → 5ae9cc287c601469.js} +1 -1
  147. package/web/.next/static/chunks/{51244236801cad96.js → 63bb5c87bc24f804.js} +1 -1
  148. package/web/.next/static/chunks/{263497416e5198a3.js → 65daed0a4e32e49d.js} +1 -1
  149. package/web/.next/static/chunks/71cd8eac141c3661.js +2 -0
  150. package/web/.next/static/chunks/{71161130b2462279.js → 96eeeb28e06de78c.js} +1 -1
  151. package/web/.next/static/chunks/{a5ff70a7709ec5af.js → 9eb3b826adeabf09.js} +1 -1
  152. package/web/.next/static/chunks/{700fc491c912dd68.js → c5e0431ad4ed3e83.js} +1 -1
  153. package/web/.next/static/chunks/{57e0b981e00941e4.js → dbdf4d220debd40f.js} +1 -1
  154. package/web/.next/server/chunks/ssr/_ab069e13._.js +0 -3
  155. package/web/.next/server/chunks/ssr/_ab069e13._.js.map +0 -1
  156. package/web/.next/server/chunks/ssr/_f605354c._.js.map +0 -1
  157. package/web/.next/static/chunks/027d779d1dd1535e.js +0 -1
  158. package/web/.next/static/chunks/844405e9e0f44c8b.js +0 -11
  159. package/web/.next/static/chunks/943a2b78e452a2fb.js +0 -2
  160. package/web/.next/static/chunks/d2739454715e5ef2.css +0 -1
  161. package/web/.next/static/chunks/f518c011aaa1941e.js +0 -1
  162. /package/web/.next/static/{oxdz8EAvGqpg8JW3gRSSs → SRaidBGUssl-JP_BPZctD}/_buildManifest.js +0 -0
  163. /package/web/.next/static/{oxdz8EAvGqpg8JW3gRSSs → SRaidBGUssl-JP_BPZctD}/_clientMiddlewareManifest.json +0 -0
  164. /package/web/.next/static/{oxdz8EAvGqpg8JW3gRSSs → SRaidBGUssl-JP_BPZctD}/_ssgManifest.js +0 -0
@@ -4,6 +4,9 @@
4
4
  * Extracts structured Evidence records from free-form agent text output.
5
5
  * Looks for a fenced JSON code block containing an array of evidence objects.
6
6
  * Returns empty array gracefully on any parsing failure.
7
+ *
8
+ * Also provides validation to ensure UI-related evidence includes app-level
9
+ * proof (not just Storybook screenshots).
7
10
  */
8
11
  import type { Evidence } from '../../../../../domain/generated/output.js';
9
12
  /**
@@ -12,4 +15,22 @@ import type { Evidence } from '../../../../../domain/generated/output.js';
12
15
  * Returns empty array when no block found, JSON is malformed, or no valid records exist.
13
16
  */
14
17
  export declare function parseEvidenceRecords(output: string): Evidence[];
18
+ export interface UiEvidenceValidationResult {
19
+ valid: boolean;
20
+ hasScreenshots: boolean;
21
+ hasAppScreenshots: boolean;
22
+ hasOnlyStorybookScreenshots: boolean;
23
+ warnings: string[];
24
+ }
25
+ /**
26
+ * Validate that UI-related evidence includes app-level proof, not just Storybook screenshots.
27
+ *
28
+ * Returns a validation result indicating whether the evidence set meets the requirement
29
+ * for app-level proof. Screenshots/videos are considered "Storybook-only" if their
30
+ * description or path contains storybook-related keywords and NO screenshots have
31
+ * app-level indicators.
32
+ *
33
+ * This validation is informational — it produces warnings but does not filter out records.
34
+ */
35
+ export declare function validateUiEvidenceHasAppProof(evidence: Evidence[]): UiEvidenceValidationResult;
15
36
  //# sourceMappingURL=evidence-output-parser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"evidence-output-parser.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/evidence-output-parser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2CAA2C,CAAC;AAwB1E;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,EAAE,CAc/D"}
1
+ {"version":3,"file":"evidence-output-parser.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/evidence-output-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2CAA2C,CAAC;AAwB1E;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,EAAE,CAc/D;AAwCD,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,OAAO,CAAC;IACf,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,2BAA2B,EAAE,OAAO,CAAC;IACrC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,0BAA0B,CAsC9F"}
@@ -4,6 +4,9 @@
4
4
  * Extracts structured Evidence records from free-form agent text output.
5
5
  * Looks for a fenced JSON code block containing an array of evidence objects.
6
6
  * Returns empty array gracefully on any parsing failure.
7
+ *
8
+ * Also provides validation to ensure UI-related evidence includes app-level
9
+ * proof (not just Storybook screenshots).
7
10
  */
8
11
  import { EvidenceType } from '../../../../../domain/generated/output.js';
9
12
  // Matches a fenced JSON code block: ```json ... ```
@@ -46,3 +49,71 @@ export function parseEvidenceRecords(output) {
46
49
  return [];
47
50
  return parsed.filter(isValidRecord);
48
51
  }
52
+ /**
53
+ * Patterns that indicate a screenshot is from Storybook rather than the actual app.
54
+ * Checked case-insensitively against description and relativePath.
55
+ */
56
+ const STORYBOOK_PATTERNS = [/storybook/i, /story\b/i, /stories/i, /\b6006\b/];
57
+ /**
58
+ * Patterns that indicate a screenshot is from the actual running application.
59
+ * Checked case-insensitively against description and relativePath.
60
+ */
61
+ const APP_PROOF_PATTERNS = [/\bapp[:\-\s]/i, /dev\s*server/i, /running\s*app/i, /actual\s*app/i];
62
+ function isScreenshot(e) {
63
+ return e.type === EvidenceType.Screenshot || e.type === EvidenceType.Video;
64
+ }
65
+ function matchesAny(text, patterns) {
66
+ return patterns.some((p) => p.test(text));
67
+ }
68
+ function isStorybookEvidence(e) {
69
+ return (matchesAny(e.description, STORYBOOK_PATTERNS) || matchesAny(e.relativePath, STORYBOOK_PATTERNS));
70
+ }
71
+ function isAppEvidence(e) {
72
+ // Explicitly marked as app-level evidence
73
+ if (matchesAny(e.description, APP_PROOF_PATTERNS) ||
74
+ matchesAny(e.relativePath, APP_PROOF_PATTERNS)) {
75
+ return true;
76
+ }
77
+ // A screenshot that is NOT storybook is treated as app-level evidence
78
+ return !isStorybookEvidence(e);
79
+ }
80
+ /**
81
+ * Validate that UI-related evidence includes app-level proof, not just Storybook screenshots.
82
+ *
83
+ * Returns a validation result indicating whether the evidence set meets the requirement
84
+ * for app-level proof. Screenshots/videos are considered "Storybook-only" if their
85
+ * description or path contains storybook-related keywords and NO screenshots have
86
+ * app-level indicators.
87
+ *
88
+ * This validation is informational — it produces warnings but does not filter out records.
89
+ */
90
+ export function validateUiEvidenceHasAppProof(evidence) {
91
+ const screenshots = evidence.filter(isScreenshot);
92
+ const warnings = [];
93
+ if (screenshots.length === 0) {
94
+ return {
95
+ valid: true,
96
+ hasScreenshots: false,
97
+ hasAppScreenshots: false,
98
+ hasOnlyStorybookScreenshots: false,
99
+ warnings,
100
+ };
101
+ }
102
+ const appScreenshots = screenshots.filter(isAppEvidence);
103
+ const storybookScreenshots = screenshots.filter(isStorybookEvidence);
104
+ const hasOnlyStorybook = storybookScreenshots.length > 0 && appScreenshots.length === 0;
105
+ if (hasOnlyStorybook) {
106
+ warnings.push('UI evidence contains only Storybook screenshots. App-level screenshots from the running application are REQUIRED for UI features.');
107
+ }
108
+ if (screenshots.length > 0 && appScreenshots.length === 0 && storybookScreenshots.length === 0) {
109
+ // Screenshots exist but none clearly identified as app or storybook — warn to be explicit
110
+ warnings.push('UI screenshots lack clear app-level indicators. Include "app" in the description or filename to confirm they are from the actual running application.');
111
+ }
112
+ return {
113
+ valid: !hasOnlyStorybook,
114
+ hasScreenshots: screenshots.length > 0,
115
+ hasAppScreenshots: appScreenshots.length > 0,
116
+ hasOnlyStorybookScreenshots: hasOnlyStorybook,
117
+ warnings,
118
+ };
119
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"evidence.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/evidence.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AAEpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAerD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,cAAc,IAG3C,OAAO,iBAAiB,KAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAuE7E"}
1
+ {"version":3,"file":"evidence.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/evidence.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AAEpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAerD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,cAAc,IAG3C,OAAO,iBAAiB,KAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAkF7E"}
@@ -22,7 +22,7 @@ import { reportNodeStart } from '../heartbeat.js';
22
22
  import { recordPhaseStart, recordPhaseEnd } from '../phase-timing-context.js';
23
23
  import { updateNodeLifecycle } from '../lifecycle-context.js';
24
24
  import { buildEvidencePrompt } from './prompts/evidence-prompts.js';
25
- import { parseEvidenceRecords } from './evidence-output-parser.js';
25
+ import { parseEvidenceRecords, validateUiEvidenceHasAppProof } from './evidence-output-parser.js';
26
26
  import { hasSettings, getSettings } from '../../../settings.service.js';
27
27
  /**
28
28
  * Factory that creates the evidence collection node function.
@@ -70,6 +70,15 @@ export function createEvidenceNode(executor) {
70
70
  log.error(`Warning: evidence parsing failed: ${msg} — continuing with empty evidence`);
71
71
  evidence = [];
72
72
  }
73
+ // --- Validate UI evidence includes app-level proof ---
74
+ const validationResult = validateUiEvidenceHasAppProof(evidence);
75
+ const validationMessages = [];
76
+ if (validationResult.warnings.length > 0) {
77
+ for (const warning of validationResult.warnings) {
78
+ log.error(`Evidence validation: ${warning}`);
79
+ validationMessages.push(`[evidence] Warning: ${warning}`);
80
+ }
81
+ }
73
82
  await recordPhaseEnd(timingId, durationMs);
74
83
  markPhaseComplete(state.specDir, 'evidence', log);
75
84
  return {
@@ -80,6 +89,7 @@ export function createEvidenceNode(executor) {
80
89
  ...(evidence.length === 0
81
90
  ? ['[evidence] Warning: no evidence records parsed from agent output']
82
91
  : []),
92
+ ...validationMessages,
83
93
  ],
84
94
  _needsReexecution: false,
85
95
  };
@@ -1 +1 @@
1
- {"version":3,"file":"evidence-prompts.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/evidence-prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,MAAM,WAAW,qBAAqB;IACpC,kEAAkE;IAClE,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,iBAAiB,EACxB,OAAO,GAAE,qBAAiD,GACzD,MAAM,CA8LR"}
1
+ {"version":3,"file":"evidence-prompts.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/evidence-prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,MAAM,WAAW,qBAAqB;IACpC,kEAAkE;IAClE,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,iBAAiB,EACxB,OAAO,GAAE,qBAAiD,GACzD,MAAM,CA0MR"}
@@ -90,11 +90,17 @@ ${cwd}
90
90
 
91
91
  Review the completed tasks above and capture evidence for each.
92
92
 
93
- ### MANDATORY Screenshot Rule
93
+ ### MANDATORY Screenshot Rule — App-Level Proof Required
94
94
 
95
- **If ANY task touches UI code (components, pages, views, styles, layouts, templates, JSX/TSX, HTML, CSS), you MUST capture at least one Screenshot.** This is non-negotiable. Changing a heading, button label, color, layout, or any visible element requires a screenshot proving the change renders correctly.
95
+ **If ANY task touches UI code (components, pages, views, styles, layouts, templates, JSX/TSX, HTML, CSS), you MUST capture at least one Screenshot from the ACTUAL RUNNING APPLICATION (dev server).** This is non-negotiable. Changing a heading, button label, color, layout, or any visible element requires a screenshot proving the change renders correctly in the real app context.
96
96
 
97
- To capture screenshots:
97
+ **CRITICAL: Storybook-only evidence is NOT sufficient for UI features.** Storybook screenshots may be included as supplementary evidence, but they do NOT replace app-level screenshots. You MUST capture screenshots from the actual running application (via the dev server) to prove the feature works in its real context with actual data, routing, and integration.
98
+
99
+ For each UI change you MUST capture:
100
+ 1. **App screenshot (REQUIRED)**: A screenshot from the running dev server showing the feature in its actual app context. Include "app" or the actual page/route name in the screenshot file name (e.g., \`app-dashboard-new-toggle.png\`, \`app-settings-page.png\`).
101
+ 2. **Storybook screenshot (OPTIONAL, supplementary)**: If the component has a Storybook story, you may also capture a Storybook screenshot as supplementary evidence. Include "storybook" in the file name (e.g., \`storybook-toggle-component.png\`).
102
+
103
+ To capture app-level screenshots:
98
104
  1. Install Playwright if not already available: \`npx playwright install chromium --with-deps 2>/dev/null || npx playwright install chromium\`
99
105
  2. Start the dev server in the background (e.g., \`npm run dev &\` or \`pnpm dev &\`)
100
106
  3. Wait for the server to be ready
@@ -114,11 +120,16 @@ To capture screenshots:
114
120
  \`\`\`
115
121
  5. Stop the dev server after capturing
116
122
 
123
+ To capture Storybook screenshots (supplementary only):
124
+ 1. Start Storybook: \`npx storybook dev -p 6006 &\` or \`pnpm dev:storybook &\`
125
+ 2. Navigate to the relevant story and capture a screenshot
126
+ 3. Stop Storybook after capturing
127
+
117
128
  If Playwright installation fails, try alternative approaches (e.g., \`npx puppeteer\`, \`curl\` for API responses). Only skip screenshots if ALL browser automation approaches fail — and in that case, explicitly note the failure reason in the evidence description.
118
129
 
119
130
  ### Evidence by Task Type
120
131
 
121
- - **UI/Web tasks**: You MUST take screenshots (see mandatory rule above). Also run and capture test output.
132
+ - **UI/Web tasks**: You MUST take screenshots FROM THE RUNNING APP (see mandatory rule above). Storybook-only screenshots are NOT acceptable as primary evidence. Also run and capture test output.
122
133
  - **Backend/API tasks**: Run the relevant test suite and capture test output showing passing tests.
123
134
  - **CLI tasks**: Run the CLI commands and capture terminal output demonstrating correct behavior.
124
135
  - **Refactoring/Infrastructure tasks**: Capture test output or build output confirming no regressions.
@@ -133,9 +144,10 @@ If Playwright installation fails, try alternative approaches (e.g., \`npx puppet
133
144
  ### Minimum Evidence Requirements
134
145
 
135
146
  Your output MUST include:
136
- 1. At least one **Screenshot** if any task modifies UI/visual code (components, styles, templates, markup)
147
+ 1. At least one **Screenshot from the running app** (NOT Storybook) if any task modifies UI/visual code (components, styles, templates, markup). The screenshot description MUST clearly indicate it was captured from the actual application (e.g., "App: dashboard page showing new toggle", "App: settings page with updated layout"). Do NOT use descriptions that suggest Storybook-only proof.
137
148
  2. At least one **TestOutput** if the project has a test suite
138
- 3. Do NOT output only TestOutput/TerminalRecording when the feature involves visible UI changes — screenshots are mandatory in that case
149
+ 3. Do NOT output only TestOutput/TerminalRecording when the feature involves visible UI changes — app-level screenshots are mandatory in that case
150
+ 4. Do NOT submit only Storybook screenshots for UI features — each UI screenshot MUST have a corresponding app-level screenshot proving the feature works in its real context
139
151
 
140
152
  ${storageSection}
141
153
 
@@ -6,6 +6,7 @@ type Story = StoryObj<typeof meta>;
6
6
  export declare const ActionNeeded: Story;
7
7
  export declare const InProgress: Story;
8
8
  export declare const Done: Story;
9
+ export declare const Pending: Story;
9
10
  export declare const Blocked: Story;
10
11
  export declare const Error: Story;
11
12
  export declare const WithClickHandler: Story;
@@ -1 +1 @@
1
- {"version":3,"file":"feature-list-item.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-list-item/feature-list-item.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,eAAe,CAgBtC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,YAAY,EAAE,KAO1B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAQxB,CAAC;AAEF,eAAO,MAAM,IAAI,EAAE,KAQlB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAOrB,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,KAOnB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAQ9B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC"}
1
+ {"version":3,"file":"feature-list-item.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-list-item/feature-list-item.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,eAAe,CAgBtC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,YAAY,EAAE,KAO1B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAQxB,CAAC;AAEF,eAAO,MAAM,IAAI,EAAE,KAQlB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAOrB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAOrB,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,KAOnB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAQ9B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC"}
@@ -39,6 +39,14 @@ export const Done = {
39
39
  modelId: 'gemini-2.5-pro',
40
40
  },
41
41
  };
42
+ export const Pending = {
43
+ args: {
44
+ name: 'Dark Mode Toggle',
45
+ status: 'pending',
46
+ agentType: 'claude-code',
47
+ modelId: 'claude-sonnet-4-6',
48
+ },
49
+ };
42
50
  export const Blocked = {
43
51
  args: {
44
52
  name: 'Dependency Resolver',
@@ -15,31 +15,31 @@ const meta = {
15
15
  export default meta;
16
16
  export const AllStatuses = {
17
17
  args: {
18
- counts: { 'action-needed': 2, 'in-progress': 3, blocked: 1, error: 1, done: 5 },
18
+ counts: { 'action-needed': 2, 'in-progress': 3, pending: 2, blocked: 1, error: 1, done: 5 },
19
19
  },
20
20
  };
21
21
  export const ActionNeededOnly = {
22
22
  args: {
23
- counts: { 'action-needed': 4, 'in-progress': 0, blocked: 0, error: 0, done: 0 },
23
+ counts: { 'action-needed': 4, 'in-progress': 0, pending: 0, blocked: 0, error: 0, done: 0 },
24
24
  },
25
25
  };
26
26
  export const InProgressOnly = {
27
27
  args: {
28
- counts: { 'action-needed': 0, 'in-progress': 2, blocked: 0, error: 0, done: 0 },
28
+ counts: { 'action-needed': 0, 'in-progress': 2, pending: 0, blocked: 0, error: 0, done: 0 },
29
29
  },
30
30
  };
31
31
  export const DoneOnly = {
32
32
  args: {
33
- counts: { 'action-needed': 0, 'in-progress': 0, blocked: 0, error: 0, done: 7 },
33
+ counts: { 'action-needed': 0, 'in-progress': 0, pending: 0, blocked: 0, error: 0, done: 7 },
34
34
  },
35
35
  };
36
36
  export const LargeCounts = {
37
37
  args: {
38
- counts: { 'action-needed': 12, 'in-progress': 99, blocked: 5, error: 3, done: 150 },
38
+ counts: { 'action-needed': 12, 'in-progress': 99, pending: 8, blocked: 5, error: 3, done: 150 },
39
39
  },
40
40
  };
41
41
  export const Empty = {
42
42
  args: {
43
- counts: { 'action-needed': 0, 'in-progress': 0, blocked: 0, error: 0, done: 0 },
43
+ counts: { 'action-needed': 0, 'in-progress': 0, pending: 0, blocked: 0, error: 0, done: 0 },
44
44
  },
45
45
  };
@@ -1,5 +1,5 @@
1
1
  import type { LucideIcon } from 'lucide-react';
2
- export type FeatureStatus = 'action-needed' | 'in-progress' | 'blocked' | 'error' | 'done';
2
+ export type FeatureStatus = 'action-needed' | 'in-progress' | 'pending' | 'blocked' | 'error' | 'done';
3
3
  export interface FeatureStatusConfig {
4
4
  icon: LucideIcon;
5
5
  iconClass: string;
@@ -1 +1 @@
1
- {"version":3,"file":"feature-status-config.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/components/common/feature-status-config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,MAAM,aAAa,GAAG,eAAe,GAAG,aAAa,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3F,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,aAAa,EAAE,mBAAmB,CA+B1E,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,aAAa,EAM7C,CAAC"}
1
+ {"version":3,"file":"feature-status-config.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/components/common/feature-status-config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,MAAM,aAAa,GACrB,eAAe,GACf,aAAa,GACb,SAAS,GACT,SAAS,GACT,OAAO,GACP,MAAM,CAAC;AAEX,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,aAAa,EAAE,mBAAmB,CAqC1E,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,aAAa,EAO7C,CAAC"}
@@ -1,4 +1,4 @@
1
- import { CircleAlert, Loader2, CircleCheck, Ban, CircleX } from 'lucide-react';
1
+ import { CircleAlert, Loader2, CircleCheck, Ban, CircleX, Clock } from 'lucide-react';
2
2
  export const featureStatusConfig = {
3
3
  'action-needed': {
4
4
  icon: CircleAlert,
@@ -12,6 +12,12 @@ export const featureStatusConfig = {
12
12
  bgClass: 'bg-blue-500/10',
13
13
  label: 'In Progress',
14
14
  },
15
+ pending: {
16
+ icon: Clock,
17
+ iconClass: 'text-slate-400',
18
+ bgClass: 'bg-slate-400/10',
19
+ label: 'Pending',
20
+ },
15
21
  blocked: {
16
22
  icon: Ban,
17
23
  iconClass: 'text-gray-400',
@@ -36,5 +42,6 @@ export const featureStatusOrder = [
36
42
  'error',
37
43
  'blocked',
38
44
  'in-progress',
45
+ 'pending',
39
46
  'done',
40
47
  ];
@@ -5,5 +5,6 @@ export default meta;
5
5
  type Story = StoryObj<typeof meta>;
6
6
  export declare const InProgress: Story;
7
7
  export declare const Done: Story;
8
+ export declare const Pending: Story;
8
9
  export declare const ActionNeeded: Story;
9
10
  //# sourceMappingURL=feature-status-group.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"feature-status-group.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-status-group/feature-status-group.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,kBAAkB,CAgBzC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,UAAU,EAAE,KAWxB,CAAC;AAEF,eAAO,MAAM,IAAI,EAAE,KAYlB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAW1B,CAAC"}
1
+ {"version":3,"file":"feature-status-group.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-status-group/feature-status-group.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,kBAAkB,CAgBzC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,UAAU,EAAE,KAWxB,CAAC;AAEF,eAAO,MAAM,IAAI,EAAE,KAYlB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAWrB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAW1B,CAAC"}
@@ -28,6 +28,13 @@ export const Done = {
28
28
  children: (_jsxs(_Fragment, { children: [_jsx(FeatureListItem, { name: "Settings Page", status: "done", duration: "2h" }), _jsx(FeatureListItem, { name: "User Profile", status: "done", duration: "1h" }), _jsx(FeatureListItem, { name: "Auth Module", status: "done", duration: "30m" })] })),
29
29
  },
30
30
  };
31
+ export const Pending = {
32
+ args: {
33
+ label: 'Pending',
34
+ count: 2,
35
+ children: (_jsxs(_Fragment, { children: [_jsx(FeatureListItem, { name: "Dark Mode", status: "pending" }), _jsx(FeatureListItem, { name: "Search Filters", status: "pending" })] })),
36
+ },
37
+ };
31
38
  export const ActionNeeded = {
32
39
  args: {
33
40
  label: 'Action Needed',
@@ -9,7 +9,7 @@ const stateMapping = {
9
9
  running: 'in-progress',
10
10
  done: 'done',
11
11
  blocked: 'blocked',
12
- pending: 'blocked',
12
+ pending: 'pending',
13
13
  error: 'error',
14
14
  creating: null,
15
15
  deleting: null,