gsd-pi 2.63.0-dev.d04bbc5 → 2.64.0-dev.9c14bd0

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 (65) hide show
  1. package/dist/resources/extensions/gsd/auto-dashboard.js +5 -5
  2. package/dist/resources/extensions/gsd/auto-post-unit.js +98 -1
  3. package/dist/resources/extensions/gsd/auto-verification.js +138 -1
  4. package/dist/resources/extensions/gsd/auto.js +5 -0
  5. package/dist/resources/extensions/gsd/post-execution-checks.js +407 -0
  6. package/dist/resources/extensions/gsd/pre-execution-checks.js +464 -0
  7. package/dist/resources/extensions/gsd/preferences-types.js +4 -0
  8. package/dist/resources/extensions/gsd/preferences-validation.js +33 -0
  9. package/dist/resources/extensions/gsd/preferences.js +4 -0
  10. package/dist/resources/extensions/gsd/verification-evidence.js +18 -0
  11. package/dist/web/standalone/.next/BUILD_ID +1 -1
  12. package/dist/web/standalone/.next/app-path-routes-manifest.json +15 -15
  13. package/dist/web/standalone/.next/build-manifest.json +2 -2
  14. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  15. package/dist/web/standalone/.next/required-server-files.json +1 -1
  16. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  17. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  18. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  19. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  20. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  21. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  22. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  23. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  24. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  25. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  26. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  27. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  28. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  29. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  30. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  31. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  32. package/dist/web/standalone/.next/server/app/index.html +1 -1
  33. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  34. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  35. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  36. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  37. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  38. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  39. package/dist/web/standalone/.next/server/app-paths-manifest.json +15 -15
  40. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  41. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  42. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  43. package/dist/web/standalone/server.js +1 -1
  44. package/package.json +1 -1
  45. package/packages/pi-coding-agent/package.json +1 -1
  46. package/pkg/package.json +1 -1
  47. package/src/resources/extensions/gsd/auto-dashboard.ts +5 -4
  48. package/src/resources/extensions/gsd/auto-post-unit.ts +122 -0
  49. package/src/resources/extensions/gsd/auto-verification.ts +190 -2
  50. package/src/resources/extensions/gsd/auto.ts +4 -0
  51. package/src/resources/extensions/gsd/post-execution-checks.ts +539 -0
  52. package/src/resources/extensions/gsd/pre-execution-checks.ts +573 -0
  53. package/src/resources/extensions/gsd/preferences-types.ts +28 -0
  54. package/src/resources/extensions/gsd/preferences-validation.ts +33 -0
  55. package/src/resources/extensions/gsd/preferences.ts +4 -0
  56. package/src/resources/extensions/gsd/tests/auto-start-time-persistence.test.ts +50 -0
  57. package/src/resources/extensions/gsd/tests/enhanced-verification-integration.test.ts +526 -0
  58. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +312 -0
  59. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +813 -0
  60. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +999 -0
  61. package/src/resources/extensions/gsd/tests/pre-execution-fail-closed.test.ts +266 -0
  62. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +457 -0
  63. package/src/resources/extensions/gsd/verification-evidence.ts +68 -0
  64. /package/dist/web/standalone/.next/static/{vIq9fmvRUaFOpguoX5j4W → SoxM61WC_ia7R2gk4VMpJ}/_buildManifest.js +0 -0
  65. /package/dist/web/standalone/.next/static/{vIq9fmvRUaFOpguoX5j4W → SoxM61WC_ia7R2gk4VMpJ}/_ssgManifest.js +0 -0
