Imported from hua-bang/pulse-agent (
packages/engine/AGENTS.md). Install upstream withnpx skills add hua-bang/pulse-agent --skill engine. Copyright stays with the author.
AGENTS.md - packages/engine
Local entry for
packages/engine. Repository harness entry:../../harness/README.md.
Module Positioning
pulse-coder-engine owns the reusable Pulse Coder runtime: the Engine/PulseAgent public API, provider selection, prompt assembly, context compaction, the streaming/tool execution loop, plugin lifecycle, hooks, services, built-in tools, and built-in plugins.
It should stay host-agnostic. CLI, remote server, canvas, ACP, and teams-specific behavior should integrate through options, plugins, hooks, tools, or services rather than being hardcoded into the core loop.
Knowledge Navigation
| Task | Read |
|---|---|
| Package overview and scripts | README.md, package.json |
| Public contracts | harness/knowledge/contracts.md |
| Architecture map + runtime invariants | harness/knowledge/architecture.md |
| Plugin mechanism and authoring | harness/knowledge/plugin-system.md |
| Loop lifecycle, timeouts, retries | harness/knowledge/loop-lifecycle.md |
| Built-in tools reference | harness/knowledge/tools-reference.md |
Orchestration module (task graph, scheduler, /orchestrator subpath) |
harness/knowledge/orchestrator.md |
| Embedding the engine in a host | harness/knowledge/host-integration.md |
| Env knobs, defaults, runtime files, compaction/offload | harness/knowledge/config-reference.md |
| Security posture, sandboxing, threat surfaces | harness/knowledge/security-posture.md |
| Confirmed-but-unfixed defects | harness/knowledge/known-defects.md |
| Undecided design/contract intent (decision-pending) | harness/spec/README.md |
| Validation | harness/validate/README.md, harness/validate/validation.yaml |
| Public exports | src/index.ts |
| Engine bootstrap and options | src/Engine.ts |
| Execution loop, streaming, retry, abort, compaction | src/core/loop.ts, src/context/ |
| Provider, model, and prompt behavior | src/config/index.ts, src/ai/index.ts, src/prompt/ |
| Plugin lifecycle, hooks, services, config plugins | src/plugin/EnginePlugin.ts, src/plugin/PluginManager.ts, src/plugin/UserConfigPlugin.ts |
| Built-in plugin order and exports | src/built-in/index.ts, src/built-in/*/ |
| Built-in tool registry and schemas | src/tools/index.ts, src/tools/ |
| Focused behavior tests | src/core/loop.test.ts, src/plugin/plugin-manager.test.ts, src/built-in/**/*.test.ts, src/tools/*.test.ts |
Local Constraints
- Prefer plugin, hook, tool, or service extension points over engine-loop hardcoding.
- Preserve tool merge order: built-in tools, then plugin tools, then
EngineOptions.toolsas the highest-priority override layer. - Built-in plugins are loaded automatically unless
disableBuiltInPluginsis set; adding, removing, or reordering them can affect CLI, remote server, canvas, and agent teams consumers. remote-server and canvas disable the defaults and hand-assemble their own ordered lists — new default plugins do NOT propagate to them automatically. - Keep source imports ESM-style and follow package-local TypeScript strictness.
- Public exports,
EngineOptions, hook signatures, service names, built-in tool schemas, and built-in plugin behavior are contracts; readharness/knowledge/contracts.mdbefore changing them. - Preserve
.pulse-coder/*paths and legacy.coder/*compatibility unless there is an explicit migration plan. - The public surface lives in TWO barrels:
src/index.tsandsrc/built-in/index.ts(./built-inis wider). Export changes must consider both — remote-server and canvas import./built-indirectly. tsconfig.jsonhas norootDiron purpose: the agent-teams built-in imports orchestrator source through the root paths alias, and re-addingrootDirbreakstypecheckwith TS6059.- Durable engine guidance changes should update this file or the local
harness/files instead of adding parallel notes.
Common Commands
pnpm --filter pulse-coder-engine test
pnpm --filter pulse-coder-engine typecheck
pnpm --filter pulse-coder-engine build
pnpm --filter pulse-coder-cli test
pnpm --filter @pulse-coder/remote-server build
Default checks are test and typecheck. Use build for public exports or package configuration changes. Cross-consumer checks are selected from the root impact overlay when public API, built-in plugin, runtime-loop, or tool contracts change. Docs-only changes only need referenced path/command checks per harness/validate/README.md.
Key Files
src/index.ts: public exports, including thePulseAgentalias and built-in plugin/type exports.src/Engine.ts: engine bootstrap, provider/model option resolution, plugin/tool merge order, compaction helper, and plan-mode service helpers.src/core/loop.ts: streaming loop, LLM/tool hooks, retries/backoff, abort handling, timeout handling, tool results, and context compaction.src/plugin/: plugin manager, hook map, service/config APIs, dependency ordering, and user config plugin loading.src/built-in/index.ts: built-in plugin registration order and public built-in plugin exports.src/tools/index.ts: built-in tool registry for file, shell, Tavily, image generation, clarification, and deferred demo tools.harness/knowledge/,harness/validate/: package contract, architecture, and validation source of truth.
Local harness surfaces: knowledge/, spec/, validate/, tools/, skills/.
harness/tools/describe-engine.mjs— structure snapshot (plugin order + deps, both-barrel asymmetry, full tool registry with defer_loading) from the built package. Run before changing built-in plugins/tools so you edit against ground truth, not drift-prone prose. Readsdist, so build first.harness/skills/add-builtin-plugin.md— ordered procedure for adding/modifying a built-in plugin (sequence + landmines + pointers, not restated facts).harness/skills/add-builtin-tool.md— the parallel procedure for adding/modifying a built-in tool (non-blocking/shell-safe rule, defer_loading, registry + escalation).harness/spec/— decision-pending intent: places where current behavior may not be intended and a maintainer must choose (public-surface accidents, inert user-config, gating posture, dead knobs). Distinct fromknowledge/(current-state facts, incl.known-defects.md) andskills/(how-to). An emptyspec/is the success state. Pass/fail checks stay in the repo runner (scripts/harness/run-harness-check.mjs); these local surfaces cover orientation (tool) and safe-change sequence (skill), which the runner does not.
Failure Capture
- Before history cleanup, read
harness/knowledge/loop-lifecycle.md; new cleanup must ship a regression test preserving later user turns. Tool I/O/UTF-8 guards live inharness/knowledge/tools-reference.md. - Engine/plugin code logs through
console.*; never write raw stdout/stderr under a host. Detail:harness/knowledge/host-integration.md(Logging ownership). - Tools must be non-blocking and shell-safe: pass args as arrays to async
execFile/spawn, never build shell strings (bothbash.tsandgrep.tswere fixed after blocking-I/O / injection bugs — seeharness/knowledge/architecture.mdRisk Areas).