@straiffi/archon 1.6.2 → 1.7.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.
- package/dist/client/assets/{GitHubActionsDialog-YYq8JstU.js → GitHubActionsDialog-B9_WJBOp.js} +1 -1
- package/dist/client/assets/TestsDialog-DKvbjH_M.js +4 -0
- package/dist/client/assets/TicketChangesModal-C8rFoKjY.js +1 -0
- package/dist/client/assets/{arc-CnuHRbeq.js → arc-D2Nn9xIj.js} +1 -1
- package/dist/client/assets/architecture-7EHR7CIX-C-4Cp4ml.js +1 -0
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-GehFBNFz.js → architectureDiagram-3BPJPVTR-DXRSRLL9.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-CTFXIE8q.js → blockDiagram-GPEHLZMM-D7EE6Dnv.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-BY9e8TiT.js → c4Diagram-AAUBKEIU-UhVzFafr.js} +1 -1
- package/dist/client/assets/channel-CNoEXkwa.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-Ck8V3BxZ.js → chunk-2J33WTMH-obbfylVr.js} +1 -1
- package/dist/client/assets/{chunk-3OPIFGDE-DvZbg_ji.js → chunk-3OPIFGDE-DPVuS-uo.js} +1 -1
- package/dist/client/assets/{chunk-4BX2VUAB-_WBpCe0m.js → chunk-4BX2VUAB-CtLS8D71.js} +1 -1
- package/dist/client/assets/{chunk-4EGX6M5U-BBQHxMeA.js → chunk-4EGX6M5U-Btnm0QNe.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-B-d-YzxI.js → chunk-55IACEB6-74CcJaub.js} +1 -1
- package/dist/client/assets/{chunk-5DO6E6H7-BA-oSVa-.js → chunk-5DO6E6H7-WLZ8L4ko.js} +1 -1
- package/dist/client/assets/{chunk-5ZQYHXKU-DZL6nSFA.js → chunk-5ZQYHXKU-Dsc03vy9.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-DMy23TqS.js → chunk-727SXJPM-COE-iq_Z.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-Ch4juSfK.js → chunk-AQP2D5EJ-DnbAdr8m.js} +1 -1
- package/dist/client/assets/{chunk-BR22UD5L-prWX503j.js → chunk-BR22UD5L-Cou5beGe.js} +1 -1
- package/dist/client/assets/{chunk-BSJP7CBP-CNtf2uaW.js → chunk-BSJP7CBP-DJ57XcV5.js} +1 -1
- package/dist/client/assets/{chunk-CSCIHK7Q-BSL0qTfP.js → chunk-CSCIHK7Q-DbTzC_WS.js} +2 -2
- package/dist/client/assets/{chunk-FHYWG6QK-BQ8n0J0S.js → chunk-FHYWG6QK-Ba10e2kj.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-CWQN4V4s.js → chunk-FMBD7UC4-CEo2wZMx.js} +1 -1
- package/dist/client/assets/{chunk-KSCS5N6A-C1zDfxY8.js → chunk-KSCS5N6A-xvviIayr.js} +1 -1
- package/dist/client/assets/{chunk-L5ZTLDWV-D8yXktZ8.js → chunk-L5ZTLDWV-DY4Q9Til.js} +1 -1
- package/dist/client/assets/{chunk-LZXEDZCA-CjmFVV-I.js → chunk-LZXEDZCA-Bbeq2DZs.js} +2 -2
- package/dist/client/assets/{chunk-MPE355IW-gHN8AuU_.js → chunk-MPE355IW-MqEt-J8G.js} +1 -1
- package/dist/client/assets/{chunk-MZUSXYTE-Clzaz1kK.js → chunk-MZUSXYTE-DdNi9lhx.js} +1 -1
- package/dist/client/assets/{chunk-N66VUXT2-CkkAOkdt.js → chunk-N66VUXT2-CjemTW4E.js} +1 -1
- package/dist/client/assets/{chunk-ND2GUHAM-Dc6gtC7r.js → chunk-ND2GUHAM-CylX1p3K.js} +1 -1
- package/dist/client/assets/{chunk-NZK2D7GU-CJMnwR03.js → chunk-NZK2D7GU-BTcALpQq.js} +1 -1
- package/dist/client/assets/{chunk-O5CBEL6O-BW2gf35w.js → chunk-O5CBEL6O-Be_5dk2_.js} +1 -1
- package/dist/client/assets/{chunk-PUPMXCY4-DAdQFv8j.js → chunk-PUPMXCY4-ZvwTw0To.js} +1 -1
- package/dist/client/assets/chunk-QZHKN3VN-LI_RZca2.js +1 -0
- package/dist/client/assets/{chunk-UIBZB4QT-BRR84OYN.js → chunk-UIBZB4QT-BTY9be9s.js} +1 -1
- package/dist/client/assets/{chunk-WCWK7LTN-CQU7Fs_W.js → chunk-WCWK7LTN-Db1n3n3-.js} +1 -1
- package/dist/client/assets/chunk-WU5MYG2G-DXPsSM4Q.js +1 -0
- package/dist/client/assets/{chunk-XPW4576I-DafcxlUi.js → chunk-XPW4576I-DObFPxjB.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-BgmK8-LI.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-Dj5LqBjo.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-DhJHP9hr.js → cose-bilkent-S5V4N54A-MlOPiG6P.js} +1 -1
- package/dist/client/assets/{dagre-BM42HDAG-vmxXhZ0y.js → dagre-BM42HDAG-CABUW7xK.js} +1 -1
- package/dist/client/assets/{dagre-CdwzCXQr.js → dagre-BWNHuDdf.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-Bf7MS2bc.js → diagram-2AECGRRQ-KvcNrpvf.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-Br3zBMUu.js → diagram-5GNKFQAL-DQV6-I4e.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-DTzQBils.js → diagram-KO2AKTUF-DYDk9roD.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-BT-zhfvW.js → diagram-LMA3HP47-Da-0u-HG.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-BkJWuAdb.js → diagram-OG6HWLK6-CuD5eRBv.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-DLuUFa06.js → erDiagram-TEJ5UH35-BL5dBE-b.js} +1 -1
- package/dist/client/assets/eventmodeling-FCH6USID-Dqb6QKoI.js +1 -0
- package/dist/client/assets/{flowDiagram-I6XJVG4X-DqxBy0Eu.js → flowDiagram-I6XJVG4X-Bke5cWs7.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-lxV5wli4.js → ganttDiagram-6RSMTGT7-5OD-ayGn.js} +1 -1
- package/dist/client/assets/gitGraph-WXDBUCRP-DYEsqh93.js +1 -0
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-iEzJEXy_.js → gitGraphDiagram-PVQCEYII-7Cf6FVfO.js} +1 -1
- package/dist/client/assets/index-D8EniXuq.css +2 -0
- package/dist/client/assets/index-DXuxAAzf.js +270 -0
- package/dist/client/assets/info-J43DQDTF-CfjXFZai.js +1 -0
- package/dist/client/assets/{infoDiagram-5YYISTIA-mjHIc-rc.js → infoDiagram-5YYISTIA-BchMN9V-.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-C3mJymgB.js → ishikawaDiagram-YF4QCWOH-D6TchjQy.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-Bl7pH31i.js → journeyDiagram-JHISSGLW-CwEcoeX-.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-iL68fF8o.js → kanban-definition-UN3LZRKU-S2V9CLGR.js} +1 -1
- package/dist/client/assets/{line-BbGkhDvA.js → line-DRheChzQ.js} +1 -1
- package/dist/client/assets/{linear-DFIW-KnM.js → linear-DT4rSZvy.js} +1 -1
- package/dist/client/assets/{mermaid-parser.core-3NnYiOiR.js → mermaid-parser.core-CN13XjLe.js} +2 -2
- package/dist/client/assets/{mermaid.core-BdUaWj-Y.js → mermaid.core-JhdSpoF5.js} +3 -3
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-sDh1lwIs.js → mindmap-definition-RKZ34NQL-657TKwRB.js} +1 -1
- package/dist/client/assets/{ordinal-C1FS1Sfe.js → ordinal-k--hYEme.js} +1 -1
- package/dist/client/assets/packet-YPE3B663-Dv0HkRHU.js +1 -0
- package/dist/client/assets/pie-LRSECV5Y-S5zPzZFN.js +1 -0
- package/dist/client/assets/{pieDiagram-4H26LBE5-CmkeWRGt.js → pieDiagram-4H26LBE5-DJ8eQ94X.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-CusAc0KA.js → quadrantDiagram-W4KKPZXB-GpYFqyb1.js} +1 -1
- package/dist/client/assets/radar-GUYGQ44K-B7psLv22.js +1 -0
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-DRjpIANs.js → requirementDiagram-4Y6WPE33-COZFWgq1.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-DNpufJOV.js → sankeyDiagram-5OEKKPKP-BdCHyfcQ.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-BD5zE-V4.js → sequenceDiagram-3UESZ5HK-DAh3Ogx0.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-fCUNQluV.js → stateDiagram-AJRCARHV-Ck8Yie8_.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-B6zibRqD.js +1 -0
- package/dist/client/assets/{timeline-definition-PNZ67QCA-C4u3WsSc.js → timeline-definition-PNZ67QCA-kYr9DNtP.js} +1 -1
- package/dist/client/assets/treeView-BLDUP644-B8H0kT67.js +1 -0
- package/dist/client/assets/treemap-LRROVOQU-DPLhFHnh.js +1 -0
- package/dist/client/assets/{vennDiagram-CIIHVFJN-HdgYgPYH.js → vennDiagram-CIIHVFJN-CC_SlRiC.js} +1 -1
- package/dist/client/assets/wardley-L42UT6IY-B5-Vb08V.js +1 -0
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-mtIAqcj8.js → wardleyDiagram-YWT4CUSO-CZ17ccSN.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-CekNHwM1.js → xychartDiagram-2RQKCTM6-Blqaj-ci.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/server/index.js +139 -2
- package/dist/server/index.js.map +1 -1
- package/dist/server/lib/git.js +19 -3
- package/dist/server/lib/git.js.map +1 -1
- package/dist/server/lib/previewProxy.js +5 -0
- package/dist/server/lib/previewProxy.js.map +1 -1
- package/dist/server/lib/projectFiles.js +313 -0
- package/dist/server/lib/projectFiles.js.map +1 -0
- package/dist/server/workers/followUp.js +1 -0
- package/dist/server/workers/followUp.js.map +1 -1
- package/package.json +1 -1
- package/dist/client/assets/TestsDialog-BDV84HfF.js +0 -4
- package/dist/client/assets/architecture-7EHR7CIX-tSrokdFP.js +0 -1
- package/dist/client/assets/channel-BHDgEkkI.js +0 -1
- package/dist/client/assets/chunk-QZHKN3VN-biOr9EeQ.js +0 -1
- package/dist/client/assets/chunk-WU5MYG2G-6nbIEzjM.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-eaJS9esZ.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-DjTlDKs4.js +0 -1
- package/dist/client/assets/eventmodeling-FCH6USID-DapHLQIh.js +0 -1
- package/dist/client/assets/gitGraph-WXDBUCRP-BTBN_hfb.js +0 -1
- package/dist/client/assets/index-B3KA0m7e.css +0 -2
- package/dist/client/assets/index-BnMFJ-iq.js +0 -265
- package/dist/client/assets/info-J43DQDTF-CgiMJYKF.js +0 -1
- package/dist/client/assets/packet-YPE3B663-Bnwqjena.js +0 -1
- package/dist/client/assets/pie-LRSECV5Y-Ctj0ef-4.js +0 -1
- package/dist/client/assets/radar-GUYGQ44K-DE0H_saz.js +0 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-CaE9ItcI.js +0 -1
- package/dist/client/assets/treeView-BLDUP644-CSAZL2OH.js +0 -1
- package/dist/client/assets/treemap-LRROVOQU-tYm4XKfP.js +0 -1
- package/dist/client/assets/wardley-L42UT6IY-DdiEFppm.js +0 -1
- /package/dist/client/assets/{array-B57E4cSs.js → array-BNor45A1.js} +0 -0
- /package/dist/client/assets/{chunk-NNHCCRGN-DRSAMe5H.js → chunk-NNHCCRGN-CZB-V-Gv.js} +0 -0
- /package/dist/client/assets/{cytoscape.esm-CVYSm6AJ.js → cytoscape.esm-B2lJcMSI.js} +0 -0
- /package/dist/client/assets/{defaultLocale-6WHJ3B09.js → defaultLocale-DPzUsThw.js} +0 -0
- /package/dist/client/assets/{dist-By2zKKTF.js → dist-CERhmQhR.js} +0 -0
- /package/dist/client/assets/{graphlib-B0DVs0bw.js → graphlib-BHOW-eWz.js} +0 -0
- /package/dist/client/assets/{init-DiYCGS1R.js → init-C0L3woqb.js} +0 -0
- /package/dist/client/assets/{katex-bgJu_0Fy.js → katex-CpjQsUQe.js} +0 -0
- /package/dist/client/assets/{path-DL_QDy2X.js → path-sMK4d_s9.js} +0 -0
- /package/dist/client/assets/{rough.esm-Bbn_-PMU.js → rough.esm-BoTisKeL.js} +0 -0
- /package/dist/client/assets/{src-Bi_byJUe.js → src-BRjoYtUW.js} +0 -0
package/dist/server/index.js
CHANGED
|
@@ -18,7 +18,7 @@ import { resolveChatSessionTarget } from './lib/chatTargets.js';
|
|
|
18
18
|
import { createChatMessage, getChatMessage, updateChatMessageContent } from './lib/chatMessages.js';
|
|
19
19
|
import { attachChatTicketProposalsToMessageContent } from './lib/chatTicketProposals.js';
|
|
20
20
|
import { createCorsOriginResolver, parseCorsOrigins } from './lib/cors.js';
|
|
21
|
-
import { abortGitOperation, branchExistsLocally, commitGitChanges, createWorktreeAsync, deleteWorktree, getBundleReviewDiffForCwd, getGitDiffData, getGitDiffFiles, getGitStatus, getGitUnifiedDiff, getProjectBranch, getProjectBranchSuggestions, getSelectedGitUnifiedDiff, hasKnownBranchRef, listUnpushedCommitsForCwd, pullGitBranch, pushCurrentBranch, rebaseGitBranchOntoBase, resolveExistingWorktreePath, resolveWorktreePath, summarizeTicketDiffFiles, switchProjectBranch, syncWorktreeFilesAsync, undoLatestUnpushedCommitForCwd } from './lib/git.js';
|
|
21
|
+
import { abortGitOperation, branchExistsLocally, commitGitChanges, createWorktreeAsync, deleteWorktree, getBundleReviewDiffForCwd, getGitDiffData, getGitDiffFiles, getGitStatus, getGitUnifiedDiff, getLocalProjectBranch, getProjectBranch, getProjectBranchSuggestions, getSelectedGitUnifiedDiff, hasKnownBranchRef, listUnpushedCommitsForCwd, pullGitBranch, pushCurrentBranch, rebaseGitBranchOntoBase, resolveExistingWorktreePath, resolveWorktreePath, summarizeTicketDiffFiles, switchProjectBranch, syncWorktreeFilesAsync, undoLatestUnpushedCommitForCwd } from './lib/git.js';
|
|
22
22
|
import config from './lib/config.js';
|
|
23
23
|
import { autoConfigProject, ProjectAutoConfigError } from './lib/projectAutoConfig.js';
|
|
24
24
|
import { analyzeRepoPath, createInitialCommit, ensureInitialCommitForWorktrees, initializeGitRepo, isInitialCommitRequiredError, } from './lib/projectRepos.js';
|
|
@@ -41,6 +41,7 @@ import { listProjectMemoryEvents } from './lib/projectMemoryEvents.js';
|
|
|
41
41
|
import { getProjectMemorySelectionForAgentRun, listProjectMemoryUsage } from './lib/projectMemorySelections.js';
|
|
42
42
|
import { decodeProjectMemoryCursor } from './lib/projectMemoryCursor.js';
|
|
43
43
|
import { getProjectFileSuggestions } from './lib/projectFileSuggestions.js';
|
|
44
|
+
import { getProjectFileManifest, ProjectFileContentError, ProjectFileTargetUnavailableError, readProjectFileContent } from './lib/projectFiles.js';
|
|
44
45
|
import { updateProjectTargetSelection } from './lib/projectTargets.js';
|
|
45
46
|
import { exportProjectMemoryArchive, importProjectMemoryArchive } from './lib/projectMemoryTransfer.js';
|
|
46
47
|
import { buildReviewFindingsResponse, computeDiffSignature, getLatestReviewRunForContext, listReviewFindings } from './lib/reviewFindings.js';
|
|
@@ -835,6 +836,87 @@ const resolveProjectFileSuggestionWorkspace = (project, options = {}) => {
|
|
|
835
836
|
cacheKey: `target:${workspace.target_kind}:${workspace.target_bundle_id ?? 'repo_root'}:${workspace.cwd}`,
|
|
836
837
|
};
|
|
837
838
|
};
|
|
839
|
+
const resolveWorkspaceFileWorkspace = (project, targetKind, bundleId, ticketId) => {
|
|
840
|
+
if (targetKind === 'repo_root') {
|
|
841
|
+
if (!existsSync(project.repo_path)) {
|
|
842
|
+
return { error: 'Repository target is unavailable', status: 409 };
|
|
843
|
+
}
|
|
844
|
+
return {
|
|
845
|
+
cwd: project.repo_path,
|
|
846
|
+
branch: getLocalProjectBranch(project),
|
|
847
|
+
project,
|
|
848
|
+
cacheKey: `workspace-files:${project.id}:repo_root:${project.repo_path}`,
|
|
849
|
+
target: { kind: 'repo_root', bundle_id: null, ticket_id: null },
|
|
850
|
+
};
|
|
851
|
+
}
|
|
852
|
+
if (targetKind === 'bundle') {
|
|
853
|
+
if (!bundleId) {
|
|
854
|
+
return { error: 'bundle_id is required for a bundle target', status: 400 };
|
|
855
|
+
}
|
|
856
|
+
const bundle = getBundle(bundleId, project.id);
|
|
857
|
+
if (!bundle || isProjectRootBundle(bundle)) {
|
|
858
|
+
return { error: 'Bundle target not found', status: 404 };
|
|
859
|
+
}
|
|
860
|
+
const cwd = resolveExistingWorktreePath(bundle.branch, project);
|
|
861
|
+
if (!cwd) {
|
|
862
|
+
return { error: 'Bundle target is unavailable', status: 409 };
|
|
863
|
+
}
|
|
864
|
+
return {
|
|
865
|
+
cwd,
|
|
866
|
+
branch: bundle.branch,
|
|
867
|
+
project,
|
|
868
|
+
cacheKey: `workspace-files:${project.id}:bundle:${bundle.id}:${cwd}`,
|
|
869
|
+
target: { kind: 'bundle', bundle_id: bundle.id, ticket_id: null },
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
if (!ticketId) {
|
|
873
|
+
return { error: 'ticket_id is required for a ticket target', status: 400 };
|
|
874
|
+
}
|
|
875
|
+
const ticket = getTicket(ticketId);
|
|
876
|
+
if (!ticket || ticket.project_id !== project.id) {
|
|
877
|
+
return { error: 'Ticket target not found', status: 404 };
|
|
878
|
+
}
|
|
879
|
+
const bundle = ticket.worktree_bundle_id ? getBundle(ticket.worktree_bundle_id, project.id) : null;
|
|
880
|
+
if (bundle && isProjectRootBundle(bundle)) {
|
|
881
|
+
if (!existsSync(project.repo_path)) {
|
|
882
|
+
return { error: 'Ticket target is unavailable', status: 409 };
|
|
883
|
+
}
|
|
884
|
+
return {
|
|
885
|
+
cwd: project.repo_path,
|
|
886
|
+
branch: getLocalProjectBranch(project),
|
|
887
|
+
project,
|
|
888
|
+
cacheKey: `workspace-files:${project.id}:ticket:${ticket.id}:${project.repo_path}`,
|
|
889
|
+
target: { kind: 'ticket', bundle_id: null, ticket_id: ticket.id },
|
|
890
|
+
};
|
|
891
|
+
}
|
|
892
|
+
const branch = resolveTicketBranch(ticket);
|
|
893
|
+
const cwd = branch ? resolveExistingWorktreePath(branch, project) : null;
|
|
894
|
+
if (!branch || !cwd) {
|
|
895
|
+
return { error: 'Ticket target is unavailable', status: 409 };
|
|
896
|
+
}
|
|
897
|
+
return {
|
|
898
|
+
cwd,
|
|
899
|
+
branch,
|
|
900
|
+
project,
|
|
901
|
+
cacheKey: `workspace-files:${project.id}:ticket:${ticket.id}:${cwd}`,
|
|
902
|
+
target: { kind: 'ticket', bundle_id: null, ticket_id: ticket.id },
|
|
903
|
+
};
|
|
904
|
+
};
|
|
905
|
+
const parseWorkspaceFileTarget = (req) => {
|
|
906
|
+
const targetKind = typeof req.query.target_kind === 'string' ? req.query.target_kind : '';
|
|
907
|
+
if (targetKind !== 'repo_root' && targetKind !== 'bundle' && targetKind !== 'ticket') {
|
|
908
|
+
return { error: 'target_kind must be repo_root, bundle, or ticket', status: 400 };
|
|
909
|
+
}
|
|
910
|
+
return {
|
|
911
|
+
targetKind,
|
|
912
|
+
bundleId: typeof req.query.bundle_id === 'string' ? req.query.bundle_id.trim() || null : null,
|
|
913
|
+
ticketId: typeof req.query.ticket_id === 'string' ? req.query.ticket_id.trim() || null : null,
|
|
914
|
+
};
|
|
915
|
+
};
|
|
916
|
+
const getWorkspaceFileTargetUnavailableMessage = (targetKind) => {
|
|
917
|
+
const targetName = targetKind === 'repo_root' ? 'Repository' : targetKind === 'bundle' ? 'Bundle' : 'Ticket';
|
|
918
|
+
return `${targetName} target is unavailable`;
|
|
919
|
+
};
|
|
838
920
|
const getProjectBranchStateForFooter = (project, options = {}) => {
|
|
839
921
|
const branchState = getProjectBranch(project, {
|
|
840
922
|
refreshRemote: options.refreshRemote,
|
|
@@ -2636,11 +2718,12 @@ app.post('/projects/:id/spec-sessions/:sessionId/snapshots/:snapshotId/export',
|
|
|
2636
2718
|
return res.status(404).json({ error: 'Not found' });
|
|
2637
2719
|
}
|
|
2638
2720
|
try {
|
|
2721
|
+
const overwrite = req.body?.overwrite === true;
|
|
2639
2722
|
const collision = checkSpecExportCollision({
|
|
2640
2723
|
specSession,
|
|
2641
2724
|
repoPath: project.repo_path,
|
|
2642
2725
|
});
|
|
2643
|
-
if (collision) {
|
|
2726
|
+
if (collision && !overwrite) {
|
|
2644
2727
|
return res.status(409).json({
|
|
2645
2728
|
error: 'A spec with this title has already been exported.',
|
|
2646
2729
|
conflicting_path: collision,
|
|
@@ -5454,6 +5537,60 @@ app.get('/projects/:id/file-suggestions', (req, res) => {
|
|
|
5454
5537
|
return res.status(500).json({ error: 'Unable to load project file suggestions' });
|
|
5455
5538
|
}
|
|
5456
5539
|
});
|
|
5540
|
+
app.get('/projects/:id/workspace-files', (req, res) => {
|
|
5541
|
+
const project = getProjectById(req.params.id);
|
|
5542
|
+
if (!project) {
|
|
5543
|
+
return res.status(404).json({ error: 'Not found' });
|
|
5544
|
+
}
|
|
5545
|
+
const target = parseWorkspaceFileTarget(req);
|
|
5546
|
+
if ('error' in target) {
|
|
5547
|
+
return res.status(target.status).json({ error: target.error });
|
|
5548
|
+
}
|
|
5549
|
+
const workspace = resolveWorkspaceFileWorkspace(project, target.targetKind, target.bundleId, target.ticketId);
|
|
5550
|
+
if ('error' in workspace) {
|
|
5551
|
+
return res.status(workspace.status).json({ error: workspace.error });
|
|
5552
|
+
}
|
|
5553
|
+
try {
|
|
5554
|
+
return res.json(getProjectFileManifest(workspace, { refresh: req.query.refresh === 'true' }));
|
|
5555
|
+
}
|
|
5556
|
+
catch (error) {
|
|
5557
|
+
if (error instanceof ProjectFileTargetUnavailableError) {
|
|
5558
|
+
return res.status(409).json({ error: getWorkspaceFileTargetUnavailableMessage(workspace.target.kind) });
|
|
5559
|
+
}
|
|
5560
|
+
console.error(`Failed to build workspace file manifest for project ${project.id}:`, error);
|
|
5561
|
+
return res.status(500).json({ error: 'Unable to load workspace files' });
|
|
5562
|
+
}
|
|
5563
|
+
});
|
|
5564
|
+
app.get('/projects/:id/workspace-files/content', (req, res) => {
|
|
5565
|
+
const project = getProjectById(req.params.id);
|
|
5566
|
+
if (!project) {
|
|
5567
|
+
return res.status(404).json({ error: 'Not found' });
|
|
5568
|
+
}
|
|
5569
|
+
const target = parseWorkspaceFileTarget(req);
|
|
5570
|
+
if ('error' in target) {
|
|
5571
|
+
return res.status(target.status).json({ error: target.error });
|
|
5572
|
+
}
|
|
5573
|
+
if (typeof req.query.path !== 'string') {
|
|
5574
|
+
return res.status(400).json({ error: 'path is required' });
|
|
5575
|
+
}
|
|
5576
|
+
const workspace = resolveWorkspaceFileWorkspace(project, target.targetKind, target.bundleId, target.ticketId);
|
|
5577
|
+
if ('error' in workspace) {
|
|
5578
|
+
return res.status(workspace.status).json({ error: workspace.error });
|
|
5579
|
+
}
|
|
5580
|
+
try {
|
|
5581
|
+
return res.json(readProjectFileContent(workspace, req.query.path));
|
|
5582
|
+
}
|
|
5583
|
+
catch (error) {
|
|
5584
|
+
if (error instanceof ProjectFileTargetUnavailableError) {
|
|
5585
|
+
return res.status(409).json({ error: getWorkspaceFileTargetUnavailableMessage(workspace.target.kind) });
|
|
5586
|
+
}
|
|
5587
|
+
if (error instanceof ProjectFileContentError) {
|
|
5588
|
+
return res.status(error.status).json({ error: error.message, reason: error.reason });
|
|
5589
|
+
}
|
|
5590
|
+
console.error(`Failed to read workspace file content for project ${project.id}:`, error);
|
|
5591
|
+
return res.status(500).json({ error: 'Unable to read workspace file' });
|
|
5592
|
+
}
|
|
5593
|
+
});
|
|
5457
5594
|
app.post('/projects/:id/git-pull', async (req, res) => {
|
|
5458
5595
|
const project = getProjectById(req.params.id);
|
|
5459
5596
|
if (!project) {
|