@kb-labs/commit-entry 2.88.0 → 2.93.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.
@@ -2,7 +2,7 @@ import { defineHandler, useConfig } from '@kb-labs/sdk';
2
2
  import { getGitStatus } from '@kb-labs/commit-core/analyzer';
3
3
  import { COMMIT_CACHE_PREFIX, resolveCommitConfig } from '@kb-labs/commit-contracts';
4
4
  import * as path from 'path';
5
- import { exec } from 'child_process';
5
+ import { execFile } from 'child_process';
6
6
  import { promisify } from 'util';
7
7
 
8
8
  // src/rest/handlers/files-handler.ts
@@ -11,7 +11,7 @@ function resolveScopePath(baseCwd, scopeId = "root", scopes) {
11
11
  const relativePath = scopeDef?.path ?? (scopeId === "root" ? "." : scopeId);
12
12
  return relativePath === "." ? baseCwd : path.join(baseCwd, relativePath);
13
13
  }
14
- var execAsync = promisify(exec);
14
+ var execFileAsync = promisify(execFile);
15
15
  var FILES_CACHE_TTL = 5e3;
16
16
  var files_handler_default = defineHandler({
17
17
  async execute(ctx, input) {
@@ -92,9 +92,8 @@ async function getDiffStats(cwd, files) {
92
92
  const batchSize = 100;
93
93
  for (let i = 0; i < files.length; i += batchSize) {
94
94
  const batch = files.slice(i, i + batchSize);
95
- const escapedFiles = batch.map((f) => `"${f.replace(/"/g, '\\"')}"`).join(" ");
96
95
  try {
97
- const { stdout } = await execAsync(`git diff --numstat HEAD -- ${escapedFiles}`, { cwd });
96
+ const { stdout } = await execFileAsync("git", ["diff", "--numstat", "HEAD", "--", ...batch], { cwd });
98
97
  const lines = stdout.trim().split("\n");
99
98
  for (const line of lines) {
100
99
  if (!line) {
@@ -120,8 +119,7 @@ async function getDiffStats(cwd, files) {
120
119
  for (const file of files) {
121
120
  if (!stats.has(file)) {
122
121
  try {
123
- const safeFile = file.replace(/"/g, '\\"');
124
- const { stdout: content } = await execAsync(`wc -l "${safeFile}"`, { cwd });
122
+ const { stdout: content } = await execFileAsync("wc", ["-l", file], { cwd });
125
123
  const match = content.trim().match(/^\s*(\d+)/);
126
124
  const lines = match && match[1] ? parseInt(match[1], 10) : 0;
127
125
  stats.set(file, { additions: lines, deletions: 0 });
@@ -1 +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"]}
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 { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst execFileAsync = promisify(execFile);\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 // Run git diff --numstat only for these specific files\n try {\n const { stdout } = await execFileAsync('git', ['diff', '--numstat', 'HEAD', '--', ...batch], { 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 { stdout: content } = await execFileAsync('wc', ['-l', file], { 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"]}
@@ -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 } from '@kb-labs/sdk';\nimport { loadPlan } from '@kb-labs/commit-core/storage';\nimport { getGitStatus } from '@kb-labs/commit-core/analyzer';\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 // Get git status (with platform cache)\n let filesChanged = 0;\n let gitStatus = 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: any };\n filesChanged = cachedData.count;\n gitStatus = cachedData.status;\n } else {\n // Fetch fresh git status\n // Resolve scope to actual directory path (same as files-handler)\n const fileConfig = await useConfig<Partial<CommitPluginConfig>>();\n const config = resolveCommitConfig(fileConfig ?? {});\n const scopeCwd = resolveScopePath(ctx.cwd, scope, config.scope?.scopes);\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 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 };\n } catch (error) {\n return {\n scope,\n hasPlan: false,\n planStatus: 'idle',\n filesChanged: 0,\n commitsInPlan: 0,\n commitsApplied: 0,\n };\n }\n },\n});\n"]}
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 } from '@kb-labs/sdk';\nimport { loadPlan } from '@kb-labs/commit-core/storage';\nimport { getGitStatus } from '@kb-labs/commit-core/analyzer';\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 // 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 // Fetch fresh git status\n // Resolve scope to actual directory path (same as files-handler)\n const fileConfig = await useConfig<Partial<CommitPluginConfig>>();\n const config = resolveCommitConfig(fileConfig ?? {});\n const scopeCwd = resolveScopePath(ctx.cwd, scope, config.scope?.scopes);\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 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 };\n } catch (error) {\n return {\n scope,\n hasPlan: false,\n planStatus: 'idle',\n filesChanged: 0,\n commitsInPlan: 0,\n commitsApplied: 0,\n };\n }\n },\n});\n"]}
@@ -5,7 +5,7 @@
5
5
  "name": "commitPlugin",
6
6
  "globalName": "commitPlugin",
7
7
  "buildInfo": {
8
- "buildVersion": "2.87.0",
8
+ "buildVersion": "2.92.0",
9
9
  "buildName": "@kb-labs/commit-entry"
10
10
  },
11
11
  "publicPath": "auto",
@@ -27,7 +27,7 @@
27
27
  {
28
28
  "id": "commitPlugin:@kb-labs/studio-event-bus",
29
29
  "name": "@kb-labs/studio-event-bus",
30
- "version": "2.87.0",
30
+ "version": "2.92.0",
31
31
  "singleton": true,
32
32
  "requiredVersion": "^0.1.0",
33
33
  "assets": {
@@ -47,7 +47,7 @@
47
47
  {
48
48
  "id": "commitPlugin:@kb-labs/studio-ui-core",
49
49
  "name": "@kb-labs/studio-ui-core",
50
- "version": "2.87.0",
50
+ "version": "2.92.0",
51
51
  "singleton": true,
52
52
  "requiredVersion": "^0.1.0",
53
53
  "assets": {
@@ -86,7 +86,7 @@
86
86
  {
87
87
  "id": "commitPlugin:@kb-labs/studio-hooks",
88
88
  "name": "@kb-labs/studio-hooks",
89
- "version": "2.87.0",
89
+ "version": "2.92.0",
90
90
  "singleton": true,
91
91
  "requiredVersion": "^0.1.0",
92
92
  "assets": {
@@ -106,7 +106,7 @@
106
106
  {
107
107
  "id": "commitPlugin:@kb-labs/studio-ui-kit",
108
108
  "name": "@kb-labs/studio-ui-kit",
109
- "version": "2.87.0",
109
+ "version": "2.92.0",
110
110
  "singleton": true,
111
111
  "requiredVersion": "^0.1.0",
112
112
  "assets": {
@@ -126,16 +126,15 @@
126
126
  }
127
127
  },
128
128
  {
129
- "id": "commitPlugin:react-dom",
130
- "name": "react-dom",
129
+ "id": "commitPlugin:react",
130
+ "name": "react",
131
131
  "version": "19.2.5",
132
132
  "singleton": true,
133
133
  "requiredVersion": "^19.0.0",
134
134
  "assets": {
135
135
  "js": {
136
136
  "sync": [
137
- "165.js",
138
- "546.js"
137
+ "405.js"
139
138
  ],
140
139
  "async": []
141
140
  },
@@ -146,15 +145,16 @@
146
145
  }
147
146
  },
148
147
  {
149
- "id": "commitPlugin:react",
150
- "name": "react",
148
+ "id": "commitPlugin:react-dom",
149
+ "name": "react-dom",
151
150
  "version": "19.2.5",
152
151
  "singleton": true,
153
152
  "requiredVersion": "^19.0.0",
154
153
  "assets": {
155
154
  "js": {
156
155
  "sync": [
157
- "405.js"
156
+ "165.js",
157
+ "546.js"
158
158
  ],
159
159
  "async": []
160
160
  },
@@ -5,7 +5,7 @@
5
5
  "name": "commitPlugin",
6
6
  "globalName": "commitPlugin",
7
7
  "buildInfo": {
8
- "buildVersion": "2.87.0",
8
+ "buildVersion": "2.92.0",
9
9
  "buildName": "@kb-labs/commit-entry"
10
10
  },
11
11
  "publicPath": "auto",
@@ -27,7 +27,7 @@
27
27
  {
28
28
  "id": "commitPlugin:@kb-labs/studio-event-bus",
29
29
  "name": "@kb-labs/studio-event-bus",
30
- "version": "2.87.0",
30
+ "version": "2.92.0",
31
31
  "requiredVersion": "^0.1.0",
32
32
  "singleton": true,
33
33
  "assets": {
@@ -48,7 +48,7 @@
48
48
  {
49
49
  "id": "commitPlugin:@kb-labs/studio-ui-core",
50
50
  "name": "@kb-labs/studio-ui-core",
51
- "version": "2.87.0",
51
+ "version": "2.92.0",
52
52
  "requiredVersion": "^0.1.0",
53
53
  "singleton": true,
54
54
  "assets": {
@@ -89,7 +89,7 @@
89
89
  {
90
90
  "id": "commitPlugin:@kb-labs/studio-hooks",
91
91
  "name": "@kb-labs/studio-hooks",
92
- "version": "2.87.0",
92
+ "version": "2.92.0",
93
93
  "requiredVersion": "^0.1.0",
94
94
  "singleton": true,
95
95
  "assets": {
@@ -110,7 +110,7 @@
110
110
  {
111
111
  "id": "commitPlugin:@kb-labs/studio-ui-kit",
112
112
  "name": "@kb-labs/studio-ui-kit",
113
- "version": "2.87.0",
113
+ "version": "2.92.0",
114
114
  "requiredVersion": "^0.1.0",
115
115
  "singleton": true,
116
116
  "assets": {
@@ -131,16 +131,15 @@
131
131
  "usedIn": []
132
132
  },
133
133
  {
134
- "id": "commitPlugin:react-dom",
135
- "name": "react-dom",
134
+ "id": "commitPlugin:react",
135
+ "name": "react",
136
136
  "version": "19.2.5",
137
137
  "requiredVersion": "^19.0.0",
138
138
  "singleton": true,
139
139
  "assets": {
140
140
  "js": {
141
141
  "sync": [
142
- "165.js",
143
- "546.js"
142
+ "405.js"
144
143
  ],
145
144
  "async": []
146
145
  },
@@ -152,15 +151,16 @@
152
151
  "usedIn": []
153
152
  },
154
153
  {
155
- "id": "commitPlugin:react",
156
- "name": "react",
154
+ "id": "commitPlugin:react-dom",
155
+ "name": "react-dom",
157
156
  "version": "19.2.5",
158
157
  "requiredVersion": "^19.0.0",
159
158
  "singleton": true,
160
159
  "assets": {
161
160
  "js": {
162
161
  "sync": [
163
- "405.js"
162
+ "165.js",
163
+ "546.js"
164
164
  ],
165
165
  "async": []
166
166
  },