Skip to content

Commit f532df8

Browse files
Thezenmonsterclaude
andcommitted
Add init/doctor tests + GitHub issue templates
18 tests for init and doctor commands covering: - DB creation, starter memory, skip on existing - MCP config output for all 4 tools - Health check, next steps, default project - Doctor checks: DB, MCP, schema, health, project, validated Issue templates: bug report, setup help, feature request. All include agentmem doctor output field for diagnostics. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent d96d835 commit f532df8

4 files changed

Lines changed: 291 additions & 0 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: Bug Report
2+
description: Something broke or isn't working as expected.
3+
title: "[Bug] "
4+
labels: ["bug"]
5+
body:
6+
- type: input
7+
id: tool
8+
attributes:
9+
label: What tool are you using?
10+
description: Claude Code, Cursor, Codex, Windsurf, or standalone CLI/Python
11+
placeholder: e.g. Claude Code
12+
validations:
13+
required: true
14+
- type: textarea
15+
id: what-happened
16+
attributes:
17+
label: What happened?
18+
description: What were you trying to do, and what went wrong?
19+
placeholder: I ran agentmem health and got...
20+
validations:
21+
required: true
22+
- type: textarea
23+
id: expected
24+
attributes:
25+
label: What did you expect?
26+
placeholder: I expected it to...
27+
validations:
28+
required: false
29+
- type: textarea
30+
id: reproduce
31+
attributes:
32+
label: Steps to reproduce
33+
description: Minimal steps to trigger the bug.
34+
placeholder: |
35+
1. pip install quilmem
36+
2. agentmem init --tool claude
37+
3. ...
38+
validations:
39+
required: false
40+
- type: textarea
41+
id: doctor-output
42+
attributes:
43+
label: Output of agentmem doctor
44+
description: Paste the output of `agentmem doctor` here.
45+
render: shell
46+
validations:
47+
required: false
48+
- type: input
49+
id: os
50+
attributes:
51+
label: OS
52+
placeholder: Windows 11 / macOS 15 / Ubuntu 24.04
53+
validations:
54+
required: false
55+
- type: input
56+
id: python-version
57+
attributes:
58+
label: Python version
59+
placeholder: e.g. 3.12
60+
validations:
61+
required: false
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: Feature Request
2+
description: Suggest something that would make agentmem more useful.
3+
title: "[Feature] "
4+
labels: ["enhancement"]
5+
body:
6+
- type: textarea
7+
id: problem
8+
attributes:
9+
label: What problem are you trying to solve?
10+
description: What's the pain point or gap you're hitting?
11+
validations:
12+
required: true
13+
- type: textarea
14+
id: solution
15+
attributes:
16+
label: What would you like to see?
17+
description: Describe the feature or behavior you'd want.
18+
validations:
19+
required: false
20+
- type: input
21+
id: tool
22+
attributes:
23+
label: What tool do you use agentmem with?
24+
placeholder: Claude Code / Cursor / Codex / Windsurf / CLI / Python API
25+
validations:
26+
required: false
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Setup Help
2+
description: Having trouble getting agentmem connected to your coding agent.
3+
title: "[Setup] "
4+
labels: ["setup"]
5+
body:
6+
- type: input
7+
id: tool
8+
attributes:
9+
label: What tool are you connecting to?
10+
placeholder: Claude Code / Cursor / Codex / Windsurf / Other
11+
validations:
12+
required: true
13+
- type: textarea
14+
id: problem
15+
attributes:
16+
label: What's not working?
17+
description: Where did you get stuck? What error did you see?
18+
placeholder: |
19+
I followed the MCP setup guide but tools don't appear in Cursor...
20+
validations:
21+
required: true
22+
- type: textarea
23+
id: init-output
24+
attributes:
25+
label: Output of agentmem init
26+
description: Paste the output of `agentmem init --tool <your-tool>` here.
27+
render: shell
28+
validations:
29+
required: false
30+
- type: textarea
31+
id: doctor-output
32+
attributes:
33+
label: Output of agentmem doctor
34+
description: Paste the output of `agentmem doctor` here.
35+
render: shell
36+
validations:
37+
required: false
38+
- type: input
39+
id: os
40+
attributes:
41+
label: OS
42+
placeholder: Windows 11 / macOS 15 / Ubuntu 24.04
43+
validations:
44+
required: false

