@kb-labs/commit-cli 0.5.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/README.md +120 -0
- package/dist/cli/commands/apply.d.ts +22 -0
- package/dist/cli/commands/apply.js +132 -0
- package/dist/cli/commands/apply.js.map +1 -0
- package/dist/cli/commands/flags.d.ts +99 -0
- package/dist/cli/commands/flags.js +73 -0
- package/dist/cli/commands/flags.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +45 -0
- package/dist/cli/commands/generate.js +149 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/index.d.ts +1 -0
- package/dist/cli/commands/index.js +73 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/open.d.ts +50 -0
- package/dist/cli/commands/open.js +80 -0
- package/dist/cli/commands/open.js.map +1 -0
- package/dist/cli/commands/push.d.ts +18 -0
- package/dist/cli/commands/push.js +71 -0
- package/dist/cli/commands/push.js.map +1 -0
- package/dist/cli/commands/reset.d.ts +15 -0
- package/dist/cli/commands/reset.js +52 -0
- package/dist/cli/commands/reset.js.map +1 -0
- package/dist/cli/commands/run.d.ts +51 -0
- package/dist/cli/commands/run.js +190 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +916 -0
- package/dist/index.js.map +1 -0
- package/dist/lifecycle/setup.d.ts +53 -0
- package/dist/lifecycle/setup.js +96 -0
- package/dist/lifecycle/setup.js.map +1 -0
- package/dist/manifest.d.ts +207 -0
- package/dist/manifest.js +833 -0
- package/dist/manifest.js.map +1 -0
- package/dist/rest/handlers/actions-handler.d.ts +16 -0
- package/dist/rest/handlers/actions-handler.js +15 -0
- package/dist/rest/handlers/actions-handler.js.map +1 -0
- package/dist/rest/handlers/apply-handler.d.ts +26 -0
- package/dist/rest/handlers/apply-handler.js +115 -0
- package/dist/rest/handlers/apply-handler.js.map +1 -0
- package/dist/rest/handlers/diff-handler.d.ts +20 -0
- package/dist/rest/handlers/diff-handler.js +64 -0
- package/dist/rest/handlers/diff-handler.js.map +1 -0
- package/dist/rest/handlers/files-handler.d.ts +16 -0
- package/dist/rest/handlers/files-handler.js +143 -0
- package/dist/rest/handlers/files-handler.js.map +1 -0
- package/dist/rest/handlers/generate-handler.d.ts +66 -0
- package/dist/rest/handlers/generate-handler.js +97 -0
- package/dist/rest/handlers/generate-handler.js.map +1 -0
- package/dist/rest/handlers/git-status-handler.d.ts +13 -0
- package/dist/rest/handlers/git-status-handler.js +58 -0
- package/dist/rest/handlers/git-status-handler.js.map +1 -0
- package/dist/rest/handlers/patch-plan-handler.d.ts +23 -0
- package/dist/rest/handlers/patch-plan-handler.js +50 -0
- package/dist/rest/handlers/patch-plan-handler.js.map +1 -0
- package/dist/rest/handlers/plan-handler.d.ts +50 -0
- package/dist/rest/handlers/plan-handler.js +32 -0
- package/dist/rest/handlers/plan-handler.js.map +1 -0
- package/dist/rest/handlers/push-handler.d.ts +25 -0
- package/dist/rest/handlers/push-handler.js +75 -0
- package/dist/rest/handlers/push-handler.js.map +1 -0
- package/dist/rest/handlers/regenerate-handler.d.ts +37 -0
- package/dist/rest/handlers/regenerate-handler.js +124 -0
- package/dist/rest/handlers/regenerate-handler.js.map +1 -0
- package/dist/rest/handlers/reset-handler.d.ts +17 -0
- package/dist/rest/handlers/reset-handler.js +30 -0
- package/dist/rest/handlers/reset-handler.js.map +1 -0
- package/dist/rest/handlers/scope-resolver.d.ts +15 -0
- package/dist/rest/handlers/scope-resolver.js +12 -0
- package/dist/rest/handlers/scope-resolver.js.map +1 -0
- package/dist/rest/handlers/scopes-handler.d.ts +12 -0
- package/dist/rest/handlers/scopes-handler.js +24 -0
- package/dist/rest/handlers/scopes-handler.js.map +1 -0
- package/dist/rest/handlers/status-handler.d.ts +27 -0
- package/dist/rest/handlers/status-handler.js +91 -0
- package/dist/rest/handlers/status-handler.js.map +1 -0
- package/dist/rest/handlers/summarize-handler.d.ts +21 -0
- package/dist/rest/handlers/summarize-handler.js +106 -0
- package/dist/rest/handlers/summarize-handler.js.map +1 -0
- package/dist/widgets/220.js +446 -0
- package/dist/widgets/220.js.map +1 -0
- package/dist/widgets/331.js +2 -0
- package/dist/widgets/331.js.map +1 -0
- package/dist/widgets/403.js +2 -0
- package/dist/widgets/403.js.map +1 -0
- package/dist/widgets/406.js +35 -0
- package/dist/widgets/406.js.map +1 -0
- package/dist/widgets/455.js +2 -0
- package/dist/widgets/455.js.map +1 -0
- package/dist/widgets/482.js +2 -0
- package/dist/widgets/482.js.map +1 -0
- package/dist/widgets/485.js +2 -0
- package/dist/widgets/485.js.map +1 -0
- package/dist/widgets/527.js +2 -0
- package/dist/widgets/527.js.map +1 -0
- package/dist/widgets/628.js +2 -0
- package/dist/widgets/628.js.map +1 -0
- package/dist/widgets/694.js +2 -0
- package/dist/widgets/694.js.map +1 -0
- package/dist/widgets/712.js +2 -0
- package/dist/widgets/712.js.map +1 -0
- package/dist/widgets/866.js +2 -0
- package/dist/widgets/866.js.map +1 -0
- package/dist/widgets/915.js +39 -0
- package/dist/widgets/915.js.map +1 -0
- package/dist/widgets/957.js +10 -0
- package/dist/widgets/957.js.map +1 -0
- package/dist/widgets/983.js +2 -0
- package/dist/widgets/983.js.map +1 -0
- package/dist/widgets/@mf-types.d.ts +3 -0
- package/dist/widgets/@mf-types.zip +0 -0
- package/dist/widgets/__federation_expose_CommitOverview.js +2 -0
- package/dist/widgets/__federation_expose_CommitOverview.js.map +1 -0
- package/dist/widgets/mf-manifest.json +260 -0
- package/dist/widgets/mf-stats.json +302 -0
- package/dist/widgets/remoteEntry.js +7 -0
- package/dist/widgets/remoteEntry.js.map +1 -0
- package/package.json +95 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/commands/flags.ts","../src/manifest.ts"],"names":[],"mappings":"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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyaA,SAAA,EAAW;AAAA,IACT;AAAA,MACE,EAAA,EAAI,kBAAA;AAAA,MACJ,YAAA,EAAc,8BAAA;AAAA,MACd,WAAA,EAAa;AAAA,KACf;AAAA,IACA;AAAA,MACE,EAAA,EAAI,oBAAA;AAAA,MACJ,YAAA,EAAc,gCAAA;AAAA,MACd,WAAA,EAAa;AAAA;AACf;AAEJ;AAEA,IAAO,gBAAA,GAAQ","file":"manifest.js","sourcesContent":["/**\n * Shared command flags definitions\n *\n * DRY pattern: Define flags once, use in both manifest and command handlers.\n */\n\n/**\n * Flags for commit:generate command\n */\nexport const generateFlags = {\n scope: {\n type: 'string',\n description: 'Filter by package name (@kb-labs/core), wildcard (@kb-labs/*), or path pattern (packages/**)',\n alias: 's',\n },\n json: {\n type: 'boolean',\n description: 'Output JSON',\n default: false,\n },\n} as const;\n\nexport type GenerateFlags = typeof generateFlags;\n\n/**\n * Flags for commit:apply command\n */\nexport const applyFlags = {\n force: {\n type: 'boolean',\n description: 'Apply even if working tree changed',\n default: false,\n alias: 'f',\n },\n json: {\n type: 'boolean',\n description: 'Output JSON',\n default: false,\n },\n} as const;\n\nexport type ApplyFlags = typeof applyFlags;\n\n/**\n * Flags for commit:push command\n */\nexport const pushFlags = {\n force: {\n type: 'boolean',\n description: 'Force push (dangerous!)',\n default: false,\n alias: 'f',\n },\n json: {\n type: 'boolean',\n description: 'Output JSON',\n default: false,\n },\n} as const;\n\nexport type PushFlags = typeof pushFlags;\n\n/**\n * Flags for commit (run) command - combines generate + apply + optional push\n */\nexport const runFlags = {\n scope: {\n type: 'string',\n description: 'Filter by package name (@kb-labs/core), wildcard (@kb-labs/*), or path pattern (packages/**)',\n alias: 's',\n },\n json: {\n type: 'boolean',\n description: 'Output JSON',\n default: false,\n },\n 'dry-run': {\n type: 'boolean',\n description: 'Generate plan only, do not apply',\n default: false,\n },\n 'with-push': {\n type: 'boolean',\n description: 'Push after apply',\n default: false,\n },\n} as const;\n\nexport type RunFlags = typeof runFlags;\n\n/**\n * Common json-only flags for simple commands\n */\nexport const jsonOnlyFlags = {\n json: {\n type: 'boolean',\n description: 'Output JSON',\n default: false,\n },\n} as const;\n\nexport type JsonOnlyFlags = typeof jsonOnlyFlags;\n\n/**\n * Empty flags for commands that take no arguments\n */\nexport const emptyFlags = {} as const;\n\nexport type EmptyFlags = typeof emptyFlags;\n","/**\n * KB Labs Commit Plugin - Manifest V3\n *\n * Migration from V2 to V3 following best practices from V3-MIGRATION-GUIDE.md\n *\n * Key changes:\n * - Schema: kb.plugin/3\n * - Commands use handler#default suffix\n * - Commands have handlerPath field\n * - All imports from @kb-labs/sdk\n */\n\nimport {\n defineCommandFlags,\n combinePermissions,\n gitWorkflowPreset,\n kbPlatformPreset,\n} from '@kb-labs/sdk';\nimport {\n COMMIT_ENV_VARS,\n COMMIT_BASE_PATH,\n COMMIT_ROUTES,\n COMMIT_CACHE_PREFIX,\n} from '@kb-labs/commit-contracts';\nimport {\n runFlags,\n generateFlags,\n applyFlags,\n pushFlags,\n jsonOnlyFlags,\n emptyFlags,\n} from './cli/commands/flags';\n\n/**\n * Build permissions using presets:\n * - gitWorkflow: HOME, USER, GIT_*, SSH_* for git operations\n * - kbPlatform: KB_* env vars and .kb/ directory\n * - Custom: COMMIT_ENV_VARS, quotas, platform services (llm, cache)\n *\n * Note: LLM access goes through platform services, no direct API keys needed.\n */\nconst pluginPermissions = combinePermissions()\n .with(gitWorkflowPreset)\n .with(kbPlatformPreset)\n .withEnv([...COMMIT_ENV_VARS])\n .withFs({\n mode: 'readWrite',\n allow: ['.kb/commit/**'],\n })\n .withPlatform({\n llm: true, // Full LLM access for commit generation\n cache: [COMMIT_CACHE_PREFIX], // Cache namespace prefix from contracts\n analytics: true, // Track commit generation events\n })\n .withQuotas({\n timeoutMs: 600000, // 10 min for LLM\n memoryMb: 512,\n })\n .build();\n\nexport const manifest = {\n schema: 'kb.plugin/3',\n id: '@kb-labs/commit',\n version: '0.1.0',\n configSection: 'commit',\n\n display: {\n name: 'Commit Generator',\n description: 'AI-powered commit generation with conventional commit support.',\n tags: ['commit', 'git', 'ai', 'conventional-commits'],\n },\n\n // Platform requirements (LLM is optional but preferred)\n platform: {\n requires: ['storage', 'cache'],\n optional: ['llm', 'analytics', 'logger'],\n },\n\n // TODO: Implement V3 setup handler\n // Setup temporarily disabled during migration - needs proper V3 implementation\n // setup: {\n // handler: './lifecycle/setup.js#default',\n // handlerPath: './lifecycle/setup.js',\n // describe: 'Initialize .kb/commit/ directory structure.',\n // permissions: permissions.combine(\n // permissions.presets.pluginWorkspace('commit'),\n // {\n // quotas: { timeoutMs: 10000, memoryMb: 128, cpuMs: 3000 },\n // }\n // ),\n // },\n\n // V3: cli wrapper with commands array\n cli: {\n commands: [\n // Main command: commit (default flow)\n {\n id: 'commit:commit', // ✅ With plugin prefix\n group: 'commit',\n describe: 'Generate and apply commits (default flow).',\n longDescription:\n 'Analyzes changes, generates commit plan with LLM, applies commits locally. ' +\n 'Use --dry-run to preview without applying, --with-push to push after applying.',\n\n // ✅ V3: handler with #default suffix\n handler: './cli/commands/run.js#default',\n handlerPath: './cli/commands/run.js',\n\n flags: defineCommandFlags(runFlags),\n\n examples: [\n 'kb commit commit',\n 'kb commit commit --dry-run',\n 'kb commit commit --with-push',\n 'kb commit commit --scope \"src/components/**\"',\n ],\n },\n\n // commit:generate - Generate commit plan\n {\n id: 'commit:generate',\n group: 'commit',\n describe: 'Generate commit plan from git changes.',\n longDescription:\n 'Analyzes staged and unstaged changes using git diff, then uses LLM to group ' +\n 'related changes and generate conventional commit messages.',\n\n handler: './cli/commands/generate.js#default',\n handlerPath: './cli/commands/generate.js',\n\n flags: defineCommandFlags(generateFlags),\n\n examples: [\n 'kb commit generate',\n 'kb commit generate --json',\n 'kb commit generate --scope \"packages/**\"',\n ],\n },\n\n // commit:apply - Apply commit plan\n {\n id: 'commit:apply',\n group: 'commit',\n describe: 'Apply current commit plan (create local commits).',\n longDescription:\n 'Creates git commits according to the current plan. Checks for staleness ' +\n '(working tree changes since plan generation) unless --force is used.',\n\n handler: './cli/commands/apply.js#default',\n handlerPath: './cli/commands/apply.js',\n\n flags: defineCommandFlags(applyFlags),\n\n examples: [\n 'kb commit apply',\n 'kb commit apply --force',\n ],\n },\n\n // commit:push - Push commits\n {\n id: 'commit:push',\n group: 'commit',\n describe: 'Push commits to remote repository.',\n longDescription:\n 'Pushes local commits to the remote. Refuses force push to protected branches ' +\n '(main, master) by default.',\n\n handler: './cli/commands/push.js#default',\n handlerPath: './cli/commands/push.js',\n\n flags: defineCommandFlags(pushFlags),\n\n examples: [\n 'kb commit push',\n ],\n },\n\n // commit:open - Show current plan\n {\n id: 'commit:open',\n group: 'commit',\n describe: 'Show current commit plan.',\n longDescription: 'Displays the current commit plan if one exists.',\n\n handler: './cli/commands/open.js#default',\n handlerPath: './cli/commands/open.js',\n\n flags: defineCommandFlags(jsonOnlyFlags),\n\n examples: [\n 'kb commit open',\n 'kb commit open --json',\n ],\n },\n\n // commit:reset - Clear current plan\n {\n id: 'commit:reset',\n group: 'commit',\n describe: 'Clear current commit plan.',\n longDescription: 'Removes the current commit plan from storage.',\n\n handler: './cli/commands/reset.js#default',\n handlerPath: './cli/commands/reset.js',\n\n flags: defineCommandFlags(emptyFlags),\n\n examples: [\n 'kb commit reset',\n ],\n },\n ],\n },\n\n capabilities: [],\n\n // ✅ V3: Manifest-first permissions using composable presets\n permissions: pluginPermissions,\n\n // REST API routes (inherit permissions from manifest)\n rest: {\n basePath: COMMIT_BASE_PATH,\n routes: [\n // GET /scopes\n {\n method: 'GET',\n path: COMMIT_ROUTES.SCOPES,\n handler: './rest/handlers/scopes-handler.js#default',\n output: {\n zod: '@kb-labs/sdk#SelectDataSchema',\n },\n },\n // GET /status\n {\n method: 'GET',\n path: COMMIT_ROUTES.STATUS,\n handler: './rest/handlers/status-handler.js#default',\n output: {\n zod: '@kb-labs/commit-contracts#StatusResponseSchema',\n },\n },\n // POST /generate\n {\n method: 'POST',\n path: COMMIT_ROUTES.GENERATE,\n handler: './rest/handlers/generate-handler.js#default',\n input: {\n zod: '@kb-labs/commit-contracts#GenerateRequestSchema',\n },\n output: {\n zod: '@kb-labs/commit-contracts#GenerateResponseSchema',\n },\n timeoutMs: 300000, // 5 minutes for LLM analysis\n },\n // GET /plan\n {\n method: 'GET',\n path: COMMIT_ROUTES.PLAN,\n handler: './rest/handlers/plan-handler.js#default',\n output: {\n zod: '@kb-labs/commit-contracts#PlanResponseSchema',\n },\n },\n // POST /apply\n {\n method: 'POST',\n path: COMMIT_ROUTES.APPLY,\n handler: './rest/handlers/apply-handler.js#default',\n input: {\n zod: '@kb-labs/commit-contracts#ApplyRequestSchema',\n },\n output: {\n zod: '@kb-labs/commit-contracts#ApplyResponseSchema',\n },\n timeoutMs: 600000, // 10 min for pre/post hooks\n },\n // POST /push\n {\n method: 'POST',\n path: COMMIT_ROUTES.PUSH,\n handler: './rest/handlers/push-handler.js#default',\n input: {\n zod: '@kb-labs/commit-contracts#PushRequestSchema',\n },\n output: {\n zod: '@kb-labs/commit-contracts#PushResponseSchema',\n },\n timeoutMs: 600000, // 10 min for pre/post push hooks\n },\n // DELETE /plan\n {\n method: 'DELETE',\n path: COMMIT_ROUTES.RESET,\n handler: './rest/handlers/reset-handler.js#default',\n output: {\n zod: '@kb-labs/commit-contracts#ResetResponseSchema',\n },\n },\n // GET /git-status\n {\n method: 'GET',\n path: COMMIT_ROUTES.GIT_STATUS,\n handler: './rest/handlers/git-status-handler.js#default',\n output: {\n zod: '@kb-labs/commit-contracts#GitStatusResponseSchema',\n },\n },\n // GET /files\n {\n method: 'GET',\n path: COMMIT_ROUTES.FILES,\n handler: './rest/handlers/files-handler.js#default',\n },\n // GET /diff\n {\n method: 'GET',\n path: COMMIT_ROUTES.DIFF,\n handler: './rest/handlers/diff-handler.js#default',\n output: {\n zod: '@kb-labs/commit-contracts#FileDiffResponseSchema',\n },\n },\n // POST /summarize\n {\n method: 'POST',\n path: COMMIT_ROUTES.SUMMARIZE,\n handler: './rest/handlers/summarize-handler.js#default',\n input: {\n zod: '@kb-labs/commit-contracts#SummarizeRequestSchema',\n },\n output: {\n zod: '@kb-labs/commit-contracts#SummarizeResponseSchema',\n },\n },\n // GET /actions\n {\n method: 'GET',\n path: COMMIT_ROUTES.ACTIONS,\n handler: './rest/handlers/actions-handler.js#default',\n output: {\n zod: '@kb-labs/commit-contracts#ActionsResponseSchema',\n },\n },\n // PATCH /plan — edit a single commit in the plan\n {\n method: 'PATCH',\n path: COMMIT_ROUTES.PATCH_PLAN,\n handler: './rest/handlers/patch-plan-handler.js#default',\n input: {\n zod: '@kb-labs/commit-contracts#PatchPlanRequestSchema',\n },\n output: {\n zod: '@kb-labs/commit-contracts#PatchPlanResponseSchema',\n },\n },\n // POST /regenerate-commit — regenerate a single commit with LLM\n {\n method: 'POST',\n path: COMMIT_ROUTES.REGENERATE_COMMIT,\n handler: './rest/handlers/regenerate-handler.js#default',\n input: {\n zod: '@kb-labs/commit-contracts#RegenerateCommitRequestSchema',\n },\n output: {\n zod: '@kb-labs/commit-contracts#RegenerateCommitResponseSchema',\n },\n timeoutMs: 300000, // 5 minutes for LLM analysis\n },\n ],\n },\n\n // Studio V2 — Module Federation pages\n studio: {\n version: 2 as const,\n remoteName: 'commitPlugin',\n pages: [\n {\n id: 'commit.overview',\n title: 'Commit',\n icon: 'GitlabOutlined',\n route: '/p/commit',\n entry: './CommitOverview',\n order: 1,\n },\n ],\n menus: [\n {\n id: 'commit',\n label: 'Commit',\n icon: 'GitlabOutlined',\n target: 'commit.overview',\n order: 30,\n },\n ],\n },\n\n // Legacy V1 studio widgets (deleted)\n /*\n _legacy_studio: {\n widgets: [\n // Workspace Selector\n {\n id: 'commit.workspace-selector',\n kind: 'select',\n title: 'Select Scope',\n description: 'Choose monorepo package or repository',\n data: {\n source: {\n type: 'rest',\n routeId: COMMIT_WIDGET_ROUTES.SCOPES,\n method: 'GET',\n },\n },\n options: {\n searchable: true,\n placeholder: 'Select scope...',\n },\n events: {\n emit: [{\n name: COMMIT_EVENTS.SCOPE_CHANGED,\n payloadMap: { scope: 'value' }, // Maps selected value to payload.scope\n }],\n },\n layoutHint: { w: 6, h: 1, minH: 1 },\n order: 0,\n },\n // Status Metrics\n {\n id: 'commit.status',\n kind: 'metric-group',\n title: 'Commit Status',\n description: 'Current plan and git status',\n data: {\n source: {\n type: 'rest',\n routeId: COMMIT_WIDGET_ROUTES.STATUS,\n method: 'GET',\n },\n },\n events: {\n subscribe: [\n {\n name: COMMIT_EVENTS.SCOPE_CHANGED,\n paramsMap: { scope: 'scope' }, // Maps payload.workspace to params.workspace\n },\n COMMIT_EVENTS.FORM_SUBMITTED,\n ],\n },\n layoutHint: { w: 6, h: 2, minH: 2 },\n order: 1,\n },\n // Plan Viewer (child of commit.plan-section)\n {\n id: 'commit.plan-viewer',\n kind: 'cardlist',\n title: '', // Title shown in parent section\n description: '',\n data: {\n source: {\n type: 'rest',\n routeId: COMMIT_WIDGET_ROUTES.PLAN,\n method: 'GET',\n },\n },\n options: {\n layout: 'list',\n emptyMessage: 'No plan. Click Generate Plan to create commits.',\n },\n events: {\n subscribe: [\n {\n name: COMMIT_EVENTS.SCOPE_CHANGED,\n paramsMap: { scope: 'scope' },\n },\n {\n name: COMMIT_EVENTS.PLAN_GENERATED,\n // When plan is generated, update widget data with cards\n // No paramsMap - use entire payload as widget data\n },\n COMMIT_EVENTS.FORM_SUBMITTED,\n ],\n },\n order: 2,\n },\n // Git Files Table (child of commit.files-section)\n {\n id: 'commit.git-files',\n kind: 'table',\n title: '', // Title shown in parent section\n description: '',\n data: {\n source: {\n type: 'rest',\n routeId: COMMIT_WIDGET_ROUTES.FILES,\n method: 'GET',\n },\n },\n options: {\n columns: [\n {\n id: 'path',\n label: 'File',\n sortable: true,\n width: '60%',\n },\n {\n id: 'status',\n label: 'Status',\n sortable: true,\n width: 80,\n },\n {\n id: 'changes',\n label: 'Changes',\n sortable: false,\n width: 120,\n },\n ],\n pagination: false,\n rowSelection: false,\n size: 'small',\n },\n events: {\n subscribe: [{\n name: COMMIT_EVENTS.SCOPE_CHANGED,\n paramsMap: { scope: 'scope' },\n }],\n },\n order: 3,\n },\n // Quick Actions Widget\n {\n id: 'commit.actions',\n kind: 'card',\n title: 'Quick Actions',\n description: 'Common commit workflow actions',\n data: {\n source: {\n type: 'rest',\n routeId: COMMIT_WIDGET_ROUTES.ACTIONS,\n method: 'GET',\n },\n },\n events: {\n subscribe: [{\n name: COMMIT_EVENTS.SCOPE_CHANGED,\n paramsMap: { scope: 'scope' },\n }],\n },\n actions: [\n {\n id: 'generate',\n label: 'Generate Plan',\n icon: 'ThunderboltOutlined',\n variant: 'primary',\n handler: {\n type: 'rest',\n routeId: COMMIT_WIDGET_ROUTES.GENERATE,\n method: 'POST',\n bodyMap: { scope: 'scope' },\n onSuccess: {\n emitEvent: COMMIT_EVENTS.PLAN_GENERATED,\n // Response data will be used as payload (contains plan + workspace)\n },\n },\n },\n {\n id: 'apply',\n label: 'Apply Commits',\n icon: 'CheckOutlined',\n variant: 'default',\n handler: {\n type: 'rest',\n routeId: COMMIT_WIDGET_ROUTES.APPLY,\n method: 'POST',\n bodyMap: { scope: 'scope' },\n },\n confirm: {\n title: 'Apply Commits',\n description: 'This will create git commits according to the plan. Continue?',\n confirmLabel: 'Apply',\n cancelLabel: 'Cancel',\n },\n },\n {\n id: 'push',\n label: 'Push',\n icon: 'UploadOutlined',\n handler: {\n type: 'rest',\n routeId: COMMIT_WIDGET_ROUTES.PUSH,\n method: 'POST',\n bodyMap: { scope: 'scope' },\n },\n confirm: {\n title: 'Push to Remote',\n description: 'This will push commits to the remote repository. Continue?',\n confirmLabel: 'Push',\n cancelLabel: 'Cancel',\n },\n },\n ],\n layoutHint: { w: 6, h: 3, minH: 2 },\n order: 6,\n },\n // Files Section (collapsible, GitLab-style)\n {\n id: 'commit.files-section',\n kind: 'section',\n title: 'Changed Files',\n description: 'Files with uncommitted changes',\n data: {\n source: { type: 'static' }, // Sections use static source (no data)\n },\n options: {\n collapsible: true,\n defaultExpanded: true,\n variant: 'bordered',\n icon: 'FolderOutlined',\n showDivider: true,\n },\n children: ['commit.git-files'],\n events: {\n subscribe: [{\n name: COMMIT_EVENTS.SCOPE_CHANGED,\n paramsMap: { scope: 'scope' },\n }],\n },\n layoutHint: { w: 6, h: 8, minH: 4 },\n order: 4,\n },\n // Plan Section (collapsible, GitLab-style)\n {\n id: 'commit.plan-section',\n kind: 'section',\n title: 'Commit Plan',\n description: 'Generated commits ready to apply',\n data: {\n source: { type: 'static' }, // Sections use static source (no data)\n },\n options: {\n collapsible: true,\n defaultExpanded: true,\n variant: 'bordered',\n icon: 'FileTextOutlined',\n showDivider: true,\n },\n children: ['commit.plan-viewer'],\n events: {\n subscribe: [\n {\n name: COMMIT_EVENTS.SCOPE_CHANGED,\n paramsMap: { scope: 'scope' },\n },\n COMMIT_EVENTS.FORM_SUBMITTED,\n ],\n },\n layoutHint: { w: 6, h: 8, minH: 4 },\n order: 5,\n },\n ],\n // Studio menus\n menus: [\n {\n id: 'commit-menu',\n label: 'Commit',\n icon: 'GitlabOutlined',\n target: '/plugins/commit/overview',\n order: 0,\n },\n {\n id: 'commit-overview',\n label: 'Overview',\n icon: 'DashboardOutlined',\n parentId: 'commit-menu',\n target: '/plugins/commit/overview',\n order: 1,\n },\n {\n id: 'commit-plan',\n label: 'Plan',\n icon: 'UnorderedListOutlined',\n parentId: 'commit-menu',\n target: '/plugins/commit/plan',\n order: 2,\n },\n {\n id: 'commit-files',\n label: 'Files',\n icon: 'FileTextOutlined',\n parentId: 'commit-menu',\n target: '/plugins/commit/files',\n order: 3,\n },\n ],\n // Studio layouts\n layouts: [\n // Overview page - Quick status and actions\n {\n id: 'commit.overview',\n kind: 'grid',\n title: 'Overview',\n description: 'Workspace status and quick actions',\n icon: 'home',\n widgets: [\n 'commit.workspace-selector',\n 'commit.status',\n 'commit.actions',\n 'commit.plan-section', // Show plan section on overview too\n ],\n config: {\n cols: 6,\n gap: 16,\n },\n order: 1,\n },\n // Plan page - GitLab-style commit plan view\n {\n id: 'commit.plan',\n kind: 'grid',\n title: 'Commit Plan',\n description: 'Review and manage generated commits',\n icon: 'list',\n widgets: [\n 'commit.workspace-selector',\n 'commit.files-section',\n 'commit.plan-section',\n ],\n actions: [\n {\n id: 'generate',\n label: 'Generate Plan',\n icon: 'ThunderboltOutlined',\n variant: 'primary',\n handler: {\n type: 'rest',\n routeId: COMMIT_WIDGET_ROUTES.GENERATE,\n method: 'POST',\n },\n },\n {\n id: 'apply',\n label: 'Apply Commits',\n icon: 'CheckOutlined',\n variant: 'default',\n handler: {\n type: 'rest',\n routeId: COMMIT_WIDGET_ROUTES.APPLY,\n method: 'POST',\n },\n confirm: {\n title: 'Apply Commits',\n description: 'This will create git commits according to the plan. Continue?',\n confirmLabel: 'Apply',\n cancelLabel: 'Cancel',\n },\n },\n {\n id: 'push',\n label: 'Push',\n icon: 'UploadOutlined',\n handler: {\n type: 'rest',\n routeId: COMMIT_WIDGET_ROUTES.PUSH,\n method: 'POST',\n },\n confirm: {\n title: 'Push to Remote',\n description: 'This will push commits to the remote repository. Continue?',\n confirmLabel: 'Push',\n cancelLabel: 'Cancel',\n },\n },\n {\n id: 'reset',\n label: 'Reset Plan',\n icon: 'DeleteOutlined',\n variant: 'danger',\n handler: {\n type: 'rest',\n routeId: COMMIT_WIDGET_ROUTES.RESET,\n method: 'DELETE',\n },\n confirm: {\n title: 'Reset Plan',\n description: 'This will delete the current commit plan. This action cannot be undone.',\n confirmLabel: 'Delete',\n cancelLabel: 'Cancel',\n },\n },\n ],\n config: {\n cols: 6,\n gap: 16,\n },\n order: 2,\n },\n // Files page - Changed files table\n {\n id: 'commit.files',\n kind: 'grid',\n title: 'Changed Files',\n description: 'Git status and modified files',\n icon: 'file',\n widgets: [\n 'commit.workspace-selector',\n 'commit.git-files',\n ],\n config: {\n cols: 6,\n gap: 16,\n },\n order: 3,\n },\n ],\n },\n */\n\n // Artifacts\n artifacts: [\n {\n id: 'commit.plan.json',\n pathTemplate: '.kb/commit/current/plan.json',\n description: 'Current commit plan.',\n },\n {\n id: 'commit.status.json',\n pathTemplate: '.kb/commit/current/status.json',\n description: 'Git status snapshot at plan generation time.',\n },\n ],\n};\n\nexport default manifest;\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
|
|
2
|
+
import { RestInput } from '@kb-labs/sdk';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* GET /actions handler
|
|
6
|
+
*
|
|
7
|
+
* Returns minimal data for actions widget (widget mainly displays action buttons).
|
|
8
|
+
* Returns currently selected scope for context.
|
|
9
|
+
*/
|
|
10
|
+
declare const _default: _kb_labs_shared_command_kit.Handler<unknown, RestInput<{
|
|
11
|
+
scope?: string;
|
|
12
|
+
}, unknown, unknown>, {
|
|
13
|
+
scope?: string | undefined;
|
|
14
|
+
}>;
|
|
15
|
+
|
|
16
|
+
export { _default as default };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { defineHandler } from '@kb-labs/sdk';
|
|
2
|
+
|
|
3
|
+
// src/rest/handlers/actions-handler.ts
|
|
4
|
+
var actions_handler_default = defineHandler({
|
|
5
|
+
async execute(_ctx, input) {
|
|
6
|
+
const scope = input.query?.scope;
|
|
7
|
+
return {
|
|
8
|
+
scope
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export { actions_handler_default as default };
|
|
14
|
+
//# sourceMappingURL=actions-handler.js.map
|
|
15
|
+
//# sourceMappingURL=actions-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/rest/handlers/actions-handler.ts"],"names":[],"mappings":";;;AASA,IAAO,0BAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,IAAA,EAAuB,KAAA,EAAgE;AACnG,IAAA,MAAM,KAAA,GAAQ,MAAM,KAAA,EAAO,KAAA;AAE3B,IAAA,OAAO;AAAA,MACL;AAAA,KACF;AAAA,EACF;AACF,CAAC","file":"actions-handler.js","sourcesContent":["import { defineHandler, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport type { ActionsResponse } from '@kb-labs/commit-contracts';\n\n/**\n * GET /actions handler\n *\n * Returns minimal data for actions widget (widget mainly displays action buttons).\n * Returns currently selected scope for context.\n */\nexport default defineHandler({\n async execute(_ctx: PluginContextV3, input: RestInput<{ scope?: string }>): Promise<ActionsResponse> {\n const scope = input.query?.scope;\n\n return {\n scope,\n };\n },\n});\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
|
|
2
|
+
import { RestInput } from '@kb-labs/sdk';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* POST /apply handler
|
|
6
|
+
*
|
|
7
|
+
* Applies the current commit plan by creating git commits.
|
|
8
|
+
*/
|
|
9
|
+
declare const _default: _kb_labs_shared_command_kit.Handler<unknown, RestInput<unknown, {
|
|
10
|
+
scope: string;
|
|
11
|
+
force: boolean;
|
|
12
|
+
commitIds?: string[] | undefined;
|
|
13
|
+
}, unknown>, {
|
|
14
|
+
scope: string;
|
|
15
|
+
result: {
|
|
16
|
+
success: boolean;
|
|
17
|
+
errors: string[];
|
|
18
|
+
appliedCommits: {
|
|
19
|
+
message: string;
|
|
20
|
+
sha: string;
|
|
21
|
+
groupId: string;
|
|
22
|
+
}[];
|
|
23
|
+
};
|
|
24
|
+
}>;
|
|
25
|
+
|
|
26
|
+
export { _default as default };
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { defineHandler, useConfig } from '@kb-labs/sdk';
|
|
2
|
+
import { resolveCommitConfig, COMMIT_CACHE_PREFIX } from '@kb-labs/commit-contracts';
|
|
3
|
+
import { applyCommitPlan } from '@kb-labs/commit-core/applier';
|
|
4
|
+
import { loadPlan } from '@kb-labs/commit-core/storage';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
import { normalize, relative } from 'path';
|
|
7
|
+
|
|
8
|
+
// src/rest/handlers/apply-handler.ts
|
|
9
|
+
function resolveScopePath(baseCwd, scopeId = "root", scopes) {
|
|
10
|
+
const scopeDef = scopes?.find((s) => s.id === scopeId);
|
|
11
|
+
const relativePath = scopeDef?.path ?? (scopeId === "root" ? "." : scopeId);
|
|
12
|
+
return relativePath === "." ? baseCwd : path.join(baseCwd, relativePath);
|
|
13
|
+
}
|
|
14
|
+
var apply_handler_default = defineHandler({
|
|
15
|
+
async execute(ctx, input) {
|
|
16
|
+
const { scope = "root", force, commitIds } = input.body ?? {};
|
|
17
|
+
const startTime = Date.now();
|
|
18
|
+
try {
|
|
19
|
+
const fileConfig = await useConfig();
|
|
20
|
+
const config = resolveCommitConfig(fileConfig ?? {});
|
|
21
|
+
const scopeCwd = resolveScopePath(ctx.cwd, scope, config.scope?.scopes);
|
|
22
|
+
const plan = await loadPlan(ctx.cwd, scope);
|
|
23
|
+
if (!plan) {
|
|
24
|
+
throw new Error("No commit plan found. Generate a plan first with POST /generate");
|
|
25
|
+
}
|
|
26
|
+
const scopeRelative = normalize(relative(ctx.cwd, scopeCwd));
|
|
27
|
+
const stripScopePrefix = (filePath) => {
|
|
28
|
+
const normalizedPath = normalize(filePath);
|
|
29
|
+
const normalizedPrefix = normalize(scopeRelative);
|
|
30
|
+
if (normalizedPath.startsWith(normalizedPrefix + "/") || normalizedPath.startsWith(normalizedPrefix + "\\")) {
|
|
31
|
+
return normalizedPath.slice(normalizedPrefix.length + 1);
|
|
32
|
+
}
|
|
33
|
+
if (normalizedPath === normalizedPrefix) {
|
|
34
|
+
return "";
|
|
35
|
+
}
|
|
36
|
+
return filePath;
|
|
37
|
+
};
|
|
38
|
+
const transformedPlan = {
|
|
39
|
+
...plan,
|
|
40
|
+
gitStatus: {
|
|
41
|
+
staged: plan.gitStatus.staged.map(stripScopePrefix),
|
|
42
|
+
unstaged: plan.gitStatus.unstaged.map(stripScopePrefix),
|
|
43
|
+
untracked: plan.gitStatus.untracked.map(stripScopePrefix)
|
|
44
|
+
},
|
|
45
|
+
commits: plan.commits.map((commit) => ({
|
|
46
|
+
...commit,
|
|
47
|
+
files: commit.files.map(stripScopePrefix)
|
|
48
|
+
}))
|
|
49
|
+
};
|
|
50
|
+
if (commitIds && commitIds.length > 0) {
|
|
51
|
+
const commitIdSet = new Set(commitIds);
|
|
52
|
+
transformedPlan.commits = transformedPlan.commits.filter((c) => commitIdSet.has(c.id));
|
|
53
|
+
if (transformedPlan.commits.length === 0) {
|
|
54
|
+
throw new Error("None of the specified commitIds found in plan");
|
|
55
|
+
}
|
|
56
|
+
const selectedFiles = new Set(transformedPlan.commits.flatMap((c) => c.files));
|
|
57
|
+
transformedPlan.gitStatus = {
|
|
58
|
+
staged: transformedPlan.gitStatus.staged.filter((f) => selectedFiles.has(f)),
|
|
59
|
+
unstaged: transformedPlan.gitStatus.unstaged.filter((f) => selectedFiles.has(f)),
|
|
60
|
+
untracked: transformedPlan.gitStatus.untracked.filter((f) => selectedFiles.has(f))
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
const appliedCacheKey = `${COMMIT_CACHE_PREFIX}plan-applied:${scope}`;
|
|
64
|
+
await ctx.platform.cache.delete(appliedCacheKey);
|
|
65
|
+
const result = await applyCommitPlan(scopeCwd, transformedPlan, { force, scope });
|
|
66
|
+
if (result.success) {
|
|
67
|
+
await ctx.platform.cache.set(
|
|
68
|
+
appliedCacheKey,
|
|
69
|
+
{
|
|
70
|
+
commitsApplied: result.appliedCommits.length,
|
|
71
|
+
planCreatedAt: plan.createdAt
|
|
72
|
+
},
|
|
73
|
+
60 * 60 * 1e3
|
|
74
|
+
// 1 hour TTL
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
if (ctx.platform.analytics) {
|
|
78
|
+
if (result.success) {
|
|
79
|
+
await ctx.platform.analytics.track("commit.apply.success", {
|
|
80
|
+
scope,
|
|
81
|
+
force,
|
|
82
|
+
commitsApplied: result.appliedCommits.length,
|
|
83
|
+
durationMs: Date.now() - startTime
|
|
84
|
+
});
|
|
85
|
+
} else {
|
|
86
|
+
await ctx.platform.analytics.track("commit.apply.failed", {
|
|
87
|
+
scope,
|
|
88
|
+
force,
|
|
89
|
+
commitsApplied: result.appliedCommits.length,
|
|
90
|
+
errors: result.errors,
|
|
91
|
+
durationMs: Date.now() - startTime
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
result,
|
|
97
|
+
scope
|
|
98
|
+
};
|
|
99
|
+
} catch (error) {
|
|
100
|
+
if (ctx.platform.analytics) {
|
|
101
|
+
await ctx.platform.analytics.track("commit.apply.error", {
|
|
102
|
+
scope,
|
|
103
|
+
force,
|
|
104
|
+
error: error instanceof Error ? error.message : String(error),
|
|
105
|
+
durationMs: Date.now() - startTime
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
throw new Error(`Failed to apply commits: ${error}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
export { apply_handler_default as default };
|
|
114
|
+
//# sourceMappingURL=apply-handler.js.map
|
|
115
|
+
//# sourceMappingURL=apply-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/rest/handlers/scope-resolver.ts","../../../src/rest/handlers/apply-handler.ts"],"names":[],"mappings":"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","file":"apply-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 } from '@kb-labs/sdk';\nimport {\n COMMIT_CACHE_PREFIX,\n type ApplyRequest,\n type ApplyResponse,\n type CommitPluginConfig,\n resolveCommitConfig,\n} from '@kb-labs/commit-contracts';\nimport { applyCommitPlan } from '@kb-labs/commit-core/applier';\nimport { loadPlan } from '@kb-labs/commit-core/storage';\nimport { resolveScopePath } from './scope-resolver';\nimport { relative, normalize } from 'node:path';\n\n/**\n * POST /apply handler\n *\n * Applies the current commit plan by creating git commits.\n */\nexport default defineHandler({\n async execute(ctx: PluginContextV3, input: RestInput<unknown, ApplyRequest>): Promise<ApplyResponse> {\n const { scope = 'root', force, commitIds } = input.body ?? {};\n const startTime = Date.now();\n\n try {\n const fileConfig = await useConfig<Partial<CommitPluginConfig>>();\n const config = resolveCommitConfig(fileConfig ?? {});\n\n // Resolve scope to actual directory path (for nested git repos)\n const scopeCwd = resolveScopePath(ctx.cwd, scope, config.scope?.scopes);\n\n // Load the plan first (plan stored in root, but paths are relative to repoRoot)\n const plan = await loadPlan(ctx.cwd, scope);\n if (!plan) {\n throw new Error('No commit plan found. Generate a plan first with POST /generate');\n }\n\n // Transform file paths from repoRoot-relative to scopeCwd-relative\n // Plan files: \"kb-labs-commit-plugin/packages/commit-cli/src/file.ts\"\n // scopeCwd: \"/absolute/path/kb-labs/kb-labs-commit-plugin\"\n // ctx.cwd: \"/absolute/path/kb-labs\"\n // Need: \"packages/commit-cli/src/file.ts\"\n\n // Use path.relative() for proper cross-platform path handling\n const scopeRelative = normalize(relative(ctx.cwd, scopeCwd));\n\n // Helper to strip scope prefix from file path\n const stripScopePrefix = (filePath: string): string => {\n // Normalize path separators (handles Windows vs Unix)\n const normalizedPath = normalize(filePath);\n const normalizedPrefix = normalize(scopeRelative);\n\n // If file starts with scope prefix, strip it\n if (normalizedPath.startsWith(normalizedPrefix + '/') ||\n normalizedPath.startsWith(normalizedPrefix + '\\\\')) {\n return normalizedPath.slice(normalizedPrefix.length + 1);\n }\n\n // If exact match (shouldn't happen for files, but handle it)\n if (normalizedPath === normalizedPrefix) {\n return '';\n }\n\n // File doesn't start with prefix - return as-is (shouldn't happen)\n return filePath;\n };\n\n const transformedPlan = {\n ...plan,\n gitStatus: {\n staged: plan.gitStatus.staged.map(stripScopePrefix),\n unstaged: plan.gitStatus.unstaged.map(stripScopePrefix),\n untracked: plan.gitStatus.untracked.map(stripScopePrefix),\n },\n commits: plan.commits.map(commit => ({\n ...commit,\n files: commit.files.map(stripScopePrefix),\n })),\n };\n\n // Filter commits if specific commitIds requested (selective apply)\n if (commitIds && commitIds.length > 0) {\n const commitIdSet = new Set(commitIds);\n transformedPlan.commits = transformedPlan.commits.filter(c => commitIdSet.has(c.id));\n\n if (transformedPlan.commits.length === 0) {\n throw new Error('None of the specified commitIds found in plan');\n }\n\n // When selectively applying commits, align gitStatus to selected files only.\n // Otherwise plan integrity checks may rightfully fail on intentionally skipped commits.\n const selectedFiles = new Set(transformedPlan.commits.flatMap(c => c.files));\n transformedPlan.gitStatus = {\n staged: transformedPlan.gitStatus.staged.filter(f => selectedFiles.has(f)),\n unstaged: transformedPlan.gitStatus.unstaged.filter(f => selectedFiles.has(f)),\n untracked: transformedPlan.gitStatus.untracked.filter(f => selectedFiles.has(f)),\n };\n }\n\n // Apply commits (git runs FROM scopeCwd, not ctx.cwd!)\n // Reset applied status before attempt to avoid stale \"Applied\" badge after failed runs.\n const appliedCacheKey = `${COMMIT_CACHE_PREFIX}plan-applied:${scope}`;\n await ctx.platform.cache.delete(appliedCacheKey);\n\n const result = await applyCommitPlan(scopeCwd, transformedPlan, { force, scope });\n\n // Store applied status in cache for status tracking\n if (result.success) {\n await ctx.platform.cache.set(\n appliedCacheKey,\n {\n commitsApplied: result.appliedCommits.length,\n planCreatedAt: plan.createdAt,\n },\n 60 * 60 * 1000 // 1 hour TTL\n );\n }\n\n // Track success/failure\n if (ctx.platform.analytics) {\n if (result.success) {\n await ctx.platform.analytics.track('commit.apply.success', {\n scope,\n force,\n commitsApplied: result.appliedCommits.length,\n durationMs: Date.now() - startTime,\n });\n } else {\n await ctx.platform.analytics.track('commit.apply.failed', {\n scope,\n force,\n commitsApplied: result.appliedCommits.length,\n errors: result.errors,\n durationMs: Date.now() - startTime,\n });\n }\n }\n\n return {\n result,\n scope,\n };\n } catch (error) {\n // Track error\n if (ctx.platform.analytics) {\n await ctx.platform.analytics.track('commit.apply.error', {\n scope,\n force,\n error: error instanceof Error ? error.message : String(error),\n durationMs: Date.now() - startTime,\n });\n }\n\n throw new Error(`Failed to apply commits: ${error}`);\n }\n },\n});\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
|
|
2
|
+
import { RestInput } from '@kb-labs/sdk';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* GET /diff handler
|
|
6
|
+
*
|
|
7
|
+
* Returns the diff for a specific file in the scope.
|
|
8
|
+
*/
|
|
9
|
+
declare const _default: _kb_labs_shared_command_kit.Handler<unknown, RestInput<{
|
|
10
|
+
scope?: string;
|
|
11
|
+
file?: string;
|
|
12
|
+
}, unknown, unknown>, {
|
|
13
|
+
additions: number;
|
|
14
|
+
deletions: number;
|
|
15
|
+
scope: string;
|
|
16
|
+
file: string;
|
|
17
|
+
diff: string;
|
|
18
|
+
}>;
|
|
19
|
+
|
|
20
|
+
export { _default as default };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { defineHandler, useLogger, useConfig } from '@kb-labs/sdk';
|
|
2
|
+
import { resolveCommitConfig } from '@kb-labs/commit-contracts';
|
|
3
|
+
import { getFileDiff } from '@kb-labs/commit-core/analyzer';
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
import { join } from 'path';
|
|
6
|
+
import { readFile } from 'fs/promises';
|
|
7
|
+
|
|
8
|
+
// src/rest/handlers/diff-handler.ts
|
|
9
|
+
function resolveScopePath(baseCwd, scopeId = "root", scopes) {
|
|
10
|
+
const scopeDef = scopes?.find((s) => s.id === scopeId);
|
|
11
|
+
const relativePath = scopeDef?.path ?? (scopeId === "root" ? "." : scopeId);
|
|
12
|
+
return relativePath === "." ? baseCwd : path.join(baseCwd, relativePath);
|
|
13
|
+
}
|
|
14
|
+
var diff_handler_default = defineHandler({
|
|
15
|
+
async execute(ctx, input) {
|
|
16
|
+
const logger = useLogger();
|
|
17
|
+
const scope = input.query?.scope || "root";
|
|
18
|
+
const file = input.query?.file;
|
|
19
|
+
logger.info("[diff-handler] Request received", { scope, file });
|
|
20
|
+
if (!file) {
|
|
21
|
+
throw new Error("File path is required");
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
const fileConfig = await useConfig();
|
|
25
|
+
const config = resolveCommitConfig(fileConfig ?? {});
|
|
26
|
+
const scopeCwd = resolveScopePath(ctx.cwd, scope, config.scope?.scopes);
|
|
27
|
+
logger.info("[diff-handler] Resolved scope", { scope, scopeCwd });
|
|
28
|
+
logger.info("[diff-handler] Calling getFileDiff", { cwd: scopeCwd, file });
|
|
29
|
+
const result = await getFileDiff(scopeCwd, file);
|
|
30
|
+
if (!result.diff || result.diff.trim().length === 0) {
|
|
31
|
+
try {
|
|
32
|
+
const absolutePath = join(scopeCwd, file);
|
|
33
|
+
const content = await readFile(absolutePath, "utf-8");
|
|
34
|
+
const additions = content.length === 0 ? 0 : content.split("\n").length;
|
|
35
|
+
return {
|
|
36
|
+
scope,
|
|
37
|
+
file,
|
|
38
|
+
diff: content,
|
|
39
|
+
additions,
|
|
40
|
+
deletions: 0
|
|
41
|
+
};
|
|
42
|
+
} catch (readError) {
|
|
43
|
+
logger.warn("[diff-handler] Failed to read file content fallback", {
|
|
44
|
+
file,
|
|
45
|
+
error: readError instanceof Error ? readError.message : String(readError)
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
scope,
|
|
51
|
+
file,
|
|
52
|
+
diff: result.diff,
|
|
53
|
+
additions: result.additions,
|
|
54
|
+
deletions: result.deletions
|
|
55
|
+
};
|
|
56
|
+
} catch (error) {
|
|
57
|
+
throw new Error(`Failed to get diff for file: ${error}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
export { diff_handler_default as default };
|
|
63
|
+
//# sourceMappingURL=diff-handler.js.map
|
|
64
|
+
//# sourceMappingURL=diff-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/rest/handlers/scope-resolver.ts","../../../src/rest/handlers/diff-handler.ts"],"names":["join"],"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;ACTA,IAAO,uBAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAAgF;AAClH,IAAA,MAAM,SAAS,SAAA,EAAU;AACzB,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,EAAO,KAAA,IAAS,MAAA;AACpC,IAAA,MAAM,IAAA,GAAO,MAAM,KAAA,EAAO,IAAA;AAE1B,IAAA,MAAA,CAAO,IAAA,CAAK,iCAAA,EAAmC,EAAE,KAAA,EAAO,MAAM,CAAA;AAE9D,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,MAAM,IAAI,MAAM,uBAAuB,CAAA;AAAA,IACzC;AAEA,IAAA,IAAI;AAEF,MAAA,MAAM,UAAA,GAAa,MAAM,SAAA,EAAuC;AAChE,MAAA,MAAM,MAAA,GAAS,mBAAA,CAAoB,UAAA,IAAc,EAAE,CAAA;AACnD,MAAA,MAAM,WAAW,gBAAA,CAAiB,GAAA,CAAI,KAAK,KAAA,EAAO,MAAA,CAAO,OAAO,MAAM,CAAA;AACtE,MAAA,MAAA,CAAO,IAAA,CAAK,+BAAA,EAAiC,EAAE,KAAA,EAAO,UAAU,CAAA;AAGhE,MAAA,MAAA,CAAO,KAAK,oCAAA,EAAsC,EAAE,GAAA,EAAK,QAAA,EAAU,MAAM,CAAA;AACzE,MAAA,MAAM,MAAA,GAAS,MAAM,WAAA,CAAY,QAAA,EAAU,IAAI,CAAA;AAI/C,MAAA,IAAI,CAAC,OAAO,IAAA,IAAQ,MAAA,CAAO,KAAK,IAAA,EAAK,CAAE,WAAW,CAAA,EAAG;AACnD,QAAA,IAAI;AACF,UAAA,MAAM,YAAA,GAAeA,IAAAA,CAAK,QAAA,EAAU,IAAI,CAAA;AACxC,UAAA,MAAM,OAAA,GAAU,MAAM,QAAA,CAAS,YAAA,EAAc,OAAO,CAAA;AACpD,UAAA,MAAM,SAAA,GAAY,QAAQ,MAAA,KAAW,CAAA,GAAI,IAAI,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA,CAAE,MAAA;AACjE,UAAA,OAAO;AAAA,YACL,KAAA;AAAA,YACA,IAAA;AAAA,YACA,IAAA,EAAM,OAAA;AAAA,YACN,SAAA;AAAA,YACA,SAAA,EAAW;AAAA,WACb;AAAA,QACF,SAAS,SAAA,EAAW;AAClB,UAAA,MAAA,CAAO,KAAK,qDAAA,EAAuD;AAAA,YACjE,IAAA;AAAA,YACA,OAAO,SAAA,YAAqB,KAAA,GAAQ,SAAA,CAAU,OAAA,GAAU,OAAO,SAAS;AAAA,WACzE,CAAA;AAAA,QACH;AAAA,MACF;AAEA,MAAA,OAAO;AAAA,QACL,KAAA;AAAA,QACA,IAAA;AAAA,QACA,MAAM,MAAA,CAAO,IAAA;AAAA,QACb,WAAW,MAAA,CAAO,SAAA;AAAA,QAClB,WAAW,MAAA,CAAO;AAAA,OACpB;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,6BAAA,EAAgC,KAAK,CAAA,CAAE,CAAA;AAAA,IACzD;AAAA,EACF;AACF,CAAC","file":"diff-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 } from '@kb-labs/sdk';\nimport { type FileDiffResponse, type CommitPluginConfig, resolveCommitConfig } from '@kb-labs/commit-contracts';\nimport { getFileDiff } from '@kb-labs/commit-core/analyzer';\nimport { resolveScopePath } from './scope-resolver';\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\n/**\n * GET /diff handler\n *\n * Returns the diff for a specific file in the scope.\n */\nexport default defineHandler({\n async execute(ctx: PluginContextV3, input: RestInput<{ scope?: string; file?: string }>): Promise<FileDiffResponse> {\n const logger = useLogger();\n const scope = input.query?.scope || 'root';\n const file = input.query?.file;\n\n logger.info('[diff-handler] Request received', { scope, file });\n\n if (!file) {\n throw new Error('File path is required');\n }\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('[diff-handler] Resolved scope', { scope, scopeCwd });\n\n // Get file diff (git runs FROM scopeCwd)\n logger.info('[diff-handler] Calling getFileDiff', { cwd: scopeCwd, file });\n const result = await getFileDiff(scopeCwd, file);\n\n // For untracked/new files git diff may be empty.\n // Fallback to raw file content so UI can render a \"new file content\" view.\n if (!result.diff || result.diff.trim().length === 0) {\n try {\n const absolutePath = join(scopeCwd, file);\n const content = await readFile(absolutePath, 'utf-8');\n const additions = content.length === 0 ? 0 : content.split('\\n').length;\n return {\n scope,\n file,\n diff: content,\n additions,\n deletions: 0,\n };\n } catch (readError) {\n logger.warn('[diff-handler] Failed to read file content fallback', {\n file,\n error: readError instanceof Error ? readError.message : String(readError),\n });\n }\n }\n\n return {\n scope,\n file,\n diff: result.diff,\n additions: result.additions,\n deletions: result.deletions,\n };\n } catch (error) {\n throw new Error(`Failed to get diff for file: ${error}`);\n }\n },\n});\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
|
|
2
|
+
import { RestInput, TableData, TableRow } from '@kb-labs/sdk';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* GET /files handler
|
|
6
|
+
*
|
|
7
|
+
* Returns flat file list with diff statistics (GitHub/GitLab style).
|
|
8
|
+
* Uses TableData format from studio-contracts.
|
|
9
|
+
*
|
|
10
|
+
* Response format: TableData with rows array
|
|
11
|
+
*/
|
|
12
|
+
declare const _default: _kb_labs_shared_command_kit.Handler<unknown, RestInput<{
|
|
13
|
+
scope?: string;
|
|
14
|
+
}, unknown, unknown>, TableData<TableRow>>;
|
|
15
|
+
|
|
16
|
+
export { _default as default };
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { defineHandler, useConfig } from '@kb-labs/sdk';
|
|
2
|
+
import { getGitStatus } from '@kb-labs/commit-core/analyzer';
|
|
3
|
+
import { COMMIT_CACHE_PREFIX, resolveCommitConfig } from '@kb-labs/commit-contracts';
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
import { exec } from 'child_process';
|
|
6
|
+
import { promisify } from 'util';
|
|
7
|
+
|
|
8
|
+
// src/rest/handlers/files-handler.ts
|
|
9
|
+
function resolveScopePath(baseCwd, scopeId = "root", scopes) {
|
|
10
|
+
const scopeDef = scopes?.find((s) => s.id === scopeId);
|
|
11
|
+
const relativePath = scopeDef?.path ?? (scopeId === "root" ? "." : scopeId);
|
|
12
|
+
return relativePath === "." ? baseCwd : path.join(baseCwd, relativePath);
|
|
13
|
+
}
|
|
14
|
+
var execAsync = promisify(exec);
|
|
15
|
+
var FILES_CACHE_TTL = 5e3;
|
|
16
|
+
var files_handler_default = defineHandler({
|
|
17
|
+
async execute(ctx, input) {
|
|
18
|
+
const scope = input.query?.scope || "root";
|
|
19
|
+
const cacheKey = `${COMMIT_CACHE_PREFIX}files-list:${scope}`;
|
|
20
|
+
const cached = await ctx.platform.cache.get(cacheKey);
|
|
21
|
+
if (cached !== null && cached !== void 0) {
|
|
22
|
+
return cached;
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
const fileConfig = await useConfig();
|
|
26
|
+
const config = resolveCommitConfig(fileConfig ?? {});
|
|
27
|
+
const scopeCwd = resolveScopePath(ctx.cwd, scope, config.scope?.scopes);
|
|
28
|
+
const gitStatus = await getGitStatus(scopeCwd);
|
|
29
|
+
const allFiles = [
|
|
30
|
+
...gitStatus.staged,
|
|
31
|
+
...gitStatus.unstaged,
|
|
32
|
+
...gitStatus.untracked
|
|
33
|
+
];
|
|
34
|
+
const diffStats = await getDiffStats(scopeCwd, allFiles);
|
|
35
|
+
const rows = [];
|
|
36
|
+
for (const file of gitStatus.staged) {
|
|
37
|
+
const stats = diffStats.get(file) ?? { additions: 0, deletions: 0 };
|
|
38
|
+
const filename = file.split("/").pop() || file;
|
|
39
|
+
rows.push({
|
|
40
|
+
path: file,
|
|
41
|
+
filename,
|
|
42
|
+
status: stats.deletions > 0 && stats.additions === 0 ? "deleted" : "modified",
|
|
43
|
+
additions: stats.additions,
|
|
44
|
+
deletions: stats.deletions,
|
|
45
|
+
changes: `+${stats.additions} -${stats.deletions}`
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
for (const file of gitStatus.unstaged) {
|
|
49
|
+
if (!rows.find((r) => r.path === file)) {
|
|
50
|
+
const stats = diffStats.get(file) ?? { additions: 0, deletions: 0 };
|
|
51
|
+
const filename = file.split("/").pop() || file;
|
|
52
|
+
rows.push({
|
|
53
|
+
path: file,
|
|
54
|
+
filename,
|
|
55
|
+
status: "modified",
|
|
56
|
+
additions: stats.additions,
|
|
57
|
+
deletions: stats.deletions,
|
|
58
|
+
changes: `+${stats.additions} -${stats.deletions}`
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
for (const file of gitStatus.untracked) {
|
|
63
|
+
const stats = diffStats.get(file) ?? { additions: 0, deletions: 0 };
|
|
64
|
+
const filename = file.split("/").pop() || file;
|
|
65
|
+
rows.push({
|
|
66
|
+
path: file,
|
|
67
|
+
filename,
|
|
68
|
+
status: "added",
|
|
69
|
+
additions: stats.additions,
|
|
70
|
+
deletions: stats.deletions,
|
|
71
|
+
changes: `+${stats.additions}`
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
rows.sort((a, b) => a.path.localeCompare(b.path));
|
|
75
|
+
const result = {
|
|
76
|
+
rows,
|
|
77
|
+
total: rows.length
|
|
78
|
+
};
|
|
79
|
+
await ctx.platform.cache.set(cacheKey, result, FILES_CACHE_TTL);
|
|
80
|
+
return result;
|
|
81
|
+
} catch (error) {
|
|
82
|
+
return { rows: [], total: 0 };
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
async function getDiffStats(cwd, files) {
|
|
87
|
+
const stats = /* @__PURE__ */ new Map();
|
|
88
|
+
if (files.length === 0) {
|
|
89
|
+
return stats;
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
const batchSize = 100;
|
|
93
|
+
for (let i = 0; i < files.length; i += batchSize) {
|
|
94
|
+
const batch = files.slice(i, i + batchSize);
|
|
95
|
+
const escapedFiles = batch.map((f) => `"${f.replace(/"/g, '\\"')}"`).join(" ");
|
|
96
|
+
try {
|
|
97
|
+
const { stdout } = await execAsync(`git diff --numstat HEAD -- ${escapedFiles}`, { cwd });
|
|
98
|
+
const lines = stdout.trim().split("\n");
|
|
99
|
+
for (const line of lines) {
|
|
100
|
+
if (!line) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
const parts = line.split(" ");
|
|
104
|
+
if (parts.length < 3 || !parts[2]) {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
const additions = parseInt(parts[0] || "0", 10);
|
|
108
|
+
const deletions = parseInt(parts[1] || "0", 10);
|
|
109
|
+
const path2 = parts[2];
|
|
110
|
+
stats.set(path2, { additions, deletions });
|
|
111
|
+
}
|
|
112
|
+
} catch {
|
|
113
|
+
for (const file of batch) {
|
|
114
|
+
if (!stats.has(file)) {
|
|
115
|
+
stats.set(file, { additions: 0, deletions: 0 });
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
for (const file of files) {
|
|
121
|
+
if (!stats.has(file)) {
|
|
122
|
+
try {
|
|
123
|
+
const safeFile = file.replace(/"/g, '\\"');
|
|
124
|
+
const { stdout: content } = await execAsync(`wc -l "${safeFile}"`, { cwd });
|
|
125
|
+
const match = content.trim().match(/^\s*(\d+)/);
|
|
126
|
+
const lines = match && match[1] ? parseInt(match[1], 10) : 0;
|
|
127
|
+
stats.set(file, { additions: lines, deletions: 0 });
|
|
128
|
+
} catch {
|
|
129
|
+
stats.set(file, { additions: 0, deletions: 0 });
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
} catch {
|
|
134
|
+
for (const file of files) {
|
|
135
|
+
stats.set(file, { additions: 0, deletions: 0 });
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return stats;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export { files_handler_default as default };
|
|
142
|
+
//# sourceMappingURL=files-handler.js.map
|
|
143
|
+
//# sourceMappingURL=files-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/rest/handlers/scope-resolver.ts","../../../src/rest/handlers/files-handler.ts"],"names":["path"],"mappings":"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","file":"files-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, type TableData, type TableRow } from '@kb-labs/sdk';\nimport { getGitStatus } from '@kb-labs/commit-core/analyzer';\nimport { COMMIT_CACHE_PREFIX, type CommitPluginConfig, resolveCommitConfig } from '@kb-labs/commit-contracts';\nimport { resolveScopePath } from './scope-resolver';\nimport { exec } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst execAsync = promisify(exec);\n\nconst FILES_CACHE_TTL = 5000; // 5 seconds (same as status-handler)\n\n/**\n * File row for table display (GitHub/GitLab style)\n */\ninterface FileRow extends TableRow {\n path: string;\n filename: string;\n status: 'modified' | 'added' | 'deleted';\n additions: number;\n deletions: number;\n changes: string; // \"+45 -12\" formatted string\n}\n\n/**\n * GET /files handler\n *\n * Returns flat file list with diff statistics (GitHub/GitLab style).\n * Uses TableData format from studio-contracts.\n *\n * Response format: TableData with rows array\n */\nexport default defineHandler({\n async execute(ctx: PluginContextV3, input: RestInput<{ scope?: string }>): Promise<TableData> {\n const scope = input.query?.scope || 'root';\n\n // Check cache first\n const cacheKey = `${COMMIT_CACHE_PREFIX}files-list:${scope}`;\n const cached = await ctx.platform.cache.get(cacheKey);\n\n if (cached !== null && cached !== undefined) {\n return cached as TableData;\n }\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\n // Get git status (git runs FROM scopeCwd, no filtering)\n const gitStatus = await getGitStatus(scopeCwd);\n\n // Get diff stats for each file\n const allFiles = [\n ...gitStatus.staged,\n ...gitStatus.unstaged,\n ...gitStatus.untracked,\n ];\n\n const diffStats = await getDiffStats(scopeCwd, allFiles);\n\n // Build flat file list\n const rows: FileRow[] = [];\n\n // Process staged files\n for (const file of gitStatus.staged) {\n const stats = diffStats.get(file) ?? { additions: 0, deletions: 0 };\n const filename = file.split('/').pop() || file;\n\n rows.push({\n path: file,\n filename,\n status: stats.deletions > 0 && stats.additions === 0 ? 'deleted' : 'modified',\n additions: stats.additions,\n deletions: stats.deletions,\n changes: `+${stats.additions} -${stats.deletions}`,\n });\n }\n\n // Process unstaged files\n for (const file of gitStatus.unstaged) {\n if (!rows.find(r => r.path === file)) {\n const stats = diffStats.get(file) ?? { additions: 0, deletions: 0 };\n const filename = file.split('/').pop() || file;\n\n rows.push({\n path: file,\n filename,\n status: 'modified',\n additions: stats.additions,\n deletions: stats.deletions,\n changes: `+${stats.additions} -${stats.deletions}`,\n });\n }\n }\n\n // Process untracked files\n for (const file of gitStatus.untracked) {\n const stats = diffStats.get(file) ?? { additions: 0, deletions: 0 };\n const filename = file.split('/').pop() || file;\n\n rows.push({\n path: file,\n filename,\n status: 'added',\n additions: stats.additions,\n deletions: stats.deletions,\n changes: `+${stats.additions}`,\n });\n }\n\n // Sort by path\n rows.sort((a, b) => a.path.localeCompare(b.path));\n\n // Return TableData\n const result: TableData = {\n rows,\n total: rows.length,\n };\n\n // Store in cache with TTL\n await ctx.platform.cache.set(cacheKey, result, FILES_CACHE_TTL);\n\n return result;\n } catch (error) {\n // Return empty table on error\n return { rows: [], total: 0 };\n }\n },\n});\n\n/**\n * Get diff statistics for specific files only\n * Uses git diff --numstat with specific file paths to avoid timeout\n */\nasync function getDiffStats(\n cwd: string,\n files: string[]\n): Promise<Map<string, { additions: number; deletions: number }>> {\n const stats = new Map<string, { additions: number; deletions: number }>();\n\n if (files.length === 0) {\n return stats;\n }\n\n try {\n // Process files in batches to avoid \"argument list too long\"\n const batchSize = 100;\n for (let i = 0; i < files.length; i += batchSize) {\n const batch = files.slice(i, i + batchSize);\n\n // Escape file paths for shell\n const escapedFiles = batch.map(f => `\"${f.replace(/\"/g, '\\\\\"')}\"`).join(' ');\n\n // Run git diff --numstat only for these specific files\n try {\n const { stdout } = await execAsync(`git diff --numstat HEAD -- ${escapedFiles}`, { cwd });\n\n const lines = stdout.trim().split('\\n');\n for (const line of lines) {\n if (!line) {continue;}\n\n const parts = line.split('\\t');\n if (parts.length < 3 || !parts[2]) {continue;}\n\n const additions = parseInt(parts[0] || '0', 10);\n const deletions = parseInt(parts[1] || '0', 10);\n const path = parts[2];\n\n stats.set(path, { additions, deletions });\n }\n } catch {\n // If batch fails, mark files as zero\n for (const file of batch) {\n if (!stats.has(file)) {\n stats.set(file, { additions: 0, deletions: 0 });\n }\n }\n }\n }\n\n // For untracked files (not in git diff output), count lines\n for (const file of files) {\n if (!stats.has(file)) {\n try {\n const safeFile = file.replace(/\"/g, '\\\\\"');\n const { stdout: content } = await execAsync(`wc -l \"${safeFile}\"`, { cwd });\n const match = content.trim().match(/^\\s*(\\d+)/);\n const lines = match && match[1] ? parseInt(match[1], 10) : 0;\n stats.set(file, { additions: lines, deletions: 0 });\n } catch {\n stats.set(file, { additions: 0, deletions: 0 });\n }\n }\n }\n } catch {\n // If all fails, return zeros\n for (const file of files) {\n stats.set(file, { additions: 0, deletions: 0 });\n }\n }\n\n return stats;\n}\n\n"]}
|