@infinitedusky/indusk-mcp 1.36.2 → 1.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/admin/.next/BUILD_ID +1 -1
- package/admin/.next/build-manifest.json +3 -3
- package/admin/.next/fallback-build-manifest.json +3 -3
- package/admin/.next/prerender-manifest.json +3 -3
- package/admin/.next/server/app/_global-error.html +1 -1
- package/admin/.next/server/app/_global-error.rsc +1 -1
- package/admin/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/admin/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/admin/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/admin/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/admin/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/admin/.next/server/chunks/ssr/[root-of-the-server]__0p.51_4._.js.map +1 -1
- package/admin/.next/server/middleware-build-manifest.js +3 -3
- package/admin/.next/server/pages/500.html +1 -1
- package/admin/.next/server/server-reference-manifest.js +1 -1
- package/admin/.next/server/server-reference-manifest.json +1 -1
- package/admin/.next/trace +1 -1
- package/admin/.next/trace-build +1 -1
- package/dist/bin/cli.js +42 -4
- package/dist/bin/commands/init.js +42 -10
- package/dist/bin/commands/telemetry.js +7 -1
- package/dist/bin/commands/update.js +104 -2
- package/dist/bin/commands/workbench.d.ts +76 -0
- package/dist/bin/commands/workbench.js +438 -0
- package/dist/bin/commands/worktree.d.ts +22 -6
- package/dist/bin/commands/worktree.js +154 -111
- package/dist/lib/config.d.ts +59 -0
- package/dist/lib/hook-migration.d.ts +42 -0
- package/dist/lib/hook-migration.js +94 -0
- package/dist/lib/path-segment.d.ts +23 -0
- package/dist/lib/path-segment.js +41 -0
- package/dist/lib/plan-parser.js +5 -13
- package/dist/lib/stray-state-audit.d.ts +3 -2
- package/dist/lib/stray-state-audit.js +14 -20
- package/dist/lib/telemetry/daemon.d.ts +18 -0
- package/dist/lib/telemetry/daemon.js +18 -2
- package/dist/lib/verify/git.d.ts +11 -4
- package/dist/lib/verify/git.js +11 -4
- package/dist/lib/verify/roots.d.ts +40 -0
- package/dist/lib/verify/roots.js +54 -0
- package/dist/lib/verify/verify.js +17 -2
- package/dist/lib/worktree/layout.d.ts +56 -0
- package/dist/lib/worktree/layout.js +136 -0
- package/dist/lib/worktree/repos.d.ts +46 -0
- package/dist/lib/worktree/repos.js +100 -0
- package/dist/lib/worktree/shareable.d.ts +47 -0
- package/dist/lib/worktree/shareable.js +301 -0
- package/dist/lib/worktree/sync.d.ts +62 -0
- package/dist/lib/worktree/sync.js +174 -0
- package/extensions/worktree/hooks/on_enable.sh +17 -10
- package/extensions/worktree/scripts/lib/workbench-helpers.sh +84 -0
- package/extensions/worktree/scripts/preflight.sh +4 -8
- package/extensions/worktree/scripts/refresh-worktree.sh +4 -8
- package/extensions/worktree/scripts/setup-worktree.sh +40 -16
- package/extensions/worktree/skill.md +8 -6
- package/hooks/_hook-paths.js +78 -15
- package/hooks/workbench-sync.js +119 -0
- package/package.json +109 -109
- package/skills/catchup.md +17 -0
- /package/admin/.next/static/{b30fOo0tUhHOxiaUT2sKQ → pg-wvx75mxUJvPhSjSoUe}/_buildManifest.js +0 -0
- /package/admin/.next/static/{b30fOo0tUhHOxiaUT2sKQ → pg-wvx75mxUJvPhSjSoUe}/_clientMiddlewareManifest.js +0 -0
- /package/admin/.next/static/{b30fOo0tUhHOxiaUT2sKQ → pg-wvx75mxUJvPhSjSoUe}/_ssgManifest.js +0 -0
|
@@ -7,9 +7,9 @@ globalThis.__BUILD_MANIFEST = {
|
|
|
7
7
|
"static/chunks/03~yq9q893hmn.js"
|
|
8
8
|
],
|
|
9
9
|
"lowPriorityFiles": [
|
|
10
|
-
"static/
|
|
11
|
-
"static/
|
|
12
|
-
"static/
|
|
10
|
+
"static/pg-wvx75mxUJvPhSjSoUe/_buildManifest.js",
|
|
11
|
+
"static/pg-wvx75mxUJvPhSjSoUe/_ssgManifest.js",
|
|
12
|
+
"static/pg-wvx75mxUJvPhSjSoUe/_clientMiddlewareManifest.js"
|
|
13
13
|
],
|
|
14
14
|
"rootMainFiles": [
|
|
15
15
|
"static/chunks/15r3deq0oc~d..js",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><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/15r3deq0oc~d..js"/><script src="/_next/static/chunks/0_r.3~d-5z8~_.js" async=""></script><script src="/_next/static/chunks/02p8lah64~lvh.js" async=""></script><script src="/_next/static/chunks/0gomaooulfzoq.js" async=""></script><script src="/_next/static/chunks/turbopack-130jszne6su0h.js" async=""></script><script src="/_next/static/chunks/0.v8w524wvk94.js" async=""></script><script src="/_next/static/chunks/0yelgl0o38y_u.js" async=""></script><meta name="next-size-adjust" content=""/><title>500: This page couldn’t load</title><link rel="icon" href="/favicon.ico?favicon.0x3dzn~oxb6tn.ico" sizes="256x256" type="image/x-icon"/><style>:root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }</style><script src="/_next/static/chunks/03~yq9q893hmn.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;display:flex;align-items:center;justify-content:center"><div style="margin-top:-32px;max-width:325px;padding:32px 28px;text-align:left"><svg width="32" height="32" viewBox="-0.2 -1.5 32 32" fill="none" style="margin-bottom:24px"><path d="M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z" fill="var(--next-error-title)"></path></svg><h1 style="font-size:24px;font-weight:500;letter-spacing:-0.02em;line-height:32px;margin:0 0 12px 0;color:var(--next-error-title)">This page couldn’t load</h1><p style="font-size:14px;font-weight:400;line-height:21px;margin:0 0 20px 0;color:var(--next-error-message)">A server error occurred. Reload to try again.</p><form style="margin:0"><button type="submit" style="display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;font-size:14px;font-weight:500;line-height:20px;border-radius:6px;cursor:pointer;color:var(--next-error-btn-text);background:var(--next-error-btn-bg);border:var(--next-error-btn-border)">Reload</button></form></div></div><!--$--><!--/$--><script src="/_next/static/chunks/15r3deq0oc~d..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[85530,[\"/_next/static/chunks/0.v8w524wvk94.js\",\"/_next/static/chunks/0yelgl0o38y_u.js\"],\"default\"]\n3:I[50571,[\"/_next/static/chunks/0.v8w524wvk94.js\",\"/_next/static/chunks/0yelgl0o38y_u.js\"],\"default\"]\n4:I[76614,[\"/_next/static/chunks/0.v8w524wvk94.js\",\"/_next/static/chunks/0yelgl0o38y_u.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n8:I[76614,[\"/_next/static/chunks/0.v8w524wvk94.js\",\"/_next/static/chunks/0yelgl0o38y_u.js\"],\"ViewportBoundary\"]\na:I[76614,[\"/_next/static/chunks/0.v8w524wvk94.js\",\"/_next/static/chunks/0yelgl0o38y_u.js\"],\"MetadataBoundary\"]\nc:I[59179,[\"/_next/static/chunks/0.v8w524wvk94.js\",\"/_next/static/chunks/0yelgl0o38y_u.js\"],\"default\",1]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"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\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"title\",null,{\"children\":\"500: This page couldn’t load\"}],[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }\"}}]]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"display\":\"flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"marginTop\":\"-32px\",\"maxWidth\":\"325px\",\"padding\":\"32px 28px\",\"textAlign\":\"left\"},\"children\":[[\"$\",\"svg\",null,{\"width\":\"32\",\"height\":\"32\",\"viewBox\":\"-0.2 -1.5 32 32\",\"fill\":\"none\",\"style\":{\"marginBottom\":\"24px\"},\"children\":[\"$\",\"path\",null,{\"d\":\"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z\",\"fill\":\"var(--next-error-title)\"}]}],[\"$\",\"h1\",null,{\"style\":{\"fontSize\":\"24px\",\"fontWeight\":500,\"letterSpacing\":\"-0.02em\",\"lineHeight\":\"32px\",\"margin\":\"0 0 12px 0\",\"color\":\"var(--next-error-title)\"},\"children\":\"This page couldn’t load\"}],[\"$\",\"p\",null,{\"style\":{\"fontSize\":\"14px\",\"fontWeight\":400,\"lineHeight\":\"21px\",\"margin\":\"0 0 20px 0\",\"color\":\"var(--next-error-message)\"},\"children\":\"A server error occurred. Reload to try again.\"}],[\"$\",\"form\",null,{\"style\":{\"margin\":0},\"children\":[\"$\",\"button\",null,{\"type\":\"submit\",\"style\":{\"display\":\"inline-flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\",\"height\":\"32px\",\"padding\":\"0 12px\",\"fontSize\":\"14px\",\"fontWeight\":500,\"lineHeight\":\"20px\",\"borderRadius\":\"6px\",\"cursor\":\"pointer\",\"color\":\"var(--next-error-btn-text)\",\"background\":\"var(--next-error-btn-bg)\",\"border\":\"var(--next-error-btn-border)\"},\"children\":\"Reload\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,null]},null,false,\"$@7\"],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$La\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lb\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$c\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"
|
|
1
|
+
<!DOCTYPE html><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/15r3deq0oc~d..js"/><script src="/_next/static/chunks/0_r.3~d-5z8~_.js" async=""></script><script src="/_next/static/chunks/02p8lah64~lvh.js" async=""></script><script src="/_next/static/chunks/0gomaooulfzoq.js" async=""></script><script src="/_next/static/chunks/turbopack-130jszne6su0h.js" async=""></script><script src="/_next/static/chunks/0.v8w524wvk94.js" async=""></script><script src="/_next/static/chunks/0yelgl0o38y_u.js" async=""></script><meta name="next-size-adjust" content=""/><title>500: This page couldn’t load</title><link rel="icon" href="/favicon.ico?favicon.0x3dzn~oxb6tn.ico" sizes="256x256" type="image/x-icon"/><style>:root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }</style><script src="/_next/static/chunks/03~yq9q893hmn.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;display:flex;align-items:center;justify-content:center"><div style="margin-top:-32px;max-width:325px;padding:32px 28px;text-align:left"><svg width="32" height="32" viewBox="-0.2 -1.5 32 32" fill="none" style="margin-bottom:24px"><path d="M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z" fill="var(--next-error-title)"></path></svg><h1 style="font-size:24px;font-weight:500;letter-spacing:-0.02em;line-height:32px;margin:0 0 12px 0;color:var(--next-error-title)">This page couldn’t load</h1><p style="font-size:14px;font-weight:400;line-height:21px;margin:0 0 20px 0;color:var(--next-error-message)">A server error occurred. Reload to try again.</p><form style="margin:0"><button type="submit" style="display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;font-size:14px;font-weight:500;line-height:20px;border-radius:6px;cursor:pointer;color:var(--next-error-btn-text);background:var(--next-error-btn-bg);border:var(--next-error-btn-border)">Reload</button></form></div></div><!--$--><!--/$--><script src="/_next/static/chunks/15r3deq0oc~d..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[85530,[\"/_next/static/chunks/0.v8w524wvk94.js\",\"/_next/static/chunks/0yelgl0o38y_u.js\"],\"default\"]\n3:I[50571,[\"/_next/static/chunks/0.v8w524wvk94.js\",\"/_next/static/chunks/0yelgl0o38y_u.js\"],\"default\"]\n4:I[76614,[\"/_next/static/chunks/0.v8w524wvk94.js\",\"/_next/static/chunks/0yelgl0o38y_u.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n8:I[76614,[\"/_next/static/chunks/0.v8w524wvk94.js\",\"/_next/static/chunks/0yelgl0o38y_u.js\"],\"ViewportBoundary\"]\na:I[76614,[\"/_next/static/chunks/0.v8w524wvk94.js\",\"/_next/static/chunks/0yelgl0o38y_u.js\"],\"MetadataBoundary\"]\nc:I[59179,[\"/_next/static/chunks/0.v8w524wvk94.js\",\"/_next/static/chunks/0yelgl0o38y_u.js\"],\"default\",1]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"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\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"title\",null,{\"children\":\"500: This page couldn’t load\"}],[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }\"}}]]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"display\":\"flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"marginTop\":\"-32px\",\"maxWidth\":\"325px\",\"padding\":\"32px 28px\",\"textAlign\":\"left\"},\"children\":[[\"$\",\"svg\",null,{\"width\":\"32\",\"height\":\"32\",\"viewBox\":\"-0.2 -1.5 32 32\",\"fill\":\"none\",\"style\":{\"marginBottom\":\"24px\"},\"children\":[\"$\",\"path\",null,{\"d\":\"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z\",\"fill\":\"var(--next-error-title)\"}]}],[\"$\",\"h1\",null,{\"style\":{\"fontSize\":\"24px\",\"fontWeight\":500,\"letterSpacing\":\"-0.02em\",\"lineHeight\":\"32px\",\"margin\":\"0 0 12px 0\",\"color\":\"var(--next-error-title)\"},\"children\":\"This page couldn’t load\"}],[\"$\",\"p\",null,{\"style\":{\"fontSize\":\"14px\",\"fontWeight\":400,\"lineHeight\":\"21px\",\"margin\":\"0 0 20px 0\",\"color\":\"var(--next-error-message)\"},\"children\":\"A server error occurred. Reload to try again.\"}],[\"$\",\"form\",null,{\"style\":{\"margin\":0},\"children\":[\"$\",\"button\",null,{\"type\":\"submit\",\"style\":{\"display\":\"inline-flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\",\"height\":\"32px\",\"padding\":\"0 12px\",\"fontSize\":\"14px\",\"fontWeight\":500,\"lineHeight\":\"20px\",\"borderRadius\":\"6px\",\"cursor\":\"pointer\",\"color\":\"var(--next-error-btn-text)\",\"background\":\"var(--next-error-btn-bg)\",\"border\":\"var(--next-error-btn-border)\"},\"children\":\"Reload\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,null]},null,false,\"$@7\"],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$La\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lb\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$c\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"pg-wvx75mxUJvPhSjSoUe\"}\n"])</script><script>self.__next_f.push([1,"d:[]\n7:\"$Wd\"\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"e:I[61299,[\"/_next/static/chunks/0.v8w524wvk94.js\",\"/_next/static/chunks/0yelgl0o38y_u.js\"],\"IconMark\"]\n6:null\nb:[[\"$\",\"link\",\"0\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.0x3dzn~oxb6tn.ico\",\"sizes\":\"256x256\",\"type\":\"image/x-icon\"}],[\"$\",\"$Le\",\"1\",{}]]\n"])</script></body></html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
self.__RSC_SERVER_MANIFEST="{\n \"node\": {},\n \"edge\": {},\n \"encryptionKey\": \"
|
|
1
|
+
self.__RSC_SERVER_MANIFEST="{\n \"node\": {},\n \"edge\": {},\n \"encryptionKey\": \"5EYfvaxmEqHHiyXyeibeBJ/A5+1f4Bd6BhbtBAaGPHw=\"\n}"
|
package/admin/.next/trace
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
[{"name":"generate-buildid","duration":
|
|
1
|
+
[{"name":"generate-buildid","duration":124,"timestamp":12051125172,"id":4,"parentId":1,"tags":{},"startTime":1787858781219,"traceId":"bbd788cfd15130cd"},{"name":"load-custom-routes","duration":209,"timestamp":12051125353,"id":5,"parentId":1,"tags":{},"startTime":1787858781220,"traceId":"bbd788cfd15130cd"},{"name":"create-dist-dir","duration":233,"timestamp":12051125576,"id":6,"parentId":1,"tags":{},"startTime":1787858781220,"traceId":"bbd788cfd15130cd"},{"name":"clean","duration":246,"timestamp":12051126678,"id":7,"parentId":1,"tags":{},"startTime":1787858781221,"traceId":"bbd788cfd15130cd"},{"name":"discover-routes","duration":4640,"timestamp":12051137117,"id":8,"parentId":1,"tags":{},"startTime":1787858781231,"traceId":"bbd788cfd15130cd"},{"name":"create-root-mapping","duration":44,"timestamp":12051141798,"id":9,"parentId":1,"tags":{},"startTime":1787858781236,"traceId":"bbd788cfd15130cd"},{"name":"generate-route-types","duration":11387,"timestamp":12051142513,"id":10,"parentId":1,"tags":{},"startTime":1787858781237,"traceId":"bbd788cfd15130cd"},{"name":"public-dir-conflict-check","duration":48,"timestamp":12051153957,"id":11,"parentId":1,"tags":{},"startTime":1787858781248,"traceId":"bbd788cfd15130cd"},{"name":"generate-routes-manifest","duration":1231,"timestamp":12051154051,"id":12,"parentId":1,"tags":{},"startTime":1787858781248,"traceId":"bbd788cfd15130cd"},{"name":"run-turbopack","duration":6753236,"timestamp":12051158032,"id":14,"parentId":1,"tags":{},"startTime":1787858781252,"traceId":"bbd788cfd15130cd"},{"name":"turbopack-build-events","duration":49,"timestamp":12051398090,"id":15,"parentId":1,"tags":{},"startTime":1787858781492,"traceId":"bbd788cfd15130cd"},{"name":"run-typescript","duration":2484871,"timestamp":12057955130,"id":16,"parentId":1,"tags":{},"startTime":1787858788049,"traceId":"bbd788cfd15130cd"},{"name":"generate-required-server-files","duration":638,"timestamp":12060440943,"id":18,"parentId":1,"tags":{},"startTime":1787858790535,"traceId":"bbd788cfd15130cd"},{"name":"check-static-error-page","duration":4269,"timestamp":12060473749,"id":20,"parentId":19,"tags":{},"startTime":1787858790568,"traceId":"bbd788cfd15130cd"},{"name":"is-page-static","duration":169650,"timestamp":12060483388,"id":30,"parentId":22,"tags":{},"startTime":1787858790578,"traceId":"bbd788cfd15130cd"},{"name":"check-page","duration":176486,"timestamp":12060476706,"id":22,"parentId":19,"tags":{"page":"/_global-error"},"startTime":1787858790571,"traceId":"bbd788cfd15130cd"},{"name":"is-page-static","duration":222056,"timestamp":12060483423,"id":31,"parentId":23,"tags":{},"startTime":1787858790578,"traceId":"bbd788cfd15130cd"},{"name":"check-page","duration":228538,"timestamp":12060477017,"id":23,"parentId":19,"tags":{"page":"/favicon.ico"},"startTime":1787858790571,"traceId":"bbd788cfd15130cd"},{"name":"is-page-static","duration":230740,"timestamp":12060483219,"id":29,"parentId":21,"tags":{},"startTime":1787858790577,"traceId":"bbd788cfd15130cd"},{"name":"check-page","duration":239641,"timestamp":12060474388,"id":21,"parentId":19,"tags":{"page":"/_not-found"},"startTime":1787858790569,"traceId":"bbd788cfd15130cd"},{"name":"is-page-static","duration":234609,"timestamp":12060487271,"id":33,"parentId":24,"tags":{},"startTime":1787858790581,"traceId":"bbd788cfd15130cd"},{"name":"check-page","duration":244155,"timestamp":12060477765,"id":24,"parentId":19,"tags":{"page":"/p/[project]"},"startTime":1787858790572,"traceId":"bbd788cfd15130cd"},{"name":"is-page-static","duration":239000,"timestamp":12060487184,"id":32,"parentId":28,"tags":{},"startTime":1787858790581,"traceId":"bbd788cfd15130cd"},{"name":"check-page","duration":248275,"timestamp":12060477965,"id":28,"parentId":19,"tags":{"page":"/"},"startTime":1787858790572,"traceId":"bbd788cfd15130cd"},{"name":"is-page-static","duration":250312,"timestamp":12060487304,"id":34,"parentId":25,"tags":{},"startTime":1787858790582,"traceId":"bbd788cfd15130cd"},{"name":"check-page","duration":259834,"timestamp":12060477828,"id":25,"parentId":19,"tags":{"page":"/p/[project]/plan/[name]"},"startTime":1787858790572,"traceId":"bbd788cfd15130cd"},{"name":"is-page-static","duration":255027,"timestamp":12060487380,"id":36,"parentId":27,"tags":{},"startTime":1787858790582,"traceId":"bbd788cfd15130cd"},{"name":"check-page","duration":264566,"timestamp":12060477923,"id":27,"parentId":19,"tags":{"page":"/p/[project]/scorecards"},"startTime":1787858790572,"traceId":"bbd788cfd15130cd"},{"name":"is-page-static","duration":260971,"timestamp":12060487334,"id":35,"parentId":26,"tags":{},"startTime":1787858790582,"traceId":"bbd788cfd15130cd"},{"name":"check-page","duration":270457,"timestamp":12060477878,"id":26,"parentId":19,"tags":{"page":"/p/[project]/research/[slug]"},"startTime":1787858790572,"traceId":"bbd788cfd15130cd"},{"name":"static-check","duration":274979,"timestamp":12060473372,"id":19,"parentId":1,"tags":{},"startTime":1787858790568,"traceId":"bbd788cfd15130cd"},{"name":"write-routes-manifest","duration":1330,"timestamp":12060749875,"id":38,"parentId":1,"tags":{},"startTime":1787858790844,"traceId":"bbd788cfd15130cd"},{"name":"load-dotenv","duration":19,"timestamp":12060758212,"id":41,"parentId":40,"tags":{},"startTime":1787858790852,"traceId":"bbd788cfd15130cd"},{"name":"run-export-path-map","duration":223,"timestamp":12060760034,"id":42,"parentId":40,"tags":{},"startTime":1787858790854,"traceId":"bbd788cfd15130cd"},{"name":"next-export","duration":231822,"timestamp":12060757562,"id":40,"parentId":1,"tags":{},"startTime":1787858790852,"traceId":"bbd788cfd15130cd"},{"name":"move-exported-app-global-error-","duration":803,"timestamp":12060990210,"id":43,"parentId":39,"tags":{},"startTime":1787858791084,"traceId":"bbd788cfd15130cd"},{"name":"static-generation","duration":239560,"timestamp":12060752695,"id":39,"parentId":1,"tags":{},"startTime":1787858790847,"traceId":"bbd788cfd15130cd"},{"name":"write-routes-manifest","duration":151,"timestamp":12060992350,"id":44,"parentId":1,"tags":{},"startTime":1787858791087,"traceId":"bbd788cfd15130cd"},{"name":"print-tree-view","duration":1634,"timestamp":12061002666,"id":45,"parentId":1,"tags":{},"startTime":1787858791097,"traceId":"bbd788cfd15130cd"},{"name":"write-route-bundle-stats","duration":7277,"timestamp":12061004309,"id":46,"parentId":1,"tags":{},"startTime":1787858791099,"traceId":"bbd788cfd15130cd"},{"name":"telemetry-flush","duration":482765,"timestamp":12061011596,"id":47,"parentId":1,"tags":{},"startTime":1787858791106,"traceId":"bbd788cfd15130cd"},{"name":"next-build","duration":10605264,"timestamp":12050889116,"id":1,"tags":{"buildMode":"default","version":"16.2.4","bundler":"turbopack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1787858780983,"traceId":"bbd788cfd15130cd"}]
|
package/admin/.next/trace-build
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
[{"name":"run-turbopack","duration":
|
|
1
|
+
[{"name":"run-turbopack","duration":6753236,"timestamp":12051158032,"id":14,"parentId":1,"tags":{},"startTime":1787858781252,"traceId":"bbd788cfd15130cd"},{"name":"turbopack-build-events","duration":49,"timestamp":12051398090,"id":15,"parentId":1,"tags":{},"startTime":1787858781492,"traceId":"bbd788cfd15130cd"},{"name":"run-typescript","duration":2484871,"timestamp":12057955130,"id":16,"parentId":1,"tags":{},"startTime":1787858788049,"traceId":"bbd788cfd15130cd"},{"name":"static-check","duration":274979,"timestamp":12060473372,"id":19,"parentId":1,"tags":{},"startTime":1787858790568,"traceId":"bbd788cfd15130cd"},{"name":"static-generation","duration":239560,"timestamp":12060752695,"id":39,"parentId":1,"tags":{},"startTime":1787858790847,"traceId":"bbd788cfd15130cd"},{"name":"telemetry-flush","duration":482765,"timestamp":12061011596,"id":47,"parentId":1,"tags":{},"startTime":1787858791106,"traceId":"bbd788cfd15130cd"},{"name":"next-build","duration":10605264,"timestamp":12050889116,"id":1,"tags":{"buildMode":"default","version":"16.2.4","bundler":"turbopack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1787858780983,"traceId":"bbd788cfd15130cd"}]
|
package/dist/bin/cli.js
CHANGED
|
@@ -437,6 +437,44 @@ telemetryCmd
|
|
|
437
437
|
const { telemetryReset } = await import("./commands/telemetry.js");
|
|
438
438
|
await telemetryReset({ otlpPort: opts.otlpPort, uiPort: opts.uiPort });
|
|
439
439
|
});
|
|
440
|
+
const workbenchCmd = program
|
|
441
|
+
.command("workbench")
|
|
442
|
+
.description("Workbench topology — materialize a cloned workbench");
|
|
443
|
+
workbenchCmd
|
|
444
|
+
.command("migrate-layout")
|
|
445
|
+
.description("Move a flat workbench's worktrees under a declared per-repo location. Dry-run by default; --apply performs it.")
|
|
446
|
+
.option("--apply", "Perform the migration instead of showing the plan")
|
|
447
|
+
.action(async (opts) => {
|
|
448
|
+
const { workbenchMigrateLayout } = await import("./commands/workbench.js");
|
|
449
|
+
workbenchMigrateLayout(rootOrExit(), { apply: opts.apply });
|
|
450
|
+
});
|
|
451
|
+
workbenchCmd
|
|
452
|
+
.command("sync")
|
|
453
|
+
.description("Commit local changes, pull, and push — blindly resolved, never blocking. Exits 0 offline; work goes out on the next sync.")
|
|
454
|
+
.option("--no-ignore-check", "Proceed even if .gitignore cannot keep worktrees out of the remote")
|
|
455
|
+
.action(async (opts) => {
|
|
456
|
+
const { workbenchSyncCommand } = await import("./commands/workbench.js");
|
|
457
|
+
workbenchSyncCommand(rootOrExit(), { noIgnoreCheck: opts.ignoreCheck === false });
|
|
458
|
+
});
|
|
459
|
+
workbenchCmd
|
|
460
|
+
.command("status")
|
|
461
|
+
.description("Per-repo publish state: materialized, and whether its commits have actually left this machine.")
|
|
462
|
+
.action(async () => {
|
|
463
|
+
const { workbenchStatusCommand } = await import("./commands/workbench.js");
|
|
464
|
+
workbenchStatusCommand(rootOrExit());
|
|
465
|
+
});
|
|
466
|
+
workbenchCmd
|
|
467
|
+
.command("restore")
|
|
468
|
+
.description("Clone every declared repo as a sibling, recreate the trunk symlinks, and print the out-of-band set. Idempotent; exits non-zero naming anything it could not resolve.")
|
|
469
|
+
.option("--worktrees", "Also recreate declared worktrees")
|
|
470
|
+
.option("--no-ignore-check", "Proceed even if .gitignore cannot keep worktrees out of the remote")
|
|
471
|
+
.action(async (opts) => {
|
|
472
|
+
const { workbenchRestore } = await import("./commands/workbench.js");
|
|
473
|
+
workbenchRestore(rootOrExit(), {
|
|
474
|
+
worktrees: opts.worktrees,
|
|
475
|
+
noIgnoreCheck: opts.ignoreCheck === false,
|
|
476
|
+
});
|
|
477
|
+
});
|
|
440
478
|
// ---- worktree extension lifecycle ----
|
|
441
479
|
// Worktree extension lifecycle. Phase 4 shipped the internal _on-enable
|
|
442
480
|
// hook; Phase 6 adds the user-facing create / refresh / list / preflight
|
|
@@ -453,11 +491,11 @@ worktreeCmd
|
|
|
453
491
|
worktreeOnEnable();
|
|
454
492
|
});
|
|
455
493
|
worktreeCmd
|
|
456
|
-
.command("create <
|
|
457
|
-
.description("Create a worktree
|
|
458
|
-
.action(async (
|
|
494
|
+
.command("create <args...>")
|
|
495
|
+
.description("Create a worktree: `create [repo] <slug> [base-branch]`. The repo is optional when the workbench declares exactly one; with several it is required, and omitting it fails naming the candidates.")
|
|
496
|
+
.action(async (args) => {
|
|
459
497
|
const { worktreeCreate } = await import("./commands/worktree.js");
|
|
460
|
-
worktreeCreate(
|
|
498
|
+
worktreeCreate(args, rootOrExit());
|
|
461
499
|
});
|
|
462
500
|
worktreeCmd
|
|
463
501
|
.command("refresh <slug>")
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { execSync, spawnSync } from "node:child_process";
|
|
2
|
-
import { cpSync, existsSync, mkdirSync, readFileSync,
|
|
2
|
+
import { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { basename, dirname, join, relative } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
import { globSync } from "glob";
|
|
7
7
|
import { ensureHooksModuleType } from "../../lib/hooks-module-type.js";
|
|
8
|
+
import { linkTrunk } from "../../lib/worktree/layout.js";
|
|
8
9
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
10
|
const packageRoot = join(__dirname, "../../..");
|
|
10
11
|
function run(cmd, options) {
|
|
@@ -376,15 +377,18 @@ export async function init(projectRoot, options = {}) {
|
|
|
376
377
|
console.error(` Expected: <sibling-parent>/${wrappedRepo} where <sibling-parent>=${siblingParent}`);
|
|
377
378
|
process.exit(1);
|
|
378
379
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
380
|
+
// Through the shared `linkTrunk`, not a local `symlinkSync`. The inline
|
|
381
|
+
// version here was a strict subset: it created a link when nothing was
|
|
382
|
+
// there and said "already exists" otherwise, so a DANGLING link (target
|
|
383
|
+
// gone — `existsSync` follows the link and reports false) took the create
|
|
384
|
+
// branch and threw EEXIST, and a REAL DIRECTORY was reported as a symlink
|
|
385
|
+
// that exists. `restore` learned both cases the hard way in A30.
|
|
386
|
+
const rel = relative(projectRoot, canonicalClone);
|
|
387
|
+
if (linkTrunk(projectRoot, wrappedRepo, canonicalClone)) {
|
|
388
|
+
console.info(`[Workbench] trunk symlink: ${wrappedRepo} -> ${rel}`);
|
|
382
389
|
}
|
|
383
390
|
else {
|
|
384
|
-
|
|
385
|
-
const rel = relative(projectRoot, canonicalClone);
|
|
386
|
-
symlinkSync(rel, trunkLink);
|
|
387
|
-
console.info(`[Workbench] created trunk symlink: ${wrappedRepo} -> ${rel}`);
|
|
391
|
+
console.info(`[Workbench] ${wrappedRepo} is a real directory, not a symlink — left as is, no trunk link made`);
|
|
388
392
|
}
|
|
389
393
|
}
|
|
390
394
|
// Detect existing tooling
|
|
@@ -542,6 +546,19 @@ export async function init(projectRoot, options = {}) {
|
|
|
542
546
|
console.info(` note: could not remove legacy ${name} MCP server — run: claude mcp remove -s project ${name}`);
|
|
543
547
|
}
|
|
544
548
|
}
|
|
549
|
+
// Retired hooks: deleting one from the package leaves it on disk AND
|
|
550
|
+
// registered in every consumer forever. Removing both halves is the twin of
|
|
551
|
+
// the MCP migration above — extend LEGACY_HOOKS, never hand-roll a loop.
|
|
552
|
+
{
|
|
553
|
+
const { removeLegacyHooks } = await import("../../lib/hook-migration.js");
|
|
554
|
+
const hookResult = removeLegacyHooks(projectRoot);
|
|
555
|
+
for (const name of hookResult.filesRemoved) {
|
|
556
|
+
console.info(` removed: ${name} (retired hook)`);
|
|
557
|
+
}
|
|
558
|
+
for (const name of hookResult.registrationsRemoved) {
|
|
559
|
+
console.info(` removed: ${name} registration from .claude/settings.json`);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
545
562
|
// 5. Generate .vscode/settings.json
|
|
546
563
|
if (!local) {
|
|
547
564
|
console.info("\n[Editor]");
|
|
@@ -844,7 +861,14 @@ export async function init(projectRoot, options = {}) {
|
|
|
844
861
|
PostToolUse: [
|
|
845
862
|
{
|
|
846
863
|
matcher: "Edit|Write",
|
|
847
|
-
hooks: [
|
|
864
|
+
hooks: [
|
|
865
|
+
{ type: "command", command: "node .claude/hooks/gate-reminder.js" },
|
|
866
|
+
// Workbench sync trigger. Inert unless worktree.shape is
|
|
867
|
+
// "workbench" — a normal-mode project keeps `.indusk/` inside
|
|
868
|
+
// its own product repo, where auto-committing every edit would
|
|
869
|
+
// commit half-finished source.
|
|
870
|
+
{ type: "command", command: "node .claude/hooks/workbench-sync.js" },
|
|
871
|
+
],
|
|
848
872
|
},
|
|
849
873
|
{
|
|
850
874
|
matcher: "Bash",
|
|
@@ -995,6 +1019,14 @@ export async function init(projectRoot, options = {}) {
|
|
|
995
1019
|
max_file_loc: 400,
|
|
996
1020
|
scopes: [],
|
|
997
1021
|
},
|
|
1022
|
+
// Still written in the SINGULAR here, deliberately. Switching the writer
|
|
1023
|
+
// to `repos[]` belongs in Build Phase 2, with the bash readers: this
|
|
1024
|
+
// phase converted the TypeScript lane, and `setup-worktree.sh` et al
|
|
1025
|
+
// still read `wrapped_repo`. Writing the plural shape now produced a
|
|
1026
|
+
// workbench that `indusk worktree create` refused outright — found by
|
|
1027
|
+
// running the suite, not by reading the diff, because nothing
|
|
1028
|
+
// type-checks the shell lane. The reduction means readers are already
|
|
1029
|
+
// plural-ready; only the writer waits.
|
|
998
1030
|
...(workbench && options.wrappedRepo && options.siblingParent
|
|
999
1031
|
? {
|
|
1000
1032
|
worktree: {
|
|
@@ -1008,7 +1040,7 @@ export async function init(projectRoot, options = {}) {
|
|
|
1008
1040
|
writeConfig(projectRoot, config);
|
|
1009
1041
|
// Workbench mode: explicitly enable the worktree extension AFTER the
|
|
1010
1042
|
// config write so the on_enable hook sees worktree.shape="workbench"
|
|
1011
|
-
// + worktree.
|
|
1043
|
+
// + worktree.repos[]. The extension is required:false so
|
|
1012
1044
|
// autoEnableExtensions doesn't pick it up.
|
|
1013
1045
|
if (workbench) {
|
|
1014
1046
|
console.info("\n[Workbench] enabling worktree extension");
|
|
@@ -225,7 +225,13 @@ export async function telemetryRegister(projectPath) {
|
|
|
225
225
|
if (!status.running) {
|
|
226
226
|
console.info("Daemon not running — starting it now...");
|
|
227
227
|
try {
|
|
228
|
-
|
|
228
|
+
// allowPortBump on purpose: this auto-start is opportunistic, not a
|
|
229
|
+
// user asking for :4318. The port guard belongs to explicit
|
|
230
|
+
// `telemetry start`, where the caller named a port and silently
|
|
231
|
+
// binding another is the bug. Applying it here made `indusk init`
|
|
232
|
+
// FAIL on any machine already running a daemon — a regression shipped
|
|
233
|
+
// in 1.36.2 and caught by the telemetry suite.
|
|
234
|
+
const meta = await daemonStart({ allowPortBump: true });
|
|
229
235
|
console.info(` OTLP: http://localhost:${meta.otlpPort}`);
|
|
230
236
|
console.info(` Jaeger UI: http://localhost:${meta.uiPort}`);
|
|
231
237
|
console.info(` Jaeger MCP: http://localhost:${meta.mcpPort}/mcp`);
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { execSync } from "node:child_process";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
3
|
import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync } from "node:fs";
|
|
4
|
-
import { dirname, join } from "node:path";
|
|
4
|
+
import { dirname, join, resolve as resolvePath } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
import { globSync } from "glob";
|
|
7
7
|
import { loadExtension } from "../../lib/extension-loader.js";
|
|
8
8
|
import { ensureHooksModuleType } from "../../lib/hooks-module-type.js";
|
|
9
9
|
import { checkLatestVersion, hasNewerVersion } from "../../lib/version-check.js";
|
|
10
|
+
import { readSiblingParent, readWorkbenchRepos } from "../../lib/worktree/repos.js";
|
|
11
|
+
import { missingIgnoreRules } from "../../lib/worktree/shareable.js";
|
|
12
|
+
import { syncWorkbench } from "../../lib/worktree/sync.js";
|
|
10
13
|
import { envIsFunctional } from "./extensions.js";
|
|
11
14
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
12
15
|
const packageRoot = join(__dirname, "../../..");
|
|
@@ -230,12 +233,32 @@ export async function update(projectRoot) {
|
|
|
230
233
|
writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}\n`);
|
|
231
234
|
console.info(" registered eval-trigger hook in settings.json");
|
|
232
235
|
}
|
|
236
|
+
// Same targeted-ensure shape as the eval-trigger block above.
|
|
237
|
+
// A hook copied by globSync but never registered in settings is
|
|
238
|
+
// a file that exists and never runs — the eval-trigger lesson.
|
|
239
|
+
const editHooks = settings.hooks?.PostToolUse ?? [];
|
|
240
|
+
const hasSyncHook = editHooks.some((entry) => entry.hooks?.some((h) => h.command?.includes("workbench-sync")));
|
|
241
|
+
if (!hasSyncHook) {
|
|
242
|
+
if (!settings.hooks)
|
|
243
|
+
settings.hooks = {};
|
|
244
|
+
if (!settings.hooks.PostToolUse)
|
|
245
|
+
settings.hooks.PostToolUse = [];
|
|
246
|
+
const editEntry = settings.hooks.PostToolUse.find((e) => e.matcher === "Edit|Write");
|
|
247
|
+
const hookDef = { type: "command", command: "node .claude/hooks/workbench-sync.js" };
|
|
248
|
+
if (editEntry?.hooks)
|
|
249
|
+
editEntry.hooks.push(hookDef);
|
|
250
|
+
else
|
|
251
|
+
settings.hooks.PostToolUse.push({ matcher: "Edit|Write", hooks: [hookDef] });
|
|
252
|
+
const { writeFileSync: wf } = await import("node:fs");
|
|
253
|
+
wf(settingsPath, `${JSON.stringify(settings, null, 2)}\n`);
|
|
254
|
+
console.info(" registered workbench-sync hook in settings.json");
|
|
255
|
+
}
|
|
233
256
|
}
|
|
234
257
|
catch {
|
|
235
258
|
console.info(" could not register eval hook in settings.json");
|
|
236
259
|
}
|
|
237
260
|
// Remove the legacy check-catchup hook (indusk-makeover follow-up, found
|
|
238
|
-
// by the
|
|
261
|
+
// by the POC versioned-workbench POC): it gates every Edit/Write on
|
|
239
262
|
// .claude/handoff.md checkboxes the post-1.29 catchup never writes, and
|
|
240
263
|
// its manual path probes the retired FalkorDB/Graphiti — permanently
|
|
241
264
|
// unsatisfiable. Delete the file AND strip its settings registration.
|
|
@@ -304,6 +327,23 @@ export async function update(projectRoot) {
|
|
|
304
327
|
}
|
|
305
328
|
}
|
|
306
329
|
}
|
|
330
|
+
// 5c. Retire hooks removed from the package.
|
|
331
|
+
//
|
|
332
|
+
// Deliberately OUTSIDE the .mcp.json guard below: a project with no
|
|
333
|
+
// .mcp.json still has hooks. Nesting this inside that guard meant the
|
|
334
|
+
// removal never ran for those projects — found by running `indusk update`
|
|
335
|
+
// against a fixture that had the orphaned hook and no .mcp.json, where the
|
|
336
|
+
// block was skipped in silence.
|
|
337
|
+
{
|
|
338
|
+
const { removeLegacyHooks } = await import("../../lib/hook-migration.js");
|
|
339
|
+
const hookResult = removeLegacyHooks(projectRoot);
|
|
340
|
+
for (const name of hookResult.filesRemoved) {
|
|
341
|
+
console.info(` removed: ${name} (retired hook)`);
|
|
342
|
+
}
|
|
343
|
+
for (const name of hookResult.registrationsRemoved) {
|
|
344
|
+
console.info(` removed: ${name} registration from .claude/settings.json`);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
307
347
|
// 5b. Migrate stale MCP configs
|
|
308
348
|
const mcpJsonPath = join(projectRoot, ".mcp.json");
|
|
309
349
|
if (existsSync(mcpJsonPath)) {
|
|
@@ -692,6 +732,18 @@ export async function update(projectRoot) {
|
|
|
692
732
|
console.info(` registered: ${added.name}`);
|
|
693
733
|
}
|
|
694
734
|
}
|
|
735
|
+
// Workbench topology check — NUDGE ONLY, never a clone.
|
|
736
|
+
//
|
|
737
|
+
// `update` runs constantly, must stay fast, and must work offline; a network
|
|
738
|
+
// clone as a side effect of a routine sync is a surprise nobody asked for.
|
|
739
|
+
// So it notices and points at `workbench restore` rather than doing it.
|
|
740
|
+
nudgeUnmaterializedRepos(projectRoot);
|
|
741
|
+
// `update` is a MUTATION CHOKEPOINT, not just a reader. POC friction #1 was
|
|
742
|
+
// exactly this: update rewrites tracked workbench files (settings.json,
|
|
743
|
+
// config.json, .gitignore), and on the second machine those sat uncommitted
|
|
744
|
+
// and blocked the next pull. Syncing here closes that loop. Workbench-only,
|
|
745
|
+
// and never fatal — a failed sync must not fail an update.
|
|
746
|
+
syncAfterUpdate(projectRoot);
|
|
695
747
|
console.info("\nDone.");
|
|
696
748
|
// Non-blocking version notice. Uses the 6h-cached lookup so we don't
|
|
697
749
|
// hit npm on every invocation. Silently no-ops when offline, when the
|
|
@@ -709,3 +761,53 @@ export async function update(projectRoot) {
|
|
|
709
761
|
// Best-effort — never let the notice break the update.
|
|
710
762
|
}
|
|
711
763
|
}
|
|
764
|
+
/**
|
|
765
|
+
* Tell the developer when declared repos are not on disk.
|
|
766
|
+
*
|
|
767
|
+
* The counterpart to `restore` living in its own command: a developer who
|
|
768
|
+
* clones a workbench has no reason to know `restore` exists, and `update` is
|
|
769
|
+
* the command they WILL run. Noticing costs a few `existsSync` calls and no
|
|
770
|
+
* network.
|
|
771
|
+
*/
|
|
772
|
+
function nudgeUnmaterializedRepos(projectRoot) {
|
|
773
|
+
const repos = readWorkbenchRepos(projectRoot);
|
|
774
|
+
if (repos.length === 0)
|
|
775
|
+
return;
|
|
776
|
+
const declaredParent = readSiblingParent(projectRoot);
|
|
777
|
+
const parent = declaredParent && existsSync(resolvePath(declaredParent))
|
|
778
|
+
? resolvePath(declaredParent)
|
|
779
|
+
: resolvePath(projectRoot, "..");
|
|
780
|
+
const missing = repos.filter((r) => !existsSync(join(parent, r.name, ".git")));
|
|
781
|
+
if (missing.length === 0)
|
|
782
|
+
return;
|
|
783
|
+
console.info("");
|
|
784
|
+
console.info(`Workbench: ${missing.length} of ${repos.length} declared repo(s) are not materialized — ${missing
|
|
785
|
+
.map((r) => r.name)
|
|
786
|
+
.join(", ")}`);
|
|
787
|
+
console.info(" Run `indusk workbench restore` to clone them and relink the trunks.");
|
|
788
|
+
const ignoreGaps = missingIgnoreRules(projectRoot);
|
|
789
|
+
if (ignoreGaps.length > 0) {
|
|
790
|
+
console.info(` (it will also scaffold the sharing rules — ${ignoreGaps[0]})`);
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
/** Commit + push what `update` just rewrote. Workbench-only, never fatal. */
|
|
794
|
+
function syncAfterUpdate(projectRoot) {
|
|
795
|
+
try {
|
|
796
|
+
const cfg = JSON.parse(readFileSync(join(projectRoot, ".indusk/config.json"), "utf-8"));
|
|
797
|
+
if (cfg?.worktree?.shape !== "workbench")
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
800
|
+
catch {
|
|
801
|
+
return;
|
|
802
|
+
}
|
|
803
|
+
try {
|
|
804
|
+
const result = syncWorkbench(projectRoot);
|
|
805
|
+
if (result.committed)
|
|
806
|
+
console.info(" workbench: committed what update rewrote");
|
|
807
|
+
if (result.pushed === "failed")
|
|
808
|
+
console.info(" workbench: push deferred (offline) — goes out next sync");
|
|
809
|
+
}
|
|
810
|
+
catch {
|
|
811
|
+
console.info(" workbench: sync skipped (see `indusk workbench sync`)");
|
|
812
|
+
}
|
|
813
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { type WorkbenchRepo } from "../../lib/worktree/repos.js";
|
|
2
|
+
/**
|
|
3
|
+
* `indusk workbench restore` — materialize a workbench that has only been
|
|
4
|
+
* cloned.
|
|
5
|
+
*
|
|
6
|
+
* A workbench context repo carries `.indusk/`, `.claude/` and its docs, but
|
|
7
|
+
* NOT the repos it wraps: those are siblings with their own remotes, and the
|
|
8
|
+
* trunk symlinks pointing at them dangle on a fresh clone. Before this command
|
|
9
|
+
* the only way through was to clone each repo and recreate each link by hand —
|
|
10
|
+
* `init` refuses an already-initialized workbench by design, and `update` is a
|
|
11
|
+
* hot path that must stay fast and offline-tolerant, so neither is the place
|
|
12
|
+
* for a network clone.
|
|
13
|
+
*
|
|
14
|
+
* Idempotent: re-running reports what is already there and writes nothing.
|
|
15
|
+
*
|
|
16
|
+
* FAILS LOUD AND PARTIAL. One unreachable remote does not abort the others,
|
|
17
|
+
* and the command exits non-zero naming everything it could not do. Half a
|
|
18
|
+
* workbench that exits 0 is indistinguishable from a whole one from the
|
|
19
|
+
* outside, and that shape — a checker that cannot tell "could not" from
|
|
20
|
+
* "did" — is the failure this codebase has three separate mechanisms to avoid.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* What restore did to one repo, including whether the trunk link happened.
|
|
24
|
+
*
|
|
25
|
+
* The `-unlinked` variants exist because `linkTrunk` deliberately refuses to
|
|
26
|
+
* remove a real directory sitting at the trunk path — and reporting that as
|
|
27
|
+
* "linked" is a claim about something that never happened.
|
|
28
|
+
*/
|
|
29
|
+
export type RestoreStatus = "present" | "present-unlinked" | "cloned" | "cloned-unlinked";
|
|
30
|
+
/**
|
|
31
|
+
* Phrase one repo's outcome.
|
|
32
|
+
*
|
|
33
|
+
* Separated from the loop that prints it so the four cases can be read — and
|
|
34
|
+
* tested — without spawning the CLI. The loop decides what happened; this says
|
|
35
|
+
* it. They are two jobs, and the four-way ternary that used to sit inline made
|
|
36
|
+
* that hard to see.
|
|
37
|
+
*/
|
|
38
|
+
export declare function restoreLine(repo: WorkbenchRepo, status: RestoreStatus, siblingParent: string): string;
|
|
39
|
+
export declare function workbenchRestore(projectRoot: string, opts?: {
|
|
40
|
+
worktrees?: boolean;
|
|
41
|
+
noIgnoreCheck?: boolean;
|
|
42
|
+
}): never;
|
|
43
|
+
/**
|
|
44
|
+
* `indusk workbench sync` — one sync point: commit, pull, push, blindly resolved.
|
|
45
|
+
*
|
|
46
|
+
* Exits 0 even when the remote is unreachable. The work is committed locally
|
|
47
|
+
* and goes out on the next sync; someone else's outage must never become your
|
|
48
|
+
* inability to work.
|
|
49
|
+
*/
|
|
50
|
+
export declare function workbenchSyncCommand(projectRoot: string, opts?: {
|
|
51
|
+
noIgnoreCheck?: boolean;
|
|
52
|
+
}): never;
|
|
53
|
+
/**
|
|
54
|
+
* `indusk workbench status` — is each declared repo materialized, and has its
|
|
55
|
+
* work actually left this machine?
|
|
56
|
+
*/
|
|
57
|
+
export declare function workbenchStatusCommand(projectRoot: string): never;
|
|
58
|
+
/**
|
|
59
|
+
* `indusk workbench migrate-layout` — move a flat workbench into declared layout.
|
|
60
|
+
*
|
|
61
|
+
* DRY-RUN BY DEFAULT. A command that relocates directories shows its plan
|
|
62
|
+
* before doing anything; `--apply` performs it.
|
|
63
|
+
*
|
|
64
|
+
* Uses `git worktree move`, never a manual rename. A git worktree is two
|
|
65
|
+
* cross-references — the worktree's `.git` file and the repo's
|
|
66
|
+
* `.git/worktrees/<name>/gitdir` pointing back — and moving the directory
|
|
67
|
+
* without repairing both leaves something that looks right and is broken. That
|
|
68
|
+
* is the only failure of this command that would matter, so it is handed to
|
|
69
|
+
* the tool that knows.
|
|
70
|
+
*
|
|
71
|
+
* Wrapped repos are never committed to or modified beyond the worktree
|
|
72
|
+
* bookkeeping: this moves worktrees, not product code.
|
|
73
|
+
*/
|
|
74
|
+
export declare function workbenchMigrateLayout(projectRoot: string, opts?: {
|
|
75
|
+
apply?: boolean;
|
|
76
|
+
}): never;
|