Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ CLI needs upgrading.

**Claude Code:** `basecamp setup claude` — installs the plugin with skills, hooks, and agent workflow support.

**Codex:** `basecamp setup codex` — registers the 37signals marketplace and installs the native plugin with Basecamp skills, diagnostics, and opt-in hooks. In Codex, review and trust the plugin hooks with `/hooks`, then start a new thread to load the skills and hooks.
**Codex:** `basecamp setup codex` — registers the 37signals marketplace and installs the native plugin with Basecamp skills, diagnostics, and opt-in commit-reference hooks. In Codex, review and trust the plugin hooks with `/hooks`, then start a new thread to load the skills and hooks. The plugin does not inject Basecamp context at session start; Codex selects the skill when a request is relevant or explicitly references Basecamp.

Manual Codex installation uses the same marketplace:

Expand Down
15 changes: 1 addition & 14 deletions hooks/hooks.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,6 @@
{
"description": "Basecamp agent hooks: session context and commit-reference nudges.",
"description": "Basecamp agent hooks: commit-reference nudges.",
"hooks": {
"SessionStart": [
{
"matcher": "startup|resume|clear|compact",
"hooks": [
{
"type": "command",
"command": "basecamp agent-hook session-start",
"timeout": 5,
"statusMessage": "Checking Basecamp status"
}
]
}
],
"PreToolUse": [
{
"matcher": "Bash",
Expand Down
2 changes: 1 addition & 1 deletion install.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ plugin, run `basecamp upgrade` and start a new session; `basecamp agent-hook
basecamp setup codex
```

This installs the shared Basecamp skill, registers the 37signals Codex marketplace, and installs the native plugin. After setup, review and trust the plugin hooks with `/hooks` (Codex lists untrusted hooks but does not run them until trusted), then start a new Codex thread to load the skills and hooks.
This installs the shared Basecamp skill, registers the 37signals Codex marketplace, and installs the native plugin. After setup, review and trust the plugin's commit-reference hooks with `/hooks` (Codex lists untrusted hooks but does not run them until trusted), then start a new Codex thread to load the skills and hooks. The plugin does not inject Basecamp context at session start; Codex selects the skill when a request is relevant or explicitly references Basecamp.

For a manual install:

Expand Down
2 changes: 0 additions & 2 deletions internal/commands/wizard_codex.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ func runCodexSetup(cmd *cobra.Command, styles *tui.Styles) error {
fmt.Fprintln(w, styles.RenderStatus(true, "37signals marketplace ready"))
fmt.Fprintln(w, styles.RenderStatus(true, "Codex plugin installed and enabled"))
fmt.Fprintln(w)
// Trust must come first: an untrusted SessionStart hook is silently
// skipped, so a thread started before trusting gets no hook context.
fmt.Fprintln(w, styles.Muted.Render(" Review and trust the plugin hooks with /hooks."))
fmt.Fprintln(w, styles.Muted.Render(" Then start a new Codex thread to load the Basecamp skills."))
return nil
Expand Down
5 changes: 2 additions & 3 deletions internal/commands/wizard_codex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,8 @@ func TestRunCodexSetupInteractiveExplainsNextSteps(t *testing.T) {

assert.Contains(t, output.String(), "Registering 37signals marketplace")
assert.Contains(t, output.String(), "Installing basecamp plugin")
// Codex lists untrusted hooks but does not run them until trusted, and
// an untrusted SessionStart is skipped — so the trust step must come
// before the new-thread step.
// Codex lists untrusted hooks but does not run them until trusted, so
// complete hook setup before starting the thread that loads the skills.
trustAt := strings.Index(output.String(), "trust the plugin hooks with /hooks")
newThreadAt := strings.Index(output.String(), "start a new Codex thread")
require.GreaterOrEqual(t, trustAt, 0)
Expand Down
1 change: 1 addition & 0 deletions internal/release/manifests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ func TestHooksFileCommandsInvokeBasecamp(t *testing.T) {
}
require.NoError(t, json.Unmarshal(data, &config))
require.NotEmpty(t, config.Hooks)
assert.NotContains(t, config.Hooks, "SessionStart", "plugins must not inject Basecamp context into every agent session")

for event, matchers := range config.Hooks {
require.NotEmpty(t, matchers, event)
Expand Down