-
代码层: - server/services/goals.js → okr-service.js;GoalsService → OkrService · this.goalsDir → okrDir,目录 goals/ → okr/ · ID 前缀 G- → O-;落盘文件 goal.json → objective.json · updateGoal → updateObjective,_nextGoalId/_saveGoal 等同步改名 · parseNodeId 层级名 ['Goal','Objective','KeyResult','SubTask'] → ['Objective','KeyResult','SubTask','SubTask'](OKR 无 Goal 这一层) - server/routes/goals.js → okr.js;:goalId → :objectiveId - 7 处调用点同步:index.js / agent-server.js / agent-chat.js / company.js / company-heartbeat-service.js / prompt-builder.js / test-company-e2e.js - 前端 OkrDashboard.vue / CompanyDashboard.vue 切到 /api/okr(前后端命名终于一致) - bin/lemon.js 新增 okr create/add-node/list/status 向后兼容(不破坏任何现有调用方): - /api/goals/* 与 /api/company/:cid/goals/* 全部保留为别名,与新路径同时挂载 - task dispatch/report 同时接受 objectiveId(新) 与 goalId(旧),写入时两字段都留 - bin/lemon.js 保留 goal * 命令别名 迁移脚本 scripts/migrate-goals-to-okr.js(npm run okr:migrate): - 目录 data/{,companies/*/}goals/ → okr/;条目 G-xxx → O-xxx - 改写 objective.json 的 id / nodes 的 key / children 数组、_index.json、 progress.json 的 goalId、history.log 文本、system/tasklog/*.json 的 goalId+nodeId - --dry-run 预演;幂等;迁移前自动备份为 *.bak-goals(已加入 .gitignore) - 处理一个反直觉边界:OkrService 构造函数会自动 mkdir 目标目录,"okr/ 已存在" 不等于"已迁移过"——只要服务被 require 过一次就留下空壳。用 isEmptyOkrDir() 区分空壳与真实数据,空壳移除后继续迁移。这个 bug 是在 fixture 上验证时发现的。 - 同样在 fixture 上发现并修掉:nodeId 的值漏改写、tasklog 迁移不幂等 验证:新增 server/tests/unit/okr-service.test.js(7 例,覆盖新命名工作正常 + 迁移纯函数的 ID 改写);全量 npm run test:unit 652 例全绿。 范围说明:NAMING §五 的 benchmark 三分(skill-/agent-/goal-)本轮未动代码—— 该节自身的建议就是存量保持现状、只对新增代码强制前缀,因为 benchmark_runs 等表 服务于线上 Arena 排行榜,改表名/路由是另一次独立迁移。 §二-四 的新 agent id 尚不存在实体,待 P2/P3 实现时按规范创建。 已知遗留(非本次引入):server/scripts/test-company-e2e.js 早已失效——它按 data/{id}/ 找公司,而 company-service 用的是 data/companies/{id}/,在 HEAD 版本 同样全部断言失败。本次只同步了其中的 OKR 命名,未修这个路径问题。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> -
# Conflicts: # system/agents/master/.claude/scheduled_tasks.json
-
hire() now checks system_agents (source_kind='template') before provisioning a new company agent: if the role has a shared template row, skip copying agent.md and instead let AgentManager.getAgentConfig()/PromptBuilder.build() resolve the prompt from the shared legacy_path at call time, with per-company context assembled from a new company-context.md. Roles without a template row (including the 6 ids that exist in both system/agents/ and system/templates/, e.g. evolver-youtube-crawler) fall back to the existing full-copy behavior unchanged. - server/services/graph-service.js (new): lookupSharedAgentMd(), upsertOrgGraphNode() - server/services/company-service.js: hire() reference-mode branch, _provisionReferenceAgent() - server/src/core/agent-manager.js: getAgentConfig() resolves prompt/companyContextPath - server/src/core/prompt-builder.js: build() concatenates company-context.md - unit + integration tests covering all 6 acceptance criteria from docs/todo/system-design/27-p1-virtual-reference.md §6, including a regression test against the real idearun:evolver-youtube-crawler naming-collision case Full regression suite (587 tests) passes; independent adversarial review found 0 blocking/major issues. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
First successful real-CLI agent invocation. After REAL.1 (system-prompt injection) + REAL.2 (mtime-diff file detection) wired, the only remaining gate was Claude auth. Once CLAUDE_CODE_OAUTH_TOKEN was added to the project .env, scripts/real-pm-smoke.js completed cleanly: Wire-up status: ✓ process spawn ✓ stream chunks (3) ✓ result text (Claude returned "DONE") ✓ files written (6: prd/index, feature-tree, user-flows, product/overview, assets/shell.{css,js}) ✓ git commit (8cb0493) 5/5 checks passed · elapsed 163s PM output quality (real Claude, not mock): - valid <article data-doc="prd" data-rev="1"> + <section data-rev="1"> structure per system prompt - nav links use correct relative paths across 4 chapters - pid (p-7gwlbl) embedded in HTML metadata - 中文 prose in the requested 克制 voice Spec-deviation confirmed (no MCP tool gateway yet — Claude only has built-in Read/Write/Bash): - ✗ agent-state/pm.json (no update_runtime_state tool) - ✗ agent-state/pm-todo.json (no write_todolist tool) - ✗ history/prd-rev-001.html (no archive_doc tool) - ✗ timeline.ndjson 'prd_drafted' event (no timeline_append tool) - ✓ core PRD site IS produced — sufficient to prove pipeline ──── code ──── - scripts/real-pm-smoke.js — loads root .env via dotenv resolved from server/node_modules (script dir has no node_modules of its own). ──── ambient ──── Files modified by user/linter while real-CLI work was in flight; merged without revert: - server/routes/devloop.js — new GET /:pid/requirements endpoint - server/services/devloop/path-resolver.js — listProjects() includes archived flag + helpers; supports project archive lifecycle - server/services/devloop/git-vault.js — commit() now accepts files[] to scope which paths the commit covers (avoids dragging linked-existing user's unstaged files into chore commits) - server/src/core/devloop/loop-controller.js — createProject uses explicit files:['project.json','timeline.ndjson'] for first chore commit (avoids same issue) - server/tests/devloop/path-resolver.test.js — coverage for archive/ patch/hardDelete helpers - web/src/components/devloop/RequirementListSection.vue (new) - web/src/views/DevLoopNewRequirement.vue (new) - web/src/views/DevLoopDashboard.vue — mounts RequirementListSection - web/src/views/DevLoopProjects.vue — list page polish - web/src/router/index.js — adds /devloop/:pid/requirements/new route - web/src/components/devloop/DashboardHeader.vue — back link tweak Test results: 233/233 vitest pass (was 230 → +3 path-resolver cases). ──── ⚠ SECURITY NOTE ──── .env is currently TRACKED in git (committed in b1a348b) even though .gitignore lists it. Existing committed contents include credentials for DOUBAO / FEISHU / GITHUB / GOOGLE / JWT. The CLAUDE_CODE_OAUTH_TOKEN + AZURE_OPENAI_API_KEY I just added to .env are NOT in this commit — they stay in your working tree only. Recommended follow-up (separate commit): git rm --cached .env git commit -m "chore: stop tracking .env (already gitignored)" And rotate every key that was in the previous committed .env. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> -
Two parallel pieces of plumbing — neither has been exercised end-to-end yet (real CLI gated on `claude /login`; Projects list view served alongside existing pages): ──── real-CLI wire-up (REAL.1 + REAL.2) ──── LemonBoss now has a clean toggle between mock & real Claude CLI: - packages/acp-core/protocol/ClaudeCliProtocol.js * `options.systemPrompt` → `--append-system-prompt <prompt>` so each devloop agent receives its role-specific prompt.md without losing Claude's default tool-use conventions. * `options.maxBudgetUsd` → `--max-budget-usd` (note: only effective in `--print` mode; documented inline). - server/src/core/devloop/loop-controller.js * callAgent now branches on `opts.mock`: - mock (P1-P5 path, untouched): fixture sequence + `mock/files` event - real: read system/templates/{agent}/prompt.md, pass as systemPrompt, snapshot project file mtimes pre-call, diff post-call to compute `files_written` — no fixture, no mock/files needed. * `_snapshotMtimes(root)` helper walks the project tree (skipping .git / node_modules / .cache / .tmp) and returns Map<relPath,mtime>. * timeline event payload now carries `real: true` flag. - scripts/real-pm-smoke.js — minimal real-CLI sanity: spawns claude, injects PM prompt, prints which files were written + git commit sha. Hard timeout 5min. Single agent → expected spend $0.10-0.30 per run when authenticated. Current status: process spawn + system-prompt injection + stream-json flow all verified up to the `Not logged in · Please run /login` gate. Auth is the only remaining blocker for executing the real smoke. ──── project CRUD routes ──── server/routes/devloop.js + server/services/devloop/path-resolver.js add the lifecycle pieces the Projects list view needs: - GET /projects?include_archived=true list w/ archive filter - PATCH /projects/:pid edit name + idea_summary - DELETE /projects/:pid soft delete (archive) - DELETE /projects/:pid?hard=true hard delete (rm -rf sandbox; unregister linked) - POST /projects/:pid/restore un-archive path-resolver exposes matching helpers: listProjects({includeArchived}), patchProjectMeta(pid,patch), hardDeleteProject(pid). ──── UI ──── - web/src/views/DevLoopProjects.vue (320 lines, new) — Projects list - web/src/router/index.js — adds `/devloop` → DevLoopProjects - web/src/components/devloop/DashboardHeader.vue — back-link now points to `/devloop` (project list) instead of `/company`. ──── housekeeping ──── - CLAUDE.md / start.sh — start.sh now boots server/index.js (full route surface incl. /api/devloop) instead of the historical agent-server.js; docs updated to reflect this. ──── tests (+12) ──── - server/tests/devloop/routes-crud.test.js — 12 cases: PATCH validation (4) · soft DELETE + list filter (4) · POST /restore (1) · hard DELETE (2) · GET /projects default behavior (1). Results: - phase0-verify .. phase5-verify: 8+7+7+6+9+9+7 all pass - vitest devloop+acp-core: 230/230 (was 218 → +12) Specs: - docs/prd/newfunction/_spec/arch-acp-bridge.md · Mock Mode - docs/prd/newfunction/_spec/plan-migration.md · "自举乐趣" (real path prep) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> -
Implements the §P4 acceptance gate from plan-migration.md, with one scope adjustment confirmed up-front: full Vue Dashboard (~1650 lines) deferred to a future UI phase, replaced by extending the existing P3 static status page with Sign Off / Abandon / Feedback controls. All P4 backend acceptance criteria are scripted (phase4-verify.js). Project status FSM (project.json.status): - server/src/core/devloop/loop-controller.js * draft → running → shipped → shipped-final | abandoned ↓ ↓ l2_blocked (feedback flips back to running) l2_exhausted * `_setProjectStatus` validates transitions via STATUS_TRANSITIONS, emits SSE `project.status`, writes timeline event. * createProject seeds status=draft; runDocsPhase end → running; runProject(shipped) → shipped; all dead-end branches (l2_blocked, l2_exhausted) also propagate to status via _safeSetStatus. L3 helpers: - signOff(pid, opts) — requires status=shipped → shipped-final; commits a `chore: sign-off` git entry; rejects other source states with InvalidProjectStatusTransition. - abandon(pid, opts) — any non-terminal → abandoned; commits + calls sseBroker.close(pid) to send SSE close frame to subscribers. - submitFeedback(pid, text, opts) — rejects in shipped-final/abandoned; invokes PM in incremental mode; on prd_rev bump writes changelog.ndjson prd_rev entry + emits prd.updated SSE; if prior status was shipped, flips back to running so next runProject can rebuild. PM incremental mock fixture: - fixtures/devloop-mock/devloop-pm.json — converted to sequence form: * sequence[0] (init) — original P1 fixture (PRD rev=1, 14 files). * sequence[1] (incremental) — appends a new section to prd/feature/feature-tree.html, bumps article data-rev to 2, writes history/prd-rev-002.html. Baseline happy-path Integrator: - fixtures/devloop-mock/devloop-integrator.json — single-shot pass. Makes vanilla runProject ship without a scenario override. P4 happy-path scenario: - fixtures/devloop-mock-scenarios/happy_path/devloop-architect.json — single-unit (todo-be only) Architect so end-to-end ship works with the baseline Coder/Tester (which only know todo-be paths). Routes: - server/routes/devloop.js: * POST /projects/:pid/sign-off — 400 InvalidProjectStatusTransition when status != 'shipped'; 200 returns { status }. * POST /projects/:pid/abandon — body { by?, reason?, note? }; 400 on terminal state; 200 returns { status: 'abandoned' }. * POST /projects/:pid/feedback — body { text (req), by?, mockFixtureDir? }; 400 on missing text or shipped-final/abandoned; 200 returns { prd_rev_before, prd_rev_after, status }. * POST /projects: now accepts optional `mockFixtureDir` so the same fixture dir threads through both the create call and later feedback (keeps mock-sequence counters aligned). Static status page (replaces full Vue Dashboard for P4): - server/public/devloop-status.html — adds: * Status badge in header (color-coded per status). * Sign Off / Abandon control buttons (disabled per current state). * Feedback textarea + Submit button → POST /feedback. * Buttons reflect FSM (signoff only when shipped; abandon/feedback locked at terminal states). Acceptance: - scripts/phase4-verify.js — 9 steps, full HTTP path: ① POST /projects → running ② POST /run → shipped ③ POST /feedback → PRD rev 1→2 + running (+ changelog entry) ④ POST /run again → shipped ⑤ POST /sign-off → shipped-final ⑥ POST /feedback (after sign-off) → 400 ⑦ POST /sign-off (after sign-off) → 400 ⑧ second project: POST /abandon → abandoned ⑨ POST /abandon (after abandon) → 400 Tests (+19 cases): - server/tests/devloop/p4-l3-feedback.test.js * 14 FSM cases covering happy path + abandon path + signOff pre-conditions + empty feedback rejection. * 5 route cases via fetch on ephemeral express app. Results: - phase0-verify: 8/8 - phase0-test-call: 7/7 - phase1-verify: 7/7 - phase2-verify: 6/6 - phase3-verify: 9/9 - phase4-verify: 9/9 - vitest devloop+acp-core: 213/213 (was 194 → +19) Spec deviations explicit: - Full Vue DevLoopDashboard.vue + Ops 4 sub-pages NOT implemented; static status page handles the demoable surface area instead. - All backend endpoints from §P4 (sign-off, abandon, feedback) are complete and tested. Specs: docs/prd/newfunction/_spec/plan-migration.md · P4 L3 + UI Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> -
Implements the §P3 acceptance gate from plan-migration.md: a single POST /api/devloop/projects/:pid/run drives the full project from L1 through L2 with 4 distinct BugTriager branches, observability via SSE stream + bugs.ndjson + changelog.ndjson, and a tiny static status page. Mock protocol — fallback dir: - packages/acp-core/protocol/ClaudeCliProtocol.js * New options.mockFallbackDir: when scenario dir lacks a per-agent fixture, fall back to the baseline fixtures/devloop-mock/. Enables scenario dirs to override only the agents that differ (Integrator + Triager + sometimes Architect). Scenario fixtures — 4 L2 branches: - fixtures/devloop-mock-scenarios/contract_mismatch/ * Architect: sequence[init, patch] — patch bumps sdd_rev → 2, units.json l2_rounds → 1, marks todo-be back to pending. * Integrator: sequence[fail (500 vs 201), pass]. * Triager: contract_mismatch confidence 0.85 with proposed_sdd_patch. - fixtures/devloop-mock-scenarios/impl_bug/ * Integrator: sequence[fail (ReferenceError), pass]. * Triager: impl_bug confidence 0.78 affected=[todo-be], proposed=null. - fixtures/devloop-mock-scenarios/spec_ambiguous/ * Triager: confidence 0.4 → LoopController emits human_intervention. - fixtures/devloop-mock-scenarios/infra_flake/ * Integrator: sequence[crashed (EADDRINUSE), pass]. * Triager: infra_flake confidence 0.95 affected=[]. - Each scenario also includes a 1-unit (todo-be) Architect.init fixture so baseline Coder/Tester (todo-be) can drive L1. LoopController: - server/src/core/devloop/loop-controller.js — adds: * runProject(pid, opts) — wave-scheduled L1 via _groupUnitsByWave, runIntegrator (devloop-integrator), runTriager (devloop-triager), then branch dispatch: - contract_mismatch+conf≥0.5 → Architect(patch) writes new units.json (already pending, l2_rounds++); emits sdd.updated + changelog sdd_rev entry; loop back to L1. - impl_bug+conf≥0.5 → unitRegistry.reset(affected); loop, no budget burn. - spec_ambiguous OR conf<0.5 → emit human_intervention_needed SSE, exit l2_blocked. - infra_flake → loop directly (no reset, no budget burn). * runDocsPhase + runUnit + callAgent all thread opts.mockFixtureDir through to the protocol. * Auto-attaches sseBroker to unit-registry and bug-tracker on module load — every FSM transition + bug op fires an SSE event. * bug_open at integration failure, bug_transition → fixed when subsequent L2 round passes. Routes: - server/routes/devloop.js: * POST /projects/:pid/run now defaults to full runProject; ?only=<id> still drills into single-unit runUnit (P2 compatibility). * GET /projects/:pid/stream — SSE with Last-Event-ID replay. * GET /projects/:pid/bugs?status=&unit_id=&severity= — bug list. - server/index.js + agent-server.js mount /public for static assets. Static status page: - server/public/devloop-status.html (~100 lines) — pure HTML, polls GET /state every 2s, renders unit DAG with status pills + timeline tail. URL ?pid= or input box. Acceptance: - scripts/phase3-verify.js — 9 steps across 4 scenarios + observability: ① contract_mismatch ships at sdd_rev=2 l2_rounds=1, sdd.updated SSE, changelog sdd_rev entry, bug open → fixed. ② impl_bug ships, sdd_rev=1, l2_rounds=0 (no budget burn). ③ spec_ambiguous → l2_blocked + human_intervention_needed SSE. ④ infra_flake ships, rerun_integrator action, l2_rounds=0. ⑤ Observability: timeline/bugs/changelog/stream.log present. ⑥ SSE replay from Last-Event-ID returns ≥2 historical events. Tests (+13 cases): - server/tests/devloop/run-project.test.js (11) — 4 scenarios end to end + SSE event capture. - server/tests/devloop/routes.test.js (+2) — full-project mode + bugs 404. Updated P2 ?only stub test → full-project 404 on unknown pid. Results: - phase0-verify: 8/8 - phase0-test-call: 7/7 - phase1-verify: 7/7 - phase2-verify: 6/6 - phase3-verify: 9/9 - vitest devloop+acp-core: 194/194 (was 181 → +13) Specs: - docs/prd/newfunction/_spec/plan-migration.md · P3 验收 - docs/prd/newfunction/_spec/loops-l2.md (failure attribution + budget) - docs/prd/newfunction/_spec/agents-integrator.md - docs/prd/newfunction/_spec/agents-triager.md Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> -
Implements the §P2 acceptance gate from plan-migration.md: a single POST /api/devloop/projects/:pid/run?only=todo-be drives the L1 inner loop (Coder → Tester → fail → Coder → Tester → pass), with the second Coder pass demonstrably reflecting on the first failure. Mock protocol — stateful sequences: - packages/acp-core/protocol/ClaudeCliProtocol.js * Mock fixtures now support `sequence: [{chunks,result,files}, ...]`. Each protocol.connect() + sendPrompt() consumes the next variant; sticks on the last entry after exhausted. * Static `ClaudeCliProtocol.resetMockState()` clears counters between test runs. Fixtures: - fixtures/devloop-mock/devloop-architect.json — units.json now has status:pending + retries:0 + retry_budget per unit, plus units/{todo-be,todo-db,todo-fe}/spec.json so Tester has acceptance criteria to read. - fixtures/devloop-mock/devloop-coder.json — sequence: implement (with intentional missing 400 branch) → retry (reflective fix, coder.log attempt:2 has last_failure/last_cause/this_fix/rationale). - fixtures/devloop-mock/devloop-tester.json — sequence: fail (1/3 failure with hint pointing at missing body validation) → pass (3/3). LoopController: - server/src/core/devloop/loop-controller.js — adds: * runUnit(pid, unitId, opts) — drives the L1 loop via unit-registry FSM (pending → coding → testing → failed → coding → testing → passed/blocked). Calls Coder then Tester per attempt; on failure, builds a retry context summarizing prior coder.log + tester failures and feeds it into the next Coder prompt. * _buildRetryContext + _findLatestTesterResult helpers. * callAgent now rewrites units.json.project_id to the real pid after mock writes (so unit-registry validation passes). Route: - server/routes/devloop.js — adds POST /projects/:pid/run?only=<unitId>. Without ?only, returns 501 (full project run lands in P3). Acceptance: - scripts/phase2-verify.js — 6 steps: 1. POST /projects (PM + Architect) 2. POST /run?only=todo-be returns ok=true, attempts=2, final=passed 3. FSM trail matches expected 6-step transition sequence 4. coder.log second entry has all 4 reflection fields 5. runs/ has ≥2 result.json with first.ok=false, last.ok=true 6. sandbox cross-unit + prd writes blocked by ToolSandboxError Tests (5 new cases): - server/tests/devloop/run-unit.test.js (4) — FSM trail, coder.log reflection, runs/ result chain, sandbox enforcement. - server/tests/devloop/routes.test.js (+3) — POST /run validation, full P2 loop, 404 on unknown unit. Results: - phase0-verify: 8/8 - phase0-test-call: 7/7 - phase1-verify: 7/7 - phase2-verify: 6/6 - vitest devloop+acp-core: 181/181 (was 174 → +7) Specs: - docs/prd/newfunction/_spec/plan-migration.md · P2 验收 - docs/prd/newfunction/_spec/loops-l1.md (retryWithReflection) - docs/prd/newfunction/_spec/agents-coder.md - docs/prd/newfunction/_spec/agents-tester.md Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> -
Implements the §P1 acceptance gate from plan-migration.md: a single POST /api/devloop/projects produces a runnable todo-demo project with multi-page PRD/SDD sites, units.json, integration spec, agent-state, and history snapshots — all via mock agents (no real Claude CLI cost). Code additions: - packages/acp-core/protocol/ClaudeCliProtocol.js * mock mode now emits an extra `mock/files` acp_event when the fixture contains a files[] array. LoopController applies it to the project root, letting mock agents produce real outputs. - server/src/core/devloop/loop-controller.js (now ~280 lines) * callAgent(pid, agentName, prompt, opts) — single-agent invocation: reads system/templates/{agent}/prompt.md, runs mock protocol, applies fixture files[], timeline-logs, auto-commits. * runDocsPhase(pid, requirement) — orchestrates PM → Architect with `docs.complete` timeline marker. * getProjectState(pid) — returns project.json + units + prd_rev/sdd_rev + timeline tail for the GET /state endpoint. - server/routes/devloop.js (new) * POST /api/devloop/projects — createProject + runDocsPhase * GET /api/devloop/projects * GET /api/devloop/projects/:pid/state - server/index.js / server/agent-server.js — mount /api/devloop. Mock fixtures (drive the full acceptance file tree): - fixtures/devloop-mock/devloop-pm.json * 14 files: prd/{index,reading-guide,product/*,feature/*,flow/*,prototype/*}.html, prd/assets/{shell.css,shell.js,search-index.json}, agent-state/{pm.json,pm-todo.json}, history/prd-rev-001.html. - fixtures/devloop-mock/devloop-architect.json * 13 files: sdd/{index,mvcp/*}.html, sdd/assets/*, units.json (3 units, DAG), integration/spec.json, agent-state/{architect.json,architect-todo.json}, history/sdd-rev-001.html. Acceptance: - scripts/phase1-verify.js — spins ephemeral express app, POSTs the todo-demo project, asserts 23 expected paths exist + 3 units with l2_rounds/l2_budget + git ≥4 commits + timeline events. Tests (12 new cases): - server/tests/devloop/loop-controller.test.js (7) — callAgent + runDocsPhase + state. - server/tests/devloop/routes.test.js (5) — POST validation, full POST, GET state, 404 on unknown pid. Results: - phase0-verify: 8/8 - phase0-test-call: 7/7 - phase1-verify: 7/7 - vitest devloop+acp-core: 174/174 (was 162 → +12) Specs: docs/prd/newfunction/_spec/plan-migration.md · P1 Docs MVP Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> -
Final P0 deliverables to make the system bootable in mock mode and pass `scripts/phase0-verify.js` + `scripts/phase0-test-call.js` end-to-end. ClaudeCliProtocol (mock mode): - LEMONBOSS_CLAUDE_MODE=mock or { mock: true } in constructor enables mock mode. connect() becomes a no-op; sendPrompt reads fixtures from fixtures/devloop-mock/{agentName}.json and emits scripted session_update chunks + session/result(mock=true). Falls back to default.json. Agent registry: - 6 entries added to system/templates/_registry.json (devloop-pm, devloop-architect, devloop-coder, devloop-tester, devloop-integrator, devloop-triager). - Per-agent dirs system/templates/devloop-{role}/ with: * prompt.md — auto-extracted from agents-{role}.html §2.2 * config.json — cli.toolPolicy.allowedTools + sandbox.writeAllowList Tooling: - scripts/extract-agent-prompts.js — regex-extracts §2.2 system prompts from 6 agent HTML pages to system/templates/devloop-{role}/prompt.md. - server/src/tools/devloop/index.js — central export (tools Map, bashHooks, dispatch). - server/src/core/devloop/loop-controller.js (P0 skeleton) — exposes createProject (sandbox alloc + git init + first commit + timeline) and commitAfterAgent (per-agent kind-routed git commit + timeline event). Mock fixtures: - fixtures/devloop-mock/default.json + devloop-pm.json Acceptance scripts: - scripts/phase0-verify.js — 8 static checks (35 tools loadable, 6 agents registered, prompt+config wired, bash guard exported, services require, fixtures present, git-vault interface, loop-controller). - scripts/phase0-test-call.js — 7 end-to-end steps under mock mode (createProject → CLI connect → sendPrompt chunks → no-op commit returns null → real write commits → git log ≥2 → timeline has both events). vitest.config.js: include packages/**/*.test.js so the mock smoke test runs in the suite. Results: - 162/162 devloop + acp-core tests pass (up from 159). - phase0-verify: 8/8. - phase0-test-call: 7/7. Specs: docs/prd/newfunction/_spec/plan-migration.md · Quick-Start step 7 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> -
Adds the DevLoop Agent tool layer (CommonJS) under server/src/tools/devloop: - _errors.js / _sandbox.js — shared infra (3 error classes + path allow-list w/ {unitId}) - tool-registry.js — loadAllTools / dispatch / listToolNames / getDevLoopTools - persistence-tools.js (5) — write_todolist · update_todo_item · update_runtime_state · timeline_append · record_memory - doc-tools.js (12) — bootstrap_prd_site · bootstrap_sdd_site · write_chapter · write_mvcp_page · archive_doc · diff_html · diff_units · echo_diff · update_search_index · validate_prd_site · validate_sdd_consistency · hash_contract - coder-tools.js (3) — contract_bridge · sandbox_check · append_coder_log (retry fields required) - tester-tools.js (5) — parse_vitest · hint_builder · bug_open · bug_transition · bug_list - integrator-tools.js (6) — port_picker · spawn_units · health_wait · run_case · parse_placeholder · collect_stderr - triager-tools.js (4) — extract_evidence · category_classifier · diff_contract_vs_impl · find_similar_bug - bash-json-guard.js — preExecute hook blocking inline JSON in Bash (CLAUDE.md L91-99) Total: 35 callable devloop tools. Tests: 88 cases across 9 files, all passing; combined with P0.0 services suite the project now has 159 green tests. Specs: - docs/prd/newfunction/_spec/arch-tool-registry.md - docs/prd/newfunction/_spec/agents-{pm,architect,coder,tester,integrator,triager}.md Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
-
- Moved data/system/ → system/ (agents, templates, skills, data, workspace) - Updated all server route/service path references - Updated all script path references - Updated all documentation references - Restructured .gitignore for cleaner system/ vs data/ boundary system/ = platform-shared assets (system agents, template library) data/ = tenant-specific company instance data
-
- System agents: 只保留 master (data/system/agents/master) - Templates: 所有可复用 agent 模板 (data/system/templates/) - Companies: 公司创建时自动部署 5 个元 Agent (innovator/hunter/digester/evolver/agent-creator) 路径修复: - agent-chat.js: /list 扫描路径修正 (system/agents + companies/*/agents) - agent-manager.js: 动态 agent 查找路径修正 - skill-config-loader.js: 修正 agents root - pipeline-service.js: pipelines 输出到 companies/{id}/pipelines/ - billing.log: 移至 companies/{id}/logs/ 下 Skills 标准化: - 所有 template agent 建立 .claude/skills/main_skill/SKILL.md - company-service._copyTemplate() 新增 .claude/ 目录复制 - innovator SKILL.md v3.0: 移除旧 l3-hunt/l2-digest 命名 - 清理重复 agent_creator, 统一为 agent-creator 清理: - 移除 data/agents, data/workspace, data/logs, data/goals 旧目录 - 清除所有未使用的 DATA_DIR 声明 - 清除 template 中的 conversations/logs/memory 运行态数据 -
The plugin bootstrap was calling resolveOpenclawDist() synchronously at module load time, which crashed the entire server if the optional @mas/openclaw-dist package wasn't installed. Now all three call sites defer resolution to runtime with try/catch graceful fallback.
-
…ter Agent cognitive auto-recovery loop - Refactored CompanyDashboard into read-only Observer UI - Enforced strict companyId:roleId namespacing across Node APIs and AgentManager - Added dynamic <env_status> injection to PromptBuilder for robust context - Introduced bin/lemon.js CLI for structured LLM tool execution - Implemented in-stream error interceptors for implicit silent retry loop
-
- Implement OKR GoalsService with hierarchical node tracking - Add /api/goals routes and integrate with dispatch/report APIs - Create Innovator agent with Hunt→Digest→Evolving pipeline - Create Hunter (l3-hunt), Digester (l2-digest), Evolver (evolving) meta agents - Copy L1/L2 dependency skills into each agent's .claude/skills/ - Fix buildSystemPrompt to scan ALL skill subdirectories (critical) - Fix agent list sorting: master pinned top, rest by lastActiveAt - Rename master-001→master, innovator-001→innovator - Establish meta agent output convention: write to target agent dir - Add CXO agent base class for management agents - Update CEO agent with delegation-first management model
-
- Agent as Micro-Container: each agent lives in data/agents/{id}/ with full encapsulation - Persona vs Capability split: agent.md (identity) + .claude/skills/main_skill/SKILL.md (workflow) - Conversations co-located: data/agents/{id}/conversations/ replaces global dir - Meta Skills renamed: meta_hunt, meta_digest, meta_creator, meta_evolving, meta_benchmark, meta_research - Dynamic Hot-Reload: AgentManager.getAgentConfig() falls back to filesystem scan - Parallel Sub-Agent orchestration via Promise.all with multi-terminal UI - Removed SQLite dependency, global skills/ directory, and legacy conversations/ - Full architecture docs: 18-local-filesystem-first-agent-encapsulation.md