appshot-cli 0.9.1 → 1.0.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 (57) hide show
  1. package/README.md +208 -98
  2. package/dist/cli.js +6 -1
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/build.d.ts.map +1 -1
  5. package/dist/commands/build.js +9 -0
  6. package/dist/commands/build.js.map +1 -1
  7. package/dist/commands/frame.d.ts.map +1 -1
  8. package/dist/commands/frame.js +11 -2
  9. package/dist/commands/frame.js.map +1 -1
  10. package/dist/commands/mcp.d.ts +3 -0
  11. package/dist/commands/mcp.d.ts.map +1 -0
  12. package/dist/commands/mcp.js +19 -0
  13. package/dist/commands/mcp.js.map +1 -0
  14. package/dist/commands/skill.d.ts +3 -0
  15. package/dist/commands/skill.d.ts.map +1 -0
  16. package/dist/commands/skill.js +119 -0
  17. package/dist/commands/skill.js.map +1 -0
  18. package/dist/core/compose.d.ts +1 -0
  19. package/dist/core/compose.d.ts.map +1 -1
  20. package/dist/core/compose.js +85 -140
  21. package/dist/core/compose.js.map +1 -1
  22. package/dist/core/layout-utils.d.ts +12 -0
  23. package/dist/core/layout-utils.d.ts.map +1 -0
  24. package/dist/core/layout-utils.js +28 -0
  25. package/dist/core/layout-utils.js.map +1 -0
  26. package/dist/core/text-utils.d.ts +1 -1
  27. package/dist/core/text-utils.d.ts.map +1 -1
  28. package/dist/core/text-utils.js +5 -9
  29. package/dist/core/text-utils.js.map +1 -1
  30. package/dist/mcp/cli-options.d.ts +112 -0
  31. package/dist/mcp/cli-options.d.ts.map +1 -0
  32. package/dist/mcp/cli-options.js +158 -0
  33. package/dist/mcp/cli-options.js.map +1 -0
  34. package/dist/mcp/server.d.ts +2 -0
  35. package/dist/mcp/server.d.ts.map +1 -0
  36. package/dist/mcp/server.js +1149 -0
  37. package/dist/mcp/server.js.map +1 -0
  38. package/dist/services/doctor.d.ts.map +1 -1
  39. package/dist/services/doctor.js +2 -1
  40. package/dist/services/doctor.js.map +1 -1
  41. package/dist/templates/registry.d.ts.map +1 -1
  42. package/dist/templates/registry.js +49 -159
  43. package/dist/templates/registry.js.map +1 -1
  44. package/dist/utils/filename-caption.d.ts +9 -0
  45. package/dist/utils/filename-caption.d.ts.map +1 -0
  46. package/dist/utils/filename-caption.js +19 -0
  47. package/dist/utils/filename-caption.js.map +1 -0
  48. package/dist/version.d.ts +2 -0
  49. package/dist/version.d.ts.map +1 -0
  50. package/dist/version.js +5 -0
  51. package/dist/version.js.map +1 -0
  52. package/package.json +7 -4
  53. package/skill/SKILL.md +225 -0
  54. package/skill/references/fonts.md +55 -0
  55. package/skill/references/gradients.md +69 -0
  56. package/skill/references/templates.md +170 -0
  57. package/skill/references/troubleshooting.md +228 -0
