@open-mercato/cezar 0.9.1-pr694.821 → 0.9.1-pr697.822

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 (61) hide show
  1. package/dist/index.js +1 -18
  2. package/dist/index.js.map +1 -1
  3. package/dist/runs/store.d.ts +0 -34
  4. package/dist/runs/store.js +0 -10
  5. package/dist/runs/store.js.map +1 -1
  6. package/dist/server/project-context.d.ts +0 -6
  7. package/dist/server/project-context.js +1 -6
  8. package/dist/server/project-context.js.map +1 -1
  9. package/dist/server/server.d.ts +1 -8
  10. package/dist/server/server.js +3 -331
  11. package/dist/server/server.js.map +1 -1
  12. package/dist/server-install/platforms/ubuntu-vps.d.ts +15 -0
  13. package/dist/server-install/platforms/ubuntu-vps.js +62 -1
  14. package/dist/server-install/platforms/ubuntu-vps.js.map +1 -1
  15. package/package.json +1 -1
  16. package/web/dist/assets/{centered-state-DsblJe6Q.js → centered-state-_B4KtyI9.js} +11 -11
  17. package/web/dist/assets/{commit-list-CAwllMBX.js → commit-list-DZ_dB5pp.js} +1 -1
  18. package/web/dist/assets/{compare-variants-JnaeMTz5.js → compare-variants-DApq2mrq.js} +1 -1
  19. package/web/dist/assets/{diff-Drvekr61.js → diff-COiZDXGN.js} +2 -2
  20. package/web/dist/assets/{diff-view-Ct3kYFRM.js → diff-view-a118OGM7.js} +1 -1
  21. package/web/dist/assets/{dist-CngV8tyE.js → dist-BDertzy3.js} +1 -1
  22. package/web/dist/assets/{git-toolbar-BLqu97v8.js → git-toolbar-D1hE6SY9.js} +1 -1
  23. package/web/dist/assets/github-Sh-4Tqz5.js +1 -0
  24. package/web/dist/assets/index-CPY_yMu5.js +22 -0
  25. package/web/dist/assets/index-CrdG_TLt.css +2 -0
  26. package/web/dist/assets/{project-router-CnKsyZKI.js → project-router-DHNVGMTs.js} +1 -1
  27. package/web/dist/assets/{repo-git-DnkvanyM.js → repo-git-BV1vqi4_.js} +1 -1
  28. package/web/dist/assets/{run-diff-LyXkHJCR.js → run-diff-VFfj5NpJ.js} +1 -1
  29. package/web/dist/assets/run-header-Y-KtnbDv.js +1 -0
  30. package/web/dist/assets/{skills-CE0HAI_G.js → skills-D_Z_u00d.js} +1 -1
  31. package/web/dist/assets/{tab-link-BbQLZUG5.js → tab-link-D6mbZhQc.js} +1 -1
  32. package/web/dist/assets/{task-changes-BYNpnV0E.js → task-changes-DXZTUtTU.js} +1 -1
  33. package/web/dist/assets/task-commits-CVAdLmlZ.js +1 -0
  34. package/web/dist/assets/{task-files-DAqPuHp1.js → task-files-BcEipRuc.js} +2 -2
  35. package/web/dist/assets/{task-thread-DMM5s2zt.js → task-thread-DFsV_WWl.js} +7 -7
  36. package/web/dist/assets/{use-desktop-BAHxMKrE.js → use-desktop-D4jq8HBV.js} +1 -1
  37. package/web/dist/assets/{workflows-DCkK4Bsn.js → workflows-T3uwAimN.js} +3 -3
  38. package/web/dist/index.html +5 -5
  39. package/dist/automations/coordinator.d.ts +0 -26
  40. package/dist/automations/coordinator.js +0 -66
  41. package/dist/automations/coordinator.js.map +0 -1
  42. package/dist/automations/github-poller.d.ts +0 -134
  43. package/dist/automations/github-poller.js +0 -159
  44. package/dist/automations/github-poller.js.map +0 -1
  45. package/dist/automations/scheduler.d.ts +0 -42
  46. package/dist/automations/scheduler.js +0 -177
  47. package/dist/automations/scheduler.js.map +0 -1
  48. package/dist/automations/store.d.ts +0 -65
  49. package/dist/automations/store.js +0 -298
  50. package/dist/automations/store.js.map +0 -1
  51. package/dist/automations/task-template.d.ts +0 -18
  52. package/dist/automations/task-template.js +0 -95
  53. package/dist/automations/task-template.js.map +0 -1
  54. package/dist/automations/types.d.ts +0 -3650
  55. package/dist/automations/types.js +0 -158
  56. package/dist/automations/types.js.map +0 -1
  57. package/web/dist/assets/github-hrWK-ST8.js +0 -1
  58. package/web/dist/assets/index-B96YnNHc.js +0 -22
  59. package/web/dist/assets/index-DdBHg6_F.css +0 -2
  60. package/web/dist/assets/run-header-BtH23tbQ.js +0 -1
  61. package/web/dist/assets/task-commits-DRnMTXtG.js +0 -1