@@ -1,46 +1,46 @@
1
1
  {
2
2
  "/_not-found/page": "app/_not-found/page.js",
3
3
  "/_global-error/page": "app/_global-error/page.js",
4
+ "/api/bridge-terminal/input/route": "app/api/bridge-terminal/input/route.js",
4
5
  "/api/boot/route": "app/api/boot/route.js",
5
6
  "/api/bridge-terminal/resize/route": "app/api/bridge-terminal/resize/route.js",
6
7
  "/api/dev-mode/route": "app/api/dev-mode/route.js",
7
- "/api/bridge-terminal/input/route": "app/api/bridge-terminal/input/route.js",
8
- "/api/bridge-terminal/stream/route": "app/api/bridge-terminal/stream/route.js",
9
8
  "/api/cleanup/route": "app/api/cleanup/route.js",
10
9
  "/api/doctor/route": "app/api/doctor/route.js",
11
10
  "/api/export-data/route": "app/api/export-data/route.js",
12
- "/api/git/route": "app/api/git/route.js",
11
+ "/api/browse-directories/route": "app/api/browse-directories/route.js",
13
12
  "/api/captures/route": "app/api/captures/route.js",
14
13
  "/api/forensics/route": "app/api/forensics/route.js",
14
+ "/api/git/route": "app/api/git/route.js",
15
15
  "/api/hooks/route": "app/api/hooks/route.js",
16
16
  "/api/history/route": "app/api/history/route.js",
17
- "/api/browse-directories/route": "app/api/browse-directories/route.js",
18
- "/api/inspect/route": "app/api/inspect/route.js",
19
- "/api/knowledge/route": "app/api/knowledge/route.js",
20
17
  "/api/experimental/route": "app/api/experimental/route.js",
21
- "/api/live-state/route": "app/api/live-state/route.js",
18
+ "/api/bridge-terminal/stream/route": "app/api/bridge-terminal/stream/route.js",
19
+ "/api/knowledge/route": "app/api/knowledge/route.js",
20
+ "/api/inspect/route": "app/api/inspect/route.js",
22
21
  "/api/preferences/route": "app/api/preferences/route.js",
23
22
  "/api/recovery/route": "app/api/recovery/route.js",
24
23
  "/api/onboarding/route": "app/api/onboarding/route.js",
25
24
  "/api/projects/route": "app/api/projects/route.js",
25
+ "/api/live-state/route": "app/api/live-state/route.js",
26
26
  "/api/session/browser/route": "app/api/session/browser/route.js",
27
27
  "/api/settings-data/route": "app/api/settings-data/route.js",
28
+ "/api/session/command/route": "app/api/session/command/route.js",
29
+ "/api/session/manage/route": "app/api/session/manage/route.js",
30
+ "/api/session/events/route": "app/api/session/events/route.js",
28
31
  "/api/shutdown/route": "app/api/shutdown/route.js",
29
32
  "/api/skill-health/route": "app/api/skill-health/route.js",
30
- "/api/session/events/route": "app/api/session/events/route.js",
31
- "/api/session/manage/route": "app/api/session/manage/route.js",
32
- "/api/terminal/input/route": "app/api/terminal/input/route.js",
33
- "/api/session/command/route": "app/api/session/command/route.js",
34
33
  "/api/steer/route": "app/api/steer/route.js",
34
+ "/api/terminal/input/route": "app/api/terminal/input/route.js",
35
+ "/api/terminal/resize/route": "app/api/terminal/resize/route.js",
36
+ "/api/files/route": "app/api/files/route.js",
35
37
  "/api/switch-root/route": "app/api/switch-root/route.js",
36
38
  "/api/terminal/sessions/route": "app/api/terminal/sessions/route.js",
39
+ "/api/terminal/upload/route": "app/api/terminal/upload/route.js",
37
40
  "/api/terminal/stream/route": "app/api/terminal/stream/route.js",
38
- "/api/terminal/resize/route": "app/api/terminal/resize/route.js",
39
41
  "/api/visualizer/route": "app/api/visualizer/route.js",
40
42
  "/api/undo/route": "app/api/undo/route.js",
41
- "/api/files/route": "app/api/files/route.js",
42
- "/api/update/route": "app/api/update/route.js",
43
- "/api/terminal/upload/route": "app/api/terminal/upload/route.js",
44
43
  "/api/remote-questions/route": "app/api/remote-questions/route.js",
44
+ "/api/update/route": "app/api/update/route.js",
45
45
  "/page": "app/page.js"
46
46
  }
