@kb-labs/release-manager-cli 2.94.0 → 2.98.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands/build.js +1 -1
- package/dist/cli/commands/build.js.map +1 -1
- package/dist/cli/commands/changelog.js +1 -1
- package/dist/cli/commands/changelog.js.map +1 -1
- package/dist/cli/commands/checks.js +1 -1
- package/dist/cli/commands/checks.js.map +1 -1
- package/dist/cli/commands/git.js +31 -12
- package/dist/cli/commands/git.js.map +1 -1
- package/dist/cli/commands/pack.js +1 -1
- package/dist/cli/commands/pack.js.map +1 -1
- package/dist/cli/commands/plan.js +1 -1
- package/dist/cli/commands/plan.js.map +1 -1
- package/dist/cli/commands/publish.js +1 -1
- package/dist/cli/commands/publish.js.map +1 -1
- package/dist/cli/commands/report.js +5 -2
- package/dist/cli/commands/report.js.map +1 -1
- package/dist/cli/commands/rollback.js +9 -1
- package/dist/cli/commands/rollback.js.map +1 -1
- package/dist/cli/commands/run.js +5 -5
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/commands/verify.js +1 -1
- package/dist/cli/commands/verify.js.map +1 -1
- package/dist/cli/commands/version.js +22 -28
- package/dist/cli/commands/version.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +43 -61
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +62 -27
- package/dist/manifest.js +43 -61
- package/dist/manifest.js.map +1 -1
- package/dist/rest/handlers/build-handler.js +34 -30
- package/dist/rest/handlers/build-handler.js.map +1 -1
- package/dist/rest/handlers/changelog-generate-handler.js +98 -64
- package/dist/rest/handlers/changelog-generate-handler.js.map +1 -1
- package/dist/rest/handlers/changelog-handler.js +28 -24
- package/dist/rest/handlers/changelog-handler.js.map +1 -1
- package/dist/rest/handlers/changelog-save-handler.js +2 -2
- package/dist/rest/handlers/changelog-save-handler.js.map +1 -1
- package/dist/rest/handlers/checklist-handler.js +49 -45
- package/dist/rest/handlers/checklist-handler.js.map +1 -1
- package/dist/rest/handlers/generate-handler.js +96 -92
- package/dist/rest/handlers/generate-handler.js.map +1 -1
- package/dist/rest/handlers/get-checks-handler.js +16 -12
- package/dist/rest/handlers/get-checks-handler.js.map +1 -1
- package/dist/rest/handlers/git-timeline-handler.js +63 -59
- package/dist/rest/handlers/git-timeline-handler.js.map +1 -1
- package/dist/rest/handlers/history-changelog-handler.js +2 -2
- package/dist/rest/handlers/history-changelog-handler.js.map +1 -1
- package/dist/rest/handlers/history-handler.js +45 -41
- package/dist/rest/handlers/history-handler.js.map +1 -1
- package/dist/rest/handlers/history-plan-handler.js +2 -2
- package/dist/rest/handlers/history-plan-handler.js.map +1 -1
- package/dist/rest/handlers/history-report-handler.js +2 -2
- package/dist/rest/handlers/history-report-handler.js.map +1 -1
- package/dist/rest/handlers/plan-handler.js +57 -53
- package/dist/rest/handlers/plan-handler.js.map +1 -1
- package/dist/rest/handlers/preview-handler.js +90 -86
- package/dist/rest/handlers/preview-handler.js.map +1 -1
- package/dist/rest/handlers/report-handler.js +36 -32
- package/dist/rest/handlers/report-handler.js.map +1 -1
- package/dist/rest/handlers/reset-handler.js +22 -18
- package/dist/rest/handlers/reset-handler.js.map +1 -1
- package/dist/rest/handlers/run-checks-handler.js +43 -39
- package/dist/rest/handlers/run-checks-handler.js.map +1 -1
- package/dist/rest/handlers/run-handler.js +53 -49
- package/dist/rest/handlers/run-handler.js.map +1 -1
- package/dist/rest/handlers/scopes-handler.js +40 -36
- package/dist/rest/handlers/scopes-handler.js.map +1 -1
- package/dist/rest/handlers/status-handler.js +49 -45
- package/dist/rest/handlers/status-handler.js.map +1 -1
- package/dist/widgets/117.js +24 -1
- package/dist/widgets/165.js +1 -1
- package/dist/widgets/370.js +1 -1
- package/dist/widgets/405.js +1 -1
- package/dist/widgets/{805.js → 46.js} +92 -92
- package/dist/widgets/50.js +1 -1
- package/dist/widgets/546.js +1 -1
- package/dist/widgets/62.js +96 -0
- package/dist/widgets/648.js +1 -0
- package/dist/widgets/669.js +1 -1
- package/dist/widgets/733.js +34 -0
- package/dist/widgets/775.js +1 -1
- package/dist/widgets/78.js +1 -0
- package/dist/widgets/968.js +2 -2
- package/dist/widgets/__federation_expose_ReleasePage.js +1 -1
- package/dist/widgets/mf-manifest.json +31 -31
- package/dist/widgets/mf-stats.json +41 -41
- package/dist/widgets/remoteEntry.js +3 -3
- package/package.json +10 -9
- package/dist/widgets/418.js +0 -38
- package/dist/widgets/451.js +0 -1
- package/dist/widgets/694.js +0 -1
- package/dist/widgets/919.js +0 -34
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/shared/utils.ts","../../../src/rest/handlers/checklist-handler.ts"],"names":["findRepoRoot"],"mappings":";;;;;AAMO,SAAS,WAAW,KAAA,EAAuB;AAChD,EAAA,OAAO,KAAA,CACJ,OAAA,CAAQ,IAAA,EAAM,EAAE,EAChB,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAClB,QAAQ,IAAA,EAAM,GAAG,CAAA,CACjB,OAAA,CAAQ,OAAO,EAAE,CAAA;AACtB;ACUA,eAAe,WAAW,GAAA,EAAuD;AAC/E,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,IAAI,IAAA,GAAO,CAAA;AACX,EAAA,MAAM,UAAU,MAAM,OAAA,CAAQ,KAAK,EAAE,aAAA,EAAe,MAAM,CAAA;AAC1D,EAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,EAAK,KAAA,CAAM,IAAI,CAAA;AACrC,IAAA,IAAI,KAAA,CAAM,aAAY,EAAG;AACvB,MAAA,MAAM,GAAA,GAAM,MAAM,UAAA,CAAW,QAAQ,CAAA;AACrC,MAAA,KAAA,IAAS,GAAA,CAAI,KAAA;AACb,MAAA,IAAA,IAAQ,GAAA,CAAI,IAAA;AAAA,IACd,CAAA,MAAO;AACL,MAAA,KAAA,EAAA;AACA,MAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,QAAQ,CAAA;AACpC,MAAA,IAAA,IAAQ,QAAA,CAAS,IAAA;AAAA,IACnB;AAAA,EACF;AACA,EAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AACvB;AAUA,eAAe,gBAAgB,QAAA,EAA4C;AACzE,EAAA,IAAI;AACF,IAAA,MAAM,UAAU,MAAM,QAAA,CAAS,KAAK,QAAA,EAAU,WAAW,GAAG,OAAO,CAAA;AACnE,IAAA,MAAM,UAAA,GAA0B,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA;AAClD,IAAA,MAAM,aAAA,GAAgB,WAAW,QAAA,CAAS,MAAA;AAC1C,IAAA,MAAM,IAAA,GAAO,UAAA,CAAW,QAAA,CAAS,CAAC,CAAA,EAAG,IAAA;AACrC,IAAA,OAAO;AAAA,MACL,UAAA,EAAY,OAAA;AAAA,MACZ,WAAA,EAAa,GAAG,aAAa,CAAA,QAAA,EAAW,kBAAkB,CAAA,GAAI,GAAA,GAAM,EAAE,CAAA,EAAA,EAAK,IAAI,CAAA,KAAA,CAAA;AAAA,MAC/E,aAAA;AAAA,MACA,IAAA;AAAA,MACA,IAAA,EAAM;AAAA,KACR;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,UAAA,EAAY,SAAA,EAAW,WAAA,EAAa,uBAAA,EAAyB,eAAe,CAAA,EAAG,IAAA,EAAM,MAAA,EAAW,IAAA,EAAM,MAAA,EAAU;AAAA,EAC3H;AACF;AAQA,eAAe,oBAAA,CAAqB,UAAkB,UAAA,EAAgE;AACpH,EAAA,IAAI;AACF,IAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,QAAA,EAAU,cAAc,CAAA;AACnD,IAAA,MAAM,OAAO,aAAa,CAAA;AAC1B,IAAA,MAAM,SAAA,GAAY,MAAM,QAAA,CAAS,aAAA,EAAe,OAAO,CAAA;AACvD,IAAA,MAAM,aAAA,GAAgB,SAAA,CAAU,KAAA,CAAM,OAAO,CAAA;AAC7C,IAAA,MAAM,YAAA,GAAe,eAAe,MAAA,IAAU,CAAA;AAC9C,IAAA,OAAO;AAAA,MACL,eAAA,EAAiB,OAAA;AAAA,MACjB,kBAAkB,CAAA,EAAG,YAAY,UAAU,YAAA,KAAiB,CAAA,GAAI,MAAM,EAAE,CAAA,WAAA,CAAA;AAAA,MACxE;AAAA,KACF;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,gBAAA,GAAmB,UAAA,KAAe,OAAA,GAAU,gCAAA,GAAmC,yBAAA;AACrF,IAAA,OAAO,EAAE,eAAA,EAAiB,SAAA,EAAW,gBAAA,EAAkB,cAAc,MAAA,EAAU;AAAA,EACjF;AACF;AASA,eAAe,gBAAA,CAAiB,MAA+B,QAAA,EAA6C;AAC1G,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,OAAO,EAAE,aAAa,SAAA,EAAW,YAAA,EAAc,kBAAkB,UAAA,EAAY,CAAA,EAAG,YAAY,CAAA,EAAE;AAAA,EAChG;AACA,EAAA,MAAM,UAAA,GAAa,KAAK,QAAA,CAAS,MAAA;AACjC,EAAA,IAAI,UAAA,GAAa,CAAA;AACjB,EAAA,KAAA,MAAW,GAAA,IAAO,KAAK,QAAA,EAAU;AAC/B,IAAA,MAAM,WAAA,GAAc,GAAA,CAAI,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,GAAI,GAAA,CAAI,IAAA,GAAO,IAAA,CAAK,QAAA,EAAU,GAAA,CAAI,IAAI,CAAA;AACjF,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,CAAO,IAAA,CAAK,WAAA,EAAa,MAAM,CAAC,CAAA;AACtC,MAAA,UAAA,EAAA;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AACA,EAAA,IAAI,eAAe,UAAA,EAAY;AAC7B,IAAA,OAAO;AAAA,MACL,WAAA,EAAa,OAAA;AAAA,MACb,cAAc,CAAA,IAAA,EAAO,UAAU,WAAW,UAAA,KAAe,CAAA,GAAI,MAAM,EAAE,CAAA,MAAA,CAAA;AAAA,MACrE,UAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AACA,EAAA,IAAI,aAAa,CAAA,EAAG;AAClB,IAAA,OAAO,EAAE,WAAA,EAAa,SAAA,EAAW,YAAA,EAAc,CAAA,EAAG,UAAU,CAAA,CAAA,EAAI,UAAU,CAAA,eAAA,CAAA,EAAmB,UAAA,EAAY,UAAA,EAAW;AAAA,EACtH;AACA,EAAA,OAAO;AAAA,IACL,WAAA,EAAa,SAAA;AAAA,IACb,cAAc,CAAA,EAAG,UAAU,WAAW,UAAA,KAAe,CAAA,GAAI,MAAM,EAAE,CAAA,WAAA,CAAA;AAAA,IACjE,UAAA;AAAA,IACA;AAAA,GACF;AACF;AASA,eAAe,kBAAA,CACb,IAAA,EACA,QAAA,EACA,WAAA,EAC6B;AAC7B,EAAA,IAAI,WAAA,KAAgB,OAAA,IAAW,CAAC,IAAA,EAAM;AACpC,IAAA,OAAO,EAAE,eAAe,SAAA,EAAW,cAAA,EAAgB,qBAAqB,UAAA,EAAY,MAAA,EAAW,WAAW,MAAA,EAAU;AAAA,EACtH;AACA,EAAA,IAAI,UAAA,GAAa,CAAA;AACjB,EAAA,IAAI,SAAA,GAAY,CAAA;AAChB,EAAA,KAAA,MAAW,GAAA,IAAO,KAAK,QAAA,EAAU;AAC/B,IAAA,MAAM,WAAA,GAAc,GAAA,CAAI,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,GAAI,GAAA,CAAI,IAAA,GAAO,IAAA,CAAK,QAAA,EAAU,GAAA,CAAI,IAAI,CAAA;AACjF,IAAA,IAAI;AACF,MAAA,MAAM,SAAS,MAAM,UAAA,CAAW,IAAA,CAAK,WAAA,EAAa,MAAM,CAAC,CAAA;AACzD,MAAA,UAAA,IAAc,MAAA,CAAO,KAAA;AACrB,MAAA,SAAA,IAAa,MAAA,CAAO,IAAA;AAAA,IACtB,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AACA,EAAA,IAAI,aAAa,CAAA,EAAG;AAClB,IAAA,OAAO;AAAA,MACL,aAAA,EAAe,OAAA;AAAA,MACf,gBAAgB,CAAA,EAAG,UAAU,QAAQ,UAAA,KAAe,CAAA,GAAI,MAAM,EAAE,CAAA,iBAAA,CAAA;AAAA,MAChE,UAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AACA,EAAA,OAAO,EAAE,aAAA,EAAe,SAAA,EAAW,cAAA,EAAgB,2BAAA,EAA6B,YAAY,SAAA,EAAU;AACxG;AAIA,IAAO,4BAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAK,KAAA,EAA6D;AAC9E,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,EAAO,KAAA,IAAS,MAAA;AACpC,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,GAAA,IAAO,OAAA,CAAQ,GAAA,EAAI;AACnC,IAAA,MAAM,QAAA,GAAW,MAAMA,YAAAA,CAAa,GAAG,CAAA;AAEvC,IAAA,MAAM,QAAA,GAAW,WAAW,KAAK,CAAA;AACjC,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,QAAA,EAAU,mBAAA,EAAqB,UAAU,SAAS,CAAA;AAExE,IAAA,MAAM,EAAE,YAAY,WAAA,EAAa,aAAA,EAAe,MAAM,IAAA,EAAK,GAAI,MAAM,eAAA,CAAgB,QAAQ,CAAA;AAC7F,IAAA,MAAM,EAAE,iBAAiB,gBAAA,EAAkB,YAAA,KAAiB,MAAM,oBAAA,CAAqB,UAAU,UAAU,CAAA;AAC3G,IAAA,MAAM,EAAE,aAAa,YAAA,EAAc,UAAA,EAAY,YAAW,GAAI,MAAM,gBAAA,CAAiB,IAAA,EAAM,QAAQ,CAAA;AACnG,IAAA,MAAM,EAAE,aAAA,EAAe,cAAA,EAAgB,UAAA,EAAY,SAAA,KAAc,MAAM,kBAAA,CAAmB,IAAA,EAAM,QAAA,EAAU,WAAW,CAAA;AAErH,IAAA,MAAM,cAAc,CAAC,EAAE,OAAO,WAAW,CAAA,IAAK,OAAO,iBAAiB,CAAA,CAAA;AACtE,IAAA,MAAM,SAAA,GAAiC,cAAc,OAAA,GAAU,OAAA;AAC/D,IAAA,MAAM,UAAA,GAAa,cACf,sBAAA,GACA,sDAAA;AAEJ,IAAA,MAAM,UAAA,GACJ,eAAe,OAAA,IACf,eAAA,KAAoB,WACpB,WAAA,KAAgB,OAAA,IAChB,aAAA,KAAkB,OAAA,IAClB,SAAA,KAAc,OAAA;AAEhB,IAAA,OAAO;AAAA,MACL,KAAA;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,MAAA,EAAQ,UAAA;AAAA,QACR,OAAA,EAAS,WAAA;AAAA,QACT,aAAA,EAAe,aAAA,GAAgB,CAAA,GAAI,aAAA,GAAgB,MAAA;AAAA,QACnD;AAAA,OACF;AAAA,MACA,SAAA,EAAW;AAAA,QACT,MAAA,EAAQ,eAAA;AAAA,QACR,OAAA,EAAS,gBAAA;AAAA,QACT;AAAA,OACF;AAAA,MACA,KAAA,EAAO;AAAA,QACL,MAAA,EAAQ,WAAA;AAAA,QACR,OAAA,EAAS,YAAA;AAAA,QACT,UAAA,EAAY,UAAA,GAAa,CAAA,GAAI,UAAA,GAAa,MAAA;AAAA,QAC1C,UAAA,EAAY,UAAA,GAAa,CAAA,GAAI,UAAA,GAAa;AAAA,OAC5C;AAAA,MACA,OAAA,EAAS;AAAA,QACP,MAAA,EAAQ,aAAA;AAAA,QACR,OAAA,EAAS,cAAA;AAAA,QACT,UAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,GAAA,EAAK;AAAA,QACH,MAAA,EAAQ,SAAA;AAAA,QACR,OAAA,EAAS;AAAA,OACX;AAAA,MACA;AAAA,KACF;AAAA,EACF;AACF,CAAC","file":"checklist-handler.js","sourcesContent":["export { findRepoRoot } from '@kb-labs/sdk';\nexport { resolveScopePath } from './resolve-scope';\n\n/**\n * Converts scope to safe directory name\n */\nexport function scopeToDir(scope: string): string {\n return scope\n .replace(/^@/, '')\n .replace(/\\//g, '-')\n .replace(/:/g, '-')\n .replace(/\\*/g, '');\n}\n\n/**\n * Converts safe directory name back to scope\n */\nexport function dirToScope(dirName: string): string {\n if (dirName === 'root') {\n return 'root';\n }\n\n const parts = dirName.split('-');\n if (parts.length >= 2) {\n return '@' + parts[0] + '-' + parts[1] + '/' + parts.slice(2).join('-');\n }\n\n return dirName;\n}\n","/**\n * Checklist handler - Get unified release checklist status\n *\n * Returns status of all release steps: plan, changelog, build, preview\n */\n\nimport { defineHandler, findRepoRoot, useEnv, type RestInput } from '@kb-labs/sdk';\nimport type {\n ReleaseChecklist,\n ChecklistItemStatus,\n ReleasePlan,\n} from '@kb-labs/release-manager-contracts';\nimport { readFile, access, readdir, stat } from 'node:fs/promises';\nimport { scopeToDir } from '../../shared/utils';\nimport { join } from 'node:path';\n\ninterface ChecklistInput {\n scope?: string;\n}\n\n// ── helpers ────────────────────────────────────────────────────────────────\n\nasync function countFiles(dir: string): Promise<{ count: number; size: number }> {\n let count = 0;\n let size = 0;\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n const sub = await countFiles(fullPath);\n count += sub.count;\n size += sub.size;\n } else {\n count++;\n const fileStat = await stat(fullPath);\n size += fileStat.size;\n }\n }\n return { count, size };\n}\n\ninterface PlanCheckResult {\n planStatus: ChecklistItemStatus;\n planMessage: string;\n packagesCount: number;\n bump: string | undefined;\n plan: ReleasePlan | undefined;\n}\n\nasync function checkPlanStatus(basePath: string): Promise<PlanCheckResult> {\n try {\n const planRaw = await readFile(join(basePath, 'plan.json'), 'utf-8');\n const parsedPlan: ReleasePlan = JSON.parse(planRaw);\n const packagesCount = parsedPlan.packages.length;\n const bump = parsedPlan.packages[0]?.bump;\n return {\n planStatus: 'ready',\n planMessage: `${packagesCount} package${packagesCount !== 1 ? 's' : ''}, ${bump} bump`,\n packagesCount,\n bump,\n plan: parsedPlan,\n };\n } catch {\n return { planStatus: 'pending', planMessage: 'No release plan found', packagesCount: 0, bump: undefined, plan: undefined };\n }\n}\n\ninterface ChangelogCheckResult {\n changelogStatus: ChecklistItemStatus;\n changelogMessage: string;\n commitsCount: number | undefined;\n}\n\nasync function checkChangelogStatus(basePath: string, planStatus: ChecklistItemStatus): Promise<ChangelogCheckResult> {\n try {\n const changelogPath = join(basePath, 'CHANGELOG.md');\n await access(changelogPath);\n const changelog = await readFile(changelogPath, 'utf-8');\n const commitMatches = changelog.match(/^- /gm);\n const commitsCount = commitMatches?.length || 0;\n return {\n changelogStatus: 'ready',\n changelogMessage: `${commitsCount} change${commitsCount !== 1 ? 's' : ''} documented`,\n commitsCount,\n };\n } catch {\n const changelogMessage = planStatus === 'ready' ? 'Generate changelog to continue' : 'Changelog not generated';\n return { changelogStatus: 'pending', changelogMessage, commitsCount: undefined };\n }\n}\n\ninterface BuildCheckResult {\n buildStatus: ChecklistItemStatus;\n buildMessage: string;\n builtCount: number;\n totalCount: number;\n}\n\nasync function checkBuildStatus(plan: ReleasePlan | undefined, repoRoot: string): Promise<BuildCheckResult> {\n if (!plan) {\n return { buildStatus: 'pending', buildMessage: 'Build required', builtCount: 0, totalCount: 0 };\n }\n const totalCount = plan.packages.length;\n let builtCount = 0;\n for (const pkg of plan.packages) {\n const packagePath = pkg.path.startsWith('/') ? pkg.path : join(repoRoot, pkg.path);\n try {\n await access(join(packagePath, 'dist'));\n builtCount++;\n } catch {\n // Not built\n }\n }\n if (builtCount === totalCount) {\n return {\n buildStatus: 'ready',\n buildMessage: `All ${totalCount} package${totalCount !== 1 ? 's' : ''} built`,\n builtCount,\n totalCount,\n };\n }\n if (builtCount > 0) {\n return { buildStatus: 'warning', buildMessage: `${builtCount}/${totalCount} packages built`, builtCount, totalCount };\n }\n return {\n buildStatus: 'pending',\n buildMessage: `${totalCount} package${totalCount !== 1 ? 's' : ''} need build`,\n builtCount,\n totalCount,\n };\n}\n\ninterface PreviewCheckResult {\n previewStatus: ChecklistItemStatus;\n previewMessage: string;\n filesCount: number | undefined;\n totalSize: number | undefined;\n}\n\nasync function checkPreviewStatus(\n plan: ReleasePlan | undefined,\n repoRoot: string,\n buildStatus: ChecklistItemStatus,\n): Promise<PreviewCheckResult> {\n if (buildStatus !== 'ready' || !plan) {\n return { previewStatus: 'pending', previewMessage: 'Waiting for build', filesCount: undefined, totalSize: undefined };\n }\n let filesCount = 0;\n let totalSize = 0;\n for (const pkg of plan.packages) {\n const packagePath = pkg.path.startsWith('/') ? pkg.path : join(repoRoot, pkg.path);\n try {\n const result = await countFiles(join(packagePath, 'dist'));\n filesCount += result.count;\n totalSize += result.size;\n } catch {\n // Skip - dist doesn't exist or error reading\n }\n }\n if (filesCount > 0) {\n return {\n previewStatus: 'ready',\n previewMessage: `${filesCount} file${filesCount !== 1 ? 's' : ''} ready to publish`,\n filesCount,\n totalSize,\n };\n }\n return { previewStatus: 'warning', previewMessage: 'No files found to publish', filesCount, totalSize };\n}\n\n// ── handler ────────────────────────────────────────────────────────────────\n\nexport default defineHandler({\n async execute(ctx, input: RestInput<ChecklistInput>): Promise<ReleaseChecklist> {\n const scope = input.query?.scope || 'root';\n const cwd = ctx.cwd ?? process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n\n const scopeDir = scopeToDir(scope);\n const basePath = join(repoRoot, '.kb/release/plans', scopeDir, 'current');\n\n const { planStatus, planMessage, packagesCount, bump, plan } = await checkPlanStatus(basePath);\n const { changelogStatus, changelogMessage, commitsCount } = await checkChangelogStatus(basePath, planStatus);\n const { buildStatus, buildMessage, builtCount, totalCount } = await checkBuildStatus(plan, repoRoot);\n const { previewStatus, previewMessage, filesCount, totalSize } = await checkPreviewStatus(plan, repoRoot, buildStatus);\n\n const hasNpmToken = !!(useEnv('NPM_TOKEN') ?? useEnv('NODE_AUTH_TOKEN'));\n const npmStatus: ChecklistItemStatus = hasNpmToken ? 'ready' : 'error';\n const npmMessage = hasNpmToken\n ? 'npm token configured'\n : 'Set NPM_TOKEN (granular access token) in environment';\n\n const canPublish =\n planStatus === 'ready' &&\n changelogStatus === 'ready' &&\n buildStatus === 'ready' &&\n previewStatus === 'ready' &&\n npmStatus === 'ready';\n\n return {\n scope,\n plan: {\n status: planStatus,\n message: planMessage,\n packagesCount: packagesCount > 0 ? packagesCount : undefined,\n bump,\n },\n changelog: {\n status: changelogStatus,\n message: changelogMessage,\n commitsCount,\n },\n build: {\n status: buildStatus,\n message: buildMessage,\n builtCount: builtCount > 0 ? builtCount : undefined,\n totalCount: totalCount > 0 ? totalCount : undefined,\n },\n preview: {\n status: previewStatus,\n message: previewMessage,\n filesCount,\n totalSize,\n },\n npm: {\n status: npmStatus,\n message: npmMessage,\n },\n canPublish,\n };\n },\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/shared/utils.ts","../../../src/rest/handlers/checklist-handler.ts"],"names":["findRepoRoot"],"mappings":"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","file":"checklist-handler.js","sourcesContent":["export { findRepoRoot } from '@kb-labs/sdk';\nexport { resolveScopePath } from './resolve-scope';\n\n/**\n * Converts scope to safe directory name\n */\nexport function scopeToDir(scope: string): string {\n return scope\n .replace(/^@/, '')\n .replace(/\\//g, '-')\n .replace(/:/g, '-')\n .replace(/\\*/g, '');\n}\n\n/**\n * Converts safe directory name back to scope\n */\nexport function dirToScope(dirName: string): string {\n if (dirName === 'root') {\n return 'root';\n }\n\n const parts = dirName.split('-');\n if (parts.length >= 2) {\n return '@' + parts[0] + '-' + parts[1] + '/' + parts.slice(2).join('-');\n }\n\n return dirName;\n}\n","/**\n * Checklist handler - Get unified release checklist status\n *\n * Returns status of all release steps: plan, changelog, build, preview\n */\n\nimport { defineHandler, findRepoRoot, useEnv, type RestInput, rethrowForRest } from '@kb-labs/sdk';\nimport type {\n ReleaseChecklist,\n ChecklistItemStatus,\n ReleasePlan,\n} from '@kb-labs/release-manager-contracts';\nimport { readFile, access, readdir, stat } from 'node:fs/promises';\nimport { scopeToDir } from '../../shared/utils';\nimport { join } from 'node:path';\n\ninterface ChecklistInput {\n scope?: string;\n}\n\n// ── helpers ────────────────────────────────────────────────────────────────\n\nasync function countFiles(dir: string): Promise<{ count: number; size: number }> {\n let count = 0;\n let size = 0;\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n const sub = await countFiles(fullPath);\n count += sub.count;\n size += sub.size;\n } else {\n count++;\n const fileStat = await stat(fullPath);\n size += fileStat.size;\n }\n }\n return { count, size };\n}\n\ninterface PlanCheckResult {\n planStatus: ChecklistItemStatus;\n planMessage: string;\n packagesCount: number;\n bump: string | undefined;\n plan: ReleasePlan | undefined;\n}\n\nasync function checkPlanStatus(basePath: string): Promise<PlanCheckResult> {\n try {\n const planRaw = await readFile(join(basePath, 'plan.json'), 'utf-8');\n const parsedPlan: ReleasePlan = JSON.parse(planRaw);\n const packagesCount = parsedPlan.packages.length;\n const bump = parsedPlan.packages[0]?.bump;\n return {\n planStatus: 'ready',\n planMessage: `${packagesCount} package${packagesCount !== 1 ? 's' : ''}, ${bump} bump`,\n packagesCount,\n bump,\n plan: parsedPlan,\n };\n } catch {\n return { planStatus: 'pending', planMessage: 'No release plan found', packagesCount: 0, bump: undefined, plan: undefined };\n }\n}\n\ninterface ChangelogCheckResult {\n changelogStatus: ChecklistItemStatus;\n changelogMessage: string;\n commitsCount: number | undefined;\n}\n\nasync function checkChangelogStatus(basePath: string, planStatus: ChecklistItemStatus): Promise<ChangelogCheckResult> {\n try {\n const changelogPath = join(basePath, 'CHANGELOG.md');\n await access(changelogPath);\n const changelog = await readFile(changelogPath, 'utf-8');\n const commitMatches = changelog.match(/^- /gm);\n const commitsCount = commitMatches?.length || 0;\n return {\n changelogStatus: 'ready',\n changelogMessage: `${commitsCount} change${commitsCount !== 1 ? 's' : ''} documented`,\n commitsCount,\n };\n } catch {\n const changelogMessage = planStatus === 'ready' ? 'Generate changelog to continue' : 'Changelog not generated';\n return { changelogStatus: 'pending', changelogMessage, commitsCount: undefined };\n }\n}\n\ninterface BuildCheckResult {\n buildStatus: ChecklistItemStatus;\n buildMessage: string;\n builtCount: number;\n totalCount: number;\n}\n\nasync function checkBuildStatus(plan: ReleasePlan | undefined, repoRoot: string): Promise<BuildCheckResult> {\n if (!plan) {\n return { buildStatus: 'pending', buildMessage: 'Build required', builtCount: 0, totalCount: 0 };\n }\n const totalCount = plan.packages.length;\n let builtCount = 0;\n for (const pkg of plan.packages) {\n const packagePath = pkg.path.startsWith('/') ? pkg.path : join(repoRoot, pkg.path);\n try {\n await access(join(packagePath, 'dist'));\n builtCount++;\n } catch {\n // Not built\n }\n }\n if (builtCount === totalCount) {\n return {\n buildStatus: 'ready',\n buildMessage: `All ${totalCount} package${totalCount !== 1 ? 's' : ''} built`,\n builtCount,\n totalCount,\n };\n }\n if (builtCount > 0) {\n return { buildStatus: 'warning', buildMessage: `${builtCount}/${totalCount} packages built`, builtCount, totalCount };\n }\n return {\n buildStatus: 'pending',\n buildMessage: `${totalCount} package${totalCount !== 1 ? 's' : ''} need build`,\n builtCount,\n totalCount,\n };\n}\n\ninterface PreviewCheckResult {\n previewStatus: ChecklistItemStatus;\n previewMessage: string;\n filesCount: number | undefined;\n totalSize: number | undefined;\n}\n\nasync function checkPreviewStatus(\n plan: ReleasePlan | undefined,\n repoRoot: string,\n buildStatus: ChecklistItemStatus,\n): Promise<PreviewCheckResult> {\n if (buildStatus !== 'ready' || !plan) {\n return { previewStatus: 'pending', previewMessage: 'Waiting for build', filesCount: undefined, totalSize: undefined };\n }\n let filesCount = 0;\n let totalSize = 0;\n for (const pkg of plan.packages) {\n const packagePath = pkg.path.startsWith('/') ? pkg.path : join(repoRoot, pkg.path);\n try {\n const result = await countFiles(join(packagePath, 'dist'));\n filesCount += result.count;\n totalSize += result.size;\n } catch {\n // Skip - dist doesn't exist or error reading\n }\n }\n if (filesCount > 0) {\n return {\n previewStatus: 'ready',\n previewMessage: `${filesCount} file${filesCount !== 1 ? 's' : ''} ready to publish`,\n filesCount,\n totalSize,\n };\n }\n return { previewStatus: 'warning', previewMessage: 'No files found to publish', filesCount, totalSize };\n}\n\n// ── handler ────────────────────────────────────────────────────────────────\n\nexport default defineHandler({\n async execute(ctx, input: RestInput<ChecklistInput>): Promise<ReleaseChecklist> {\n try {\n const scope = input.query?.scope || 'root';\n const cwd = ctx.cwd ?? process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n\n const scopeDir = scopeToDir(scope);\n const basePath = join(repoRoot, '.kb/release/plans', scopeDir, 'current');\n\n const { planStatus, planMessage, packagesCount, bump, plan } = await checkPlanStatus(basePath);\n const { changelogStatus, changelogMessage, commitsCount } = await checkChangelogStatus(basePath, planStatus);\n const { buildStatus, buildMessage, builtCount, totalCount } = await checkBuildStatus(plan, repoRoot);\n const { previewStatus, previewMessage, filesCount, totalSize } = await checkPreviewStatus(plan, repoRoot, buildStatus);\n\n const hasNpmToken = !!(useEnv('NPM_TOKEN') ?? useEnv('NODE_AUTH_TOKEN'));\n const npmStatus: ChecklistItemStatus = hasNpmToken ? 'ready' : 'error';\n const npmMessage = hasNpmToken\n ? 'npm token configured'\n : 'Set NPM_TOKEN (granular access token) in environment';\n\n const canPublish =\n planStatus === 'ready' &&\n changelogStatus === 'ready' &&\n buildStatus === 'ready' &&\n previewStatus === 'ready' &&\n npmStatus === 'ready';\n\n return {\n scope,\n plan: {\n status: planStatus,\n message: planMessage,\n packagesCount: packagesCount > 0 ? packagesCount : undefined,\n bump,\n },\n changelog: {\n status: changelogStatus,\n message: changelogMessage,\n commitsCount,\n },\n build: {\n status: buildStatus,\n message: buildMessage,\n builtCount: builtCount > 0 ? builtCount : undefined,\n totalCount: totalCount > 0 ? totalCount : undefined,\n },\n preview: {\n status: previewStatus,\n message: previewMessage,\n filesCount,\n totalSize,\n },\n npm: {\n status: npmStatus,\n message: npmMessage,\n },\n canPublish,\n };\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineHandler, findRepoRoot, useConfig } from '@kb-labs/sdk';
|
|
1
|
+
import { defineHandler, findRepoRoot, useConfig, rethrowForRest } from '@kb-labs/sdk';
|
|
2
2
|
import { RELEASE_CACHE_PREFIX } from '@kb-labs/release-manager-contracts';
|
|
3
3
|
import { planRelease } from '@kb-labs/release-manager-core';
|
|
4
4
|
|
|
@@ -10,101 +10,105 @@ function scopeToDir(scope) {
|
|
|
10
10
|
// src/rest/handlers/generate-handler.ts
|
|
11
11
|
var generate_handler_default = defineHandler({
|
|
12
12
|
async execute(ctx, input) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
13
|
+
try {
|
|
14
|
+
const scope = input.body?.scope || "root";
|
|
15
|
+
const bump = input.body?.bump || "auto";
|
|
16
|
+
const useLLM = input.body?.useLLM ?? true;
|
|
17
|
+
const cwd = ctx.cwd ?? process.cwd();
|
|
18
|
+
const repoRoot = await findRepoRoot(cwd);
|
|
19
|
+
ctx.platform?.logger?.info?.("Generating release plan", { scope, bump, useLLM });
|
|
20
|
+
const releaseConfig = await useConfig();
|
|
21
|
+
const config = {
|
|
22
|
+
bump,
|
|
23
|
+
strategy: "semver",
|
|
24
|
+
registry: "https://registry.npmjs.org",
|
|
25
|
+
rollback: { enabled: true },
|
|
26
|
+
versioningStrategy: releaseConfig?.versioningStrategy,
|
|
27
|
+
packages: releaseConfig?.packages,
|
|
28
|
+
scopes: releaseConfig?.scopes,
|
|
29
|
+
publish: releaseConfig?.publish
|
|
30
|
+
};
|
|
31
|
+
const corePlan = await planRelease({
|
|
32
|
+
cwd: repoRoot,
|
|
33
|
+
config,
|
|
34
|
+
scope: scope !== "root" ? scope : void 0,
|
|
35
|
+
bumpOverride: bump
|
|
36
|
+
});
|
|
37
|
+
let tokensUsed = 0;
|
|
38
|
+
const confidences = [];
|
|
39
|
+
const enhancedPackages = [];
|
|
40
|
+
for (const pkg of corePlan.packages) {
|
|
41
|
+
let reason = "Based on " + pkg.bump + " bump";
|
|
42
|
+
let pkgConfidence = 0.7;
|
|
43
|
+
if (useLLM && ctx.platform?.llm) {
|
|
44
|
+
const gitAnalysis = await analyzeGitCommits(ctx, pkg.path);
|
|
45
|
+
if (gitAnalysis.commits.length > 0) {
|
|
46
|
+
const llmResult = await analyzePlanWithLLM(ctx, {
|
|
47
|
+
packageName: pkg.name,
|
|
48
|
+
currentVersion: pkg.currentVersion || "0.0.0",
|
|
49
|
+
nextVersion: pkg.nextVersion || "0.0.1",
|
|
50
|
+
commits: gitAnalysis.commits,
|
|
51
|
+
detectedBump: pkg.bump
|
|
52
|
+
});
|
|
53
|
+
reason = llmResult.reason;
|
|
54
|
+
pkgConfidence = llmResult.confidence;
|
|
55
|
+
tokensUsed += llmResult.tokensUsed;
|
|
56
|
+
} else {
|
|
57
|
+
reason = "No unreleased commits detected";
|
|
58
|
+
pkgConfidence = 0.9;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
enhancedPackages.push({
|
|
62
|
+
...pkg,
|
|
63
|
+
reason
|
|
64
|
+
});
|
|
65
|
+
if (pkgConfidence > 0) {
|
|
66
|
+
confidences.push(pkgConfidence);
|
|
58
67
|
}
|
|
59
68
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
69
|
+
const confidence = confidences.length > 0 ? confidences.reduce((sum, c) => sum + c, 0) / confidences.length : 0;
|
|
70
|
+
const plan = {
|
|
71
|
+
schemaVersion: "1.0",
|
|
72
|
+
scope,
|
|
73
|
+
packages: enhancedPackages,
|
|
74
|
+
strategy: corePlan.strategy,
|
|
75
|
+
registry: corePlan.registry,
|
|
76
|
+
rollbackEnabled: corePlan.rollbackEnabled,
|
|
77
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
78
|
+
};
|
|
79
|
+
const scopeDir = scopeToDir(scope);
|
|
80
|
+
const planDir = repoRoot + "/.kb/release/plans/" + scopeDir + "/current";
|
|
81
|
+
await ctx.runtime.fs.mkdir(planDir, { recursive: true });
|
|
82
|
+
const planPath = planDir + "/plan.json";
|
|
83
|
+
await ctx.runtime.fs.writeFile(planPath, JSON.stringify(plan, null, 2), { encoding: "utf-8" });
|
|
84
|
+
const cacheKey = RELEASE_CACHE_PREFIX + "plan:" + scope;
|
|
85
|
+
await ctx.platform?.cache?.delete(cacheKey);
|
|
86
|
+
await ctx.platform?.analytics?.track?.("release.plan.generated", {
|
|
87
|
+
scope,
|
|
88
|
+
packagesCount: plan.packages.length,
|
|
89
|
+
bump,
|
|
90
|
+
strategy: plan.strategy,
|
|
91
|
+
useLLM,
|
|
92
|
+
tokensUsed,
|
|
93
|
+
confidence
|
|
63
94
|
});
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
95
|
+
ctx.platform?.logger?.info?.("Release plan generated", {
|
|
96
|
+
scope,
|
|
97
|
+
packagesCount: plan.packages.length,
|
|
98
|
+
useLLM,
|
|
99
|
+
tokensUsed,
|
|
100
|
+
confidence
|
|
101
|
+
});
|
|
102
|
+
return {
|
|
103
|
+
plan,
|
|
104
|
+
planPath: ".kb/release/plans/" + scopeDir + "/current/plan.json",
|
|
105
|
+
scope,
|
|
106
|
+
tokensUsed,
|
|
107
|
+
confidence
|
|
108
|
+
};
|
|
109
|
+
} catch (err) {
|
|
110
|
+
rethrowForRest(err);
|
|
67
111
|
}
|
|
68
|
-
const confidence = confidences.length > 0 ? confidences.reduce((sum, c) => sum + c, 0) / confidences.length : 0;
|
|
69
|
-
const plan = {
|
|
70
|
-
schemaVersion: "1.0",
|
|
71
|
-
scope,
|
|
72
|
-
packages: enhancedPackages,
|
|
73
|
-
strategy: corePlan.strategy,
|
|
74
|
-
registry: corePlan.registry,
|
|
75
|
-
rollbackEnabled: corePlan.rollbackEnabled,
|
|
76
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
77
|
-
};
|
|
78
|
-
const scopeDir = scopeToDir(scope);
|
|
79
|
-
const planDir = repoRoot + "/.kb/release/plans/" + scopeDir + "/current";
|
|
80
|
-
await ctx.runtime.fs.mkdir(planDir, { recursive: true });
|
|
81
|
-
const planPath = planDir + "/plan.json";
|
|
82
|
-
await ctx.runtime.fs.writeFile(planPath, JSON.stringify(plan, null, 2), { encoding: "utf-8" });
|
|
83
|
-
const cacheKey = RELEASE_CACHE_PREFIX + "plan:" + scope;
|
|
84
|
-
await ctx.platform?.cache?.delete(cacheKey);
|
|
85
|
-
await ctx.platform?.analytics?.track?.("release.plan.generated", {
|
|
86
|
-
scope,
|
|
87
|
-
packagesCount: plan.packages.length,
|
|
88
|
-
bump,
|
|
89
|
-
strategy: plan.strategy,
|
|
90
|
-
useLLM,
|
|
91
|
-
tokensUsed,
|
|
92
|
-
confidence
|
|
93
|
-
});
|
|
94
|
-
ctx.platform?.logger?.info?.("Release plan generated", {
|
|
95
|
-
scope,
|
|
96
|
-
packagesCount: plan.packages.length,
|
|
97
|
-
useLLM,
|
|
98
|
-
tokensUsed,
|
|
99
|
-
confidence
|
|
100
|
-
});
|
|
101
|
-
return {
|
|
102
|
-
plan,
|
|
103
|
-
planPath: ".kb/release/plans/" + scopeDir + "/current/plan.json",
|
|
104
|
-
scope,
|
|
105
|
-
tokensUsed,
|
|
106
|
-
confidence
|
|
107
|
-
};
|
|
108
112
|
}
|
|
109
113
|
});
|
|
110
114
|
async function analyzeGitCommits(ctx, pkgPath) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/shared/utils.ts","../../../src/rest/handlers/generate-handler.ts"],"names":["findRepoRoot"],"mappings":"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","file":"generate-handler.js","sourcesContent":["export { findRepoRoot } from '@kb-labs/sdk';\nexport { resolveScopePath } from './resolve-scope';\n\n/**\n * Converts scope to safe directory name\n */\nexport function scopeToDir(scope: string): string {\n return scope\n .replace(/^@/, '')\n .replace(/\\//g, '-')\n .replace(/:/g, '-')\n .replace(/\\*/g, '');\n}\n\n/**\n * Converts safe directory name back to scope\n */\nexport function dirToScope(dirName: string): string {\n if (dirName === 'root') {\n return 'root';\n }\n\n const parts = dirName.split('-');\n if (parts.length >= 2) {\n return '@' + parts[0] + '-' + parts[1] + '/' + parts.slice(2).join('-');\n }\n\n return dirName;\n}\n","/**\n * Generate release plan handler - Analyze changes and create release plan\n *\n * Writes: .kb/release/plans/{scope}/current/plan.json\n */\n\nimport { defineHandler, findRepoRoot, type RestInput, type PluginContextV3, useConfig } from '@kb-labs/sdk';\nimport type {\n GeneratePlanRequest,\n GeneratePlanResponse,\n ReleasePlan,\n PackageVersion,\n} from '@kb-labs/release-manager-contracts';\nimport { RELEASE_CACHE_PREFIX } from '@kb-labs/release-manager-contracts';\nimport { planRelease, type ReleaseConfig, type VersionBump } from '@kb-labs/release-manager-core';\nimport { scopeToDir } from '../../shared/utils';\n\nexport default defineHandler({\n async execute(ctx, input: RestInput<unknown, GeneratePlanRequest>): Promise<GeneratePlanResponse> {\n const scope = input.body?.scope || 'root';\n const bump = input.body?.bump || 'auto';\n const useLLM = input.body?.useLLM ?? true;\n const cwd = ctx.cwd ?? process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n\n ctx.platform?.logger?.info?.('Generating release plan', { scope, bump, useLLM });\n\n // Read versioningStrategy from kb.config.json release section\n const releaseConfig = await useConfig<ReleaseConfig>();\n\n // Create config for core planner\n const config: ReleaseConfig = {\n bump: bump as VersionBump,\n strategy: 'semver',\n registry: 'https://registry.npmjs.org',\n rollback: { enabled: true },\n versioningStrategy: releaseConfig?.versioningStrategy,\n packages: releaseConfig?.packages,\n scopes: releaseConfig?.scopes,\n publish: releaseConfig?.publish,\n };\n\n // Use core planner to discover packages and compute versions.\n // Always discover from repoRoot; scope is a filter applied inside planner.\n const corePlan = await planRelease({\n cwd: repoRoot,\n config,\n scope: scope !== 'root' ? scope : undefined,\n bumpOverride: bump as VersionBump | undefined,\n });\n\n let tokensUsed = 0;\n const confidences: number[] = [];\n\n // If LLM is enabled, enhance each package with AI reasoning\n const enhancedPackages: PackageVersion[] = [];\n\n for (const pkg of corePlan.packages) {\n let reason = 'Based on ' + pkg.bump + ' bump';\n let pkgConfidence = 0.7;\n\n if (useLLM && ctx.platform?.llm) {\n // Get git commits for this package to provide context to LLM\n const gitAnalysis = await analyzeGitCommits(ctx, pkg.path);\n\n if (gitAnalysis.commits.length > 0) {\n const llmResult = await analyzePlanWithLLM(ctx, {\n packageName: pkg.name,\n currentVersion: pkg.currentVersion || '0.0.0',\n nextVersion: pkg.nextVersion || '0.0.1',\n commits: gitAnalysis.commits,\n detectedBump: pkg.bump,\n });\n\n reason = llmResult.reason;\n pkgConfidence = llmResult.confidence;\n tokensUsed += llmResult.tokensUsed;\n } else {\n reason = 'No unreleased commits detected';\n pkgConfidence = 0.9;\n }\n }\n\n enhancedPackages.push({\n ...pkg,\n reason,\n });\n\n // Collect confidence scores for averaging\n if (pkgConfidence > 0) {\n confidences.push(pkgConfidence);\n }\n }\n\n // Calculate average confidence across all packages\n const confidence = confidences.length > 0\n ? confidences.reduce((sum, c) => sum + c, 0) / confidences.length\n : 0;\n\n const plan: ReleasePlan = {\n schemaVersion: '1.0',\n scope,\n packages: enhancedPackages,\n strategy: corePlan.strategy,\n registry: corePlan.registry,\n rollbackEnabled: corePlan.rollbackEnabled,\n createdAt: new Date().toISOString(),\n };\n\n // Ensure directory exists\n const scopeDir = scopeToDir(scope);\n const planDir = repoRoot + '/.kb/release/plans/' + scopeDir + '/current';\n await ctx.runtime.fs.mkdir(planDir, { recursive: true });\n\n // Write plan\n const planPath = planDir + '/plan.json';\n await ctx.runtime.fs.writeFile(planPath, JSON.stringify(plan, null, 2), { encoding: 'utf-8' });\n\n // Invalidate cache\n const cacheKey = RELEASE_CACHE_PREFIX + 'plan:' + scope;\n await ctx.platform?.cache?.delete(cacheKey);\n\n // Track analytics\n await ctx.platform?.analytics?.track?.('release.plan.generated', {\n scope,\n packagesCount: plan.packages.length,\n bump,\n strategy: plan.strategy,\n useLLM,\n tokensUsed,\n confidence,\n });\n\n ctx.platform?.logger?.info?.('Release plan generated', {\n scope,\n packagesCount: plan.packages.length,\n useLLM,\n tokensUsed,\n confidence,\n });\n\n return {\n plan,\n planPath: '.kb/release/plans/' + scopeDir + '/current/plan.json',\n scope,\n tokensUsed,\n confidence,\n };\n }\n});\n\n/**\n * Analyze git commits to get context for package\n */\nasync function analyzeGitCommits(ctx: PluginContextV3, pkgPath: string): Promise<{\n commits: Array<{ type: string; message: string; sha: string }>;\n}> {\n try {\n ctx.platform?.logger?.info?.('Starting git analysis', { pkgPath });\n\n // Get last git tag\n const lastTagResult = await ctx.api.shell.exec(\n 'git',\n ['describe', '--tags', '--abbrev=0'],\n { cwd: pkgPath }\n );\n const lastTag = lastTagResult.code === 0 ? lastTagResult.stdout.trim() : undefined;\n\n ctx.platform?.logger?.info?.('Got last tag', { lastTag, code: lastTagResult.code });\n\n // Get commits since last tag\n const gitLogArgs = lastTag\n ? ['log', lastTag + '..HEAD', '--pretty=format:%H|%s', '--max-count=20']\n : ['log', '--pretty=format:%H|%s', '--max-count=20'];\n\n ctx.platform?.logger?.info?.('Executing git log', { args: gitLogArgs });\n\n const logResult = await ctx.api.shell.exec('git', gitLogArgs, { cwd: pkgPath });\n\n ctx.platform?.logger?.info?.('Git log result', {\n code: logResult.code,\n stdout: logResult.stdout?.substring(0, 200),\n stderr: logResult.stderr?.substring(0, 200),\n args: gitLogArgs,\n cwd: pkgPath,\n });\n\n const commits: Array<{ type: string; message: string; sha: string }> = [];\n if (logResult.code === 0 && logResult.stdout) {\n const lines = logResult.stdout.trim().split('\\n').filter(Boolean);\n\n for (const line of lines) {\n const parts = line.split('|');\n const sha = parts[0];\n const message = parts[1];\n if (!sha || !message) {continue;}\n\n const parsed = parseConventionalCommit(message);\n commits.push({\n sha: sha.substring(0, 7),\n message,\n type: parsed.type,\n });\n }\n }\n\n return { commits };\n } catch (error) {\n ctx.platform?.logger?.error?.('Git analysis failed', error instanceof Error ? error : undefined);\n return { commits: [] };\n }\n}\n\n/**\n * Parse conventional commit message\n */\nfunction parseConventionalCommit(message: string): { type: string } {\n if (message.includes('BREAKING CHANGE') || message.includes('!:')) {\n return { type: 'BREAKING' };\n }\n\n const match = message.match(/^(\\w+)(?:\\([^)]+\\))?!?:\\s*(.+)/);\n if (!match) {\n return { type: 'unknown' };\n }\n\n const type = match[1];\n if (!type) {return { type: 'unknown' };}\n\n return { type: type.toLowerCase() };\n}\n\n/**\n * Analyze plan using LLM to provide reasoning for version bump\n */\nasync function analyzePlanWithLLM(\n ctx: PluginContextV3,\n input: {\n packageName: string;\n currentVersion: string;\n nextVersion: string;\n commits: Array<{ type: string; message: string; sha: string }>;\n detectedBump: string;\n }\n): Promise<{ reason: string; tokensUsed: number; confidence: number }> {\n const { packageName, currentVersion, nextVersion, commits, detectedBump } = input;\n\n // Build commit list\n const commitList = commits.length > 0\n ? commits.slice(0, 10).map(c => '- [' + c.sha + '] ' + c.type + ': ' + c.message).join('\\n')\n : '(No unreleased commits)';\n\n const prompt = 'You are analyzing a release plan for a package to provide clear reasoning for the version bump.\\n\\nPackage: ' + packageName + '\\nCurrent version: ' + currentVersion + '\\nNext version: ' + nextVersion + '\\nDetected bump: ' + detectedBump + '\\n\\nRecent commits:\\n' + commitList + '\\n\\nYour task:\\nProvide a clear, concise reason (1-2 sentences) explaining WHY this version bump is appropriate based on the commits.\\n\\nFocus on:\\n- What changed (new features, bug fixes, breaking changes)\\n- Why it requires this specific bump type\\n\\nRespond ONLY with valid JSON in this format:\\n{\\n \"reason\": \"Brief explanation (1-2 sentences focusing on what changed)\",\\n \"confidence\": 0.0-1.0\\n}';\n\n try {\n const response = await ctx.platform!.llm!.complete(prompt, {\n maxTokens: 200,\n temperature: 0.3,\n });\n\n const parsed = JSON.parse(response.content);\n\n return {\n reason: parsed.reason || detectedBump + ' bump based on commit analysis',\n tokensUsed: response.usage.completionTokens + response.usage.promptTokens,\n confidence: parsed.confidence || 0.7,\n };\n } catch (error) {\n ctx.platform?.logger?.error?.(\n 'LLM reasoning failed, using simple explanation',\n error instanceof Error ? error : undefined\n );\n\n // Fallback to simple explanation\n const typeCount: Record<string, number> = {};\n commits.forEach(c => {\n typeCount[c.type] = (typeCount[c.type] || 0) + 1;\n });\n\n const summary = Object.entries(typeCount)\n .map(entry => entry[1] + ' ' + entry[0])\n .join(', ');\n\n return {\n reason: commits.length > 0\n ? 'Based on ' + commits.length + ' commit(s): ' + summary\n : 'No unreleased changes',\n tokensUsed: 0,\n confidence: 0.6,\n };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/shared/utils.ts","../../../src/rest/handlers/generate-handler.ts"],"names":["findRepoRoot"],"mappings":"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","file":"generate-handler.js","sourcesContent":["export { findRepoRoot } from '@kb-labs/sdk';\nexport { resolveScopePath } from './resolve-scope';\n\n/**\n * Converts scope to safe directory name\n */\nexport function scopeToDir(scope: string): string {\n return scope\n .replace(/^@/, '')\n .replace(/\\//g, '-')\n .replace(/:/g, '-')\n .replace(/\\*/g, '');\n}\n\n/**\n * Converts safe directory name back to scope\n */\nexport function dirToScope(dirName: string): string {\n if (dirName === 'root') {\n return 'root';\n }\n\n const parts = dirName.split('-');\n if (parts.length >= 2) {\n return '@' + parts[0] + '-' + parts[1] + '/' + parts.slice(2).join('-');\n }\n\n return dirName;\n}\n","/**\n * Generate release plan handler - Analyze changes and create release plan\n *\n * Writes: .kb/release/plans/{scope}/current/plan.json\n */\n\nimport { defineHandler, findRepoRoot, type RestInput, type PluginContextV3, useConfig, rethrowForRest } from '@kb-labs/sdk';\nimport type {\n GeneratePlanRequest,\n GeneratePlanResponse,\n ReleasePlan,\n PackageVersion,\n} from '@kb-labs/release-manager-contracts';\nimport { RELEASE_CACHE_PREFIX } from '@kb-labs/release-manager-contracts';\nimport { planRelease, type ReleaseConfig, type VersionBump } from '@kb-labs/release-manager-core';\nimport { scopeToDir } from '../../shared/utils';\n\nexport default defineHandler({\n async execute(ctx, input: RestInput<unknown, GeneratePlanRequest>): Promise<GeneratePlanResponse> {\n try {\n const scope = input.body?.scope || 'root';\n const bump = input.body?.bump || 'auto';\n const useLLM = input.body?.useLLM ?? true;\n const cwd = ctx.cwd ?? process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n\n ctx.platform?.logger?.info?.('Generating release plan', { scope, bump, useLLM });\n\n // Read versioningStrategy from kb.config.json release section\n const releaseConfig = await useConfig<ReleaseConfig>();\n\n // Create config for core planner\n const config: ReleaseConfig = {\n bump: bump as VersionBump,\n strategy: 'semver',\n registry: 'https://registry.npmjs.org',\n rollback: { enabled: true },\n versioningStrategy: releaseConfig?.versioningStrategy,\n packages: releaseConfig?.packages,\n scopes: releaseConfig?.scopes,\n publish: releaseConfig?.publish,\n };\n\n // Use core planner to discover packages and compute versions.\n // Always discover from repoRoot; scope is a filter applied inside planner.\n const corePlan = await planRelease({\n cwd: repoRoot,\n config,\n scope: scope !== 'root' ? scope : undefined,\n bumpOverride: bump as VersionBump | undefined,\n });\n\n let tokensUsed = 0;\n const confidences: number[] = [];\n\n // If LLM is enabled, enhance each package with AI reasoning\n const enhancedPackages: PackageVersion[] = [];\n\n for (const pkg of corePlan.packages) {\n let reason = 'Based on ' + pkg.bump + ' bump';\n let pkgConfidence = 0.7;\n\n if (useLLM && ctx.platform?.llm) {\n // Get git commits for this package to provide context to LLM\n const gitAnalysis = await analyzeGitCommits(ctx, pkg.path);\n\n if (gitAnalysis.commits.length > 0) {\n const llmResult = await analyzePlanWithLLM(ctx, {\n packageName: pkg.name,\n currentVersion: pkg.currentVersion || '0.0.0',\n nextVersion: pkg.nextVersion || '0.0.1',\n commits: gitAnalysis.commits,\n detectedBump: pkg.bump,\n });\n\n reason = llmResult.reason;\n pkgConfidence = llmResult.confidence;\n tokensUsed += llmResult.tokensUsed;\n } else {\n reason = 'No unreleased commits detected';\n pkgConfidence = 0.9;\n }\n }\n\n enhancedPackages.push({\n ...pkg,\n reason,\n });\n\n // Collect confidence scores for averaging\n if (pkgConfidence > 0) {\n confidences.push(pkgConfidence);\n }\n }\n\n // Calculate average confidence across all packages\n const confidence = confidences.length > 0\n ? confidences.reduce((sum, c) => sum + c, 0) / confidences.length\n : 0;\n\n const plan: ReleasePlan = {\n schemaVersion: '1.0',\n scope,\n packages: enhancedPackages,\n strategy: corePlan.strategy,\n registry: corePlan.registry,\n rollbackEnabled: corePlan.rollbackEnabled,\n createdAt: new Date().toISOString(),\n };\n\n // Ensure directory exists\n const scopeDir = scopeToDir(scope);\n const planDir = repoRoot + '/.kb/release/plans/' + scopeDir + '/current';\n await ctx.runtime.fs.mkdir(planDir, { recursive: true });\n\n // Write plan\n const planPath = planDir + '/plan.json';\n await ctx.runtime.fs.writeFile(planPath, JSON.stringify(plan, null, 2), { encoding: 'utf-8' });\n\n // Invalidate cache\n const cacheKey = RELEASE_CACHE_PREFIX + 'plan:' + scope;\n await ctx.platform?.cache?.delete(cacheKey);\n\n // Track analytics\n await ctx.platform?.analytics?.track?.('release.plan.generated', {\n scope,\n packagesCount: plan.packages.length,\n bump,\n strategy: plan.strategy,\n useLLM,\n tokensUsed,\n confidence,\n });\n\n ctx.platform?.logger?.info?.('Release plan generated', {\n scope,\n packagesCount: plan.packages.length,\n useLLM,\n tokensUsed,\n confidence,\n });\n\n return {\n plan,\n planPath: '.kb/release/plans/' + scopeDir + '/current/plan.json',\n scope,\n tokensUsed,\n confidence,\n };\n } catch (err) {\n rethrowForRest(err);\n }\n }\n});\n\n/**\n * Analyze git commits to get context for package\n */\nasync function analyzeGitCommits(ctx: PluginContextV3, pkgPath: string): Promise<{\n commits: Array<{ type: string; message: string; sha: string }>;\n}> {\n try {\n ctx.platform?.logger?.info?.('Starting git analysis', { pkgPath });\n\n // Get last git tag\n const lastTagResult = await ctx.api.shell.exec(\n 'git',\n ['describe', '--tags', '--abbrev=0'],\n { cwd: pkgPath }\n );\n const lastTag = lastTagResult.code === 0 ? lastTagResult.stdout.trim() : undefined;\n\n ctx.platform?.logger?.info?.('Got last tag', { lastTag, code: lastTagResult.code });\n\n // Get commits since last tag\n const gitLogArgs = lastTag\n ? ['log', lastTag + '..HEAD', '--pretty=format:%H|%s', '--max-count=20']\n : ['log', '--pretty=format:%H|%s', '--max-count=20'];\n\n ctx.platform?.logger?.info?.('Executing git log', { args: gitLogArgs });\n\n const logResult = await ctx.api.shell.exec('git', gitLogArgs, { cwd: pkgPath });\n\n ctx.platform?.logger?.info?.('Git log result', {\n code: logResult.code,\n stdout: logResult.stdout?.substring(0, 200),\n stderr: logResult.stderr?.substring(0, 200),\n args: gitLogArgs,\n cwd: pkgPath,\n });\n\n const commits: Array<{ type: string; message: string; sha: string }> = [];\n if (logResult.code === 0 && logResult.stdout) {\n const lines = logResult.stdout.trim().split('\\n').filter(Boolean);\n\n for (const line of lines) {\n const parts = line.split('|');\n const sha = parts[0];\n const message = parts[1];\n if (!sha || !message) {continue;}\n\n const parsed = parseConventionalCommit(message);\n commits.push({\n sha: sha.substring(0, 7),\n message,\n type: parsed.type,\n });\n }\n }\n\n return { commits };\n } catch (error) {\n ctx.platform?.logger?.error?.('Git analysis failed', error instanceof Error ? error : undefined);\n return { commits: [] };\n }\n}\n\n/**\n * Parse conventional commit message\n */\nfunction parseConventionalCommit(message: string): { type: string } {\n if (message.includes('BREAKING CHANGE') || message.includes('!:')) {\n return { type: 'BREAKING' };\n }\n\n const match = message.match(/^(\\w+)(?:\\([^)]+\\))?!?:\\s*(.+)/);\n if (!match) {\n return { type: 'unknown' };\n }\n\n const type = match[1];\n if (!type) {return { type: 'unknown' };}\n\n return { type: type.toLowerCase() };\n}\n\n/**\n * Analyze plan using LLM to provide reasoning for version bump\n */\nasync function analyzePlanWithLLM(\n ctx: PluginContextV3,\n input: {\n packageName: string;\n currentVersion: string;\n nextVersion: string;\n commits: Array<{ type: string; message: string; sha: string }>;\n detectedBump: string;\n }\n): Promise<{ reason: string; tokensUsed: number; confidence: number }> {\n const { packageName, currentVersion, nextVersion, commits, detectedBump } = input;\n\n // Build commit list\n const commitList = commits.length > 0\n ? commits.slice(0, 10).map(c => '- [' + c.sha + '] ' + c.type + ': ' + c.message).join('\\n')\n : '(No unreleased commits)';\n\n const prompt = 'You are analyzing a release plan for a package to provide clear reasoning for the version bump.\\n\\nPackage: ' + packageName + '\\nCurrent version: ' + currentVersion + '\\nNext version: ' + nextVersion + '\\nDetected bump: ' + detectedBump + '\\n\\nRecent commits:\\n' + commitList + '\\n\\nYour task:\\nProvide a clear, concise reason (1-2 sentences) explaining WHY this version bump is appropriate based on the commits.\\n\\nFocus on:\\n- What changed (new features, bug fixes, breaking changes)\\n- Why it requires this specific bump type\\n\\nRespond ONLY with valid JSON in this format:\\n{\\n \"reason\": \"Brief explanation (1-2 sentences focusing on what changed)\",\\n \"confidence\": 0.0-1.0\\n}';\n\n try {\n const response = await ctx.platform!.llm!.complete(prompt, {\n maxTokens: 200,\n temperature: 0.3,\n });\n\n const parsed = JSON.parse(response.content);\n\n return {\n reason: parsed.reason || detectedBump + ' bump based on commit analysis',\n tokensUsed: response.usage.completionTokens + response.usage.promptTokens,\n confidence: parsed.confidence || 0.7,\n };\n } catch (error) {\n ctx.platform?.logger?.error?.(\n 'LLM reasoning failed, using simple explanation',\n error instanceof Error ? error : undefined\n );\n\n // Fallback to simple explanation\n const typeCount: Record<string, number> = {};\n commits.forEach(c => {\n typeCount[c.type] = (typeCount[c.type] || 0) + 1;\n });\n\n const summary = Object.entries(typeCount)\n .map(entry => entry[1] + ' ' + entry[0])\n .join(', ');\n\n return {\n reason: commits.length > 0\n ? 'Based on ' + commits.length + ' commit(s): ' + summary\n : 'No unreleased changes',\n tokensUsed: 0,\n confidence: 0.6,\n };\n }\n}\n"]}
|
|
@@ -1,19 +1,23 @@
|
|
|
1
|
-
import { defineHandler, useConfig } from '@kb-labs/sdk';
|
|
1
|
+
import { defineHandler, useConfig, rethrowForRest } from '@kb-labs/sdk';
|
|
2
2
|
|
|
3
3
|
// src/rest/handlers/get-checks-handler.ts
|
|
4
4
|
var get_checks_handler_default = defineHandler({
|
|
5
5
|
async execute(ctx, input) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
6
|
+
try {
|
|
7
|
+
const scope = input.query?.scope ?? "root";
|
|
8
|
+
const config = await useConfig();
|
|
9
|
+
const checks = config?.scopes?.[scope]?.checks ?? config?.checks ?? [];
|
|
10
|
+
return {
|
|
11
|
+
scope,
|
|
12
|
+
checks: checks.map((c) => ({
|
|
13
|
+
id: c.id,
|
|
14
|
+
name: c.name ?? c.id,
|
|
15
|
+
optional: c.optional
|
|
16
|
+
}))
|
|
17
|
+
};
|
|
18
|
+
} catch (err) {
|
|
19
|
+
rethrowForRest(err);
|
|
20
|
+
}
|
|
17
21
|
}
|
|
18
22
|
});
|
|
19
23
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/rest/handlers/get-checks-handler.ts"],"names":[],"mappings":";;;AAWA,IAAO,6BAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAK,KAAA,EAAyE;AAC1F,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,EAAO,KAAA,IAAS,MAAA;AAEpC,
|
|
1
|
+
{"version":3,"sources":["../../../src/rest/handlers/get-checks-handler.ts"],"names":[],"mappings":";;;AAWA,IAAO,6BAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAK,KAAA,EAAyE;AAC1F,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,EAAO,KAAA,IAAS,MAAA;AAEpC,MAAA,MAAM,MAAA,GAAS,MAAM,SAAA,EAAyB;AAC9C,MAAA,MAAM,MAAA,GAA8B,QAAQ,MAAA,GAAS,KAAK,GAAG,MAAA,IAAU,MAAA,EAAQ,UAAU,EAAC;AAE1F,MAAA,OAAO;AAAA,QACL,KAAA;AAAA,QACA,MAAA,EAAQ,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,UACzB,IAAI,CAAA,CAAE,EAAA;AAAA,UACN,IAAA,EAAM,CAAA,CAAE,IAAA,IAAQ,CAAA,CAAE,EAAA;AAAA,UAClB,UAAU,CAAA,CAAE;AAAA,SACd,CAAE;AAAA,OACJ;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"get-checks-handler.js","sourcesContent":["/**\n * Get configured checks handler\n *\n * Returns the list of checks defined in kb.config.json release.checks\n * without running them. Used by the UI to show what will be checked.\n */\n\nimport { defineHandler, type RestInput, useConfig, rethrowForRest } from '@kb-labs/sdk';\nimport type { GetChecksResponse } from '@kb-labs/release-manager-contracts';\nimport type { ReleaseConfig, CustomCheckConfig } from '@kb-labs/release-manager-core';\n\nexport default defineHandler({\n async execute(ctx, input: RestInput<{ scope?: string }, never>): Promise<GetChecksResponse> {\n try {\n const scope = input.query?.scope ?? 'root';\n\n const config = await useConfig<ReleaseConfig>();\n const checks: CustomCheckConfig[] = config?.scopes?.[scope]?.checks ?? config?.checks ?? [];\n\n return {\n scope,\n checks: checks.map((c) => ({\n id: c.id,\n name: c.name ?? c.id,\n optional: c.optional,\n })),\n };\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineHandler, findRepoRoot } from '@kb-labs/sdk';
|
|
1
|
+
import { defineHandler, findRepoRoot, rethrowForRest } from '@kb-labs/sdk';
|
|
2
2
|
import { readFile } from 'fs/promises';
|
|
3
3
|
import { join } from 'path';
|
|
4
4
|
import globby from 'globby';
|
|
@@ -31,68 +31,72 @@ async function resolveScopePath(repoRoot, scope) {
|
|
|
31
31
|
// src/rest/handlers/git-timeline-handler.ts
|
|
32
32
|
var git_timeline_handler_default = defineHandler({
|
|
33
33
|
async execute(ctx, input) {
|
|
34
|
-
const scope = input.query?.scope || "root";
|
|
35
|
-
const cwd = ctx.cwd || process.cwd();
|
|
36
|
-
const repoRoot = await findRepoRoot(cwd);
|
|
37
|
-
const scopePath = await resolveScopePath(repoRoot, scope);
|
|
38
|
-
let currentVersion;
|
|
39
34
|
try {
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
cwd: scopePath
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
35
|
+
const scope = input.query?.scope || "root";
|
|
36
|
+
const cwd = ctx.cwd || process.cwd();
|
|
37
|
+
const repoRoot = await findRepoRoot(cwd);
|
|
38
|
+
const scopePath = await resolveScopePath(repoRoot, scope);
|
|
39
|
+
let currentVersion;
|
|
40
|
+
try {
|
|
41
|
+
const pkg = JSON.parse(await readFile(join(scopePath, "package.json"), "utf-8"));
|
|
42
|
+
currentVersion = pkg.version;
|
|
43
|
+
} catch {
|
|
44
|
+
}
|
|
45
|
+
const lastTagResult = await ctx.api.shell.exec(
|
|
46
|
+
"git",
|
|
47
|
+
["describe", "--tags", "--abbrev=0"],
|
|
48
|
+
{ cwd: scopePath }
|
|
49
|
+
);
|
|
50
|
+
const lastTag = lastTagResult.code === 0 ? lastTagResult.stdout.trim() : void 0;
|
|
51
|
+
const gitLogArgs = lastTag ? ["log", `${lastTag}..HEAD`, "--pretty=format:%H|%s|%an|%aI", "--"] : ["log", "--pretty=format:%H|%s|%an|%aI", "--max-count=50", "--"];
|
|
52
|
+
const logResult = await ctx.api.shell.exec("git", gitLogArgs, { cwd: scopePath });
|
|
53
|
+
ctx.platform?.logger?.info?.("Git timeline log result", {
|
|
54
|
+
code: logResult.code,
|
|
55
|
+
stdout: logResult.stdout?.substring(0, 300),
|
|
56
|
+
stderr: logResult.stderr?.substring(0, 300),
|
|
57
|
+
args: gitLogArgs,
|
|
58
|
+
cwd: scopePath,
|
|
59
|
+
lastTag
|
|
60
|
+
});
|
|
61
|
+
const commits = [];
|
|
62
|
+
if (logResult.code === 0 && logResult.stdout) {
|
|
63
|
+
const lines = logResult.stdout.trim().split("\n").filter(Boolean);
|
|
64
|
+
for (const line of lines) {
|
|
65
|
+
const [sha, message, author, date] = line.split("|");
|
|
66
|
+
if (!sha || !message) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const parsed = parseConventionalCommit(message);
|
|
70
|
+
commits.push({
|
|
71
|
+
sha: sha || "",
|
|
72
|
+
shortSha: sha ? sha.substring(0, 7) : "",
|
|
73
|
+
message: message || "",
|
|
74
|
+
type: parsed.type,
|
|
75
|
+
bump: parsed.bump,
|
|
76
|
+
scope: parsed.scope,
|
|
77
|
+
author: author || "Unknown",
|
|
78
|
+
date: date || (/* @__PURE__ */ new Date()).toISOString()
|
|
79
|
+
});
|
|
67
80
|
}
|
|
68
|
-
const parsed = parseConventionalCommit(message);
|
|
69
|
-
commits.push({
|
|
70
|
-
sha: sha || "",
|
|
71
|
-
shortSha: sha ? sha.substring(0, 7) : "",
|
|
72
|
-
message: message || "",
|
|
73
|
-
type: parsed.type,
|
|
74
|
-
bump: parsed.bump,
|
|
75
|
-
scope: parsed.scope,
|
|
76
|
-
author: author || "Unknown",
|
|
77
|
-
date: date || (/* @__PURE__ */ new Date()).toISOString()
|
|
78
|
-
});
|
|
79
81
|
}
|
|
82
|
+
const suggestedBump = calculateSuggestedBump(commits);
|
|
83
|
+
let suggestedVersion;
|
|
84
|
+
if (currentVersion && suggestedBump !== "none") {
|
|
85
|
+
suggestedVersion = bumpVersion(currentVersion, suggestedBump);
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
scope,
|
|
89
|
+
currentVersion,
|
|
90
|
+
suggestedVersion,
|
|
91
|
+
suggestedBump,
|
|
92
|
+
commits,
|
|
93
|
+
unreleased: commits.length,
|
|
94
|
+
lastTag,
|
|
95
|
+
hasUnreleasedChanges: commits.length > 0
|
|
96
|
+
};
|
|
97
|
+
} catch (err) {
|
|
98
|
+
rethrowForRest(err);
|
|
80
99
|
}
|
|
81
|
-
const suggestedBump = calculateSuggestedBump(commits);
|
|
82
|
-
let suggestedVersion;
|
|
83
|
-
if (currentVersion && suggestedBump !== "none") {
|
|
84
|
-
suggestedVersion = bumpVersion(currentVersion, suggestedBump);
|
|
85
|
-
}
|
|
86
|
-
return {
|
|
87
|
-
scope,
|
|
88
|
-
currentVersion,
|
|
89
|
-
suggestedVersion,
|
|
90
|
-
suggestedBump,
|
|
91
|
-
commits,
|
|
92
|
-
unreleased: commits.length,
|
|
93
|
-
lastTag,
|
|
94
|
-
hasUnreleasedChanges: commits.length > 0
|
|
95
|
-
};
|
|
96
100
|
}
|
|
97
101
|
});
|
|
98
102
|
function parseConventionalCommit(message) {
|