@klarkxy/dsh-git-commit 0.2.5 → 0.3.1

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/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/git.ts","../src/plan.ts","../src/service.ts","../src/storage.ts","../src/index.ts"],"sourcesContent":["import { execFile } from 'node:child_process'\nimport { createHash } from 'node:crypto'\nimport { constants } from 'node:fs'\nimport { copyFile, lstat, mkdtemp, open, readFile, readlink, realpath, rm } from 'node:fs/promises'\nimport { tmpdir } from 'node:os'\nimport { isAbsolute, join, relative, resolve } from 'node:path'\nimport { GIT_TIMEOUT_MS, MAX_UNTRACKED_PREVIEW_CHARS } from './contracts.ts'\n\nexport interface GitRunOptions {\n readonly cwd: string\n readonly signal?: AbortSignal\n readonly timeoutMs?: number\n}\n\nexport class GitError extends Error {\n readonly stderr: string\n constructor(message: string, stderr = '') {\n super(message)\n this.name = 'GitError'\n this.stderr = stderr\n }\n}\n\nexport type GitRunner = (args: readonly string[], options: GitRunOptions) => Promise<string>\n\n/** NUL separator used by `git status -z` without embedding a control byte in this source file. */\nconst NUL = String.fromCharCode(0)\n\n/** Spawn git without a shell; arguments are passed literally. */\nexport const execGit: GitRunner = (args, options) => new Promise((resolve, reject) => {\n try {\n execFile('git', [...args], {\n cwd: options.cwd,\n encoding: 'utf8',\n maxBuffer: 32 * 1024 * 1024,\n timeout: options.timeoutMs ?? GIT_TIMEOUT_MS,\n signal: options.signal,\n windowsHide: true,\n env: { ...process.env, GIT_TERMINAL_PROMPT: '0', GIT_LITERAL_PATHSPECS: '1' },\n }, (error, stdout, stderr) => {\n if (error) {\n if (options.signal?.aborted) {\n reject(Object.assign(new Error('dsh-git-commit: git command cancelled'), { code: 'cancelled' }))\n return\n }\n reject(Object.assign(new GitError(stderr.trim() || error.message, stderr), { code: (error as NodeJS.ErrnoException).code }))\n return\n }\n resolve(stdout)\n })\n } catch (error) {\n reject(error)\n }\n})\n\nexport function isGitMissing(error: unknown): boolean {\n return typeof error === 'object' && error !== null && (error as { code?: unknown }).code === 'ENOENT'\n}\n\nexport type ChangeStatus = 'modified' | 'added' | 'deleted' | 'renamed' | 'copied' | 'untracked'\n\nexport interface ChangedFile {\n readonly path: string\n readonly status: ChangeStatus\n /** Rename source in porcelain -z output; committed with the destination. */\n readonly origin?: string\n /** True when the index already stages this path. */\n readonly staged: boolean\n}\n\nexport function statusLetter(kind: ChangeStatus): string {\n switch (kind) {\n case 'added': return 'A'\n case 'deleted': return 'D'\n case 'renamed': return 'R'\n case 'copied': return 'C'\n case 'untracked': return '?'\n default: return 'M'\n }\n}\n\n/**\n * Parse `git status --porcelain=v1 -z --untracked-files=all` output.\n * In -z mode rename/copy entries put the destination path first, then a NUL, then the origin path.\n */\nexport function parsePorcelain(output: string): ChangedFile[] {\n const tokens = output.split(NUL)\n const files: ChangedFile[] = []\n let index = 0\n while (index < tokens.length) {\n const token = tokens[index]\n index += 1\n if (!token) continue\n if (token.length < 4) continue\n const x = token[0] ?? ' '\n const y = token[1] ?? ' '\n const path = token.slice(3)\n if (x === '!' && y === '!') continue\n if (x === '?' && y === '?') {\n files.push({ path, status: 'untracked', staged: false })\n continue\n }\n if (x === 'R' || x === 'C' || y === 'R' || y === 'C') {\n const origin = tokens[index]\n index += 1\n if (!origin) throw new GitError('dsh-git-commit: incomplete rename status')\n files.push({ path, origin, status: x === 'C' || y === 'C' ? 'copied' : 'renamed', staged: x !== ' ' && x !== '?' })\n continue\n }\n if (x === 'U' || y === 'U' || (x === 'A' && y === 'A') || (x === 'D' && y === 'D')) {\n throw new GitError(`dsh-git-commit: resolve merge conflicts before committing (${path})`)\n }\n const status: ChangeStatus = x === 'D' || y === 'D' ? 'deleted' : x === 'A' || y === 'A' ? 'added' : 'modified'\n files.push({ path, status, staged: x !== ' ' && x !== '?' })\n }\n return files\n}\n\nexport interface RepoInfo {\n readonly root: string\n readonly branch: string\n}\n\nexport async function repoInfo(run: GitRunner, cwd: string, signal?: AbortSignal): Promise<RepoInfo> {\n const root = (await run(['rev-parse', '--show-toplevel'], { cwd, signal })).trim()\n let branch = (await run(['symbolic-ref', '--quiet', '--short', 'HEAD'], { cwd: root, signal }).catch(() => '')).trim()\n if (!branch) branch = (await run(['rev-parse', '--short', 'HEAD'], { cwd: root, signal }).catch(() => '')).trim()\n return { root, branch: branch || 'HEAD' }\n}\n\nexport async function workingTreeChanges(run: GitRunner, root: string, signal?: AbortSignal): Promise<ChangedFile[]> {\n const output = await run(['status', '--porcelain=v1', '-z', '--untracked-files=all'], { cwd: root, signal })\n return parsePorcelain(output)\n}\n\n/** Exact index/worktree content fingerprint, including untracked file bytes. */\nexport async function workspaceSnapshot(run: GitRunner, root: string, signal?: AbortSignal): Promise<{ files: ChangedFile[]; fingerprint: string }> {\n const status = await run(['status', '--porcelain=v1', '-z', '--untracked-files=all'], { cwd: root, signal })\n const files = parsePorcelain(status)\n const hash = createHash('sha256').update(status)\n hash.update(await run(['symbolic-ref', '--quiet', 'HEAD'], { cwd: root, signal }).catch(() => 'DETACHED'))\n hash.update(await run(['rev-parse', 'HEAD'], { cwd: root, signal }).catch(() => 'unborn'))\n hash.update(await run(['diff', '--cached', '--binary', '--no-ext-diff'], { cwd: root, signal }))\n hash.update(await run(['diff', '--binary', '--no-ext-diff'], { cwd: root, signal }))\n for (const file of files) {\n if (file.status !== 'untracked') continue\n hash.update(file.path)\n hash.update(await worktreePathDigest(run, root, file.path, signal))\n }\n return { files, fingerprint: hash.digest('hex') }\n}\n\n/** A worktree content check for groups waiting behind earlier commits. */\nexport async function pathVersions(run: GitRunner, root: string, paths: readonly string[], signal?: AbortSignal): Promise<string> {\n const hash = createHash('sha256')\n for (const path of paths) {\n hash.update(path)\n hash.update(await worktreePathDigest(run, root, path, signal))\n }\n return hash.digest('hex')\n}\n\nasync function worktreePathDigest(run: GitRunner, root: string, path: string, signal?: AbortSignal): Promise<string> {\n const absolute = resolve(root, path)\n let stat\n try {\n stat = await lstat(absolute)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return 'missing'\n throw error\n }\n const hash = createHash('sha256').update(String(stat.mode))\n if (stat.isSymbolicLink()) hash.update(await readlink(absolute))\n else if (stat.isFile()) {\n const handle = await open(absolute, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0))\n try {\n if (!(await handle.stat()).isFile() || !(await lstat(absolute)).isFile()) throw new GitError(`dsh-git-commit: file changed while reading (${path})`)\n for await (const chunk of handle.createReadStream({ autoClose: false })) {\n signal?.throwIfAborted()\n hash.update(chunk)\n }\n if (!(await lstat(absolute)).isFile()) throw new GitError(`dsh-git-commit: file changed while reading (${path})`)\n } finally {\n await handle.close()\n }\n } else if (stat.isDirectory()) {\n hash.update(await run(['-C', absolute, 'rev-parse', 'HEAD'], { cwd: root, signal }))\n hash.update(await run(['-C', absolute, 'status', '--porcelain=v1', '-z'], { cwd: root, signal }))\n }\n return hash.digest('hex')\n}\n\nexport async function recentSubjects(run: GitRunner, root: string, count: number, signal?: AbortSignal): Promise<string[]> {\n const output = await run(['log', `-${count}`, '--pretty=%s'], { cwd: root, signal }).catch(() => '')\n return output.split('\\n').map(line => line.trim()).filter(Boolean)\n}\n\n/** Combined staged+worktree stat and diff against HEAD for the given paths. */\nexport async function diffAgainstHead(\n run: GitRunner, root: string, paths: readonly string[], signal?: AbortSignal,\n): Promise<{ stat: string; diff: string }> {\n const args = paths.length > 0 ? ['--', ...paths] : []\n const stat = await run(['diff', 'HEAD', '--stat', '--no-color', ...args], { cwd: root, signal }).catch(() => '')\n const diff = await run(['diff', 'HEAD', '--no-color', '--no-ext-diff', ...args], { cwd: root, signal }).catch(() => '')\n return { stat, diff }\n}\n\nexport interface UntrackedPreview {\n readonly path: string\n readonly preview: string\n readonly binary: boolean\n}\n\nexport async function untrackedPreview(root: string, path: string): Promise<UntrackedPreview> {\n try {\n const absolute = resolve(root, path)\n const rootReal = await realpath(root)\n const withinRoot = async () => {\n const target = await realpath(absolute)\n const rel = relative(rootReal, target)\n return rel !== '' && rel !== '..' && !rel.startsWith(`..${String.fromCharCode(47)}`)\n && !rel.startsWith(`..${String.fromCharCode(92)}`) && !isAbsolute(rel)\n }\n if (!await withinRoot()) return { path, preview: '', binary: true }\n if (!(await lstat(absolute)).isFile()) return { path, preview: '', binary: true }\n const handle = await open(absolute, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0))\n let buffer: Buffer\n try {\n const bounded = Buffer.alloc(MAX_UNTRACKED_PREVIEW_CHARS * 4)\n const { bytesRead } = await handle.read(bounded, 0, bounded.length, 0)\n buffer = bounded.subarray(0, bytesRead)\n } finally {\n await handle.close()\n }\n if (!await withinRoot() || !(await lstat(absolute)).isFile()) return { path, preview: '', binary: true }\n if (buffer.includes(0)) return { path, preview: '', binary: true }\n const text = buffer.toString('utf8')\n return { path, preview: text.slice(0, MAX_UNTRACKED_PREVIEW_CHARS), binary: false }\n } catch {\n return { path, preview: '', binary: true }\n }\n}\n\nexport interface ExecutedCommit {\n readonly hash: string\n readonly skipped: boolean\n}\n\n/** Known commits or an uncertain current group must survive a rejected run. */\nexport class PartialCommitError extends Error {\n readonly commits: readonly ExecutedCommit[]\n readonly cause: unknown\n readonly uncertain?: { readonly message: string; readonly files: readonly string[] }\n constructor(commits: readonly ExecutedCommit[], cause: unknown, uncertain?: { readonly message: string; readonly files: readonly string[] }) {\n super(cause instanceof Error ? cause.message : String(cause))\n this.name = 'PartialCommitError'\n this.commits = commits\n this.cause = cause\n this.uncertain = uncertain\n }\n}\n\nasync function indexBytes(path: string): Promise<Buffer | undefined> {\n try { return await readFile(path) }\n catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return undefined\n throw error\n }\n}\n\nasync function headOid(run: GitRunner, root: string): Promise<string> {\n try { return (await run(['rev-parse', '--verify', 'HEAD'], { cwd: root })).trim() }\n catch (error) {\n if (error instanceof GitError && /Needed a single revision|not a valid object name HEAD/u.test(error.stderr)) return ''\n throw error\n }\n}\n\n/**\n * Commit each group from the worktree. `--only` keeps other staged paths out of\n * this commit; an exact index backup protects the current group on failure.\n */\nexport async function commitGroups(\n run: GitRunner,\n root: string,\n groups: ReadonlyArray<{ message: string; files: readonly string[] }>,\n selected: readonly ChangedFile[],\n signal?: AbortSignal,\n verify?: (paths: readonly string[]) => Promise<void>,\n): Promise<ExecutedCommit[]> {\n const commits: ExecutedCommit[] = []\n let partialFailure: PartialCommitError | undefined\n const fail = (error: unknown): never => {\n if (error instanceof PartialCommitError) { partialFailure = error; throw error }\n if (commits.length === 0) throw error\n partialFailure = new PartialCommitError(commits, error)\n throw partialFailure\n }\n for (const group of groups) {\n if (group.files.length === 0) continue\n const paths = group.files.flatMap(path => {\n const file = selected.find(file => file.path === path)\n return file?.status === 'renamed' && file.origin ? [path, file.origin] : [path]\n })\n let backupDir: string | undefined\n try {\n signal?.throwIfAborted()\n await verify?.(paths)\n const gitPath = (await run(['rev-parse', '--git-path', 'index'], { cwd: root, signal })).trim()\n const indexPath = isAbsolute(gitPath) ? gitPath : resolve(root, gitPath)\n backupDir = await mkdtemp(join(tmpdir(), 'dsh-git-commit-'))\n const backupPath = join(backupDir, 'index')\n let hadIndex = true\n try {\n await copyFile(indexPath, backupPath)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error\n hadIndex = false\n }\n const head = await headOid(run, root)\n const originalIndex = await indexBytes(indexPath)\n if (hadIndex ? !originalIndex?.equals(await readFile(backupPath)) : originalIndex !== undefined) {\n throw new GitError('dsh-git-commit: index changed before committing; retry')\n }\n let stagedIndex = originalIndex\n let committed = false\n let commitInvoked = false\n try {\n signal?.throwIfAborted()\n await run(['add', '-A', '--', ...group.files], { cwd: root, signal })\n stagedIndex = await indexBytes(indexPath)\n signal?.throwIfAborted()\n commitInvoked = true\n await run(['commit', '--quiet', '--only', '-m', group.message, '--', ...paths], { cwd: root, signal })\n committed = true\n let hash = ''\n try {\n // Result collection and index cleanup must survive request cancellation/unload.\n hash = (await run(['rev-parse', '--short', 'HEAD'], { cwd: root })).trim()\n } catch (error) {\n // The commit object exists. A failed hash read must not look like \"nothing was committed\".\n commits.push({ hash: '', skipped: false })\n throw error\n }\n if (!hash) {\n commits.push({ hash: '', skipped: false })\n throw new GitError('dsh-git-commit: commit was created but its hash could not be read')\n }\n commits.push({ hash, skipped: false })\n } catch (error) {\n if (!committed) {\n let currentHead: string\n try { currentHead = await headOid(run, root) }\n catch {\n // A failed inspection cannot prove the rejected commit left HEAD\n // unchanged. Keep its original diagnostic and do not restore.\n if (commitInvoked) throw new PartialCommitError(commits, error, { message: group.message, files: [...group.files] })\n throw error\n }\n if (currentHead !== head) {\n // The rejected command may have completed, or another owner may have\n // advanced HEAD. Preserve both HEAD and index without attributing it.\n if (commitInvoked) throw new PartialCommitError(commits, error, { message: group.message, files: [...group.files] })\n throw error\n }\n const currentIndex = await indexBytes(indexPath)\n const indexUntouched = currentIndex === undefined ? stagedIndex === undefined : currentIndex.equals(stagedIndex ?? Buffer.alloc(0))\n if (currentHead === head && indexUntouched) {\n if (hadIndex) await copyFile(backupPath, indexPath)\n else await rm(indexPath, { force: true })\n }\n }\n // A created commit stays. Only this group's uncommitted index is eligible for restore.\n throw error\n }\n } catch (error) {\n fail(error)\n } finally {\n if (backupDir) {\n try { await rm(backupDir, { recursive: true, force: true }) }\n catch (error) { fail(partialFailure ?? error) }\n }\n }\n }\n return commits\n}\n\n/** One deterministic commit for every selected path; used when the model plan is unavailable. */\nexport function fallbackGroup(files: readonly ChangedFile[], localeHint: 'zh' | 'en'): { message: string; files: readonly string[] } {\n const message = localeHint === 'zh'\n ? `chore: 提交 ${files.length} 个文件的修改`\n : `chore: commit changes to ${files.length} file${files.length === 1 ? '' : 's'}`\n return { message, files: files.map(file => file.path) }\n}\n","import { MAX_MANIFEST_CHARS, MAX_MESSAGE_CHARS } from './contracts.ts'\nimport { statusLetter, type ChangedFile, type UntrackedPreview } from './git.ts'\n\nexport interface PlanGroup {\n readonly message: string\n readonly files: readonly string[]\n}\n\nexport interface PlanInput {\n readonly files: readonly ChangedFile[]\n readonly recentSubjects: readonly string[]\n readonly stat: string\n readonly diff: string\n readonly untracked: readonly UntrackedPreview[]\n}\n\nexport function planSystemPrompt(): string {\n return [\n 'You split a git working-tree change set into a small number of coherent commits.',\n 'Return exactly one JSON object: {\"groups\":[{\"message\":\"<commit message>\",\"files\":[\"<path>\",...]}]}.',\n 'Rules:',\n '- Every listed file must appear in exactly one group; do not invent paths.',\n '- One to five groups. Group files that belong to the same logical change.',\n '- Order groups so earlier commits do not depend on later ones.',\n '- Each message is a single line of at most 72 characters, no trailing period.',\n '- Match the language and style of the recent commit subjects when provided; otherwise use English conventional-commit style.',\n '- Return no Markdown, code fence, or explanation.',\n ].join('\\n')\n}\n\nfunction truncateMiddle(text: string, maxChars: number): string {\n if (text.length <= maxChars) return text\n const half = Math.floor((maxChars - 40) / 2)\n return `${text.slice(0, half)}\\n… [${text.length - maxChars} chars omitted] …\\n${text.slice(-half)}`\n}\n\nexport function buildPlanInput(input: PlanInput): string {\n const sections: string[] = []\n sections.push('Scope: all current workspace changes of the repository.')\n if (input.recentSubjects.length > 0) {\n sections.push(['Recent commit subjects (style reference):', ...input.recentSubjects.map(s => `- ${s}`)].join('\\n'))\n }\n const manifest = input.files.map(file => `- ${statusLetter(file.status)} ${file.origin ? `${file.origin} ${file.status === 'copied' ? '=>' : '->'} ` : ''}${file.path}`).join('\\n')\n sections.push(`Changed files:\\n${manifest}`)\n if (input.stat.trim()) sections.push(`Diff stat:\\n${input.stat.trim()}`)\n if (input.diff.trim()) sections.push(`Diff against HEAD:\\n${input.diff}`)\n for (const untracked of input.untracked) {\n sections.push(untracked.binary\n ? `New binary file: ${untracked.path}`\n : `New file ${untracked.path}:\\n${untracked.preview}`)\n }\n return truncateMiddle(sections.join('\\n\\n'), MAX_MANIFEST_CHARS)\n}\n\nexport function sanitizeMessage(raw: unknown): string | undefined {\n if (typeof raw !== 'string') return undefined\n const line = raw.replace(/\\s+/gu, ' ').trim().replace(/\\.+$/u, '')\n if (!line) return undefined\n return line.length > MAX_MESSAGE_CHARS ? line.slice(0, MAX_MESSAGE_CHARS).trim() : line\n}\n\n/** Extract the first balanced top-level JSON object from model output. */\nexport function extractJsonObject(text: string): string | undefined {\n const fenced = /```(?:json)?\\s*([\\s\\S]*?)```/u.exec(text)\n const candidate = fenced?.[1] ?? text\n const start = candidate.indexOf('{')\n if (start === -1) return undefined\n let depth = 0\n let inString = false\n let escaped = false\n for (let index = start; index < candidate.length; index += 1) {\n const char = candidate[index]\n if (inString) {\n if (escaped) escaped = false\n else if (char === '\\\\') escaped = true\n else if (char === '\"') inString = false\n continue\n }\n if (char === '\"') inString = true\n else if (char === '{') depth += 1\n else if (char === '}') {\n depth -= 1\n if (depth === 0) return candidate.slice(start, index + 1)\n }\n }\n return undefined\n}\n\n/**\n * Validate the model plan against the exact change set. Returns undefined when\n * the output is malformed, covers the wrong files, or duplicates a file.\n */\nexport function parsePlan(text: string, files: readonly ChangedFile[]): PlanGroup[] | undefined {\n const json = extractJsonObject(text)\n if (!json) return undefined\n let parsed: unknown\n try {\n parsed = JSON.parse(json)\n } catch {\n return undefined\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return undefined\n const groups = (parsed as { groups?: unknown }).groups\n if (!Array.isArray(groups) || groups.length === 0 || groups.length > 8) return undefined\n const allowed = new Set(files.map(file => file.path))\n const seen = new Set<string>()\n const plan: PlanGroup[] = []\n for (const group of groups) {\n if (!group || typeof group !== 'object') return undefined\n const message = sanitizeMessage((group as { message?: unknown }).message)\n const paths = (group as { files?: unknown }).files\n if (!message || !Array.isArray(paths) || paths.length === 0) return undefined\n const groupFiles: string[] = []\n for (const path of paths) {\n if (typeof path !== 'string' || !allowed.has(path) || seen.has(path)) return undefined\n seen.add(path)\n groupFiles.push(path)\n }\n plan.push({ message, files: groupFiles })\n }\n if (seen.size !== allowed.size) return undefined\n return plan\n}\n","import { callLlmText, resolveFeatureModel, type LlmTextCaller } from '@klarkxy/dsh-plugin-kit'\nimport { modelRouteOverride } from '@klarkxy/dsh-model-route'\nimport {\n DEFAULT_MAX_OUTPUT_TOKENS, RECENT_LOG_COUNT,\n defaultSettings, normalizeFallback, type CommitGroupResult, type CommitModelInfo, type CommitRunResult,\n type GitCommitSettings, type GitCommitStatus, type PartialCommitResult,\n} from './contracts.ts'\nimport {\n commitGroups, diffAgainstHead, execGit, fallbackGroup, isGitMissing, PartialCommitError, pathVersions, recentSubjects, repoInfo,\n untrackedPreview, workspaceSnapshot, workingTreeChanges, type ChangedFile, type ExecutedCommit, type GitRunner, type UntrackedPreview,\n} from './git.ts'\nimport { buildPlanInput, parsePlan, planSystemPrompt, type PlanGroup } from './plan.ts'\n\nexport interface SessionLike {\n readonly id: string\n readonly header?: { readonly cwd?: string }\n}\n\nexport interface SessionStoreLike {\n get(id: string): SessionLike | undefined\n}\n\nexport interface AgentStoreLike {\n get(id: string): { readonly status?: string } | undefined\n}\n\nexport interface GitCommitServiceDeps {\n readonly plugin: string\n readonly onSettingsChanged?: (revision: number) => void\n readonly llm: LlmTextCaller\n readonly host?: unknown\n readonly sessions: SessionStoreLike\n readonly agents?: AgentStoreLike\n readonly run?: GitRunner\n readonly preview?: (root: string, path: string) => Promise<UntrackedPreview>\n /** Plugin-page settings row; absent keeps the shared purpose route. */\n readonly settings?: {\n load(): Promise<GitCommitSettings>\n save(settings: GitCommitSettings): Promise<void>\n }\n}\n\nexport class CommitRunError extends Error {\n readonly code: string\n /** Commits already created when this run stopped. Absent when nothing was written. */\n readonly partial?: PartialCommitResult\n constructor(code: string, message: string, partial?: PartialCommitResult) {\n super(message)\n this.name = code === 'cancelled' ? 'AbortError' : 'CommitRunError'\n this.code = code\n this.partial = partial\n }\n}\n\nfunction modelInfo(route: { provider: string; model: string } | undefined, source: CommitModelInfo['source']): CommitModelInfo | undefined {\n if (!route?.provider || !route.model) return undefined\n return { provider: route.provider, model: route.model, source }\n}\n\nfunction looksChinese(subjects: readonly string[]): boolean {\n return subjects.some(subject => /[一-鿿]/u.test(subject))\n}\n\nfunction normalizeCwd(cwd: string | undefined): string | undefined {\n if (typeof cwd !== 'string') return undefined\n const normalized = cwd.trim().replaceAll('\\\\', '/')\n if (!normalized) return undefined\n return normalized === '/' || /^[A-Za-z]:\\/$/.test(normalized) ? normalized : normalized.replace(/\\/+$/, '')\n}\n\nexport class GitCommitService {\n private readonly deps: GitCommitServiceDeps\n private readonly run: GitRunner\n private readonly preview: (root: string, path: string) => Promise<UntrackedPreview>\n private running: Promise<unknown> | undefined\n private settings: GitCommitSettings\n private settingsPending: Promise<void> = Promise.resolve()\n private readonly settingsReady: Promise<void>\n private settingsFailure: CommitRunError | undefined\n private settingsAdopted = false\n private disposed = false\n /** Aborted on unload so an in-flight model plan receives the same signal as a cancelled request. */\n private readonly lifetime = new AbortController()\n\n constructor(deps: GitCommitServiceDeps) {\n this.deps = deps\n this.run = deps.run ?? execGit\n this.preview = deps.preview ?? untrackedPreview\n this.settings = defaultSettings()\n // A missing row is resolved by storage; an unreadable row must not select a different model.\n this.settingsReady = deps.settings?.load().then(\n loaded => { if (loaded && !this.settingsAdopted) this.settings = structuredClone(loaded) },\n () => {\n if (!this.settingsAdopted) this.settingsFailure = new CommitRunError(\n 'settings-unavailable', 'dsh-git-commit: saved settings could not be read; reload the plugin before retrying',\n )\n },\n ) ?? Promise.resolve()\n }\n\n /** A refreshed row wins over a pending initial read. */\n adoptSettings(next: GitCommitSettings): void {\n if (this.disposed) throw new CommitRunError('disposed', 'dsh-git-commit: plugin disabled')\n this.settingsAdopted = true\n this.settingsFailure = undefined\n this.settings = structuredClone(next)\n }\n\n /** Existing synchronous snapshot API; host operations wait for initialization first. */\n getSettings(): GitCommitSettings {\n this.workSignal()\n if (this.settingsFailure) throw this.settingsFailure\n return structuredClone(this.settings)\n }\n\n async ready(): Promise<void> {\n this.workSignal()\n await this.settingsReady\n this.workSignal()\n if (this.settingsFailure) throw this.settingsFailure\n }\n\n /** Request cancellation and plugin unload share one signal. A disposed service rejects before any new work. */\n private workSignal(signal?: AbortSignal): AbortSignal {\n if (this.disposed || this.lifetime.signal.aborted) {\n throw new CommitRunError('disposed', 'dsh-git-commit: plugin is no longer active')\n }\n return signal ? AbortSignal.any([signal, this.lifetime.signal]) : this.lifetime.signal\n }\n\n private async waitForSettings(signal?: AbortSignal): Promise<void> {\n signal?.throwIfAborted()\n if (!signal) { await this.ready(); return }\n let onAbort: () => void = () => {}\n const aborted = new Promise<never>((_, reject) => {\n onAbort = () => {\n try { signal.throwIfAborted() }\n catch (error) { reject(error) }\n }\n signal.addEventListener('abort', onAbort, { once: true })\n if (signal.aborted) onAbort()\n })\n try { await Promise.race([this.settingsReady, aborted]) }\n finally { signal.removeEventListener('abort', onAbort) }\n signal.throwIfAborted()\n if (this.settingsFailure) throw this.settingsFailure\n }\n\n private selectedModel(sessionId: string) {\n const page = modelRouteOverride(this.settings.model)\n return { route: resolveFeatureModel(this.deps.host, page, sessionId), source: page ? 'page' as const : 'default' as const }\n }\n\n async updateSettings(patch: Omit<GitCommitSettings, 'revision'>, expectedRevision: number): Promise<GitCommitSettings> {\n const detached = structuredClone(patch)\n const result = this.settingsPending.then(async () => {\n await this.ready()\n if (this.disposed) throw new CommitRunError('disposed', 'dsh-git-commit: plugin disabled')\n if (expectedRevision !== this.settings.revision) {\n throw new CommitRunError('stale', 'dsh-git-commit: settings changed; reload and retry')\n }\n const next: GitCommitSettings = {\n revision: expectedRevision + 1,\n model: detached.model,\n allowFallback: normalizeFallback(detached.allowFallback),\n }\n await this.deps.settings?.save(next)\n this.settings = next\n try { this.deps.onSettingsChanged?.(next.revision) } catch {}\n return structuredClone(next)\n })\n this.settingsPending = result.then(() => {}, () => {})\n return result\n }\n\n start(): void {}\n\n async dispose(): Promise<void> {\n this.disposed = true\n this.lifetime.abort()\n await this.settingsReady\n await this.settingsPending\n await this.running?.catch(() => {})\n }\n\n private async resolveRepo(sessionId: string, signal?: AbortSignal): Promise<{ root: string; branch: string }> {\n const session = this.deps.sessions.get(sessionId)\n if (!session) throw new CommitRunError('no-session', 'dsh-git-commit: session is not live on this host')\n const cwd = normalizeCwd(session.header?.cwd)\n if (!cwd) throw new CommitRunError('no-cwd', 'dsh-git-commit: session has no working directory')\n try {\n return await repoInfo(this.run, cwd, signal)\n } catch (error) {\n signal?.throwIfAborted()\n if (isGitMissing(error)) throw new CommitRunError('no-git', 'dsh-git-commit: git executable not found')\n throw new CommitRunError('not-a-repo', 'dsh-git-commit: session directory is not inside a git repository')\n }\n }\n\n async status(sessionId: string, signal?: AbortSignal): Promise<GitCommitStatus> {\n const work = this.workSignal(signal)\n await this.waitForSettings(work)\n let resolved\n try {\n resolved = await this.resolveRepo(sessionId, work)\n } catch (error) {\n if (error instanceof CommitRunError) {\n return { available: false, reason: error.code, detail: error.message, workspace: { files: 0 } }\n }\n throw error\n }\n const changes = await workingTreeChanges(this.run, resolved.root, work)\n work.throwIfAborted()\n const selected = this.selectedModel(sessionId)\n const model = modelInfo(selected.route, selected.source)\n return {\n available: true,\n root: resolved.root,\n branch: resolved.branch,\n workspace: { files: changes.length },\n ...(model ? { model } : {}),\n }\n }\n\n async commit(sessionId: string, signal?: AbortSignal): Promise<CommitRunResult> {\n if (this.disposed || this.lifetime.signal.aborted) {\n throw new CommitRunError('disposed', 'dsh-git-commit: plugin is no longer active')\n }\n if (this.running) throw new CommitRunError('busy', 'dsh-git-commit: a commit run is already in progress')\n const work = this.workSignal(signal)\n const run = this.runCommit(sessionId, work)\n this.running = run\n try {\n return await run\n } catch (error) {\n if (error instanceof CommitRunError && error.partial) throw error\n if (work.aborted) throw new CommitRunError('cancelled', 'dsh-git-commit: commit run cancelled')\n throw error\n } finally {\n this.running = undefined\n }\n }\n\n private async runCommit(sessionId: string, signal: AbortSignal): Promise<CommitRunResult> {\n await this.waitForSettings(signal)\n if (this.disposed || signal?.aborted) throw new CommitRunError('cancelled', 'dsh-git-commit: plugin is no longer active')\n const session = this.deps.sessions.get(sessionId)\n const sessionCwd = normalizeCwd(session?.header?.cwd)\n const resolved = await this.resolveRepo(sessionId, signal)\n const assertReady = () => {\n signal?.throwIfAborted()\n if (this.disposed || !this.deps.llm) throw new CommitRunError('cancelled', 'dsh-git-commit: plugin is no longer active')\n const currentSession = this.deps.sessions.get(sessionId)\n if (currentSession !== session || normalizeCwd(currentSession?.header?.cwd) !== sessionCwd) {\n throw new CommitRunError('session-changed', 'dsh-git-commit: session workspace changed during planning')\n }\n if (this.deps.agents?.get(sessionId)?.status === 'running') {\n throw new CommitRunError('session-running', 'dsh-git-commit: wait for the session turn to finish')\n }\n }\n assertReady()\n const initial = await workspaceSnapshot(this.run, resolved.root, signal)\n const branchRef = await this.run(['symbolic-ref', '--quiet', 'HEAD'], { cwd: resolved.root, signal }).catch(() => 'DETACHED')\n const selected: ChangedFile[] = initial.files\n if (selected.length === 0) {\n throw new CommitRunError('no-changes', 'dsh-git-commit: working tree is clean')\n }\n const paths = selected.flatMap(file => file.status === 'renamed' && file.origin ? [file.path, file.origin] : [file.path])\n const originalVersions = await pathVersions(this.run, resolved.root, paths, signal)\n const [{ stat, diff }, subjects] = await Promise.all([\n diffAgainstHead(this.run, resolved.root, paths, signal),\n recentSubjects(this.run, resolved.root, RECENT_LOG_COUNT, signal),\n ])\n const untracked: UntrackedPreview[] = []\n for (const file of selected) {\n assertReady()\n if (file.status === 'untracked') untracked.push(await this.preview(resolved.root, file.path))\n }\n\n let groups: PlanGroup[] | undefined\n let planFailure = 'no model route was available'\n let model: CommitModelInfo | undefined\n const planned = this.selectedModel(sessionId)\n if (planned.route) {\n try {\n const result = await callLlmText(this.deps.llm, {\n plugin: this.deps.plugin,\n route: planned.route,\n system: planSystemPrompt(),\n text: buildPlanInput({ files: selected, recentSubjects: subjects, stat, diff, untracked }),\n maxTokens: DEFAULT_MAX_OUTPUT_TOKENS,\n signal,\n sessionId,\n })\n model = modelInfo(result, planned.source)\n groups = parsePlan(result.text, selected)\n if (!groups) planFailure = 'the model returned a plan that does not cover the change set'\n } catch (error) {\n assertReady()\n if (error instanceof CommitRunError) throw error\n planFailure = error instanceof Error ? error.message : String(error)\n }\n }\n\n // Without a plan the run would write commits nobody asked for, so it stops\n // here — before the index or the worktree is touched. A single fallback\n // commit stays available, but only when the settings row asked for it.\n if (!groups && !this.settings.allowFallback) {\n throw new CommitRunError('plan-unavailable', `dsh-git-commit: no commit plan (${planFailure})`)\n }\n\n assertReady()\n const current = await workspaceSnapshot(this.run, resolved.root, signal)\n if (current.fingerprint !== initial.fingerprint) {\n throw new CommitRunError('workspace-changed', 'dsh-git-commit: workspace changed during planning; retry the commit')\n }\n const effective = groups ?? [fallbackGroup(selected, looksChinese(subjects) ? 'zh' : 'en')]\n const describe = (executed: readonly ExecutedCommit[]): CommitGroupResult[] => {\n const commits: CommitGroupResult[] = []\n for (let index = 0; index < executed.length; index += 1) {\n const result = executed[index]\n const group = effective[index]\n if (!result || !group || result.skipped) continue\n commits.push({ hash: result.hash, message: group.message, files: [...group.files] })\n }\n return commits\n }\n let executed: ExecutedCommit[]\n try {\n executed = await commitGroups(this.run, resolved.root, effective, selected, signal, async () => {\n assertReady()\n const currentBranchRef = await this.run(['symbolic-ref', '--quiet', 'HEAD'], { cwd: resolved.root, signal }).catch(() => 'DETACHED')\n if (currentBranchRef !== branchRef) {\n throw new CommitRunError('workspace-changed', 'dsh-git-commit: branch changed during the commit run')\n }\n if (await pathVersions(this.run, resolved.root, paths, signal) !== originalVersions) {\n throw new CommitRunError('workspace-changed', 'dsh-git-commit: selected file changed during the commit run')\n }\n // A new merge conflict must never be passed to git add or git commit.\n await workingTreeChanges(this.run, resolved.root, signal)\n })\n } catch (error) {\n if (!(error instanceof PartialCommitError)) throw error\n const commits = describe(error.commits)\n const cause = error.cause\n const cancelled = signal?.aborted\n || (typeof cause === 'object' && cause !== null && (cause as { code?: unknown }).code === 'cancelled')\n || (cause instanceof Error && cause.name === 'AbortError')\n const code = cause instanceof CommitRunError ? cause.code : cancelled ? 'cancelled' : 'commit-failed'\n const message = cause instanceof Error ? cause.message : String(cause)\n throw new CommitRunError(code, message, {\n branch: resolved.branch,\n commits,\n fallback: groups === undefined,\n failure: { code, message },\n remaining: effective.slice(error.commits.length + (error.uncertain ? 1 : 0)).map(group => ({ message: group.message, files: [...group.files] })),\n ...(error.uncertain ? { uncertain: [error.uncertain] } : {}),\n ...(model ? { model } : {}),\n })\n }\n const commits = describe(executed)\n if (commits.length === 0) throw new CommitRunError('no-changes', 'dsh-git-commit: nothing was committed')\n return {\n branch: resolved.branch,\n commits,\n fallback: groups === undefined,\n ...(model ? { model } : {}),\n }\n }\n}\n","import { defineDomain, domainTable } from '@deepseek-ai/dsh-storage-domain'\nimport { z } from 'zod'\nimport {\n SETTINGS_KEY, defaultSettings, normalizeModelRoute, type GitCommitSettings,\n} from './contracts.ts'\n\nexport { SETTINGS_KEY }\n\nconst modelRouteSchema = z.object({\n provider: z.string().max(250),\n model: z.string().max(250),\n reasoningEffort: z.string().max(80).optional(),\n}).strict()\n\n/** Version 1 stored no settings row, so a missing record fills defaults. */\nexport const settingsSchema = z.object({\n revision: z.number().int().nonnegative(),\n model: modelRouteSchema,\n // Rows written before the flag existed read as the default: reject, do not commit.\n allowFallback: z.boolean().default(false),\n}).strict()\n\nexport const updateSettingsSchema = z.object({\n expectedRevision: z.number().int().nonnegative(),\n settings: z.object({ model: z.unknown(), allowFallback: z.unknown().optional() }).strict(),\n}).strict()\n\nexport const gitCommitDomain = defineDomain({\n name: 'dsh_editor_git_commit',\n version: 1,\n tables: {\n settings: domainTable<string, GitCommitSettings>(settingsSchema),\n },\n})\n\nexport function parseSettings(value: unknown): GitCommitSettings {\n const parsed = settingsSchema.safeParse(value)\n if (!parsed.success) return defaultSettings()\n return {\n revision: parsed.data.revision,\n model: normalizeModelRoute(parsed.data.model),\n allowFallback: parsed.data.allowFallback,\n }\n}\n\nexport type { GitCommitSettings }\n","import type { Context } from '@deepseek-ai/cordis'\nimport type { LlmTextCaller } from '@klarkxy/dsh-plugin-kit'\nimport { registerHostRpc, type HostRpcContext } from '@klarkxy/dsh-plugin-kit/host-rpc'\nimport { registerModelSettings, notifyModelSettingsChanged, type ModelSettingsEvents } from '@klarkxy/dsh-plugin-kit/model-settings'\nimport {\n PLUGIN_NAME, RPC_CHANNEL, SETTINGS_KEY, normalizeFallback, normalizeModelRoute,\n type CommitRunResult, type GitCommitSettings, type GitCommitStatus, type RpcResult,\n} from './contracts.ts'\nimport { CommitRunError, GitCommitService, type AgentStoreLike, type SessionStoreLike } from './service.ts'\nimport { gitCommitDomain, parseSettings, updateSettingsSchema } from './storage.ts'\n\nexport const name = PLUGIN_NAME\nexport const inject = ['llm', 'sessions', 'agents', 'storageDomain', 'connection', 'webServer', 'sessionProjections', 'agentDefaultModel'] as const\nexport { GitCommitService } from './service.ts'\nexport { parsePorcelain } from './git.ts'\nexport { parsePlan, buildPlanInput } from './plan.ts'\nexport { defaultSettings, normalizeFallback, normalizeModelRoute } from './contracts.ts'\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context { gitCommit: GitCommitService }\n}\n\ntype DomainTableHandle = {\n get(key: string): unknown\n put(key: string, value: unknown): Promise<void>\n}\n\ntype DomainHandle = {\n table(name: 'settings'): DomainTableHandle\n close(): Promise<void>\n}\n\ntype Host = Context & HostRpcContext & {\n llm: LlmTextCaller\n sessions: SessionStoreLike\n agents: AgentStoreLike\n storageDomain: { open: (spec: typeof gitCommitDomain) => Promise<DomainHandle> }\n}\n\nfunction stringField(payload: unknown, key: string): string | undefined {\n if (!payload || typeof payload !== 'object') return undefined\n const value = (payload as Record<string, unknown>)[key]\n return typeof value === 'string' && value.trim() ? value : undefined\n}\n\nfunction fail(error: unknown): RpcResult<never> {\n if (error instanceof CommitRunError) {\n return {\n ok: false,\n error: {\n code: error.code,\n message: error.message,\n ...(error.partial ? { partial: error.partial } : {}),\n },\n }\n }\n const message = error instanceof Error ? error.message : String(error)\n return { ok: false, error: { code: 'internal', message } }\n}\n\nexport async function handleRpc(\n service: GitCommitService,\n endpoint: string,\n payload: unknown,\n signal: AbortSignal,\n): Promise<RpcResult> {\n try {\n switch (endpoint) {\n case 'status': {\n const sessionId = stringField(payload, 'sessionId')\n if (!sessionId) return { ok: false, error: { code: 'bad-request', message: 'sessionId is required' } }\n const value: GitCommitStatus = await service.status(sessionId, signal)\n return { ok: true, value }\n }\n case 'settings': {\n await service.ready()\n return { ok: true, value: service.getSettings() }\n }\n case 'settings.update': {\n const parsed = updateSettingsSchema.safeParse(payload)\n if (!parsed.success) return { ok: false, error: { code: 'bad-request', message: 'settings patch is invalid' } }\n const value: GitCommitSettings = await service.updateSettings(\n {\n model: normalizeModelRoute(parsed.data.settings.model),\n allowFallback: normalizeFallback(parsed.data.settings.allowFallback),\n },\n parsed.data.expectedRevision,\n )\n return { ok: true, value }\n }\n case 'commit': {\n const sessionId = stringField(payload, 'sessionId')\n if (!sessionId) return { ok: false, error: { code: 'bad-request', message: 'sessionId is required' } }\n const value: CommitRunResult = await service.commit(sessionId, signal)\n return { ok: true, value }\n }\n default:\n return { ok: false, error: { code: 'not-found', message: `unknown endpoint: ${endpoint}` } }\n }\n } catch (error) {\n return fail(error)\n }\n}\n\nexport function apply(ctx: Context): void {\n const host = ctx as Host\n // Publish immediately; service operations wait for the initial stored row.\n const domainPromise = host.storageDomain.open(gitCommitDomain)\n const tablePromise = domainPromise.then(domain => domain.table('settings'))\n const service = new GitCommitService({\n plugin: PLUGIN_NAME,\n onSettingsChanged: revision => notifyModelSettingsChanged(ctx, PLUGIN_NAME, revision),\n llm: host.llm,\n host,\n sessions: host.sessions,\n agents: host.agents,\n settings: {\n load: async () => parseSettings((await tablePromise).get(SETTINGS_KEY)),\n save: async settings => { await (await tablePromise).put(SETTINGS_KEY, settings) },\n },\n })\n service.start()\n ctx.provide('gitCommit', service)\n ctx.effect(() => async () => {\n await service.dispose()\n await (await domainPromise).close()\n }, 'git-commit.lifecycle')\n ctx.effect(() => registerHostRpc(host, RPC_CHANNEL, (endpoint, payload, signal) => handleRpc(service, endpoint, payload, signal)), 'git-commit.rpc')\n ctx.effect(() => registerModelSettings(ctx as unknown as ModelSettingsEvents, {\n ns: PLUGIN_NAME, title: { zh: 'Git 提交', en: 'Git Commit' },\n async read(signal) {\n await service.ready(); signal.throwIfAborted()\n const settings = service.getSettings()\n return { revision: settings.revision, fields: [{ path: ['model'], label: { zh: '提交模型', en: 'Commit model' }, current: settings.model,\n followLabel: { zh: '当前会话 / 宿主默认模型', en: 'Current conversation / host default' }, allowFollow: true }] }\n },\n async write(path, route, expectedRevision, signal) {\n if (path.length !== 1 || path[0] !== 'model') throw new Error('Unknown Git Commit model setting')\n await service.ready(); signal.throwIfAborted()\n return service.updateSettings({ ...service.getSettings(), model: route }, expectedRevision)\n },\n }), 'git-commit.model-settings')\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/git.ts","../src/plan.ts","../src/service.ts","../src/storage.ts","../src/index.ts"],"sourcesContent":["import { execFile } from 'node:child_process'\nimport { createHash } from 'node:crypto'\nimport { constants } from 'node:fs'\nimport { copyFile, lstat, mkdtemp, open, readFile, readlink, realpath, rm } from 'node:fs/promises'\nimport { tmpdir } from 'node:os'\nimport { isAbsolute, join, relative, resolve } from 'node:path'\nimport { GIT_TIMEOUT_MS, MAX_UNTRACKED_PREVIEW_CHARS } from './contracts.ts'\n\nexport interface GitRunOptions {\n readonly cwd: string\n readonly signal?: AbortSignal\n readonly timeoutMs?: number\n}\n\nexport class GitError extends Error {\n readonly stderr: string\n constructor(message: string, stderr = '') {\n super(message)\n this.name = 'GitError'\n this.stderr = stderr\n }\n}\n\nexport type GitRunner = (args: readonly string[], options: GitRunOptions) => Promise<string>\n\n/** NUL separator used by `git status -z` without embedding a control byte in this source file. */\nconst NUL = String.fromCharCode(0)\n\n/** Spawn git without a shell; arguments are passed literally. */\nexport const execGit: GitRunner = (args, options) => new Promise((resolve, reject) => {\n try {\n execFile('git', [...args], {\n cwd: options.cwd,\n encoding: 'utf8',\n maxBuffer: 32 * 1024 * 1024,\n timeout: options.timeoutMs ?? GIT_TIMEOUT_MS,\n signal: options.signal,\n windowsHide: true,\n env: { ...process.env, GIT_TERMINAL_PROMPT: '0', GIT_LITERAL_PATHSPECS: '1' },\n }, (error, stdout, stderr) => {\n if (error) {\n if (options.signal?.aborted) {\n reject(Object.assign(new Error('dsh-git-commit: git command cancelled'), { code: 'cancelled' }))\n return\n }\n reject(Object.assign(new GitError(stderr.trim() || error.message, stderr), { code: (error as NodeJS.ErrnoException).code }))\n return\n }\n resolve(stdout)\n })\n } catch (error) {\n reject(error)\n }\n})\n\nexport function isGitMissing(error: unknown): boolean {\n return typeof error === 'object' && error !== null && (error as { code?: unknown }).code === 'ENOENT'\n}\n\nexport type ChangeStatus = 'modified' | 'added' | 'deleted' | 'renamed' | 'copied' | 'untracked'\n\nexport interface ChangedFile {\n readonly path: string\n readonly status: ChangeStatus\n /** Rename source in porcelain -z output; committed with the destination. */\n readonly origin?: string\n /** True when the index already stages this path. */\n readonly staged: boolean\n}\n\nexport function statusLetter(kind: ChangeStatus): string {\n switch (kind) {\n case 'added': return 'A'\n case 'deleted': return 'D'\n case 'renamed': return 'R'\n case 'copied': return 'C'\n case 'untracked': return '?'\n default: return 'M'\n }\n}\n\n/**\n * Parse `git status --porcelain=v1 -z --untracked-files=all` output.\n * In -z mode rename/copy entries put the destination path first, then a NUL, then the origin path.\n */\nexport function parsePorcelain(output: string): ChangedFile[] {\n const tokens = output.split(NUL)\n const files: ChangedFile[] = []\n let index = 0\n while (index < tokens.length) {\n const token = tokens[index]\n index += 1\n if (!token) continue\n if (token.length < 4) continue\n const x = token[0] ?? ' '\n const y = token[1] ?? ' '\n const path = token.slice(3)\n if (x === '!' && y === '!') continue\n if (x === '?' && y === '?') {\n files.push({ path, status: 'untracked', staged: false })\n continue\n }\n if (x === 'R' || x === 'C' || y === 'R' || y === 'C') {\n const origin = tokens[index]\n index += 1\n if (!origin) throw new GitError('dsh-git-commit: incomplete rename status')\n files.push({ path, origin, status: x === 'C' || y === 'C' ? 'copied' : 'renamed', staged: x !== ' ' && x !== '?' })\n continue\n }\n if (x === 'U' || y === 'U' || (x === 'A' && y === 'A') || (x === 'D' && y === 'D')) {\n throw new GitError(`dsh-git-commit: resolve merge conflicts before committing (${path})`)\n }\n const status: ChangeStatus = x === 'D' || y === 'D' ? 'deleted' : x === 'A' || y === 'A' ? 'added' : 'modified'\n files.push({ path, status, staged: x !== ' ' && x !== '?' })\n }\n return files\n}\n\nexport interface RepoInfo {\n readonly root: string\n readonly branch: string\n}\n\nexport async function repoInfo(run: GitRunner, cwd: string, signal?: AbortSignal): Promise<RepoInfo> {\n const root = (await run(['rev-parse', '--show-toplevel'], { cwd, signal })).trim()\n let branch = (await run(['symbolic-ref', '--quiet', '--short', 'HEAD'], { cwd: root, signal }).catch(() => '')).trim()\n if (!branch) branch = (await run(['rev-parse', '--short', 'HEAD'], { cwd: root, signal }).catch(() => '')).trim()\n return { root, branch: branch || 'HEAD' }\n}\n\nexport async function workingTreeChanges(run: GitRunner, root: string, signal?: AbortSignal): Promise<ChangedFile[]> {\n const output = await run(['status', '--porcelain=v1', '-z', '--untracked-files=all'], { cwd: root, signal })\n return parsePorcelain(output)\n}\n\n/** Exact index/worktree content fingerprint, including untracked file bytes. */\nexport async function workspaceSnapshot(run: GitRunner, root: string, signal?: AbortSignal): Promise<{ files: ChangedFile[]; fingerprint: string }> {\n const status = await run(['status', '--porcelain=v1', '-z', '--untracked-files=all'], { cwd: root, signal })\n const files = parsePorcelain(status)\n const hash = createHash('sha256').update(status)\n hash.update(await run(['symbolic-ref', '--quiet', 'HEAD'], { cwd: root, signal }).catch(() => 'DETACHED'))\n hash.update(await run(['rev-parse', 'HEAD'], { cwd: root, signal }).catch(() => 'unborn'))\n hash.update(await run(['diff', '--cached', '--binary', '--no-ext-diff'], { cwd: root, signal }))\n hash.update(await run(['diff', '--binary', '--no-ext-diff'], { cwd: root, signal }))\n for (const file of files) {\n if (file.status !== 'untracked') continue\n hash.update(file.path)\n hash.update(await worktreePathDigest(run, root, file.path, signal))\n }\n return { files, fingerprint: hash.digest('hex') }\n}\n\n/** A worktree content check for groups waiting behind earlier commits. */\nexport async function pathVersions(run: GitRunner, root: string, paths: readonly string[], signal?: AbortSignal): Promise<string> {\n const hash = createHash('sha256')\n for (const path of paths) {\n hash.update(path)\n hash.update(await worktreePathDigest(run, root, path, signal))\n }\n return hash.digest('hex')\n}\n\nasync function worktreePathDigest(run: GitRunner, root: string, path: string, signal?: AbortSignal): Promise<string> {\n const absolute = resolve(root, path)\n let stat\n try {\n stat = await lstat(absolute)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return 'missing'\n throw error\n }\n const hash = createHash('sha256').update(String(stat.mode))\n if (stat.isSymbolicLink()) hash.update(await readlink(absolute))\n else if (stat.isFile()) {\n const handle = await open(absolute, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0))\n try {\n if (!(await handle.stat()).isFile() || !(await lstat(absolute)).isFile()) throw new GitError(`dsh-git-commit: file changed while reading (${path})`)\n for await (const chunk of handle.createReadStream({ autoClose: false })) {\n signal?.throwIfAborted()\n hash.update(chunk)\n }\n if (!(await lstat(absolute)).isFile()) throw new GitError(`dsh-git-commit: file changed while reading (${path})`)\n } finally {\n await handle.close()\n }\n } else if (stat.isDirectory()) {\n hash.update(await run(['-C', absolute, 'rev-parse', 'HEAD'], { cwd: root, signal }))\n hash.update(await run(['-C', absolute, 'status', '--porcelain=v1', '-z'], { cwd: root, signal }))\n }\n return hash.digest('hex')\n}\n\nexport async function recentSubjects(run: GitRunner, root: string, count: number, signal?: AbortSignal): Promise<string[]> {\n const output = await run(['log', `-${count}`, '--pretty=%s'], { cwd: root, signal }).catch(() => '')\n return output.split('\\n').map(line => line.trim()).filter(Boolean)\n}\n\n/** Combined staged+worktree stat and diff against HEAD for the given paths. */\nexport async function diffAgainstHead(\n run: GitRunner, root: string, paths: readonly string[], signal?: AbortSignal,\n): Promise<{ stat: string; diff: string }> {\n const args = paths.length > 0 ? ['--', ...paths] : []\n const stat = await run(['diff', 'HEAD', '--stat', '--no-color', ...args], { cwd: root, signal }).catch(() => '')\n const diff = await run(['diff', 'HEAD', '--no-color', '--no-ext-diff', ...args], { cwd: root, signal }).catch(() => '')\n return { stat, diff }\n}\n\nexport interface UntrackedPreview {\n readonly path: string\n readonly preview: string\n readonly binary: boolean\n}\n\nexport async function untrackedPreview(root: string, path: string): Promise<UntrackedPreview> {\n try {\n const absolute = resolve(root, path)\n const rootReal = await realpath(root)\n const withinRoot = async () => {\n const target = await realpath(absolute)\n const rel = relative(rootReal, target)\n return rel !== '' && rel !== '..' && !rel.startsWith(`..${String.fromCharCode(47)}`)\n && !rel.startsWith(`..${String.fromCharCode(92)}`) && !isAbsolute(rel)\n }\n if (!await withinRoot()) return { path, preview: '', binary: true }\n if (!(await lstat(absolute)).isFile()) return { path, preview: '', binary: true }\n const handle = await open(absolute, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0))\n let buffer: Buffer\n try {\n const bounded = Buffer.alloc(MAX_UNTRACKED_PREVIEW_CHARS * 4)\n const { bytesRead } = await handle.read(bounded, 0, bounded.length, 0)\n buffer = bounded.subarray(0, bytesRead)\n } finally {\n await handle.close()\n }\n if (!await withinRoot() || !(await lstat(absolute)).isFile()) return { path, preview: '', binary: true }\n if (buffer.includes(0)) return { path, preview: '', binary: true }\n const text = buffer.toString('utf8')\n return { path, preview: text.slice(0, MAX_UNTRACKED_PREVIEW_CHARS), binary: false }\n } catch {\n return { path, preview: '', binary: true }\n }\n}\n\nexport interface ExecutedCommit {\n readonly hash: string\n readonly skipped: boolean\n}\n\n/** Known commits or an uncertain current group must survive a rejected run. */\nexport class PartialCommitError extends Error {\n readonly commits: readonly ExecutedCommit[]\n readonly cause: unknown\n readonly uncertain?: { readonly message: string; readonly files: readonly string[] }\n constructor(commits: readonly ExecutedCommit[], cause: unknown, uncertain?: { readonly message: string; readonly files: readonly string[] }) {\n super(cause instanceof Error ? cause.message : String(cause))\n this.name = 'PartialCommitError'\n this.commits = commits\n this.cause = cause\n this.uncertain = uncertain\n }\n}\n\nasync function indexBytes(path: string): Promise<Buffer | undefined> {\n try { return await readFile(path) }\n catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return undefined\n throw error\n }\n}\n\nasync function headOid(run: GitRunner, root: string): Promise<string> {\n try { return (await run(['rev-parse', '--verify', 'HEAD'], { cwd: root })).trim() }\n catch (error) {\n if (error instanceof GitError && /Needed a single revision|not a valid object name HEAD/u.test(error.stderr)) return ''\n throw error\n }\n}\n\n/**\n * Commit each group from the worktree. `--only` keeps other staged paths out of\n * this commit; an exact index backup protects the current group on failure.\n */\nexport async function commitGroups(\n run: GitRunner,\n root: string,\n groups: ReadonlyArray<{ message: string; files: readonly string[] }>,\n selected: readonly ChangedFile[],\n signal?: AbortSignal,\n verify?: (paths: readonly string[]) => Promise<void>,\n): Promise<ExecutedCommit[]> {\n const commits: ExecutedCommit[] = []\n let partialFailure: PartialCommitError | undefined\n const fail = (error: unknown): never => {\n if (error instanceof PartialCommitError) { partialFailure = error; throw error }\n if (commits.length === 0) throw error\n partialFailure = new PartialCommitError(commits, error)\n throw partialFailure\n }\n for (const group of groups) {\n if (group.files.length === 0) continue\n const paths = group.files.flatMap(path => {\n const file = selected.find(file => file.path === path)\n return file?.status === 'renamed' && file.origin ? [path, file.origin] : [path]\n })\n let backupDir: string | undefined\n try {\n signal?.throwIfAborted()\n await verify?.(paths)\n const gitPath = (await run(['rev-parse', '--git-path', 'index'], { cwd: root, signal })).trim()\n const indexPath = isAbsolute(gitPath) ? gitPath : resolve(root, gitPath)\n backupDir = await mkdtemp(join(tmpdir(), 'dsh-git-commit-'))\n const backupPath = join(backupDir, 'index')\n let hadIndex = true\n try {\n await copyFile(indexPath, backupPath)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error\n hadIndex = false\n }\n const head = await headOid(run, root)\n const originalIndex = await indexBytes(indexPath)\n if (hadIndex ? !originalIndex?.equals(await readFile(backupPath)) : originalIndex !== undefined) {\n throw new GitError('dsh-git-commit: index changed before committing; retry')\n }\n let stagedIndex = originalIndex\n let committed = false\n let commitInvoked = false\n try {\n signal?.throwIfAborted()\n await run(['add', '-A', '--', ...group.files], { cwd: root, signal })\n stagedIndex = await indexBytes(indexPath)\n signal?.throwIfAborted()\n commitInvoked = true\n await run(['commit', '--quiet', '--only', '-m', group.message, '--', ...paths], { cwd: root, signal })\n committed = true\n let hash = ''\n try {\n // Result collection and index cleanup must survive request cancellation/unload.\n hash = (await run(['rev-parse', '--short', 'HEAD'], { cwd: root })).trim()\n } catch (error) {\n // The commit object exists. A failed hash read must not look like \"nothing was committed\".\n commits.push({ hash: '', skipped: false })\n throw error\n }\n if (!hash) {\n commits.push({ hash: '', skipped: false })\n throw new GitError('dsh-git-commit: commit was created but its hash could not be read')\n }\n commits.push({ hash, skipped: false })\n } catch (error) {\n if (!committed) {\n let currentHead: string\n try { currentHead = await headOid(run, root) }\n catch {\n // A failed inspection cannot prove the rejected commit left HEAD\n // unchanged. Keep its original diagnostic and do not restore.\n if (commitInvoked) throw new PartialCommitError(commits, error, { message: group.message, files: [...group.files] })\n throw error\n }\n if (currentHead !== head) {\n // The rejected command may have completed, or another owner may have\n // advanced HEAD. Preserve both HEAD and index without attributing it.\n if (commitInvoked) throw new PartialCommitError(commits, error, { message: group.message, files: [...group.files] })\n throw error\n }\n const currentIndex = await indexBytes(indexPath)\n const indexUntouched = currentIndex === undefined ? stagedIndex === undefined : currentIndex.equals(stagedIndex ?? Buffer.alloc(0))\n if (currentHead === head && indexUntouched) {\n if (hadIndex) await copyFile(backupPath, indexPath)\n else await rm(indexPath, { force: true })\n }\n }\n // A created commit stays. Only this group's uncommitted index is eligible for restore.\n throw error\n }\n } catch (error) {\n fail(error)\n } finally {\n if (backupDir) {\n try { await rm(backupDir, { recursive: true, force: true }) }\n catch (error) { fail(partialFailure ?? error) }\n }\n }\n }\n return commits\n}\n\n/** One deterministic commit for every selected path; used when the model plan is unavailable. */\nexport function fallbackGroup(files: readonly ChangedFile[], localeHint: 'zh' | 'en'): { message: string; files: readonly string[] } {\n const message = localeHint === 'zh'\n ? `chore: 提交 ${files.length} 个文件的修改`\n : `chore: commit changes to ${files.length} file${files.length === 1 ? '' : 's'}`\n return { message, files: files.map(file => file.path) }\n}\n","import { MAX_MANIFEST_CHARS, MAX_MESSAGE_CHARS } from './contracts.ts'\nimport { statusLetter, type ChangedFile, type UntrackedPreview } from './git.ts'\n\nexport interface PlanGroup {\n readonly message: string\n readonly files: readonly string[]\n}\n\nexport interface PlanInput {\n readonly files: readonly ChangedFile[]\n readonly recentSubjects: readonly string[]\n readonly stat: string\n readonly diff: string\n readonly untracked: readonly UntrackedPreview[]\n}\n\nexport function planSystemPrompt(): string {\n return [\n 'You split a git working-tree change set into a small number of coherent commits.',\n 'Return exactly one JSON object: {\"groups\":[{\"message\":\"<commit message>\",\"files\":[\"<path>\",...]}]}.',\n 'Rules:',\n '- Every listed file must appear in exactly one group; do not invent paths.',\n '- One to five groups. Group files that belong to the same logical change.',\n '- Order groups so earlier commits do not depend on later ones.',\n '- Each message is a single line of at most 72 characters, no trailing period.',\n '- Match the language and style of the recent commit subjects when provided; otherwise use English conventional-commit style.',\n '- Return no Markdown, code fence, or explanation.',\n ].join('\\n')\n}\n\nfunction truncateMiddle(text: string, maxChars: number): string {\n if (text.length <= maxChars) return text\n const half = Math.floor((maxChars - 40) / 2)\n return `${text.slice(0, half)}\\n… [${text.length - maxChars} chars omitted] …\\n${text.slice(-half)}`\n}\n\nexport function buildPlanInput(input: PlanInput): string {\n const sections: string[] = []\n sections.push('Scope: all current workspace changes of the repository.')\n if (input.recentSubjects.length > 0) {\n sections.push(['Recent commit subjects (style reference):', ...input.recentSubjects.map(s => `- ${s}`)].join('\\n'))\n }\n const manifest = input.files.map(file => `- ${statusLetter(file.status)} ${file.origin ? `${file.origin} ${file.status === 'copied' ? '=>' : '->'} ` : ''}${file.path}`).join('\\n')\n sections.push(`Changed files:\\n${manifest}`)\n if (input.stat.trim()) sections.push(`Diff stat:\\n${input.stat.trim()}`)\n if (input.diff.trim()) sections.push(`Diff against HEAD:\\n${input.diff}`)\n for (const untracked of input.untracked) {\n sections.push(untracked.binary\n ? `New binary file: ${untracked.path}`\n : `New file ${untracked.path}:\\n${untracked.preview}`)\n }\n return truncateMiddle(sections.join('\\n\\n'), MAX_MANIFEST_CHARS)\n}\n\nexport function sanitizeMessage(raw: unknown): string | undefined {\n if (typeof raw !== 'string') return undefined\n const line = raw.replace(/\\s+/gu, ' ').trim().replace(/\\.+$/u, '')\n if (!line) return undefined\n return line.length > MAX_MESSAGE_CHARS ? line.slice(0, MAX_MESSAGE_CHARS).trim() : line\n}\n\n/** Extract the first balanced top-level JSON object from model output. */\nexport function extractJsonObject(text: string): string | undefined {\n const fenced = /```(?:json)?\\s*([\\s\\S]*?)```/u.exec(text)\n const candidate = fenced?.[1] ?? text\n const start = candidate.indexOf('{')\n if (start === -1) return undefined\n let depth = 0\n let inString = false\n let escaped = false\n for (let index = start; index < candidate.length; index += 1) {\n const char = candidate[index]\n if (inString) {\n if (escaped) escaped = false\n else if (char === '\\\\') escaped = true\n else if (char === '\"') inString = false\n continue\n }\n if (char === '\"') inString = true\n else if (char === '{') depth += 1\n else if (char === '}') {\n depth -= 1\n if (depth === 0) return candidate.slice(start, index + 1)\n }\n }\n return undefined\n}\n\n/**\n * Validate the model plan against the exact change set. Returns undefined when\n * the output is malformed, covers the wrong files, or duplicates a file.\n */\nexport function parsePlan(text: string, files: readonly ChangedFile[]): PlanGroup[] | undefined {\n const json = extractJsonObject(text)\n if (!json) return undefined\n let parsed: unknown\n try {\n parsed = JSON.parse(json)\n } catch {\n return undefined\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return undefined\n const groups = (parsed as { groups?: unknown }).groups\n if (!Array.isArray(groups) || groups.length === 0 || groups.length > 8) return undefined\n const allowed = new Set(files.map(file => file.path))\n const seen = new Set<string>()\n const plan: PlanGroup[] = []\n for (const group of groups) {\n if (!group || typeof group !== 'object') return undefined\n const message = sanitizeMessage((group as { message?: unknown }).message)\n const paths = (group as { files?: unknown }).files\n if (!message || !Array.isArray(paths) || paths.length === 0) return undefined\n const groupFiles: string[] = []\n for (const path of paths) {\n if (typeof path !== 'string' || !allowed.has(path) || seen.has(path)) return undefined\n seen.add(path)\n groupFiles.push(path)\n }\n plan.push({ message, files: groupFiles })\n }\n if (seen.size !== allowed.size) return undefined\n return plan\n}\n","import { callLlmText, resolveFeatureModel, type LlmTextCaller } from '@klarkxy/dsh-plugin-kit'\nimport { modelRouteOverride } from '@klarkxy/dsh-model-route'\nimport {\n DEFAULT_MAX_OUTPUT_TOKENS, RECENT_LOG_COUNT,\n defaultSettings, normalizeFallback, type CommitGroupResult, type CommitModelInfo, type CommitRunResult,\n type GitCommitSettings, type GitCommitStatus, type PartialCommitResult,\n} from './contracts.ts'\nimport {\n commitGroups, diffAgainstHead, execGit, fallbackGroup, isGitMissing, PartialCommitError, pathVersions, recentSubjects, repoInfo,\n untrackedPreview, workspaceSnapshot, workingTreeChanges, type ChangedFile, type ExecutedCommit, type GitRunner, type UntrackedPreview,\n} from './git.ts'\nimport { buildPlanInput, parsePlan, planSystemPrompt, type PlanGroup } from './plan.ts'\n\nexport interface SessionLike {\n readonly id: string\n readonly header?: { readonly cwd?: string }\n}\n\nexport interface SessionStoreLike {\n get(id: string): SessionLike | undefined\n}\n\nexport interface AgentStoreLike {\n get(id: string): { readonly status?: string } | undefined\n}\n\nexport interface GitCommitServiceDeps {\n readonly plugin: string\n readonly onSettingsChanged?: (revision: number) => void\n readonly llm: LlmTextCaller\n readonly host?: unknown\n readonly sessions: SessionStoreLike\n readonly workingDirectory: { get(session: SessionLike): string }\n readonly agents?: AgentStoreLike\n readonly run?: GitRunner\n readonly preview?: (root: string, path: string) => Promise<UntrackedPreview>\n /** Plugin-page settings row; absent keeps the shared purpose route. */\n readonly settings?: {\n load(): Promise<GitCommitSettings>\n save(settings: GitCommitSettings): Promise<void>\n }\n}\n\nexport class CommitRunError extends Error {\n readonly code: string\n /** Commits already created when this run stopped. Absent when nothing was written. */\n readonly partial?: PartialCommitResult\n constructor(code: string, message: string, partial?: PartialCommitResult) {\n super(message)\n this.name = code === 'cancelled' ? 'AbortError' : 'CommitRunError'\n this.code = code\n this.partial = partial\n }\n}\n\nfunction modelInfo(route: { provider: string; model: string } | undefined, source: CommitModelInfo['source']): CommitModelInfo | undefined {\n if (!route?.provider || !route.model) return undefined\n return { provider: route.provider, model: route.model, source }\n}\n\nfunction looksChinese(subjects: readonly string[]): boolean {\n return subjects.some(subject => /[一-鿿]/u.test(subject))\n}\n\nfunction normalizeCwd(cwd: string | undefined): string | undefined {\n if (typeof cwd !== 'string') return undefined\n const normalized = cwd.trim().replaceAll('\\\\', '/')\n if (!normalized) return undefined\n return normalized === '/' || /^[A-Za-z]:\\/$/.test(normalized) ? normalized : normalized.replace(/\\/+$/, '')\n}\n\nexport class GitCommitService {\n private readonly deps: GitCommitServiceDeps\n private readonly run: GitRunner\n private readonly preview: (root: string, path: string) => Promise<UntrackedPreview>\n private running: Promise<unknown> | undefined\n private settings: GitCommitSettings\n private settingsPending: Promise<void> = Promise.resolve()\n private readonly settingsReady: Promise<void>\n private settingsFailure: CommitRunError | undefined\n private settingsAdopted = false\n private disposed = false\n /** Aborted on unload so an in-flight model plan receives the same signal as a cancelled request. */\n private readonly lifetime = new AbortController()\n\n constructor(deps: GitCommitServiceDeps) {\n this.deps = deps\n this.run = deps.run ?? execGit\n this.preview = deps.preview ?? untrackedPreview\n this.settings = defaultSettings()\n // A missing row is resolved by storage; an unreadable row must not select a different model.\n this.settingsReady = deps.settings?.load().then(\n loaded => { if (loaded && !this.settingsAdopted) this.settings = structuredClone(loaded) },\n () => {\n if (!this.settingsAdopted) this.settingsFailure = new CommitRunError(\n 'settings-unavailable', 'dsh-git-commit: saved settings could not be read; reload the plugin before retrying',\n )\n },\n ) ?? Promise.resolve()\n }\n\n /** A refreshed row wins over a pending initial read. */\n adoptSettings(next: GitCommitSettings): void {\n if (this.disposed) throw new CommitRunError('disposed', 'dsh-git-commit: plugin disabled')\n this.settingsAdopted = true\n this.settingsFailure = undefined\n this.settings = structuredClone(next)\n }\n\n /** Existing synchronous snapshot API; host operations wait for initialization first. */\n getSettings(): GitCommitSettings {\n this.workSignal()\n if (this.settingsFailure) throw this.settingsFailure\n return structuredClone(this.settings)\n }\n\n async ready(): Promise<void> {\n this.workSignal()\n await this.settingsReady\n this.workSignal()\n if (this.settingsFailure) throw this.settingsFailure\n }\n\n /** Request cancellation and plugin unload share one signal. A disposed service rejects before any new work. */\n private workSignal(signal?: AbortSignal): AbortSignal {\n if (this.disposed || this.lifetime.signal.aborted) {\n throw new CommitRunError('disposed', 'dsh-git-commit: plugin is no longer active')\n }\n return signal ? AbortSignal.any([signal, this.lifetime.signal]) : this.lifetime.signal\n }\n\n private async waitForSettings(signal?: AbortSignal): Promise<void> {\n signal?.throwIfAborted()\n if (!signal) { await this.ready(); return }\n let onAbort: () => void = () => {}\n const aborted = new Promise<never>((_, reject) => {\n onAbort = () => {\n try { signal.throwIfAborted() }\n catch (error) { reject(error) }\n }\n signal.addEventListener('abort', onAbort, { once: true })\n if (signal.aborted) onAbort()\n })\n try { await Promise.race([this.settingsReady, aborted]) }\n finally { signal.removeEventListener('abort', onAbort) }\n signal.throwIfAborted()\n if (this.settingsFailure) throw this.settingsFailure\n }\n\n private selectedModel(sessionId: string) {\n const page = modelRouteOverride(this.settings.model)\n return { route: resolveFeatureModel(this.deps.host, page, sessionId), source: page ? 'page' as const : 'default' as const }\n }\n\n async updateSettings(patch: Omit<GitCommitSettings, 'revision'>, expectedRevision: number): Promise<GitCommitSettings> {\n const detached = structuredClone(patch)\n const result = this.settingsPending.then(async () => {\n await this.ready()\n if (this.disposed) throw new CommitRunError('disposed', 'dsh-git-commit: plugin disabled')\n if (expectedRevision !== this.settings.revision) {\n throw new CommitRunError('stale', 'dsh-git-commit: settings changed; reload and retry')\n }\n const next: GitCommitSettings = {\n revision: expectedRevision + 1,\n model: detached.model,\n allowFallback: normalizeFallback(detached.allowFallback),\n }\n await this.deps.settings?.save(next)\n this.settings = next\n try { this.deps.onSettingsChanged?.(next.revision) } catch {}\n return structuredClone(next)\n })\n this.settingsPending = result.then(() => {}, () => {})\n return result\n }\n\n start(): void {}\n\n async dispose(): Promise<void> {\n this.disposed = true\n this.lifetime.abort()\n await this.settingsReady\n await this.settingsPending\n await this.running?.catch(() => {})\n }\n\n private async resolveRepo(sessionId: string, signal?: AbortSignal): Promise<{ root: string; branch: string }> {\n const session = this.deps.sessions.get(sessionId)\n if (!session) throw new CommitRunError('no-session', 'dsh-git-commit: session is not live on this host')\n const cwd = normalizeCwd(this.deps.workingDirectory.get(session))\n if (!cwd) throw new CommitRunError('no-cwd', 'dsh-git-commit: session has no working directory')\n try {\n return await repoInfo(this.run, cwd, signal)\n } catch (error) {\n signal?.throwIfAborted()\n if (isGitMissing(error)) throw new CommitRunError('no-git', 'dsh-git-commit: git executable not found')\n throw new CommitRunError('not-a-repo', 'dsh-git-commit: session directory is not inside a git repository')\n }\n }\n\n async status(sessionId: string, signal?: AbortSignal): Promise<GitCommitStatus> {\n const work = this.workSignal(signal)\n await this.waitForSettings(work)\n let resolved\n try {\n resolved = await this.resolveRepo(sessionId, work)\n } catch (error) {\n if (error instanceof CommitRunError) {\n return { available: false, reason: error.code, detail: error.message, workspace: { files: 0 } }\n }\n throw error\n }\n const changes = await workingTreeChanges(this.run, resolved.root, work)\n work.throwIfAborted()\n const selected = this.selectedModel(sessionId)\n const model = modelInfo(selected.route, selected.source)\n return {\n available: true,\n root: resolved.root,\n branch: resolved.branch,\n workspace: { files: changes.length },\n ...(model ? { model } : {}),\n }\n }\n\n async commit(sessionId: string, signal?: AbortSignal): Promise<CommitRunResult> {\n if (this.disposed || this.lifetime.signal.aborted) {\n throw new CommitRunError('disposed', 'dsh-git-commit: plugin is no longer active')\n }\n if (this.running) throw new CommitRunError('busy', 'dsh-git-commit: a commit run is already in progress')\n const work = this.workSignal(signal)\n const run = this.runCommit(sessionId, work)\n this.running = run\n try {\n return await run\n } catch (error) {\n if (error instanceof CommitRunError && error.partial) throw error\n if (work.aborted) throw new CommitRunError('cancelled', 'dsh-git-commit: commit run cancelled')\n throw error\n } finally {\n this.running = undefined\n }\n }\n\n private async runCommit(sessionId: string, signal: AbortSignal): Promise<CommitRunResult> {\n await this.waitForSettings(signal)\n if (this.disposed || signal?.aborted) throw new CommitRunError('cancelled', 'dsh-git-commit: plugin is no longer active')\n const session = this.deps.sessions.get(sessionId)\n const sessionCwd = session ? normalizeCwd(this.deps.workingDirectory.get(session)) : undefined\n const resolved = await this.resolveRepo(sessionId, signal)\n const assertReady = () => {\n signal?.throwIfAborted()\n if (this.disposed || !this.deps.llm) throw new CommitRunError('cancelled', 'dsh-git-commit: plugin is no longer active')\n const currentSession = this.deps.sessions.get(sessionId)\n if (currentSession !== session || (currentSession ? normalizeCwd(this.deps.workingDirectory.get(currentSession)) : undefined) !== sessionCwd) {\n throw new CommitRunError('session-changed', 'dsh-git-commit: session workspace changed during planning')\n }\n if (this.deps.agents?.get(sessionId)?.status === 'running') {\n throw new CommitRunError('session-running', 'dsh-git-commit: wait for the session turn to finish')\n }\n }\n assertReady()\n const initial = await workspaceSnapshot(this.run, resolved.root, signal)\n const branchRef = await this.run(['symbolic-ref', '--quiet', 'HEAD'], { cwd: resolved.root, signal }).catch(() => 'DETACHED')\n const selected: ChangedFile[] = initial.files\n if (selected.length === 0) {\n throw new CommitRunError('no-changes', 'dsh-git-commit: working tree is clean')\n }\n const paths = selected.flatMap(file => file.status === 'renamed' && file.origin ? [file.path, file.origin] : [file.path])\n const originalVersions = await pathVersions(this.run, resolved.root, paths, signal)\n const [{ stat, diff }, subjects] = await Promise.all([\n diffAgainstHead(this.run, resolved.root, paths, signal),\n recentSubjects(this.run, resolved.root, RECENT_LOG_COUNT, signal),\n ])\n const untracked: UntrackedPreview[] = []\n for (const file of selected) {\n assertReady()\n if (file.status === 'untracked') untracked.push(await this.preview(resolved.root, file.path))\n }\n\n let groups: PlanGroup[] | undefined\n let planFailure = 'no model route was available'\n let model: CommitModelInfo | undefined\n const planned = this.selectedModel(sessionId)\n if (planned.route) {\n try {\n const result = await callLlmText(this.deps.llm, {\n plugin: this.deps.plugin,\n route: planned.route,\n system: planSystemPrompt(),\n text: buildPlanInput({ files: selected, recentSubjects: subjects, stat, diff, untracked }),\n maxTokens: DEFAULT_MAX_OUTPUT_TOKENS,\n signal,\n sessionId,\n })\n model = modelInfo(result, planned.source)\n groups = parsePlan(result.text, selected)\n if (!groups) planFailure = 'the model returned a plan that does not cover the change set'\n } catch (error) {\n assertReady()\n if (error instanceof CommitRunError) throw error\n planFailure = error instanceof Error ? error.message : String(error)\n }\n }\n\n // Without a plan the run would write commits nobody asked for, so it stops\n // here — before the index or the worktree is touched. A single fallback\n // commit stays available, but only when the settings row asked for it.\n if (!groups && !this.settings.allowFallback) {\n throw new CommitRunError('plan-unavailable', `dsh-git-commit: no commit plan (${planFailure})`)\n }\n\n assertReady()\n const current = await workspaceSnapshot(this.run, resolved.root, signal)\n if (current.fingerprint !== initial.fingerprint) {\n throw new CommitRunError('workspace-changed', 'dsh-git-commit: workspace changed during planning; retry the commit')\n }\n const effective = groups ?? [fallbackGroup(selected, looksChinese(subjects) ? 'zh' : 'en')]\n const describe = (executed: readonly ExecutedCommit[]): CommitGroupResult[] => {\n const commits: CommitGroupResult[] = []\n for (let index = 0; index < executed.length; index += 1) {\n const result = executed[index]\n const group = effective[index]\n if (!result || !group || result.skipped) continue\n commits.push({ hash: result.hash, message: group.message, files: [...group.files] })\n }\n return commits\n }\n let executed: ExecutedCommit[]\n try {\n const commitRun: GitRunner = (args, options) => {\n // Async index preparation can yield after verification. Recheck the\n // session immediately before either Git mutation is dispatched.\n if (args[0] === 'add' || args[0] === 'commit') assertReady()\n return this.run(args, options)\n }\n executed = await commitGroups(commitRun, resolved.root, effective, selected, signal, async () => {\n assertReady()\n const currentBranchRef = await this.run(['symbolic-ref', '--quiet', 'HEAD'], { cwd: resolved.root, signal }).catch(() => 'DETACHED')\n if (currentBranchRef !== branchRef) {\n throw new CommitRunError('workspace-changed', 'dsh-git-commit: branch changed during the commit run')\n }\n if (await pathVersions(this.run, resolved.root, paths, signal) !== originalVersions) {\n throw new CommitRunError('workspace-changed', 'dsh-git-commit: selected file changed during the commit run')\n }\n // A new merge conflict must never be passed to git add or git commit.\n await workingTreeChanges(this.run, resolved.root, signal)\n assertReady()\n })\n } catch (error) {\n if (!(error instanceof PartialCommitError)) throw error\n const commits = describe(error.commits)\n const cause = error.cause\n const cancelled = signal?.aborted\n || (typeof cause === 'object' && cause !== null && (cause as { code?: unknown }).code === 'cancelled')\n || (cause instanceof Error && cause.name === 'AbortError')\n const code = cause instanceof CommitRunError ? cause.code : cancelled ? 'cancelled' : 'commit-failed'\n const message = cause instanceof Error ? cause.message : String(cause)\n throw new CommitRunError(code, message, {\n branch: resolved.branch,\n commits,\n fallback: groups === undefined,\n failure: { code, message },\n remaining: effective.slice(error.commits.length + (error.uncertain ? 1 : 0)).map(group => ({ message: group.message, files: [...group.files] })),\n ...(error.uncertain ? { uncertain: [error.uncertain] } : {}),\n ...(model ? { model } : {}),\n })\n }\n const commits = describe(executed)\n if (commits.length === 0) throw new CommitRunError('no-changes', 'dsh-git-commit: nothing was committed')\n return {\n branch: resolved.branch,\n commits,\n fallback: groups === undefined,\n ...(model ? { model } : {}),\n }\n }\n}\n","import { defineDomain, domainTable } from '@deepseek-ai/dsh-storage-domain'\nimport { z } from 'zod'\nimport {\n SETTINGS_KEY, defaultSettings, normalizeModelRoute, type GitCommitSettings,\n} from './contracts.ts'\n\nexport { SETTINGS_KEY }\n\nconst modelRouteSchema = z.object({\n provider: z.string().max(250),\n model: z.string().max(250),\n reasoningEffort: z.string().max(80).optional(),\n}).strict()\n\n/** Version 1 stored no settings row, so a missing record fills defaults. */\nexport const settingsSchema = z.object({\n revision: z.number().int().nonnegative(),\n model: modelRouteSchema,\n // Rows written before the flag existed read as the default: reject, do not commit.\n allowFallback: z.boolean().default(false),\n}).strict()\n\nexport const updateSettingsSchema = z.object({\n expectedRevision: z.number().int().nonnegative(),\n settings: z.object({ model: z.unknown(), allowFallback: z.unknown().optional() }).strict(),\n}).strict()\n\nexport const gitCommitDomain = defineDomain({\n name: 'dsh_editor_git_commit',\n version: 1,\n tables: {\n settings: domainTable<string, GitCommitSettings>(settingsSchema),\n },\n})\n\nexport function parseSettings(value: unknown): GitCommitSettings {\n const parsed = settingsSchema.safeParse(value)\n if (!parsed.success) return defaultSettings()\n return {\n revision: parsed.data.revision,\n model: normalizeModelRoute(parsed.data.model),\n allowFallback: parsed.data.allowFallback,\n }\n}\n\nexport type { GitCommitSettings }\n","import type { Context } from '@deepseek-ai/cordis'\nimport type { LlmTextCaller } from '@klarkxy/dsh-plugin-kit'\nimport { registerHostRpc, type HostRpcContext } from '@klarkxy/dsh-plugin-kit/host-rpc'\nimport { modelSettingsChangesIdentity } from '@klarkxy/dsh-plugin-kit/contracts'\nimport { createModelSettingsChanges } from '@klarkxy/dsh-plugin-kit/model-settings-changes'\nimport { registerModelSettings, notifyModelSettingsChanged, type ModelSettingsEvents } from '@klarkxy/dsh-plugin-kit/model-settings'\nimport {\n PLUGIN_NAME, RPC_CHANNEL, SETTINGS_KEY, normalizeFallback, normalizeModelRoute,\n type CommitRunResult, type GitCommitSettings, type GitCommitStatus, type RpcResult,\n} from './contracts.ts'\nimport { CommitRunError, GitCommitService, type AgentStoreLike, type GitCommitServiceDeps, type SessionStoreLike } from './service.ts'\nimport { gitCommitDomain, parseSettings, updateSettingsSchema } from './storage.ts'\n\nexport const name = PLUGIN_NAME\nexport const inject = ['llm', 'sessions', 'workingDirectory', 'agents', 'storageDomain', 'connection', 'webServer', 'sessionProjections', 'agentDefaultModel'] as const\nexport { GitCommitService } from './service.ts'\nexport { parsePorcelain } from './git.ts'\nexport { parsePlan, buildPlanInput } from './plan.ts'\nexport { defaultSettings, normalizeFallback, normalizeModelRoute } from './contracts.ts'\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context { gitCommit: GitCommitService }\n}\n\ntype DomainTableHandle = {\n get(key: string): unknown\n put(key: string, value: unknown): Promise<void>\n}\n\ntype DomainHandle = {\n table(name: 'settings'): DomainTableHandle\n close(): Promise<void>\n}\n\ntype Host = Context & HostRpcContext & {\n llm: LlmTextCaller\n sessions: SessionStoreLike\n workingDirectory: GitCommitServiceDeps['workingDirectory']\n agents: AgentStoreLike\n storageDomain: { open: (spec: typeof gitCommitDomain) => Promise<DomainHandle> }\n}\n\nfunction stringField(payload: unknown, key: string): string | undefined {\n if (!payload || typeof payload !== 'object') return undefined\n const value = (payload as Record<string, unknown>)[key]\n return typeof value === 'string' && value.trim() ? value : undefined\n}\n\nfunction fail(error: unknown): RpcResult<never> {\n if (error instanceof CommitRunError) {\n return {\n ok: false,\n error: {\n code: error.code,\n message: error.message,\n ...(error.partial ? { partial: error.partial } : {}),\n },\n }\n }\n const message = error instanceof Error ? error.message : String(error)\n return { ok: false, error: { code: 'internal', message } }\n}\n\nexport async function handleRpc(\n service: GitCommitService,\n endpoint: string,\n payload: unknown,\n signal: AbortSignal,\n): Promise<RpcResult> {\n try {\n switch (endpoint) {\n case 'status': {\n const sessionId = stringField(payload, 'sessionId')\n if (!sessionId) return { ok: false, error: { code: 'bad-request', message: 'sessionId is required' } }\n const value: GitCommitStatus = await service.status(sessionId, signal)\n return { ok: true, value }\n }\n case 'settings': {\n await service.ready()\n return { ok: true, value: service.getSettings() }\n }\n case 'settings.update': {\n const parsed = updateSettingsSchema.safeParse(payload)\n if (!parsed.success) return { ok: false, error: { code: 'bad-request', message: 'settings patch is invalid' } }\n const value: GitCommitSettings = await service.updateSettings(\n {\n model: normalizeModelRoute(parsed.data.settings.model),\n allowFallback: normalizeFallback(parsed.data.settings.allowFallback),\n },\n parsed.data.expectedRevision,\n )\n return { ok: true, value }\n }\n case 'commit': {\n const sessionId = stringField(payload, 'sessionId')\n if (!sessionId) return { ok: false, error: { code: 'bad-request', message: 'sessionId is required' } }\n const value: CommitRunResult = await service.commit(sessionId, signal)\n return { ok: true, value }\n }\n default:\n return { ok: false, error: { code: 'not-found', message: `unknown endpoint: ${endpoint}` } }\n }\n } catch (error) {\n return fail(error)\n }\n}\n\nexport function apply(ctx: Context): void {\n createModelSettingsChanges(ctx, modelSettingsChangesIdentity(PLUGIN_NAME), PLUGIN_NAME)\n const host = ctx as Host\n // Publish immediately; service operations wait for the initial stored row.\n const domainPromise = host.storageDomain.open(gitCommitDomain)\n const tablePromise = domainPromise.then(domain => domain.table('settings'))\n const service = new GitCommitService({\n plugin: PLUGIN_NAME,\n onSettingsChanged: revision => notifyModelSettingsChanged(ctx, PLUGIN_NAME, revision),\n llm: host.llm,\n host,\n sessions: host.sessions,\n workingDirectory: host.workingDirectory,\n agents: host.agents,\n settings: {\n load: async () => parseSettings((await tablePromise).get(SETTINGS_KEY)),\n save: async settings => { await (await tablePromise).put(SETTINGS_KEY, settings) },\n },\n })\n service.start()\n ctx.provide('gitCommit', service)\n ctx.effect(() => async () => {\n await service.dispose()\n await (await domainPromise).close()\n }, 'git-commit.lifecycle')\n ctx.effect(() => registerHostRpc(host, RPC_CHANNEL, (endpoint, payload, signal) => handleRpc(service, endpoint, payload, signal)), 'git-commit.rpc')\n ctx.effect(() => registerModelSettings(ctx as unknown as ModelSettingsEvents, {\n ns: PLUGIN_NAME, title: { zh: 'Git 提交', en: 'Git Commit' },\n async read(signal) {\n await service.ready(); signal.throwIfAborted()\n const settings = service.getSettings()\n return { revision: settings.revision, fields: [{ path: ['model'], label: { zh: '提交模型', en: 'Commit model' }, current: settings.model,\n followLabel: { zh: '当前会话 / 宿主默认模型', en: 'Current conversation / host default' }, allowFollow: true }] }\n },\n async write(path, route, expectedRevision, signal) {\n if (path.length !== 1 || path[0] !== 'model') throw new Error('Unknown Git Commit model setting')\n await service.ready(); signal.throwIfAborted()\n return service.updateSettings({ ...service.getSettings(), model: route }, expectedRevision)\n },\n }), 'git-commit.model-settings')\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@klarkxy/dsh-git-commit",
3
- "version": "0.2.5",
3
+ "version": "0.3.1",
4
4
  "description": "Git Commit: commit workspace changes from the conversation header, with model-planned commit groups.",
5
5
  "icon": "./icon.svg",
6
6
  "license": "SEE LICENSE IN LICENSE",
7
7
  "type": "module",
8
8
  "engines": {
9
9
  "node": ">=22",
10
- "dsh": ">=0.2.0-rc.2"
10
+ "dsh": ">=0.2.1-rc.1"
11
11
  },
12
12
  "main": "./lib/index.js",
13
13
  "types": "./lib/index.d.ts",
@@ -74,13 +74,15 @@
74
74
  "test": "vitest run --root ../.. --config vitest.editor-plugins.config.ts --maxWorkers=2 plugins/dsh-git-commit/src"
75
75
  },
76
76
  "dependencies": {
77
- "@klarkxy/dsh-model-route": "0.2.4",
78
- "@klarkxy/dsh-plugin-kit": "0.3.4",
77
+ "@klarkxy/dsh-model-route": "0.2.6",
78
+ "@klarkxy/dsh-plugin-kit": "0.5.0",
79
79
  "zod": "^4.1.5"
80
80
  },
81
81
  "peerDependencies": {
82
82
  "@deepseek-ai/cordis": ">=4.0.4",
83
- "@deepseek-ai/dsh-storage-domain": ">=0.2.0-rc.2"
83
+ "@deepseek-ai/dsh-storage-domain": ">=0.2.0-rc.2",
84
+ "@deepseek-ai/dsh-working-directory": ">=0.2.1-rc.1",
85
+ "@deepseek-ai/dsh-typert-protocol": ">=0.2.0-rc.2"
84
86
  },
85
87
  "peerDependenciesMeta": {
86
88
  "@deepseek-ai/cordis": {
@@ -88,19 +90,27 @@
88
90
  },
89
91
  "@deepseek-ai/dsh-storage-domain": {
90
92
  "optional": true
93
+ },
94
+ "@deepseek-ai/dsh-working-directory": {
95
+ "optional": true
96
+ },
97
+ "@deepseek-ai/dsh-typert-protocol": {
98
+ "optional": true
91
99
  }
92
100
  },
93
101
  "devDependencies": {
94
- "@deepseek-ai/cordis": "4.0.4",
95
- "@deepseek-ai/dsh-storage-domain": "0.2.0-rc.2",
96
- "zod": "^4.1.5",
102
+ "@deepseek-ai/cordis": "4.0.5",
103
+ "@deepseek-ai/dsh-storage-domain": "0.2.1-rc.1",
104
+ "zod": "4.4.3",
97
105
  "react": "^18.2.0",
98
106
  "react-dom": "^18.2.0",
99
107
  "@types/react": "18.3.31",
100
108
  "@types/react-dom": "^18.3.0",
101
- "@deepseek-ai/dsh-client-ui-primitives": "0.2.0-rc.2",
109
+ "@deepseek-ai/dsh-client-ui-primitives": "0.2.1-rc.1",
102
110
  "jsdom": "29.1.1",
103
- "@types/jsdom": "28.0.3"
111
+ "@types/jsdom": "28.0.3",
112
+ "@deepseek-ai/dsh-working-directory": "0.2.1-rc.1",
113
+ "@deepseek-ai/dsh-typert-protocol": "0.2.1-rc.1"
104
114
  },
105
115
  "keywords": [
106
116
  "dsh",
@@ -124,6 +134,6 @@
124
134
  "registry": "https://registry.npmjs.org/"
125
135
  },
126
136
  "dshRelease": {
127
- "contentHash": "2ebca43f02172ef3a53e87ffaa0b8ad1f3b91a994bed1601c053874402014703"
137
+ "contentHash": "3f83b7742c2c11ddbc2d03595c4338fb8f5ebd60f427ef911617f192ee34e48e"
128
138
  }
129
139
  }