Skip to content

Commit 8731b3f

Browse files
authored
feat(setup): add Qoder and QoderWork integrations (#62)
Add setup targets for Qoder and QoderWork that install the mnemon skill, prompt files, and native command hooks using each host's settings.json configuration. Qoder supports project-local .qoder/ and user-wide ~/.qoder/ installs, while QoderWork uses its documented ~/.qoderwork/ user config. The integration registers SessionStart, UserPromptSubmit, and Stop hooks, preserves unrelated settings, and adds eject coverage plus setup tests. Validated with go test ./internal/setup and go build -o mnemon .
1 parent 23ec779 commit 8731b3f

14 files changed

Lines changed: 778 additions & 22 deletions

File tree

README.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,18 @@ One command deploys the mnemon skill, prompt files, and TRAE native hooks for
121121
both TRAE IDE and TRAE Work to `.trae/`. The integration uses `SessionStart`,
122122
`UserPromptSubmit`, and `Stop` hooks in `.trae/hooks.json`.
123123

124+
### [Qoder](https://qoder.com/) (QoderWork)
125+
126+
```bash
127+
mnemon setup --target qoder --yes
128+
mnemon setup --target qoderwork --yes
129+
```
130+
131+
Qoder deploys the mnemon skill, prompt files, and native hooks to `.qoder/`
132+
or `~/.qoder/`. QoderWork uses its native user config at `~/.qoderwork/`.
133+
Both integrations register `SessionStart`, `UserPromptSubmit`, and `Stop`
134+
hooks in `settings.json`.
135+
124136
### [OpenClaw](https://github.com/openclaw/openclaw)
125137

126138
```bash
@@ -221,7 +233,7 @@ memory is useful.
221233

222234
- **Zero user-side operation** — install once; supported runtimes can use hooks, minimal runtimes can use persistent rules
223235
- **LLM-supervised** — the host LLM decides what to remember, update, and forget; no embedded LLM, no API keys
224-
- **Multi-framework support** — Claude Code, Codex, and Cursor (hooks), OpenClaw (plugins), Pi (extensions), Nanobot (skills), and more
236+
- **Multi-framework support** — Claude Code, Codex, Cursor, Qoder, and QoderWork (hooks), OpenClaw (plugins), Pi (extensions), Nanobot (skills), and more
225237
- **Markdown-installable harness**`SKILL.md`, `INSTALL.md`, `GUIDELINE.md`, and four lifecycle reminders
226238
- **Four-graph architecture** — temporal, entity, causal, and semantic edges, not just vector similarity
227239
- **Intent-native protocol** — three primitives (`remember`, `link`, `recall`) map to the LLM's cognitive vocabulary, not database syntax; structured JSON output with signal transparency
@@ -238,8 +250,14 @@ All your local agentic AIs — across sessions and frameworks — sharing one po
238250
```
239251
Claude Code ──┐
240252
253+
Codex ────────┤
254+
241255
Cursor ───────┤
242256
257+
Qoder ────────┤
258+
259+
QoderWork ────┤
260+
243261
OpenClaw ─────┤
244262
245263
Pi ───────────┤
@@ -254,7 +272,7 @@ All your local agentic AIs — across sessions and frameworks — sharing one po
254272
```
255273

256274
The foundation is in place: a single `~/.mnemon` database that any agent can
257-
read and write. Claude Code, Codex, and Cursor setup automate hook
275+
read and write. Claude Code, Codex, Cursor, Qoder, and QoderWork setup automate hook
258276
installation; OpenClaw can use plugin hooks; Pi integrates via native skills
259277
and TypeScript lifecycle extensions; Nanobot integrates via skill files;
260278
NanoClaw integrates via container skills and volume mounts. The same harness can

cmd/setup.go

Lines changed: 131 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,20 @@ var setupCmd = &cobra.Command{
2222
Short: "Deploy mnemon into LLM CLI environments",
2323
Long: `Detect installed LLM CLIs and deploy mnemon integration.
2424
25-
By default, installs to project-local config (.claude/, .codex/, .cursor/, .trae/, .openclaw/, .nanobot/, .pi/).
26-
Use --global to install to user-wide config (~/.claude/, ~/.codex/, ~/.cursor/, ~/.trae/, ~/.openclaw/, ~/.nanobot/workspace/, ~/.pi/agent/).
27-
Hermes Agent uses its native user config at ~/.hermes/.
25+
By default, installs to project-local config (.claude/, .codex/, .cursor/, .trae/, .qoder/, .openclaw/, .nanobot/, .pi/).
26+
Use --global to install to user-wide config (~/.claude/, ~/.codex/, ~/.cursor/, ~/.trae/, ~/.qoder/, ~/.openclaw/, ~/.nanobot/workspace/, ~/.pi/agent/).
27+
Hermes Agent and QoderWork use their native user config at ~/.hermes/ and ~/.qoderwork/.
2828
29-
Supported environments: Claude Code, Codex, Cursor, Trae, OpenClaw, Nanobot, Pi, Hermes Agent.
29+
Supported environments: Claude Code, Codex, Cursor, Trae, Qoder, QoderWork, OpenClaw, Nanobot, Pi, Hermes Agent.
3030
3131
Examples:
3232
mnemon setup # Interactive: project-local install
3333
mnemon setup --global # Interactive: user-wide install
3434
mnemon setup --target claude-code # Non-interactive: Claude Code only
3535
mnemon setup --target cursor # Non-interactive: Cursor skill only
3636
mnemon setup --target trae # Non-interactive: Trae skill and hooks
37+
mnemon setup --target qoder # Non-interactive: Qoder skill and hooks
38+
mnemon setup --target qoderwork # Non-interactive: QoderWork skill and hooks
3739
mnemon setup --target hermes # Non-interactive: Hermes Agent only
3840
mnemon setup --eject # Interactive: remove integrations
3941
mnemon setup --eject --target claude-code # Non-interactive: remove Claude Code only
@@ -42,16 +44,16 @@ Examples:
4244
}
4345

