fifony 0.1.42 → 0.1.43

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.
Files changed (58) hide show
  1. package/app/dist/assets/{CommandPalette-DNR5umI1.js → CommandPalette-M4VAMxCU.js} +1 -1
  2. package/app/dist/assets/{KeyboardShortcutsHelp-Dpl19F20.js → KeyboardShortcutsHelp-DkvPUXQq.js} +1 -1
  3. package/app/dist/assets/OnboardingWizard-B7V9hoCR.js +1 -0
  4. package/app/dist/assets/analytics.lazy-zVJdF880.js +1 -0
  5. package/app/dist/assets/{api-ChEctgc5.js → api-CkVfYg_m.js} +1 -1
  6. package/app/dist/assets/{createLucideIcon-R47sXufx.js → createLucideIcon-Dfk_Hxud.js} +1 -1
  7. package/app/dist/assets/index-BpiCi7Ew.css +1 -0
  8. package/app/dist/assets/index-D2INW0zc.js +47 -0
  9. package/app/dist/assets/vendor-BEoYbFV1.js +9 -0
  10. package/app/dist/index.html +5 -5
  11. package/app/dist/service-worker.js +9 -4
  12. package/bin/fifony.js +3 -0
  13. package/dist/agent/pty-daemon.js +177 -0
  14. package/dist/agent/run-local.js +177 -43
  15. package/dist/{agent-NNGZEKZH.js → agent-RMQTTUEC.js} +37 -16
  16. package/dist/analytics-broadcaster-O6YBP66L.js +145 -0
  17. package/dist/chunk-3NE23NYW.js +82 -0
  18. package/dist/chunk-42AMQAJG.js +404 -0
  19. package/dist/{chunk-H5N7O5NP.js → chunk-AILXZ2TD.js} +79 -147
  20. package/dist/{chunk-I2UHVKHS.js → chunk-BRSR26VK.js} +2 -2
  21. package/dist/chunk-E2EWEYA4.js +1302 -0
  22. package/dist/chunk-ESWHDHH6.js +102 -0
  23. package/dist/{chunk-NB44PCD2.js → chunk-FJNH3G2Z.js} +1061 -1138
  24. package/dist/chunk-MVTGAKQK.js +493 -0
  25. package/dist/chunk-QQQLP3PL.js +155 -0
  26. package/dist/chunk-SOBLO4YZ.js +2016 -0
  27. package/dist/chunk-YRSH2CLW.js +13784 -0
  28. package/dist/cli.js +335 -44
  29. package/dist/{issue-state-machine-GPQNZYUZ.js → fsm-issue-YGGF7SIL.js} +9 -5
  30. package/dist/helpers-L7NYO5XS.js +53 -0
  31. package/dist/issue-log-broadcaster-WZAHISYB.js +84 -0
  32. package/dist/{issues-MZLRSXD6.js → issues-3QRR7KM6.js} +10 -8
  33. package/dist/log-analyzer-K7MXQB4T.js +287 -0
  34. package/dist/mcp/server.js +109 -137
  35. package/dist/parallel-executor-6INE6NDO.js +118 -0
  36. package/dist/pid-manager-UBWXVSMD.js +21 -0
  37. package/dist/queue-workers-XFZK3TT5.js +32 -0
  38. package/dist/replan-issue.command-4UCWYHGZ.js +15 -0
  39. package/dist/scheduler-ZP7GOZDW.js +26 -0
  40. package/dist/{settings-NGY33WQE.js → settings-ZAWDCFP2.js} +32 -8
  41. package/dist/settings.resource-5CW456AZ.js +24 -0
  42. package/dist/store-M6NCKMZY.js +97 -0
  43. package/dist/{web-push-CRVDJKWR.js → web-push-AX5IIK3P.js} +2 -2
  44. package/dist/{workspace-D3F3XGSI.js → workspace-CJTWFWTJ.js} +5 -4
  45. package/package.json +8 -7
  46. package/app/dist/assets/OnboardingWizard-CijMhJDW.js +0 -1
  47. package/app/dist/assets/analytics.lazy-Dq90a756.js +0 -1
  48. package/app/dist/assets/index-Dy_fM427.js +0 -54
  49. package/app/dist/assets/index-Q9jBP0Pz.css +0 -1
  50. package/app/dist/assets/vendor-DkWeBvNl.js +0 -9
  51. package/dist/chunk-2CVTK5F2.js +0 -288
  52. package/dist/chunk-37N5OFHM.js +0 -125
  53. package/dist/chunk-JTKUWIQD.js +0 -8406
  54. package/dist/chunk-RBDBGU2C.js +0 -303
  55. package/dist/issue-runner-CMZPSVC7.js +0 -16
  56. package/dist/queue-workers-XZ6DGH4W.js +0 -23
  57. package/dist/scheduler-NVE6L3P7.js +0 -22
  58. package/dist/store-4HCGBN4L.js +0 -65
