Skip to content

Commit 07ee0b2

Browse files
authored
Fix effective prompt contract drift (#297)
1 parent c00bbe8 commit 07ee0b2

10 files changed

Lines changed: 59 additions & 1910 deletions

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

Lines changed: 9 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -36,32 +36,9 @@ Use the composed Data Machine AGENTS.md guidance for the coding runtime, workspa
3636
3737
## Bridge Diagnostics
3838
39-
For Kimaki bridge failures, inspect \`$HOME/.kimaki/kimaki.log\`. The log is reset every time Kimaki restarts, so it only covers the current run.
39+
For Kimaki bridge failures, inspect \$HOME/.kimaki/kimaki.log. The log is reset every time Kimaki restarts, so it only covers the current run.
4040
`;
4141

42-
const KIMAKI_GENERIC_SECTION_HEADINGS = [
43-
"## permissions",
44-
"## upgrading kimaki",
45-
"## debugging kimaki issues",
46-
"## uploading files to discord",
47-
"## requesting files from the user",
48-
"## archiving the current thread",
49-
"## aborting a session",
50-
"## discord user mentions",
51-
"## starting new sessions from CLI",
52-
"## running opencode commands via kimaki send",
53-
"## switching agents in the current session",
54-
"## scheduled sends and task management",
55-
"## reading other sessions",
56-
"## cross-project commands",
57-
"## waiting for a session to finish",
58-
"## creating worktrees",
59-
"## generating audio from text",
60-
"## running dev servers with tunnel access",
61-
"## markdown formatting",
62-
"## Callouts in Kimaki Discord",
63-
];
64-
6542
const fleetContextFilter: Plugin = async () => {
6643
return {
6744
// Replace Kimaki's generic CLI/orchestration prompt with managed guidance.
@@ -122,85 +99,23 @@ const fleetContextFilter: Plugin = async () => {
12299
};
123100
};
124101

125-
/**
126-
* Identify Kimaki's generated system prompt without matching composed AGENTS.md
127-
* or other OpenCode system blocks from the managed install.
128-
*
129-
* @param {string} block - System prompt block.
130-
* @return {boolean} Whether this block is Kimaki's generated bridge prompt.
131-
*/
132-
function isKimakiSystemPrompt(block: string): boolean {
133-
return (
134-
block.includes("The user is reading your messages from inside Discord, via kimaki.dev") ||
135-
block.includes("## debugging kimaki issues") ||
136-
block.includes("## uploading files to discord") ||
137-
block.includes("Your current OpenCode session ID is:")
138-
);
139-
}
140-
102+
// Replace only positively identified Kimaki prompt text. Both transforms use
103+
// this helper because message transforms also receive unrelated text.
141104
function replaceKimakiSystemPrompt(block: string): string {
142-
const filteredBlock = stripKimakiGenericSections(block);
143-
const kimakiStart = kimakiSystemPromptStart(filteredBlock);
105+
const kimakiStart = kimakiSystemPromptStart(block);
144106
if (kimakiStart === -1) {
145-
return filteredBlock;
146-
}
147-
148-
const prefix = filteredBlock.slice(0, kimakiStart).trimEnd();
149-
return [prefix, MANAGED_KIMAKI_SYSTEM_PROMPT].filter(Boolean).join("\n\n");
150-
}
151-
152-
function stripKimakiGenericSections(block: string): string {
153-
let result = block;
154-
for (const heading of KIMAKI_GENERIC_SECTION_HEADINGS) {
155-
result = stripMarkdownSection(result, heading);
156-
}
157-
return result.replace(/\n{3,}/g, "\n\n").trimEnd();
158-
}
159-
160-
function stripMarkdownSection(block: string, heading: string): string {
161-
const lines = block.split("\n");
162-
const level = headingLevel(heading);
163-
let start = -1;
164-
let inFence = false;
165-
166-
for (let i = 0; i < lines.length; i++) {
167-
if (/^```/.test(lines[i])) {
168-
inFence = !inFence;
169-
continue;
170-
}
171-
if (!inFence && lines[i] === heading) {
172-
start = i;
173-
break;
174-
}
175-
}
176-
177-
if (start === -1) {
178107
return block;
179108
}
180109

181-
let end = lines.length;
182-
inFence = false;
183-
for (let i = start + 1; i < lines.length; i++) {
184-
if (/^```/.test(lines[i])) {
185-
inFence = !inFence;
186-
continue;
187-
}
188-
const match = !inFence ? lines[i].match(/^(#{1,6})\s+\S/) : null;
189-
if (match && match[1].length <= level) {
190-
end = i;
191-
break;
192-
}
193-
}
194-
195-
return [...lines.slice(0, start), ...lines.slice(end)].join("\n");
196-
}
197-
198-
function headingLevel(heading: string): number {
199-
return heading.match(/^#+/)?.[0].length ?? 2;
110+
// Only replace a positively identified Kimaki prompt. Message transforms
111+
// also see ordinary user and composed AGENTS.md text.
112+
const prefix = block.slice(0, kimakiStart).trimEnd();
113+
return [prefix, MANAGED_KIMAKI_SYSTEM_PROMPT].filter(Boolean).join("\n\n");
200114
}
201115

202116
function kimakiSystemPromptStart(block: string): number {
203117
const markers = [
118+
"## Kimaki Discord Bridge",
204119
"The user is reading your messages from inside Discord, via kimaki.dev",
205120
"Your current OpenCode session ID is:",
206121
"## debugging kimaki issues",

bridges/kimaki/post-upgrade.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ const fs = require('node:fs')
184184
185185
const file = process.env.SYSTEM_MESSAGE_FILE
186186
const marker = 'wp-coding-agents managed Kimaki system prompt patch'
187+
const literalDollar = '$'
187188
const source = fs.readFileSync(file, 'utf8')
188189
189190
if (source.includes(marker)) {
@@ -203,7 +204,7 @@ Use the composed Data Machine AGENTS.md guidance for the coding runtime, workspa
203204
204205
## Bridge Diagnostics
205206
206-
For Kimaki bridge failures, inspect $HOME/.kimaki/kimaki.log. The log is reset every time Kimaki restarts, so it only covers the current run.
207+
For Kimaki bridge failures, inspect \\${literalDollar}HOME/.kimaki/kimaki.log. The log is reset every time Kimaki restarts, so it only covers the current run.
207208
\`;
208209
`
209210

0 commit comments

Comments
 (0)