@kb-labs/commit-entry 2.119.0-canary.e120bc0ee → 2.119.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.
Files changed (51) hide show
  1. package/dist/cli/commands/apply.js.map +1 -1
  2. package/dist/cli/commands/flags.js.map +1 -1
  3. package/dist/cli/commands/generate.js.map +1 -1
  4. package/dist/cli/commands/index.js.map +1 -1
  5. package/dist/cli/commands/open.js.map +1 -1
  6. package/dist/cli/commands/push.js.map +1 -1
  7. package/dist/cli/commands/reset.js.map +1 -1
  8. package/dist/cli/commands/run.js.map +1 -1
  9. package/dist/cli/index.js.map +1 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/lifecycle/index.js.map +1 -1
  12. package/dist/lifecycle/setup.js.map +1 -1
  13. package/dist/manifest.js.map +1 -1
  14. package/dist/rest/handlers/actions-handler.js.map +1 -1
  15. package/dist/rest/handlers/apply-handler.js.map +1 -1
  16. package/dist/rest/handlers/diff-handler.js.map +1 -1
  17. package/dist/rest/handlers/files-handler.js.map +1 -1
  18. package/dist/rest/handlers/generate-handler.js.map +1 -1
  19. package/dist/rest/handlers/git-status-handler.js.map +1 -1
  20. package/dist/rest/handlers/patch-plan-handler.js.map +1 -1
  21. package/dist/rest/handlers/plan-handler.js.map +1 -1
  22. package/dist/rest/handlers/push-handler.js.map +1 -1
  23. package/dist/rest/handlers/regenerate-handler.js.map +1 -1
  24. package/dist/rest/handlers/reset-handler.js.map +1 -1
  25. package/dist/rest/handlers/scope-resolver.js.map +1 -1
  26. package/dist/rest/handlers/scopes-handler.js.map +1 -1
  27. package/dist/rest/handlers/status-handler.js.map +1 -1
  28. package/dist/rest/handlers/summarize-handler.js.map +1 -1
  29. package/package.json +7 -7
  30. package/dist/manifest.json +0 -415
  31. package/dist/widgets/117.js +0 -32
  32. package/dist/widgets/165.js +0 -1
  33. package/dist/widgets/326.js +0 -1
  34. package/dist/widgets/370.js +0 -1
  35. package/dist/widgets/405.js +0 -1
  36. package/dist/widgets/46.js +0 -445
  37. package/dist/widgets/50.js +0 -1
  38. package/dist/widgets/546.js +0 -1
  39. package/dist/widgets/648.js +0 -1
  40. package/dist/widgets/669.js +0 -1
  41. package/dist/widgets/707.js +0 -1
  42. package/dist/widgets/775.js +0 -1
  43. package/dist/widgets/78.js +0 -1
  44. package/dist/widgets/832.js +0 -96
  45. package/dist/widgets/875.js +0 -25
  46. package/dist/widgets/945.js +0 -1
  47. package/dist/widgets/968.js +0 -9
  48. package/dist/widgets/__federation_expose_CommitOverview.js +0 -1
  49. package/dist/widgets/mf-manifest.json +0 -229
  50. package/dist/widgets/mf-stats.json +0 -253
  51. package/dist/widgets/remoteEntry.js +0 -7
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/rest/handlers/scope-resolver.ts","../../../src/rest/handlers/regenerate-handler.ts"],"names":[],"mappings":"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","file":"regenerate-handler.js","sourcesContent":["import * as path from 'node:path';\nimport type { CommitScope } from '@kb-labs/commit-contracts';\n\n/**\n * Resolves a scope id to an absolute filesystem path.\n *\n * Looks up the scope in the provided scopes array by id.\n * Falls back to treating the id as a relative path from baseCwd (legacy compat).\n *\n * @param baseCwd - Workspace root (ctx.cwd)\n * @param scopeId - Scope identifier, e.g. \"root\", \"public/kb-labs\"\n * @param scopes - Configured scopes from CommitPluginConfig.scope.scopes\n */\nexport function resolveScopePath(\n baseCwd: string,\n scopeId: string = 'root',\n scopes?: CommitScope[],\n): string {\n const scopeDef = scopes?.find((s) => s.id === scopeId);\n const relativePath = scopeDef?.path ?? (scopeId === 'root' ? '.' : scopeId);\n return relativePath === '.' ? baseCwd : path.join(baseCwd, relativePath);\n}\n","import { defineHandler, useConfig, type PluginContextV3, type RestInput, useLLM, useLogger, rethrowForRest } from '@kb-labs/sdk';\nimport type { LLMMessage } from '@kb-labs/sdk';\nimport {\n COMMIT_CACHE_PREFIX,\n type RegenerateCommitRequest,\n type RegenerateCommitResponse,\n type CommitGroup,\n type CommitPluginConfig,\n resolveCommitConfig,\n} from '@kb-labs/commit-contracts';\nimport { loadPlan, savePlan } from '@kb-labs/commit-core/storage';\nimport { getFileSummaries, getFileDiffs } from '@kb-labs/commit-core/analyzer';\nimport { COMMIT_PLAN_TOOL, SYSTEM_PROMPT_WITH_DIFF } from '@kb-labs/commit-core/generator';\nimport { resolveScopePath } from './scope-resolver';\n\n/**\n * POST /regenerate-commit handler\n *\n * Re-analyzes files from a single commit using LLM and replaces it in the plan.\n * Uses Phase 2 approach (with diff context) for best results.\n */\nexport default defineHandler({\n async execute(ctx: PluginContextV3, input: RestInput<unknown, RegenerateCommitRequest>): Promise<RegenerateCommitResponse> {\n const logger = useLogger();\n const { scope = 'root', commitId, instruction } = input.body ?? {};\n\n if (!commitId) {\n throw new Error('commitId is required');\n }\n\n const plan = await loadPlan(ctx.cwd, scope);\n if (!plan) {\n throw new Error('No commit plan found. Generate a plan first.');\n }\n\n const commitIndex = plan.commits.findIndex(c => c.id === commitId);\n if (commitIndex === -1) {\n throw new Error(`Commit \"${commitId}\" not found in plan`);\n }\n\n const existingCommit = plan.commits[commitIndex]!;\n const files = existingCommit.files;\n\n if (files.length === 0) {\n throw new Error('Commit has no files to regenerate');\n }\n\n const llm = useLLM();\n if (!llm || !llm.chatWithTools) {\n throw new Error('LLM is not available for regeneration');\n }\n\n try {\n // Resolve scope for file operations\n const fileConfig = await useConfig<Partial<CommitPluginConfig>>();\n const config = resolveCommitConfig(fileConfig ?? {});\n const scopeCwd = resolveScopePath(ctx.cwd, scope, config.scope?.scopes);\n\n // Get fresh file summaries and diffs\n const summaries = await getFileSummaries(scopeCwd, files);\n const diffs = await getFileDiffs(scopeCwd, files);\n\n // Build prompt for single commit regeneration\n const fileContext = summaries.map(s => {\n const diff = diffs.get(s.path) || '';\n return `File: ${s.path} (${s.status}, +${s.additions}/-${s.deletions})${diff ? `\\nDiff:\\n${diff}` : ''}`;\n }).join('\\n\\n');\n\n const instructionText = instruction\n ? `\\n\\nUser instruction: ${instruction}`\n : '';\n\n const userPrompt = `Analyze these files and generate exactly ONE commit following conventional commit conventions.\nThese files were previously grouped as: ${existingCommit.type}(${existingCommit.scope || ''}): ${existingCommit.message}\n\nRe-analyze them and generate an improved commit message.${instructionText}\n\nFiles to analyze:\n${fileContext}`;\n\n const messages: LLMMessage[] = [\n { role: 'system', content: SYSTEM_PROMPT_WITH_DIFF },\n { role: 'user', content: userPrompt },\n ];\n\n const response = await llm.chatWithTools(messages, {\n tools: [COMMIT_PLAN_TOOL],\n toolChoice: {\n type: 'function',\n function: { name: 'generate_commit_plan' },\n },\n temperature: 0.3,\n });\n\n const toolCall = response.toolCalls?.[0];\n if (!toolCall || toolCall.name !== 'generate_commit_plan') {\n throw new Error('LLM did not call generate_commit_plan tool');\n }\n\n const toolArgs = toolCall.input as { commits: CommitGroup[] };\n\n // Take the first commit from LLM output (we asked for exactly one)\n const regeneratedCommit = toolArgs.commits[0];\n if (!regeneratedCommit) {\n throw new Error('LLM returned no commits');\n }\n\n // Preserve the original commit ID and files\n regeneratedCommit.id = existingCommit.id;\n regeneratedCommit.files = existingCommit.files;\n\n // Replace in plan\n plan.commits[commitIndex] = regeneratedCommit;\n await savePlan(ctx.cwd, plan, scope);\n\n // Regenerated plan is no longer considered applied.\n const appliedCacheKey = `${COMMIT_CACHE_PREFIX}plan-applied:${scope}`;\n await ctx.platform.cache.delete(appliedCacheKey);\n\n await logger.info('[regenerate-handler] Commit regenerated', {\n scope,\n commitId,\n oldMessage: `${existingCommit.type}: ${existingCommit.message}`,\n newMessage: `${regeneratedCommit.type}: ${regeneratedCommit.message}`,\n });\n\n // Track analytics\n if (ctx.platform.analytics) {\n await ctx.platform.analytics.track('commit.regenerate.success', {\n scope,\n commitId,\n hadInstruction: !!instruction,\n filesCount: files.length,\n });\n }\n\n return {\n success: true,\n scope,\n commitId,\n commit: regeneratedCommit,\n };\n } catch (error) {\n if (ctx.platform.analytics) {\n await ctx.platform.analytics.track('commit.regenerate.error', {\n scope,\n commitId,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n rethrowForRest(error);\n }\n },\n});\n"]}
1
+ {"version":3,"sources":["../../../../home/runner/work/kb-labs/kb-labs/plugins/commit/entry/src/rest/handlers/scope-resolver.ts","../../../../home/runner/work/kb-labs/kb-labs/plugins/commit/entry/src/rest/handlers/regenerate-handler.ts"],"names":[],"mappings":"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","file":"regenerate-handler.js","sourcesContent":["import * as path from 'node:path';\nimport type { CommitScope } from '@kb-labs/commit-contracts';\n\n/**\n * Resolves a scope id to an absolute filesystem path.\n *\n * Looks up the scope in the provided scopes array by id.\n * Falls back to treating the id as a relative path from baseCwd (legacy compat).\n *\n * @param baseCwd - Workspace root (ctx.cwd)\n * @param scopeId - Scope identifier, e.g. \"root\", \"public/kb-labs\"\n * @param scopes - Configured scopes from CommitPluginConfig.scope.scopes\n */\nexport function resolveScopePath(\n baseCwd: string,\n scopeId: string = 'root',\n scopes?: CommitScope[],\n): string {\n const scopeDef = scopes?.find((s) => s.id === scopeId);\n const relativePath = scopeDef?.path ?? (scopeId === 'root' ? '.' : scopeId);\n return relativePath === '.' ? baseCwd : path.join(baseCwd, relativePath);\n}\n","import { defineHandler, useConfig, type PluginContextV3, type RestInput, useLLM, useLogger, rethrowForRest } from '@kb-labs/sdk';\nimport type { LLMMessage } from '@kb-labs/sdk';\nimport {\n COMMIT_CACHE_PREFIX,\n type RegenerateCommitRequest,\n type RegenerateCommitResponse,\n type CommitGroup,\n type CommitPluginConfig,\n resolveCommitConfig,\n} from '@kb-labs/commit-contracts';\nimport { loadPlan, savePlan } from '@kb-labs/commit-core/storage';\nimport { getFileSummaries, getFileDiffs } from '@kb-labs/commit-core/analyzer';\nimport { COMMIT_PLAN_TOOL, SYSTEM_PROMPT_WITH_DIFF } from '@kb-labs/commit-core/generator';\nimport { resolveScopePath } from './scope-resolver';\n\n/**\n * POST /regenerate-commit handler\n *\n * Re-analyzes files from a single commit using LLM and replaces it in the plan.\n * Uses Phase 2 approach (with diff context) for best results.\n */\nexport default defineHandler({\n async execute(ctx: PluginContextV3, input: RestInput<unknown, RegenerateCommitRequest>): Promise<RegenerateCommitResponse> {\n const logger = useLogger();\n const { scope = 'root', commitId, instruction } = input.body ?? {};\n\n if (!commitId) {\n throw new Error('commitId is required');\n }\n\n const plan = await loadPlan(ctx.cwd, scope);\n if (!plan) {\n throw new Error('No commit plan found. Generate a plan first.');\n }\n\n const commitIndex = plan.commits.findIndex(c => c.id === commitId);\n if (commitIndex === -1) {\n throw new Error(`Commit \"${commitId}\" not found in plan`);\n }\n\n const existingCommit = plan.commits[commitIndex]!;\n const files = existingCommit.files;\n\n if (files.length === 0) {\n throw new Error('Commit has no files to regenerate');\n }\n\n const llm = useLLM();\n if (!llm || !llm.chatWithTools) {\n throw new Error('LLM is not available for regeneration');\n }\n\n try {\n // Resolve scope for file operations\n const fileConfig = await useConfig<Partial<CommitPluginConfig>>();\n const config = resolveCommitConfig(fileConfig ?? {});\n const scopeCwd = resolveScopePath(ctx.cwd, scope, config.scope?.scopes);\n\n // Get fresh file summaries and diffs\n const summaries = await getFileSummaries(scopeCwd, files);\n const diffs = await getFileDiffs(scopeCwd, files);\n\n // Build prompt for single commit regeneration\n const fileContext = summaries.map(s => {\n const diff = diffs.get(s.path) || '';\n return `File: ${s.path} (${s.status}, +${s.additions}/-${s.deletions})${diff ? `\\nDiff:\\n${diff}` : ''}`;\n }).join('\\n\\n');\n\n const instructionText = instruction\n ? `\\n\\nUser instruction: ${instruction}`\n : '';\n\n const userPrompt = `Analyze these files and generate exactly ONE commit following conventional commit conventions.\nThese files were previously grouped as: ${existingCommit.type}(${existingCommit.scope || ''}): ${existingCommit.message}\n\nRe-analyze them and generate an improved commit message.${instructionText}\n\nFiles to analyze:\n${fileContext}`;\n\n const messages: LLMMessage[] = [\n { role: 'system', content: SYSTEM_PROMPT_WITH_DIFF },\n { role: 'user', content: userPrompt },\n ];\n\n const response = await llm.chatWithTools(messages, {\n tools: [COMMIT_PLAN_TOOL],\n toolChoice: {\n type: 'function',\n function: { name: 'generate_commit_plan' },\n },\n temperature: 0.3,\n });\n\n const toolCall = response.toolCalls?.[0];\n if (!toolCall || toolCall.name !== 'generate_commit_plan') {\n throw new Error('LLM did not call generate_commit_plan tool');\n }\n\n const toolArgs = toolCall.input as { commits: CommitGroup[] };\n\n // Take the first commit from LLM output (we asked for exactly one)\n const regeneratedCommit = toolArgs.commits[0];\n if (!regeneratedCommit) {\n throw new Error('LLM returned no commits');\n }\n\n // Preserve the original commit ID and files\n regeneratedCommit.id = existingCommit.id;\n regeneratedCommit.files = existingCommit.files;\n\n // Replace in plan\n plan.commits[commitIndex] = regeneratedCommit;\n await savePlan(ctx.cwd, plan, scope);\n\n // Regenerated plan is no longer considered applied.\n const appliedCacheKey = `${COMMIT_CACHE_PREFIX}plan-applied:${scope}`;\n await ctx.platform.cache.delete(appliedCacheKey);\n\n await logger.info('[regenerate-handler] Commit regenerated', {\n scope,\n commitId,\n oldMessage: `${existingCommit.type}: ${existingCommit.message}`,\n newMessage: `${regeneratedCommit.type}: ${regeneratedCommit.message}`,\n });\n\n // Track analytics\n if (ctx.platform.analytics) {\n await ctx.platform.analytics.track('commit.regenerate.success', {\n scope,\n commitId,\n hadInstruction: !!instruction,\n filesCount: files.length,\n });\n }\n\n return {\n success: true,\n scope,\n commitId,\n commit: regeneratedCommit,\n };\n } catch (error) {\n if (ctx.platform.analytics) {\n await ctx.platform.analytics.track('commit.regenerate.error', {\n scope,\n commitId,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n rethrowForRest(error);\n }\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/rest/handlers/reset-handler.ts"],"names":[],"mappings":";;;;;AAYA,IAAO,wBAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAAuE;AACzG,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,EAAO,KAAA,IAAS,MAAA;AAEpC,IAAA,IAAI;AACF,MAAA,MAAM,SAAA,CAAU,GAAA,CAAI,GAAA,EAAK,KAAK,CAAA;AAC9B,MAAA,MAAM,eAAA,GAAkB,CAAA,EAAG,mBAAmB,CAAA,aAAA,EAAgB,KAAK,CAAA,CAAA;AACnE,MAAA,MAAM,GAAA,CAAI,QAAA,CAAS,KAAA,CAAM,MAAA,CAAO,eAAe,CAAA;AAE/C,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,IAAA;AAAA,QACT,OAAA,EAAS,kCAAA;AAAA,QACT;AAAA,OACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,cAAA,CAAe,KAAK,CAAA;AAAA,IACtB;AAAA,EACF;AACF,CAAC","file":"reset-handler.js","sourcesContent":["import { defineHandler, type PluginContextV3, type RestInput, rethrowForRest } from '@kb-labs/sdk';\nimport {\n COMMIT_CACHE_PREFIX,\n type ResetResponse,\n} from '@kb-labs/commit-contracts';\nimport { clearPlan } from '@kb-labs/commit-core/storage';\n\n/**\n * DELETE /plan handler\n *\n * Deletes the current commit plan.\n */\nexport default defineHandler({\n async execute(ctx: PluginContextV3, input: RestInput<{ scope?: string }, unknown>): Promise<ResetResponse> {\n const scope = input.query?.scope || 'root';\n\n try {\n await clearPlan(ctx.cwd, scope);\n const appliedCacheKey = `${COMMIT_CACHE_PREFIX}plan-applied:${scope}`;\n await ctx.platform.cache.delete(appliedCacheKey);\n\n return {\n success: true,\n message: 'Commit plan deleted successfully',\n scope,\n };\n } catch (error) {\n rethrowForRest(error);\n }\n },\n});\n"]}
1
+ {"version":3,"sources":["../../../../home/runner/work/kb-labs/kb-labs/plugins/commit/entry/src/rest/handlers/reset-handler.ts"],"names":[],"mappings":";;;;;AAYA,IAAO,wBAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAAuE;AACzG,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,EAAO,KAAA,IAAS,MAAA;AAEpC,IAAA,IAAI;AACF,MAAA,MAAM,SAAA,CAAU,GAAA,CAAI,GAAA,EAAK,KAAK,CAAA;AAC9B,MAAA,MAAM,eAAA,GAAkB,CAAA,EAAG,mBAAmB,CAAA,aAAA,EAAgB,KAAK,CAAA,CAAA;AACnE,MAAA,MAAM,GAAA,CAAI,QAAA,CAAS,KAAA,CAAM,MAAA,CAAO,eAAe,CAAA;AAE/C,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,IAAA;AAAA,QACT,OAAA,EAAS,kCAAA;AAAA,QACT;AAAA,OACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,cAAA,CAAe,KAAK,CAAA;AAAA,IACtB;AAAA,EACF;AACF,CAAC","file":"reset-handler.js","sourcesContent":["import { defineHandler, type PluginContextV3, type RestInput, rethrowForRest } from '@kb-labs/sdk';\nimport {\n COMMIT_CACHE_PREFIX,\n type ResetResponse,\n} from '@kb-labs/commit-contracts';\nimport { clearPlan } from '@kb-labs/commit-core/storage';\n\n/**\n * DELETE /plan handler\n *\n * Deletes the current commit plan.\n */\nexport default defineHandler({\n async execute(ctx: PluginContextV3, input: RestInput<{ scope?: string }, unknown>): Promise<ResetResponse> {\n const scope = input.query?.scope || 'root';\n\n try {\n await clearPlan(ctx.cwd, scope);\n const appliedCacheKey = `${COMMIT_CACHE_PREFIX}plan-applied:${scope}`;\n await ctx.platform.cache.delete(appliedCacheKey);\n\n return {\n success: true,\n message: 'Commit plan deleted successfully',\n scope,\n };\n } catch (error) {\n rethrowForRest(error);\n }\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/rest/handlers/scope-resolver.ts"],"names":[],"mappings":";;;AAaO,SAAS,gBAAA,CACd,OAAA,EACA,OAAA,GAAkB,MAAA,EAClB,MAAA,EACQ;AACR,EAAA,MAAM,WAAW,MAAA,EAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,OAAO,CAAA;AACrD,EAAA,MAAM,YAAA,GAAe,QAAA,EAAU,IAAA,KAAS,OAAA,KAAY,SAAS,GAAA,GAAM,OAAA,CAAA;AACnE,EAAA,OAAO,YAAA,KAAiB,GAAA,GAAM,OAAA,GAAe,IAAA,CAAA,IAAA,CAAK,SAAS,YAAY,CAAA;AACzE","file":"scope-resolver.js","sourcesContent":["import * as path from 'node:path';\nimport type { CommitScope } from '@kb-labs/commit-contracts';\n\n/**\n * Resolves a scope id to an absolute filesystem path.\n *\n * Looks up the scope in the provided scopes array by id.\n * Falls back to treating the id as a relative path from baseCwd (legacy compat).\n *\n * @param baseCwd - Workspace root (ctx.cwd)\n * @param scopeId - Scope identifier, e.g. \"root\", \"public/kb-labs\"\n * @param scopes - Configured scopes from CommitPluginConfig.scope.scopes\n */\nexport function resolveScopePath(\n baseCwd: string,\n scopeId: string = 'root',\n scopes?: CommitScope[],\n): string {\n const scopeDef = scopes?.find((s) => s.id === scopeId);\n const relativePath = scopeDef?.path ?? (scopeId === 'root' ? '.' : scopeId);\n return relativePath === '.' ? baseCwd : path.join(baseCwd, relativePath);\n}\n"]}
1
+ {"version":3,"sources":["../../../../home/runner/work/kb-labs/kb-labs/plugins/commit/entry/src/rest/handlers/scope-resolver.ts"],"names":[],"mappings":";;;AAaO,SAAS,gBAAA,CACd,OAAA,EACA,OAAA,GAAkB,MAAA,EAClB,MAAA,EACQ;AACR,EAAA,MAAM,WAAW,MAAA,EAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,OAAO,CAAA;AACrD,EAAA,MAAM,YAAA,GAAe,QAAA,EAAU,IAAA,KAAS,OAAA,KAAY,SAAS,GAAA,GAAM,OAAA,CAAA;AACnE,EAAA,OAAO,YAAA,KAAiB,GAAA,GAAM,OAAA,GAAe,IAAA,CAAA,IAAA,CAAK,SAAS,YAAY,CAAA;AACzE","file":"scope-resolver.js","sourcesContent":["import * as path from 'node:path';\nimport type { CommitScope } from '@kb-labs/commit-contracts';\n\n/**\n * Resolves a scope id to an absolute filesystem path.\n *\n * Looks up the scope in the provided scopes array by id.\n * Falls back to treating the id as a relative path from baseCwd (legacy compat).\n *\n * @param baseCwd - Workspace root (ctx.cwd)\n * @param scopeId - Scope identifier, e.g. \"root\", \"public/kb-labs\"\n * @param scopes - Configured scopes from CommitPluginConfig.scope.scopes\n */\nexport function resolveScopePath(\n baseCwd: string,\n scopeId: string = 'root',\n scopes?: CommitScope[],\n): string {\n const scopeDef = scopes?.find((s) => s.id === scopeId);\n const relativePath = scopeDef?.path ?? (scopeId === 'root' ? '.' : scopeId);\n return relativePath === '.' ? baseCwd : path.join(baseCwd, relativePath);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/rest/handlers/scopes-handler.ts"],"names":[],"mappings":";;;;AASA,IAAO,yBAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,IAAA,EAAuB,MAAA,EAAsC;AACzE,IAAA,IAAI;AACF,MAAA,MAAM,UAAA,GAAa,MAAM,SAAA,EAAuC;AAChE,MAAA,MAAM,MAAA,GAAS,mBAAA,CAAoB,UAAA,IAAc,EAAE,CAAA;AAEnD,MAAA,MAAM,MAAA,GAAS,MAAA,CAAO,KAAA,EAAO,MAAA,IAAU,CAAC,EAAE,EAAA,EAAI,MAAA,EAAQ,KAAA,EAAO,MAAA,EAAQ,IAAA,EAAM,GAAA,EAAK,CAAA;AAChF,MAAA,MAAM,YAAY,MAAA,CAAO,KAAA,EAAO,WAAW,MAAA,CAAO,CAAC,GAAG,EAAA,IAAM,MAAA;AAE5D,MAAA,OAAO;AAAA,QACL,KAAA,EAAO,SAAA;AAAA,QACP,OAAA,EAAS,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,UAC1B,OAAO,CAAA,CAAE,EAAA;AAAA,UACT,OAAO,CAAA,CAAE,KAAA;AAAA,UACT,aAAa,CAAA,CAAE;AAAA,SACjB,CAAE;AAAA,OACJ;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"scopes-handler.js","sourcesContent":["import { defineHandler, useConfig, type PluginContextV3, type SelectData, rethrowForRest } from '@kb-labs/sdk';\nimport { type CommitPluginConfig, resolveCommitConfig } from '@kb-labs/commit-contracts';\n\n/**\n * GET /scopes handler\n *\n * Returns available scopes from kb.config.json (plugins.commit.scope.scopes).\n * Falls back to a single \"root\" scope if not configured.\n */\nexport default defineHandler({\n async execute(_ctx: PluginContextV3, _input: unknown): Promise<SelectData> {\n try {\n const fileConfig = await useConfig<Partial<CommitPluginConfig>>();\n const config = resolveCommitConfig(fileConfig ?? {});\n\n const scopes = config.scope?.scopes ?? [{ id: 'root', label: 'root', path: '.' }];\n const defaultId = config.scope?.default ?? scopes[0]?.id ?? 'root';\n\n return {\n value: defaultId,\n options: scopes.map((s) => ({\n value: s.id,\n label: s.label,\n description: s.description,\n })),\n };\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
1
+ {"version":3,"sources":["../../../../home/runner/work/kb-labs/kb-labs/plugins/commit/entry/src/rest/handlers/scopes-handler.ts"],"names":[],"mappings":";;;;AASA,IAAO,yBAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,IAAA,EAAuB,MAAA,EAAsC;AACzE,IAAA,IAAI;AACF,MAAA,MAAM,UAAA,GAAa,MAAM,SAAA,EAAuC;AAChE,MAAA,MAAM,MAAA,GAAS,mBAAA,CAAoB,UAAA,IAAc,EAAE,CAAA;AAEnD,MAAA,MAAM,MAAA,GAAS,MAAA,CAAO,KAAA,EAAO,MAAA,IAAU,CAAC,EAAE,EAAA,EAAI,MAAA,EAAQ,KAAA,EAAO,MAAA,EAAQ,IAAA,EAAM,GAAA,EAAK,CAAA;AAChF,MAAA,MAAM,YAAY,MAAA,CAAO,KAAA,EAAO,WAAW,MAAA,CAAO,CAAC,GAAG,EAAA,IAAM,MAAA;AAE5D,MAAA,OAAO;AAAA,QACL,KAAA,EAAO,SAAA;AAAA,QACP,OAAA,EAAS,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,UAC1B,OAAO,CAAA,CAAE,EAAA;AAAA,UACT,OAAO,CAAA,CAAE,KAAA;AAAA,UACT,aAAa,CAAA,CAAE;AAAA,SACjB,CAAE;AAAA,OACJ;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"scopes-handler.js","sourcesContent":["import { defineHandler, useConfig, type PluginContextV3, type SelectData, rethrowForRest } from '@kb-labs/sdk';\nimport { type CommitPluginConfig, resolveCommitConfig } from '@kb-labs/commit-contracts';\n\n/**\n * GET /scopes handler\n *\n * Returns available scopes from kb.config.json (plugins.commit.scope.scopes).\n * Falls back to a single \"root\" scope if not configured.\n */\nexport default defineHandler({\n async execute(_ctx: PluginContextV3, _input: unknown): Promise<SelectData> {\n try {\n const fileConfig = await useConfig<Partial<CommitPluginConfig>>();\n const config = resolveCommitConfig(fileConfig ?? {});\n\n const scopes = config.scope?.scopes ?? [{ id: 'root', label: 'root', path: '.' }];\n const defaultId = config.scope?.default ?? scopes[0]?.id ?? 'root';\n\n return {\n value: defaultId,\n options: scopes.map((s) => ({\n value: s.id,\n label: s.label,\n description: s.description,\n })),\n };\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/rest/handlers/scope-resolver.ts","../../../src/rest/handlers/status-handler.ts"],"names":[],"mappings":"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","file":"status-handler.js","sourcesContent":["import * as path from 'node:path';\nimport type { CommitScope } from '@kb-labs/commit-contracts';\n\n/**\n * Resolves a scope id to an absolute filesystem path.\n *\n * Looks up the scope in the provided scopes array by id.\n * Falls back to treating the id as a relative path from baseCwd (legacy compat).\n *\n * @param baseCwd - Workspace root (ctx.cwd)\n * @param scopeId - Scope identifier, e.g. \"root\", \"public/kb-labs\"\n * @param scopes - Configured scopes from CommitPluginConfig.scope.scopes\n */\nexport function resolveScopePath(\n baseCwd: string,\n scopeId: string = 'root',\n scopes?: CommitScope[],\n): string {\n const scopeDef = scopes?.find((s) => s.id === scopeId);\n const relativePath = scopeDef?.path ?? (scopeId === 'root' ? '.' : scopeId);\n return relativePath === '.' ? baseCwd : path.join(baseCwd, relativePath);\n}\n","import { defineHandler, useConfig, type RestInput, type PluginContextV3, rethrowForRest } from '@kb-labs/sdk';\nimport { loadPlan } from '@kb-labs/commit-core/storage';\nimport { getGitStatus, getCurrentBranch } from '@kb-labs/commit-core/analyzer';\nimport { checkPlanStaleness } from '@kb-labs/commit-core/validator';\nimport { COMMIT_CACHE_PREFIX, type StatusResponse, type PlanStatus, type CommitPluginConfig, resolveCommitConfig } from '@kb-labs/commit-contracts';\nimport { resolveScopePath } from './scope-resolver';\n\nconst STATUS_CACHE_TTL = 5000; // 5 seconds\n\n/**\n * GET /status handler\n *\n * Returns current status for a scope according to StatusResponse contract.\n * Uses ctx.platform.cache for git status caching.\n */\nexport default defineHandler({\n async execute(ctx: PluginContextV3, input: RestInput<{ scope?: string }>): Promise<StatusResponse> {\n const scope = input.query?.scope || 'root';\n\n ctx.platform.logger.info(`[status-handler] Fetching status for scope: ${scope}`);\n\n try {\n // Load current plan\n const plan = await loadPlan(ctx.cwd, scope);\n ctx.platform.logger.info(`[status-handler] Plan loaded: ${!!plan}`);\n\n // Resolve scope to actual directory path (same as files-handler) — needed\n // for git status, branch lookup, and disambiguating which checkout/worktree\n // this Studio instance is pointed at.\n const fileConfig = await useConfig<Partial<CommitPluginConfig>>();\n const config = resolveCommitConfig(fileConfig ?? {});\n const scopeCwd = resolveScopePath(ctx.cwd, scope, config.scope?.scopes);\n\n // Get git status (with platform cache)\n let filesChanged = 0;\n let gitStatus: { staged: string[]; unstaged: string[]; untracked: string[] } | null = null;\n const cacheKey = `${COMMIT_CACHE_PREFIX}git-status:${scope}`;\n ctx.platform.logger.info(`[status-handler] Cache key: ${cacheKey}`);\n\n // Try to get from cache\n const cached = await ctx.platform.cache.get(cacheKey);\n ctx.platform.logger.info(`[status-handler] Cache hit: ${!!cached}`);\n\n if (cached !== null && cached !== undefined) {\n // Use cached value\n const cachedData = cached as { count: number; status: { staged: string[]; unstaged: string[]; untracked: string[] } | null };\n filesChanged = cachedData.count;\n gitStatus = cachedData.status;\n } else {\n ctx.platform.logger.info(`[status-handler] Resolved scope CWD: ${scopeCwd}`);\n\n gitStatus = await getGitStatus(scopeCwd);\n ctx.platform.logger.info(`[status-handler] Git status fetched - staged: ${gitStatus.staged.length}, unstaged: ${gitStatus.unstaged.length}, untracked: ${gitStatus.untracked.length}`);\n\n filesChanged =\n gitStatus.staged.length +\n gitStatus.unstaged.length +\n gitStatus.untracked.length;\n\n ctx.platform.logger.info(`[status-handler] Total files changed: ${filesChanged}`);\n\n // Cache the result\n await ctx.platform.cache.set(\n cacheKey,\n { count: filesChanged, status: gitStatus },\n STATUS_CACHE_TTL\n );\n }\n\n // Determine plan status\n let planStatus: PlanStatus = 'idle';\n let commitsApplied = 0;\n\n if (plan) {\n // Check if commits were applied (stored in cache after apply)\n const appliedCacheKey = `${COMMIT_CACHE_PREFIX}plan-applied:${scope}`;\n const appliedData = await ctx.platform.cache.get(appliedCacheKey);\n\n if (appliedData) {\n const applied = appliedData as { commitsApplied: number; planCreatedAt?: string };\n // Only trust applied marker if it belongs to the current plan version.\n if (!applied.planCreatedAt || applied.planCreatedAt === plan.createdAt) {\n commitsApplied = applied.commitsApplied;\n planStatus = 'applied';\n } else {\n await ctx.platform.cache.delete(appliedCacheKey);\n planStatus = 'ready';\n }\n } else {\n planStatus = 'ready';\n }\n }\n\n const branch = await getCurrentBranch(scopeCwd).catch(() => undefined);\n\n // Proactively surface plan staleness — the same check `applyCommitPlan`\n // runs as a last-second guard, but here it's informational so Studio/CLI/MCP\n // can warn the user before they even attempt Apply.\n let planStale: boolean | undefined;\n let planStaleReason: string | undefined;\n if (plan) {\n const staleness = await checkPlanStaleness(scopeCwd, plan, scope);\n planStale = staleness.isStale;\n planStaleReason = staleness.isStale ? staleness.reason : undefined;\n }\n\n return {\n scope,\n hasPlan: !!plan,\n planStatus,\n filesChanged,\n commitsInPlan: plan?.commits.length || 0,\n commitsApplied,\n planTimestamp: plan?.createdAt,\n gitStatus: gitStatus || undefined,\n branch,\n workingDir: ctx.cwd,\n planStale,\n planStaleReason,\n };\n } catch (error) {\n rethrowForRest(error);\n }\n },\n});\n"]}
1
+ {"version":3,"sources":["../../../../home/runner/work/kb-labs/kb-labs/plugins/commit/entry/src/rest/handlers/scope-resolver.ts","../../../../home/runner/work/kb-labs/kb-labs/plugins/commit/entry/src/rest/handlers/status-handler.ts"],"names":[],"mappings":"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","file":"status-handler.js","sourcesContent":["import * as path from 'node:path';\nimport type { CommitScope } from '@kb-labs/commit-contracts';\n\n/**\n * Resolves a scope id to an absolute filesystem path.\n *\n * Looks up the scope in the provided scopes array by id.\n * Falls back to treating the id as a relative path from baseCwd (legacy compat).\n *\n * @param baseCwd - Workspace root (ctx.cwd)\n * @param scopeId - Scope identifier, e.g. \"root\", \"public/kb-labs\"\n * @param scopes - Configured scopes from CommitPluginConfig.scope.scopes\n */\nexport function resolveScopePath(\n baseCwd: string,\n scopeId: string = 'root',\n scopes?: CommitScope[],\n): string {\n const scopeDef = scopes?.find((s) => s.id === scopeId);\n const relativePath = scopeDef?.path ?? (scopeId === 'root' ? '.' : scopeId);\n return relativePath === '.' ? baseCwd : path.join(baseCwd, relativePath);\n}\n","import { defineHandler, useConfig, type RestInput, type PluginContextV3, rethrowForRest } from '@kb-labs/sdk';\nimport { loadPlan } from '@kb-labs/commit-core/storage';\nimport { getGitStatus, getCurrentBranch } from '@kb-labs/commit-core/analyzer';\nimport { checkPlanStaleness } from '@kb-labs/commit-core/validator';\nimport { COMMIT_CACHE_PREFIX, type StatusResponse, type PlanStatus, type CommitPluginConfig, resolveCommitConfig } from '@kb-labs/commit-contracts';\nimport { resolveScopePath } from './scope-resolver';\n\nconst STATUS_CACHE_TTL = 5000; // 5 seconds\n\n/**\n * GET /status handler\n *\n * Returns current status for a scope according to StatusResponse contract.\n * Uses ctx.platform.cache for git status caching.\n */\nexport default defineHandler({\n async execute(ctx: PluginContextV3, input: RestInput<{ scope?: string }>): Promise<StatusResponse> {\n const scope = input.query?.scope || 'root';\n\n ctx.platform.logger.info(`[status-handler] Fetching status for scope: ${scope}`);\n\n try {\n // Load current plan\n const plan = await loadPlan(ctx.cwd, scope);\n ctx.platform.logger.info(`[status-handler] Plan loaded: ${!!plan}`);\n\n // Resolve scope to actual directory path (same as files-handler) — needed\n // for git status, branch lookup, and disambiguating which checkout/worktree\n // this Studio instance is pointed at.\n const fileConfig = await useConfig<Partial<CommitPluginConfig>>();\n const config = resolveCommitConfig(fileConfig ?? {});\n const scopeCwd = resolveScopePath(ctx.cwd, scope, config.scope?.scopes);\n\n // Get git status (with platform cache)\n let filesChanged = 0;\n let gitStatus: { staged: string[]; unstaged: string[]; untracked: string[] } | null = null;\n const cacheKey = `${COMMIT_CACHE_PREFIX}git-status:${scope}`;\n ctx.platform.logger.info(`[status-handler] Cache key: ${cacheKey}`);\n\n // Try to get from cache\n const cached = await ctx.platform.cache.get(cacheKey);\n ctx.platform.logger.info(`[status-handler] Cache hit: ${!!cached}`);\n\n if (cached !== null && cached !== undefined) {\n // Use cached value\n const cachedData = cached as { count: number; status: { staged: string[]; unstaged: string[]; untracked: string[] } | null };\n filesChanged = cachedData.count;\n gitStatus = cachedData.status;\n } else {\n ctx.platform.logger.info(`[status-handler] Resolved scope CWD: ${scopeCwd}`);\n\n gitStatus = await getGitStatus(scopeCwd);\n ctx.platform.logger.info(`[status-handler] Git status fetched - staged: ${gitStatus.staged.length}, unstaged: ${gitStatus.unstaged.length}, untracked: ${gitStatus.untracked.length}`);\n\n filesChanged =\n gitStatus.staged.length +\n gitStatus.unstaged.length +\n gitStatus.untracked.length;\n\n ctx.platform.logger.info(`[status-handler] Total files changed: ${filesChanged}`);\n\n // Cache the result\n await ctx.platform.cache.set(\n cacheKey,\n { count: filesChanged, status: gitStatus },\n STATUS_CACHE_TTL\n );\n }\n\n // Determine plan status\n let planStatus: PlanStatus = 'idle';\n let commitsApplied = 0;\n\n if (plan) {\n // Check if commits were applied (stored in cache after apply)\n const appliedCacheKey = `${COMMIT_CACHE_PREFIX}plan-applied:${scope}`;\n const appliedData = await ctx.platform.cache.get(appliedCacheKey);\n\n if (appliedData) {\n const applied = appliedData as { commitsApplied: number; planCreatedAt?: string };\n // Only trust applied marker if it belongs to the current plan version.\n if (!applied.planCreatedAt || applied.planCreatedAt === plan.createdAt) {\n commitsApplied = applied.commitsApplied;\n planStatus = 'applied';\n } else {\n await ctx.platform.cache.delete(appliedCacheKey);\n planStatus = 'ready';\n }\n } else {\n planStatus = 'ready';\n }\n }\n\n const branch = await getCurrentBranch(scopeCwd).catch(() => undefined);\n\n // Proactively surface plan staleness — the same check `applyCommitPlan`\n // runs as a last-second guard, but here it's informational so Studio/CLI/MCP\n // can warn the user before they even attempt Apply.\n let planStale: boolean | undefined;\n let planStaleReason: string | undefined;\n if (plan) {\n const staleness = await checkPlanStaleness(scopeCwd, plan, scope);\n planStale = staleness.isStale;\n planStaleReason = staleness.isStale ? staleness.reason : undefined;\n }\n\n return {\n scope,\n hasPlan: !!plan,\n planStatus,\n filesChanged,\n commitsInPlan: plan?.commits.length || 0,\n commitsApplied,\n planTimestamp: plan?.createdAt,\n gitStatus: gitStatus || undefined,\n branch,\n workingDir: ctx.cwd,\n planStale,\n planStaleReason,\n };\n } catch (error) {\n rethrowForRest(error);\n }\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/rest/handlers/scope-resolver.ts","../../../src/rest/handlers/summarize-handler.ts"],"names":[],"mappings":"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","file":"summarize-handler.js","sourcesContent":["import * as path from 'node:path';\nimport type { CommitScope } from '@kb-labs/commit-contracts';\n\n/**\n * Resolves a scope id to an absolute filesystem path.\n *\n * Looks up the scope in the provided scopes array by id.\n * Falls back to treating the id as a relative path from baseCwd (legacy compat).\n *\n * @param baseCwd - Workspace root (ctx.cwd)\n * @param scopeId - Scope identifier, e.g. \"root\", \"public/kb-labs\"\n * @param scopes - Configured scopes from CommitPluginConfig.scope.scopes\n */\nexport function resolveScopePath(\n baseCwd: string,\n scopeId: string = 'root',\n scopes?: CommitScope[],\n): string {\n const scopeDef = scopes?.find((s) => s.id === scopeId);\n const relativePath = scopeDef?.path ?? (scopeId === 'root' ? '.' : scopeId);\n return relativePath === '.' ? baseCwd : path.join(baseCwd, relativePath);\n}\n","import { defineHandler, useConfig, type PluginContextV3, type RestInput, useLogger, useLLM, rethrowForRest } from '@kb-labs/sdk';\nimport { type SummarizeRequest, type SummarizeResponse, type CommitPluginConfig, resolveCommitConfig } from '@kb-labs/commit-contracts';\nimport { getFileDiff, getAllChangedFiles, getGitStatus } from '@kb-labs/commit-core/analyzer';\nimport { resolveScopePath } from './scope-resolver';\n\n/**\n * POST /summarize handler\n *\n * Summarizes changes using LLM. Can summarize:\n * - All changes in scope (if no file specified)\n * - Specific file changes (if file specified)\n */\nexport default defineHandler({\n async execute(ctx: PluginContextV3, input: RestInput<unknown, SummarizeRequest>): Promise<SummarizeResponse> {\n const logger = useLogger();\n const llm = useLLM();\n\n if (!llm) {\n throw new Error('LLM is not available. Please configure an LLM adapter.');\n }\n\n const { scope = 'root', file } = input.body || {};\n\n logger.info('[summarize-handler] Request received', { scope, file });\n\n try {\n // Resolve scope to actual directory path\n const fileConfig = await useConfig<Partial<CommitPluginConfig>>();\n const config = resolveCommitConfig(fileConfig ?? {});\n const scopeCwd = resolveScopePath(ctx.cwd, scope, config.scope?.scopes);\n logger.info('[summarize-handler] Resolved scope', { scope, scopeCwd });\n\n let prompt: string;\n\n if (file) {\n // Summarize specific file\n logger.info('[summarize-handler] Summarizing file', { file });\n\n // Get file diff (git runs FROM scopeCwd)\n const diffResult = await getFileDiff(scopeCwd, file);\n\n prompt = `Analyze this git diff and provide a concise summary of what changed in this file.\n\nFile: ${file}\n\nDiff:\n\\`\\`\\`diff\n${diffResult.diff}\n\\`\\`\\`\n\nProvide a 2-3 sentence summary focusing on:\n- What was added, modified, or removed\n- The purpose/intent of the changes\n- Any notable impacts\n\nKeep it concise and technical.`;\n } else {\n // Summarize all changes\n logger.info('[summarize-handler] Summarizing all changes');\n\n // Get git status (git runs FROM scopeCwd)\n const gitStatus = await getGitStatus(scopeCwd);\n const files = getAllChangedFiles(gitStatus);\n\n if (files.length === 0) {\n return {\n scope,\n summary: 'No changes detected in this scope.',\n };\n }\n\n // Get diffs for all files (limit to first 10 to avoid token overflow)\n const filesToSummarize = files.slice(0, 10);\n const diffs = await Promise.all(\n filesToSummarize.map(async (f) => {\n const diff = await getFileDiff(scopeCwd, f);\n return { file: f, diff: diff.diff, additions: diff.additions, deletions: diff.deletions };\n })\n );\n\n const diffsText = diffs\n .map((d) => `### ${d.file} (+${d.additions} -${d.deletions})\\n\\`\\`\\`diff\\n${d.diff}\\n\\`\\`\\``)\n .join('\\n\\n');\n\n prompt = `Analyze these git diffs and provide a high-level summary of all changes in this scope.\n\nTotal files changed: ${files.length}\n${files.length > 10 ? `(Showing first 10 files)` : ''}\n\n${diffsText}\n\nProvide a 3-5 sentence summary covering:\n- Overall theme of the changes\n- Key features added, bugs fixed, or refactorings done\n- Any notable architectural changes\n\nKeep it concise and at a high level.`;\n }\n\n // Call LLM\n logger.info('[summarize-handler] Calling LLM');\n const result = await llm.complete(prompt, {\n systemPrompt: 'You are a technical code reviewer. Provide concise, accurate summaries of code changes.',\n temperature: 0.3,\n maxTokens: 500,\n });\n\n logger.info('[summarize-handler] LLM response received', {\n tokensUsed: result.usage.promptTokens + result.usage.completionTokens,\n });\n\n return {\n scope,\n file,\n summary: result.content.trim(),\n tokensUsed: result.usage.promptTokens + result.usage.completionTokens,\n };\n } catch (error) {\n logger.error('[summarize-handler] Error', error as Error);\n rethrowForRest(error);\n }\n },\n});\n"]}
1
+ {"version":3,"sources":["../../../../home/runner/work/kb-labs/kb-labs/plugins/commit/entry/src/rest/handlers/scope-resolver.ts","../../../../home/runner/work/kb-labs/kb-labs/plugins/commit/entry/src/rest/handlers/summarize-handler.ts"],"names":[],"mappings":"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","file":"summarize-handler.js","sourcesContent":["import * as path from 'node:path';\nimport type { CommitScope } from '@kb-labs/commit-contracts';\n\n/**\n * Resolves a scope id to an absolute filesystem path.\n *\n * Looks up the scope in the provided scopes array by id.\n * Falls back to treating the id as a relative path from baseCwd (legacy compat).\n *\n * @param baseCwd - Workspace root (ctx.cwd)\n * @param scopeId - Scope identifier, e.g. \"root\", \"public/kb-labs\"\n * @param scopes - Configured scopes from CommitPluginConfig.scope.scopes\n */\nexport function resolveScopePath(\n baseCwd: string,\n scopeId: string = 'root',\n scopes?: CommitScope[],\n): string {\n const scopeDef = scopes?.find((s) => s.id === scopeId);\n const relativePath = scopeDef?.path ?? (scopeId === 'root' ? '.' : scopeId);\n return relativePath === '.' ? baseCwd : path.join(baseCwd, relativePath);\n}\n","import { defineHandler, useConfig, type PluginContextV3, type RestInput, useLogger, useLLM, rethrowForRest } from '@kb-labs/sdk';\nimport { type SummarizeRequest, type SummarizeResponse, type CommitPluginConfig, resolveCommitConfig } from '@kb-labs/commit-contracts';\nimport { getFileDiff, getAllChangedFiles, getGitStatus } from '@kb-labs/commit-core/analyzer';\nimport { resolveScopePath } from './scope-resolver';\n\n/**\n * POST /summarize handler\n *\n * Summarizes changes using LLM. Can summarize:\n * - All changes in scope (if no file specified)\n * - Specific file changes (if file specified)\n */\nexport default defineHandler({\n async execute(ctx: PluginContextV3, input: RestInput<unknown, SummarizeRequest>): Promise<SummarizeResponse> {\n const logger = useLogger();\n const llm = useLLM();\n\n if (!llm) {\n throw new Error('LLM is not available. Please configure an LLM adapter.');\n }\n\n const { scope = 'root', file } = input.body || {};\n\n logger.info('[summarize-handler] Request received', { scope, file });\n\n try {\n // Resolve scope to actual directory path\n const fileConfig = await useConfig<Partial<CommitPluginConfig>>();\n const config = resolveCommitConfig(fileConfig ?? {});\n const scopeCwd = resolveScopePath(ctx.cwd, scope, config.scope?.scopes);\n logger.info('[summarize-handler] Resolved scope', { scope, scopeCwd });\n\n let prompt: string;\n\n if (file) {\n // Summarize specific file\n logger.info('[summarize-handler] Summarizing file', { file });\n\n // Get file diff (git runs FROM scopeCwd)\n const diffResult = await getFileDiff(scopeCwd, file);\n\n prompt = `Analyze this git diff and provide a concise summary of what changed in this file.\n\nFile: ${file}\n\nDiff:\n\\`\\`\\`diff\n${diffResult.diff}\n\\`\\`\\`\n\nProvide a 2-3 sentence summary focusing on:\n- What was added, modified, or removed\n- The purpose/intent of the changes\n- Any notable impacts\n\nKeep it concise and technical.`;\n } else {\n // Summarize all changes\n logger.info('[summarize-handler] Summarizing all changes');\n\n // Get git status (git runs FROM scopeCwd)\n const gitStatus = await getGitStatus(scopeCwd);\n const files = getAllChangedFiles(gitStatus);\n\n if (files.length === 0) {\n return {\n scope,\n summary: 'No changes detected in this scope.',\n };\n }\n\n // Get diffs for all files (limit to first 10 to avoid token overflow)\n const filesToSummarize = files.slice(0, 10);\n const diffs = await Promise.all(\n filesToSummarize.map(async (f) => {\n const diff = await getFileDiff(scopeCwd, f);\n return { file: f, diff: diff.diff, additions: diff.additions, deletions: diff.deletions };\n })\n );\n\n const diffsText = diffs\n .map((d) => `### ${d.file} (+${d.additions} -${d.deletions})\\n\\`\\`\\`diff\\n${d.diff}\\n\\`\\`\\``)\n .join('\\n\\n');\n\n prompt = `Analyze these git diffs and provide a high-level summary of all changes in this scope.\n\nTotal files changed: ${files.length}\n${files.length > 10 ? `(Showing first 10 files)` : ''}\n\n${diffsText}\n\nProvide a 3-5 sentence summary covering:\n- Overall theme of the changes\n- Key features added, bugs fixed, or refactorings done\n- Any notable architectural changes\n\nKeep it concise and at a high level.`;\n }\n\n // Call LLM\n logger.info('[summarize-handler] Calling LLM');\n const result = await llm.complete(prompt, {\n systemPrompt: 'You are a technical code reviewer. Provide concise, accurate summaries of code changes.',\n temperature: 0.3,\n maxTokens: 500,\n });\n\n logger.info('[summarize-handler] LLM response received', {\n tokensUsed: result.usage.promptTokens + result.usage.completionTokens,\n });\n\n return {\n scope,\n file,\n summary: result.content.trim(),\n tokensUsed: result.usage.promptTokens + result.usage.completionTokens,\n };\n } catch (error) {\n logger.error('[summarize-handler] Error', error as Error);\n rethrowForRest(error);\n }\n },\n});\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kb-labs/commit-entry",
3
3
  "description": "CLI commands and manifest for KB Labs Commit plugin - AI-powered commit generation.",
4
- "version": "2.119.0-canary.e120bc0ee",
4
+ "version": "2.119.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
@@ -25,9 +25,9 @@
25
25
  ],
26
26
  "dependencies": {
27
27
  "glob": "^11.0.0",
28
- "@kb-labs/commit-contracts": "2.119.0-canary.e120bc0ee",
29
- "@kb-labs/commit-core": "2.119.0-canary.e120bc0ee",
30
- "@kb-labs/sdk": "2.115.4"
28
+ "@kb-labs/commit-contracts": "2.119.0",
29
+ "@kb-labs/sdk": "2.115.4",
30
+ "@kb-labs/commit-core": "2.119.0"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@rspack/cli": "^2.1.2",
@@ -39,11 +39,11 @@
39
39
  "tsup": "^8.5.0",
40
40
  "typescript": "^5.6.3",
41
41
  "vitest": "^3.2.6",
42
- "@kb-labs/studio-plugin-tools": "2.119.0-canary.e120bc0ee",
43
- "@kb-labs/devkit": "2.119.0-canary.e120bc0ee"
42
+ "@kb-labs/devkit": "2.119.0",
43
+ "@kb-labs/studio-plugin-tools": "2.119.0"
44
44
  },
45
45
  "engines": {
46
- "node": ">=22.0.0",
46
+ "node": ">=24.0.0",
47
47
  "pnpm": ">=9.0.0"
48
48
  },
49
49
  "kb": {
@@ -1,415 +0,0 @@
1
- {
2
- "schema": "kb.plugin/3",
3
- "id": "@kb-labs/commit",
4
- "version": "0.1.0",
5
- "configSection": "commit",
6
- "display": {
7
- "name": "Commit Generator",
8
- "description": "AI-powered conventional commit generation",
9
- "tags": [
10
- "commit",
11
- "git",
12
- "ai",
13
- "conventional-commits"
14
- ]
15
- },
16
- "platform": {
17
- "requires": [
18
- "storage",
19
- "cache"
20
- ],
21
- "optional": [
22
- "llm",
23
- "analytics",
24
- "logger"
25
- ]
26
- },
27
- "cli": {
28
- "groupMeta": [
29
- {
30
- "path": "commit",
31
- "describe": "AI-powered conventional commit generation."
32
- }
33
- ],
34
- "commands": [
35
- {
36
- "path": "commit",
37
- "category": "Pipeline",
38
- "describe": "Generate and apply commits (default flow).",
39
- "operationType": "execute",
40
- "longDescription": "Analyzes changes, generates commit plan with LLM, applies commits locally. Use --dry-run to preview without applying, --with-push to push after applying.",
41
- "handler": "./cli/commands/run.js#default",
42
- "flags": [
43
- {
44
- "name": "scope",
45
- "type": "string",
46
- "alias": "s",
47
- "description": "Filter by package name (@kb-labs/core), wildcard (@kb-labs/*), or path pattern (packages/**)"
48
- },
49
- {
50
- "name": "json",
51
- "type": "boolean",
52
- "default": false,
53
- "description": "Output JSON"
54
- },
55
- {
56
- "name": "dry-run",
57
- "type": "boolean",
58
- "default": false,
59
- "description": "Generate plan only, do not apply"
60
- },
61
- {
62
- "name": "with-push",
63
- "type": "boolean",
64
- "default": false,
65
- "description": "Push after apply"
66
- }
67
- ],
68
- "examples": [
69
- "kb commit commit",
70
- "kb commit commit --dry-run",
71
- "kb commit commit --with-push",
72
- "kb commit commit --scope \"src/components/**\""
73
- ]
74
- },
75
- {
76
- "path": "commit generate",
77
- "category": "Pipeline",
78
- "describe": "Generate commit plan from git changes.",
79
- "operationType": "execute",
80
- "longDescription": "Analyzes staged and unstaged changes using git diff, then uses LLM to group related changes and generate conventional commit messages.",
81
- "handler": "./cli/commands/generate.js#default",
82
- "flags": [
83
- {
84
- "name": "scope",
85
- "type": "string",
86
- "alias": "s",
87
- "description": "Filter by package name (@kb-labs/core), wildcard (@kb-labs/*), or path pattern (packages/**)"
88
- },
89
- {
90
- "name": "json",
91
- "type": "boolean",
92
- "default": false,
93
- "description": "Output JSON"
94
- }
95
- ],
96
- "examples": [
97
- "kb commit generate",
98
- "kb commit generate --json",
99
- "kb commit generate --scope \"packages/**\""
100
- ]
101
- },
102
- {
103
- "path": "commit apply",
104
- "category": "Pipeline",
105
- "describe": "Apply current commit plan (create local commits).",
106
- "operationType": "mutate",
107
- "longDescription": "Creates git commits according to the current plan. Checks for staleness (working tree changes since plan generation) unless --force is used.",
108
- "handler": "./cli/commands/apply.js#default",
109
- "flags": [
110
- {
111
- "name": "force",
112
- "type": "boolean",
113
- "alias": "f",
114
- "default": false,
115
- "description": "Apply even if working tree changed"
116
- },
117
- {
118
- "name": "json",
119
- "type": "boolean",
120
- "default": false,
121
- "description": "Output JSON"
122
- }
123
- ],
124
- "examples": [
125
- "kb commit apply",
126
- "kb commit apply --force"
127
- ]
128
- },
129
- {
130
- "path": "commit push",
131
- "category": "Pipeline",
132
- "describe": "Push commits to remote repository.",
133
- "operationType": "execute",
134
- "longDescription": "Pushes local commits to the remote. Refuses force push to protected branches (main, master) by default.",
135
- "handler": "./cli/commands/push.js#default",
136
- "flags": [
137
- {
138
- "name": "force",
139
- "type": "boolean",
140
- "alias": "f",
141
- "default": false,
142
- "description": "Force push (dangerous!)"
143
- },
144
- {
145
- "name": "json",
146
- "type": "boolean",
147
- "default": false,
148
- "description": "Output JSON"
149
- }
150
- ],
151
- "examples": [
152
- "kb commit push"
153
- ]
154
- },
155
- {
156
- "path": "commit open",
157
- "category": "Plan",
158
- "describe": "Show current commit plan.",
159
- "operationType": "read",
160
- "longDescription": "Displays the current commit plan if one exists.",
161
- "handler": "./cli/commands/open.js#default",
162
- "flags": [
163
- {
164
- "name": "json",
165
- "type": "boolean",
166
- "default": false,
167
- "description": "Output JSON"
168
- }
169
- ],
170
- "examples": [
171
- "kb commit open",
172
- "kb commit open --json"
173
- ]
174
- },
175
- {
176
- "path": "commit reset",
177
- "category": "Plan",
178
- "describe": "Clear current commit plan.",
179
- "operationType": "mutate",
180
- "longDescription": "Removes the current commit plan from storage.",
181
- "handler": "./cli/commands/reset.js#default",
182
- "flags": [],
183
- "examples": [
184
- "kb commit reset"
185
- ]
186
- }
187
- ]
188
- },
189
- "capabilities": [],
190
- "permissions": {
191
- "fs": {
192
- "read": [
193
- "**/.git/**",
194
- "**/.gitignore",
195
- "**/.gitattributes",
196
- ".kb/**",
197
- ".kb/commit/**"
198
- ],
199
- "write": [
200
- "**/.git/**",
201
- "**/.gitignore",
202
- "**/.gitattributes",
203
- ".kb/**",
204
- ".kb/commit/**"
205
- ]
206
- },
207
- "env": {
208
- "read": [
209
- "HOME",
210
- "USER",
211
- "PATH",
212
- "SHELL",
213
- "TERM",
214
- "LANG",
215
- "LC_ALL",
216
- "TZ",
217
- "TMPDIR",
218
- "GIT_*",
219
- "SSH_AUTH_SOCK",
220
- "SSH_AGENT_PID",
221
- "NODE_ENV",
222
- "KB_*",
223
- "KB_COMMIT_LLM_ENABLED",
224
- "KB_COMMIT_LLM_TEMPERATURE",
225
- "KB_COMMIT_LLM_MAX_TOKENS",
226
- "KB_COMMIT_STORAGE_DIR",
227
- "KB_COMMIT_AUTO_STAGE"
228
- ]
229
- },
230
- "platform": {
231
- "llm": true,
232
- "analytics": true,
233
- "cache": {
234
- "namespaces": [
235
- "commit:"
236
- ]
237
- }
238
- },
239
- "quotas": {
240
- "timeoutMs": 600000,
241
- "memoryMb": 512
242
- }
243
- },
244
- "rest": {
245
- "basePath": "/v1/plugins/commit",
246
- "routes": [
247
- {
248
- "method": "GET",
249
- "path": "/scopes",
250
- "handler": "./rest/handlers/scopes-handler.js#default",
251
- "output": {
252
- "zod": "@kb-labs/sdk#SelectDataSchema"
253
- }
254
- },
255
- {
256
- "method": "GET",
257
- "path": "/status",
258
- "handler": "./rest/handlers/status-handler.js#default",
259
- "output": {
260
- "zod": "@kb-labs/commit-contracts#StatusResponseSchema"
261
- }
262
- },
263
- {
264
- "method": "POST",
265
- "path": "/generate",
266
- "handler": "./rest/handlers/generate-handler.js#default",
267
- "input": {
268
- "zod": "@kb-labs/commit-contracts#GenerateRequestSchema"
269
- },
270
- "output": {
271
- "zod": "@kb-labs/commit-contracts#GenerateResponseSchema"
272
- },
273
- "timeoutMs": 300000
274
- },
275
- {
276
- "method": "GET",
277
- "path": "/plan",
278
- "handler": "./rest/handlers/plan-handler.js#default",
279
- "output": {
280
- "zod": "@kb-labs/commit-contracts#PlanResponseSchema"
281
- }
282
- },
283
- {
284
- "method": "POST",
285
- "path": "/apply",
286
- "handler": "./rest/handlers/apply-handler.js#default",
287
- "input": {
288
- "zod": "@kb-labs/commit-contracts#ApplyRequestSchema"
289
- },
290
- "output": {
291
- "zod": "@kb-labs/commit-contracts#ApplyResponseSchema"
292
- },
293
- "timeoutMs": 600000
294
- },
295
- {
296
- "method": "POST",
297
- "path": "/push",
298
- "handler": "./rest/handlers/push-handler.js#default",
299
- "input": {
300
- "zod": "@kb-labs/commit-contracts#PushRequestSchema"
301
- },
302
- "output": {
303
- "zod": "@kb-labs/commit-contracts#PushResponseSchema"
304
- },
305
- "timeoutMs": 600000
306
- },
307
- {
308
- "method": "DELETE",
309
- "path": "/plan",
310
- "handler": "./rest/handlers/reset-handler.js#default",
311
- "output": {
312
- "zod": "@kb-labs/commit-contracts#ResetResponseSchema"
313
- }
314
- },
315
- {
316
- "method": "GET",
317
- "path": "/git-status",
318
- "handler": "./rest/handlers/git-status-handler.js#default",
319
- "output": {
320
- "zod": "@kb-labs/commit-contracts#GitStatusResponseSchema"
321
- }
322
- },
323
- {
324
- "method": "GET",
325
- "path": "/files",
326
- "handler": "./rest/handlers/files-handler.js#default"
327
- },
328
- {
329
- "method": "GET",
330
- "path": "/diff",
331
- "handler": "./rest/handlers/diff-handler.js#default",
332
- "output": {
333
- "zod": "@kb-labs/commit-contracts#FileDiffResponseSchema"
334
- }
335
- },
336
- {
337
- "method": "POST",
338
- "path": "/summarize",
339
- "handler": "./rest/handlers/summarize-handler.js#default",
340
- "input": {
341
- "zod": "@kb-labs/commit-contracts#SummarizeRequestSchema"
342
- },
343
- "output": {
344
- "zod": "@kb-labs/commit-contracts#SummarizeResponseSchema"
345
- }
346
- },
347
- {
348
- "method": "GET",
349
- "path": "/actions",
350
- "handler": "./rest/handlers/actions-handler.js#default",
351
- "output": {
352
- "zod": "@kb-labs/commit-contracts#ActionsResponseSchema"
353
- }
354
- },
355
- {
356
- "method": "PATCH",
357
- "path": "/plan",
358
- "handler": "./rest/handlers/patch-plan-handler.js#default",
359
- "input": {
360
- "zod": "@kb-labs/commit-contracts#PatchPlanRequestSchema"
361
- },
362
- "output": {
363
- "zod": "@kb-labs/commit-contracts#PatchPlanResponseSchema"
364
- }
365
- },
366
- {
367
- "method": "POST",
368
- "path": "/regenerate-commit",
369
- "handler": "./rest/handlers/regenerate-handler.js#default",
370
- "input": {
371
- "zod": "@kb-labs/commit-contracts#RegenerateCommitRequestSchema"
372
- },
373
- "output": {
374
- "zod": "@kb-labs/commit-contracts#RegenerateCommitResponseSchema"
375
- },
376
- "timeoutMs": 300000
377
- }
378
- ]
379
- },
380
- "studio": {
381
- "version": 2,
382
- "remoteName": "commitPlugin",
383
- "pages": [
384
- {
385
- "id": "commit.overview",
386
- "title": "Commit",
387
- "icon": "GitlabOutlined",
388
- "route": "/p/commit",
389
- "entry": "./CommitOverview",
390
- "order": 1
391
- }
392
- ],
393
- "menus": [
394
- {
395
- "id": "commit",
396
- "label": "Commit",
397
- "icon": "GitlabOutlined",
398
- "target": "commit.overview",
399
- "order": 30
400
- }
401
- ]
402
- },
403
- "artifacts": [
404
- {
405
- "id": "commit.plan.json",
406
- "pathTemplate": ".kb/commit/current/plan.json",
407
- "description": "Current commit plan."
408
- },
409
- {
410
- "id": "commit.status.json",
411
- "pathTemplate": ".kb/commit/current/status.json",
412
- "description": "Git status snapshot at plan generation time."
413
- }
414
- ]
415
- }