@vanillagreen/pi-claude-bridge 1.1.3 → 1.2.0
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/README.md +8 -1
- package/bundle/index.js +14934 -12019
- package/package.json +23 -6
- package/src/config.ts +3 -0
- package/src/index.ts +401 -11
- package/src/prompt-context.ts +45 -11
package/src/prompt-context.ts
CHANGED
|
@@ -76,8 +76,15 @@ function extractHeadingSection(systemPrompt: string | undefined, headings: strin
|
|
|
76
76
|
}
|
|
77
77
|
if (start < 0) return undefined;
|
|
78
78
|
const rest = systemPrompt.slice(start).trim();
|
|
79
|
-
const
|
|
80
|
-
|
|
79
|
+
const endCandidates = [
|
|
80
|
+
rest.slice(1).search(/\n##\s+/),
|
|
81
|
+
rest.search(/\n<\/project_instructions>/),
|
|
82
|
+
rest.search(/\n<\/project_context>/),
|
|
83
|
+
]
|
|
84
|
+
.map((index, offset) => (index >= 0 && offset === 0 ? index + 1 : index))
|
|
85
|
+
.filter((index) => index >= 0);
|
|
86
|
+
const end = endCandidates.length > 0 ? Math.min(...endCandidates) : -1;
|
|
87
|
+
return (end >= 0 ? rest.slice(0, end) : rest).trim();
|
|
81
88
|
}
|
|
82
89
|
|
|
83
90
|
function extractBlockByMarkers(systemPrompt: string | undefined, markers: RegExp[]): string | undefined {
|
|
@@ -93,7 +100,7 @@ export function buildPromptContextAppend(systemPrompt: string | undefined, cwd:
|
|
|
93
100
|
|
|
94
101
|
if (settings.includeAppendSystemPromptMd) {
|
|
95
102
|
for (const file of readAppendSystemPromptFiles(cwd)) {
|
|
96
|
-
parts.push(
|
|
103
|
+
parts.push(xmlBlock("append_system_prompt", { label: file.label }, file.content));
|
|
97
104
|
labels.push(file.label);
|
|
98
105
|
}
|
|
99
106
|
}
|
|
@@ -101,7 +108,7 @@ export function buildPromptContextAppend(systemPrompt: string | undefined, cwd:
|
|
|
101
108
|
if (settings.includeProjectAgentsHook) {
|
|
102
109
|
const projectAgents = extractHeadingSection(systemPrompt, ["## Project Agents", "## Project Subagents"]);
|
|
103
110
|
if (projectAgents) {
|
|
104
|
-
parts.push(
|
|
111
|
+
parts.push(xmlBlock("before_agent_start", { source: "project-agents" }, projectAgents));
|
|
105
112
|
labels.push("project agents hook");
|
|
106
113
|
}
|
|
107
114
|
}
|
|
@@ -109,7 +116,7 @@ export function buildPromptContextAppend(systemPrompt: string | undefined, cwd:
|
|
|
109
116
|
if (settings.includeTaskPanelHook) {
|
|
110
117
|
const taskReminder = extractBlockByMarkers(systemPrompt, [/^Task workflow reminder:/]);
|
|
111
118
|
if (taskReminder) {
|
|
112
|
-
parts.push(
|
|
119
|
+
parts.push(xmlBlock("before_agent_start", { source: "task-panel" }, taskReminder));
|
|
113
120
|
labels.push("task panel hook");
|
|
114
121
|
}
|
|
115
122
|
}
|
|
@@ -117,7 +124,7 @@ export function buildPromptContextAppend(systemPrompt: string | undefined, cwd:
|
|
|
117
124
|
if (settings.includeCavemanHook) {
|
|
118
125
|
const caveman = extractBlockByMarkers(systemPrompt, [/^You MUST respond in caveman /m]);
|
|
119
126
|
if (caveman) {
|
|
120
|
-
parts.push(
|
|
127
|
+
parts.push(xmlBlock("before_agent_start", { source: "caveman" }, caveman));
|
|
121
128
|
labels.push("caveman hook");
|
|
122
129
|
}
|
|
123
130
|
}
|
|
@@ -125,10 +132,37 @@ export function buildPromptContextAppend(systemPrompt: string | undefined, cwd:
|
|
|
125
132
|
if (parts.length === 0) return { labels };
|
|
126
133
|
return {
|
|
127
134
|
labels,
|
|
128
|
-
text:
|
|
129
|
-
"
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
135
|
+
text: xmlBlock(
|
|
136
|
+
"forwarded_pi_context",
|
|
137
|
+
{},
|
|
138
|
+
[
|
|
139
|
+
"The following content was explicitly enabled in pi-claude-bridge settings and comes from Pi prompt files or before_agent_start prompt hooks.",
|
|
140
|
+
...parts,
|
|
141
|
+
].join("\n\n"),
|
|
142
|
+
false,
|
|
143
|
+
),
|
|
133
144
|
};
|
|
134
145
|
}
|
|
146
|
+
|
|
147
|
+
function escapeXmlAttr(value: string): string {
|
|
148
|
+
return value
|
|
149
|
+
.replace(/&/g, "&")
|
|
150
|
+
.replace(/"/g, """)
|
|
151
|
+
.replace(/</g, "<")
|
|
152
|
+
.replace(/>/g, ">");
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function escapeXmlText(value: string): string {
|
|
156
|
+
return value
|
|
157
|
+
.replace(/&/g, "&")
|
|
158
|
+
.replace(/</g, "<")
|
|
159
|
+
.replace(/>/g, ">");
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function xmlBlock(tag: string, attrs: Record<string, string>, content: string, escapeContent = true): string {
|
|
163
|
+
const attrText = Object.entries(attrs)
|
|
164
|
+
.map(([key, value]) => ` ${key}="${escapeXmlAttr(value)}"`)
|
|
165
|
+
.join("");
|
|
166
|
+
const body = escapeContent ? escapeXmlText(content.trim()) : content.trim();
|
|
167
|
+
return `<${tag}${attrText}>\n${body}\n</${tag}>`;
|
|
168
|
+
}
|