@@ -1 +1 @@
1
- <!DOCTYPE html><!--vIq9fmvRUaFOpguoX5j4W--><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/><link rel="preload" href="/_next/static/media/4cf2300e9c8272f7-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="preload" href="/_next/static/media/93f479601ee12b01-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/css/de70bee13400563f.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/f6e8833d46e738d8.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-a1c1e452c6b32d04.js"/><script src="/_next/static/chunks/4bd1b696-e5d7c65570c947b7.js" async=""></script><script src="/_next/static/chunks/3794-337d1ca25ad99a89.js" async=""></script><script src="/_next/static/chunks/main-app-fdab67f7802d7832.js" async=""></script><script src="/_next/static/chunks/4986-c2fc8845ce785303.js" async=""></script><script src="/_next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js" async=""></script><meta name="robots" content="noindex"/><meta name="next-size-adjust" content=""/><title>404: This page could not be found.</title><title>GSD</title><meta name="description" content="The evolution of Get Shit Done — now a real coding agent. One command. Walk away. Come back to a built project."/><meta name="application-name" content="GSD"/><link rel="icon" href="/icon-light-32x32.png" media="(prefers-color-scheme: light)"/><link rel="icon" href="/icon-dark-32x32.png" media="(prefers-color-scheme: dark)"/><link rel="icon" href="/icon.svg" type="image/svg+xml"/><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body class="__variable_188709 __variable_9a8899 font-sans antialiased"><div hidden=""><!--$--><!--/$--></div><script>((a,b,c,d,e,f,g,h)=>{let i=document.documentElement,j=["light","dark"];function k(b){var c;(Array.isArray(a)?a:[a]).forEach(a=>{let c="class"===a,d=c&&f?e.map(a=>f[a]||a):e;c?(i.classList.remove(...d),i.classList.add(f&&f[b]?f[b]:b)):i.setAttribute(a,b)}),c=b,h&&j.includes(c)&&(i.style.colorScheme=c)}if(d)k(d);else try{let a=localStorage.getItem(b)||c,d=g&&"system"===a?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":a;k(d)}catch(a){}})("class","theme","dark",null,["light","dark"],null,true,true)</script><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false"></section><script src="/_next/static/chunks/webpack-a1c1e452c6b32d04.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[21942,[\"4986\",\"static/chunks/4986-c2fc8845ce785303.js\",\"7177\",\"static/chunks/app/layout-a16c7a7ecdf0c2cf.js\"],\"ThemeProvider\"]\n3:I[57121,[],\"\"]\n4:I[74581,[],\"\"]\n5:I[61549,[\"4986\",\"static/chunks/4986-c2fc8845ce785303.js\",\"7177\",\"static/chunks/app/layout-a16c7a7ecdf0c2cf.js\"],\"Toaster\"]\n6:I[90484,[],\"OutletBoundary\"]\n7:\"$Sreact.suspense\"\n9:I[90484,[],\"ViewportBoundary\"]\nb:I[90484,[],\"MetadataBoundary\"]\nd:I[27123,[],\"\"]\n:HL[\"/_next/static/media/4cf2300e9c8272f7-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/media/93f479601ee12b01-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/css/de70bee13400563f.css\",\"style\"]\n:HL[\"/_next/static/css/f6e8833d46e738d8.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"vIq9fmvRUaFOpguoX5j4W\",\"c\":[\"\",\"_not-found\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/de70bee13400563f.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/f6e8833d46e738d8.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"suppressHydrationWarning\":true,\"children\":[\"$\",\"body\",null,{\"className\":\"__variable_188709 __variable_9a8899 font-sans antialiased\",\"children\":[\"$\",\"$L2\",null,{\"attribute\":\"class\",\"defaultTheme\":\"dark\",\"children\":[[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}],[\"$\",\"$L5\",null,{\"position\":\"bottom-right\"}]]}]}]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L6\",null,{\"children\":[\"$\",\"$7\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@8\"}]}]]}],{},null,false,false]},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[\"$\",\"$L9\",null,{\"children\":\"$La\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$Lb\",null,{\"children\":[\"$\",\"$7\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lc\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$d\",[]],\"S\":true}\n"])</script><script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no\"}]]\n"])</script><script>self.__next_f.push([1,"e:I[86869,[],\"IconMark\"]\n8:null\nc:[[\"$\",\"title\",\"0\",{\"children\":\"GSD\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"The evolution of Get Shit Done — now a real coding agent. One command. Walk away. Come back to a built project.\"}],[\"$\",\"meta\",\"2\",{\"name\":\"application-name\",\"content\":\"GSD\"}],[\"$\",\"link\",\"3\",{\"rel\":\"icon\",\"href\":\"/icon-light-32x32.png\",\"media\":\"(prefers-color-scheme: light)\"}],[\"$\",\"link\",\"4\",{\"rel\":\"icon\",\"href\":\"/icon-dark-32x32.png\",\"media\":\"(prefers-color-scheme: dark)\"}],[\"$\",\"link\",\"5\",{\"rel\":\"icon\",\"href\":\"/icon.svg\",\"type\":\"image/svg+xml\"}],[\"$\",\"$Le\",\"6\",{}]]\n"])</script></body></html>
1
+ <!DOCTYPE html><!--SoxM61WC_ia7R2gk4VMpJ--><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/><link rel="preload" href="/_next/static/media/4cf2300e9c8272f7-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="preload" href="/_next/static/media/93f479601ee12b01-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/css/de70bee13400563f.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/f6e8833d46e738d8.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-a1c1e452c6b32d04.js"/><script src="/_next/static/chunks/4bd1b696-e5d7c65570c947b7.js" async=""></script><script src="/_next/static/chunks/3794-337d1ca25ad99a89.js" async=""></script><script src="/_next/static/chunks/main-app-fdab67f7802d7832.js" async=""></script><script src="/_next/static/chunks/4986-c2fc8845ce785303.js" async=""></script><script src="/_next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js" async=""></script><meta name="robots" content="noindex"/><meta name="next-size-adjust" content=""/><title>404: This page could not be found.</title><title>GSD</title><meta name="description" content="The evolution of Get Shit Done — now a real coding agent. One command. Walk away. Come back to a built project."/><meta name="application-name" content="GSD"/><link rel="icon" href="/icon-light-32x32.png" media="(prefers-color-scheme: light)"/><link rel="icon" href="/icon-dark-32x32.png" media="(prefers-color-scheme: dark)"/><link rel="icon" href="/icon.svg" type="image/svg+xml"/><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body class="__variable_188709 __variable_9a8899 font-sans antialiased"><div hidden=""><!--$--><!--/$--></div><script>((a,b,c,d,e,f,g,h)=>{let i=document.documentElement,j=["light","dark"];function k(b){var c;(Array.isArray(a)?a:[a]).forEach(a=>{let c="class"===a,d=c&&f?e.map(a=>f[a]||a):e;c?(i.classList.remove(...d),i.classList.add(f&&f[b]?f[b]:b)):i.setAttribute(a,b)}),c=b,h&&j.includes(c)&&(i.style.colorScheme=c)}if(d)k(d);else try{let a=localStorage.getItem(b)||c,d=g&&"system"===a?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":a;k(d)}catch(a){}})("class","theme","dark",null,["light","dark"],null,true,true)</script><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false"></section><script src="/_next/static/chunks/webpack-a1c1e452c6b32d04.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[21942,[\"4986\",\"static/chunks/4986-c2fc8845ce785303.js\",\"7177\",\"static/chunks/app/layout-a16c7a7ecdf0c2cf.js\"],\"ThemeProvider\"]\n3:I[57121,[],\"\"]\n4:I[74581,[],\"\"]\n5:I[61549,[\"4986\",\"static/chunks/4986-c2fc8845ce785303.js\",\"7177\",\"static/chunks/app/layout-a16c7a7ecdf0c2cf.js\"],\"Toaster\"]\n6:I[90484,[],\"OutletBoundary\"]\n7:\"$Sreact.suspense\"\n9:I[90484,[],\"ViewportBoundary\"]\nb:I[90484,[],\"MetadataBoundary\"]\nd:I[27123,[],\"\"]\n:HL[\"/_next/static/media/4cf2300e9c8272f7-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/media/93f479601ee12b01-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/css/de70bee13400563f.css\",\"style\"]\n:HL[\"/_next/static/css/f6e8833d46e738d8.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"SoxM61WC_ia7R2gk4VMpJ\",\"c\":[\"\",\"_not-found\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/de70bee13400563f.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/f6e8833d46e738d8.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"suppressHydrationWarning\":true,\"children\":[\"$\",\"body\",null,{\"className\":\"__variable_188709 __variable_9a8899 font-sans antialiased\",\"children\":[\"$\",\"$L2\",null,{\"attribute\":\"class\",\"defaultTheme\":\"dark\",\"children\":[[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}],[\"$\",\"$L5\",null,{\"position\":\"bottom-right\"}]]}]}]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L6\",null,{\"children\":[\"$\",\"$7\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@8\"}]}]]}],{},null,false,false]},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[\"$\",\"$L9\",null,{\"children\":\"$La\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$Lb\",null,{\"children\":[\"$\",\"$7\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lc\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$d\",[]],\"S\":true}\n"])</script><script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no\"}]]\n"])</script><script>self.__next_f.push([1,"e:I[86869,[],\"IconMark\"]\n8:null\nc:[[\"$\",\"title\",\"0\",{\"children\":\"GSD\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"The evolution of Get Shit Done — now a real coding agent. One command. Walk away. Come back to a built project.\"}],[\"$\",\"meta\",\"2\",{\"name\":\"application-name\",\"content\":\"GSD\"}],[\"$\",\"link\",\"3\",{\"rel\":\"icon\",\"href\":\"/icon-light-32x32.png\",\"media\":\"(prefers-color-scheme: light)\"}],[\"$\",\"link\",\"4\",{\"rel\":\"icon\",\"href\":\"/icon-dark-32x32.png\",\"media\":\"(prefers-color-scheme: dark)\"}],[\"$\",\"link\",\"5\",{\"rel\":\"icon\",\"href\":\"/icon.svg\",\"type\":\"image/svg+xml\"}],[\"$\",\"$Le\",\"6\",{}]]\n"])</script></body></html>
@@ -1,2 +1,2 @@
1
- <!DOCTYPE html><!--vIq9fmvRUaFOpguoX5j4W--><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-a1c1e452c6b32d04.js"/><script src="/_next/static/chunks/4bd1b696-e5d7c65570c947b7.js" async=""></script><script src="/_next/static/chunks/3794-337d1ca25ad99a89.js" async=""></script><script src="/_next/static/chunks/main-app-fdab67f7802d7832.js" async=""></script><meta name="next-size-adjust" content=""/><title>500: Internal Server Error.</title><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}
2
- @media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-a1c1e452c6b32d04.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[57121,[],\"\"]\n3:I[74581,[],\"\"]\n4:I[90484,[],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n7:I[90484,[],\"ViewportBoundary\"]\n9:I[90484,[],\"MetadataBoundary\"]\nb:I[27123,[],\"\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"vIq9fmvRUaFOpguoX5j4W\",\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"_global-error\",{\"children\":[\"__PAGE__\",{}]}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"title\",null,{\"children\":\"500: Internal Server Error.\"}]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"lineHeight\":\"48px\"},\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"paddingRight\":23,\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\"},\"children\":\"500\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"28px\"},\"children\":\"Internal Server Error.\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,false]},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L7\",null,{\"children\":\"$L8\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L9\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$La\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$b\",[]],\"S\":true}\n"])</script><script>self.__next_f.push([1,"8:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\na:[]\n"])</script></body></html>
1
+ <!DOCTYPE html><!--SoxM61WC_ia7R2gk4VMpJ--><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-a1c1e452c6b32d04.js"/><script src="/_next/static/chunks/4bd1b696-e5d7c65570c947b7.js" async=""></script><script src="/_next/static/chunks/3794-337d1ca25ad99a89.js" async=""></script><script src="/_next/static/chunks/main-app-fdab67f7802d7832.js" async=""></script><meta name="next-size-adjust" content=""/><title>500: Internal Server Error.</title><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}
2
+ @media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-a1c1e452c6b32d04.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[57121,[],\"\"]\n3:I[74581,[],\"\"]\n4:I[90484,[],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n7:I[90484,[],\"ViewportBoundary\"]\n9:I[90484,[],\"MetadataBoundary\"]\nb:I[27123,[],\"\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"SoxM61WC_ia7R2gk4VMpJ\",\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"_global-error\",{\"children\":[\"__PAGE__\",{}]}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"title\",null,{\"children\":\"500: Internal Server Error.\"}]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"lineHeight\":\"48px\"},\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"paddingRight\":23,\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\"},\"children\":\"500\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"28px\"},\"children\":\"Internal Server Error.\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,false]},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L7\",null,{\"children\":\"$L8\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L9\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$La\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$b\",[]],\"S\":true}\n"])</script><script>self.__next_f.push([1,"8:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\na:[]\n"])</script></body></html>
@@ -1 +1 @@
1
- {"node":{},"edge":{},"encryptionKey":"EDMPJs/935ZVJU4F6Jj0fqKKTN1tV8OT0A8hAR9C6cM="}
1
+ {"node":{},"edge":{},"encryptionKey":"doBJp0T0m+8UNpJEv4IVYKJPtQfZhg0tqEV4k1dMeNg="}
@@ -15,7 +15,7 @@ const currentPort = parseInt(process.env.PORT, 10) || 3000
15
15
  const hostname = process.env.HOSTNAME || '0.0.0.0'
