@kb-labs/release-manager-cli 2.93.0 → 2.96.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/{919.js → 215.js} +1 -1
- package/dist/widgets/370.js +1 -1
- package/dist/widgets/{805.js → 46.js} +92 -92
- package/dist/widgets/50.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/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 +39 -39
- package/dist/widgets/remoteEntry.js +2 -2
- package/package.json +9 -8
- package/dist/widgets/418.js +0 -38
- package/dist/widgets/451.js +0 -1
- package/dist/widgets/694.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/shared/resolve-scope.ts","../../../src/rest/handlers/git-timeline-handler.ts"],"names":["findRepoRoot","readFile","join"],"mappings":"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","file":"git-timeline-handler.js","sourcesContent":["import { join } from 'node:path';\nimport { readFile } from 'node:fs/promises';\nimport globby from 'globby';\n\n/**\n * Resolve scope name to absolute filesystem path.\n * Scans all package.json in repoRoot to find the matching package by name.\n */\nexport async function resolveScopePath(repoRoot: string, scope: string): Promise<string> {\n if (scope === 'root') {\n return repoRoot;\n }\n\n if (scope.startsWith('@')) {\n const packageJsonPaths = await globby('**/package.json', {\n cwd: repoRoot,\n absolute: true,\n onlyFiles: true,\n ignore: ['**/node_modules/**', '**/dist/**', '**/build/**', '**/.git/**', '**/.*/**'],\n });\n\n for (const pkgJsonPath of packageJsonPaths) {\n try {\n const pkg = JSON.parse(await readFile(pkgJsonPath, 'utf-8'));\n if (pkg.name === scope) {\n return join(pkgJsonPath, '..');\n }\n } catch { /* skip */ }\n }\n }\n\n // Direct path or fallback\n return join(repoRoot, scope);\n}\n","/**\n * Git Timeline handler - Get git commit history and version preview\n *\n * Analyzes conventional commits since last tag and suggests next version\n */\n\nimport { defineHandler, findRepoRoot, type RestInput } from '@kb-labs/sdk';\nimport type {\n GitTimelineResponse,\n GitCommit,\n GitTimelineInput,\n} from '@kb-labs/release-manager-contracts';\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { resolveScopePath } from '../../shared/utils';\n\nexport default defineHandler({\n async execute(ctx, input: RestInput<GitTimelineInput>): Promise<GitTimelineResponse> {\n const scope = input.query?.scope || 'root';\n const cwd = ctx.cwd || process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n\n // Get scope path using proper package discovery\n const scopePath = await resolveScopePath(repoRoot, scope);\n\n // Get current version from package.json\n let currentVersion: string | undefined;\n try {\n const pkg = JSON.parse(await readFile(join(scopePath, 'package.json'), 'utf-8'));\n currentVersion = pkg.version;\n } catch {\n // No version found\n }\n\n // Get last git tag\n const lastTagResult = await ctx.api.shell.exec(\n 'git',\n ['describe', '--tags', '--abbrev=0'],\n { cwd: scopePath }\n );\n const lastTag = lastTagResult.code === 0 ? lastTagResult.stdout.trim() : undefined;\n\n // Get commits since last tag (or all commits if no tag)\n const gitLogArgs = lastTag\n ? ['log', `${lastTag}..HEAD`, '--pretty=format:%H|%s|%an|%aI', '--']\n : ['log', '--pretty=format:%H|%s|%an|%aI', '--max-count=50', '--'];\n\n const logResult = await ctx.api.shell.exec('git', gitLogArgs, { cwd: scopePath });\n\n ctx.platform?.logger?.info?.('Git timeline log result', {\n code: logResult.code,\n stdout: logResult.stdout?.substring(0, 300),\n stderr: logResult.stderr?.substring(0, 300),\n args: gitLogArgs,\n cwd: scopePath,\n lastTag,\n });\n\n // Parse commits\n const commits: GitCommit[] = [];\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 [sha, message, author, date] = line.split('|');\n if (!sha || !message) {continue;}\n\n const parsed = parseConventionalCommit(message);\n\n commits.push({\n sha: sha || '',\n shortSha: sha ? sha.substring(0, 7) : '',\n message: message || '',\n type: parsed.type,\n bump: parsed.bump,\n scope: parsed.scope,\n author: author || 'Unknown',\n date: date || new Date().toISOString(),\n });\n }\n }\n\n // Calculate suggested bump\n const suggestedBump = calculateSuggestedBump(commits);\n\n // Calculate suggested version\n let suggestedVersion: string | undefined;\n if (currentVersion && suggestedBump !== 'none') {\n suggestedVersion = bumpVersion(currentVersion, suggestedBump);\n }\n\n return {\n scope,\n currentVersion,\n suggestedVersion,\n suggestedBump,\n commits,\n unreleased: commits.length,\n lastTag,\n hasUnreleasedChanges: commits.length > 0,\n };\n },\n});\n\n/**\n * Parse conventional commit message\n * Format: type(scope): subject\n * Examples:\n * - feat: add new feature → minor\n * - fix: bug fix → patch\n * - feat!: breaking change → major\n * - BREAKING CHANGE: → major\n */\nfunction parseConventionalCommit(message: string): {\n type: GitCommit['type'];\n bump: GitCommit['bump'];\n scope?: string;\n} {\n // Check for BREAKING CHANGE\n if (message.includes('BREAKING CHANGE') || message.includes('!:')) {\n return { type: 'BREAKING', bump: 'major' };\n }\n\n // Parse conventional commit format\n const match = message.match(/^(\\w+)(?:\\(([^)]+)\\))?!?:\\s*(.+)/);\n\n if (!match) {\n return { type: 'unknown', bump: 'none' };\n }\n\n const [, type, scope] = match;\n\n // Type safety: if no type matched, return unknown\n if (!type) {\n return { type: 'unknown', bump: 'none', scope };\n }\n\n // Map type to bump\n let bump: GitCommit['bump'] = 'none';\n let commitType: GitCommit['type'] = 'unknown';\n\n switch (type.toLowerCase()) {\n case 'feat':\n commitType = 'feat';\n bump = 'minor';\n break;\n case 'fix':\n commitType = 'fix';\n bump = 'patch';\n break;\n case 'perf':\n commitType = 'perf';\n bump = 'patch';\n break;\n case 'chore':\n commitType = 'chore';\n bump = 'none';\n break;\n case 'docs':\n commitType = 'docs';\n bump = 'none';\n break;\n case 'refactor':\n commitType = 'refactor';\n bump = 'none';\n break;\n case 'test':\n commitType = 'test';\n bump = 'none';\n break;\n case 'style':\n commitType = 'style';\n bump = 'none';\n break;\n case 'ci':\n commitType = 'ci';\n bump = 'none';\n break;\n case 'build':\n commitType = 'build';\n bump = 'none';\n break;\n case 'revert':\n commitType = 'revert';\n bump = 'patch';\n break;\n default:\n commitType = 'unknown';\n bump = 'none';\n }\n\n return { type: commitType, bump, scope };\n}\n\n/**\n * Calculate suggested version bump based on commits\n */\nfunction calculateSuggestedBump(commits: GitCommit[]): 'major' | 'minor' | 'patch' | 'none' {\n if (commits.length === 0) {return 'none';}\n\n // Priority: major > minor > patch > none\n let hasMajor = false;\n let hasMinor = false;\n let hasPatch = false;\n\n for (const commit of commits) {\n if (commit.bump === 'major') {hasMajor = true;}\n if (commit.bump === 'minor') {hasMinor = true;}\n if (commit.bump === 'patch') {hasPatch = true;}\n }\n\n if (hasMajor) {return 'major';}\n if (hasMinor) {return 'minor';}\n if (hasPatch) {return 'patch';}\n return 'none';\n}\n\n/**\n * Bump semver version\n */\nfunction bumpVersion(version: string, bump: 'major' | 'minor' | 'patch'): string {\n const parts = version.split('.').map((v) => parseInt(v, 10));\n const [major = 0, minor = 0, patch = 0] = parts;\n\n switch (bump) {\n case 'major':\n return `${major + 1}.0.0`;\n case 'minor':\n return `${major}.${minor + 1}.0`;\n case 'patch':\n return `${major}.${minor}.${patch + 1}`;\n default:\n return version;\n }\n}\n\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/shared/resolve-scope.ts","../../../src/rest/handlers/git-timeline-handler.ts"],"names":["findRepoRoot","readFile","join"],"mappings":"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","file":"git-timeline-handler.js","sourcesContent":["import { join } from 'node:path';\nimport { readFile } from 'node:fs/promises';\nimport globby from 'globby';\n\n/**\n * Resolve scope name to absolute filesystem path.\n * Scans all package.json in repoRoot to find the matching package by name.\n */\nexport async function resolveScopePath(repoRoot: string, scope: string): Promise<string> {\n if (scope === 'root') {\n return repoRoot;\n }\n\n if (scope.startsWith('@')) {\n const packageJsonPaths = await globby('**/package.json', {\n cwd: repoRoot,\n absolute: true,\n onlyFiles: true,\n ignore: ['**/node_modules/**', '**/dist/**', '**/build/**', '**/.git/**', '**/.*/**'],\n });\n\n for (const pkgJsonPath of packageJsonPaths) {\n try {\n const pkg = JSON.parse(await readFile(pkgJsonPath, 'utf-8'));\n if (pkg.name === scope) {\n return join(pkgJsonPath, '..');\n }\n } catch { /* skip */ }\n }\n }\n\n // Direct path or fallback\n return join(repoRoot, scope);\n}\n","/**\n * Git Timeline handler - Get git commit history and version preview\n *\n * Analyzes conventional commits since last tag and suggests next version\n */\n\nimport { defineHandler, findRepoRoot, type RestInput, rethrowForRest } from '@kb-labs/sdk';\nimport type {\n GitTimelineResponse,\n GitCommit,\n GitTimelineInput,\n} from '@kb-labs/release-manager-contracts';\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { resolveScopePath } from '../../shared/utils';\n\nexport default defineHandler({\n async execute(ctx, input: RestInput<GitTimelineInput>): Promise<GitTimelineResponse> {\n try {\n const scope = input.query?.scope || 'root';\n const cwd = ctx.cwd || process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n\n // Get scope path using proper package discovery\n const scopePath = await resolveScopePath(repoRoot, scope);\n\n // Get current version from package.json\n let currentVersion: string | undefined;\n try {\n const pkg = JSON.parse(await readFile(join(scopePath, 'package.json'), 'utf-8'));\n currentVersion = pkg.version;\n } catch {\n // No version found\n }\n\n // Get last git tag\n const lastTagResult = await ctx.api.shell.exec(\n 'git',\n ['describe', '--tags', '--abbrev=0'],\n { cwd: scopePath }\n );\n const lastTag = lastTagResult.code === 0 ? lastTagResult.stdout.trim() : undefined;\n\n // Get commits since last tag (or all commits if no tag)\n const gitLogArgs = lastTag\n ? ['log', `${lastTag}..HEAD`, '--pretty=format:%H|%s|%an|%aI', '--']\n : ['log', '--pretty=format:%H|%s|%an|%aI', '--max-count=50', '--'];\n\n const logResult = await ctx.api.shell.exec('git', gitLogArgs, { cwd: scopePath });\n\n ctx.platform?.logger?.info?.('Git timeline log result', {\n code: logResult.code,\n stdout: logResult.stdout?.substring(0, 300),\n stderr: logResult.stderr?.substring(0, 300),\n args: gitLogArgs,\n cwd: scopePath,\n lastTag,\n });\n\n // Parse commits\n const commits: GitCommit[] = [];\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 [sha, message, author, date] = line.split('|');\n if (!sha || !message) {continue;}\n\n const parsed = parseConventionalCommit(message);\n\n commits.push({\n sha: sha || '',\n shortSha: sha ? sha.substring(0, 7) : '',\n message: message || '',\n type: parsed.type,\n bump: parsed.bump,\n scope: parsed.scope,\n author: author || 'Unknown',\n date: date || new Date().toISOString(),\n });\n }\n }\n\n // Calculate suggested bump\n const suggestedBump = calculateSuggestedBump(commits);\n\n // Calculate suggested version\n let suggestedVersion: string | undefined;\n if (currentVersion && suggestedBump !== 'none') {\n suggestedVersion = bumpVersion(currentVersion, suggestedBump);\n }\n\n return {\n scope,\n currentVersion,\n suggestedVersion,\n suggestedBump,\n commits,\n unreleased: commits.length,\n lastTag,\n hasUnreleasedChanges: commits.length > 0,\n };\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n\n/**\n * Parse conventional commit message\n * Format: type(scope): subject\n * Examples:\n * - feat: add new feature → minor\n * - fix: bug fix → patch\n * - feat!: breaking change → major\n * - BREAKING CHANGE: → major\n */\nfunction parseConventionalCommit(message: string): {\n type: GitCommit['type'];\n bump: GitCommit['bump'];\n scope?: string;\n} {\n // Check for BREAKING CHANGE\n if (message.includes('BREAKING CHANGE') || message.includes('!:')) {\n return { type: 'BREAKING', bump: 'major' };\n }\n\n // Parse conventional commit format\n const match = message.match(/^(\\w+)(?:\\(([^)]+)\\))?!?:\\s*(.+)/);\n\n if (!match) {\n return { type: 'unknown', bump: 'none' };\n }\n\n const [, type, scope] = match;\n\n // Type safety: if no type matched, return unknown\n if (!type) {\n return { type: 'unknown', bump: 'none', scope };\n }\n\n // Map type to bump\n let bump: GitCommit['bump'] = 'none';\n let commitType: GitCommit['type'] = 'unknown';\n\n switch (type.toLowerCase()) {\n case 'feat':\n commitType = 'feat';\n bump = 'minor';\n break;\n case 'fix':\n commitType = 'fix';\n bump = 'patch';\n break;\n case 'perf':\n commitType = 'perf';\n bump = 'patch';\n break;\n case 'chore':\n commitType = 'chore';\n bump = 'none';\n break;\n case 'docs':\n commitType = 'docs';\n bump = 'none';\n break;\n case 'refactor':\n commitType = 'refactor';\n bump = 'none';\n break;\n case 'test':\n commitType = 'test';\n bump = 'none';\n break;\n case 'style':\n commitType = 'style';\n bump = 'none';\n break;\n case 'ci':\n commitType = 'ci';\n bump = 'none';\n break;\n case 'build':\n commitType = 'build';\n bump = 'none';\n break;\n case 'revert':\n commitType = 'revert';\n bump = 'patch';\n break;\n default:\n commitType = 'unknown';\n bump = 'none';\n }\n\n return { type: commitType, bump, scope };\n}\n\n/**\n * Calculate suggested version bump based on commits\n */\nfunction calculateSuggestedBump(commits: GitCommit[]): 'major' | 'minor' | 'patch' | 'none' {\n if (commits.length === 0) {return 'none';}\n\n // Priority: major > minor > patch > none\n let hasMajor = false;\n let hasMinor = false;\n let hasPatch = false;\n\n for (const commit of commits) {\n if (commit.bump === 'major') {hasMajor = true;}\n if (commit.bump === 'minor') {hasMinor = true;}\n if (commit.bump === 'patch') {hasPatch = true;}\n }\n\n if (hasMajor) {return 'major';}\n if (hasMinor) {return 'minor';}\n if (hasPatch) {return 'patch';}\n return 'none';\n}\n\n/**\n * Bump semver version\n */\nfunction bumpVersion(version: string, bump: 'major' | 'minor' | 'patch'): string {\n const parts = version.split('.').map((v) => parseInt(v, 10));\n const [major = 0, minor = 0, patch = 0] = parts;\n\n switch (bump) {\n case 'major':\n return `${major + 1}.0.0`;\n case 'minor':\n return `${major}.${minor + 1}.0`;\n case 'patch':\n return `${major}.${minor}.${patch + 1}`;\n default:\n return version;\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
|
|
|
@@ -23,7 +23,7 @@ var history_changelog_handler_default = defineHandler({
|
|
|
23
23
|
scope
|
|
24
24
|
};
|
|
25
25
|
} catch (error) {
|
|
26
|
-
|
|
26
|
+
rethrowForRest(error);
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/shared/utils.ts","../../../src/rest/handlers/history-changelog-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;;;ACKA,IAAO,oCAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAK,KAAA,EAA+F;AAChH,IAAA,MAAM,EAAE,KAAA,EAAO,EAAA,EAAG,GAAI,KAAA,CAAM,MAAA;AAC5B,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,gBAAgB,IAAA,CAAK,QAAA,EAAU,qBAAA,EAAuB,QAAA,EAAU,IAAI,cAAc,CAAA;AAExF,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,QAAA,CAAS,aAAA,EAAe,OAAO,CAAA;AAEtD,MAAA,OAAO;AAAA,QACL,EAAA;AAAA,QACA,QAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,
|
|
1
|
+
{"version":3,"sources":["../../../src/shared/utils.ts","../../../src/rest/handlers/history-changelog-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;;;ACKA,IAAO,oCAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAK,KAAA,EAA+F;AAChH,IAAA,MAAM,EAAE,KAAA,EAAO,EAAA,EAAG,GAAI,KAAA,CAAM,MAAA;AAC5B,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,gBAAgB,IAAA,CAAK,QAAA,EAAU,qBAAA,EAAuB,QAAA,EAAU,IAAI,cAAc,CAAA;AAExF,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,QAAA,CAAS,aAAA,EAAe,OAAO,CAAA;AAEtD,MAAA,OAAO;AAAA,QACL,EAAA;AAAA,QACA,QAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,cAAA,CAAe,KAAK,CAAA;AAAA,IACtB;AAAA,EACF;AACF,CAAC","file":"history-changelog-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 * History changelog handler - Get specific changelog from history\n *\n * Reads: .kb/release/history/{scope}/{id}/changelog.md\n */\n\nimport { defineHandler, findRepoRoot, type RestInput, rethrowForRest } from '@kb-labs/sdk';\nimport type { HistoryChangelogResponse } from '@kb-labs/release-manager-contracts';\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { scopeToDir } from '../../shared/utils';\n\nexport interface HistoryChangelogParams {\n scope: string; // Scope (e.g., \"root\" or \"@kb-labs/shared\")\n id: string; // Release ID (folder name like 2026-01-04T12-30-00Z)\n}\n\nexport default defineHandler({\n async execute(ctx, input: RestInput<unknown, unknown, HistoryChangelogParams>): Promise<HistoryChangelogResponse> {\n const { scope, id } = input.params!;\n const cwd = ctx.cwd ?? process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n\n const scopeDir = scopeToDir(scope);\n const changelogPath = join(repoRoot, '.kb/release/history', scopeDir, id, 'changelog.md');\n\n try {\n const markdown = await readFile(changelogPath, 'utf-8');\n\n return {\n id,\n markdown,\n scope,\n };\n } catch (error) {\n rethrowForRest(error);\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 { readdir, readFile } from 'fs/promises';
|
|
3
3
|
import { join } from 'path';
|
|
4
4
|
|
|
@@ -20,51 +20,55 @@ function dirToScope(dirName) {
|
|
|
20
20
|
// src/rest/handlers/history-handler.ts
|
|
21
21
|
var history_handler_default = defineHandler({
|
|
22
22
|
async execute(ctx, input) {
|
|
23
|
-
const filterScope = input.query?.scope;
|
|
24
|
-
const cwd = ctx.cwd ?? process.cwd();
|
|
25
|
-
const repoRoot = await findRepoRoot(cwd);
|
|
26
|
-
const historyDir = join(repoRoot, ".kb/release/history");
|
|
27
23
|
try {
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
24
|
+
const filterScope = input.query?.scope;
|
|
25
|
+
const cwd = ctx.cwd ?? process.cwd();
|
|
26
|
+
const repoRoot = await findRepoRoot(cwd);
|
|
27
|
+
const historyDir = join(repoRoot, ".kb/release/history");
|
|
28
|
+
try {
|
|
29
|
+
const releases = [];
|
|
30
|
+
const scopeEntries = await readdir(historyDir, { withFileTypes: true });
|
|
31
|
+
const scopeFolders = scopeEntries.filter((e) => e.isDirectory());
|
|
32
|
+
for (const scopeFolder of scopeFolders) {
|
|
33
|
+
const scopeDirName = scopeFolder.name;
|
|
34
|
+
const scope = dirToScope(scopeDirName);
|
|
35
|
+
if (filterScope) {
|
|
36
|
+
const filterDirName = scopeToDir(filterScope);
|
|
37
|
+
if (scopeDirName !== filterDirName) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
38
40
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
|
|
41
|
+
const scopeDir = join(historyDir, scopeDirName);
|
|
42
|
+
const releaseEntries = await readdir(scopeDir, { withFileTypes: true });
|
|
43
|
+
const releaseFolders = releaseEntries.filter((e) => e.isDirectory());
|
|
44
|
+
for (const releaseFolder of releaseFolders) {
|
|
45
|
+
const releaseId = releaseFolder.name;
|
|
46
|
+
const reportPath = join(scopeDir, releaseId, "report.json");
|
|
47
|
+
try {
|
|
48
|
+
const reportRaw = await readFile(reportPath, "utf-8");
|
|
49
|
+
const report = JSON.parse(reportRaw);
|
|
50
|
+
releases.push({
|
|
51
|
+
id: releaseId,
|
|
52
|
+
timestamp: report.ts,
|
|
53
|
+
scope: report.scope || scope,
|
|
54
|
+
version: report.result?.version,
|
|
55
|
+
packages: report.result?.published || [],
|
|
56
|
+
success: report.result?.ok || false,
|
|
57
|
+
stage: report.stage,
|
|
58
|
+
error: report.result?.errors?.[0]
|
|
59
|
+
});
|
|
60
|
+
} catch {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
61
63
|
}
|
|
62
64
|
}
|
|
65
|
+
releases.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
|
|
66
|
+
return { releases };
|
|
67
|
+
} catch {
|
|
68
|
+
return { releases: [] };
|
|
63
69
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
} catch {
|
|
67
|
-
return { releases: [] };
|
|
70
|
+
} catch (err) {
|
|
71
|
+
rethrowForRest(err);
|
|
68
72
|
}
|
|
69
73
|
}
|
|
70
74
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/shared/utils.ts","../../../src/rest/handlers/history-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;AAKO,SAAS,WAAW,OAAA,EAAyB;AAClD,EAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,GAAG,CAAA;AAC/B,EAAA,IAAI,KAAA,CAAM,UAAU,CAAA,EAAG;AACrB,IAAA,OAAO,GAAA,GAAM,KAAA,CAAM,CAAC,CAAA,GAAI,MAAM,KAAA,CAAM,CAAC,CAAA,GAAI,GAAA,GAAM,KAAA,CAAM,KAAA,CAAM,CAAC,CAAA,CAAE,KAAK,GAAG,CAAA;AAAA,EACxE;AAEA,EAAA,OAAO,OAAA;AACT;;;ACZA,IAAO,0BAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAK,KAAA,EAA0D;AAC3E,IAAA,MAAM,WAAA,GAAc,MAAM,KAAA,EAAO,KAAA;AACjC,
|
|
1
|
+
{"version":3,"sources":["../../../src/shared/utils.ts","../../../src/rest/handlers/history-handler.ts"],"names":["findRepoRoot"],"mappings":"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","file":"history-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 * History handler - List all release history\n *\n * Reads: .kb/release/history/{scope}/{releaseId}/report.json\n */\n\nimport { defineHandler, findRepoRoot, type RestInput, rethrowForRest } from '@kb-labs/sdk';\nimport type { HistoryResponse, ReleaseHistoryItem } from '@kb-labs/release-manager-contracts';\nimport { readFile, readdir } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { dirToScope, scopeToDir } from '../../shared/utils';\n\nexport interface HistoryInput {\n scope?: string; // Optional scope filter\n}\n\nexport default defineHandler({\n async execute(ctx, input: RestInput<HistoryInput>): Promise<HistoryResponse> {\n try {\n const filterScope = input.query?.scope; // Optional scope filter\n const cwd = ctx.cwd ?? process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n const historyDir = join(repoRoot, '.kb/release/history');\n\n try {\n const releases: ReleaseHistoryItem[] = [];\n\n // Read all scope directories\n const scopeEntries = await readdir(historyDir, { withFileTypes: true });\n const scopeFolders = scopeEntries.filter((e) => e.isDirectory());\n\n for (const scopeFolder of scopeFolders) {\n const scopeDirName = scopeFolder.name; // e.g., 'kb-labs-shared' or 'root'\n const scope = dirToScope(scopeDirName); // Convert to '@kb-labs/shared' or 'root'\n\n // If filter provided, skip non-matching scopes\n if (filterScope) {\n const filterDirName = scopeToDir(filterScope);\n if (scopeDirName !== filterDirName) {\n continue;\n }\n }\n\n const scopeDir = join(historyDir, scopeDirName);\n\n // Read all release folders within this scope\n const releaseEntries = await readdir(scopeDir, { withFileTypes: true });\n const releaseFolders = releaseEntries.filter((e) => e.isDirectory());\n\n for (const releaseFolder of releaseFolders) {\n const releaseId = releaseFolder.name;\n const reportPath = join(scopeDir, releaseId, 'report.json');\n\n try {\n const reportRaw = await readFile(reportPath, 'utf-8');\n const report = JSON.parse(reportRaw);\n\n releases.push({\n id: releaseId,\n timestamp: report.ts,\n scope: report.scope || scope,\n version: report.result?.version,\n packages: report.result?.published || [],\n success: report.result?.ok || false,\n stage: report.stage,\n error: report.result?.errors?.[0],\n });\n } catch {\n // Skip invalid/incomplete releases\n continue;\n }\n }\n }\n\n // Sort by timestamp descending (newest first)\n releases.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());\n\n return { releases };\n } catch {\n // No history directory yet\n return { releases: [] };\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
|
|
|
@@ -23,7 +23,7 @@ var history_plan_handler_default = defineHandler({
|
|
|
23
23
|
plan
|
|
24
24
|
};
|
|
25
25
|
} catch (error) {
|
|
26
|
-
|
|
26
|
+
rethrowForRest(error);
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/shared/utils.ts","../../../src/rest/handlers/history-plan-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;;;ACKA,IAAO,+BAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAK,KAAA,EAAqF;AACtG,IAAA,MAAM,EAAE,KAAA,EAAO,EAAA,EAAG,GAAI,KAAA,CAAM,MAAA;AAC5B,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,WAAW,IAAA,CAAK,QAAA,EAAU,qBAAA,EAAuB,QAAA,EAAU,IAAI,WAAW,CAAA;AAEhF,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,MAAM,QAAA,CAAS,QAAA,EAAU,OAAO,CAAA;AAChD,MAAA,MAAM,IAAA,GAAoB,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA;AAE5C,MAAA,OAAO;AAAA,QACL,EAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,
|
|
1
|
+
{"version":3,"sources":["../../../src/shared/utils.ts","../../../src/rest/handlers/history-plan-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;;;ACKA,IAAO,+BAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAK,KAAA,EAAqF;AACtG,IAAA,MAAM,EAAE,KAAA,EAAO,EAAA,EAAG,GAAI,KAAA,CAAM,MAAA;AAC5B,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,WAAW,IAAA,CAAK,QAAA,EAAU,qBAAA,EAAuB,QAAA,EAAU,IAAI,WAAW,CAAA;AAEhF,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,MAAM,QAAA,CAAS,QAAA,EAAU,OAAO,CAAA;AAChD,MAAA,MAAM,IAAA,GAAoB,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA;AAE5C,MAAA,OAAO;AAAA,QACL,EAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,cAAA,CAAe,KAAK,CAAA;AAAA,IACtB;AAAA,EACF;AACF,CAAC","file":"history-plan-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 * History plan handler - Get specific release plan from history\n *\n * Reads: .kb/release/history/{scope}/{id}/plan.json\n */\n\nimport { defineHandler, findRepoRoot, type RestInput, rethrowForRest } from '@kb-labs/sdk';\nimport type { HistoryPlanResponse, ReleasePlan } from '@kb-labs/release-manager-contracts';\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { scopeToDir } from '../../shared/utils';\n\nexport interface HistoryPlanParams {\n scope: string; // Scope (e.g., \"root\" or \"@kb-labs/shared\")\n id: string; // Release ID (folder name like 2026-01-04T12-30-00Z)\n}\n\nexport default defineHandler({\n async execute(ctx, input: RestInput<unknown, unknown, HistoryPlanParams>): Promise<HistoryPlanResponse> {\n const { scope, id } = input.params!;\n const cwd = ctx.cwd ?? process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n\n const scopeDir = scopeToDir(scope);\n const planPath = join(repoRoot, '.kb/release/history', scopeDir, id, 'plan.json');\n\n try {\n const planRaw = await readFile(planPath, 'utf-8');\n const plan: ReleasePlan = JSON.parse(planRaw);\n\n return {\n id,\n plan,\n };\n } catch (error) {\n rethrowForRest(error);\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
|
|
|
@@ -23,7 +23,7 @@ var history_report_handler_default = defineHandler({
|
|
|
23
23
|
report
|
|
24
24
|
};
|
|
25
25
|
} catch (error) {
|
|
26
|
-
|
|
26
|
+
rethrowForRest(error);
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/shared/utils.ts","../../../src/rest/handlers/history-report-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;;;ACKA,IAAO,iCAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAK,KAAA,EAAyF;AAC1G,IAAA,MAAM,EAAE,KAAA,EAAO,EAAA,EAAG,GAAI,KAAA,CAAM,MAAA;AAC5B,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,aAAa,IAAA,CAAK,QAAA,EAAU,qBAAA,EAAuB,QAAA,EAAU,IAAI,aAAa,CAAA;AAEpF,IAAA,IAAI;AACF,MAAA,MAAM,SAAA,GAAY,MAAM,QAAA,CAAS,UAAA,EAAY,OAAO,CAAA;AACpD,MAAA,MAAM,MAAA,GAAwB,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA;AAElD,MAAA,OAAO;AAAA,QACL,EAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,
|
|
1
|
+
{"version":3,"sources":["../../../src/shared/utils.ts","../../../src/rest/handlers/history-report-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;;;ACKA,IAAO,iCAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAK,KAAA,EAAyF;AAC1G,IAAA,MAAM,EAAE,KAAA,EAAO,EAAA,EAAG,GAAI,KAAA,CAAM,MAAA;AAC5B,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,aAAa,IAAA,CAAK,QAAA,EAAU,qBAAA,EAAuB,QAAA,EAAU,IAAI,aAAa,CAAA;AAEpF,IAAA,IAAI;AACF,MAAA,MAAM,SAAA,GAAY,MAAM,QAAA,CAAS,UAAA,EAAY,OAAO,CAAA;AACpD,MAAA,MAAM,MAAA,GAAwB,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA;AAElD,MAAA,OAAO;AAAA,QACL,EAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,cAAA,CAAe,KAAK,CAAA;AAAA,IACtB;AAAA,EACF;AACF,CAAC","file":"history-report-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 * History report handler - Get specific release report from history\n *\n * Reads: .kb/release/history/{scope}/{id}/report.json\n */\n\nimport { defineHandler, findRepoRoot, type RestInput, rethrowForRest } from '@kb-labs/sdk';\nimport type { HistoryReportResponse, ReleaseReport } from '@kb-labs/release-manager-contracts';\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { scopeToDir } from '../../shared/utils';\n\nexport interface HistoryReportParams {\n scope: string; // Scope (e.g., \"root\" or \"@kb-labs/shared\")\n id: string; // Release ID (folder name like 2026-01-04T12-30-00Z)\n}\n\nexport default defineHandler({\n async execute(ctx, input: RestInput<unknown, unknown, HistoryReportParams>): Promise<HistoryReportResponse> {\n const { scope, id } = input.params!;\n const cwd = ctx.cwd ?? process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n\n const scopeDir = scopeToDir(scope);\n const reportPath = join(repoRoot, '.kb/release/history', scopeDir, id, 'report.json');\n\n try {\n const reportRaw = await readFile(reportPath, 'utf-8');\n const report: ReleaseReport = JSON.parse(reportRaw);\n\n return {\n id,\n report,\n };\n } catch (error) {\n rethrowForRest(error);\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 { RELEASE_CACHE_PREFIX } from '@kb-labs/release-manager-contracts';
|
|
3
3
|
|
|
4
4
|
// src/rest/handlers/plan-handler.ts
|
|
@@ -10,59 +10,63 @@ function scopeToDir(scope) {
|
|
|
10
10
|
var CACHE_TTL_MS = 15e3;
|
|
11
11
|
var plan_handler_default = defineHandler({
|
|
12
12
|
async execute(ctx, input) {
|
|
13
|
-
const scope = input.query?.scope || "root";
|
|
14
|
-
const cwd = ctx.cwd ?? process.cwd();
|
|
15
|
-
const repoRoot = await findRepoRoot(cwd);
|
|
16
|
-
ctx.platform?.logger?.info?.("Plan handler called", { scope, query: input.query });
|
|
17
|
-
const scopeDirName = scopeToDir(scope);
|
|
18
|
-
const planPath = `${repoRoot}/.kb/release/plans/${scopeDirName}/current/plan.json`;
|
|
19
|
-
const cacheKey = `${RELEASE_CACHE_PREFIX}plan:${scope}`;
|
|
20
|
-
const cached = await ctx.platform?.cache?.get(cacheKey);
|
|
21
|
-
if (cached !== void 0 && cached !== null) {
|
|
22
|
-
ctx.platform?.logger?.info?.("Returning cached plan response", {
|
|
23
|
-
scope,
|
|
24
|
-
hasPlan: cached.hasPlan,
|
|
25
|
-
fromCache: true
|
|
26
|
-
});
|
|
27
|
-
return cached;
|
|
28
|
-
}
|
|
29
|
-
let raw;
|
|
30
|
-
try {
|
|
31
|
-
raw = await ctx.runtime.fs.readFile(planPath, "utf-8");
|
|
32
|
-
} catch (error) {
|
|
33
|
-
ctx.platform?.logger?.info?.("No plan found for scope", {
|
|
34
|
-
scope,
|
|
35
|
-
planPath,
|
|
36
|
-
error: error instanceof Error ? error.message : "Unknown error"
|
|
37
|
-
});
|
|
38
|
-
const response = {
|
|
39
|
-
hasPlan: false,
|
|
40
|
-
scope
|
|
41
|
-
};
|
|
42
|
-
await ctx.platform?.cache?.set(cacheKey, response, 5e3);
|
|
43
|
-
return response;
|
|
44
|
-
}
|
|
45
13
|
try {
|
|
46
|
-
const
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
await ctx.platform?.cache?.
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
14
|
+
const scope = input.query?.scope || "root";
|
|
15
|
+
const cwd = ctx.cwd ?? process.cwd();
|
|
16
|
+
const repoRoot = await findRepoRoot(cwd);
|
|
17
|
+
ctx.platform?.logger?.info?.("Plan handler called", { scope, query: input.query });
|
|
18
|
+
const scopeDirName = scopeToDir(scope);
|
|
19
|
+
const planPath = `${repoRoot}/.kb/release/plans/${scopeDirName}/current/plan.json`;
|
|
20
|
+
const cacheKey = `${RELEASE_CACHE_PREFIX}plan:${scope}`;
|
|
21
|
+
const cached = await ctx.platform?.cache?.get(cacheKey);
|
|
22
|
+
if (cached !== void 0 && cached !== null) {
|
|
23
|
+
ctx.platform?.logger?.info?.("Returning cached plan response", {
|
|
24
|
+
scope,
|
|
25
|
+
hasPlan: cached.hasPlan,
|
|
26
|
+
fromCache: true
|
|
27
|
+
});
|
|
28
|
+
return cached;
|
|
29
|
+
}
|
|
30
|
+
let raw;
|
|
31
|
+
try {
|
|
32
|
+
raw = await ctx.runtime.fs.readFile(planPath, "utf-8");
|
|
33
|
+
} catch (error) {
|
|
34
|
+
ctx.platform?.logger?.info?.("No plan found for scope", {
|
|
35
|
+
scope,
|
|
36
|
+
planPath,
|
|
37
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
38
|
+
});
|
|
39
|
+
const response = {
|
|
40
|
+
hasPlan: false,
|
|
41
|
+
scope
|
|
42
|
+
};
|
|
43
|
+
await ctx.platform?.cache?.set(cacheKey, response, 5e3);
|
|
44
|
+
return response;
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
const plan = JSON.parse(raw);
|
|
48
|
+
const response = {
|
|
49
|
+
hasPlan: true,
|
|
50
|
+
plan,
|
|
51
|
+
scope
|
|
52
|
+
};
|
|
53
|
+
ctx.platform?.logger?.info?.("Plan loaded successfully", { scope, hasPlan: true });
|
|
54
|
+
await ctx.platform?.cache?.set(cacheKey, response, CACHE_TTL_MS);
|
|
55
|
+
return response;
|
|
56
|
+
} catch (error) {
|
|
57
|
+
ctx.platform?.logger?.error?.(
|
|
58
|
+
"Failed to parse release plan",
|
|
59
|
+
error instanceof Error ? error : void 0,
|
|
60
|
+
{ scope }
|
|
61
|
+
);
|
|
62
|
+
const response = {
|
|
63
|
+
hasPlan: false,
|
|
64
|
+
scope
|
|
65
|
+
};
|
|
66
|
+
return response;
|
|
67
|
+
}
|
|
68
|
+
} catch (err) {
|
|
69
|
+
rethrowForRest(err);
|
|
66
70
|
}
|
|
67
71
|
}
|
|
68
72
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/shared/utils.ts","../../../src/rest/handlers/plan-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;;;ACAA,IAAM,YAAA,GAAe,IAAA;AAErB,IAAO,uBAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAK,KAAA,EAAoD;AACrE,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,EAAO,KAAA,IAAS,MAAA;AACpC,
|
|
1
|
+
{"version":3,"sources":["../../../src/shared/utils.ts","../../../src/rest/handlers/plan-handler.ts"],"names":["findRepoRoot"],"mappings":"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","file":"plan-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 * Plan handler - Get current release plan for a scope\n *\n * Reads: .kb/release/plans/{scope}/current/plan.json\n * Cache: 15s TTL to avoid repeated file reads\n */\n\nimport { defineHandler, findRepoRoot, type RestInput, rethrowForRest } from '@kb-labs/sdk';\nimport type { PlanResponse, ReleasePlan, PlanInput } from '@kb-labs/release-manager-contracts';\nimport { RELEASE_CACHE_PREFIX } from '@kb-labs/release-manager-contracts';\nimport { scopeToDir } from '../../shared/utils';\n\nconst CACHE_TTL_MS = 15000; // 15 seconds\n\nexport default defineHandler({\n async execute(ctx, input: RestInput<PlanInput>): Promise<PlanResponse> {\n try {\n const scope = input.query?.scope || 'root';\n const cwd = ctx.cwd ?? process.cwd();\n const repoRoot = await findRepoRoot(cwd);\n\n ctx.platform?.logger?.info?.('Plan handler called', { scope, query: input.query });\n\n const scopeDirName = scopeToDir(scope);\n const planPath = `${repoRoot}/.kb/release/plans/${scopeDirName}/current/plan.json`;\n const cacheKey = `${RELEASE_CACHE_PREFIX}plan:${scope}`;\n\n // Try cache first\n const cached = await ctx.platform?.cache?.get(cacheKey);\n if (cached !== undefined && cached !== null) {\n ctx.platform?.logger?.info?.('Returning cached plan response', {\n scope,\n hasPlan: (cached as PlanResponse).hasPlan,\n fromCache: true\n });\n return cached as PlanResponse;\n }\n\n // Cache miss - read from file\n let raw: string;\n try {\n raw = await ctx.runtime.fs.readFile(planPath, 'utf-8');\n } catch (error) {\n // No plan found for this scope\n ctx.platform?.logger?.info?.('No plan found for scope', {\n scope,\n planPath,\n error: error instanceof Error ? error.message : 'Unknown error'\n });\n\n const response: PlanResponse = {\n hasPlan: false,\n scope,\n };\n // Cache negative result too (shorter TTL)\n await ctx.platform?.cache?.set(cacheKey, response, 5000); // 5s for \"not found\"\n return response;\n }\n\n try {\n const plan: ReleasePlan = JSON.parse(raw);\n const response: PlanResponse = {\n hasPlan: true,\n plan,\n scope,\n };\n\n ctx.platform?.logger?.info?.('Plan loaded successfully', { scope, hasPlan: true });\n\n // Cache successful result\n await ctx.platform?.cache?.set(cacheKey, response, CACHE_TTL_MS);\n return response;\n } catch (error) {\n ctx.platform?.logger?.error?.(\n 'Failed to parse release plan',\n error instanceof Error ? error : undefined,\n { scope }\n );\n\n const response: PlanResponse = {\n hasPlan: false,\n scope,\n };\n return response;\n }\n } catch (err) {\n rethrowForRest(err);\n }\n }\n});\n"]}
|