Skip to content

Commit 3afc7ff

Browse files
committed
feat: add default permissions to ctx init and prompting guide
ctx init now pre-seeds permissions for all ctx commands in settings.local.json, so /ctx-* slash commands work out of the box. Permissions are merged additively to preserve user customizations. Also adds: - Prompting guide documentation (docs/prompting-guide.md) - make site-setup, site, site-serve targets for documentation Signed-off-by: Jose Alekhinne <alekhinejose@gmail.com>
1 parent ed6760f commit 3afc7ff

20 files changed

Lines changed: 2231 additions & 36 deletions

File tree

.context/LEARNINGS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,3 +348,5 @@ directory component (e.g., `/home/user/ctx/internal/...`).
348348
- **[2026-01-26-0553]** Claude Code settings.local.json hook keys are 'PreToolUse' and 'SessionEnd' (not 'PreToolUseHooks'/'SessionEndHooks'). The 'Hooks' suffix causes 'Invalid key in record' errors.
349349

350350
- **[2026-01-26-0612]** Go's json.Marshal escapes `>`, `<`, and `&` as unicode (\u003e, \u003c, \u0026) by default for HTML safety. Use json.Encoder with SetEscapeHTML(false) when generating config files that contain shell commands like `2>/dev/null`.
351+
352+
- **[2026-01-27-054706]** Claude Code slash commands using `!` bash syntax require matching permissions in settings.local.json. When adding new /ctx-* commands, ensure ctx init pre-seeds the required Bash(ctx <subcommand>:*) permissions. Use additive merging for user config - never remove existing permissions.

Makefile

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#
33
# Common targets for Go developers
44

5-
.PHONY: build test vet fmt lint clean all release build-all dogfood help test-coverage smoke
5+
.PHONY: build test vet fmt lint clean all release build-all dogfood help test-coverage smoke site site-serve site-setup
66

77
# Default binary name and output
88
BINARY := ctx
@@ -114,6 +114,20 @@ install:
114114
cp $(BINARY) /usr/local/bin/$(BINARY)
115115
@echo "Installed ctx to /usr/local/bin/ctx"
116116

117+
## site-setup: Create venv and install zensical
118+
site-setup:
119+
python3 -m venv .venv
120+
.venv/bin/pip install --upgrade pip
121+
.venv/bin/pip install zensical
122+
123+
## site: Build documentation site
124+
site:
125+
.venv/bin/zensical build
126+
127+
## site-serve: Serve documentation site locally
128+
site-serve:
129+
.venv/bin/zensical serve
130+
117131
## help: Show this help
118132
help:
119133
@echo "Context CLI - Available targets:"

docs/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ ctx drift
215215

216216
## Next Steps
217217

218+
- [Prompting Guide](prompting-guide.md) — Effective prompts for AI sessions
218219
- [CLI Reference](cli-reference.md) — All commands and options
219220
- [Context Files](context-files.md) — File formats and structure
220221
- [Ralph Loop Integration](ralph-loop.md) — Autonomous AI development workflows

