duaer-spec 0.6.4 → 0.8.0

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.
@@ -0,0 +1,62 @@
1
+ <!-- duaer-spec agent ops (develop+main, feat/fix, .worktree, push opt-in) -->
2
+
3
+ # Agent development workflow
4
+
5
+ Part of **duaer-spec**. Authoritative over Duaer when they conflict.
6
+
7
+ ## Required branches
8
+
9
+ | Branch | Role |
10
+ |---|---|
11
+ | `main` | Production / online |
12
+ | `develop` | Day-to-day integration |
13
+ | `feat/<name>` | Feature → merge to `develop` |
14
+ | `fix/<name>` | Bugfix → `develop` (hotfix: from `main` → `main` then `develop`) |
15
+
16
+ Detail: `docs/agent/branching-and-release.md`.
17
+
18
+ ## Isolated development (mandatory worktree)
19
+
20
+ Before editing files for a new request:
21
+
22
+ 1. Update local **`develop`** (hotfix: **`main`**)
23
+ 2. Create `feat/<name>` or `fix/<name>`
24
+ 3. Create worktree at **`.worktree/feat-<name>`** or **`.worktree/fix-<name>`**
25
+ (slash → hyphen). Do **not** reuse the Brief folder name
26
+ (`.duaer/specs/<nnn-slug>/`) as the worktree id.
27
+ 4. Develop only inside that worktree
28
+ 5. Never develop on `main` / `develop` or in the primary checkout
29
+ 6. Never reuse another agent's branch/worktree
30
+ 7. Never commit `.worktree/`
31
+
32
+ ```bash
33
+ mkdir -p .worktree
34
+ git worktree add .worktree/feat-login -b feat/login develop
35
+ cd .worktree/feat-login
36
+ # Brief lives inside the checkout, e.g. .duaer/specs/002-login/
37
+ ```
38
+
39
+ ## Immutable habits
40
+
41
+ - Spec-sync for behavior changes; ADR when architecture/security/contracts change
42
+ - One logical change per commit; leave the worktree clean
43
+ - User/protocol-visible changes update E2E scenario docs
44
+ - Merge into **`develop`** when done (hotfix: **`main`**, then back-merge **`develop`**)
45
+ - **Handoff (mandatory):** stop worktree-bound processes → remove `.worktree/<id>` →
46
+ restart from primary checkout on `develop` (`duaer handoff [--run]`, `.duaer/handoff.json`)
47
+ - Push only when the user explicitly asks
48
+ - Promote **`develop` → `main`** only when the user asks to go online
49
+
50
+ ## GitHub issue / PR intake
51
+
52
+ Issue: verify before work; comment in issue language; close when conclusive.
53
+ PR: judge principle; merge sound PRs; no silent reimplementation.
54
+ Neither authorizes push by itself.
55
+
56
+ ## Commits
57
+
58
+ ```text
59
+ type(scope): description
60
+ ```
61
+
62
+ Types: `feat fix docs test chore refactor perf build ci` — English, imperative.
@@ -0,0 +1,9 @@
1
+ <!-- Keep AI-generated page copy minimal (duaer-spec agent ops) -->
2
+
3
+ # AI-generated page content
4
+
5
+ AI-generated pages must not contain redundant explanatory text.
6
+
7
+ - No filler introductions, repeated summaries, or prose that only explains an obvious control
8
+ - Prefer concise labels, headings, helper text, and empty states
9
+ - Put rationale and implementation detail in docs or code comments, not in the UI, unless the user asks for explanatory content
@@ -0,0 +1,51 @@
1
+ <!-- Autonomous digital employee — run Duaer job loop without asking the user to operate -->
2
+
3
+ # Digital employee (autonomous)
4
+
5
+ You are a **digital employee** in this repo. The human gives intent in normal
6
+ language. **You** run the delivery process. Do **not** ask them to type slash
7
+ commands, CLI flags, or phase names (`specify`, `plan`, `tasks`, …).
8
+
9
+ If this conflicts with root `AGENTS.md` (worktrees, commits, Issue/PR),
10
+ **AGENTS.md wins**.
11
+
12
+ ## When the human asks for work
13
+
14
+ For new behavior, fixes, refactors that change product behavior, or architecture:
15
+
16
+ 0. **Isolate first (mandatory):** update **`develop`** (hotfix: **`main`**),
17
+ create `feat|fix/<name>`, add worktree at `.worktree/feat-<name>` or
18
+ `.worktree/fix-<name>` (slash → hyphen). Never name the worktree after the
19
+ Brief folder (do **not** use `.worktree/<nnn-slug>` when the Spec is
20
+ `.duaer/specs/<nnn-slug>/`). Work only in the worktree. Never commit
21
+ `.worktree/`. Never develop on `main` or `develop`.
22
+ 1. **Silently follow** the procedure in `.claude/skills/duaer-do/SKILL.md`
23
+ (assign Brief → light tasks → implement → converge → handoff line).
24
+ 2. Do **not** wait for `/duaer-do` or any other skill invocation.
25
+ 3. Do **not** say “please run `/duaer-specify`” — you do it.
26
+ 4. Do **not** dump a methodology tutorial unless they ask how Duaer works.
27
+ 5. Merge to **`develop`** when done (hotfix: **`main`**, then back-merge
28
+ **`develop`**). Promote to **`main`** only if the user asks to go online.
29
+ 6. **Handoff (mandatory):** stop processes bound to `.worktree/<id>/`, remove
30
+ the worktree, then restart services from the primary checkout on `develop`
31
+ using `.duaer/handoff.json` / `duaer handoff [--run]`. Never leave the user
32
+ on a dead worktree server.
33
+ See `docs/agent/branching-and-release.md`.
34
+
35
+ ## Handoff
36
+
37
+ - End with whether the **job** is accepted or still open (one clear line).
38
+ - Do **not** claim “done” / “finished” / “complete” unless `delivery.json` is
39
+ `accepted` and open tasks are clear.
40
+ - Do **not** tell them to run `duaer status` unless they want a machine check;
41
+ you already know the handoff state.
42
+
43
+ ## Forbidden
44
+
45
+ - Jump from chat to code with no Brief under `.duaer/specs/`.
46
+ - Making the human operate the workflow.
47
+
48
+ ## Optional finer tools (agent-only)
49
+
50
+ Step skills (`duaer-specify`, `duaer-plan`, …) are **your** playbooks when a
51
+ job is large. The human should not need to know they exist.
@@ -22,7 +22,8 @@ For new behavior, fixes, refactors that change product behavior, or architecture
22
22
  Brief folder (do **not** use `.worktree/<nnn-slug>` when the Spec is
23
23
  `.duaer/specs/<nnn-slug>/`). Work only in the worktree. Never commit
