spec-cat 0.1.21 → 0.1.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/{qt0TxNaY.js → -EMqkm_u.js} +1 -1
  3. package/.output/public/_nuxt/{N3ZxlKm3.js → BDd_kh9e.js} +1 -1
  4. package/.output/public/_nuxt/BJKzOiTU.js +1 -0
  5. package/.output/public/_nuxt/{DqNujSig.js → Bk4uZfKR.js} +1 -1
  6. package/.output/public/_nuxt/C9Qk2Hno.js +1 -0
  7. package/.output/public/_nuxt/CDLI67Cr.js +1 -0
  8. package/.output/public/_nuxt/CLPz4Oer.js +1 -0
  9. package/.output/public/_nuxt/CYVeOpC3.js +1 -0
  10. package/.output/public/_nuxt/CZbP5QXb.js +1 -0
  11. package/.output/public/_nuxt/DQtVbA-s.js +150 -0
  12. package/.output/public/_nuxt/DXWMFGmi.js +1 -0
  13. package/.output/public/_nuxt/DgiJut-o.js +1 -0
  14. package/.output/public/_nuxt/{DUodkQcr.js → FbKhJXKu.js} +3 -3
  15. package/.output/public/_nuxt/builds/latest.json +1 -1
  16. package/.output/public/_nuxt/builds/meta/53b5c409-86a8-4624-8a0f-5bf31ab82deb.json +1 -0
  17. package/.output/public/_nuxt/default.eSO6fRPf.css +1 -0
  18. package/.output/public/_nuxt/entry.BtencOYX.css +1 -0
  19. package/.output/public/_nuxt/useTheme.Dp77PlfC.css +1 -0
  20. package/.output/server/chunks/_/conversationStore.mjs +13 -1
  21. package/.output/server/chunks/_/conversationStore.mjs.map +1 -1
  22. package/.output/server/chunks/_/git.mjs +7 -6
  23. package/.output/server/chunks/_/git.mjs.map +1 -1
  24. package/.output/server/chunks/_/git2.mjs.map +1 -1
  25. package/.output/server/chunks/_/gitApiHelpers.mjs +43 -0
  26. package/.output/server/chunks/_/gitApiHelpers.mjs.map +1 -0
  27. package/.output/server/chunks/_/jobPersister.mjs +326 -0
  28. package/.output/server/chunks/_/jobPersister.mjs.map +1 -0
  29. package/.output/server/chunks/_/jobQueue.mjs +714 -0
  30. package/.output/server/chunks/_/jobQueue.mjs.map +1 -0
  31. package/.output/server/chunks/build/client.precomputed.mjs +1 -1
  32. package/.output/server/chunks/build/client.precomputed.mjs.map +1 -1
  33. package/.output/server/chunks/nitro/nitro.mjs +693 -657
  34. package/.output/server/chunks/routes/_ws.mjs +133 -527
  35. package/.output/server/chunks/routes/_ws.mjs.map +1 -1
  36. package/.output/server/chunks/routes/api/git/branch-rename.post.mjs +5 -18
  37. package/.output/server/chunks/routes/api/git/branch-rename.post.mjs.map +1 -1
  38. package/.output/server/chunks/routes/api/git/branch.delete.mjs +5 -18
  39. package/.output/server/chunks/routes/api/git/branch.delete.mjs.map +1 -1
  40. package/.output/server/chunks/routes/api/git/branches.get.mjs +5 -18
  41. package/.output/server/chunks/routes/api/git/branches.get.mjs.map +1 -1
  42. package/.output/server/chunks/routes/api/git/checkout.post.mjs +5 -19
  43. package/.output/server/chunks/routes/api/git/checkout.post.mjs.map +1 -1
  44. package/.output/server/chunks/routes/api/git/cherry-pick.post.mjs +5 -18
  45. package/.output/server/chunks/routes/api/git/cherry-pick.post.mjs.map +1 -1
  46. package/.output/server/chunks/routes/api/git/clean.post.mjs +5 -19
  47. package/.output/server/chunks/routes/api/git/clean.post.mjs.map +1 -1
  48. package/.output/server/chunks/routes/api/git/commit/_id_.get.mjs +23 -26
  49. package/.output/server/chunks/routes/api/git/commit/_id_.get.mjs.map +1 -1
  50. package/.output/server/chunks/routes/api/git/commit.post.mjs +5 -19
  51. package/.output/server/chunks/routes/api/git/commit.post.mjs.map +1 -1
  52. package/.output/server/chunks/routes/api/git/diff.get.mjs +5 -24
  53. package/.output/server/chunks/routes/api/git/diff.get.mjs.map +1 -1
  54. package/.output/server/chunks/routes/api/git/fetch.post.mjs +5 -18
  55. package/.output/server/chunks/routes/api/git/fetch.post.mjs.map +1 -1
  56. package/.output/server/chunks/routes/api/git/file-diff.get.mjs +5 -24
  57. package/.output/server/chunks/routes/api/git/file-diff.get.mjs.map +1 -1
  58. package/.output/server/chunks/routes/api/git/graph.get.mjs +9 -20
  59. package/.output/server/chunks/routes/api/git/graph.get.mjs.map +1 -1
  60. package/.output/server/chunks/routes/api/git/log.get.mjs +5 -24
  61. package/.output/server/chunks/routes/api/git/log.get.mjs.map +1 -1
  62. package/.output/server/chunks/routes/api/git/merge-base.get.mjs +5 -24
  63. package/.output/server/chunks/routes/api/git/merge-base.get.mjs.map +1 -1
  64. package/.output/server/chunks/routes/api/git/merge.post.mjs +5 -18
  65. package/.output/server/chunks/routes/api/git/merge.post.mjs.map +1 -1
  66. package/.output/server/chunks/routes/api/git/pull.post.mjs +14 -26
  67. package/.output/server/chunks/routes/api/git/pull.post.mjs.map +1 -1
  68. package/.output/server/chunks/routes/api/git/push.post.mjs +15 -27
  69. package/.output/server/chunks/routes/api/git/push.post.mjs.map +1 -1
  70. package/.output/server/chunks/routes/api/git/rebase.post.mjs +10 -22
  71. package/.output/server/chunks/routes/api/git/rebase.post.mjs.map +1 -1
  72. package/.output/server/chunks/routes/api/git/remote.delete.mjs +5 -18
  73. package/.output/server/chunks/routes/api/git/remote.delete.mjs.map +1 -1
  74. package/.output/server/chunks/routes/api/git/remote.post.mjs +10 -22
  75. package/.output/server/chunks/routes/api/git/remote.post.mjs.map +1 -1
  76. package/.output/server/chunks/routes/api/git/remote.put.mjs +5 -18
  77. package/.output/server/chunks/routes/api/git/remote.put.mjs.map +1 -1
  78. package/.output/server/chunks/routes/api/git/remotes.get.mjs +5 -18
  79. package/.output/server/chunks/routes/api/git/remotes.get.mjs.map +1 -1
  80. package/.output/server/chunks/routes/api/git/reset.post.mjs +12 -24
  81. package/.output/server/chunks/routes/api/git/reset.post.mjs.map +1 -1
  82. package/.output/server/chunks/routes/api/git/revert.post.mjs +5 -18
  83. package/.output/server/chunks/routes/api/git/revert.post.mjs.map +1 -1
  84. package/.output/server/chunks/routes/api/git/show.get.mjs +5 -24
  85. package/.output/server/chunks/routes/api/git/show.get.mjs.map +1 -1
  86. package/.output/server/chunks/routes/api/git/stage.post.mjs +9 -22
  87. package/.output/server/chunks/routes/api/git/stage.post.mjs.map +1 -1
  88. package/.output/server/chunks/routes/api/git/stash-apply.post.mjs +5 -19
  89. package/.output/server/chunks/routes/api/git/stash-apply.post.mjs.map +1 -1
  90. package/.output/server/chunks/routes/api/git/stash-branch.post.mjs +5 -19
  91. package/.output/server/chunks/routes/api/git/stash-branch.post.mjs.map +1 -1
  92. package/.output/server/chunks/routes/api/git/stash-drop.post.mjs +5 -19
  93. package/.output/server/chunks/routes/api/git/stash-drop.post.mjs.map +1 -1
  94. package/.output/server/chunks/routes/api/git/stash-pop.post.mjs +5 -19
  95. package/.output/server/chunks/routes/api/git/stash-pop.post.mjs.map +1 -1
  96. package/.output/server/chunks/routes/api/git/stash.get.mjs +5 -25
  97. package/.output/server/chunks/routes/api/git/stash.get.mjs.map +1 -1
  98. package/.output/server/chunks/routes/api/git/stash.post.mjs +5 -19
  99. package/.output/server/chunks/routes/api/git/stash.post.mjs.map +1 -1
  100. package/.output/server/chunks/routes/api/git/state.get.mjs +5 -25
  101. package/.output/server/chunks/routes/api/git/state.get.mjs.map +1 -1
  102. package/.output/server/chunks/routes/api/git/status.get.mjs +5 -25
  103. package/.output/server/chunks/routes/api/git/status.get.mjs.map +1 -1
  104. package/.output/server/chunks/routes/api/git/tag/_name_.get.mjs +5 -18
  105. package/.output/server/chunks/routes/api/git/tag/_name_.get.mjs.map +1 -1
  106. package/.output/server/chunks/routes/api/git/tag-push.post.mjs +10 -22
  107. package/.output/server/chunks/routes/api/git/tag-push.post.mjs.map +1 -1
  108. package/.output/server/chunks/routes/api/git/tag.delete.mjs +5 -18
  109. package/.output/server/chunks/routes/api/git/tag.delete.mjs.map +1 -1
  110. package/.output/server/chunks/routes/api/git/tag.post.mjs +17 -29
  111. package/.output/server/chunks/routes/api/git/tag.post.mjs.map +1 -1
  112. package/.output/server/chunks/routes/api/git/unstage.post.mjs +5 -19
  113. package/.output/server/chunks/routes/api/git/unstage.post.mjs.map +1 -1
  114. package/.output/server/chunks/routes/api/index.get.mjs +25 -14
  115. package/.output/server/chunks/routes/api/index.get.mjs.map +1 -1
  116. package/.output/server/chunks/routes/api/index.get2.mjs +14 -141
  117. package/.output/server/chunks/routes/api/index.get2.mjs.map +1 -1
  118. package/.output/server/chunks/routes/api/index.get3.mjs +167 -0
  119. package/.output/server/chunks/routes/api/index.get3.mjs.map +1 -0
  120. package/.output/server/chunks/routes/api/index.post.mjs +77 -116
  121. package/.output/server/chunks/routes/api/index.post.mjs.map +1 -1
  122. package/.output/server/chunks/routes/api/index.post2.mjs +149 -0
  123. package/.output/server/chunks/routes/api/index.post2.mjs.map +1 -0
  124. package/.output/server/chunks/routes/api/jobs/_id/cancel.post.mjs +48 -0
  125. package/.output/server/chunks/routes/api/jobs/_id/cancel.post.mjs.map +1 -0
  126. package/.output/server/chunks/routes/api/jobs/_id_.get.mjs +55 -0
  127. package/.output/server/chunks/routes/api/jobs/_id_.get.mjs.map +1 -0
  128. package/.output/server/chunks/routes/api/repository/status.get.mjs +1 -1
  129. package/.output/server/package.json +1 -1
  130. package/package.json +1 -1
  131. package/.output/public/_nuxt/BIw1AQHU.js +0 -150
  132. package/.output/public/_nuxt/DBtLi_wJ.js +0 -1
  133. package/.output/public/_nuxt/DSDWvT5-.js +0 -1
  134. package/.output/public/_nuxt/K5rMM4le.js +0 -1
  135. package/.output/public/_nuxt/builds/meta/c0768eef-2dd5-410c-8648-edbd9e6c218c.json +0 -1
  136. package/.output/public/_nuxt/ddKcAgQK.js +0 -1
  137. package/.output/public/_nuxt/default.CZoNL3P_.css +0 -1
  138. package/.output/public/_nuxt/entry.DLBgeD7S.css +0 -1
  139. package/.output/public/_nuxt/sxXWehCn.js +0 -1