docs/prompting-guide.md

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
---
2+
# / Context: https://ctx.ist
3+
# ,'`./ do you remember?
4+
# `.,'\
5+
# \ Copyright 2026-present Context contributors.
6+
# SPDX-License-Identifier: Apache-2.0
7+
8+
title: Prompting Guide
9+
icon: lucide/message-circle
10+
---
11+
12+
![ctx](images/ctx-banner.png)
13+
14+
## Prompting Guide
15+
16+
Effective prompts for working with AI assistants in ctx-enabled projects.
17+
18+
### Why This Matters
19+
20+
AI assistants don't automatically read context files. The right prompt triggers
21+
the right behavior. This guide documents prompts that reliably produce good results.
22+
23+
---
24+
25+
## Session Start
26+
27+
### "Do you remember?"
28+
29+
**What it does**: Triggers the AI to read AGENT_PLAYBOOK, CONSTITUTION, sessions/,
30+
and other context files before responding.
31+
32+
**When to use**: Start of every important session.
33+
34+
```
35+
Do you remember what we were working on?
36+
```
37+
38+
**Why it works**: The question implies prior context exists. The AI checks files
39+
rather than admitting ignorance.
40+
41+
### "What's the current state?"
42+
43+
**What it does**: Prompts reading of TASKS.md, recent sessions, and status overview.
44+
45+
**When to use**: Resuming work after a break.
46+
47+
**Variants**:
48+
49+
- "Where did we leave off?"
50+
- "What's in progress?"
51+
- "Show me the open tasks"
52+
53+
---
54+
55+
## During Work
56+
57+
### "Why doesn't X work?"
58+
59+
**What it does**: Triggers root cause analysis rather than surface-level fixes.
60+
61+
**When to use**: When something fails unexpectedly.
62+
63+
**Why it works**: Framing as "why" encourages investigation before action.
64+
The AI will trace through code, check configurations, and identify the actual cause.
65+
66+
!!! example "Real example"
67+
"Why can't I run /ctx-save?" led to discovering missing permissions
68+
in settings.local.json bootstrapping—a fix that benefited all users.
69+
70+
### "Is this consistent with our decisions?"
71+
72+
**What it does**: Prompts checking DECISIONS.md before implementing.
73+
74+
**When to use**: Before making architectural choices.
75+
76+
**Variants**:
77+
78+
- "Check if we've decided on this before"
79+
- "Does this align with our conventions?"
80+
81+
### "What would break if we..."
82+
83+
**What it does**: Triggers defensive thinking and impact analysis.
84+
85+
**When to use**: Before making significant changes.
86+
87+
```
88+
What would break if we change the Settings struct?
89+
```
90+
91+
### "Before you start, read X"
92+
93+
**What it does**: Ensures specific context is loaded before work begins.
94+
95+
**When to use**: When you know relevant context exists in a specific file.
96+
97+
```
98+
Before you start, read .context/sessions/2026-01-20-auth-discussion.md
99+
```
100+
101+
---
102+
103+
## Reflection & Persistence
104+
105+
### "What did we learn?"
106+
107+
**What it does**: Prompts reflection on the session and often triggers adding
108+
learnings to LEARNINGS.md.
109+
110+
**When to use**: After completing a task or debugging session.
111+
112+
**Why it works**: Explicit reflection prompt. The AI will summarize insights
113+
and often offer to persist them.
114+
115+
### "Add this as a learning/decision"
116+
117+
**What it does**: Explicit persistence request.
118+
119+
**When to use**: When you've discovered something worth remembering.
120+
121+
```
122+
Add this as a learning: "JSON marshal escapes angle brackets by default"
123+
```
124+
125+
### "Save context before we end"
126+
127+
**What it does**: Triggers context persistence before session close.
128+
129+
**When to use**: End of session, or before switching topics.
130+
131+
**Variants**:
132+
133+
- "Let's persist what we did"
134+
- "Update the context files"
135+
- `/ctx-save` (slash command in Claude Code)
136+
137+
---
138+
139+
## Exploration & Research
140+
141+
### "Explore the codebase for X"
142+
143+
**What it does**: Triggers thorough codebase search rather than guessing.
144+
145+
**When to use**: When you need to understand how something works.
146+
147+
**Why it works**: "Explore" signals that investigation is needed, not immediate action.
148+
149+
### "How does X work in this codebase?"
150+
151+
**What it does**: Prompts reading actual code rather than explaining general concepts.
152+
153+
**When to use**: Understanding existing implementation.
154+
155+
```
156+
How does session saving work in this codebase?
157+
```
158+
159+
### "Find all places where X"
160+
161+
**What it does**: Comprehensive search across the codebase.
162+
163+
**When to use**: Before refactoring or understanding impact.
164+
165+
---
166+
167+
## Meta & Process
168+
169+
### "What should we document from this?"
170+
171+
**What it does**: Prompts identifying learnings, decisions, and conventions
172+
worth persisting.
173+
174+
**When to use**: After complex discussions or implementations.
175+
176+
### "Is this the right approach?"
177+
178+
**What it does**: Invites the AI to challenge the current direction.
179+
180+
**When to use**: When you want a sanity check.
181+
182+
**Why it works**: Gives permission to disagree. AIs often default to agreeing;
183+
this prompt signals you want honest assessment.
184+
185+
### "What am I missing?"
186+
187+
**What it does**: Prompts thinking about edge cases, overlooked requirements,
188+
or unconsidered approaches.
189+
190+
**When to use**: Before finalizing a design or implementation.
191+
192+
---
193+
194+
## Anti-Patterns
195+
196+
Prompts that tend to produce poor results:
197+
198+
| Prompt | Problem | Better Alternative |
199+
|--------|---------|-------------------|
200+
| "Fix this" | Too vague, may patch symptoms | "Why is this failing?" |
201+
| "Make it work" | Encourages quick hacks | "What's the right way to solve this?" |
202+
| "Just do it" | Skips planning | "Plan this, then implement" |
203+
| "You should remember" | Confrontational | "Do you remember?" |
204+
| "Obviously..." | Discourages questions | State the requirement directly |
205+
206+
---
207+
208+
## Quick Reference
209+
210+
| Goal | Prompt |
211+
|------|--------|
212+
| Load context | "Do you remember?" |
213+
| Resume work | "What's the current state?" |
214+
| Debug | "Why doesn't X work?" |
215+
| Validate | "Is this consistent with our decisions?" |
216+
| Impact analysis | "What would break if we..." |
217+
| Reflect | "What did we learn?" |
218+
| Persist | "Add this as a learning" |
219+
| Explore | "How does X work in this codebase?" |
220+
| Sanity check | "Is this the right approach?" |
221+
| Completeness | "What am I missing?" |
222+
223+
---
224+
225+
## Contributing
226+
227+
Found a prompt that works well?
228+
[Open an issue](https://github.com/ActiveMemory/ctx/issues) or PR with:
229+
230+
1. The prompt text
231+
2. What behavior it triggers
232+
3. When to use it
233+
4. Why it works (optional but helpful)

internal/claude/embed.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,24 @@ func GetCommand(name string) ([]byte, error) {
7979
return content, nil
8080
}
8181

82+
// CreateDefaultPermissions returns the default permissions for ctx commands.
83+
//
84+
// These permissions allow Claude Code to run ctx CLI commands without
85+
// prompting for approval. All ctx subcommands are pre-approved.
86+
//
87+
// Returns:
88+
// - []string: List of permission patterns for ctx commands
89+
func CreateDefaultPermissions() []string {
90+
return []string{
91+
"Bash(ctx status:*)",
92+
"Bash(ctx agent:*)",
93+
"Bash(ctx add:*)",
94+
"Bash(ctx session:*)",
95+
"Bash(ctx tasks:*)",
96+
"Bash(ctx loop:*)",
97+
}
98+
}
99+
82100
// CreateDefaultHooks returns the default ctx hooks configuration for
83101
// Claude Code.
84102
//

internal/claude/embed_test.go

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,16 +142,43 @@ func TestSettingsStructure(t *testing.T) {
142142
// Test that Settings struct can be instantiated correctly
143143
settings := Settings{
144144
Hooks: CreateDefaultHooks(""),
145-
Permissions: map[string]interface{}{
146-
"allow": []string{"read", "write"},
145+
Permissions: PermissionsConfig{
146+
Allow: []string{"Bash(ctx status:*)", "Bash(ctx agent:*)"},
147147
},
148148
}
149149

150150
if len(settings.Hooks.PreToolUse) == 0 {
151151
t.Error("Settings.Hooks.PreToolUse should not be empty")
152152
}
153153

154-
if settings.Permissions == nil {
155-
t.Error("Settings.Permissions should not be nil")
154+
if len(settings.Permissions.Allow) == 0 {
155+
t.Error("Settings.Permissions.Allow should not be empty")
156+
}
157+
}
158+
159+
func TestCreateDefaultPermissions(t *testing.T) {
160+
perms := CreateDefaultPermissions()
161+
162+
if len(perms) == 0 {
163+
t.Error("CreateDefaultPermissions should return permissions")
164+
}
165+
166+
// Check that essential ctx commands are included
167+
expected := []string{
168+
"Bash(ctx status:*)",
169+
"Bash(ctx agent:*)",
170+
"Bash(ctx add:*)",
171+
"Bash(ctx session:*)",
172+
}
173+
174+
permSet := make(map[string]bool)
175+
for _, p := range perms {
176+
permSet[p] = true
177+
}
178+
179+
for _, e := range expected {
180+
if !permSet[e] {
181+
t.Errorf("Missing expected permission: %s", e)
182+
}
156183
}
157184
}

internal/claude/types.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,23 @@ type Hook struct {
4343
Command string `json:"command"`
4444
}
4545

46+
// PermissionsConfig represents the permissions section of Claude Code's
47+
// settings.local.json.
48+
//
49+
// Fields:
50+
// - Allow: List of tool patterns that are pre-approved (e.g., "Bash(ctx status:*)")
51+
type PermissionsConfig struct {
52+
Allow []string `json:"allow,omitempty"`
53+
}
54+
4655
// Settings represents the full Claude Code settings.local.json structure.
4756
//
4857
// This is used when reading or writing project-level Claude Code configuration.
4958
//
5059
// Fields:
5160
// - Hooks: Hook configuration for lifecycle events
52-
// - Permissions: Tool permission overrides (key: tool pattern, value: permission)
61+
// - Permissions: Tool permission configuration
5362
type Settings struct {
54-
Hooks HookConfig `json:"hooks,omitempty"`
55-
Permissions map[string]interface{} `json:"permissions,omitempty"`
63+
Hooks HookConfig `json:"hooks,omitempty"`
64+
Permissions PermissionsConfig `json:"permissions,omitempty"`
5665
}

0 commit comments

Comments
 (0)