sparkecoder 0.1.124 → 0.1.125
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/dist/agent/index.d.ts +3 -3
- package/dist/agent/index.js +145 -71
- package/dist/agent/index.js.map +1 -1
- package/dist/cli.js +188 -89
- package/dist/cli.js.map +1 -1
- package/dist/db/index.d.ts +2 -2
- package/dist/{index-Bcz0aCAR.d.ts → index-DczYH89U.d.ts} +104 -104
- package/dist/index.d.ts +5 -5
- package/dist/index.js +188 -89
- package/dist/index.js.map +1 -1
- package/dist/{schema-BWbWmfDQ.d.ts → schema-DxrKyetI.d.ts} +3 -3
- package/dist/{search-DOzC4ojH.d.ts → search-CVVfuBPZ.d.ts} +4 -4
- package/dist/server/index.js +188 -89
- package/dist/server/index.js.map +1 -1
- package/dist/skills/default/memory.md +49 -0
- package/dist/skills/default/skill-authoring.md +96 -0
- package/dist/tools/index.d.ts +3 -3
- package/dist/tools/index.js +12 -4
- package/dist/tools/index.js.map +1 -1
- package/package.json +1 -1
- package/src/skills/default/memory.md +49 -0
- package/src/skills/default/skill-authoring.md +96 -0
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/web/.next/build-manifest.json +2 -2
- package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
- package/web/.next/standalone/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/standalone/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.html +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.html +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/installation.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.html +1 -1
- package/web/.next/standalone/web/.next/server/app/index.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.html +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/pages/404.html +1 -1
- package/web/.next/standalone/web/.next/server/pages/500.html +2 -2
- package/web/.next/standalone/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/server-reference-manifest.json +1 -1
- /package/web/.next/standalone/web/.next/static/{cYXZ7UzGc5TttFIXRRcSC → qtMOCCjmqN22PUb49g4j-}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{cYXZ7UzGc5TttFIXRRcSC → qtMOCCjmqN22PUb49g4j-}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/{cYXZ7UzGc5TttFIXRRcSC → qtMOCCjmqN22PUb49g4j-}/_ssgManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/static/{cYXZ7UzGc5TttFIXRRcSC → qtMOCCjmqN22PUb49g4j-}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/static/{cYXZ7UzGc5TttFIXRRcSC → qtMOCCjmqN22PUb49g4j-}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/static/{cYXZ7UzGc5TttFIXRRcSC → qtMOCCjmqN22PUb49g4j-}/_ssgManifest.js +0 -0
- /package/web/.next/static/{cYXZ7UzGc5TttFIXRRcSC → qtMOCCjmqN22PUb49g4j-}/_buildManifest.js +0 -0
- /package/web/.next/static/{cYXZ7UzGc5TttFIXRRcSC → qtMOCCjmqN22PUb49g4j-}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{cYXZ7UzGc5TttFIXRRcSC → qtMOCCjmqN22PUb49g4j-}/_ssgManifest.js +0 -0
package/dist/agent/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import 'ai';
|
|
2
|
-
import '../schema-
|
|
3
|
-
export { A as Agent, a as AgentOptions, b as AgentRunOptions, c as AgentStreamResult, C as ContextManager, M as MessageAttachment, d as buildSystemPrompt, e as buildTaskPromptAddendum } from '../index-
|
|
4
|
-
import '../search-
|
|
2
|
+
import '../schema-DxrKyetI.js';
|
|
3
|
+
export { A as Agent, a as AgentOptions, b as AgentRunOptions, c as AgentStreamResult, C as ContextManager, M as MessageAttachment, d as buildSystemPrompt, e as buildTaskPromptAddendum } from '../index-DczYH89U.js';
|
|
4
|
+
import '../search-CVVfuBPZ.js';
|
|
5
5
|
import 'drizzle-orm/sqlite-core';
|
|
6
6
|
import 'zod';
|
package/dist/agent/index.js
CHANGED
|
@@ -32,7 +32,10 @@ var init_types = __esm({
|
|
|
32
32
|
// not listed here. Values match `process.platform`
|
|
33
33
|
// (darwin, linux, win32, freebsd, ...). If omitted or empty, the skill is
|
|
34
34
|
// available on all platforms.
|
|
35
|
-
platforms: z.array(z.string()).optional().default([])
|
|
35
|
+
platforms: z.array(z.string()).optional().default([]),
|
|
36
|
+
// Optional approximate token budget for always-loaded content. If set,
|
|
37
|
+
// the prompt builder truncates this skill/rule before injecting it.
|
|
38
|
+
contextBudgetTokens: z.number().int().positive().optional()
|
|
36
39
|
});
|
|
37
40
|
TaskConfigSchema = z.object({
|
|
38
41
|
enabled: z.boolean(),
|
|
@@ -958,6 +961,8 @@ function parseSkillFrontmatter(content) {
|
|
|
958
961
|
data[key2] = true;
|
|
959
962
|
} else if (value === "false") {
|
|
960
963
|
data[key2] = false;
|
|
964
|
+
} else if (/^\d+$/.test(value)) {
|
|
965
|
+
data[key2] = Number(value);
|
|
961
966
|
} else {
|
|
962
967
|
data[key2] = value;
|
|
963
968
|
}
|
|
@@ -1017,7 +1022,8 @@ async function loadSkillsFromDirectory(directory, options = {}) {
|
|
|
1017
1022
|
loadType,
|
|
1018
1023
|
priority,
|
|
1019
1024
|
sourceDir: directory,
|
|
1020
|
-
platforms: parsed.metadata.platforms
|
|
1025
|
+
platforms: parsed.metadata.platforms,
|
|
1026
|
+
contextBudgetTokens: parsed.metadata.contextBudgetTokens
|
|
1021
1027
|
});
|
|
1022
1028
|
} else {
|
|
1023
1029
|
const name = getSkillNameFromPath(filePath);
|
|
@@ -1031,7 +1037,8 @@ async function loadSkillsFromDirectory(directory, options = {}) {
|
|
|
1031
1037
|
loadType: forceAlwaysApply ? "always" : defaultLoadType,
|
|
1032
1038
|
priority,
|
|
1033
1039
|
sourceDir: directory,
|
|
1034
|
-
platforms: []
|
|
1040
|
+
platforms: [],
|
|
1041
|
+
contextBudgetTokens: void 0
|
|
1035
1042
|
});
|
|
1036
1043
|
}
|
|
1037
1044
|
}
|
|
@@ -1161,11 +1168,12 @@ function formatSkillsForContext(skills) {
|
|
|
1161
1168
|
if (onDemandSkills.length === 0) {
|
|
1162
1169
|
return "No on-demand skills available.";
|
|
1163
1170
|
}
|
|
1164
|
-
const lines = ["
|
|
1171
|
+
const lines = ["<available_skills>", "Use the load_skill tool to load one of these into context:"];
|
|
1165
1172
|
for (const skill of onDemandSkills) {
|
|
1166
1173
|
const globInfo = skill.globs?.length ? ` [auto-loads for: ${skill.globs.join(", ")}]` : "";
|
|
1167
1174
|
lines.push(`- ${skill.name}: ${skill.description}${globInfo}`);
|
|
1168
1175
|
}
|
|
1176
|
+
lines.push("</available_skills>");
|
|
1169
1177
|
return lines.join("\n");
|
|
1170
1178
|
}
|
|
1171
1179
|
function formatAlwaysLoadedSkills(skills) {
|
|
@@ -1174,13 +1182,22 @@ function formatAlwaysLoadedSkills(skills) {
|
|
|
1174
1182
|
}
|
|
1175
1183
|
const sections = [];
|
|
1176
1184
|
for (const skill of skills) {
|
|
1177
|
-
sections.push(
|
|
1178
|
-
|
|
1179
|
-
|
|
1185
|
+
sections.push(`<skill name="${escapeXmlAttribute(skill.name)}">
|
|
1186
|
+
${truncateSkillContent(skill)}
|
|
1187
|
+
</skill>`);
|
|
1180
1188
|
}
|
|
1181
|
-
return
|
|
1189
|
+
return `<always_loaded_rules_and_skills>
|
|
1190
|
+
${sections.join("\n\n")}
|
|
1191
|
+
</always_loaded_rules_and_skills>`;
|
|
1192
|
+
}
|
|
1193
|
+
function truncateSkillContent(skill) {
|
|
1194
|
+
if (!skill.contextBudgetTokens) return skill.content;
|
|
1195
|
+
const maxChars = Math.max(200, skill.contextBudgetTokens * 4);
|
|
1196
|
+
if (skill.content.length <= maxChars) return skill.content;
|
|
1197
|
+
const omitted = skill.content.length - maxChars;
|
|
1198
|
+
return `${skill.content.slice(0, maxChars).trimEnd()}
|
|
1182
1199
|
|
|
1183
|
-
${
|
|
1200
|
+
... [${skill.name} truncated by contextBudgetTokens=${skill.contextBudgetTokens}; ${omitted} chars omitted. Read ${skill.filePath} for the full file.]`;
|
|
1184
1201
|
}
|
|
1185
1202
|
function formatGlobMatchedSkills(skills) {
|
|
1186
1203
|
if (skills.length === 0) {
|
|
@@ -1188,21 +1205,24 @@ function formatGlobMatchedSkills(skills) {
|
|
|
1188
1205
|
}
|
|
1189
1206
|
const sections = [];
|
|
1190
1207
|
for (const skill of skills) {
|
|
1191
|
-
sections.push(
|
|
1192
|
-
|
|
1193
|
-
|
|
1208
|
+
sections.push(`<skill name="${escapeXmlAttribute(skill.name)}">
|
|
1209
|
+
${skill.content}
|
|
1210
|
+
</skill>`);
|
|
1194
1211
|
}
|
|
1195
|
-
return
|
|
1196
|
-
|
|
1197
|
-
|
|
1212
|
+
return `<glob_matched_skills>
|
|
1213
|
+
${sections.join("\n\n")}
|
|
1214
|
+
</glob_matched_skills>`;
|
|
1198
1215
|
}
|
|
1199
1216
|
function formatAgentsMdContent(content) {
|
|
1200
1217
|
if (!content) {
|
|
1201
1218
|
return "";
|
|
1202
1219
|
}
|
|
1203
|
-
return
|
|
1204
|
-
|
|
1205
|
-
|
|
1220
|
+
return `<project_instructions source="AGENTS.md">
|
|
1221
|
+
${content}
|
|
1222
|
+
</project_instructions>`;
|
|
1223
|
+
}
|
|
1224
|
+
function escapeXmlAttribute(value) {
|
|
1225
|
+
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
1206
1226
|
}
|
|
1207
1227
|
var init_skills = __esm({
|
|
1208
1228
|
"src/skills/index.ts"() {
|
|
@@ -6021,14 +6041,18 @@ async function buildSystemPrompt(options) {
|
|
|
6021
6041
|
const platform2 = process.platform === "win32" ? "Windows" : process.platform === "darwin" ? "macOS" : "Linux";
|
|
6022
6042
|
const currentDate = (/* @__PURE__ */ new Date()).toLocaleDateString("en-US", { weekday: "long", year: "numeric", month: "long", day: "numeric" });
|
|
6023
6043
|
const searchInstructions = getSearchInstructions();
|
|
6024
|
-
const systemPrompt =
|
|
6044
|
+
const systemPrompt = `<system_prompt>
|
|
6045
|
+
<identity>
|
|
6046
|
+
You are SparkECoder, an expert AI coding assistant. You help developers write, debug, and improve code.
|
|
6047
|
+
</identity>
|
|
6025
6048
|
|
|
6026
|
-
|
|
6049
|
+
<environment>
|
|
6027
6050
|
- **Platform**: ${platform2} (${os.release()})
|
|
6028
6051
|
- **Date**: ${currentDate}
|
|
6029
6052
|
- **Working Directory**: ${workingDirectory}
|
|
6053
|
+
</environment>
|
|
6030
6054
|
|
|
6031
|
-
|
|
6055
|
+
<core_capabilities>
|
|
6032
6056
|
You have access to powerful tools for:
|
|
6033
6057
|
- **bash**: Execute commands in the terminal (see below for details)
|
|
6034
6058
|
- **read_file**: Read file contents to understand code and context
|
|
@@ -6042,8 +6066,9 @@ You have access to powerful tools for:
|
|
|
6042
6066
|
|
|
6043
6067
|
|
|
6044
6068
|
IMPORTANT: If you have zero context of where you are working, always explore it first to understand the structure before doing things for the user.
|
|
6069
|
+
</core_capabilities>
|
|
6045
6070
|
|
|
6046
|
-
|
|
6071
|
+
<planning_and_task_management>
|
|
6047
6072
|
Use the **todo tool** to manage both immediate tasks AND persistent plans:
|
|
6048
6073
|
|
|
6049
6074
|
**For simple tasks (< 5 steps):** Just use regular todos (add/mark/clear).
|
|
@@ -6063,8 +6088,9 @@ Use the **todo tool** to manage both immediate tasks AND persistent plans:
|
|
|
6063
6088
|
- Only top-level checklist items (- [ ]) become todos \u2014 indented sub-items are part of the task detail
|
|
6064
6089
|
- Sections named Overview, Notes, Key Decisions, etc. are not treated as phases
|
|
6065
6090
|
- You can clear the todo list and restart it, and do multiple things inside of one session
|
|
6091
|
+
</planning_and_task_management>
|
|
6066
6092
|
|
|
6067
|
-
|
|
6093
|
+
<bash_tool>
|
|
6068
6094
|
The bash tool runs commands in the terminal. Every command runs in its own session with logs saved to disk.
|
|
6069
6095
|
|
|
6070
6096
|
**Run a command (default - waits for completion):**
|
|
@@ -6111,22 +6137,25 @@ bash({ id: "abc123", input: "my text" }) // send text input
|
|
|
6111
6137
|
- Use \`input: "text"\` for text input prompts
|
|
6112
6138
|
|
|
6113
6139
|
Terminal output is stored in the global SparkECoder data directory. Use the \`tail\` option to read recent output.
|
|
6140
|
+
</bash_tool>
|
|
6114
6141
|
|
|
6115
|
-
|
|
6142
|
+
<guidelines>
|
|
6116
6143
|
|
|
6117
|
-
|
|
6144
|
+
<code_quality>
|
|
6118
6145
|
- Write clean, maintainable, well-documented code
|
|
6119
6146
|
- Follow existing code style and conventions in the project
|
|
6120
6147
|
- Use meaningful variable and function names
|
|
6121
6148
|
- Add comments for complex logic
|
|
6149
|
+
</code_quality>
|
|
6122
6150
|
|
|
6123
|
-
|
|
6151
|
+
<problem_solving>
|
|
6124
6152
|
- Before making changes, understand the existing code structure
|
|
6125
6153
|
- Break complex tasks into smaller, manageable steps using the todo tool
|
|
6126
6154
|
- Test changes when possible using the bash tool
|
|
6127
6155
|
- Handle errors gracefully and provide helpful error messages
|
|
6156
|
+
</problem_solving>
|
|
6128
6157
|
|
|
6129
|
-
|
|
6158
|
+
<file_operations>
|
|
6130
6159
|
- Use \`read_file\` to understand code before modifying
|
|
6131
6160
|
- Use \`write_file\` with mode "str_replace" for targeted edits to existing files
|
|
6132
6161
|
- Use \`write_file\` with mode "full" only for new files or complete rewrites
|
|
@@ -6135,8 +6164,9 @@ Terminal output is stored in the global SparkECoder data directory. Use the \`ta
|
|
|
6135
6164
|
- If the user asks to write/create a file, always use \`write_file\` rather than printing the full contents
|
|
6136
6165
|
- If the user requests a file but does not provide a path, choose a sensible default (e.g. \`index.html\`) and proceed
|
|
6137
6166
|
- For large content (hundreds of lines), avoid placing it in chat output; write to a file instead
|
|
6167
|
+
</file_operations>
|
|
6138
6168
|
|
|
6139
|
-
|
|
6169
|
+
<linter_tool>
|
|
6140
6170
|
The linter tool uses Language Server Protocol (LSP) to detect type errors and lint issues:
|
|
6141
6171
|
\`\`\`
|
|
6142
6172
|
linter({}) // Check all recently edited files
|
|
@@ -6144,8 +6174,9 @@ linter({ paths: ["src/app.ts"] }) // Check specific files
|
|
|
6144
6174
|
linter({ paths: ["src/"] }) // Check all files in a directory
|
|
6145
6175
|
\`\`\`
|
|
6146
6176
|
Use this proactively after making code changes to catch errors early.
|
|
6177
|
+
</linter_tool>
|
|
6147
6178
|
|
|
6148
|
-
|
|
6179
|
+
<code_graph_tool>
|
|
6149
6180
|
The code_graph tool uses the TypeScript language server to inspect a symbol's type hierarchy and usage graph:
|
|
6150
6181
|
\`\`\`
|
|
6151
6182
|
code_graph({ symbol: "UserCard" }) // Search workspace for symbol
|
|
@@ -6171,8 +6202,9 @@ code_graph({ symbol: "formatUser", filePath: "utils.ts", depth: 2 }) // Travers
|
|
|
6171
6202
|
- For exploratory "how does X work?" questions \u2014 use \`explore_agent\` instead
|
|
6172
6203
|
- For exact string searches \u2014 use grep/rg directly
|
|
6173
6204
|
- For non-TypeScript/JavaScript files \u2014 code_graph only supports TS/JS/TSX/JSX
|
|
6205
|
+
</code_graph_tool>
|
|
6174
6206
|
|
|
6175
|
-
|
|
6207
|
+
<searching_and_exploration>
|
|
6176
6208
|
|
|
6177
6209
|
**Choose the right search approach:**
|
|
6178
6210
|
|
|
@@ -6223,8 +6255,9 @@ code_graph({ symbol: "formatUser", filePath: "utils.ts", depth: 2 }) // Travers
|
|
|
6223
6255
|
- "Find files named config" \u2192 Use \`find . -name "*config*"\`
|
|
6224
6256
|
|
|
6225
6257
|
${searchInstructions}
|
|
6258
|
+
</searching_and_exploration>
|
|
6226
6259
|
|
|
6227
|
-
|
|
6260
|
+
<software_design_principles>
|
|
6228
6261
|
|
|
6229
6262
|
1. **Modularity** \u2014 Write simple parts connected by clean interfaces
|
|
6230
6263
|
2. **Clarity** \u2014 Clarity is better than cleverness
|
|
@@ -6243,8 +6276,9 @@ ${searchInstructions}
|
|
|
6243
6276
|
15. **Optimization** \u2014 Prototype before polishing. Get it working before you optimize it
|
|
6244
6277
|
16. **Diversity** \u2014 Distrust all claims for "one true way"
|
|
6245
6278
|
17. **Extensibility** \u2014 Design for the future, because it will be here sooner than you think
|
|
6279
|
+
</software_design_principles>
|
|
6246
6280
|
|
|
6247
|
-
|
|
6281
|
+
<ui_design_principles>
|
|
6248
6282
|
|
|
6249
6283
|
1. **Simplicity** \u2014 Simplicity is the ultimate sophistication. Remove everything unnecessary.
|
|
6250
6284
|
2. **Focus** \u2014 Say no to 1,000 things to say yes to the few that matter most.
|
|
@@ -6256,8 +6290,9 @@ ${searchInstructions}
|
|
|
6256
6290
|
8. **Feedback** \u2014 Every action deserves a response. Make interactions feel alive.
|
|
6257
6291
|
9. **Forgiveness** \u2014 Make it easy to undo. Never punish exploration.
|
|
6258
6292
|
10. **Beauty** \u2014 Aesthetics are not superficial. Beautiful things work better because people care about them.
|
|
6293
|
+
</ui_design_principles>
|
|
6259
6294
|
|
|
6260
|
-
|
|
6295
|
+
<agent_behavior_rules>
|
|
6261
6296
|
|
|
6262
6297
|
1. Understand first - Read relevant files before making any changes. Use the \`explore_agent\` tool for exploratory questions about how things work, and direct searches (grep/rg) for finding exact strings or file names.
|
|
6263
6298
|
2. Plan for complexity - If the task involves 3+ steps or has meaningful trade-offs, create a todo list to track progress before implementing.
|
|
@@ -6266,13 +6301,16 @@ ${searchInstructions}
|
|
|
6266
6301
|
5. Be direct - Focus on technical accuracy rather than validation. If see issues with an approach or need clarification, say so.
|
|
6267
6302
|
6. Verify my work - After making changes, check for linter errors and fix any introduced.
|
|
6268
6303
|
7. Respect boundaries - Only commit code when explicitly asked, avoid creating unnecessary files, and don't make assumptions about things uncertain about.
|
|
6304
|
+
</agent_behavior_rules>
|
|
6269
6305
|
|
|
6270
6306
|
|
|
6271
|
-
|
|
6307
|
+
<communication>
|
|
6272
6308
|
- Explain your reasoning and approach
|
|
6273
6309
|
- Be concise but thorough
|
|
6274
6310
|
- Ask clarifying questions when requirements are ambiguous
|
|
6275
6311
|
- Report progress on multi-step tasks
|
|
6312
|
+
</communication>
|
|
6313
|
+
</guidelines>
|
|
6276
6314
|
|
|
6277
6315
|
${agentsMdContent}
|
|
6278
6316
|
|
|
@@ -6280,18 +6318,24 @@ ${alwaysLoadedContent}
|
|
|
6280
6318
|
|
|
6281
6319
|
${globMatchedContent}
|
|
6282
6320
|
|
|
6283
|
-
|
|
6321
|
+
<on_demand_skills>
|
|
6284
6322
|
${onDemandSkillsContext}
|
|
6323
|
+
</on_demand_skills>
|
|
6285
6324
|
|
|
6286
|
-
|
|
6325
|
+
<current_task_list>
|
|
6287
6326
|
${todosContext}
|
|
6327
|
+
</current_task_list>
|
|
6288
6328
|
|
|
6289
6329
|
${plansContext}
|
|
6290
6330
|
|
|
6291
|
-
${customInstructions ?
|
|
6292
|
-
${customInstructions}
|
|
6331
|
+
${customInstructions ? `<custom_instructions>
|
|
6332
|
+
${customInstructions}
|
|
6333
|
+
</custom_instructions>` : ""}
|
|
6293
6334
|
|
|
6294
|
-
|
|
6335
|
+
<final_reminder>
|
|
6336
|
+
Remember: You are a helpful, capable coding assistant. Take initiative, be thorough, and deliver high-quality results.
|
|
6337
|
+
</final_reminder>
|
|
6338
|
+
</system_prompt>`;
|
|
6295
6339
|
return systemPrompt;
|
|
6296
6340
|
}
|
|
6297
6341
|
function formatTodosForContext(todos) {
|
|
@@ -6317,7 +6361,7 @@ function formatPlansForContext(plans, shouldContinue) {
|
|
|
6317
6361
|
if (plans.length === 0) return "";
|
|
6318
6362
|
let totalChars = 0;
|
|
6319
6363
|
const sections = [];
|
|
6320
|
-
sections.push(
|
|
6364
|
+
sections.push(`<persistent_plans count="${plans.length}">`);
|
|
6321
6365
|
sections.push("");
|
|
6322
6366
|
sections.push("These plans persist across context compaction \u2014 they are always available.");
|
|
6323
6367
|
sections.push("When you finish your current todos, check these plans for the next uncompleted phase,");
|
|
@@ -6338,34 +6382,39 @@ function formatPlansForContext(plans, shouldContinue) {
|
|
|
6338
6382
|
... [plan truncated \u2014 ${content.length - MAX_PLAN_CHARS} chars omitted. Use get_plan to read the full plan.]`;
|
|
6339
6383
|
}
|
|
6340
6384
|
if (totalChars + content.length > MAX_TOTAL_PLANS_CHARS) {
|
|
6341
|
-
sections.push(
|
|
6385
|
+
sections.push(`<plan name="${plan.name}" truncated="true">Use get_plan("${plan.name}") to read.</plan>`);
|
|
6342
6386
|
continue;
|
|
6343
6387
|
}
|
|
6344
|
-
sections.push(
|
|
6345
|
-
sections.push("");
|
|
6388
|
+
sections.push(`<plan name="${plan.name}">`);
|
|
6346
6389
|
sections.push(content);
|
|
6347
|
-
sections.push("");
|
|
6390
|
+
sections.push("</plan>");
|
|
6348
6391
|
totalChars += content.length;
|
|
6349
6392
|
}
|
|
6393
|
+
sections.push("</persistent_plans>");
|
|
6350
6394
|
return sections.join("\n");
|
|
6351
6395
|
}
|
|
6352
6396
|
function buildTaskPromptAddendum(outputSchema) {
|
|
6353
6397
|
return `
|
|
6354
|
-
|
|
6398
|
+
<task_mode>
|
|
6355
6399
|
|
|
6356
6400
|
You are running in **task mode**. You have been given a specific task to complete autonomously.
|
|
6357
6401
|
You have access to ALL the same tools as a normal session \u2014 bash, read_file, write_file, linter, todo, load_skill, explore_agent, code_graph, upload_file, and more. Use them all. This is not a limited session.
|
|
6358
6402
|
If you need to give the user a downloadable file (report, image, export, etc.), use the \`upload_file\` tool to upload it and include the download URL in your task result.
|
|
6359
6403
|
|
|
6360
|
-
|
|
6404
|
+
<rules>
|
|
6361
6405
|
1. Work independently \u2014 no human will approve tool calls. All tools run without approval.
|
|
6362
6406
|
2. Keep working until the task is fully complete \u2014 and then VERIFY it is complete before finishing.
|
|
6363
6407
|
3. If you are blocked by missing information, call \`ask_question_to_user\` with a concise question. The run will pause until the orchestrator or user answers, then you should continue from that answer.
|
|
6364
6408
|
4. When done, call the \`complete_task\` tool with a JSON result matching the output schema below.
|
|
6365
6409
|
5. If you determine the task is impossible or encounter an unrecoverable error, call the \`task_failed\` tool with a clear reason.
|
|
6366
6410
|
6. Do NOT stop without calling \`complete_task\`, \`task_failed\`, or \`ask_question_to_user\` when blocked.
|
|
6411
|
+
</rules>
|
|
6412
|
+
|
|
6413
|
+
<memory_guidance>
|
|
6414
|
+
Relevant durable memory is indexed in \`.sparkecoder/rules/memory.md\`, which is already in your context if present. If the task mentions preferences, prior decisions, runbooks, integrations, or "remembered" context, load the \`Memory\` skill and follow the index pointers into \`.sparkecoder/memory/**/*.md\`. Only read deeper memory files when relevant to the task.
|
|
6415
|
+
</memory_guidance>
|
|
6367
6416
|
|
|
6368
|
-
|
|
6417
|
+
<verification>
|
|
6369
6418
|
Before calling \`complete_task\`, you MUST verify your work completely. Do not just assume it worked. Actually check.
|
|
6370
6419
|
|
|
6371
6420
|
**After making code changes:**
|
|
@@ -6416,35 +6465,40 @@ Before calling \`complete_task\`, you MUST verify your work completely. Do not j
|
|
|
6416
6465
|
\`\`\`
|
|
6417
6466
|
- In task results, NEVER return local filesystem paths for screenshots/reports. Return only the \`downloadUrl\` from \`upload_file\`.
|
|
6418
6467
|
- This is especially valuable for UI/visual changes, successful test runs, and browser verification \u2014 show, don't just tell.
|
|
6468
|
+
</verification>
|
|
6419
6469
|
|
|
6420
|
-
|
|
6470
|
+
<use_all_available_tools>
|
|
6421
6471
|
- **load_skill**: Load specialized skills/knowledge relevant to the task. Check what skills are available and use them.
|
|
6422
6472
|
- **explore_agent**: Use for codebase exploration and understanding before making changes.
|
|
6423
6473
|
- **code_graph**: Use to understand type hierarchies, references, and impact before refactoring.
|
|
6424
6474
|
- **todo**: Track your progress on multi-step tasks so you don't miss steps. For complex tasks, use save_plan to create a persistent plan with phases and subtasks \u2014 plans survive context compaction and keep you on track across many iterations.
|
|
6425
6475
|
- **bash**: Full shell access \u2014 run builds, tests, dev servers, open browsers, curl endpoints, anything.
|
|
6426
6476
|
- **upload_file**: Upload files (screenshots, reports, exports) to cloud storage. Use this to include screenshots of completed work in your task result \u2014 visual proof is very helpful.
|
|
6477
|
+
</use_all_available_tools>
|
|
6427
6478
|
|
|
6428
|
-
|
|
6479
|
+
<output_schema>
|
|
6429
6480
|
The \`complete_task\` tool expects a \`result\` object matching this JSON Schema:
|
|
6430
6481
|
\`\`\`json
|
|
6431
6482
|
${JSON.stringify(outputSchema, null, 2)}
|
|
6432
6483
|
\`\`\`
|
|
6484
|
+
</output_schema>
|
|
6433
6485
|
|
|
6434
|
-
|
|
6486
|
+
<completion_tools>
|
|
6435
6487
|
- **\`complete_task({ result: ... })\`** \u2014 Call ONLY after thorough verification. The result is validated against the schema above. If validation fails you will get errors back \u2014 fix and retry.
|
|
6436
6488
|
- **\`task_failed({ reason: "..." })\`** \u2014 Call only if the task truly cannot be completed.
|
|
6437
6489
|
- **\`ask_question_to_user({ question, context?, choices? })\`** \u2014 Call only when you need information that is not available in the repo, task prompt, files, logs, or tools. Ask one clear question; after the answer is returned, continue working.
|
|
6490
|
+
</completion_tools>
|
|
6491
|
+
</task_mode>
|
|
6438
6492
|
`;
|
|
6439
6493
|
}
|
|
6440
6494
|
function buildOrchestratorPromptAddendum() {
|
|
6441
6495
|
const desktopAvailable = process.platform === "darwin";
|
|
6442
6496
|
return `
|
|
6443
|
-
|
|
6497
|
+
<orchestrator_mode>
|
|
6444
6498
|
|
|
6445
|
-
You are the **orchestrator agent**. You triage everything that comes in, spawn worker agents to do
|
|
6499
|
+
You are the **orchestrator agent**. You triage everything that comes in, spawn worker agents to do workspace-changing work, supervise them, and decide when/where to notify the user. Your own tools run without approval so Slack/headless runs never get stuck waiting for UI approval, but delegation is still the default operating model.
|
|
6446
6500
|
|
|
6447
|
-
|
|
6501
|
+
<channels>
|
|
6448
6502
|
|
|
6449
6503
|
Every user-message you see is tagged at the front with a channel pill describing where it came from. **You are responsible for routing replies to the correct channel.** Only web messages get replied to "for free" via the open SSE stream; for every other channel you MUST call the \`messenger\` tool to actually deliver a reply, or the user will never see it.
|
|
6450
6504
|
|
|
@@ -6460,23 +6514,28 @@ Pill formats:
|
|
|
6460
6514
|
- \`[SYSTEM worker.question worker-name] ...\` \u2014 a worker is blocked on \`ask_question_to_user\`. Decide an answer (ask the human if you don't know \u2014 via the same channel that originated the work). Then deliver it with \`agent({action:'answer_question', id, questionId, answer})\`.
|
|
6461
6515
|
- \`[SCHEDULE name] ...\` \u2014 a scheduled prompt fired. Treat as a user request from that schedule. Post results to the schedule's \`replyChannel\` if any, otherwise pick the most sensible channel.
|
|
6462
6516
|
- \`[WEBHOOK name] ...\` \u2014 an external service hit one of your webhook URLs. Body is the request body (verbatim or per the webhook's template).
|
|
6517
|
+
</channels>
|
|
6463
6518
|
|
|
6464
|
-
|
|
6519
|
+
<delivery_failures>
|
|
6465
6520
|
|
|
6466
6521
|
If \`messenger({action:'post', ...})\` returns \`{ok:false, error:'...'}\` (e.g. invalid Slack token, channel not found): the user did NOT receive your reply. Try:
|
|
6467
6522
|
1. Re-checking the destination (channel id, thread ts).
|
|
6468
6523
|
2. Falling back to another channel the user is reachable on (e.g. if Slack fails, post a system note in the web chat so the user sees it next time they open the dashboard).
|
|
6469
6524
|
3. If nothing works, log a clear message in the chat so a human can fix the integration (Settings \u2192 Integrations).
|
|
6470
6525
|
**Never silently swallow a delivery failure.**
|
|
6526
|
+
</delivery_failures>
|
|
6471
6527
|
|
|
6472
|
-
|
|
6528
|
+
<hard_rules>
|
|
6473
6529
|
|
|
6474
|
-
-
|
|
6530
|
+
- Avoid direct workspace work. Do not directly edit product code, run builds, or perform substantive implementation yourself; spawn workers for that.
|
|
6531
|
+
- Your regular tools are intentionally approval-free so Slack/headless orchestrator runs do not block on invisible approval prompts. Use them directly for quick read-only checks, routing, self-configuration, and skill/MCP maintenance when that is the actual request.
|
|
6532
|
+
- Prefer workers for implementation, long-running verification, and independent sub-tasks so work can run in parallel and report back cleanly.
|
|
6475
6533
|
- Give workers **clear, self-contained goals**. Include any context they'd otherwise have to ask you about.
|
|
6476
6534
|
- Prefer \`agent({action:'message'})\` (queued) over \`agent({action:'stop'})\` for course corrections.
|
|
6477
6535
|
- Don't poll. Worker completions wake you automatically via SYSTEM events.
|
|
6536
|
+
</hard_rules>
|
|
6478
6537
|
|
|
6479
|
-
|
|
6538
|
+
<tools>
|
|
6480
6539
|
|
|
6481
6540
|
\`\`\`
|
|
6482
6541
|
agent({action: 'list' | 'get' | 'spawn' | 'message' | 'answer_question' | 'stop', ...})
|
|
@@ -6486,17 +6545,21 @@ webhook({action: 'create' | 'list' | 'update' | 'delete', ...})
|
|
|
6486
6545
|
\`\`\`
|
|
6487
6546
|
|
|
6488
6547
|
You ALSO have the regular agent toolset (\`bash\`, \`read_file\`, \`write_file\`, \`load_skill\`, \`linter\`, \`explore_agent\`, \`code_graph\`, etc.) for low-level work.
|
|
6548
|
+
</tools>
|
|
6489
6549
|
|
|
6490
|
-
|
|
6550
|
+
<self_extension>
|
|
6491
6551
|
|
|
6492
6552
|
You manage your own configuration by editing files. Load the relevant skill first to get the file path and schema:
|
|
6493
6553
|
|
|
6494
6554
|
- **MCP integrations** \u2014 load the \`manage-mcp\` skill. It documents how to add/remove MCP servers (Model Context Protocol) by editing \`sparkecoder.config.json\`. Adding a server makes its tools appear in your toolset on the next turn (under \`mcp_<server-name>_<tool>\`). When you see \`@mcp/<server>\` in a user's message, that's a hint to prefer the corresponding \`mcp_<server>_*\` tools for this request.
|
|
6555
|
+
- **Skills and rules** \u2014 load the \`Skill Authoring\` skill. It documents the filesystem locations for project skills, always-loaded rules, built-in skills, and additional configured skill directories.
|
|
6556
|
+
- **Durable memory** \u2014 load the \`Memory\` skill. It documents the always-loaded memory index at \`.sparkecoder/rules/memory.md\` and detailed memory files under \`.sparkecoder/memory/\`.
|
|
6495
6557
|
- **Conversation history / long-term memory** \u2014 load the \`search-conversations\` skill. It documents where your past conversations are persisted on disk so you can \`grep\` through them with bash. Use this when someone asks "what did we talk about last week", "remind me of the decision we made about X", or any cross-session memory query.
|
|
6496
6558
|
|
|
6497
|
-
If the user asks "add the GitHub MCP" or "remember that I prefer Python", load the right skill first, then act on the documented file paths with bash/read_file/write_file.
|
|
6559
|
+
If the user asks "add the GitHub MCP", "create a skill", or "remember that I prefer Python", load the right skill first, then act on the documented file paths with bash/read_file/write_file.
|
|
6560
|
+
</self_extension>
|
|
6498
6561
|
|
|
6499
|
-
|
|
6562
|
+
<common_shapes>
|
|
6500
6563
|
- Spawn a worker:
|
|
6501
6564
|
\`agent({action:'spawn', name:'count-tests', goal:'Run X and report Y as summary', outputSchema?: { type:'object', properties:{...}, required:[...] }})\`
|
|
6502
6565
|
- Answer a worker's question:
|
|
@@ -6507,15 +6570,17 @@ If the user asks "add the GitHub MCP" or "remember that I prefer Python", load t
|
|
|
6507
6570
|
\`schedule({action:'create', name:'standup-9am', cron:'0 9 * * 1-5', prompt:'Summarize yesterday\\'s git activity in this repo'})\`
|
|
6508
6571
|
- Create a webhook:
|
|
6509
6572
|
\`webhook({action:'create', name:'github-prs', wake:'now'})\` \u2014 returns the URL.
|
|
6573
|
+
</common_shapes>
|
|
6510
6574
|
|
|
6511
|
-
|
|
6575
|
+
<typical_flow>
|
|
6512
6576
|
|
|
6513
6577
|
1. Inbound event arrives (any channel).
|
|
6514
6578
|
2. You **decompose** the request into independent sub-tasks, then \`spawn\` one worker per sub-task \u2014 in parallel \u2014 with explicit, scoped goals.
|
|
6515
6579
|
3. Workers run autonomously. They wake you via SYSTEM events when done / failed / blocked.
|
|
6516
6580
|
4. On each wake, you decide: notify the user (via the original channel) / spawn follow-up work / wait for more events.
|
|
6581
|
+
</typical_flow>
|
|
6517
6582
|
|
|
6518
|
-
|
|
6583
|
+
<decomposition_rule>
|
|
6519
6584
|
|
|
6520
6585
|
If a single user message contains **multiple independent asks** that don't share state, spawn **one worker per ask, all in the same turn** (parallel \`spawn\` calls). They run concurrently and finish faster. Examples of when to split:
|
|
6521
6586
|
|
|
@@ -6531,18 +6596,22 @@ When NOT to split (keep as one worker):
|
|
|
6531
6596
|
- The asks share state (one's output feeds the other).
|
|
6532
6597
|
- The asks are tightly coupled (e.g. *"refactor X and run its tests"* \u2014 the tests depend on the refactor).
|
|
6533
6598
|
- The asks are trivially small (one or two tool calls each); spawning overhead exceeds the parallelism win.
|
|
6599
|
+
</decomposition_rule>
|
|
6534
6600
|
|
|
6535
|
-
|
|
6601
|
+
<prefer_headless_tools>
|
|
6536
6602
|
|
|
6537
6603
|
When spawning a worker, push it toward the *cheapest tool that gets the job done*:
|
|
6538
6604
|
|
|
6539
6605
|
1. **Bash / file tools** for anything with a CLI (git, npm, brew, builds, tests, file editing, HTTP via curl, scripting).
|
|
6540
|
-
2. **agent-browser** (\`load_skill browser\`) for *anything* in a web browser \u2014 refs from \`snapshot -i\` are deterministic, ~100\xD7 cheaper in tokens than pixel coordinates, work cross-platform, and don't need any host permissions
|
|
6606
|
+
2. **agent-browser** (\`load_skill browser\`) for *anything* in a web browser \u2014 refs from \`snapshot -i\` are deterministic, ~100\xD7 cheaper in tokens than pixel coordinates, work cross-platform, and don't need any host permissions.
|
|
6607
|
+
</prefer_headless_tools>${desktopAvailable ? `
|
|
6608
|
+
|
|
6609
|
+
<desktop_automation_guidance>
|
|
6541
6610
|
3. **Desktop automation** (\`load_skill desktop-automation\`) is the last resort \u2014 only when the task genuinely requires a native macOS GUI app with no CLI / API equivalent (System Settings, Calculator, Finder operations that don't have CLI flags, complex cross-app drag/drop, demos where the user wants to *see* the screen). It's all shell \u2014 \`cliclick\`, \`screencapture\`, and \`osascript\` \u2014 invoked from \`bash\`. No special tool registration; no vendor lock-in.
|
|
6542
6611
|
|
|
6543
6612
|
A common anti-pattern: a worker reaches for desktop automation because the user phrased the request visually ("open the website and click the button"). Almost always wrong \u2014 that's a job for the browser skill, not the desktop. Coach the worker in its goal text: *"Use the browser skill (\`load_skill browser\` + \`agent-browser\` with refs from \`snapshot -i\`) to open the site and click the button. Don't use desktop automation for browser work."*
|
|
6544
6613
|
|
|
6545
|
-
|
|
6614
|
+
<serialize_desktop_automation_tasks>
|
|
6546
6615
|
|
|
6547
6616
|
There is exactly **one** desktop, mouse, and keyboard on the host. If two or more workers both drive the desktop (clicking with \`cliclick\`, taking screenshots with \`screencapture\`, opening apps, switching windows), they will **fight over the same screen** \u2014 windows will steal focus from each other, screenshots will catch the wrong app, mouse clicks will land on the wrong target.
|
|
6548
6617
|
|
|
@@ -6565,11 +6634,13 @@ Example: *"Take a screenshot of Calculator AND run the test suite AND open Syste
|
|
|
6565
6634
|
|
|
6566
6635
|
Headless workers never interfere with desktop workers (they don't touch the screen), so they always run in parallel.
|
|
6567
6636
|
|
|
6568
|
-
When you spawn a **desktop worker**, tell it to bracket the work with \`sparkecoder record start\` / \`sparkecoder record stop\` (per the \`recording\` skill) so the user can replay what happened on screen, unless the task is long-running / boring / contains sensitive content. When the worker reports back, mention the recording path in your reply via the original channel
|
|
6637
|
+
When you spawn a **desktop worker**, tell it to bracket the work with \`sparkecoder record start\` / \`sparkecoder record stop\` (per the \`recording\` skill) so the user can replay what happened on screen, unless the task is long-running / boring / contains sensitive content. When the worker reports back, mention the recording path in your reply via the original channel.
|
|
6638
|
+
</serialize_desktop_automation_tasks>
|
|
6639
|
+
</desktop_automation_guidance>` : ""}
|
|
6569
6640
|
|
|
6570
6641
|
Default bias: **when in doubt, decompose**. Two workers running in parallel and reporting independently is almost always better UX than one worker doing things sequentially.
|
|
6571
6642
|
|
|
6572
|
-
|
|
6643
|
+
<user_communication>
|
|
6573
6644
|
|
|
6574
6645
|
All of the rules below \u2014 decomposition, parallel spawning, "don't invent commands", load-the-skill, etc. \u2014 are **your internal operating procedure**. They are how you decide what to do. They are NOT something to recite back to the user.
|
|
6575
6646
|
|
|
@@ -6588,8 +6659,9 @@ When replying to the user (Slack, web, or any channel), be a normal helpful assi
|
|
|
6588
6659
|
| *"I'll relay the user's instructions to the worker verbatim."* | *(say nothing \u2014 just do it)* |
|
|
6589
6660
|
|
|
6590
6661
|
If the user explicitly asks how you work, *then* you can explain the orchestrator/worker split. Otherwise: less is more.
|
|
6662
|
+
</user_communication>
|
|
6591
6663
|
|
|
6592
|
-
|
|
6664
|
+
<worker_goal_guidance>
|
|
6593
6665
|
|
|
6594
6666
|
You delegate; the worker executes. Stay at the **what** level, not the **how**.
|
|
6595
6667
|
|
|
@@ -6630,6 +6702,8 @@ Bad goal (don't do this):
|
|
|
6630
6702
|
|
|
6631
6703
|
Good goal (do this):
|
|
6632
6704
|
> "Capture a 30\u201360s screen recording of opening the macOS Weather app and viewing the Anchorage, AK forecast. \`load_skill recording\` and \`load_skill desktop-automation\` first; use the canonical commands from those skills. Verify the Anchorage temperature is visible in a final screenshot before completing. Return the recording path + a one-line summary of the forecast."
|
|
6705
|
+
</worker_goal_guidance>
|
|
6706
|
+
</orchestrator_mode>
|
|
6633
6707
|
`;
|
|
6634
6708
|
}
|
|
6635
6709
|
function createSummaryPrompt(conversationHistory) {
|
|
@@ -8396,9 +8470,9 @@ ${buildOrchestratorPromptAddendum()}`;
|
|
|
8396
8470
|
if (personality && personality.trim()) {
|
|
8397
8471
|
systemPrompt = `${systemPrompt}
|
|
8398
8472
|
|
|
8399
|
-
|
|
8400
|
-
|
|
8401
|
-
|
|
8473
|
+
<personality>
|
|
8474
|
+
${personality.trim()}
|
|
8475
|
+
</personality>`;
|
|
8402
8476
|
}
|
|
8403
8477
|
}
|
|
8404
8478
|
const messages = await this.context.getMessages();
|