spec-cat 0.1.22 → 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 (48) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/{NsKpYGKU.js → -EMqkm_u.js} +1 -1
  3. package/.output/public/_nuxt/{CXuoBUW5.js → BDd_kh9e.js} +1 -1
  4. package/.output/public/_nuxt/{CXlw6va7.js → BJKzOiTU.js} +1 -1
  5. package/.output/public/_nuxt/{B6Qdx9x3.js → Bk4uZfKR.js} +1 -1
  6. package/.output/public/_nuxt/{D2jWy6Yv.js → C9Qk2Hno.js} +1 -1
  7. package/.output/public/_nuxt/{DuDc88rI.js → CDLI67Cr.js} +1 -1
  8. package/.output/public/_nuxt/{BDt4jGdk.js → CLPz4Oer.js} +1 -1
  9. package/.output/public/_nuxt/{hWTomhWa.js → CYVeOpC3.js} +1 -1
  10. package/.output/public/_nuxt/{DYq0avGL.js → CZbP5QXb.js} +1 -1
  11. package/.output/public/_nuxt/DQtVbA-s.js +150 -0
  12. package/.output/public/_nuxt/DXWMFGmi.js +1 -0
  13. package/.output/public/_nuxt/{CnyGP5yJ.js → DgiJut-o.js} +1 -1
  14. package/.output/public/_nuxt/{xDSloGc6.js → FbKhJXKu.js} +2 -2
  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/useTheme.Dp77PlfC.css +1 -0
  18. package/.output/server/chunks/_/conversationStore.mjs +13 -1
  19. package/.output/server/chunks/_/conversationStore.mjs.map +1 -1
  20. package/.output/server/chunks/_/jobPersister.mjs +326 -0
  21. package/.output/server/chunks/_/jobPersister.mjs.map +1 -0
  22. package/.output/server/chunks/_/jobQueue.mjs +714 -0
  23. package/.output/server/chunks/_/jobQueue.mjs.map +1 -0
  24. package/.output/server/chunks/build/client.precomputed.mjs +1 -1
  25. package/.output/server/chunks/build/client.precomputed.mjs.map +1 -1
  26. package/.output/server/chunks/nitro/nitro.mjs +655 -647
  27. package/.output/server/chunks/routes/_ws.mjs +133 -527
  28. package/.output/server/chunks/routes/_ws.mjs.map +1 -1
  29. package/.output/server/chunks/routes/api/index.get.mjs +25 -14
  30. package/.output/server/chunks/routes/api/index.get.mjs.map +1 -1
  31. package/.output/server/chunks/routes/api/index.get2.mjs +14 -141
  32. package/.output/server/chunks/routes/api/index.get2.mjs.map +1 -1
  33. package/.output/server/chunks/routes/api/index.get3.mjs +167 -0
  34. package/.output/server/chunks/routes/api/index.get3.mjs.map +1 -0
  35. package/.output/server/chunks/routes/api/index.post.mjs +77 -116
  36. package/.output/server/chunks/routes/api/index.post.mjs.map +1 -1
  37. package/.output/server/chunks/routes/api/index.post2.mjs +149 -0
  38. package/.output/server/chunks/routes/api/index.post2.mjs.map +1 -0
  39. package/.output/server/chunks/routes/api/jobs/_id/cancel.post.mjs +48 -0
  40. package/.output/server/chunks/routes/api/jobs/_id/cancel.post.mjs.map +1 -0
  41. package/.output/server/chunks/routes/api/jobs/_id_.get.mjs +55 -0
  42. package/.output/server/chunks/routes/api/jobs/_id_.get.mjs.map +1 -0
  43. package/.output/server/package.json +1 -1
  44. package/package.json +1 -1
  45. package/.output/public/_nuxt/Ce5fR5lE.js +0 -150
  46. package/.output/public/_nuxt/builds/meta/23707bc3-d223-45cd-b9db-ffcc7aca2680.json +0 -1
  47. package/.output/public/_nuxt/useTheme.CYXKgjUm.css +0 -1
  48. package/.output/public/_nuxt/z5m_gN1E.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":";;;;;;;;;;;;;;;;;;;;;;;;;AAaA,MAAA,SAAA,GAAA,UAAA,IAAA,CAAA;AAEA,SAAA,gBAAA,GAAA;AACA,EAAA,OAAA,IAAA,CAAA,QAAA,CAAA,QAAA,CAAA,EAAA,CAAA,CAAA,SAAA,CAAA,GAAA,EAAA,CAAA;AACA;AAEA,eAAA,eAAA,WAAA,EAAA;AACA,EAAA,IAAA;AACA,IAAA,MAAA,EAAA,MAAA,EAAA,GAAA,MAAA,UAAA,iCAAA,EAAA;AAAA,MACA,GAAA,EAAA;AAAA,KACA,CAAA;AACA,IAAA,MAAA,MAAA,GAAA,OAAA,IAAA,EAAA;AACA,IAAA,IAAA,WAAA,MAAA,EAAA;AACA,MAAA,MAAA,EAAA,MAAA,EAAA,IAAA,EAAA,GAAA,MAAA,UAAA,oBAAA,EAAA;AAAA,QACA,GAAA,EAAA;AAAA,OACA,CAAA;AACA,MAAA,OAAA,KAAA,IAAA,EAAA;AAAA,IACA;AACA,IAAA,OAAA,MAAA;AAAA,EACA,CAAA,CAAA,MAAA;AACA,IAAA,OAAA,MAAA;AAAA,EACA;AACA;AAEA,eAAA,iBAAA,CAAA,aAAA,UAAA,EAAA;AACA,EAAA,IAAA;AACA,IAAA,MAAA,UAAA,CAAA,uBAAA,EAAA,UAAA,IAAA,EAAA,GAAA,EAAA,aAAA,CAAA;AACA,IAAA,OAAA,IAAA;AAAA,EACA,CAAA,CAAA,MAAA;AACA,IAAA,OAAA,KAAA;AAAA,EACA;AACA;AAEA,eAAA,qBAAA,WAAA,EAAA;AACA,EAAA,IAAA;AAEA,IAAA,MAAA,EAAA,MAAA,EAAA,YAAA,EAAA,GAAA,MAAA,SAAA;AAAA,MACA,kEAAA;AAAA,MACA,EAAA,KAAA,WAAA;AAAA,KACA;AAEA,IAAA,MAAA,UAAA,YAAA,CACA,KAAA,CAAA,IAAA,CAAA,CACA,IAAA,CAAA,MAAA,KAAA;AACA,MAAA,MAAA,KAAA,GAAA,MAAA,CAAA,KAAA,CAAA,WAAA,CAAA;AACA,MAAA,OAAA,QAAA,QAAA,CAAA,KAAA,CAAA,CAAA,CAAA,EAAA,EAAA,CAAA,GAAA,CAAA;AAAA,IACA,CAAA,CAAA,CACA,MAAA,CAAA,CAAA,CAAA,KAAA,IAAA,CAAA,CAAA;AAGA,IAAA,MAAA,QAAA,GAAA,IAAA,CAAA,WAAA,EAAA,OAAA,CAAA;AACA,IAAA,IAAA,UAAA,CAAA,QAAA,CAAA,EAAA;AACA,MAAA,MAAA,EAAA,QAAA,QAAA,EAAA,GAAA,MAAA,SAAA,CAAA,CAAA,MAAA,EAAA,QAAA,CAAA,0BAAA,CAAA,CAAA;AACA,MAAA,MAAA,cAAA,QAAA,CACA,KAAA,CAAA,IAAA,CAAA,CACA,IAAA,CAAA,GAAA,KAAA;AACA,QAAA,MAAA,IAAA,GAAA,IAAA,KAAA,CAAA,GAAA,EAAA,MAAA,CAAA,OAAA,CAAA,CAAA,GAAA,EAAA,IAAA,EAAA;AACA,QAAA,MAAA,KAAA,GAAA,IAAA,CAAA,KAAA,CAAA,WAAA,CAAA;AACA,QAAA,OAAA,QAAA,QAAA,CAAA,KAAA,CAAA,CAAA,CAAA,EAAA,EAAA,CAAA,GAAA,CAAA;AAAA,MACA,CAAA,CAAA,CACA,MAAA,CAAA,CAAA,CAAA,KAAA,IAAA,CAAA,CAAA;AAEA,MAAA,OAAA,CAAA,IAAA,CAAA,GAAA,WAAA,CAAA;AAAA,IACA;AAEA,IAAA,OAAA,OAAA,CAAA,SAAA,CAAA,GAAA,IAAA,CAAA,IAAA,GAAA,OAAA,IAAA,CAAA,GAAA,CAAA;AAAA,EACA,CAAA,CAAA,MAAA;AACA,IAAA,OAAA,CAAA;AAAA,EACA;AACA;AAEA,SAAA,kBAAA,CAAA,WAAA,EAAA,SAAA,EAAA,MAAA,EAAA;AACA,EAAA,MAAA,MAAA,MAAA,CAAA,MAAA,IAAA,CAAA,CAAA,CAAA,QAAA,CAAA,GAAA,GAAA,CAAA;AAEA,EAAA,IAAA,SAAA,EAAA;AACA,IAAA,OAAA,CAAA,EAAA,GAAA,CAAA,CAAA,EAAA,SAAA,CAAA,WAAA,EAAA,CAAA,OAAA,CAAA,aAAA,EAAA,GAAA,CAAA,CAAA,OAAA,CAAA,KAAA,EAAA,EAAA,CAAA,CAAA,CAAA;AAAA,EACA;AAGA,EAAA,MAAA,SAAA,GAAA,CAAA,GAAA,EAAA,IAAA,EAAA,OAAA,KAAA,EAAA,IAAA,EAAA,KAAA,EAAA,IAAA,EAAA,MAAA,IAAA,EAAA,IAAA,EAAA,KAAA,EAAA,IAAA,EAAA,QAAA,IAAA,CAAA;AACA,EAAA,MAAA,KAAA,GAAA,WAAA,CACA,WAAA,EAAA,CACA,OAAA,CAAA,gBAAA,EAAA,CAAA,CACA,KAAA,CAAA,KAAA,CAAA,CACA,MAAA,CAAA,OAAA,CAAA,CAAA,MAAA,GAAA,CAAA,IAAA,CAAA,SAAA,CAAA,QAAA,CAAA,CAAA,CAAA,CAAA,CACA,KAAA,CAAA,CAAA,EAAA,CAAA,CAAA;AAEA,EAAA,OAAA,GAAA,GAAA,CAAA,CAAA,EAAA,KAAA,CAAA,IAAA,CAAA,GAAA,CAAA,CAAA,CAAA;AACA;AAEA,mBAAA,kBAAA,CAAA,OAAA,KAAA,KAAA;AACA,EAAA,MAAA,KAAA,GAAA,SAAA,KAAA,CAAA;AACA,EAAA,MAAA,gBAAA,GAAA,KAAA,CAAA,gBAAA,IAAA,aAAA,EAAA;AAEA,EAAA,MAAA,IAAA,GAAA,MAAA,QAAA,CAAA,KAAA,CAAA;AAEA,EAAA,IAAA,EAAA,6BAAA,WAAA,CAAA,EAAA;AACA,IAAA,MAAA,WAAA,CAAA;AAAA,MACA,UAAA,EAAA,GAAA;AAAA,MACA,OAAA,EAAA;AAAA,KACA,CAAA;AAAA,EACA;AAEA,EAAA,MAAA,CAAA,GAAA,CAAA,KAAA,mBAAA,EAAA,EAAA,kBAAA,WAAA,EAAA,IAAA,CAAA,aAAA,CAAA;AAEA,EAAA,IAAA;AACA,IAAA,MAAA,UAAA,GAAA,MAAA,oBAAA,CAAA,gBAAA,CAAA;AACA,IAAA,MAAA,aAAA,kBAAA,CAAA,IAAA,CAAA,WAAA,EAAA,IAAA,CAAA,WAAA,UAAA,CAAA;AACA,IAAA,MAAA,UAAA,GAAA,IAAA,CAAA,UAAA,IAAA,MAAA,eAAA,gBAAA,CAAA;AAGA,IAAA,MAAA,YAAA,GAAA,MAAA,iBAAA,CAAA,gBAAA,EAAA,UAAA,CAAA;AACA,IAAA,IAAA,YAAA,EAAA;AACA,MAAA,MAAA,WAAA,CAAA;AAAA,QACA,UAAA,EAAA,GAAA;AAAA,QACA,OAAA,EAAA,WAAA,UAAA,CAAA,gBAAA;AAAA,OACA,CAAA;AAAA,IACA;AAGA,IAAA,MAAA,SAAA,CAAA,cAAA,UAAA,CAAA,CAAA,EAAA,UAAA,CAAA,CAAA,EAAA,EAAA,GAAA,EAAA,gBAAA,EAAA,CAAA;AAGA,IAAA,MAAA,WAAA,gBAAA,EAAA;AACA,IAAA,MAAA,YAAA,GAAA,CAAA,KAAA,EAAA,UAAA,CAAA,CAAA,EAAA,QAAA,CAAA,CAAA;AAEA,IAAA,MAAA,SAAA,CAAA,CAAA,kBAAA,EAAA,YAAA,CAAA,GAAA,EAAA,UAAA,CAAA,CAAA,CAAA,EAAA;AAAA,MACA,GAAA,EAAA;AAAA,KACA,CAAA;AAGA,IAAA,MAAA,MAAA,GAAA,0BAAA;AACA,IAAA,MAAA,EAAA,QAAA,YAAA,EAAA,GAAA,MAAA,SAAA,CAAA,CAAA,qBAAA,EAAA,MAAA,CAAA,CAAA,CAAA,EAAA;AAAA,MACA,GAAA,EAAA;AAAA,KACA,CAAA;AACA,IAAA,MAAA,CAAA,IAAA,EAAA,SAAA,EAAA,OAAA,EAAA,MAAA,EAAA,IAAA,CAAA,GAAA,YAAA,CAAA,IAAA,EAAA,CAAA,KAAA,CAAA,KAAA,CAAA;AAEA,IAAA,MAAA,QAAA,GAAA;AAAA,MACA,IAAA,EAAA,UAAA;AAAA,MACA,IAAA,EAAA,YAAA;AAAA,MACA,MAAA,EAAA,UAAA;AAAA,MACA,MAAA,EAAA,KAAA;AAAA,MACA,SAAA,EAAA,KAAA;AAAA,MACA,QAAA,EAAA,KAAA;AAAA,MACA,MAAA,EAAA,OAAA;AAAA,MACA,WAAA,EAAA,CAAA;AAAA,MACA,YAAA,EAAA,IAAA,EAAA,SAAA,EAAA,OAAA,EAAA,QAAA,IAAA;AAAA,KACA;AAEA,IAAA,MAAA,CAAA,IAAA,IAAA,CAAA,kBAAA,EAAA,EAAA,UAAA,EAAA,cAAA,CAAA;AAEA,IAAA,OAAA;AAAA,MACA,OAAA,EAAA,IAAA;AAAA,MACA;AAAA,KACA;AAAA,EACA,SAAA,KAAA,EAAA;AACA,IAAA,MAAA,eAAA,KAAA,YAAA,KAAA,GAAA,KAAA,CAAA,OAAA,GAAA,OAAA,KAAA,CAAA;AACA,IAAA,MAAA,CAAA,IAAA,KAAA,CAAA,2BAAA,EAAA,EAAA,KAAA,EAAA,cAAA,CAAA;AAEA,IAAA,OAAA;AAAA,MACA,OAAA,EAAA,KAAA;AAAA,MACA,KAAA,EAAA;AAAA,KACA;AAAA,EACA;AACA,CAAA,CAAA;;;;"}
@@ -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,6 +1,6 @@
1
1
  {
2
2
  "name": "spec-cat-prod",
3
- "version": "0.1.22",
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.22",
3
+ "version": "0.1.23",
4
4
  "description": "Spec-driven development workbench",
5
5
  "license": "MIT",
6
6
  "keywords": [