@straiffi/archon 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/README.md +224 -0
  2. package/dist/cli.js +216 -0
  3. package/dist/client/assets/index-8_-boBBA.css +2 -0
  4. package/dist/client/assets/index-s_jjeqha.js +176 -0
  5. package/dist/client/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
  6. package/dist/client/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
  7. package/dist/client/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  8. package/dist/client/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  9. package/dist/client/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
  10. package/dist/client/favicon.svg +62 -0
  11. package/dist/client/icons.svg +24 -0
  12. package/dist/client/index.html +14 -0
  13. package/dist/server/db.js +764 -0
  14. package/dist/server/db.js.map +1 -0
  15. package/dist/server/index.js +5134 -0
  16. package/dist/server/index.js.map +1 -0
  17. package/dist/server/lib/agent.js +1302 -0
  18. package/dist/server/lib/agent.js.map +1 -0
  19. package/dist/server/lib/buildChains.js +2 -0
  20. package/dist/server/lib/buildChains.js.map +1 -0
  21. package/dist/server/lib/buildFlow.js +59 -0
  22. package/dist/server/lib/buildFlow.js.map +1 -0
  23. package/dist/server/lib/buildSequences.js +599 -0
  24. package/dist/server/lib/buildSequences.js.map +1 -0
  25. package/dist/server/lib/bundleActivity.js +95 -0
  26. package/dist/server/lib/bundleActivity.js.map +1 -0
  27. package/dist/server/lib/bundlePullRequests.js +126 -0
  28. package/dist/server/lib/bundlePullRequests.js.map +1 -0
  29. package/dist/server/lib/chatMessages.js +60 -0
  30. package/dist/server/lib/chatMessages.js.map +1 -0
  31. package/dist/server/lib/chatTargets.js +123 -0
  32. package/dist/server/lib/chatTargets.js.map +1 -0
  33. package/dist/server/lib/chatTicketProposals.js +180 -0
  34. package/dist/server/lib/chatTicketProposals.js.map +1 -0
  35. package/dist/server/lib/chats.js +279 -0
  36. package/dist/server/lib/chats.js.map +1 -0
  37. package/dist/server/lib/config.js +3 -0
  38. package/dist/server/lib/config.js.map +1 -0
  39. package/dist/server/lib/cors.js +30 -0
  40. package/dist/server/lib/cors.js.map +1 -0
  41. package/dist/server/lib/directoryPicker.js +174 -0
  42. package/dist/server/lib/directoryPicker.js.map +1 -0
  43. package/dist/server/lib/git.js +1284 -0
  44. package/dist/server/lib/git.js.map +1 -0
  45. package/dist/server/lib/integrations/github.js +511 -0
  46. package/dist/server/lib/integrations/github.js.map +1 -0
  47. package/dist/server/lib/integrations/index.js +162 -0
  48. package/dist/server/lib/integrations/index.js.map +1 -0
  49. package/dist/server/lib/integrations/jira.js +283 -0
  50. package/dist/server/lib/integrations/jira.js.map +1 -0
  51. package/dist/server/lib/integrations/planning.js +27 -0
  52. package/dist/server/lib/integrations/planning.js.map +1 -0
  53. package/dist/server/lib/integrations/types.js +2 -0
  54. package/dist/server/lib/integrations/types.js.map +1 -0
  55. package/dist/server/lib/lightweightPrompt.js +88 -0
  56. package/dist/server/lib/lightweightPrompt.js.map +1 -0
  57. package/dist/server/lib/models.js +219 -0
  58. package/dist/server/lib/models.js.map +1 -0
  59. package/dist/server/lib/preview.js +377 -0
  60. package/dist/server/lib/preview.js.map +1 -0
  61. package/dist/server/lib/previewProxy.js +659 -0
  62. package/dist/server/lib/previewProxy.js.map +1 -0
  63. package/dist/server/lib/projectAutoConfig.js +682 -0
  64. package/dist/server/lib/projectAutoConfig.js.map +1 -0
  65. package/dist/server/lib/projectFileSuggestions.js +133 -0
  66. package/dist/server/lib/projectFileSuggestions.js.map +1 -0
  67. package/dist/server/lib/projectMemory.js +1519 -0
  68. package/dist/server/lib/projectMemory.js.map +1 -0
  69. package/dist/server/lib/projectMemoryPrompt.js +390 -0
  70. package/dist/server/lib/projectMemoryPrompt.js.map +1 -0
  71. package/dist/server/lib/projectMemoryScan.js +681 -0
  72. package/dist/server/lib/projectMemoryScan.js.map +1 -0
  73. package/dist/server/lib/projectMemorySuggestions.js +166 -0
  74. package/dist/server/lib/projectMemorySuggestions.js.map +1 -0
  75. package/dist/server/lib/projectMemoryTransfer.js +958 -0
  76. package/dist/server/lib/projectMemoryTransfer.js.map +1 -0
  77. package/dist/server/lib/projects.js +569 -0
  78. package/dist/server/lib/projects.js.map +1 -0
  79. package/dist/server/lib/promptSkills.js +28 -0
  80. package/dist/server/lib/promptSkills.js.map +1 -0
  81. package/dist/server/lib/queue.js +15 -0
  82. package/dist/server/lib/queue.js.map +1 -0
  83. package/dist/server/lib/reviewFindings.js +390 -0
  84. package/dist/server/lib/reviewFindings.js.map +1 -0
  85. package/dist/server/lib/run.js +416 -0
  86. package/dist/server/lib/run.js.map +1 -0
  87. package/dist/server/lib/runtimePaths.js +93 -0
  88. package/dist/server/lib/runtimePaths.js.map +1 -0
  89. package/dist/server/lib/shell.js +27 -0
  90. package/dist/server/lib/shell.js.map +1 -0
  91. package/dist/server/lib/skills.js +124 -0
  92. package/dist/server/lib/skills.js.map +1 -0
  93. package/dist/server/lib/startDev.js +18 -0
  94. package/dist/server/lib/startDev.js.map +1 -0
  95. package/dist/server/lib/staticClient.js +80 -0
  96. package/dist/server/lib/staticClient.js.map +1 -0
  97. package/dist/server/lib/terminal.js +366 -0
  98. package/dist/server/lib/terminal.js.map +1 -0
  99. package/dist/server/lib/ticketDependencies.js +174 -0
  100. package/dist/server/lib/ticketDependencies.js.map +1 -0
  101. package/dist/server/lib/ticketMessages.js +65 -0
  102. package/dist/server/lib/ticketMessages.js.map +1 -0
  103. package/dist/server/lib/ticketOpenQuestions.js +128 -0
  104. package/dist/server/lib/ticketOpenQuestions.js.map +1 -0
  105. package/dist/server/lib/ticketUndo.js +549 -0
  106. package/dist/server/lib/ticketUndo.js.map +1 -0
  107. package/dist/server/lib/tickets.js +981 -0
  108. package/dist/server/lib/tickets.js.map +1 -0
  109. package/dist/server/lib/types.js +2 -0
  110. package/dist/server/lib/types.js.map +1 -0
  111. package/dist/server/package.json +3 -0
  112. package/dist/server/workers/build.js +229 -0
  113. package/dist/server/workers/build.js.map +1 -0
  114. package/dist/server/workers/chat.js +190 -0
  115. package/dist/server/workers/chat.js.map +1 -0
  116. package/dist/server/workers/followUp.js +204 -0
  117. package/dist/server/workers/followUp.js.map +1 -0
  118. package/dist/server/workers/plan.js +1130 -0
  119. package/dist/server/workers/plan.js.map +1 -0
  120. package/dist/server/workers/planFollowUp.js +360 -0
  121. package/dist/server/workers/planFollowUp.js.map +1 -0
  122. package/dist/server/workers/review.js +167 -0
  123. package/dist/server/workers/review.js.map +1 -0
  124. package/package.json +40 -0
