Skip to content

Commit 0ecfe6a

Browse files
authored
fix(kimaki): strip project routing guidance (#104)
1 parent d9d4996 commit 0ecfe6a

6 files changed

Lines changed: 63 additions & 29 deletions

File tree

bridges/kimaki/plugins/dm-context-filter.ts

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@
2525
// --project` / `session search --channel <id>`. These are cross-project
2626
// discovery vectors; on a single-project fleet server the agent only ever
2727
// needs to list sessions in the current project (no flags required).
28-
// 11. Project discovery inlines — scattered `kimaki project list|add|create`,
29-
// `kimaki send --project`, and bare `kimaki send --channel <channel_id>`
30-
// examples that survive section stripping. These let the agent discover
31-
// other Discord channels and route minion sessions away from the current
32-
// thread. See Extra-Chill/data-machine-code#49.
28+
// 11. Project discovery/guidance inlines — scattered prose and examples for
29+
// `kimaki project list|add|create`, `kimaki send --project`, bare
30+
// `kimaki send --channel <channel_id>`, `#project-name` resolution, and
31+
// "project channel" routing. These let the agent discover other Discord
32+
// channels and route minion sessions away from the current thread. See
33+
// Extra-Chill/data-machine-code#49.
3334
// 12. Agent override inlines — `--agent <current_agent>` examples from the
3435
// generic Kimaki prompt. On DM-managed sites the Discord channel owns the
3536
// personal-agent binding; passing the runtime agent (for example `opencode`)
@@ -244,7 +245,7 @@ function stripWorktreeInlines(block: string): string {
244245
}
245246

246247
/**
247-
* Remove project / channel discovery examples that survive section stripping.
248+
* Remove project / channel discovery guidance that survives section stripping.
248249
*
249250
* The system prompt bakes the current channel ID into most `kimaki send`
250251
* examples via `${channelId}`, which is the safe/correct form for this
@@ -257,6 +258,8 @@ function stripWorktreeInlines(block: string): string {
257258
* - `kimaki send --channel <channel_id>` with a literal `<channel_id>`
258259
* placeholder (as opposed to the baked-in current-channel ID) — teaches
259260
* the agent it can pick a channel freely.
261+
* - `#project-name` / "project channel" prose — teaches the agent to treat
262+
* repo/project channels as valid routing targets.
260263
*
261264
* On DM-managed sites the current Discord thread is the only correct target
262265
* for minion sessions. Cross-repo work uses DM Code's workspace worktrees,
@@ -268,6 +271,28 @@ function stripWorktreeInlines(block: string): string {
268271
function stripProjectDiscoveryInlines(block: string): string {
269272
let result = block;
270273

274+
// If upstream renames the cross-project section, strip its distinctive prose
275+
// before deleting leftover command lines below.
276+
result = result.replace(
277+
/\n+When the user references another project by name,[\s\S]*?root project directories\.\n/g,
278+
"\n"
279+
);
280+
281+
result = result.replace(
282+
/\n+When the user uses `#project-name` syntax,[\s\S]*?before acting,[^\n]*\n/g,
283+
"\n"
284+
);
285+
286+
result = result.replace(
287+
/\n+To send a task to another project:[\s\S]*?(?=\n\S|$)/g,
288+
"\n"
289+
);
290+
291+
result = result.replace(
292+
/\n+When sending prompts to other projects,[^\n]*\n/g,
293+
"\n"
294+
);
295+
271296
// Standalone `kimaki project ...` commands on their own lines (inside any
272297
// surviving section or orphaned between sections). Covers list|add|create.
273298
result = result.replace(
@@ -305,6 +330,13 @@ function stripProjectDiscoveryInlines(block: string): string {
305330
"\n"
306331
);
307332

333+
// Remove any whole-line project-routing prose that may survive if Kimaki
334+
// changes surrounding headings or examples.
335+
result = result.replace(
336+
/\n+[^\n]*(?:project channel|cross-project|#project-name|other project|another project)[^\n]*\n/gi,
337+
"\n"
338+
);
339+
308340
return result;
309341
}
310342

tests/effective-prompt/README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
Pluggable harness that renders the kimaki opencode system prompt, runs the
44
`dm-context-filter` plugin over it, snapshots the result, and asserts that
5-
no banned phrases (`worktree`, `--cwd`, etc) leak into the filtered prompt
6-
that an opencode session actually sees.
5+
no banned phrases (`worktree`, `--cwd`, `kimaki project`, `--project`,
6+
`#project-name`, etc) leak into the filtered prompt that an opencode session
7+
actually sees.
78

89
## Why
910

@@ -49,8 +50,8 @@ Each scenario is a JSON file in `scenarios/`. Override any of:
4950
- **`baseline`** — name from `filters.mjs`. Default
5051
`"broken-stripsection"` (proves new filter strips strictly more).
5152
- **`triggers`** — array of `{ name, pattern }`. Pattern is a JS regex
52-
string; prefix with `(?i)` for case-insensitive. Default: `worktree`
53-
+ `--cwd`.
53+
string; prefix with `(?i)` for case-insensitive. Default: `worktree`,
54+
`--cwd`, `--agent`, and Kimaki project/channel routing guidance.
5455
- **`allowLeakInSection`** — array of section headings (e.g. `"## Minion
5556
Session Routing"`) where trigger matches are intentional and must not
5657
count as leaks.

tests/effective-prompt/__snapshots__/default.baseline.txt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,20 +53,15 @@ kimaki project list --json # machine-readable output
5353
# Add an existing directory as a project
5454
```
5555

56-
To send a task to another project:
57-
5856
```bash
5957
# Send to a specific channel
6058

6159
# Or use --project to resolve from directory
6260
```
6361

64-
When sending prompts to other projects, always ask the agent to plan first, never build upfront. The prompt should start with "Plan how to ..." so the user can review before greenlighting implementation.
65-
6662
Use cases:
6763
- **Updating a fork or dependency** the user maintains locally
6864
- **Coordinating changes** across related repos (e.g., SDK + docs)
69-
- **Delegating subtasks** to isolated sessions in other projects
7065

7166
# Start a session and wait for it to finish
7267

@@ -77,7 +72,6 @@ kimaki send --thread <thread_id> --prompt 'Run the tests' --wait
7772
The command exits with the session markdown on stdout once the model finishes responding.
7873

7974
Use `--wait` when you need to:
80-
- **Fix a bug in another project** before continuing here (e.g. fix a dependency, then resume)
8175
- **Run a task in a separate worktree** and use the result in your current session
8276
- **Chain sessions sequentially** where the next depends on the previous output
8377

tests/effective-prompt/__snapshots__/no-agents-no-thread.baseline.txt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,15 @@ kimaki project list --json # machine-readable output
5151
# Add an existing directory as a project
5252
```
5353

54-
To send a task to another project:
55-
5654
```bash
5755
# Send to a specific channel
5856

5957
# Or use --project to resolve from directory
6058
```
6159

62-
When sending prompts to other projects, always ask the agent to plan first, never build upfront. The prompt should start with "Plan how to ..." so the user can review before greenlighting implementation.
63-
6460
Use cases:
6561
- **Updating a fork or dependency** the user maintains locally
6662
- **Coordinating changes** across related repos (e.g., SDK + docs)
67-
- **Delegating subtasks** to isolated sessions in other projects
6863

6964
# Start a session and wait for it to finish
7065

@@ -75,7 +70,6 @@ kimaki send --thread <thread_id> --prompt 'Run the tests' --wait
7570
The command exits with the session markdown on stdout once the model finishes responding.
7671

7772
Use `--wait` when you need to:
78-
- **Fix a bug in another project** before continuing here (e.g. fix a dependency, then resume)
7973
- **Run a task in a separate worktree** and use the result in your current session
8074
- **Chain sessions sequentially** where the next depends on the previous output
8175

tests/effective-prompt/filters.mjs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { dirname, join } from "node:path"
2020
import { fileURLToPath } from "node:url"
2121

2222
const __dirname = dirname(fileURLToPath(import.meta.url))
23-
const PLUGIN_PATH = join(__dirname, "..", "..", "kimaki", "plugins", "dm-context-filter.ts")
23+
const PLUGIN_PATH = join(__dirname, "..", "..", "bridges", "kimaki", "plugins", "dm-context-filter.ts")
2424

2525
// ---------------------------------------------------------------------------
2626
// "current" filter — extract the filter helpers from the live plugin
@@ -65,11 +65,16 @@ function stripWorktreeInlines(block) {
6565

6666
function stripProjectDiscoveryInlines(block) {
6767
let result = block
68+
result = result.replace(/\n+When the user references another project by name,[\s\S]*?root project directories\.\n/g, "\n")
69+
result = result.replace(/\n+When the user uses `#project-name` syntax,[\s\S]*?before acting,[^\n]*\n/g, "\n")
70+
result = result.replace(/\n+To send a task to another project:[\s\S]*?(?=\n\S|$)/g, "\n")
71+
result = result.replace(/\n+When sending prompts to other projects,[^\n]*\n/g, "\n")
6872
result = result.replace(/\n+kimaki project (?:list|add|create)[^\n]*\n/g, "\n")
6973
result = result.replace(/\n+kimaki send --project [^\n]*\n/g, "\n")
7074
result = result.replace(/\n+kimaki send --channel <channel_id>[^\n]*\n/g, "\n")
7175
result = result.replace(/\n+kimaki session search [^\n]*--channel <channel_id>[^\n]*\n/g, "\n")
7276
result = result.replace(/\n+kimaki (?:session|task) [^\n]*--project [^\n]*\n/g, "\n")
77+
result = result.replace(/\n+[^\n]*(?:project channel|cross-project|#project-name|other project|another project)[^\n]*\n/gi, "\n")
7378
return result
7479
}
7580

tests/effective-prompt/run.mjs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
// kimaki-shipped system prompt. Three things make it durable:
1010
//
1111
// 1. It loads the LIVE installed kimaki module (not a copy), so a
12-
// kimaki upgrade that introduces new --worktree language fails the
13-
// next test run.
12+
// kimaki upgrade that introduces new --worktree or project-routing
13+
// language fails the next test run.
1414
// 2. It loads the LIVE plugin source from kimaki/plugins/, so a filter
1515
// change in this repo immediately reflows the snapshots.
1616
// 3. It writes named .txt snapshots to __snapshots__/, so reviewers
@@ -27,7 +27,8 @@
2727
// "broken-stripsection" (the regex-only stripSection that misfires
2828
// on fenced bash comments). The harness asserts the baseline
2929
// strips strictly LESS than the current filter.
30-
// - triggers: array of { name, pattern }. Default: worktree + --cwd.
30+
// - triggers: array of { name, pattern }. Default: worktree, --cwd,
31+
// --agent, and Kimaki project/channel routing language.
3132
// Lines matching any trigger in the filtered output count as leaks.
3233
// - allowLeakInSection: array of section headings where trigger
3334
// matches are intentional (e.g. the appended Minion Routing note
@@ -72,9 +73,16 @@ const VERBOSE = args.includes("--verbose")
7273
// ---------------------------------------------------------------------------
7374

7475
const DEFAULT_TRIGGERS = [
75-
{ name: "worktree", pattern: "(?i)worktree" },
76-
{ name: "--cwd", pattern: "--cwd" },
77-
{ name: "--agent", pattern: "--agent" },
76+
{ name: "worktree", pattern: "(?i)worktree" },
77+
{ name: "--cwd", pattern: "--cwd" },
78+
{ name: "--agent", pattern: "--agent" },
79+
{ name: "kimaki project", pattern: "kimaki project" },
80+
{ name: "--project", pattern: "--project" },
81+
{ name: "project channel", pattern: "(?i)project channel" },
82+
{ name: "cross-project", pattern: "(?i)cross-project" },
83+
{ name: "#project-name", pattern: "#project-name" },
84+
{ name: "other project", pattern: "(?i)other project" },
85+
{ name: "another project", pattern: "(?i)another project" },
7886
]
7987

8088
const DEFAULT_ALLOW_LEAK_SECTIONS = [

0 commit comments

Comments
 (0)