From 6a030e1790766354552e37048710778c1cc82c2c Mon Sep 17 00:00:00 2001 From: unohee Date: Sat, 27 Jun 2026 09:11:52 +0900 Subject: [PATCH] =?UTF-8?q?fix(daemon):=20enableProject=EA=B0=80=20allowed?= =?UTF-8?q?Projects=EB=8F=84=20=EA=B0=B1=EC=8B=A0=20=E2=80=94=20openswarm?= =?UTF-8?q?=20add=20=EB=A7=A4=ED=95=91=20=EB=AF=B8=EC=A0=81=EC=9A=A9=20?= =?UTF-8?q?=EB=B2=84=EA=B7=B8=20(INT-1973)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit openswarm add(또는 대시보드 enable)로 repo 등록 + openswarm.json 매핑이 정확해도 데몬이 'No repo mapped … Skipping'으로 픽업 못 하던 버그(사용자: WAVE). 원인: enableProject()가 enabledProjects에만 add하고 config.allowedProjects는 미갱신. 그런데 resolveProjectPath는 allowedProjects 경로의 openswarm.json만 읽음 → enable됐지만 not-allowed인 repo는 매핑 파일을 안 읽어 resolve 실패. - autonomousRunner.enableProject: updateAllowedProjects로 config+DecisionEngine 동기화 (dedup). enable 게이트가 disabled를 막으므로 disableProject는 그대로. - projectHandler.ts: 거짓이던 주석을 실제 동작과 일치하게 정정. 테스트: enableProject 후 getAllowedProjects/getEnabledProjects 포함 + dedup. 전체 green. INT-1969 후속(사용자 보고). --- .../autonomousRunner.enable.test.ts | 32 +++++++++++++++++++ src/automation/autonomousRunner.ts | 8 +++++ src/cli/projectHandler.ts | 6 ++-- 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 src/automation/autonomousRunner.enable.test.ts diff --git a/src/automation/autonomousRunner.enable.test.ts b/src/automation/autonomousRunner.enable.test.ts new file mode 100644 index 0000000..2689c29 --- /dev/null +++ b/src/automation/autonomousRunner.enable.test.ts @@ -0,0 +1,32 @@ +// Purpose: enableProject must also add the repo to allowedProjects so +// resolveProjectPath reads its openswarm.json mapping (INT-1973). +import { describe, it, expect } from 'vitest'; +import { AutonomousRunner } from './autonomousRunner.js'; +import type { AutonomousConfig } from './runnerTypes.js'; + +const cfg = (over: Partial = {}): AutonomousConfig => ({ + linearTeamId: 'team', + allowedProjects: ['/x/a'], + heartbeatSchedule: '0 * * * *', + autoExecute: false, + maxConsecutiveTasks: 1, + cooldownSeconds: 0, + dryRun: true, + ...over, +}); + +describe('AutonomousRunner.enableProject (INT-1973)', () => { + it('enabling a repo also allows it (resolveProjectPath reads only allowed paths)', () => { + const r = new AutonomousRunner(cfg()); + r.enableProject('/x/wave'); + expect(r.getEnabledProjects()).toContain('/x/wave'); + expect(r.getAllowedProjects()).toContain('/x/wave'); + }); + + it('does not duplicate an already-allowed path', () => { + const r = new AutonomousRunner(cfg({ allowedProjects: ['/x/a'] })); + r.enableProject('/x/a'); + expect(r.getAllowedProjects().filter((p) => p === '/x/a')).toHaveLength(1); + expect(r.getEnabledProjects()).toContain('/x/a'); + }); +}); diff --git a/src/automation/autonomousRunner.ts b/src/automation/autonomousRunner.ts index 5485dd4..bfff8b5 100644 --- a/src/automation/autonomousRunner.ts +++ b/src/automation/autonomousRunner.ts @@ -1358,6 +1358,14 @@ export class AutonomousRunner { enableProject(projectPath: string): void { this.enabledProjects.add(projectPath); + // Enabling a repo (via `openswarm add` / the dashboard) must also ALLOW it: + // resolveProjectPath only reads a repo's openswarm.json for paths in + // allowedProjects, so an enabled-but-not-allowed repo never resolves + // ("No repo mapped"). Keep config + DecisionEngine in sync. (INT-1970) + const allowed = this.config.allowedProjects ?? []; + if (!allowed.includes(projectPath)) { + this.updateAllowedProjects([...allowed, projectPath]); + } console.log(`[AutonomousRunner] Project enabled: ${projectPath}`); } diff --git a/src/cli/projectHandler.ts b/src/cli/projectHandler.ts index e170675..115a4f7 100644 --- a/src/cli/projectHandler.ts +++ b/src/cli/projectHandler.ts @@ -4,8 +4,10 @@ // // Manage the work-repo registry the daemon reads at startup // (~/.claude/openswarm-repos.json — the same file the web dashboard writes). -// `setWebRunner` (src/support/web.ts) merges `enabled` into both the runner's -// enabled set AND its allowedProjects, so a repo added here is actually worked. +// `setWebRunner` (src/support/web.ts) calls runner.enableProject() for each +// enabled repo, which adds it to BOTH the enabled set AND allowedProjects +// (INT-1973) — the latter is required so resolveProjectPath reads the repo's +// openswarm.json mapping. A repo added here is therefore actually worked. // // `add` also offers a Linear team/project picker (shared with `openswarm init` // via ./linearMapping) and writes the repo↔Linear mapping into the repo's