@specific.dev/cli 0.1.175 → 0.1.177

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 (100) hide show
  1. package/dist/admin/404/index.html +1 -1
  2. package/dist/admin/404.html +1 -1
  3. package/dist/admin/__next.!KGRlZmF1bHQp.__PAGE__.txt +2 -2
  4. package/dist/admin/__next.!KGRlZmF1bHQp.txt +1 -1
  5. package/dist/admin/__next._full.txt +3 -3
  6. package/dist/admin/__next._head.txt +1 -1
  7. package/dist/admin/__next._index.txt +2 -2
  8. package/dist/admin/__next._tree.txt +2 -2
  9. package/dist/admin/_next/static/chunks/{411d73f9ad4901a2.js → 076d0b19f149e961.js} +2 -2
  10. package/dist/admin/_next/static/chunks/{f11bf31415d76903.css → 25ac6c65cd7c74e2.css} +1 -1
  11. package/dist/admin/_not-found/__next._full.txt +2 -2
  12. package/dist/admin/_not-found/__next._head.txt +1 -1
  13. package/dist/admin/_not-found/__next._index.txt +2 -2
  14. package/dist/admin/_not-found/__next._not-found.__PAGE__.txt +1 -1
  15. package/dist/admin/_not-found/__next._not-found.txt +1 -1
  16. package/dist/admin/_not-found/__next._tree.txt +2 -2
  17. package/dist/admin/_not-found/index.html +1 -1
  18. package/dist/admin/_not-found/index.txt +2 -2
  19. package/dist/admin/crons/__next.!KGRlZmF1bHQp.crons.__PAGE__.txt +2 -2
  20. package/dist/admin/crons/__next.!KGRlZmF1bHQp.crons.txt +1 -1
  21. package/dist/admin/crons/__next.!KGRlZmF1bHQp.txt +1 -1
  22. package/dist/admin/crons/__next._full.txt +3 -3
  23. package/dist/admin/crons/__next._head.txt +1 -1
  24. package/dist/admin/crons/__next._index.txt +2 -2
  25. package/dist/admin/crons/__next._tree.txt +2 -2
  26. package/dist/admin/crons/index.html +1 -1
  27. package/dist/admin/crons/index.txt +3 -3
  28. package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.__PAGE__.txt +1 -1
  29. package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.txt +1 -1
  30. package/dist/admin/databases/__next.!KGRlZmF1bHQp.txt +1 -1
  31. package/dist/admin/databases/__next._full.txt +2 -2
  32. package/dist/admin/databases/__next._head.txt +1 -1
  33. package/dist/admin/databases/__next._index.txt +2 -2
  34. package/dist/admin/databases/__next._tree.txt +2 -2
  35. package/dist/admin/databases/index.html +1 -1
  36. package/dist/admin/databases/index.txt +2 -2
  37. package/dist/admin/fullscreen/__next._full.txt +3 -3
  38. package/dist/admin/fullscreen/__next._head.txt +1 -1
  39. package/dist/admin/fullscreen/__next._index.txt +2 -2
  40. package/dist/admin/fullscreen/__next._tree.txt +2 -2
  41. package/dist/admin/fullscreen/__next.fullscreen.__PAGE__.txt +2 -2
  42. package/dist/admin/fullscreen/__next.fullscreen.txt +1 -1
  43. package/dist/admin/fullscreen/databases/__next._full.txt +2 -2
  44. package/dist/admin/fullscreen/databases/__next._head.txt +1 -1
  45. package/dist/admin/fullscreen/databases/__next._index.txt +2 -2
  46. package/dist/admin/fullscreen/databases/__next._tree.txt +2 -2
  47. package/dist/admin/fullscreen/databases/__next.fullscreen.databases.__PAGE__.txt +1 -1
  48. package/dist/admin/fullscreen/databases/__next.fullscreen.databases.txt +1 -1
  49. package/dist/admin/fullscreen/databases/__next.fullscreen.txt +1 -1
  50. package/dist/admin/fullscreen/databases/index.html +1 -1
  51. package/dist/admin/fullscreen/databases/index.txt +2 -2
  52. package/dist/admin/fullscreen/index.html +1 -1
  53. package/dist/admin/fullscreen/index.txt +3 -3
  54. package/dist/admin/index.html +1 -1
  55. package/dist/admin/index.txt +3 -3
  56. package/dist/admin/mail/__next.!KGRlZmF1bHQp.mail.__PAGE__.txt +1 -1
  57. package/dist/admin/mail/__next.!KGRlZmF1bHQp.mail.txt +1 -1
  58. package/dist/admin/mail/__next.!KGRlZmF1bHQp.txt +1 -1
  59. package/dist/admin/mail/__next._full.txt +2 -2
  60. package/dist/admin/mail/__next._head.txt +1 -1
  61. package/dist/admin/mail/__next._index.txt +2 -2
  62. package/dist/admin/mail/__next._tree.txt +2 -2
  63. package/dist/admin/mail/index.html +1 -1
  64. package/dist/admin/mail/index.txt +2 -2
  65. package/dist/admin/services/__next.!KGRlZmF1bHQp.services.__PAGE__.txt +1 -1
  66. package/dist/admin/services/__next.!KGRlZmF1bHQp.services.txt +1 -1
  67. package/dist/admin/services/__next.!KGRlZmF1bHQp.txt +1 -1
  68. package/dist/admin/services/__next._full.txt +2 -2
  69. package/dist/admin/services/__next._head.txt +1 -1
  70. package/dist/admin/services/__next._index.txt +2 -2
  71. package/dist/admin/services/__next._tree.txt +2 -2
  72. package/dist/admin/services/index.html +1 -1
  73. package/dist/admin/services/index.txt +2 -2
  74. package/dist/admin/storage/__next.!KGRlZmF1bHQp.storage.__PAGE__.txt +1 -1
  75. package/dist/admin/storage/__next.!KGRlZmF1bHQp.storage.txt +1 -1
  76. package/dist/admin/storage/__next.!KGRlZmF1bHQp.txt +1 -1
  77. package/dist/admin/storage/__next._full.txt +2 -2
  78. package/dist/admin/storage/__next._head.txt +1 -1
  79. package/dist/admin/storage/__next._index.txt +2 -2
  80. package/dist/admin/storage/__next._tree.txt +2 -2
  81. package/dist/admin/storage/index.html +1 -1
  82. package/dist/admin/storage/index.txt +2 -2
  83. package/dist/admin/workflows/__next.!KGRlZmF1bHQp.txt +1 -1
  84. package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.__PAGE__.txt +1 -1
  85. package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.txt +1 -1
  86. package/dist/admin/workflows/__next._full.txt +2 -2
  87. package/dist/admin/workflows/__next._head.txt +1 -1
  88. package/dist/admin/workflows/__next._index.txt +2 -2
  89. package/dist/admin/workflows/__next._tree.txt +2 -2
  90. package/dist/admin/workflows/index.html +1 -1
  91. package/dist/admin/workflows/index.txt +2 -2
  92. package/dist/cli.js +30 -7
  93. package/dist/docs/index.md +1 -0
  94. package/dist/docs/previews.md +34 -0
  95. package/dist/docs/services.md +2 -0
  96. package/dist/docs/volumes.md +6 -0
  97. package/package.json +1 -1
  98. /package/dist/admin/_next/static/{4p_gKX-ebPN5Vy0IhSe2O → Fo_inRBskzCROMa2zWxU5}/_buildManifest.js +0 -0
  99. /package/dist/admin/_next/static/{4p_gKX-ebPN5Vy0IhSe2O → Fo_inRBskzCROMa2zWxU5}/_clientMiddlewareManifest.json +0 -0
  100. /package/dist/admin/_next/static/{4p_gKX-ebPN5Vy0IhSe2O → Fo_inRBskzCROMa2zWxU5}/_ssgManifest.js +0 -0
