@straiffi/archon 1.4.7 → 1.4.8
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/dist/client/assets/GitHubActionsDialog-ln1X9xDf.js +1 -0
- package/dist/client/assets/{TestsDialog-CcSvemLJ.js → TestsDialog-Cp3Da2W0.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-DJjMJGQa.js → architectureDiagram-3BPJPVTR-CFEtd9pl.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-D7qr0WKZ.js → blockDiagram-GPEHLZMM-9UsBOlSn.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-Dtpwhh8J.js → c4Diagram-AAUBKEIU--TsvWn6X.js} +1 -1
- package/dist/client/assets/channel-BjRPoR7Z.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-BImOu1wB.js → chunk-2J33WTMH-B3FphDWz.js} +1 -1
- package/dist/client/assets/{chunk-3OPIFGDE-WBqy9pqS.js → chunk-3OPIFGDE-CLbUIPKK.js} +1 -1
- package/dist/client/assets/{chunk-5ZQYHXKU-gzwfOytX.js → chunk-5ZQYHXKU-CUHKY5eH.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-DZRDmsY-.js → chunk-727SXJPM-DfKJ4Ud0.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-BNsOD4b1.js → chunk-AQP2D5EJ-B0oLVoZs.js} +1 -1
- package/dist/client/assets/{chunk-CSCIHK7Q-Be5NZf-h.js → chunk-CSCIHK7Q-Czl8GWBW.js} +1 -1
- package/dist/client/assets/{chunk-KSCS5N6A-t3G5p-H3.js → chunk-KSCS5N6A-pOOnuun_.js} +1 -1
- package/dist/client/assets/{chunk-L5ZTLDWV-08eeTRtA.js → chunk-L5ZTLDWV-DzRVeTqf.js} +1 -1
- package/dist/client/assets/{chunk-LZXEDZCA-BhEnRZZ3.js → chunk-LZXEDZCA-MVhzvLVp.js} +2 -2
- package/dist/client/assets/{chunk-ND2GUHAM-n8aRhp2g.js → chunk-ND2GUHAM-BeNiy3nE.js} +1 -1
- package/dist/client/assets/{chunk-NZK2D7GU-BzDdHd-c.js → chunk-NZK2D7GU-CnENvQ9d.js} +1 -1
- package/dist/client/assets/{chunk-O5CBEL6O-B4hb9RKU.js → chunk-O5CBEL6O-CkqDMX_f.js} +1 -1
- package/dist/client/assets/{chunk-WU5MYG2G-95dAWX8f.js → chunk-WU5MYG2G-sJ18xVVM.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-BjzBLL5f.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-BDLW6NLv.js +1 -0
- package/dist/client/assets/{dagre-BM42HDAG-BrFwfUb5.js → dagre-BM42HDAG-BWnmF2aL.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-C-spx6S1.js → diagram-2AECGRRQ-CASRQI5Y.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-CTGmw6IF.js → diagram-5GNKFQAL-CY8fXRrV.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-CGR_6C8P.js → diagram-KO2AKTUF-vtm-gqIm.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-Biu8iKKN.js → diagram-LMA3HP47-Ck-iA5q1.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-CgPqxTkQ.js → diagram-OG6HWLK6-ALBEY2Nn.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-Dvb5W4CZ.js → erDiagram-TEJ5UH35-BAHPzYR7.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-tU7PIdFt.js → flowDiagram-I6XJVG4X-pUYj1KCo.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-Cxn3Y-uw.js → ganttDiagram-6RSMTGT7-zw-EKZcX.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-C3ODPbCH.js → gitGraphDiagram-PVQCEYII-DmPxQKXO.js} +1 -1
- package/dist/client/assets/index-BokL1E46.css +2 -0
- package/dist/client/assets/index-WeECH1eZ.js +260 -0
- package/dist/client/assets/{infoDiagram-5YYISTIA-DI-gw2Xm.js → infoDiagram-5YYISTIA-D0zuFK8l.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-Boo7JuBN.js → ishikawaDiagram-YF4QCWOH-BoNe_Ie6.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-N9__o75J.js → journeyDiagram-JHISSGLW-ByAP1uL0.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-BbtqdHL3.js → kanban-definition-UN3LZRKU-CGXOqdl0.js} +1 -1
- package/dist/client/assets/{line-MwEcOq8D.js → line-BZ3JWBtG.js} +1 -1
- package/dist/client/assets/{mermaid-parser.core-C_-_i9ct.js → mermaid-parser.core-DuHIifHL.js} +1 -1
- package/dist/client/assets/{mermaid.core-jFmh7tic.js → mermaid.core-Co8EqKSU.js} +3 -3
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-cAM3OmtA.js → mindmap-definition-RKZ34NQL-Cv3-5Q_b.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-B7wO_tA6.js → pieDiagram-4H26LBE5-DziVyTJT.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-41IRD1HZ.js → quadrantDiagram-W4KKPZXB-DjNtV4An.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-CRp-2G5Y.js → requirementDiagram-4Y6WPE33-Cs3npD-z.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-C2jxwbv9.js → sankeyDiagram-5OEKKPKP-DxepDJwc.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-C0ifwFNY.js → sequenceDiagram-3UESZ5HK-DIPg-NEj.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-DtkDso6_.js → stateDiagram-AJRCARHV-DUA-Ko9b.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-D6OlcyEp.js +1 -0
- package/dist/client/assets/{timeline-definition-PNZ67QCA-DwL2DqkA.js → timeline-definition-PNZ67QCA-wvi8pREg.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-Cd1A1glE.js → vennDiagram-CIIHVFJN-CabtIweB.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-DpWpjU7R.js → wardleyDiagram-YWT4CUSO-BiOWydTY.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-BROvAGf_.js → xychartDiagram-2RQKCTM6-sWfRgDRl.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/server/db.js +50 -9
- package/dist/server/db.js.map +1 -1
- package/dist/server/index.js +218 -5
- package/dist/server/index.js.map +1 -1
- package/dist/server/lib/attachments.js +36 -26
- package/dist/server/lib/attachments.js.map +1 -1
- package/dist/server/lib/chats.js +2 -2
- package/dist/server/lib/chats.js.map +1 -1
- package/dist/server/lib/integrations/github-issues.js +107 -12
- package/dist/server/lib/integrations/github-issues.js.map +1 -1
- package/dist/server/lib/integrations/importedIssueImages.js +210 -0
- package/dist/server/lib/integrations/importedIssueImages.js.map +1 -0
- package/dist/server/lib/integrations/jira.js +132 -21
- package/dist/server/lib/integrations/jira.js.map +1 -1
- package/dist/server/lib/specOperations.js +9 -4
- package/dist/server/lib/specOperations.js.map +1 -1
- package/dist/server/lib/specs.js +2 -7
- package/dist/server/lib/specs.js.map +1 -1
- package/package.json +1 -1
- package/dist/client/assets/GitHubActionsDialog-B0yRjwYQ.js +0 -1
- package/dist/client/assets/channel-JBvp4GqN.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-vGoYHbZF.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-DuL6ksKg.js +0 -1
- package/dist/client/assets/index--HKq89za.css +0 -2
- package/dist/client/assets/index-QYW4Cu-e.js +0 -260
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-CpWls-En.js +0 -1
package/dist/server/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import { adjectives, animals, uniqueNamesGenerator } from 'unique-names-generato
|
|
|
10
10
|
import db from './db.js';
|
|
11
11
|
import { deleteChatSession, getChatSession, listChatSessions, updateChatSessionMode } from './lib/chats.js';
|
|
12
12
|
import { deleteSpecSession, getCreatedTicketIdsForSnapshot, getSpecSession, getSpecSnapshot, listSpecSessions } from './lib/specs.js';
|
|
13
|
-
import { createChatAttachment, createSpecAttachment, deleteChatAttachment, deleteSpecSessionAttachment,
|
|
13
|
+
import { createChatAttachment, createSpecAttachment, getAttachmentById, deleteChatAttachment, deleteSpecSessionAttachment, getChatAttachmentForSession, getChatAttachmentLinkedMessageId, getSpecAttachmentForSession, getSpecAttachmentLinkedMessageId, MAX_CHAT_ATTACHMENTS_PER_TURN, MAX_CHAT_ATTACHMENT_SIZE_BYTES, MAX_SPEC_ATTACHMENTS_PER_TURN, MAX_SPEC_ATTACHMENT_SIZE_BYTES, readChatAttachmentContent, readSpecAttachmentContent, validateImageAttachment, } from './lib/attachments.js';
|
|
14
14
|
import { createProjectChatSession, resolveChatMode, resolveChatTool, stopProjectChatSessionResponse, submitProjectChatSessionMessage, } from './lib/chatOperations.js';
|
|
15
15
|
import { createProjectSpecSession, deleteProjectSpecSession, stopProjectSpecSessionResponse, submitProjectSpecSessionMessage, updateProjectSpecSessionMode, } from './lib/specOperations.js';
|
|
16
16
|
import { buildProjectSpecReviewRevisionDraft, getProjectSpecReviewFindings, startProjectSpecReview, stopProjectSpecReview, } from './lib/specReviewOperations.js';
|
|
@@ -49,8 +49,9 @@ import { shutdownRealtimeServer } from './lib/shutdown.js';
|
|
|
49
49
|
import { resolveClientBuildPaths, shouldServeClientApp, STATIC_CLIENT_DIRECTORY_OPTIONS, STATIC_CLIENT_INDEX_OPTIONS, } from './lib/staticClient.js';
|
|
50
50
|
import { deleteIntegrationConnection, getGitHubConnectionConfig, getJiraConnectionConfig, listIntegrationConnections, upsertIntegrationConnection, } from './lib/integrations/index.js';
|
|
51
51
|
import { createGitHubPullRequest, createOrFindGitHubPullRequest, findOpenGitHubPullRequest, findOpenGitHubPullRequestByHeadBranch, getGitHubPullRequestComments, getGitHubPullRequestReviews, getGitHubPullRequest, GitHubApiError, hasGitHubRemoteBranch, resolveGitHubRepository, validateGitHubConnection, } from './lib/integrations/github.js';
|
|
52
|
-
import { importJiraIssue, JiraApiError, validateJiraConnection } from './lib/integrations/jira.js';
|
|
53
|
-
import { importGitHubIssue } from './lib/integrations/github-issues.js';
|
|
52
|
+
import { importJiraIssue, JiraApiError, prepareJiraIssueImport, validateJiraConnection } from './lib/integrations/jira.js';
|
|
53
|
+
import { importGitHubIssue, prepareGitHubIssueImport } from './lib/integrations/github-issues.js';
|
|
54
|
+
import { buildImportedIssueSessionTitle, importProviderHostedIssueImages } from './lib/integrations/importedIssueImages.js';
|
|
54
55
|
import { dispatchGitHubWorkflow, getGitHubWorkflowDispatchConfig, getGitHubWorkflowRun, getGitHubWorkflowRunJobs, listGitHubWorkflows, listGitHubWorkflowRuns, } from './lib/integrations/githubActions.js';
|
|
55
56
|
import { clearAllGitHubActionsSessions, getActiveTrackedRunCount, getTrackedGitHubActionsRuns, trackGitHubActionsRun, } from './lib/integrations/githubActionsSessions.js';
|
|
56
57
|
import { PlanningReferenceError, resolveExternalPlanningDescription } from './lib/integrations/planning.js';
|
|
@@ -2068,7 +2069,7 @@ app.post('/projects/:id/chat-sessions/:sessionId/attachments', (req, res) => {
|
|
|
2068
2069
|
}
|
|
2069
2070
|
catch (uploadError) {
|
|
2070
2071
|
for (const attachmentId of createdAttachmentIds) {
|
|
2071
|
-
const attachment =
|
|
2072
|
+
const attachment = getAttachmentById(attachmentId);
|
|
2072
2073
|
if (!attachment) {
|
|
2073
2074
|
continue;
|
|
2074
2075
|
}
|
|
@@ -2353,7 +2354,7 @@ app.post('/projects/:id/spec-sessions/:sessionId/attachments', (req, res) => {
|
|
|
2353
2354
|
}
|
|
2354
2355
|
catch (uploadError) {
|
|
2355
2356
|
for (const attachmentId of createdAttachmentIds) {
|
|
2356
|
-
const attachment =
|
|
2357
|
+
const attachment = getAttachmentById(attachmentId);
|
|
2357
2358
|
if (!attachment) {
|
|
2358
2359
|
continue;
|
|
2359
2360
|
}
|
|
@@ -3580,6 +3581,76 @@ app.get('/integrations', (req, res) => {
|
|
|
3580
3581
|
}
|
|
3581
3582
|
return res.json({ connections: listIntegrationConnections(result.project.id) });
|
|
3582
3583
|
});
|
|
3584
|
+
const NOOP_BROADCASTER = {
|
|
3585
|
+
emit: () => undefined,
|
|
3586
|
+
};
|
|
3587
|
+
const buildSpecImportSessionPayload = (payload, draft) => {
|
|
3588
|
+
return {
|
|
3589
|
+
tool: payload?.tool,
|
|
3590
|
+
mode: payload?.mode,
|
|
3591
|
+
model: payload?.model,
|
|
3592
|
+
variant: payload?.variant,
|
|
3593
|
+
skills: payload?.skills,
|
|
3594
|
+
title: buildImportedIssueSessionTitle(draft),
|
|
3595
|
+
external_source: draft.external_source,
|
|
3596
|
+
};
|
|
3597
|
+
};
|
|
3598
|
+
const prepareSpecImportResponse = async ({ projectId, payload, preparedDraft, importOptions, broadcaster, }) => {
|
|
3599
|
+
const draft = {
|
|
3600
|
+
title: preparedDraft.title,
|
|
3601
|
+
description: preparedDraft.description,
|
|
3602
|
+
external_source: preparedDraft.external_source,
|
|
3603
|
+
};
|
|
3604
|
+
const imported = await importProviderHostedIssueImages({
|
|
3605
|
+
...importOptions,
|
|
3606
|
+
draft,
|
|
3607
|
+
imageCandidates: preparedDraft.image_candidates,
|
|
3608
|
+
});
|
|
3609
|
+
if (imported.importedImages.length === 0) {
|
|
3610
|
+
return {
|
|
3611
|
+
draft,
|
|
3612
|
+
prompt_text: imported.promptText,
|
|
3613
|
+
external_source: draft.external_source,
|
|
3614
|
+
spec_session: null,
|
|
3615
|
+
imported_attachments: [],
|
|
3616
|
+
import_notice: imported.notice,
|
|
3617
|
+
};
|
|
3618
|
+
}
|
|
3619
|
+
const createResult = createProjectSpecSession({
|
|
3620
|
+
projectId,
|
|
3621
|
+
payload: buildSpecImportSessionPayload(payload, draft),
|
|
3622
|
+
broadcaster: NOOP_BROADCASTER,
|
|
3623
|
+
});
|
|
3624
|
+
if (!createResult.ok) {
|
|
3625
|
+
throw new HttpError(createResult.status, createResult.error);
|
|
3626
|
+
}
|
|
3627
|
+
if (!createResult.value) {
|
|
3628
|
+
throw new Error('Unable to create the imported spec session.');
|
|
3629
|
+
}
|
|
3630
|
+
const specSession = createResult.value;
|
|
3631
|
+
try {
|
|
3632
|
+
const importedAttachments = imported.importedImages.map(image => createSpecAttachment({
|
|
3633
|
+
specSessionId: specSession.id,
|
|
3634
|
+
originalName: image.originalName,
|
|
3635
|
+
mimeType: image.mimeType,
|
|
3636
|
+
buffer: image.buffer,
|
|
3637
|
+
projectId,
|
|
3638
|
+
}));
|
|
3639
|
+
broadcaster.emit('spec-session:created', specSession);
|
|
3640
|
+
return {
|
|
3641
|
+
draft,
|
|
3642
|
+
prompt_text: imported.promptText,
|
|
3643
|
+
external_source: draft.external_source,
|
|
3644
|
+
spec_session: specSession,
|
|
3645
|
+
imported_attachments: importedAttachments,
|
|
3646
|
+
import_notice: imported.notice,
|
|
3647
|
+
};
|
|
3648
|
+
}
|
|
3649
|
+
catch (error) {
|
|
3650
|
+
deleteSpecSession(specSession.id);
|
|
3651
|
+
throw error;
|
|
3652
|
+
}
|
|
3653
|
+
};
|
|
3583
3654
|
app.post('/integrations/github/connect', async (req, res) => {
|
|
3584
3655
|
const result = getRequiredProject(req);
|
|
3585
3656
|
if ('error' in result) {
|
|
@@ -3751,6 +3822,77 @@ app.post('/integrations/jira/resolve/issue', async (req, res) => {
|
|
|
3751
3822
|
return res.status(500).json({ error: getErrorMessage(error) || 'Unable to import the Jira issue.' });
|
|
3752
3823
|
}
|
|
3753
3824
|
});
|
|
3825
|
+
app.post('/integrations/jira/prepare-spec-import', async (req, res) => {
|
|
3826
|
+
const result = getRequiredProject(req);
|
|
3827
|
+
if ('error' in result) {
|
|
3828
|
+
return res.status(400).json({ error: result.error });
|
|
3829
|
+
}
|
|
3830
|
+
const jiraConfig = getJiraConnectionConfig(result.project.id);
|
|
3831
|
+
if (!jiraConfig) {
|
|
3832
|
+
return res.status(400).json({ error: 'Jira is not connected for this project.' });
|
|
3833
|
+
}
|
|
3834
|
+
const issue = asTrimmedString(req.body?.issue);
|
|
3835
|
+
if (!issue) {
|
|
3836
|
+
return res.status(400).json({ error: 'issue is required' });
|
|
3837
|
+
}
|
|
3838
|
+
try {
|
|
3839
|
+
const prepared = await prepareJiraIssueImport(jiraConfig, issue);
|
|
3840
|
+
const response = await prepareSpecImportResponse({
|
|
3841
|
+
projectId: result.project.id,
|
|
3842
|
+
payload: req.body,
|
|
3843
|
+
preparedDraft: prepared,
|
|
3844
|
+
importOptions: { provider: 'jira', config: jiraConfig },
|
|
3845
|
+
broadcaster: io,
|
|
3846
|
+
});
|
|
3847
|
+
return res.json(response);
|
|
3848
|
+
}
|
|
3849
|
+
catch (error) {
|
|
3850
|
+
console.warn(`[integrations] jira spec import failed project=${result.project.id} issue=${issue}`, error);
|
|
3851
|
+
if (error instanceof JiraApiError) {
|
|
3852
|
+
return res.status(error.status).json({ error: error.publicMessage });
|
|
3853
|
+
}
|
|
3854
|
+
if (error instanceof HttpError) {
|
|
3855
|
+
return res.status(error.status).json({ error: error.message });
|
|
3856
|
+
}
|
|
3857
|
+
return res.status(500).json({ error: getErrorMessage(error) || 'Unable to prepare the Jira issue for spec import.' });
|
|
3858
|
+
}
|
|
3859
|
+
});
|
|
3860
|
+
app.post('/integrations/jira/prepare/spec-import', async (req, res) => {
|
|
3861
|
+
const result = getRequiredProject(req);
|
|
3862
|
+
if ('error' in result) {
|
|
3863
|
+
return res.status(400).json({ error: result.error });
|
|
3864
|
+
}
|
|
3865
|
+
const jiraConfig = getJiraConnectionConfig(result.project.id);
|
|
3866
|
+
if (!jiraConfig) {
|
|
3867
|
+
return res.status(400).json({ error: 'Jira is not connected for this project.' });
|
|
3868
|
+
}
|
|
3869
|
+
const issue = asTrimmedString(req.body?.issue);
|
|
3870
|
+
if (!issue) {
|
|
3871
|
+
return res.status(400).json({ error: 'issue is required' });
|
|
3872
|
+
}
|
|
3873
|
+
console.info(`[integrations] jira prepare spec import project=${result.project.id} issue=${issue}`);
|
|
3874
|
+
try {
|
|
3875
|
+
const prepared = await prepareJiraIssueImport(jiraConfig, issue);
|
|
3876
|
+
const response = await prepareSpecImportResponse({
|
|
3877
|
+
projectId: result.project.id,
|
|
3878
|
+
payload: req.body,
|
|
3879
|
+
preparedDraft: prepared,
|
|
3880
|
+
importOptions: { provider: 'jira', config: jiraConfig },
|
|
3881
|
+
broadcaster: io,
|
|
3882
|
+
});
|
|
3883
|
+
return res.json(response);
|
|
3884
|
+
}
|
|
3885
|
+
catch (error) {
|
|
3886
|
+
console.warn(`[integrations] jira prepare spec import failed project=${result.project.id} issue=${issue}`, error);
|
|
3887
|
+
if (error instanceof JiraApiError) {
|
|
3888
|
+
return res.status(error.status).json({ error: error.publicMessage });
|
|
3889
|
+
}
|
|
3890
|
+
if (error instanceof HttpError) {
|
|
3891
|
+
return res.status(error.status).json({ error: error.message });
|
|
3892
|
+
}
|
|
3893
|
+
return res.status(500).json({ error: getErrorMessage(error) || 'Unable to prepare the Jira issue for spec import.' });
|
|
3894
|
+
}
|
|
3895
|
+
});
|
|
3754
3896
|
app.post('/integrations/github/resolve/issue', async (req, res) => {
|
|
3755
3897
|
const result = getRequiredProject(req);
|
|
3756
3898
|
if ('error' in result) {
|
|
@@ -3780,6 +3922,77 @@ app.post('/integrations/github/resolve/issue', async (req, res) => {
|
|
|
3780
3922
|
return res.status(500).json({ error: getErrorMessage(error) || 'Unable to import the GitHub issue.' });
|
|
3781
3923
|
}
|
|
3782
3924
|
});
|
|
3925
|
+
app.post('/integrations/github/prepare-spec-import', async (req, res) => {
|
|
3926
|
+
const result = getRequiredProject(req);
|
|
3927
|
+
if ('error' in result) {
|
|
3928
|
+
return res.status(400).json({ error: result.error });
|
|
3929
|
+
}
|
|
3930
|
+
const githubConfig = getGitHubConnectionConfig(result.project.id);
|
|
3931
|
+
if (!githubConfig) {
|
|
3932
|
+
return res.status(400).json({ error: 'GitHub is not connected for this project.' });
|
|
3933
|
+
}
|
|
3934
|
+
const issue = asTrimmedString(req.body?.issue);
|
|
3935
|
+
if (!issue) {
|
|
3936
|
+
return res.status(400).json({ error: 'issue is required' });
|
|
3937
|
+
}
|
|
3938
|
+
try {
|
|
3939
|
+
const prepared = await prepareGitHubIssueImport(githubConfig, issue);
|
|
3940
|
+
const response = await prepareSpecImportResponse({
|
|
3941
|
+
projectId: result.project.id,
|
|
3942
|
+
payload: req.body,
|
|
3943
|
+
preparedDraft: prepared,
|
|
3944
|
+
importOptions: { provider: 'github', config: githubConfig },
|
|
3945
|
+
broadcaster: io,
|
|
3946
|
+
});
|
|
3947
|
+
return res.json(response);
|
|
3948
|
+
}
|
|
3949
|
+
catch (error) {
|
|
3950
|
+
console.warn(`[integrations] github spec import failed project=${result.project.id} issue=${issue}`, error);
|
|
3951
|
+
if (error instanceof GitHubApiError) {
|
|
3952
|
+
return res.status(error.status).json({ error: error.publicMessage });
|
|
3953
|
+
}
|
|
3954
|
+
if (error instanceof HttpError) {
|
|
3955
|
+
return res.status(error.status).json({ error: error.message });
|
|
3956
|
+
}
|
|
3957
|
+
return res.status(500).json({ error: getErrorMessage(error) || 'Unable to prepare the GitHub issue for spec import.' });
|
|
3958
|
+
}
|
|
3959
|
+
});
|
|
3960
|
+
app.post('/integrations/github/prepare/spec-import', async (req, res) => {
|
|
3961
|
+
const result = getRequiredProject(req);
|
|
3962
|
+
if ('error' in result) {
|
|
3963
|
+
return res.status(400).json({ error: result.error });
|
|
3964
|
+
}
|
|
3965
|
+
const githubConfig = getGitHubConnectionConfig(result.project.id);
|
|
3966
|
+
if (!githubConfig) {
|
|
3967
|
+
return res.status(400).json({ error: 'GitHub is not connected for this project.' });
|
|
3968
|
+
}
|
|
3969
|
+
const issue = asTrimmedString(req.body?.issue);
|
|
3970
|
+
if (!issue) {
|
|
3971
|
+
return res.status(400).json({ error: 'issue is required' });
|
|
3972
|
+
}
|
|
3973
|
+
console.info(`[integrations] github prepare spec import project=${result.project.id} issue=${issue}`);
|
|
3974
|
+
try {
|
|
3975
|
+
const prepared = await prepareGitHubIssueImport(githubConfig, issue);
|
|
3976
|
+
const response = await prepareSpecImportResponse({
|
|
3977
|
+
projectId: result.project.id,
|
|
3978
|
+
payload: req.body,
|
|
3979
|
+
preparedDraft: prepared,
|
|
3980
|
+
importOptions: { provider: 'github', config: githubConfig },
|
|
3981
|
+
broadcaster: io,
|
|
3982
|
+
});
|
|
3983
|
+
return res.json(response);
|
|
3984
|
+
}
|
|
3985
|
+
catch (error) {
|
|
3986
|
+
console.warn(`[integrations] github prepare spec import failed project=${result.project.id} issue=${issue}`, error);
|
|
3987
|
+
if (error instanceof GitHubApiError) {
|
|
3988
|
+
return res.status(error.status).json({ error: error.publicMessage });
|
|
3989
|
+
}
|
|
3990
|
+
if (error instanceof HttpError) {
|
|
3991
|
+
return res.status(error.status).json({ error: error.message });
|
|
3992
|
+
}
|
|
3993
|
+
return res.status(500).json({ error: getErrorMessage(error) || 'Unable to prepare the GitHub issue for spec import.' });
|
|
3994
|
+
}
|
|
3995
|
+
});
|
|
3783
3996
|
app.get('/integrations/github/actions/workflows', async (req, res) => {
|
|
3784
3997
|
const result = getRequiredProject(req);
|
|
3785
3998
|
if ('error' in result) {
|