4446
func init() {
45-
setupCmd.Flags().StringVar(&setupTarget, "target", "", "target environment (claude-code, codex, cursor, trae, openclaw, nanobot, pi, hermes)")
47+
setupCmd.Flags().StringVar(&setupTarget, "target", "", "target environment (claude-code, codex, cursor, trae, qoder, qoderwork, openclaw, nanobot, pi, hermes)")
4648
setupCmd.Flags().BoolVar(&setupEject, "eject", false, "remove mnemon integrations")
4749
setupCmd.Flags().BoolVar(&setupYes, "yes", false, "auto-confirm all prompts (CI-friendly)")
4850
setupCmd.Flags().BoolVar(&setupGlobal, "global", false, "install to user-wide config instead of project-local config")
4951
rootCmd.AddCommand(setupCmd)
5052
}
5153

5254
func runSetup(cmd *cobra.Command, args []string) error {
53-
if setupTarget != "" && setupTarget != "claude-code" && setupTarget != "codex" && setupTarget != "cursor" && setupTarget != "trae" && setupTarget != "openclaw" && setupTarget != "nanobot" && setupTarget != "pi" && setupTarget != "hermes" {
54-
return fmt.Errorf("invalid target %q (must be claude-code, codex, cursor, trae, openclaw, nanobot, pi, or hermes)", setupTarget)
55+
if setupTarget != "" && setupTarget != "claude-code" && setupTarget != "codex" && setupTarget != "cursor" && setupTarget != "trae" && setupTarget != "qoder" && setupTarget != "qoderwork" && setupTarget != "openclaw" && setupTarget != "nanobot" && setupTarget != "pi" && setupTarget != "hermes" {
56+
return fmt.Errorf("invalid target %q (must be claude-code, codex, cursor, trae, qoder, qoderwork, openclaw, nanobot, pi, or hermes)", setupTarget)
5557
}
5658

5759
envs := setup.DetectEnvironments(setupGlobal)
@@ -87,7 +89,7 @@ func runInstallFlow(envs []setup.Environment) error {
8789

8890
if len(detected) == 0 {
8991
fmt.Println("\nNo supported LLM CLI environments detected.")
90-
fmt.Println("Install Claude Code, Codex, Cursor, Trae, OpenClaw, Nanobot, Pi, or Hermes Agent, then run 'mnemon setup' again.")
92+
fmt.Println("Install Claude Code, Codex, Cursor, Trae, Qoder, QoderWork, OpenClaw, Nanobot, Pi, or Hermes Agent, then run 'mnemon setup' again.")
9193
return nil
9294
}
9395

@@ -135,6 +137,10 @@ func installEnv(env *setup.Environment) error {
135137
err = installCursor(env)
136138
case "trae":
137139
err = installTrae(env)
140+
case "qoder":
141+
err = installQoder(env)
142+
case "qoderwork":
143+
err = installQoderWork(env)
138144
case "openclaw":
139145
err = installOpenClaw(env)
140146
case "nanobot":
@@ -569,6 +575,109 @@ func installTrae(env *setup.Environment) error {
569575
return nil
570576
}
571577

578+
// ─── Qoder ──────────────────────────────────────────────────────────
579+
580+
func installQoder(env *setup.Environment) error {
581+
configDir := env.ConfigDir
582+
583+
if !setupGlobal && !setupYes && setup.IsInteractive() {
584+
home := setup.HomeDir()
585+
localDir := ".qoder"
586+
globalDir := home + "/.qoder"
587+
idx := setup.SelectOne("Install scope",
588+
[]string{
589+
fmt.Sprintf("Local — this project only (%s/)", localDir),
590+
fmt.Sprintf("Global — all projects (%s/)", globalDir),
591+
}, 0)
592+
if idx == 1 {
593+
configDir = globalDir
594+
} else {
595+
configDir = localDir
596+
}
597+
}
598+
599+
fmt.Printf("\nSetting up Qoder (%s)...\n", configDir)
600+
601+
return installQoderLike(
602+
configDir,
603+
setup.QoderWriteSkill,
604+
setup.QoderRegisterHooks,
605+
"Restart Qoder IDE/CLI to activate the mnemon skill and hooks.",
606+
"Run 'mnemon setup --eject --target qoder' to remove.",
607+
)
608+
}
609+
610+
// ─── QoderWork ──────────────────────────────────────────────────────
611+
612+
func installQoderWork(env *setup.Environment) error {
613+
configDir := env.ConfigDir
614+
615+
fmt.Printf("\nSetting up QoderWork (%s)...\n", configDir)
616+
617+
return installQoderLike(
618+
configDir,
619+
setup.QoderWorkWriteSkill,
620+
setup.QoderWorkRegisterHooks,
621+
"Restart QoderWork to activate the mnemon skill and hooks.",
622+
"Run 'mnemon setup --eject --target qoderwork' to remove.",
623+
)
624+
}
625+
626+
func installQoderLike(configDir string, writeSkill func(string) (string, error), registerHooks func(string) (string, error), activation, ejectHint string) error {
627+
fmt.Println("\n[1/3] Skill")
628+
if path, err := writeSkill(configDir); err != nil {
629+
setup.StatusError(0, 0, "Skill", err)
630+
return err
631+
} else {
632+
setup.StatusOK(0, 0, "Skill", path)
633+
}
634+
635+
fmt.Println("\n[2/3] Prompts")
636+
var promptPath string
637+
if path, err := setup.WritePromptFiles(); err != nil {
638+
setup.StatusError(0, 0, "Prompts", err)
639+
return err
640+
} else {
641+
setup.StatusOK(0, 0, "Prompts", path)
642+
promptPath = path
643+
}
644+
645+
fmt.Println("\n[3/3] Hooks")
646+
for _, hook := range []struct {
647+
label string
648+
filename string
649+
content []byte
650+
}{
651+
{"Hook: prime", "prime.sh", assets.QoderPrimeHook},
652+
{"Hook: remind", "user_prompt.sh", assets.QoderUserPromptHook},
653+
{"Hook: nudge", "stop.sh", assets.QoderStopHook},
654+
} {
655+
if path, err := setup.QoderWriteHook(configDir, hook.filename, hook.content); err != nil {
656+
setup.StatusError(0, 0, hook.label, err)
657+
return err
658+
} else {
659+
setup.StatusOK(0, 0, hook.label, path)
660+
}
661+
}
662+
if path, err := registerHooks(configDir); err != nil {
663+
setup.StatusError(0, 0, "Settings", err)
664+
return err
665+
} else {
666+
setup.StatusUpdated(0, 0, "Settings", path)
667+
}
668+
669+
fmt.Println()
670+
fmt.Println("Setup complete!")
671+
fmt.Printf(" Skill %s/skills/mnemon/SKILL.md\n", configDir)
672+
fmt.Printf(" Hooks %s/settings.json (SessionStart, UserPromptSubmit, Stop)\n", configDir)
673+
fmt.Printf(" Prompts %s/ (guide.md, skill.md)\n", promptPath)
674+
fmt.Println()
675+
fmt.Println(activation)
676+
fmt.Println(ejectHint)
677+
678+
return nil
679+
}
680+
572681
// ─── OpenClaw ───────────────────────────────────────────────────────
573682

574683
func installOpenClaw(env *setup.Environment) error {
@@ -1010,6 +1119,20 @@ func ejectEnv(env *setup.Environment) error {
10101119
return errs[0]
10111120
}
10121121

1122+
case "qoder":
1123+
errs := setup.QoderEject(env.ConfigDir)
1124+
ejectMarkdown("AGENTS.md", "Remove memory guidance from ./AGENTS.md?")
1125+
if len(errs) > 0 {
1126+
return errs[0]
1127+
}
1128+
1129+
case "qoderwork":
1130+
errs := setup.QoderWorkEject(env.ConfigDir)
1131+
ejectMarkdown("AGENTS.md", "Remove memory guidance from ./AGENTS.md?")
1132+
if len(errs) > 0 {
1133+
return errs[0]
1134+
}
1135+
10131136
case "openclaw":
10141137
errs := setup.OpenClawEject(env.ConfigDir)
10151138
ejectMarkdown("AGENTS.md", "Remove memory guidance from ./AGENTS.md?")

docs/USAGE.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ mnemon setup --target claude-code
3232
mnemon setup --target codex
3333
mnemon setup --target cursor
3434
mnemon setup --target trae
35+
mnemon setup --target qoder
36+
mnemon setup --target qoderwork
3537
mnemon setup --target openclaw
3638
mnemon setup --target pi
3739
mnemon setup --target nanobot --global
@@ -47,8 +49,8 @@ mnemon setup --eject --target claude-code
4749

4850
| Flag | Default | Description |
4951
|---|---|---|
50-
| `--global` | `false` | Install to user-wide config instead of project-local (recommended for Nanobot: installs to `~/.nanobot/workspace/`; Pi installs to `~/.pi/agent/`; Hermes installs to `~/.hermes/`) |
51-
| `--target <name>` | (auto-detect) | Target environment: `claude-code`, `codex`, `cursor`, `trae`, `openclaw`, `nanobot`, `pi`, or `hermes` |
52+
| `--global` | `false` | Install to user-wide config instead of project-local (recommended for Nanobot: installs to `~/.nanobot/workspace/`; Pi installs to `~/.pi/agent/`; Hermes installs to `~/.hermes/`; QoderWork installs to `~/.qoderwork/`) |
53+
| `--target <name>` | (auto-detect) | Target environment: `claude-code`, `codex`, `cursor`, `trae`, `qoder`, `qoderwork`, `openclaw`, `nanobot`, `pi`, or `hermes` |
5254
| `--eject` | `false` | Remove mnemon integrations |
5355
| `--yes` | `false` | Auto-confirm all prompts |
5456

docs/zh/README.md

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,15 +92,26 @@ mnemon setup
9292

9393
`mnemon setup` 自动检测 Claude Code,交互式部署技能文件、钩子和行为引导。启动新会话 — 记忆自动运作。
9494

95-
### [Trae](https://www.trae.ai/)
95+
### [TRAE](https://www.trae.ai/) (TRAE Work)
9696

9797
```bash
9898
mnemon setup --target trae --yes
9999
```
100100

101-
一条命令将 mnemon skill、prompt 文件和 Trae 原生 hooks 部署到 `.trae/`
102-
该集成使用 `.trae/hooks.json` 中的 `SessionStart``UserPromptSubmit`
103-
`Stop` hooks。
101+
一条命令将 mnemon skill、prompt 文件和 TRAE 原生 hooks 部署到 `.trae/`
102+
同时覆盖 TRAE IDE 和 TRAE Work。该集成使用 `.trae/hooks.json` 中的
103+
`SessionStart``UserPromptSubmit``Stop` hooks。
104+
105+
### [Qoder](https://qoder.com/) (QoderWork)
106+
107+
```bash
108+
mnemon setup --target qoder --yes
109+
mnemon setup --target qoderwork --yes
110+
```
111+
112+
Qoder 会将 mnemon skill、prompt 文件和原生 hooks 部署到 `.qoder/`
113+
`~/.qoder/`。QoderWork 使用原生用户级配置 `~/.qoderwork/`。两者都会在
114+
`settings.json` 中注册 `SessionStart``UserPromptSubmit``Stop` hooks。
104115

105116
### [OpenClaw](https://github.com/openclaw/openclaw)
106117

@@ -185,7 +196,7 @@ Agent 工作,并且只在有用时调用 Mnemon
185196

186197
- **零用户操作** — 安装一次;支持 hook 的 runtime 可用 hook,minimal runtime 可用持久规则
187198
- **LLM 监督式** — 宿主 LLM 主动决定记什么、更新什么、遗忘什么;无内嵌 LLM,无 API 密钥
188-
- **多框架支持** — Claude Code 和 Codex(hooks)、OpenClaw(plugins)、Pi(extensions)、Nanobot(skills)等
199+
- **多框架支持** — Claude Code、Codex、Cursor、QoderQoderWork(hooks)、OpenClaw(plugins)、Pi(extensions)、Nanobot(skills)等
189200
- **Markdown 可安装 harness**`SKILL.md``INSTALL.md``GUIDELINE.md` 和四个生命周期提醒
190201
- **四图架构** — 时序、实体、因果、语义四种边,不仅仅是向量相似度
191202
- **意图原生协议** — 三个原语(`remember``link``recall`)映射到 LLM 的认知词汇而非数据库语法;结构化 JSON 输出,带信号透明度

docs/zh/USAGE.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ mnemon setup --target claude-code
3232
mnemon setup --target codex
3333
mnemon setup --target cursor
3434
mnemon setup --target trae
35+
mnemon setup --target qoder
36+
mnemon setup --target qoderwork
3537
mnemon setup --target openclaw
3638
mnemon setup --target pi
3739
mnemon setup --target nanobot --global
@@ -47,8 +49,8 @@ mnemon setup --eject --target claude-code
4749

4850
| 标志 | 默认值 | 说明 |
4951
|---|---|---|
50-
| `--global` | `false` | 安装到用户级配置而非项目本地(Nanobot 推荐安装到 `~/.nanobot/workspace/`;Pi 安装到 `~/.pi/agent/`;Hermes 安装到 `~/.hermes/`|
51-
| `--target <name>` | (自动检测) | 目标环境:`claude-code``codex``cursor``trae``openclaw``nanobot``pi``hermes` |
52+
| `--global` | `false` | 安装到用户级配置而非项目本地(Nanobot 推荐安装到 `~/.nanobot/workspace/`;Pi 安装到 `~/.pi/agent/`;Hermes 安装到 `~/.hermes/`;QoderWork 安装到 `~/.qoderwork/`|
53+
| `--target <name>` | (自动检测) | 目标环境:`claude-code``codex``cursor``trae``qoder``qoderwork``openclaw``nanobot``pi``hermes` |
5254
| `--eject` | `false` | 移除 mnemon 集成 |
5355
| `--yes` | `false` | 自动确认所有提示 |
5456

internal/setup/assets/assets.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,21 @@ var TraeUserPromptHook []byte
5656
//go:embed trae/stop.sh
5757
var TraeStopHook []byte
5858

59+
//go:embed qoder/SKILL.md
60+
var QoderSkill []byte
61+
62+
//go:embed qoderwork/SKILL.md
63+
var QoderWorkSkill []byte
64+
65+
//go:embed qoder/prime.sh
66+
var QoderPrimeHook []byte
67+
68+
//go:embed qoder/user_prompt.sh
69+
var QoderUserPromptHook []byte
70+
71+
//go:embed qoder/stop.sh
72+
var QoderStopHook []byte
73+
5974
//go:embed openclaw/SKILL.md
6075
var OpenClawSkill []byte
6176

@@ -106,5 +121,5 @@ var HermesCompactHook []byte
106121

107122
// All returns the embedded filesystem for inspection.
108123
//
109-
//go:embed claude codex cursor trae openclaw nanoclaw nanobot pi hermes
124+
//go:embed claude codex cursor trae qoder qoderwork openclaw nanoclaw nanobot pi hermes
110125
var All embed.FS

0 commit comments

Comments
 (0)