aas-setup 1.0.1
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.
- package/LICENSE +21 -0
- package/README.md +73 -0
- package/bin/aas-setup.mjs +34 -0
- package/configs/opencode/agent/ai-slop-remover.md +55 -0
- package/configs/opencode/agent/docs-writer.md +15 -0
- package/configs/opencode/agent/review.md +18 -0
- package/configs/opencode/agent/security-audit.md +17 -0
- package/configs/opencode/command/batch.md +58 -0
- package/configs/opencode/command/plannotator-annotate.md +6 -0
- package/configs/opencode/command/plannotator-last.md +3 -0
- package/configs/opencode/command/plannotator-review.md +6 -0
- package/configs/opencode/command/simplify.md +47 -0
- package/configs/opencode/opencode.json +137 -0
- package/configs/pi/AGENTS.md +49 -0
- package/configs/pi/mcp.json +24 -0
- package/configs/pi/models.json +0 -0
- package/configs/pi/settings.json +37 -0
- package/configs/pi/themes/dracula.json +87 -0
- package/configs/pi/themes/kanagawa.json +88 -0
- package/configs/reference/MEMORY.md +239 -0
- package/configs/reference/agent-memory.md +5 -0
- package/configs/reference/best-practices.md +270 -0
- package/configs/reference/git-guidelines.md +62 -0
- package/package.json +37 -0
- package/src/agents/opencode.mjs +22 -0
- package/src/agents/pi.mjs +22 -0
- package/src/agents/types.mjs +30 -0
- package/src/commands/init.mjs +99 -0
- package/src/commands/select.mjs +52 -0
- package/src/lib/exec.mjs +35 -0
- package/src/lib/fs.mjs +107 -0
- package/src/lib/log.mjs +39 -0
- package/src/lib/paths.mjs +47 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/badlogic/pi-mono/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
|
|
3
|
+
"name": "dracula",
|
|
4
|
+
"vars": {
|
|
5
|
+
"background": "#282a36",
|
|
6
|
+
"currentLine": "#44475a",
|
|
7
|
+
"foreground": "#f8f8f2",
|
|
8
|
+
"comment": "#6272a4",
|
|
9
|
+
"cyan": "#8be9fd",
|
|
10
|
+
"green": "#50fa7b",
|
|
11
|
+
"orange": "#ffb86c",
|
|
12
|
+
"pink": "#ff79c6",
|
|
13
|
+
"purple": "#bd93f9",
|
|
14
|
+
"red": "#ff5555",
|
|
15
|
+
"yellow": "#f1fa8c",
|
|
16
|
+
"bgLight": "#343746",
|
|
17
|
+
"bgLighter": "#3c3f58",
|
|
18
|
+
"bgDark": "#21222c",
|
|
19
|
+
"bgGreenTint": "#2a3a2e",
|
|
20
|
+
"bgRedTint": "#3a2a2e",
|
|
21
|
+
"bgPurpleTint": "#2e2a3a"
|
|
22
|
+
},
|
|
23
|
+
"colors": {
|
|
24
|
+
"accent": "purple",
|
|
25
|
+
"border": "purple",
|
|
26
|
+
"borderAccent": "pink",
|
|
27
|
+
"borderMuted": "comment",
|
|
28
|
+
"success": "green",
|
|
29
|
+
"error": "red",
|
|
30
|
+
"warning": "yellow",
|
|
31
|
+
"muted": "comment",
|
|
32
|
+
"dim": "#545978",
|
|
33
|
+
"text": "foreground",
|
|
34
|
+
"thinkingText": "comment",
|
|
35
|
+
|
|
36
|
+
"selectedBg": "currentLine",
|
|
37
|
+
"userMessageBg": "bgLight",
|
|
38
|
+
"userMessageText": "foreground",
|
|
39
|
+
"customMessageBg": "bgPurpleTint",
|
|
40
|
+
"customMessageText": "foreground",
|
|
41
|
+
"customMessageLabel": "purple",
|
|
42
|
+
"toolPendingBg": "bgDark",
|
|
43
|
+
"toolSuccessBg": "bgGreenTint",
|
|
44
|
+
"toolErrorBg": "bgRedTint",
|
|
45
|
+
"toolTitle": "foreground",
|
|
46
|
+
"toolOutput": "comment",
|
|
47
|
+
|
|
48
|
+
"mdHeading": "orange",
|
|
49
|
+
"mdLink": "cyan",
|
|
50
|
+
"mdLinkUrl": "comment",
|
|
51
|
+
"mdCode": "green",
|
|
52
|
+
"mdCodeBlock": "foreground",
|
|
53
|
+
"mdCodeBlockBorder": "comment",
|
|
54
|
+
"mdQuote": "comment",
|
|
55
|
+
"mdQuoteBorder": "comment",
|
|
56
|
+
"mdHr": "comment",
|
|
57
|
+
"mdListBullet": "pink",
|
|
58
|
+
|
|
59
|
+
"toolDiffAdded": "green",
|
|
60
|
+
"toolDiffRemoved": "red",
|
|
61
|
+
"toolDiffContext": "comment",
|
|
62
|
+
|
|
63
|
+
"syntaxComment": "comment",
|
|
64
|
+
"syntaxKeyword": "pink",
|
|
65
|
+
"syntaxFunction": "green",
|
|
66
|
+
"syntaxVariable": "foreground",
|
|
67
|
+
"syntaxString": "yellow",
|
|
68
|
+
"syntaxNumber": "purple",
|
|
69
|
+
"syntaxType": "cyan",
|
|
70
|
+
"syntaxOperator": "pink",
|
|
71
|
+
"syntaxPunctuation": "foreground",
|
|
72
|
+
|
|
73
|
+
"thinkingOff": "#545978",
|
|
74
|
+
"thinkingMinimal": "comment",
|
|
75
|
+
"thinkingLow": "cyan",
|
|
76
|
+
"thinkingMedium": "purple",
|
|
77
|
+
"thinkingHigh": "pink",
|
|
78
|
+
"thinkingXhigh": "red",
|
|
79
|
+
|
|
80
|
+
"bashMode": "green"
|
|
81
|
+
},
|
|
82
|
+
"export": {
|
|
83
|
+
"pageBg": "#1e1f29",
|
|
84
|
+
"cardBg": "bgDark",
|
|
85
|
+
"infoBg": "#3a3728"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/badlogic/pi-mono/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
|
|
3
|
+
"name": "kanagawa",
|
|
4
|
+
"vars": {
|
|
5
|
+
"background": "#1F1F28",
|
|
6
|
+
"currentLine": "#363646",
|
|
7
|
+
"foreground": "#DCD7BA",
|
|
8
|
+
"comment": "#727169",
|
|
9
|
+
"cyan": "#7FB4CA",
|
|
10
|
+
"green": "#98BB6C",
|
|
11
|
+
"orange": "#FFA066",
|
|
12
|
+
"pink": "#D27E99",
|
|
13
|
+
"purple": "#957FB8",
|
|
14
|
+
"red": "#FF5D62",
|
|
15
|
+
"yellow": "#E6C384",
|
|
16
|
+
"blue": "#7E9CD8",
|
|
17
|
+
"bgLight": "#2A2A37",
|
|
18
|
+
"bgLighter": "#363646",
|
|
19
|
+
"bgDark": "#16161D",
|
|
20
|
+
"bgGreenTint": "#2A2E27",
|
|
21
|
+
"bgRedTint": "#2E2626",
|
|
22
|
+
"bgPurpleTint": "#26262E"
|
|
23
|
+
},
|
|
24
|
+
"colors": {
|
|
25
|
+
"accent": "cyan",
|
|
26
|
+
"border": "cyan",
|
|
27
|
+
"borderAccent": "blue",
|
|
28
|
+
"borderMuted": "comment",
|
|
29
|
+
"success": "green",
|
|
30
|
+
"error": "red",
|
|
31
|
+
"warning": "orange",
|
|
32
|
+
"muted": "comment",
|
|
33
|
+
"dim": "#54546D",
|
|
34
|
+
"text": "foreground",
|
|
35
|
+
"thinkingText": "comment",
|
|
36
|
+
|
|
37
|
+
"selectedBg": "currentLine",
|
|
38
|
+
"userMessageBg": "bgLight",
|
|
39
|
+
"userMessageText": "foreground",
|
|
40
|
+
"customMessageBg": "bgPurpleTint",
|
|
41
|
+
"customMessageText": "foreground",
|
|
42
|
+
"customMessageLabel": "purple",
|
|
43
|
+
"toolPendingBg": "bgDark",
|
|
44
|
+
"toolSuccessBg": "bgGreenTint",
|
|
45
|
+
"toolErrorBg": "bgRedTint",
|
|
46
|
+
"toolTitle": "foreground",
|
|
47
|
+
"toolOutput": "comment",
|
|
48
|
+
|
|
49
|
+
"mdHeading": "orange",
|
|
50
|
+
"mdLink": "cyan",
|
|
51
|
+
"mdLinkUrl": "comment",
|
|
52
|
+
"mdCode": "green",
|
|
53
|
+
"mdCodeBlock": "foreground",
|
|
54
|
+
"mdCodeBlockBorder": "comment",
|
|
55
|
+
"mdQuote": "comment",
|
|
56
|
+
"mdQuoteBorder": "comment",
|
|
57
|
+
"mdHr": "comment",
|
|
58
|
+
"mdListBullet": "pink",
|
|
59
|
+
|
|
60
|
+
"toolDiffAdded": "green",
|
|
61
|
+
"toolDiffRemoved": "red",
|
|
62
|
+
"toolDiffContext": "comment",
|
|
63
|
+
|
|
64
|
+
"syntaxComment": "comment",
|
|
65
|
+
"syntaxKeyword": "red",
|
|
66
|
+
"syntaxFunction": "blue",
|
|
67
|
+
"syntaxVariable": "foreground",
|
|
68
|
+
"syntaxString": "green",
|
|
69
|
+
"syntaxNumber": "purple",
|
|
70
|
+
"syntaxType": "yellow",
|
|
71
|
+
"syntaxOperator": "red",
|
|
72
|
+
"syntaxPunctuation": "foreground",
|
|
73
|
+
|
|
74
|
+
"thinkingOff": "#54546D",
|
|
75
|
+
"thinkingMinimal": "comment",
|
|
76
|
+
"thinkingLow": "cyan",
|
|
77
|
+
"thinkingMedium": "purple",
|
|
78
|
+
"thinkingHigh": "pink",
|
|
79
|
+
"thinkingXhigh": "red",
|
|
80
|
+
|
|
81
|
+
"bashMode": "green"
|
|
82
|
+
},
|
|
83
|
+
"export": {
|
|
84
|
+
"pageBg": "#16161D",
|
|
85
|
+
"cardBg": "bgDark",
|
|
86
|
+
"infoBg": "#2A2E27"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# ๐ MEMORY.md - AI Agent Knowledge Management
|
|
2
|
+
|
|
3
|
+
**Purpose**: Tell agents when to use **qmd** (durable project KB), when to use **agentmemory** (session-only learnings), and when to skip recording entirely. Cross-session task continuity goes through `/handoffs` + `/pickup`, not these stores.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## ๐ Pre-flight Check: Is Knowledge Base Ready?
|
|
8
|
+
|
|
9
|
+
Before using qmd knowledge features, check if the project's knowledge base is set up:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Check if qmd is installed
|
|
13
|
+
command -v qmd || echo "qmd not found - install with: bun install -g @tobilu/qmd"
|
|
14
|
+
|
|
15
|
+
# Check if MCP server is configured (should return qmd server info)
|
|
16
|
+
mcp__qmd__status
|
|
17
|
+
|
|
18
|
+
# Check if project collection exists
|
|
19
|
+
qmd collection list
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**If NOT set up for this project, automatically set it up:**
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Auto-detect project name: try git remote, fallback to repo folder name, then current folder
|
|
26
|
+
PROJECT_NAME=$(
|
|
27
|
+
{ git remote get-url origin 2>/dev/null | xargs basename -s .git 2>/dev/null; } ||
|
|
28
|
+
{ git rev-parse --show-toplevel 2>/dev/null | xargs basename; } ||
|
|
29
|
+
basename "$PWD"
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
# Filter out empty or invalid values (like "origin" or URL-like strings)
|
|
33
|
+
if [ -z "$PROJECT_NAME" ] || [ "$PROJECT_NAME" = "origin" ] || [[ "$PROJECT_NAME" =~ ^[./:] ]]; then
|
|
34
|
+
PROJECT_NAME=$(
|
|
35
|
+
{ git rev-parse --show-toplevel 2>/dev/null | xargs basename; } ||
|
|
36
|
+
basename "$PWD"
|
|
37
|
+
)
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
# 1. Create project directory structure
|
|
41
|
+
mkdir -p ~/.ai-knowledges/$PROJECT_NAME/learnings
|
|
42
|
+
mkdir -p ~/.ai-knowledges/$PROJECT_NAME/issues
|
|
43
|
+
|
|
44
|
+
# 2. Add to qmd (check for existing collection more robustly)
|
|
45
|
+
ERR_FILE="/tmp/qmd-collection-add-$$.err"
|
|
46
|
+
if qmd collection add ~/.ai-knowledges/$PROJECT_NAME --name $PROJECT_NAME 2>"$ERR_FILE"; then
|
|
47
|
+
echo "โ Collection '$PROJECT_NAME' added"
|
|
48
|
+
rm -f "$ERR_FILE"
|
|
49
|
+
elif grep -qi "already exists" "$ERR_FILE" 2>/dev/null; then
|
|
50
|
+
echo "โ Collection '$PROJECT_NAME' already exists"
|
|
51
|
+
rm -f "$ERR_FILE"
|
|
52
|
+
elif qmd collection list 2>/dev/null | grep -q "^$PROJECT_NAME$"; then
|
|
53
|
+
echo "โ Collection '$PROJECT_NAME' already exists"
|
|
54
|
+
rm -f "$ERR_FILE"
|
|
55
|
+
else
|
|
56
|
+
echo "โ Warning: Could not verify collection setup"
|
|
57
|
+
rm -f "$ERR_FILE"
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
# 3. Add context (skip if already exists)
|
|
61
|
+
qmd context add qmd://$PROJECT_NAME "Knowledge base for $PROJECT_NAME project" 2>/dev/null || true
|
|
62
|
+
|
|
63
|
+
# 4. Generate embeddings for search
|
|
64
|
+
qmd embed 2>/dev/null || true
|
|
65
|
+
|
|
66
|
+
# Inform user
|
|
67
|
+
echo "โ Knowledge base initialized for: $PROJECT_NAME"
|
|
68
|
+
echo " Storage: ~/.ai-knowledges/$PROJECT_NAME"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## ๐ When to Use qmd Knowledge
|
|
74
|
+
|
|
75
|
+
**DO use qmd for:**
|
|
76
|
+
|
|
77
|
+
- Project-specific learnings (architecture decisions, gotchas, patterns)
|
|
78
|
+
- Issue resolution notes (how you fixed something)
|
|
79
|
+
- Project conventions and standards
|
|
80
|
+
- Context that should persist across sessions
|
|
81
|
+
|
|
82
|
+
**DON'T use for:**
|
|
83
|
+
|
|
84
|
+
- Temporary debugging context (use `/handoffs` and `/pickup` instead)
|
|
85
|
+
- General programming knowledge (already in your training)
|
|
86
|
+
- Obvious implementations
|
|
87
|
+
- Boilerplate code
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## ๐ง Agentmemory (session memory MCP)
|
|
92
|
+
|
|
93
|
+
`agentmemory` is a per-session, per-project memory MCP for **short-lived learnings that the agent itself discovered during the current run**. It is _not_ durable storage and _not_ a substitute for qmd.
|
|
94
|
+
|
|
95
|
+
### Use `agentmemory` for (session-only, not durable)
|
|
96
|
+
|
|
97
|
+
- Discoveries made in _this_ run: "the build is blocked on env var `X`", "branch Y has a WIP constraint", "the failing test depends on fixture Z"
|
|
98
|
+
- Pre-commit / post-commit style findings the _current_ agent wants to surface to itself on the next pass
|
|
99
|
+
- Hints the next session today will need but no one will need in a month
|
|
100
|
+
|
|
101
|
+
### Do NOT use `agentmemory` for
|
|
102
|
+
|
|
103
|
+
- Anything that survives a session boundary with value โ that is qmd
|
|
104
|
+
- Recurring gotchas, project-local facts, architecture smells, code review notes โ these are durable and belong in qmd
|
|
105
|
+
- Long-form docs, ADRs, runbooks โ write to disk and let qmd index them
|
|
106
|
+
- Cross-project or cross-machine knowledge โ qmd collections are the canonical layer
|
|
107
|
+
- Cross-session task continuity โ use `/handoffs` (write) and `/pickup` (resume), not agentmemory
|
|
108
|
+
- Secrets, tokens, or anything user-private (memory is per-project, not encrypted)
|
|
109
|
+
|
|
110
|
+
### Decision rule (apply before every record)
|
|
111
|
+
|
|
112
|
+
> "Will the next agent working on this project benefit from this in 3 months?"
|
|
113
|
+
>
|
|
114
|
+
> - **Yes** โ `mcp__qmd__*` (`/qmd-knowledge` skill)
|
|
115
|
+
> - **No, but the next session today might** โ `mcp__agentmemory__memory_save`
|
|
116
|
+
> - **No at all** โ don't record
|
|
117
|
+
> - **"I need to keep working on this tomorrow"** โ write a `/handoffs` plan, not a memory note
|
|
118
|
+
|
|
119
|
+
### Three memory lanes
|
|
120
|
+
|
|
121
|
+
| Lane | Horizon | Tool |
|
|
122
|
+
| ------------- | ------------------- | ------------------------------------------------- |
|
|
123
|
+
| `qmd` | Months | `mcp__qmd__save` via `/qmd-knowledge` skill |
|
|
124
|
+
| `agentmemory` | Today, same project | `mcp__agentmemory__memory_save` |
|
|
125
|
+
| `/handoffs` | Cross-session task | `/handoffs` slash command โ resume with `/pickup` |
|
|
126
|
+
|
|
127
|
+
If you find yourself wanting both "remember this for me next time" and "let me continue this tomorrow" โ that is two separate stores; pick the lane that matches the actual horizon.
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## ๐ ๏ธ How to Use qmd (via MCP Server)
|
|
132
|
+
|
|
133
|
+
When qmd MCP server is configured, you can autonomously:
|
|
134
|
+
|
|
135
|
+
### Search Knowledge
|
|
136
|
+
|
|
137
|
+
```text
|
|
138
|
+
mcp__qmd__query - for best quality (hybrid search with reranking)
|
|
139
|
+
mcp__qmd__search - for fast keyword search
|
|
140
|
+
mcp__qmd__vsearch - for semantic similarity search
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Read Documents
|
|
144
|
+
|
|
145
|
+
```text
|
|
146
|
+
mcp__qmd__get - get single document by path or docid
|
|
147
|
+
mcp__qmd__multi_get - get multiple by glob pattern
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Check Status
|
|
151
|
+
|
|
152
|
+
```text
|
|
153
|
+
mcp__qmd__status - see collections and health
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## ๐ What About Recording?
|
|
159
|
+
|
|
160
|
+
### ๐ซ Do not directly write to ~/.ai-knowledges/
|
|
161
|
+
|
|
162
|
+
Instead, use the `qmd-knowledge` skill:
|
|
163
|
+
|
|
164
|
+
- Invoke via `/qmd-knowledge` slash command
|
|
165
|
+
- Agent will handle proper file creation and embedding updates
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## ๐ Best Practices
|
|
170
|
+
|
|
171
|
+
### ๐จ Session Wrap-up
|
|
172
|
+
|
|
173
|
+
At the end of a work session, consider prompting the user about key learnings:
|
|
174
|
+
|
|
175
|
+
> "What were the main discoveries or decisions from this session? Would you like me to record any learnings โ and if so, into qmd (durable) or agentmemory (session)?"
|
|
176
|
+
|
|
177
|
+
### ๐จ Pattern Detection โ Decision Rule
|
|
178
|
+
|
|
179
|
+
When you spot a knowledge-capture trigger, **apply the 3-month rule first**, then choose a lane.
|
|
180
|
+
|
|
181
|
+
| Phrase | Lane |
|
|
182
|
+
| -------------------------------------------- | --------------------------------------- |
|
|
183
|
+
| "I learned thatโฆ" / "The fix wasโฆ" (general) | Usually qmd โ unless it is session-only |
|
|
184
|
+
| "Blocked on X until env var Y" | `agentmemory` (session) |
|
|
185
|
+
| "Branch W has a WIP constraint" | `agentmemory` (session) |
|
|
186
|
+
| "Don't forget toโฆ" / recurring gotcha | qmd (durable) |
|
|
187
|
+
| "This project uses pattern P" | qmd (durable, project-local) |
|
|
188
|
+
| "Continue debugging tomorrow" / "resume X" | `/handoffs` + `/pickup` (not memory) |
|
|
189
|
+
|
|
190
|
+
If unsure, ask the user which lane โ never record into both.
|
|
191
|
+
|
|
192
|
+
### ๐จ Auto-Index Updates
|
|
193
|
+
|
|
194
|
+
The record script automatically runs `qmd embed` after each write, ensuring the knowledge base is searchable immediately. No manual re-indexing required.
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## ๐ Quick Reference
|
|
199
|
+
|
|
200
|
+
All tools are MCP-style names so agents can call them by exact string.
|
|
201
|
+
|
|
202
|
+
### qmd (durable)
|
|
203
|
+
|
|
204
|
+
| Task | Tool/Command |
|
|
205
|
+
| ---------------- | ---------------------- |
|
|
206
|
+
| Search knowledge | `mcp__qmd__query` |
|
|
207
|
+
| Get document | `mcp__qmd__get` |
|
|
208
|
+
| Record learning | `/qmd-knowledge` skill |
|
|
209
|
+
| Check status | `mcp__qmd__status` |
|
|
210
|
+
|
|
211
|
+
### agentmemory (session)
|
|
212
|
+
|
|
213
|
+
| Task | Tool |
|
|
214
|
+
| ------------------------ | -------------------------------------------- |
|
|
215
|
+
| Save a finding | `mcp__agentmemory__memory_save` |
|
|
216
|
+
| Recall past findings | `mcp__agentmemory__memory_recall` |
|
|
217
|
+
| Hybrid recall + rerank | `mcp__agentmemory__memory_smart_search` |
|
|
218
|
+
| List recent sessions | `mcp__agentmemory__memory_sessions` |
|
|
219
|
+
| Export memory | `mcp__agentmemory__memory_export` |
|
|
220
|
+
| Audit memory | `mcp__agentmemory__memory_audit` |
|
|
221
|
+
| Delete a specific memory | `mcp__agentmemory__memory_governance_delete` |
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## ๐ Project Detection
|
|
226
|
+
|
|
227
|
+
The `qmd-knowledge` skill auto-detects project from:
|
|
228
|
+
|
|
229
|
+
1. `QMD_PROJECT` env var (if set)
|
|
230
|
+
2. Git repository name
|
|
231
|
+
3. Current directory name
|
|
232
|
+
|
|
233
|
+
Knowledge is stored in `~/.ai-knowledges/{project-name}/`
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## ๐ See Also
|
|
238
|
+
|
|
239
|
+
- [qmd GitHub](https://github.com/tobi/qmd) - qmd tool documentation
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Agent Memory Guidelines
|
|
2
|
+
|
|
3
|
+
- Auto-capture learnings as you work: save decisions, debugging discoveries, user preferences, and tool quirks using `mem_save` (agentmemory) โ do not wait to be asked.
|
|
4
|
+
- After fixing a non-trivial bug or learning something project-specific, persist it immediately so future sessions benefit.
|
|
5
|
+
- Keep memories concise and actionable โ prefer facts and patterns over narrative.
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
# Software Development Best Practices
|
|
2
|
+
|
|
3
|
+
## AI Tool Session Management
|
|
4
|
+
|
|
5
|
+
### Run Commands in tmux for Debuggability
|
|
6
|
+
|
|
7
|
+
Always run long-running commands, development servers, tests, and interactive sessions inside tmux with the **current directory name as the session name**. This enables easy debugging and monitoring.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Create session named after current directory (e.g., "my-project")
|
|
11
|
+
SESSION=$(basename "$PWD")
|
|
12
|
+
tmux new -d -s "$SESSION" 2>/dev/null || true
|
|
13
|
+
|
|
14
|
+
# Run dev server with portless if available, otherwise fallback to npm
|
|
15
|
+
if command -v portless &>/dev/null; then
|
|
16
|
+
tmux send-keys -t "$SESSION" 'portless run npm run dev' Enter
|
|
17
|
+
else
|
|
18
|
+
tmux send-keys -t "$SESSION" 'npm run dev' Enter
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
# To check status later from another terminal:
|
|
22
|
+
tmux ls # list all sessions
|
|
23
|
+
tmux attach -t my-project # attach to debug
|
|
24
|
+
tmux capture-pane -p -t my-project -S -100 # view last 100 lines without attaching
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Benefits:**
|
|
28
|
+
|
|
29
|
+
- Sessions survive terminal disconnects
|
|
30
|
+
- Stable `.localhost` URLs via portless (no port numbers to remember)
|
|
31
|
+
- Easy to reattach and debug from any terminal
|
|
32
|
+
- Capture output without interrupting the process
|
|
33
|
+
- Multiple users/agents can monitor the same session
|
|
34
|
+
|
|
35
|
+
**Best Practice:** For AI-assisted log analysis, pair with [LogPilot](https://github.com/machuqiji/logpilot):
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
logpilot watch "$SESSION" --pane "$SESSION:0.0"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Example package.json:**
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"scripts": {
|
|
46
|
+
"dev": "portless run next dev"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Context
|
|
54
|
+
|
|
55
|
+
Comprehensive development guidelines for Agent OS projects, based on Kent Beck's "Tidy First?" principles and Kent C. Dodds' programming wisdom.
|
|
56
|
+
|
|
57
|
+
> "Software design is an exercise in human relationships" - Kent Beck
|
|
58
|
+
|
|
59
|
+
## ๐ฏ Core Principles
|
|
60
|
+
|
|
61
|
+
### ๐งน Tidy First Philosophy
|
|
62
|
+
|
|
63
|
+
- **Small, Safe Steps**: Make big changes through small, reversible steps
|
|
64
|
+
- **Human Relationships**: Code is communication between humans
|
|
65
|
+
- **Economic Thinking**: Balance current effort against future options
|
|
66
|
+
- **Eliminate Problems**: Remove complexity rather than managing it
|
|
67
|
+
|
|
68
|
+
### โจ Code Quality Fundamentals
|
|
69
|
+
|
|
70
|
+
- **Don't Solve Problems, Eliminate Them**: Look for ways to reduce complexity
|
|
71
|
+
- **Optimize for Readability**: Prioritize code clarity over clever solutions
|
|
72
|
+
- **Self-Documenting Code**: Use meaningful names and clear structure
|
|
73
|
+
- **Test for Confidence**: Write tests that give confidence to change
|
|
74
|
+
|
|
75
|
+
### ๐ Change-Friendly Design
|
|
76
|
+
|
|
77
|
+
- **Separate Tidying from Behavior Changes**: Keep refactoring separate from new features
|
|
78
|
+
- **Build for the Next Developer**: Consider maintainability and understanding
|
|
79
|
+
- **Options Over Things**: Create flexibility for uncertain future requirements
|
|
80
|
+
- **Progressive Enhancement**: Start simple, add complexity when needed
|
|
81
|
+
|
|
82
|
+
## ๐ฆ Dependencies
|
|
83
|
+
|
|
84
|
+
### ๐ง Choose Libraries Wisely
|
|
85
|
+
|
|
86
|
+
When adding third-party dependencies:
|
|
87
|
+
|
|
88
|
+
- Select the most popular and actively maintained option
|
|
89
|
+
- Check the library's GitHub repository for:
|
|
90
|
+
- Recent commits (within last 6 months)
|
|
91
|
+
- Active issue resolution
|
|
92
|
+
- Number of stars/downloads
|
|
93
|
+
- Clear documentation
|
|
94
|
+
|
|
95
|
+
## ๐งน Tidying Practices
|
|
96
|
+
|
|
97
|
+
### โฐ When to Tidy
|
|
98
|
+
|
|
99
|
+
**Before making a change**:
|
|
100
|
+
|
|
101
|
+
- Will tidying make the change easier? โ Yes โ Tidy first
|
|
102
|
+
- Will tidying take longer than the change? โ No โ Make change first, tidy after
|
|
103
|
+
- Is the change urgent? โ Skip tidying for now, schedule for later
|
|
104
|
+
|
|
105
|
+
### ๐ง Core Tidying Techniques
|
|
106
|
+
|
|
107
|
+
#### ๐ก๏ธ Guard Clauses
|
|
108
|
+
|
|
109
|
+
Move preconditions to the top and return early:
|
|
110
|
+
|
|
111
|
+
```javascript
|
|
112
|
+
// โ Nested conditions
|
|
113
|
+
function processUser(user) {
|
|
114
|
+
if (user) {
|
|
115
|
+
if (user.isActive) {
|
|
116
|
+
if (user.hasPermission) {
|
|
117
|
+
// main logic
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// โ
Guard clauses
|
|
124
|
+
function processUser(user) {
|
|
125
|
+
if (!user) return;
|
|
126
|
+
if (!user.isActive) return;
|
|
127
|
+
if (!user.hasPermission) return;
|
|
128
|
+
|
|
129
|
+
// main logic
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
#### ๐๏ธ Dead Code Elimination
|
|
134
|
+
|
|
135
|
+
Delete code that isn't executed or referenced.
|
|
136
|
+
|
|
137
|
+
#### โ๏ธ Normalize Symmetries
|
|
138
|
+
|
|
139
|
+
Use consistent patterns throughout the codebase.
|
|
140
|
+
|
|
141
|
+
#### ๐ Helper Variables and Functions
|
|
142
|
+
|
|
143
|
+
Extract complex expressions into well-named variables:
|
|
144
|
+
|
|
145
|
+
```javascript
|
|
146
|
+
// โ Complex expression
|
|
147
|
+
if (
|
|
148
|
+
user.subscription.plan.tier === "premium" &&
|
|
149
|
+
user.subscription.status === "active" &&
|
|
150
|
+
user.subscription.expiresAt > new Date()
|
|
151
|
+
) {
|
|
152
|
+
// logic
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// โ
Helper variable
|
|
156
|
+
const hasActivePremiumSubscription =
|
|
157
|
+
user.subscription.plan.tier === "premium" &&
|
|
158
|
+
user.subscription.status === "active" &&
|
|
159
|
+
user.subscription.expiresAt > new Date();
|
|
160
|
+
|
|
161
|
+
if (hasActivePremiumSubscription) {
|
|
162
|
+
// logic
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## ๐งช Testing Strategy
|
|
167
|
+
|
|
168
|
+
### ๐ The Testing Trophy Approach
|
|
169
|
+
|
|
170
|
+
Based on Kent C. Dodds' testing philosophy:
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
๐ End-to-End (E2E)
|
|
174
|
+
โ High confidence, slow, expensive
|
|
175
|
+
๐ฅ Integration Tests
|
|
176
|
+
โ Good confidence, moderate speed
|
|
177
|
+
๐ฅ Unit Tests
|
|
178
|
+
โ Low confidence, fast, cheap
|
|
179
|
+
๐
Static Analysis
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### ๐ Testing Guidelines
|
|
183
|
+
|
|
184
|
+
#### ๐ช Write Tests That Give Confidence
|
|
185
|
+
|
|
186
|
+
- Test behavior, not implementation details
|
|
187
|
+
- Focus on user-facing functionality
|
|
188
|
+
- Prefer integration tests over isolated unit tests
|
|
189
|
+
|
|
190
|
+
#### ๐๏ธ Test Structure
|
|
191
|
+
|
|
192
|
+
```javascript
|
|
193
|
+
// โ
Clear test structure
|
|
194
|
+
test("should increment counter when button is clicked", () => {
|
|
195
|
+
// Arrange
|
|
196
|
+
render(<Counter />);
|
|
197
|
+
const button = screen.getByRole("button", { name: /increment/i });
|
|
198
|
+
const counter = screen.getByTestId("counter-value");
|
|
199
|
+
|
|
200
|
+
// Act
|
|
201
|
+
expect(counter).toHaveTextContent("0");
|
|
202
|
+
fireEvent.click(button);
|
|
203
|
+
|
|
204
|
+
// Assert
|
|
205
|
+
expect(counter).toHaveTextContent("1");
|
|
206
|
+
});
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
#### ๐ Avoid Testing Implementation Details
|
|
210
|
+
|
|
211
|
+
- Don't test internal state or private methods
|
|
212
|
+
- Test the component's public interface
|
|
213
|
+
- Mock at the network boundary, not internal functions
|
|
214
|
+
|
|
215
|
+
## โก Performance Practices
|
|
216
|
+
|
|
217
|
+
### ๐ Optimize for the Right Metrics
|
|
218
|
+
|
|
219
|
+
- Focus on user-centric performance (loading, interaction)
|
|
220
|
+
- Measure before optimizing
|
|
221
|
+
- Avoid premature micro-optimizations
|
|
222
|
+
|
|
223
|
+
### ๐ Progressive Enhancement
|
|
224
|
+
|
|
225
|
+
- Build core functionality that works without JavaScript
|
|
226
|
+
- Enhance with client-side features
|
|
227
|
+
- Use lazy loading for non-critical resources
|
|
228
|
+
|
|
229
|
+
### ๐ Performance Patterns
|
|
230
|
+
|
|
231
|
+
```javascript
|
|
232
|
+
// โ
Lazy loading with Suspense
|
|
233
|
+
const HeavyComponent = lazy(() => import("./heavy-component"));
|
|
234
|
+
|
|
235
|
+
function App() {
|
|
236
|
+
return (
|
|
237
|
+
<Suspense fallback={<Skeleton />}>
|
|
238
|
+
<HeavyComponent />
|
|
239
|
+
</Suspense>
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## ๐ค Collaboration Practices
|
|
245
|
+
|
|
246
|
+
### ๐ฌ Code as Communication
|
|
247
|
+
|
|
248
|
+
- Express intent clearly through naming and structure
|
|
249
|
+
- Document decisions, not implementation
|
|
250
|
+
- Consider the next developer who will read this code
|
|
251
|
+
|
|
252
|
+
### ๐ Pull Request Guidelines
|
|
253
|
+
|
|
254
|
+
**For Authors**:
|
|
255
|
+
|
|
256
|
+
- Separate tidying commits from behavior changes
|
|
257
|
+
- Write clear commit messages
|
|
258
|
+
- Include context in PR descriptions
|
|
259
|
+
|
|
260
|
+
**For Reviewers**:
|
|
261
|
+
|
|
262
|
+
- Focus on correctness, simplicity, and maintainability
|
|
263
|
+
- Ask questions when unclear
|
|
264
|
+
- Praise good solutions
|
|
265
|
+
|
|
266
|
+
### โป๏ธ Continuous Improvement
|
|
267
|
+
|
|
268
|
+
- Reflect on decisions and learn from mistakes
|
|
269
|
+
- Share knowledge through documentation and mentoring
|
|
270
|
+
- Regularly refactor and clean up technical debt
|