u-foo 2.1.0 → 2.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/package.json +1 -1
- package/src/agent/defaultBootstrap.js +128 -5
package/package.json
CHANGED
|
@@ -26,6 +26,16 @@ function hasMetaCommandArgs(args = []) {
|
|
|
26
26
|
return hasArg(args, ["-h", "--help", "-v", "--version"]);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
function readOptionalFile(filePath) {
|
|
30
|
+
const target = asTrimmedString(filePath);
|
|
31
|
+
if (!target) return "";
|
|
32
|
+
try {
|
|
33
|
+
return fs.readFileSync(target, "utf8");
|
|
34
|
+
} catch {
|
|
35
|
+
return "";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
29
39
|
/**
|
|
30
40
|
* Load the team activity timeline for prompt injection.
|
|
31
41
|
* The daemon syncs manual inputs every ~30s; bus messages are appended in real-time.
|
|
@@ -67,6 +77,11 @@ function defaultBootstrapFile(projectRoot, agentType = "") {
|
|
|
67
77
|
return path.join(getUfooPaths(projectRoot).agentDir, safeAgentType, "default-bootstrap.md");
|
|
68
78
|
}
|
|
69
79
|
|
|
80
|
+
function mergedBootstrapFile(projectRoot, agentType = "") {
|
|
81
|
+
const safeAgentType = asTrimmedString(agentType).replace(/[^a-zA-Z0-9._-]/g, "-") || "agent";
|
|
82
|
+
return path.join(getUfooPaths(projectRoot).agentDir, safeAgentType, "merged-bootstrap.md");
|
|
83
|
+
}
|
|
84
|
+
|
|
70
85
|
function prepareDefaultBootstrapFile({
|
|
71
86
|
projectRoot,
|
|
72
87
|
agentType = "",
|
|
@@ -80,6 +95,83 @@ function prepareDefaultBootstrapFile({
|
|
|
80
95
|
return { ok: true, file };
|
|
81
96
|
}
|
|
82
97
|
|
|
98
|
+
function mergePromptSegments(...segments) {
|
|
99
|
+
return segments
|
|
100
|
+
.map((item) => String(item || "").trim())
|
|
101
|
+
.filter(Boolean)
|
|
102
|
+
.join("\n\n");
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function mergeClaudePromptArgs({
|
|
106
|
+
projectRoot,
|
|
107
|
+
agentType = "claude-code",
|
|
108
|
+
args = [],
|
|
109
|
+
bootstrapText = "",
|
|
110
|
+
} = {}) {
|
|
111
|
+
const currentArgs = Array.isArray(args) ? args.slice() : [];
|
|
112
|
+
for (let index = 0; index < currentArgs.length; index += 1) {
|
|
113
|
+
const item = asTrimmedString(currentArgs[index]);
|
|
114
|
+
if (!item) continue;
|
|
115
|
+
|
|
116
|
+
if (item === "--append-system-prompt") {
|
|
117
|
+
const existingFile = asTrimmedString(currentArgs[index + 1]);
|
|
118
|
+
const mergedText = mergePromptSegments(readOptionalFile(existingFile), bootstrapText);
|
|
119
|
+
const prepared = prepareDefaultBootstrapFile({
|
|
120
|
+
projectRoot,
|
|
121
|
+
agentType,
|
|
122
|
+
targetFile: mergedBootstrapFile(projectRoot, agentType),
|
|
123
|
+
promptText: mergedText,
|
|
124
|
+
});
|
|
125
|
+
currentArgs[index + 1] = prepared.file;
|
|
126
|
+
return { args: currentArgs, file: prepared.file, promptText: mergedText };
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (item.startsWith("--append-system-prompt=")) {
|
|
130
|
+
const existingFile = item.slice("--append-system-prompt=".length);
|
|
131
|
+
const mergedText = mergePromptSegments(readOptionalFile(existingFile), bootstrapText);
|
|
132
|
+
const prepared = prepareDefaultBootstrapFile({
|
|
133
|
+
projectRoot,
|
|
134
|
+
agentType,
|
|
135
|
+
targetFile: mergedBootstrapFile(projectRoot, agentType),
|
|
136
|
+
promptText: mergedText,
|
|
137
|
+
});
|
|
138
|
+
currentArgs[index] = `--append-system-prompt=${prepared.file}`;
|
|
139
|
+
return { args: currentArgs, file: prepared.file, promptText: mergedText };
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (item === "--system-prompt") {
|
|
143
|
+
const existingPrompt = String(currentArgs[index + 1] || "");
|
|
144
|
+
currentArgs[index + 1] = mergePromptSegments(existingPrompt, bootstrapText);
|
|
145
|
+
return { args: currentArgs, file: "", promptText: String(currentArgs[index + 1] || "") };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (item.startsWith("--system-prompt=")) {
|
|
149
|
+
const existingPrompt = item.slice("--system-prompt=".length);
|
|
150
|
+
const mergedText = mergePromptSegments(existingPrompt, bootstrapText);
|
|
151
|
+
currentArgs[index] = `--system-prompt=${mergedText}`;
|
|
152
|
+
return { args: currentArgs, file: "", promptText: mergedText };
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function mergeCodexPromptArgs({ args = [], bootstrapText = "" } = {}) {
|
|
159
|
+
const currentArgs = Array.isArray(args) ? args.slice() : [];
|
|
160
|
+
const lastIndex = currentArgs.length - 1;
|
|
161
|
+
if (lastIndex < 0) return null;
|
|
162
|
+
const lastItem = asTrimmedString(currentArgs[lastIndex]);
|
|
163
|
+
const promptIndex = lastItem && !lastItem.startsWith("-") ? lastIndex : -1;
|
|
164
|
+
|
|
165
|
+
if (promptIndex < 0) return null;
|
|
166
|
+
|
|
167
|
+
currentArgs[promptIndex] = mergePromptSegments(bootstrapText, currentArgs[promptIndex]);
|
|
168
|
+
return {
|
|
169
|
+
args: currentArgs,
|
|
170
|
+
promptText: String(currentArgs[promptIndex] || ""),
|
|
171
|
+
promptIndex,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
83
175
|
function resolveDefaultManualBootstrap({
|
|
84
176
|
projectRoot,
|
|
85
177
|
agentType = "",
|
|
@@ -98,10 +190,22 @@ function resolveDefaultManualBootstrap({
|
|
|
98
190
|
}
|
|
99
191
|
|
|
100
192
|
if (normalizedAgent === "claude-code") {
|
|
101
|
-
if (hasArg(currentArgs, ["--append-system-prompt", "--system-prompt"])) {
|
|
102
|
-
return { args: currentArgs, env: {}, mode: "skip" };
|
|
103
|
-
}
|
|
104
193
|
const promptText = buildDefaultStartupBootstrapPrompt({ agentType: normalizedAgent, projectRoot });
|
|
194
|
+
const merged = mergeClaudePromptArgs({
|
|
195
|
+
projectRoot,
|
|
196
|
+
agentType: normalizedAgent,
|
|
197
|
+
args: currentArgs,
|
|
198
|
+
bootstrapText: promptText,
|
|
199
|
+
});
|
|
200
|
+
if (merged) {
|
|
201
|
+
return {
|
|
202
|
+
args: merged.args,
|
|
203
|
+
env: {},
|
|
204
|
+
mode: "merged-system-prompt",
|
|
205
|
+
file: merged.file,
|
|
206
|
+
promptText: merged.promptText,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
105
209
|
const prepared = prepareDefaultBootstrapFile({
|
|
106
210
|
projectRoot,
|
|
107
211
|
agentType: normalizedAgent,
|
|
@@ -117,10 +221,29 @@ function resolveDefaultManualBootstrap({
|
|
|
117
221
|
}
|
|
118
222
|
|
|
119
223
|
if (normalizedAgent === "codex") {
|
|
224
|
+
const promptText = buildDefaultStartupBootstrapPrompt({ agentType: normalizedAgent, projectRoot });
|
|
225
|
+
const merged = mergeCodexPromptArgs({
|
|
226
|
+
args: currentArgs,
|
|
227
|
+
bootstrapText: promptText,
|
|
228
|
+
});
|
|
229
|
+
if (merged) {
|
|
230
|
+
return {
|
|
231
|
+
args: merged.args,
|
|
232
|
+
env: {},
|
|
233
|
+
mode: "initial-prompt-arg",
|
|
234
|
+
promptText: merged.promptText,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
120
237
|
if (currentArgs.length > 0) {
|
|
121
|
-
return {
|
|
238
|
+
return {
|
|
239
|
+
args: currentArgs,
|
|
240
|
+
env: {
|
|
241
|
+
UFOO_STARTUP_BOOTSTRAP_TEXT: promptText,
|
|
242
|
+
},
|
|
243
|
+
mode: "post-launch-inject",
|
|
244
|
+
promptText,
|
|
245
|
+
};
|
|
122
246
|
}
|
|
123
|
-
const promptText = buildDefaultStartupBootstrapPrompt({ agentType: normalizedAgent, projectRoot });
|
|
124
247
|
return {
|
|
125
248
|
args: currentArgs,
|
|
126
249
|
env: {
|