@@ -1,11 +1,4 @@
1
1
  import { existsSync, readFileSync, statSync } from 'node:fs';
2
- import { randomUUID } from 'node:crypto';
3
- import { AutomationStore } from '../automations/store.js';
4
- import { AutomationCoordinator } from '../automations/coordinator.js';
5
- import { GithubPoller } from '../automations/github-poller.js';
6
- import { ProjectAutomationScheduler, WorkspaceAutomationScheduler } from '../automations/scheduler.js';
7
- import { launchAutomationRun, reconcileAutomationReceipts, validateAutomationPrompt } from '../automations/task-template.js';
8
- import { automationEventSchema, automationFiltersSchema, automationLogResultSchema, automationTaskSchema, } from '../automations/types.js';
9
2
  import { access, constants as fsConstants, mkdir, readFile, realpath, stat, unlink, writeFile } from 'node:fs/promises';
10
3
  import { basename, dirname, join, resolve, sep } from 'node:path';
11
4
  import { fileURLToPath } from 'node:url';
@@ -49,7 +42,7 @@ import { expandTilde } from '../paths.js';
49
42
  import { isLoopbackHostHeader, normalizeHostname, resolveCapabilities } from './capabilities.js';
50
43
  import { createSocketHub } from './ws.js';
51
44
  import { browseDirectory, isInsideBrowseRoot, isLexicallyInsideBrowseRoot, resolveBrowseRoot } from './fs-browse.js';
52
- import { parseRemote, resolveForge } from './forge/index.js';
45
+ import { resolveForge } from './forge/index.js';
53
46
  import { fetchGithub, fetchGithubChecks, fetchGithubComments, fetchGithubPrDiff, GithubPrNotFoundError, GH_CHECKS_MAX } from './github.js';
54
47
  import { ensureLaunchKey } from './launch-key.js';
55
48
  import { openInTerminal } from './open-in-terminal.js';
@@ -71,39 +64,6 @@ const providerEnabledSchema = z.object({ enabled: z.boolean() }).strict();
71
64
  const providerRetrySchema = z.object({
72
65
  authFailureId: z.string().min(1).max(128),
73
66
  }).strict();