@@ -14,11 +14,11 @@ f:"$Sreact.suspense"
14
14
  11:I[15478,["/_next/static/chunks/b2b4aada246f4749.js","/_next/static/chunks/7c2bbd09e9922443.js"],"ViewportBoundary"]
15
15
  13:I[15478,["/_next/static/chunks/b2b4aada246f4749.js","/_next/static/chunks/7c2bbd09e9922443.js"],"MetadataBoundary"]
16
16
  15:I[47541,[],"default"]
17
- :HL["/_next/static/chunks/f11bf31415d76903.css","style"]
17
+ :HL["/_next/static/chunks/25ac6c65cd7c74e2.css","style"]
18
18
  :HL["/_next/static/media/797e433ab948586e-s.p.29207c2f.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
19
19
  :HL["/_next/static/media/83afe278b6a6bb3c-s.p.3a6ba036.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
20
20
  :HL["/_next/static/media/caa3a2e1cccd8315-s.p.3b6cae6d.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
21
- 0:{"P":null,"b":"4p_gKX-ebPN5Vy0IhSe2O","c":["","workflows",""],"q":"","i":false,"f":[[["",{"children":["(default)",{"children":["workflows",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/f11bf31415d76903.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/_next/static/chunks/c52b2ebc474a0535.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","className":"inter_b2991b2-module__9mH_6q__variable","suppressHydrationWarning":true,"children":["$","body",null,{"className":"geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased","children":["$","$L2",null,{"attribute":"class","defaultTheme":"system","enableSystem":true,"disableTransitionOnChange":true,"children":["$","$L3",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]}]}]]}],{"children":[["$","$1","c",{"children":[[["$","script","script-0",{"src":"/_next/static/chunks/21d31e8f6bca9c4d.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/_next/static/chunks/b44581875c51fcd8.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/_next/static/chunks/65e3cacf9bc29c63.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/_next/static/chunks/dc5c264e3262a84a.js","async":true,"nonce":"$undefined"}]],["$","$L6",null,{"children":[["$","$L7",null,{}],["$","$L8",null,{"className":"overflow-hidden","children":["$","$L9",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:style","children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:1:props:style","children":404}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:style","children":["$","h2",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style","children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]]}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","$La",null,{"Component":"$b","serverProvidedParams":{"searchParams":{},"params":{},"promises":["$@c","$@d"]}}],[["$","script","script-0",{"src":"/_next/static/chunks/e3baf0c708c5b9ae.js","async":true,"nonce":"$undefined"}]],["$","$Le",null,{"children":["$","$f",null,{"name":"Next.MetadataOutlet","children":"$@10"}]}]]}],{},null,false,false]},null,false,false]},null,false,false]},null,false,false],["$","$1","h",{"children":[null,["$","$L11",null,{"children":"$L12"}],["$","div",null,{"hidden":true,"children":["$","$L13",null,{"children":["$","$f",null,{"name":"Next.Metadata","children":"$L14"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$15",[]],"S":true}
21
+ 0:{"P":null,"b":"Fo_inRBskzCROMa2zWxU5","c":["","workflows",""],"q":"","i":false,"f":[[["",{"children":["(default)",{"children":["workflows",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/25ac6c65cd7c74e2.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/_next/static/chunks/c52b2ebc474a0535.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","className":"inter_b2991b2-module__9mH_6q__variable","suppressHydrationWarning":true,"children":["$","body",null,{"className":"geist_a71539c9-module__T19VSG__variable geist_mono_8d43a2aa-module__8Li5zG__variable antialiased","children":["$","$L2",null,{"attribute":"class","defaultTheme":"system","enableSystem":true,"disableTransitionOnChange":true,"children":["$","$L3",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]}]}]]}],{"children":[["$","$1","c",{"children":[[["$","script","script-0",{"src":"/_next/static/chunks/21d31e8f6bca9c4d.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/_next/static/chunks/b44581875c51fcd8.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/_next/static/chunks/65e3cacf9bc29c63.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/_next/static/chunks/dc5c264e3262a84a.js","async":true,"nonce":"$undefined"}]],["$","$L6",null,{"children":[["$","$L7",null,{}],["$","$L8",null,{"className":"overflow-hidden","children":["$","$L9",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:style","children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:1:props:style","children":404}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:style","children":["$","h2",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style","children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]]}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","$La",null,{"Component":"$b","serverProvidedParams":{"searchParams":{},"params":{},"promises":["$@c","$@d"]}}],[["$","script","script-0",{"src":"/_next/static/chunks/e3baf0c708c5b9ae.js","async":true,"nonce":"$undefined"}]],["$","$Le",null,{"children":["$","$f",null,{"name":"Next.MetadataOutlet","children":"$@10"}]}]]}],{},null,false,false]},null,false,false]},null,false,false]},null,false,false],["$","$1","h",{"children":[null,["$","$L11",null,{"children":"$L12"}],["$","div",null,{"hidden":true,"children":["$","$L13",null,{"children":["$","$f",null,{"name":"Next.Metadata","children":"$L14"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$15",[]],"S":true}
22
22
  c:{}
23
23
  d:"$0:f:0:1:1:children:1:children:1:children:0:props:children:0:props:serverProvidedParams:params"
24
24
  12:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
package/dist/cli.js CHANGED
@@ -368588,8 +368588,19 @@ function parseVolumes(fieldObj) {
368588
368588
  return volumes;
368589
368589
  }
368590
368590
  if (!Array.isArray(volumeData)) {
368591
- for (const [name] of Object.entries(volumeData)) {
368592
- volumes.push({ name });
368591
+ for (const [name, fieldsArray] of Object.entries(volumeData)) {
368592
+ const volume = { name };
368593
+ const fields = Array.isArray(fieldsArray) ? fieldsArray[0] : fieldsArray;
368594
+ if (fields && typeof fields === "object" && !Array.isArray(fields)) {
368595
+ const resetCommand = fields.reset_command;
368596
+ if (resetCommand !== void 0) {
368597
+ if (typeof resetCommand !== "string" || resetCommand.trim() === "") {
368598
+ throw new Error(`Volume "${name}" has an invalid "reset_command" value. Must be a non-empty string.`);
368599
+ }
368600
+ volume.reset_command = resetCommand;
368601
+ }
368602
+ }
368603
+ volumes.push(volume);
368593
368604
  }
368594
368605
  }
368595
368606
  return volumes;
@@ -374729,7 +374740,7 @@ function trackEvent(event, properties) {
374729
374740
  event,
374730
374741
  properties: {
374731
374742
  ...properties,
374732
- cli_version: "0.1.175",
374743
+ cli_version: "0.1.177",
374733
374744
  platform: process.platform,
374734
374745
  node_version: process.version,
374735
374746
  project_id: getProjectId()
@@ -375591,8 +375602,19 @@ function parseVolumes2(fieldObj) {
375591
375602
  return volumes;
375592
375603
  }
375593
375604
  if (!Array.isArray(volumeData)) {
375594
- for (const [name] of Object.entries(volumeData)) {
375595
- volumes.push({ name });
375605
+ for (const [name, fieldsArray] of Object.entries(volumeData)) {
375606
+ const volume = { name };
375607
+ const fields = Array.isArray(fieldsArray) ? fieldsArray[0] : fieldsArray;
375608
+ if (fields && typeof fields === "object" && !Array.isArray(fields)) {
375609
+ const resetCommand = fields.reset_command;
375610
+ if (resetCommand !== void 0) {
375611
+ if (typeof resetCommand !== "string" || resetCommand.trim() === "") {
375612
+ throw new Error(`Volume "${name}" has an invalid "reset_command" value. Must be a non-empty string.`);
375613
+ }
375614
+ volume.reset_command = resetCommand;
375615
+ }
375616
+ }
375617
+ volumes.push(volume);
375596
375618
  }
375597
375619
  }
375598
375620
  return volumes;
@@ -376898,6 +376920,7 @@ function formatErrorCode(code) {
376898
376920
  deploy_failed: "Service failed to deploy",
376899
376921
  health_check_failed: "Health check failed",
376900
376922
  post_deploy_failed: "Post-deploy hook failed",
376923
+ volume_reset_failed: "Volume reset failed",
376901
376924
  internal_error: "Internal error"
376902
376925
  };
376903
376926
  return labels[code] || code;
@@ -379092,7 +379115,7 @@ function compareVersions(a, b) {
379092
379115
  return 0;
379093
379116
  }
379094
379117
  async function checkForUpdate() {
379095
- const currentVersion = "0.1.175";
379118
+ const currentVersion = "0.1.177";
379096
379119
  const response = await fetch(`${BINARIES_BASE_URL}/latest?t=${Date.now()}`);
379097
379120
  if (!response.ok) {
379098
379121
  throw new Error(`Failed to check for updates: HTTP ${response.status}`);
@@ -379772,7 +379795,7 @@ async function domainAddCommand(service, domain, options2) {
379772
379795
  var program = new Command();
379773
379796
  var env = "production";
379774
379797
  var envLabel = env !== "production" ? `[${env.toUpperCase()}] ` : "";
379775
- program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.175").enablePositionalOptions();
379798
+ program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.177").enablePositionalOptions();
379776
379799
  program.command("init").description("Initialize project for use with a coding agent").option("--agent <name...>", "Agents to configure (cursor, claude, codex, other)").addHelpText("after", `
379777
379800
  Examples:
379778
379801
  $ specific init
@@ -28,6 +28,7 @@ After deploying, the user can manage their project from the Specific Dashboard a
28
28
  - [Volumes](/volumes): define persistent storage volumes for services to store files in.
29
29
  - [Temporal](/temporal): managed durable workflow engine for background tasks, AI agents and more.
30
30
  - [Observability](/observability): query logs and metrics from running environments using `specific query` for debugging and analytics.
31
+ - [Preview environments](/previews): ephemeral copies of an environment created per pull request, with the parent's databases branched, object storage forked, and volumes cloned.
31
32
  <!-- beta:mail -->
32
33
  - [Mail](/mail): managed email sending via SMTP for transactional emails.
33
34
  <!-- /beta:mail -->
@@ -0,0 +1,34 @@
1
+ # Preview Environments
2
+
3
+ A preview environment is a temporary, fully isolated copy of an existing environment. It runs the same services with their own URLs and their own network namespace, on top of its own copy of the parent's stateful data — so a change can be tested end to end without touching the parent.
4
+
5
+ ## How previews are created
6
+
7
+ - **Per pull request** — with the GitHub integration connected, Specific creates a preview environment for each open pull request, keeps it up to date as new commits are pushed, and posts its URL back on the PR.
8
+ - **Manually** — previews can also be created on demand.
9
+
10
+ Preview environments are ephemeral: pull-request previews are removed when the PR is closed or merged, and a preview can be given an expiry, after which Specific cleans it up automatically.
11
+
12
+ Run `specific status` to list every environment and its `env_…` ID, including preview environments. Target a preview with `--environment` on commands that take one (see `specific docs observability`).
13
+
14
+ ## What's copied from the parent
15
+
16
+ A preview branches off a parent environment and starts from its data. Each resource is forked in the way that's fastest for that service:
17
+
18
+ - **Postgres** databases are branched (an instant, copy-on-write branch).
19
+ - **Object storage** buckets are forked.
20
+ - **Volumes** are cloned — a byte-for-byte copy of the parent volume's contents.
21
+
22
+ The preview gets its own isolated database, buckets, and volumes; writing to them never affects the parent.
23
+
24
+ ## Volumes in previews
25
+
26
+ Because a volume is copied byte for byte, a preview's service starts on an exact replica of the parent's on-disk data — uploads, caches, database files, and search indexes alike. This needs no extra configuration: the service boots on the cloned data exactly as it would after a restart, and writes to the preview's copy never affect the parent.
27
+
28
+ ---
29
+
30
+ Related topics:
31
+
32
+ - Run `specific docs volumes` for declaring persistent volumes
33
+ - Run `specific docs services` for service configuration
34
+ - Run `specific docs observability` for querying a preview's logs and metrics
@@ -560,3 +560,5 @@ Related topics:
560
560
  - Run `specific docs crons` for scheduled jobs (a service that runs on a schedule)
561
561
  - Run `specific docs exec` for running one-off commands during development
562
562
  - Run `specific docs postgres` for database configuration
563
+ - Run `specific docs volumes` for persistent storage volumes
564
+ - Run `specific docs previews` for preview environments
@@ -61,3 +61,9 @@ fs.writeFileSync(path.join(uploadsDir, "myfile.txt"), "Hello, world!");
61
61
  // Read it back (persists across restarts)
62
62
  const content = fs.readFileSync(path.join(uploadsDir, "myfile.txt"), "utf8");
63
63
  ```
64
+
65
+ ## Preview environments
66
+
67
+ Preview environments clone each volume's contents byte for byte from the parent environment, so a preview's service starts on an exact copy of the parent's data with no extra configuration.
68
+
69
+ See `specific docs previews` for how preview environments work.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@specific.dev/cli",
3
- "version": "0.1.175",
3
+ "version": "0.1.177",
4
4
  "description": "CLI for Specific infrastructure-as-code",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",