@@ -1 +1 @@
1
- {"version":3,"file":"frame.js","sourceRoot":"","sources":["../../src/commands/frame.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"frame.js","sourceRoot":"","sources":["../../src/commands/frame.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,eAAe,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AAClI,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAkBtD,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,GAAW;IAClC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,KAAK,UAAU,qBAAqB,CAAC,IAAY;IAC/C,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAChE,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,CAAC;YACjD,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;QACxB,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACjD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,SAAiB,EAAE,SAAiB,EAAE,OAA4B;IACjG,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAE3E,8BAA8B;IAC9B,IAAI,KAAK,GAAG,GAAG,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC;QAChC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,oBAAoB,KAAK,IAAI,MAAM,8BAA8B,CAAC,CAAC,CAAC;QAClI,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACrC,CAAC;IAED,gCAAgC;IAChC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACjE,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,yBAAyB,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,qCAAqC,CAAC,CAAC,CAAC;IACpJ,CAAC;IAED,IAAI,MAAM,GAAsB,OAAO,CAAC,MAAM,IAAI,8BAA8B,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAChG,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,iCAAiC,KAAK,IAAI,MAAM,6BAA6B,CAAC,CAAC,CAAC;QAC9I,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACrC,CAAC;IAED,eAAe;IACf,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,eAAe,CAC/C,SAAS,EACT,SAAS,EACT,MAAM,EACN,SAAS,EACT,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CACxB,CAAC;IAEF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,CAAC;QAC1F,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACrC,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,MAAM,KAAK,WAAW,GAAG,CAAC,CAAC,CAAC;QAChG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,eAAe,KAAK,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,cAAc,QAAQ,CAAC,WAAW,KAAK,QAAQ,CAAC,UAAU,IAAI,QAAQ,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;QAC3G,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACrC,CAAC;IAED,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC,CAAC;QAC7F,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACrC,CAAC;IAED,yBAAyB;IACzB,IAAI,gBAAwB,CAAC;IAC7B,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC9C,gBAAgB,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;IACvD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,yBAAyB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5I,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACrC,CAAC;IAED,mDAAmD;IACnD,IAAI,SAAiB,CAAC;IACtB,IAAI,CAAC;QACH,SAAS,GAAG,MAAM,gBAAgB,CAAC;YACjC,UAAU,EAAE,gBAAgB;YAC5B,KAAK;YACL,aAAa,EAAE;gBACb,UAAU,EAAE,QAAQ,CAAC,UAAU;gBAC/B,WAAW,EAAE,QAAQ,CAAC,WAAW;gBACjC,UAAU,EAAE,QAAQ,CAAC,UAAU;gBAC/B,QAAQ,EAAE,QAAQ,CAAC,QAAQ;gBAC3B,UAAU,EAAE,QAAQ,CAAC,UAAU;gBAC/B,WAAW,EAAE,QAAQ,CAAC,WAAW;gBACjC,IAAI,EAAE,QAAQ,CAAC,IAAI;aACpB;YACD,YAAY,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK;YACrC,WAAW,EAAE,EAAE;YACf,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,mBAAmB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACtI,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACrC,CAAC;IAED,wBAAwB;IACxB,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC;IACvC,MAAM,GAAG,GAAG,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;IAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;IACnE,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC1F,MAAM,SAAS,CAAC,SAAS,CAAC,CAAC;IAE3B,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,SAAS,CAAC;IACzC,IAAI,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,MAAM,GAAG,GAAG,EAAE,CAAC;IACrF,IAAI,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAE5C,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACzB,kEAAkE;YAClE,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,GAAG,SAAS,CAAC;gBACnB,OAAO,GAAG,GAAG,QAAQ,GAAG,MAAM,GAAG,GAAG,EAAE,CAAC;gBACvC,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,qBAAqB;QACvB,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,MAAM,KAAK,WAAW,gBAAgB,CAAC,CAAC,CAAC;QACzG,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACrC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,iBAAiB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACpI,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACrC,CAAC;AACH,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,QAAQ;IAC9B,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;SAC7B,WAAW,CAAC,6FAA6F,CAAC;SAC1G,QAAQ,CAAC,SAAS,EAAE,+BAA+B,CAAC;SACpD,MAAM,CAAC,oBAAoB,EAAE,2CAA2C,CAAC;SACzE,MAAM,CAAC,qBAAqB,EAAE,2CAA2C,CAAC;SAC1E,MAAM,CAAC,iBAAiB,EAAE,iCAAiC,CAAC;SAC5D,MAAM,CAAC,qBAAqB,EAAE,0BAA0B,EAAE,KAAK,CAAC;SAChE,MAAM,CAAC,iBAAiB,EAAE,sCAAsC,EAAE,SAAS,CAAC;SAC5E,MAAM,CAAC,aAAa,EAAE,8BAA8B,CAAC;SACrD,MAAM,CAAC,WAAW,EAAE,kCAAkC,CAAC;SACvD,MAAM,CAAC,qBAAqB,EAAE,0CAA0C,EAAE,UAAU,CAAC;SACrF,MAAM,CAAC,WAAW,EAAE,2BAA2B,CAAC;SAChD,WAAW,CAAC,OAAO,EAAE;EACxB,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC;IAClB,EAAE,CAAC,GAAG,CAAC,oCAAoC,CAAC;;;IAG5C,EAAE,CAAC,GAAG,CAAC,4BAA4B,CAAC;;;IAGpC,EAAE,CAAC,GAAG,CAAC,qBAAqB,CAAC;;;IAG7B,EAAE,CAAC,GAAG,CAAC,6BAA6B,CAAC;;;IAGrC,EAAE,CAAC,GAAG,CAAC,6BAA6B,CAAC;oDACW,CAAC;SAChD,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,IAAI,EAAE,EAAE;QACpC,MAAM,cAAc,GAAG,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC;QACtG,MAAM,eAAe,GAAgB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAC7D,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,cAA2B,CAAC,EAAE,CAAC;YAC3D,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,yCAAyC,CAAC,EAAE,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAC7F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,OAAO,GAAwB;YACnC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;YAClC,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;YACjD,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;YAClC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;YAC9B,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;YAC5B,SAAS,EAAE,cAA2B;SACvC,CAAC;QAEF,qCAAqC;QACrC,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACnF,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,2BAA2B,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,CAAC;YACH,iEAAiE;YACjE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACzC,MAAM,uBAAuB,CAAC,SAAS,CAAC,CAAC;YAEzC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACtC,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAEtC,IAAI,cAAc,GAAG,CAAC,CAAC;YACvB,IAAI,WAAW,GAAG,CAAC,CAAC;YAEpB,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;gBAClB,8CAA8C;gBAC9C,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;oBACnB,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;gBAChD,CAAC;gBACD,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;gBACnE,cAAc,IAAI,GAAG,CAAC,SAAS,CAAC;gBAChC,WAAW,IAAI,GAAG,CAAC,MAAM,CAAC;YAC5B,CAAC;iBAAM,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBAC9B,cAAc;gBACd,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS;oBAC7B,CAAC,CAAC,MAAM,qBAAqB,CAAC,SAAS,CAAC;oBACxC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;yBAC5B,MAAM,CAAC,OAAO,CAAC;yBACf,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;gBAEvC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACvB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,iBAAiB,CAAC,CAAC;oBAC/C,OAAO;gBACT,CAAC;gBAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC,MAAM,SAAS,CAAC,CAAC;gBAE/H,IAAI,YAAY,GAAG,CAAC,CAAC;gBACrB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,YAAY,EAAE,CAAC;oBACf,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,YAAY,IAAI,KAAK,CAAC,MAAM,iBAAiB,CAAC,CAAC,CAAC;oBACpF,CAAC;oBACD,yCAAyC;oBACzC,IAAI,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;wBACxC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;wBACzD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;wBAC5D,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;wBACrF,cAAc,IAAI,GAAG,CAAC,SAAS,CAAC;wBAChC,WAAW,IAAI,GAAG,CAAC,MAAM,CAAC;oBAC5B,CAAC;yBAAM,CAAC;wBACN,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;wBAC9D,cAAc,IAAI,GAAG,CAAC,SAAS,CAAC;wBAChC,WAAW,IAAI,GAAG,CAAC,MAAM,CAAC;oBAC5B,CAAC;gBACH,CAAC;gBAED,sBAAsB;gBACtB,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;gBACrD,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,mCAAmC,CAAC,CAAC;gBACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,UAAU;YACV,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACnB,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;gBACjD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,cAAc,yBAAyB,CAAC,CAAC,CAAC;YACrE,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;gBACjD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,cAAc,mBAAmB,CAAC,CAAC,CAAC;gBAC9D,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;oBACpB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,WAAW,SAAS,CAAC,CAAC,CAAC;gBACjD,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACxF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export default function mcpCmd(): Command;
3
+ //# sourceMappingURL=mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,MAAM,CAAC,OAAO,UAAU,MAAM,YAa7B"}
@@ -0,0 +1,19 @@
1
+ import { Command } from 'commander';
2
+ import pc from 'picocolors';
3
+ import { startMcpServer } from '../mcp/server.js';
4
+ export default function mcpCmd() {
5
+ return new Command('mcp')
6
+ .description('Start the Appshot Model Context Protocol (MCP) server')
7
+ .option('--stdio', 'Use stdio transport (default)', true)
8
+ .action(async () => {
9
+ console.error(pc.dim('Starting Appshot MCP server on stdio transport...'));
10
+ try {
11
+ await startMcpServer();
12
+ }
13
+ catch (error) {
14
+ console.error(pc.red('MCP server failed:'), error instanceof Error ? error.message : String(error));
15
+ process.exit(1);
16
+ }
17
+ });
18
+ }
19
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,CAAC,OAAO,UAAU,MAAM;IAC5B,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC;SACtB,WAAW,CAAC,uDAAuD,CAAC;SACpE,MAAM,CAAC,SAAS,EAAE,+BAA+B,EAAE,IAAI,CAAC;SACxD,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC,CAAC;QAC3E,IAAI,CAAC;YACH,MAAM,cAAc,EAAE,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACpG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export default function skillCmd(): Command;
3
+ //# sourceMappingURL=skill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../../src/commands/skill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsCpC,MAAM,CAAC,OAAO,UAAU,QAAQ,YA0F/B"}
@@ -0,0 +1,119 @@
1
+ import { Command } from 'commander';
2
+ import { promises as fs } from 'fs';
3
+ import path from 'path';
4
+ import os from 'os';
5
+ import pc from 'picocolors';
6
+ import { fileURLToPath } from 'url';
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = path.dirname(__filename);
9
+ async function copyDir(src, dest) {
10
+ let count = 0;
11
+ await fs.mkdir(dest, { recursive: true });
12
+ const entries = await fs.readdir(src, { withFileTypes: true });
13
+ for (const entry of entries) {
14
+ const srcPath = path.join(src, entry.name);
15
+ const destPath = path.join(dest, entry.name);
16
+ if (entry.isDirectory()) {
17
+ count += await copyDir(srcPath, destPath);
18
+ }
19
+ else {
20
+ await fs.copyFile(srcPath, destPath);
21
+ count++;
22
+ }
23
+ }
24
+ return count;
25
+ }
26
+ async function fileExists(filePath) {
27
+ try {
28
+ await fs.access(filePath);
29
+ return true;
30
+ }
31
+ catch {
32
+ return false;
33
+ }
34
+ }
35
+ export default function skillCmd() {
36
+ const cmd = new Command('skill')
37
+ .description('Install appshot skill for Claude Code')
38
+ .option('--force', 'overwrite existing skill installation')
39
+ .option('--uninstall', 'remove the skill')
40
+ .option('--path <dir>', 'custom installation path')
41
+ .addHelpText('after', `
42
+ ${pc.bold('Examples:')}
43
+ ${pc.dim('# Install skill to Claude Code')}
44
+ $ appshot skill
45
+
46
+ ${pc.dim('# Reinstall/update skill')}
47
+ $ appshot skill --force
48
+
49
+ ${pc.dim('# Uninstall skill')}
50
+ $ appshot skill --uninstall
51
+
52
+ ${pc.dim('# Install to custom path')}
53
+ $ appshot skill --path ~/my-skills/appshot
54
+
55
+ ${pc.bold('What the skill provides:')}
56
+ • Tool documentation for AI assistants
57
+ • Workflow guidance and best practices
58
+ • Template recommendations by app type
59
+ • Troubleshooting guides
60
+ • Reference files for gradients, fonts, and templates
61
+
62
+ ${pc.bold('Default installation path:')}
63
+ ~/.claude/skills/appshot/`)
64
+ .action(async (opts) => {
65
+ try {
66
+ // Determine paths
67
+ const skillSource = path.resolve(__dirname, '../../skill');
68
+ const defaultDest = path.join(os.homedir(), '.claude', 'skills', 'appshot');
69
+ const skillDest = opts.path ? path.resolve(opts.path) : defaultDest;
70
+ // Check if source exists
71
+ if (!await fileExists(skillSource)) {
72
+ console.error(pc.red('Error:'), 'Skill source not found. This may be a packaging issue.');
73
+ process.exit(1);
74
+ }
75
+ // Handle uninstall
76
+ if (opts.uninstall) {
77
+ if (await fileExists(skillDest)) {
78
+ await fs.rm(skillDest, { recursive: true });
79
+ console.log(pc.green('✓'), `Uninstalled skill from ${pc.cyan(skillDest)}`);
80
+ }
81
+ else {
82
+ console.log(pc.yellow('⚠'), 'Skill not installed at', pc.cyan(skillDest));
83
+ }
84
+ return;
85
+ }
86
+ // Check for existing installation
87
+ if (await fileExists(skillDest) && !opts.force) {
88
+ console.log(pc.yellow('⚠'), 'Skill already installed at', pc.cyan(skillDest));
89
+ console.log(pc.dim(' Use --force to overwrite'));
90
+ return;
91
+ }
92
+ // Remove existing if force
93
+ if (await fileExists(skillDest)) {
94
+ await fs.rm(skillDest, { recursive: true });
95
+ }
96
+ // Ensure parent directory exists
97
+ await fs.mkdir(path.dirname(skillDest), { recursive: true });
98
+ // Copy skill files
99
+ const fileCount = await copyDir(skillSource, skillDest);
100
+ console.log(pc.green('✓'), `Installed appshot skill (${fileCount} files)`);
101
+ console.log(pc.dim(' Location:'), pc.cyan(skillDest));
102
+ console.log();
103
+ console.log(pc.bold('Skill contents:'));
104
+ console.log(pc.dim(' • SKILL.md - Main documentation'));
105
+ console.log(pc.dim(' • references/templates.md - 8 template styles'));
106
+ console.log(pc.dim(' • references/gradients.md - 24 gradient presets'));
107
+ console.log(pc.dim(' • references/fonts.md - 10 font families'));
108
+ console.log(pc.dim(' • references/troubleshooting.md - Common fixes'));
109
+ console.log();
110
+ console.log(pc.green('Claude Code will now use the appshot skill for screenshot tasks.'));
111
+ }
112
+ catch (error) {
113
+ console.error(pc.red('Error:'), error instanceof Error ? error.message : String(error));
114
+ process.exit(1);
115
+ }
116
+ });
117
+ return cmd;
118
+ }
119
+ //# sourceMappingURL=skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.js","sourceRoot":"","sources":["../../src/commands/skill.ts"],"names":[],"mappings":"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"}
@@ -69,6 +69,7 @@ export declare function composeFrameOnly(options: {
69
69
  outputFormat?: 'png' | 'jpeg';
70
70
  jpegQuality?: number;
71
71
  verbose?: boolean;
72
+ frameTone?: 'original' | 'neutral';
72
73
  }): Promise<Buffer>;
73
74
  /**
74
75
  * Get a safe font stack that Sharp's SVG renderer can use
@@ -1 +1 @@
1
- {"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../../src/core/compose.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../../src/core/compose.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,7 @@ import { renderBackground, validateBackgroundDimensions } from './background.js'
6
6
  import { applyRoundedCorners } from './mask-generator.js';
7
7
  import { calculateAdaptiveCaptionHeight, wrapText } from './text-utils.js';
8
8
  import { FontService } from '../services/fonts.js';
9
+ import { resolveLayoutSpacing } from './layout-utils.js';
9
10
  /**
10
11
  * Parse font name to extract style and weight
11
12
  */
@@ -130,16 +131,22 @@ export async function composeAppStoreScreenshot(options) {
130
131
  const frameOffset = deviceConfig.frameOffset !== undefined ? deviceConfig.frameOffset : 25; // Default 25% cut off
131
132
  const framePosition = deviceConfig.framePosition !== undefined ? deviceConfig.framePosition : 'center';
132
133
  const deviceFrameScale = deviceConfig.frameScale;
133
- const boxCfg = deviceConfig.captionBox || captionConfig.box || {};
134
- const marginTop = boxCfg.marginTop || 0;
135
- const marginBottom = boxCfg.marginBottom || 0;
134
+ const { captionTopInsetAbove, deviceTopInsetBelow, bottomInset, gapAbove, gapBelow, overlayBottomSpacing } = resolveLayoutSpacing(captionConfig, deviceConfig);
136
135
  const sideMarginDbg = captionConfig.background?.sideMargin ?? 30;
137
136
  if (verbose) {
138
137
  console.log(pc.dim(' Layout settings:'));
139
138
  console.log(pc.dim(` Caption position: ${captionPosition}`));
140
139
  console.log(pc.dim(` Frame position: ${String(framePosition)}`));
141
140
  console.log(pc.dim(` Frame scale: ${deviceFrameScale ?? '(auto)'}`));
142
- console.log(pc.dim(` Margins: top=${marginTop}px, bottom=${marginBottom}px, side=${sideMarginDbg}px`));
141
+ const insetTop = captionPosition === 'above' ? captionTopInsetAbove : deviceTopInsetBelow;
142
+ console.log(pc.dim(` Insets: top=${insetTop}px, bottom=${bottomInset}px, side=${sideMarginDbg}px`));
143
+ if (captionPosition !== 'overlay') {
144
+ const gap = captionPosition === 'below' ? gapBelow : gapAbove;
145
+ console.log(pc.dim(` Caption gap: ${gap}px`));
146
+ }
147
+ else {
148
+ console.log(pc.dim(` Overlay bottom spacing: ${overlayBottomSpacing}px`));
149
+ }
143
150
  }
144
151
  // Calculate dimensions based on output
145
152
  // Pre-calculate device dimensions for caption height calculation
@@ -299,7 +306,7 @@ export async function composeAppStoreScreenshot(options) {
299
306
  // Get caption box config
300
307
  const captionBoxConfig = deviceConfig.captionBox || captionConfig.box || {};
301
308
  const lineHeight = captionBoxConfig.lineHeight || 1.4;
302
- const topMargin = captionBoxConfig.marginTop || 0;
309
+ const captionTop = captionTopInsetAbove;
303
310
  if (captionLines.length === 0) {
304
311
  // Fallback if no lines were calculated
305
312
  captionLines = [caption];
@@ -335,7 +342,7 @@ export async function composeAppStoreScreenshot(options) {
335
342
  .toBuffer();
336
343
  composites.push({
337
344
  input: captionImage,
338
- top: Math.max(0, topMargin),
345
+ top: Math.max(0, captionTop),
339
346
  left: 0
340
347
  });
341
348
  if (options.onDebug) {
@@ -347,9 +354,9 @@ export async function composeAppStoreScreenshot(options) {
347
354
  deviceTop,
348
355
  deviceBottom: deviceTop + targetDeviceHeight,
349
356
  deviceHeight: targetDeviceHeight,
350
- captionTop: Math.max(0, topMargin),
357
+ captionTop: Math.max(0, captionTop),
351
358
  captionHeight,
352
- marginTop: topMargin,
359
+ marginTop: captionTopInsetAbove,
353
360
  marginBottom: bm
354
361
  });
355
362
  }
@@ -391,18 +398,17 @@ export async function composeAppStoreScreenshot(options) {
391
398
  let availableHeight;
392
399
  // For 'above' positioning, reduce available height by caption
393
400
  // For 'below' positioning, we'll adjust positioning later but calculate scale normally
394
- const boxConfig = deviceConfig.captionBox || captionConfig.box || {};
395
- const topMargin = boxConfig.marginTop || 0;
396
- const bottomMargin = boxConfig.marginBottom || 0;
397
401
  if (captionPosition === 'above') {
398
- availableHeight = Math.max(100, outputHeight - captionHeight - topMargin - bottomMargin);
402
+ const reserved = captionTopInsetAbove + captionHeight + gapAbove + bottomInset;
403
+ availableHeight = Math.max(100, outputHeight - reserved);
399
404
  }
400
405
  else if (captionPosition === 'below') {
401
- availableHeight = Math.max(100, outputHeight - captionHeight - bottomMargin);
406
+ const reserved = deviceTopInsetBelow + captionHeight + gapBelow + bottomInset;
407
+ availableHeight = Math.max(100, outputHeight - reserved);
402
408
  }
403
409
  else {
404
410
  // 'overlay' positioning doesn't reduce available space
405
- availableHeight = outputHeight - bottomMargin;
411
+ availableHeight = Math.max(100, outputHeight - bottomInset);
406
412
  }
407
413
  // Respect explicit frameScale by basing scale on the full output height.
408
414
  // This keeps device size under user control and avoids unexpected shrinking
@@ -584,138 +590,69 @@ export async function composeAppStoreScreenshot(options) {
584
590
  }
585
591
  }
586
592
  // Recalculate position with actual caption height
587
- let availableSpace = 0; // Declare here for wider scope
588
593
  if (captionPosition === 'above') {
589
- // Caption above: position device below caption area
594
+ const captionBottom = captionTopInsetAbove + captionHeight;
595
+ const deviceAreaTop = captionBottom + gapAbove;
596
+ const deviceAreaBottom = canvasHeight - bottomInset;
597
+ const availableTrack = deviceAreaBottom - deviceAreaTop - targetDeviceHeight;
598
+ const clampedTrack = Math.max(0, availableTrack);
590
599
  if (typeof framePosition === 'number') {
591
- // Custom position as percentage from top (0-100)
592
- const boxConfig = deviceConfig.captionBox || captionConfig.box || {};
593
- const topMargin = boxConfig.marginTop || 0;
594
- const bottomMargin = boxConfig.marginBottom || 0;
595
- availableSpace = canvasHeight - topMargin - captionHeight - bottomMargin - targetDeviceHeight;
596
- // Fix for watch: if there's no available space, adjust positioning to work
597
- if (availableSpace < 0 && frameMetadata.deviceType === 'watch') {
598
- // For watch with negative space, position relative to full canvas minus device height
599
- // This allows the watch to overlap with the caption area when needed
600
- const totalAvailable = canvasHeight - bottomMargin - targetDeviceHeight;
601
- if (verbose) {
602
- console.log(pc.dim(' Watch positioning fix applied (overlap mode)'));
603
- console.log(pc.dim(` Original available: ${availableSpace}px`));
604
- console.log(pc.dim(` Using total available: ${totalAvailable}px`));
605
- }
606
- // Position from top of canvas, allowing overlap with caption
607
- deviceTop = Math.floor(totalAvailable * (framePosition / 100));
608
- }
609
- else {
610
- // Normal positioning for other devices or when space is available
611
- deviceTop = topMargin + captionHeight + Math.floor(availableSpace * (framePosition / 100));
612
- if (verbose) {
613
- console.log(pc.dim(' Frame positioning (above mode):'));
614
- console.log(pc.dim(` Canvas height: ${canvasHeight}px`));
615
- console.log(pc.dim(` Caption height: ${captionHeight}px`));
616
- console.log(pc.dim(` Device height: ${targetDeviceHeight}px`));
617
- console.log(pc.dim(` Top margin: ${topMargin}px`));
618
- console.log(pc.dim(` Bottom margin: ${bottomMargin}px`));
619
- console.log(pc.dim(` Available space: ${availableSpace}px`));
620
- console.log(pc.dim(` Frame position %: ${framePosition}`));
621
- console.log(pc.dim(` Calculated deviceTop: ${deviceTop}px`));
622
- }
623
- }
624
- // Debug logging for watch positioning issue
625
- if (verbose && frameMetadata.deviceType === 'watch') {
626
- console.log(pc.dim(' Watch positioning debug:'));
627
- console.log(pc.dim(` Canvas height: ${canvasHeight}px`));
628
- console.log(pc.dim(` Caption height: ${captionHeight}px`));
629
- console.log(pc.dim(` Target device height: ${targetDeviceHeight}px`));
630
- console.log(pc.dim(` Available space: ${availableSpace}px`));
631
- console.log(pc.dim(` Device top: ${deviceTop}px`));
632
- }
600
+ deviceTop = deviceAreaTop + Math.floor(clampedTrack * (framePosition / 100));
633
601
  }
634
602
  else if (framePosition === 'top') {
635
- const boxConfig = deviceConfig.captionBox || captionConfig.box || {};
636
- const topMargin = boxConfig.marginTop || 0;
637
- deviceTop = topMargin + captionHeight;
603
+ deviceTop = deviceAreaTop;
638
604
  }
639
605
  else if (framePosition === 'bottom') {
640
- const boxConfig = deviceConfig.captionBox || captionConfig.box || {};
641
- const bottomMargin = boxConfig.marginBottom || 0;
642
- deviceTop = canvasHeight - bottomMargin - targetDeviceHeight;
606
+ deviceTop = deviceAreaBottom - targetDeviceHeight;
643
607
  }
644
608
  else if (framePosition === 'center') {
645
- // Default centered positioning
646
- const boxConfig = deviceConfig.captionBox || captionConfig.box || {};
647
- const topMargin = boxConfig.marginTop || 0;
648
- const bottomMargin = boxConfig.marginBottom || 0;
649
- const availableSpace2 = canvasHeight - topMargin - captionHeight - bottomMargin;
650
- deviceTop = topMargin + captionHeight + Math.floor((availableSpace2 - targetDeviceHeight) / 2);
609
+ deviceTop = deviceAreaTop + Math.floor(clampedTrack / 2);
651
610
  }
652
611
  else {
653
- const boxConfig = deviceConfig.captionBox || captionConfig.box || {};
654
- const topMargin = boxConfig.marginTop || 0;
655
- deviceTop = topMargin + captionHeight;
612
+ deviceTop = deviceAreaTop;
656
613
  }
657
- // Ensure device doesn't go off canvas
658
- const boxConfig2 = deviceConfig.captionBox || captionConfig.box || {};
659
- const bottomMargin2 = boxConfig2.marginBottom || 0;
660
- // For watch with negative available space, allow overlap with caption
661
- if (frameMetadata.deviceType === 'watch' && typeof framePosition === 'number' && availableSpace < 0) {
662
- // Only clamp to canvas bounds, not caption height
663
- // With partialFrame, allow device to extend beyond canvas by the cropped amount
664
- const bottomAdjustment = partialFrame ? croppedPixels : 0;
665
- deviceTop = Math.floor(Math.max(0, Math.min(deviceTop, canvasHeight - bottomMargin2 - targetDeviceHeight + bottomAdjustment)));
666
- }
667
- else {
668
- // Normal clamping for other devices
669
- const topMargin2 = (deviceConfig.captionBox || captionConfig.box || {}).marginTop || 0;
670
- // With partialFrame, allow device to extend beyond canvas by the cropped amount
671
- const bottomAdjustment = partialFrame ? croppedPixels : 0;
672
- deviceTop = Math.floor(Math.max(topMargin2 + captionHeight, Math.min(deviceTop, canvasHeight - bottomMargin2 - targetDeviceHeight + bottomAdjustment)));
614
+ const bottomAdjustment = partialFrame ? croppedPixels : 0;
615
+ const minDeviceTop = Math.max(0, deviceAreaTop);
616
+ const maxDeviceTop = deviceAreaBottom - targetDeviceHeight + bottomAdjustment;
617
+ deviceTop = Math.floor(Math.max(minDeviceTop, Math.min(deviceTop, maxDeviceTop)));
618
+ if (verbose) {
619
+ console.log(pc.dim(' Frame positioning (above mode):'));
620
+ console.log(pc.dim(` Device area: ${deviceAreaTop}px ${deviceAreaBottom}px`));
621
+ console.log(pc.dim(` Available track: ${availableTrack}px`));
622
+ console.log(pc.dim(` Calculated deviceTop: ${deviceTop}px`));
673
623
  }
674
624
  }
675
625
  else if (captionPosition === 'below') {
676
- // Caption below: position device in upper area, leaving space for caption at bottom
677
- const captionBoxConfig = deviceConfig.captionBox || captionConfig.box || {};
678
- // Apply a sensible default gap when marginTop is undefined to meet user expectations
679
- // of a small clearance between device and caption. If marginTop is explicitly set,
680
- // it wins. Otherwise we default to max(12px, half border width).
681
- const borderWidthForGap = (deviceConfig.captionBorder || captionConfig.border)?.width || 0;
682
- const defaultBelowGap = Math.max(12, Math.round(borderWidthForGap / 2));
683
- const marginTop = (captionBoxConfig.marginTop !== undefined)
684
- ? captionBoxConfig.marginTop
685
- : defaultBelowGap;
686
- const marginBottom = captionBoxConfig.marginBottom || 0;
687
- // Calculate ideal positions
688
- // Device area is everything except caption, marginTop gap, and marginBottom
689
- const deviceAreaHeight = canvasHeight - captionHeight - marginTop - marginBottom;
690
- const spaceWithMargins = deviceAreaHeight - targetDeviceHeight;
691
- const maxOverlapSlack = (canvasHeight - captionHeight) - targetDeviceHeight;
692
- const effectiveAvailableSpace = spaceWithMargins >= 0
693
- ? spaceWithMargins
694
- : Math.max(0, maxOverlapSlack);
626
+ const captionAnchorTop = canvasHeight - bottomInset - captionHeight;
627
+ const deviceAreaTop = deviceTopInsetBelow;
628
+ const deviceAreaBottom = Math.max(deviceAreaTop, captionAnchorTop - gapBelow);
629
+ const availableTrack = deviceAreaBottom - deviceAreaTop - targetDeviceHeight;
630
+ const clampedTrack = Math.max(0, availableTrack);
695
631
  if (typeof framePosition === 'number') {
696
- // Custom position as percentage within device area
697
- deviceTop = Math.floor(effectiveAvailableSpace * (framePosition / 100));
632
+ deviceTop = deviceAreaTop + Math.floor(clampedTrack * (framePosition / 100));
698
633
  }
699
634
  else if (framePosition === 'top') {
700
- deviceTop = 0;
635
+ deviceTop = deviceAreaTop;
701
636
  }
702
637
  else if (framePosition === 'bottom') {
703
- deviceTop = effectiveAvailableSpace;
638
+ deviceTop = deviceAreaBottom - targetDeviceHeight;
704
639
  }
705
640
  else if (framePosition === 'center') {
706
- // Default centered positioning in device area
707
- deviceTop = Math.floor(effectiveAvailableSpace / 2);
641
+ deviceTop = deviceAreaTop + Math.floor(clampedTrack / 2);
708
642
  }
709
643
  else {
710
- // Default to centered in device area
711
- deviceTop = Math.floor(effectiveAvailableSpace / 2);
644
+ deviceTop = deviceAreaTop;
712
645
  }
713
- // Ensure device doesn't go off canvas
714
- // With partialFrame, allow device to extend beyond canvas by the cropped amount
715
646
  const bottomAdjustmentBelow = partialFrame ? croppedPixels : 0;
716
- // Clamp device position to available space (allowing overlap slack when needed)
717
- const maxDeviceTop = effectiveAvailableSpace + bottomAdjustmentBelow;
718
- deviceTop = Math.floor(Math.max(0, Math.min(deviceTop, maxDeviceTop)));
647
+ const minDeviceTop = deviceAreaTop;
648
+ const maxDeviceTop = deviceAreaBottom - targetDeviceHeight + bottomAdjustmentBelow;
649
+ deviceTop = Math.floor(Math.max(minDeviceTop, Math.min(deviceTop, maxDeviceTop)));
650
+ if (verbose) {
651
+ console.log(pc.dim(' Frame positioning (below mode):'));
652
+ console.log(pc.dim(` Device area: ${deviceAreaTop}px → ${deviceAreaBottom}px`));
653
+ console.log(pc.dim(` Gap below: ${gapBelow}px`));
654
+ console.log(pc.dim(` Calculated deviceTop: ${deviceTop}px`));
655
+ }
719
656
  }
720
657
  else {
721
658
  // 'overlay' positioning: position device using the full canvas height.
@@ -723,7 +660,7 @@ export async function composeAppStoreScreenshot(options) {
723
660
  // top margin should not influence device placement. Respect explicit
724
661
  // bottom spacing only.
725
662
  const marginTop = 0; // ignore top margin for overlay
726
- const marginBottom = (deviceConfig.captionBox || captionConfig.box || {}).marginBottom || 0;
663
+ const marginBottom = overlayBottomSpacing;
727
664
  if (typeof framePosition === 'number') {
728
665
  // Custom position as percentage within available space (accounting for margins)
729
666
  const availableSpace = canvasHeight - marginTop - marginBottom - targetDeviceHeight;
@@ -782,16 +719,16 @@ export async function composeAppStoreScreenshot(options) {
782
719
  let availableHeight;
783
720
  let deviceTop;
784
721
  if (captionPosition === 'above') {
785
- availableHeight = outputHeight - captionHeight;
786
- deviceTop = Math.floor(captionHeight);
722
+ availableHeight = outputHeight - captionTopInsetAbove - captionHeight - gapAbove - bottomInset;
723
+ deviceTop = captionTopInsetAbove + captionHeight + gapAbove;
787
724
  }
788
725
  else if (captionPosition === 'below') {
789
- availableHeight = outputHeight - captionHeight;
790
- deviceTop = 0; // Start from top when caption is below
726
+ availableHeight = outputHeight - deviceTopInsetBelow - captionHeight - gapBelow - bottomInset;
727
+ deviceTop = deviceTopInsetBelow;
791
728
  }
792
729
  else {
793
730
  // 'overlay' positioning
794
- availableHeight = outputHeight;
731
+ availableHeight = outputHeight - bottomInset;
795
732
  deviceTop = 0;
796
733
  }
797
734
  // Calculate scale to fit within available space while maintaining aspect ratio
@@ -812,7 +749,9 @@ export async function composeAppStoreScreenshot(options) {
812
749
  }
813
750
  // For 'below' positioning, center the screenshot in the available device area
814
751
  if (captionPosition === 'below') {
815
- deviceTop = Math.floor((availableHeight - targetHeight) / 2);
752
+ const deviceAreaBottom = (outputHeight - bottomInset - captionHeight) - gapBelow;
753
+ const track = Math.max(0, deviceAreaBottom - deviceTop - targetHeight);
754
+ deviceTop = deviceTop + Math.floor(track / 2);
816
755
  }
817
756
  // Center the screenshot horizontally
818
757
  const deviceLeft = Math.floor((canvasWidth - targetWidth) / 2);
@@ -834,12 +773,8 @@ export async function composeAppStoreScreenshot(options) {
834
773
  // Get caption box config
835
774
  const captionBoxConfig = deviceConfig.captionBox || captionConfig.box || {};
836
775
  const lineHeight = captionBoxConfig.lineHeight || 1.4;
837
- const borderWidthForGap = (deviceConfig.captionBorder || captionConfig.border)?.width || 0;
838
- const defaultBelowGap = Math.max(12, Math.round(borderWidthForGap / 2));
839
- const marginTop = (captionBoxConfig.marginTop !== undefined)
840
- ? captionBoxConfig.marginTop
841
- : defaultBelowGap;
842
- const bottomMargin = captionBoxConfig.marginBottom || 0;
776
+ const marginTop = gapBelow;
777
+ const marginBottom = bottomInset;
843
778
  if (captionLines.length === 0) {
844
779
  // Fallback if no lines were calculated
845
780
  captionLines = [caption];
@@ -870,7 +805,7 @@ export async function composeAppStoreScreenshot(options) {
870
805
  // bottom under normal conditions, and moves down only if the device
871
806
  // intrudes into the reserved area.
872
807
  const deviceBottom = deviceTop + targetDeviceHeight; // includes watch bands
873
- const bottomAnchorTop = canvasHeight - captionHeight - bottomMargin;
808
+ const bottomAnchorTop = canvasHeight - marginBottom - captionHeight;
874
809
  const justBelowDeviceTop = deviceBottom + marginTop;
875
810
  const captionTop = Math.max(bottomAnchorTop, justBelowDeviceTop);
876
811
  composites.push({
@@ -934,8 +869,7 @@ export async function composeAppStoreScreenshot(options) {
934
869
  }
935
870
  // Position overlay text at bottom of canvas for overlay mode
936
871
  // Use marginBottom from captionBox if available, otherwise use paddingBottom
937
- const captionBoxConfig2 = deviceConfig.captionBox || captionConfig.box || {};
938
- const marginBottom = captionBoxConfig2.marginBottom;
872
+ const bottomSpacing = overlayBottomSpacing;
939
873
  const totalTextHeight = overlayLines.length * fontSize * lineHeight;
940
874
  // Use device-specific font if available, otherwise use global caption font
941
875
  const fontToUse = deviceConfig.captionFont || captionConfig.font;
@@ -953,7 +887,6 @@ export async function composeAppStoreScreenshot(options) {
953
887
  // Anchor overlay by the OUTER BOX bottom (including padding and border stroke)
954
888
  const bgPadding = backgroundConfig?.padding ?? 20;
955
889
  const strokeWidth = borderConfig?.width ?? 0; // stroke is centered on rect; half extends outward
956
- const bottomSpacing = (marginBottom ?? captionConfig.paddingBottom ?? 60); // respect explicit 0
957
890
  const boxHeight = totalTextHeight + (bgPadding * 2);
958
891
  const rectBottom = canvasHeight - bottomSpacing - (strokeWidth > 0 ? strokeWidth / 2 : 0);
959
892
  const rectY = rectBottom - boxHeight; // top of the fill/border rects
@@ -1063,10 +996,22 @@ export async function composeAppStoreScreenshot(options) {
1063
996
  * No gradient or captions are applied; output is frame-sized.
1064
997
  */
1065
998
  export async function composeFrameOnly(options) {
1066
- const { screenshot, frame, frameMetadata, outputFormat = 'png', jpegQuality = 92, verbose = false } = options;
999
+ const { screenshot, frame, frameMetadata, outputFormat = 'png', jpegQuality = 92, verbose = false, frameTone = 'original' } = options;
1067
1000
  if (!frame || !frameMetadata) {
1068
1001
  throw new Error('composeFrameOnly requires a frame buffer and frame metadata');
1069
1002
  }
1003
+ let frameBuffer = frame;
1004
+ if (frameTone === 'neutral') {
1005
+ try {
1006
+ frameBuffer = await sharp(frame).modulate({ saturation: 0 }).toBuffer();
1007
+ if (verbose) {
1008
+ console.log(pc.dim(' Frame tone: neutral/desaturated'));
1009
+ }
1010
+ }
1011
+ catch (err) {
1012
+ console.warn(pc.yellow('Warning:'), pc.dim(`Failed to apply neutral frame tone: ${err instanceof Error ? err.message : String(err)}`));
1013
+ }
1014
+ }
1070
1015
  const { frameWidth, frameHeight, screenRect } = frameMetadata;
1071
1016
  if (verbose) {
1072
1017
  console.log(pc.dim('Framing with transparent background:'));
@@ -1128,7 +1073,7 @@ export async function composeFrameOnly(options) {
1128
1073
  // Composite screenshot at screen coordinates, then overlay frame image
1129
1074
  let composed = base.composite([
1130
1075
  { input: resizedScreenshot, top: screenRect.y, left: screenRect.x },
1131
- { input: frame, top: 0, left: 0 }
1076
+ { input: frameBuffer, top: 0, left: 0 }
1132
1077
  ]);
1133
1078
  if (outputFormat === 'png') {
1134
1079
  return composed.png().toBuffer();