@@ -1,8 +1,9 @@
1
- import { d as defineEventHandler, f as getQuery, e as getProjectDir, b as readBody, c as createError, l as logger } from '../../nitro/nitro.mjs';
1
+ import { d as defineEventHandler, b as readBody, c as createError, e as getProjectDir } from '../../nitro/nitro.mjs';
2
2
  import { exec } from 'node:child_process';
3
3
  import { promisify } from 'node:util';
4
- import { existsSync } from 'node:fs';
5
- import { join } from 'node:path';
4
+ import { j as jobQueue } from '../../_/jobQueue.mjs';
5
+ import { s as startPersisting } from '../../_/jobPersister.mjs';
6
+ import { a as generateConversationId, b as generateConversationTitle, u as upsertConversationInStorage, S as STORAGE_VERSION } from '../../_/conversationStore.mjs';
6
7
  import 'node:http';
7
8
  import 'node:https';
8
9
  import 'node:crypto';
@@ -18,131 +19,91 @@ import 'tls';
18
19
  import 'url';
19
20
  import 'node:events';
20
21
  import 'node:buffer';
22
+ import 'node:fs';
23
+ import 'node:path';
21
24
  import 'node:os';
22
25
  import 'node:module';
23
26
  import 'node:fs/promises';
24
27
  import 'node:url';