24
24
  `.worktree/`. Never develop on `main` or `develop`.
25
- 1. **Silently follow** the procedure in `.cursor/skills/duaer-do/SKILL.md`
25
+ 1. **Silently follow** the procedure in the `duaer-do` skill
26
+ (`.cursor/skills/duaer-do/SKILL.md` or `.claude/skills/duaer-do/SKILL.md`)
26
27
  (assign Brief → light tasks → implement → converge → handoff line).
27
28
  2. Do **not** wait for `/duaer-do` or any other skill invocation.
28
29
  3. Do **not** say “please run `/duaer-specify`” — you do it.
package/ADOPT.md CHANGED
@@ -32,9 +32,14 @@ npx duaer-spec init --here --ops
32
32
  npx duaer-spec update --method # rare; usually omit
33
33
  ```
34
34
 
35
+ Works with **Cursor**, **Claude Code**, and **Codex** (all hosts installed by default).
36
+
35
37
  ## What you get
36
38
 
37
39
  - Autonomous job loop (ask → Brief → work → accept)
40
+ - Cursor: `.cursor/rules` + `.cursor/skills`
41
+ - Claude Code: `CLAUDE.md` + `.claude/rules` + `.claude/skills`
42
+ - Codex: `AGENTS.md` + `.agents/skills`
38
43
  - `.duaer/handoff.json` + `duaer handoff` after worktree remove
39
44
  - Agent ops: `main` / `develop` / `feat` / `fix` + `.worktree/`
40
45
 
package/AGENTS.md CHANGED
@@ -19,6 +19,21 @@ documentation unless the adopting project explicitly overrides.
19
19
 
20
20
  Follow the project's [baseline](docs/baseline.md) (or its local equivalent).
21
21
 
22
+ ## Autonomous job loop (all hosts)
23
+
24
+ For product work (new behavior, fixes, refactors), **you** run Brief → work →
25
+ accept. Do **not** ask the human to type slash commands, phase names, or CLI
26
+ flags.
27
+
28
+ 1. Isolate: `feat|fix/<name>` + `.worktree/feat-<name>/` (or `fix-…`); never
29
+ reuse the Brief folder name as the worktree id.
30
+ 2. Follow the `duaer-do` skill under the host skill root:
31
+ - Codex: `.agents/skills/duaer-do/SKILL.md`
32
+ - Cursor: `.cursor/skills/duaer-do/SKILL.md`
33
+ - Claude Code: `.claude/skills/duaer-do/SKILL.md`
34
+ 3. Briefs live in `.duaer/specs/<nnn-slug>/`. Method notes: [`DUADER.md`](DUADER.md).
35
+ 4. One handoff line; never claim done unless `delivery.json` is `accepted`.
36
+
22
37
  ## GitHub Issue Handling
23
38
 
24
39
  When the user provides a GitHub issue URL (or an unambiguous issue number for
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.8.0 — 2026-09-15
4
+
5
+ ### Codex host
6
+
7
+ - Mirror `duaer-*` skills to `.agents/skills/` (Codex discovery path)
8
+ - `AGENTS.md` always-on section names the Codex / Cursor / Claude skill roots
9
+ - Cursor and Claude Code installs unchanged
10
+
11
+ ## 0.7.0 — 2026-09-15
12
+
13
+ ### Claude Code host
14
+
15
+ - `init` / `update` install **both** Cursor and Claude Code surfaces
16
+ - Claude: `CLAUDE.md`, `.claude/rules/*.md`, `.claude/skills/duaer-*` (mirrored)
17
+ - Cursor: `.cursor/rules/*.mdc`, `.cursor/skills/duaer-*` (unchanged)
18
+
3
19
  ## 0.6.4 — 2026-09-15
4
20
 
5
21
  ### Worktree ≠ Brief folder name
package/CLAUDE.md ADDED
@@ -0,0 +1,27 @@
1
+ # CLAUDE.md — duaer-spec
2
+
3
+ This repository uses **duaer-spec**: coding agents are digital employees.
4
+
5
+ **Precedence:** `AGENTS.md` (ops) wins over `DUADER.md` / `.duaer/` (method).
6
+
7
+ ## Always on
8
+
9
+ - Follow `.claude/rules/` in this project.
10
+ - For product work, run the job loop in `.claude/skills/duaer-do/SKILL.md`
11
+ without waiting for slash commands.
12
+ - Do not ask the human to operate phases, CLI flags, or skill names.
13
+
14
+ ## Layout
15
+
16
+ | Host | Always-on | Skills |
17
+ |---|---|---|
18
+ | Cursor | `.cursor/rules/` | `.cursor/skills/` |
19
+ | Claude Code | `CLAUDE.md` + `.claude/rules/` | `.claude/skills/` |
20
+ | Codex | `AGENTS.md` | `.agents/skills/` |
21
+
22
+ Installed by `npx duaer-spec init --here` / `update`.
23
+
24
+ ## Branches
25
+
26
+ See `docs/agent/branching-and-release.md` and `AGENTS.md`.
27
+ Worktree: `.worktree/feat-<name>/` — not the same name as `.duaer/specs/<nnn-slug>/`.
package/DUADER.md CHANGED
@@ -14,7 +14,7 @@ runs Brief → work → accept. Humans are not the operators of the phase machin
14
14
 
15
15
  ## Agent procedure (autonomous)
16
16
 
17
- Follow `.cursor/skills/duaer-do/SKILL.md` on every product ask — **without**
17
+ Follow the `duaer-do` skill (`.cursor/skills/`, `.claude/skills/`, or `.agents/skills/`) on every product ask — **without**
18
18
  waiting for a slash invocation:
19
19
 
20
20
  1. Assign Brief + `active-job.json`
@@ -38,8 +38,9 @@ Humans need not configure it for everyday use.
38
38
  .duaer/active-job.json
39
39
  .duaer/specs/<nnn-slug>/ # Brief (≠ worktree folder name)
40
40
  spec.md | tasks.md | delivery.json
41
- .cursor/rules/duaer-spec.mdc # autonomous behavior
42
- .cursor/skills/duaer-do/ # default job loop
41
+ .cursor/rules|skills/ # Cursor host
42
+ .claude/rules|skills/ + CLAUDE.md # Claude Code host
43
+ .agents/skills/ + AGENTS.md # Codex host
43
44
  ```
44
45
 
45
46
  Worktree and Brief are different layers. Prefer
package/README.md CHANGED
@@ -19,7 +19,9 @@ npx duaer-spec init --here
19
19
  npx duaer-spec update
20
20
  ```
21
21
 
22
- Then use Cursor as usual — describe what you want.
22
+ Then use **Cursor**, **Claude Code**, or **Codex** — describe what you want.
23
+
24
+ Install writes `.cursor/`, `.claude/` (+ `CLAUDE.md`), and `.agents/skills/` (Codex).
23
25
 
24
26
  中文说明:[`README.zh-CN.md`](README.zh-CN.md)
25
27
 
package/README.zh-CN.md CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  **Duaer** 把 AI 编程助手变成**数字员工**:你用自然语言提需求,它自己跑 Spec → 实现 → 验收;只有交接干净才算完成。
4
4
 
5
- 你**不用**操作流程。装一次之后,说话即可。
5
+ 你**不用**操作流程。装一次之后,在 **Cursor**、**Claude Code** 或 **Codex** 里说话即可。
6
+
7
+ `init` / `update` 会写入 `.cursor/`、`.claude/`(+ `CLAUDE.md`)、以及 Codex 的 `.agents/skills/`。
6
8
 
7
9
  ## 安装
8
10
 
package/bin/duaer.mjs CHANGED
@@ -209,13 +209,27 @@ function installMethod(target, opts) {
209
209
  writeDefaultPolicy(target, opts)
210
210
  writeDefaultHandoff(target, opts)
211
211
 
212
- ensureDir(join(target, '.cursor', 'skills'))
212
+ installCursorMethod(target, opts)
213
+ installClaudeMethod(target, opts)
214
+ installCodexMethod(target, opts)
215
+
216
+ copyPath(join(PKG_ROOT, 'DUADER.md'), join(target, 'DUADER.md'), opts)
217
+ console.log(' DUADER.md')
218
+ ensureWorktreeGitignore(target)
219
+ }
220
+
221
+ function mirrorDuaerSkills(target, skillsDir, opts, label) {
222
+ ensureDir(skillsDir)
213
223
  const skillsRoot = join(PKG_ROOT, '.cursor', 'skills')
214
224
  for (const name of readdirSync(skillsRoot)) {
215
225
  if (!name.startsWith('duaer-')) continue
216
- copyPath(join(skillsRoot, name), join(target, '.cursor', 'skills', name), opts)
226
+ copyPath(join(skillsRoot, name), join(skillsDir, name), opts)
217
227
  }
218
- console.log(' .cursor/skills/duaer-*')
228
+ console.log(` ${label}`)
229
+ }
230
+
231
+ function installCursorMethod(target, opts) {
232
+ mirrorDuaerSkills(target, join(target, '.cursor', 'skills'), opts, '.cursor/skills/duaer-*')
219
233
 
220
234
  ensureDir(join(target, '.cursor', 'rules'))
221
235
  copyPath(
@@ -224,10 +238,72 @@ function installMethod(target, opts) {
224
238
  opts,
225
239
  )
226
240
  console.log(' .cursor/rules/duaer-spec.mdc')
241
+ }
227
242
 
228
- copyPath(join(PKG_ROOT, 'DUADER.md'), join(target, 'DUADER.md'), opts)
229
- console.log(' DUADER.md')
230
- ensureWorktreeGitignore(target)
243
+ function installClaudeMethod(target, opts) {
244
+ mirrorDuaerSkills(
245
+ target,
246
+ join(target, '.claude', 'skills'),
247
+ opts,
248
+ '.claude/skills/duaer-* (mirrored from .cursor/skills)',
249
+ )
250
+
251
+ ensureDir(join(target, '.claude', 'rules'))
252
+ const claudeRule = join(PKG_ROOT, '.claude', 'rules', 'duaer-spec.md')
253
+ if (existsSync(claudeRule)) {
254
+ copyPath(claudeRule, join(target, '.claude', 'rules', 'duaer-spec.md'), opts)
255
+ } else {
256
+ writeIfNeeded(
257
+ join(target, '.claude', 'rules', 'duaer-spec.md'),
258
+ cursorRuleToClaude(
259
+ readFileSync(join(PKG_ROOT, '.cursor', 'rules', 'duaer-spec.mdc'), 'utf8'),
260
+ '.claude',
261
+ ),
262
+ opts,
263
+ )
264
+ }
265
+ console.log(' .claude/rules/duaer-spec.md')
266
+
267
+ const claudeMdSrc = join(PKG_ROOT, 'CLAUDE.md')
268
+ if (existsSync(claudeMdSrc)) {
269
+ copyPath(claudeMdSrc, join(target, 'CLAUDE.md'), opts)
270
+ } else {
271
+ writeIfNeeded(join(target, 'CLAUDE.md'), defaultClaudeMd(), opts)
272
+ }
273
+ console.log(' CLAUDE.md')
274
+ }
275
+
276
+ function installCodexMethod(target, opts) {
277
+ // Codex discovers repo skills under .agents/skills (not .codex/skills).
278
+ // Always-on guidance is AGENTS.md (installed with ops).
279
+ mirrorDuaerSkills(
280
+ target,
281
+ join(target, '.agents', 'skills'),
282
+ opts,
283
+ '.agents/skills/duaer-* (Codex; mirrored from .cursor/skills)',
284
+ )
285
+ }
286
+
287
+ function cursorRuleToClaude(mdc, skillHost) {
288
+ let body = mdc.replace(/^---\n[\s\S]*?\n---\n+/, (fm) => {
289
+ const desc = (fm.match(/^description:\s*(.+)$/m) || [])[1]
290
+ return desc ? `<!-- ${desc.trim()} -->\n\n` : ''
291
+ })
292
+ body = body.replaceAll('.cursor/skills/', `${skillHost}/skills/`)
293
+ return body.trimEnd() + '\n'
294
+ }
295
+
296
+ function defaultClaudeMd() {
297
+ return `# CLAUDE.md — duaer-spec
298
+
299
+ This project uses **duaer-spec**: coding agents are digital employees.
300
+
301
+ **Precedence:** \`AGENTS.md\` (ops) wins over \`DUADER.md\` / \`.duaer/\` (method).
302
+
303
+ - Follow \`.claude/rules/\`
304
+ - Job loop: \`.claude/skills/duaer-do/SKILL.md\` (no slash commands required)
305
+ - Branches / worktrees: see \`AGENTS.md\` and \`docs/agent/branching-and-release.md\`
306
+ `
231
307
  }
232
308
 
233
309
  function ensureWorktreeGitignore(target) {
@@ -259,6 +335,22 @@ function installOps(target, opts) {
259
335
  }
260
336
  console.log(' .cursor/rules/agents-workflow.mdc, ai-ui-copy.mdc')
261
337
 
338
+ ensureDir(join(target, '.claude', 'rules'))
339
+ for (const name of ['agents-workflow.md', 'ai-ui-copy.md']) {
340
+ const src = join(PKG_ROOT, '.claude', 'rules', name)
341
+ if (existsSync(src)) {
342
+ copyPath(src, join(target, '.claude', 'rules', name), opts)
343
+ } else {
344
+ const mdc = name.replace(/\.md$/, '.mdc')
345
+ writeIfNeeded(
346
+ join(target, '.claude', 'rules', name),
347
+ cursorRuleToClaude(readFileSync(join(PKG_ROOT, '.cursor', 'rules', mdc), 'utf8'), '.claude'),
348
+ opts,
349
+ )
350
+ }
351
+ }
352
+ console.log(' .claude/rules/agents-workflow.md, ai-ui-copy.md')
353
+
262
354
  ensureDir(join(target, 'docs', 'agent'))
263
355
  for (const name of [
264
356
  'workflow.md',
@@ -336,7 +428,7 @@ function cmdInit(opts) {
336
428
  console.log(`
337
429
  Hired.
338
430
 
339
- Talk to the agent in plain language.
431
+ Talk to the agent in plain language (Cursor, Claude Code, or Codex).
340
432
  Later update: npx duaer-spec update
341
433
  `)
342
434
  }
@@ -472,8 +564,13 @@ function checkWorkplace(target) {
472
564
  ['DUADER.md', 'method'],
473
565
  ['.cursor/rules/duaer-spec.mdc', 'method'],
474
566
  ['.cursor/skills/duaer-specify/SKILL.md', 'method'],
567
+ ['.claude/rules/duaer-spec.md', 'method'],
568
+ ['.claude/skills/duaer-do/SKILL.md', 'method'],
569
+ ['.agents/skills/duaer-do/SKILL.md', 'method'],
570
+ ['CLAUDE.md', 'method'],
475
571
  ['AGENTS.md', 'ops'],
476
572
  ['.cursor/rules/agents-workflow.mdc', 'ops'],
573
+ ['.claude/rules/agents-workflow.md', 'ops'],
477
574
  ['docs/agent/workflow.md', 'ops'],
478
575
  ]
479
576
  let missing = 0
@@ -38,6 +38,8 @@ the table for their app.
38
38
  | E2E-011 | Installed docs (`DUADER.md`, `docs/agent/`) document `update` | manual |
39
39
  | E2E-012 | `README.zh-CN.md` covers install, update, branch model | manual |
40
40
  | E2E-013 | Worktree id ≠ Brief `<nnn-slug>`; path is `.worktree/feat-…/.duaer/specs/…` | manual |
41
+ | E2E-014 | Init installs Cursor + Claude hosts (`CLAUDE.md`, `.claude/skills`) | manual |
42
+ | E2E-015 | Init installs Codex skills under `.agents/skills/` | manual |
41
43
 
42
44
  ## Traceability
43
45
 
@@ -56,3 +58,5 @@ the table for their app.
56
58
  | E2E-011 | DUADER + agent docs | Update path in installed 说明 |
57
59
  | E2E-012 | `README.zh-CN.md` | Chinese 说明文档 |
58
60
  | E2E-013 | AGENTS / branching naming | Avoid double `<nnn-slug>` |
61
+ | E2E-014 | Claude + Cursor install | Dual host |
62
+ | E2E-015 | Codex `.agents/skills` | Triple host |
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "duaer-spec",
3
- "version": "0.6.4",
4
- "description": "Digital employees: autonomous delivery; main/develop/feat/fix; simple update",
3
+ "version": "0.8.0",
4
+ "description": "Digital employees for Cursor, Claude Code, and Codex; main/develop/feat/fix",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "duaer": "bin/duaer.mjs",
@@ -11,7 +11,9 @@
11
11
  "bin",
12
12
  ".duaer",
13
13
  ".cursor",
14
+ ".claude",
14
15
  "AGENTS.md",
16
+ "CLAUDE.md",
15
17
  "DUADER.md",
16
18
  "ADOPT.md",
17
19
  "CHANGELOG.md",
@@ -43,7 +45,11 @@
43
45
  "agents",
44
46
  "cursor",
45
47
  "ai-engineering",
46
- "controllable-delivery"
48
+ "controllable-delivery",
49
+ "claude",
50
+ "claude-code",
51
+ "codex",
52
+ "openai-codex"
47
53
  ],
48
54
  "license": "MIT",
49
55
  "scripts": {