74
- const automationEditableSchema = z
75
- .object({
76
- name: z.string().trim().min(1).max(200),
77
- description: z.string().max(2_000).optional(),
78
- enabled: z.boolean().optional(),
79
- events: z.array(automationEventSchema).min(1).max(4),
80
- intervalSeconds: z.number().int().min(60).max(86_400),
81
- filters: automationFiltersSchema,
82
- task: automationTaskSchema,
83
- })
84
- .strict();
85
- const automationCreateSchema = automationEditableSchema.extend({ enable: z.boolean().optional() });
86
- const automationUpdateSchema = automationEditableSchema.extend({ expectedRevision: z.number().int().positive() });
87
- const automationCheckSchema = z.object({ mode: z.enum(['preview', 'execute']) }).strict();
88
- const automationLogQuerySchema = z.object({
89
- automationId: z.string().optional(),
90
- result: automationLogResultSchema.optional(),
91
- event: automationEventSchema.optional(),
92
- since: z.string().datetime().optional(),
93
- cursor: z.coerce.number().int().positive().optional(),
94
- limit: z.coerce.number().int().min(1).max(100).default(100),
95
- });
96
- function editableAutomation(definition) {
97
- return {
98
- name: definition.name,
99
- description: definition.description,
100
- enabled: definition.enabled,
101
- events: definition.events,
102
- intervalSeconds: definition.intervalSeconds,
103
- filters: definition.filters,
104
- task: definition.task,
105
- };
106
- }
107
67
  const SCOPED_PREFIX = '/api/p/:projectId';