28
+ import '../../_/aiProviderSelection.mjs';
29
+ import '../../_/aiProviderRegistry.mjs';
30
+ import '../../_/providerProcessError.mjs';
31
+ import '../../_/uiAdapter.mjs';
25
32
 
26
33
  const execAsync = promisify(exec);
27
- function generateRandomId() {
28
- return Math.random().toString(36).substring(2, 10);
29
- }
30
- async function getCurrentHead(projectPath) {
31
- try {
32
- const { stdout } = await execAsync("git rev-parse --abbrev-ref HEAD", {
33
- cwd: projectPath
34
- });
35
- const branch = stdout.trim();
36
- if (branch === "HEAD") {
37
- const { stdout: hash } = await execAsync("git rev-parse HEAD", {
38
- cwd: projectPath
39
- });
40
- return hash.trim();
41
- }
42
- return branch;
43
- } catch {
44
- return "main";
45
- }
46
- }
47
- async function checkBranchExists(projectPath, branchName) {
48
- try {
49
- await execAsync(`git rev-parse --verify ${branchName}`, { cwd: projectPath });
50
- return true;
51
- } catch {
52
- return false;
53
- }
54
- }
55
- async function getNextFeatureNumber(projectPath) {
56
- try {
57
- const { stdout: branchOutput } = await execAsync(
58
- 'git branch -a --format="%(refname:short)" 2>/dev/null || echo ""',
59
- { cwd: projectPath }
60
- );
61
- const numbers = branchOutput.split("\n").map((branch) => {
62
- const match = branch.match(/^(\d{3})-/);
63
- return match ? parseInt(match[1], 10) : 0;
64
- }).filter((n) => n > 0);
65
- const specsDir = join(projectPath, "specs");
66
- if (existsSync(specsDir)) {
67
- const { stdout: lsOutput } = await execAsync(`ls -d ${specsDir}/*/ 2>/dev/null || echo ""`);
68
- const specNumbers = lsOutput.split("\n").map((dir) => {
69
- const name = dir.split("/").filter(Boolean).pop() || "";
70
- const match = name.match(/^(\d{3})-/);
71
- return match ? parseInt(match[1], 10) : 0;
72
- }).filter((n) => n > 0);
73
- numbers.push(...specNumbers);
74
- }
75
- return numbers.length > 0 ? Math.max(...numbers) + 1 : 1;
76
- } catch {
77
- return 1;
78
- }
79
- }
80
- function generateBranchName(description, shortName, number) {
81
- const num = String(number || 1).padStart(3, "0");
82
- if (shortName) {
83
- return `${num}-${shortName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+$/, "")}`;
84
- }
85
- const stopWords = ["a", "an", "the", "and", "or", "but", "in", "on", "at", "to", "for", "of", "with", "by"];
86
- const words = description.toLowerCase().replace(/[^a-z0-9\s]/g, "").split(/\s+/).filter((w) => w.length > 1 && !stopWords.includes(w)).slice(0, 4);
87
- return `${num}-${words.join("-")}`;
88
- }
89
34
  const index_post = defineEventHandler(async (event) => {
90
- const query = getQuery(event);
91
- const workingDirectory = query.workingDirectory || getProjectDir();
35
+ var _a;
92
36
  const body = await readBody(event);
93
- if (!(body == null ? void 0 : body.description)) {
94
- throw createError({
95
- statusCode: 400,
96
- message: "Description is required"
97
- });
37
+ if (!((_a = body == null ? void 0 : body.message) == null ? void 0 : _a.trim())) {
38
+ throw createError({ statusCode: 400, statusMessage: "message is required" });
98
39
  }
99
- logger.api.info("Creating worktree", { workingDirectory, description: body.description });
40
+ const source = body.source || "scheduler";
41
+ const conversationId = body.conversationId || generateConversationId();
42
+ const now = (/* @__PURE__ */ new Date()).toISOString();
43
+ const projectDir = getProjectDir();
44
+ if (body.featureId && !/^[a-zA-Z0-9_\-]+$/.test(body.featureId)) {
45
+ throw createError({ statusCode: 400, statusMessage: "Invalid featureId format (alphanumeric, hyphens, underscores only)" });
46
+ }
47
+ const branchName = body.featureId || `sc/${conversationId}`;
48
+ const worktreePath = body.featureId ? `/tmp/sc-${body.featureId}-${conversationId}` : `/tmp/sc-${conversationId}`;
49
+ let worktreeResult = { success: false };
100
50
  try {
101
- const nextNumber = await getNextFeatureNumber(workingDirectory);
102
- const branchName = generateBranchName(body.description, body.shortName, nextNumber);
103
- const baseBranch = body.baseBranch || await getCurrentHead(workingDirectory);
104
- const branchExists = await checkBranchExists(workingDirectory, branchName);
105
- if (branchExists) {
106
- throw createError({
107
- statusCode: 409,
108
- message: `Branch '${branchName}' already exists`
109
- });
51
+ const { stdout: baseBranchRaw } = await execAsync("git rev-parse --abbrev-ref HEAD", { cwd: projectDir });
52
+ const baseBranch = baseBranchRaw.trim();
53
+ const { stdout: baseHead } = await execAsync(`git rev-parse --verify "refs/heads/${baseBranch}^{commit}"`, { cwd: projectDir });
54
+ const base = baseHead.trim();
55
+ if (body.featureId) {
56
+ try {
57
+ await execAsync(`git rev-parse --verify "${branchName}"`, { cwd: projectDir });
58
+ console.log(`[jobs.post] Branch "${branchName}" already exists, skipping worktree creation`);
59
+ } catch {
60
+ await execAsync(`git worktree add -b "${branchName}" "${worktreePath}" "${base}"`, { cwd: projectDir });
61
+ worktreeResult = { success: true, worktreePath, branch: branchName, baseBranch };
62
+ }
63
+ } else {
64
+ await execAsync(`git worktree add -b "${branchName}" "${worktreePath}" "${base}"`, { cwd: projectDir });
65
+ worktreeResult = { success: true, worktreePath, branch: branchName, baseBranch };
110
66
  }
111
- await execAsync(`git branch ${branchName} ${baseBranch}`, { cwd: workingDirectory });
112
- const randomId = generateRandomId();
113
- const worktreePath = `/tmp/${branchName}-${randomId}`;
114
- await execAsync(`git worktree add "${worktreePath}" "${branchName}"`, {
115
- cwd: workingDirectory
116
- });
117
- const format = "%H|||%h|||%s|||%an|||%ar";
118
- const { stdout: commitOutput } = await execAsync(`git log -1 --format="${format}"`, {
119
- cwd: worktreePath
120
- });
121
- const [hash, shortHash, message, author, date] = commitOutput.trim().split("|||");
122
- const worktree = {
123
- name: branchName,
124
- path: worktreePath,
125
- branch: branchName,
126
- isMain: false,
127
- isCurrent: false,
128
- isLocked: false,
129
- status: "clean",
130
- commitCount: 0,
131
- lastCommit: { hash, shortHash, message, author, date }
132
- };
133
- logger.api.info("Worktree created", { branchName, worktreePath });
134
- return {
135
- success: true,
136
- worktree
137
- };
138
- } catch (error) {
139
- const errorMessage = error instanceof Error ? error.message : String(error);
140
- logger.api.error("Failed to create worktree", { error: errorMessage });
141
- return {
142
- success: false,
143
- error: errorMessage
144
- };
67
+ } catch (err) {
68
+ console.warn("[jobs.post] Failed to create worktree for server job:", err instanceof Error ? err.message : err);
145
69
  }
70
+ const conversationCwd = worktreeResult.success ? worktreeResult.worktreePath : body.cwd || projectDir;
71
+ const conversation = {
72
+ id: conversationId,
73
+ title: body.title || generateConversationTitle(body.message),
74
+ messages: [],
75
+ createdAt: now,
76
+ updatedAt: now,
77
+ cwd: conversationCwd,
78
+ source,
79
+ featureId: body.featureId,
80
+ providerId: body.providerId,
81
+ providerModelKey: body.providerModelKey,
82
+ ...worktreeResult.success && {
83
+ worktreePath: worktreeResult.worktreePath,
84
+ worktreeBranch: worktreeResult.branch,
85
+ hasWorktree: true,
86
+ baseBranch: worktreeResult.baseBranch
87
+ }
88
+ };
89
+ await upsertConversationInStorage(conversation, STORAGE_VERSION);
90
+ const jobMessage = {
91
+ message: body.message,
92
+ conversationId,
93
+ requestId: `req-${Date.now()}-${Math.random().toString(36).substring(2, 8)}`,
94
+ permissionMode: body.permissionMode || "bypass",
95
+ cwd: conversationCwd,
96
+ featureId: body.featureId,
97
+ providerId: body.providerId,
98
+ providerModelKey: body.providerModelKey
99
+ };
100
+ startPersisting(conversationId, body.message);
101
+ const jobId = jobQueue.submit(jobMessage, source);
102
+ return {
103
+ jobId,
104
+ conversationId,
105
+ source
106
+ };
146
107
  });
147
108
 
148
109
  export { index_post as default };
@@ -1 +1 @@
1
- {"version":3,"file":"index.post.mjs","sources":["../../../../../server/api/worktrees/index.post.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.post.mjs","sources":["../../../../../server/api/jobs/index.post.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,149 @@
1
+ import { d as defineEventHandler, f as getQuery, e as getProjectDir, b as readBody, c as createError, l as logger } from '../../nitro/nitro.mjs';
2
+ import { exec } from 'node:child_process';
3
+ import { promisify } from 'node:util';
4
+ import { existsSync } from 'node:fs';
5
+ import { join } from 'node:path';
6
+ import 'node:http';
7
+ import 'node:https';
8
+ import 'node:crypto';
9
+ import 'stream';
10
+ import 'events';
11
+ import 'http';
12
+ import 'crypto';
13
+ import 'buffer';
14
+ import 'zlib';
15
+ import 'https';
16
+ import 'net';
17
+ import 'tls';
18
+ import 'url';
19
+ import 'node:events';
20
+ import 'node:buffer';
21
+ import 'node:os';
22
+ import 'node:module';
23
+ import 'node:fs/promises';
24
+ import 'node:url';
25
+
26
+ const execAsync = promisify(exec);
27
+ function generateRandomId() {
28
+ return Math.random().toString(36).substring(2, 10);
29
+ }
30
+ async function getCurrentHead(projectPath) {
31
+ try {
32
+ const { stdout } = await execAsync("git rev-parse --abbrev-ref HEAD", {
33
+ cwd: projectPath
34
+ });
35
+ const branch = stdout.trim();
36
+ if (branch === "HEAD") {
37
+ const { stdout: hash } = await execAsync("git rev-parse HEAD", {
38
+ cwd: projectPath
39
+ });
40
+ return hash.trim();
41
+ }
42
+ return branch;
43
+ } catch {
44
+ return "main";
45
+ }
46
+ }
47
+ async function checkBranchExists(projectPath, branchName) {
48
+ try {
49
+ await execAsync(`git rev-parse --verify ${branchName}`, { cwd: projectPath });
50
+ return true;
51
+ } catch {
52
+ return false;
53
+ }
54
+ }
55
+ async function getNextFeatureNumber(projectPath) {
56
+ try {
57
+ const { stdout: branchOutput } = await execAsync(
58
+ 'git branch -a --format="%(refname:short)" 2>/dev/null || echo ""',
59
+ { cwd: projectPath }
60
+ );
61
+ const numbers = branchOutput.split("\n").map((branch) => {
62
+ const match = branch.match(/^(\d{3})-/);
63
+ return match ? parseInt(match[1], 10) : 0;
64
+ }).filter((n) => n > 0);
65
+ const specsDir = join(projectPath, "specs");
66
+ if (existsSync(specsDir)) {
67
+ const { stdout: lsOutput } = await execAsync(`ls -d ${specsDir}/*/ 2>/dev/null || echo ""`);
68
+ const specNumbers = lsOutput.split("\n").map((dir) => {
69
+ const name = dir.split("/").filter(Boolean).pop() || "";
70
+ const match = name.match(/^(\d{3})-/);
71
+ return match ? parseInt(match[1], 10) : 0;
72
+ }).filter((n) => n > 0);
73
+ numbers.push(...specNumbers);
74
+ }
75
+ return numbers.length > 0 ? Math.max(...numbers) + 1 : 1;
76
+ } catch {
77
+ return 1;
78
+ }
79
+ }
80
+ function generateBranchName(description, shortName, number) {
81
+ const num = String(number || 1).padStart(3, "0");
82
+ if (shortName) {
83
+ return `${num}-${shortName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+$/, "")}`;
84
+ }
85
+ const stopWords = ["a", "an", "the", "and", "or", "but", "in", "on", "at", "to", "for", "of", "with", "by"];
86
+ const words = description.toLowerCase().replace(/[^a-z0-9\s]/g, "").split(/\s+/).filter((w) => w.length > 1 && !stopWords.includes(w)).slice(0, 4);
87
+ return `${num}-${words.join("-")}`;
88
+ }
89
+ const index_post = defineEventHandler(async (event) => {
90
+ const query = getQuery(event);
91
+ const workingDirectory = query.workingDirectory || getProjectDir();
92
+ const body = await readBody(event);
93
+ if (!(body == null ? void 0 : body.description)) {
94
+ throw createError({
95
+ statusCode: 400,
96
+ message: "Description is required"
97
+ });
98
+ }
99
+ logger.api.info("Creating worktree", { workingDirectory, description: body.description });
100
+ try {
101
+ const nextNumber = await getNextFeatureNumber(workingDirectory);
102
+ const branchName = generateBranchName(body.description, body.shortName, nextNumber);
103
+ const baseBranch = body.baseBranch || await getCurrentHead(workingDirectory);
104
+ const branchExists = await checkBranchExists(workingDirectory, branchName);
105
+ if (branchExists) {
106
+ throw createError({
107
+ statusCode: 409,
108
+ message: `Branch '${branchName}' already exists`
109
+ });
110
+ }
111
+ await execAsync(`git branch ${branchName} ${baseBranch}`, { cwd: workingDirectory });
112
+ const randomId = generateRandomId();
113
+ const worktreePath = `/tmp/${branchName}-${randomId}`;
114
+ await execAsync(`git worktree add "${worktreePath}" "${branchName}"`, {
115
+ cwd: workingDirectory
116
+ });
117
+ const format = "%H|||%h|||%s|||%an|||%ar";
118
+ const { stdout: commitOutput } = await execAsync(`git log -1 --format="${format}"`, {
119
+ cwd: worktreePath
120
+ });
121
+ const [hash, shortHash, message, author, date] = commitOutput.trim().split("|||");
122
+ const worktree = {
123
+ name: branchName,
124
+ path: worktreePath,
125
+ branch: branchName,
126
+ isMain: false,
127
+ isCurrent: false,
128
+ isLocked: false,
129
+ status: "clean",
130
+ commitCount: 0,
131
+ lastCommit: { hash, shortHash, message, author, date }
132
+ };
133
+ logger.api.info("Worktree created", { branchName, worktreePath });
134
+ return {
135
+ success: true,
136
+ worktree
137
+ };
138
+ } catch (error) {
139
+ const errorMessage = error instanceof Error ? error.message : String(error);
140
+ logger.api.error("Failed to create worktree", { error: errorMessage });
141
+ return {
142
+ success: false,
143
+ error: errorMessage
144
+ };
145
+ }
146
+ });
147
+
148
+ export { index_post as default };
149
+ //# sourceMappingURL=index.post2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.post2.mjs","sources":["../../../../../server/api/worktrees/index.post.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { d as defineEventHandler, h as getRouterParam, c as createError } from '../../../../nitro/nitro.mjs';
2
+ import { j as jobQueue } from '../../../../_/jobQueue.mjs';
3
+ import 'node:http';
4
+ import 'node:https';
5
+ import 'node:crypto';
6
+ import 'stream';
7
+ import 'events';
8
+ import 'http';
9
+ import 'crypto';
10
+ import 'buffer';
11
+ import 'zlib';
12
+ import 'https';
13
+ import 'net';
14
+ import 'tls';
15
+ import 'url';
16
+ import 'node:events';
17
+ import 'node:buffer';
18
+ import 'node:fs';
19
+ import 'node:path';
20
+ import 'node:os';
21
+ import 'node:module';
22
+ import 'node:fs/promises';
23
+ import 'node:url';
24
+ import 'node:child_process';
25
+ import 'node:util';
26
+ import '../../../../_/aiProviderSelection.mjs';
27
+ import '../../../../_/aiProviderRegistry.mjs';
28
+ import '../../../../_/providerProcessError.mjs';
29
+ import '../../../../_/uiAdapter.mjs';
30
+
31
+ const cancel_post = defineEventHandler((event) => {
32
+ const id = getRouterParam(event, "id");
33
+ if (!id) {
34
+ throw createError({ statusCode: 400, statusMessage: "Job ID is required" });
35
+ }
36
+ const job = jobQueue.getJob(id);
37
+ if (!job) {
38
+ throw createError({ statusCode: 404, statusMessage: "Job not found" });
39
+ }
40
+ if (job.status === "done" || job.status === "error") {
41
+ return { success: false, reason: "Job already finished" };
42
+ }
43
+ jobQueue.abort(job.conversationId);
44
+ return { success: true };
45
+ });
46
+
47
+ export { cancel_post as default };
48
+ //# sourceMappingURL=cancel.post.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cancel.post.mjs","sources":["../../../../../../../server/api/jobs/[id]/cancel.post.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,oBAAA,kBAAA,CAAA,CAAA,KAAA,KAAA;AACA,EAAA,MAAA,EAAA,GAAA,cAAA,CAAA,KAAA,EAAA,IAAA,CAAA;AACA,EAAA,IAAA,CAAA,EAAA,EAAA;AACA,IAAA,MAAA,YAAA,EAAA,UAAA,EAAA,GAAA,EAAA,aAAA,EAAA,sBAAA,CAAA;AAAA,EACA;AAEA,EAAA,MAAA,GAAA,GAAA,QAAA,CAAA,MAAA,CAAA,EAAA,CAAA;AACA,EAAA,IAAA,CAAA,GAAA,EAAA;AACA,IAAA,MAAA,YAAA,EAAA,UAAA,EAAA,GAAA,EAAA,aAAA,EAAA,iBAAA,CAAA;AAAA,EACA;AAEA,EAAA,IAAA,GAAA,CAAA,MAAA,KAAA,MAAA,IAAA,GAAA,CAAA,WAAA,OAAA,EAAA;AACA,IAAA,OAAA,EAAA,OAAA,EAAA,KAAA,EAAA,MAAA,EAAA,sBAAA,EAAA;AAAA,EACA;AAEA,EAAA,QAAA,CAAA,KAAA,CAAA,IAAA,cAAA,CAAA;AACA,EAAA,OAAA,EAAA,SAAA,IAAA,EAAA;AACA,CAAA,CAAA;;;;"}
@@ -0,0 +1,55 @@
1
+ import { d as defineEventHandler, h as getRouterParam, c as createError, f as getQuery } from '../../../nitro/nitro.mjs';
2
+ import { j as jobQueue } from '../../../_/jobQueue.mjs';
3
+ import 'node:http';
4
+ import 'node:https';
5
+ import 'node:crypto';
6
+ import 'stream';
7
+ import 'events';
8
+ import 'http';
9
+ import 'crypto';
10
+ import 'buffer';
11
+ import 'zlib';
12
+ import 'https';
13
+ import 'net';
14
+ import 'tls';
15
+ import 'url';
16
+ import 'node:events';
17
+ import 'node:buffer';
18
+ import 'node:fs';
19
+ import 'node:path';
20
+ import 'node:os';
21
+ import 'node:module';
22
+ import 'node:fs/promises';
23
+ import 'node:url';
24
+ import 'node:child_process';
25
+ import 'node:util';
26
+ import '../../../_/aiProviderSelection.mjs';
27
+ import '../../../_/aiProviderRegistry.mjs';
28
+ import '../../../_/providerProcessError.mjs';
29
+ import '../../../_/uiAdapter.mjs';
30
+
31
+ const _id__get = defineEventHandler((event) => {
32
+ const id = getRouterParam(event, "id");
33
+ if (!id) {
34
+ throw createError({ statusCode: 400, statusMessage: "Job ID is required" });
35
+ }
36
+ const job = jobQueue.getJob(id);
37
+ if (!job) {
38
+ throw createError({ statusCode: 404, statusMessage: "Job not found" });
39
+ }
40
+ const query = getQuery(event);
41
+ const cursor = typeof query.cursor === "string" ? parseInt(query.cursor, 10) : 0;
42
+ const validCursor = Number.isFinite(cursor) && cursor >= 0 ? cursor : 0;
43
+ return {
44
+ id: job.id,
45
+ conversationId: job.conversationId,
46
+ source: job.source,
47
+ status: job.status,
48
+ createdAt: job.createdAt,
49
+ events: job.events.slice(validCursor),
50
+ nextCursor: job.events.length
51
+ };
52
+ });
53
+
54
+ export { _id__get as default };
55
+ //# sourceMappingURL=_id_.get.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_id_.get.mjs","sources":["../../../../../../server/api/jobs/[id].get.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,iBAAA,kBAAA,CAAA,CAAA,KAAA,KAAA;AACA,EAAA,MAAA,EAAA,GAAA,cAAA,CAAA,KAAA,EAAA,IAAA,CAAA;AACA,EAAA,IAAA,CAAA,EAAA,EAAA;AACA,IAAA,MAAA,YAAA,EAAA,UAAA,EAAA,GAAA,EAAA,aAAA,EAAA,sBAAA,CAAA;AAAA,EACA;AAEA,EAAA,MAAA,GAAA,GAAA,QAAA,CAAA,MAAA,CAAA,EAAA,CAAA;AACA,EAAA,IAAA,CAAA,GAAA,EAAA;AACA,IAAA,MAAA,YAAA,EAAA,UAAA,EAAA,GAAA,EAAA,aAAA,EAAA,iBAAA,CAAA;AAAA,EACA;AAEA,EAAA,MAAA,KAAA,GAAA,SAAA,KAAA,CAAA;AACA,EAAA,MAAA,MAAA,GAAA,OAAA,KAAA,CAAA,MAAA,KAAA,WAAA,QAAA,CAAA,KAAA,CAAA,MAAA,EAAA,EAAA,CAAA,GAAA,CAAA;AACA,EAAA,MAAA,cAAA,MAAA,CAAA,QAAA,CAAA,MAAA,CAAA,IAAA,MAAA,IAAA,IAAA,MAAA,GAAA,CAAA;AAEA,EAAA,OAAA;AAAA,IACA,IAAA,GAAA,CAAA,EAAA;AAAA,IACA,gBAAA,GAAA,CAAA,cAAA;AAAA,IACA,QAAA,GAAA,CAAA,MAAA;AAAA,IACA,QAAA,GAAA,CAAA,MAAA;AAAA,IACA,WAAA,GAAA,CAAA,SAAA;AAAA,IACA,MAAA,EAAA,GAAA,CAAA,MAAA,CAAA,KAAA,CAAA,WAAA,CAAA;AAAA,IACA,UAAA,EAAA,IAAA,MAAA,CAAA;AAAA,GACA;AACA,CAAA,CAAA;;;;"}
@@ -1,5 +1,5 @@
1
1
  import { d as defineEventHandler, e as getProjectDir, c as createError } from '../../../nitro/nitro.mjs';
2
- import { a as isGitRepository, b as execGitCommand } from '../../../_/git.mjs';
2
+ import { W as isGitRepository, a as execGitCommand } from '../../../_/git.mjs';
3
3
  import 'node:http';
4
4
  import 'node:https';
5
5
  import 'node:crypto';
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spec-cat-prod",
3
- "version": "0.1.21",
3
+ "version": "0.1.23",
4
4
  "type": "module",
5
5
  "private": true,
6
6
  "dependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spec-cat",
3
- "version": "0.1.21",
3
+ "version": "0.1.23",
4
4
  "description": "Spec-driven development workbench",
5
5
  "license": "MIT",
6
6
  "keywords": [