16
16
 
17
17
  let keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT, 10)
18
- const nextConfig = {"env":{},"typescript":{"ignoreBuildErrors":true},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.mjs","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":true},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/__w/gsd-2/gsd-2","cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"dynamicOnHover":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":9,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":false,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":false,"lockDistDir":true,"isolatedDevBuild":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":false,"optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.mjs","serverExternalPackages":["@gsd/native","node-pty"],"turbopack":{"root":"/__w/gsd-2/gsd-2"},"distDirRoot":".next"}
18
+ const nextConfig = {"env":{},"typescript":{"ignoreBuildErrors":true},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.mjs","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":true},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/__w/gsd-2/gsd-2","cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"dynamicOnHover":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":5,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":false,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":false,"lockDistDir":true,"isolatedDevBuild":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":false,"optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.mjs","serverExternalPackages":["@gsd/native","node-pty"],"turbopack":{"root":"/__w/gsd-2/gsd-2"},"distDirRoot":".next"}
19
19
 
20
20
  process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
21
21
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gsd-pi",
3
- "version": "2.63.0-dev.d04bbc5",
3
+ "version": "2.64.0-dev.9c14bd0",
4
4
  "description": "GSD — Get Shit Done coding agent",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gsd/pi-coding-agent",
3
- "version": "2.63.0",
3
+ "version": "2.64.0",
4
4
  "description": "Coding agent CLI (vendored from pi-mono)",
5
5
  "type": "module",
6
6
  "piConfig": {
package/pkg/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glittercowboy/gsd",
3
- "version": "2.63.0",
3
+ "version": "2.64.0",
4
4
  "piConfig": {
5
5
  "name": "gsd",
6
6
  "configDir": ".gsd"
@@ -585,10 +585,11 @@ export function updateProgressWidget(
585
585
  lines.push(rightAlign(headerLeft, headerRight, width));
586
586
 
587
587
  // Worktree/branch right-aligned below header
588
- if (worktreeName && cachedBranch) {
589
- lines.push(rightAlign("", theme.fg("dim", `${worktreeName} (${cachedBranch})`), width));
590
- } else if (cachedBranch) {
591
- lines.push(rightAlign("", theme.fg("dim", cachedBranch), width));
588
+ const branchLabel = worktreeName && cachedBranch
589
+ ? `${worktreeName} (${cachedBranch})`
590
+ : cachedBranch ?? "";
591
+ if (branchLabel) {
592
+ lines.push(rightAlign("", theme.fg("dim", branchLabel), width));
592
593
  }
593
594
 
594
595
  // Show health signal details when degraded (yellow/red)
@@ -18,6 +18,7 @@ import { loadFile, parseSummary, resolveAllOverrides } from "./files.js";
18
18
  import { loadPrompt } from "./prompt-loader.js";
19
19
  import {
20
20
  resolveSliceFile,
21
+ resolveSlicePath,
21
22
  resolveTaskFile,
22
23
  resolveMilestoneFile,
23
24
  resolveTasksDir,
@@ -59,6 +60,10 @@ import { validateFileChanges } from "./safety/file-change-validator.js";
59
60
  import { validateContent } from "./safety/content-validator.js";
60
61
  import { resolveSafetyHarnessConfig } from "./safety/safety-harness.js";
61
62
  import { resolveExpectedArtifactPath as resolveArtifactForContent } from "./auto-artifact-paths.js";
63
+ import { loadEffectiveGSDPreferences } from "./preferences.js";
64
+ import { getSliceTasks } from "./gsd-db.js";
65
+ import { runPreExecutionChecks, type PreExecutionResult } from "./pre-execution-checks.js";
66
+ import { writePreExecutionEvidence } from "./verification-evidence.js";
62
67
 
63
68
  /** Maximum verification retry attempts before escalating to blocker placeholder (#2653). */
64
69
  const MAX_VERIFICATION_RETRIES = 3;
@@ -772,6 +777,123 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
772
777
  }
773
778
  }
774
779
 
780
+ // ── Pre-execution checks (after plan-slice completes) ──
781
+ if (
782
+ s.currentUnit &&
783
+ s.currentUnit.type === "plan-slice"
784
+ ) {
785
+ let preExecPauseNeeded = false;
786
+ await runSafely("postUnitPostVerification", "pre-execution-checks", async () => {
787
+ try {
788
+ // Check preferences — respect enhanced_verification and enhanced_verification_pre
789
+ const prefs = loadEffectiveGSDPreferences()?.preferences;
790
+ const enhancedEnabled = prefs?.enhanced_verification !== false; // default true
791
+ const preEnabled = prefs?.enhanced_verification_pre !== false; // default true
792
+
793
+ if (!enhancedEnabled || !preEnabled) {
794
+ debugLog("postUnitPostVerification", {
795
+ phase: "pre-execution-checks",
796
+ skipped: true,
797
+ reason: "disabled by preferences",
798
+ });
799
+ return;
800
+ }
801
+
802
+ // Parse the unit ID to get milestone/slice IDs
803
+ const { milestone: mid, slice: sid } = parseUnitId(s.currentUnit!.id);
804
+ if (!mid || !sid) {
805
+ debugLog("postUnitPostVerification", {
806
+ phase: "pre-execution-checks",
807
+ skipped: true,
808
+ reason: "could not parse milestone/slice from unit ID",
809
+ });
810
+ return;
811
+ }
812
+
813
+ // Get tasks for this slice from DB
814
+ const tasks = getSliceTasks(mid, sid);
815
+ if (tasks.length === 0) {
816
+ debugLog("postUnitPostVerification", {
817
+ phase: "pre-execution-checks",
818
+ skipped: true,
819
+ reason: "no tasks found for slice",
820
+ });
821
+ return;
822
+ }
823
+
824
+ // Run pre-execution checks
825
+ const result: PreExecutionResult = await runPreExecutionChecks(tasks, s.basePath);
826
+
827
+ // Log summary to stderr in existing verification output format
828
+ const emoji = result.status === "pass" ? "✅" : result.status === "warn" ? "⚠️" : "❌";
829
+ process.stderr.write(
830
+ `gsd-pre-exec: ${emoji} Pre-execution checks ${result.status} for ${mid}/${sid} (${result.durationMs}ms)\n`,
831
+ );
832
+
833
+ // Log individual check results
834
+ for (const check of result.checks) {
835
+ const checkEmoji = check.passed ? "✓" : check.blocking ? "✗" : "⚠";
836
+ process.stderr.write(
837
+ `gsd-pre-exec: ${checkEmoji} [${check.category}] ${check.target}: ${check.message}\n`,
838
+ );
839
+ }
840
+
841
+ // Write evidence JSON to slice artifacts directory
842
+ const slicePath = resolveSlicePath(s.basePath, mid, sid);
843
+ if (slicePath) {
844
+ writePreExecutionEvidence(result, slicePath, mid, sid);
845
+ }
846
+
847
+ // Notify UI
848
+ if (result.status === "fail") {
849
+ const blockingCount = result.checks.filter(c => !c.passed && c.blocking).length;
850
+ ctx.ui.notify(
851
+ `Pre-execution checks failed: ${blockingCount} blocking issue${blockingCount === 1 ? "" : "s"} found`,
852
+ "error",
853
+ );
854
+ preExecPauseNeeded = true;
855
+ } else if (result.status === "warn") {
856
+ ctx.ui.notify(
857
+ `Pre-execution checks passed with warnings`,
858
+ "warning",
859
+ );
860
+ // Strict mode: treat warnings as blocking
861
+ if (prefs?.enhanced_verification_strict === true) {
862
+ preExecPauseNeeded = true;
863
+ }
864
+ }
865
+
866
+ debugLog("postUnitPostVerification", {
867
+ phase: "pre-execution-checks",
868
+ status: result.status,
869
+ checkCount: result.checks.length,
870
+ durationMs: result.durationMs,
871
+ });
872
+ } catch (preExecError) {
873
+ // Fail-closed: if runPreExecutionChecks throws, pause auto-mode instead of silently continuing
874
+ const errorMessage = preExecError instanceof Error ? preExecError.message : String(preExecError);
875
+ debugLog("postUnitPostVerification", {
876
+ phase: "pre-execution-checks",
877
+ error: errorMessage,
878
+ failClosed: true,
879
+ });
880
+ logError("engine", `gsd-pre-exec: Pre-execution checks threw an error: ${errorMessage}`);
881
+ ctx.ui.notify(
882
+ `Pre-execution checks error: ${errorMessage} — pausing for human review`,
883
+ "error",
884
+ );
885
+ preExecPauseNeeded = true;
886
+ }
887
+ });
888
+
889
+ // Check for blocking failures after runSafely completes
890
+ if (preExecPauseNeeded) {
891
+ debugLog("postUnitPostVerification", { phase: "pre-execution-checks", pausing: true, reason: "blocking failures detected" });
892
+ await pauseAuto(ctx, pi);
893
+ return "stopped";
894
+ }
895
+ }
896
+
775
897
  // ── Triage check ──
776
898
  if (
777
899
  !s.stepMode &&
@@ -11,9 +11,10 @@
11
11
  */
12
12
 
13
13
  import type { ExtensionContext, ExtensionAPI } from "@gsd/pi-coding-agent";
14
+ import { mkdirSync, writeFileSync } from "node:fs";
14
15
  import { resolveSliceFile, resolveSlicePath } from "./paths.js";
15
16
  import { parseUnitId } from "./unit-id.js";
16
- import { isDbAvailable, getTask } from "./gsd-db.js";
17
+ import { isDbAvailable, getTask, getSliceTasks, type TaskRow } from "./gsd-db.js";
17
18
  import { loadEffectiveGSDPreferences } from "./preferences.js";
18
19
  import {
19
20
  runVerificationGate,
@@ -21,9 +22,11 @@ import {
21
22
  captureRuntimeErrors,
22
23
  runDependencyAudit,
23
24
  } from "./verification-gate.js";
24
- import { writeVerificationJSON } from "./verification-evidence.js";
25
+ import { writeVerificationJSON, type PostExecutionCheckJSON, type EvidenceJSON } from "./verification-evidence.js";
25
26
  import { logWarning } from "./workflow-logger.js";
27
+ import { runPostExecutionChecks, type PostExecutionResult } from "./post-execution-checks.js";
26
28
  import type { AutoSession } from "./auto/session.js";
29
+ import type { VerificationResult as VerificationGateResult } from "./types.js";
27
30
  import { join } from "node:path";
28
31
 
29
32
  export interface VerificationContext {
@@ -183,11 +186,140 @@ export async function runPostUnitVerification(
183
186
  return "continue";
184
187
  }
185
188
 
189
+ // ── Post-execution checks (run after main verification passes for execute-task units) ──
190
+ let postExecChecks: PostExecutionCheckJSON[] | undefined;
191
+ let postExecBlockingFailure = false;
192
+
193
+ if (result.passed && mid && sid && tid) {
194
+ // Check preferences — respect enhanced_verification and enhanced_verification_post
195
+ const enhancedEnabled = prefs?.enhanced_verification !== false; // default true
196
+ const postEnabled = prefs?.enhanced_verification_post !== false; // default true
197
+
198
+ if (enhancedEnabled && postEnabled && isDbAvailable()) {
199
+ try {
200
+ // Get the completed task from DB
201
+ const taskRow = getTask(mid, sid, tid);
202
+ if (taskRow && taskRow.key_files && taskRow.key_files.length > 0) {
203
+ // Get all tasks in the slice
204
+ const allTasks = getSliceTasks(mid, sid);
205
+ // Filter to prior completed tasks (status = 'complete' or 'done', before current task)
206
+ const priorTasks = allTasks.filter(
207
+ (t: TaskRow) =>
208
+ (t.status === "complete" || t.status === "done") &&
209
+ t.id !== tid &&
210
+ t.sequence < taskRow.sequence
211
+ );
212
+
213
+ // Run post-execution checks
214
+ const postExecResult: PostExecutionResult = runPostExecutionChecks(
215
+ taskRow,
216
+ priorTasks,
217
+ s.basePath
218
+ );
219
+
220
+ // Store checks for evidence JSON
221
+ postExecChecks = postExecResult.checks;
222
+
223
+ // Log summary to stderr with gsd-post-exec: prefix
224
+ const emoji =
225
+ postExecResult.status === "pass"
226
+ ? "✅"
227
+ : postExecResult.status === "warn"
228
+ ? "⚠️"
229
+ : "❌";
230
+ process.stderr.write(
231
+ `gsd-post-exec: ${emoji} Post-execution checks ${postExecResult.status} for ${mid}/${sid}/${tid} (${postExecResult.durationMs}ms)\n`
232
+ );
233
+
234
+ // Log individual check results
235
+ for (const check of postExecResult.checks) {
236
+ const checkEmoji = check.passed
237
+ ? "✓"
238
+ : check.blocking
239
+ ? "✗"
240
+ : "⚠";
241
+ process.stderr.write(
242
+ `gsd-post-exec: ${checkEmoji} [${check.category}] ${check.target}: ${check.message}\n`
243
+ );
244
+ }
245
+
246
+ // Check for blocking failures
247
+ if (postExecResult.status === "fail") {
248
+ postExecBlockingFailure = true;
249
+ const blockingCount = postExecResult.checks.filter(
250
+ (c) => !c.passed && c.blocking
251
+ ).length;
252
+ ctx.ui.notify(
253
+ `Post-execution checks failed: ${blockingCount} blocking issue${blockingCount === 1 ? "" : "s"} found`,
254
+ "error"
255
+ );
256
+ } else if (postExecResult.status === "warn") {
257
+ ctx.ui.notify(
258
+ `Post-execution checks passed with warnings`,
259
+ "warning"
260
+ );
261
+ // Strict mode: treat warnings as blocking
262
+ if (prefs?.enhanced_verification_strict === true) {
263
+ postExecBlockingFailure = true;
264
+ }
265
+ }
266
+ }
267
+ } catch (postExecErr) {
268
+ // Post-execution check errors are non-fatal — log and continue
269
+ logWarning("engine", `gsd-post-exec: error — ${(postExecErr as Error).message}`);
270
+ }
271
+ }
272
+ }
273
+
274
+ // Re-write verification evidence JSON with post-execution checks
275
+ if (postExecChecks && postExecChecks.length > 0 && mid && sid && tid) {
276
+ try {
277
+ const sDir = resolveSlicePath(s.basePath, mid, sid);
278
+ if (sDir) {
279
+ const tasksDir = join(sDir, "tasks");
280
+ // Add postExecutionChecks to the result for the JSON write
281
+ const resultWithPostExec = {
282
+ ...result,
283
+ // Mark as failed if there was a blocking post-exec failure
284
+ passed: result.passed && !postExecBlockingFailure,
285
+ };
286
+ // Manually write with postExecutionChecks field
287
+ writeVerificationJSONWithPostExec(
288
+ resultWithPostExec,
289
+ tasksDir,
290
+ tid,
291
+ s.currentUnit.id,
292
+ postExecChecks,
293
+ postExecBlockingFailure ? attempt + 1 : undefined,
294
+ postExecBlockingFailure ? maxRetries : undefined
295
+ );
296
+ }
297
+ } catch (evidenceErr) {
298
+ logWarning("engine", `verification-evidence: post-exec write error — ${(evidenceErr as Error).message}`);
299
+ }
300
+ }
301
+
302
+ // Update result.passed based on post-execution checks
303
+ if (postExecBlockingFailure) {
304
+ result.passed = false;
305
+ }
306
+
186
307
  // ── Auto-fix retry logic ──
187
308
  if (result.passed) {
188
309
  s.verificationRetryCount.delete(s.currentUnit.id);
189
310
  s.pendingVerificationRetry = null;
190
311
  return "continue";
312
+ } else if (postExecBlockingFailure) {
313
+ // Post-execution failures are cross-task consistency issues — retrying the same task won't fix them.
314
+ // Skip retry and pause immediately for human review.
315
+ s.verificationRetryCount.delete(s.currentUnit.id);
316
+ s.pendingVerificationRetry = null;
317
+ ctx.ui.notify(
318
+ `Post-execution checks failed — cross-task consistency issue detected, pausing for human review`,
319
+ "error",
320
+ );
321
+ await pauseAuto(ctx, pi);
322
+ return "pause";
191
323
  } else if (autoFixEnabled && attempt + 1 <= maxRetries) {
192
324
  const nextAttempt = attempt + 1;
193
325
  s.verificationRetryCount.set(s.currentUnit.id, nextAttempt);
@@ -231,3 +363,59 @@ export async function runPostUnitVerification(
231
363
  return "continue";
232
364
  }
233
365
  }
366
+
367
+ /**
368
+ * Write verification evidence JSON with post-execution checks included.
369
+ * This is a variant of writeVerificationJSON that adds the postExecutionChecks field.
370
+ */
371
+ function writeVerificationJSONWithPostExec(
372
+ result: VerificationGateResult,
373
+ tasksDir: string,
374
+ taskId: string,
375
+ unitId: string,
376
+ postExecutionChecks: PostExecutionCheckJSON[],
377
+ retryAttempt?: number,
378
+ maxRetries?: number,
379
+ ): void {
380
+ mkdirSync(tasksDir, { recursive: true });
381
+
382
+ const evidence: EvidenceJSON = {
383
+ schemaVersion: 1,
384
+ taskId,
385
+ unitId: unitId ?? taskId,
386
+ timestamp: result.timestamp,
387
+ passed: result.passed,
388
+ discoverySource: result.discoverySource,
389
+ checks: result.checks.map((check) => ({
390
+ command: check.command,
391
+ exitCode: check.exitCode,
392
+ durationMs: check.durationMs,
393
+ verdict: check.exitCode === 0 ? "pass" : "fail",
394
+ })),
395
+ ...(retryAttempt !== undefined ? { retryAttempt } : {}),
396
+ ...(maxRetries !== undefined ? { maxRetries } : {}),
397
+ postExecutionChecks,
398
+ };
399
+
400
+ if (result.runtimeErrors && result.runtimeErrors.length > 0) {
401
+ evidence.runtimeErrors = result.runtimeErrors.map(e => ({
402
+ source: e.source,
403
+ severity: e.severity,
404
+ message: e.message,
405
+ blocking: e.blocking,
406
+ }));
407
+ }
408
+
409
+ if (result.auditWarnings && result.auditWarnings.length > 0) {
410
+ evidence.auditWarnings = result.auditWarnings.map(w => ({
411
+ name: w.name,
412
+ severity: w.severity,
413
+ title: w.title,
414
+ url: w.url,
415
+ fixAvailable: w.fixAvailable,
416
+ }));
417
+ }
418
+
419
+ const filePath = join(tasksDir, `${taskId}-VERIFY.json`);
420
+ writeFileSync(filePath, JSON.stringify(evidence, null, 2) + "\n", "utf-8");
421
+ }