{"_id":"@g7e6-sdlc/sdlc-cli","_rev":"36-51b59951b5a1f5952eb59cb1cf7c2797","name":"@g7e6-sdlc/sdlc-cli","dist-tags":{"beta":"1.2.0-beta.1","latest":"1.5.4"},"versions":{"0.1.0":{"name":"@g7e6-sdlc/sdlc-cli","version":"0.1.0","_id":"@g7e6-sdlc/sdlc-cli@0.1.0","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"f040b79f693a38fd1a46eb7fc7664bec6a320399","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-0.1.0.tgz","fileCount":17,"integrity":"sha512-6Z6BI7/dBVHoeOBLzF+peldf38is8HCn462yxYUoNUOfnF0eZn6zrjaAy6wmExTHAUGGstMbT1+YDM/esAGChQ==","signatures":[{"sig":"MEUCIQCxl0B/RTugXgf2jbO/aXpxUe+KWtaxLBXNE5w43r/EWgIgSJXzHC6Xz2N2cNWlBWQmmp/6FAIPNimEwcrE3pJ1R8Q=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":116355},"type":"module","engines":{"node":">=20"},"gitHead":"531d58a0584fb55863e3b993d3c711d430317a65","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_0.1.0_1782962153982_0.7977249174576333","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@g7e6-sdlc/sdlc-cli","version":"0.2.0","_id":"@g7e6-sdlc/sdlc-cli@0.2.0","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"668ee320e17a897031c81f25ebdd7244f1ecfcd7","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-0.2.0.tgz","fileCount":17,"integrity":"sha512-R4Mvz7ebh2gvriEI5XFFy6Jgr40ZpBJFUmQxLQfTOmeNQSXVozh6AGU/mnVIaVvtXNfkBd1n9z3XyA3FNJ1qeQ==","signatures":[{"sig":"MEUCIQDSy8FZcF3slpqZhKAuznfRjqMEK25IynFXNeOZP40KQAIgVPj9FcqRBKlnWewER+WfOdaJ0VmdV5HkxwkFfQNcoBk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":119780},"type":"module","engines":{"node":">=20"},"gitHead":"400933b398b97cabf9f85e13de5ef24b8ca4b1eb","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_0.2.0_1782967089227_0.3831174280245988","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@g7e6-sdlc/sdlc-cli","version":"0.3.0","_id":"@g7e6-sdlc/sdlc-cli@0.3.0","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"f860e8c22818f69725c38717e7bcedb26378becb","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-0.3.0.tgz","fileCount":17,"integrity":"sha512-rfVgR+XJMB5ifoSulkakdckwYQ+DNuqprE/EZn6ky400wNJjVizic+5H8LqY6IegxY+hHwIgu0kIOifgYOU9sw==","signatures":[{"sig":"MEUCIEHGFi1IjQgXF33hqALn3I7K5IvV5ML1dZhcshil6HnLAiEA/P7tjDJe6FTxO3yu8eAK0vn1Kw6Ay5baMxYHVjW9Vko=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":120578},"type":"module","engines":{"node":">=20"},"gitHead":"95c0284e963d1fd7001b34457e21c2bc94d346fc","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_0.3.0_1782987257297_0.18154959726534048","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@g7e6-sdlc/sdlc-cli","version":"0.4.0","_id":"@g7e6-sdlc/sdlc-cli@0.4.0","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"ef004b3731f47266306ce9f616caec460863565f","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-0.4.0.tgz","fileCount":17,"integrity":"sha512-QOYAahZcevgY1ueeAQpBGUA0AufK2363ipFEcUA6SHVWTvZYChBlfz8x5s9bEnGF+EeWv2udI0F9rXuOFL3LFw==","signatures":[{"sig":"MEQCIBsjloOp2Jy1exJ26BIEbXLcn3Aypf8XyHroHIbrmYQCAiAYJPo6tt2dly0g9aoFLcddgoyxXwCLDEqFgPx/54JqAQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":123335},"type":"module","engines":{"node":">=20"},"gitHead":"2ab7cf1329d6a97bd46b3bd0b44636fea47032e7","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_0.4.0_1783144518816_0.45235117629524657","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"name":"@g7e6-sdlc/sdlc-cli","version":"0.4.1","_id":"@g7e6-sdlc/sdlc-cli@0.4.1","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"abb2aac09f0efed7d2adef0a789c7683a893e830","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-0.4.1.tgz","fileCount":17,"integrity":"sha512-MmOLZGR52CK3s9kUxN2OWYUMv1C10J/C6Liqp8zY6PenXubfr3TwZUw2zcrXx3TIYjSJrkRdAphph7RFLdQe9g==","signatures":[{"sig":"MEUCIQD/e/ET/OVrV/Uhbg85gA4cHx03te1QFhGGTjq5SbOY3wIgZz+Ax9RadjZSpCnPlOXsjXQkXWO/rDyM6eopxxyqACw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":123695},"type":"module","engines":{"node":">=20"},"gitHead":"d904ad88e921f5b434fe1d834830f69c78c4ca23","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_0.4.1_1783434423304_0.583651860459969","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@g7e6-sdlc/sdlc-cli","version":"0.5.0","_id":"@g7e6-sdlc/sdlc-cli@0.5.0","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"5dd239902b7214342f79fb6b5a66f9eb82de4fe3","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-0.5.0.tgz","fileCount":17,"integrity":"sha512-PKKxzx1EUss/E88fw1KmG2tn8eSCcjJgwKTfica3iB2nIZO4euqjjVtIqaJGTpgdy93TE/UdKMBW/GMQX0shXw==","signatures":[{"sig":"MEUCIDY0JxBDtqjJj4TxNkUMXPYRdpjRXaiws0CANn3ZPbQVAiEAwEumC6mVVNO1FbduX3WaFTjBgY/BWANeAhUfjYX/XCA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":135964},"type":"module","engines":{"node":">=20"},"gitHead":"711487516ed276cc2751673831125adc71f3e8a9","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_0.5.0_1783567359226_0.8972632548844237","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"name":"@g7e6-sdlc/sdlc-cli","version":"0.5.1","_id":"@g7e6-sdlc/sdlc-cli@0.5.1","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"b89fe01f3ed8109d374b9d6676e6abf919a852b7","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-0.5.1.tgz","fileCount":17,"integrity":"sha512-3TTLvp94l/jqVeQP26nexxu5YA4UxseL+2u0Qblhvgcau77O+wba/IHyMGLi3cL2qaaQ2imIV6NwyczPIEy3ug==","signatures":[{"sig":"MEYCIQDo3Qv57QC/1nPcFDBuqS6KATe8nUe8+uoN2wAURJdpWAIhALtxOGkLDPAwiJsDmRiEV7OJHcPUp65tht6X4fzZt0dW","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":136446},"type":"module","engines":{"node":">=20"},"gitHead":"e0ac8bdd2f0d5d015c077b02db976813b92cbe3e","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_0.5.1_1783576509636_0.7877125336540252","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@g7e6-sdlc/sdlc-cli","version":"0.6.0","_id":"@g7e6-sdlc/sdlc-cli@0.6.0","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"96af2d1444931347ec0b682ca3fed798f8b6a79e","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-0.6.0.tgz","fileCount":17,"integrity":"sha512-8kO7w9bDq4yRs6KRrJfr5TA2JFp7Ekg26HZIuvCJilNe8j/b/aZm/ygxZw9QBqyi1k+6NcAwMcti31bg+FnyOw==","signatures":[{"sig":"MEUCIAOmZiCtv5L+EgzD6ZeXvUJhVgNhfshwT0I3LXzm0r3qAiEAoEGkIU4CMCRJZxKskGMJgQcay72g8VLkuQ6C7eOwWD4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":139990},"type":"module","engines":{"node":">=20"},"gitHead":"d867c2f13efef7264d5461eebd684263739dbf65","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_0.6.0_1783657367696_0.7120262788828009","host":"s3://npm-registry-packages-npm-production"}},"0.6.1":{"name":"@g7e6-sdlc/sdlc-cli","version":"0.6.1","_id":"@g7e6-sdlc/sdlc-cli@0.6.1","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"216901e3f511d3d0431382aa5593a2f5962fbcdf","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-0.6.1.tgz","fileCount":17,"integrity":"sha512-JgVKvvq4XOy11fzqKZB/m6UyGVHe3b/NKFHjsJksT+j6AkV77jcBjUPaoKN6LQo/xv/b+0H5v3rLFqtB3c9YRQ==","signatures":[{"sig":"MEUCIQDzSy4eo5YMHOaET6S6ETFeyTGRT9Sgo/l9HnBIjM8vEwIgfPBFkwfI4aWTz+72ZUwX6cNzttKzBZ+0hgdsJUj/yRI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":140616},"type":"module","engines":{"node":">=20"},"gitHead":"32e7aab6b81bcb0e6d4abff92c36cf9c3d602043","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_0.6.1_1783662284723_0.3846948539724029","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@g7e6-sdlc/sdlc-cli","version":"0.7.0","_id":"@g7e6-sdlc/sdlc-cli@0.7.0","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"73430deb1d67580b6076cba9f08f7bc2969012f9","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-0.7.0.tgz","fileCount":17,"integrity":"sha512-WegU0dRMdczT6JeCxeMxjCazGA5SyQCoxNUNiAsA80Lh28qYbgkpiuZLOM7jbIu7lPr0LNPIAwRmpNVX2xVjdA==","signatures":[{"sig":"MEYCIQDhcHXxkAKa0H24C77cKV0w2MkIteuRdGRoPMfAG/Da+AIhAKpaiJybl3ybB7sG8Tf2vJEfJDjdDuQAw9YxT+EJdc3z","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":147245},"type":"module","engines":{"node":">=20"},"gitHead":"a0bf52300d798c44c089c3769bb598a38362a99f","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_0.7.0_1784022457538_0.627343367280297","host":"s3://npm-registry-packages-npm-production"}},"0.7.1":{"name":"@g7e6-sdlc/sdlc-cli","version":"0.7.1","_id":"@g7e6-sdlc/sdlc-cli@0.7.1","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"72a69973636bfa3b71b0984a062724158452af62","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-0.7.1.tgz","fileCount":17,"integrity":"sha512-AmZwc+BYe4RxakCC8R4IYo61+TRUZpSHlNzW2HFBSpdlFexN5ZEt5/W4z9B33HLcC3dyr8hX21iD5Y6qkaTJvg==","signatures":[{"sig":"MEYCIQDD5usahj0C5KdGbumxDsPJxW3IHxKBM8C6MTzIEgZ3JAIhAJpMF5jH0IJYffXBkSgVAWBSr+sDHeA11KiI1B1ftNlx","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":147259},"type":"module","engines":{"node":">=20"},"gitHead":"09e1dd55bcd24af9b4c8126b98255d194d8b68c2","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_0.7.1_1784105954044_0.05009920848146843","host":"s3://npm-registry-packages-npm-production"}},"0.7.2":{"name":"@g7e6-sdlc/sdlc-cli","version":"0.7.2","_id":"@g7e6-sdlc/sdlc-cli@0.7.2","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"b80f5bb2b27c4d99a73de6c2ae040564c143b17c","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-0.7.2.tgz","fileCount":17,"integrity":"sha512-tZn3urtFQK0rcu/Ms6mpoMWz/hDneeVbnwajYINlHj3yoJ7TcabahlfpSV2YFybJN8iT4PLizIXkV6+lpv/Xfg==","signatures":[{"sig":"MEQCIFV/IpNVH4iXu53oFPASijT7Xq/SO5x1yd6tgmAsrzJVAiAG6u07eYAQVgutNi4vsP7HvL9/4UnasBDNYScYBxZhog==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":149649},"type":"module","engines":{"node":">=20"},"gitHead":"f564f7f25b614f9d54dc5d6d7a96994f12a6ada9","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_0.7.2_1784628419737_0.5636274146854432","host":"s3://npm-registry-packages-npm-production"}},"0.7.3":{"name":"@g7e6-sdlc/sdlc-cli","version":"0.7.3","_id":"@g7e6-sdlc/sdlc-cli@0.7.3","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"dc7fc1933e76f1756ca902b1c9f22d9e6228530c","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-0.7.3.tgz","fileCount":17,"integrity":"sha512-dxSMnu0Xe51v0PRxMJwREOOKDCo/5uPN4ASV45hfpxHrVJKV2MHp/Fxm/9Mt3+2RcDXUTKbxAyU6LNbFUaFASw==","signatures":[{"sig":"MEQCIDaTbMa2buJ8hDK8e2GB2WMskQmeHpsGXCPHldhhnUwXAiAZWvVb6JXd8IMhNayfuOPI81KRjaTHKLC5n+v67nNi5Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":151520},"type":"module","engines":{"node":">=20"},"gitHead":"325362fcc6095cbfa62327b43acaaa53e2d331f1","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_0.7.3_1784719538824_0.2029253263494908","host":"s3://npm-registry-packages-npm-production"}},"0.7.4":{"name":"@g7e6-sdlc/sdlc-cli","version":"0.7.4","_id":"@g7e6-sdlc/sdlc-cli@0.7.4","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"66894d62e404b8ba22d7bd8094935a1aa117a651","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-0.7.4.tgz","fileCount":17,"integrity":"sha512-9EXcMY3kkcSfpPrr9H0nxshIOwPk9nVUdGP4Y+2MSrPhPbNQEDIzyJB/sCeN5SWm0C/AV/nzIazEK+yciyXN0A==","signatures":[{"sig":"MEYCIQDwNPKysSrc7EJKUzVcal6XVgpa+CUYeeql1BEJcPXA8gIhAI8Sj1Yo9eHxhcdIXm0Y1sHuo+Y27X9s2mId7qnyjxjo","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":151740},"type":"module","engines":{"node":">=20"},"gitHead":"cc486bc2ff1105caabda8b8926f1594eb907998d","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_0.7.4_1785118560803_0.5598563067954963","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@g7e6-sdlc/sdlc-cli","version":"0.8.0","_id":"@g7e6-sdlc/sdlc-cli@0.8.0","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"ead80afc582964ce62b4488e688c9ebcc4991898","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-0.8.0.tgz","fileCount":17,"integrity":"sha512-BtX0H5xo0SDalfn6dvYvm66fapVgJ0IBhrHXGUUAw527ikIpN3q5k0XuAQDVzLbDmblMKJQgoKhfiitxCjfshg==","signatures":[{"sig":"MEUCICeNbhcKz/zJ7L46pDzH/lJy/RVIvURNUybqhL7qqs48AiEAtEWCQN0opqRK2xcGXI+1/+Yvmy6HvhZlDFa3Xkw7aVc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":191909},"type":"module","engines":{"node":">=20"},"gitHead":"0ff497528bbb00c8dbabcd9cd4086f74cb2a3040","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_0.8.0_1785225903090_0.808479471366937","host":"s3://npm-registry-packages-npm-production"}},"0.8.1":{"name":"@g7e6-sdlc/sdlc-cli","version":"0.8.1","_id":"@g7e6-sdlc/sdlc-cli@0.8.1","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"c96b640e3cb696cf68cd6659dc3a66701b1b589b","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-0.8.1.tgz","fileCount":21,"integrity":"sha512-QXV2OrRZyaUxRWA23MLMRh7u4RihU9ICcr0u0yEK5ZMFkvNB+ZAscB9A+eCwLClULUh+60o/TAIds/gKPMwaqw==","signatures":[{"sig":"MEUCIFuPqJuOoqOiCeh1FbIIGpfbgDVlt0MQKXeQtyf3BSV4AiEA91nvAKbQx3XkPtsS9E+d87BymwuCe4m5D7wyUdqGUeY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":233809},"type":"module","engines":{"node":">=20"},"gitHead":"6af026303fd35a578b8af129c3daae3f4b4088af","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_0.8.1_1785392676618_0.05260756064772809","host":"s3://npm-registry-packages-npm-production"}},"0.8.2":{"name":"@g7e6-sdlc/sdlc-cli","version":"0.8.2","_id":"@g7e6-sdlc/sdlc-cli@0.8.2","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"0b328c46df67a3d7bc11a39d03fe65aa012053ab","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-0.8.2.tgz","fileCount":21,"integrity":"sha512-iS6YYuunSIrqpvji7sVqz0p7H6sJNE+S47vn3WN8P0vusncmJsY+RXbe3f1O6hXq3PARoswGy/mx6NlyXqMvJw==","signatures":[{"sig":"MEUCIDnbMB0IqN1lMH2ofuVoBV3R+uuF4IsjGdQGO23DOkeJAiEAwNb+ropb27eLpAJ4Kyv6+YygW/btDa7Ddnb98K5XLnE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":247248},"type":"module","engines":{"node":">=20"},"gitHead":"7767d4aa8f7cb4707571453a0b1fe1cc39a77ef4","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_0.8.2_1785405290164_0.24288801362597723","host":"s3://npm-registry-packages-npm-production"}},"0.8.3":{"name":"@g7e6-sdlc/sdlc-cli","version":"0.8.3","_id":"@g7e6-sdlc/sdlc-cli@0.8.3","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"f1ff7e88e3fba90b054735dbafa36f3825e43ea8","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-0.8.3.tgz","fileCount":21,"integrity":"sha512-wSKcftskrOTqELdl37zrN/3c4fzYlRz7+17eJEGt17xWJz8EXwANleYnnQbxORB32GAnSyYE7B3PQp0YbJybZQ==","signatures":[{"sig":"MEUCIQC/z4+7VckeyMbuDVmcaxGWNtvO45svm0KrdgIWLXORvgIgWQb9gpujSNakIKbBFaNCEGaxXQ/AqdyBEmLRlyR6+pc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":253109},"type":"module","engines":{"node":">=20"},"gitHead":"2312058ccc1e1eaa2bd1501a1369d7108eba7761","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_0.8.3_1785484784052_0.931203849462839","host":"s3://npm-registry-packages-npm-production"}},"0.8.4-beta.0":{"name":"@g7e6-sdlc/sdlc-cli","version":"0.8.4-beta.0","_id":"@g7e6-sdlc/sdlc-cli@0.8.4-beta.0","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"c7577e89de8ce8bcce201cad8a1b9dbf69a41f40","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-0.8.4-beta.0.tgz","fileCount":21,"integrity":"sha512-rmMVsaWVNhXCZAvJi5tG+63UM3leRxahdviBUzazzX3iiMqy9WO2WXfTAU5k98XjZ2KIVltp7HLgcx0QcCPhKg==","signatures":[{"sig":"MEUCIFpB2O/vaGTKczIKxPJZ9qm4R2PvYbAMyc05+2RHn6fvAiEA6gSGIo8/NgdgqrHS0Dx6LNudMT5joWNhXdyoR8vyjek=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":283590},"type":"module","engines":{"node":">=20"},"gitHead":"fc745b4f1731e9788c8dfcc3027aa56efa28568b","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true","migrate:prd-modules":"tsx scripts/migrate-prd-modules.ts"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tsx":"4.19.2","tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_0.8.4-beta.0_1785978648490_0.9384413904986828","host":"s3://npm-registry-packages-npm-production"}},"0.8.4-beta.1":{"name":"@g7e6-sdlc/sdlc-cli","version":"0.8.4-beta.1","_id":"@g7e6-sdlc/sdlc-cli@0.8.4-beta.1","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"1965fbdcec9046e6518ab23b85c4c34c95ac933e","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-0.8.4-beta.1.tgz","fileCount":13,"integrity":"sha512-M9yJqFh2qKkzyzjUcPMuMGRK4KDjeM8H/2EnZybRpEq5NdFDdCwEWqQ7wI2OwZ14b5Aa0g9vnrPj4UOZfoSz8g==","signatures":[{"sig":"MEUCIQDijj+Ca9rWZR0hCWbijUHQl0gqWR3brZpGIzYis/9JcAIgF5UPbl6RGEmhRr4IfbzIy51AHwZml8KqQafJAWwG5I8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":272054},"type":"module","engines":{"node":">=20"},"gitHead":"50cf1603aba8d640ad8c3705eeb370d3c57b435a","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true","migrate:prd-modules":"tsx scripts/migrate-prd-modules.ts"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tsx":"4.19.2","tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_0.8.4-beta.1_1785983278100_0.3342282470479059","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@g7e6-sdlc/sdlc-cli","version":"1.0.0","_id":"@g7e6-sdlc/sdlc-cli@1.0.0","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"424127597f4ab1c169d222857cdc7584cbffce55","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-1.0.0.tgz","fileCount":13,"integrity":"sha512-T5g7jBltfhFOsbrpiyWvMwG7PX+SVNxWGswwq7jei69r+rzRsPFphoaJjfPWmMggj3G262pg1H8tPXZmsFuRbw==","signatures":[{"sig":"MEYCIQCMFcPpDI905MsYUILM/S3/T9laEZ69vWtjApZzbiqPAAIhAOiExx8N7trqBWjkHJQ2JcE7DENkDpeDWspb7MNNBAnV","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":291606},"type":"module","engines":{"node":">=20"},"gitHead":"42ec3f270a527011080255a600f580614f983dd0","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true","migrate:prd-modules":"tsx scripts/migrate-prd-modules.ts"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"4.19.2","tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_1.0.0_1786351616380_0.6671667777816164","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@g7e6-sdlc/sdlc-cli","version":"1.0.1","_id":"@g7e6-sdlc/sdlc-cli@1.0.1","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"2c82f13956918e7874058e6b5b8a05583187b434","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-1.0.1.tgz","fileCount":13,"integrity":"sha512-rYnmP+k1NrwFZPeAaPb9JIWmCqwL60uihWSmocLhfzDb59aHqst8Gp5bLlsGPOizD+/GmD2VG1I/UfgXDHKpAQ==","signatures":[{"sig":"MEQCICzWNXx4YCJSx+1yqareP4d9TSlf8xt6zK59zqNcnITHAiB67LExbRRRW80JmZOTIA5WKF/j8zvc9NKh7ICTeM6o5g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":295559},"type":"module","engines":{"node":">=20"},"gitHead":"9d2ad7811ab9505ee5bd74d1355bf55e8a023d74","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true","migrate:prd-modules":"tsx scripts/migrate-prd-modules.ts"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"4.19.2","tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_1.0.1_1786436799412_0.5786139130015435","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@g7e6-sdlc/sdlc-cli","version":"1.0.2","_id":"@g7e6-sdlc/sdlc-cli@1.0.2","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"84ddb725336b38b1a75a16c4e3903133fc12e172","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-1.0.2.tgz","fileCount":13,"integrity":"sha512-q8BjRMa9QLoj9rd74RBEpV2q1MzI9uw2A2nDNHUZgt9PpO+twRFNzZ00rIOHS8ghHBU01s4tGcGjkQEB+KwmIg==","signatures":[{"sig":"MEUCIAs1WAqOV6NzGuZaVTNFfGJ08p/46DmDnHS4IO6XjU0LAiEAzOhtjwZWDe0dT3cY24WXmJ4q7L/XejLxaCanRvcxgxE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":295843},"type":"module","engines":{"node":">=20"},"gitHead":"5b931ca0e671a5d0fa5e7f7bab544a4757e8d89a","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true","migrate:prd-modules":"tsx scripts/migrate-prd-modules.ts"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"4.19.2","tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_1.0.2_1786506914098_0.5519645726833664","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@g7e6-sdlc/sdlc-cli","version":"1.0.3","_id":"@g7e6-sdlc/sdlc-cli@1.0.3","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"fe337a946509f4033260091ad3afc50f45d53d85","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-1.0.3.tgz","fileCount":13,"integrity":"sha512-/jPEmrjuUNFcG8RIPqpsXpUpJxsuc+Sau3xEg4bwUEUbw2tn6wQHbKzVb92hTH2K47SOVR4dLpyOT5sk5RdQLA==","signatures":[{"sig":"MEYCIQDbjGZJdySSWR/7N79/PsqTzBD1+Mxm8wYCHnWcV3TR7gIhAKQ4H8yvZAH11sRO55KUUUv6FubEO3kivNgV0j9sAz0J","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":301580},"type":"module","engines":{"node":">=20"},"gitHead":"bfdd4c12f85ec106c96634613afc989fa03ea84c","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true","migrate:prd-modules":"tsx scripts/migrate-prd-modules.ts"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"4.19.2","tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_1.0.3_1786587973502_0.6971867508802845","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@g7e6-sdlc/sdlc-cli","version":"1.1.0","_id":"@g7e6-sdlc/sdlc-cli@1.1.0","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"e1bc98c3a4c7f3d04fda7c4e525cfa08e96625b3","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-1.1.0.tgz","fileCount":13,"integrity":"sha512-dypDTKnhIhgxR5aIPwk5WwDW5wPV+P2Fm9U75au/8se9/+ktQ5UPsVGURJcCBGg+d9MbqdatKGodBr29DAYhyQ==","signatures":[{"sig":"MEQCIBmG+5sN8PO/CIm0HrzlXl/JhikfXQ6sgq2TbFe/Hp1DAiBXEBCIA537OugJuO4ihBU6ix7jLU1qAL2O3mvNVxxK8Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":327163},"type":"module","engines":{"node":">=20"},"gitHead":"c73b7ed932220378860dbe7b4f82e5300e2d34a0","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true","migrate:prd-modules":"tsx scripts/migrate-prd-modules.ts"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"4.19.2","tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_1.1.0_1787657217854_0.6283835402108595","host":"s3://npm-registry-packages-npm-production"}},"1.2.0-beta.0":{"name":"@g7e6-sdlc/sdlc-cli","version":"1.2.0-beta.0","_id":"@g7e6-sdlc/sdlc-cli@1.2.0-beta.0","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"8d2e0d0347ea965e3ea8ffd9855b5903b9615229","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-1.2.0-beta.0.tgz","fileCount":13,"integrity":"sha512-9kvDHn07DA1LHCpTXrhqaJfM/FFsls+PKun0j0WP3XdnzkHQNnYaseQFTe5IHJEhdS9Eb5q/NzwxPsv7xfNItQ==","signatures":[{"sig":"MEUCIHhxOIwcMTmInv/iByQl6Yg4jAsuhU6iB/4v5IhvdqEsAiEAvCM6AAsGD4LuWQjPHOVALPkvPIyYyG9Gg3rXJLGb+VM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":339676},"type":"module","engines":{"node":">=20"},"gitHead":"4ff6d294240a639df739858b28f17384d1740e86","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true","migrate:prd-modules":"tsx scripts/migrate-prd-modules.ts"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tsx":"4.19.2","tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_1.2.0-beta.0_1787751640195_0.34471883561592676","host":"s3://npm-registry-packages-npm-production"}},"1.2.0-beta.1":{"name":"@g7e6-sdlc/sdlc-cli","version":"1.2.0-beta.1","_id":"@g7e6-sdlc/sdlc-cli@1.2.0-beta.1","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"68684d8e73d6017ad6c7ebb8589c58be6b2df254","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-1.2.0-beta.1.tgz","fileCount":13,"integrity":"sha512-cKladuqDdMq0LLWKOdlDbrBsWJFNhlx+5OlePCdz4fEXLGYFfLN3oy6stBjspncRPh+542l0NKi8dAdl6M2GFw==","signatures":[{"sig":"MEQCIDrL+96wX8ry0l+8+fqhBY0l2WMxJcm58gESPb4aBOiHAiBSW45ZP8aqfJdtdVvJ2KXjTBO/SLs+if2cDisDOtfmLg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":340031},"type":"module","engines":{"node":">=20"},"gitHead":"e956daab6e95a3d0d2f5b3f6af421e9e15ba2b8b","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true","migrate:prd-modules":"tsx scripts/migrate-prd-modules.ts"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tsx":"4.19.2","tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_1.2.0-beta.1_1787802393346_0.8540371975190266","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@g7e6-sdlc/sdlc-cli","version":"1.2.0","_id":"@g7e6-sdlc/sdlc-cli@1.2.0","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"2d4289d94b6a804497ec147b332192ff0d0e3841","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-1.2.0.tgz","fileCount":23,"integrity":"sha512-pcoKrjJK1MQYI+ckvjkvyIyiqUkCLmUbfUOvDUPs6CL+O2QtKwxwwxZDSk7gEP8kSjiDjSh14w9mo+MNDo0tGQ==","signatures":[{"sig":"MEQCIAr0viqDLIOZgKVU0xiWx5LyRJmub+GWvljHEhis5EGbAiBc/nMRQw8DrP+yzvr4xV5zAN7HFjIPKVbj7kB68T2ZvQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":422923},"type":"module","engines":{"node":">=20"},"gitHead":"b7e1d2f602f89ccc24622df771b65dfa313c6444","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true","migrate:prd-modules":"tsx scripts/migrate-prd-modules.ts"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"4.19.2","tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_1.2.0_1788231291282_0.5505165801549334","host":"s3://npm-registry-packages-npm-production"}},"1.4.0":{"name":"@g7e6-sdlc/sdlc-cli","version":"1.4.0","_id":"@g7e6-sdlc/sdlc-cli@1.4.0","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"dc14af6f409050a400578ba48c47c19895400f9e","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-1.4.0.tgz","fileCount":23,"integrity":"sha512-HkQuqzAhTIVZEqYsJpsW8MndgCaV5SXFHqsNHW87Rx8Q5/aI+7AKJEKAP9Uepva1MhDJx7yR0ohKW1ExjKJpbA==","signatures":[{"sig":"MEYCIQCs+yBNmCnIurlOdCTm0CT3PAi+2PqJgRn2DHqBOk/wOQIhAIA3hiB/fBCxJGk+58uJUsXI3vD56b+tNmf6ZNwxEgqU","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":436121},"type":"module","engines":{"node":">=20"},"gitHead":"4789f2ed465672041f05b9e9c56c28df5f8c4fe2","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true","migrate:prd-modules":"tsx scripts/migrate-prd-modules.ts"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"4.19.2","tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_1.4.0_1788748058602_0.7380117609611272","host":"s3://npm-registry-packages-npm-production"}},"1.4.1":{"name":"@g7e6-sdlc/sdlc-cli","version":"1.4.1","_id":"@g7e6-sdlc/sdlc-cli@1.4.1","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"b86690048756bf246a53a1b7294c629e91e8f28c","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-1.4.1.tgz","fileCount":23,"integrity":"sha512-i97dh8PbstlzfDAd8Y5YubEVTXL1CByboIvjsOvVGvB6bo4geGvFZjdrt8outJf+jhooqpBJUXQWWih97LB5Vg==","signatures":[{"sig":"MEQCICbcvW8+jzHkAHwrlkFQKnQN/sC1PNP5Fg58g/zzxmfhAiBhU7rupwyxTgeUtaaFNqwIM60XGhTk99kboe4SNite2g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":437696},"type":"module","engines":{"node":">=20"},"gitHead":"78452dd1a27103cd2f87026352ffaf36e90bf10c","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true","migrate:prd-modules":"tsx scripts/migrate-prd-modules.ts"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"4.19.2","tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_1.4.1_1788772164547_0.01373611243819406","host":"s3://npm-registry-packages-npm-production"}},"1.5.0":{"name":"@g7e6-sdlc/sdlc-cli","version":"1.5.0","_id":"@g7e6-sdlc/sdlc-cli@1.5.0","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"edea68364afbc6d66959abf73aaadc07489d93c1","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-1.5.0.tgz","fileCount":23,"integrity":"sha512-vdLqHX0RBXDeL/qbkiHXi8ymmZ91LlD2ztZboDdZvp2BCnjGTwcDYxCI3cql1CB5oOV4/6XQEAtG1JrsOoraFw==","signatures":[{"sig":"MEQCID8ro4VkOCewD460ypoCLKJ/oNyWhtOcBYIueFE9PylXAiBxpHP4bcHnnvyWAEU3agMgFF+dO6mF5U2TVejx8xac8Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":631800},"type":"module","engines":{"node":">=20"},"gitHead":"b5b2439aa849033f3a3322940f121fe8d1587a9a","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true","migrate:prd-modules":"tsx scripts/migrate-prd-modules.ts"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","mysql2":"^3.24.4","ioredis":"^6.0.0","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"4.19.2","tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_1.5.0_1789390484852_0.8832341841726856","host":"s3://npm-registry-packages-npm-production"}},"1.5.1":{"name":"@g7e6-sdlc/sdlc-cli","version":"1.5.1","_id":"@g7e6-sdlc/sdlc-cli@1.5.1","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"41cda1e259c2569cea7eed971a73589ff3dfed24","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-1.5.1.tgz","fileCount":23,"integrity":"sha512-XcSrYZfQLmkedI7LZtpjcifPHc0+Av9A5dKm4Zs5ImVFFUbzTh1HEk3KcmjwdAdImYkVzYU/AuHxLu1O2AWtYQ==","signatures":[{"sig":"MEUCIQDGqEr+PcIowP39vSX/xgUb0WnWxuaX7qwJx4dDxDhHBQIgZsJXB5dc3zAEXCAZxl/Dc6H6DG5lAC8+kNSCWKrYd9Y=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":631800},"type":"module","engines":{"node":">=20"},"gitHead":"3e888c1966b1350e49cf8a129057ded1fd4d3bf7","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true","migrate:prd-modules":"tsx scripts/migrate-prd-modules.ts"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","mysql2":"^3.24.4","ioredis":"^6.0.0","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"4.19.2","tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_1.5.1_1789390859697_0.8561714503866789","host":"s3://npm-registry-packages-npm-production"}},"1.5.2":{"name":"@g7e6-sdlc/sdlc-cli","version":"1.5.2","_id":"@g7e6-sdlc/sdlc-cli@1.5.2","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"3172d2419a609619c3b840cebae2f2122c2da8b1","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-1.5.2.tgz","fileCount":23,"integrity":"sha512-TCFdwUJn/79wHp/3CHCu0R8JnCFXEW7LuPf3YFFppoRMCE1dA0oWQAHIGcRbssI60pUxWCskYvcRq4mOIFrK4A==","signatures":[{"sig":"MEUCIQDKoDwJrPAtnyOcbcARlK7Kt0+J68vq2mpA0izHaK6EVwIgO62hFUhMrF7EdXff5pKTrcW4ztlJDeOHvctaZ0QIdio=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":666284},"type":"module","engines":{"node":">=20"},"gitHead":"31ad4bb0c88b34595425217ccf03da19e812546c","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true","migrate:prd-modules":"tsx scripts/migrate-prd-modules.ts"},"_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","mysql2":"^3.24.4","ioredis":"^6.0.0","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"4.19.2","tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"tmp":"tmp/sdlc-cli_1.5.2_1789473747094_0.37532862196008954","host":"s3://npm-registry-packages-npm-production"}},"1.5.4":{"_id":"@g7e6-sdlc/sdlc-cli@1.5.4","bin":{"sdlc-cli":"dist/cli.js"},"dist":{"shasum":"8d08878c69cb515814f5373aa1beecd4c41439c3","tarball":"https://registry.npmjs.org/@g7e6-sdlc/sdlc-cli/-/sdlc-cli-1.5.4.tgz","fileCount":16,"integrity":"sha512-fmdYw9TkG3z9vuOXjtWEnPugTFFbY0/pW/QQivRBvxYgIucjC6IG3FJN05LECPhruk9dwxWw44fV2ugyFAYkRA==","signatures":[{"sig":"MEUCIQCjJWHjV840gVyB4S+w4XAxrle5OYE0KmrZL0apHqYUJwIgOIp7+x2NHC+nwYkGyYTsKDP8e5KYq/bSQuUcKCuYY5k=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIC5dAyzGyrFGqDwx0O3mmmN8drn81R6EgSQP7DCpaeYCAiBYjhHp3KizyYEKJOeRCAEHcNRNJlczdbT0MZPMYqH9CA=="}],"unpackedSize":568189},"name":"@g7e6-sdlc/sdlc-cli","type":"module","engines":{"node":">=20"},"gitHead":"783d70da2eadacb41810ff44ec7e1e09ca75038e","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node ./dist/cli.js install || true","migrate:prd-modules":"tsx scripts/migrate-prd-modules.ts"},"version":"1.5.4","_npmUser":{"name":"devinrex","email":"605493682@qq.com"},"_npmVersion":"11.11.0","description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","directories":{},"maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.24.1","yaml":"^2.6.1","mysql2":"^3.24.4","ioredis":"^6.0.0","clipanion":"^4.0.0-rc.4","fast-glob":"^3.3.2","simple-git":"^3.27.0","gray-matter":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"4.19.2","tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.3","@types/node":"^22.10.5"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sdlc-cli_1.5.4_1789911562289_0.9246103202094285"}}},"time":{"created":"2026-07-02T03:15:53.781Z","modified":"2026-09-20T13:39:22.632Z","0.1.0":"2026-07-02T03:15:54.223Z","0.2.0":"2026-07-02T04:38:09.359Z","0.3.0":"2026-07-02T10:14:17.488Z","0.4.0":"2026-07-04T05:55:18.949Z","0.4.1":"2026-07-07T14:27:03.451Z","0.5.0":"2026-07-09T03:22:39.362Z","0.5.1":"2026-07-09T05:55:09.792Z","0.6.0":"2026-07-10T04:22:47.838Z","0.6.1":"2026-07-10T05:44:44.858Z","0.7.0":"2026-07-14T09:47:37.785Z","0.7.1":"2026-07-15T08:59:14.194Z","0.7.2":"2026-07-21T10:06:59.925Z","0.7.3":"2026-07-22T11:25:38.949Z","0.7.4":"2026-07-27T02:16:00.986Z","0.8.0":"2026-07-28T08:05:03.224Z","0.8.1":"2026-07-30T06:24:36.772Z","0.8.2":"2026-07-30T09:54:50.323Z","0.8.3":"2026-07-31T07:59:44.200Z","0.8.4-beta.0":"2026-08-06T01:10:48.655Z","0.8.4-beta.1":"2026-08-06T02:27:58.377Z","1.0.0":"2026-08-10T08:46:56.557Z","1.0.1":"2026-08-11T08:26:39.579Z","1.0.2":"2026-08-12T03:55:14.236Z","1.0.3":"2026-08-13T02:26:13.656Z","1.1.0":"2026-08-25T11:26:58.007Z","1.2.0-beta.0":"2026-08-26T13:40:40.356Z","1.2.0-beta.1":"2026-08-27T03:46:33.538Z","1.2.0":"2026-09-01T02:54:51.421Z","1.4.0":"2026-09-07T02:27:38.729Z","1.4.1":"2026-09-07T09:09:24.691Z","1.5.0":"2026-09-14T12:54:44.994Z","1.5.1":"2026-09-14T13:00:59.834Z","1.5.2":"2026-09-15T12:02:27.348Z","1.5.3":"2026-09-18T02:58:51.062Z","1.5.4":"2026-09-20T13:39:22.391Z"},"description":"SDLC 最小集 CLI（sdlc-cli）— 本地即真源的中间产物仓库与工作区装配","maintainers":[{"name":"devinrex","email":"605493682@qq.com"}],"readme":"# sdlc-cli\n\n> SDLC 最小集 CLI —— **本地即真源**的中间产物仓库与工作区装配。\n\n`sdlc-cli` 把软件开发生命周期(SDLC)的**中间产物**(需求、技术方案、测试用例/记录)以结构化文件 + git 提交的形式沉淀在本地,并按一次开发任务把 **中间产物 + 代码仓 worktree + 知识库** 装配进一个工作区。CLI 只负责**定位、校验、装配**;自然语言交互由配套的 `assembling-workspace` skill 承担,通过 needs 协议回报缺失项、由 skill 补齐后重调。\n\n---\n\n## 特性\n\n- **中间产物仓(context-repo)**:Jira / PRD 的 `manifest.yaml`、`tech-spec/`、`prd/`、`test-cases/`、`test-runs/` 骨架,可版本化、可事务提交。\n- **工作区装配**:一条命令把 context-repo、代码仓 worktree、知识库装进 `~/sdlc-workspaces/<product>/<id>/`（无产品时为 `_misc/<id>/`）。\n- **两种装配入口**:`--jira`(dev 视图,装代码仓 + 建 Jira 骨架)与 `--prd`(product 视图,建 PRD 骨架)。\n- **多知识库**:`knowledge_base` 支持单个或数组;每个 URL 全局共享一份克隆(`.kb-shares/<key>`),工作区内只是指向共享源的软链。\n- **工作区引导文件**:装配时首次生成 `AGENTS.md` 真源与 `CLAUDE.md` import stub,refresh 不覆盖手改内容。\n- **本地/远程代码仓**:`repos.<id>.local` 配本地路径则直接用(不拉 mirror),远程仓 clone 到全局共享 mirror `~/sdlc-workspaces/.mirrors/<urlKey>` 复用(按**仓库 URL** 规整出 `<basename>-<hash8>`,故不同 group 的同名项目、或改过 remote 地址的同一逻辑 id 都不会撞车);两者在**新建 worktree 前都会 best-effort `fetch`** 刷新,worktree 统一基于远程跟踪分支 `origin/<base>`。\n- **worktree 基分支**:可在 `repos.<id>.base` 配仓级默认值，也可用 `--repo-base <逻辑id>=<分支>` 按次覆盖。优先级为 `--repo-base > workspace cache > repos.<id>.base > origin/main > origin/master`；最终分支不存在则报错。\n- **worktree hook 隔离**:CLI 通过统一 `addWorktree()` 自动创建 context-repo 或代码仓 worktree 时,仅对本次 `git worktree add` 设置 `core.hooksPath=/dev/null`,避免用户全局 `post-checkout` hook 阻断装配或自动生成依赖目录;进入 worktree 后的日常 Git 操作仍使用用户原有 hook 配置。\n- **needs 协议**:装配缺信息时不做破坏性动作,一次性回报所有 `*_MISSING`,便于上层对话补齐。\n- **多仓交付**:`deliver plan / base set / apply` 三步把一个 Jira 的全部已挂载代码仓与 context-repo 提交、push 并建 GitLab Ready MR;`plan` 只读、`apply` 重校验 plan_id 后按仓顺序执行,任一仓失败即停。\n- **采集上报**:`kb` 组走 32KB JSON 小事件,`session` 组走 MB 级会话 transcript(采集 / 投递 / 补传 / 取整包 / 会话反馈),两条通道刻意分开、只复用机制(目录锁、幂等键、指数退避、死信)。\n- **只读透传与直连**:`db`(MySQL direct/Archery、Redis direct,审计集中写入工作区全局根)、`gapi`(DevCloud API 检索)、`apollo`(配置中心)、`jira`(REST v2 直连,写命令默认 dry-run)、`cp`(审核发起与状态)。\n\n## 环境要求\n\n- Node.js **≥ 20**\n- git\n\n## 安装\n\n```bash\n# 从 registry 安装(全局)\nnpm i -g @g7e6-sdlc/sdlc-cli\n\n# 或用 npx 直接跑\nnpx @g7e6-sdlc/sdlc-cli --help\n```\n\n安装时 `postinstall` 会调用 `sdlc-cli install`:在 `~/.sdlc/config.yaml` **缺失时**写入默认配置模板(含 `archery.base_url` 与空 `access_key` 占位);已存在则做升级合并——补缺失的 `gapi.base_url` / `archery.base_url` / `apollo.server_urls` / `session_collector` 整键默认,用户已有值一律不覆盖、token/AK 不补写、无新增键则文件不动,并把随包 `skills/` 注册到 `~/.claude/skills` 与 `~/.agents/skills`。\n\n若通过 `npx @g7e6-sdlc/sdlc-cli install` 运行(检测到从 npx 临时目录执行),`install` 还会自动 `npm i -g @g7e6-sdlc/sdlc-cli`(安装与当前相同的版本),让终端直接拥有全局 `sdlc-cli` 命令。已全局安装则跳过;在全局安装的 postinstall / 本地 `pnpm install` 场景下不会触发(避免递归与误装)。自安装失败仅告警、不影响退出码,可按提示手动 `npm i -g @g7e6-sdlc/sdlc-cli`。`pnpm dlx` / `yarn dlx` 不在自动识别范围,请手动全局安装。也可手动初始化:\n\n```bash\nsdlc-cli install          # 确保配置存在,并注册随包 skills\n# 或\nsdlc-cli config init      # 仅确保配置模板存在\n```\n\n## 快速开始\n\n```bash\n# 1) 初始化全局配置\nsdlc-cli install\n\n# 2) 登记代码仓逻辑地址(顶层全局,与产品无关)\nsdlc-cli config set repos.backend.remote git@git.g7e6.com:checkout/backend.git\n#   本地已有 clone 时可直接用本地路径(不拉 mirror,但建 worktree 前仍会 best-effort fetch):\nsdlc-cli config set repos.backend.local  ~/code/backend\n#   仓库长期基于 develop 开发时，可配置默认基准分支：\nsdlc-cli config set repos.backend.base develop\n\n# 3)(可选)登记产品预设,便于按 Jira 前缀自动带出地址\nsdlc-cli config set products.checkout.context_repo   git@git.g7e6.com:sdlc/checkout-context.git\nsdlc-cli config set products.checkout.knowledge_base '[git@git.g7e6.com:kb/checkout-kb.git]'\nsdlc-cli config set products.checkout.jira_prefixes  '[PROJ, CHK]'\nsdlc-cli config set products.checkout.keywords       '[结账, 支付, checkout]'\nsdlc-cli config set products.checkout.epic           'CHK-100'\nsdlc-cli config set products.checkout.repos          '[backend, frontend]'\n\n# 4) 装配一个 dev 工作区(围绕 Jira)\nsdlc-cli ws create --jira PROJ-123 \\\n  --epic EPIC-1 --title \"登录 SSO 后端\" \\\n  --repo backend --prd-ref PRD-login\n\n# 装配结果:~/sdlc-workspaces/checkout/PROJ-123/  (若命中产品预设)\n#   或:~/sdlc-workspaces/_misc/PROJ-123/  (若无产品匹配)\n#   context-repo/   —— 中间产物(共享 mirror 的 worktree,已建 Jira 骨架并提交)\n#   repos/backend/  —— 代码仓 worktree(分支 feature/PROJ-123-<时间戳>)\n#   knowledge/      —— 知识库(指向全局共享源的软链)\n#   AGENTS.md       —— 工作区操作引导(首次生成,refresh 不覆盖)\n```\n\n若装配缺少必需信息(如 context-repo / 知识库地址),命令不会做破坏性动作,而是以 `needs-input` 返回所有缺失项(如 `CONTEXT_REPO_MISSING`、`KNOWLEDGE_MISSING`),补齐后重跑即可。dev 视图的 `--prd-ref` 为必填，支持 `PRD-x`、`prds/PRD-x` 或 `prds/<模块>/PRD-x`；带模块路径用于精确定位，但 Jira manifest 仍保存稳定的 `PRD-x`。缺省时待 context-repo 就绪后报 `PRD_REF_REQUIRED`(回带 context-repo 已有 PRD 候选 `candidates[]`,供 skill 语义推导/选择),补齐后重跑;`--epic` / `--title` 为非必填:缺省不报 need、不阻断装配(epic 缺省不写 manifest,title 缺省兜底为主 id),可后补。\n\n## 核心概念\n\n### 中间产物仓(context-repo)\n\n一个工作区**唯一**的中间产物 git 仓,存放结构化的需求/设计/测试产物。同一 context-repo URL 跨工作区共享一份全局 mirror(`.mirrors/<ctxKey>`),工作区里的 `context-repo/` 是该 mirror 的 git worktree(每个 jira/prd 各自一个分支):\n\n```\ncontext-repo/\n├── requirements/<jira>/      # dev 视图:Jira 中间产物\n│   ├── manifest.yaml         #   身份、标题、epic、prd.ref、repos[] 声明\n│   ├── tech-spec/            #   技术方案\n│   └── test-runs/            #   测试执行记录\n└── prds/<prd>/               # product 视图:PRD 中间产物\n    ├── manifest.yaml\n    ├── prd/                  #   PRD 正文\n    └── test-cases/           #   测试用例\n```\n\n\"本地即真源\" = 真相落在这套本地文件里,通过 `ctx` 命令读写、`ctx commit` 事务提交、`ctx impact` 做影响分析。\n\n### 工作区布局\n\n工作区分**两类**:产品工作区(`ws init`,一个产品建一次、长期复用)与任务工作区(`ws create`,随 Jira/PRD 生死)。二者结构同形(都是一个目录下挂 `context-repo/` + `knowledge/`),故产品工作区靠**标记文件** `.sdlc-product.yaml` 判别、目录名带 `-product` 后缀,与任务工作区的产品层级区分开。\n\n```\n~/sdlc-workspaces/\n├── .mirrors/<urlKey>/          # 全局共享 mirror:context-repo 与远程代码仓共用(按仓库 URL 命名,跨工作区复用)\n├── .kb-shares/<urlKey>/        # 全局共享知识库(同 URL 跨工作区共享一份克隆)\n├── products/                   # 产品工作区根(config workspace.products_root,默认 <root>/products)\n│   └── <product>-product/      # 产品工作区(如 geai-product);一个产品一份,长期资产\n│       ├── .sdlc-product.yaml  # ★ 产品标记:判别产品工作区的唯一判据,产品名的唯一来源;含 context_repo + knowledge_base 地址表\n│       ├── CLAUDE.md           # 工作区结构与初始约定(真源,首次生成、不覆盖)\n│       ├── AGENTS.md           # 指向 CLAUDE.md(方向与任务工作区相反)\n│       ├── context-repo/       # 独立 clone(不是 worktree)\n│       └── knowledge/<name>/   # 独立 clone(不是软链——长期资产,独立副本更省心)\n├── <product>/                  # 任务工作区的产品层(如 xjny / hualu / geai)\n│   └── <id>/                   # 一个任务工作区(id = Jira 号或 PRD 号)\n│       ├── context-repo/       # 共享 mirror 的 worktree(单实例)\n│       ├── repos/<name>/       # 代码仓 worktree\n│       ├── knowledge/<name>/   # 指向 .kb-shares/<urlKey> 的软链(可多个)\n│       ├── AGENTS.md           # 工作区真源引导(首次生成)\n│       ├── CLAUDE.md           # @AGENTS.md import stub\n│       └── .workspace-cache.yaml # 身份缓存(再次装配可省略参数)\n└── _misc/                      # 无产品兜底\n    └── <id>/                   # 无产品匹配时的工作区\n```\n\n**任务工作区的产品层规则**：\n- `<product>` 为命中的产品名（如 xjny / hualu），由 `resolveProduct(id, opts.product)` 或产品预设确定\n- 无产品时统一落 `_misc/` 目录，保持「永远有产品层」的一致结构\n- 定位时靠扫描 `<root>/*/<id>/context-repo`（跳过 `.` 开头的隐藏目录），不依赖 `jira_prefixes`\n- 旧平铺 workspace（`<root>/<id>/`）作为 fallback 兼容保留，零命中时回退检查\n\n**产品工作区判别规则**：\n- **判据只认 `.sdlc-product.yaml`**，不看目录结构。两类工作区都是「一个目录挂 `context-repo/`」，靠结构无法区分——早先的 `prds/`+`requirements/` 判据会把任务工作区的 context-repo 也认成产品，`ws which` 因此报出一串以 Jira 号为名的假候选\n- **产品名取自标记的 `product` 字段**，不从目录名推断。所以目录名可以带 `-product` 后缀（甚至叫别的）而不影响识别，`canonical_name` 也不会被后缀污染\n- **扫描只看 `products_root` 的直接子目录**，不递归、不扫 cwd。cwd 的正当用途由「从 cwd 向上查找」承担（在 context-repo 里就地跑命令照样命中，且比向下猜更准）\n- **无标记的旧布局目录不被识别**。判据换代前建的产品工作区（`<root>/<product>/context-repo`，无后缀无标记）会报 `PRODUCT_WORKSPACE_MISSING`，需重跑 `ws init --product <name>`\n- **标记同时记录仓库地址**：`context_repo`（字符串）+ `knowledge_base`（`[{name, repo}]`，`name` 即 `knowledge/<name>` 目录名；无知识库时该字段不落）。产品工作区的两者都是独立 clone、离开 config 看不出血缘，落在标记里让 agent 不必回读 `~/.sdlc/config.yaml`\n\n**产品工作区的引导文件**：`ws init` 在工作区根生成 `CLAUDE.md`（结构 + 初始约定的**真源**）与 `AGENTS.md`（`@CLAUDE.md` + 普通链接，两种读法都能落到同一份）。**方向与任务工作区相反**——任务工作区是 `AGENTS.md` 正文 + `CLAUDE.md` stub。两者都是缺失才建、永不覆盖，人改过的内容不会被重跑冲掉。内容含：目录结构（含 `context-repo/` 内部分层）、「路径向 CLI 要」「归属：定义在 PRD、执行在 Jira」「不在此写业务代码」「知识库只读、复用优先」等初始约定、常用命令、仓库地址回显。\n\n`ws which` 的 resolved 信封回带 `workspace_kind` 字段标明命中来源：`product`（产品工作区）/ `dev`（任务工作区，cwd 向上查找时会命中）/ `unknown`（裸 context-repo，如 `--repo` 指到任意仓）。调用方按需自行判断——就地读写 PRD 时 `dev` 反而是对的，装配产品级资产时才须 `product`。\n\n`<ctxKey>` / `<urlKey>` 均规整为 `<basename>-<hash8>`(url 的 sha1 前 8 位),同一 URL 幂等复用同一份共享源。\n\n### 配置文件 `~/.sdlc/config.yaml`\n\n单层全局配置:\n\n```yaml\nworkspace:\n  root: ~/sdlc-workspaces\n  products_root: ~/sdlc-workspaces/products  # 产品工作区根（可选；默认 <workspace.root>/products）\nkb:\n  collector:\n    server_url: http://sdlc-knowledge-base.g7in.com/  # base URL,固定拼 /api/collector/events\n    server_token: \"\"                                     # 输出时脱敏\n    timeout_ms: 1000\n    flush_limit: 50\n    worker_interval_seconds: 60\n    worker_max_seconds: 900\nsession_collector:                 # 会话 transcript 采集（session 命令组）\n  enabled: true\n  include: []                      # 空 = 全采；非空 = 白名单，需命中其一\n  exclude:                         # 优先于 include；内置默认见下\n    - \"~/.claude/**\"\n    - \"~/.codex/**\"\n    - \"~/.ssh/**\"\n    - \"~/.gnupg/**\"\n    - \"**/node_modules/**\"\n  collect_subagents: true\n  floor_bytes:                     # 去抖阈值 = 硬崩溃时最多丢多少内容的上界\n    claude: 1048576                # 1MB\n    codex: 2097152                 # 2MB\n  skip_files_larger_than: 0        # 0 = 不限\n  feedback_flush_limit: 20         # session flush 每轮最多投多少条会话反馈；0 = 不限\n  server_url: \"\"                   # 空则回落内置默认 https://devlake.chinawayltd.com\n  server_token: \"\"                 # transcript 路由不读；配了则反馈请求带 Bearer 头\ncp:                                # 可选:CP 审核（默认模板里是注释,按需打开）\n  service:\n    base_url: https://devlake.example.com     # cp request/status 的服务地址,未配即用法错误\n  jira:                            # 只读 Jira 坐标；schema 收下并由 getCpConfig() 回带给上层消费方，\n    base_url: https://jira.example.com        #   当前没有 CLI 命令读它（jira 组走环境变量，两者不共用）\n    read_token: \"\"                 # 输出时脱敏\nfeishu:                            # 可选:sdlc-lite 定稿发布落点\n  folder_token: \"\"                 # 目标文件夹标识（不是凭证,故 config get 回真值不脱敏）；不配则落个人空间根目录\nproducts: {}                       # 可选:地址预设分组(缺产品也能装配)\n#  checkout:\n#    context_repo:   git@git.g7e6.com:sdlc/checkout-context.git\n#    knowledge_base:                # 单个字符串或数组均可\n#      - git@git.g7e6.com:kb/checkout-kb.git\n#      - git@git.g7e6.com:kb/common-kb.git\n#    jira_prefixes:  [PROJ, CHK]    # 便利:jira 号自动带出上面两个地址\n#    description: \"结账支付系统\"    # 可选:展示用产品说明\n#    keywords:                      # 可选:供语义匹配的关键词\n#      - 结账\n#      - 支付\n#      - checkout\n#    epic: DEMO-100                 # 本产品默认 epic/迭代 id（可选，首次装配自动带出）\n#    repos: [backend, frontend]     # 本产品默认要装的逻辑仓 id（可选，对应下方 repos 表的 key）\n#    databases: [checkout-mysql]    # 可选:数据库归属视图,供 db list/search --product 过滤\nrepos: {}                          # 逻辑 id → 地址(顶层全局)\n#  backend:  { remote: git@git.g7e6.com:checkout/backend.git, local: ~/code/backend, base: develop }\n#  frontend: { remote: git@git.g7e6.com:checkout/frontend.git, base: main }\n#  sdlc/backend: { remote: git@git.g7e6.com:sdlc/backend.git }  # 同名项目可用 <group>/<project> 区分\n#  tms/backend:  { remote: git@git.g7e6.com:tms/backend.git }\n```\n\n- 逻辑 id 是**自取的短名**,格式不限,含 `/` 时工作区里按层级落位(`repos/sdlc/backend/`)。不同 group 的同名项目建议写成 `<group>/<project>`,便于在工作区里一眼区分;共享 mirror 按**仓库 URL** 而非逻辑 id 命名,故即便两个 id 同名(或同一 id 改过 remote 地址)也不会取到错的仓。\n- `repos.<id>.local` 存在(`~` 会展开)则**直接用本地路径**建 worktree、不拉 mirror,但建 worktree 前会对本地仓做 best-effort `fetch`(无 remote/离线则静默跳过);否则用 `remote` clone 到全局 mirror。两条路径的 worktree 都基于远程跟踪分支 `origin/<base>`。\n- CLI 通过统一 `addWorktree()` 自动创建 worktree 时跳过用户 Git hooks；该行为不修改全局或仓库 Git 配置，也不影响 worktree 建成后的 commit / merge / rebase / push hooks。\n- `repos.<id>.base` 是该仓新工作区的默认基准分支。实际优先级为 `--repo-base > workspace cache > repos.<id>.base > origin/main > origin/master`；缓存优先可防止全局配置变化后已有工作区重建到另一条基线。\n- `products` 是**可选**的地址预设:通过 `jira_prefixes` 让 Jira 号自动带出 `context_repo` / `knowledge_base`;`description` / `keywords` 供上层 skill 展示与语义匹配;`epic` / `repos` 供装配首次兜底（命中产品后自动带出默认 epic 与代码仓清单，无需再手传 `--epic`/`--repo`）。缺产品不阻断装配,命令行显式地址优先。\n- 配置写入按整体 **strict** schema 校验,顶层只接受这些键:`workspace`、`repos`、`products`、`kb`、`session_collector`、`cp`、`feishu`、`gapi`、`apollo`、`databases`、`archery`。写错一个键名不会被静默忽略,而是当场报错(旧版本遗留的 `kb.collector.schedule_*` 两个字段也因此需手工删除,见下方 kb 段的历史清理说明)。数据库连接字段与完整示例见下方 `db` 命令,应用 token 见 `gapi` 命令。\n- `config get/list/set` 的输出对 password / token / access_key 及其父对象**递归脱敏**。**唯一的窄豁免是 `feishu.folder_token`**:它是目标文件夹标识而非凭证(就写在飞书文件夹 URL 里、本身不授权,鉴权走 `lark-cli` 的 OAuth),脱敏会让 skill 把字面量 `[REDACTED]` 当 token 传下去、只换回一个「文件夹不存在」。\n- `kb.collector.server_url` 是采集服务 base URL,CLI 固定请求 `POST /api/collector/events`;`server_token` 只从配置文件读取,`config get/list/set` 输出会脱敏。\n- 采集失败 outbox 固定在 `<workspaceRoot>/.sdlc/kb/`,不需要配置路径。\n- 测试可用环境变量 `SDLC_CONFIG` 覆盖配置文件路径。\n- `session_collector` 是会话 transcript 采集配置。`exclude` **键缺失**时用内置默认(两个 IDE 自己的日志目录 + `~/.ssh` / `~/.gnupg` / `node_modules`);显式配成空数组视为用户主动清空。`include` 为空即全采,非空则为白名单;`exclude` 始终优先。\n- `session_collector.floor_bytes` 是去抖阈值,语义是「硬崩溃时最多丢多少内容」的上界。两侧取值不同是实测结论,**不要期望触发率一致**:Claude 1MB → 1.50x 放大 / 6% 轮次触发;Codex 单轮就长 143KB,2MB → 1.30x / 42% 触发,调 floor 压不下触发率。\n- 去抖状态落在 `~/.sdlc/session-upload/<sha256(realpath)>.json`,**一文件一 key**。不放 workspace root 是因为 `workspace.root` 可配,改配置等于状态全丢、全量重传;这是本机簿记,与工作区无语义关系。\n- `install` 在配置已存在时会补 `session_collector` 整段默认(已有该段则一律不动,段内缺键也不补)。`server_url` / `server_token` 不写入:后者本期根本不读,而 `server_url` 空串等于回落内置默认 `https://devlake.chinawayltd.com`(见下条)。\n- `session_collector.server_url` 为空时回落内置默认 `https://devlake.chinawayltd.com`。**主机不回落 `kb.collector.server_url`**:上传接口在 devlake 上、kb 事件收集在 `sdlc-knowledge-base.g7in.com` 上,两个服务不同源,回落过去是稳定 404。`session_collector.server_token` 保留但不读(devlake 该路由无鉴权,客户端不发 `Authorization` 头)。投递的批量与超时**不进配置**:`--limit` 默认 20、`--timeout-ms` 默认 30000(单文件 p50 就 225KB、最大实测 14.7MB,kb 那边的 1 秒在这里必然全军超时),两者只由命令行覆盖,hook 会显式传参。\n\n## 命令参考\n\n研发常用命令与配置见 [GAPI / Apollo / DB / KB 速查](docs/gapi-apollo-db-kb.md)；面向人的上手教程见 [使用指南](docs/使用指南.md)。**子命令与参数的最终形态以 `sdlc-cli <组> -h` 为准**（clipanion 直接从命令类生成，不会与代码漂开）。\n\n| 组 | 子命令 | 一句话 |\n| --- | --- | --- |\n| `config` | `init` / `get` / `set` / `list` | 全局单层配置 `~/.sdlc/config.yaml` |\n| `ctx` | `resolve` / `new` / `commit` / `manifest` / `status` / `impact` / `feedback` / `assets` / `modules` / `scaffold` / `init-tech-spec` | 中间产物仓的落位、事务提交与读时计算 |\n| `ws` | `create` / `sync` / `destroy` / `mount` / `unmount` / `which` / `init` | 工作区装配与变更 |\n| `kb` | `send` / `send-batch` / `flush` / `worker` | 知识库事件采集上报（异步落盘 + 投递） |\n| `session` | `collect` / `flush` / `status` / `download` / `backfill` / `feedback` | 会话 transcript 采集、取回、补传与会话反馈 |\n| `deliver` | `plan` / `base set` / `apply` | 多仓 commit + push + GitLab Ready MR |\n| `cp` | `request` / `status` | CP 审核发起与运行态查询 |\n| `jira` | `check` / `get` / `comment` / `update` / `transition` / `link` | Jira 直连（读 / 评论 / 字段 / 流转 / 关联） |\n| `gapi` | `search` / `list` / `detail` | DevCloud API 检索（只读透传） |\n| `apollo` | `get` | Apollo 配置查询（只读透传） |\n| `db` | `list` / `search` / `query` / `schema` / `check` | 配置驱动的数据库只读查询 |\n| `install` | — | 初始化 / 升级合并配置，注册随包 skills |\n\n所有命令支持 `--json` 输出结构化结果,便于 skill / 脚本消费。**两个例外**:`gapi` / `apollo` 组纯透传下游原始数据,无 `--json` 开关。\n\n### `install`\n\n初始化 `~/.sdlc/config.yaml`(缺失则写默认模板;已存在则补缺失的 `gapi.base_url` / `archery.base_url` / `apollo.server_urls` / `session_collector` 整键默认,已有地址和 token/AK 不覆盖、token/AK 不补写、无新增键则文件不动),并把随包 skills 覆盖注册到 `~/.claude/skills` 与 `~/.agents/skills`。skill 复制与升级合并失败只进入告警,不改变退出码。\n\n### `config` —— 全局配置\n\n| 命令 | 说明 |\n| --- | --- |\n| `config init` | 写入默认配置模板(不覆盖已有) |\n| `config get <key>` | 读一项(点号 key,如 `repos.backend.remote`) |\n| `config set <key> <value>` | 写一项(value 经 YAML 解析,支持数组/数字/布尔),写前整体 schema 校验 |\n| `config list` | 打印全部配置 |\n\n### `deliver` —— 多仓交付\n\n交付一个 Jira 的全部已挂载代码仓和 `context-repo`。`plan` 只读，返回\n`plan_id` 以及每仓的 `source -> target`、文件和动作；历史 cache 缺少代码仓\n基准分支时，先用 `base set` 补齐，CLI 不自动采用推荐值。\n\n```bash\nsdlc-cli deliver plan --jira PROJ-123 --summary \"登录改动\" --json\nsdlc-cli deliver base set --jira PROJ-123 --repo-base backend=develop --json\nsdlc-cli deliver apply --jira PROJ-123 --plan <plan_id> --summary \"登录改动\" --json\n```\n\n`apply` 会重新校验 `plan_id`，然后按仓库顺序 commit、push 并创建或复用\nGitLab Ready MR；任一仓失败即停止后续仓库。代码仓目标分支来自 workspace\ncache，`context-repo` 固定为 `master`，不降级到 `main`。命令只支持 GitLab，\n不 force-push、不合并 MR，也不写执行日志。\n\n### `kb` —— 知识库采集上报\n\n`kb` 命令组承接知识召回与知识蒸馏的采集上报。请求体保持服务端旧接口契约:固定 `POST /api/collector/events`,**顶层**字段只包含 `event_type`、`knowledge_base`、`event_time`、`idempotency_key`、`payload`;客户端身份走 `payload.client`(见下文),不新增顶层字段。\n\n**上报一律异步**:`send` / `send-batch` 前台只把事件原子落盘到 outbox 排队(本进程不发网络请求、不等待投递),入 outbox 成功即视为上报成功。\n\n**采集补偿机制**——实际投递统一收口到 `kb flush`(唯一 HTTP 出口),由两类触发源拉起,外加手工 flush:\n\n- **落盘后异步触发**:`send` / `send-batch` 仅在本次**新建** outbox 文件时 best-effort 派生**一个**即弃的 detached 后台 `kb flush`(不等待、不读结果、不改退出码;单条命中同 key 去重(`deduped`)不派生,`send-batch` 无论多少条也只派生 1 次、`queued === 0` 则不派生)。当前入口不是打包产物 `.js` 时跳过(`no-runnable-entry`),仅少一次提速,不影响命令结果。\n- **agents session hook**:同级 `agents` 仓的 session hook 在 Agent 生命周期节点(Claude `SessionStart` / `SessionEnd`、Codex `SessionStart` / `Stop`)前台调用一次 `kb flush --limit 50 --timeout-ms 1500 --include-auth-blocked --json`(总时长由 hook 外层 1500ms 硬超时约束),失败一律吞掉、不阻断会话。\n- **agents session hook**:同级 `agents` 仓的 `session-hook.js` 在 Claude `Stop` / `SessionEnd`、Codex `Stop` / `SessionEnd` / `SubagentStop` 调用 `session collect`(参数见挂载矩阵),薄适配层不做任何判定;`kb-flush-hook.js` 在其既有挂载点并列投递两个 outbox(`kb flush --limit 50` 与 `session flush --limit 20`,两个子进程并发、共用同一个 1500ms 外层硬超时)。两者退出码恒 0,失败一律吞掉、不阻断会话。\n- **手工 flush**:随时执行 `sdlc-cli kb flush` 立即投递。\n\n各触发源跑的都是同一个 `kb flush`,靠 outbox 锁收敛并发(重入返回 `locked: true`、退出码 0)、靠 `idempotency_key` 状态文件保证不重复投递,因此叠加不会重复上报。没有新的 session、CLI 调用或手工 flush 时不会发生网络投递——投递失败的事件保留在 outbox,由下一次触发按退避与幂等规则补报。\n\n> **历史 schedule 清理**(从旧版本升级的用户):本版本已移除 `kb schedule` 定时补偿,不再安装/检查/卸载任何系统定时任务、不再生成 wrapper 脚本。已安装的定时任务**不会自动清理**,需手工删除:Windows 任务 `G7E6SDLCCollectorFlush`(schtasks)、macOS launchd label `com.g7e6.sdlc.collector.flush`、Linux unit `sdlc-kb-collector-flush.timer` / `sdlc-kb-collector-flush.service`,以及 wrapper `~/.sdlc/kb-collector-flush.sh`(Windows `.cmd`)。同时请手工编辑 `~/.sdlc/config.yaml`,从 `kb.collector` 删除 `schedule_auto_install` 与 `schedule_interval_seconds` 两个字段(strict schema 已不再接受,不删会导致 `config set` / `install` 升级合并报错),删除后再执行任意 `config set` 即恢复正常。\n\n| 命令 | 说明 |\n| --- | --- |\n| `sdlc-cli kb send --event-type knowledge_retrieval --knowledge-base <kb> [--payload-encoding utf-8\\|gb18030\\|utf-16le\\|utf-16be] --payload-stdin --json` | 从 stdin 读取**单条** payload JSON(须为对象)并入 outbox |\n| `sdlc-cli kb send-batch [--event-type <t>] [--knowledge-base <kb>] [--payload-encoding utf-8\\|gb18030\\|utf-16le\\|utf-16be] --payload-stdin --json` | 从 stdin 读取**数组** JSON 批量入 outbox,字段与单条完全一致;逐条顺序处理,单条失败不影响其余(整批有失败时退出码 1) |\n| `sdlc-cli kb flush [--limit 50] [--timeout-ms 1000] [--include-auth-blocked] [--force] --json` | 投递 `<workspaceRoot>/.sdlc/kb/events/*.json`;抢锁失败返回 `locked: true` 且退出码 0 |\n| `sdlc-cli kb worker --interval 60 --max-seconds 900 --limit 50 --json` | 手工循环 flush；命令保留，顶层 help 不展示，日常补报直接用 flush |\n\n- **不校验事件类型，也不校验 payload 内容**——payload 只校验「是 JSON」（单条须为对象、批量须为数组；批量的逐项要求为「项是对象、`payload` 是对象、`event_type` 能取到非空值」），**完全原样透传，不删字段、不脱敏、不改写**。CLI 是上报工具，结构与取值由使用方与服务端约定。超 32KB 的 payload 会截断字符串、砍数组、丢最大字段以瘦身，此时打 `payload_truncated: true` 标记。\n  - **唯一例外是最外层的 `agent_platform`**:它标识调用方所在的 AI 工具,属于客户端身份而非业务数据,CLI 会**消费并从 payload 移除**它,归并进 `payload.client` 的 `ai_tool` / `ai_tool_version`(见下)。这是刻意为之,不是漏删。\n- **客户端身份自动补 `payload.client`**:`kb.collector.server_token` 是可选项,未配置 token 时服务端拿不到身份线索,故 CLI 恒定补一份本地弱身份,便于归因到人。\n\n  | 字段 | 来源 | 取不到时 |\n  | --- | --- | --- |\n  | `os_user` | `os.userInfo().username`,失败回退 `USER` / `USERNAME` / `LOGNAME` | 省略 |\n  | `git_user` | `git config --get user.name`(按 cwd 取,仓库级配置覆盖全局) | 省略 |\n  | `git_email` | `git config --get user.email`(同上) | 省略 |\n  | `workspace_id` | 从 cwd 上溯找到的工作区目录名(判据为 `.workspace-cache.yaml` 或 `.sdlc-product.yaml`) | 省略 |\n  | `ai_tool` | payload 最外层 `agent_platform` 的取值(约定 `claude-code` / `codex`),裁掉两侧空白后原样上报 | payload 无该字段、或取值为空/非字符串时省略(连同 `ai_tool_version`) |\n  | `ai_tool_version` | `agent_platform` 取值在已知表内时,执行 `<工具> --version` 抽出的版本号(兼容 `2.1.220 (Claude Code)` 与 `codex-cli 0.147.0` 两种输出格式) | 省略 |\n  | `sdlc_cli_version` | 本 CLI 自身版本,读运行包的 `package.json`(与 `sdlc-cli --version` 同一真源) | 省略 |\n  | `os_platform` | `os.platform()`(`darwin` / `linux` / `win32` 等) | 省略 |\n  | `os_version` | `os.release()` | 省略 |\n\n  ```json\n  { \"event_type\": \"knowledge_retrieval\", \"payload\": {\n      \"session_id\": \"session-1\",\n      \"client\": {\n        \"os_user\": \"dengfuwei\", \"git_user\": \"dengfuwei\", \"git_email\": \"dengfuwei@example.com\",\n        \"workspace_id\": \"PROJ-123\", \"ai_tool\": \"codex\", \"ai_tool_version\": \"0.147.0\",\n        \"sdlc_cli_version\": \"1.0.0\", \"os_platform\": \"darwin\", \"os_version\": \"25.4.0\"\n      }\n  } }\n  ```\n\n  **AI 工具只认 payload 里的 `agent_platform`,CLI 不自行探测。** 调用方(skill)本就会在 payload 最外层带上 `agent_platform`,无需额外参数;CLI 不做任何自动探测——环境变量会继承给整个子进程树(在 Claude Code 里开 shell 再跑 codex,`CLAUDECODE` 仍在),父进程链也会被 wrapper 打断,两种探测都会误判,而错误归因比没有数据更糟。取值不在已知表(`claude-code` → `claude`、`codex` → `codex`)内时仍原样上报到 `ai_tool`,但不取版本:该值来自外部输入,不能直接当可执行命令名执行。同一批(`send-batch`)里各条可带不同 `agent_platform`,逐条独立解析;同名工具的版本在进程内缓存,不重复启动子进程。\n\n  四条约束：① 无开关，恒定上报；取不到的字段直接省略，不发空字符串。② 身份在**入队时**解析并随事件落盘——投递可能发生在别的进程与工作目录，届时再取会拿到与事件无关的身份。③ **不参与 `idempotency_key` 推导**：同一份业务 payload 换机器、改 git 配置、换 AI 工具后仍是同一个键,去重语义不变;`agent_platform` 的摘除也发生在算键**之前**,故键始终能从落盘事件复算出来。④ 注入发生在**瘦身之后**，大 payload 硬裁剪不会丢掉身份（代价是最终 payload 可能略微超出 32KB 自我约束上限）。使用方自带的 `payload.client` 保留其余子字段，同名字段由 CLI 覆盖。\n- stdin 默认自动识别 UTF-8、UTF-16LE/BE(BOM 或 JSON NUL 分布)与常见 GBK/CP936(`gb18030`)；遇到 GBK 字节同时也是合法 UTF-8 的歧义内容时,用 `--payload-encoding gb18030` 或环境变量 `SDLC_KB_PAYLOAD_ENCODING=gb18030` 强制指定。\n- `send-batch` 的数组元素可分属不同知识库;元素内的 `event_type` / `knowledge_base` 优先,缺失时回退到命令行同名参数。\n- outbox 固定为 `<workspaceRoot>/.sdlc/kb/`，包含 `events/`、`corrupt/` 和 `lock.d/`；根目录取配置项 `workspace.root`，配置文件的存放位置不决定队列位置。\n\n### `session` —— 会话 transcript 采集、取回与补传\n\n采集 Claude Code 与 Codex 在本机留下的会话 transcript(JSONL)。设计见 `docs/superpowers/specs/2026-09-09-session-transcript-collect-design.md`,决策编号即代码注释里引的「设计 §Dx」。\n\n与 `kb` 组是**平级的第二条通道**,不是同一个 outbox:transcript 是 MB 级文件,而 kb 事件通道锁定了 32KB payload 上限与唯一 HTTP 出口两条不变量,两种载荷合并会让那条不变量名存实亡。复用的是机制(目录锁、幂等键、指数退避、死信),不是同一个队列。\n\n> **当前进度：M4（hook 接线）+ M6（archive 下载）+ 补传（`session backfill`）**。判定链(M1)+ outbox 落盘与排障视图(M2)+ 投递(M3)+ 两个 IDE 的 hook 接线与两侧 subagent(M4)+ 按会话取整包(M6)+ 一键补传(见下方「补传(`session backfill`)」小节)。服务端两半(上传路由与 archive 路由)都已在 devlake 仓,**补传对服务端零改动**。读取接口(列表 / 详情 / 单文件读)仍在 M5。\n\n| 命令 | 说明 |\n| --- | --- |\n| `sdlc-cli session collect --transcript <abs> --session-id <id> --ide <claude\\|codex> --cwd <abs> [--hook-event <name>] [--final] [--scan-subagents] [--dry-run] --json` | 判定 → 落 outbox 条目；带 `--dry-run` 时只打印判定不写盘 |\n| `sdlc-cli session flush [--limit <n>] [--timeout-ms <ms>] [--force] [--include-auth-blocked] --json` | 唯一 HTTP 出口：抢锁 → 挑条目 → gzip → multipart POST → 回写状态；恒退 0 |\n| `sdlc-cli session status [--limit <n>] --json` | outbox 积压（ready / waiting / auth_blocked / dead / corrupt / pending_bytes）与去抖状态（每文件已上传大小与次数），只读 |\n| `sdlc-cli session download <session-id> [--out <dir>] [--timeout-ms <ms>] [--force] --json` | 按会话 id 拉主会话 + 全部 subagent 的 zip 整包，原样落盘为 `session-<id>.zip` |\n| `sdlc-cli session backfill [--ide <claude\\|codex>] [--session-id <id>]… [--since <ISO>] [--until <ISO>] [--limit <n>] [--force] [--verify-sha256] [--dry-run] [--timeout-ms <ms>] [--retries <n>] [--max-failures <n>] [--git-email <addr>] [--claude-root <dir>] [--codex-root <dir>] --json` | 一键补传：扫全机两侧目录，把没传过的**直传**（不走 outbox）；失败退非 0 |\n| `sdlc-cli session feedback --ide <claude\\|codex> --session-id <id> --title <t> (--content <c> \\| --content-file <path\\|->) [--transcript <abs>] [--with-subagents] [--no-transcript] [--timeout-ms <ms>] [--dry-run] --json` | 记一条「这次会话哪里不对」的用户反馈，连正文一起落库；**唯一由人主动触发**的一条 |\n\n判定链与退出码:\n\n1. `session_collector.enabled` 为 `false` → `state: \"skipped\"`、`reason: \"disabled\"`,退 0。\n2. 路径过滤:`realpath(--cwd)` 后先比 `exclude`(命中即拒)再比 `include`。未命中 → `state: \"skipped\"`、`reason: \"filter-excluded\"`,退 0。过滤用的是 `--cwd` 的**触发时刻**值,不是正文里的会话起始 `session_cwd`——实测 41% 的会话中途换过 cwd,用起始值会让 `cd` 出工作区后的轮次继续被采。\n3. 主文件去抖判定:只 `stat`,不读内容。`size - 上次成功上传的大小 >= floor_bytes` 才上传;首次见到必传;`--final` 对 **subagent 文件**需确有增长才传(不是无条件上传),而**主文件**在 `--final` 时恒传(`reason: \"final-main\"`)——服务端的会话完成标记是单向且不自愈的,只能靠一个带 `final=true` 的请求置上,而 `Stop` 与 `SessionEnd` 之间文件没长是常态。代价是每次会话结束多一个幂等请求(内容没变时服务端返 `200 unchanged`)。\n4. 主文件判定为上传时才发现 subagent:Claude 列 `<transcript 去 .jsonl>/subagents/`,Codex 读父文件收 `sub_agent_activity.agent_thread_id` 后按 id 精确定位(含 `archived_sessions` 回退,不扫日期目录)。因第 3 步的主文件在 `--final` 时恒判上传,`SessionEnd` 恒开这一步——那些在 `Stop` 之后又长了一点、但增量不足 `floor_bytes` 的子文件,尾部内容因此不会漏传。\n5. 判定要上传的文件落进 outbox:`<workspace.root>/.sdlc/session/outbox/entries/<sha256(ide+session_id+file_kind)>.json`,**一条目一文件、存指针不存文件副本**。同一文件重复触发覆盖同一条目(不堆积),故 outbox 大小被「本机活跃文件数」封顶而非「触发次数」。合并规则:`expected_size` 取最新、`final` 一旦 true 保持 true、`cwd` 取最新而 `session_cwd` 保留最早、重试状态(`attempts` / `next_attempt_at` / `auth_blocked` / `dead`)**不因重新入队而重置**。\n\n头部解析同时取 `client_surface`——**运行载体的 wire 原值**,与 `ide`(厂商)是两个维度:Claude 取头部行的 `entrypoint`(`cli` / `sdk-cli`),Codex 取首行 `payload.originator`(`codex-tui` 终端 / `codex_work_desktop` 桌面 App)。两侧都不归一成统一词表(归一表放哪一侧,那一侧就得跟着上游出新取值改代码),取不到写 `null`;与 `session_cwd` 共用同一次前 5 行读取,额外 IO 为零,且同样恒取**父会话**的值。\n\n`--final` 且某个 subagent 文件本轮没长过(判定为 `below-threshold`)时,若条目已在队未投成,则**只给它补一次 `final` 标记**,不新建条目、不产生新的上传。这样 `SessionEnd` 的完成信号不会因为「这一轮没新内容」而丢失。条目已投成(被删)时补不上,那一半由主文件的 `final-main` 兜底。`--json` 顶层的 `queued` / `merged` / `final_patched` 就是这三种落盘结果各自的计数——`merged` 不是「什么都没做」,它把 `expected_size` 与 `final` 合进了已有条目;`failed` 是落盘写失败的文件数(逐个文件隔离,不影响其余文件,退出码仍是 0)。\n\n#### 投递(`session flush`)\n\n一次性进程,**不驻留、不自排程**:抢 outbox 锁 → 按状态挑至多 `--limit` 条(默认 20)→ **串行**发送 → 退出。抢不到锁返回 `locked: true` 并退 0,不排队等待(下一次 hook 还会再来)。\n\n请求是 `POST <server_url>/api/ai-coding/transcript-sessions/files`(服务端在 devlake,默认 `https://devlake.chinawayltd.com`),`multipart/form-data` 两段:`meta`(JSON)与 `file`(`filename` = `main.jsonl.gz` / `agent-<id>.jsonl.gz` / `agent-<id>.meta.json`)。该路由无鉴权,客户端不发 `Authorization` 头。`.meta` 走 `encoding: identity` **不压缩**(143 字节 JSON,gzip 后反而更大,且服务端要直接当 JSON 读),其余走 gzip。gzip 放在 flush 而非 collect:collect 在 hook 的 1.5 秒预算内,压 2.7MB 要几百毫秒。\n\n`meta.size` / `meta.sha256` 一律按**实际读到的明文字节**算,**不用条目里的 `expected_size`**(那只是入队快照,仅供排障对比)。入队后文件又长了时传的就是新版本——这正是全文替换语义想要的,因为下次上传本来也要覆盖它。\n\n响应码 → 条目动作:\n\n| 码 | 动作 |\n| --- | --- |\n| `201` / `200` | 删条目;去抖状态推进 `uploaded_size`(明文字节)与 `upload_count` |\n| `400` / `413`、其余 4xx | 标 `dead` 留在盘上,`session flush --force` 可重试(attempts 归零) |\n| `401` / `403` | 标 `auth_blocked`,**不加退避、不自增 attempts**;token 修好后自愈 |\n| `408` / `429` / `5xx` / 网络 / 超时 | 指数退避写 `next_attempt_at`(60/120/300/900/1800/3600 秒,30 次判死信) |\n\n三种不发请求的情形:源文件已删除 → **丢弃条目**(`discarded` 计数,不留死信,`--force` 一万次也不会成功);源文件为空 → 走退避留在队里(全文替换语义下上传空内容会把服务端已存的好版本整体覆盖掉);超 `session_collector.skip_files_larger_than` → 丢弃(省一次注定 `413` 的 MB 级上传)。\n\n`--json` 的五个计数:`flushed`(已投)/ `failed`(留在盘上)/ `skipped`(被规则挡掉,没发请求)/ `discarded`(条目已删,没发请求)/ `corrupt`(条目文件读不出来,已搬进 `.sdlc/session/outbox/corrupt/`)。`--limit` 只约束 `flushed + failed`——它要控的是网络往返,不是 `stat` 与 `readdir`。\n\n`--force` 与 `--include-auth-blocked` **刻意正交**:前者覆盖「退避未到点」与「已判死信」,后者覆盖「token 不对」。合并会让 `--force` 每次都捞上一批注定 401 的条目白发请求。\n\n**投递触发有三层**(设计 §D7),都跑同一个 `session flush`、共用同一把锁:① `collect` 落盘后 best-effort 派生**一个**即弃的 detached `session flush`(`queued` 或 `merged` 时派生,整次命令最多 1 个进程,绝不按文件条数派生;`final_patched` 不派生);② 下一次任意 hook 触发时,`collect` 发现 `size - last >= FLOOR` 仍成立会重新入队(覆盖式,无副作用)——这是全文替换带来的自愈;③ M4 起 `agents` 侧 hook 在 SessionStart / SessionEnd 并列前台调一次。**没有定时任务、没有常驻进程**:彻底不再开 IDE 时,最后那批没投成的条目会一直躺在 outbox 里,这是刻意接受的语义。\n\n去抖状态(`~/.sdlc/session-upload/`)**由投递写、不由 collect 写**:`uploaded_size` 只在上传成功后才推进(反序会在失败时永久跳过那段内容),写的是**明文**字节数,与 `statSync().size` 同口径。`upload_count` 同样在这里自增——它是去抖效果的唯一观测口径,刻意不进服务端。\n\nsession 通道与 kb 事件通道是**刻意的两条通道,不要合并**:那条走 32KB JSON 小事件,这条走 MB 级文件指针;复用的是机制(目录锁、幂等键、指数退避、死信),不是同一个队列。两者是 `.sdlc/` 下的同级兄弟,互不嵌套——`ls <workspace.root>/.sdlc` 的直接子目录即「有哪几条通道」:\n\n```\n<workspace.root>/.sdlc/\n├── kb/                  # kb 事件通道\n│   ├── events/\n│   ├── corrupt/\n│   └── lock.d\n└── session/             # session transcript 通道\n    ├── outbox/\n    │   ├── entries/\n    │   ├── corrupt/\n    │   └── lock.d       # flush 的投递锁\n    └── backfill/\n        └── lock.d       # 补传的独占锁,与 flush 那把刻意分开\n```\n\nsession 侧刻意多一层 `outbox/`(kb 侧是 `.sdlc/kb/events/`、没有中间层):session 通道下有**两件**东西,把补传锁塞进 outbox 根会让 outbox 根同时装条目和外来锁,将来给 outbox 根加一次清理就会连带端掉补传锁。\n\n> **旧路径迁移(2026-09-14)**:session 的 outbox 与补传锁曾在 `<workspace.root>/.kb/session-outbox/` 与 `.kb/session-backfill/`,现统一迁到 `.sdlc/` 下与 kb 通道同级。**CLI 不扫描、不自动迁移旧目录**(照 kb 通道 2026-09-09 那次的先例):旧机器上如有积压条目,手工 `mv <workspace.root>/.kb/session-outbox/entries/*.json <workspace.root>/.sdlc/session/outbox/entries/` 即可,条目文件名与内容不变。`.kb/session-backfill/` 下只有瞬态锁,直接删。去抖状态 `~/.sdlc/session-upload/` **不在本次迁移范围**——它派生自配置文件所在目录(为的是让 `SDLC_CONFIG` 同时隔离配置与状态),跟着 `workspace.root` 走会让改配置等于状态全丢。\n\n**用法错误退 2,其余采集路径自身的判定恒退 0**:过滤未命中、未达阈值、transcript 不存在一律算成功,采集是旁路,绝不因它让 hook 失败。**落盘失败也不例外**——目录不可写、磁盘满等写失败逐个文件隔离(一个文件失败不影响其余文件落盘),计进 `--json` 的顶层 `failed` 并附 `SESSION_ENTRY_WRITE_FAILED` 警告,退出码仍是 0。唯一的例外是配置文件本身损坏(`~/.sdlc/config.yaml` 解析失败)——这会让仓库里所有命令一样失败,`session collect` 不特殊化,按 `ctx` / `kb` 等命令统一的业务错误退 1。\n\n`--ide` **不自动探测**,沿用 `kb` 组 `resolveAiToolIdentity` 的立场:环境变量会继承给整个子进程树、父进程链会被 wrapper 打断,两种探测都会误判,而错误归因比没有数据更糟。\n\n**文件身份从文件自身推导,不信 `--session-id`**:Claude 看路径是否在 `.../<session-id>/subagents/` 下,Codex 看首行 `payload.thread_source`。命中即 `session_id` 取父、`file_kind` 取 `agent-<id>`。这样「父会话扫描」与「子文件被单独递进来」两条路径产生完全相同的身份,不会因触发顺序不同而漂移。`file_kind` 取值为 `main` / `agent-<id>` / `agent-<id>.meta`(`.meta` 仅 Claude)。\n\n#### 补传(`session backfill`)\n\n```bash\nsdlc-cli session backfill --dry-run          # 先看要传什么，零请求\nsdlc-cli session backfill                    # 扫全机、直传所有没传过的\nsdlc-cli session backfill --ide claude --since 2026-08-01\nsdlc-cli session backfill --session-id <id> --limit 20 --json\n```\n\n主链路是 **hook 驱动、只采当前会话**的,这留下三个缺口:hook 从未装过 / 装错了 / 某段时间被关掉;hook 装了但投递一直失败且**源文件已被清理**;换机器、`~/.sdlc/session-upload/` 被清、`workspace.root` 改过。三者共同的形状是「本机磁盘上有完整的 transcript,服务端没有,而投递的三层补偿一层都够不着」——它们都以「条目还在 outbox 里」为前提。`session backfill` 是补这三个缺口的**第二条上传路径**。\n\n**不走 outbox**:读文件 → gzip → multipart POST,串行、进程内完成,不落条目、不排队、不退避。服务端零改动(复用同一个上传路由与 `kb.session.v1` 契约)。\n\n四条必须记牢的语义:\n\n- **一律不发 `final`**:服务端 `complete` 列是单向 0→1、撤销要手工改库,而补传是事后动作,没有任何本地信息能可靠证明一个会话真的结束了(「按 mtime 判闲置」会把「闲置 30 分钟后又继续」的真实会话误标成完成,且误标不自愈)。`meta.final` 显式发 `false`、不省略该键。代价明确且已接受:**hook 从未装过的那批历史会话 `complete` 恒为 0**,按 `complete` 筛选的看板口径覆盖不到它们;那些会话日后再被打开时 `SessionEnd` 会正常置上。\n- **完全无视 outbox**:不读、不写、不删条目,**不抢 flush 那把锁**(用自己的 `<workspace.root>/.sdlc/session/backfill/lock.d`)。共用锁会让 backfill 首轮那十几分钟里所有 hook 触发的投递空转,而那正是主链路的常态路径。代价是重叠文件下次 `flush` 会白发一次拿 `200 unchanged`。有一个反直觉的正面效果:backfill 成功后**推进去抖状态**,于是 hook 那侧下次判 `below-threshold` 而不重传整份文件——两条路径共用同一份 `~/.sdlc/session-upload/` 簿记,「这个文件已经传到多大」只有一个真源。\n- **身份解析按 `session_cwd` → `process.cwd()` → `--git-email` 回落**,顺序不可调。服务端 `storage_path` 与 `user_key` 是 first-write-wins,而 `user_key` 由 `git_email` 的 local part 推出;会话的 `session_cwd` 已被删(工作区销毁是常态)时 `git config` 取不到值 → 落 `os-<os_user>` → 与 hook 当初写的不同 → 字节落进新目录而会话行仍指向旧目录,**那批 `file_kind` 不可达且不自愈**。「hook 传了一半、事后 backfill 补剩下」正是本命令最常见的用法,所以这不是理论风险。已销毁工作区拿不到 `workspace_id` 是可接受的次要退化(服务端身份列在值为 `None` 时保持原值,不会污染 hook 写过的好值)。\n- **时间窗按 `session_started_at`,不按文件 mtime**:mtime 是「最后一次追加的时刻」,一个跨天的长会话 mtime 落在结束那天,按它筛会把会话归到错误的日期。`session_started_at` 本来就必须读(它决定服务端的目录段),故这么筛是零额外成本。\n\n判「已传过」**只比字节数**(`size === uploaded_size` 即跳过),与去抖判定同口径。transcript 是只追加文件,「长度不变而内容变了」在正常路径上不存在;要严格比对加 `--verify-sha256`(会把全部内容读一遍算哈希)。补传**不看 `floor_bytes`**——那是「硬崩溃时最多丢多少」的上界,与「这份历史文件传没传过」无关。\n\n**遵守 `session_collector.enabled`**:配成 `false` 时拒绝执行并退 1。那个开关的语义是「不要上传我的 transcript」,一次批量补传正是它该挡住的动作,「人主动敲的」不构成例外。\n\n失败处理没有队列可退避,所以要么当场重试、要么当场停:`5xx` / `408` / `429` / 超时 / 网络错误进程内重试 `--retries` 次(退避 1s、3s);`400` / `413` 及其余 4xx 不重试(请求本身不对);`401` / `403` **立刻中止全局**(配置问题,后面几百个必然同样失败);连续失败达 `--max-failures`(默认 10)也中止,**遇成功即归零**。\n\n**串行,不并发,不提供 `--concurrency`**:单文件最大实测 14.7MB,并发几路会同时占住带宽;且服务端 17-POST 扇出的死锁风险是主链路已 park 的问题,补传一次几百个文件没有理由主动去撞它。\n\n退出码(照 `session download` 的立场,人主动敲的命令失败必须退非 0):\n\n| 码 | 含义 |\n| --- | --- |\n| `0` | 全部成功,或全部已传过(含 `--dry-run`) |\n| `1` | 有文件失败;或 `session_collector.enabled` 为 `false`;或抢不到锁 |\n| `2` | 用法错误(`--since` 不是合法时间、`--ide` 取值非法、`--limit` 非正整数等) |\n| `3` | 中止(`401` / `403` 鉴权失败、超 `--max-failures`) |\n\n`--json` 的计数:`scanned`(枚举到的候选会话数)/ `planned`(判定要传的文件数)/ `uploaded` / `unchanged` / `failed` / `skipped` / `not_attempted`(被 `--limit` 截断或中止后没轮到的)/ `bytes`(实际上行的明文合计)/ `elapsed_ms` / `aborted`,外加 `skipped_by_reason` 分类计数与 `files[]` 明细。跳过原因有 `already-uploaded` / `missing-started-at` / `empty` / `too-large` / `source-missing` / `unknown-cwd` / `path-excluded` / `out-of-window` / `subagents-disabled`。文本模式**逐文件流式打印**(500+ 文件不能憋到最后才出声),`--json` 只在末尾发一个信封。\n\n#### 会话反馈(`session feedback`)\n\n```bash\nsdlc-cli session feedback --ide claude --session-id \"$CLAUDE_CODE_SESSION_ID\" \\\n  --title \"改完测试没跑就说完成了\" --content-file - --json\n```\n\n本组唯一**由人主动触发**的命令:把「用户觉得这次会话哪里不对」连同当次正文一起落库——那条信息事后无论怎么解析 transcript 都重建不出来。\n\n- **先落盘、再发送、成功才删**(与 transcript 侧相反的可靠性口径):transcript 传丢了下次 hook 会重传,**反馈传丢了就真丢了**。崩在 POST 中间时条目还在盘上;发成功而进程被杀,最坏是下次 drain 白发一次拿 `200 unchanged`。落盘条目由 `session flush` 顺带投递(额度独立,见 `session_collector.feedback_flush_limit`,默认 20、`0` 为不限——不占 transcript 的 `--limit`,否则一批大文件会把用户的反馈挤到下一轮)。\n- **`payload` 整块不可变**:投递时原样发出、不重算任何字段。transcript 每次 flush 都按实际字节重算 `size` / `sha256`(文件会长),反馈没有「会长」这回事,重算只会引入落盘值与发出值的漂移。\n- **`--session-id` 必填,CLI 不猜**:猜错的后果是把反馈静默挂到别人的会话上、事后无人发现,宁可当场报取不到 id(Claude 取 `$CLAUDE_CODE_SESSION_ID`,Codex 取 `$CODEX_SESSION_ID`)。`--ide` 同样不自动探测。\n- **正文默认强制推一次**(不等去抖),只推主文件;`--with-subagents` 连子会话一起推,`--no-transcript` 只落反馈不推正文。反馈落库与正文上传是**两件独立的事**,正文没传成不影响反馈已落库(输出第二行会写「已排队」,会话结束时自动补传)。\n- 长度上限:`--title` ≤ 200 字符,正文 ≤ **16383** 字符(与服务端 `text` 列按全 4 字节字符换算的容量同值;客户端取更大值会让超出那段吃 413,而 413 记死信不重试 = 丢掉一条不可重建的反馈)。多行正文一律走 `--content-file`(`-` 读 stdin)。\n- 端点 / token / 超时**不新增顶层配置键**,与 transcript 同源(同一服务、同一 blueprint);`schema_version` 固定 `kb.session.feedback.v1`,不复用 `kb.session.v1`。默认超时 10000ms(几 KB 的 JSON,且用户正在等)。\n- 反馈是 **append-only**:提交后改不了,想改口就再提一条,两条都留着。别和 `ctx feedback add` 搞混——那个反馈 PRD 正文的缺口、落 context-repo 给需求方看,本命令反馈 AI 会话的问题、落 devlake 给工具建设方看。\n\n#### 取整包(`session download`)\n\n```bash\nsdlc-cli session download ddfcb3b9-f80e-4ad5-8a47-783fccfb1ce9 --out ./tmp --json\n# → ./tmp/session-ddfcb3b9-f80e-4ad5-8a47-783fccfb1ce9.zip\n```\n\n`GET <server_url>/api/ai-coding/transcript-sessions/<session_id>/archive` → **原样落盘,不解包**。包内是主会话与全部 subagent(设计 §D13):\n\n```\nsession-<id>.zip\n  manifest.json                        ← 固定首条目,从服务端两张索引表生成\n  main.jsonl.gz                        ← 服务端磁盘字节原样,零解压零重压\n  agent-<id>.jsonl.gz\n  agent-<id>.meta.json                 ← Claude 才有\n```\n\nzip 用 **stored 模式**(不压缩):内容已经是 gzip,再压一遍压缩率退化到接近 1.0。选 zip 而非 tar 是因为消费方包含浏览器回放页面——那边有 `fflate` / `JSZip` 现成,解 tar 要自己写解析器。\n\n`manifest.json` 是**首条目**,让流式消费方读到第一个条目就知道整包结构。它带 `client.*` 七列与父子关系、调用点(`tool_use_id` / `spawn_depth` / `agent_type`),消费端解包即可**离线**重建全部关系,不必回连服务端。要把一个会话交给别人,走这个命令而不是 rsync 目录。\n\n**缺文件标记而不是报错**:服务端 DB 有行、磁盘找不到时,该条目在 `manifest.files[]` 里标 `\"missing\": true` 且不在包里,接口仍返 200。其余文件仍可用,消费端能明确知道缺了哪个。\n\n**只能传父会话 id,子会话不单独成包**:子 agent 不占会话行(服务端会话表唯一键是 `session_id`,子文件只在文件表占 `(session_id, agent-<id>)` 一行),所以传 subagent 自己的 id 必然 404。但那种 404 会**反查出父会话 id 并告诉你**:\n\n```\n$ sdlc-cli session download a168a989331390044\nerror: a168a989331390044 是 subagent 的 id,子会话不单独成包——它随父会话\n       ddfcb3b9-f80e-4ad5-8a47-783fccfb1ce9 一起打包。\n       请改用:sdlc-cli session download ddfcb3b9-f80e-4ad5-8a47-783fccfb1ce9\n```\n\n三种输入形态都认(裸 `agent_id`、`agent-<id>`、`agent-<id>.meta`),它们在服务端归一成同一个查询键后走 `idx_transcript_file_agent` 索引。这次反查**只发生在 404 路径上**,正常出包一次都不查。旧服务端不带 `parent_session_id` 时客户端退回通用文案,两侧无需同步上线。\n\n要某个 subagent 的正文就下父会话的包,从里面取 `agent-<id>.jsonl.gz`——`manifest.json` 里有它的 `agent_id` / `tool_use_id` / `description` / `spawn_depth`,认得出是哪个。\n\n**落盘走 tmp + rename**:直接写目标名会在中途失败(网络断、磁盘满、Ctrl-C)时留下一个长度不足却看起来正常的 zip,而 zip 的坏损要解包才发现。校验只有一条——服务端声明的 `Content-Length` 与实际写入字节相等(stored 模式下服务端能精确预计算该值),通过才改名,故目标路径要么不存在、要么是一个完整的包。服务端未发该头时跳过校验(设计允许的形态)。客户端**不解析 zip 内容**,包里有什么是消费方的事。\n\n**退出码与本组其余命令相反**:`collect` / `flush` / `status` 恒退 0(采集是旁路,绝不因它让 hook 失败),而 `download` 是人主动敲的,失败必须退非 0——否则 `sdlc-cli session download X && analyze session-X.zip` 会在 404 之后照样跑下一步。\n\n| 退出码 | 情形 |\n| --- | --- |\n| `0` | 落盘成功 |\n| `1` | 目标文件已存在（加 `--force` 覆盖） |\n| `2` | 参数不合法（空 session-id、`--out` 指向普通文件、`--timeout-ms` 非正整数） |\n| `3` | `404` 会话不存在（或传了 subagent id，此时报 `SESSION_ARCHIVE_IS_SUBAGENT` 并带 `parent_session_id`）/ `401`·`403` 鉴权 / `5xx` / 网络不可达 / 超时 / 下载被截断 |\n\n端点与鉴权复用投递侧的同一组配置键(`session_collector.server_url` / `server_token`):两个方向打的是同一个服务,分成两个键会让「传上去了但拉不下来」变成一类可配置出来的故障。devlake 该 blueprint 目前无鉴权校验,但配了 `server_token` 就照契约发 `Bearer`——服务端将来加校验时客户端不必改代码、不必同步上线。\n\n### `ctx` —— 中间产物仓库\n\n> **context-repo 根定位(所有 `ctx` 子命令通用)**:①显式 `--repo <路径>` → ②从 cwd **向上查找**(目录同时含 `prds/` 和 `requirements/` 即为根)→ ③按 workspace id fallback → ③.5 **仅 PRD 实体**:按 PRD id 反查 `products_root` 下带 `.sdlc-product.yaml` 标记的产品工作区(唯一命中即用,多命中报错要求 `--repo`)→ ④从 cwd 向下探一层。因此**只要 cwd 在 context-repo 内(或其子目录),`--repo` 可省略,无需装配 workspace 即可就地运行**;cwd 不在 repo 内时用 `--repo <路径>`(当前目录即 repo 根可用 `--repo .`)。零环境依赖类 skill(如 `generating-tests`、`requirement-split-estimator`)据此在 context-repo 下直接落库,不强制走 workspace。\n>\n> 来源③.5 补的是这个缺口:③的匹配式是 `<root>/<x>/<id>/context-repo`,而产品工作区目录名是**产品名**(`<产品>-product`),永远匹配不上 PRD id——没有③.5 时「已 `ws init` 建好产品工作区、但 cwd 不在其中」会照样落空、skill 降级 pwd 留档,而同处境下 `ws which` 靠标记能命中,两条路能力不对等。**例外**:`ctx scaffold` 建的是还不存在的 PRD、无 id 可反查,故不吃③/③.5,须 cwd 在仓内或显式 `--repo`。\n\n| 命令 | 关键选项 | 说明 |\n| --- | --- | --- |\n| `ctx resolve` | `--jira` / `--prd` / `--asset`,可选 `--kind`、`--repo` | 解析实体根目录或某类产物落位目录 |\n| `ctx new [kind]` | `--jira` 或 `--prd`,可选 `--name`(默认 `draft`)、`--repo` | 在落位目录创建带 frontmatter 的空壳 `.md` |\n| `ctx commit <entity>` | `-m/--message`,可选 `--local`、`--dry-run`、`--repo` | 事务提交该实体的中间产物改动,**提交后默认 `push -u origin <当前分支>`**(远程无同名分支则新建);`--local` 只提本地不推;推送失败只报 `PUSH_FAILED` / `PUSH_SKIPPED` warning,退出码仍 0 |\n| `ctx manifest get <entity> <key>` | 可选 `--repo` | 读 manifest 字段 |\n| `ctx manifest set <entity> <key> <value>` | 可选 `--repo` | 写 manifest 字段 |\n| `ctx status <entity>` | 可选 `--repo` | 查看 Jira 派生阶段(仅 Jira 有定义) |\n| `ctx impact` | `--prd` 或 `--asset`,可选 `--repo` | 分析 PRD / 共享资产的本地改动与受影响 Jira |\n| `ctx feedback add` | `--prd`、`--type <defect\\|supplement>`、`--from-jira`、`--title`,可选 `--repo` | 追加一条 PRD 反馈(下游发现的缺陷/补充) |\n| `ctx feedback list` | `--prd` 或 `--jira`,可选 `--type`、`--open`、`--repo` | 列反馈(读时扫 `feedback/`) |\n| `ctx feedback digest --prd <id>` | 可选 `--repo` | 聚合 open defect 成待回写清单 |\n| `ctx assets list` | 可选 `--type`、`--group-by type`、`--repo` | 列共享资产(读时扫 `assets/<id>/manifest.yaml`,`--group-by` 目前只支持 `type`) |\n| `ctx modules` | 可选 `--repo` | 列 `prds/` 下的功能模块及各自 PRD 数(判据:无 `manifest.yaml` 的目录才是模块) |\n| `ctx scaffold <prd>` | `--module <name>` 或 `--no-module`,可选 `--title`、`--repo` | 创建 PRD 骨架(新结构 01-04 目录 + `manifest.created_at`) |\n| `ctx init-tech-spec` | `--jira`,可选 `--mode <explore\\|bounded\\|lite-spec\\|full>`、`--done`、`--repo` | 幂等创建 `requirements/<jira>/tech-spec/manifest.yaml`(已存在不覆盖);详见 [ctx-init-tech-spec](docs/ctx-init-tech-spec.md) |\n\n`ctx feedback`:下游(技术方案)发现「PRD 需要改」时,就近沉淀为 append-only 反馈,落 `prds/<PRD>/feedback/`,不阻塞方案设计。`type` 只有 `defect`(PRD 缺陷待回写)/`supplement`(技术侧补充不必回写)两值;id 形如 `FB-<YYYYMMDDTHHmmss>-<rand4>`(时间戳+随机后缀,多 Jira 并发写同一 PRD 不撞名)。`list` 的 `--prd`/`--jira` 二选一(`--jira` 跨多 PRD 反查),`--open` 只留未闭环。闭环 = 人工把 `FB-*.md` 移入 `feedback/resolved/`,「是否闭环」由文件所在目录读时算出,不存状态字段。**本次不实现「据 digest 更新 PRD 正文」那一步(digest 到清单为止)。**\n\n`ctx new/resolve` 的合法 `kind`(即路由表 `ROUTES` 的全部键,新增产物类型 = 加一行、skill 零改动):\n\n| kind | 挂在 | 落位（旧结构 → 新结构） |\n| --- | --- | --- |\n| `prd-doc` | PRD | `prds/<id>/prd/` → `prd/02_ai_output/` |\n| `origin-input` | PRD | `prds/<id>/prd/01_origin_input/`（仅新结构） |\n| `iterate` | PRD | `prds/<id>/prd/04_iterate/`（仅新结构） |\n| `req-analysis` | PRD | `prds/<id>/req-analysis/` → `prd/02_ai_output/` |\n| `prototype` | PRD | `prds/<id>/prd/prototype/` → `prd/03_prototype/` |\n| `test-cases` | PRD | `prds/<id>/test-cases/cases/` |\n| `estimation` | PRD | `prds/<id>/estimation/` |\n| `tech-spec` | Jira | `requirements/<id>/tech-spec/` |\n| `task-breakdown` | Jira | `requirements/<id>/task-breakdown/` |\n| `plan` | Jira | `requirements/<id>/plan/` |\n| `retro` | Jira | `requirements/<id>/retro/` |\n| `test-run` | Jira | `requirements/<id>/test-runs/` |\n| `asset` | asset | `assets/<id>/`（自挂，无二级子路由） |\n\n新旧结构自动分发:PRD 目录下存在 `prd/02_ai_output/` 即判为新结构,该 kind 有 `dirNew` 时优先用它。位置参数 `<entity>` 会自动判别:`PRD-*` 为 PRD,其余为 Jira;`--jira` / `--prd` 入口显式指定实体类型,共享资产只经 `--asset` 进入(不可字面判别的第三实体,首次 resolve 即视为创建、不校验父实体)。\n\n### `ws` —— 工作区装配与变更\n\n- `ws create` —— 装配工作区（缺信息时以 needs 协议回报，见下方说明）\n- `ws sync` —— 同步工作区\n- `ws destroy` —— 销毁工作区\n- `ws mount` / `ws unmount` —— 挂载/卸载代码仓或知识库\n- `ws init --product <name> [--root <path>]` —— 初始化产品工作区（克隆 context-repo 到 `<products_root>/<product>-product/context-repo`、克隆知识库到 `knowledge/<name>`，在工作区根写 `.sdlc-product.yaml` 标记（含两者仓库地址）+ `CLAUDE.md`/`AGENTS.md` 引导）\n- `ws which [--repo <path>] [--product <name>] [--prd <id>] [--new-prd]` —— 定位当前产品工作区（按优先级梯度：显式 repo/product → cwd 向上 → 单 PRD 命中 → 单候选 → 歧义/缺失需求）；候选只取 `products_root` 下带标记的目录，回带 `workspace_kind` 标明命中来源\n\n> 具体子命令形态以 `sdlc-cli ws -h` 为准。装配缺信息时以 needs 协议回报,常见码:`CONTEXT_REPO_MISSING`、`KNOWLEDGE_MISSING`、`REPO_REMOTE_MISSING`、`PRD_REF_REQUIRED`(dev 必填,回带 `candidates[]`;`--epic` / `--title` 非必填,缺省不报 need);非阻断告警包含 `PRD_REF_NOT_FOUND`(给的 PRD 尚不在 context-repo,仍先装配)、`ALREADY_PRESENT` 等。\n\n`ws create` 的选项:`--jira` / `--prd`(二选一)、`--product`、`--epic`、`--title`、`--context-repo`、`--knowledge`(可重复)、`--prd-ref`、`--repo`(可重复)、`--repo-remote <id>=<url>`(可重复)、`--branch`、`--repo-base <id>=<分支>`(可重复)、`--module` / `--no-module`。`ws sync <entity>` 只对 context-repo 做 `pull --rebase`,**不 push、不动代码仓 worktree**(全仓库唯一的 `pull --rebase` 点);`ws destroy <entity>` 先注销各 worktree 再删工作区目录,**共享 mirror 与 `.kb-shares` 不删**。`ws unmount` 在工作树脏时报 `REPO_DIRTY` / `KNOWLEDGE_DIRTY`,确认丢弃才加 `--force`。\n\n### `jira` —— Jira 直连（REST v2 + Basic auth）\n\n登录信息按「环境变量 > 内置默认」解析:`JIRA_SERVER`(默认 `https://issues.chinawayltd.com/`)、`JIRA_USERNAME`、`JIRA_PASSWORD`。**不读 `~/.sdlc/config.yaml`**——`cp.jira.*` 是 CP 审核那条链路自己的只读配置,两者不共用。\n\n**全组写命令默认 dry-run**:`comment` / `update` / `transition` / `link` 缺 `--confirm` 时只回将提交的 payload,不发请求、不解析凭证。\n\n| 命令 | 关键选项 | 说明 |\n| --- | --- | --- |\n| `jira check` | — | 报告凭证与鉴权状态;**缺凭证不算失败**（`state: \"auth-missing\"`,退 0） |\n| `jira get` | `--jira`,可选 `--field`(可重复) | 读 issue;缺省读默认字段集 |\n| `jira comment` | `--jira`、`--body`,可选 `--dedupe-marker` / `--upsert-marker`、`--confirm` | 加评论;`--dedupe-marker` 命中即跳过,`--upsert-marker` 无匹配则新增、单条匹配则跳过或更新、多条匹配报 `JIRA_COMMENT_MARKER_CONFLICT`（两个 marker 互斥） |\n| `jira update` | `--jira`、`--set <字段>=<JSON 或裸串>`(可重复),可选 `--confirm` | 改字段 |\n| `jira transition` | `--jira`、`--to <状态名>`,可选 `--max-steps`(默认 6)、`--confirm` | 流转到目标状态,自动多步寻路 |\n| `jira link` | `--from`、`--to`,可选 `--type`(默认 `Relates`)、`--confirm` | 建 issue 关联 |\n\n错误码:`JIRA_AUTH_MISSING` / `JIRA_KEY_INVALID` / `JIRA_SET_INVALID` / `JIRA_ARG_INVALID` / `JIRA_COMMENT_EMPTY` / `JIRA_UPDATE_EMPTY` / `JIRA_COMMENT_MARKER_EXCLUSIVE` / `JIRA_COMMENT_UPSERT_MARKER_EMPTY` / `JIRA_TRANSITION_TARGET_EMPTY` / `JIRA_SERVER_INVALID`（exit 2）；`JIRA_TRANSITION_NO_PATH` / `JIRA_TRANSITION_MAX_STEPS` / `JIRA_COMMENT_MARKER_CONFLICT` / `JIRA_COMMENT_ID_MISSING`（exit 1）；`JIRA_AUTH_FAILED` / `JIRA_NOT_FOUND` / `JIRA_BAD_REQUEST` / `JIRA_SERVER_ERROR` / `JIRA_REQUEST_FAILED` / `JIRA_UNREACHABLE`（exit 3）。\n\n### `cp` —— CP 审核\n\n```bash\nsdlc-cli cp request --jira PROJ-123 --cp CP3 --material <url>#<version> --reviewer zhangsan --json\nsdlc-cli cp request --jira PROJ-123 --cp CP3 --material <url>#<version> --self-review --json\nsdlc-cli cp status  --jira PROJ-123 [--cp CP3] --json\n```\n\n- `--cp` 只接 `CP1`..`CP6`（其余为用法错误）。`--material` 同时给出材料地址与版本,版本缺失回 `MATERIAL_VERSION_MISSING`。\n- 未指定 `--reviewer` 时回 `REVIEWER_MISSING`;`--self-review` 表示执行人自审并自动按通过处理（`review_mode: \"self\"`）。\n- 执行人身份取 `resolveClientIdentity(cwd)` 的 `git_email`,取不到即用法错误（`cp_executor_email_missing`）——审核记录必须归因到人。\n- 幂等键由 `jira + cp + material_version` 推出,同一材料版本重复发起不产生第二条审核。\n- 服务地址取 `cp.service.base_url`,未配即用法错误（`cp_service_config_missing` / `cp_service_base_url_missing`）;请求打 `POST /api/cp-review/requests`,查询打 `GET /api/cp-review/status`。旧配置的 `cp.builder.trigger_url` 作为兼容回退仍被接受（`cp.service` 缺失时由它推导服务根地址），但仅当该 URL 以 `/api/cp-review/requests` 结尾且不带 query / hash / 用户名密码——否则报错要求手工改成 `cp.service.base_url`。\n\n### `db` —— 数据库发现、查询与检测\n\n连接与凭证仅取 `~/.sdlc/config.yaml`,命令引用精确的 key/env,支持 MySQL direct、MySQL Archery、Redis direct 三种组合。SQL/cmd 通过简单只读校验后使用配置账号执行;认证、权限与执行错误由数据库或 Archery 返回。\n\n| 命令（均支持 `--json`） | 作用 |\n|---|---|\n| `db list [--type mysql\\|redis] [--product <名>]` | 枚举安全摘要与配置就绪状态 |\n| `db search <关键字> [--type mysql\\|redis] [--product <名>]` | 搜索指定配置字段,额外返回命中的字段路径 `matches` |\n| `db query <key> [--env <env>] (--sql <SQL> \\| --cmd <命令>) [--timeout-ms <ms>]` | 执行 MySQL SQL 或 Redis 命令;输入必须且只能给一个非空值,须与 type 匹配 |\n| `db schema <key> [--env <env>] [--table <t>]` | MySQL 列配置库中的表名/注释,指定表时返回建表 SQL 与列信息;Redis 返回 INFO keyspace 与 DBSIZE |\n| `db check <key> [--env <env> \\| --all]` | MySQL/Archery 执行 SELECT 1,Redis 执行 PING;所有环境先预检,再按环境名顺序逐个检测 |\n\n可合并到配置的完整示例（凭证为示例值）:\n\n```yaml\narchery:\n  base_url: https://archery.chinawayltd.com  # install/config init 新建时写入;运行时不回落\n  access_key: \"\"                          # 缺省/空串时使用 Archery 返回 need\ndatabases:\n  checkout-mysql:\n    type: mysql\n    note: 订单主库\n    envs:\n      dev: {host: mysql.example.com, user: reader, password: example-password, database: checkout}\n      prod: {channel: archery, instance: mysql-prod-01, database: checkout}\n  shared-redis:\n    type: redis\n    note: 热点缓存\n    envs:\n      dev: {host: redis.example.com, port: 6379, db: 0}\nproducts:\n  checkout:\n    databases: [checkout-mysql, shared-redis]\n```\n\n- 每个数据库须有 `type: mysql|redis` 与至少一个完整 env;环境名自定义。缺省 `channel: direct`,MySQL/Redis 默认 port 分别为 3306/6379,port 必须为 1..65535 的整数。MySQL direct 的 host/user 非空,password 必须为字符串（允许空密码）,database 可省略;Redis host 必填,username/password 可省略,db 默认 0 且为非负整数。Archery 仅支持 MySQL,instance/database 非空,凭证取全局 access_key。\n- 新库通过 `config set databases.<key> '<完整 YAML 对象>'` 一次写入,如 `sdlc-cli config set databases.cache '{type: redis, envs: {dev: {host: redis.example.com}}}'`。缺字段、空 envs、非法 type/channel 是配置错误（exit 1）;`config get/set/list` 对 password/access_key/token 及其父对象递归脱敏。默认模板与 install 不补 `databases` 条目。\n- Archery 默认地址只在 `DEFAULT_CONFIG_TEMPLATE` 中定义:`install` / `config init` 新建配置时写入上述 base_url 与 `access_key: \"\"`;`install` 对已有配置只补缺失 base_url,保留自定义地址及任何 access_key;`config init` 对已有文件不覆盖。运行时仅读配置,AK 缺省/空串仍返回 `ARCHERY_KEY_MISSING`;AK 已有而 base_url 缺失时返回配置错误（exit 1）,执行 `sdlc-cli install` 补默认地址或 `sdlc-cli config set archery.base_url <地址>` 后重试。\n- 单环境自动选择,多环境未传 `--env` 返回 `DB_ENV_REQUIRED`;所有 needs 都不连接。`--all` 与 `--env` 互斥,全部环境预检无 needs 后才执行,一项检测失败仍保留后续结果。MySQL 未配 database 时仍可 query/check,schema 要求先补配置;Redis 不支持 `--table`。\n- list/search 按 key/env 排序,保留名称大小写。search 仅在 key/note/type/环境名/host/database/db/instance 中做不区分大小写的子串匹配。`--product` 按归属数组与 type/关键词取交集;未知产品 exit 1,空归属/无命中成功,悬空 key 忽略。未收录的 key 仍可查询。空 key/env/product/关键词/表名、非法 type 或参数组合是用法错误（exit 2）。\n- SQL 扫描识别 `--` / `#` / `/* */` 普通注释;首 token 允许 SELECT/SHOW/DESCRIBE/DESC/EXPLAIN/WITH,拒绝分号、可执行注释、WITH 混写与 INTO OUTFILE/DUMPFILE;执行原 SQL,不自动改写。Redis 使用只读命令白名单,引号/转义在进程内拆分,不经过 shell;SELECT/EVAL/写命令均拒绝。仅在实际 direct 执行时加载对应驱动,list/search/needs/Archery 不加载数据库驱动。\n- query 默认总超时 10000ms,`--timeout-ms` 须为正整数;schema 每次操作、check 每环境固定 10000ms。每次独立连接,超时销毁连接或 abort HTTP,不重试、不自动翻页。\n- 普通结果最多 500 行/项,确实裁剪时才 `truncated:true`。MySQL `rowCount` 为输出行数;Redis null 为 0、标量为 1、数组按元素、HGETALL 按字段、ZRANGE WITHSCORES 按完整成员/分值对计数。SCAN 保留完整单页和独立 cursor,不套 500 项裁剪。Archery 请求 limit=501,服务端可能返回更少,不据此猜测总量或截断状态。\n\n成功/needs 写 stdout,`--json` 使用 `{ok:true,state,...}`。业务错误 exit 1、参数错误 exit 2、连接/认证/权限/执行/超时错误 exit 3;错误 JSON 写 stderr,形如 `{error:{code:数字,message,details?}}`,stdout 为空。clipanion 解析错误沿用文本输出。check 任一环境失败时 exit 3,完整 `results` 位于 `stderr.error.details.results`;成功时单环境也用 results 数组。文本模式展示相同业务字段。\n\n| 成功命令 | state | 信封业务字段 |\n|---|---|---|\n| list | `listed` | `databases: DbSummary[]`, `archery: {configured:boolean}` |\n| search | `searched` | 同 list,命中条目增加 `matches: string[]` |\n| query（MySQL） | `queried` | `columns, rows, rowCount, truncated, elapsedMs, matched, meta?` |\n| query（Redis） | `queried` | `value, cursor?, rowCount, truncated, elapsedMs, matched` |\n| schema | `schema` | `matched, schema, rowCount, truncated, elapsedMs` |\n| check | `checked` | `results: [{ok,latencyMs,key,env,channel,error?}]` |\n\n`DbSummary={key,type,note?,envs:[{env,channel,ready,missing:string[]}]}`;missing 是配置字段路径,Archery 摘要同时检查 `archery.base_url` 与 `archery.access_key`,两项齐备时才 `archery.configured:true` 且对应环境 ready。ready 不表示连通或权限已验证。`matched={key,env,type,channel}`。schema 的 MySQL 结果为 `{tables:[{name,comment}]}` 或 `{table,createSql,columns:[{name,type,nullable,default,extra,comment}]}`,Redis 为 `{keyspace,dbSize}`;rowCount 分别为表数、列数或 dbSize。摘要和 needs 不输出连接对象或凭证。\n\n每环境的一次 query/schema/check（含执行失败）追加一条审计至 `<workspaceRoot>/.sdlc/db-audit.jsonl`。workspaceRoot 取 `workspace.root`,未配置默认 `~/sdlc-workspaces`;不随 cwd 分散落盘。日志仅含时间、可识别的 os_user/git_user/workspace_id、key/env/channel、kind、statement、计数/耗时与成功/错误;无法识别的身份字段省略。query 保存原 SQL/cmd,schema/check 保存 `{operation:\"schema\",table?}` / `{operation:\"check\"}`。不记录凭证和查询数据行;参数/配置/needs/只读拒绝不写执行审计,写日志失败仅 stderr 告警。\n\n### `gapi` —— DevCloud API 检索（只读透传）\n\n在 DevCloud 平台检索 API 定义。stdout 直接输出接口原始 JSON——无 `--json`、无渲染，适合管道与脚本消费。\n\n```bash\nsdlc-cli gapi search --keyword 订单 --scope app [--app checkout] [--page 1] [--size 15]\nsdlc-cli gapi list --scope app [--page 1] [--size 15]\nsdlc-cli gapi detail --id 123\n```\n\n| 命令 | 作用 | 备注 |\n|---|---|---|\n| `gapi search` | 按关键字搜索 API | `--scope app/product/user`（默认 app），`--app` 仅限 app 维度；user 维度不支持分页 |\n| `gapi list` | 列出 API | 仅 `--scope app/product` |\n| `gapi detail` | 查 API 详情（OPENAPI 格式） | 无需 token |\n\n配置（`~/.sdlc/config.yaml`，全部可选；`base_url` 缺省用内置默认）：\n\n```yaml\ngapi:\n  base_url: http://devcloud.chinawayltd.com   # 可选，内置默认同值\n  # app_token: <按检索维度配置，app / product / user 三选或多选；留空视为未配置，用到时报 GAPI_TOKEN_MISSING>\n  # product_token: ...\n  # user_token: ...\n  apps:\n    checkout: {app_token: example-app-token}\n```\n\n`--app <应用名>` 优先取 `gapi.apps.<应用名>.app_token`;映射不存在、token 缺省或空串均回落全局 `gapi.app_token`,最终仍为空时报 `GAPI_TOKEN_MISSING`。不传 --app 保留全局 token 行为。`gapi.apps` 每项仅接受可选字符串 app_token;配置输出递归脱敏。--keyword 仍必填,--app 显式空值或与 product/user scope 同用在请求前报用法错误;list/detail 不接受 --app。\n\n错误码：`GAPI_TOKEN_MISSING`（exit 1，缺对应维度 token）；`GAPI_AUTH_FAILED` / `GAPI_NOT_FOUND` / `GAPI_BAD_REQUEST` / `GAPI_SERVER_ERROR` / `GAPI_REQUEST_FAILED` / `GAPI_UNREACHABLE`（exit 3）；`GAPI_APP_INVALID` / `GAPI_SCOPE_INVALID` / `GAPI_LIST_SCOPE_INVALID` / `GAPI_USER_SCOPE_NO_PAGING` / `GAPI_ID_INVALID` / `GAPI_PAGING_INVALID`（exit 2）。\n\n### `apollo` —— Apollo 配置查询（只读透传）\n\n查询 Apollo 配置中心应用配置，stdout 输出配置原文。\n\n```bash\nsdlc-cli apollo get --app order-app --env dev [--cluster default] [--namespace application] [--format properties|json|raw]\nsdlc-cli apollo get --app order-app --server http://apollo-api.dev.chinawayltd.com:8080\n```\n\n- `--env`（`dev/test/demo/pro`，不区分大小写）与 `--server` 必填其一，`--server` 优先。\n- `--format` 对应 Apollo 官方路径前缀：`json` → `/configfiles/json/...`，`raw` → `/configfiles/raw/...`，`properties`（默认）无前缀。\n- 四环境地址内置默认，可在 config.yaml 覆盖：\n\n```yaml\napollo:\n  server_urls:\n    dev: http://apollo-api.dev.chinawayltd.com:8080\n    test: http://apollo-api.test.chinawayltd.com:8080\n    demo: http://apollo-api.demo.chinawayltd.com:8080\n    pro:  http://apollo.merak.chinawayltd.com:8000\n```\n\n错误码：`APOLLO_TARGET_REQUIRED` / `APOLLO_ENV_INVALID` / `APOLLO_SERVER_INVALID` / `APOLLO_APP_REQUIRED` / `APOLLO_FORMAT_INVALID`（exit 2）；`APOLLO_AUTH_FAILED` / `APOLLO_NOT_FOUND` / `APOLLO_BAD_REQUEST` / `APOLLO_SERVER_ERROR` / `APOLLO_REQUEST_FAILED` / `APOLLO_UNREACHABLE`（exit 3）。\n\n## 随包 skills\n\n`skills/` 下每个含 `SKILL.md` 的子目录都会在 `sdlc-cli install` 时覆盖注册到 `~/.claude/skills` 与 `~/.agents/skills`(新增 skill 无需改代码,放进目录即被识别)。它们是 CLI 的**语义前端**:负责从对话里抽参数、按 needs 追问、转述结果;破坏性动作仍由 CLI 执行。\n\n| skill | 负责什么 |\n| --- | --- |\n| `configuring-sdlc` | `~/.sdlc/config.yaml` 的自然语言前端:识别要配的维度(workspace / products / repos)、补齐缺失项、覆盖前确认,再调 `config set/get/list` |\n| `initializing-context-repo` | 把一个目录初始化成规范 context-repo:建 `prds/` + `requirements/` + `assets/` 三层骨架、按模板生成 `AGENTS.md` 导航(真源)与 `CLAUDE.md` 软链、写根 `manifest.yaml`(产品名,供 `ws init` 校验)、按需建 `prds/` 下功能模块。导航按需求产出形态分两套(走标准流程写四段式 `prd/` 与命名规范,不走则只写粗略结构)。新仓从零建与已有仓补齐都走它;只落文件,不碰 git、不写配置 |\n\n> 工作区装配的对话前端(`assembling-workspace`)与各研发阶段 skill(`ingesting-prd`、`generating-tests`、`extracting-assets` 等)在**独立的 `agents` 仓**维护,不随本包发布;本包 skill 与它们通过命令契约协作。\n\n## needs 码\n\nneeds 是**阻断性缺失**:回报 needs 时 CLI **绝不做破坏性动作**(装配的经典顺序是「先把所有 needs 收集完,非空则早返回,否则才动 git」)。与之相对,warnings 是非阻断提示(如 `PRD_REF_NOT_FOUND`、`ALREADY_PRESENT`、`SESSION_ENTRY_WRITE_FAILED`、`ctx commit` 的 `PUSH_FAILED` / `PUSH_SKIPPED`),不改状态、不改退出码。needs 里只有 `PRD_REF_REQUIRED` 额外回带 `candidates[]`(context-repo 已有 PRD 清单),供 skill 语义推导/选择。\n\n| 码 | 场景 | skill 行为 |\n|---|---|---|\n| `CONTEXT_REPO_MISSING` | ws create 拿不到 context-repo 地址 | 问产品或直接给 `--context-repo` |\n| `KNOWLEDGE_MISSING` | ws create 拿不到知识库地址 | 问产品或给 `--knowledge`（可多个） |\n| `REPO_REMOTE_MISSING` | 某逻辑仓既无 `repos.<id>.remote` 也无 `local`，带 `repo` 字段 | 补配置或给 `--repo-remote <id>=<url>` |\n| `REPO_BASE_PENDING` / `REPO_BASE_REQUIRED` | 基准分支未定（装配 / 交付发现阶段），带候选 ref | 让用户选定后 `--repo-base` 或 `deliver base set` 持久化 |\n| `PRODUCT_WORKSPACE_MISSING` | ws which 未找到带 `.sdlc-product.yaml` 标记的产品工作区（含「目录在但无标记」的旧布局） | 提示运行 ws init |\n| `PRODUCT_AMBIGUOUS` | ws which 找到多个产品工作区 | 列出候选，要求 --product 指定 |\n| `REPO_MANIFEST_MISSING` | ws init 时 context-repo 根缺 `manifest.yaml`（产品名无从校验） | 先走 `initializing-context-repo` 补齐 |\n| `PRD_REF_REQUIRED` | ws create 的 dev 视图未给 `--prd-ref`（dev 必填），回带 `candidates[]` | 从候选语义推导→确认/选择后补 `--prd-ref` 重调 |\n| `PRD_MODULE_REQUIRED` | ctx scaffold 未指定 --module/--no-module | 列出已有模块（或提示命名第一个），要求用户选择 |\n| `MATERIAL_VERSION_MISSING` | cp request 的 `--material` 没带版本 | 问清材料版本后重调 |\n| `REVIEWER_MISSING` | cp request 未指定 `--reviewer` 且非自审 | 问审核人，或确认改走 `--self-review` |\n| `DB_NOT_FOUND` | databases 无此 key,附安全摘要 `databases` | 先搜索已有库;新库用 config set 一次写完整条目 |\n| `DB_ENV_REQUIRED` | 多环境未指定 --env,附安全摘要 `environments` | 选择已配环境后重调 |\n| `DB_ENV_MISSING` | 指定环境缺失,带 key/env | 补完整环境条目后重调 |\n| `ARCHERY_KEY_MISSING` | Archery AK 缺省或为空,带 key/env | 补 archery.access_key 后重调 |\n\ndb 的 needs 返回 exit 0,stdout 为 `{ok:true,state:\"needs-input\",needs:[...]}`;数据库候选用 `databases`、环境候选用 `environments`,不复用 PRD 的 `candidates` 字段。\n\n`deliver` 的阻断项不是「缺信息」而是「仓库状态不允许交付」,统一以同样的信封回报,但要人去处理工作树而不是补参数:`DETACHED_HEAD`、`SOURCE_EQUALS_TARGET`、`ORIGIN_MISSING`、`OPERATION_IN_PROGRESS`（rebase/merge 进行中）、`CONFLICTS_PRESENT`、`TARGET_MISSING`、`REMOTE_OBJECT_MISSING`、`UNSUPPORTED_GIT_HOST`（只支持 GitLab）、`GITLAB_AUTH_REQUIRED`、`MR_CREATE_UNCONFIRMED`、`MR_TERMINAL_WITH_NEW_COMMITS`（已有终态 MR 又出现新提交）、`PLAN_STALE`（plan_id 已失效,需重新 `plan`）、`PLAN_BLOCKED`。\n\n## 开发\n\n```bash\npnpm install\npnpm build        # tsup 打包到 dist/\npnpm test         # vitest 运行测试\npnpm typecheck    # tsc --noEmit\npnpm dev          # tsup --watch\n```\n\n- 技术栈:TypeScript(ESM)、clipanion(命令)、zod(schema 校验)、simple-git、gray-matter / yaml。\n- 测试通过 `SDLC_CONFIG` 环境变量隔离配置路径,用临时目录 + git 仓构造夹具。\n\n## License\n\n私有 / 内部使用。\n","readmeFilename":"README.md"}