fifony 0.1.26 → 0.1.27-next.84df008
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 +152 -129
- package/app/dist/assets/{KeyboardShortcutsHelp-lTNj9GiT.js → KeyboardShortcutsHelp-By0KcDhZ.js} +1 -1
- package/app/dist/assets/OnboardingWizard-5cz7Onsu.js +1 -0
- package/app/dist/assets/{analytics.lazy-C42PFRzr.js → analytics.lazy-ArFwnOEn.js} +1 -1
- package/app/dist/assets/{createLucideIcon-BWC-guQt.js → createLucideIcon-DgMTp0yx.js} +1 -1
- package/app/dist/assets/index-59O8esMr.js +45 -0
- package/app/dist/assets/{index-Qr2OPvRO.css → index-DuBwUsuf.css} +1 -1
- package/app/dist/assets/vendor-D-IqxHHu.js +9 -0
- package/app/dist/dinofffaur.webp +0 -0
- package/app/dist/index.html +4 -4
- package/app/dist/service-worker.js +1 -1
- package/dist/agent/run-local.js +57 -144
- package/dist/agent-KMXNVDRO.js +74 -0
- package/dist/chunk-FJR4ALEN.js +847 -0
- package/dist/{chunk-2F3Q2MAG.js → chunk-HSGUPFTV.js} +1224 -611
- package/dist/chunk-O5AEQXUV.js +311 -0
- package/dist/chunk-OONOOWNC.js +123 -0
- package/dist/{chunk-NFHVAIPW.js → chunk-UYCDOH6S.js} +380 -795
- package/dist/chunk-XENKNHFS.js +295 -0
- package/dist/cli.js +6 -4
- package/dist/issue-runner-JJAFMHKV.js +15 -0
- package/dist/{issue-state-machine-OWABY5S2.js → issue-state-machine-ACMUJSXC.js} +5 -3
- package/dist/issues-VDFXBK3N.js +40 -0
- package/dist/mcp/server.js +23 -121
- package/dist/queue-workers-U47CVPTO.js +23 -0
- package/dist/scheduler-MEXEDV4M.js +21 -0
- package/dist/{store-WN47MDT5.js → store-AG6LLYJ7.js} +7 -5
- package/dist/workspace-474CCKTW.js +44 -0
- package/package.json +6 -6
- package/app/dist/assets/OnboardingWizard-B6LlJR9B.js +0 -1
- package/app/dist/assets/index-fVSxs9d5.js +0 -43
- package/app/dist/assets/vendor-BTlTWMUF.js +0 -9
- package/dist/chunk-AMOGDOM7.js +0 -796
- package/dist/chunk-IA7IMQ5F.js +0 -91
- package/dist/issue-runner-DA4IDLKX.js +0 -13
- package/dist/queue-workers-JIH5ZMNQ.js +0 -20
package/dist/mcp/server.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
inferCapabilityPaths,
|
|
3
2
|
parseIssueState,
|
|
4
|
-
renderPrompt
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
renderPrompt
|
|
4
|
+
} from "../chunk-O5AEQXUV.js";
|
|
5
|
+
import "../chunk-OONOOWNC.js";
|
|
7
6
|
|
|
8
7
|
// src/mcp/server.ts
|
|
9
8
|
import { env as env3, stdin } from "process";
|
|
@@ -88,15 +87,10 @@ async function initDatabase() {
|
|
|
88
87
|
identifier: "string|required",
|
|
89
88
|
title: "string|required",
|
|
90
89
|
description: "string|optional",
|
|
91
|
-
priority: "number|required",
|
|
92
90
|
state: "string|required",
|
|
93
91
|
branchName: "string|optional",
|
|
94
92
|
labels: "json|required",
|
|
95
93
|
paths: "json|optional",
|
|
96
|
-
inferredPaths: "json|optional",
|
|
97
|
-
capabilityCategory: "string|optional",
|
|
98
|
-
capabilityOverlays: "json|optional",
|
|
99
|
-
capabilityRationale: "json|optional",
|
|
100
94
|
blockedBy: "json|required",
|
|
101
95
|
assignedToWorker: "boolean|required",
|
|
102
96
|
createdAt: "datetime|required",
|
|
@@ -117,11 +111,7 @@ async function initDatabase() {
|
|
|
117
111
|
commandOutputTail: "string|optional"
|
|
118
112
|
},
|
|
119
113
|
partitions: {
|
|
120
|
-
byState: { fields: { state: "string" } }
|
|
121
|
-
byCapabilityCategory: { fields: { capabilityCategory: "string" } },
|
|
122
|
-
byStateAndCapability: {
|
|
123
|
-
fields: { state: "string", capabilityCategory: "string" }
|
|
124
|
-
}
|
|
114
|
+
byState: { fields: { state: "string" } }
|
|
125
115
|
},
|
|
126
116
|
asyncPartitions: true
|
|
127
117
|
});
|
|
@@ -190,10 +180,10 @@ async function listRecords(resource, limit = 100) {
|
|
|
190
180
|
}
|
|
191
181
|
async function listIssues(filters = {}) {
|
|
192
182
|
await initDatabase();
|
|
193
|
-
const { state
|
|
183
|
+
const { state } = filters;
|
|
194
184
|
if (!issueResource) return [];
|
|
195
|
-
const partition = state
|
|
196
|
-
const partitionValues = state
|
|
185
|
+
const partition = state ? "byState" : null;
|
|
186
|
+
const partitionValues = state ? { state } : {};
|
|
197
187
|
const records = await issueResource.list({ partition, partitionValues, limit: 500 });
|
|
198
188
|
return records.map((record) => record);
|
|
199
189
|
}
|
|
@@ -367,13 +357,6 @@ async function buildIntegrationGuide() {
|
|
|
367
357
|
stateRoot: STATE_ROOT
|
|
368
358
|
});
|
|
369
359
|
}
|
|
370
|
-
function computeCapabilityCounts(issues) {
|
|
371
|
-
return issues.reduce((accumulator, issue) => {
|
|
372
|
-
const key = typeof issue.capabilityCategory === "string" && issue.capabilityCategory.trim() ? issue.capabilityCategory.trim() : "default";
|
|
373
|
-
accumulator[key] = (accumulator[key] ?? 0) + 1;
|
|
374
|
-
return accumulator;
|
|
375
|
-
}, {});
|
|
376
|
-
}
|
|
377
360
|
async function buildStateSummary() {
|
|
378
361
|
const runtime = await getRuntimeSnapshot();
|
|
379
362
|
const issues = await getIssues();
|
|
@@ -386,7 +369,6 @@ async function buildStateSummary() {
|
|
|
386
369
|
accumulator[key] = (accumulator[key] ?? 0) + 1;
|
|
387
370
|
return accumulator;
|
|
388
371
|
}, {});
|
|
389
|
-
const byCapability = computeCapabilityCounts(issues);
|
|
390
372
|
return JSON.stringify({
|
|
391
373
|
workspaceRoot: WORKSPACE_ROOT,
|
|
392
374
|
persistenceRoot: PERSISTENCE_ROOT,
|
|
@@ -394,29 +376,20 @@ async function buildStateSummary() {
|
|
|
394
376
|
runtimeUpdatedAt: runtime.updatedAt ?? null,
|
|
395
377
|
issueCount: issues.length,
|
|
396
378
|
issuesByState: byState,
|
|
397
|
-
issuesByCapability: byCapability,
|
|
398
379
|
sessionCount: sessions.length,
|
|
399
380
|
pipelineCount: pipelines.length,
|
|
400
381
|
recentEventCount: events.length
|
|
401
382
|
}, null, 2);
|
|
402
383
|
}
|
|
403
384
|
async function buildIssuePrompt(issue, provider, role) {
|
|
404
|
-
const resolution = resolveTaskCapabilities({
|
|
405
|
-
id: issue.id,
|
|
406
|
-
identifier: issue.identifier,
|
|
407
|
-
title: issue.title,
|
|
408
|
-
description: typeof issue.description === "string" ? issue.description : "",
|
|
409
|
-
labels: Array.isArray(issue.labels) ? issue.labels.filter((value) => typeof value === "string") : [],
|
|
410
|
-
paths: Array.isArray(issue.paths) ? issue.paths.filter((value) => typeof value === "string") : []
|
|
411
|
-
});
|
|
412
385
|
return renderPrompt("mcp-issue", {
|
|
413
386
|
role,
|
|
414
387
|
provider,
|
|
415
388
|
id: issue.id,
|
|
416
389
|
title: issue.title,
|
|
417
390
|
state: issue.state ?? "Planning",
|
|
418
|
-
capabilityCategory:
|
|
419
|
-
overlays:
|
|
391
|
+
capabilityCategory: "",
|
|
392
|
+
overlays: [],
|
|
420
393
|
paths: Array.isArray(issue.paths) ? issue.paths.filter((value) => typeof value === "string") : [],
|
|
421
394
|
description: issue.description || "No description provided."
|
|
422
395
|
});
|
|
@@ -431,8 +404,7 @@ async function listResourcesMcp() {
|
|
|
431
404
|
{ uri: "fifony://guide/integration", name: "Fifony MCP integration guide", description: "How to wire an MCP client to this Fifony workspace.", mimeType: "text/markdown" },
|
|
432
405
|
{ uri: "fifony://state/summary", name: "Fifony state summary", description: "Compact summary of the current runtime, issue, and pipeline state.", mimeType: "application/json" },
|
|
433
406
|
{ uri: "fifony://issues", name: "Fifony issues", description: "Full issue list from the durable Fifony store.", mimeType: "application/json" },
|
|
434
|
-
{ uri: "fifony://integrations", name: "Fifony integrations", description: "Discovered local integrations such as agency-agents and impeccable skills.", mimeType: "application/json" }
|
|
435
|
-
{ uri: "fifony://capabilities", name: "Fifony capability routing", description: "How Fifony would route current issues to providers, profiles, and overlays.", mimeType: "application/json" }
|
|
407
|
+
{ uri: "fifony://integrations", name: "Fifony integrations", description: "Discovered local integrations such as agency-agents and impeccable skills.", mimeType: "application/json" }
|
|
436
408
|
];
|
|
437
409
|
resources.push(
|
|
438
410
|
{ uri: "fifony://analytics", name: "Token usage analytics", description: "Token usage analytics snapshot including totals, cost estimates, and per-model breakdown.", mimeType: "application/json" },
|
|
@@ -460,38 +432,6 @@ async function readResource(uri) {
|
|
|
460
432
|
if (uri === "fifony://integrations") {
|
|
461
433
|
return [{ uri, mimeType: "application/json", text: JSON.stringify(discoverIntegrations(WORKSPACE_ROOT), null, 2) }];
|
|
462
434
|
}
|
|
463
|
-
if (uri === "fifony://capabilities") {
|
|
464
|
-
const issues = await getIssues();
|
|
465
|
-
return [{
|
|
466
|
-
uri,
|
|
467
|
-
mimeType: "application/json",
|
|
468
|
-
text: JSON.stringify(
|
|
469
|
-
issues.map((issue) => ({
|
|
470
|
-
issueId: issue.id,
|
|
471
|
-
title: issue.title,
|
|
472
|
-
paths: Array.isArray(issue.paths) ? issue.paths.filter((value) => typeof value === "string") : [],
|
|
473
|
-
inferredPaths: inferCapabilityPaths({
|
|
474
|
-
id: issue.id,
|
|
475
|
-
identifier: issue.identifier,
|
|
476
|
-
title: issue.title,
|
|
477
|
-
description: issue.description,
|
|
478
|
-
labels: Array.isArray(issue.labels) ? issue.labels.filter((value) => typeof value === "string") : [],
|
|
479
|
-
paths: Array.isArray(issue.paths) ? issue.paths.filter((value) => typeof value === "string") : []
|
|
480
|
-
}),
|
|
481
|
-
resolution: resolveTaskCapabilities({
|
|
482
|
-
id: issue.id,
|
|
483
|
-
identifier: issue.identifier,
|
|
484
|
-
title: issue.title,
|
|
485
|
-
description: issue.description,
|
|
486
|
-
labels: Array.isArray(issue.labels) ? issue.labels.filter((value) => typeof value === "string") : [],
|
|
487
|
-
paths: Array.isArray(issue.paths) ? issue.paths.filter((value) => typeof value === "string") : []
|
|
488
|
-
})
|
|
489
|
-
})),
|
|
490
|
-
null,
|
|
491
|
-
2
|
|
492
|
-
)
|
|
493
|
-
}];
|
|
494
|
-
}
|
|
495
435
|
if (uri === "fifony://analytics") {
|
|
496
436
|
try {
|
|
497
437
|
const result = await apiGet("/api/analytics/tokens");
|
|
@@ -578,21 +518,20 @@ async function readResource(uri) {
|
|
|
578
518
|
function listTools() {
|
|
579
519
|
return [
|
|
580
520
|
{ name: "fifony.status", description: "Return a compact status summary for the current Fifony workspace.", inputSchema: { type: "object", properties: {}, additionalProperties: false } },
|
|
581
|
-
{ name: "fifony.list_issues", description: "List issues from the Fifony durable store.", inputSchema: { type: "object", properties: { state: { type: "string" }
|
|
582
|
-
{ name: "fifony.create_issue", description: "Create a new issue directly in the Fifony durable store.", inputSchema: { type: "object", properties: { id: { type: "string" }, title: { type: "string" }, description: { type: "string" },
|
|
521
|
+
{ name: "fifony.list_issues", description: "List issues from the Fifony durable store.", inputSchema: { type: "object", properties: { state: { type: "string" } }, additionalProperties: false } },
|
|
522
|
+
{ name: "fifony.create_issue", description: "Create a new issue directly in the Fifony durable store.", inputSchema: { type: "object", properties: { id: { type: "string" }, title: { type: "string" }, description: { type: "string" }, state: { type: "string" }, paths: { type: "array", items: { type: "string" } } }, required: ["title"], additionalProperties: false } },
|
|
583
523
|
{ name: "fifony.update_issue_state", description: "Update an issue state in the Fifony store and append an event.", inputSchema: { type: "object", properties: { issueId: { type: "string" }, state: { type: "string" }, note: { type: "string" } }, required: ["issueId", "state"], additionalProperties: false } },
|
|
584
524
|
{ name: "fifony.plan", description: "Generate an AI plan for an issue. The issue must be in Planning state. Returns the plan summary and step count.", inputSchema: { type: "object", properties: { issueId: { type: "string", description: "The issue identifier to plan." }, fast: { type: "boolean", description: "Use fast planning mode (less thorough but quicker)." } }, required: ["issueId"], additionalProperties: false } },
|
|
585
525
|
{ name: "fifony.refine", description: "Refine an existing plan with feedback. The issue must already have a plan.", inputSchema: { type: "object", properties: { issueId: { type: "string", description: "The issue identifier whose plan to refine." }, feedback: { type: "string", description: "Feedback to guide the plan refinement." } }, required: ["issueId", "feedback"], additionalProperties: false } },
|
|
586
|
-
{ name: "fifony.approve", description: "Approve a plan and
|
|
526
|
+
{ name: "fifony.approve", description: "Approve a plan and queue the issue for execution.", inputSchema: { type: "object", properties: { issueId: { type: "string", description: "The issue identifier to approve." } }, required: ["issueId"], additionalProperties: false } },
|
|
587
527
|
{ name: "fifony.merge", description: "Merge workspace changes back into the project root. Copies new/modified files from the issue workspace to TARGET_ROOT and removes files that were deleted. Skips fifony internal files, node_modules, .git, and dist.", inputSchema: { type: "object", properties: { issueId: { type: "string", description: "The issue identifier whose workspace to merge." } }, required: ["issueId"], additionalProperties: false } },
|
|
588
528
|
{ name: "fifony.analytics", description: "Get token usage analytics including overall totals, cost estimates, and top issues by token consumption.", inputSchema: { type: "object", properties: {}, additionalProperties: false } },
|
|
589
529
|
{ name: "fifony.integration_config", description: "Generate a ready-to-paste MCP client configuration snippet for this Fifony workspace.", inputSchema: { type: "object", properties: { client: { type: "string" } }, additionalProperties: false } },
|
|
590
530
|
{ name: "fifony.list_integrations", description: "List discovered local integrations such as agency-agents profiles and impeccable skills.", inputSchema: { type: "object", properties: {}, additionalProperties: false } },
|
|
591
531
|
{ name: "fifony.integration_snippet", description: "Generate a workflow or prompt snippet for a discovered integration.", inputSchema: { type: "object", properties: { integration: { type: "string" } }, required: ["integration"], additionalProperties: false } },
|
|
592
|
-
{ name: "fifony.resolve_capabilities", description: "Resolve which providers, roles, profiles, and overlays Fifony should use for a task.", inputSchema: { type: "object", properties: { title: { type: "string" }, description: { type: "string" }, labels: { type: "array", items: { type: "string" } }, paths: { type: "array", items: { type: "string" } } }, required: ["title"], additionalProperties: false } },
|
|
593
532
|
{ name: "fifony.get_issue", description: "Get full detail of a single issue including plan, history, events, and diff status.", inputSchema: { type: "object", properties: { issueId: { type: "string", description: "The issue identifier." } }, required: ["issueId"], additionalProperties: false } },
|
|
594
533
|
{ name: "fifony.cancel_issue", description: "Cancel an issue, moving it to Cancelled state.", inputSchema: { type: "object", properties: { issueId: { type: "string", description: "The issue identifier to cancel." } }, required: ["issueId"], additionalProperties: false } },
|
|
595
|
-
{ name: "fifony.retry_issue", description: "Retry a failed or blocked issue,
|
|
534
|
+
{ name: "fifony.retry_issue", description: "Retry a failed or blocked issue, re-queuing it for execution.", inputSchema: { type: "object", properties: { issueId: { type: "string", description: "The issue identifier to retry." } }, required: ["issueId"], additionalProperties: false } },
|
|
596
535
|
{ name: "fifony.enhance", description: "AI-enhance an issue title or description. Provide either an issueId to enhance an existing issue, or title+description for standalone enhancement.", inputSchema: { type: "object", properties: { issueId: { type: "string", description: "Issue identifier (optional, for existing issues)." }, title: { type: "string", description: "Issue title (for standalone enhancement)." }, description: { type: "string", description: "Issue description (for standalone enhancement)." }, field: { type: "string", enum: ["title", "description"], description: "Which field to enhance." } }, required: ["field"], additionalProperties: false } },
|
|
597
536
|
{ name: "fifony.get_diff", description: "Get git diff for an issue's workspace, including per-file summary and full diff text.", inputSchema: { type: "object", properties: { issueId: { type: "string", description: "The issue identifier." } }, required: ["issueId"], additionalProperties: false } },
|
|
598
537
|
{ name: "fifony.get_live", description: "Get live agent output for a running issue, including log tail, PID, elapsed time, and status.", inputSchema: { type: "object", properties: { issueId: { type: "string", description: "The issue identifier." } }, required: ["issueId"], additionalProperties: false } },
|
|
@@ -617,8 +556,7 @@ async function callTool(name, args = {}) {
|
|
|
617
556
|
if (name === "fifony.status") return toolText(await buildStateSummary());
|
|
618
557
|
if (name === "fifony.list_issues") {
|
|
619
558
|
const stateFilter = typeof args.state === "string" && args.state.trim() ? args.state.trim() : "";
|
|
620
|
-
|
|
621
|
-
return toolText(JSON.stringify(await listIssues({ state: stateFilter || void 0, capabilityCategory: capabilityCategory || void 0 }), null, 2));
|
|
559
|
+
return toolText(JSON.stringify(await listIssues({ state: stateFilter || void 0 }), null, 2));
|
|
622
560
|
}
|
|
623
561
|
if (name === "fifony.create_issue") {
|
|
624
562
|
await initDatabase();
|
|
@@ -628,26 +566,17 @@ async function callTool(name, args = {}) {
|
|
|
628
566
|
const explicitId = typeof args.id === "string" && args.id.trim() ? args.id.trim() : "";
|
|
629
567
|
const issueId = explicitId || `LOCAL-${hashInput(`${title}:${nowIso()}`)}`.toUpperCase();
|
|
630
568
|
const description = typeof args.description === "string" ? args.description : "";
|
|
631
|
-
const priority = typeof args.priority === "number" ? args.priority : 2;
|
|
632
569
|
const state = parseIssueState(args.state) ?? "Planning";
|
|
633
|
-
const baseLabels = Array.isArray(args.labels) ? args.labels.filter((value) => typeof value === "string") : ["fifony", "mcp"];
|
|
634
570
|
const paths = Array.isArray(args.paths) ? args.paths.filter((value) => typeof value === "string") : [];
|
|
635
|
-
const
|
|
636
|
-
const resolution = resolveTaskCapabilities({ id: issueId, identifier: issueId, title, description, labels: baseLabels, paths });
|
|
637
|
-
const labels = [...new Set([...baseLabels, resolution.category ? `capability:${resolution.category}` : "", ...resolution.overlays.map((overlay) => `overlay:${overlay}`)].filter(Boolean))];
|
|
571
|
+
const labels = [];
|
|
638
572
|
const record = await issueResource2?.insert({
|
|
639
573
|
id: issueId,
|
|
640
574
|
identifier: issueId,
|
|
641
575
|
title,
|
|
642
576
|
description,
|
|
643
|
-
priority,
|
|
644
577
|
state,
|
|
645
578
|
labels,
|
|
646
579
|
paths,
|
|
647
|
-
inferredPaths,
|
|
648
|
-
capabilityCategory: resolution.category,
|
|
649
|
-
capabilityOverlays: resolution.overlays,
|
|
650
|
-
capabilityRationale: resolution.rationale,
|
|
651
580
|
blockedBy: [],
|
|
652
581
|
assignedToWorker: false,
|
|
653
582
|
createdAt: nowIso(),
|
|
@@ -657,7 +586,7 @@ async function callTool(name, args = {}) {
|
|
|
657
586
|
attempts: 0,
|
|
658
587
|
maxAttempts: 3
|
|
659
588
|
});
|
|
660
|
-
await appendEvent("info", `Issue ${issueId} created through MCP.`, { title, state, labels, paths
|
|
589
|
+
await appendEvent("info", `Issue ${issueId} created through MCP.`, { title, state, labels, paths }, issueId);
|
|
661
590
|
return toolText(JSON.stringify(record ?? { id: issueId }, null, 2));
|
|
662
591
|
}
|
|
663
592
|
if (name === "fifony.update_issue_state") {
|
|
@@ -714,8 +643,8 @@ async function callTool(name, args = {}) {
|
|
|
714
643
|
const issue = result.issue;
|
|
715
644
|
return toolText(JSON.stringify({
|
|
716
645
|
issueId,
|
|
717
|
-
state: issue?.state ?? "
|
|
718
|
-
message: `Plan approved for ${issueId}. Issue moved to
|
|
646
|
+
state: issue?.state ?? "PendingApproval",
|
|
647
|
+
message: `Plan approved for ${issueId}. Issue moved to PendingApproval and is ready for execution.`
|
|
719
648
|
}, null, 2));
|
|
720
649
|
}
|
|
721
650
|
if (name === "fifony.merge") {
|
|
@@ -755,13 +684,6 @@ async function callTool(name, args = {}) {
|
|
|
755
684
|
const integration = typeof args.integration === "string" ? args.integration : "";
|
|
756
685
|
return toolText(await buildIntegrationSnippet(integration, WORKSPACE_ROOT));
|
|
757
686
|
}
|
|
758
|
-
if (name === "fifony.resolve_capabilities") {
|
|
759
|
-
const title = typeof args.title === "string" ? args.title : "";
|
|
760
|
-
const description = typeof args.description === "string" ? args.description : "";
|
|
761
|
-
const labels = Array.isArray(args.labels) ? args.labels.filter((value) => typeof value === "string") : [];
|
|
762
|
-
const paths = Array.isArray(args.paths) ? args.paths.filter((value) => typeof value === "string") : [];
|
|
763
|
-
return toolText(JSON.stringify({ inferredPaths: inferCapabilityPaths({ title, description, labels, paths }), resolution: resolveTaskCapabilities({ title, description, labels, paths }) }, null, 2));
|
|
764
|
-
}
|
|
765
687
|
if (name === "fifony.get_issue") {
|
|
766
688
|
const issueId = typeof args.issueId === "string" ? args.issueId.trim() : "";
|
|
767
689
|
if (!issueId) throw new Error("issueId is required");
|
|
@@ -804,7 +726,7 @@ async function callTool(name, args = {}) {
|
|
|
804
726
|
try {
|
|
805
727
|
const result = await apiPost(`/api/issues/${encodeURIComponent(issueId)}/retry`);
|
|
806
728
|
const issue = result.issue;
|
|
807
|
-
return toolText(JSON.stringify({ issueId, state: issue?.state ?? "
|
|
729
|
+
return toolText(JSON.stringify({ issueId, state: issue?.state ?? "PendingApproval", message: `Issue ${issueId} has been retried.` }, null, 2));
|
|
808
730
|
} catch (error) {
|
|
809
731
|
throw new Error(`Failed to retry issue ${issueId}: ${String(error)}`);
|
|
810
732
|
}
|
|
@@ -927,7 +849,6 @@ function listPrompts() {
|
|
|
927
849
|
{ name: "fifony-integrate-client", description: "Generate setup instructions for connecting an MCP-capable client to Fifony.", arguments: [{ name: "client", description: "Client name, e.g. codex or claude.", required: true }, { name: "goal", description: "What the client should do with Fifony.", required: false }] },
|
|
928
850
|
{ name: "fifony-plan-issue", description: "Generate a planning prompt for a specific issue in the Fifony store.", arguments: [{ name: "issueId", description: "Issue identifier.", required: true }, { name: "provider", description: "Agent provider name.", required: false }] },
|
|
929
851
|
{ name: "fifony-use-integration", description: "Generate a concrete integration prompt for agency-agents or impeccable.", arguments: [{ name: "integration", description: "Integration id: agency-agents or impeccable.", required: true }] },
|
|
930
|
-
{ name: "fifony-route-task", description: "Explain which providers, profiles, and overlays Fifony would choose for a task.", arguments: [{ name: "title", description: "Task title.", required: true }, { name: "description", description: "Task description.", required: false }, { name: "labels", description: "Comma-separated labels.", required: false }, { name: "paths", description: "Comma-separated target paths or files.", required: false }] },
|
|
931
852
|
{ name: "fifony-diagnose-blocked", description: "Help diagnose why an issue is blocked or failing, analyzing the issue plan, last error, history, and events.", arguments: [{ name: "issueId", description: "Issue identifier to diagnose.", required: true }] },
|
|
932
853
|
{ name: "fifony-weekly-summary", description: "Generate a weekly progress summary including issues created, completed, blocked, and token usage.", arguments: [] },
|
|
933
854
|
{ name: "fifony-refine-plan", description: "Guided plan refinement prompt that shows the current plan and helps provide specific feedback.", arguments: [{ name: "issueId", description: "Issue identifier whose plan to refine.", required: true }, { name: "concern", description: "Optional specific concern to address in refinement.", required: false }] },
|
|
@@ -975,25 +896,6 @@ async function getPrompt(name, args = {}) {
|
|
|
975
896
|
}]
|
|
976
897
|
};
|
|
977
898
|
}
|
|
978
|
-
if (name === "fifony-route-task") {
|
|
979
|
-
const title = typeof args.title === "string" ? args.title : "";
|
|
980
|
-
const description = typeof args.description === "string" ? args.description : "";
|
|
981
|
-
const labels = typeof args.labels === "string" ? args.labels.split(",").map((label) => label.trim()).filter(Boolean) : [];
|
|
982
|
-
const paths = typeof args.paths === "string" ? args.paths.split(",").map((value) => value.trim()).filter(Boolean) : [];
|
|
983
|
-
const resolution = resolveTaskCapabilities({ title, description, labels, paths });
|
|
984
|
-
return {
|
|
985
|
-
description: "Task routing prompt produced by the Fifony capability resolver.",
|
|
986
|
-
messages: [{
|
|
987
|
-
role: "user",
|
|
988
|
-
content: {
|
|
989
|
-
type: "text",
|
|
990
|
-
text: await renderPrompt("mcp-route-task", {
|
|
991
|
-
resolutionJson: JSON.stringify(resolution, null, 2)
|
|
992
|
-
})
|
|
993
|
-
}
|
|
994
|
-
}]
|
|
995
|
-
};
|
|
996
|
-
}
|
|
997
899
|
if (name === "fifony-diagnose-blocked") {
|
|
998
900
|
const issueId = typeof args.issueId === "string" ? args.issueId.trim() : "";
|
|
999
901
|
if (!issueId) throw new Error("issueId is required");
|
|
@@ -1065,10 +967,10 @@ async function getPrompt(name, args = {}) {
|
|
|
1065
967
|
return accumulator;
|
|
1066
968
|
}, {});
|
|
1067
969
|
const totalIssues = issues.length;
|
|
1068
|
-
const completed = byState["
|
|
970
|
+
const completed = byState["Approved"] ?? 0;
|
|
1069
971
|
const blocked = (byState["Blocked"] ?? 0) + (byState["Failed"] ?? 0);
|
|
1070
|
-
const inProgress = (byState["Running"] ?? 0) + (byState["Reviewing"] ?? 0) + (byState["
|
|
1071
|
-
const planned = byState["
|
|
972
|
+
const inProgress = (byState["Running"] ?? 0) + (byState["Reviewing"] ?? 0) + (byState["PendingDecision"] ?? 0) + (byState["Queued"] ?? 0);
|
|
973
|
+
const planned = byState["PendingApproval"] ?? 0;
|
|
1072
974
|
const planning = byState["Planning"] ?? 0;
|
|
1073
975
|
const cancelled = byState["Cancelled"] ?? 0;
|
|
1074
976
|
const inputTokens = typeof overall.inputTokens === "number" ? overall.inputTokens : 0;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
areQueueWorkersActive,
|
|
3
|
+
cleanTerminalWorkspaces,
|
|
4
|
+
enqueue,
|
|
5
|
+
getQueueStats,
|
|
6
|
+
initQueueWorkers,
|
|
7
|
+
recoverOrphans,
|
|
8
|
+
recoverState,
|
|
9
|
+
stopQueueWorkers
|
|
10
|
+
} from "./chunk-XENKNHFS.js";
|
|
11
|
+
import "./chunk-DVU3CXWA.js";
|
|
12
|
+
import "./chunk-OONOOWNC.js";
|
|
13
|
+
export {
|
|
14
|
+
areQueueWorkersActive,
|
|
15
|
+
cleanTerminalWorkspaces,
|
|
16
|
+
enqueue,
|
|
17
|
+
getQueueStats,
|
|
18
|
+
initQueueWorkers,
|
|
19
|
+
recoverOrphans,
|
|
20
|
+
recoverState,
|
|
21
|
+
stopQueueWorkers
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=queue-workers-U47CVPTO.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
analyzeParallelizability,
|
|
3
|
+
ensureNotStale,
|
|
4
|
+
hasTerminalQueue,
|
|
5
|
+
installGracefulShutdown,
|
|
6
|
+
isShuttingDown
|
|
7
|
+
} from "./chunk-HSGUPFTV.js";
|
|
8
|
+
import "./chunk-FJR4ALEN.js";
|
|
9
|
+
import "./chunk-UYCDOH6S.js";
|
|
10
|
+
import "./chunk-O5AEQXUV.js";
|
|
11
|
+
import "./chunk-XENKNHFS.js";
|
|
12
|
+
import "./chunk-DVU3CXWA.js";
|
|
13
|
+
import "./chunk-OONOOWNC.js";
|
|
14
|
+
export {
|
|
15
|
+
analyzeParallelizability,
|
|
16
|
+
ensureNotStale,
|
|
17
|
+
hasTerminalQueue,
|
|
18
|
+
installGracefulShutdown,
|
|
19
|
+
isShuttingDown
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=scheduler-MEXEDV4M.js.map
|
|
@@ -18,16 +18,18 @@ import {
|
|
|
18
18
|
persistStateFull,
|
|
19
19
|
replacePersistedSetting,
|
|
20
20
|
setActiveApiPlugin
|
|
21
|
-
} from "./chunk-
|
|
22
|
-
import "./chunk-IA7IMQ5F.js";
|
|
21
|
+
} from "./chunk-HSGUPFTV.js";
|
|
23
22
|
import {
|
|
24
23
|
hasDirtyState,
|
|
25
24
|
markEventDirty,
|
|
26
25
|
markIssueDirty,
|
|
27
26
|
markIssuePlanDirty
|
|
28
|
-
} from "./chunk-
|
|
29
|
-
import "./chunk-
|
|
27
|
+
} from "./chunk-FJR4ALEN.js";
|
|
28
|
+
import "./chunk-UYCDOH6S.js";
|
|
29
|
+
import "./chunk-O5AEQXUV.js";
|
|
30
|
+
import "./chunk-XENKNHFS.js";
|
|
30
31
|
import "./chunk-DVU3CXWA.js";
|
|
32
|
+
import "./chunk-OONOOWNC.js";
|
|
31
33
|
export {
|
|
32
34
|
closeStateStore,
|
|
33
35
|
getAgentPipelineResource,
|
|
@@ -53,4 +55,4 @@ export {
|
|
|
53
55
|
replacePersistedSetting,
|
|
54
56
|
setActiveApiPlugin
|
|
55
57
|
};
|
|
56
|
-
//# sourceMappingURL=store-
|
|
58
|
+
//# sourceMappingURL=store-AG6LLYJ7.js.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import {
|
|
2
|
+
bootstrapSource,
|
|
3
|
+
cleanWorkspace,
|
|
4
|
+
computeDiffStats,
|
|
5
|
+
createGitWorktree,
|
|
6
|
+
detectDefaultBranch,
|
|
7
|
+
dryMerge,
|
|
8
|
+
ensureSourceReady,
|
|
9
|
+
ensureWorktreeCommitted,
|
|
10
|
+
hydrateIssuePathsFromWorkspace,
|
|
11
|
+
inferChangedWorkspacePaths,
|
|
12
|
+
mergeWorkspace,
|
|
13
|
+
parseDiffStats,
|
|
14
|
+
prepareWorkspace,
|
|
15
|
+
rebaseWorktree,
|
|
16
|
+
setSkipSource,
|
|
17
|
+
shouldSkipMergePath,
|
|
18
|
+
syncIssueDiffStatsToStore,
|
|
19
|
+
writeVersionedArtifacts
|
|
20
|
+
} from "./chunk-UYCDOH6S.js";
|
|
21
|
+
import "./chunk-O5AEQXUV.js";
|
|
22
|
+
import "./chunk-DVU3CXWA.js";
|
|
23
|
+
import "./chunk-OONOOWNC.js";
|
|
24
|
+
export {
|
|
25
|
+
bootstrapSource,
|
|
26
|
+
cleanWorkspace,
|
|
27
|
+
computeDiffStats,
|
|
28
|
+
createGitWorktree,
|
|
29
|
+
detectDefaultBranch,
|
|
30
|
+
dryMerge,
|
|
31
|
+
ensureSourceReady,
|
|
32
|
+
ensureWorktreeCommitted,
|
|
33
|
+
hydrateIssuePathsFromWorkspace,
|
|
34
|
+
inferChangedWorkspacePaths,
|
|
35
|
+
mergeWorkspace,
|
|
36
|
+
parseDiffStats,
|
|
37
|
+
prepareWorkspace,
|
|
38
|
+
rebaseWorktree,
|
|
39
|
+
setSkipSource,
|
|
40
|
+
shouldSkipMergePath,
|
|
41
|
+
syncIssueDiffStatsToStore,
|
|
42
|
+
writeVersionedArtifacts
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=workspace-474CCKTW.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fifony",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.27-next.84df008",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -50,14 +50,14 @@
|
|
|
50
50
|
"pino-pretty": "^13.1.3",
|
|
51
51
|
"raffel": "^1.0.18",
|
|
52
52
|
"recker": "^1.0.86",
|
|
53
|
-
"s3db.js": "21.3.
|
|
54
|
-
"yaml": "^2.8.
|
|
53
|
+
"s3db.js": "21.3.8",
|
|
54
|
+
"yaml": "^2.8.3"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@tailwindcss/vite": "^4.2.2",
|
|
58
|
-
"@tanstack/react-query": "^5.
|
|
59
|
-
"@tanstack/react-router": "^1.
|
|
60
|
-
"@tanstack/router-plugin": "^1.
|
|
58
|
+
"@tanstack/react-query": "^5.94.5",
|
|
59
|
+
"@tanstack/react-router": "^1.168.1",
|
|
60
|
+
"@tanstack/router-plugin": "^1.167.2",
|
|
61
61
|
"@vitejs/plugin-react": "^6.0.1",
|
|
62
62
|
"daisyui": "^5.5.19",
|
|
63
63
|
"lucide-react": "^0.577.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{n as e}from"./rolldown-runtime-DF2fYuay.js";import{I as t,h as n,m as r}from"./vendor-BTlTWMUF.js";import{t as i}from"./createLucideIcon-BWC-guQt.js";import{A as a,B as o,C as s,E as c,F as l,M as u,N as d,O as f,P as p,R as m,S as h,T as g,_,a as v,c as y,d as b,f as x,g as S,i as C,j as w,k as T,l as E,n as D,p as O,t as k,u as A,v as j,w as M,x as N}from"./index-fVSxs9d5.js";var P=i(`brain`,[[`path`,{d:`M12 18V5`,key:`adv99a`}],[`path`,{d:`M15 13a4.17 4.17 0 0 1-3-4 4.17 4.17 0 0 1-3 4`,key:`1e3is1`}],[`path`,{d:`M17.598 6.5A3 3 0 1 0 12 5a3 3 0 1 0-5.598 1.5`,key:`1gqd8o`}],[`path`,{d:`M17.997 5.125a4 4 0 0 1 2.526 5.77`,key:`iwvgf7`}],[`path`,{d:`M18 18a4 4 0 0 0 2-7.464`,key:`efp6ie`}],[`path`,{d:`M19.967 17.483A4 4 0 1 1 12 18a4 4 0 1 1-7.967-.517`,key:`1gq6am`}],[`path`,{d:`M6 18a4 4 0 0 1-2-7.464`,key:`k1g0md`}],[`path`,{d:`M6.003 5.125a4 4 0 0 0-2.526 5.77`,key:`q97ue3`}]]),ee=i(`chevron-left`,[[`path`,{d:`m15 18-6-6 6-6`,key:`1wnfg3`}]]),F=i(`chevron-right`,[[`path`,{d:`m9 18 6-6-6-6`,key:`mthhwq`}]]),I=i(`flame`,[[`path`,{d:`M12 3q1 4 4 6.5t3 5.5a1 1 0 0 1-14 0 5 5 0 0 1 1-3 1 1 0 0 0 5 0c0-2-1.5-3-1.5-5q0-2 2.5-4`,key:`1slcih`}]]),L=i(`folder-root`,[[`path`,{d:`M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z`,key:`1fr9dc`}],[`circle`,{cx:`12`,cy:`13`,r:`2`,key:`1c1ljs`}],[`path`,{d:`M12 15v5`,key:`11xva1`}]]),R=i(`pencil-line`,[[`path`,{d:`M13 21h8`,key:`1jsn5i`}],[`path`,{d:`m15 5 4 4`,key:`1mk7zo`}],[`path`,{d:`M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z`,key:`1a8usu`}]]),z=i(`rocket`,[[`path`,{d:`M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5`,key:`qeys4`}],[`path`,{d:`M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09`,key:`u4xsad`}],[`path`,{d:`M9 12a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.4 22.4 0 0 1-4 2z`,key:`676m9`}],[`path`,{d:`M9 12H4s.55-3.03 2-4c1.62-1.08 5 .05 5 .05`,key:`92ym6u`}]]),te=i(`shield-check`,[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}],[`path`,{d:`m9 12 2 2 4-4`,key:`dzmm74`}]]),B=e(t(),1),V=n();function ne(){let e=(0,B.useRef)(null),t=(0,B.useRef)([]),n=(0,B.useRef)(null);return(0,B.useEffect)(()=>{let r=e.current;if(!r)return;let i=r.getContext(`2d`),a=[`♪`,`♫`,`♩`,`♬`],o=[`oklch(0.75 0.18 250)`,`oklch(0.80 0.16 200)`,`oklch(0.70 0.20 330)`,`oklch(0.85 0.14 85)`,`oklch(0.75 0.18 145)`,`oklch(0.80 0.12 280)`,`oklch(0.78 0.15 30)`],s=o.length,c=a.length,l=document.createElement(`canvas`);l.width=s*56,l.height=c*56;let u=l.getContext(`2d`);u.textAlign=`center`,u.textBaseline=`middle`,u.font=`48px serif`;let d=[];for(let e=0;e<c;e++){d[e]=[];for(let t=0;t<s;t++){let n=t*56+56/2,r=e*56+56/2;u.fillStyle=o[t],u.fillText(a[e],n,r),d[e][t]={x:t*56,y:e*56}}}let f=0,p=0,m=()=>{let e=window.devicePixelRatio||1;f=window.innerWidth,p=window.innerHeight,r.width=f*e,r.height=p*e,r.style.width=f+`px`,r.style.height=p+`px`,i.setTransform(e,0,0,e,0,0)};m();function h(){let e=f/2,t=p*.38,n=Math.random()*Math.PI*2,r=Math.random()*1.8+.4,i=Math.random()*20,a=Math.floor(Math.random()*c),o=Math.floor(Math.random()*s);return{x:e+Math.cos(n)*i,y:t+Math.sin(n)*i,vx:Math.cos(n)*r,vy:Math.sin(n)*r,gravity:.003+Math.random()*.005,scale:Math.random()*.4+.25,si:a,ci:o,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.04,life:0,maxLife:180+Math.random()*200,fadeIn:15}}let g=Math.min(Math.floor(f*p/6e3),120);t.current=[];for(let e=0;e<g;e++){let e=h(),n=Math.random()*e.maxLife*.8;e.x+=e.vx*n,e.y+=e.vy*n+.5*e.gravity*n*n,e.rotation+=e.rotationSpeed*n,e.life=n,t.current.push(e)}let _=Math.max(1,Math.floor(g/90)),v=0,y=()=>{if(i.clearRect(0,0,f,p),v++,v%2==0)for(let e=0;e<_;e++)t.current.push(h());let e=[];for(let n of t.current){if(n.life++,n.x+=n.vx,n.y+=n.vy,n.vy+=n.gravity,n.rotation+=n.rotationSpeed,n.vx*=.998,n.vy*=.998,n.life>n.maxLife||n.x<-60||n.x>f+60||n.y<-60||n.y>p+60)continue;e.push(n);let t=Math.min(1,n.life/n.fadeIn),r=n.maxLife*.6,a=t*(n.life>r?1-(n.life-r)/(n.maxLife-r):1)*.45;if(a<=.01)continue;let o=d[n.si][n.ci],s=56*n.scale,c=s/2;i.save(),i.translate(n.x,n.y),i.rotate(n.rotation),i.globalAlpha=a,i.drawImage(l,o.x,o.y,56,56,-c,-c,s,s),i.restore()}t.current=e,n.current=requestAnimationFrame(y)};return n.current=requestAnimationFrame(y),window.addEventListener(`resize`,m),()=>{cancelAnimationFrame(n.current),window.removeEventListener(`resize`,m)}},[]),(0,V.jsx)(`canvas`,{ref:e,className:`fixed inset-0 pointer-events-none`,style:{zIndex:0},"aria-hidden":`true`})}var H=[`Welcome`,`Setup`,`Pipeline`,`Agents & Skills`,`Preferences`,`Launch`];function re(){return H}function ie(){return H.length}var ae=[`Setup`,`Pipeline`,`Agents`,`Preferences`,`Launch`];function U(){return ae}var W=[{value:`low`,label:`Low`,icon:D,description:`Quick and light -- fast responses, less thorough`,color:`text-info`},{value:`medium`,label:`Medium`,icon:j,description:`Balanced -- good mix of speed and quality`,color:`text-success`},{value:`high`,label:`High`,icon:P,description:`Thorough -- deeper analysis, takes more time`,color:`text-warning`},{value:`extra-high`,label:`Extra High`,icon:I,description:`Maximum depth -- most thorough, slowest`,color:`text-error`}],G={codex:W,claude:W.filter(e=>e.value!==`extra-high`),gemini:W.filter(e=>e.value!==`extra-high`)};function K(e,t){return G[t?.[e]||`codex`]||W}var q=[{value:`auto`,label:`Auto`},{value:`light`,label:`Light`},{value:`dark`,label:`Dark`},{value:`black`,label:`Black`},{value:`cupcake`,label:`Cupcake`},{value:`night`,label:`Night`},{value:`sunset`,label:`Sunset`}],J=[{role:`planner`,label:`Planner`,description:`Scopes the issue, breaks it into steps, and decides the approach`,icon:P,color:`text-info`},{role:`executor`,label:`Executor`,description:`Implements the plan — writes code, edits files, runs commands`,icon:D,color:`text-primary`},{role:`reviewer`,label:`Reviewer`,description:`Validates the result — checks correctness, scope, and quality`,icon:E,color:`text-secondary`}];async function Y(e,t,n=`ui`){return o.post(`/settings/${encodeURIComponent(e)}`,{value:t,scope:n,source:`user`})}function X(e,t=`medium`){return W.some(t=>t.value===e)?e:t}function oe(e){return!e||typeof e!=`object`||Array.isArray(e)?{planner:`medium`,executor:`medium`,reviewer:`medium`}:{planner:X(e.planner??e.default,`medium`),executor:X(e.executor??e.default,`medium`),reviewer:X(e.reviewer??e.default,`medium`)}}function se(e,t,n={}){return{plan:{provider:e.planner||e.executor||``,model:n.plan||``,effort:t.planner||`medium`},execute:{provider:e.executor||``,model:n.execute||``,effort:t.executor||`medium`},review:{provider:e.reviewer||e.executor||``,model:n.review||``,effort:t.reviewer||`medium`}}}function ce({current:e}){let t=U(),n=e-1;return(0,V.jsx)(`ul`,{className:`steps steps-horizontal w-full max-w-2xl text-xs`,children:t.map((e,t)=>{let r=t<n,i=t===n;return(0,V.jsx)(`li`,{"data-content":r?`✓`:t+1,className:`step ${r||i?`step-primary`:``}`,style:{transition:`color 0.3s ease`},children:e},e)})})}function le({direction:e,stepKey:t,center:n,children:r}){return(0,V.jsx)(`div`,{className:`${e===`forward`?`animate-slide-in-right`:`animate-slide-in-left`} w-full max-w-2xl mx-auto ${n?`my-auto`:``}`,children:r},t)}function ue({step:e,stepCount:t,stepName:n,canProceed:r,launching:i,onBack:a,onNext:o,onLaunch:s}){return e===0?null:(0,V.jsxs)(`div`,{className:`relative z-10 p-4 pb-6 flex items-center max-w-2xl mx-auto w-full justify-between`,children:[(0,V.jsxs)(`button`,{className:`btn btn-ghost gap-1`,onClick:a,disabled:i,children:[(0,V.jsx)(ee,{className:`size-4`}),` Back`]}),e<t-1?(0,V.jsxs)(`button`,{className:`btn btn-primary gap-1`,onClick:o,disabled:!r,children:[`Next `,(0,V.jsx)(F,{className:`size-4`})]}):(0,V.jsx)(`button`,{className:`btn btn-primary btn-lg gap-2 animate-pulse-soft`,onClick:s,disabled:i,children:i?(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(O,{className:`size-5 animate-spin`}),` Launching...`]}):(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(z,{className:`size-5`}),` Launch fifony`]})})]})}function de({workspacePath:e,onGetStarted:t}){return(0,V.jsxs)(`div`,{className:`flex flex-col items-center text-center gap-6 stagger-children py-4`,children:[(0,V.jsx)(`img`,{src:`/assets/dinofffaur.png`,alt:`fifony mascot`,className:`h-72 sm:h-96 object-contain animate-bounce-in select-none pointer-events-none`,style:{filter:`drop-shadow(0 12px 40px rgba(128, 0, 255, 0.3))`}}),(0,V.jsxs)(`h1`,{className:`text-4xl sm:text-5xl font-bold tracking-tight leading-none`,style:{fontFamily:`'Space Grotesk', system-ui, sans-serif`},children:[`Welcome to `,(0,V.jsx)(`span`,{className:`text-primary`,children:`fifony`})]}),(0,V.jsx)(`p`,{className:`text-base-content/60 text-lg max-w-md`,children:`Let's set up your AI orchestration project in just a few steps.`}),e&&(0,V.jsxs)(`div`,{className:`badge badge-lg badge-soft badge-primary gap-2`,children:[(0,V.jsx)(y,{className:`size-3.5`}),`Project target: `,e]}),(0,V.jsxs)(`button`,{className:`btn btn-primary btn-lg gap-2 mt-2`,onClick:t,children:[`Get Started `,(0,V.jsx)(F,{className:`size-5`})]})]})}var fe=new Set([`main`,`master`]);function Z(){let[e,t]=(0,B.useState)(null),[n,r]=(0,B.useState)(!1),[i,a]=(0,B.useState)(!1);return(0,B.useEffect)(()=>{o.get(`/gitignore/status`).then(t).catch(()=>t({exists:!1,hasFifony:!1}))},[]),e===null||e.hasFifony?null:i?(0,V.jsxs)(`div`,{className:`alert alert-success py-2.5 text-sm animate-fade-in`,children:[(0,V.jsx)(te,{className:`size-4 shrink-0`}),(0,V.jsxs)(`span`,{children:[(0,V.jsx)(`code`,{children:`.fifony/`}),` adicionado ao `,(0,V.jsx)(`code`,{children:`.gitignore`})]})]}):(0,V.jsxs)(`div`,{className:`alert alert-warning py-2.5 text-sm`,children:[(0,V.jsx)(te,{className:`size-4 shrink-0`}),(0,V.jsxs)(`div`,{className:`flex-1`,children:[(0,V.jsxs)(`span`,{children:[(0,V.jsx)(`code`,{children:`.fifony/`}),` não está no `,(0,V.jsx)(`code`,{children:`.gitignore`})]}),(0,V.jsx)(`span`,{className:`text-base-content/50 block text-xs mt-0.5`,children:`O fifony guarda estado local lá — não deve ser commitado.`})]}),(0,V.jsx)(`button`,{className:`btn btn-xs btn-warning`,onClick:async()=>{r(!0);try{await o.post(`/gitignore/add`),a(!0)}catch{}finally{r(!1)}},disabled:n,children:n?(0,V.jsx)(O,{className:`size-3 animate-spin`}):`Adicionar`})]})}function Q({currentBranch:e,onBranchCreated:t}){let[n,r]=(0,B.useState)(null),[i,a]=(0,B.useState)(!1),[c,l]=(0,B.useState)(null),[u,d]=(0,B.useState)(e);(0,B.useEffect)(()=>{o.get(`/git/status`).then(e=>{r(e),e.branch&&d(e.branch)}).catch(()=>r({isGit:!0,branch:e,hasCommits:!0}))},[]);let[f,p]=(0,B.useState)(`develop`),[m,h]=(0,B.useState)(!1),[g,y]=(0,B.useState)(null),[b,C]=(0,B.useState)(!1),w=n===null||n.isGit,T=fe.has(u),E=/^[a-zA-Z0-9/_.-]+$/.test(f.trim())&&f.trim().length>0;async function D(){a(!0),l(null);try{let e=await o.post(`/git/init`,{});if(!e.ok)throw Error(e.error||`Failed to initialize git.`);r({isGit:!0,branch:e.branch,hasCommits:!0}),d(e.branch)}catch(e){l(e instanceof Error?e.message:String(e))}finally{a(!1)}}async function k(){if(!(!E||m)){h(!0),y(null);try{let e=await o.post(`/git/branch`,{branchName:f.trim()});if(!e.ok)throw Error(e.error||`Failed to create branch.`);C(!0),t?.(f.trim())}catch(e){y(e instanceof Error?e.message:String(e))}finally{h(!1)}}}return(0,V.jsxs)(`div`,{className:`bg-base-200 rounded-2xl p-5 flex flex-col gap-4`,children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,V.jsx)(_,{className:`size-4 text-primary`}),(0,V.jsx)(`div`,{className:`text-sm font-semibold`,children:`Working branch`})]}),(0,V.jsx)(`p`,{className:`text-xs text-base-content/50 -mt-2`,children:`Agents create worktrees based on the current branch. We recommend not working directly on main.`}),n!==null&&!n.isGit&&(0,V.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,V.jsxs)(`div`,{className:`alert alert-warning py-3`,children:[(0,V.jsx)(S,{className:`size-4 shrink-0`}),(0,V.jsxs)(`div`,{className:`text-sm`,children:[(0,V.jsx)(`p`,{className:`font-semibold`,children:`Not a git repository`}),(0,V.jsx)(`p`,{className:`opacity-80 mt-0.5`,children:`fifony requires git to create agent worktrees. Initialize one here.`})]})]}),c&&(0,V.jsxs)(`p`,{className:`text-xs text-error flex items-center gap-1`,children:[(0,V.jsx)(v,{className:`size-3`}),` `,c]}),(0,V.jsxs)(`button`,{className:`btn btn-primary gap-2 self-start`,onClick:D,disabled:i,children:[i?(0,V.jsx)(O,{className:`size-4 animate-spin`}):(0,V.jsx)(S,{className:`size-4`}),`Initialize git repository`]})]}),w&&(0,V.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-2 px-4 py-3 rounded-box border border-base-300 bg-base-100`,children:[(0,V.jsx)(_,{className:`size-4 opacity-50 shrink-0`}),(0,V.jsx)(`span`,{className:`text-sm opacity-50`,children:`Current branch:`}),(0,V.jsx)(`span`,{className:`font-mono text-sm font-semibold`,children:u||(n===null?`…`:`—`)}),T&&(0,V.jsx)(`span`,{className:`badge badge-warning badge-sm ml-auto shrink-0`,children:`protected`})]}),T&&(0,V.jsxs)(`div`,{className:`alert alert-warning py-3`,children:[(0,V.jsx)(v,{className:`size-4 shrink-0`}),(0,V.jsxs)(`div`,{className:`text-sm`,children:[(0,V.jsxs)(`p`,{className:`font-semibold`,children:[`Working directly on `,(0,V.jsx)(`span`,{className:`font-mono`,children:u})]}),(0,V.jsx)(`p`,{className:`opacity-80 mt-0.5`,children:`In teams with protected branches, local merges are rejected. Create a working branch or use Push PR mode.`})]})]}),b?(0,V.jsxs)(`div`,{className:`alert alert-success py-3 text-sm`,children:[(0,V.jsx)(s,{className:`size-4 shrink-0`}),(0,V.jsxs)(`div`,{children:[(0,V.jsx)(`p`,{className:`font-semibold`,children:`Branch created successfully`}),(0,V.jsxs)(`p`,{className:`opacity-75 font-mono mt-0.5`,children:[`Now on `,(0,V.jsx)(`span`,{className:`text-success-content`,children:f.trim()}),` — agents will use this as the base branch`]})]})]}):(0,V.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,V.jsx)(`label`,{className:`text-sm font-medium`,children:`Create a new branch now`}),(0,V.jsxs)(`div`,{className:`flex gap-2`,children:[(0,V.jsxs)(`label`,{className:`input input-bordered flex items-center gap-2 flex-1`,children:[(0,V.jsx)(_,{className:`size-3.5 opacity-40`}),(0,V.jsx)(`input`,{type:`text`,className:`grow font-mono text-sm`,value:f,onChange:e=>{p(e.target.value),y(null)},onKeyDown:e=>e.key===`Enter`&&k(),placeholder:`develop`,disabled:m})]}),(0,V.jsx)(`button`,{className:`btn btn-primary`,onClick:k,disabled:!E||m,children:m?(0,V.jsx)(x,{className:`size-4 animate-spin`}):`Create`})]}),g&&(0,V.jsxs)(`p`,{className:`text-xs text-error flex items-center gap-1`,children:[(0,V.jsx)(v,{className:`size-3`}),` `,g]}),(0,V.jsxs)(`p`,{className:`text-xs opacity-40`,children:[`Equivalent to: `,(0,V.jsxs)(`span`,{className:`font-mono`,children:[`git checkout -b `,f.trim()||`develop`]})]})]}),(0,V.jsx)(Z,{})]})]})}function pe({projectName:e,setProjectName:t,detectedProjectName:n,projectSource:r,workspacePath:i,currentBranch:o,onBranchCreated:s}){let c=a(e),l=T(c||n),u=c?r===`saved`||r===`detected`?r:`manual`:n?`detected`:`missing`;return(0,V.jsxs)(`div`,{className:`flex flex-col gap-6 py-4`,children:[(0,V.jsxs)(`div`,{className:`text-center space-y-3`,children:[(0,V.jsx)(`div`,{className:`inline-flex size-14 items-center justify-center rounded-full bg-primary/10 text-primary mx-auto`,children:(0,V.jsx)(L,{className:`size-7`})}),(0,V.jsxs)(`div`,{className:`space-y-2`,children:[(0,V.jsx)(`h2`,{className:`text-2xl font-bold tracking-tight`,children:`Set up your workspace`}),(0,V.jsx)(`p`,{className:`text-base-content/60 max-w-xl mx-auto text-sm`,children:`Name your project and configure the working branch`})]})]}),(0,V.jsxs)(`div`,{className:`bg-base-200 rounded-2xl p-5 flex flex-col gap-4`,children:[(0,V.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,V.jsxs)(`div`,{children:[(0,V.jsx)(`div`,{className:`text-sm font-semibold`,children:`Project name`}),(0,V.jsx)(`div`,{className:`text-xs text-base-content/50`,children:`This becomes the default queue title for future runs.`})]}),u===`saved`&&(0,V.jsxs)(`span`,{className:`badge badge-primary badge-soft gap-1.5`,children:[(0,V.jsx)(y,{className:`size-3`}),`Saved configuration`]}),u===`detected`&&(0,V.jsxs)(`span`,{className:`badge badge-secondary badge-soft gap-1.5`,children:[(0,V.jsx)(y,{className:`size-3`}),`Detected automatically`]}),u===`manual`&&(0,V.jsxs)(`span`,{className:`badge badge-accent badge-soft gap-1.5`,children:[(0,V.jsx)(R,{className:`size-3`}),`Edited manually`]}),u===`missing`&&(0,V.jsxs)(`span`,{className:`badge badge-warning badge-soft gap-1.5`,children:[(0,V.jsx)(v,{className:`size-3`}),`Manual entry required`]})]}),(0,V.jsxs)(`label`,{className:`form-control w-full gap-2`,children:[(0,V.jsx)(`span`,{className:`label-text text-sm font-medium`,children:`Project`}),(0,V.jsx)(`input`,{type:`text`,className:`input input-bordered w-full text-base`,placeholder:n||`Enter your project name`,value:e,onChange:e=>t(e.target.value),onBlur:n=>{let r=a(n.target.value);r!==e&&t(r)}})]}),i&&(0,V.jsxs)(`div`,{className:`text-xs text-base-content/50 break-all`,children:[`Workspace: `,i]}),!n&&!c&&(0,V.jsxs)(`div`,{className:`alert alert-warning text-sm`,children:[(0,V.jsx)(v,{className:`size-4 shrink-0`}),(0,V.jsx)(`span`,{children:`We could not detect a project name from the current directory. Enter one to continue.`})]}),(0,V.jsxs)(`div`,{className:`rounded-xl border border-base-300/70 bg-base-100 px-4 py-3`,children:[(0,V.jsx)(`div`,{className:`text-xs uppercase tracking-[0.2em] text-base-content/40`,children:`Queue title preview`}),(0,V.jsx)(`div`,{className:`mt-1.5 text-base font-semibold tracking-tight break-words`,children:l})]})]}),(0,V.jsx)(Q,{currentBranch:o,onBranchCreated:s})]})}var me={planner:`plan`,executor:`execute`,reviewer:`review`};function he({options:e,value:t,onChange:n}){return(0,V.jsx)(`div`,{className:`flex gap-1 flex-wrap`,children:e.map(e=>{let r=e.value===t,i=e.icon;return(0,V.jsxs)(`button`,{type:`button`,onClick:()=>n(e.value),className:`flex items-center gap-1 px-2.5 py-1 rounded-full text-[11px] font-medium border transition-all ${r?`${e.color} border-current bg-base-300`:`text-base-content/35 border-base-content/10 hover:border-base-content/30 hover:text-base-content/60`}`,children:[(0,V.jsx)(i,{className:`size-2.5`}),e.label]},e.value)})})}function ge({providers:e,providersLoading:t,pipeline:n,setPipeline:r,efforts:i,setEfforts:a,models:o,setModels:s,modelsByProvider:l}){let u=Array.isArray(e)?e:[],d=u.filter(e=>e.available!==!1);return(0,B.useEffect)(()=>{for(let e of[`planner`,`executor`,`reviewer`]){let t=K(e,n),r=i[e];r&&!t.some(e=>e.value===r)&&a(t=>({...t,[e]:`high`}))}},[n,i,a]),(0,V.jsxs)(`div`,{className:`flex flex-col gap-5 w-full max-w-lg`,children:[(0,V.jsxs)(`div`,{className:`text-center`,children:[(0,V.jsx)(z,{className:`size-9 text-primary mx-auto mb-2`}),(0,V.jsx)(`h2`,{className:`text-2xl font-bold`,children:`Agent Pipeline`}),(0,V.jsx)(`p`,{className:`text-sm text-base-content/50 mt-1`,children:`Configure which CLI and reasoning depth runs each stage`})]}),t?(0,V.jsxs)(`div`,{className:`flex flex-col items-center gap-3 py-10`,children:[(0,V.jsx)(O,{className:`size-7 text-primary animate-spin`}),(0,V.jsx)(`p`,{className:`text-sm text-base-content/50`,children:`Detecting available CLIs…`})]}):d.length===0?(0,V.jsx)(`div`,{className:`alert alert-warning text-sm`,children:`No providers detected. Install claude, codex, or gemini CLI first.`}):(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(`div`,{className:`flex flex-wrap gap-2 justify-center`,children:u.map(e=>{let t=e.id||e.name||e,n=e.available!==!1;return(0,V.jsxs)(`span`,{className:`badge gap-1.5 badge-sm ${n?`badge-success`:`badge-ghost opacity-40`}`,children:[n?(0,V.jsx)(h,{className:`size-3`}):(0,V.jsx)(N,{className:`size-3`}),(0,V.jsx)(`span`,{className:`font-mono`,children:t}),e.path&&(0,V.jsx)(`span`,{className:`opacity-50 text-[9px] hidden sm:inline`,children:e.path})]},t)})}),(0,V.jsx)(`div`,{className:`flex flex-col`,children:J.map((e,t)=>{let u=e.icon,f=n[e.role]||d[0]?.id||d[0]?.name||``,p=me[e.role],m=o?.[p]||``,h=l?.[f]||[],g=K(e.role,n),_=i?.[e.role]||`high`;return(0,V.jsxs)(`div`,{children:[t>0&&(0,V.jsx)(`div`,{className:`flex justify-center py-1.5 text-base-content/20`,children:(0,V.jsx)(c,{className:`size-4`})}),(0,V.jsx)(`div`,{className:`bg-base-200 rounded-xl p-4`,children:(0,V.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,V.jsx)(`div`,{className:`size-8 rounded-lg flex items-center justify-center bg-base-300 shrink-0 ${e.color}`,children:(0,V.jsx)(u,{className:`size-4`})}),(0,V.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,V.jsx)(`span`,{className:`font-semibold text-sm`,children:e.label}),(0,V.jsx)(`p`,{className:`text-[11px] text-base-content/40 leading-tight mt-0.5 truncate`,children:e.description})]}),(0,V.jsx)(`select`,{className:`select select-sm select-bordered w-28 shrink-0`,value:f,onChange:t=>{let n=t.target.value;r(t=>({...t,[e.role]:n}));let i=l?.[n]?.[0]?.id||``;s(e=>({...e,[p]:i}))},children:d.map(e=>{let t=e.id||e.name||e;return(0,V.jsx)(`option`,{value:t,children:t},t)})})]}),(0,V.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,V.jsx)(`span`,{className:`text-[10px] text-base-content/40 shrink-0 w-10`,children:`Effort`}),(0,V.jsx)(he,{options:g,value:_,onChange:t=>a(n=>({...n,[e.role]:t}))})]}),h.length>0&&(0,V.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,V.jsx)(`span`,{className:`text-[10px] text-base-content/40 shrink-0 w-10`,children:`Model`}),(0,V.jsx)(`select`,{className:`select select-xs select-bordered flex-1`,value:m,onChange:e=>s(t=>({...t,[p]:e.target.value})),children:h.map(e=>(0,V.jsx)(`option`,{value:e.id,children:e.label||e.id},e.id))})]})]})})]},e.role)})}),(0,V.jsx)(`p`,{className:`text-[11px] text-base-content/35 text-center`,children:`Pipeline runs top to bottom: plan → execute → review`})]})]})}function _e({selectedAgents:e,setSelectedAgents:t,existingAgents:n}){let[r,i]=(0,B.useState)([]),[a,s]=(0,B.useState)(!1),c=(0,B.useRef)(!1),[l,u]=(0,B.useState)([]),[d,f]=(0,B.useState)(!1),[p,m]=(0,B.useState)(``),[h,_]=(0,B.useState)(()=>new Set),[v,y]=(0,B.useState)({}),b=(0,B.useRef)(!1),[x,S]=(0,B.useState)(``),C=(0,B.useCallback)(()=>o.get(`/catalog/agents`).catch(()=>({agents:[]})).then(e=>{let t=e?.agents||[];return i(t),t}),[]);(0,B.useEffect)(()=>{c.current||(c.current=!0,s(!0),C().then(r=>{let i=new Set((n||[]).map(e=>e.name)),a=r.filter(e=>!i.has(e.name)).map(e=>e.name);a.length>0&&e.length===0&&t(a)}).finally(()=>s(!1)))},[]);let w=(0,B.useCallback)(()=>(m(``),f(!0),o.get(`/reference-repositories`).then(e=>{u(e?.repositories||[])}).catch(e=>{let t=e?.message||`Failed to load reference repositories.`;t.toLowerCase().includes(`route not found`)?m(`Backend route not loaded. Start Fifony with --dev (or run pnpm build:server) and retry.`):m(t)}).finally(()=>f(!1))),[]);(0,B.useEffect)(()=>{b.current||(b.current=!0,w())},[w]);let T=(0,B.useMemo)(()=>new Set((n||[]).map(e=>e.name)),[n]),D=(0,B.useMemo)(()=>{let e=x.trim().toLowerCase();return e?r.filter(t=>[t?.name,t?.displayName,t?.description].filter(Boolean).join(` `).toLowerCase().includes(e)):r},[x,r]),k=(0,B.useCallback)(e=>{t(t=>t.includes(e)?t.filter(t=>t!==e):[...t,e])},[t]),j=(0,B.useCallback)(()=>{t(r.filter(e=>!T.has(e.name)).map(e=>e.name))},[r,T,t]),N=(0,B.useCallback)(()=>t([]),[t]),P=(0,B.useCallback)(async e=>{_(t=>new Set([...t,e])),y(t=>({...t,[e]:``}));try{let t=((await o.post(`/reference-repositories/sync`,{repository:e}))?.results||[]).find(t=>t.id===e);if(t?.action===`failed`){y(n=>({...n,[e]:t.message||`Sync failed.`}));return}await o.post(`/reference-repositories/import`,{repository:e,kind:`agents`,global:!1}),await Promise.all([w(),C()]),y(t=>({...t,[e]:`Synced & imported.`}))}catch(t){y(n=>({...n,[e]:t?.message||`Failed.`}))}finally{_(t=>{let n=new Set(t);return n.delete(e),n})}},[w,C]);return a?(0,V.jsxs)(`div`,{className:`flex flex-col items-center gap-3 py-12`,children:[(0,V.jsx)(O,{className:`size-8 text-primary animate-spin`}),(0,V.jsx)(`p`,{className:`text-sm text-base-content/50`,children:`Loading catalog...`})]}):(0,V.jsxs)(`div`,{className:`flex flex-col gap-6 stagger-children`,children:[(0,V.jsxs)(`div`,{className:`text-center`,children:[(0,V.jsx)(g,{className:`size-10 text-primary mx-auto mb-3`}),(0,V.jsx)(`h2`,{className:`text-2xl font-bold`,children:`Agents`}),(0,V.jsx)(`p`,{className:`text-base-content/60 mt-1`,children:`Choose which agents to install`})]}),(0,V.jsx)(`div`,{className:`card bg-base-200`,children:(0,V.jsxs)(`div`,{className:`card-body gap-3 p-4`,children:[(0,V.jsx)(`h3`,{className:`font-semibold text-sm`,children:`Sources`}),p&&(0,V.jsx)(`div`,{className:`alert alert-warning text-xs`,children:p}),d?(0,V.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-base-content/60`,children:[(0,V.jsx)(O,{className:`size-3 animate-spin`}),` Loading...`]}):(0,V.jsx)(`div`,{className:`grid grid-cols-2 xl:grid-cols-4 gap-2`,children:l.map(e=>{let t=h.has(e.id),n=e?.artifactCounts??null,r=e?.present&&e?.synced;return(0,V.jsxs)(`div`,{className:`rounded-lg border border-base-300/70 bg-base-100 p-2 flex flex-col gap-1.5`,children:[(0,V.jsx)(`div`,{className:`font-medium text-xs truncate`,children:e.name}),r&&n?(0,V.jsxs)(`div`,{className:`text-[11px] text-base-content/60`,children:[n.agents,` agents`]}):(0,V.jsx)(`span`,{className:`badge badge-xs badge-warning`,children:`Not synced`}),v[e.id]&&(0,V.jsx)(`p`,{className:`text-[11px] text-base-content/60 truncate`,children:v[e.id]}),(0,V.jsxs)(`button`,{className:`btn btn-xs btn-outline gap-1 mt-auto`,onClick:()=>P(e.id),disabled:t,children:[t?(0,V.jsx)(O,{className:`size-3 animate-spin`}):(0,V.jsx)(A,{className:`size-3`}),t?`Syncing…`:r?`Re-sync`:`Sync`]})]},e.id)})})]})}),(0,V.jsxs)(`div`,{className:`space-y-2`,children:[(0,V.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,V.jsxs)(`h3`,{className:`font-semibold text-sm flex items-center gap-2`,children:[(0,V.jsx)(g,{className:`size-4 opacity-50`}),`Agents (`,r.length,`)`]}),(0,V.jsxs)(`div`,{className:`flex gap-1`,children:[(0,V.jsx)(`button`,{className:`btn btn-xs btn-ghost`,onClick:j,children:`Select All`}),(0,V.jsx)(`button`,{className:`btn btn-xs btn-ghost`,onClick:N,children:`None`})]})]}),(0,V.jsxs)(`label`,{className:`input input-bordered input-sm flex items-center gap-2`,children:[(0,V.jsx)(E,{className:`size-4 opacity-60`}),(0,V.jsx)(`input`,{type:`text`,className:`grow`,placeholder:`Search agents...`,value:x,onChange:e=>S(e.target.value)})]}),D.length===0&&r.length>0&&(0,V.jsx)(`div`,{className:`text-sm text-base-content/60`,children:`No agents match your search.`}),(0,V.jsx)(`div`,{className:`space-y-1 pt-1`,children:D.map(t=>{let n=T.has(t.name),r=n||e.includes(t.name);return(0,V.jsx)(`button`,{className:`w-full rounded-md border border-transparent px-2 py-2 text-left transition-all ${n?`opacity-70 bg-base-100/40`:`hover:bg-base-100`} ${r&&!n?`ring-1 ring-primary ring-offset-1 ring-offset-base-200`:``}`,onClick:()=>!n&&k(t.name),disabled:n,children:(0,V.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,V.jsx)(`span`,{className:`mt-0.5 text-base`,children:t.emoji||`🤖`}),(0,V.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,V.jsx)(`span`,{className:`font-medium text-sm truncate`,children:t.displayName||t.name}),t.source&&(0,V.jsx)(`span`,{className:`badge badge-xs badge-ghost shrink-0`,children:t.source}),n?(0,V.jsxs)(`span`,{className:`badge badge-xs badge-success gap-1 shrink-0`,children:[(0,V.jsx)(M,{className:`size-3`}),` Installed`]}):(0,V.jsx)(`input`,{type:`checkbox`,className:`checkbox checkbox-primary checkbox-sm self-start mt-0.5 shrink-0`,checked:r,readOnly:!0,tabIndex:-1})]}),t.description&&(0,V.jsx)(`p`,{className:`text-xs text-base-content/60 mt-1 truncate`,children:t.description})]})]})},t.name)})})]}),r.length===0&&(0,V.jsx)(`div`,{className:`alert alert-info text-sm`,children:`No agents found in the catalog. Sync a source above or add them later from the settings page.`})]})}var ve={auto:{bg:null,label:`Auto`},light:{bg:`#ffffff`,accent:`#7c3aed`},dark:{bg:`#1d232a`,accent:`#661ae6`},black:{bg:`#000000`,accent:`#ffffff`},cupcake:{bg:`#faf7f5`,accent:`#ef9fbc`},night:{bg:`#0f172a`,accent:`#38bdf8`},sunset:{bg:`#1a1019`,accent:`#ff865b`}};function ye({theme:e,selected:t,onClick:n}){let r=ve[e.value];return(0,V.jsxs)(`button`,{onClick:n,title:e.label,className:`flex flex-col items-center gap-1.5 group focus:outline-none`,children:[(0,V.jsx)(`div`,{className:`w-10 h-10 rounded-xl border-2 transition-all overflow-hidden flex-shrink-0 ${t?`border-primary ring-2 ring-primary ring-offset-2 ring-offset-base-200 scale-110`:`border-base-300 group-hover:border-base-content/30 group-hover:scale-105`}`,style:r.bg?{background:r.bg}:void 0,children:r.bg?(0,V.jsxs)(`div`,{className:`w-full h-full flex flex-col`,children:[(0,V.jsx)(`div`,{className:`flex-1`,style:{background:r.bg}}),(0,V.jsx)(`div`,{className:`h-3 w-full`,style:{background:r.accent}})]}):(0,V.jsxs)(`div`,{className:`w-full h-full flex`,children:[(0,V.jsx)(`div`,{className:`flex-1 bg-white`}),(0,V.jsx)(`div`,{className:`flex-1 bg-neutral`})]})}),(0,V.jsx)(`span`,{className:`text-xs font-medium transition-colors ${t?`text-primary`:`text-base-content/50 group-hover:text-base-content/80`}`,children:e.label})]})}function be({concurrency:e,setConcurrency:t,selectedTheme:n,setSelectedTheme:r}){let i=Number.isFinite(e)?Math.max(1,Math.min(10,e)):1;return(0,V.jsxs)(`div`,{className:`flex flex-col gap-6 stagger-children`,children:[(0,V.jsxs)(`div`,{className:`text-center`,children:[(0,V.jsx)(C,{className:`size-10 text-primary mx-auto mb-3`}),(0,V.jsx)(`h2`,{className:`text-2xl font-bold`,children:`Workers & Theme`}),(0,V.jsx)(`p`,{className:`text-base-content/60 mt-1 text-sm`,children:`Configure parallel workers and visual theme`})]}),(0,V.jsx)(`div`,{className:`card bg-base-200`,children:(0,V.jsxs)(`div`,{className:`card-body p-5 gap-3`,children:[(0,V.jsxs)(`h3`,{className:`font-semibold text-sm flex items-center gap-2`,children:[(0,V.jsx)(C,{className:`size-4 opacity-50`}),`Worker Concurrency`]}),(0,V.jsxs)(`p`,{className:`text-xs text-base-content/60`,children:[`How many agents can work in parallel (`,i,` worker`,i===1?``:`s`,`)`]}),(0,V.jsxs)(`div`,{className:`w-full max-w-xs`,children:[(0,V.jsx)(`input`,{type:`range`,min:1,max:10,step:1,value:i,onChange:e=>t(Math.round(Number(e.target.value))),"aria-label":`Number of parallel workers`,className:`range range-primary range-sm w-full`}),(0,V.jsx)(`div`,{className:`flex justify-between px-2.5 mt-2 text-xs`,children:Array.from({length:10},(e,t)=>(0,V.jsx)(`span`,{children:`|`},t))}),(0,V.jsx)(`div`,{className:`flex justify-between px-2.5 mt-2 text-xs`,children:Array.from({length:10},(e,t)=>(0,V.jsx)(`span`,{children:t+1},t))})]}),(0,V.jsxs)(`p`,{className:`text-xs text-base-content/50 bg-base-100 rounded-lg px-3 py-2 mt-1`,children:[(0,V.jsx)(`span`,{className:`font-medium text-base-content/70`,children:`Tip:`}),` 2–4 workers is recommended for most projects. More workers consume more API quota and may hit rate limits.`]})]})}),(0,V.jsx)(`div`,{className:`card bg-base-200`,children:(0,V.jsxs)(`div`,{className:`card-body p-5 gap-4`,children:[(0,V.jsxs)(`h3`,{className:`font-semibold text-sm flex items-center gap-2`,children:[(0,V.jsx)(b,{className:`size-4 opacity-50`}),`Theme`]}),(0,V.jsx)(`div`,{className:`flex flex-wrap gap-5 justify-center py-1`,children:q.map(e=>(0,V.jsx)(ye,{theme:e,selected:n===e.value,onClick:()=>r(e.value)},e.value))})]})})]})}function xe({config:e,launching:t}){return(0,V.jsxs)(`div`,{className:`flex flex-col items-center text-center gap-6 stagger-children py-4`,children:[(0,V.jsx)(`div`,{className:`animate-bounce-in`,children:(0,V.jsx)(z,{className:`size-16 sm:size-20 text-primary mx-auto`})}),(0,V.jsx)(`h2`,{className:`text-2xl sm:text-3xl font-bold`,children:`You're All Set!`}),(0,V.jsx)(`p`,{className:`text-base-content/60 max-w-md`,children:`Here's a summary of your configuration. Hit launch when you're ready.`}),(0,V.jsx)(`div`,{className:`card bg-base-200 w-full max-w-sm`,children:(0,V.jsxs)(`div`,{className:`card-body p-4 gap-2 text-sm text-left`,children:[(0,V.jsxs)(`div`,{className:`flex justify-between gap-4`,children:[(0,V.jsx)(`span`,{className:`text-base-content/60`,children:`Queue title`}),(0,V.jsx)(`span`,{className:`font-semibold text-right break-words`,children:e.queueTitle||`fifony`})]}),(0,V.jsx)(`div`,{className:`divider my-0`}),(0,V.jsxs)(`div`,{className:`flex justify-between`,children:[(0,V.jsx)(`span`,{className:`text-base-content/60`,children:`Pipeline`}),(0,V.jsxs)(`span`,{className:`font-semibold capitalize text-xs font-mono`,children:[e.pipeline?.planner||`?`,` → `,e.pipeline?.executor||`?`,` → `,e.pipeline?.reviewer||`?`]})]}),(0,V.jsx)(`div`,{className:`divider my-0`}),(0,V.jsxs)(`div`,{className:`flex justify-between`,children:[(0,V.jsx)(`span`,{className:`text-base-content/60`,children:`Domains`}),(0,V.jsx)(`span`,{className:`font-semibold`,children:e.domains?.length>0?e.domains.length+` selected`:`none`})]}),(0,V.jsx)(`div`,{className:`divider my-0`}),(0,V.jsxs)(`div`,{className:`flex justify-between`,children:[(0,V.jsx)(`span`,{className:`text-base-content/60`,children:`Agents`}),(0,V.jsxs)(`span`,{className:`font-semibold`,children:[e.agents?.length||0,` to install`]})]}),(0,V.jsx)(`div`,{className:`divider my-0`}),(0,V.jsxs)(`div`,{className:`flex justify-between`,children:[(0,V.jsx)(`span`,{className:`text-base-content/60`,children:`Skills`}),(0,V.jsxs)(`span`,{className:`font-semibold`,children:[e.skills?.length||0,` to install`]})]}),(0,V.jsx)(`div`,{className:`divider my-0`}),(0,V.jsxs)(`div`,{className:`flex justify-between`,children:[(0,V.jsx)(`span`,{className:`text-base-content/60`,children:`Plan`}),(0,V.jsx)(`span`,{className:`font-semibold capitalize`,children:e.efforts.planner})]}),(0,V.jsx)(`div`,{className:`divider my-0`}),(0,V.jsxs)(`div`,{className:`flex justify-between`,children:[(0,V.jsx)(`span`,{className:`text-base-content/60`,children:`Execute`}),(0,V.jsx)(`span`,{className:`font-semibold capitalize`,children:e.efforts.executor})]}),(0,V.jsx)(`div`,{className:`divider my-0`}),(0,V.jsxs)(`div`,{className:`flex justify-between`,children:[(0,V.jsx)(`span`,{className:`text-base-content/60`,children:`Review`}),(0,V.jsx)(`span`,{className:`font-semibold capitalize`,children:e.efforts.reviewer})]}),(0,V.jsx)(`div`,{className:`divider my-0`}),(0,V.jsxs)(`div`,{className:`flex justify-between`,children:[(0,V.jsx)(`span`,{className:`text-base-content/60`,children:`Workers`}),(0,V.jsx)(`span`,{className:`font-semibold`,children:e.concurrency})]}),(0,V.jsx)(`div`,{className:`divider my-0`}),(0,V.jsxs)(`div`,{className:`flex justify-between`,children:[(0,V.jsx)(`span`,{className:`text-base-content/60`,children:`Theme`}),(0,V.jsx)(`span`,{className:`font-semibold capitalize`,children:e.theme})]})]})}),t&&(0,V.jsxs)(`div`,{className:`flex items-center gap-2 text-sm text-base-content/50`,children:[(0,V.jsx)(O,{className:`size-4 animate-spin`}),`Saving configuration & installing agents...`]})]})}function Se({onComplete:e}){let t=r(),n=m(),i=p(n.data),[s,c]=(0,B.useState)(0),[h,g]=(0,B.useState)(`forward`),[_,v]=(0,B.useState)(!1),[y,b]=(0,B.useState)(null),x=(0,B.useRef)(!1),S=(0,B.useRef)(!1),[C,E]=(0,B.useState)({planner:``,executor:``,reviewer:``}),[D,O]=(0,B.useState)(()=>oe(null)),[A,j]=(0,B.useState)(3),[M,N]=(0,B.useState)(`auto`),[P,ee]=(0,B.useState)(``),[F,I]=(0,B.useState)(`missing`),[L,R]=(0,B.useState)(null),[z,te]=(0,B.useState)([]),[H,ae]=(0,B.useState)([]),U=ie(),W=re()[s]||``,[G,K]=(0,B.useState)(null),[q,J]=(0,B.useState)(!1),[X,fe]=(0,B.useState)({}),[Z,Q]=(0,B.useState)({plan:``,execute:``,review:``}),[me,he]=(0,B.useState)(``),[ve,ye]=(0,B.useState)(``);(0,B.useEffect)(()=>{o.get(`/state`).then(e=>{R(e||{}),he(e?.sourceRepoUrl||e?.config?.sourceRepo||``),ye(e?.config?.defaultBranch||``)}).catch(()=>{R({})})},[]),(0,B.useEffect)(()=>{if(x.current||n.isLoading)return;x.current=!0;let e=d(i,`runtime.pipeline`,null),t=d(i,`runtime.workflowConfig`,null),r=d(i,`runtime.defaultEffort`,null),a=d(i,`ui.theme`,`auto`),o=d(i,`runtime.workerConcurrency`,3);if(Array.isArray(e)&&e.length>0){let t=Object.fromEntries(e.map(e=>[e.role,e.provider]));E({planner:t.planner||``,executor:t.executor||``,reviewer:t.reviewer||``})}t&&typeof t==`object`&&Q({plan:t.plan?.model||``,execute:t.execute?.model||``,review:t.review?.model||``}),O(oe(r)),typeof a==`string`&&a.trim()&&N(a);let s=Number.parseInt(String(o??2),10);Number.isFinite(s)&&j(Math.min(10,Math.max(1,s)))},[i,n.isLoading]),(0,B.useEffect)(()=>{if(S.current||n.isLoading||L===null)return;S.current=!0;let e=w(i,L);ee(e.projectName),I(e.source)},[L,i,n.isLoading]);let Se=(0,B.useCallback)(e=>{ee(e),I(`manual`)},[]),$=a(P),Ce=T($);(0,B.useEffect)(()=>{document.title=T($||L?.detectedProjectName||L?.projectName||``)},[$,L]),(0,B.useEffect)(()=>{s>=1&&G===null&&(J(!0),Promise.all([o.get(`/providers`),o.get(`/config/workflow?details=1`).catch(()=>null)]).then(([e,t])=>{let n=Array.isArray(e)?e:e?.providers||[];K(n);let r=t?.models||{};fe(r);let i=n.filter(e=>e.available!==!1),a=i[0]?.id||i[0]?.name||``,o=i.find(e=>(e.id||e.name)===`claude`),s=a,c=o?`claude`:s,l={planner:c,executor:s,reviewer:c};E(e=>({planner:e.planner||l.planner,executor:e.executor||l.executor,reviewer:e.reviewer||l.reviewer})),Q(e=>({plan:e.plan||r[c]?.[0]?.id||``,execute:e.execute||r[s]?.[0]?.id||``,review:e.review||r[c]?.[0]?.id||``}))}).catch(()=>{K([])}).finally(()=>{J(!1)}))},[s,G]),(0,B.useEffect)(()=>{let e=M===`auto`?window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`:M;document.documentElement.setAttribute(`data-theme`,e)},[M]);let we=(0,B.useCallback)(e=>{if(e===`Setup`)$&&Y(f,$,`system`).catch(()=>{});else if(e===`Pipeline`){let e=[{provider:C.planner,role:`planner`},{provider:C.executor,role:`executor`},{provider:C.reviewer,role:`reviewer`}];Y(`runtime.agentProvider`,C.executor,`runtime`).catch(()=>{}),Y(`runtime.pipeline`,e,`runtime`).catch(()=>{}),Y(`runtime.defaultEffort`,D,`runtime`).catch(()=>{}),Y(`runtime.workflowConfig`,se(C,D,Z),`runtime`).catch(()=>{})}else e===`Preferences`&&(Y(`ui.theme`,M,`ui`).catch(()=>{}),o.post(`/config/concurrency`,{concurrency:A}).catch(()=>{}))},[C,D,Z,A,M,$]),Te=(0,B.useCallback)(()=>{s<U-1&&(we(W),g(`forward`),c(e=>e+1))},[s,U,W,we]),Ee=(0,B.useCallback)(()=>{s>0&&(g(`backward`),c(e=>e-1))},[s]),De=(0,B.useCallback)(async()=>{if($){v(!0);try{let n=[Y(f,$,`system`),Y(`ui.theme`,M,`ui`),Y(`ui.onboarding.completed`,!0,`ui`)],r=[{provider:C.planner,role:`planner`},{provider:C.executor,role:`executor`},{provider:C.reviewer,role:`reviewer`}];n.push(Y(`runtime.agentProvider`,C.executor,`runtime`)),n.push(Y(`runtime.pipeline`,r,`runtime`)),n.push(Y(`runtime.defaultEffort`,D,`runtime`)),n.push(Y(`runtime.workflowConfig`,se(C,D,Z),`runtime`)),n.push(o.post(`/config/concurrency`,{concurrency:A})),z.length>0&&n.push(o.post(`/install/agents`,{agents:z})),H.length>0&&n.push(o.post(`/install/skills`,{skills:H})),await Promise.allSettled(n),t.setQueryData(u,e=>l(e,{id:f,scope:`system`,value:$,source:`user`,updatedAt:new Date().toISOString()})),t.setQueryData(u,e=>l(e,{id:`ui.onboarding.completed`,scope:`ui`,value:!0,source:`user`,updatedAt:new Date().toISOString()})),b({x:window.innerWidth/2,y:window.innerHeight/3}),setTimeout(()=>{t.invalidateQueries({queryKey:u}),e?.()},1200)}catch{t.setQueryData(u,e=>l(e,{id:f,scope:`system`,value:$,source:`user`,updatedAt:new Date().toISOString()})),t.setQueryData(u,e=>l(e,{id:`ui.onboarding.completed`,scope:`ui`,value:!0,source:`user`,updatedAt:new Date().toISOString()})),await Y(`ui.onboarding.completed`,!0,`ui`).catch(()=>{}),t.invalidateQueries({queryKey:u}),e?.()}}},[$,C,D,Z,A,M,z,H,t,e]),Oe=W===`Welcome`||W===`Setup`&&!!$||W===`Pipeline`&&(C.executor||q)||W===`Agents & Skills`||W===`Preferences`||W===`Launch`,ke=[],Ae=[],je={projectName:$,queueTitle:Ce,pipeline:C,efforts:D,concurrency:A,theme:M,agents:z,skills:H};return(0,V.jsxs)(`div`,{className:`fixed inset-0 z-50 bg-base-100 flex flex-col overflow-hidden`,children:[s===0&&(0,V.jsx)(ne,{}),y&&(0,V.jsx)(k,{x:y.x,y:y.y,active:!0,onDone:()=>b(null)}),s>0&&(0,V.jsx)(`div`,{className:`relative z-10 pt-6 pb-2 px-4 flex justify-center`,children:(0,V.jsx)(ce,{current:s})}),(0,V.jsx)(`div`,{className:`relative z-10 flex-1 flex flex-col items-center justify-start px-4 py-6 overflow-y-auto`,children:(0,V.jsxs)(le,{direction:h,stepKey:s,center:W===`Welcome`||W===`Setup`||W===`Pipeline`||W===`Launch`,children:[W===`Welcome`&&(0,V.jsx)(de,{workspacePath:me,onGetStarted:Te}),W===`Setup`&&(0,V.jsx)(pe,{projectName:P,setProjectName:Se,detectedProjectName:L?.detectedProjectName||``,projectSource:F,workspacePath:me,currentBranch:ve,onBranchCreated:e=>ye(e)}),W===`Pipeline`&&(0,V.jsx)(ge,{providers:G||[],providersLoading:q,pipeline:C,setPipeline:E,efforts:D,setEfforts:O,models:Z,setModels:Q,modelsByProvider:X}),W===`Agents & Skills`&&(0,V.jsx)(_e,{selectedAgents:z,setSelectedAgents:te,selectedSkills:H,setSelectedSkills:ae,existingAgents:ke,existingSkills:Ae}),W===`Preferences`&&(0,V.jsx)(be,{concurrency:A,setConcurrency:j,selectedTheme:M,setSelectedTheme:N}),W===`Launch`&&(0,V.jsx)(xe,{config:je,launching:_})]})}),(0,V.jsx)(ue,{step:s,stepCount:U,stepName:W,canProceed:Oe,launching:_,onBack:Ee,onNext:Te,onLaunch:De})]})}export{Se as default};
|