108
68
  /**
109
69
  * The project-scoped route table of a `createApp()` app, derived from its
@@ -628,7 +588,6 @@ export function createApp(deps) {
628
588
  dataDir: bootDataDir,
629
589
  store: deps.store,
630
590
  manager: deps.manager,
631
- automationStore: deps.automationStore ?? AutomationStore.open(bootDataDir),
632
591
  launchKey: ensureLaunchKey(bootDataDir), // bookmarklet auto-start secret (spec 011)
633
592
  };
634
593
  // Non-boot projects build lazily on first scoped request; their managers
@@ -645,13 +604,6 @@ export function createApp(deps) {
645
604
  // Workspace-level SSE bus (step 2.8) — the registry mutators and the
646
605
  // checkout flow (Phase 4) emit here; /api/workspace/events relays.
647
606
  const workspaceEvents = deps.workspaceEvents ?? new WorkspaceEventBus();
648
- const emitAutomationChange = (project, automationId, revision, deleted = false) => workspaceEvents.emit('automation-change', {
649
- project: project.id,
650
- automationId,
651
- revision,
652
- ...(deleted ? { deleted: true } : {}),
653
- });
654
- const automationsChanged = () => deps.automationsChanged?.();
655
607
  const providerRuntimeAuth = deps.providerRuntimeAuth
656
608
  ?? new ProviderRuntimeAuthObserver(providerAuth, (status) => {
657
609
  workspaceEvents.emit('provider-status', status);
@@ -1879,215 +1831,6 @@ export function createApp(deps) {
1879
1831
  return c.json({ error: blocked }, 409);
1880
1832
  return c.json(await planChain(repoRoot, parsed.data.task));
1881
1833
  });
1882
- const manualChecks = new Map();
1883
- api.get('/automations', async (c) => {
1884
- const { root, automationStore } = c.get('project');
1885
- const forge = resolveForge(await getRepoInfo(root));
1886
- const availability = forge?.detectCached() ?? {
1887
- available: false,
1888
- reason: forge ? 'GitHub availability is still being checked' : 'No GitHub remote is configured',
1889
- };
1890
- const automations = automationStore.list().map((automation) => {
1891
- const logs = automationStore.logs({ automationId: automation.id, limit: 100 });
1892
- return {
1893
- ...automation,
1894
- state: automationStore.state(automation.id),
1895
- latestLog: logs[0],
1896
- counts: {
1897
- matches: logs.filter((row) => row.result === 'launched' || row.result === 'duplicate').length,
1898
- launched: logs.filter((row) => row.result === 'launched').length,
1899
- duplicates: logs.filter((row) => row.result === 'duplicate').length,
1900
- errors: logs.filter((row) => row.result === 'error' || row.result === 'rate-limited').length,
1901
- },
1902
- };
1903
- });
1904
- return c.json({
1905
- ...availability,
1906
- scheduler: {
1907
- state: automations.some((item) => item.enabled) ? 'scheduled' : 'idle',
1908
- nextDue: automations.map((item) => item.state?.nextCheckAt).filter(Boolean).sort()[0],
1909
- },
1910
- automations,
1911
- });
1912
- });
1913
- api.post('/automations', async (c) => {
1914
- const { automationStore } = c.get('project');
1915
- const parsed = automationCreateSchema.safeParse(await c.req.json().catch(() => null));
1916
- if (!parsed.success)
1917
- return c.json({ error: parsed.error.issues.map((issue) => issue.message).join('; ') }, 400);
1918
- const promptIssue = validateAutomationPrompt(parsed.data.task.prompt);
1919
- if (promptIssue)
1920
- return c.json({ error: promptIssue }, 400);
1921
- const { enable, ...input } = parsed.data;
1922
- try {
1923
- const automation = automationStore.create({ ...input, enabled: enable === true });
1924
- if (enable) {
1925
- const baselineAt = new Date().toISOString();
1926
- automationStore.setState(automation.id, {
1927
- revision: automation.revision,
1928
- baselineAt,
1929
- cursor: { timestamp: baselineAt },
1930
- nextCheckAt: new Date(Date.now() + automation.intervalSeconds * 1_000).toISOString(),
1931
- });
1932
- }
1933
- emitAutomationChange(c.get('project'), automation.id, automation.revision);
1934
- automationsChanged();
1935
- return c.json({ automation }, 201);
1936
- }
1937
- catch (error) {
1938
- return c.json({ error: error instanceof Error ? error.message : String(error) }, 400);
1939
- }
1940
- });
1941
- api.get('/automations/:id', (c) => {
1942
- const { automationStore } = c.get('project');
1943
- const automation = automationStore.get(c.req.param('id'));
1944
- return automation
1945
- ? c.json({ automation, state: automationStore.state(automation.id), latestLog: automationStore.logs({ automationId: automation.id, limit: 1 })[0] })
1946
- : c.json({ error: 'not found' }, 404);
1947
- });
1948
- api.put('/automations/:id', async (c) => {
1949
- const { automationStore } = c.get('project');
1950
- const parsed = automationUpdateSchema.safeParse(await c.req.json().catch(() => null));
1951
- if (!parsed.success)
1952
- return c.json({ error: parsed.error.issues.map((issue) => issue.message).join('; ') }, 400);
1953
- const promptIssue = validateAutomationPrompt(parsed.data.task.prompt);
1954
- if (promptIssue)
1955
- return c.json({ error: promptIssue }, 400);
1956
- const { expectedRevision, ...input } = parsed.data;
1957
- if (!automationStore.get(c.req.param('id')))
1958
- return c.json({ error: 'not found' }, 404);
1959
- try {
1960
- const automation = automationStore.update(c.req.param('id'), expectedRevision, { ...input, enabled: input.enabled ?? false });
1961
- emitAutomationChange(c.get('project'), automation.id, automation.revision);
1962
- automationsChanged();
1963
- return c.json({ automation });
1964
- }
1965
- catch (error) {
1966
- const message = error instanceof Error ? error.message : String(error);
1967
- return c.json({ error: message }, message.includes('conflict') ? 409 : 400);
1968
- }
1969
- });
1970
- api.delete('/automations/:id', (c) => {
1971
- const id = c.req.param('id');
1972
- const store = c.get('project').automationStore;
1973
- const current = store.get(id);
1974
- if (!current || !store.delete(id))
1975
- return c.json({ error: 'not found' }, 404);
1976
- emitAutomationChange(c.get('project'), id, current.revision, true);
1977
- automationsChanged();
1978
- return c.body(null, 204);
1979
- });
1980
- api.post('/automations/:id/enable', (c) => {
1981
- const store = c.get('project').automationStore;
1982
- const current = store.get(c.req.param('id'));
1983
- if (!current)
1984
- return c.json({ error: 'not found' }, 404);
1985
- const automation = store.update(current.id, current.revision, { ...editableAutomation(current), enabled: true });
1986
- const baselineAt = new Date().toISOString();
1987
- store.setState(automation.id, {
1988
- ...store.state(automation.id),
1989
- revision: automation.revision,
1990
- baselineAt,
1991
- cursor: { timestamp: baselineAt },
1992
- nextCheckAt: new Date(Date.now() + automation.intervalSeconds * 1_000).toISOString(),
1993
- });
1994
- store.appendLog({ automationId: automation.id, revision: automation.revision, result: 'baseline', reason: 'Enabled from a current-time baseline; existing records were not launched.' });
1995
- emitAutomationChange(c.get('project'), automation.id, automation.revision);
1996
- automationsChanged();
1997
- return c.json({ automation });
1998
- });
1999
- api.post('/automations/:id/pause', (c) => {
2000
- const store = c.get('project').automationStore;
2001
- const current = store.get(c.req.param('id'));
2002
- if (!current)
2003
- return c.json({ error: 'not found' }, 404);
2004
- const automation = store.update(current.id, current.revision, { ...editableAutomation(current), enabled: false });
2005
- emitAutomationChange(c.get('project'), automation.id, automation.revision);
2006
- automationsChanged();
2007
- return c.json({ automation });
2008
- });
2009
- api.post('/automations/:id/check', async (c) => {
2010
- const project = c.get('project');
2011
- const store = project.automationStore;
2012
- const automation = store.get(c.req.param('id'));
2013
- if (!automation)
2014
- return c.json({ error: 'not found' }, 404);
2015
- const parsed = automationCheckSchema.safeParse(await c.req.json().catch(() => null));
2016
- if (!parsed.success)
2017
- return c.json({ error: parsed.error.issues.map((issue) => issue.message).join('; ') }, 400);
2018
- const id = randomUUID();
2019
- const check = { id, automationId: automation.id, mode: parsed.data.mode, status: 'queued', createdAt: new Date().toISOString() };
2020
- if (manualChecks.size >= 200)
2021
- manualChecks.delete(manualChecks.keys().next().value);
2022
- manualChecks.set(id, check);
2023
- void (async () => {
2024
- check.status = 'running';
2025
- try {
2026
- const remote = parseRemote((await getRepoInfo(project.root))?.remote ?? '');
2027
- if (!remote || remote.host !== 'github.com')
2028
- throw new Error('No GitHub remote is configured');
2029
- const scheduler = new ProjectAutomationScheduler({
2030
- projectId: project.id,
2031
- owner: remote.owner,
2032
- repo: remote.repo,
2033
- store,
2034
- poller: new GithubPoller(),
2035
- launch: parsed.data.mode === 'execute'
2036
- ? (definition, candidate, receiptId) => launchAutomationRun({ root: project.root, manager: project.manager, store: project.store, definition, candidate, receiptId })
2037
- : undefined,
2038
- onChange: (automationId, revision) => emitAutomationChange(project, automationId, revision),
2039
- });
2040
- const result = await scheduler.check(automation, parsed.data.mode);
2041
- Object.assign(check, { status: 'complete', completedAt: new Date().toISOString(), matches: result.candidates.length, truncated: result.truncated });
2042
- }
2043
- catch (error) {
2044
- Object.assign(check, { status: 'error', completedAt: new Date().toISOString(), error: error instanceof Error ? error.message : String(error) });
2045
- }
2046
- })();
2047
- return c.json({ checkId: id }, 202);
2048
- });
2049
- api.get('/automation-checks/:checkId', (c) => {
2050
- const check = manualChecks.get(c.req.param('checkId'));
2051
- return check ? c.json(check) : c.json({ error: 'not found' }, 404);
2052
- });
2053
- api.get('/automation-log', (c) => {
2054
- const parsed = automationLogQuerySchema.safeParse(c.req.query());
2055
- if (!parsed.success)
2056
- return c.json({ error: parsed.error.issues.map((issue) => issue.message).join('; ') }, 400);
2057
- return c.json({ records: c.get('project').automationStore.logs(parsed.data) });
2058
- });
2059
- api.post('/automation-log/:receiptId/retry', async (c) => {
2060
- const project = c.get('project');
2061
- const store = project.automationStore;
2062
- const receipt = [...store.latestReceipts().values()].find((row) => row.receiptId === c.req.param('receiptId'));
2063
- if (!receipt)
2064
- return c.json({ error: 'not found' }, 404);
2065
- if (receipt.status !== 'launch-error' || receipt.runId)
2066
- return c.json({ error: 'receipt is not retryable' }, 409);
2067
- if (!receipt.candidate)
2068
- return c.json({ error: 'receipt predates retry context and cannot be retried safely' }, 409);
2069
- const definition = store.get(receipt.automationId);
2070
- if (!definition)
2071
- return c.json({ error: 'automation not found' }, 404);
2072
- const lease = store.acquireLease();
2073
- if (!lease)
2074
- return c.json({ error: 'automation polling lease is held by another process' }, 409);
2075
- const reserved = { ...receipt, status: 'reserved', error: undefined, updatedAt: new Date().toISOString() };
2076
- store.appendReceipt(reserved);
2077
- try {
2078
- const launched = await launchAutomationRun({ root: project.root, manager: project.manager, store: project.store, definition, candidate: receipt.candidate, receiptId: receipt.receiptId });
2079
- store.appendReceipt({ ...reserved, status: 'launched', runId: launched.runId, updatedAt: new Date().toISOString() });
2080
- emitAutomationChange(project, definition.id, definition.revision);
2081
- return c.json({ receiptId: receipt.receiptId, runId: launched.runId }, 202);
2082
- }
2083
- catch (error) {
2084
- store.appendReceipt({ ...reserved, status: 'launch-error', error: error instanceof Error ? error.message : String(error), updatedAt: new Date().toISOString() });
2085
- return c.json({ error: error instanceof Error ? error.message : String(error) }, 409);
2086
- }
2087
- finally {
2088
- lease.release();
2089
- }
2090
- });
2091
1834
  // ---- runs ----------------------------------------------------------------
2092
1835
  // Additive `usage` field (#348): the latest CPU/RSS/proc-count sample of the
2093
1836
  // run's live process tree — absent for finished runs and when `ps` yields
@@ -3641,24 +3384,7 @@ export function startServer(deps, port) {
3641
3384
  // The subscription hub rides the same HTTP server (one port, zero config):
3642
3385
  // createApp registers the topics, the `upgrade` hook below owns the socket.
3643
3386
  const socketHub = deps.socketHub ?? createSocketHub();
3644
- const automationCoordinator = new AutomationCoordinator({ listProjects });
3645
- const bootProjectId = deps.bootProjectId ?? 'default';
3646
- const bootAutomationStore = automationCoordinator.store(bootProjectId, deps.repoRoot);
3647
- const sharedContexts = deps.contexts ?? new ProjectContexts({
3648
- listProjects,
3649
- semaphore: deps.semaphore,
3650
- automationStore: (projectId, root) => automationCoordinator.store(projectId, root),
3651
- });
3652
- let rescheduleAutomations = () => { };
3653
- const app = createApp({
3654
- ...deps,
3655
- contexts: sharedContexts,
3656
- automationStore: bootAutomationStore,
3657
- workspaceEvents,
3658
- skillsUpdate,
3659
- socketHub,
3660
- automationsChanged: () => rescheduleAutomations(),
3661
- });
3387
+ const app = createApp({ ...deps, workspaceEvents, skillsUpdate, socketHub });
3662
3388
  // SECURITY: default to loopback. This server executes agents locally and its endpoints are
3663
3389
  // same-origin-trusted (only /api/health is CORS-open); binding to a non-loopback host would
3664
3390
  // expose an agent-executing box to the network. `bindHost` exists only for a deliberate
@@ -3670,60 +3396,17 @@ export function startServer(deps, port) {
3670
3396
  hostname: deps.bindHost ?? '127.0.0.1',
3671
3397
  });
3672
3398
  const coordinator = new SkillsUpdateCoordinator(skillsUpdate, async () => effectiveSkillsAutoUpdate(await loadWorkspaceConfig()));
3673
- const automationProjects = new Map();
3674
- const automationScheduler = new WorkspaceAutomationScheduler({
3675
- coordinator: automationCoordinator,
3676
- handle: (projectId, store) => {
3677
- const project = automationProjects.get(projectId);
3678
- if (!project)
3679
- return undefined;
3680
- return {
3681
- projectId,
3682
- owner: project.owner,
3683
- repo: project.repo,
3684
- store,
3685
- poller: new GithubPoller(),
3686
- onChange: (automationId, revision) => workspaceEvents.emit('automation-change', { project: projectId, automationId, revision }),
3687
- launch: async (definition, candidate, receiptId) => {
3688
- const bootId = deps.bootProjectId ?? 'default';
3689
- const context = projectId === bootId
3690
- ? { root: deps.repoRoot, manager: deps.manager, store: deps.store }
3691
- : await sharedContexts.context(projectId);
3692
- return launchAutomationRun({
3693
- root: context.root,
3694
- manager: context.manager,
3695
- store: context.store,
3696
- definition,
3697
- candidate,
3698
- receiptId,
3699
- });
3700
- },
3701
- };
3702
- },
3703
- });
3704
- rescheduleAutomations = () => { void automationScheduler.reschedule(); };
3705
3399
  const unsubscribe = workspaceEvents.on((event, data) => {
3706
3400
  if (event === 'project-added') {
3707
3401
  const project = data.project;
3708
3402
  if (project && typeof project.id === 'string' && typeof project.root === 'string' && project.status !== 'missing') {
3709
3403
  coordinator.add(project.id, project.root);
3710
- void getRepoInfo(project.root).then((info) => {
3711
- const parsed = parseRemote(info?.remote ?? '');
3712
- if (parsed?.host === 'github.com')
3713
- automationProjects.set(project.id, { root: project.root, owner: parsed.owner, repo: parsed.repo });
3714
- return automationScheduler.reschedule();
3715
- });
3716
3404
  }
3717
3405
  }
3718
3406
  else if (event === 'project-removed') {
3719
3407
  const id = data.id;
3720
3408
  if (typeof id === 'string')
3721
3409
  coordinator.remove(id);
3722
- if (typeof id === 'string') {
3723
- automationCoordinator.remove(id);
3724
- automationProjects.delete(id);
3725
- void automationScheduler.reschedule();
3726
- }
3727
3410
  }
3728
3411
  });
3729
3412
  server.once('listening', () => {
@@ -3731,20 +3414,9 @@ export function startServer(deps, port) {
3731
3414
  const all = projects.some((project) => project.root === deps.repoRoot)
3732
3415
  ? projects : [{ id: deps.bootProjectId ?? 'default', root: deps.repoRoot, status: 'ok' }, ...projects];
3733
3416
  coordinator.start(all);
3734
- void Promise.all(all.map(async (project) => {
3735
- const parsed = parseRemote((await getRepoInfo(project.root))?.remote ?? '');
3736
- if (parsed?.host === 'github.com')
3737
- automationProjects.set(project.id, { root: project.root, owner: parsed.owner, repo: parsed.repo });
3738
- const automationStore = automationCoordinator.store(project.id, project.root);
3739
- const runStore = project.id === (deps.bootProjectId ?? 'default')
3740
- ? deps.store
3741
- : sharedContexts.peek(project.id)?.store;
3742
- if (automationStore && runStore)
3743
- reconcileAutomationReceipts(automationStore, runStore);
3744
- })).then(() => automationScheduler.start()).catch(() => undefined);
3745
3417
  }).catch(() => undefined);
3746
3418
  });
3747
- server.once('close', () => { unsubscribe(); coordinator.stop(); automationScheduler.stop(); });
3419
+ server.once('close', () => { unsubscribe(); coordinator.stop(); });
3748
3420
  socketHub.attach(server, (req) => verifyWsUpgrade(req, deps.bindHost));
3749
3421
  return server;
3750
3422
  }