spec-cat 0.1.61 → 0.1.63
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/.output/nitro.json +1 -1
- package/.output/public/_nuxt/2zamijve.js +1 -0
- package/.output/public/_nuxt/{Bhr6Zo3T.js → BEjIzkrM.js} +54 -54
- package/.output/public/_nuxt/{DVCRp6I2.js → BaSsfm-t.js} +1 -1
- package/.output/public/_nuxt/BjdLSVUw.js +1 -0
- package/.output/public/_nuxt/{qOn4ZFdM.js → Bz2rU2zs.js} +1 -1
- package/.output/public/_nuxt/{8Elu-15_.js → D4LyIv_t.js} +1 -1
- package/.output/public/_nuxt/{C7AMOFY8.js → DIOhMCOf.js} +2 -2
- package/.output/public/_nuxt/{BpYxF7v5.js → DPOGSCeV.js} +1 -1
- package/.output/public/_nuxt/{CbE7c0sD.js → DeqM2TrP.js} +1 -1
- package/.output/public/_nuxt/{C8fQuSPf.js → DwpuOtAP.js} +1 -1
- package/.output/public/_nuxt/{DTRKuZ1Z.js → FfyCVKRU.js} +1 -1
- package/.output/public/_nuxt/{C4M037xP.js → Su-Cl_JF.js} +1 -1
- package/.output/public/_nuxt/builds/latest.json +1 -1
- package/.output/public/_nuxt/builds/meta/74089fa1-2fbb-4792-94aa-7535d2aec557.json +1 -0
- package/.output/public/_nuxt/{DCnFPBGM.js → zrVRZSxq.js} +1 -1
- package/.output/server/chunks/_/asyncLock.mjs +17 -0
- package/.output/server/chunks/_/asyncLock.mjs.map +1 -0
- package/.output/server/chunks/_/chatGit.mjs +22 -0
- package/.output/server/chunks/_/chatGit.mjs.map +1 -0
- package/.output/server/chunks/_/claude.mjs +2 -1
- package/.output/server/chunks/_/claude.mjs.map +1 -1
- package/.output/server/chunks/_/claudeProvider.mjs +2 -1
- package/.output/server/chunks/_/claudeProvider.mjs.map +1 -1
- package/.output/server/chunks/_/codexProvider.mjs +14 -2
- package/.output/server/chunks/_/codexProvider.mjs.map +1 -1
- package/.output/server/chunks/_/jobQueue.mjs +1 -1
- package/.output/server/chunks/_/validateWorktree.mjs +1 -1
- package/.output/server/chunks/_/worktreePaths.mjs +1 -1
- package/.output/server/chunks/build/client.precomputed.mjs +1 -1
- package/.output/server/chunks/build/client.precomputed.mjs.map +1 -1
- package/.output/server/chunks/nitro/nitro.mjs +611 -611
- package/.output/server/chunks/routes/api/chat/compare.get.mjs +5 -0
- package/.output/server/chunks/routes/api/chat/compare.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/chat/finalize.post.mjs +94 -93
- package/.output/server/chunks/routes/api/chat/finalize.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/chat/generate-commit-message.post.mjs +2 -0
- package/.output/server/chunks/routes/api/chat/generate-commit-message.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/chat/preview-sync.post.mjs +28 -22
- package/.output/server/chunks/routes/api/chat/preview-sync.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/chat/preview.delete.mjs +24 -23
- package/.output/server/chunks/routes/api/chat/preview.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/chat/preview.post.mjs +53 -48
- package/.output/server/chunks/routes/api/chat/preview.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/chat/rebase.post.mjs +39 -41
- package/.output/server/chunks/routes/api/chat/rebase.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/chat/worktree-commit.post.mjs +56 -46
- package/.output/server/chunks/routes/api/chat/worktree-commit.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/chat/worktree.delete.mjs +38 -30
- package/.output/server/chunks/routes/api/chat/worktree.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/chat/worktree.post.mjs +73 -65
- package/.output/server/chunks/routes/api/chat/worktree.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/chat.post.mjs +16 -3
- package/.output/server/chunks/routes/api/chat.post.mjs.map +1 -1
- package/.output/server/package.json +1 -1
- package/package.json +1 -1
- package/.output/public/_nuxt/BeBeZcRQ.js +0 -1
- package/.output/public/_nuxt/C_6kiUg6.js +0 -1
- package/.output/public/_nuxt/builds/meta/81746bdb-ce0f-42a7-9dd1-65c11a21de2d.json +0 -1
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { d as defineEventHandler, f as getQuery, c as createError, l as logger } from '../../../nitro/nitro.mjs';
|
|
2
2
|
import { i as isGitRepositorySync } from '../../../_/git.mjs';
|
|
3
3
|
import { e as execGitArgs } from '../../../_/gitExec.mjs';
|
|
4
|
+
import { v as validateWorktreePath } from '../../../_/validateWorktree.mjs';
|
|
5
|
+
import { a as assertSafeBranchName } from '../../../_/chatGit.mjs';
|
|
4
6
|
import 'node:http';
|
|
5
7
|
import 'node:https';
|
|
6
8
|
import 'node:crypto';
|
|
@@ -24,6 +26,7 @@ import 'node:fs/promises';
|
|
|
24
26
|
import 'node:url';
|
|
25
27
|
import 'child_process';
|
|
26
28
|
import 'util';
|
|
29
|
+
import '../../../_/worktreePaths.mjs';
|
|
27
30
|
|
|
28
31
|
const compare_get = defineEventHandler(async (event) => {
|
|
29
32
|
try {
|
|
@@ -36,6 +39,8 @@ const compare_get = defineEventHandler(async (event) => {
|
|
|
36
39
|
statusMessage: "worktreePath and baseBranch are required"
|
|
37
40
|
});
|
|
38
41
|
}
|
|
42
|
+
validateWorktreePath(worktreePath);
|
|
43
|
+
assertSafeBranchName(baseBranch, "base branch");
|
|
39
44
|
if (!isGitRepositorySync(worktreePath)) {
|
|
40
45
|
throw createError({
|
|
41
46
|
statusCode: 400,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compare.get.mjs","sources":["../../../../../../server/api/chat/compare.get.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"compare.get.mjs","sources":["../../../../../../server/api/chat/compare.get.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWA,oBAAA,kBAAA,CAAA,OAAA,KAAA,KAAA;AACA,EAAA,IAAA;AACA,IAAA,MAAA,KAAA,GAAA,SAAA,KAAA,CAAA;AACA,IAAA,MAAA,eAAA,KAAA,CAAA,YAAA;AACA,IAAA,MAAA,aAAA,KAAA,CAAA,UAAA;AAEA,IAAA,IAAA,CAAA,YAAA,IAAA,CAAA,UAAA,EAAA;AACA,MAAA,MAAA,WAAA,CAAA;AAAA,QACA,UAAA,EAAA,GAAA;AAAA,QACA,aAAA,EAAA;AAAA,OACA,CAAA;AAAA,IACA;AAEA,IAAA,oBAAA,CAAA,YAAA,CAAA;AACA,IAAA,oBAAA,CAAA,YAAA,aAAA,CAAA;AAEA,IAAA,IAAA,CAAA,mBAAA,CAAA,YAAA,CAAA,EAAA;AACA,MAAA,MAAA,WAAA,CAAA;AAAA,QACA,UAAA,EAAA,GAAA;AAAA,QACA,aAAA,EAAA;AAAA,OACA,CAAA;AAAA,IACA;AAEA,IAAA,MAAA,MAAA,GAAA,YAAA,YAAA,EAAA;AAAA,MACA,UAAA;AAAA,MACA,cAAA;AAAA,MACA,SAAA;AAAA,MACA,GAAA,UAAA,CAAA,OAAA;AAAA,KACA,CAAA;AAEA,IAAA,MAAA,CAAA,WAAA,QAAA,CAAA,GAAA,OAAA,IAAA,EAAA,CAAA,MAAA,KAAA,CAAA;AACA,IAAA,MAAA,SAAA,MAAA,CAAA,QAAA,CAAA,SAAA,IAAA,GAAA,EAAA,EAAA,CAAA,IAAA,CAAA;AACA,IAAA,MAAA,QAAA,MAAA,CAAA,QAAA,CAAA,QAAA,IAAA,GAAA,EAAA,EAAA,CAAA,IAAA,CAAA;AAEA,IAAA,OAAA,EAAA,OAAA,MAAA,EAAA;AAAA,EACA,SAAA,KAAA,EAAA;AACA,IAAA,IAAA,KAAA,IAAA,OAAA,KAAA,KAAA,QAAA,IAAA,gBAAA,KAAA,EAAA;AACA,MAAA,MAAA,KAAA;AAAA,IACA;AAEA,IAAA,MAAA,CAAA,GAAA,CAAA,KAAA,CAAA,uCAAA,EAAA,EAAA,OAAA,CAAA;AACA,IAAA,MAAA,WAAA,CAAA;AAAA,MACA,UAAA,EAAA,GAAA;AAAA,MACA,aAAA,EAAA;AAAA,KACA,CAAA;AAAA,EACA;AACA,CAAA,CAAA;;;;"}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { d as defineEventHandler, b as readBody, c as createError, e as getProjectDir, l as logger } from '../../../nitro/nitro.mjs';
|
|
2
|
-
import { execSync
|
|
3
|
-
import { promisify } from 'node:util';
|
|
2
|
+
import { execSync } from 'node:child_process';
|
|
4
3
|
import { existsSync } from 'node:fs';
|
|
5
4
|
import { rm } from 'node:fs/promises';
|
|
6
5
|
import { r as resolveExistingBaseBranch } from '../../../_/baseBranch.mjs';
|
|
7
6
|
import { b as guardServerProviderCapability } from '../../../_/aiProviderSelection.mjs';
|
|
8
7
|
import { g as getChatWorktreePath } from '../../../_/worktreePaths.mjs';
|
|
8
|
+
import { v as validateWorktreePath } from '../../../_/validateWorktree.mjs';
|
|
9
|
+
import { a as assertSafeBranchName, l as localBranchRef, g as git } from '../../../_/chatGit.mjs';
|
|
10
|
+
import { a as autoCommitChanges } from '../../../_/claudeService.mjs';
|
|
11
|
+
import { w as withLock } from '../../../_/asyncLock.mjs';
|
|
9
12
|
import 'node:http';
|
|
10
13
|
import 'node:https';
|
|
11
14
|
import 'node:crypto';
|
|
@@ -29,18 +32,21 @@ import '../../../_/gitExec.mjs';
|
|
|
29
32
|
import 'child_process';
|
|
30
33
|
import 'util';
|
|
31
34
|
import '../../../_/aiProviderRegistry.mjs';
|
|
35
|
+
import '../../../_/claude.mjs';
|
|
32
36
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
async function collectConflictFiles(worktreePath) {
|
|
38
|
+
try {
|
|
39
|
+
const diffOutput = await git(worktreePath, ["diff", "--name-only", "--diff-filter=U"]);
|
|
40
|
+
const files = diffOutput.split("\n").filter(Boolean);
|
|
41
|
+
if (files.length > 0) return files;
|
|
42
|
+
} catch {
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const statusOutput = await git(worktreePath, ["status", "--porcelain"]);
|
|
46
|
+
return statusOutput.split("\n").filter((line) => /^(UU|AA|DU|UD|UA|AU|DD)\s/.test(line)).map((line) => line.substring(3).trim());
|
|
47
|
+
} catch {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
44
50
|
}
|
|
45
51
|
const finalize_post = defineEventHandler(async (event) => {
|
|
46
52
|
const body = await readBody(event);
|
|
@@ -59,8 +65,12 @@ const finalize_post = defineEventHandler(async (event) => {
|
|
|
59
65
|
return providerGuard.failure;
|
|
60
66
|
}
|
|
61
67
|
const projectDir = getProjectDir();
|
|
62
|
-
const branchName = body.worktreeBranch || `sc/${conversationId}
|
|
68
|
+
const branchName = assertSafeBranchName(body.worktreeBranch || `sc/${conversationId}`, "branch");
|
|
63
69
|
const worktreePath = body.worktreePath || getChatWorktreePath(conversationId);
|
|
70
|
+
const previewBranch = body.previewBranch ? assertSafeBranchName(body.previewBranch, "preview branch") : void 0;
|
|
71
|
+
if (existsSync(worktreePath)) {
|
|
72
|
+
validateWorktreePath(worktreePath);
|
|
73
|
+
}
|
|
64
74
|
logger.chat.info("Finalizing conversation", { conversationId, branchName });
|
|
65
75
|
const baseBranch = await resolveExistingBaseBranch({
|
|
66
76
|
cwd: projectDir,
|
|
@@ -70,98 +80,89 @@ const finalize_post = defineEventHandler(async (event) => {
|
|
|
70
80
|
if (!baseBranch) {
|
|
71
81
|
return { success: false, error: "Unable to resolve a valid base branch for this worktree." };
|
|
72
82
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
return { success: false, error: "Worktree directory not found. It may have been cleaned up." };
|
|
76
|
-
}
|
|
77
|
-
await autoCommitChanges(worktreePath);
|
|
78
|
-
let commitCount;
|
|
79
|
-
try {
|
|
80
|
-
const countStr = await git(worktreePath, `rev-list --count ${baseBranch}..HEAD`);
|
|
81
|
-
commitCount = parseInt(countStr, 10);
|
|
82
|
-
} catch {
|
|
83
|
-
return { success: false, error: `Cannot compare with base branch "${baseBranch}". It may not exist.` };
|
|
84
|
-
}
|
|
85
|
-
if (commitCount === 0) {
|
|
86
|
-
return { success: false, error: "No commits to finalize." };
|
|
87
|
-
}
|
|
88
|
-
const mergeBase = await git(worktreePath, `merge-base ${baseBranch} HEAD`);
|
|
89
|
-
await git(worktreePath, `reset --soft ${mergeBase}`);
|
|
90
|
-
execSync("git commit -F -", { cwd: worktreePath, input: commitMessage, encoding: "utf-8" });
|
|
83
|
+
const baseBranchRef = localBranchRef(baseBranch, "base branch");
|
|
84
|
+
return withLock(projectDir, async () => {
|
|
91
85
|
try {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
86
|
+
if (!existsSync(worktreePath)) {
|
|
87
|
+
return { success: false, error: "Worktree directory not found. It may have been cleaned up." };
|
|
88
|
+
}
|
|
89
|
+
await autoCommitChanges(worktreePath);
|
|
90
|
+
let commitCount;
|
|
96
91
|
try {
|
|
97
|
-
const
|
|
98
|
-
|
|
92
|
+
const countStr = await git(worktreePath, ["rev-list", "--count", `${baseBranchRef}..HEAD`]);
|
|
93
|
+
commitCount = parseInt(countStr, 10);
|
|
99
94
|
} catch {
|
|
100
|
-
|
|
101
|
-
const statusOutput = await git(worktreePath, "status --porcelain");
|
|
102
|
-
conflictFiles = statusOutput.split("\n").filter((line) => /^(UU|AA|DU|UD|UA|AU|DD)\s/.test(line)).map((line) => line.substring(3).trim());
|
|
103
|
-
} catch {
|
|
104
|
-
}
|
|
95
|
+
return { success: false, error: `Cannot compare with base branch "${baseBranch}". It may not exist.` };
|
|
105
96
|
}
|
|
106
|
-
|
|
107
|
-
success: false,
|
|
108
|
-
error: `Rebase conflict with "${baseBranch}". Resolve conflicts to continue.`,
|
|
109
|
-
conflictFiles,
|
|
110
|
-
rebaseInProgress: true
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
const previewBranch = body.previewBranch;
|
|
114
|
-
try {
|
|
115
|
-
const currentBranch = await git(projectDir, "rev-parse --abbrev-ref HEAD");
|
|
116
|
-
if (currentBranch !== baseBranch) {
|
|
117
|
-
await git(projectDir, `checkout "${baseBranch}"`);
|
|
97
|
+
if (commitCount === 0) {
|
|
98
|
+
return { success: false, error: "No commits to finalize." };
|
|
118
99
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
100
|
+
try {
|
|
101
|
+
await git(worktreePath, ["rebase", baseBranchRef]);
|
|
102
|
+
} catch {
|
|
103
|
+
logger.chat.warn("Rebase conflict during finalize", { conversationId });
|
|
104
|
+
const conflictFiles = await collectConflictFiles(worktreePath);
|
|
105
|
+
return {
|
|
106
|
+
success: false,
|
|
107
|
+
error: `Rebase conflict with "${baseBranch}". Resolve conflicts to continue.`,
|
|
108
|
+
conflictFiles,
|
|
109
|
+
rebaseInProgress: true
|
|
110
|
+
};
|
|
127
111
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
logger.chat.info("Base branch updated", { baseBranch, newHead });
|
|
131
|
-
try {
|
|
132
|
-
await execAsync(`git worktree remove "${worktreePath}" --force`, { cwd: projectDir });
|
|
133
|
-
} catch {
|
|
112
|
+
await git(worktreePath, ["reset", "--soft", baseBranchRef]);
|
|
113
|
+
execSync("git commit -F -", { cwd: worktreePath, input: commitMessage, encoding: "utf-8" });
|
|
134
114
|
try {
|
|
135
|
-
await
|
|
115
|
+
const currentBranch = await git(projectDir, ["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
116
|
+
if (currentBranch !== baseBranch) {
|
|
117
|
+
await git(projectDir, ["switch", baseBranch]);
|
|
118
|
+
}
|
|
136
119
|
} catch {
|
|
137
120
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
121
|
+
const newHead = await git(worktreePath, ["rev-parse", "HEAD"]);
|
|
122
|
+
await git(projectDir, ["update-ref", `refs/heads/${baseBranch}`, newHead]);
|
|
123
|
+
try {
|
|
124
|
+
const mainBranch = await git(projectDir, ["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
125
|
+
if (mainBranch === baseBranch) {
|
|
126
|
+
await git(projectDir, ["reset", "--hard", "HEAD"]);
|
|
127
|
+
}
|
|
128
|
+
} catch {
|
|
129
|
+
}
|
|
130
|
+
logger.chat.info("Base branch updated", { baseBranch, newHead });
|
|
131
|
+
try {
|
|
132
|
+
await git(projectDir, ["worktree", "remove", worktreePath, "--force"]);
|
|
133
|
+
} catch {
|
|
134
|
+
try {
|
|
135
|
+
await rm(worktreePath, { recursive: true, force: true });
|
|
136
|
+
} catch {
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
await git(projectDir, ["worktree", "prune"]).catch(() => {
|
|
140
|
+
});
|
|
147
141
|
try {
|
|
148
|
-
await git(projectDir,
|
|
142
|
+
await git(projectDir, ["branch", "-D", branchName]);
|
|
149
143
|
} catch {
|
|
144
|
+
logger.chat.warn("Failed to delete temp branch", { branchName });
|
|
150
145
|
}
|
|
146
|
+
if (previewBranch) {
|
|
147
|
+
try {
|
|
148
|
+
await git(projectDir, ["branch", "-D", previewBranch]);
|
|
149
|
+
} catch {
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
logger.chat.info("Conversation finalized", { conversationId, newCommit: newHead });
|
|
153
|
+
return {
|
|
154
|
+
success: true,
|
|
155
|
+
newCommit: newHead
|
|
156
|
+
};
|
|
157
|
+
} catch (error) {
|
|
158
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
159
|
+
logger.chat.error("Finalize failed", { conversationId, error: errorMessage });
|
|
160
|
+
return {
|
|
161
|
+
success: false,
|
|
162
|
+
error: errorMessage
|
|
163
|
+
};
|
|
151
164
|
}
|
|
152
|
-
|
|
153
|
-
return {
|
|
154
|
-
success: true,
|
|
155
|
-
newCommit: newHead
|
|
156
|
-
};
|
|
157
|
-
} catch (error) {
|
|
158
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
159
|
-
logger.chat.error("Finalize failed", { conversationId, error: errorMessage });
|
|
160
|
-
return {
|
|
161
|
-
success: false,
|
|
162
|
-
error: errorMessage
|
|
163
|
-
};
|
|
164
|
-
}
|
|
165
|
+
});
|
|
165
166
|
});
|
|
166
167
|
|
|
167
168
|
export { finalize_post as default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"finalize.post.mjs","sources":["../../../../../../server/api/chat/finalize.post.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"finalize.post.mjs","sources":["../../../../../../server/api/chat/finalize.post.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,7 @@ import { s as sendMessage } from '../../../_/claudeService.mjs';
|
|
|
6
6
|
import { b as guardServerProviderCapability } from '../../../_/aiProviderSelection.mjs';
|
|
7
7
|
import { r as resolveExistingBaseBranch } from '../../../_/baseBranch.mjs';
|
|
8
8
|
import { g as getChatWorktreePath } from '../../../_/worktreePaths.mjs';
|
|
9
|
+
import { v as validateWorktreePath } from '../../../_/validateWorktree.mjs';
|
|
9
10
|
import 'node:http';
|
|
10
11
|
import 'node:https';
|
|
11
12
|
import 'node:crypto';
|
|
@@ -53,6 +54,7 @@ const generateCommitMessage_post = defineEventHandler(async (event) => {
|
|
|
53
54
|
if (!existsSync(worktreePath)) {
|
|
54
55
|
throw createError({ statusCode: 404, message: "Worktree not found" });
|
|
55
56
|
}
|
|
57
|
+
validateWorktreePath(worktreePath);
|
|
56
58
|
const providerGuard = await guardServerProviderCapability(
|
|
57
59
|
"autoCommit",
|
|
58
60
|
"Switch to a provider with auto-commit support or disable AI-generated commit messages."
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-commit-message.post.mjs","sources":["../../../../../../server/api/chat/generate-commit-message.post.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generate-commit-message.post.mjs","sources":["../../../../../../server/api/chat/generate-commit-message.post.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { d as defineEventHandler, b as readBody, c as createError, e as getProjectDir, l as logger } from '../../../nitro/nitro.mjs';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { v as validateWorktreePath } from '../../../_/validateWorktree.mjs';
|
|
4
|
+
import { a as assertSafeBranchName, g as git } from '../../../_/chatGit.mjs';
|
|
5
|
+
import { w as withLock } from '../../../_/asyncLock.mjs';
|
|
4
6
|
import 'node:http';
|
|
5
7
|
import 'node:https';
|
|
6
8
|
import 'node:crypto';
|
|
@@ -16,18 +18,16 @@ import 'tls';
|
|
|
16
18
|
import 'url';
|
|
17
19
|
import 'node:events';
|
|
18
20
|
import 'node:buffer';
|
|
19
|
-
import 'node:fs';
|
|
20
21
|
import 'node:path';
|
|
21
22
|
import 'node:os';
|
|
22
23
|
import 'node:module';
|
|
23
24
|
import 'node:fs/promises';
|
|
24
25
|
import 'node:url';
|
|
26
|
+
import '../../../_/worktreePaths.mjs';
|
|
27
|
+
import '../../../_/gitExec.mjs';
|
|
28
|
+
import 'child_process';
|
|
29
|
+
import 'util';
|
|
25
30
|
|
|
26
|
-
const execAsync = promisify(exec);
|
|
27
|
-
async function git(cwd, cmd) {
|
|
28
|
-
const { stdout } = await execAsync(`git ${cmd}`, { cwd });
|
|
29
|
-
return stdout.trim();
|
|
30
|
-
}
|
|
31
31
|
const previewSync_post = defineEventHandler(async (event) => {
|
|
32
32
|
const body = await readBody(event);
|
|
33
33
|
if (!(body == null ? void 0 : body.previewBranch) || !(body == null ? void 0 : body.worktreePath)) {
|
|
@@ -36,22 +36,28 @@ const previewSync_post = defineEventHandler(async (event) => {
|
|
|
36
36
|
message: "previewBranch and worktreePath are required"
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
|
-
const {
|
|
39
|
+
const { worktreePath } = body;
|
|
40
|
+
const previewBranch = assertSafeBranchName(body.previewBranch, "preview branch");
|
|
40
41
|
const projectDir = getProjectDir();
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
await git(projectDir, `update-ref refs/heads/${previewBranch} ${worktreeHead}`);
|
|
44
|
-
const currentBranch = await git(projectDir, "rev-parse --abbrev-ref HEAD");
|
|
45
|
-
if (currentBranch === previewBranch) {
|
|
46
|
-
await git(projectDir, `reset --hard ${worktreeHead}`);
|
|
47
|
-
}
|
|
48
|
-
logger.chat.info("Preview synced", { previewBranch, commit: worktreeHead });
|
|
49
|
-
return { success: true, commit: worktreeHead };
|
|
50
|
-
} catch (error) {
|
|
51
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
52
|
-
logger.chat.error("Preview sync failed", { previewBranch, error: errorMessage });
|
|
53
|
-
return { success: false, error: errorMessage };
|
|
42
|
+
if (existsSync(worktreePath)) {
|
|
43
|
+
validateWorktreePath(worktreePath);
|
|
54
44
|
}
|
|
45
|
+
return withLock(projectDir, async () => {
|
|
46
|
+
try {
|
|
47
|
+
const worktreeHead = await git(worktreePath, ["rev-parse", "HEAD"]);
|
|
48
|
+
await git(projectDir, ["update-ref", `refs/heads/${previewBranch}`, worktreeHead]);
|
|
49
|
+
const currentBranch = await git(projectDir, ["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
50
|
+
if (currentBranch === previewBranch) {
|
|
51
|
+
await git(projectDir, ["reset", "--hard", worktreeHead]);
|
|
52
|
+
}
|
|
53
|
+
logger.chat.info("Preview synced", { previewBranch, commit: worktreeHead });
|
|
54
|
+
return { success: true, commit: worktreeHead };
|
|
55
|
+
} catch (error) {
|
|
56
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
57
|
+
logger.chat.error("Preview sync failed", { previewBranch, error: errorMessage });
|
|
58
|
+
return { success: false, error: errorMessage };
|
|
59
|
+
}
|
|
60
|
+
});
|
|
55
61
|
});
|
|
56
62
|
|
|
57
63
|
export { previewSync_post as default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preview-sync.post.mjs","sources":["../../../../../../server/api/chat/preview-sync.post.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"preview-sync.post.mjs","sources":["../../../../../../server/api/chat/preview-sync.post.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkBA,yBAAA,kBAAA,CAAA,OAAA,KAAA,KAAA;AACA,EAAA,MAAA,IAAA,GAAA,MAAA,QAAA,CAGA,KAAA,CAAA;AAEA,EAAA,IAAA,EAAA,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAA,aAAA,CAAA,IAAA,EAAA,6BAAA,YAAA,CAAA,EAAA;AACA,IAAA,MAAA,WAAA,CAAA;AAAA,MACA,UAAA,EAAA,GAAA;AAAA,MACA,OAAA,EAAA;AAAA,KACA,CAAA;AAAA,EACA;AAEA,EAAA,MAAA,EAAA,cAAA,GAAA,IAAA;AACA,EAAA,MAAA,aAAA,GAAA,oBAAA,CAAA,IAAA,CAAA,aAAA,EAAA,gBAAA,CAAA;AACA,EAAA,MAAA,aAAA,aAAA,EAAA;AAEA,EAAA,IAAA,UAAA,CAAA,YAAA,CAAA,EAAA;AACA,IAAA,oBAAA,CAAA,YAAA,CAAA;AAAA,EACA;AAEA,EAAA,OAAA,QAAA,CAAA,YAAA,YAAA;AACA,IAAA,IAAA;AAEA,MAAA,MAAA,eAAA,MAAA,GAAA,CAAA,cAAA,CAAA,WAAA,EAAA,MAAA,CAAA,CAAA;AAGA,MAAA,MAAA,GAAA,CAAA,YAAA,CAAA,YAAA,EAAA,cAAA,aAAA,CAAA,CAAA,EAAA,YAAA,CAAA,CAAA;AAGA,MAAA,MAAA,aAAA,GAAA,MAAA,GAAA,CAAA,UAAA,EAAA,CAAA,WAAA,EAAA,cAAA,EAAA,MAAA,CAAA,CAAA;AACA,MAAA,IAAA,kBAAA,aAAA,EAAA;AACA,QAAA,MAAA,IAAA,UAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,YAAA,CAAA,CAAA;AAAA,MACA;AAEA,MAAA,MAAA,CAAA,KAAA,IAAA,CAAA,gBAAA,EAAA,EAAA,aAAA,EAAA,MAAA,EAAA,cAAA,CAAA;AAEA,MAAA,OAAA,EAAA,OAAA,EAAA,IAAA,EAAA,MAAA,EAAA,YAAA,EAAA;AAAA,IACA,SAAA,KAAA,EAAA;AACA,MAAA,MAAA,eAAA,KAAA,YAAA,KAAA,GAAA,KAAA,CAAA,OAAA,GAAA,OAAA,KAAA,CAAA;AACA,MAAA,MAAA,CAAA,KAAA,KAAA,CAAA,qBAAA,EAAA,EAAA,aAAA,EAAA,KAAA,EAAA,cAAA,CAAA;AAEA,MAAA,OAAA,EAAA,OAAA,EAAA,KAAA,EAAA,KAAA,EAAA,YAAA,EAAA;AAAA,IACA;AAAA,EACA,CAAA,CAAA;AACA,CAAA,CAAA;;;;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { d as defineEventHandler, b as readBody, c as createError, e as getProjectDir, l as logger } from '../../../nitro/nitro.mjs';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { a as assertSafeBranchName, g as git } from '../../../_/chatGit.mjs';
|
|
3
|
+
import { w as withLock } from '../../../_/asyncLock.mjs';
|
|
4
4
|
import 'node:http';
|
|
5
5
|
import 'node:https';
|
|
6
6
|
import 'node:crypto';
|
|
@@ -22,12 +22,10 @@ import 'node:os';
|
|
|
22
22
|
import 'node:module';
|
|
23
23
|
import 'node:fs/promises';
|
|
24
24
|
import 'node:url';
|
|
25
|
+
import '../../../_/gitExec.mjs';
|
|
26
|
+
import 'child_process';
|
|
27
|
+
import 'util';
|
|
25
28
|
|
|
26
|
-
const execAsync = promisify(exec);
|
|
27
|
-
async function git(cwd, cmd) {
|
|
28
|
-
const { stdout } = await execAsync(`git ${cmd}`, { cwd });
|
|
29
|
-
return stdout.trim();
|
|
30
|
-
}
|
|
31
29
|
const preview_delete = defineEventHandler(async (event) => {
|
|
32
30
|
const body = await readBody(event);
|
|
33
31
|
if (!(body == null ? void 0 : body.previewBranch) || !(body == null ? void 0 : body.baseBranch)) {
|
|
@@ -36,26 +34,29 @@ const preview_delete = defineEventHandler(async (event) => {
|
|
|
36
34
|
message: "previewBranch and baseBranch are required"
|
|
37
35
|
});
|
|
38
36
|
}
|
|
39
|
-
const
|
|
37
|
+
const previewBranch = assertSafeBranchName(body.previewBranch, "preview branch");
|
|
38
|
+
const baseBranch = assertSafeBranchName(body.baseBranch, "base branch");
|
|
40
39
|
const projectDir = getProjectDir();
|
|
41
40
|
logger.chat.info("Ending preview", { previewBranch, baseBranch });
|
|
42
|
-
|
|
43
|
-
await git(projectDir, `checkout "${baseBranch}"`);
|
|
41
|
+
return withLock(projectDir, async () => {
|
|
44
42
|
try {
|
|
45
|
-
await git(projectDir,
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
await git(projectDir, ["checkout", baseBranch]);
|
|
44
|
+
try {
|
|
45
|
+
await git(projectDir, ["branch", "-D", previewBranch]);
|
|
46
|
+
} catch {
|
|
47
|
+
logger.chat.warn("Failed to delete preview branch", { previewBranch });
|
|
48
|
+
}
|
|
49
|
+
logger.chat.info("Preview ended", { previewBranch });
|
|
50
|
+
return { success: true };
|
|
51
|
+
} catch (error) {
|
|
52
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
53
|
+
logger.chat.error("Failed to end preview", { error: errorMessage });
|
|
54
|
+
return {
|
|
55
|
+
success: false,
|
|
56
|
+
error: errorMessage
|
|
57
|
+
};
|
|
48
58
|
}
|
|
49
|
-
|
|
50
|
-
return { success: true };
|
|
51
|
-
} catch (error) {
|
|
52
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
53
|
-
logger.chat.error("Failed to end preview", { error: errorMessage });
|
|
54
|
-
return {
|
|
55
|
-
success: false,
|
|
56
|
-
error: errorMessage
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
+
});
|
|
59
60
|
});
|
|
60
61
|
|
|
61
62
|
export { preview_delete as default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preview.delete.mjs","sources":["../../../../../../server/api/chat/preview.delete.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"preview.delete.mjs","sources":["../../../../../../server/api/chat/preview.delete.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,uBAAA,kBAAA,CAAA,OAAA,KAAA,KAAA;AACA,EAAA,MAAA,IAAA,GAAA,MAAA,QAAA,CAGA,KAAA,CAAA;AAEA,EAAA,IAAA,EAAA,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAA,aAAA,CAAA,IAAA,EAAA,6BAAA,UAAA,CAAA,EAAA;AACA,IAAA,MAAA,WAAA,CAAA;AAAA,MACA,UAAA,EAAA,GAAA;AAAA,MACA,OAAA,EAAA;AAAA,KACA,CAAA;AAAA,EACA;AAEA,EAAA,MAAA,aAAA,GAAA,oBAAA,CAAA,IAAA,CAAA,aAAA,EAAA,gBAAA,CAAA;AACA,EAAA,MAAA,UAAA,GAAA,oBAAA,CAAA,IAAA,CAAA,UAAA,EAAA,aAAA,CAAA;AACA,EAAA,MAAA,aAAA,aAAA,EAAA;AAEA,EAAA,MAAA,CAAA,KAAA,IAAA,CAAA,gBAAA,EAAA,EAAA,aAAA,EAAA,YAAA,CAAA;AAEA,EAAA,OAAA,QAAA,CAAA,YAAA,YAAA;AACA,IAAA,IAAA;AAEA,MAAA,MAAA,GAAA,CAAA,UAAA,EAAA,CAAA,UAAA,EAAA,UAAA,CAAA,CAAA;AAGA,MAAA,IAAA;AACA,QAAA,MAAA,IAAA,UAAA,EAAA,CAAA,QAAA,EAAA,IAAA,EAAA,aAAA,CAAA,CAAA;AAAA,MACA,CAAA,CAAA,MAAA;AACA,QAAA,MAAA,CAAA,IAAA,CAAA,IAAA,CAAA,iCAAA,EAAA,EAAA,eAAA,CAAA;AAAA,MACA;AAEA,MAAA,MAAA,CAAA,IAAA,CAAA,IAAA,CAAA,eAAA,EAAA,EAAA,eAAA,CAAA;AAEA,MAAA,OAAA,EAAA,SAAA,IAAA,EAAA;AAAA,IACA,SAAA,KAAA,EAAA;AACA,MAAA,MAAA,eAAA,KAAA,YAAA,KAAA,GAAA,KAAA,CAAA,OAAA,GAAA,OAAA,KAAA,CAAA;AACA,MAAA,MAAA,CAAA,KAAA,KAAA,CAAA,uBAAA,EAAA,EAAA,KAAA,EAAA,cAAA,CAAA;AAEA,MAAA,OAAA;AAAA,QACA,OAAA,EAAA,KAAA;AAAA,QACA,KAAA,EAAA;AAAA,OACA;AAAA,IACA;AAAA,EACA,CAAA,CAAA;AACA,CAAA,CAAA;;;;"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { d as defineEventHandler, b as readBody, c as createError, e as getProjectDir, l as logger } from '../../../nitro/nitro.mjs';
|
|
2
|
-
import { exec } from 'node:child_process';
|
|
3
|
-
import { promisify } from 'node:util';
|
|
4
2
|
import { existsSync } from 'node:fs';
|
|
3
|
+
import { v as validateWorktreePath } from '../../../_/validateWorktree.mjs';
|
|
4
|
+
import { a as assertSafeBranchName, g as git } from '../../../_/chatGit.mjs';
|
|
5
|
+
import { a as autoCommitChanges } from '../../../_/claudeService.mjs';
|
|
6
|
+
import { w as withLock } from '../../../_/asyncLock.mjs';
|
|
5
7
|
import 'node:http';
|
|
6
8
|
import 'node:https';
|
|
7
9
|
import 'node:crypto';
|
|
@@ -22,12 +24,13 @@ import 'node:os';
|
|
|
22
24
|
import 'node:module';
|
|
23
25
|
import 'node:fs/promises';
|
|
24
26
|
import 'node:url';
|
|
27
|
+
import '../../../_/worktreePaths.mjs';
|
|
28
|
+
import '../../../_/gitExec.mjs';
|
|
29
|
+
import 'child_process';
|
|
30
|
+
import 'util';
|
|
31
|
+
import 'node:child_process';
|
|
32
|
+
import '../../../_/claude.mjs';
|
|
25
33
|
|
|
26
|
-
const execAsync = promisify(exec);
|
|
27
|
-
async function git(cwd, cmd) {
|
|
28
|
-
const { stdout } = await execAsync(`git ${cmd}`, { cwd });
|
|
29
|
-
return stdout.trim();
|
|
30
|
-
}
|
|
31
34
|
const preview_post = defineEventHandler(async (event) => {
|
|
32
35
|
const body = await readBody(event);
|
|
33
36
|
if (!(body == null ? void 0 : body.conversationId) || !(body == null ? void 0 : body.worktreePath) || !(body == null ? void 0 : body.baseBranch)) {
|
|
@@ -36,54 +39,56 @@ const preview_post = defineEventHandler(async (event) => {
|
|
|
36
39
|
message: "conversationId, worktreePath, and baseBranch are required"
|
|
37
40
|
});
|
|
38
41
|
}
|
|
39
|
-
const { conversationId, worktreePath
|
|
42
|
+
const { conversationId, worktreePath } = body;
|
|
43
|
+
assertSafeBranchName(body.baseBranch, "base branch");
|
|
40
44
|
const projectDir = getProjectDir();
|
|
41
45
|
const previewBranch = "sc/preview";
|
|
46
|
+
if (existsSync(worktreePath)) {
|
|
47
|
+
validateWorktreePath(worktreePath);
|
|
48
|
+
}
|
|
42
49
|
logger.chat.info("Creating preview branch", { conversationId, previewBranch });
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
await git(worktreePath, "
|
|
50
|
-
await git(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
return withLock(projectDir, async () => {
|
|
51
|
+
try {
|
|
52
|
+
if (!existsSync(worktreePath)) {
|
|
53
|
+
return { success: false, error: "Worktree directory not found." };
|
|
54
|
+
}
|
|
55
|
+
await autoCommitChanges(worktreePath);
|
|
56
|
+
const worktreeHead = await git(worktreePath, ["rev-parse", "HEAD"]);
|
|
57
|
+
const mainStatus = await git(projectDir, ["status", "--porcelain"]);
|
|
58
|
+
if (mainStatus) {
|
|
59
|
+
return {
|
|
60
|
+
success: false,
|
|
61
|
+
error: "Main worktree has uncommitted changes. Please commit or stash them first."
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
let branchExists = false;
|
|
65
|
+
try {
|
|
66
|
+
await git(projectDir, ["rev-parse", "--verify", `refs/heads/${previewBranch}`]);
|
|
67
|
+
branchExists = true;
|
|
68
|
+
} catch {
|
|
69
|
+
}
|
|
70
|
+
if (branchExists) {
|
|
71
|
+
await git(projectDir, ["checkout", previewBranch]);
|
|
72
|
+
await git(projectDir, ["reset", "--hard", worktreeHead]);
|
|
73
|
+
} else {
|
|
74
|
+
await git(projectDir, ["branch", previewBranch, worktreeHead]);
|
|
75
|
+
await git(projectDir, ["checkout", previewBranch]);
|
|
76
|
+
}
|
|
77
|
+
logger.chat.info("Preview branch active", { previewBranch, worktreeHead });
|
|
78
|
+
return {
|
|
79
|
+
success: true,
|
|
80
|
+
previewBranch,
|
|
81
|
+
commit: worktreeHead
|
|
82
|
+
};
|
|
83
|
+
} catch (error) {
|
|
84
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
85
|
+
logger.chat.error("Failed to create preview", { conversationId, error: errorMessage });
|
|
55
86
|
return {
|
|
56
87
|
success: false,
|
|
57
|
-
error:
|
|
88
|
+
error: errorMessage
|
|
58
89
|
};
|
|
59
90
|
}
|
|
60
|
-
|
|
61
|
-
try {
|
|
62
|
-
await git(projectDir, `rev-parse --verify "refs/heads/${previewBranch}"`);
|
|
63
|
-
branchExists = true;
|
|
64
|
-
} catch {
|
|
65
|
-
}
|
|
66
|
-
if (branchExists) {
|
|
67
|
-
await git(projectDir, `checkout "${previewBranch}"`);
|
|
68
|
-
await git(projectDir, `reset --hard ${worktreeHead}`);
|
|
69
|
-
} else {
|
|
70
|
-
await git(projectDir, `branch "${previewBranch}" ${worktreeHead}`);
|
|
71
|
-
await git(projectDir, `checkout "${previewBranch}"`);
|
|
72
|
-
}
|
|
73
|
-
logger.chat.info("Preview branch active", { previewBranch, worktreeHead });
|
|
74
|
-
return {
|
|
75
|
-
success: true,
|
|
76
|
-
previewBranch,
|
|
77
|
-
commit: worktreeHead
|
|
78
|
-
};
|
|
79
|
-
} catch (error) {
|
|
80
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
81
|
-
logger.chat.error("Failed to create preview", { conversationId, error: errorMessage });
|
|
82
|
-
return {
|
|
83
|
-
success: false,
|
|
84
|
-
error: errorMessage
|
|
85
|
-
};
|
|
86
|
-
}
|
|
91
|
+
});
|
|
87
92
|
});
|
|
88
93
|
|
|
89
94
|
export { preview_post as default };
|