taskplane 0.13.0 → 0.14.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/bin/taskplane.mjs +6 -2
- package/extensions/taskplane/supervisor-primer.md +7 -0
- package/extensions/taskplane/supervisor.ts +238 -34
- package/package.json +1 -1
- package/templates/agents/local/supervisor.md +33 -0
- package/templates/agents/supervisor-routing.md +91 -0
- package/templates/agents/supervisor.md +166 -0
package/bin/taskplane.mjs
CHANGED
|
@@ -507,6 +507,7 @@ async function cmdUninstall(args) {
|
|
|
507
507
|
".pi/agents/task-worker.md",
|
|
508
508
|
".pi/agents/task-reviewer.md",
|
|
509
509
|
".pi/agents/task-merger.md",
|
|
510
|
+
".pi/agents/supervisor.md",
|
|
510
511
|
".pi/batch-state.json",
|
|
511
512
|
".pi/batch-history.json",
|
|
512
513
|
".pi/orch-abort-signal",
|
|
@@ -1301,7 +1302,7 @@ async function cmdInit(args) {
|
|
|
1301
1302
|
const skipIfExists = !force && !userConfirmedOverwrite;
|
|
1302
1303
|
|
|
1303
1304
|
// Agent prompts
|
|
1304
|
-
for (const agent of ["task-worker.md", "task-reviewer.md", "task-merger.md"]) {
|
|
1305
|
+
for (const agent of ["task-worker.md", "task-reviewer.md", "task-merger.md", "supervisor.md"]) {
|
|
1305
1306
|
copyTemplate(
|
|
1306
1307
|
path.join(TEMPLATES_DIR, "agents", "local", agent),
|
|
1307
1308
|
path.join(taskplaneDir, "agents", agent),
|
|
@@ -1524,7 +1525,7 @@ async function cmdInit(args) {
|
|
|
1524
1525
|
|
|
1525
1526
|
// Agent prompts — copy thin local files (base prompts ship in the package
|
|
1526
1527
|
// and are composed automatically by the task-runner at runtime)
|
|
1527
|
-
for (const agent of ["task-worker.md", "task-reviewer.md", "task-merger.md"]) {
|
|
1528
|
+
for (const agent of ["task-worker.md", "task-reviewer.md", "task-merger.md", "supervisor.md"]) {
|
|
1528
1529
|
copyTemplate(
|
|
1529
1530
|
path.join(TEMPLATES_DIR, "agents", "local", agent),
|
|
1530
1531
|
path.join(projectRoot, ".pi", "agents", agent),
|
|
@@ -1685,6 +1686,7 @@ function printFileList(vars, noExamples, preset, exampleTemplateDirs = [], proje
|
|
|
1685
1686
|
".pi/agents/task-worker.md",
|
|
1686
1687
|
".pi/agents/task-reviewer.md",
|
|
1687
1688
|
".pi/agents/task-merger.md",
|
|
1689
|
+
".pi/agents/supervisor.md",
|
|
1688
1690
|
".pi/task-runner.yaml",
|
|
1689
1691
|
];
|
|
1690
1692
|
if (preset !== "runner-only") files.push(".pi/task-orchestrator.yaml");
|
|
@@ -1723,6 +1725,7 @@ function printWorkspaceFileList(vars, noExamples, preset, exampleTemplateDirs, c
|
|
|
1723
1725
|
`${prefix}/agents/task-worker.md`,
|
|
1724
1726
|
`${prefix}/agents/task-reviewer.md`,
|
|
1725
1727
|
`${prefix}/agents/task-merger.md`,
|
|
1728
|
+
`${prefix}/agents/supervisor.md`,
|
|
1726
1729
|
`${prefix}/task-runner.yaml`,
|
|
1727
1730
|
];
|
|
1728
1731
|
if (preset !== "runner-only") files.push(`${prefix}/task-orchestrator.yaml`);
|
|
@@ -2518,6 +2521,7 @@ function cmdDoctor() {
|
|
|
2518
2521
|
{ path: "agents/task-worker.md", required: true },
|
|
2519
2522
|
{ path: "agents/task-reviewer.md", required: true },
|
|
2520
2523
|
{ path: "agents/task-merger.md", required: true },
|
|
2524
|
+
{ path: "agents/supervisor.md", required: false },
|
|
2521
2525
|
{ path: "taskplane.json", required: false },
|
|
2522
2526
|
];
|
|
2523
2527
|
|
|
@@ -25,6 +25,12 @@ reviewers), or merge branches (that's merge agents). You supervise all of them.
|
|
|
25
25
|
full filesystem and command-line access. Use it to read state files, run git
|
|
26
26
|
commands, edit batch state, manage tmux sessions, and run verification.
|
|
27
27
|
|
|
28
|
+
**Your system prompt** is built from `templates/agents/supervisor.md` (base
|
|
29
|
+
template, ships with the package) composed with `.pi/agents/supervisor.md`
|
|
30
|
+
(project-specific overrides). The operator can customize your behavior by
|
|
31
|
+
editing the local override file. Dynamic batch context (IDs, paths, counts,
|
|
32
|
+
guardrails) is injected at runtime.
|
|
33
|
+
|
|
28
34
|
---
|
|
29
35
|
|
|
30
36
|
## 2. Architecture in 60 Seconds
|
|
@@ -1070,6 +1076,7 @@ Create the directory and add thin override files:
|
|
|
1070
1076
|
- `.pi/agents/task-worker.md` — worker prompt overrides (can be empty initially)
|
|
1071
1077
|
- `.pi/agents/task-reviewer.md` — reviewer prompt overrides (can be empty initially)
|
|
1072
1078
|
- `.pi/agents/task-merger.md` — merger prompt overrides (can be empty initially)
|
|
1079
|
+
- `.pi/agents/supervisor.md` — supervisor prompt overrides (can be empty initially)
|
|
1073
1080
|
|
|
1074
1081
|
Each file can start with a brief comment explaining its purpose:
|
|
1075
1082
|
```markdown
|
|
@@ -1748,6 +1748,171 @@ function resolvePrimerPath(): string {
|
|
|
1748
1748
|
}
|
|
1749
1749
|
}
|
|
1750
1750
|
|
|
1751
|
+
|
|
1752
|
+
// ── Template Loading (TP-058) ────────────────────────────────────────
|
|
1753
|
+
|
|
1754
|
+
/**
|
|
1755
|
+
* Resolve the path to a base supervisor template shipped with the package.
|
|
1756
|
+
*
|
|
1757
|
+
* Templates live in `<package-root>/templates/agents/`. This function derives
|
|
1758
|
+
* the package root from the extension file's location
|
|
1759
|
+
* (`<package-root>/extensions/taskplane/supervisor.ts`).
|
|
1760
|
+
*
|
|
1761
|
+
* @param name - Template filename without extension (e.g. "supervisor", "supervisor-routing")
|
|
1762
|
+
* @returns Absolute path to the template file
|
|
1763
|
+
*
|
|
1764
|
+
* @since TP-058
|
|
1765
|
+
*/
|
|
1766
|
+
function resolveBaseTemplatePath(name: string): string {
|
|
1767
|
+
try {
|
|
1768
|
+
const thisDir = dirname(fileURLToPath(import.meta.url));
|
|
1769
|
+
// thisDir = <package-root>/extensions/taskplane/
|
|
1770
|
+
return join(thisDir, "..", "..", "templates", "agents", `${name}.md`);
|
|
1771
|
+
} catch {
|
|
1772
|
+
return join(__dirname, "..", "..", "templates", "agents", `${name}.md`);
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
/**
|
|
1777
|
+
* Parse a simple frontmatter+body markdown file.
|
|
1778
|
+
* Returns null if the file doesn't exist or has no frontmatter.
|
|
1779
|
+
*
|
|
1780
|
+
* @since TP-058
|
|
1781
|
+
*/
|
|
1782
|
+
function parseSupervisorTemplate(filePath: string): { fm: Record<string, string>; body: string } | null {
|
|
1783
|
+
if (!existsSync(filePath)) return null;
|
|
1784
|
+
const raw = readFileSync(filePath, "utf-8").replace(/\r\n/g, "\n");
|
|
1785
|
+
const match = raw.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
1786
|
+
if (!match) return null;
|
|
1787
|
+
const fm: Record<string, string> = {};
|
|
1788
|
+
for (const line of match[1].split("\n")) {
|
|
1789
|
+
const idx = line.indexOf(":");
|
|
1790
|
+
if (idx > 0) {
|
|
1791
|
+
const key = line.slice(0, idx).trim();
|
|
1792
|
+
if (!key.startsWith("#")) { // Skip commented-out frontmatter
|
|
1793
|
+
fm[key] = line.slice(idx + 1).trim();
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
return { fm, body: match[2].trim() };
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1800
|
+
/**
|
|
1801
|
+
* Load a supervisor template: base (from package) + local override (from project).
|
|
1802
|
+
*
|
|
1803
|
+
* Follows the same composition pattern as `loadAgentDef()` in task-runner.ts:
|
|
1804
|
+
* - Base template: shipped in `templates/agents/{name}.md`
|
|
1805
|
+
* - Local override: `.pi/agents/{name}.md` in the project
|
|
1806
|
+
* - If local has `standalone: true`, use it exclusively
|
|
1807
|
+
* - Otherwise, compose base + local with a separator
|
|
1808
|
+
*
|
|
1809
|
+
* @param name - Template name (e.g. "supervisor", "supervisor-routing")
|
|
1810
|
+
* @param stateRoot - Root path for .pi/ state directory
|
|
1811
|
+
* @returns The composed template body, or null if no template found
|
|
1812
|
+
*
|
|
1813
|
+
* @since TP-058
|
|
1814
|
+
*/
|
|
1815
|
+
export function loadSupervisorTemplate(name: string, stateRoot: string, localName?: string): string | null {
|
|
1816
|
+
const basePath = resolveBaseTemplatePath(name);
|
|
1817
|
+
const baseDef = parseSupervisorTemplate(basePath);
|
|
1818
|
+
|
|
1819
|
+
// Load local override from .pi/agents/{localName}.md (defaults to base name)
|
|
1820
|
+
// This allows routing template (base: "supervisor-routing") to share the
|
|
1821
|
+
// same local override as the main supervisor (local: "supervisor").
|
|
1822
|
+
const effectiveLocalName = localName || name;
|
|
1823
|
+
const localPath = stateRoot ? join(stateRoot, ".pi", "agents", `${effectiveLocalName}.md`) : "";
|
|
1824
|
+
const localDef = localPath ? parseSupervisorTemplate(localPath) : null;
|
|
1825
|
+
|
|
1826
|
+
// No base and no local → null (triggers fallback to inline prompt)
|
|
1827
|
+
if (!baseDef && !localDef) return null;
|
|
1828
|
+
|
|
1829
|
+
// Local with standalone: true → use local as-is, ignore base
|
|
1830
|
+
if (localDef?.fm.standalone === "true") {
|
|
1831
|
+
return localDef.body;
|
|
1832
|
+
}
|
|
1833
|
+
|
|
1834
|
+
// Compose base + local
|
|
1835
|
+
const baseBody = baseDef?.body || "";
|
|
1836
|
+
const localBody = localDef?.body || "";
|
|
1837
|
+
if (localBody) {
|
|
1838
|
+
return baseBody + "\n\n---\n\n## Project-Specific Guidance\n\n" + localBody;
|
|
1839
|
+
}
|
|
1840
|
+
return baseBody;
|
|
1841
|
+
}
|
|
1842
|
+
|
|
1843
|
+
/**
|
|
1844
|
+
* Replace `{{variable}}` placeholders in a template string.
|
|
1845
|
+
*
|
|
1846
|
+
* @param template - Template string with `{{key}}` placeholders
|
|
1847
|
+
* @param vars - Key-value map of variable replacements
|
|
1848
|
+
* @returns Template with all known placeholders replaced
|
|
1849
|
+
*
|
|
1850
|
+
* @since TP-058
|
|
1851
|
+
*/
|
|
1852
|
+
function replaceTemplateVars(template: string, vars: Record<string, string>): string {
|
|
1853
|
+
return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
|
|
1854
|
+
return key in vars ? vars[key] : match;
|
|
1855
|
+
});
|
|
1856
|
+
}
|
|
1857
|
+
|
|
1858
|
+
|
|
1859
|
+
/**
|
|
1860
|
+
* Build the guardrails section dynamically based on integration mode (TP-043).
|
|
1861
|
+
* Extracted as a helper so both the template path and inline fallback can reuse it.
|
|
1862
|
+
* @since TP-058
|
|
1863
|
+
*/
|
|
1864
|
+
function buildGuardrailsSection(integrationMode: string): string {
|
|
1865
|
+
if (integrationMode === "supervised" || integrationMode === "auto") {
|
|
1866
|
+
const modeNote = integrationMode === "supervised"
|
|
1867
|
+
? `**Supervised mode:** Before executing integration, describe your plan and ask the operator for confirmation.`
|
|
1868
|
+
: `**Auto mode:** Execute integration directly. Report the outcome to the operator. Pause only on errors or conflicts.`;
|
|
1869
|
+
return `## What You Must NEVER Do
|
|
1870
|
+
|
|
1871
|
+
1. Never delete \`.pi/batch-state.json\` without operator approval
|
|
1872
|
+
2. Never modify task code (files that workers wrote)
|
|
1873
|
+
3. Never modify PROMPT.md files
|
|
1874
|
+
4. Never \`git reset --hard\` with uncommitted changes
|
|
1875
|
+
5. Never skip tasks/waves without telling the operator
|
|
1876
|
+
6. Never create GitHub releases
|
|
1877
|
+
|
|
1878
|
+
## Integration Permissions (mode: ${integrationMode})
|
|
1879
|
+
|
|
1880
|
+
You are authorized to perform integration operations after batch completion:
|
|
1881
|
+
- \`git push origin <orch-branch>\` — push the orch branch for PR creation
|
|
1882
|
+
- \`gh pr create\` — create pull requests for integration
|
|
1883
|
+
- \`git merge --ff-only\` or \`git merge --no-edit\` — local branch integration
|
|
1884
|
+
- \`git branch -D <orch-branch>\` — cleanup after successful integration
|
|
1885
|
+
|
|
1886
|
+
${modeNote}`;
|
|
1887
|
+
}
|
|
1888
|
+
return `## What You Must NEVER Do
|
|
1889
|
+
|
|
1890
|
+
1. Never \`git push\` to any remote
|
|
1891
|
+
2. Never delete \`.pi/batch-state.json\` without operator approval
|
|
1892
|
+
3. Never modify task code (files that workers wrote)
|
|
1893
|
+
4. Never modify PROMPT.md files
|
|
1894
|
+
5. Never \`git reset --hard\` with uncommitted changes
|
|
1895
|
+
6. Never skip tasks/waves without telling the operator
|
|
1896
|
+
7. Never create PRs or GitHub releases`;
|
|
1897
|
+
}
|
|
1898
|
+
|
|
1899
|
+
/**
|
|
1900
|
+
* Build the autonomy level description for the current autonomy setting.
|
|
1901
|
+
* @since TP-058
|
|
1902
|
+
*/
|
|
1903
|
+
function buildAutonomyDescription(autonomyLabel: string): string {
|
|
1904
|
+
switch (autonomyLabel) {
|
|
1905
|
+
case "interactive":
|
|
1906
|
+
return `**Your current level is INTERACTIVE.** ASK the operator before any Tier 0 Known or Destructive action. Explain what you want to do, why, and what the alternatives are. Let the operator decide.`;
|
|
1907
|
+
case "supervised":
|
|
1908
|
+
return `**Your current level is SUPERVISED.** Execute Tier 0 Known patterns automatically (retries, cleanup, session restarts). ASK before Destructive actions (manual merges, state editing, skipping tasks, killing sessions). Always explain what you did and why.`;
|
|
1909
|
+
case "autonomous":
|
|
1910
|
+
return `**Your current level is AUTONOMOUS.** Execute all recovery actions automatically. Pause and summarize only when you're genuinely stuck and cannot resolve the issue. The operator trusts you to make reasonable decisions.`;
|
|
1911
|
+
default:
|
|
1912
|
+
return "";
|
|
1913
|
+
}
|
|
1914
|
+
}
|
|
1915
|
+
|
|
1751
1916
|
/**
|
|
1752
1917
|
* Build the supervisor system prompt.
|
|
1753
1918
|
*
|
|
@@ -1789,38 +1954,37 @@ export function buildSupervisorSystemPrompt(
|
|
|
1789
1954
|
const actionsPath = auditTrailPath(stateRoot);
|
|
1790
1955
|
const integrationMode = config.orchestrator.integration;
|
|
1791
1956
|
|
|
1792
|
-
//
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
6. Never skip tasks/waves without telling the operator
|
|
1822
|
-
7. Never create PRs or GitHub releases`;
|
|
1957
|
+
// Build dynamic sections
|
|
1958
|
+
const guardrailsSection = buildGuardrailsSection(integrationMode);
|
|
1959
|
+
const autonomyGuidance = buildAutonomyDescription(autonomyLabel);
|
|
1960
|
+
|
|
1961
|
+
// TP-058: Try template-based prompt first, fall back to inline prompt.
|
|
1962
|
+
const template = loadSupervisorTemplate("supervisor", stateRoot);
|
|
1963
|
+
if (template) {
|
|
1964
|
+
const vars: Record<string, string> = {
|
|
1965
|
+
batchId: batchState.batchId || "(initializing — read batch state file)",
|
|
1966
|
+
phase: batchState.phase,
|
|
1967
|
+
baseBranch: batchState.baseBranch,
|
|
1968
|
+
orchBranch: batchState.orchBranch || "(legacy mode)",
|
|
1969
|
+
waveSummary,
|
|
1970
|
+
totalTasks: String(batchState.totalTasks),
|
|
1971
|
+
succeededTasks: String(batchState.succeededTasks),
|
|
1972
|
+
failedTasks: String(batchState.failedTasks),
|
|
1973
|
+
skippedTasks: String(batchState.skippedTasks),
|
|
1974
|
+
blockedTasks: String(batchState.blockedTasks),
|
|
1975
|
+
autonomy: autonomyLabel,
|
|
1976
|
+
batchStatePath,
|
|
1977
|
+
eventsPath,
|
|
1978
|
+
actionsPath,
|
|
1979
|
+
stateRoot,
|
|
1980
|
+
primerPath,
|
|
1981
|
+
guardrailsSection,
|
|
1982
|
+
autonomyGuidance,
|
|
1983
|
+
};
|
|
1984
|
+
return replaceTemplateVars(template, vars);
|
|
1985
|
+
}
|
|
1823
1986
|
|
|
1987
|
+
// ── Fallback: inline prompt (backward compatibility when template missing) ──
|
|
1824
1988
|
const prompt = `# Supervisor Agent
|
|
1825
1989
|
|
|
1826
1990
|
You are the **batch supervisor** — a persistent agent that monitors a Taskplane
|
|
@@ -1915,7 +2079,7 @@ Every action you take falls into one of three categories:
|
|
|
1915
2079
|
| Tier 0 Known | ❓ ASK | ✅ auto | ✅ auto |
|
|
1916
2080
|
| Destructive | ❓ ASK | ❓ ASK | ✅ auto |
|
|
1917
2081
|
|
|
1918
|
-
${
|
|
2082
|
+
${autonomyGuidance}
|
|
1919
2083
|
|
|
1920
2084
|
## Audit Trail
|
|
1921
2085
|
|
|
@@ -2020,8 +2184,33 @@ export function buildRoutingSystemPrompt(
|
|
|
2020
2184
|
const primerPath = resolvePrimerPath();
|
|
2021
2185
|
|
|
2022
2186
|
// Map routing state to the appropriate script section in the primer
|
|
2187
|
+
const scriptGuidance = buildRoutingScriptGuidance(routingContext.routingState, primerPath);
|
|
2188
|
+
|
|
2189
|
+
// TP-058: Try template-based prompt first, fall back to inline prompt.
|
|
2190
|
+
const template = loadSupervisorTemplate("supervisor-routing", stateRoot, "supervisor");
|
|
2191
|
+
if (template) {
|
|
2192
|
+
const vars: Record<string, string> = {
|
|
2193
|
+
routingState: routingContext.routingState,
|
|
2194
|
+
contextMessage: routingContext.contextMessage,
|
|
2195
|
+
scriptGuidance,
|
|
2196
|
+
primerPath,
|
|
2197
|
+
};
|
|
2198
|
+
return replaceTemplateVars(template, vars);
|
|
2199
|
+
}
|
|
2200
|
+
|
|
2201
|
+
// ── Fallback: inline prompt (backward compatibility when template missing) ──
|
|
2202
|
+
return buildRoutingInlinePrompt(routingContext, primerPath, scriptGuidance);
|
|
2203
|
+
}
|
|
2204
|
+
|
|
2205
|
+
/**
|
|
2206
|
+
* Build the script guidance section for routing prompts.
|
|
2207
|
+
* Contains the per-state instructions that guide the supervisor's behavior.
|
|
2208
|
+
*
|
|
2209
|
+
* @since TP-058
|
|
2210
|
+
*/
|
|
2211
|
+
function buildRoutingScriptGuidance(routingState: string, primerPath: string): string {
|
|
2023
2212
|
let scriptGuidance: string;
|
|
2024
|
-
switch (
|
|
2213
|
+
switch (routingState) {
|
|
2025
2214
|
case "no-config":
|
|
2026
2215
|
scriptGuidance = `## Your Mission: Onboarding
|
|
2027
2216
|
|
|
@@ -2048,6 +2237,7 @@ When the conversation reaches the config generation phase, create ALL of these
|
|
|
2048
2237
|
- \`.pi/agents/task-worker.md\` — worker prompt overrides (can start empty with a brief comment)
|
|
2049
2238
|
- \`.pi/agents/task-reviewer.md\` — reviewer prompt overrides (can start empty with a brief comment)
|
|
2050
2239
|
- \`.pi/agents/task-merger.md\` — merger prompt overrides (can start empty with a brief comment)
|
|
2240
|
+
- \`.pi/agents/supervisor.md\` — supervisor prompt overrides (can start empty with a brief comment)
|
|
2051
2241
|
- \`.gitignore\` entries — add Taskplane working file patterns if not already present
|
|
2052
2242
|
|
|
2053
2243
|
Use conservative creation: check if each file exists before writing. If files
|
|
@@ -2152,7 +2342,7 @@ A completed batch exists that hasn't been integrated yet.
|
|
|
2152
2342
|
default:
|
|
2153
2343
|
scriptGuidance = `## Your Mission: Project Assistance
|
|
2154
2344
|
|
|
2155
|
-
Detected state: ${
|
|
2345
|
+
Detected state: ${routingState}
|
|
2156
2346
|
|
|
2157
2347
|
1. **Read the primer** at \`${primerPath}\`
|
|
2158
2348
|
2. **Assess the situation** and help the operator with their next step
|
|
@@ -2160,6 +2350,20 @@ Detected state: ${routingContext.routingState}
|
|
|
2160
2350
|
break;
|
|
2161
2351
|
}
|
|
2162
2352
|
|
|
2353
|
+
return scriptGuidance;
|
|
2354
|
+
}
|
|
2355
|
+
|
|
2356
|
+
/**
|
|
2357
|
+
* Inline fallback for the routing system prompt.
|
|
2358
|
+
* Used when the base template file cannot be found.
|
|
2359
|
+
*
|
|
2360
|
+
* @since TP-058
|
|
2361
|
+
*/
|
|
2362
|
+
function buildRoutingInlinePrompt(
|
|
2363
|
+
routingContext: SupervisorRoutingContext,
|
|
2364
|
+
primerPath: string,
|
|
2365
|
+
scriptGuidance: string,
|
|
2366
|
+
): string {
|
|
2163
2367
|
const prompt = `# Project Supervisor
|
|
2164
2368
|
|
|
2165
2369
|
You are the **project supervisor** — a conversational agent that helps operators
|
package/package.json
CHANGED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: supervisor
|
|
3
|
+
# tools: read,write,edit,bash,grep,find,ls
|
|
4
|
+
# model:
|
|
5
|
+
# standalone: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
<!-- ═══════════════════════════════════════════════════════════════════
|
|
9
|
+
Project-Specific Supervisor Guidance
|
|
10
|
+
|
|
11
|
+
This file is COMPOSED with the base supervisor prompt shipped in the
|
|
12
|
+
taskplane package. Your content here is appended after the base prompt.
|
|
13
|
+
|
|
14
|
+
The base prompt (maintained by taskplane) handles:
|
|
15
|
+
- Supervisor identity and standing orders
|
|
16
|
+
- Recovery action classification and autonomy levels
|
|
17
|
+
- Audit trail format and rules
|
|
18
|
+
- Batch monitoring, failure handling, operator communication
|
|
19
|
+
- Orchestrator tool reference (orch_status, orch_pause, etc.)
|
|
20
|
+
- Startup checklist and operational knowledge
|
|
21
|
+
|
|
22
|
+
Add project-specific supervisor rules below. Common examples:
|
|
23
|
+
- Run linter before integration ("always run `npm run lint` after merge")
|
|
24
|
+
- CI dashboard URL for failure triage
|
|
25
|
+
- PR template or label conventions
|
|
26
|
+
- Project-specific recovery procedures
|
|
27
|
+
- Team notification preferences (Slack, etc.)
|
|
28
|
+
- Custom health check commands
|
|
29
|
+
|
|
30
|
+
To override frontmatter values (tools, model), uncomment and edit above.
|
|
31
|
+
To use this file as a FULLY STANDALONE prompt (ignoring the base),
|
|
32
|
+
uncomment `standalone: true` above and write the complete prompt below.
|
|
33
|
+
═══════════════════════════════════════════════════════════════════ -->
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: supervisor-routing
|
|
3
|
+
description: Project supervisor routing agent — onboarding, batch planning, and conversational flows
|
|
4
|
+
tools: read,write,edit,bash,grep,find,ls
|
|
5
|
+
# model:
|
|
6
|
+
---
|
|
7
|
+
# Project Supervisor
|
|
8
|
+
|
|
9
|
+
You are the **project supervisor** — a conversational agent that helps operators
|
|
10
|
+
set up, plan, and manage their Taskplane project. You were activated because the
|
|
11
|
+
operator typed `/orch` without arguments, and I detected the project state.
|
|
12
|
+
|
|
13
|
+
## Identity
|
|
14
|
+
|
|
15
|
+
You share this terminal session with the human operator. You are a senior
|
|
16
|
+
engineer helping them get the most out of Taskplane. Be conversational, helpful,
|
|
17
|
+
and adaptive — follow the scripts as guides, not rigid templates. If the
|
|
18
|
+
operator wants to skip ahead or go minimal, respect that.
|
|
19
|
+
|
|
20
|
+
## Detected State
|
|
21
|
+
|
|
22
|
+
**Routing state:** {{routingState}}
|
|
23
|
+
**Context:** {{contextMessage}}
|
|
24
|
+
|
|
25
|
+
{{scriptGuidance}}
|
|
26
|
+
|
|
27
|
+
## Capabilities
|
|
28
|
+
|
|
29
|
+
You have full tool access: `read`, `write`, `edit`, `bash`, `grep`, `find`, `ls`.
|
|
30
|
+
Use these to:
|
|
31
|
+
- Analyze project structure (read files, list directories, grep for patterns)
|
|
32
|
+
- Read existing configuration and docs
|
|
33
|
+
- Generate configuration files and CONTEXT.md documents
|
|
34
|
+
- Run git commands for branch analysis
|
|
35
|
+
- Run `gh` CLI commands for GitHub integration (issues, branch protection)
|
|
36
|
+
- Create task folders and PROMPT.md files
|
|
37
|
+
|
|
38
|
+
### Orchestrator Tools
|
|
39
|
+
|
|
40
|
+
You also have orchestrator tools available for batch management:
|
|
41
|
+
- **orch_status()** — Check batch status
|
|
42
|
+
- **orch_resume(force?)** — Resume a paused batch
|
|
43
|
+
- **orch_integrate(mode?, force?, branch?)** — Integrate completed batch (modes: "fast-forward", "merge", "pr")
|
|
44
|
+
- **orch_pause()** — Pause running batch
|
|
45
|
+
- **orch_abort(hard?)** — Abort running batch
|
|
46
|
+
|
|
47
|
+
Use these when the conversation leads to batch operations (e.g., integrating a completed batch).
|
|
48
|
+
|
|
49
|
+
## Operational Knowledge
|
|
50
|
+
|
|
51
|
+
**IMPORTANT:** Read `{{primerPath}}` for your complete operational runbook.
|
|
52
|
+
It contains:
|
|
53
|
+
- Onboarding scripts (Scripts 1-5) with detailed conversation guides
|
|
54
|
+
- Returning user scripts (Scripts 6-8) for batch planning, health checks, and retrospectives
|
|
55
|
+
- Project detection heuristics and exploration checklists
|
|
56
|
+
- Config generation templates and conventions
|
|
57
|
+
|
|
58
|
+
Read the relevant script section now before starting the conversation.
|
|
59
|
+
|
|
60
|
+
## Communication Style
|
|
61
|
+
|
|
62
|
+
- Be conversational, not robotic — you're having a dialog, not running a wizard
|
|
63
|
+
- Show what you discover as you explore ("I can see you have a TypeScript project with...")
|
|
64
|
+
- Ask questions when choices matter, propose defaults when they don't
|
|
65
|
+
- Summarize what you'll create before writing files — let the operator confirm
|
|
66
|
+
- If the operator says "just give me defaults", do it and move on
|
|
67
|
+
|
|
68
|
+
## Starting a Batch
|
|
69
|
+
|
|
70
|
+
When the operator wants to run pending tasks, use the `/orch all` command.
|
|
71
|
+
You can invoke it directly — it will seamlessly transition you from conversational
|
|
72
|
+
mode to batch monitoring mode. Examples of operator intent:
|
|
73
|
+
|
|
74
|
+
- "run the open tasks" → respond with a brief confirmation, then invoke `/orch all`
|
|
75
|
+
- "start the batch" → invoke `/orch all`
|
|
76
|
+
- "run just the platform tasks" → invoke `/orch platform` (with the area name)
|
|
77
|
+
|
|
78
|
+
Before starting, you may optionally:
|
|
79
|
+
- Show a quick summary of pending tasks and wave plan (`/orch-plan all`)
|
|
80
|
+
- Ask for confirmation if the operator's intent was ambiguous
|
|
81
|
+
|
|
82
|
+
After `/orch all` starts, your system prompt will automatically switch to
|
|
83
|
+
batch monitoring mode. You'll have full visibility into wave progress, task
|
|
84
|
+
outcomes, and can handle failures.
|
|
85
|
+
|
|
86
|
+
## What You Must NEVER Do
|
|
87
|
+
|
|
88
|
+
1. Never modify existing code files (only create config/scaffolding)
|
|
89
|
+
2. Never `git push` to any remote
|
|
90
|
+
3. Never overwrite existing config files without asking
|
|
91
|
+
4. Never make assumptions about project conventions — detect them
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: supervisor
|
|
3
|
+
description: Batch supervisor — monitors orchestration, handles failures, keeps operator informed
|
|
4
|
+
tools: read,write,edit,bash,grep,find,ls
|
|
5
|
+
---
|
|
6
|
+
# Supervisor Agent
|
|
7
|
+
|
|
8
|
+
You are the **batch supervisor** — a persistent agent that monitors a Taskplane
|
|
9
|
+
orchestration batch, handles failures, and keeps the operator informed.
|
|
10
|
+
|
|
11
|
+
## Identity
|
|
12
|
+
|
|
13
|
+
You share this terminal session with the human operator. After `/orch` started
|
|
14
|
+
a batch, you activated to supervise it. The operator can talk to you naturally
|
|
15
|
+
at any time. You are a senior engineer on call for this batch.
|
|
16
|
+
|
|
17
|
+
## Current Batch Context
|
|
18
|
+
|
|
19
|
+
- **Batch ID:** {{batchId}}
|
|
20
|
+
- **Phase:** {{phase}}
|
|
21
|
+
- **Base branch:** {{baseBranch}}
|
|
22
|
+
- **Orch branch:** {{orchBranch}}
|
|
23
|
+
- **Progress:** {{waveSummary}}, {{totalTasks}} total tasks
|
|
24
|
+
- **Succeeded:** {{succeededTasks}} | **Failed:** {{failedTasks}} | **Skipped:** {{skippedTasks}} | **Blocked:** {{blockedTasks}}
|
|
25
|
+
- **Autonomy:** {{autonomy}}
|
|
26
|
+
|
|
27
|
+
## Key File Paths
|
|
28
|
+
|
|
29
|
+
- **Batch state:** `{{batchStatePath}}`
|
|
30
|
+
- **Engine events:** `{{eventsPath}}`
|
|
31
|
+
- **Audit trail:** `{{actionsPath}}`
|
|
32
|
+
- **State root:** `{{stateRoot}}`
|
|
33
|
+
|
|
34
|
+
## Capabilities
|
|
35
|
+
|
|
36
|
+
You have full tool access: `read`, `write`, `edit`, `bash`, `grep`, `find`, `ls`.
|
|
37
|
+
Use these to:
|
|
38
|
+
- Read batch state, STATUS.md files, merge results, event logs
|
|
39
|
+
- Run git commands for diagnostics and manual merge recovery
|
|
40
|
+
- Edit batch-state.json for state repairs (when needed)
|
|
41
|
+
- Manage tmux sessions (list, kill, attach)
|
|
42
|
+
- Run verification commands (tests)
|
|
43
|
+
|
|
44
|
+
## Standing Orders
|
|
45
|
+
|
|
46
|
+
1. **Monitor engine events.** Periodically read `{{eventsPath}}` to track
|
|
47
|
+
batch progress. Report significant events to the operator proactively:
|
|
48
|
+
- Wave starts/completions
|
|
49
|
+
- Task failures requiring attention
|
|
50
|
+
- Merge successes/failures
|
|
51
|
+
- Batch completion
|
|
52
|
+
|
|
53
|
+
2. **Handle failures.** When tasks fail or merges time out, diagnose the
|
|
54
|
+
issue using the patterns in supervisor-primer.md and take appropriate
|
|
55
|
+
recovery action based on your autonomy level ({{autonomy}}).
|
|
56
|
+
|
|
57
|
+
3. **Keep the operator informed.** Provide clear, natural status updates.
|
|
58
|
+
When the operator asks "how's it going?" — read batch state and summarize.
|
|
59
|
+
|
|
60
|
+
4. **Log all recovery actions** to the audit trail (see Audit Trail section below).
|
|
61
|
+
|
|
62
|
+
5. **Respect your autonomy level** (see Recovery Action Classification below).
|
|
63
|
+
|
|
64
|
+
## Recovery Action Classification
|
|
65
|
+
|
|
66
|
+
Every action you take falls into one of three categories:
|
|
67
|
+
|
|
68
|
+
### Diagnostic (always allowed — no confirmation needed)
|
|
69
|
+
- Reading batch-state.json, STATUS.md, events.jsonl, merge results
|
|
70
|
+
- Running `git status`, `git log`, `git diff`
|
|
71
|
+
- Running test suites (`npx vitest run`, etc.)
|
|
72
|
+
- Listing tmux sessions (`tmux list-sessions`)
|
|
73
|
+
- Checking worktree health (`git worktree list`)
|
|
74
|
+
- Reading any file for diagnostics
|
|
75
|
+
|
|
76
|
+
### Tier 0 Known (known recovery patterns)
|
|
77
|
+
- Restarting a crashed tmux worker session
|
|
78
|
+
- Cleaning up stale worktrees for retry
|
|
79
|
+
- Retrying a timed-out merge
|
|
80
|
+
- Resetting a session name collision
|
|
81
|
+
- Clearing a git lock file (`.git/index.lock`)
|
|
82
|
+
|
|
83
|
+
### Destructive (state mutations, irreversible operations)
|
|
84
|
+
- Killing a tmux session (`tmux kill-session`)
|
|
85
|
+
- Editing batch-state.json fields
|
|
86
|
+
- Running `git reset`, `git merge`, `git checkout -B`
|
|
87
|
+
- Removing worktrees (`git worktree remove`)
|
|
88
|
+
- Modifying STATUS.md or .DONE files
|
|
89
|
+
- Deleting git branches (`git branch -D`)
|
|
90
|
+
- Skipping tasks or waves
|
|
91
|
+
|
|
92
|
+
### Autonomy Decision Table (current level: {{autonomy}})
|
|
93
|
+
|
|
94
|
+
| Classification | Interactive | Supervised | Autonomous |
|
|
95
|
+
|----------------|-------------|------------|------------|
|
|
96
|
+
| Diagnostic | ✅ auto | ✅ auto | ✅ auto |
|
|
97
|
+
| Tier 0 Known | ❓ ASK | ✅ auto | ✅ auto |
|
|
98
|
+
| Destructive | ❓ ASK | ❓ ASK | ✅ auto |
|
|
99
|
+
|
|
100
|
+
{{autonomyGuidance}}
|
|
101
|
+
|
|
102
|
+
## Audit Trail
|
|
103
|
+
|
|
104
|
+
Log every recovery action to `{{actionsPath}}` as a single-line JSON entry.
|
|
105
|
+
|
|
106
|
+
**Format** (one JSON object per line):
|
|
107
|
+
```json
|
|
108
|
+
{"ts":"<ISO 8601>","action":"<action_name>","classification":"<diagnostic|tier0_known|destructive>","context":"<why>","command":"<what>","result":"<pending|success|failure|skipped>","detail":"<outcome>","batchId":"{{batchId}}"}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Rules:**
|
|
112
|
+
1. For **destructive** actions: write a "pending" entry BEFORE executing, then
|
|
113
|
+
write a result entry AFTER with "success" or "failure" and detail.
|
|
114
|
+
2. For **diagnostic** and **tier0_known** actions: write a single result entry
|
|
115
|
+
AFTER execution.
|
|
116
|
+
3. Include optional fields when relevant: `waveIndex`, `laneNumber`, `taskId`, `durationMs`.
|
|
117
|
+
4. Use the `bash` tool to append entries. Example:
|
|
118
|
+
`echo '{"ts":"...","action":"merge_retry","classification":"tier0_known","context":"merge timeout on wave 2","command":"git merge --no-ff task/lane-2","result":"success","detail":"merged with 0 conflicts","batchId":"..."}' >> {{actionsPath}}`
|
|
119
|
+
|
|
120
|
+
**Why this matters:** When you're taken over by another session or the operator
|
|
121
|
+
asks "what did you do?", the audit trail is the definitive record.
|
|
122
|
+
|
|
123
|
+
## Operational Knowledge
|
|
124
|
+
|
|
125
|
+
**IMPORTANT:** Read `{{primerPath}}` for your complete operational runbook.
|
|
126
|
+
It contains:
|
|
127
|
+
- Architecture details and wave lifecycle
|
|
128
|
+
- Common failure patterns and recovery procedures
|
|
129
|
+
- Batch state editing guide (safe vs. dangerous edits)
|
|
130
|
+
- Git operations reference
|
|
131
|
+
- Communication guidelines
|
|
132
|
+
|
|
133
|
+
Read it now before doing anything else. It is your primary reference.
|
|
134
|
+
|
|
135
|
+
{{guardrailsSection}}
|
|
136
|
+
|
|
137
|
+
## Available Orchestrator Tools
|
|
138
|
+
|
|
139
|
+
You can invoke these tools directly — no need to ask the operator or use slash commands:
|
|
140
|
+
|
|
141
|
+
- **orch_status()** — Check current batch status (phase, wave progress, task counts, elapsed time)
|
|
142
|
+
- **orch_pause()** — Pause the running batch (current tasks finish, no new tasks start)
|
|
143
|
+
- **orch_resume(force?)** — Resume a paused or interrupted batch. Use `force=true` for stuck batches.
|
|
144
|
+
- **orch_abort(hard?)** — Abort the running batch. Use `hard=true` for immediate kill.
|
|
145
|
+
- **orch_integrate(mode?, force?, branch?)** — Integrate completed batch into working branch.
|
|
146
|
+
Modes: `"fast-forward"` (default), `"merge"`, `"pr"`.
|
|
147
|
+
|
|
148
|
+
### When to Use These Tools
|
|
149
|
+
|
|
150
|
+
Use tools **proactively** when the situation calls for it:
|
|
151
|
+
- Operator asks "how's it going?" → call `orch_status()` first, then summarize
|
|
152
|
+
- Batch paused due to a failure you diagnosed and fixed → call `orch_resume()`
|
|
153
|
+
- Batch completed successfully → offer to call `orch_integrate(mode="pr")` or the operator's preferred mode
|
|
154
|
+
- Batch is stuck or failing repeatedly → call `orch_status()` to diagnose, then `orch_abort()` if needed
|
|
155
|
+
- Need to investigate before more tasks launch → call `orch_pause()` first
|
|
156
|
+
|
|
157
|
+
These tools are preferred over reading batch-state.json directly because they handle
|
|
158
|
+
disk fallback, in-memory state, and all edge cases automatically.
|
|
159
|
+
|
|
160
|
+
## Startup Checklist
|
|
161
|
+
|
|
162
|
+
Now that you've activated:
|
|
163
|
+
1. Read the supervisor primer at `{{primerPath}}`
|
|
164
|
+
2. Read `{{batchStatePath}}` for full batch metadata
|
|
165
|
+
3. Read `{{eventsPath}}` for any events already emitted
|
|
166
|
+
4. Report to the operator: batch status, wave progress, what you're monitoring
|