tests/test_cli_onboarding.py

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
"""Tests for init and doctor CLI commands — core activation path."""
2+
3+
import os
4+
import tempfile
5+
6+
import pytest
7+
from click.testing import CliRunner
8+
9+
from agentmem.cli import main
10+
11+
12+
@pytest.fixture
13+
def runner():
14+
return CliRunner()
15+
16+
17+
@pytest.fixture
18+
def fresh_db():
19+
with tempfile.NamedTemporaryFile(suffix=".db", delete=False) as f:
20+
db_path = f.name
21+
# Delete the file so init creates it fresh
22+
os.unlink(db_path)
23+
yield db_path
24+
if os.path.exists(db_path):
25+
os.unlink(db_path)
26+
27+
28+
@pytest.fixture
29+
def existing_db():
30+
with tempfile.NamedTemporaryFile(suffix=".db", delete=False) as f:
31+
db_path = f.name
32+
# Create a DB with some content
33+
from agentmem import Memory
34+
mem = Memory(path=db_path, project="test")
35+
mem.add(type="decision", title="Existing rule", content="Already here")
36+
mem.close()
37+
yield db_path
38+
if os.path.exists(db_path):
39+
os.unlink(db_path)
40+
41+
42+
# ── init tests ──────────────────────────────────────────────
43+
44+
class TestInit:
45+
46+
def test_init_creates_db(self, runner, fresh_db):
47+
result = runner.invoke(main, ["--db", fresh_db, "init", "--project", "myapp"])
48+
assert result.exit_code == 0
49+
assert os.path.exists(fresh_db)
50+
assert "Created database" in result.output
51+
52+
def test_init_adds_starter_memory(self, runner, fresh_db):
53+
result = runner.invoke(main, ["--db", fresh_db, "init", "--project", "myapp"])
54+
assert result.exit_code == 0
55+
assert "Added starter memory" in result.output
56+
57+
# Verify the memory exists
58+
from agentmem import Memory
59+
mem = Memory(path=fresh_db, project="myapp")
60+
assert mem.stats()["total"] == 1
61+
records = mem.list()
62+
assert records[0].title == "Project: myapp"
63+
mem.close()
64+
65+
def test_init_skips_starter_on_existing_db(self, runner, existing_db):
66+
result = runner.invoke(main, ["--db", existing_db, "--project", "test", "init"])
67+
assert result.exit_code == 0
68+
assert "Skipped starter memory" in result.output
69+
70+
def test_init_runs_health_check(self, runner, fresh_db):
71+
result = runner.invoke(main, ["--db", fresh_db, "init", "--project", "test"])
72+
assert result.exit_code == 0
73+
assert "Health:" in result.output
74+
75+
def test_init_shows_next_steps(self, runner, fresh_db):
76+
result = runner.invoke(main, ["--db", fresh_db, "init", "--project", "test"])
77+
assert result.exit_code == 0
78+
assert "Next steps:" in result.output
79+
assert "agentmem add" in result.output
80+
assert "agentmem health" in result.output
81+
82+
def test_init_claude_config(self, runner, fresh_db):
83+
result = runner.invoke(main, ["--db", fresh_db, "init", "--tool", "claude", "--project", "app"])
84+
assert result.exit_code == 0
85+
assert "mcpServers" in result.output
86+
assert '"type": "stdio"' in result.output
87+
assert "agentmem" in result.output
88+
assert ".claude/settings.json" in result.output
89+
90+
def test_init_cursor_config(self, runner, fresh_db):
91+
result = runner.invoke(main, ["--db", fresh_db, "init", "--tool", "cursor", "--project", "app"])
92+
assert result.exit_code == 0
93+
assert "mcpServers" in result.output
94+
assert ".cursor/mcp.json" in result.output
95+
96+
def test_init_codex_config(self, runner, fresh_db):
97+
result = runner.invoke(main, ["--db", fresh_db, "init", "--tool", "codex", "--project", "app"])
98+
assert result.exit_code == 0
99+
assert "[mcp_servers.agentmem]" in result.output
100+
assert "config.toml" in result.output
101+
102+
def test_init_windsurf_config(self, runner, fresh_db):
103+
result = runner.invoke(main, ["--db", fresh_db, "init", "--tool", "windsurf", "--project", "app"])
104+
assert result.exit_code == 0
105+
assert ".windsurf/mcp.json" in result.output
106+
107+
def test_init_no_tool_skips_config(self, runner, fresh_db):
108+
result = runner.invoke(main, ["--db", fresh_db, "init", "--project", "test"])
109+
assert result.exit_code == 0
110+
assert "Skipped MCP config" in result.output
111+
assert "--tool claude" in result.output
112+
113+
def test_init_uses_cwd_as_default_project(self, runner, fresh_db):
114+
result = runner.invoke(main, ["--db", fresh_db, "init"])
115+
assert result.exit_code == 0
116+
# Should use the current directory name as project
117+
assert "Project:" in result.output
118+
119+
120+
# ── doctor tests ──────────────────────────────────────────────
121+
122+
class TestDoctor:
123+
124+
def test_doctor_healthy_db(self, runner, existing_db):
125+
result = runner.invoke(main, ["--db", existing_db, "--project", "test", "doctor"])
126+
assert result.exit_code == 0
127+
assert "[OK] Database:" in result.output
128+
assert "[OK] Schema version: 2" in result.output
129+
130+
def test_doctor_missing_db(self, runner, fresh_db):
131+
result = runner.invoke(main, ["--db", fresh_db, "doctor"])
132+
assert result.exit_code == 0
133+
assert "[FAIL] Database not found" in result.output
134+
assert "agentmem init" in result.output
135+
136+
def test_doctor_checks_mcp(self, runner, existing_db):
137+
result = runner.invoke(main, ["--db", existing_db, "doctor"])
138+
assert result.exit_code == 0
139+
# Should have either [OK] or [WARN] for MCP
140+
assert "MCP package" in result.output
141+
142+
def test_doctor_checks_health(self, runner, existing_db):
143+
result = runner.invoke(main, ["--db", existing_db, "--project", "test", "doctor"])
144+
assert result.exit_code == 0
145+
assert "Health:" in result.output
146+
147+
def test_doctor_warns_no_project(self, runner, existing_db):
148+
result = runner.invoke(main, ["--db", existing_db, "doctor"])
149+
assert result.exit_code == 0
150+
assert "No project scope" in result.output or "[OK] Project:" in result.output
151+
152+
def test_doctor_warns_no_validated(self, runner, existing_db):
153+
result = runner.invoke(main, ["--db", existing_db, "--project", "test", "doctor"])
154+
assert result.exit_code == 0
155+
assert "No validated memories" in result.output or "Validated memories:" in result.output
156+
157+
def test_doctor_reports_all_passed(self, runner, existing_db):
158+
result = runner.invoke(main, ["--db", existing_db, "--project", "test", "doctor"])
159+
assert result.exit_code == 0
160+
assert "All checks passed" in result.output or "Some checks failed" in result.output

0 commit comments

Comments
 (0)