refactor: move project instructions to prompt group
This commit is contained in:
@@ -9,6 +9,7 @@ Packages are grouped by modular role at `packages/<group>/<pkg>/`. The group dir
|
||||
| Group | Role | Release expectation |
|
||||
|---|---|---|
|
||||
| [`core/`](core/README.md) | Product API spine: session, system-prompt, tools, agent, and the concrete loop | Product — stable surface |
|
||||
| [`prompt/`](prompt/README.md) | Prompt and request-context extensions that shape model inputs | Product — stable surface |
|
||||
| [`llm/`](llm/README.md) | LLM capability family: the abstract service + provider adapters | Product — stable surface |
|
||||
| [`bash/`](bash/README.md) | Bash capability family: the executor seam, a local impl, and the model-facing tool | Product — stable surface |
|
||||
| [`compact/`](compact/README.md) | Compaction capability family: the abstract seam (backend + tool deferred) | Product — stable surface |
|
||||
@@ -63,9 +64,9 @@ The rule: **extension** plugins depend on interfaces, never on the concrete loop
|
||||
| `system-prompt/` | `core` | Prompt-section + tool-schema assembly registry | `ctx.systemPrompt` |
|
||||
| `tools/` | `core` | Tool registry + `tools/execute` waterfall | `ctx.tools` |
|
||||
| `agent/` | `core` | Agent interface, registry, `agent/*` event vocabulary | `ctx.agents` |
|
||||
| `project-instructions/` | `core` | `AGENTS.md`/`CLAUDE.md` workspace context loader | (listens on `agent/request`) |
|
||||
| `agent-loop/` | `core` | THE concrete loop plugin: `ReactLoopAgent` + the loop driver | `ctx.agentLoop` |
|
||||
| `agent-core/` | `core` | Bundle plugin: the providerless/executor-less/UI-less spine as code (forwards `agent-loop`'s `agents`) | (loads the spine) |
|
||||
| `project-instructions/` | `prompt` | `AGENTS.md`/`CLAUDE.md` workspace context loader | (listens on `agent/request`) |
|
||||
| `bash/` | `bash` | Abstract bash executor seam (interface + vocabulary) | `ctx.bash` |
|
||||
| `bash-local/` | `bash` | Local-subprocess `BashExecutor` implementation | (registers `ctx.bash`) |
|
||||
| `tool-bash/` | `bash` | Model-facing `bash`/`bash_output`/`bash_kill` tool schemas | (registers on `ctx.tools`) |
|
||||
|
||||
@@ -8,10 +8,9 @@ The packages every harness build is assembled from: the session log, the system-
|
||||
| `system-prompt/` | Prompt-section + tool-schema assembly registry | `ctx.systemPrompt` |
|
||||
| `tools/` | Tool registry + `tools/execute` waterfall | `ctx.tools` |
|
||||
| `agent/` | Agent interface, registry, `agent/*` event vocabulary | `ctx.agents` |
|
||||
| `project-instructions/` | `AGENTS.md`/`CLAUDE.md` workspace context loader | (listens on `agent/request`) |
|
||||
| `agent-loop/` | The concrete loop plugin: `ReactLoopAgent` + the loop driver | `ctx.agentLoop` |
|
||||
| `agent-core/` | Bundle plugin: the providerless/executor-less/UI-less spine as code | (loads the spine) |
|
||||
|
||||
`agent-loop` is the one concrete implementation of the `agent` seam and lives here because it is the harness's default product loop; everything else in `core/` is interface/vocabulary. Plugins depend on the `agent` vocabulary, never on `agent-loop` directly, so the loop stays swappable.
|
||||
|
||||
`agent-core` is the composition counterpart: one bundle plugin that loads the whole providerless spine (`timer` + `llm` + sessions + system-prompt + tools + agents + invariants + `tool-bash` + project-instructions + `agent-loop`) and forwards `agent-loop`'s `agents` list as its own config. App packages (`ui/stdio-agent`, `ui/acp-agent`) consume it and add only a front door; a leaf adds only the swappable backends. It lives in `core/` because it composes exclusively `core/` + interface packages and ships no provider, executor, or UI of its own.
|
||||
`agent-core` is the composition counterpart: one bundle plugin that loads the whole providerless spine (`timer` + `llm` + sessions + system-prompt + tools + agents + invariants + `tool-bash` + project-instructions + `agent-loop`) and forwards `agent-loop`'s `agents` list as its own config. App packages (`ui/stdio-agent`, `ui/acp-agent`) consume it and add only a front door; a leaf adds only the swappable backends. It lives in `core/` because it is the default spine bundle and ships no provider, executor, or UI of its own; it may include product prompt/tool extensions that are common to every front door.
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
"path": "../../core/agent"
|
||||
},
|
||||
{
|
||||
"path": "../../core/project-instructions"
|
||||
"path": "../../prompt/project-instructions"
|
||||
},
|
||||
{
|
||||
"path": "../../core/agent-loop"
|
||||
|
||||
9
packages/prompt/README.md
Normal file
9
packages/prompt/README.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# prompt/ — prompt and request-context extensions
|
||||
|
||||
Product packages that contribute model-facing prompt or request-context behavior without being core agent/session/tool primitives. These packages usually consume existing seams such as `agent/request` or `system-prompt/assemble`; they do not own the loop and do not provide LLM adapters, execution backends, or UI front doors.
|
||||
|
||||
| Package | Role | ctx key |
|
||||
|---|---|---|
|
||||
| `project-instructions/` | `AGENTS.md`/`CLAUDE.md` workspace context loader | (listens on `agent/request`) |
|
||||
|
||||
`project-instructions` lives here because it is semantically a prompt/context extension: it adds workspace guidance to the model request. It deliberately uses the per-agent `agent/request` seam instead of a global `ctx.systemPrompt.section()` so multiple live sessions with different `cwd` values do not leak instruction files into one another.
|
||||
@@ -1,7 +1,7 @@
|
||||
import { chmod, mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises'
|
||||
import { join } from 'node:path'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { Context } from 'cordis'
|
||||
import type { GenerateOptions } from '@deepseek-ai/dsh-llm'
|
||||
import { Session, SessionId, SESSION_FORMAT_VERSION } from '@deepseek-ai/dsh-session'
|
||||
@@ -198,16 +198,18 @@ describe('project instruction discovery', () => {
|
||||
it('labels the default DSH home as ~/.dsh when HOME points at the configured default', async () => {
|
||||
const root = await tempRepo()
|
||||
const home = await tempRepo()
|
||||
const previousHome = process.env.HOME
|
||||
try {
|
||||
process.env.HOME = home
|
||||
await write(join(home, '.dsh/AGENTS.md'), 'global default rule')
|
||||
|
||||
const files = await discoverBaselineInstructionFiles({ cwd: root })
|
||||
vi.resetModules()
|
||||
vi.doMock('node:os', () => ({ homedir: () => home }))
|
||||
const isolated = await import('@deepseek-ai/dsh-project-instructions')
|
||||
const files = await isolated.discoverBaselineInstructionFiles({ cwd: root })
|
||||
|
||||
expect(files.map(file => file.displayPath)).toEqual(['~/.dsh/AGENTS.md'])
|
||||
} finally {
|
||||
process.env.HOME = previousHome
|
||||
vi.doUnmock('node:os')
|
||||
vi.resetModules()
|
||||
await rm(root, { recursive: true, force: true })
|
||||
await rm(home, { recursive: true, force: true })
|
||||
}
|
||||
Reference in New Issue
Block a user