duclaw-cli 1.7.2 → 1.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle.js +1292 -380
- package/dist/main.js +1 -1
- package/dist/web/assets/index-C2IdC4IZ.css +1 -0
- package/dist/web/assets/index-U7WfpOzC.js +59 -0
- package/dist/web/favicon.svg +1 -0
- package/dist/web/icons.svg +24 -0
- package/dist/web/index.html +14 -0
- package/package.json +27 -4
- package/skills/duclaw-saas-release/SKILL.md +161 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="46" fill="none" viewBox="0 0 48 46"><path fill="#863bff" d="M25.946 44.938c-.664.845-2.021.375-2.021-.698V33.937a2.26 2.26 0 0 0-2.262-2.262H10.287c-.92 0-1.456-1.04-.92-1.788l7.48-10.471c1.07-1.497 0-3.578-1.842-3.578H1.237c-.92 0-1.456-1.04-.92-1.788L10.013.474c.214-.297.556-.474.92-.474h28.894c.92 0 1.456 1.04.92 1.788l-7.48 10.471c-1.07 1.498 0 3.579 1.842 3.579h11.377c.943 0 1.473 1.088.89 1.83L25.947 44.94z" style="fill:#863bff;fill:color(display-p3 .5252 .23 1);fill-opacity:1"/><mask id="a" width="48" height="46" x="0" y="0" maskUnits="userSpaceOnUse" style="mask-type:alpha"><path fill="#000" d="M25.842 44.938c-.664.844-2.021.375-2.021-.698V33.937a2.26 2.26 0 0 0-2.262-2.262H10.183c-.92 0-1.456-1.04-.92-1.788l7.48-10.471c1.07-1.498 0-3.579-1.842-3.579H1.133c-.92 0-1.456-1.04-.92-1.787L9.91.473c.214-.297.556-.474.92-.474h28.894c.92 0 1.456 1.04.92 1.788l-7.48 10.471c-1.07 1.498 0 3.578 1.842 3.578h11.377c.943 0 1.473 1.088.89 1.832L25.843 44.94z" style="fill:#000;fill-opacity:1"/></mask><g mask="url(#a)"><g filter="url(#b)"><ellipse cx="5.508" cy="14.704" fill="#ede6ff" rx="5.508" ry="14.704" style="fill:#ede6ff;fill:color(display-p3 .9275 .9033 1);fill-opacity:1" transform="matrix(.00324 1 1 -.00324 -4.47 31.516)"/></g><g filter="url(#c)"><ellipse cx="10.399" cy="29.851" fill="#ede6ff" rx="10.399" ry="29.851" style="fill:#ede6ff;fill:color(display-p3 .9275 .9033 1);fill-opacity:1" transform="matrix(.00324 1 1 -.00324 -39.328 7.883)"/></g><g filter="url(#d)"><ellipse cx="5.508" cy="30.487" fill="#7e14ff" rx="5.508" ry="30.487" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.814 -25.913 -14.639)scale(1 -1)"/></g><g filter="url(#e)"><ellipse cx="5.508" cy="30.599" fill="#7e14ff" rx="5.508" ry="30.599" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.814 -32.644 -3.334)scale(1 -1)"/></g><g filter="url(#f)"><ellipse cx="5.508" cy="30.599" fill="#7e14ff" rx="5.508" ry="30.599" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="matrix(.00324 1 1 -.00324 -34.34 30.47)"/></g><g filter="url(#g)"><ellipse cx="14.072" cy="22.078" fill="#ede6ff" rx="14.072" ry="22.078" style="fill:#ede6ff;fill:color(display-p3 .9275 .9033 1);fill-opacity:1" transform="rotate(93.35 24.506 48.493)scale(-1 1)"/></g><g filter="url(#h)"><ellipse cx="3.47" cy="21.501" fill="#7e14ff" rx="3.47" ry="21.501" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.009 28.708 47.59)scale(-1 1)"/></g><g filter="url(#i)"><ellipse cx="3.47" cy="21.501" fill="#7e14ff" rx="3.47" ry="21.501" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.009 28.708 47.59)scale(-1 1)"/></g><g filter="url(#j)"><ellipse cx=".387" cy="8.972" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(39.51 .387 8.972)"/></g><g filter="url(#k)"><ellipse cx="47.523" cy="-6.092" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 47.523 -6.092)"/></g><g filter="url(#l)"><ellipse cx="41.412" cy="6.333" fill="#47bfff" rx="5.971" ry="9.665" style="fill:#47bfff;fill:color(display-p3 .2799 .748 1);fill-opacity:1" transform="rotate(37.892 41.412 6.333)"/></g><g filter="url(#m)"><ellipse cx="-1.879" cy="38.332" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 -1.88 38.332)"/></g><g filter="url(#n)"><ellipse cx="-1.879" cy="38.332" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 -1.88 38.332)"/></g><g filter="url(#o)"><ellipse cx="35.651" cy="29.907" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 35.651 29.907)"/></g><g filter="url(#p)"><ellipse cx="38.418" cy="32.4" fill="#47bfff" rx="5.971" ry="15.297" style="fill:#47bfff;fill:color(display-p3 .2799 .748 1);fill-opacity:1" transform="rotate(37.892 38.418 32.4)"/></g></g><defs><filter id="b" width="60.045" height="41.654" x="-19.77" y="16.149" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="7.659"/></filter><filter id="c" width="90.34" height="51.437" x="-54.613" y="-7.533" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="7.659"/></filter><filter id="d" width="79.355" height="29.4" x="-49.64" y="2.03" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="e" width="79.579" height="29.4" x="-45.045" y="20.029" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="f" width="79.579" height="29.4" x="-43.513" y="21.178" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="g" width="74.749" height="58.852" x="15.756" y="-17.901" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="7.659"/></filter><filter id="h" width="61.377" height="25.362" x="23.548" y="2.284" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="i" width="61.377" height="25.362" x="23.548" y="2.284" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="j" width="56.045" height="63.649" x="-27.636" y="-22.853" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="k" width="54.814" height="64.646" x="20.116" y="-38.415" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="l" width="33.541" height="35.313" x="24.641" y="-11.323" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="m" width="54.814" height="64.646" x="-29.286" y="6.009" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="n" width="54.814" height="64.646" x="-29.286" y="6.009" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="o" width="54.814" height="64.646" x="8.244" y="-2.416" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="p" width="39.409" height="43.623" x="18.713" y="10.588" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter></defs></svg>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<symbol id="bluesky-icon" viewBox="0 0 16 17">
|
|
3
|
+
<g clip-path="url(#bluesky-clip)"><path fill="#08060d" d="M7.75 7.735c-.693-1.348-2.58-3.86-4.334-5.097-1.68-1.187-2.32-.981-2.74-.79C.188 2.065.1 2.812.1 3.251s.241 3.602.398 4.13c.52 1.744 2.367 2.333 4.07 2.145-2.495.37-4.71 1.278-1.805 4.512 3.196 3.309 4.38-.71 4.987-2.746.608 2.036 1.307 5.91 4.93 2.746 2.72-2.746.747-4.143-1.747-4.512 1.702.189 3.55-.4 4.07-2.145.156-.528.397-3.691.397-4.13s-.088-1.186-.575-1.406c-.42-.19-1.06-.395-2.741.79-1.755 1.24-3.64 3.752-4.334 5.099"/></g>
|
|
4
|
+
<defs><clipPath id="bluesky-clip"><path fill="#fff" d="M.1.85h15.3v15.3H.1z"/></clipPath></defs>
|
|
5
|
+
</symbol>
|
|
6
|
+
<symbol id="discord-icon" viewBox="0 0 20 19">
|
|
7
|
+
<path fill="#08060d" d="M16.224 3.768a14.5 14.5 0 0 0-3.67-1.153c-.158.286-.343.67-.47.976a13.5 13.5 0 0 0-4.067 0c-.128-.306-.317-.69-.476-.976A14.4 14.4 0 0 0 3.868 3.77C1.546 7.28.916 10.703 1.231 14.077a14.7 14.7 0 0 0 4.5 2.306q.545-.748.965-1.587a9.5 9.5 0 0 1-1.518-.74q.191-.14.372-.293c2.927 1.369 6.107 1.369 8.999 0q.183.152.372.294-.723.437-1.52.74.418.838.963 1.588a14.6 14.6 0 0 0 4.504-2.308c.37-3.911-.63-7.302-2.644-10.309m-9.13 8.234c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.894 0 1.614.82 1.599 1.82.001 1-.705 1.82-1.6 1.82m5.91 0c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.893 0 1.614.82 1.599 1.82 0 1-.706 1.82-1.6 1.82"/>
|
|
8
|
+
</symbol>
|
|
9
|
+
<symbol id="documentation-icon" viewBox="0 0 21 20">
|
|
10
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="m15.5 13.333 1.533 1.322c.645.555.967.833.967 1.178s-.322.623-.967 1.179L15.5 18.333m-3.333-5-1.534 1.322c-.644.555-.966.833-.966 1.178s.322.623.966 1.179l1.534 1.321"/>
|
|
11
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M17.167 10.836v-4.32c0-1.41 0-2.117-.224-2.68-.359-.906-1.118-1.621-2.08-1.96-.599-.21-1.349-.21-2.848-.21-2.623 0-3.935 0-4.983.369-1.684.591-3.013 1.842-3.641 3.428C3 6.449 3 7.684 3 10.154v2.122c0 2.558 0 3.838.706 4.726q.306.383.713.671c.76.536 1.79.64 3.581.66"/>
|
|
12
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M3 10a2.78 2.78 0 0 1 2.778-2.778c.555 0 1.209.097 1.748-.047.48-.129.854-.503.982-.982.145-.54.048-1.194.048-1.749a2.78 2.78 0 0 1 2.777-2.777"/>
|
|
13
|
+
</symbol>
|
|
14
|
+
<symbol id="github-icon" viewBox="0 0 19 19">
|
|
15
|
+
<path fill="#08060d" fill-rule="evenodd" d="M9.356 1.85C5.05 1.85 1.57 5.356 1.57 9.694a7.84 7.84 0 0 0 5.324 7.44c.387.079.528-.168.528-.376 0-.182-.013-.805-.013-1.454-2.165.467-2.616-.935-2.616-.935-.349-.91-.864-1.143-.864-1.143-.71-.48.051-.48.051-.48.787.051 1.2.805 1.2.805.695 1.194 1.817.857 2.268.649.064-.507.27-.857.49-1.052-1.728-.182-3.545-.857-3.545-3.87 0-.857.31-1.558.8-2.104-.078-.195-.349-1 .077-2.078 0 0 .657-.208 2.14.805a7.5 7.5 0 0 1 1.946-.26c.657 0 1.328.092 1.946.26 1.483-1.013 2.14-.805 2.14-.805.426 1.078.155 1.883.078 2.078.502.546.799 1.247.799 2.104 0 3.013-1.818 3.675-3.558 3.87.284.247.528.714.528 1.454 0 1.052-.012 1.896-.012 2.156 0 .208.142.455.528.377a7.84 7.84 0 0 0 5.324-7.441c.013-4.338-3.48-7.844-7.773-7.844" clip-rule="evenodd"/>
|
|
16
|
+
</symbol>
|
|
17
|
+
<symbol id="social-icon" viewBox="0 0 20 20">
|
|
18
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M12.5 6.667a4.167 4.167 0 1 0-8.334 0 4.167 4.167 0 0 0 8.334 0"/>
|
|
19
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M2.5 16.667a5.833 5.833 0 0 1 8.75-5.053m3.837.474.513 1.035c.07.144.257.282.414.309l.93.155c.596.1.736.536.307.965l-.723.73a.64.64 0 0 0-.152.531l.207.903c.164.715-.213.991-.84.618l-.872-.52a.63.63 0 0 0-.577 0l-.872.52c-.624.373-1.003.094-.84-.618l.207-.903a.64.64 0 0 0-.152-.532l-.723-.729c-.426-.43-.289-.864.306-.964l.93-.156a.64.64 0 0 0 .412-.31l.513-1.034c.28-.562.735-.562 1.012 0"/>
|
|
20
|
+
</symbol>
|
|
21
|
+
<symbol id="x-icon" viewBox="0 0 19 19">
|
|
22
|
+
<path fill="#08060d" fill-rule="evenodd" d="M1.893 1.98c.052.072 1.245 1.769 2.653 3.77l2.892 4.114c.183.261.333.48.333.486s-.068.089-.152.183l-.522.593-.765.867-3.597 4.087c-.375.426-.734.834-.798.905a1 1 0 0 0-.118.148c0 .01.236.017.664.017h.663l.729-.83c.4-.457.796-.906.879-.999a692 692 0 0 0 1.794-2.038c.034-.037.301-.34.594-.675l.551-.624.345-.392a7 7 0 0 1 .34-.374c.006 0 .93 1.306 2.052 2.903l2.084 2.965.045.063h2.275c1.87 0 2.273-.003 2.266-.021-.008-.02-1.098-1.572-3.894-5.547-2.013-2.862-2.28-3.246-2.273-3.266.008-.019.282-.332 2.085-2.38l2-2.274 1.567-1.782c.022-.028-.016-.03-.65-.03h-.674l-.3.342a871 871 0 0 1-1.782 2.025c-.067.075-.405.458-.75.852a100 100 0 0 1-.803.91c-.148.172-.299.344-.99 1.127-.304.343-.32.358-.345.327-.015-.019-.904-1.282-1.976-2.808L6.365 1.85H1.8zm1.782.91 8.078 11.294c.772 1.08 1.413 1.973 1.425 1.984.016.017.241.02 1.05.017l1.03-.004-2.694-3.766L7.796 5.75 5.722 2.852l-1.039-.004-1.039-.004z" clip-rule="evenodd"/>
|
|
23
|
+
</symbol>
|
|
24
|
+
</svg>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="./favicon.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>web</title>
|
|
8
|
+
<script type="module" crossorigin src="./assets/index-U7WfpOzC.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="./assets/index-C2IdC4IZ.css">
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<div id="root"></div>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,22 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"packageManager": "pnpm@10.10.0+sha512.d615db246fe70f25dcfea6d8d73dee782ce23e2245e3c4f6f888249fb568149318637dca73c2c5c8ef2a4ca0d5657fb9567188bfab47f566d1ee6ce987815c39",
|
|
3
3
|
"name": "duclaw-cli",
|
|
4
|
-
"version": "1.7.
|
|
4
|
+
"version": "1.7.4",
|
|
5
5
|
"description": "AI Agent多智能体团队 - 支持飞书 Channel、团队协作、定时任务、Skill... etc 当成openclaw 用",
|
|
6
6
|
"bin": {
|
|
7
|
-
"duclaw-cli": "
|
|
7
|
+
"duclaw-cli": "dist/main.js"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"dist/",
|
|
11
|
-
"skills/"
|
|
11
|
+
"skills/",
|
|
12
|
+
"web/dist/"
|
|
12
13
|
],
|
|
13
14
|
"scripts": {
|
|
14
15
|
"start": "npx tsx src/main.ts",
|
|
15
16
|
"dev:web": "cd web && pnpm dev",
|
|
17
|
+
"dev:cp": "pnpm --filter @duclaw/control-plane dev",
|
|
18
|
+
"dev:portal": "pnpm --filter @duclaw/portal dev",
|
|
19
|
+
"dev:saas": "pnpm --filter @duclaw/control-plane dev & pnpm --filter @duclaw/portal dev; wait",
|
|
20
|
+
"cp:infra:up": "pnpm --filter @duclaw/control-plane infra:up",
|
|
21
|
+
"cp:db:push": "pnpm --filter @duclaw/control-plane db:push",
|
|
22
|
+
"cp:db:generate": "pnpm --filter @duclaw/control-plane db:generate",
|
|
16
23
|
"build": "node build.js",
|
|
17
24
|
"build:tsc": "tsc",
|
|
18
25
|
"build:web": "cd web && pnpm build",
|
|
19
|
-
"build:
|
|
26
|
+
"build:portal": "pnpm --filter @duclaw/portal build",
|
|
27
|
+
"build:all": "pnpm build:web && pnpm build",
|
|
28
|
+
"core:pack": "pnpm build:all && node scripts/packCorePackage.js",
|
|
29
|
+
"tenant:base:build": "docker build -f docker/Dockerfile.base --target deps-base -t duclaw-deps-base:node23 . && docker build -f docker/Dockerfile.base --target runtime-base -t duclaw-runtime-base:node23 .",
|
|
30
|
+
"tenant:image:build": "node scripts/buildTenantImage.js",
|
|
31
|
+
"tenant:image:build:npm": "node scripts/buildTenantImageFromNpm.js",
|
|
32
|
+
"tenant:image:build:full": "pnpm tenant:base:build && pnpm tenant:image:build"
|
|
20
33
|
},
|
|
21
34
|
"dependencies": {
|
|
22
35
|
"@anthropic-ai/sdk": "^0.78.0",
|
|
@@ -43,5 +56,15 @@
|
|
|
43
56
|
"tsx": "^4.21.0",
|
|
44
57
|
"typescript": "^5.9.3",
|
|
45
58
|
"vitest": "^4.0.18"
|
|
59
|
+
},
|
|
60
|
+
"pnpm": {
|
|
61
|
+
"onlyBuiltDependencies": [
|
|
62
|
+
"better-sqlite3",
|
|
63
|
+
"bcrypt",
|
|
64
|
+
"@prisma/client",
|
|
65
|
+
"@prisma/engines",
|
|
66
|
+
"prisma",
|
|
67
|
+
"protobufjs"
|
|
68
|
+
]
|
|
46
69
|
}
|
|
47
70
|
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: duclaw-saas-release
|
|
3
|
+
description: |
|
|
4
|
+
Release and roll out Duclaw Core updates to the SaaS layer without coupling Core back to SaaS.
|
|
5
|
+
Use this skill when updating tenant images, publishing Core versions, building tenant images from local source or npm, updating TENANT_IMAGE, or rolling out already-running tenants to a new image tag.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Duclaw SaaS Release
|
|
9
|
+
|
|
10
|
+
Use this skill for the release/update chain between Core and SaaS.
|
|
11
|
+
|
|
12
|
+
Boundary rule:
|
|
13
|
+
|
|
14
|
+
- Core may evolve to support SaaS
|
|
15
|
+
- SaaS may orchestrate Core
|
|
16
|
+
- Core must not depend on SaaS internals
|
|
17
|
+
|
|
18
|
+
This skill assumes:
|
|
19
|
+
|
|
20
|
+
- Core = `src/` + `web/`
|
|
21
|
+
- SaaS = `control-plane/` + `portal/`
|
|
22
|
+
- Tenant runtime is updated by **image tag + container recreate**
|
|
23
|
+
- `Restart` alone does **not** switch image versions
|
|
24
|
+
|
|
25
|
+
## Pick The Right Flow
|
|
26
|
+
|
|
27
|
+
Use **Local Source Flow** when:
|
|
28
|
+
|
|
29
|
+
- You changed Core code locally
|
|
30
|
+
- You want a local SaaS environment to use the latest Core immediately
|
|
31
|
+
|
|
32
|
+
Use **Published npm Flow** when:
|
|
33
|
+
|
|
34
|
+
- SaaS is deployed on another machine
|
|
35
|
+
- That machine can access npm, but not your local source tree
|
|
36
|
+
|
|
37
|
+
## Local Source Flow
|
|
38
|
+
|
|
39
|
+
1. Build or refresh base images if needed:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pnpm tenant:base:build
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Only needed when base images are missing, or `docker/Dockerfile.base` changed.
|
|
46
|
+
|
|
47
|
+
2. Build the tenant image from the current local Core source:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pnpm tenant:image:build
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
This flow uses:
|
|
54
|
+
|
|
55
|
+
- `build:all`
|
|
56
|
+
- `core:pack`
|
|
57
|
+
- Docker build from the packed Core artifact
|
|
58
|
+
|
|
59
|
+
3. Roll out existing tenants to the new image:
|
|
60
|
+
|
|
61
|
+
Dry run first:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pnpm --filter @duclaw/control-plane rollout:image --image duclaw:latest --dry-run --all
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Then real rollout:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
pnpm --filter @duclaw/control-plane rollout:image --image duclaw:latest --all
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Target only one tenant when safer:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pnpm --filter @duclaw/control-plane rollout:image --image duclaw:latest --tenant <tenantId>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Published npm Flow
|
|
80
|
+
|
|
81
|
+
1. Publish a Core version to npm, for example `duclaw-cli@1.8.0`
|
|
82
|
+
|
|
83
|
+
2. On the SaaS machine, build a tenant image from npm:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
pnpm tenant:base:build
|
|
87
|
+
IMAGE_REPO=registry/duclaw-runtime pnpm tenant:image:build:npm --version 1.8.0
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
If base images already exist, skip `tenant:base:build`.
|
|
91
|
+
|
|
92
|
+
If `--version` is omitted, the command resolves npm `latest`.
|
|
93
|
+
|
|
94
|
+
3. Update `TENANT_IMAGE` in `control-plane/.env`
|
|
95
|
+
|
|
96
|
+
Example:
|
|
97
|
+
|
|
98
|
+
```env
|
|
99
|
+
TENANT_IMAGE="registry/duclaw-runtime:1.8.0"
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Important:
|
|
103
|
+
|
|
104
|
+
- `TENANT_IMAGE` affects **future new tenants**
|
|
105
|
+
- existing tenants keep their own `imageTag` until rollout
|
|
106
|
+
|
|
107
|
+
4. Restart control-plane so the new default takes effect
|
|
108
|
+
|
|
109
|
+
5. Roll out existing tenants:
|
|
110
|
+
|
|
111
|
+
Dry run:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
pnpm --filter @duclaw/control-plane rollout:image --image registry/duclaw-runtime:1.8.0 --dry-run --all
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Real rollout:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
pnpm --filter @duclaw/control-plane rollout:image --image registry/duclaw-runtime:1.8.0 --all
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Scope the rollout if needed:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
pnpm --filter @duclaw/control-plane rollout:image --image registry/duclaw-runtime:1.8.0 --tenant <tenantId>
|
|
127
|
+
pnpm --filter @duclaw/control-plane rollout:image --image registry/duclaw-runtime:1.8.0 --user <userId>
|
|
128
|
+
pnpm --filter @duclaw/control-plane rollout:image --image registry/duclaw-runtime:1.8.0 --limit 10 --all
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Rollback
|
|
132
|
+
|
|
133
|
+
Rollback uses the same rollout mechanism with an older image tag.
|
|
134
|
+
|
|
135
|
+
1. Set `TENANT_IMAGE` back to the old stable tag
|
|
136
|
+
2. Restart control-plane
|
|
137
|
+
3. Roll out existing tenants to the old tag
|
|
138
|
+
|
|
139
|
+
Example:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
pnpm --filter @duclaw/control-plane rollout:image --image registry/duclaw-runtime:1.7.9 --all
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Operational Rules
|
|
146
|
+
|
|
147
|
+
- Prefer immutable version tags in production, not `latest`
|
|
148
|
+
- Use `--dry-run` before large rollouts
|
|
149
|
+
- Roll out one tenant first when risk is non-trivial
|
|
150
|
+
- Treat image build and tenant rollout as separate steps
|
|
151
|
+
- Never assume `restart` updates running tenants to a new Core version
|
|
152
|
+
|
|
153
|
+
## Canonical Files
|
|
154
|
+
|
|
155
|
+
Read these only when you need deeper context:
|
|
156
|
+
|
|
157
|
+
- `docs/CORE-SAAS-BOUNDARY.md`
|
|
158
|
+
- `docs/SAAS-QUICKSTART.md`
|
|
159
|
+
- `docker/Dockerfile.npm`
|
|
160
|
+
- `scripts/buildTenantImageFromNpm.js`
|
|
161
|
+
- `control-plane/scripts/rolloutImage.ts`
|