@1agh/maude 0.42.0 → 0.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (332) hide show
  1. package/apps/studio/.ai/cache/_stats.json +7 -0
  2. package/apps/studio/acp/bootstrap-brief.ts +12 -2
  3. package/apps/studio/acp/bridge.ts +44 -10
  4. package/apps/studio/acp/env.ts +23 -0
  5. package/apps/studio/acp/login-state.ts +263 -0
  6. package/apps/studio/acp/plugin-bootstrap.ts +31 -25
  7. package/apps/studio/acp/probe.ts +152 -1
  8. package/apps/studio/annotations-layer.tsx +1451 -324
  9. package/apps/studio/annotations-model.ts +58 -0
  10. package/apps/studio/api.ts +568 -24
  11. package/apps/studio/bin/_audio-search.mjs +140 -0
  12. package/apps/studio/bin/_import-asset-pdf-worker.mjs +34 -0
  13. package/apps/studio/bin/_import-asset.mjs +815 -0
  14. package/apps/studio/bin/_import-brand.mjs +635 -0
  15. package/apps/studio/bin/_import-tokens-alias-resolver.mjs +95 -0
  16. package/apps/studio/bin/_import-tokens.mjs +1201 -0
  17. package/apps/studio/bin/_ingest-footage.mjs +386 -0
  18. package/apps/studio/bin/_probe-footage-playwright.mjs +269 -0
  19. package/apps/studio/bin/_transcribe.mjs +419 -0
  20. package/apps/studio/bin/_transcribe.test.mjs +80 -0
  21. package/apps/studio/bin/_video-playwright.mjs +141 -71
  22. package/apps/studio/bin/audio-search.sh +28 -0
  23. package/apps/studio/bin/generate.sh +154 -0
  24. package/apps/studio/bin/import-asset.sh +34 -0
  25. package/apps/studio/bin/import-brand.sh +29 -0
  26. package/apps/studio/bin/import-tokens.sh +33 -0
  27. package/apps/studio/bin/ingest-footage.sh +27 -0
  28. package/apps/studio/bin/photo-adjust.sh +163 -0
  29. package/apps/studio/bin/photo-bg-remove.sh +258 -0
  30. package/apps/studio/bin/probe-footage.sh +28 -0
  31. package/apps/studio/bin/read-annotations.mjs +125 -2
  32. package/apps/studio/bin/transcribe.sh +39 -0
  33. package/apps/studio/canvas-edit.ts +656 -12
  34. package/apps/studio/canvas-lib.tsx +637 -10
  35. package/apps/studio/canvas-pipeline.ts +65 -7
  36. package/apps/studio/canvas-shell.tsx +156 -16
  37. package/apps/studio/client/app.jsx +2385 -699
  38. package/apps/studio/client/export-center.jsx +35 -1
  39. package/apps/studio/client/generate-dialog.jsx +352 -0
  40. package/apps/studio/client/github.js +18 -0
  41. package/apps/studio/client/inspector-controls.jsx +781 -0
  42. package/apps/studio/client/panels/BrandUploadPanel.jsx +233 -0
  43. package/apps/studio/client/panels/ChatPanel.jsx +15 -33
  44. package/apps/studio/client/panels/GitPanel.jsx +8 -0
  45. package/apps/studio/client/panels/IntroVideoDialog.jsx +44 -0
  46. package/apps/studio/client/panels/OnboardingWizard.jsx +12 -0
  47. package/apps/studio/client/panels/ReadinessList.jsx +227 -7
  48. package/apps/studio/client/panels/RepoBranchSwitcher.jsx +133 -21
  49. package/apps/studio/client/panels/SettingsPanel.jsx +828 -0
  50. package/apps/studio/client/panels/SetupChecklist.jsx +223 -0
  51. package/apps/studio/client/panels/StickerPicker.jsx +160 -0
  52. package/apps/studio/client/panels/TimelinePanel.jsx +15 -2
  53. package/apps/studio/client/photo-knobs.jsx +432 -0
  54. package/apps/studio/client/styles/3-shell-maude.css +376 -28
  55. package/apps/studio/client/styles/4-components.css +223 -0
  56. package/apps/studio/client/styles/6-acp-chat.css +86 -0
  57. package/apps/studio/client/tour/quick-setup-tour.js +39 -0
  58. package/apps/studio/commands/annotation-strokes-command.ts +13 -3
  59. package/apps/studio/commands/edit-source-command.ts +31 -4
  60. package/apps/studio/config.schema.json +70 -0
  61. package/apps/studio/context-menu.tsx +42 -8
  62. package/apps/studio/context.ts +16 -0
  63. package/apps/studio/design-setup-readiness.ts +115 -0
  64. package/apps/studio/dist/client.bundle.js +5572 -21
  65. package/apps/studio/dist/comment-mount.js +2 -2
  66. package/apps/studio/dist/runtime/.min-sizes.json +1 -0
  67. package/apps/studio/dist/runtime/@imgly_background-removal.js +5543 -0
  68. package/apps/studio/dist/runtime/pixi-js.js +519 -519
  69. package/apps/studio/dist/styles.css +1 -1
  70. package/apps/studio/dom-selection.ts +25 -0
  71. package/apps/studio/draw/palette.ts +34 -0
  72. package/apps/studio/exporters/jobs.ts +47 -5
  73. package/apps/studio/exporters/video.ts +24 -4
  74. package/apps/studio/footage/schema.test.ts +287 -0
  75. package/apps/studio/footage/schema.ts +662 -0
  76. package/apps/studio/footage-store.ts +235 -0
  77. package/apps/studio/fs-watch.ts +10 -0
  78. package/apps/studio/generation/adapters/elevenlabs.ts +370 -0
  79. package/apps/studio/generation/adapters/gemini.ts +542 -0
  80. package/apps/studio/generation/adapters/groq.test.ts +80 -0
  81. package/apps/studio/generation/adapters/groq.ts +247 -0
  82. package/apps/studio/generation/audio-library.test.ts +95 -0
  83. package/apps/studio/generation/audio-library.ts +156 -0
  84. package/apps/studio/generation/captions.test.ts +78 -0
  85. package/apps/studio/generation/captions.ts +132 -0
  86. package/apps/studio/generation/download.ts +76 -0
  87. package/apps/studio/generation/elevenlabs.test.ts +223 -0
  88. package/apps/studio/generation/gemini.test.ts +350 -0
  89. package/apps/studio/generation/jobs.test.ts +128 -0
  90. package/apps/studio/generation/jobs.ts +243 -0
  91. package/apps/studio/generation/keys.test.ts +75 -0
  92. package/apps/studio/generation/keys.ts +162 -0
  93. package/apps/studio/generation/prefs.test.ts +95 -0
  94. package/apps/studio/generation/prefs.ts +82 -0
  95. package/apps/studio/generation/registry.ts +88 -0
  96. package/apps/studio/generation/types.test.ts +123 -0
  97. package/apps/studio/generation/types.ts +266 -0
  98. package/apps/studio/generation/whisper-models.test.ts +152 -0
  99. package/apps/studio/generation/whisper-models.ts +257 -0
  100. package/apps/studio/generation/whisper-spike-results.md +61 -0
  101. package/apps/studio/git/endpoints.ts +68 -7
  102. package/apps/studio/git/service.ts +199 -21
  103. package/apps/studio/github/service.ts +67 -0
  104. package/apps/studio/handoff.ts +3 -2
  105. package/apps/studio/http.ts +1039 -22
  106. package/apps/studio/input-router.tsx +10 -0
  107. package/apps/studio/inspect.ts +53 -1
  108. package/apps/studio/media/intro.mp4 +0 -0
  109. package/apps/studio/media-commit-chain.ts +119 -0
  110. package/apps/studio/paths.ts +20 -0
  111. package/apps/studio/photo/filters.ts +285 -0
  112. package/apps/studio/photo/pipeline.ts +607 -0
  113. package/apps/studio/photo/schema.ts +367 -0
  114. package/apps/studio/photo-store.ts +154 -0
  115. package/apps/studio/readiness.ts +108 -20
  116. package/apps/studio/runtime-bundle.ts +29 -6
  117. package/apps/studio/scaffold-design.ts +1145 -0
  118. package/apps/studio/server.ts +18 -2
  119. package/apps/studio/stickers/figjam-doodle/manifest.json +104 -0
  120. package/apps/studio/stickers/figjam-doodle/slice1.png +0 -0
  121. package/apps/studio/stickers/figjam-doodle/slice10.png +0 -0
  122. package/apps/studio/stickers/figjam-doodle/slice11.png +0 -0
  123. package/apps/studio/stickers/figjam-doodle/slice12.png +0 -0
  124. package/apps/studio/stickers/figjam-doodle/slice13.png +0 -0
  125. package/apps/studio/stickers/figjam-doodle/slice14.png +0 -0
  126. package/apps/studio/stickers/figjam-doodle/slice15.png +0 -0
  127. package/apps/studio/stickers/figjam-doodle/slice16.png +0 -0
  128. package/apps/studio/stickers/figjam-doodle/slice17.png +0 -0
  129. package/apps/studio/stickers/figjam-doodle/slice18.png +0 -0
  130. package/apps/studio/stickers/figjam-doodle/slice19.png +0 -0
  131. package/apps/studio/stickers/figjam-doodle/slice2.png +0 -0
  132. package/apps/studio/stickers/figjam-doodle/slice20.png +0 -0
  133. package/apps/studio/stickers/figjam-doodle/slice21.png +0 -0
  134. package/apps/studio/stickers/figjam-doodle/slice22.png +0 -0
  135. package/apps/studio/stickers/figjam-doodle/slice23.png +0 -0
  136. package/apps/studio/stickers/figjam-doodle/slice24.png +0 -0
  137. package/apps/studio/stickers/figjam-doodle/slice3.png +0 -0
  138. package/apps/studio/stickers/figjam-doodle/slice4.png +0 -0
  139. package/apps/studio/stickers/figjam-doodle/slice5.png +0 -0
  140. package/apps/studio/stickers/figjam-doodle/slice6.png +0 -0
  141. package/apps/studio/stickers/figjam-doodle/slice7.png +0 -0
  142. package/apps/studio/stickers/figjam-doodle/slice8.png +0 -0
  143. package/apps/studio/stickers/figjam-doodle/slice9.png +0 -0
  144. package/apps/studio/stickers/life-style/best.png +0 -0
  145. package/apps/studio/stickers/life-style/come-on.png +0 -0
  146. package/apps/studio/stickers/life-style/cut.png +0 -0
  147. package/apps/studio/stickers/life-style/detox.png +0 -0
  148. package/apps/studio/stickers/life-style/just.png +0 -0
  149. package/apps/studio/stickers/life-style/manifest.json +68 -0
  150. package/apps/studio/stickers/life-style/mirror.png +0 -0
  151. package/apps/studio/stickers/life-style/nice.png +0 -0
  152. package/apps/studio/stickers/life-style/objects.png +0 -0
  153. package/apps/studio/stickers/life-style/ok.png +0 -0
  154. package/apps/studio/stickers/life-style/queen.png +0 -0
  155. package/apps/studio/stickers/life-style/star.png +0 -0
  156. package/apps/studio/stickers/life-style/sun.png +0 -0
  157. package/apps/studio/stickers/life-style/water.png +0 -0
  158. package/apps/studio/stickers/life-style/yeah.png +0 -0
  159. package/apps/studio/stickers/life-style/you-can.png +0 -0
  160. package/apps/studio/stickers/opposing-thoughts/check-the-deets.png +0 -0
  161. package/apps/studio/stickers/opposing-thoughts/cut-it.png +0 -0
  162. package/apps/studio/stickers/opposing-thoughts/dope.png +0 -0
  163. package/apps/studio/stickers/opposing-thoughts/fresh.png +0 -0
  164. package/apps/studio/stickers/opposing-thoughts/hot.png +0 -0
  165. package/apps/studio/stickers/opposing-thoughts/idea.png +0 -0
  166. package/apps/studio/stickers/opposing-thoughts/keep-exploring.png +0 -0
  167. package/apps/studio/stickers/opposing-thoughts/killed-it.png +0 -0
  168. package/apps/studio/stickers/opposing-thoughts/love-it.png +0 -0
  169. package/apps/studio/stickers/opposing-thoughts/manifest.json +88 -0
  170. package/apps/studio/stickers/opposing-thoughts/not-sure.png +0 -0
  171. package/apps/studio/stickers/opposing-thoughts/ok.png +0 -0
  172. package/apps/studio/stickers/opposing-thoughts/pure-gold.png +0 -0
  173. package/apps/studio/stickers/opposing-thoughts/save-for-later.png +0 -0
  174. package/apps/studio/stickers/opposing-thoughts/steal-this.png +0 -0
  175. package/apps/studio/stickers/opposing-thoughts/take-a-peek.png +0 -0
  176. package/apps/studio/stickers/opposing-thoughts/this-or-that.png +0 -0
  177. package/apps/studio/stickers/opposing-thoughts/thoughts.png +0 -0
  178. package/apps/studio/stickers/opposing-thoughts/vibes.png +0 -0
  179. package/apps/studio/stickers/opposing-thoughts/winner.png +0 -0
  180. package/apps/studio/stickers/opposing-thoughts/wip.png +0 -0
  181. package/apps/studio/stickers/project-status/group-100.png +0 -0
  182. package/apps/studio/stickers/project-status/group-101.png +0 -0
  183. package/apps/studio/stickers/project-status/group-102.png +0 -0
  184. package/apps/studio/stickers/project-status/group-103.png +0 -0
  185. package/apps/studio/stickers/project-status/group-104.png +0 -0
  186. package/apps/studio/stickers/project-status/group-105.png +0 -0
  187. package/apps/studio/stickers/project-status/group-106.png +0 -0
  188. package/apps/studio/stickers/project-status/group-107.png +0 -0
  189. package/apps/studio/stickers/project-status/group-108.png +0 -0
  190. package/apps/studio/stickers/project-status/group-109.png +0 -0
  191. package/apps/studio/stickers/project-status/group-110.png +0 -0
  192. package/apps/studio/stickers/project-status/group-111.png +0 -0
  193. package/apps/studio/stickers/project-status/group-112.png +0 -0
  194. package/apps/studio/stickers/project-status/group-113.png +0 -0
  195. package/apps/studio/stickers/project-status/group-114.png +0 -0
  196. package/apps/studio/stickers/project-status/group-115.png +0 -0
  197. package/apps/studio/stickers/project-status/group-117.png +0 -0
  198. package/apps/studio/stickers/project-status/group-118.png +0 -0
  199. package/apps/studio/stickers/project-status/group-119.png +0 -0
  200. package/apps/studio/stickers/project-status/group-120.png +0 -0
  201. package/apps/studio/stickers/project-status/group-121.png +0 -0
  202. package/apps/studio/stickers/project-status/group-122.png +0 -0
  203. package/apps/studio/stickers/project-status/group-41.png +0 -0
  204. package/apps/studio/stickers/project-status/group-42.png +0 -0
  205. package/apps/studio/stickers/project-status/group-43.png +0 -0
  206. package/apps/studio/stickers/project-status/group-44.png +0 -0
  207. package/apps/studio/stickers/project-status/group-45.png +0 -0
  208. package/apps/studio/stickers/project-status/group-46.png +0 -0
  209. package/apps/studio/stickers/project-status/group-47.png +0 -0
  210. package/apps/studio/stickers/project-status/group-48.png +0 -0
  211. package/apps/studio/stickers/project-status/group-49.png +0 -0
  212. package/apps/studio/stickers/project-status/group-50.png +0 -0
  213. package/apps/studio/stickers/project-status/group-51.png +0 -0
  214. package/apps/studio/stickers/project-status/group-52.png +0 -0
  215. package/apps/studio/stickers/project-status/group-53.png +0 -0
  216. package/apps/studio/stickers/project-status/group-54.png +0 -0
  217. package/apps/studio/stickers/project-status/group-55.png +0 -0
  218. package/apps/studio/stickers/project-status/group-56.png +0 -0
  219. package/apps/studio/stickers/project-status/group-57.png +0 -0
  220. package/apps/studio/stickers/project-status/group-58.png +0 -0
  221. package/apps/studio/stickers/project-status/group-59.png +0 -0
  222. package/apps/studio/stickers/project-status/group-60.png +0 -0
  223. package/apps/studio/stickers/project-status/group-61.png +0 -0
  224. package/apps/studio/stickers/project-status/group-62.png +0 -0
  225. package/apps/studio/stickers/project-status/group-63.png +0 -0
  226. package/apps/studio/stickers/project-status/group-64.png +0 -0
  227. package/apps/studio/stickers/project-status/group-65.png +0 -0
  228. package/apps/studio/stickers/project-status/group-66.png +0 -0
  229. package/apps/studio/stickers/project-status/group-67.png +0 -0
  230. package/apps/studio/stickers/project-status/group-68.png +0 -0
  231. package/apps/studio/stickers/project-status/group-69.png +0 -0
  232. package/apps/studio/stickers/project-status/group-70.png +0 -0
  233. package/apps/studio/stickers/project-status/group-71.png +0 -0
  234. package/apps/studio/stickers/project-status/group-72.png +0 -0
  235. package/apps/studio/stickers/project-status/group-73.png +0 -0
  236. package/apps/studio/stickers/project-status/group-74.png +0 -0
  237. package/apps/studio/stickers/project-status/group-75.png +0 -0
  238. package/apps/studio/stickers/project-status/group-76.png +0 -0
  239. package/apps/studio/stickers/project-status/group-77.png +0 -0
  240. package/apps/studio/stickers/project-status/group-78.png +0 -0
  241. package/apps/studio/stickers/project-status/group-79.png +0 -0
  242. package/apps/studio/stickers/project-status/group-80.png +0 -0
  243. package/apps/studio/stickers/project-status/group-81.png +0 -0
  244. package/apps/studio/stickers/project-status/group-82.png +0 -0
  245. package/apps/studio/stickers/project-status/group-83.png +0 -0
  246. package/apps/studio/stickers/project-status/group-84.png +0 -0
  247. package/apps/studio/stickers/project-status/group-85.png +0 -0
  248. package/apps/studio/stickers/project-status/group-86.png +0 -0
  249. package/apps/studio/stickers/project-status/group-87.png +0 -0
  250. package/apps/studio/stickers/project-status/group-88.png +0 -0
  251. package/apps/studio/stickers/project-status/group-89.png +0 -0
  252. package/apps/studio/stickers/project-status/group-90.png +0 -0
  253. package/apps/studio/stickers/project-status/group-91.png +0 -0
  254. package/apps/studio/stickers/project-status/group-92.png +0 -0
  255. package/apps/studio/stickers/project-status/group-93.png +0 -0
  256. package/apps/studio/stickers/project-status/group-94.png +0 -0
  257. package/apps/studio/stickers/project-status/group-96.png +0 -0
  258. package/apps/studio/stickers/project-status/group-97.png +0 -0
  259. package/apps/studio/stickers/project-status/group-98.png +0 -0
  260. package/apps/studio/stickers/project-status/group-99.png +0 -0
  261. package/apps/studio/stickers/project-status/manifest.json +328 -0
  262. package/apps/studio/test/_helpers.ts +15 -2
  263. package/apps/studio/test/acp-bootstrap-brief.test.ts +11 -0
  264. package/apps/studio/test/acp-bridge.test.ts +34 -1
  265. package/apps/studio/test/acp-commands.test.ts +2 -1
  266. package/apps/studio/test/acp-env.test.ts +30 -0
  267. package/apps/studio/test/acp-plugin-bootstrap.test.ts +23 -57
  268. package/apps/studio/test/acp-session-plugins.test.ts +72 -1
  269. package/apps/studio/test/annotation-strokes-command.test.ts +17 -0
  270. package/apps/studio/test/annotations-layer.test.ts +174 -0
  271. package/apps/studio/test/asset-api.test.ts +3 -3
  272. package/apps/studio/test/canvas-edit.test.ts +17 -6
  273. package/apps/studio/test/canvas-origin-gate.test.ts +50 -0
  274. package/apps/studio/test/csp-canvas-shell.test.ts +11 -0
  275. package/apps/studio/test/csrf-write-guard.test.ts +23 -1
  276. package/apps/studio/test/design-setup-readiness.test.ts +155 -0
  277. package/apps/studio/test/dynamic-text-edit.test.ts +162 -0
  278. package/apps/studio/test/edit-source-command.test.ts +23 -0
  279. package/apps/studio/test/element-structural-edit.test.ts +154 -0
  280. package/apps/studio/test/fixtures/fake-claude-auth.mjs +13 -0
  281. package/apps/studio/test/footage-store.test.ts +100 -0
  282. package/apps/studio/test/generate-route.test.ts +106 -0
  283. package/apps/studio/test/git-branches.test.ts +97 -0
  284. package/apps/studio/test/github-api.test.ts +56 -1
  285. package/apps/studio/test/import-asset-browser.test.ts +64 -0
  286. package/apps/studio/test/import-asset-route.test.ts +71 -0
  287. package/apps/studio/test/import-asset.test.ts +399 -0
  288. package/apps/studio/test/import-brand-browser.test.ts +88 -0
  289. package/apps/studio/test/import-brand-route.test.ts +120 -0
  290. package/apps/studio/test/import-brand.test.ts +206 -0
  291. package/apps/studio/test/import-tokens.test.ts +722 -0
  292. package/apps/studio/test/input-router.test.ts +33 -0
  293. package/apps/studio/test/inspect-script-syntax.test.ts +53 -0
  294. package/apps/studio/test/media-commit-chain.test.ts +210 -0
  295. package/apps/studio/test/photo-bg-remove-validation.test.ts +71 -0
  296. package/apps/studio/test/photo-canvas-bundle.test.ts +61 -0
  297. package/apps/studio/test/photo-edit-api.test.ts +201 -0
  298. package/apps/studio/test/photo-filters.test.ts +149 -0
  299. package/apps/studio/test/photo-pipeline.test.ts +106 -0
  300. package/apps/studio/test/photo-taxonomy.test.ts +96 -0
  301. package/apps/studio/test/read-annotations.test.ts +164 -0
  302. package/apps/studio/test/readiness.test.ts +13 -11
  303. package/apps/studio/test/scaffold-design.test.ts +122 -0
  304. package/apps/studio/test/shell-importmap.test.ts +49 -0
  305. package/apps/studio/test/text-editability-stamp.test.ts +131 -0
  306. package/apps/studio/test/timeline-parse.test.ts +57 -0
  307. package/apps/studio/test/tool-palette-insert-anchor.test.ts +5 -3
  308. package/apps/studio/test/tour-overlay.test.tsx +16 -0
  309. package/apps/studio/test/undo-stack.test.ts +33 -0
  310. package/apps/studio/test/video-asset.test.ts +5 -5
  311. package/apps/studio/test/video-render-bridge.test.ts +23 -1
  312. package/apps/studio/text-caret.ts +239 -0
  313. package/apps/studio/tool-palette.tsx +49 -21
  314. package/apps/studio/ui-prefs.ts +130 -0
  315. package/apps/studio/undo-stack.ts +94 -2
  316. package/apps/studio/use-annotation-resize.tsx +4 -4
  317. package/apps/studio/use-canvas-media-drop.tsx +40 -1
  318. package/apps/studio/use-chrome-visibility.tsx +8 -2
  319. package/apps/studio/use-selection-set.tsx +21 -0
  320. package/apps/studio/video-comp.tsx +48 -7
  321. package/apps/studio/whats-new.json +149 -0
  322. package/apps/studio/ws.ts +5 -0
  323. package/cli/bin/maude.mjs +6 -6
  324. package/cli/commands/design.mjs +67 -3
  325. package/cli/lib/gitignore-block.mjs +2 -0
  326. package/cli/lib/pkg-root.mjs +107 -0
  327. package/cli/lib/pkg-root.test.mjs +79 -0
  328. package/cli/lib/reconstruct-toolset.test.mjs +194 -0
  329. package/cli/lib/update-check.mjs +8 -0
  330. package/package.json +13 -11
  331. package/plugins/design/dependencies.json +18 -0
  332. package/plugins/design/templates/_shell.html +1 -0
