@straiffi/archon 1.2.4 → 1.2.5

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.
@@ -5,7 +5,7 @@
5
5
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>Archon</title>
8
- <script type="module" crossorigin src="/assets/index-DfuQewLh.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-DHJbmRpg.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-BYbx6iT9.js">
10
10
  <link rel="modulepreload" crossorigin href="/assets/badge-Bpry9xkS.js">
11
11
  <link rel="stylesheet" crossorigin href="/assets/index-CRirnlH7.css">
@@ -1435,6 +1435,88 @@ const reviewBundleTickets = (projectId, bundleId) => {
1435
1435
  }),
1436
1436
  };
1437
1437
  };
1438
+ const buildBundleTickets = (projectId, bundleId, broadcaster) => {
1439
+ const project = getProjectById(projectId);
1440
+ if (!project) {
1441
+ return { ok: false, status: 404, error: 'Project not found' };
1442
+ }
1443
+ const bundle = getBundle(bundleId, project.id);
1444
+ if (!bundle) {
1445
+ return { ok: false, status: 404, error: 'Bundle not found' };
1446
+ }
1447
+ const planTickets = listBundleSliceTickets(project.id, bundle.id, 'plan');
1448
+ if (planTickets.length === 0) {
1449
+ return { ok: false, status: 409, error: 'No plan tickets are available to build in this bundle' };
1450
+ }
1451
+ const bundleTicketIds = listBundleTickets(project.id, bundle.id).map(ticket => ticket.id);
1452
+ const orderedPlanTicketIds = getDependencyOrderedBundleTicketIds(project.id, planTickets.map(ticket => ticket.id));
1453
+ const planTicketById = new Map(planTickets.map(ticket => [ticket.id, ticket]));
1454
+ const orderedPlanTickets = orderedPlanTicketIds
1455
+ .map(ticketId => planTicketById.get(ticketId))
1456
+ .filter((ticket) => ticket !== undefined);
1457
+ const bundleBuildBlocker = orderedPlanTickets.find(ticket => getBundleBuildBlockerResponse(ticket) !== null);
1458
+ if (bundleBuildBlocker) {
1459
+ const blockerResponse = getBundleBuildBlockerResponse(bundleBuildBlocker);
1460
+ if (!blockerResponse) {
1461
+ return { ok: false, status: 409, error: 'Unable to build the bundle right now.' };
1462
+ }
1463
+ return { ok: false, status: 409, error: blockerResponse.error, details: blockerResponse };
1464
+ }
1465
+ for (const planTicket of orderedPlanTickets) {
1466
+ const buildValidation = prepareTicketForBuild(planTicket.id, {
1467
+ ignoredBlockerTicketIds: bundleTicketIds,
1468
+ updateState: false,
1469
+ });
1470
+ if (!buildValidation.ok) {
1471
+ return {
1472
+ ok: false,
1473
+ status: buildValidation.status,
1474
+ error: buildValidation.error,
1475
+ ...(buildValidation.blockers ? { details: { blockers: buildValidation.blockers } } : {}),
1476
+ };
1477
+ }
1478
+ }
1479
+ const movedTickets = [];
1480
+ for (const planTicket of orderedPlanTickets) {
1481
+ const buildTransition = prepareTicketForBuild(planTicket.id, {
1482
+ ignoredBlockerTicketIds: bundleTicketIds,
1483
+ });
1484
+ if (!buildTransition.ok) {
1485
+ return {
1486
+ ok: false,
1487
+ status: buildTransition.status,
1488
+ error: buildTransition.error,
1489
+ ...(buildTransition.blockers ? { details: { blockers: buildTransition.blockers } } : {}),
1490
+ };
1491
+ }
1492
+ movedTickets.push(buildTransition.ticket);
1493
+ }
1494
+ emitUpdatedTickets(movedTickets.map(ticket => ticket.id));
1495
+ const details = serializeBundleDetails(project, bundle, {
1496
+ target_ticket_id: movedTickets[0]?.id ?? null,
1497
+ });
1498
+ return {
1499
+ ok: true,
1500
+ status: 200,
1501
+ value: details,
1502
+ afterResponse: () => {
1503
+ for (const [index, movedTicket] of movedTickets.entries()) {
1504
+ if (!movedTicket.project_id || !movedTicket.worktree_bundle_id) {
1505
+ continue;
1506
+ }
1507
+ const queuedBuild = enqueueBundledBuild({
1508
+ ticketId: movedTicket.id,
1509
+ projectId: movedTicket.project_id,
1510
+ worktreeBundleId: movedTicket.worktree_bundle_id,
1511
+ activate: index === 0 && shouldStartBundleBuildNow(movedTicket),
1512
+ });
1513
+ if (queuedBuild.shouldStartNow) {
1514
+ startBuild(movedTicket, broadcaster);
1515
+ }
1516
+ }
1517
+ },
1518
+ };
1519
+ };
1438
1520
  const getCurrentReviewWorkspaceSignature = (ticket) => {
1439
1521
  if (!ticket) {
1440
1522
  return null;
@@ -1951,6 +2033,7 @@ app.post('/mobile-access/enable', async (req, res) => {
1951
2033
  clientBuild: resolveClientBuildPaths(import.meta.url),
1952
2034
  broadcaster: io,
1953
2035
  preferredProjectId,
2036
+ buildBundle: buildBundleTickets,
1954
2037
  reviewBundleTickets,
1955
2038
  getBundleDetails: getProjectBundleDetails,
1956
2039
  submitBundleFollowUp: submitBundleFollowUpResponse,
@@ -2754,67 +2837,15 @@ app.post('/bundles/:id/build', (req, res) => {
2754
2837
  if ('error' in result) {
2755
2838
  return res.status(400).json({ error: result.error });
2756
2839
  }
2757
- const bundle = getBundle(req.params.id, result.project.id);
2758
- if (!bundle) {
2759
- return res.status(404).json({ error: 'Bundle not found' });
2760
- }
2761
- const planTickets = listBundleSliceTickets(result.project.id, bundle.id, 'plan');
2762
- if (planTickets.length === 0) {
2763
- return res.status(409).json({ error: 'No plan tickets are available to build in this bundle' });
2764
- }
2765
- const bundleTicketIds = listBundleTickets(result.project.id, bundle.id).map(ticket => ticket.id);
2766
- const orderedPlanTicketIds = getDependencyOrderedBundleTicketIds(result.project.id, planTickets.map(ticket => ticket.id));
2767
- const planTicketById = new Map(planTickets.map(ticket => [ticket.id, ticket]));
2768
- const orderedPlanTickets = orderedPlanTicketIds
2769
- .map(ticketId => planTicketById.get(ticketId))
2770
- .filter((ticket) => ticket !== undefined);
2771
- const bundleBuildBlocker = orderedPlanTickets.find(ticket => getBundleBuildBlockerResponse(ticket) !== null);
2772
- if (bundleBuildBlocker) {
2773
- return res.status(409).json(getBundleBuildBlockerResponse(bundleBuildBlocker));
2774
- }
2775
- for (const planTicket of orderedPlanTickets) {
2776
- const buildValidation = prepareTicketForBuild(planTicket.id, {
2777
- ignoredBlockerTicketIds: bundleTicketIds,
2778
- updateState: false,
2779
- });
2780
- if (!buildValidation.ok) {
2781
- return res.status(buildValidation.status).json({
2782
- error: buildValidation.error,
2783
- ...(buildValidation.blockers ? { blockers: buildValidation.blockers } : {}),
2784
- });
2785
- }
2786
- }
2787
- const movedTickets = [];
2788
- for (const planTicket of orderedPlanTickets) {
2789
- const buildTransition = prepareTicketForBuild(planTicket.id, {
2790
- ignoredBlockerTicketIds: bundleTicketIds,
2791
- });
2792
- if (!buildTransition.ok) {
2793
- return res.status(buildTransition.status).json({
2794
- error: buildTransition.error,
2795
- ...(buildTransition.blockers ? { blockers: buildTransition.blockers } : {}),
2796
- });
2797
- }
2798
- movedTickets.push(buildTransition.ticket);
2799
- }
2800
- emitUpdatedTickets(movedTickets.map(ticket => ticket.id));
2801
- res.json(serializeBundleDetails(result.project, bundle, {
2802
- target_ticket_id: movedTickets[0]?.id ?? null,
2803
- }));
2804
- for (const [index, movedTicket] of movedTickets.entries()) {
2805
- if (!movedTicket.project_id || !movedTicket.worktree_bundle_id) {
2806
- continue;
2807
- }
2808
- const queuedBuild = enqueueBundledBuild({
2809
- ticketId: movedTicket.id,
2810
- projectId: movedTicket.project_id,
2811
- worktreeBundleId: movedTicket.worktree_bundle_id,
2812
- activate: index === 0 && shouldStartBundleBuildNow(movedTicket),
2840
+ const buildResult = buildBundleTickets(result.project.id, req.params.id, io);
2841
+ if (!buildResult.ok) {
2842
+ return res.status(buildResult.status).json({
2843
+ error: buildResult.error,
2844
+ ...('details' in buildResult ? buildResult.details : {}),
2813
2845
  });
2814
- if (queuedBuild.shouldStartNow) {
2815
- startBuild(movedTicket, io);
2816
- }
2817
2846
  }
2847
+ res.status(buildResult.status).json(buildResult.value);
2848
+ buildResult.afterResponse?.();
2818
2849
  });
2819
2850
  app.post('/bundles/:id/review', (req, res) => {
2820
2851
  const result = getRequiredProject(req);