@@ -0,0 +1,95 @@
1
+ import { resolveTicketBranch } from './tickets.js';
2
+ const bundleActivities = new Map();
3
+ const getBundleId = (ticket) => {
4
+ return ticket?.worktree_bundle_id?.trim() ?? '';
5
+ };
6
+ const getExplicitBundleId = (bundleId) => {
7
+ return bundleId?.trim() ?? '';
8
+ };
9
+ const upsertBundleActivity = (bundleId, nextEntry) => {
10
+ const currentEntries = bundleActivities.get(bundleId) ?? [];
11
+ const nextEntries = currentEntries.filter(entry => entry.ticketId !== nextEntry.ticketId || entry.kind !== nextEntry.kind);
12
+ nextEntries.push(nextEntry);
13
+ bundleActivities.set(bundleId, nextEntries);
14
+ };
15
+ const removeBundleActivity = (bundleId, ticketId, kind) => {
16
+ const currentEntries = bundleActivities.get(bundleId);
17
+ if (!currentEntries) {
18
+ return;
19
+ }
20
+ const nextEntries = currentEntries.filter(entry => entry.ticketId !== ticketId || entry.kind !== kind);
21
+ if (nextEntries.length === 0) {
22
+ bundleActivities.delete(bundleId);
23
+ return;
24
+ }
25
+ bundleActivities.set(bundleId, nextEntries);
26
+ };
27
+ const listBundleActivities = (bundleId) => bundleActivities.get(bundleId) ?? [];
28
+ export const registerBundleActivity = (ticket, kind) => {
29
+ const bundleId = getBundleId(ticket);
30
+ if (!bundleId) {
31
+ return;
32
+ }
33
+ upsertBundleActivity(bundleId, { ticketId: ticket.id, kind });
34
+ };
35
+ export const unregisterBundleActivity = (ticket, kind) => {
36
+ const bundleId = getBundleId(ticket);
37
+ if (!bundleId) {
38
+ return;
39
+ }
40
+ removeBundleActivity(bundleId, ticket.id, kind);
41
+ };
42
+ export const isBundleBuildBlocked = (ticket) => {
43
+ return isBundleBuildBlockedById(ticket?.worktree_bundle_id);
44
+ };
45
+ export const isBundleBuildBlockedById = (bundleId) => {
46
+ const normalizedBundleId = getExplicitBundleId(bundleId);
47
+ if (!normalizedBundleId) {
48
+ return null;
49
+ }
50
+ const blockingKinds = ['review', 'build_follow_up', 'review_follow_up'];
51
+ const blocker = listBundleActivities(normalizedBundleId).find(entry => blockingKinds.includes(entry.kind));
52
+ if (!blocker) {
53
+ return null;
54
+ }
55
+ return {
56
+ kind: blocker.kind,
57
+ ticketId: blocker.ticketId,
58
+ };
59
+ };
60
+ export const getBundlePlanMutationBlocker = (ticket) => {
61
+ return getBundlePlanMutationBlockerById(ticket?.worktree_bundle_id);
62
+ };
63
+ export const getBundlePlanMutationBlockerById = (bundleId) => {
64
+ const normalizedBundleId = getExplicitBundleId(bundleId);
65
+ if (!normalizedBundleId) {
66
+ return null;
67
+ }
68
+ const blockingKinds = ['build', 'build_follow_up', 'review_follow_up'];
69
+ const blocker = listBundleActivities(normalizedBundleId).find(entry => blockingKinds.includes(entry.kind));
70
+ if (!blocker) {
71
+ return null;
72
+ }
73
+ return {
74
+ kind: blocker.kind,
75
+ ticketId: blocker.ticketId,
76
+ };
77
+ };
78
+ export const shouldBlockPlanForBundleMutation = (ticket, branch) => {
79
+ if (!ticket?.worktree_bundle_id) {
80
+ return false;
81
+ }
82
+ const bundleBranch = resolveTicketBranch(ticket);
83
+ return shouldBlockPlanForBundleMutationById(ticket.worktree_bundle_id, branch, bundleBranch);
84
+ };
85
+ export const shouldBlockPlanForBundleMutationById = (bundleId, branch, bundleBranch) => {
86
+ const normalizedBundleId = getExplicitBundleId(bundleId);
87
+ if (!normalizedBundleId || !bundleBranch || !branch) {
88
+ return false;
89
+ }
90
+ return bundleBranch === branch;
91
+ };
92
+ export const clearBundleActivities = () => {
93
+ bundleActivities.clear();
94
+ };
95
+ //# sourceMappingURL=bundleActivity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundleActivity.js","sourceRoot":"","sources":["../../../server/lib/bundleActivity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,126 @@
1
+ import { randomUUID } from 'crypto';
2
+ import db from '../db.js';
3
+ const normalizePullRequestState = (value) => {
4
+ if (value === 'draft' || value === 'open' || value === 'merged' || value === 'closed') {
5
+ return value;
6
+ }
7
+ return null;
8
+ };
9
+ const normalizeBundlePullRequestRecord = (row) => {
10
+ if (!row) {
11
+ return null;
12
+ }
13
+ const number = Number(row.pr_number ?? 0);
14
+ const state = normalizePullRequestState(row.state);
15
+ if (!number || !row.pr_url || !row.pr_title || !row.base_branch || !row.head_branch || !state) {
16
+ return null;
17
+ }
18
+ return {
19
+ id: row.id,
20
+ bundleId: row.bundle_id,
21
+ projectId: row.project_id,
22
+ provider: 'github',
23
+ repoHost: row.repo_host,
24
+ repoOwner: row.repo_owner,
25
+ repoName: row.repo_name,
26
+ number,
27
+ url: row.pr_url,
28
+ title: row.pr_title,
29
+ baseBranch: row.base_branch,
30
+ headBranch: row.head_branch,
31
+ state,
32
+ isDraft: Boolean(row.is_draft),
33
+ mergedAt: row.merged_at,
34
+ closedAt: row.closed_at,
35
+ githubNodeId: row.github_pr_node_id,
36
+ lastSyncedAt: row.last_synced_at,
37
+ createdAt: row.created_at,
38
+ updatedAt: row.updated_at,
39
+ };
40
+ };
41
+ export const serializeBundlePullRequest = (record) => {
42
+ if (!record) {
43
+ return null;
44
+ }
45
+ return {
46
+ provider: 'github',
47
+ number: record.number,
48
+ url: record.url,
49
+ title: record.title,
50
+ state: record.state,
51
+ base_branch: record.baseBranch,
52
+ head_branch: record.headBranch,
53
+ last_synced_at: record.lastSyncedAt,
54
+ };
55
+ };
56
+ export const getBundlePullRequestRecord = (bundleId, projectId) => {
57
+ const row = db.prepare('SELECT * FROM bundle_pull_requests WHERE bundle_id = ? AND project_id = ? AND provider = ?').get(bundleId, projectId, 'github');
58
+ return normalizeBundlePullRequestRecord(row);
59
+ };
60
+ export const listBundlePullRequestRecords = (projectId) => {
61
+ const rows = db.prepare('SELECT * FROM bundle_pull_requests WHERE project_id = ? AND provider = ? ORDER BY updated_at DESC, created_at DESC').all(projectId, 'github');
62
+ return rows
63
+ .map(row => normalizeBundlePullRequestRecord(row))
64
+ .filter((record) => record !== null);
65
+ };
66
+ export const upsertBundlePullRequest = (input) => {
67
+ const existing = getBundlePullRequestRecord(input.bundleId, input.projectId);
68
+ const id = existing?.id ?? randomUUID();
69
+ db.prepare(`
70
+ INSERT INTO bundle_pull_requests (
71
+ id,
72
+ bundle_id,
73
+ project_id,
74
+ provider,
75
+ repo_host,
76
+ repo_owner,
77
+ repo_name,
78
+ pr_number,
79
+ pr_url,
80
+ pr_title,
81
+ base_branch,
82
+ head_branch,
83
+ state,
84
+ is_draft,
85
+ merged_at,
86
+ closed_at,
87
+ github_pr_node_id,
88
+ last_synced_at
89
+ )
90
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
91
+ ON CONFLICT(project_id, bundle_id, provider) DO UPDATE SET
92
+ repo_host = excluded.repo_host,
93
+ repo_owner = excluded.repo_owner,
94
+ repo_name = excluded.repo_name,
95
+ pr_number = excluded.pr_number,
96
+ pr_url = excluded.pr_url,
97
+ pr_title = excluded.pr_title,
98
+ base_branch = excluded.base_branch,
99
+ head_branch = excluded.head_branch,
100
+ state = excluded.state,
101
+ is_draft = excluded.is_draft,
102
+ merged_at = excluded.merged_at,
103
+ closed_at = excluded.closed_at,
104
+ github_pr_node_id = excluded.github_pr_node_id,
105
+ last_synced_at = excluded.last_synced_at,
106
+ updated_at = CURRENT_TIMESTAMP
107
+ `).run(id, input.bundleId, input.projectId, 'github', input.repoHost, input.repoOwner, input.repoName, input.number, input.url, input.title, input.baseBranch, input.headBranch, input.state, input.isDraft ? 1 : 0, input.mergedAt, input.closedAt, input.githubNodeId, input.lastSyncedAt);
108
+ return getBundlePullRequestRecord(input.bundleId, input.projectId);
109
+ };
110
+ export const shouldSyncBundlePullRequest = (record, ttlMs) => {
111
+ if (!record?.lastSyncedAt) {
112
+ return true;
113
+ }
114
+ const lastSyncedAtMs = Date.parse(record.lastSyncedAt);
115
+ if (Number.isNaN(lastSyncedAtMs)) {
116
+ return true;
117
+ }
118
+ return Date.now() - lastSyncedAtMs >= ttlMs;
119
+ };
120
+ export const hasOpenBundlePullRequest = (record) => {
121
+ return record?.state === 'draft' || record?.state === 'open';
122
+ };
123
+ export const hasTerminalBundlePullRequest = (record) => {
124
+ return record?.state === 'merged' || record?.state === 'closed';
125
+ };
126
+ //# sourceMappingURL=bundlePullRequests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundlePullRequests.js","sourceRoot":"","sources":["../../../server/lib/bundlePullRequests.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import { randomUUID } from 'crypto';
2
+ import db from '../db.js';
3
+ import { parseChatTicketProposalsFromMessageContent } from './chatTicketProposals.js';
4
+ const listChatMessagesStatement = db.prepare(`
5
+ SELECT id, chat_session_id, role, kind, content, created_at
6
+ FROM chat_messages
7
+ WHERE chat_session_id = ?
8
+ ORDER BY created_at ASC, rowid ASC
9
+ `);
10
+ const insertChatMessageStatement = db.prepare(`
11
+ INSERT INTO chat_messages (id, chat_session_id, role, kind, content)
12
+ VALUES (?, ?, ?, ?, ?)
13
+ `);
14
+ const getChatMessageStatement = db.prepare(`
15
+ SELECT id, chat_session_id, role, kind, content, created_at
16
+ FROM chat_messages
17
+ WHERE id = ?
18
+ `);
19
+ const updateChatMessageContentStatement = db.prepare(`
20
+ UPDATE chat_messages
21
+ SET content = ?
22
+ WHERE id = ?
23
+ `);
24
+ const touchChatSessionStatement = db.prepare(`
25
+ UPDATE chat_sessions
26
+ SET updated_at = CURRENT_TIMESTAMP
27
+ WHERE id = ?
28
+ `);
29
+ export const listChatMessages = (chatSessionId) => {
30
+ return listChatMessagesStatement.all(chatSessionId).map(row => ({
31
+ ...row,
32
+ ticket_proposals: parseChatTicketProposalsFromMessageContent(row.content),
33
+ }));
34
+ };
35
+ export const getChatMessage = (chatMessageId) => {
36
+ const row = getChatMessageStatement.get(chatMessageId);
37
+ if (!row) {
38
+ return null;
39
+ }
40
+ return {
41
+ ...row,
42
+ ticket_proposals: parseChatTicketProposalsFromMessageContent(row.content),
43
+ };
44
+ };
45
+ export const createChatMessage = ({ chatSessionId, role, kind, content, }) => {
46
+ const id = randomUUID();
47
+ insertChatMessageStatement.run(id, chatSessionId, role, kind, content);
48
+ touchChatSessionStatement.run(chatSessionId);
49
+ return id;
50
+ };
51
+ export const updateChatMessageContent = (chatMessageId, content) => {
52
+ const existing = getChatMessage(chatMessageId);
53
+ if (!existing) {
54
+ return null;
55
+ }
56
+ updateChatMessageContentStatement.run(content, chatMessageId);
57
+ touchChatSessionStatement.run(existing.chat_session_id);
58
+ return getChatMessage(chatMessageId);
59
+ };
60
+ //# sourceMappingURL=chatMessages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chatMessages.js","sourceRoot":"","sources":["../../../server/lib/chatMessages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACnC,OAAO,EAAE,MAAM,UAAU,CAAA;AACzB,OAAO,EAAE,0CAA0C,EAAE,MAAM,0BAA0B,CAAA;AAGrF,MAAM,yBAAyB,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;CAK5C,CAAC,CAAA;AAEF,MAAM,0BAA0B,GAAG,EAAE,CAAC,OAAO,CAAC;;;CAG7C,CAAC,CAAA;AAEF,MAAM,uBAAuB,GAAG,EAAE,CAAC,OAAO,CAAC;;;;CAI1C,CAAC,CAAA;AAEF,MAAM,iCAAiC,GAAG,EAAE,CAAC,OAAO,CAAC;;;;CAIpD,CAAC,CAAA;AAEF,MAAM,yBAAyB,GAAG,EAAE,CAAC,OAAO,CAAC;;;;CAI5C,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,aAAqB,EAAiB,EAAE;IACvE,OAAQ,yBAAyB,CAAC,GAAG,CAAC,aAAa,CAAsB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpF,GAAG,GAAG;QACN,gBAAgB,EAAE,0CAA0C,CAAC,GAAG,CAAC,OAAO,CAAC;KAC1E,CAAC,CAAC,CAAA;AACL,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,aAAqB,EAAsB,EAAE;IAC1E,MAAM,GAAG,GAAG,uBAAuB,CAAC,GAAG,CAAC,aAAa,CAA+B,CAAA;IACpF,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO;QACL,GAAG,GAAG;QACN,gBAAgB,EAAE,0CAA0C,CAAC,GAAG,CAAC,OAAO,CAAC;KAC1E,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,EAChC,aAAa,EACb,IAAI,EACJ,IAAI,EACJ,OAAO,GAMR,EAAE,EAAE;IACH,MAAM,EAAE,GAAG,UAAU,EAAE,CAAA;IACvB,0BAA0B,CAAC,GAAG,CAAC,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IACtE,yBAAyB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;IAC5C,OAAO,EAAE,CAAA;AACX,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,aAAqB,EAAE,OAAe,EAAE,EAAE;IACjF,MAAM,QAAQ,GAAG,cAAc,CAAC,aAAa,CAAC,CAAA;IAC9C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,CAAA;IACb,CAAC;IAED,iCAAiC,CAAC,GAAG,CAAC,OAAO,EAAE,aAAa,CAAC,CAAA;IAC7D,yBAAyB,CAAC,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAA;IACvD,OAAO,cAAc,CAAC,aAAa,CAAC,CAAA;AACtC,CAAC,CAAA"}
@@ -0,0 +1,123 @@
1
+ import { branchExistsLocally, getProjectBranch, resolveExistingWorktreePath } from './git.js';
2
+ import { getProjectActiveTarget, getProjectById } from './projects.js';
3
+ import { getBundle, isProjectRootBundle } from './tickets.js';
4
+ const resolveProject = (chatSession, project) => {
5
+ return project ?? getProjectById(chatSession.project_id);
6
+ };
7
+ export const resolveChatSessionTarget = (chatSession, project) => {
8
+ const resolvedProject = resolveProject(chatSession, project);
9
+ if (!resolvedProject) {
10
+ if (chatSession.target_kind === 'bundle') {
11
+ return {
12
+ target_kind: 'bundle',
13
+ target_bundle_id: chatSession.target_bundle_id ?? null,
14
+ target_available: false,
15
+ target_unavailable_reason: 'Project no longer exists.',
16
+ branch: chatSession.target_branch_snapshot ?? null,
17
+ cwd: null,
18
+ };
19
+ }
20
+ return {
21
+ target_kind: 'repo_root',
22
+ target_bundle_id: null,
23
+ target_available: false,
24
+ target_unavailable_reason: 'Project no longer exists.',
25
+ branch: chatSession.target_branch_snapshot ?? null,
26
+ cwd: null,
27
+ };
28
+ }
29
+ if (chatSession.target_kind === 'bundle') {
30
+ const bundleId = chatSession.target_bundle_id ?? null;
31
+ if (!bundleId) {
32
+ return {
33
+ target_kind: 'bundle',
34
+ target_bundle_id: null,
35
+ target_available: false,
36
+ target_unavailable_reason: 'Target bundle is missing.',
37
+ branch: chatSession.target_branch_snapshot ?? null,
38
+ cwd: null,
39
+ };
40
+ }
41
+ const bundle = getBundle(bundleId, resolvedProject.id);
42
+ if (!bundle || isProjectRootBundle(bundle)) {
43
+ return {
44
+ target_kind: 'bundle',
45
+ target_bundle_id: bundleId,
46
+ target_available: false,
47
+ target_unavailable_reason: 'Target bundle no longer exists.',
48
+ branch: chatSession.target_branch_snapshot ?? null,
49
+ cwd: null,
50
+ };
51
+ }
52
+ const worktreePath = resolveExistingWorktreePath(bundle.branch, resolvedProject);
53
+ if (!worktreePath) {
54
+ return {
55
+ target_kind: 'bundle',
56
+ target_bundle_id: bundle.id,
57
+ target_available: false,
58
+ target_unavailable_reason: 'Target bundle worktree is unavailable.',
59
+ branch: bundle.branch,
60
+ cwd: null,
61
+ };
62
+ }
63
+ return {
64
+ target_kind: 'bundle',
65
+ target_bundle_id: bundle.id,
66
+ target_available: true,
67
+ target_unavailable_reason: null,
68
+ branch: bundle.branch,
69
+ cwd: worktreePath,
70
+ };
71
+ }
72
+ const branch = chatSession.target_branch_snapshot ?? null;
73
+ if (!branch) {
74
+ return {
75
+ target_kind: 'repo_root',
76
+ target_bundle_id: null,
77
+ target_available: true,
78
+ target_unavailable_reason: null,
79
+ branch: null,
80
+ cwd: resolvedProject.repo_path,
81
+ };
82
+ }
83
+ if (!branchExistsLocally(branch, resolvedProject)) {
84
+ return {
85
+ target_kind: 'repo_root',
86
+ target_bundle_id: null,
87
+ target_available: false,
88
+ target_unavailable_reason: `Target branch "${branch}" no longer exists locally.`,
89
+ branch,
90
+ cwd: null,
91
+ };
92
+ }
93
+ return {
94
+ target_kind: 'repo_root',
95
+ target_bundle_id: null,
96
+ target_available: true,
97
+ target_unavailable_reason: null,
98
+ branch,
99
+ cwd: resolvedProject.repo_path,
100
+ };
101
+ };
102
+ export const doesChatSessionTargetMatchProjectTarget = (chatSession, project) => {
103
+ const resolvedProject = resolveProject(chatSession, project);
104
+ if (!resolvedProject) {
105
+ return false;
106
+ }
107
+ const activeTarget = getProjectActiveTarget(resolvedProject);
108
+ if (chatSession.target_kind === 'bundle') {
109
+ return activeTarget.kind === 'bundle' && Boolean(chatSession.target_bundle_id) && activeTarget.bundle_id === chatSession.target_bundle_id;
110
+ }
111
+ if (activeTarget.kind === 'bundle') {
112
+ return false;
113
+ }
114
+ if (!chatSession.target_branch_snapshot) {
115
+ return true;
116
+ }
117
+ const branchState = getProjectBranch(resolvedProject, { includeDiffStats: false });
118
+ if (branchState.status !== 'ready' || !branchState.branch) {
119
+ return false;
120
+ }
121
+ return branchState.branch === chatSession.target_branch_snapshot;
122
+ };
123
+ //# sourceMappingURL=chatTargets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chatTargets.js","sourceRoot":"","sources":["../../../server/lib/chatTargets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,180 @@
1
+ const CHAT_TICKET_PROPOSALS_TAG = 'archon-ticket-proposals';
2
+ const MAX_CHAT_TICKET_PROPOSALS = 5;
3
+ const MAX_CHAT_TICKET_DEPENDENCIES = 10;
4
+ const stripChatTicketProposalBlock = (output) => {
5
+ return output.replace(new RegExp(`<${CHAT_TICKET_PROPOSALS_TAG}>[\\s\\S]*?<\\/${CHAT_TICKET_PROPOSALS_TAG}>`, 'g'), '').trim();
6
+ };
7
+ const normalizeRequiredString = (value) => {
8
+ if (typeof value !== 'string') {
9
+ return null;
10
+ }
11
+ const trimmed = value.trim();
12
+ return trimmed ? trimmed : null;
13
+ };
14
+ const normalizeProposalTickets = (value) => {
15
+ if (!Array.isArray(value)) {
16
+ return [];
17
+ }
18
+ const normalized = [];
19
+ const seenKeys = new Set();
20
+ for (const ticket of value) {
21
+ const key = normalizeRequiredString(ticket?.key);
22
+ const title = normalizeRequiredString(ticket?.title);
23
+ const description = normalizeRequiredString(ticket?.description);
24
+ if (!key || !title || !description) {
25
+ continue;
26
+ }
27
+ const dedupeKey = key.toLowerCase();
28
+ if (seenKeys.has(dedupeKey)) {
29
+ continue;
30
+ }
31
+ seenKeys.add(dedupeKey);
32
+ normalized.push({ key, title, description });
33
+ if (normalized.length >= MAX_CHAT_TICKET_PROPOSALS) {
34
+ break;
35
+ }
36
+ }
37
+ return normalized;
38
+ };
39
+ const normalizeProposalDependencies = (value, ticketKeys) => {
40
+ if (!Array.isArray(value)) {
41
+ return [];
42
+ }
43
+ const normalized = [];
44
+ const seenKeys = new Set();
45
+ for (const dependency of value) {
46
+ const blockerKey = normalizeRequiredString(dependency?.blocker_key);
47
+ const dependentKey = normalizeRequiredString(dependency?.dependent_key);
48
+ if (!blockerKey || !dependentKey || blockerKey === dependentKey) {
49
+ continue;
50
+ }
51
+ if (!ticketKeys.has(blockerKey) || !ticketKeys.has(dependentKey)) {
52
+ continue;
53
+ }
54
+ const dedupeKey = `${blockerKey.toLowerCase()}::${dependentKey.toLowerCase()}`;
55
+ if (seenKeys.has(dedupeKey)) {
56
+ continue;
57
+ }
58
+ seenKeys.add(dedupeKey);
59
+ normalized.push({ blocker_key: blockerKey, dependent_key: dependentKey });
60
+ if (normalized.length >= MAX_CHAT_TICKET_DEPENDENCIES) {
61
+ break;
62
+ }
63
+ }
64
+ return normalized;
65
+ };
66
+ const normalizeCreatedTickets = (value, ticketKeys) => {
67
+ if (!Array.isArray(value)) {
68
+ return [];
69
+ }
70
+ const normalized = [];
71
+ const seenKeys = new Set();
72
+ for (const createdTicket of value) {
73
+ const key = normalizeRequiredString(createdTicket?.key);
74
+ const ticketId = normalizeRequiredString(createdTicket?.ticket_id);
75
+ const title = normalizeRequiredString(createdTicket?.title);
76
+ if (!key || !ticketId || !title || !ticketKeys.has(key)) {
77
+ continue;
78
+ }
79
+ const dedupeKey = key.toLowerCase();
80
+ if (seenKeys.has(dedupeKey)) {
81
+ continue;
82
+ }
83
+ seenKeys.add(dedupeKey);
84
+ normalized.push({ key, ticket_id: ticketId, title });
85
+ }
86
+ return normalized;
87
+ };
88
+ const normalizeStoredChatTicketProposals = (value) => {
89
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
90
+ return null;
91
+ }
92
+ const tickets = normalizeProposalTickets(value.tickets);
93
+ if (tickets.length === 0) {
94
+ return null;
95
+ }
96
+ const ticketKeys = new Set(tickets.map(ticket => ticket.key));
97
+ const dependencies = normalizeProposalDependencies(value.dependencies, ticketKeys);
98
+ const status = value.status === 'applied'
99
+ ? 'applied'
100
+ : 'pending';
101
+ const createdTickets = normalizeCreatedTickets(value.created_tickets, ticketKeys);
102
+ const appliedAt = status === 'applied'
103
+ ? normalizeRequiredString(value.applied_at)
104
+ : null;
105
+ return {
106
+ tickets,
107
+ dependencies,
108
+ status,
109
+ created_tickets: createdTickets,
110
+ applied_at: appliedAt,
111
+ };
112
+ };
113
+ export const CHAT_TICKET_PROPOSAL_PROMPT_RULES = [
114
+ 'Only when the user explicitly asks to create tickets, split work into tickets, or break a plan into board tasks, append a machine-readable block using these exact markers:',
115
+ `<${CHAT_TICKET_PROPOSALS_TAG}>`,
116
+ '{"tickets":[{"key":"ticket-key","title":"Ticket title","description":"Implementation-ready ticket description."}],"dependencies":[{"blocker_key":"ticket-key","dependent_key":"other-ticket-key"}]}',
117
+ `</${CHAT_TICKET_PROPOSALS_TAG}>`,
118
+ '- Omit the block entirely when ticket creation is not requested or would be premature.',
119
+ '- Return between 1 and 5 tickets when you do include the block.',
120
+ '- Each ticket must have a stable `key`, a concise `title`, and a concrete implementation-ready `description`.',
121
+ '- Only include dependencies when one proposed ticket must happen before another.',
122
+ '- The JSON must be valid and must not be wrapped in code fences.',
123
+ ].join('\n');
124
+ export const extractChatTicketProposalsFromOutput = (output) => {
125
+ const match = output.match(new RegExp(`<${CHAT_TICKET_PROPOSALS_TAG}>([\\s\\S]*?)<\\/${CHAT_TICKET_PROPOSALS_TAG}>`));
126
+ if (!match) {
127
+ return {
128
+ cleanedOutput: output.trim(),
129
+ ticketProposals: null,
130
+ };
131
+ }
132
+ let ticketProposals = null;
133
+ try {
134
+ const parsed = JSON.parse(match[1].trim());
135
+ const tickets = normalizeProposalTickets(parsed.tickets);
136
+ if (tickets.length > 0) {
137
+ const ticketKeys = new Set(tickets.map(ticket => ticket.key));
138
+ ticketProposals = {
139
+ tickets,
140
+ dependencies: normalizeProposalDependencies(parsed.dependencies, ticketKeys),
141
+ };
142
+ }
143
+ }
144
+ catch {
145
+ ticketProposals = null;
146
+ }
147
+ return {
148
+ cleanedOutput: stripChatTicketProposalBlock(output),
149
+ ticketProposals,
150
+ };
151
+ };
152
+ export const parseChatTicketProposalsFromMessageContent = (content) => {
153
+ const match = content.match(new RegExp(`<${CHAT_TICKET_PROPOSALS_TAG}>([\\s\\S]*?)<\\/${CHAT_TICKET_PROPOSALS_TAG}>`));
154
+ if (!match) {
155
+ return null;
156
+ }
157
+ try {
158
+ return normalizeStoredChatTicketProposals(JSON.parse(match[1].trim()));
159
+ }
160
+ catch {
161
+ return null;
162
+ }
163
+ };
164
+ export const attachChatTicketProposalsToMessageContent = (content, ticketProposals) => {
165
+ const cleanedContent = stripChatTicketProposalBlock(content);
166
+ const serialized = JSON.stringify(ticketProposals);
167
+ return cleanedContent
168
+ ? `${cleanedContent}\n\n<${CHAT_TICKET_PROPOSALS_TAG}>${serialized}</${CHAT_TICKET_PROPOSALS_TAG}>`
169
+ : `<${CHAT_TICKET_PROPOSALS_TAG}>${serialized}</${CHAT_TICKET_PROPOSALS_TAG}>`;
170
+ };
171
+ export const createPendingChatTicketProposals = (value) => {
172
+ return {
173
+ tickets: value.tickets,
174
+ dependencies: value.dependencies,
175
+ status: 'pending',
176
+ created_tickets: [],
177
+ applied_at: null,
178
+ };
179
+ };
180
+ //# sourceMappingURL=chatTicketProposals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chatTicketProposals.js","sourceRoot":"","sources":["../../../server/lib/chatTicketProposals.ts"],"names":[],"mappings":"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"}