@@ -0,0 +1,79 @@
1
+ // pkg-root.mjs tests (DDR-166 T0b).
2
+ //
3
+ // The regression this locks down: a naive single-anchor check
4
+ // (`apps/studio/bin/screenshot.sh` alone) false-positives inside the Tauri
5
+ // desktop build, because `stage-resources.mjs` stages a full working copy of
6
+ // `apps/studio` into `target/debug/apps/studio/` for the sidecar's own
7
+ // runtime resolution — that staged copy has no `cli/`, so a compiled `maude`
8
+ // binary walking up from `target/debug/maude` matched it and stopped one
9
+ // level too early, resolving PKG_ROOT to `target/debug` instead of the real
10
+ // repo root. Caught by live testing against the real Tauri build (not a
11
+ // synthetic path), not by static review — worth a regression test.
12
+
13
+ import assert from 'node:assert/strict';
14
+ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
15
+ import { tmpdir } from 'node:os';
16
+ import { join } from 'node:path';
17
+ import { test } from 'node:test';
18
+
19
+ import { isPkgRoot, resolvePkgRoot } from './pkg-root.mjs';
20
+
21
+ function makeRealRoot(base) {
22
+ mkdirSync(join(base, 'apps', 'studio', 'bin'), { recursive: true });
23
+ writeFileSync(join(base, 'apps', 'studio', 'bin', 'screenshot.sh'), '#!/bin/sh\n');
24
+ mkdirSync(join(base, 'cli', 'commands'), { recursive: true });
25
+ writeFileSync(join(base, 'cli', 'commands', 'design.mjs'), 'export const run = () => {};\n');
26
+ }
27
+
28
+ test('isPkgRoot requires BOTH anchors — the staged-resources false-positive is rejected', () => {
29
+ const tmp = mkdtempSync(join(tmpdir(), 'maude-pkgroot-'));
30
+ try {
31
+ // The exact shape of the bug: apps/studio/bin/screenshot.sh present
32
+ // (mirrors stage-resources.mjs's staged copy), no cli/ at all.
33
+ mkdirSync(join(tmp, 'apps', 'studio', 'bin'), { recursive: true });
34
+ writeFileSync(join(tmp, 'apps', 'studio', 'bin', 'screenshot.sh'), '#!/bin/sh\n');
35
+ assert.equal(isPkgRoot(tmp), false);
36
+
37
+ // cli/ alone, no apps/studio — also not a real root.
38
+ const tmp2 = mkdtempSync(join(tmpdir(), 'maude-pkgroot-'));
39
+ try {
40
+ mkdirSync(join(tmp2, 'cli', 'commands'), { recursive: true });
41
+ writeFileSync(join(tmp2, 'cli', 'commands', 'design.mjs'), '');
42
+ assert.equal(isPkgRoot(tmp2), false);
43
+ } finally {
44
+ rmSync(tmp2, { recursive: true, force: true });
45
+ }
46
+
47
+ // Both anchors together — a genuine package root.
48
+ makeRealRoot(tmp);
49
+ assert.equal(isPkgRoot(tmp), true);
50
+ } finally {
51
+ rmSync(tmp, { recursive: true, force: true });
52
+ }
53
+ });
54
+
55
+ test('resolvePkgRoot honors MAUDE_PKG_ROOT only when it actually satisfies both anchors', () => {
56
+ const real = mkdtempSync(join(tmpdir(), 'maude-pkgroot-real-'));
57
+ const fake = mkdtempSync(join(tmpdir(), 'maude-pkgroot-fake-'));
58
+ const prevOverride = process.env.MAUDE_PKG_ROOT;
59
+ try {
60
+ makeRealRoot(real);
61
+ // Fake: only the staged-resources-shaped anchor, same false-positive shape.
62
+ mkdirSync(join(fake, 'apps', 'studio', 'bin'), { recursive: true });
63
+ writeFileSync(join(fake, 'apps', 'studio', 'bin', 'screenshot.sh'), '#!/bin/sh\n');
64
+
65
+ process.env.MAUDE_PKG_ROOT = real;
66
+ assert.equal(resolvePkgRoot(), real);
67
+
68
+ process.env.MAUDE_PKG_ROOT = fake;
69
+ // Falls through past the (rejected) override to whatever the real
70
+ // walk-up finds in THIS test process — just assert it's NOT the fake
71
+ // dir, since accepting it would be exactly the regression.
72
+ assert.notEqual(resolvePkgRoot(), fake);
73
+ } finally {
74
+ if (prevOverride === undefined) delete process.env.MAUDE_PKG_ROOT;
75
+ else process.env.MAUDE_PKG_ROOT = prevOverride;
76
+ rmSync(real, { recursive: true, force: true });
77
+ rmSync(fake, { recursive: true, force: true });
78
+ }
79
+ });
@@ -0,0 +1,194 @@
1
+ // DDR-174 regression guard (T15).
2
+ //
3
+ // The whole security architecture of `/design:import --reconstruct` rests on
4
+ // ONE fact: every agent turn that ever reads the untrusted source image —
5
+ // `reconstruct-agent` (authoring) AND `reconstruct-critic` (the reality-check
6
+ // comparator) — has `tools: Read, Write, Glob, Grep` and NEVER `Bash`,
7
+ // `WebSearch`, or `WebFetch`. DDR-174's own Consequences section calls for
8
+ // exactly this test: "a targeted grep-based test mirroring
9
+ // plugin-cli-reachability.test.mjs's pattern should assert BOTH the authoring
10
+ // agent's AND the comparator agent's frontmatter never gain
11
+ // Bash/WebSearch/WebFetch, not just this DDR's prose." A future maintainer
12
+ // "helpfully" widening either agent's toolset (e.g. "just give it Bash so it
13
+ // can screenshot itself") would silently reopen DDR-174's entire closure —
14
+ // this fails loudly instead.
15
+
16
+ import assert from 'node:assert/strict';
17
+ import { readFileSync } from 'node:fs';
18
+ import { test } from 'node:test';
19
+
20
+ const AGENTS = [
21
+ 'plugins/design/agents/reconstruct-agent.md',
22
+ 'plugins/design/agents/reconstruct-critic.md',
23
+ ];
24
+
25
+ const FRONTMATTER_RE = /^---\n([\s\S]*?)\n---/;
26
+
27
+ function readFrontmatter(path) {
28
+ const text = readFileSync(path, 'utf8');
29
+ const fm = FRONTMATTER_RE.exec(text);
30
+ assert.ok(fm, `${path}: no frontmatter block found`);
31
+ return fm[1];
32
+ }
33
+
34
+ function readToolsLine(path) {
35
+ const fm = readFrontmatter(path);
36
+ const toolsLine = fm.split('\n').find((l) => l.startsWith('tools:'));
37
+ assert.ok(toolsLine, `${path}: frontmatter has no tools: line`);
38
+ return toolsLine;
39
+ }
40
+
41
+ for (const path of AGENTS) {
42
+ test(`${path}: tools: line never grants Bash`, () => {
43
+ const line = readToolsLine(path);
44
+ assert.ok(
45
+ !/\bBash\b/.test(line),
46
+ `${path} declares Bash — this reopens DDR-174's core closure (the agent reads an untrusted image and must never hold a shell). Line: ${line}`
47
+ );
48
+ });
49
+
50
+ test(`${path}: tools: line never grants WebSearch or WebFetch`, () => {
51
+ const line = readToolsLine(path);
52
+ assert.ok(
53
+ !/\bWebSearch\b/.test(line) && !/\bWebFetch\b/.test(line),
54
+ `${path} declares WebSearch/WebFetch — DDR-174 requires these agents have no tool call that reaches the network. Line: ${line}`
55
+ );
56
+ });
57
+
58
+ test(`${path}: tools: line is exactly Read, Write, Glob, Grep`, () => {
59
+ const line = readToolsLine(path);
60
+ const tools = line
61
+ .replace(/^tools:\s*/, '')
62
+ .split(',')
63
+ .map((t) => t.trim())
64
+ .filter(Boolean);
65
+ assert.deepEqual(
66
+ [...tools].sort(),
67
+ ['Glob', 'Grep', 'Read', 'Write'],
68
+ `${path}: expected exactly Read/Write/Glob/Grep per DDR-174 Decision 1, got: ${line}`
69
+ );
70
+ });
71
+
72
+ // DDR-174 Addendum (post-implementation adversarial review) — Write has no
73
+ // path restriction (Claude Code has no per-subagent path-scoping mechanism,
74
+ // verified authoritatively, not assumed) and the only real closure for a
75
+ // non-bypassPermissions session is a human approval prompt on any write.
76
+ // `permissionMode: default` is what makes that prompt happen instead of
77
+ // silently inheriting the parent session's (possibly bypassPermissions)
78
+ // mode. A future maintainer removing this line silently re-widens the
79
+ // agent's effective write reach for every downstream consumer NOT running
80
+ // bypassPermissions.
81
+ test(`${path}: frontmatter declares permissionMode: default (DDR-174 Addendum)`, () => {
82
+ const fm = readFrontmatter(path);
83
+ const line = fm.split('\n').find((l) => l.startsWith('permissionMode:'));
84
+ assert.ok(
85
+ line,
86
+ `${path}: missing permissionMode: default — without it this agent silently inherits the parent session's permission mode (e.g. bypassPermissions), losing the one real per-write approval gate available for its unrestricted Write tool (DDR-174 Addendum)`
87
+ );
88
+ assert.equal(
89
+ line.replace(/^permissionMode:\s*/, '').trim(),
90
+ 'default',
91
+ `${path}: permissionMode must be exactly "default" (prompts on every write), not a looser mode. Line: ${line}`
92
+ );
93
+ });
94
+ }
95
+
96
+ test('import.md diff-check is whole-repo scoped, not just $DESIGN_ROOT (DDR-174 Addendum)', () => {
97
+ // The first implementation scoped `git status --porcelain -- "$DESIGN_ROOT"`,
98
+ // which made a write to .claude/settings.json, CLAUDE.md, or plugins/**
99
+ // structurally invisible to the check — an adversarial review built a full
100
+ // exploit chain out of exactly that gap. Assert the pathspec was actually
101
+ // widened, not just documented as widened in prose.
102
+ const importMd = readFileSync('plugins/design/commands/import.md', 'utf8');
103
+ assert.ok(
104
+ !/git -C "\$REPO" status --porcelain -- "\$DESIGN_ROOT"/.test(importMd),
105
+ 'import.md must NOT scope the diff-check to $DESIGN_ROOT only — this was the exact gap the DDR-174 Addendum closes (a write outside $DESIGN_ROOT, e.g. to .claude/settings.json, would be invisible to a $DESIGN_ROOT-scoped check)'
106
+ );
107
+ const wholeRepoOccurrences = (importMd.match(/git -C "\$REPO" status --porcelain\b/g) || [])
108
+ .length;
109
+ assert.ok(
110
+ wholeRepoOccurrences >= 2,
111
+ `import.md must run an UNSCOPED \`git -C "$REPO" status --porcelain\` for both the BEFORE (step 4) and AFTER (step 5b) snapshots — found ${wholeRepoOccurrences} occurrence(s)`
112
+ );
113
+ });
114
+
115
+ test('import.md snapshots the two well-known global Claude Code config paths (DDR-174 Addendum)', () => {
116
+ // A repo-scoped git diff can never see $HOME/.claude/** — these are the two
117
+ // specific files an adversarial review named as attack targets (a planted
118
+ // hook, or a poisoned global CLAUDE.md loaded into every future session).
119
+ const importMd = readFileSync('plugins/design/commands/import.md', 'utf8');
120
+ assert.ok(
121
+ importMd.includes('$HOME/.claude/settings.json') &&
122
+ importMd.includes('$HOME/.claude/CLAUDE.md'),
123
+ 'import.md must snapshot $HOME/.claude/settings.json and $HOME/.claude/CLAUDE.md before/after each round and hard-fail on any change (DDR-174 Addendum) — these are outside any repo-scoped diff check'
124
+ );
125
+ });
126
+
127
+ test('import.md stat calls are portable (GNU-first, BSD-fallback), not BSD-only (DDR-174 Addendum confirmation pass)', () => {
128
+ // The first Addendum revision used BSD-only `stat -f` unconditionally — it
129
+ // silently no-ops on Linux (a platform this project ships a .deb for),
130
+ // because GNU `stat -f` means something else entirely and errors out,
131
+ // swallowed by the trailing `2>/dev/null`. Both empty strings compare
132
+ // equal, so the check trivially "passes" without ever having checked
133
+ // anything. Assert every stat call tries GNU syntax (`stat -c`) first.
134
+ const importMd = readFileSync('plugins/design/commands/import.md', 'utf8');
135
+ // Only scan actual shell inside fenced ```bash blocks — prose elsewhere
136
+ // legitimately mentions `stat -f` by name when explaining the old bug.
137
+ const codeBlocks = [...importMd.matchAll(/```bash\n([\s\S]*?)```/g)].map((m) => m[1]).join('\n');
138
+ const bareStatF = codeBlocks.match(/(?<!\|\| )\bstat -f\b/g) || [];
139
+ assert.deepEqual(
140
+ bareStatF,
141
+ [],
142
+ `import.md has a \`stat -f\` call in executable shell with no \`stat -c\` GNU fallback tried first — this silently no-ops on Linux (DDR-174 Addendum confirmation-pass finding). Found ${bareStatF.length} bare occurrence(s).`
143
+ );
144
+ const statCOccurrences = (codeBlocks.match(/stat -c '/g) || []).length;
145
+ assert.ok(
146
+ statCOccurrences >= 4,
147
+ `expected at least 4 GNU-first \`stat -c\` attempts (2 for the non-git repo-wide fallback, 2 for the global-config snapshot) — found ${statCOccurrences}`
148
+ );
149
+ });
150
+
151
+ test('import.md non-git fallback excludes _history/ (DDR-174 Addendum confirmation pass)', () => {
152
+ // The reconstruct loop writes its own screenshots/verdict files under
153
+ // _history/_reconstruct/<slug>/ every round. A git-repo target gets this
154
+ // excluded for free via .gitignore; the non-git `find`-based fallback has
155
+ // no such filter and would false-positive-abort on its own round-1 output
156
+ // the moment round 2's diff check runs, in a non-git target repo.
157
+ const importMd = readFileSync('plugins/design/commands/import.md', 'utf8');
158
+ const findOccurrences = importMd.match(/find "\$REPO" -type f[^\n]*/g) || [];
159
+ assert.ok(
160
+ findOccurrences.length >= 2,
161
+ 'expected the non-git fallback find command in both step 4 and step 5b'
162
+ );
163
+ for (const line of findOccurrences) {
164
+ assert.ok(
165
+ line.includes("-not -path '*/_history/*'"),
166
+ `non-git fallback find command must exclude _history/ (its own round-N artifacts) or every multi-round run in a non-git target repo false-positive-aborts: ${line}`
167
+ );
168
+ }
169
+ });
170
+
171
+ test('import.md uses mktemp for the _active.json patch, not a fixed /tmp filename (DDR-174 Addendum)', () => {
172
+ const importMd = readFileSync('plugins/design/commands/import.md', 'utf8');
173
+ assert.ok(
174
+ !/\/tmp\/active\.json\.tmp/.test(importMd),
175
+ 'import.md must not use a fixed, predictable /tmp filename for the _active.json patch — a symlink race target on a shared machine (DDR-174 Addendum adversarial finding)'
176
+ );
177
+ assert.ok(/mktemp/.test(importMd), 'import.md must use mktemp for its temp file(s)');
178
+ });
179
+
180
+ test('design-critic.md is never repurposed as the reconstruct comparator (DDR-174 Decision 1 Round-2)', () => {
181
+ // The comparator must be reconstruct-critic (Bash-free), never the default
182
+ // Bash-capable design-critic — assert import.md's orchestrator spawns the
183
+ // dedicated agent, not design-critic, for the reality-check step.
184
+ const importMd = readFileSync('plugins/design/commands/import.md', 'utf8');
185
+ const reconstructSection = importMd.slice(importMd.indexOf('## `--reconstruct'));
186
+ assert.ok(
187
+ reconstructSection.includes('design:reconstruct-critic'),
188
+ 'import.md --reconstruct mode must spawn design:reconstruct-critic for the reality-check step'
189
+ );
190
+ assert.ok(
191
+ !/subagent_type:\s*"design:design-critic"/.test(reconstructSection),
192
+ 'import.md --reconstruct mode must NOT spawn the default design-critic as its comparator (DDR-174 Decision 1 Round-2) — it is Bash-capable and reopens the trifecta this DDR closes'
193
+ );
194
+ });
@@ -15,6 +15,7 @@ import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
15
15
  import { homedir } from 'node:os';
16
16
  import { dirname, join } from 'node:path';
17
17
  import { fileURLToPath } from 'node:url';
18
+ import { isCompiledBinary } from './pkg-root.mjs';
18
19
 
19
20
  const PKG_NAME = '@1agh/maude';
20
21
  const REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
@@ -31,6 +32,13 @@ function shouldSkip() {
31
32
  if (process.env.NO_UPDATE_NOTIFIER) return true;
32
33
  if (process.env.CI) return true;
33
34
  if (!process.stderr.isTTY) return true;
35
+ // DDR-166 T0b — a Tauri-bundled `maude` binary updates via the app's own
36
+ // auto-updater (DDR-126), not `npm i -g @1agh/maude@latest`; the notice
37
+ // would be actively wrong advice. Also sidesteps spawnDetachedRefresh()'s
38
+ // self-respawn, which re-invokes `import.meta.url` as a script path — a
39
+ // real file:// path in dev/node, but Bun's virtual `/$bunfs/root` inside
40
+ // this exact compiled binary (DDR-045-class trap).
41
+ if (isCompiledBinary()) return true;
34
42
  return false;
35
43
  }
36
44
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1agh/maude",
3
- "version": "0.42.0",
3
+ "version": "0.44.0",
4
4
  "description": "Marketplace of Claude Code plugins by Michal Dovrtěl: `design` (canvas-first design iteration) + `flow` (generic agentic workflow loop with .ai second brain). Ships the `maude` CLI (with `mdcc` legacy alias) to scaffold workspace, run the design dev server, and manage configs.",
5
5
  "type": "module",
6
6
  "engines": {
@@ -47,16 +47,17 @@
47
47
  "prepublishOnly": "bash scripts/check-version-parity.sh && bash apps/studio/bin/check-runtime-bundles.sh",
48
48
  "test:e2e:desktop:lifecycle": "pnpm --filter @maude/desktop-e2e e2e:lifecycle",
49
49
  "test:e2e:desktop:switchrepos": "pnpm --filter @maude/desktop-e2e e2e:switchrepos",
50
- "test:e2e:desktop:onboarding": "pnpm --filter @maude/desktop-e2e e2e:onboarding"
50
+ "test:e2e:desktop:onboarding": "pnpm --filter @maude/desktop-e2e e2e:onboarding",
51
+ "test:e2e:desktop:acp-cold-start": "pnpm --filter @maude/desktop-e2e e2e:acp-cold-start"
51
52
  },
52
53
  "optionalDependencies": {
53
- "@1agh/maude-darwin-arm64": "0.42.0",
54
- "@1agh/maude-darwin-x64": "0.42.0",
55
- "@1agh/maude-linux-arm64": "0.42.0",
56
- "@1agh/maude-linux-arm64-musl": "0.42.0",
57
- "@1agh/maude-linux-x64": "0.42.0",
58
- "@1agh/maude-linux-x64-musl": "0.42.0",
59
- "@1agh/maude-win32-x64": "0.42.0"
54
+ "@1agh/maude-darwin-arm64": "0.44.0",
55
+ "@1agh/maude-darwin-x64": "0.44.0",
56
+ "@1agh/maude-linux-arm64": "0.44.0",
57
+ "@1agh/maude-linux-arm64-musl": "0.44.0",
58
+ "@1agh/maude-linux-x64": "0.44.0",
59
+ "@1agh/maude-linux-x64-musl": "0.44.0",
60
+ "@1agh/maude-win32-x64": "0.44.0"
60
61
  },
61
62
  "files": [
62
63
  "cli",
@@ -94,9 +95,10 @@
94
95
  "scaffold"
95
96
  ],
96
97
  "devDependencies": {
97
- "@biomejs/biome": "^2.4.16",
98
+ "@biomejs/biome": "^2.5.3",
98
99
  "@changesets/cli": "^2.27.10",
99
- "@playwright/test": "^1.60.0"
100
+ "@playwright/test": "^1.61.1",
101
+ "lucide-react": "^1.24.0"
100
102
  },
101
103
  "dependencies": {
102
104
  "ajv": "^8.20.0",
@@ -195,6 +195,24 @@
195
195
  "fallbackBehavior": "Phase 31 (DDR-123) — the native ACP chat sidepanel drives the user's OWN installed `claude` CLI on their Pro/Max subscription (never API billing). Without it the panel shows the not-connected explainer ('run `claude` in a terminal and `/login`'); every other design surface is unaffected.",
196
196
  "usedBy": ["dev-server/acp/probe.ts", "dev-server/acp/bridge.ts"],
197
197
  "docsUrl": "https://docs.claude.com/en/docs/claude-code"
198
+ },
199
+ {
200
+ "id": "whisper-cpp",
201
+ "type": "cli",
202
+ "hardness": "soft",
203
+ "check": {
204
+ "command": "whisper-cli --help",
205
+ "expectExit": 0
206
+ },
207
+ "install": {
208
+ "darwin": "brew install whisper-cpp",
209
+ "linux": "https://github.com/ggml-org/whisper.cpp#quick-start",
210
+ "preferred": "https://github.com/ggml-org/whisper.cpp"
211
+ },
212
+ "autoInstall": false,
213
+ "fallbackBehavior": "feature-ai-media-generation Phase 2 (DDR-164) — `maude design transcribe` uses whisper.cpp for local, no-key, word-timestamped subtitles (the DEFAULT subtitle path). Without it, transcription falls back to cloud STT (ElevenLabs Scribe / Groq Whisper) via a provider key. whisper.cpp also needs a ggml model file (--model / $MAUDE_WHISPER_MODEL); it ships no default and does not auto-download — see https://huggingface.co/ggerganov/whisper.cpp (e.g. ggml-large-v3-turbo.bin).",
214
+ "usedBy": ["dev-server/bin/transcribe.sh", "dev-server/bin/_transcribe.mjs"],
215
+ "docsUrl": "https://github.com/ggml-org/whisper.cpp"
198
216
  }
199
217
  ]
200
218
  }
@@ -135,6 +135,7 @@
135
135
  "react/jsx-runtime": "/_canvas-runtime/react_jsx-runtime.js",
136
136
  "react/jsx-dev-runtime": "/_canvas-runtime/react_jsx-dev-runtime.js",
137
137
  "pixi.js": "/_canvas-runtime/pixi-js.js",
138
+ "@imgly/background-removal": "/_canvas-runtime/@imgly_background-removal.js",
138
139
  "motion": "/_canvas-runtime/motion.js",
139
140
  "motion/react": "/_canvas-runtime/motion_react.js",
140
141
  "yjs": "/_canvas-runtime/yjs.js",