@@ -1,288 +0,0 @@
1
- import {
2
- ALLOWED_STATES,
3
- DEBUG_BOOT
4
- } from "./chunk-37N5OFHM.js";
5
-
6
- // src/concerns/helpers.ts
7
- import { env } from "process";
8
- import { parse as parseYaml } from "yaml";
9
- function now() {
10
- return (/* @__PURE__ */ new Date()).toISOString();
11
- }
12
- function isoWeek(date) {
13
- const d = date ? new Date(date) : /* @__PURE__ */ new Date();
14
- if (Number.isNaN(d.getTime())) return "";
15
- const tmp = new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()));
16
- const dayNum = tmp.getUTCDay() || 7;
17
- tmp.setUTCDate(tmp.getUTCDate() + 4 - dayNum);
18
- const yearStart = new Date(Date.UTC(tmp.getUTCFullYear(), 0, 1));
19
- const weekNo = Math.ceil(((tmp.getTime() - yearStart.getTime()) / 864e5 + 1) / 7);
20
- return `${tmp.getUTCFullYear()}-W${String(weekNo).padStart(2, "0")}`;
21
- }
22
- function resolveEnvVar(value) {
23
- if (!value.startsWith("$")) return value;
24
- const varName = value.slice(1);
25
- const resolved = env[varName];
26
- return resolved && resolved.trim().length > 0 ? resolved.trim() : "";
27
- }
28
- function toStringValue(value, fallback = "") {
29
- if (typeof value !== "string" || value.trim().length === 0) return fallback;
30
- const trimmed = value.trim();
31
- if (trimmed.startsWith("$") && /^\$[A-Za-z_][A-Za-z0-9_]*$/.test(trimmed)) {
32
- const resolved = resolveEnvVar(trimmed);
33
- return resolved.length > 0 ? resolved : fallback;
34
- }
35
- return trimmed;
36
- }
37
- function toNumberValue(value, fallback = 1) {
38
- const parsed = typeof value === "number" ? value : typeof value === "string" ? Number.parseInt(value, 10) : Number.NaN;
39
- return Number.isFinite(parsed) && parsed > 0 ? Math.round(parsed) : fallback;
40
- }
41
- function toBooleanValue(value, fallback) {
42
- return typeof value === "boolean" ? value : fallback;
43
- }
44
- function toStringArray(value) {
45
- if (!Array.isArray(value)) return [];
46
- return value.filter((entry) => typeof entry === "string" && entry.trim().length > 0).map((entry) => entry.trim());
47
- }
48
- function clamp(value, min, max) {
49
- return Math.min(Math.max(value, min), max);
50
- }
51
- function parseIssueState(value) {
52
- const raw = typeof value === "string" ? value.trim() : "";
53
- if (ALLOWED_STATES.includes(raw)) {
54
- return raw;
55
- }
56
- return void 0;
57
- }
58
- function normalizeState(value, fallback = "Planning") {
59
- return parseIssueState(value) ?? fallback;
60
- }
61
- function parseEnvNumber(name, fallback) {
62
- return toNumberValue(env[name], fallback);
63
- }
64
- function parseIntArg(value, fallback) {
65
- const parsed = Number.parseInt(value, 10);
66
- return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
67
- }
68
- function parsePositiveIntEnv(name, fallback) {
69
- const source = env[name];
70
- if (!source) return fallback;
71
- return parseIntArg(source, fallback);
72
- }
73
- function withRetryBackoff(attempt, baseDelayMs) {
74
- return Math.min(baseDelayMs * 2 ** attempt, 5 * 60 * 1e3);
75
- }
76
- function idToSafePath(value) {
77
- return value.toLowerCase().replace(/[^a-z0-9._-]/g, "-");
78
- }
79
- function appendFileTail(target, text, maxLength) {
80
- const merged = `${target}
81
- ${text}`;
82
- if (merged.length <= maxLength) return merged;
83
- return `\u2026${merged.slice(-(maxLength - 1))}`;
84
- }
85
- function debugBoot(message) {
86
- if (!DEBUG_BOOT) return;
87
- console.error(`[FIFONY_DEBUG_BOOT] ${message}`);
88
- }
89
- function fail(message) {
90
- console.error(message);
91
- process.exit(1);
92
- }
93
- function extractJsonObjects(text) {
94
- const results = [];
95
- let depth = 0;
96
- let start = -1;
97
- let inStr = false;
98
- let esc = false;
99
- for (let i = 0; i < text.length; i++) {
100
- const ch = text[i];
101
- if (inStr) {
102
- if (esc) {
103
- esc = false;
104
- continue;
105
- }
106
- if (ch === "\\") {
107
- esc = true;
108
- continue;
109
- }
110
- if (ch === '"') {
111
- inStr = false;
112
- }
113
- continue;
114
- }
115
- if (ch === '"') {
116
- inStr = true;
117
- continue;
118
- }
119
- if (ch === "{") {
120
- if (depth === 0) start = i;
121
- depth++;
122
- } else if (ch === "}") {
123
- depth = Math.max(0, depth - 1);
124
- if (depth === 0 && start >= 0) {
125
- results.push(text.slice(start, i + 1));
126
- start = -1;
127
- }
128
- }
129
- }
130
- return results;
131
- }
132
- function repairTruncatedJson(text) {
133
- const firstBrace = text.indexOf("{");
134
- if (firstBrace < 0) return null;
135
- let json = text.slice(firstBrace);
136
- let inStr = false;
137
- let esc = false;
138
- const stack = [];
139
- for (let i = 0; i < json.length; i++) {
140
- const ch = json[i];
141
- if (inStr) {
142
- if (esc) {
143
- esc = false;
144
- continue;
145
- }
146
- if (ch === "\\") {
147
- esc = true;
148
- continue;
149
- }
150
- if (ch === '"') {
151
- inStr = false;
152
- }
153
- continue;
154
- }
155
- if (ch === '"') {
156
- inStr = true;
157
- continue;
158
- }
159
- if (ch === "{") stack.push("{");
160
- else if (ch === "[") stack.push("[");
161
- else if (ch === "}") {
162
- if (stack.length > 0 && stack[stack.length - 1] === "{") stack.pop();
163
- } else if (ch === "]") {
164
- if (stack.length > 0 && stack[stack.length - 1] === "[") stack.pop();
165
- }
166
- }
167
- if (!inStr && stack.length === 0) return json;
168
- if (inStr) {
169
- if (json.endsWith("\\")) json = json.slice(0, -1);
170
- json += '"';
171
- }
172
- json = json.replace(/[,:\s]+$/, "");
173
- while (stack.length > 0) {
174
- const open = stack.pop();
175
- json += open === "{" ? "}" : "]";
176
- }
177
- return json;
178
- }
179
-
180
- // src/agents/prompting.ts
181
- import { TemplateEngine } from "recker";
182
-
183
- // src/agents/generated/prompts.ts
184
- var PROMPT_TEMPLATES = {
185
- "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 capabilitiesManifest}}\n{{capabilitiesManifest}}\n{{/if}}\n\n{{#if skillContext}}\n{{skillContext}}\n{{/if}}\n\n{{#if targetPaths.length}}\nTarget paths: {{targetPaths | join ", "}}\n{{/if}}\n\nWorkspace: {{workspacePath}}\n\n{{basePrompt}}\n',
186
- // src/agents/prompts/agent-provider-base.stub.md
187
- "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',
188
- // src/agents/prompts/agent-turn.stub.md
189
- "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 capabilitiesManifest}}\n{{capabilitiesManifest}}\n{{/if}}\n\n{{#if skillContext}}\n{{skillContext}}\n{{/if}}\n\n{{planPrompt}}\n\n{{#if suggestedAgents.length}}\n## Agents (Claude-specific)\nYou have access to the Agent tool for spawning subagents. Use these agents for this task:\n{{#each suggestedAgents}}\n- Use the **{{this}}** agent for specialized work in its domain.\n{{/each}}\n\nLaunch agents for independent subtasks to maximize parallelism.\nUse the main thread for coordination and integration.\n{{/if}}\n\n{{#if suggestedSkills.length}}\n## Skills\nInvoke these skills during execution:\n{{#each suggestedSkills}}\n- Run **/{{this}}** for specialized quality checks and procedures.\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 `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',
190
- // src/agents/prompts/compile-execution-claude.stub.md
191
- "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 capabilitiesManifest}}\n{{capabilitiesManifest}}\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 suggestedSkills.length}}\n## Skills\nInvoke these skills during execution:\n{{#each suggestedSkills}}\n- Run **/{{this}}** for specialized quality checks and procedures.\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 `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',
192
- // src/agents/prompts/compile-execution-codex.stub.md
193
- "compile-review": "Review the work done for {{issueIdentifier}}.\n\nTitle: {{title}}\nDescription: {{description}}\nWorkspace: {{workspacePath}}\n{{#if images.length}}\n\n## Visual Evidence (screenshots attached to this issue)\n{{#each images}}\n- {{this}}\n{{/each}}\nCompare the implementation against these screenshots if they show expected behavior or bugs.\n{{/if}}\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 `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",
194
- // src/agents/prompts/compile-review.stub.md
195
- "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',
196
- // src/agents/prompts/integrations-agency-agents.stub.md
197
- "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',
198
- // src/agents/prompts/integrations-impeccable.stub.md
199
- "issue-enhancer-description": 'You are helping improve issue metadata for a software execution queue.\nRewrite the description to be clearer, complete, and directly actionable.\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- The value should be in Portuguese if the input is in Portuguese; otherwise in English.\n\nAfter your analysis, return a single JSON code block as the LAST thing in your output:\n```json\n{ "field": "description", "value": "<REPLACE_WITH_ACTUAL_DESCRIPTION>" }\n```\n',
200
- // src/agents/prompts/issue-enhancer-description.stub.md
201
- "issue-enhancer-title": 'You are helping improve issue metadata for a software execution queue.\nRewrite the title for clarity, actionability, and specificity.\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\nReturn a single JSON code block as the LAST thing in your output:\n```json\n{ "field": "title", "value": "<REPLACE_WITH_ACTUAL_TITLE>" }\n```\n',
202
- // src/agents/prompts/issue-enhancer-title.stub.md
203
- "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- Focus only on: summary, steps, estimatedComplexity, suggestedPaths.\n{{/if}}\n\n{{#if availableCapabilities}}\n## Installed Capabilities (recommend from these lists)\n\n{{#if availableSkills.length}}\n### Skills\n{{#each availableSkills}}\n- **{{name}}**{{#if description}} \u2014 {{description}}{{/if}}{{#if whenToUse}} (Use when: {{whenToUse}}){{/if}}\n{{/each}}\n{{/if}}\n{{#if availableAgents.length}}\n### Agents\n{{#each availableAgents}}\n- **{{name}}**{{#if description}} \u2014 {{description}}{{/if}}{{#if whenToUse}} (Use when: {{whenToUse}}){{/if}}{{#if avoidIf}} (Avoid if: {{avoidIf}}){{/if}}\n{{/each}}\n{{/if}}\n{{#if availableCommands.length}}\n### Commands\n{{#each availableCommands}}\n- /{{name}}\n{{/each}}\n{{/if}}\n\nRecommend skills and agents ONLY from these lists. Do not invent names.\nOnly recommend when there is a concrete benefit \u2014 not everything needs skills or agents.\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\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\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\n## Instructions\n\nYou are encouraged to explore the codebase \u2014 read files, search for patterns, inspect structure \u2014 to produce an informed plan. Use any tools available to you.\n\nAfter your analysis, you MUST output the final plan as a single JSON code block (```json ... ```).\nThe JSON block must be the LAST thing in your output. Any analysis or reasoning should come BEFORE it.\n\nIMPORTANT: Replace ALL placeholder values with real content specific to the issue above. Do NOT copy the example values literally \u2014 every field must contain actual plan content derived from the issue.\n\nUse these exact field names:\n\n```json\n{\n "summary": "<YOUR one-line summary here>",\n "estimatedComplexity": "trivial|low|medium|high",\n "steps": [\n {\n "step": 1,\n "action": "<YOUR concrete action here>",\n "files": ["<real/path/to/file.ts>"],\n "details": "<YOUR additional context>",\n "doneWhen": "<YOUR acceptance criterion>"\n }\n ],\n "assumptions": ["<YOUR assumptions>"],\n "constraints": ["<YOUR constraints>"],\n "unknowns": [\n { "question": "<YOUR question>", "whyItMatters": "<YOUR reason>", "howToResolve": "<YOUR approach>" }\n ],\n "successCriteria": ["<YOUR criteria>"],\n "risks": [\n { "risk": "<YOUR risk>", "impact": "<YOUR impact>", "mitigation": "<YOUR mitigation>" }\n ],\n "suggestedPaths": ["<real/path/to/relevant/file.ts>"],\n "suggestedSkills": ["<skill-name-from-list-above>"],\n "suggestedAgents": ["<agent-name-from-list-above>"],\n "suggestedEffort": { "default": "medium", "planner": "low", "executor": "medium", "reviewer": "medium" }\n}\n```\n',
204
- // src/agents/prompts/issue-planner.stub.md
205
- "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{{#if images}}\n\n## Visual Evidence\n{{#each images}}\n- {{this}}\n{{/each}}\n{{/if}}\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, suggestedSkills, and suggestedAgents if affected by the changes.\n\nYou may explore the codebase to inform your revisions. After your analysis, return the revised plan as a single JSON code block (```json ... ```) as the LAST thing in your output.\n",
206
- // src/agents/prompts/issue-planner-refine.stub.md
207
- "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",
208
- // src/agents/prompts/mcp-integrate-client.stub.md
209
- "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',
210
- // src/agents/prompts/mcp-integration-guide.stub.md
211
- "mcp-issue": 'You are integrating with fifony as the {{role}} using {{provider}}.\n\nIssue ID: {{id}}\nTitle: {{title}}\nState: {{state}}\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',
212
- // src/agents/prompts/mcp-issue.stub.md
213
- "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",
214
- // src/agents/prompts/mcp-review-workflow.stub.md
215
- "merge-conflict-resolver": 'You are resolving git merge conflicts in a software project.\n\n## Context\n\nIssue: {{issueIdentifier}} \u2014 {{title}}\n{{#if description}}\nDescription: {{description}}\n{{/if}}\nMerging branch `{{featureBranch}}` into `{{baseBranch}}`.\n\n## Conflicting Files\n\nThe following files have conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`) that you must resolve:\n\n{{#each conflictFiles}}\n- {{this}}\n{{/each}}\n\n## Instructions\n\n1. Read each conflicting file and understand the intent of BOTH sides.\n2. Resolve ALL conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`) by choosing the correct combination of changes. Prefer keeping both sides\' intent when possible.\n3. CRITICAL: Before staging, run `grep -n "^<<<<<<<" <file>` on EACH file to verify zero conflict markers remain. If any markers remain, fix them first.\n4. After verifying each file is clean, stage with `git add <file>`.\n5. Do NOT commit \u2014 the merge commit will be created automatically after you finish.\n6. Do NOT modify files that are not in the conflict list.\n7. Do NOT use `git add .` or `git add -A` \u2014 stage only the conflicting files listed above.\n',
216
- // src/agents/prompts/merge-conflict-resolver.stub.md
217
- "project-analysis": `You are analyzing a software project to help configure an AI-powered development assistant.
218
-
219
- Look at the project structure, source code, configuration files, and any documentation you can find. Pay special attention to:
220
- - README, CLAUDE.md, AGENTS.md, or any project documentation
221
- - Build files: package.json, Cargo.toml, pyproject.toml, build.gradle, Gemfile, go.mod, Makefile, CMakeLists.txt, pom.xml, etc.
222
- - Source code directories and their contents
223
- - Configuration files (.env, docker-compose, terraform, etc.)
224
- - CI/CD pipelines (.github/workflows, .gitlab-ci, Jenkinsfile, etc.)
225
-
226
- Return a JSON object with exactly these fields:
227
-
228
- {
229
- "description": "A concise 2-3 sentence description of what this project does, its purpose, and who it's for.",
230
- "language": "The primary programming language (e.g. typescript, python, rust, java, kotlin, ruby, go, swift, c++)",
231
- "domains": ["Array of relevant domain tags that apply to this project"],
232
- "stack": ["Array of key technologies, frameworks, and tools used"],
233
- "suggestedAgents": ["Array of specialist agent names that would help develop this project"]
234
- }
235
-
236
- For "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.
237
-
238
- For "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.
239
-
240
- Return ONLY the JSON object. No markdown fences, no explanation, no extra text.
241
- `,
242
- // src/agents/prompts/project-analysis.stub.md
243
- "workflow-default": "You are working on {{issue.identifier}}.\n\nTitle: {{issue.title}}\nDescription:\n{{issue.description}}\n",
244
- // src/agents/prompts/workflow-default.stub.md
245
- "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'
246
- // src/agents/prompts/workflow-plan-section.stub.md
247
- };
248
-
249
- // src/agents/prompting.ts
250
- var engine = new TemplateEngine({
251
- cache: true,
252
- format: "raw",
253
- strict: false
254
- });
255
- function normalizePrompt(text) {
256
- return text.replace(/\r\n/g, "\n").replace(/\n{3,}/g, "\n\n").trim();
257
- }
258
- async function renderPrompt(name, context = {}) {
259
- return renderPromptString(PROMPT_TEMPLATES[name], context);
260
- }
261
- async function renderPromptString(template, context = {}) {
262
- const rendered = await engine.render(template, context);
263
- return normalizePrompt(rendered);
264
- }
265
-
266
- export {
267
- now,
268
- isoWeek,
269
- toStringValue,
270
- toNumberValue,
271
- toBooleanValue,
272
- toStringArray,
273
- clamp,
274
- parseIssueState,
275
- normalizeState,
276
- parseEnvNumber,
277
- parseIntArg,
278
- parsePositiveIntEnv,
279
- withRetryBackoff,
280
- idToSafePath,
281
- appendFileTail,
282
- debugBoot,
283
- fail,
284
- extractJsonObjects,
285
- repairTruncatedJson,
286
- renderPrompt
287
- };
288
- //# sourceMappingURL=chunk-2CVTK5F2.js.map
@@ -1,125 +0,0 @@
1
- // src/concerns/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
- import { existsSync } from "fs";
7
- var __filename = fileURLToPath(import.meta.url);
8
- var __dirname = dirname(__filename);
9
- function findPackageRoot(startDir) {
10
- let dir = startDir;
11
- for (let i = 0; i < 5; i++) {
12
- if (existsSync(join(dir, "package.json"))) return dir;
13
- const parent = dirname(dir);
14
- if (parent === dir) break;
15
- dir = parent;
16
- }
17
- return resolve(startDir, "../..");
18
- }
19
- var PACKAGE_ROOT = findPackageRoot(__dirname);
20
- var CLI_ARGS = argv.slice(2);
21
- function readArgValue(args, flag) {
22
- const index = args.indexOf(flag);
23
- if (index === -1) return void 0;
24
- const value = args[index + 1];
25
- if (!value || value.startsWith("--")) return void 0;
26
- return value;
27
- }
28
- function resolveInputPath(value) {
29
- if (value.startsWith("~/")) {
30
- return resolve(homedir(), value.slice(2));
31
- }
32
- return resolve(value);
33
- }
34
- function resolvePersistenceRoot(value) {
35
- const resolved = value.startsWith("file://") ? fileURLToPath(value) : resolveInputPath(value);
36
- return basename(resolved) === ".fifony" ? resolved : join(resolved, ".fifony");
37
- }
38
- var CLI_WORKSPACE_ROOT = readArgValue(CLI_ARGS, "--workspace");
39
- var CLI_PERSISTENCE = readArgValue(CLI_ARGS, "--persistence");
40
- var TARGET_ROOT = resolveInputPath(
41
- env.FIFONY_WORKSPACE_ROOT ?? CLI_WORKSPACE_ROOT ?? getCwd()
42
- );
43
- var STATE_ROOT = resolvePersistenceRoot(
44
- env.FIFONY_PERSISTENCE ?? CLI_PERSISTENCE ?? env.FIFONY_BOOTSTRAP_ROOT ?? TARGET_ROOT
45
- );
46
- var SOURCE_ROOT = `${STATE_ROOT}/source`;
47
- var WORKSPACE_ROOT = `${STATE_ROOT}/workspaces`;
48
- var SOURCE_MARKER = `${SOURCE_ROOT}/.fifony-local-source-ready`;
49
- var ATTACHMENTS_ROOT = `${STATE_ROOT}/attachments`;
50
- var S3DB_DATABASE_PATH = `${STATE_ROOT}/fifony.sqlite`;
51
- var S3DB_RUNTIME_RESOURCE = "runtime_state";
52
- var S3DB_ISSUE_RESOURCE = "issues";
53
- var S3DB_ISSUE_PLAN_RESOURCE = "issue_plans";
54
- var S3DB_EVENT_RESOURCE = "events";
55
- var S3DB_SETTINGS_RESOURCE = "settings";
56
- var S3DB_AGENT_SESSION_RESOURCE = "agent_sessions";
57
- var S3DB_AGENT_PIPELINE_RESOURCE = "agent_pipelines";
58
- var S3DB_RUNTIME_RECORD_ID = "current";
59
- var S3DB_RUNTIME_SCHEMA_VERSION = 1;
60
- var FRONTEND_DIR = `${PACKAGE_ROOT}/app/dist`;
61
- var FRONTEND_INDEX = `${FRONTEND_DIR}/index.html`;
62
- var FRONTEND_MANIFEST_JSON = `${FRONTEND_DIR}/manifest.webmanifest`;
63
- var FRONTEND_SERVICE_WORKER_JS = `${FRONTEND_DIR}/service-worker.js`;
64
- var FRONTEND_ICON_SVG = `${FRONTEND_DIR}/icon.svg`;
65
- var FRONTEND_MASKABLE_ICON_SVG = `${FRONTEND_DIR}/icon-maskable.svg`;
66
- var FRONTEND_OFFLINE_HTML = `${FRONTEND_DIR}/offline.html`;
67
- var DEBUG_BOOT = env.FIFONY_DEBUG_BOOT === "1";
68
- var ALLOWED_STATES = [
69
- "Planning",
70
- "PendingApproval",
71
- "Queued",
72
- "Running",
73
- "Reviewing",
74
- "PendingDecision",
75
- "Blocked",
76
- "Approved",
77
- "Merged",
78
- "Cancelled",
79
- "Archived"
80
- ];
81
- var TERMINAL_STATES = /* @__PURE__ */ new Set(["Merged", "Cancelled", "Archived"]);
82
- var COMPLETED_STATES = /* @__PURE__ */ new Set(["Approved", "Merged", "Cancelled", "Archived"]);
83
- var EXECUTING_STATES = /* @__PURE__ */ new Set(["Running", "Reviewing"]);
84
- var PERSIST_EVENTS_MAX = 500;
85
- var FAST_BOOT = CLI_ARGS.includes("--fast-boot");
86
- var SKIP_SOURCE = FAST_BOOT || CLI_ARGS.includes("--skip-source");
87
- var SKIP_SCAN = FAST_BOOT || CLI_ARGS.includes("--skip-scan");
88
- var SKIP_RECOVERY = FAST_BOOT || CLI_ARGS.includes("--skip-recovery");
89
- var QUIET_MODE = CLI_ARGS.includes("--quiet") || CLI_ARGS.includes("--silent");
90
-
91
- export {
92
- PACKAGE_ROOT,
93
- CLI_ARGS,
94
- TARGET_ROOT,
95
- STATE_ROOT,
96
- SOURCE_ROOT,
97
- WORKSPACE_ROOT,
98
- SOURCE_MARKER,
99
- ATTACHMENTS_ROOT,
100
- S3DB_DATABASE_PATH,
101
- S3DB_RUNTIME_RESOURCE,
102
- S3DB_ISSUE_RESOURCE,
103
- S3DB_ISSUE_PLAN_RESOURCE,
104
- S3DB_EVENT_RESOURCE,
105
- S3DB_SETTINGS_RESOURCE,
106
- S3DB_AGENT_SESSION_RESOURCE,
107
- S3DB_AGENT_PIPELINE_RESOURCE,
108
- S3DB_RUNTIME_RECORD_ID,
109
- S3DB_RUNTIME_SCHEMA_VERSION,
110
- FRONTEND_DIR,
111
- FRONTEND_INDEX,
112
- FRONTEND_MANIFEST_JSON,
113
- FRONTEND_SERVICE_WORKER_JS,
114
- FRONTEND_ICON_SVG,
115
- FRONTEND_MASKABLE_ICON_SVG,
116
- FRONTEND_OFFLINE_HTML,
117
- DEBUG_BOOT,
118
- ALLOWED_STATES,
119
- TERMINAL_STATES,
120
- COMPLETED_STATES,
121
- EXECUTING_STATES,
122
- PERSIST_EVENTS_MAX,
123
- QUIET_MODE
124
- };
125
- //# sourceMappingURL=chunk-37N5OFHM.js.map