fifony 0.1.21 → 0.1.22
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 +7 -0
- package/app/dist/assets/{KeyboardShortcutsHelp-BTjiQe_Y.js → KeyboardShortcutsHelp-DFstgyXD.js} +1 -1
- package/app/dist/assets/OnboardingWizard-Daehu2Uj.js +1 -0
- package/app/dist/assets/analytics.lazy-C1-iSRM_.js +1 -0
- package/app/dist/assets/{createLucideIcon-DtZs0TX0.js → createLucideIcon-BWC-guQt.js} +1 -1
- package/app/dist/assets/index-DbIrs0MK.css +1 -0
- package/app/dist/assets/index-O_FDwkw6.js +43 -0
- package/app/dist/assets/vendor-BTlTWMUF.js +9 -0
- package/app/dist/index.html +4 -5
- package/app/dist/service-worker.js +1 -1
- package/bin/fifony-wrap.js +53 -0
- package/dist/agent/cli-wrapper.js +78 -0
- package/dist/agent/cli-wrapper.js.map +1 -0
- package/dist/agent/run-local.js +93 -7889
- package/dist/agent/run-local.js.map +1 -1
- package/dist/chunk-F6JEQIP2.js +449 -0
- package/dist/chunk-F6JEQIP2.js.map +1 -0
- package/dist/{chunk-SMGXYOWU.js → chunk-O665NS5E.js} +411 -9
- package/dist/chunk-O665NS5E.js.map +1 -0
- package/dist/chunk-VP6TGOMT.js +8915 -0
- package/dist/chunk-VP6TGOMT.js.map +1 -0
- package/dist/cli.js +182 -0
- package/dist/cli.js.map +1 -1
- package/dist/issue-runner-MDCJ4G26.js +11 -0
- package/dist/issue-runner-MDCJ4G26.js.map +1 -0
- package/dist/mcp/server.js +589 -595
- package/dist/mcp/server.js.map +1 -1
- package/dist/queue-workers-LAYOT4E5.js +21 -0
- package/dist/queue-workers-LAYOT4E5.js.map +1 -0
- package/package.json +10 -9
- package/app/dist/assets/OnboardingWizard-BALlquG0.js +0 -1
- package/app/dist/assets/analytics.lazy-DjSzXIey.js +0 -1
- package/app/dist/assets/index-BV11ScVl.js +0 -42
- package/app/dist/assets/index-DWbxgKSd.css +0 -1
- package/app/dist/assets/vendor-BoGBoEwT.js +0 -9
- package/app/dist/assets/zap-DpjdVd1i.js +0 -1
- package/dist/chunk-SMGXYOWU.js.map +0 -1
|
@@ -1,3 +1,254 @@
|
|
|
1
|
+
// src/agent/constants.ts
|
|
2
|
+
import { basename, dirname, join, resolve } from "path";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
|
+
import { env, argv, cwd as getCwd } from "process";
|
|
5
|
+
import { homedir } from "os";
|
|
6
|
+
var __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
var __dirname = dirname(__filename);
|
|
8
|
+
var PACKAGE_ROOT = resolve(__dirname, "../..");
|
|
9
|
+
var CLI_ARGS = argv.slice(2);
|
|
10
|
+
function readArgValue(args, flag) {
|
|
11
|
+
const index = args.indexOf(flag);
|
|
12
|
+
if (index === -1) return void 0;
|
|
13
|
+
const value = args[index + 1];
|
|
14
|
+
if (!value || value.startsWith("--")) return void 0;
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
function resolveInputPath(value) {
|
|
18
|
+
if (value.startsWith("~/")) {
|
|
19
|
+
return resolve(homedir(), value.slice(2));
|
|
20
|
+
}
|
|
21
|
+
return resolve(value);
|
|
22
|
+
}
|
|
23
|
+
function resolvePersistenceRoot(value) {
|
|
24
|
+
const resolved = value.startsWith("file://") ? fileURLToPath(value) : resolveInputPath(value);
|
|
25
|
+
return basename(resolved) === ".fifony" ? resolved : join(resolved, ".fifony");
|
|
26
|
+
}
|
|
27
|
+
var CLI_WORKSPACE_ROOT = readArgValue(CLI_ARGS, "--workspace");
|
|
28
|
+
var CLI_PERSISTENCE = readArgValue(CLI_ARGS, "--persistence");
|
|
29
|
+
var TARGET_ROOT = resolveInputPath(
|
|
30
|
+
env.FIFONY_WORKSPACE_ROOT ?? CLI_WORKSPACE_ROOT ?? getCwd()
|
|
31
|
+
);
|
|
32
|
+
var STATE_ROOT = resolvePersistenceRoot(
|
|
33
|
+
env.FIFONY_PERSISTENCE ?? CLI_PERSISTENCE ?? env.FIFONY_BOOTSTRAP_ROOT ?? TARGET_ROOT
|
|
34
|
+
);
|
|
35
|
+
var SOURCE_ROOT = `${STATE_ROOT}/source`;
|
|
36
|
+
var WORKSPACE_ROOT = `${STATE_ROOT}/workspaces`;
|
|
37
|
+
var SOURCE_MARKER = `${SOURCE_ROOT}/.fifony-local-source-ready`;
|
|
38
|
+
var ATTACHMENTS_ROOT = `${STATE_ROOT}/attachments`;
|
|
39
|
+
var S3DB_DATABASE_PATH = `${STATE_ROOT}/s3db`;
|
|
40
|
+
var S3DB_BUCKET = env.FIFONY_STORAGE_BUCKET ?? "fifony";
|
|
41
|
+
var S3DB_KEY_PREFIX = env.FIFONY_STORAGE_KEY_PREFIX ?? "state";
|
|
42
|
+
var S3DB_RUNTIME_RESOURCE = "runtime_state";
|
|
43
|
+
var S3DB_ISSUE_RESOURCE = "issues";
|
|
44
|
+
var S3DB_ISSUE_PLAN_RESOURCE = "issue_plans";
|
|
45
|
+
var S3DB_EVENT_RESOURCE = "events";
|
|
46
|
+
var S3DB_SETTINGS_RESOURCE = "settings";
|
|
47
|
+
var S3DB_AGENT_SESSION_RESOURCE = "agent_sessions";
|
|
48
|
+
var S3DB_AGENT_PIPELINE_RESOURCE = "agent_pipelines";
|
|
49
|
+
var S3DB_RUNTIME_RECORD_ID = "current";
|
|
50
|
+
var S3DB_RUNTIME_SCHEMA_VERSION = 1;
|
|
51
|
+
var FRONTEND_DIR = `${PACKAGE_ROOT}/app/dist`;
|
|
52
|
+
var FRONTEND_INDEX = `${FRONTEND_DIR}/index.html`;
|
|
53
|
+
var FRONTEND_MANIFEST_JSON = `${FRONTEND_DIR}/manifest.webmanifest`;
|
|
54
|
+
var FRONTEND_SERVICE_WORKER_JS = `${FRONTEND_DIR}/service-worker.js`;
|
|
55
|
+
var FRONTEND_ICON_SVG = `${FRONTEND_DIR}/icon.svg`;
|
|
56
|
+
var FRONTEND_MASKABLE_ICON_SVG = `${FRONTEND_DIR}/icon-maskable.svg`;
|
|
57
|
+
var FRONTEND_OFFLINE_HTML = `${FRONTEND_DIR}/offline.html`;
|
|
58
|
+
var DEBUG_BOOT = env.FIFONY_DEBUG_BOOT === "1";
|
|
59
|
+
var ALLOWED_STATES = [
|
|
60
|
+
"Planning",
|
|
61
|
+
"Planned",
|
|
62
|
+
"Queued",
|
|
63
|
+
"Running",
|
|
64
|
+
"Reviewing",
|
|
65
|
+
"Reviewed",
|
|
66
|
+
"Blocked",
|
|
67
|
+
"Done",
|
|
68
|
+
"Cancelled"
|
|
69
|
+
];
|
|
70
|
+
var TERMINAL_STATES = /* @__PURE__ */ new Set(["Done", "Cancelled"]);
|
|
71
|
+
var EXECUTING_STATES = /* @__PURE__ */ new Set(["Running", "Reviewing"]);
|
|
72
|
+
var PERSIST_EVENTS_MAX = 500;
|
|
73
|
+
var FAST_BOOT = CLI_ARGS.includes("--fast-boot");
|
|
74
|
+
var SKIP_SOURCE = FAST_BOOT || CLI_ARGS.includes("--skip-source");
|
|
75
|
+
var SKIP_SCAN = FAST_BOOT || CLI_ARGS.includes("--skip-scan");
|
|
76
|
+
var SKIP_RECOVERY = FAST_BOOT || CLI_ARGS.includes("--skip-recovery");
|
|
77
|
+
|
|
78
|
+
// src/agent/helpers.ts
|
|
79
|
+
import { env as env2 } from "process";
|
|
80
|
+
import { parse as parseYaml } from "yaml";
|
|
81
|
+
function now() {
|
|
82
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
83
|
+
}
|
|
84
|
+
function isoWeek(date) {
|
|
85
|
+
const d = date ? new Date(date) : /* @__PURE__ */ new Date();
|
|
86
|
+
if (Number.isNaN(d.getTime())) return "";
|
|
87
|
+
const tmp = new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()));
|
|
88
|
+
const dayNum = tmp.getUTCDay() || 7;
|
|
89
|
+
tmp.setUTCDate(tmp.getUTCDate() + 4 - dayNum);
|
|
90
|
+
const yearStart = new Date(Date.UTC(tmp.getUTCFullYear(), 0, 1));
|
|
91
|
+
const weekNo = Math.ceil(((tmp.getTime() - yearStart.getTime()) / 864e5 + 1) / 7);
|
|
92
|
+
return `${tmp.getUTCFullYear()}-W${String(weekNo).padStart(2, "0")}`;
|
|
93
|
+
}
|
|
94
|
+
function sleep(ms) {
|
|
95
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
96
|
+
}
|
|
97
|
+
function resolveEnvVar(value) {
|
|
98
|
+
if (!value.startsWith("$")) return value;
|
|
99
|
+
const varName = value.slice(1);
|
|
100
|
+
const resolved = env2[varName];
|
|
101
|
+
return resolved && resolved.trim().length > 0 ? resolved.trim() : "";
|
|
102
|
+
}
|
|
103
|
+
function toStringValue(value, fallback = "") {
|
|
104
|
+
if (typeof value !== "string" || value.trim().length === 0) return fallback;
|
|
105
|
+
const trimmed = value.trim();
|
|
106
|
+
if (trimmed.startsWith("$") && /^\$[A-Za-z_][A-Za-z0-9_]*$/.test(trimmed)) {
|
|
107
|
+
const resolved = resolveEnvVar(trimmed);
|
|
108
|
+
return resolved.length > 0 ? resolved : fallback;
|
|
109
|
+
}
|
|
110
|
+
return trimmed;
|
|
111
|
+
}
|
|
112
|
+
function toNumberValue(value, fallback = 1) {
|
|
113
|
+
const parsed = typeof value === "number" ? value : typeof value === "string" ? Number.parseInt(value, 10) : Number.NaN;
|
|
114
|
+
return Number.isFinite(parsed) && parsed > 0 ? Math.round(parsed) : fallback;
|
|
115
|
+
}
|
|
116
|
+
function toStringArray(value) {
|
|
117
|
+
if (!Array.isArray(value)) return [];
|
|
118
|
+
return value.filter((entry) => typeof entry === "string" && entry.trim().length > 0).map((entry) => entry.trim());
|
|
119
|
+
}
|
|
120
|
+
function clamp(value, min, max) {
|
|
121
|
+
return Math.min(Math.max(value, min), max);
|
|
122
|
+
}
|
|
123
|
+
function parseIssueState(value) {
|
|
124
|
+
const raw = typeof value === "string" ? value.trim() : "";
|
|
125
|
+
if (ALLOWED_STATES.includes(raw)) {
|
|
126
|
+
return raw;
|
|
127
|
+
}
|
|
128
|
+
return void 0;
|
|
129
|
+
}
|
|
130
|
+
function normalizeState(value, fallback = "Planning") {
|
|
131
|
+
return parseIssueState(value) ?? fallback;
|
|
132
|
+
}
|
|
133
|
+
function parseEnvNumber(name, fallback) {
|
|
134
|
+
return toNumberValue(env2[name], fallback);
|
|
135
|
+
}
|
|
136
|
+
function parseIntArg(value, fallback) {
|
|
137
|
+
const parsed = Number.parseInt(value, 10);
|
|
138
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
139
|
+
}
|
|
140
|
+
function parsePositiveIntEnv(name, fallback) {
|
|
141
|
+
const source = env2[name];
|
|
142
|
+
if (!source) return fallback;
|
|
143
|
+
return parseIntArg(source, fallback);
|
|
144
|
+
}
|
|
145
|
+
function withRetryBackoff(attempt, baseDelayMs) {
|
|
146
|
+
return Math.min(baseDelayMs * 2 ** attempt, 5 * 60 * 1e3);
|
|
147
|
+
}
|
|
148
|
+
function idToSafePath(value) {
|
|
149
|
+
return value.toLowerCase().replace(/[^a-z0-9._-]/g, "-");
|
|
150
|
+
}
|
|
151
|
+
function appendFileTail(target, text, maxLength) {
|
|
152
|
+
const merged = `${target}
|
|
153
|
+
${text}`;
|
|
154
|
+
if (merged.length <= maxLength) return merged;
|
|
155
|
+
return `\u2026${merged.slice(-(maxLength - 1))}`;
|
|
156
|
+
}
|
|
157
|
+
function debugBoot(message) {
|
|
158
|
+
if (!DEBUG_BOOT) return;
|
|
159
|
+
console.error(`[FIFONY_DEBUG_BOOT] ${message}`);
|
|
160
|
+
}
|
|
161
|
+
function fail(message) {
|
|
162
|
+
console.error(message);
|
|
163
|
+
process.exit(1);
|
|
164
|
+
}
|
|
165
|
+
function extractJsonObjects(text) {
|
|
166
|
+
const results = [];
|
|
167
|
+
let depth = 0;
|
|
168
|
+
let start = -1;
|
|
169
|
+
let inStr = false;
|
|
170
|
+
let esc = false;
|
|
171
|
+
for (let i = 0; i < text.length; i++) {
|
|
172
|
+
const ch = text[i];
|
|
173
|
+
if (inStr) {
|
|
174
|
+
if (esc) {
|
|
175
|
+
esc = false;
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
if (ch === "\\") {
|
|
179
|
+
esc = true;
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
if (ch === '"') {
|
|
183
|
+
inStr = false;
|
|
184
|
+
}
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
if (ch === '"') {
|
|
188
|
+
inStr = true;
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
if (ch === "{") {
|
|
192
|
+
if (depth === 0) start = i;
|
|
193
|
+
depth++;
|
|
194
|
+
} else if (ch === "}") {
|
|
195
|
+
depth = Math.max(0, depth - 1);
|
|
196
|
+
if (depth === 0 && start >= 0) {
|
|
197
|
+
results.push(text.slice(start, i + 1));
|
|
198
|
+
start = -1;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return results;
|
|
203
|
+
}
|
|
204
|
+
function repairTruncatedJson(text) {
|
|
205
|
+
const firstBrace = text.indexOf("{");
|
|
206
|
+
if (firstBrace < 0) return null;
|
|
207
|
+
let json = text.slice(firstBrace);
|
|
208
|
+
let inStr = false;
|
|
209
|
+
let esc = false;
|
|
210
|
+
const stack = [];
|
|
211
|
+
for (let i = 0; i < json.length; i++) {
|
|
212
|
+
const ch = json[i];
|
|
213
|
+
if (inStr) {
|
|
214
|
+
if (esc) {
|
|
215
|
+
esc = false;
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
if (ch === "\\") {
|
|
219
|
+
esc = true;
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
if (ch === '"') {
|
|
223
|
+
inStr = false;
|
|
224
|
+
}
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
if (ch === '"') {
|
|
228
|
+
inStr = true;
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
if (ch === "{") stack.push("{");
|
|
232
|
+
else if (ch === "[") stack.push("[");
|
|
233
|
+
else if (ch === "}") {
|
|
234
|
+
if (stack.length > 0 && stack[stack.length - 1] === "{") stack.pop();
|
|
235
|
+
} else if (ch === "]") {
|
|
236
|
+
if (stack.length > 0 && stack[stack.length - 1] === "[") stack.pop();
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (!inStr && stack.length === 0) return json;
|
|
240
|
+
if (inStr) {
|
|
241
|
+
if (json.endsWith("\\")) json = json.slice(0, -1);
|
|
242
|
+
json += '"';
|
|
243
|
+
}
|
|
244
|
+
json = json.replace(/[,:\s]+$/, "");
|
|
245
|
+
while (stack.length > 0) {
|
|
246
|
+
const open = stack.pop();
|
|
247
|
+
json += open === "{" ? "}" : "]";
|
|
248
|
+
}
|
|
249
|
+
return json;
|
|
250
|
+
}
|
|
251
|
+
|
|
1
252
|
// src/routing/capability-resolver.ts
|
|
2
253
|
function tokenize(issue) {
|
|
3
254
|
const labels = (issue.labels ?? []).filter((label) => !label.startsWith("capability:") && !label.startsWith("overlay:"));
|
|
@@ -305,11 +556,114 @@ var PROMPT_TEMPLATES = {
|
|
|
305
556
|
// src/prompts/integrations-agency-agents.stub.md
|
|
306
557
|
"integrations-impeccable": '# Impeccable integration idea\n\nUse impeccable-oriented skills as a frontend review layer around fifony issues.\n\nSuggested pattern:\n\n1. Use `agency-senior-developer` or `codex` as executor.\n2. Route UI-heavy issues to a reviewer prompt that explicitly asks for impeccable-style critique.\n3. Expose the resulting review through the fifony MCP prompts or as a follow-up review issue.\n\nSuggested labels:\n- frontend\n- ui\n- design-system\n\nSuggested reviewer prompt seed:\n"Review this implementation using impeccable standards for frontend quality, polish, hierarchy, spacing, responsiveness, and interaction clarity."\n',
|
|
307
558
|
// src/prompts/integrations-impeccable.stub.md
|
|
308
|
-
"issue-enhancer-description":
|
|
559
|
+
"issue-enhancer-description": `You are helping improve issue metadata for a software execution queue.
|
|
560
|
+
Rewrite the description to be clearer, complete, and directly actionable.
|
|
561
|
+
Return strict JSON only with this schema:
|
|
562
|
+
{ "field": "description", "value": "..." }
|
|
563
|
+
|
|
564
|
+
Issue type: {{issueType}}
|
|
565
|
+
Current title: {{title}}
|
|
566
|
+
Current description: {{description}}
|
|
567
|
+
{{#if images}}
|
|
568
|
+
Visual evidence (attached screenshots for context):
|
|
569
|
+
{{#each images}}
|
|
570
|
+
- {{this}}
|
|
571
|
+
{{/each}}
|
|
572
|
+
{{/if}}
|
|
573
|
+
|
|
574
|
+
Rules:
|
|
575
|
+
- Keep it concise but include meaningful acceptance criteria tailored to the issue type.
|
|
576
|
+
- For "bug": focus on problem description, expected behavior, and steps to reproduce.
|
|
577
|
+
- For "feature": focus on goal, acceptance criteria, and any relevant notes.
|
|
578
|
+
- For "refactor": describe current state, desired state, and scope.
|
|
579
|
+
- For "docs": describe what to document and target audience.
|
|
580
|
+
- For "chore": describe the task and why it's needed now.
|
|
581
|
+
- Use markdown formatting appropriate for the type (## headings, bullet points).
|
|
582
|
+
- Avoid extra wrappers, outer quotes, or extra explanation.
|
|
583
|
+
- The value should be in Portuguese if the input is in Portuguese; otherwise in English.
|
|
584
|
+
`,
|
|
309
585
|
// src/prompts/issue-enhancer-description.stub.md
|
|
310
|
-
"issue-enhancer-title": 'You are helping improve issue metadata for a software execution queue.\nRewrite the title for clarity, actionability, and specificity.\nReturn strict JSON only with this schema:\n{ "field": "title", "value": "..." }\n\nCurrent title: {{title}}\nDescription context: {{description}}\n\nRules:\n- Keep it concise and suitable as a task title.\n- Use imperative language when possible.\n- Do not include markdown, quotes, or extra explanation.\n- The value should be in Portuguese if the input is in Portuguese; otherwise in English.\n',
|
|
586
|
+
"issue-enhancer-title": 'You are helping improve issue metadata for a software execution queue.\nRewrite the title for clarity, actionability, and specificity.\nReturn strict JSON only with this schema:\n{ "field": "title", "value": "..." }\n\nIssue type: {{issueType}}\nCurrent title: {{title}}\nDescription context: {{description}}\n{{#if images}}\nVisual evidence (attached screenshots for context):\n{{#each images}}\n- {{this}}\n{{/each}}\n{{/if}}\n\nRules:\n- Keep it concise and suitable as a task title.\n- Use imperative language when possible.\n- If the issue type is "bug", start with "fix: ". If "feature", start with "feat: ". If "refactor", start with "refactor: ". If "docs", start with "docs: ". If "chore", start with "chore: ". For "blank", use no prefix.\n- Do not include markdown, quotes, or extra explanation.\n- The value should be in Portuguese if the input is in Portuguese; otherwise in English.\n',
|
|
311
587
|
// src/prompts/issue-enhancer-title.stub.md
|
|
312
|
-
"issue-planner":
|
|
588
|
+
"issue-planner": `You are a senior technical execution planner.
|
|
589
|
+
Produce the best possible plan for the issue below, filling the JSON schema precisely.
|
|
590
|
+
{{#if fast}}
|
|
591
|
+
|
|
592
|
+
FAST MODE: Be brief and direct. Minimize reasoning depth.
|
|
593
|
+
- 2-4 steps maximum. Skip optional fields (unknowns, risks, alternatives).
|
|
594
|
+
- No tooling reflection needed \u2014 set shouldUseSkills: false, shouldUseSubagents: false.
|
|
595
|
+
- Focus only on: summary, steps, estimatedComplexity, suggestedPaths, suggestedLabels.
|
|
596
|
+
{{/if}}
|
|
597
|
+
|
|
598
|
+
Issue title: {{title}}
|
|
599
|
+
Issue description: {{description}}
|
|
600
|
+
{{#if images}}
|
|
601
|
+
Visual evidence (attached screenshots for context):
|
|
602
|
+
{{#each images}}
|
|
603
|
+
- {{this}}
|
|
604
|
+
{{/each}}
|
|
605
|
+
{{/if}}
|
|
606
|
+
{{#unless fast}}
|
|
607
|
+
|
|
608
|
+
Quality rules:
|
|
609
|
+
- Be concrete, not generic. No vague phrases like 'implement' or 'improve' without detail.
|
|
610
|
+
- Break work into actionable steps (2-8 steps). Each step describes WHAT, not HOW.
|
|
611
|
+
- Each step must have a clear 'doneWhen' acceptance criterion.
|
|
612
|
+
- Identify assumptions, constraints, unknowns, and risks.
|
|
613
|
+
- For unknowns, specify what question needs answering and how to resolve it.
|
|
614
|
+
- Suggest file paths that are likely relevant to the changes.
|
|
615
|
+
- Suggest labels: bug, feature, frontend, backend, docs, refactor, security, performance, etc.
|
|
616
|
+
|
|
617
|
+
Complexity estimation:
|
|
618
|
+
- trivial: < 5 min, single-file cosmetic change
|
|
619
|
+
- low: 5-15 min, small focused change
|
|
620
|
+
- medium: 15-60 min, multi-file change with testing
|
|
621
|
+
- high: > 1 hour, architectural change or new feature
|
|
622
|
+
|
|
623
|
+
Tooling reflection (REQUIRED):
|
|
624
|
+
- Evaluate whether the task benefits from using skills (specialized instructions for quality/consistency).
|
|
625
|
+
- Evaluate whether subtasks should use subagents (parallel work, isolated context, specialization).
|
|
626
|
+
- Only recommend skills/agents when there is a concrete justification.
|
|
627
|
+
- For each step, set ownerType: 'agent' for automated work, 'human' for manual review, 'skill' for specialized skills, 'subagent' for delegated work.
|
|
628
|
+
|
|
629
|
+
Effort suggestion:
|
|
630
|
+
- low: simple fixes, no deep reasoning needed
|
|
631
|
+
- medium: standard development work
|
|
632
|
+
- high: complex architecture, security, or cross-cutting changes
|
|
633
|
+
- Set per-role if different: planner, executor, reviewer
|
|
634
|
+
{{/unless}}
|
|
635
|
+
|
|
636
|
+
Return strict JSON matching EXACTLY this schema. No text outside JSON. Use these exact field names:
|
|
637
|
+
|
|
638
|
+
\`\`\`json
|
|
639
|
+
{
|
|
640
|
+
"summary": "one-line summary of what needs to be done",
|
|
641
|
+
"estimatedComplexity": "trivial|low|medium|high",
|
|
642
|
+
"steps": [
|
|
643
|
+
{
|
|
644
|
+
"step": 1,
|
|
645
|
+
"action": "what to do (concrete, specific)",
|
|
646
|
+
"files": ["path/to/file.ts"],
|
|
647
|
+
"details": "additional context if needed",
|
|
648
|
+
"ownerType": "agent|human|skill|subagent|tool",
|
|
649
|
+
"doneWhen": "acceptance criterion as a single string"
|
|
650
|
+
}
|
|
651
|
+
],
|
|
652
|
+
"assumptions": ["..."],
|
|
653
|
+
"constraints": ["..."],
|
|
654
|
+
"unknowns": [
|
|
655
|
+
{ "question": "...", "whyItMatters": "...", "howToResolve": "..." }
|
|
656
|
+
],
|
|
657
|
+
"successCriteria": ["..."],
|
|
658
|
+
"risks": [
|
|
659
|
+
{ "risk": "...", "impact": "...", "mitigation": "..." }
|
|
660
|
+
],
|
|
661
|
+
"suggestedPaths": ["path/to/relevant/file.ts"],
|
|
662
|
+
"suggestedLabels": ["frontend", "bug", "feature", "..."],
|
|
663
|
+
"suggestedEffort": { "default": "medium", "planner": "low", "executor": "medium", "reviewer": "medium" }
|
|
664
|
+
}
|
|
665
|
+
\`\`\`
|
|
666
|
+
`,
|
|
313
667
|
// src/prompts/issue-planner.stub.md
|
|
314
668
|
"issue-planner-refine": "You are a senior technical execution planner refining an existing plan based on user feedback.\n\n## Original Issue\nTitle: {{title}}\nDescription: {{description}}\n\n## Current Plan (JSON)\n```json\n{{currentPlan}}\n```\n\n## User Feedback\n{{feedback}}\n\n## Instructions\n\nRevise the plan above to address the user's feedback precisely.\n\nRules:\n- Keep all parts of the plan that are NOT affected by the feedback unchanged.\n- Only modify, add, or remove elements that the feedback specifically requests.\n- Preserve the same JSON schema structure as the current plan.\n- Maintain step numbering consistency after changes.\n- If feedback asks to add steps, insert them in the logical position and renumber.\n- If feedback asks to remove steps, renumber remaining steps sequentially.\n- Update the summary if the overall direction changed.\n- Re-evaluate estimatedComplexity if the scope changed significantly.\n- Update suggestedPaths and suggestedLabels if affected by the changes.\n\nReturn strict JSON. No text outside JSON.\n",
|
|
315
669
|
// src/prompts/issue-planner-refine.stub.md
|
|
@@ -317,9 +671,9 @@ var PROMPT_TEMPLATES = {
|
|
|
317
671
|
// src/prompts/mcp-integrate-client.stub.md
|
|
318
672
|
"mcp-integration-guide": '# fifony MCP integration\n\nWorkspace root: `{{workspaceRoot}}`\nPersistence root: `{{persistenceRoot}}`\nState root: `{{stateRoot}}`\n\nRecommended MCP client command:\n\n```json\n{\n "mcpServers": {\n "fifony": {\n "command": "npx",\n "args": ["fifony", "mcp", "--workspace", "{{workspaceRoot}}", "--persistence", "{{persistenceRoot}}"]\n }\n }\n}\n```\n\nExpected workflow:\n\n1. Read `fifony://guide/overview` and `fifony://state/summary`.\n2. Use `fifony.list_issues` or read `fifony://issues`.\n3. Create work with `fifony.create_issue`.\n4. Update workflow state with `fifony.update_issue_state`.\n5. Use the prompts exposed by this MCP server to structure planning or execution.\n\nThe MCP server is read-write against the same `s3db` filesystem store used by the fifony runtime.\n',
|
|
319
673
|
// src/prompts/mcp-integration-guide.stub.md
|
|
320
|
-
"mcp-issue": 'You are integrating with fifony as the {{role}} using {{provider}}.\n\nIssue ID: {{id}}\nTitle: {{title}}\nState: {{state}}\nCapability category: {{capabilityCategory}}\n{{#if overlays.length}}\nOverlays: {{overlays | join ", "}}\n{{/if}}\n{{#if paths.length}}\nPaths: {{paths | join ", "}}\n{{/if}}\nDescription:\n{{description}}\n\nUse fifony as the source of truth:\n-
|
|
674
|
+
"mcp-issue": 'You are integrating with fifony as the {{role}} using {{provider}}.\n\nIssue ID: {{id}}\nTitle: {{title}}\nState: {{state}}\nCapability category: {{capabilityCategory}}\n{{#if overlays.length}}\nOverlays: {{overlays | join ", "}}\n{{/if}}\n{{#if paths.length}}\nPaths: {{paths | join ", "}}\n{{/if}}\nDescription:\n{{description}}\n\nUse fifony as the source of truth:\n- Persist transitions through the fifony tools instead of inventing local state.\n- Keep outputs actionable and aligned with the tracked issue lifecycle.\n',
|
|
321
675
|
// src/prompts/mcp-issue.stub.md
|
|
322
|
-
"mcp-review-workflow": "Review the
|
|
676
|
+
"mcp-review-workflow": "Review the pipeline configuration for this fifony workspace as {{provider}}.\n\nWorkspace: {{workspaceRoot}}\n\nFocus on:\n- provider orchestration quality (plan/execute/review stages)\n- hooks safety (beforeRun, afterRun, afterCreate, beforeRemove)\n- prompt clarity\n- issue lifecycle correctness\n- what an MCP client needs in order to integrate cleanly\n",
|
|
323
677
|
// src/prompts/mcp-review-workflow.stub.md
|
|
324
678
|
"mcp-route-task": "Use this routing decision as the execution plan for the task.\n\n{{resolutionJson}}\n",
|
|
325
679
|
// src/prompts/mcp-route-task.stub.md
|
|
@@ -373,11 +727,59 @@ async function renderPromptString(template, context = {}) {
|
|
|
373
727
|
}
|
|
374
728
|
|
|
375
729
|
export {
|
|
730
|
+
PACKAGE_ROOT,
|
|
731
|
+
CLI_ARGS,
|
|
732
|
+
TARGET_ROOT,
|
|
733
|
+
STATE_ROOT,
|
|
734
|
+
SOURCE_ROOT,
|
|
735
|
+
WORKSPACE_ROOT,
|
|
736
|
+
SOURCE_MARKER,
|
|
737
|
+
ATTACHMENTS_ROOT,
|
|
738
|
+
S3DB_DATABASE_PATH,
|
|
739
|
+
S3DB_BUCKET,
|
|
740
|
+
S3DB_KEY_PREFIX,
|
|
741
|
+
S3DB_RUNTIME_RESOURCE,
|
|
742
|
+
S3DB_ISSUE_RESOURCE,
|
|
743
|
+
S3DB_ISSUE_PLAN_RESOURCE,
|
|
744
|
+
S3DB_EVENT_RESOURCE,
|
|
745
|
+
S3DB_SETTINGS_RESOURCE,
|
|
746
|
+
S3DB_AGENT_SESSION_RESOURCE,
|
|
747
|
+
S3DB_AGENT_PIPELINE_RESOURCE,
|
|
748
|
+
S3DB_RUNTIME_RECORD_ID,
|
|
749
|
+
S3DB_RUNTIME_SCHEMA_VERSION,
|
|
750
|
+
FRONTEND_DIR,
|
|
751
|
+
FRONTEND_INDEX,
|
|
752
|
+
FRONTEND_MANIFEST_JSON,
|
|
753
|
+
FRONTEND_SERVICE_WORKER_JS,
|
|
754
|
+
FRONTEND_ICON_SVG,
|
|
755
|
+
FRONTEND_MASKABLE_ICON_SVG,
|
|
756
|
+
FRONTEND_OFFLINE_HTML,
|
|
757
|
+
ALLOWED_STATES,
|
|
758
|
+
TERMINAL_STATES,
|
|
759
|
+
EXECUTING_STATES,
|
|
760
|
+
PERSIST_EVENTS_MAX,
|
|
761
|
+
now,
|
|
762
|
+
isoWeek,
|
|
763
|
+
sleep,
|
|
764
|
+
toStringValue,
|
|
765
|
+
toNumberValue,
|
|
766
|
+
toStringArray,
|
|
767
|
+
clamp,
|
|
768
|
+
parseIssueState,
|
|
769
|
+
normalizeState,
|
|
770
|
+
parseEnvNumber,
|
|
771
|
+
parseIntArg,
|
|
772
|
+
parsePositiveIntEnv,
|
|
773
|
+
withRetryBackoff,
|
|
774
|
+
idToSafePath,
|
|
775
|
+
appendFileTail,
|
|
776
|
+
debugBoot,
|
|
777
|
+
fail,
|
|
778
|
+
extractJsonObjects,
|
|
779
|
+
repairTruncatedJson,
|
|
376
780
|
inferCapabilityPaths,
|
|
377
781
|
resolveTaskCapabilities,
|
|
378
782
|
mergeCapabilityProviders,
|
|
379
|
-
|
|
380
|
-
renderPrompt,
|
|
381
|
-
renderPromptString
|
|
783
|
+
renderPrompt
|
|
382
784
|
};
|
|
383
|
-
//# sourceMappingURL=chunk-
|
|
785
|
+
//# sourceMappingURL=chunk-O665NS5E.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/agent/constants.ts","../src/agent/helpers.ts","../src/routing/capability-resolver.ts","../src/prompting.ts","../src/generated/prompts.ts"],"sourcesContent":["import { basename, dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { env, argv, cwd as getCwd } from \"node:process\";\nimport { homedir } from \"node:os\";\nimport type { IssueState } from \"./types.ts\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nexport const PACKAGE_ROOT = resolve(__dirname, \"../..\");\nexport const CLI_ARGS = argv.slice(2);\n\nfunction readArgValue(args: string[], flag: string): string | undefined {\n const index = args.indexOf(flag);\n if (index === -1) return undefined;\n const value = args[index + 1];\n if (!value || value.startsWith(\"--\")) return undefined;\n return value;\n}\n\nfunction resolveInputPath(value: string): string {\n if (value.startsWith(\"~/\")) {\n return resolve(homedir(), value.slice(2));\n }\n return resolve(value);\n}\n\nexport function resolvePersistenceRoot(value: string): string {\n const resolved = value.startsWith(\"file://\")\n ? fileURLToPath(value)\n : resolveInputPath(value);\n\n return basename(resolved) === \".fifony\"\n ? resolved\n : join(resolved, \".fifony\");\n}\n\nconst CLI_WORKSPACE_ROOT = readArgValue(CLI_ARGS, \"--workspace\");\nconst CLI_PERSISTENCE = readArgValue(CLI_ARGS, \"--persistence\");\n\nexport const TARGET_ROOT = resolveInputPath(\n env.FIFONY_WORKSPACE_ROOT ?? CLI_WORKSPACE_ROOT ?? getCwd(),\n);\n\nexport const STATE_ROOT = resolvePersistenceRoot(\n env.FIFONY_PERSISTENCE\n ?? CLI_PERSISTENCE\n ?? env.FIFONY_BOOTSTRAP_ROOT\n ?? TARGET_ROOT,\n);\n\nexport const SOURCE_ROOT = `${STATE_ROOT}/source`;\nexport const WORKSPACE_ROOT = `${STATE_ROOT}/workspaces`;\nexport const SOURCE_MARKER = `${SOURCE_ROOT}/.fifony-local-source-ready`;\n\nexport const ATTACHMENTS_ROOT = `${STATE_ROOT}/attachments`;\n\nexport const S3DB_DATABASE_PATH = `${STATE_ROOT}/s3db`;\nexport const S3DB_BUCKET = env.FIFONY_STORAGE_BUCKET ?? \"fifony\";\nexport const S3DB_KEY_PREFIX = env.FIFONY_STORAGE_KEY_PREFIX ?? \"state\";\n\nexport const S3DB_RUNTIME_RESOURCE = \"runtime_state\";\nexport const S3DB_ISSUE_RESOURCE = \"issues\";\nexport const S3DB_ISSUE_PLAN_RESOURCE = \"issue_plans\";\nexport const S3DB_EVENT_RESOURCE = \"events\";\nexport const S3DB_SETTINGS_RESOURCE = \"settings\";\nexport const S3DB_AGENT_SESSION_RESOURCE = \"agent_sessions\";\nexport const S3DB_AGENT_PIPELINE_RESOURCE = \"agent_pipelines\";\nexport const S3DB_RUNTIME_RECORD_ID = \"current\";\nexport const S3DB_RUNTIME_SCHEMA_VERSION = 1;\n\nexport const FRONTEND_DIR = `${PACKAGE_ROOT}/app/dist`;\nexport const FRONTEND_INDEX = `${FRONTEND_DIR}/index.html`;\nexport const FRONTEND_MANIFEST_JSON = `${FRONTEND_DIR}/manifest.webmanifest`;\nexport const FRONTEND_SERVICE_WORKER_JS = `${FRONTEND_DIR}/service-worker.js`;\nexport const FRONTEND_ICON_SVG = `${FRONTEND_DIR}/icon.svg`;\nexport const FRONTEND_MASKABLE_ICON_SVG = `${FRONTEND_DIR}/icon-maskable.svg`;\nexport const FRONTEND_OFFLINE_HTML = `${FRONTEND_DIR}/offline.html`;\n\nexport const DEBUG_BOOT = env.FIFONY_DEBUG_BOOT === \"1\";\n\nexport const ALLOWED_STATES: IssueState[] = [\n \"Planning\",\n \"Planned\",\n \"Queued\",\n \"Running\",\n \"Reviewing\",\n \"Reviewed\",\n \"Blocked\",\n \"Done\",\n \"Cancelled\",\n];\n\nexport const TERMINAL_STATES = new Set<IssueState>([\"Done\", \"Cancelled\"]);\nexport const EXECUTING_STATES = new Set<IssueState>([\"Running\", \"Reviewing\"]);\nexport const PERSIST_EVENTS_MAX = 500;\n\n// ── CLI skip flags ──────────────────────────────────────────────────────────\nconst FAST_BOOT = CLI_ARGS.includes(\"--fast-boot\");\nexport const SKIP_SOURCE = FAST_BOOT || CLI_ARGS.includes(\"--skip-source\");\nexport const SKIP_SCAN = FAST_BOOT || CLI_ARGS.includes(\"--skip-scan\");\nexport const SKIP_RECOVERY = FAST_BOOT || CLI_ARGS.includes(\"--skip-recovery\");\n","import { env } from \"node:process\";\nimport { parse as parseYaml } from \"yaml\";\nimport type { IssueState, JsonRecord } from \"./types.ts\";\nimport { ALLOWED_STATES, DEBUG_BOOT } from \"./constants.ts\";\n\nexport function now(): string {\n return new Date().toISOString();\n}\n\n/** Returns ISO week string like \"2026-W12\" for a given date (defaults to now). */\nexport function isoWeek(date?: Date | string): string {\n const d = date ? new Date(date) : new Date();\n if (Number.isNaN(d.getTime())) return \"\";\n // ISO week: week starts Monday, week 1 contains Jan 4\n const tmp = new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()));\n const dayNum = tmp.getUTCDay() || 7; // Monday=1 ... Sunday=7\n tmp.setUTCDate(tmp.getUTCDate() + 4 - dayNum);\n const yearStart = new Date(Date.UTC(tmp.getUTCFullYear(), 0, 1));\n const weekNo = Math.ceil(((tmp.getTime() - yearStart.getTime()) / 86_400_000 + 1) / 7);\n return `${tmp.getUTCFullYear()}-W${String(weekNo).padStart(2, \"0\")}`;\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction resolveEnvVar(value: string): string {\n if (!value.startsWith(\"$\")) return value;\n const varName = value.slice(1);\n const resolved = env[varName];\n return resolved && resolved.trim().length > 0 ? resolved.trim() : \"\";\n}\n\nexport function toStringValue(value: unknown, fallback = \"\"): string {\n if (typeof value !== \"string\" || value.trim().length === 0) return fallback;\n const trimmed = value.trim();\n // Resolve $VAR_NAME indirection (full value is a single env var reference)\n if (trimmed.startsWith(\"$\") && /^\\$[A-Za-z_][A-Za-z0-9_]*$/.test(trimmed)) {\n const resolved = resolveEnvVar(trimmed);\n return resolved.length > 0 ? resolved : fallback;\n }\n return trimmed;\n}\n\nexport function toNumberValue(value: unknown, fallback = 1): number {\n const parsed =\n typeof value === \"number\"\n ? value\n : typeof value === \"string\"\n ? Number.parseInt(value, 10)\n : Number.NaN;\n\n return Number.isFinite(parsed) && parsed > 0 ? Math.round(parsed) : fallback;\n}\n\nexport function toBooleanValue(value: unknown, fallback: boolean): boolean {\n return typeof value === \"boolean\" ? value : fallback;\n}\n\nexport function toStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value\n .filter((entry): entry is string => typeof entry === \"string\" && entry.trim().length > 0)\n .map((entry) => entry.trim());\n}\n\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nexport function parseIssueState(value: unknown): IssueState | undefined {\n const raw = typeof value === \"string\" ? value.trim() : \"\";\n if ((ALLOWED_STATES as readonly string[]).includes(raw)) {\n return raw as IssueState;\n }\n return undefined;\n}\n\nexport function normalizeState(value: unknown, fallback: IssueState = \"Planning\"): IssueState {\n return parseIssueState(value) ?? fallback;\n}\n\nexport function parseEnvNumber(name: string, fallback: number): number {\n return toNumberValue(env[name], fallback);\n}\n\nexport function parseIntArg(value: string, fallback: number): number {\n const parsed = Number.parseInt(value, 10);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;\n}\n\nexport function parsePositiveIntEnv(name: string, fallback: number): number {\n const source = env[name];\n if (!source) return fallback;\n return parseIntArg(source, fallback);\n}\n\nexport function withRetryBackoff(attempt: number, baseDelayMs: number): number {\n return Math.min(baseDelayMs * 2 ** attempt, 5 * 60 * 1000);\n}\n\nexport function idToSafePath(value: string): string {\n return value.toLowerCase().replace(/[^a-z0-9._-]/g, \"-\");\n}\n\nexport function appendFileTail(target: string, text: string, maxLength: number): string {\n const merged = `${target}\\n${text}`;\n if (merged.length <= maxLength) return merged;\n return `…${merged.slice(-(maxLength - 1))}`;\n}\n\nexport function parseFrontMatter(source: string): { config: JsonRecord; body: string } {\n const match = source.match(/^---\\s*\\n([\\s\\S]*?)\\n---\\s*\\n?([\\s\\S]*)$/);\n if (!match) {\n return { config: {}, body: source.trim() };\n }\n\n const rawConfig = parseYaml(match[1]) as unknown;\n const config = rawConfig && typeof rawConfig === \"object\" && !Array.isArray(rawConfig)\n ? rawConfig as JsonRecord\n : {};\n\n return { config, body: match[2].trim() };\n}\n\nexport function getNestedRecord(source: unknown, key: string): JsonRecord {\n if (!source || typeof source !== \"object\" || Array.isArray(source)) return {};\n const value = (source as JsonRecord)[key];\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? value as JsonRecord\n : {};\n}\n\nexport function getNestedString(source: unknown, key: string, fallback = \"\"): string {\n if (!source || typeof source !== \"object\" || Array.isArray(source)) return fallback;\n return toStringValue((source as JsonRecord)[key], fallback);\n}\n\nexport function getNestedNumber(source: unknown, key: string, fallback: number): number {\n if (!source || typeof source !== \"object\" || Array.isArray(source)) return fallback;\n return toNumberValue((source as JsonRecord)[key], fallback);\n}\n\nexport function debugBoot(message: string): void {\n if (!DEBUG_BOOT) return;\n console.error(`[FIFONY_DEBUG_BOOT] ${message}`);\n}\n\nexport function fail(message: string): never {\n console.error(message);\n process.exit(1);\n}\n\n/** Extract top-level JSON object candidates from a text that may contain prose around them. */\nexport function extractJsonObjects(text: string): string[] {\n const results: string[] = [];\n let depth = 0;\n let start = -1;\n let inStr = false;\n let esc = false;\n\n for (let i = 0; i < text.length; i++) {\n const ch = text[i];\n if (inStr) {\n if (esc) { esc = false; continue; }\n if (ch === \"\\\\\") { esc = true; continue; }\n if (ch === \"\\\"\") { inStr = false; }\n continue;\n }\n if (ch === \"\\\"\") { inStr = true; continue; }\n if (ch === \"{\") {\n if (depth === 0) start = i;\n depth++;\n } else if (ch === \"}\") {\n depth = Math.max(0, depth - 1);\n if (depth === 0 && start >= 0) {\n results.push(text.slice(start, i + 1));\n start = -1;\n }\n }\n }\n return results;\n}\n\n/**\n * Attempt to repair truncated JSON by closing open strings, arrays, and objects.\n * Returns the repaired string or null if no valid JSON start was found.\n */\nexport function repairTruncatedJson(text: string): string | null {\n // Find the first top-level '{' to start from\n const firstBrace = text.indexOf(\"{\");\n if (firstBrace < 0) return null;\n\n let json = text.slice(firstBrace);\n\n // Track nesting to figure out what needs closing\n let inStr = false;\n let esc = false;\n const stack: string[] = []; // tracks '{' and '['\n\n for (let i = 0; i < json.length; i++) {\n const ch = json[i];\n if (inStr) {\n if (esc) { esc = false; continue; }\n if (ch === \"\\\\\") { esc = true; continue; }\n if (ch === \"\\\"\") { inStr = false; }\n continue;\n }\n if (ch === \"\\\"\") { inStr = true; continue; }\n if (ch === \"{\") stack.push(\"{\");\n else if (ch === \"[\") stack.push(\"[\");\n else if (ch === \"}\") { if (stack.length > 0 && stack[stack.length - 1] === \"{\") stack.pop(); }\n else if (ch === \"]\") { if (stack.length > 0 && stack[stack.length - 1] === \"[\") stack.pop(); }\n }\n\n // Nothing to repair — JSON is already complete\n if (!inStr && stack.length === 0) return json;\n\n // Close open string\n if (inStr) {\n // Remove trailing incomplete escape sequence\n if (json.endsWith(\"\\\\\")) json = json.slice(0, -1);\n json += \"\\\"\";\n }\n\n // Remove trailing comma or colon (invalid before closing bracket)\n json = json.replace(/[,:\\s]+$/, \"\");\n\n // Close open brackets in reverse order\n while (stack.length > 0) {\n const open = stack.pop();\n json += open === \"{\" ? \"}\" : \"]\";\n }\n\n return json;\n}\n","export type CapabilityResolverRole = \"planner\" | \"executor\" | \"reviewer\";\n\nexport type CapabilityResolverIssue = {\n id?: string;\n identifier?: string;\n title: string;\n description?: string;\n labels?: string[];\n paths?: string[];\n};\n\nexport type CapabilityResolverBaseProvider = {\n provider: string;\n role: CapabilityResolverRole;\n command: string;\n profile?: string;\n profilePath?: string;\n profileInstructions?: string;\n};\n\nexport type CapabilityResolverSuggestion = {\n provider: string;\n role: CapabilityResolverRole;\n profile: string;\n reason: string;\n};\n\nexport type CapabilityResolution = {\n category: string;\n rationale: string[];\n overlays: string[];\n providers: CapabilityResolverSuggestion[];\n};\n\nexport type CapabilityResolverOverride = {\n match?: {\n labels?: string[];\n terms?: string[];\n category?: string;\n paths?: string[];\n };\n category?: string;\n rationale?: string[];\n overlays?: string[];\n providers?: CapabilityResolverSuggestion[];\n};\n\nexport type CapabilityResolverOptions = {\n enabled?: boolean;\n overrides?: CapabilityResolverOverride[];\n};\n\nfunction tokenize(issue: CapabilityResolverIssue): string {\n const labels = (issue.labels ?? []).filter((label) => !label.startsWith(\"capability:\") && !label.startsWith(\"overlay:\"));\n return [\n issue.identifier ?? \"\",\n issue.title,\n issue.description ?? \"\",\n ...labels,\n ...(issue.paths ?? []),\n ].join(\" \").toLowerCase();\n}\n\nfunction normalizePath(value: string): string {\n return value.trim().replaceAll(\"\\\\\", \"/\").toLowerCase();\n}\n\nexport function inferCapabilityPaths(issue: CapabilityResolverIssue): string[] {\n const labels = (issue.labels ?? []).filter((label) => !label.startsWith(\"capability:\") && !label.startsWith(\"overlay:\"));\n const sources = [issue.title, issue.description ?? \"\", ...labels];\n const matches = new Set<string>();\n const pattern = /(?:[A-Za-z0-9._-]+\\/)+(?:[A-Za-z0-9._-]+)|(?:[A-Za-z0-9._-]+\\.(?:ts|tsx|js|jsx|mjs|cjs|css|scss|sass|less|html|md|mdx|json|yml|yaml|sql|sh))+/g;\n\n for (const source of sources) {\n for (const match of source.match(pattern) ?? []) {\n matches.add(normalizePath(match));\n }\n }\n\n return [...matches];\n}\n\nfunction getIssuePaths(issue: CapabilityResolverIssue): string[] {\n return [...new Set([\n ...(issue.paths ?? [])\n .filter((value): value is string => typeof value === \"string\" && value.trim().length > 0)\n .map(normalizePath),\n ...inferCapabilityPaths(issue),\n ])];\n}\n\nfunction hasAny(text: string, terms: string[]): boolean {\n return terms.some((term) => text.includes(term));\n}\n\nfunction hasPathMatch(paths: string[], fragments: string[] = [], extensions: string[] = []): boolean {\n return paths.some((path) => {\n if (fragments.some((fragment) => path.includes(fragment))) {\n return true;\n }\n\n return extensions.some((extension) => path.endsWith(extension));\n });\n}\n\nfunction buildResolution(\n category: string,\n rationale: string[],\n overlays: string[],\n providers: CapabilityResolverSuggestion[],\n): CapabilityResolution {\n return {\n category,\n rationale,\n overlays,\n providers,\n };\n}\n\nfunction uniq(values: string[]): string[] {\n return [...new Set(values.filter(Boolean))];\n}\n\nfunction matchesOverride(\n issue: CapabilityResolverIssue,\n resolution: CapabilityResolution,\n override: CapabilityResolverOverride,\n): boolean {\n const match = override.match ?? {};\n const issueLabels = new Set((issue.labels ?? []).map((label) => label.toLowerCase()));\n const text = tokenize(issue);\n const paths = getIssuePaths(issue);\n\n if (match.category && match.category !== resolution.category) {\n return false;\n }\n\n if (match.labels?.length) {\n const requiredLabels = match.labels.map((label) => label.toLowerCase());\n if (!requiredLabels.every((label) => issueLabels.has(label))) {\n return false;\n }\n }\n\n if (match.terms?.length) {\n if (!match.terms.some((term) => text.includes(term.toLowerCase()))) {\n return false;\n }\n }\n\n if (match.paths?.length) {\n const expectedPaths = match.paths.map((path) => normalizePath(path));\n if (!expectedPaths.some((expectedPath) => paths.some((path) => path.includes(expectedPath)))) {\n return false;\n }\n }\n\n return Boolean(match.category || match.labels?.length || match.terms?.length || match.paths?.length);\n}\n\nfunction applyOverrides(\n issue: CapabilityResolverIssue,\n resolution: CapabilityResolution,\n options?: CapabilityResolverOptions,\n): CapabilityResolution {\n if (options?.enabled === false) {\n return buildResolution(\n \"workflow-disabled\",\n [\"Automatic capability routing was disabled by workflow configuration.\"],\n [],\n [\n { provider: \"codex\", role: \"executor\", profile: \"\", reason: \"Fallback executor because routing is disabled.\" },\n ],\n );\n }\n\n const override = options?.overrides?.find((entry) => matchesOverride(issue, resolution, entry));\n if (!override) {\n return resolution;\n }\n\n return {\n category: override.category ?? resolution.category,\n rationale: uniq([...(resolution.rationale ?? []), ...(override.rationale ?? []), \"Workflow routing override applied.\"]),\n overlays: uniq([...(resolution.overlays ?? []), ...(override.overlays ?? [])]),\n providers: override.providers?.length ? override.providers : resolution.providers,\n };\n}\n\nexport function resolveTaskCapabilities(\n issue: CapabilityResolverIssue,\n options?: CapabilityResolverOptions,\n): CapabilityResolution {\n const text = tokenize(issue);\n const paths = getIssuePaths(issue);\n const frontendPathMatch = hasPathMatch(\n paths,\n [\"src/web\", \"web\", \"frontend\", \"ui\", \"component\", \"dashboard\", \"style\", \"apps/web\"],\n [\".css\", \".scss\", \".sass\", \".less\", \".html\", \".tsx\", \".jsx\", \".vue\", \".svelte\"],\n );\n const securityPathMatch = hasPathMatch(\n paths,\n [\"security\", \"auth\", \"crypto\", \"secret\", \"permission\", \"token\"],\n [\".pem\", \".key\", \".crt\"],\n );\n const architecturePathMatch = hasPathMatch(\n paths,\n [\"workflow.md\", \"architecture.md\", \"spec.md\", \"claude.md\", \"openspec/\"],\n [],\n );\n const devopsPathMatch = hasPathMatch(\n paths,\n [\".github/workflows\", \"docker\", \"k8s\", \"helm\", \"terraform\", \"infra\", \"deploy\", \"release\"],\n [\".yml\", \".yaml\", \".tf\"],\n );\n const backendPathMatch = hasPathMatch(\n paths,\n [\"src/api\", \"api\", \"src/protocol\", \"protocol\", \"server\", \"persistence\", \"scanner\", \"ws\", \"websocket\", \"db\", \"apps/api\"],\n [\".sql\"],\n );\n const docsPathMatch = hasPathMatch(\n paths,\n [\"docs\", \"readme\", \"guide\", \"tutorial\"],\n [\".md\", \".mdx\"],\n );\n let resolution: CapabilityResolution;\n\n if (frontendPathMatch || hasAny(text, [\"frontend\", \"ui\", \"ux\", \"design\", \"css\", \"html\", \"layout\", \"component\", \"react\", \"vue\"])) {\n resolution = buildResolution(\n \"frontend-ui\",\n [\n ...(frontendPathMatch ? [\"Detected frontend-oriented target paths or file extensions.\"] : []),\n \"Detected frontend or design-oriented keywords in the task.\",\n \"Use Claude to plan and review, Codex to implement.\",\n \"Apply impeccable-style polish as a review overlay when available.\",\n ],\n [\"impeccable\", \"frontend-design\"],\n [\n { provider: \"claude\", role: \"planner\", profile: \"agency-ui-designer\", reason: \"UI planning and structure.\" },\n { provider: \"codex\", role: \"executor\", profile: \"agency-frontend-developer\", reason: \"Frontend implementation.\" },\n { provider: \"claude\", role: \"reviewer\", profile: \"agency-accessibility-auditor\", reason: \"Critical UX and accessibility review.\" },\n ],\n );\n return applyOverrides(issue, resolution, options);\n }\n\n if (securityPathMatch || hasAny(text, [\"security\", \"auth\", \"oauth\", \"token\", \"secret\", \"permission\", \"compliance\", \"vulnerability\"])) {\n resolution = buildResolution(\n \"security\",\n [\n ...(securityPathMatch ? [\"Detected security-sensitive target paths or file extensions.\"] : []),\n \"Detected security-sensitive keywords.\",\n \"Use a security profile to scope the work and keep a strict review pass.\",\n ],\n [\"security-review\"],\n [\n { provider: \"claude\", role: \"planner\", profile: \"agency-security-engineer\", reason: \"Threat and risk framing.\" },\n { provider: \"codex\", role: \"executor\", profile: \"agency-security-engineer\", reason: \"Implementation with security context.\" },\n { provider: \"claude\", role: \"reviewer\", profile: \"agency-code-reviewer\", reason: \"Independent correctness review.\" },\n ],\n );\n return applyOverrides(issue, resolution, options);\n }\n\n if (architecturePathMatch || hasAny(text, [\"architecture\", \"design doc\", \"spec\", \"workflow\", \"orchestr\", \"roadmap\", \"plan\"])) {\n resolution = buildResolution(\n \"architecture\",\n [\n ...(architecturePathMatch ? [\"Detected workflow, architecture, or specification files in the targeted paths.\"] : []),\n \"Detected architecture or planning-oriented keywords.\",\n \"Favor stronger planning and review roles around the executor.\",\n ],\n [\"spec-review\"],\n [\n { provider: \"claude\", role: \"planner\", profile: \"agency-software-architect\", reason: \"Architecture and system framing.\" },\n { provider: \"codex\", role: \"executor\", profile: \"agency-senior-developer\", reason: \"Translate architecture into implementation.\" },\n { provider: \"claude\", role: \"reviewer\", profile: \"agency-code-reviewer\", reason: \"Challenge assumptions and regressions.\" },\n ],\n );\n return applyOverrides(issue, resolution, options);\n }\n\n if (devopsPathMatch || hasAny(text, [\"deploy\", \"release\", \"ci\", \"cicd\", \"github actions\", \"docker\", \"terraform\", \"kubernetes\"])) {\n resolution = buildResolution(\n \"devops\",\n [\n ...(devopsPathMatch ? [\"Detected deployment, infrastructure, or CI/CD paths in the task scope.\"] : []),\n \"Detected release, deployment, or infrastructure keywords.\",\n \"Use a delivery-focused planner and a stricter reliability review pass.\",\n ],\n [\"delivery-review\"],\n [\n { provider: \"claude\", role: \"planner\", profile: \"agency-devops-automator\", reason: \"CI/CD and deployment framing.\" },\n { provider: \"codex\", role: \"executor\", profile: \"agency-devops-automator\", reason: \"Implement workflow and release changes.\" },\n { provider: \"claude\", role: \"reviewer\", profile: \"agency-sre-site-reliability-engineer\", reason: \"Reliability and rollback review.\" },\n ],\n );\n return applyOverrides(issue, resolution, options);\n }\n\n if (hasAny(text, [\"bug\", \"fix\", \"regression\", \"debug\", \"crash\", \"broken\", \"error\", \"fail\"])) {\n resolution = buildResolution(\n \"bugfix\",\n [\n \"Detected bug-fix or debugging keywords.\",\n \"Use Codex to execute the fix and Claude to frame and verify the change.\",\n ],\n [\"debug\"],\n [\n { provider: \"claude\", role: \"planner\", profile: \"agency-code-reviewer\", reason: \"Clarify failure mode and acceptance criteria.\" },\n { provider: \"codex\", role: \"executor\", profile: \"agency-senior-developer\", reason: \"Implement and iterate quickly.\" },\n { provider: \"claude\", role: \"reviewer\", profile: \"agency-code-reviewer\", reason: \"Catch regressions and weak reasoning.\" },\n ],\n );\n return applyOverrides(issue, resolution, options);\n }\n\n if (backendPathMatch || hasAny(text, [\"api\", \"backend\", \"database\", \"protocol\", \"server\", \"ws\", \"websocket\", \"persistence\"])) {\n resolution = buildResolution(\n \"backend\",\n [\n ...(backendPathMatch ? [\"Detected backend, protocol, or persistence paths in the task scope.\"] : []),\n \"Detected backend, API, protocol, or persistence keywords.\",\n \"Use backend-oriented planning and critical review around the executor.\",\n ],\n [\"backend-review\"],\n [\n { provider: \"claude\", role: \"planner\", profile: \"agency-backend-architect\", reason: \"API and data-model framing.\" },\n { provider: \"codex\", role: \"executor\", profile: \"agency-senior-developer\", reason: \"Implement the backend changes.\" },\n { provider: \"claude\", role: \"reviewer\", profile: \"agency-code-reviewer\", reason: \"Critical regression review.\" },\n ],\n );\n return applyOverrides(issue, resolution, options);\n }\n\n if (docsPathMatch || hasAny(text, [\"docs\", \"readme\", \"guide\", \"documentation\", \"tutorial\"])) {\n resolution = buildResolution(\n \"documentation\",\n [\n ...(docsPathMatch ? [\"Detected documentation-oriented paths or file extensions.\"] : []),\n \"Detected documentation keywords.\",\n \"Use writing-oriented planning with an implementation pass that can still edit code and docs together.\",\n ],\n [\"documentation\"],\n [\n { provider: \"claude\", role: \"planner\", profile: \"agency-technical-writer\", reason: \"Structure and narrative.\" },\n { provider: \"codex\", role: \"executor\", profile: \"agency-technical-writer\", reason: \"Apply documentation edits in repo context.\" },\n { provider: \"claude\", role: \"reviewer\", profile: \"agency-code-reviewer\", reason: \"Check coherence with the implementation.\" },\n ],\n );\n return applyOverrides(issue, resolution, options);\n }\n\n resolution = buildResolution(\n \"default\",\n [\n \"No specialized pattern matched strongly.\",\n \"Default to a balanced planner/executor/reviewer pipeline using both Claude and Codex.\",\n ],\n [],\n [\n { provider: \"claude\", role: \"planner\", profile: \"agency-senior-project-manager\", reason: \"Clarify scope and acceptance criteria.\" },\n { provider: \"codex\", role: \"executor\", profile: \"agency-senior-developer\", reason: \"Implement the requested change.\" },\n { provider: \"claude\", role: \"reviewer\", profile: \"agency-code-reviewer\", reason: \"Critical review before closure.\" },\n ],\n );\n\n return applyOverrides(issue, resolution, options);\n}\n\nexport function mergeCapabilityProviders(\n baseProviders: CapabilityResolverBaseProvider[],\n resolution: CapabilityResolution,\n): CapabilityResolverBaseProvider[] {\n return resolution.providers.map((suggestion) => {\n const exact = baseProviders.find((provider) => provider.provider === suggestion.provider && provider.role === suggestion.role);\n const sameRole = baseProviders.find((provider) => provider.role === suggestion.role);\n const sameProvider = baseProviders.find((provider) => provider.provider === suggestion.provider);\n const base = exact ?? sameRole ?? sameProvider;\n\n return {\n provider: suggestion.provider,\n role: suggestion.role,\n command: base?.command ?? \"\",\n profile: suggestion.profile || base?.profile || \"\",\n profilePath: base?.profilePath ?? \"\",\n profileInstructions: base?.profileInstructions ?? \"\",\n };\n });\n}\n","import { TemplateEngine } from \"recker\";\nimport { PROMPT_TEMPLATES, type PromptTemplateName } from \"./generated/prompts.ts\";\n\nconst engine = new TemplateEngine({\n cache: true,\n format: \"raw\",\n strict: false,\n});\n\nfunction normalizePrompt(text: string): string {\n return text\n .replace(/\\r\\n/g, \"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n\nexport async function renderPrompt(\n name: PromptTemplateName,\n context: Record<string, unknown> = {},\n): Promise<string> {\n return renderPromptString(PROMPT_TEMPLATES[name], context);\n}\n\nexport async function renderPromptString(\n template: string,\n context: Record<string, unknown> = {},\n): Promise<string> {\n const rendered = await engine.render(template, context);\n return normalizePrompt(rendered);\n}\n","// Generated by scripts/generate-prompts.ts. Do not edit directly.\n\nexport const PROMPT_TEMPLATES = {\n \"agent-provider-base\": \"{{#if isPlanner}}\\nRole: planner.\\nAnalyze the issue and prepare an execution plan for the implementation agents.\\nDo not claim the issue is complete unless the plan itself is the deliverable.\\n{{else}}\\n{{#if isReviewer}}\\nRole: reviewer.\\nInspect the workspace and review the current implementation critically.\\nIf rework is required, emit `FIFONY_STATUS=continue` and provide actionable `nextPrompt` feedback.\\nEmit `FIFONY_STATUS=done` only when the work is acceptable.\\n{{else}}\\nRole: executor.\\nImplement the required changes in the workspace.\\nUse any planner guidance or prior reviewer feedback already persisted in the workspace.\\n{{/if}}\\n{{/if}}\\n\\n{{#if hasImpeccableOverlay}}\\nImpeccable overlay is active.\\nRaise the bar on UI polish, clarity, responsiveness, visual hierarchy, and interaction quality.\\n{{#if isReviewer}}\\nReview with a stricter frontend and product-quality standard than a normal correctness-only pass.\\n{{else}}\\nWhen touching frontend work, do not settle for baseline implementation quality.\\n{{/if}}\\n{{/if}}\\n\\n{{#if hasFrontendDesignOverlay}}\\nFrontend-design overlay is active.\\nPrefer stronger hierarchy, spacing, and readability decisions over generic implementation choices.\\n{{/if}}\\n\\n{{#if profileInstructions}}\\n## Agent Profile\\n{{profileInstructions}}\\n{{/if}}\\n\\n{{#if skillContext}}\\n{{skillContext}}\\n{{/if}}\\n\\n{{#if capabilityCategory}}\\nCapability routing: {{capabilityCategory}}.\\nSelection reason: {{selectionReason}}\\n{{#if overlays.length}}\\nOverlays: {{overlays | join \\\", \\\"}}.\\n{{/if}}\\n{{/if}}\\n\\n{{#if targetPaths.length}}\\nTarget paths: {{targetPaths | join \\\", \\\"}}\\n{{/if}}\\n\\nWorkspace: {{workspacePath}}\\n\\n{{basePrompt}}\\n\", // src/prompts/agent-provider-base.stub.md\n \"agent-turn\": \"Continue working on {{issueIdentifier}}.\\nTurn {{turnIndex}} of {{maxTurns}}.\\n\\nBase objective:\\n{{basePrompt}}\\n\\nContinuation guidance:\\n{{continuation}}\\n\\nPrevious command output tail:\\n```text\\n{{outputTail}}\\n```\\n\\nBefore exiting successfully, emit one of the following control markers:\\n- `FIFONY_STATUS=continue` if more turns are required.\\n- `FIFONY_STATUS=done` if the issue is complete.\\n- `FIFONY_STATUS=blocked` if manual intervention is required.\\nYou may also write `fifony-result.json` with `{ \\\"status\\\": \\\"...\\\", \\\"summary\\\": \\\"...\\\", \\\"nextPrompt\\\": \\\"...\\\" }`.\\n\", // src/prompts/agent-turn.stub.md\n \"compile-execution-claude\": \"{{#if isPlanner}}\\nRole: planner. Analyze the issue and prepare an execution plan.\\n{{else}}\\n{{#if isReviewer}}\\nRole: reviewer. Inspect and review the implementation critically.\\n{{else}}\\nRole: executor. Implement the required changes.\\n{{/if}}\\n{{/if}}\\n\\n{{#if profileInstructions}}\\n## Agent Profile\\n{{profileInstructions}}\\n{{/if}}\\n\\n{{#if skillContext}}\\n{{skillContext}}\\n{{/if}}\\n\\n{{planPrompt}}\\n\\n{{#if subagentsToUse.length}}\\n## Subagent Strategy (Claude-specific)\\nYou have access to the Agent tool for spawning subagents. Use them for:\\n{{#each subagentsToUse}}\\n- **{{name}}** ({{role}}): {{why}}\\n{{/each}}\\n\\nLaunch subagents for independent subtasks to maximize parallelism.\\nUse the main thread for coordination and integration.\\n{{/if}}\\n\\n{{#if skillsToUse.length}}\\n## Skills to Activate\\n{{#each skillsToUse}}\\n- Invoke **/{{name}}** - {{why}}\\n{{/each}}\\n{{/if}}\\n\\n{{#if suggestedPaths.length}}\\nTarget paths: {{suggestedPaths | join \\\", \\\"}}\\n{{/if}}\\n\\nWorkspace: {{workspacePath}}\\n\\nIssue: {{issueIdentifier}}\\nTitle: {{title}}\\nDescription: {{description}}\\n\\n## Structured Input\\nThe file `fifony-execution-payload.json` in the workspace contains the canonical structured data for this task.\\nUse it as the source of truth for constraints, success criteria, execution intent, and plan details.\\nIf there is any conflict between this prompt and the structured fields in the payload, prioritize the payload.\\n\\n{{#if validationItems.length}}\\n## Pre-completion enforcement\\nBefore reporting done, verify:\\n{{#each validationItems}}\\n- {{value}}\\n{{/each}}\\n{{/if}}\\n\", // src/prompts/compile-execution-claude.stub.md\n \"compile-execution-codex\": \"{{#if isReviewer}}\\nRole: reviewer. Inspect and review the implementation critically.\\n{{else}}\\n{{#if isPlanner}}\\nRole: planner. Analyze and prepare an execution plan.\\n{{else}}\\nRole: executor. Implement the required changes in the workspace.\\n{{/if}}\\n{{/if}}\\n\\n{{#if profileInstructions}}\\n## Agent Profile\\n{{profileInstructions}}\\n{{/if}}\\n\\n{{#if skillContext}}\\n{{skillContext}}\\n{{/if}}\\n\\nIssue: {{issueIdentifier}}\\nTitle: {{title}}\\nDescription: {{description}}\\nWorkspace: {{workspacePath}}\\n\\n{{planPrompt}}\\n\\n{{#if phases.length}}\\n## Checkpoint Execution (Codex mode)\\nExecute in strict phases. After each phase, verify outputs before proceeding.\\n{{#each phases}}\\n- **{{phaseName}}**: {{goal}}\\n{{#if outputs.length}} Checkpoint: verify {{outputs | join \\\", \\\"}} before next phase.{{/if}}\\n{{/each}}\\n{{else}}\\n## Execution Order\\nExecute steps in order. Verify each step's `doneWhen` criterion before proceeding.\\n{{/if}}\\n\\n{{#if suggestedPaths.length}}\\nTarget paths: {{suggestedPaths | join \\\", \\\"}}\\nFocus changes on these paths. Do not make unnecessary changes elsewhere.\\n{{/if}}\\n\\n{{#if skillsToUse.length}}\\n## Specialized Procedures\\n{{#each skillsToUse}}\\n- Apply **{{name}}** procedure: {{why}}\\n{{/each}}\\n{{/if}}\\n\\n{{#if validationItems.length}}\\n## Pre-completion checks\\nBefore reporting done, run:\\n{{#each validationItems}}\\n- {{value}}\\n{{/each}}\\n{{/if}}\\n\\n## Structured Input\\nThe file `fifony-execution-payload.json` in the workspace contains the canonical structured data for this task.\\nUse it as the source of truth for constraints, success criteria, execution intent, and plan details.\\nIf there is any conflict between this prompt and the structured fields in the payload, prioritize the payload.\\n\\n## Output Format\\n\\n{{outputContract}}\\n\", // src/prompts/compile-execution-codex.stub.md\n \"compile-review\": \"Review the work done for {{issueIdentifier}}.\\n\\nTitle: {{title}}\\nDescription: {{description}}\\nWorkspace: {{workspacePath}}\\n\\n{{#if planPrompt}}\\n# Original Execution Plan\\n\\n{{planPrompt}}\\n{{/if}}\\n\\n{{#if successCriteria.length}}\\n# Success Criteria (evaluate against these)\\n{{#each successCriteria}}\\n- [ ] {{value}}\\n{{/each}}\\n{{/if}}\\n\\n{{#if deliverables.length}}\\n# Expected Deliverables\\n{{#each deliverables}}\\n- [ ] {{value}}\\n{{/each}}\\n{{/if}}\\n\\n{{#if diffSummary}}\\n# Changes Made (diff summary)\\n```\\n{{diffSummary}}\\n```\\n{{/if}}\\n\\n# Structured Context\\nIf `fifony-execution-payload.json` exists in the workspace, read it for the canonical structured task data.\\nUse the `successCriteria`, `constraints`, and `deliverables` fields as your evaluation checklist.\\n\\n# Review Instructions\\n\\n1. Verify each success criterion from the plan is met.\\n2. Check that all expected deliverables are present.\\n3. Review the diff for correctness, security issues, and code quality.\\n4. Verify validation checks pass (run commands if specified in the plan).\\n5. Check for unintended side effects or regressions.\\n\\nIf the work is acceptable, emit FIFONY_STATUS=done.\\nIf rework is needed, emit FIFONY_STATUS=continue and provide actionable feedback in nextPrompt.\\nIf the work is fundamentally broken, emit FIFONY_STATUS=blocked.\\n\", // src/prompts/compile-review.stub.md\n \"integrations-agency-agents\": \"---\\nagent:\\n providers:\\n - provider: claude\\n role: planner\\n profile: agency-senior-project-manager\\n - provider: codex\\n role: executor\\n profile: agency-senior-developer\\n - provider: claude\\n role: reviewer\\n profile: agency-code-reviewer\\ncodex:\\n command: \\\"codex\\\"\\nclaude:\\n command: \\\"claude\\\"\\n---\\n\\nUse local agency agent profiles discovered from workspace or home directories.\\nWorkspace: {{workspaceRoot}}\\n\", // src/prompts/integrations-agency-agents.stub.md\n \"integrations-impeccable\": \"# Impeccable integration idea\\n\\nUse impeccable-oriented skills as a frontend review layer around fifony issues.\\n\\nSuggested pattern:\\n\\n1. Use `agency-senior-developer` or `codex` as executor.\\n2. Route UI-heavy issues to a reviewer prompt that explicitly asks for impeccable-style critique.\\n3. Expose the resulting review through the fifony MCP prompts or as a follow-up review issue.\\n\\nSuggested labels:\\n- frontend\\n- ui\\n- design-system\\n\\nSuggested reviewer prompt seed:\\n\\\"Review this implementation using impeccable standards for frontend quality, polish, hierarchy, spacing, responsiveness, and interaction clarity.\\\"\\n\", // src/prompts/integrations-impeccable.stub.md\n \"issue-enhancer-description\": \"You are helping improve issue metadata for a software execution queue.\\nRewrite the description to be clearer, complete, and directly actionable.\\nReturn strict JSON only with this schema:\\n{ \\\"field\\\": \\\"description\\\", \\\"value\\\": \\\"...\\\" }\\n\\nIssue type: {{issueType}}\\nCurrent title: {{title}}\\nCurrent description: {{description}}\\n{{#if images}}\\nVisual evidence (attached screenshots for context):\\n{{#each images}}\\n- {{this}}\\n{{/each}}\\n{{/if}}\\n\\nRules:\\n- Keep it concise but include meaningful acceptance criteria tailored to the issue type.\\n- For \\\"bug\\\": focus on problem description, expected behavior, and steps to reproduce.\\n- For \\\"feature\\\": focus on goal, acceptance criteria, and any relevant notes.\\n- For \\\"refactor\\\": describe current state, desired state, and scope.\\n- For \\\"docs\\\": describe what to document and target audience.\\n- For \\\"chore\\\": describe the task and why it's needed now.\\n- Use markdown formatting appropriate for the type (## headings, bullet points).\\n- Avoid extra wrappers, outer quotes, or extra explanation.\\n- The value should be in Portuguese if the input is in Portuguese; otherwise in English.\\n\", // src/prompts/issue-enhancer-description.stub.md\n \"issue-enhancer-title\": \"You are helping improve issue metadata for a software execution queue.\\nRewrite the title for clarity, actionability, and specificity.\\nReturn strict JSON only with this schema:\\n{ \\\"field\\\": \\\"title\\\", \\\"value\\\": \\\"...\\\" }\\n\\nIssue type: {{issueType}}\\nCurrent title: {{title}}\\nDescription context: {{description}}\\n{{#if images}}\\nVisual evidence (attached screenshots for context):\\n{{#each images}}\\n- {{this}}\\n{{/each}}\\n{{/if}}\\n\\nRules:\\n- Keep it concise and suitable as a task title.\\n- Use imperative language when possible.\\n- If the issue type is \\\"bug\\\", start with \\\"fix: \\\". If \\\"feature\\\", start with \\\"feat: \\\". If \\\"refactor\\\", start with \\\"refactor: \\\". If \\\"docs\\\", start with \\\"docs: \\\". If \\\"chore\\\", start with \\\"chore: \\\". For \\\"blank\\\", use no prefix.\\n- Do not include markdown, quotes, or extra explanation.\\n- The value should be in Portuguese if the input is in Portuguese; otherwise in English.\\n\", // src/prompts/issue-enhancer-title.stub.md\n \"issue-planner\": \"You are a senior technical execution planner.\\nProduce the best possible plan for the issue below, filling the JSON schema precisely.\\n{{#if fast}}\\n\\nFAST MODE: Be brief and direct. Minimize reasoning depth.\\n- 2-4 steps maximum. Skip optional fields (unknowns, risks, alternatives).\\n- No tooling reflection needed — set shouldUseSkills: false, shouldUseSubagents: false.\\n- Focus only on: summary, steps, estimatedComplexity, suggestedPaths, suggestedLabels.\\n{{/if}}\\n\\nIssue title: {{title}}\\nIssue description: {{description}}\\n{{#if images}}\\nVisual evidence (attached screenshots for context):\\n{{#each images}}\\n- {{this}}\\n{{/each}}\\n{{/if}}\\n{{#unless fast}}\\n\\nQuality rules:\\n- Be concrete, not generic. No vague phrases like 'implement' or 'improve' without detail.\\n- Break work into actionable steps (2-8 steps). Each step describes WHAT, not HOW.\\n- Each step must have a clear 'doneWhen' acceptance criterion.\\n- Identify assumptions, constraints, unknowns, and risks.\\n- For unknowns, specify what question needs answering and how to resolve it.\\n- Suggest file paths that are likely relevant to the changes.\\n- Suggest labels: bug, feature, frontend, backend, docs, refactor, security, performance, etc.\\n\\nComplexity estimation:\\n- trivial: < 5 min, single-file cosmetic change\\n- low: 5-15 min, small focused change\\n- medium: 15-60 min, multi-file change with testing\\n- high: > 1 hour, architectural change or new feature\\n\\nTooling reflection (REQUIRED):\\n- Evaluate whether the task benefits from using skills (specialized instructions for quality/consistency).\\n- Evaluate whether subtasks should use subagents (parallel work, isolated context, specialization).\\n- Only recommend skills/agents when there is a concrete justification.\\n- For each step, set ownerType: 'agent' for automated work, 'human' for manual review, 'skill' for specialized skills, 'subagent' for delegated work.\\n\\nEffort suggestion:\\n- low: simple fixes, no deep reasoning needed\\n- medium: standard development work\\n- high: complex architecture, security, or cross-cutting changes\\n- Set per-role if different: planner, executor, reviewer\\n{{/unless}}\\n\\nReturn strict JSON matching EXACTLY this schema. No text outside JSON. Use these exact field names:\\n\\n```json\\n{\\n \\\"summary\\\": \\\"one-line summary of what needs to be done\\\",\\n \\\"estimatedComplexity\\\": \\\"trivial|low|medium|high\\\",\\n \\\"steps\\\": [\\n {\\n \\\"step\\\": 1,\\n \\\"action\\\": \\\"what to do (concrete, specific)\\\",\\n \\\"files\\\": [\\\"path/to/file.ts\\\"],\\n \\\"details\\\": \\\"additional context if needed\\\",\\n \\\"ownerType\\\": \\\"agent|human|skill|subagent|tool\\\",\\n \\\"doneWhen\\\": \\\"acceptance criterion as a single string\\\"\\n }\\n ],\\n \\\"assumptions\\\": [\\\"...\\\"],\\n \\\"constraints\\\": [\\\"...\\\"],\\n \\\"unknowns\\\": [\\n { \\\"question\\\": \\\"...\\\", \\\"whyItMatters\\\": \\\"...\\\", \\\"howToResolve\\\": \\\"...\\\" }\\n ],\\n \\\"successCriteria\\\": [\\\"...\\\"],\\n \\\"risks\\\": [\\n { \\\"risk\\\": \\\"...\\\", \\\"impact\\\": \\\"...\\\", \\\"mitigation\\\": \\\"...\\\" }\\n ],\\n \\\"suggestedPaths\\\": [\\\"path/to/relevant/file.ts\\\"],\\n \\\"suggestedLabels\\\": [\\\"frontend\\\", \\\"bug\\\", \\\"feature\\\", \\\"...\\\"],\\n \\\"suggestedEffort\\\": { \\\"default\\\": \\\"medium\\\", \\\"planner\\\": \\\"low\\\", \\\"executor\\\": \\\"medium\\\", \\\"reviewer\\\": \\\"medium\\\" }\\n}\\n```\\n\", // src/prompts/issue-planner.stub.md\n \"issue-planner-refine\": \"You are a senior technical execution planner refining an existing plan based on user feedback.\\n\\n## Original Issue\\nTitle: {{title}}\\nDescription: {{description}}\\n\\n## Current Plan (JSON)\\n```json\\n{{currentPlan}}\\n```\\n\\n## User Feedback\\n{{feedback}}\\n\\n## Instructions\\n\\nRevise the plan above to address the user's feedback precisely.\\n\\nRules:\\n- Keep all parts of the plan that are NOT affected by the feedback unchanged.\\n- Only modify, add, or remove elements that the feedback specifically requests.\\n- Preserve the same JSON schema structure as the current plan.\\n- Maintain step numbering consistency after changes.\\n- If feedback asks to add steps, insert them in the logical position and renumber.\\n- If feedback asks to remove steps, renumber remaining steps sequentially.\\n- Update the summary if the overall direction changed.\\n- Re-evaluate estimatedComplexity if the scope changed significantly.\\n- Update suggestedPaths and suggestedLabels if affected by the changes.\\n\\nReturn strict JSON. No text outside JSON.\\n\", // src/prompts/issue-planner-refine.stub.md\n \"mcp-integrate-client\": \"Integrate {{client}} with the local fifony MCP server.\\n\\nGoal: {{goal}}\\n\\n{{integrationGuide}}\\n\\nUse the available fifony resources and tools instead of inventing your own persistence model.\\n\", // src/prompts/mcp-integrate-client.stub.md\n \"mcp-integration-guide\": \"# fifony MCP integration\\n\\nWorkspace root: `{{workspaceRoot}}`\\nPersistence root: `{{persistenceRoot}}`\\nState root: `{{stateRoot}}`\\n\\nRecommended MCP client command:\\n\\n```json\\n{\\n \\\"mcpServers\\\": {\\n \\\"fifony\\\": {\\n \\\"command\\\": \\\"npx\\\",\\n \\\"args\\\": [\\\"fifony\\\", \\\"mcp\\\", \\\"--workspace\\\", \\\"{{workspaceRoot}}\\\", \\\"--persistence\\\", \\\"{{persistenceRoot}}\\\"]\\n }\\n }\\n}\\n```\\n\\nExpected workflow:\\n\\n1. Read `fifony://guide/overview` and `fifony://state/summary`.\\n2. Use `fifony.list_issues` or read `fifony://issues`.\\n3. Create work with `fifony.create_issue`.\\n4. Update workflow state with `fifony.update_issue_state`.\\n5. Use the prompts exposed by this MCP server to structure planning or execution.\\n\\nThe MCP server is read-write against the same `s3db` filesystem store used by the fifony runtime.\\n\", // src/prompts/mcp-integration-guide.stub.md\n \"mcp-issue\": \"You are integrating with fifony as the {{role}} using {{provider}}.\\n\\nIssue ID: {{id}}\\nTitle: {{title}}\\nState: {{state}}\\nCapability category: {{capabilityCategory}}\\n{{#if overlays.length}}\\nOverlays: {{overlays | join \\\", \\\"}}\\n{{/if}}\\n{{#if paths.length}}\\nPaths: {{paths | join \\\", \\\"}}\\n{{/if}}\\nDescription:\\n{{description}}\\n\\nUse fifony as the source of truth:\\n- Persist transitions through the fifony tools instead of inventing local state.\\n- Keep outputs actionable and aligned with the tracked issue lifecycle.\\n\", // src/prompts/mcp-issue.stub.md\n \"mcp-review-workflow\": \"Review the pipeline configuration for this fifony workspace as {{provider}}.\\n\\nWorkspace: {{workspaceRoot}}\\n\\nFocus on:\\n- provider orchestration quality (plan/execute/review stages)\\n- hooks safety (beforeRun, afterRun, afterCreate, beforeRemove)\\n- prompt clarity\\n- issue lifecycle correctness\\n- what an MCP client needs in order to integrate cleanly\\n\", // src/prompts/mcp-review-workflow.stub.md\n \"mcp-route-task\": \"Use this routing decision as the execution plan for the task.\\n\\n{{resolutionJson}}\\n\", // src/prompts/mcp-route-task.stub.md\n \"project-analysis\": \"You are analyzing a software project to help configure an AI-powered development assistant.\\n\\nLook at the project structure, source code, configuration files, and any documentation you can find. Pay special attention to:\\n- README, CLAUDE.md, AGENTS.md, or any project documentation\\n- Build files: package.json, Cargo.toml, pyproject.toml, build.gradle, Gemfile, go.mod, Makefile, CMakeLists.txt, pom.xml, etc.\\n- Source code directories and their contents\\n- Configuration files (.env, docker-compose, terraform, etc.)\\n- CI/CD pipelines (.github/workflows, .gitlab-ci, Jenkinsfile, etc.)\\n\\nReturn a JSON object with exactly these fields:\\n\\n{\\n \\\"description\\\": \\\"A concise 2-3 sentence description of what this project does, its purpose, and who it's for.\\\",\\n \\\"language\\\": \\\"The primary programming language (e.g. typescript, python, rust, java, kotlin, ruby, go, swift, c++)\\\",\\n \\\"domains\\\": [\\\"Array of relevant domain tags that apply to this project\\\"],\\n \\\"stack\\\": [\\\"Array of key technologies, frameworks, and tools used\\\"],\\n \\\"suggestedAgents\\\": [\\\"Array of specialist agent names that would help develop this project\\\"]\\n}\\n\\nFor \\\"domains\\\", choose from: frontend, backend, mobile, devops, database, ai-ml, security, testing, games, ecommerce, fintech, healthcare, education, saas, design, product, marketing, embedded, blockchain, spatial-computing, data-engineering.\\n\\nFor \\\"suggestedAgents\\\", choose from: frontend-developer, backend-architect, database-optimizer, security-engineer, devops-automator, mobile-app-builder, ai-engineer, ui-designer, ux-architect, code-reviewer, technical-writer, sre, data-engineer, software-architect, game-designer.\\n\\nReturn ONLY the JSON object. No markdown fences, no explanation, no extra text.\\n\", // src/prompts/project-analysis.stub.md\n \"workflow-default\": \"You are working on {{issue.identifier}}.\\n\\nTitle: {{issue.title}}\\nDescription:\\n{{issue.description}}\\n\", // src/prompts/workflow-default.stub.md\n \"workflow-plan-section\": \"## Execution Plan\\n\\nComplexity: {{estimatedComplexity}}\\nSummary: {{summary}}\\n\\nSteps:\\n{{#each steps}}\\n{{step}}. {{action}}{{#if files.length}} (files: {{files | join \\\", \\\"}}){{/if}}{{#if details}} - {{details}}{{/if}}\\n{{/each}}\\n\\nFollow this plan. Complete each step in order.\\n\", // src/prompts/workflow-plan-section.stub.md\n} as const;\n\nexport type PromptTemplateName = keyof typeof PROMPT_TEMPLATES;\n"],"mappings":"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","names":["env","resolve","env","env"]}
|