@hasna/assistants 0.6.61 → 0.6.62

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -54941,31 +54941,1136 @@ var init_aggregator = __esm(() => {
54941
54941
  };
54942
54942
  });
54943
54943
 
54944
+ // packages/core/src/swarm/critic.ts
54945
+ class SwarmCritic {
54946
+ config;
54947
+ constructor(config) {
54948
+ this.config = { ...DEFAULT_CRITIC_CONFIG, ...config };
54949
+ }
54950
+ getConfig() {
54951
+ return { ...this.config };
54952
+ }
54953
+ isEnabled() {
54954
+ return this.config.enabled;
54955
+ }
54956
+ async review(params) {
54957
+ if (!this.config.enabled) {
54958
+ return this.createPassingReview("Critic disabled");
54959
+ }
54960
+ const startTime = Date.now();
54961
+ const prompt = this.buildCriticPrompt(params);
54962
+ const result = await this.runCriticAgent({
54963
+ prompt,
54964
+ subagentManager: params.subagentManager,
54965
+ sessionId: params.sessionId,
54966
+ cwd: params.cwd,
54967
+ depth: params.depth
54968
+ });
54969
+ const review = this.parseCriticOutput(result, startTime);
54970
+ const staticIssues = this.runStaticChecks(params.aggregatedResult, params.tasks);
54971
+ review.issues.push(...staticIssues);
54972
+ this.recalculateScores(review);
54973
+ return review;
54974
+ }
54975
+ runStaticChecks(result, tasks) {
54976
+ const issues = [];
54977
+ let issueId = 0;
54978
+ if (result.metadata.confidence < 0.5) {
54979
+ issues.push({
54980
+ id: `static-${issueId++}`,
54981
+ category: "quality",
54982
+ severity: "medium",
54983
+ title: "Low confidence score",
54984
+ description: `Aggregated result has low confidence (${(result.metadata.confidence * 100).toFixed(1)}%)`,
54985
+ autoFixable: false
54986
+ });
54987
+ }
54988
+ if (result.metadata.failedTasks > 0) {
54989
+ const failRate = result.metadata.failedTasks / (result.metadata.contributingTasks + result.metadata.failedTasks);
54990
+ if (failRate > 0.3) {
54991
+ issues.push({
54992
+ id: `static-${issueId++}`,
54993
+ category: "incomplete",
54994
+ severity: failRate > 0.5 ? "high" : "medium",
54995
+ title: "High task failure rate",
54996
+ description: `${result.metadata.failedTasks} tasks failed (${(failRate * 100).toFixed(1)}% failure rate)`,
54997
+ autoFixable: false
54998
+ });
54999
+ }
55000
+ }
55001
+ if (result.metadata.conflictCount > 0) {
55002
+ issues.push({
55003
+ id: `static-${issueId++}`,
55004
+ category: "conflict",
55005
+ severity: result.metadata.conflictCount > 3 ? "high" : "medium",
55006
+ title: "Conflicts detected",
55007
+ description: `${result.metadata.conflictCount} conflicts were detected and resolved. Manual review recommended.`,
55008
+ autoFixable: false
55009
+ });
55010
+ }
55011
+ if (!result.content || result.content.length < 50) {
55012
+ issues.push({
55013
+ id: `static-${issueId++}`,
55014
+ category: "incomplete",
55015
+ severity: "critical",
55016
+ title: "Empty or minimal result",
55017
+ description: "The aggregated result is empty or very short",
55018
+ autoFixable: false
55019
+ });
55020
+ }
55021
+ if (this.config.checkSecurity) {
55022
+ const securityIssues = this.checkSecurityPatterns(result.content);
55023
+ issues.push(...securityIssues.map((i) => ({
55024
+ ...i,
55025
+ id: `static-${issueId++}`
55026
+ })));
55027
+ }
55028
+ const coveredTaskIds = new Set(result.sections.flatMap((s) => s.sources));
55029
+ const uncoveredTasks = tasks.filter((t) => !coveredTaskIds.has(t.id));
55030
+ if (uncoveredTasks.length > 0) {
55031
+ issues.push({
55032
+ id: `static-${issueId++}`,
55033
+ category: "missing_step",
55034
+ severity: uncoveredTasks.length > 2 ? "high" : "medium",
55035
+ title: "Tasks not covered in result",
55036
+ description: `${uncoveredTasks.length} tasks have no corresponding content in the result`,
55037
+ relatedTasks: uncoveredTasks.map((t) => t.id),
55038
+ autoFixable: false
55039
+ });
55040
+ }
55041
+ return issues;
55042
+ }
55043
+ hasBlockingIssues(review) {
55044
+ const blockingThreshold = SEVERITY_WEIGHTS[this.config.blockingSeverity];
55045
+ for (const issue of review.issues) {
55046
+ if (SEVERITY_WEIGHTS[issue.severity] >= blockingThreshold) {
55047
+ return true;
55048
+ }
55049
+ if (this.config.blockingCategories.includes(issue.category)) {
55050
+ return true;
55051
+ }
55052
+ }
55053
+ return false;
55054
+ }
55055
+ generateFollowUps(review) {
55056
+ const followUps = [];
55057
+ let actionId = 0;
55058
+ for (const issue of review.issues) {
55059
+ if (issue.severity === "info")
55060
+ continue;
55061
+ const action = {
55062
+ id: `followup-${actionId++}`,
55063
+ type: issue.autoFixable ? "revision" : "manual",
55064
+ description: issue.suggestedFix || `Address: ${issue.title}`,
55065
+ priority: this.severityToPriority(issue.severity),
55066
+ relatedIssues: [issue.id],
55067
+ required: SEVERITY_WEIGHTS[issue.severity] >= SEVERITY_WEIGHTS["high"]
55068
+ };
55069
+ if (issue.autoFixable || issue.category === "missing_step") {
55070
+ action.type = "task";
55071
+ action.taskDefinition = {
55072
+ description: `Fix: ${issue.title}
55073
+
55074
+ ${issue.description}
55075
+
55076
+ Suggested fix: ${issue.suggestedFix || "Address the issue"}`,
55077
+ role: "worker",
55078
+ priority: action.priority
55079
+ };
55080
+ }
55081
+ followUps.push(action);
55082
+ }
55083
+ return followUps;
55084
+ }
55085
+ buildCriticPrompt(params) {
55086
+ const taskSummary = params.tasks.map((t) => `- [${t.id}] ${t.description}`).join(`
55087
+ `);
55088
+ let prompt = `# Critic Review Task
55089
+
55090
+ ## Original Goal
55091
+ ${params.goal}
55092
+
55093
+ ## Tasks Executed
55094
+ ${taskSummary}
55095
+
55096
+ ## Aggregated Result
55097
+ ${params.aggregatedResult.content}
55098
+
55099
+ ## Metadata
55100
+ - Contributing tasks: ${params.aggregatedResult.metadata.contributingTasks}
55101
+ - Failed tasks: ${params.aggregatedResult.metadata.failedTasks}
55102
+ - Confidence: ${(params.aggregatedResult.metadata.confidence * 100).toFixed(1)}%
55103
+ - Conflicts: ${params.aggregatedResult.metadata.conflictCount}
55104
+
55105
+ ## Review Instructions
55106
+
55107
+ Analyze the result and provide your assessment as JSON with:
55108
+ - "approved": boolean - whether the result meets quality standards
55109
+ - "qualityScore": number (0-1) - overall quality assessment
55110
+ - "issues": array of issues found, each with:
55111
+ - "category": one of "conflict", "missing_step", "unsafe_action", "incomplete", "quality", "consistency", "security", "performance", "correctness"
55112
+ - "severity": one of "critical", "high", "medium", "low", "info"
55113
+ - "title": brief issue title
55114
+ - "description": detailed description
55115
+ - "suggestedFix": suggested resolution (optional)
55116
+ - "summary": brief summary of findings
55117
+ - "feedback": detailed feedback for improvement
55118
+
55119
+ Check for:
55120
+ `;
55121
+ if (this.config.checkSecurity) {
55122
+ prompt += `- Security issues (credentials, unsafe operations)
55123
+ `;
55124
+ }
55125
+ if (this.config.checkPerformance) {
55126
+ prompt += `- Performance concerns
55127
+ `;
55128
+ }
55129
+ if (this.config.checkConsistency) {
55130
+ prompt += `- Consistency with the original goal
55131
+ `;
55132
+ }
55133
+ prompt += `- Completeness of the response
55134
+ - Correctness of information
55135
+ - Missing steps or tasks
55136
+ - Conflicting information
55137
+
55138
+ `;
55139
+ if (this.config.customPrompt) {
55140
+ prompt += `
55141
+ ## Additional Instructions
55142
+ ${this.config.customPrompt}
55143
+ `;
55144
+ }
55145
+ return prompt;
55146
+ }
55147
+ async runCriticAgent(params) {
55148
+ const systemPrompt = ROLE_SYSTEM_PROMPTS.critic;
55149
+ const config = {
55150
+ task: `${systemPrompt}
55151
+
55152
+ ---
55153
+
55154
+ ${params.prompt}`,
55155
+ tools: this.config.criticTools,
55156
+ maxTurns: this.config.maxTurns,
55157
+ parentSessionId: params.sessionId,
55158
+ depth: params.depth + 1,
55159
+ cwd: params.cwd
55160
+ };
55161
+ const timeoutPromise = new Promise((_, reject) => {
55162
+ setTimeout(() => reject(new Error("Critic timeout")), this.config.timeoutMs);
55163
+ });
55164
+ try {
55165
+ return await Promise.race([
55166
+ params.subagentManager.spawn(config),
55167
+ timeoutPromise
55168
+ ]);
55169
+ } catch (error) {
55170
+ return {
55171
+ success: false,
55172
+ error: error instanceof Error ? error.message : String(error),
55173
+ toolCalls: 0,
55174
+ turns: 0
55175
+ };
55176
+ }
55177
+ }
55178
+ parseCriticOutput(result, startTime) {
55179
+ const durationMs = Date.now() - startTime;
55180
+ if (!result.success || !result.result) {
55181
+ return {
55182
+ approved: false,
55183
+ qualityScore: 0,
55184
+ confidence: 0,
55185
+ issues: [{
55186
+ id: "parse-error",
55187
+ category: "quality",
55188
+ severity: "high",
55189
+ title: "Critic review failed",
55190
+ description: result.error || "No result from critic agent",
55191
+ autoFixable: false
55192
+ }],
55193
+ followUps: [],
55194
+ summary: "Critic review failed",
55195
+ feedback: result.error || "No output from critic",
55196
+ reviewedAt: Date.now(),
55197
+ durationMs
55198
+ };
55199
+ }
55200
+ try {
55201
+ const jsonMatch = result.result.match(/\{[\s\S]*\}/);
55202
+ if (!jsonMatch) {
55203
+ throw new Error("No JSON found in critic output");
55204
+ }
55205
+ const parsed = JSON.parse(jsonMatch[0]);
55206
+ return {
55207
+ approved: parsed.approved ?? false,
55208
+ qualityScore: parsed.qualityScore ?? 0.5,
55209
+ confidence: 0.8,
55210
+ issues: (parsed.issues || []).map((issue, index) => ({
55211
+ id: `critic-${index}`,
55212
+ category: issue.category || "quality",
55213
+ severity: issue.severity || "medium",
55214
+ title: issue.title || "Unknown issue",
55215
+ description: issue.description || "",
55216
+ suggestedFix: issue.suggestedFix,
55217
+ autoFixable: !!issue.suggestedFix
55218
+ })),
55219
+ followUps: [],
55220
+ summary: parsed.summary || "",
55221
+ feedback: parsed.feedback || "",
55222
+ reviewedAt: Date.now(),
55223
+ durationMs
55224
+ };
55225
+ } catch (error) {
55226
+ const approved = result.result.toLowerCase().includes("approved") && !result.result.toLowerCase().includes("not approved");
55227
+ return {
55228
+ approved,
55229
+ qualityScore: approved ? 0.7 : 0.3,
55230
+ confidence: 0.5,
55231
+ issues: [],
55232
+ followUps: [],
55233
+ summary: result.result.slice(0, 200),
55234
+ feedback: result.result,
55235
+ reviewedAt: Date.now(),
55236
+ durationMs
55237
+ };
55238
+ }
55239
+ }
55240
+ checkSecurityPatterns(content) {
55241
+ const issues = [];
55242
+ const credentialPatterns = [
55243
+ /api[_-]?key\s*[=:]\s*['"][^'"]+['"]/i,
55244
+ /password\s*[=:]\s*['"][^'"]+['"]/i,
55245
+ /secret\s*[=:]\s*['"][^'"]+['"]/i,
55246
+ /token\s*[=:]\s*['"][^'"]+['"]/i
55247
+ ];
55248
+ for (const pattern of credentialPatterns) {
55249
+ if (pattern.test(content)) {
55250
+ issues.push({
55251
+ category: "security",
55252
+ severity: "critical",
55253
+ title: "Potential credential exposure",
55254
+ description: "Content may contain hardcoded credentials",
55255
+ suggestedFix: "Remove or mask sensitive values",
55256
+ autoFixable: false
55257
+ });
55258
+ break;
55259
+ }
55260
+ }
55261
+ const unsafePatterns = [
55262
+ { pattern: /rm\s+-rf\s+[/*]/, title: "Dangerous file deletion" },
55263
+ { pattern: /drop\s+database/i, title: "Database deletion" },
55264
+ { pattern: /truncate\s+table/i, title: "Table truncation" },
55265
+ { pattern: /--force/, title: "Force flag usage" }
55266
+ ];
55267
+ for (const { pattern, title } of unsafePatterns) {
55268
+ if (pattern.test(content)) {
55269
+ issues.push({
55270
+ category: "unsafe_action",
55271
+ severity: "high",
55272
+ title,
55273
+ description: `Found potentially unsafe operation: ${pattern.source}`,
55274
+ autoFixable: false
55275
+ });
55276
+ }
55277
+ }
55278
+ return issues;
55279
+ }
55280
+ recalculateScores(review) {
55281
+ if (review.issues.length === 0) {
55282
+ review.qualityScore = Math.max(review.qualityScore, 0.8);
55283
+ return;
55284
+ }
55285
+ let totalPenalty = 0;
55286
+ for (const issue of review.issues) {
55287
+ totalPenalty += SEVERITY_WEIGHTS[issue.severity];
55288
+ }
55289
+ const penalty = Math.min(totalPenalty * 0.15, 0.8);
55290
+ review.qualityScore = Math.max(0, review.qualityScore - penalty);
55291
+ if (this.hasBlockingIssues(review)) {
55292
+ review.approved = false;
55293
+ }
55294
+ review.followUps = this.generateFollowUps(review);
55295
+ }
55296
+ severityToPriority(severity) {
55297
+ switch (severity) {
55298
+ case "critical":
55299
+ return 1;
55300
+ case "high":
55301
+ return 2;
55302
+ case "medium":
55303
+ return 3;
55304
+ case "low":
55305
+ return 4;
55306
+ case "info":
55307
+ return 5;
55308
+ default:
55309
+ return 3;
55310
+ }
55311
+ }
55312
+ createPassingReview(reason) {
55313
+ return {
55314
+ approved: true,
55315
+ qualityScore: 1,
55316
+ confidence: 1,
55317
+ issues: [],
55318
+ followUps: [],
55319
+ summary: reason,
55320
+ feedback: "",
55321
+ reviewedAt: Date.now(),
55322
+ durationMs: 0
55323
+ };
55324
+ }
55325
+ }
55326
+ function createSwarmCritic(config) {
55327
+ return new SwarmCritic(config);
55328
+ }
55329
+ var DEFAULT_CRITIC_CONFIG, SEVERITY_WEIGHTS;
55330
+ var init_critic = __esm(() => {
55331
+ init_types3();
55332
+ DEFAULT_CRITIC_CONFIG = {
55333
+ enabled: true,
55334
+ blockingSeverity: "high",
55335
+ maxIssues: 10,
55336
+ blockingCategories: ["unsafe_action", "security", "correctness"],
55337
+ checkSecurity: true,
55338
+ checkPerformance: true,
55339
+ checkConsistency: true,
55340
+ maxTurns: 10,
55341
+ criticTools: ["read", "grep", "glob"],
55342
+ timeoutMs: 60000
55343
+ };
55344
+ SEVERITY_WEIGHTS = {
55345
+ critical: 1,
55346
+ high: 0.7,
55347
+ medium: 0.4,
55348
+ low: 0.2,
55349
+ info: 0.05
55350
+ };
55351
+ });
55352
+
55353
+ // packages/core/src/swarm/postback.ts
55354
+ class SwarmPostback {
55355
+ config;
55356
+ constructor(config) {
55357
+ this.config = { ...DEFAULT_POSTBACK_CONFIG, ...config };
55358
+ }
55359
+ getConfig() {
55360
+ return { ...this.config };
55361
+ }
55362
+ createPostback(params) {
55363
+ const { swarmId, sessionId, goal, plan, result, aggregatedResult, criticReview } = params;
55364
+ const taskOutcomes = this.extractTaskOutcomes(plan.tasks, result);
55365
+ const artifacts = this.extractArtifacts(result, taskOutcomes);
55366
+ const structuredData = {
55367
+ summary: this.generateSummary(result, criticReview),
55368
+ goal,
55369
+ success: result.success,
55370
+ qualityScore: criticReview?.qualityScore ?? (result.success ? 0.8 : 0.3),
55371
+ taskOutcomes,
55372
+ artifacts: artifacts.slice(0, this.config.maxArtifacts),
55373
+ issues: criticReview?.issues || [],
55374
+ followUps: criticReview?.followUps || [],
55375
+ metrics: result.metrics,
55376
+ metadata: aggregatedResult?.metadata || this.createDefaultMetadata(result),
55377
+ durationMs: result.durationMs
55378
+ };
55379
+ const content = this.formatContent(structuredData);
55380
+ return {
55381
+ id: `postback-${swarmId}`,
55382
+ format: this.config.format,
55383
+ content,
55384
+ structuredData: this.config.format === "structured" ? structuredData : undefined,
55385
+ timestamp: Date.now(),
55386
+ swarmId,
55387
+ sessionId
55388
+ };
55389
+ }
55390
+ formatAsMarkdown(data) {
55391
+ if (this.config.customTemplate) {
55392
+ return this.applyTemplate(this.config.customTemplate, data);
55393
+ }
55394
+ const parts = [];
55395
+ const statusIcon = data.success ? "\u2705" : "\u274C";
55396
+ parts.push(`## ${statusIcon} Swarm Execution Complete`);
55397
+ parts.push("");
55398
+ parts.push(`**Goal:** ${data.goal}`);
55399
+ parts.push("");
55400
+ parts.push(data.summary);
55401
+ parts.push("");
55402
+ if (this.config.includeMetrics) {
55403
+ parts.push("### Metrics");
55404
+ parts.push(`- Tasks: ${data.metrics.completedTasks}/${data.metrics.totalTasks} completed`);
55405
+ if (data.metrics.failedTasks > 0) {
55406
+ parts.push(`- Failed: ${data.metrics.failedTasks}`);
55407
+ }
55408
+ parts.push(`- Tool calls: ${data.metrics.toolCalls}`);
55409
+ if (this.config.showDuration) {
55410
+ parts.push(`- Duration: ${this.formatDuration(data.durationMs)}`);
55411
+ }
55412
+ parts.push(`- Quality: ${(data.qualityScore * 100).toFixed(0)}%`);
55413
+ parts.push("");
55414
+ }
55415
+ if (this.config.includeTaskDetails && data.taskOutcomes.length > 0) {
55416
+ parts.push("### Task Outcomes");
55417
+ for (const outcome of data.taskOutcomes) {
55418
+ const statusEmoji = this.getStatusEmoji(outcome.status);
55419
+ parts.push(`${statusEmoji} **${outcome.description}**`);
55420
+ if (outcome.summary) {
55421
+ parts.push(` ${outcome.summary}`);
55422
+ }
55423
+ if (outcome.error) {
55424
+ parts.push(` \u26A0\uFE0F Error: ${outcome.error}`);
55425
+ }
55426
+ }
55427
+ parts.push("");
55428
+ }
55429
+ if (this.config.includeArtifacts && data.artifacts.length > 0) {
55430
+ parts.push("### Artifacts");
55431
+ for (const artifact of data.artifacts) {
55432
+ if (artifact.type === "code" && this.config.showCodeBlocks) {
55433
+ parts.push(`**${artifact.name}** (${artifact.language || "code"})`);
55434
+ parts.push("```" + (artifact.language || ""));
55435
+ parts.push(this.truncate(artifact.content));
55436
+ parts.push("```");
55437
+ } else if (artifact.type === "file") {
55438
+ parts.push(`\uD83D\uDCC4 **${artifact.name}**: \`${artifact.path}\``);
55439
+ } else if (artifact.type === "link") {
55440
+ parts.push(`\uD83D\uDD17 **${artifact.name}**: ${artifact.url}`);
55441
+ } else {
55442
+ parts.push(`- **${artifact.name}**: ${this.truncate(artifact.content)}`);
55443
+ }
55444
+ }
55445
+ parts.push("");
55446
+ }
55447
+ if (this.config.includeIssues && data.issues.length > 0) {
55448
+ parts.push("### Issues Found");
55449
+ for (const issue of data.issues) {
55450
+ const severityEmoji = this.getSeverityEmoji(issue.severity);
55451
+ parts.push(`${severityEmoji} **${issue.title}** (${issue.severity})`);
55452
+ parts.push(` ${issue.description}`);
55453
+ if (issue.suggestedFix) {
55454
+ parts.push(` \uD83D\uDCA1 Fix: ${issue.suggestedFix}`);
55455
+ }
55456
+ }
55457
+ parts.push("");
55458
+ }
55459
+ if (this.config.includeFollowUps && data.followUps.length > 0) {
55460
+ const required = data.followUps.filter((f) => f.required);
55461
+ if (required.length > 0) {
55462
+ parts.push("### Required Follow-ups");
55463
+ for (const followUp of required) {
55464
+ parts.push(`- [ ] ${followUp.description}`);
55465
+ }
55466
+ parts.push("");
55467
+ }
55468
+ }
55469
+ return parts.join(`
55470
+ `).slice(0, this.config.maxContentLength);
55471
+ }
55472
+ formatAsJson(data) {
55473
+ return JSON.stringify(data, null, 2);
55474
+ }
55475
+ formatAsPlain(data) {
55476
+ const parts = [];
55477
+ parts.push(`SWARM EXECUTION ${data.success ? "COMPLETE" : "FAILED"}`);
55478
+ parts.push(`Goal: ${data.goal}`);
55479
+ parts.push("");
55480
+ parts.push(data.summary);
55481
+ parts.push("");
55482
+ if (this.config.includeMetrics) {
55483
+ parts.push(`Tasks: ${data.metrics.completedTasks}/${data.metrics.totalTasks}`);
55484
+ parts.push(`Duration: ${this.formatDuration(data.durationMs)}`);
55485
+ parts.push("");
55486
+ }
55487
+ if (this.config.includeTaskDetails) {
55488
+ parts.push("TASKS:");
55489
+ for (const outcome of data.taskOutcomes) {
55490
+ parts.push(`[${outcome.status.toUpperCase()}] ${outcome.description}`);
55491
+ }
55492
+ parts.push("");
55493
+ }
55494
+ if (this.config.includeIssues && data.issues.length > 0) {
55495
+ parts.push("ISSUES:");
55496
+ for (const issue of data.issues) {
55497
+ parts.push(`[${issue.severity.toUpperCase()}] ${issue.title}`);
55498
+ }
55499
+ }
55500
+ return parts.join(`
55501
+ `).slice(0, this.config.maxContentLength);
55502
+ }
55503
+ createInboxMessage(postback) {
55504
+ return {
55505
+ type: "swarm_result",
55506
+ title: `Swarm completed: ${postback.structuredData?.goal || "Unknown"}`,
55507
+ content: postback.content,
55508
+ metadata: {
55509
+ swarmId: postback.swarmId,
55510
+ sessionId: postback.sessionId,
55511
+ success: postback.structuredData?.success,
55512
+ qualityScore: postback.structuredData?.qualityScore,
55513
+ taskCount: postback.structuredData?.taskOutcomes.length,
55514
+ artifactCount: postback.structuredData?.artifacts.length,
55515
+ issueCount: postback.structuredData?.issues.length,
55516
+ durationMs: postback.structuredData?.durationMs
55517
+ }
55518
+ };
55519
+ }
55520
+ extractTaskOutcomes(tasks, result) {
55521
+ const outcomes = [];
55522
+ for (const task of tasks) {
55523
+ const taskResult = result.taskResults[task.id];
55524
+ const outcome = {
55525
+ taskId: task.id,
55526
+ description: task.description,
55527
+ role: task.role,
55528
+ status: this.mapTaskStatus(task.status, taskResult),
55529
+ summary: taskResult?.result ? this.truncate(taskResult.result) : undefined,
55530
+ result: taskResult?.result,
55531
+ error: taskResult?.error,
55532
+ durationMs: task.completedAt && task.startedAt ? task.completedAt - task.startedAt : undefined,
55533
+ artifacts: this.extractArtifactsFromResult(task.id, taskResult)
55534
+ };
55535
+ outcomes.push(outcome);
55536
+ }
55537
+ return outcomes;
55538
+ }
55539
+ extractArtifacts(result, outcomes) {
55540
+ const artifacts = [];
55541
+ for (const outcome of outcomes) {
55542
+ artifacts.push(...outcome.artifacts);
55543
+ }
55544
+ return artifacts;
55545
+ }
55546
+ extractArtifactsFromResult(taskId, result) {
55547
+ if (!result?.result)
55548
+ return [];
55549
+ const artifacts = [];
55550
+ let artifactId = 0;
55551
+ const codeBlockPattern = /```(\w+)?\n([\s\S]*?)```/g;
55552
+ let match;
55553
+ while ((match = codeBlockPattern.exec(result.result)) !== null) {
55554
+ const language = match[1] || "text";
55555
+ const content = match[2].trim();
55556
+ if (content.length > 20) {
55557
+ artifacts.push({
55558
+ id: `${taskId}-code-${artifactId++}`,
55559
+ type: "code",
55560
+ name: `Code block ${artifactId}`,
55561
+ content,
55562
+ sourceTaskId: taskId,
55563
+ language,
55564
+ size: content.length
55565
+ });
55566
+ }
55567
+ }
55568
+ const filePattern = /(?:created?|wrote?|saved?|output|file).*?[`"']([^`"'\s]+\.\w+)[`"']/gi;
55569
+ while ((match = filePattern.exec(result.result)) !== null) {
55570
+ artifacts.push({
55571
+ id: `${taskId}-file-${artifactId++}`,
55572
+ type: "file",
55573
+ name: match[1].split("/").pop() || match[1],
55574
+ content: "",
55575
+ path: match[1],
55576
+ sourceTaskId: taskId
55577
+ });
55578
+ }
55579
+ const urlPattern = /https?:\/\/[^\s<>"']+/g;
55580
+ while ((match = urlPattern.exec(result.result)) !== null) {
55581
+ artifacts.push({
55582
+ id: `${taskId}-link-${artifactId++}`,
55583
+ type: "link",
55584
+ name: "Link",
55585
+ content: match[0],
55586
+ url: match[0],
55587
+ sourceTaskId: taskId
55588
+ });
55589
+ }
55590
+ return artifacts;
55591
+ }
55592
+ mapTaskStatus(taskStatus, result) {
55593
+ if (taskStatus === "completed" && result?.success)
55594
+ return "completed";
55595
+ if (taskStatus === "completed" && !result?.success)
55596
+ return "partial";
55597
+ if (taskStatus === "failed")
55598
+ return "failed";
55599
+ if (taskStatus === "blocked" || taskStatus === "cancelled")
55600
+ return "skipped";
55601
+ return "partial";
55602
+ }
55603
+ generateSummary(result, criticReview) {
55604
+ const parts = [];
55605
+ if (result.success) {
55606
+ parts.push(`Successfully completed ${result.metrics.completedTasks} tasks.`);
55607
+ } else {
55608
+ parts.push(`Execution encountered issues: ${result.error || "Unknown error"}`);
55609
+ }
55610
+ if (criticReview) {
55611
+ if (criticReview.approved) {
55612
+ parts.push("Critic review passed.");
55613
+ } else {
55614
+ parts.push(`Critic found ${criticReview.issues.length} issues.`);
55615
+ }
55616
+ }
55617
+ if (result.result) {
55618
+ parts.push("");
55619
+ parts.push(this.truncate(result.result, 300));
55620
+ }
55621
+ return parts.join(" ");
55622
+ }
55623
+ createDefaultMetadata(result) {
55624
+ return {
55625
+ confidence: result.success ? 0.7 : 0.3,
55626
+ coverage: result.metrics.completedTasks / Math.max(result.metrics.totalTasks, 1),
55627
+ contributingTasks: result.metrics.completedTasks,
55628
+ failedTasks: result.metrics.failedTasks,
55629
+ conflictCount: 0,
55630
+ deduplicationCount: 0,
55631
+ sectionCount: Object.keys(result.taskResults).length,
55632
+ totalLength: result.result?.length || 0,
55633
+ strategy: "merge",
55634
+ conflictResolution: "highest_conf",
55635
+ aggregatedAt: Date.now()
55636
+ };
55637
+ }
55638
+ formatContent(data) {
55639
+ switch (this.config.format) {
55640
+ case "markdown":
55641
+ return this.formatAsMarkdown(data);
55642
+ case "json":
55643
+ return this.formatAsJson(data);
55644
+ case "plain":
55645
+ return this.formatAsPlain(data);
55646
+ case "structured":
55647
+ return this.formatAsMarkdown(data);
55648
+ default:
55649
+ return this.formatAsMarkdown(data);
55650
+ }
55651
+ }
55652
+ applyTemplate(template, data) {
55653
+ return template.replace(/\{\{goal\}\}/g, data.goal).replace(/\{\{summary\}\}/g, data.summary).replace(/\{\{success\}\}/g, String(data.success)).replace(/\{\{qualityScore\}\}/g, String(data.qualityScore)).replace(/\{\{taskCount\}\}/g, String(data.taskOutcomes.length)).replace(/\{\{completedTasks\}\}/g, String(data.metrics.completedTasks)).replace(/\{\{failedTasks\}\}/g, String(data.metrics.failedTasks)).replace(/\{\{duration\}\}/g, this.formatDuration(data.durationMs)).replace(/\{\{issueCount\}\}/g, String(data.issues.length));
55654
+ }
55655
+ truncate(text, maxLength) {
55656
+ const limit = maxLength || this.config.truncationLength;
55657
+ if (!this.config.truncateResults || text.length <= limit) {
55658
+ return text;
55659
+ }
55660
+ return text.slice(0, limit) + "...";
55661
+ }
55662
+ formatDuration(ms) {
55663
+ if (ms < 1000)
55664
+ return `${ms}ms`;
55665
+ if (ms < 60000)
55666
+ return `${(ms / 1000).toFixed(1)}s`;
55667
+ const minutes = Math.floor(ms / 60000);
55668
+ const seconds = Math.round(ms % 60000 / 1000);
55669
+ return `${minutes}m ${seconds}s`;
55670
+ }
55671
+ getStatusEmoji(status) {
55672
+ switch (status) {
55673
+ case "completed":
55674
+ return "\u2705";
55675
+ case "failed":
55676
+ return "\u274C";
55677
+ case "partial":
55678
+ return "\u26A0\uFE0F";
55679
+ case "skipped":
55680
+ return "\u23ED\uFE0F";
55681
+ default:
55682
+ return "\u2022";
55683
+ }
55684
+ }
55685
+ getSeverityEmoji(severity) {
55686
+ switch (severity) {
55687
+ case "critical":
55688
+ return "\uD83D\uDD34";
55689
+ case "high":
55690
+ return "\uD83D\uDFE0";
55691
+ case "medium":
55692
+ return "\uD83D\uDFE1";
55693
+ case "low":
55694
+ return "\uD83D\uDFE2";
55695
+ case "info":
55696
+ return "\u2139\uFE0F";
55697
+ default:
55698
+ return "\u2022";
55699
+ }
55700
+ }
55701
+ }
55702
+ function createSwarmPostback(config) {
55703
+ return new SwarmPostback(config);
55704
+ }
55705
+ var DEFAULT_POSTBACK_CONFIG;
55706
+ var init_postback = __esm(() => {
55707
+ DEFAULT_POSTBACK_CONFIG = {
55708
+ format: "markdown",
55709
+ includeTaskDetails: true,
55710
+ includeArtifacts: true,
55711
+ includeMetrics: true,
55712
+ includeIssues: true,
55713
+ includeFollowUps: true,
55714
+ maxContentLength: 1e4,
55715
+ maxArtifacts: 20,
55716
+ truncateResults: true,
55717
+ truncationLength: 500,
55718
+ showCodeBlocks: true,
55719
+ showDuration: true
55720
+ };
55721
+ });
55722
+
55723
+ // packages/core/src/swarm/status.ts
55724
+ class SwarmStatusProvider {
55725
+ config;
55726
+ swarmId;
55727
+ sessionId;
55728
+ state = null;
55729
+ tasks = new Map;
55730
+ agents = new Map;
55731
+ logs = new Map;
55732
+ listeners = new Set;
55733
+ startTime = 0;
55734
+ completedTimes = [];
55735
+ constructor(swarmId, sessionId, config) {
55736
+ this.config = { ...DEFAULT_STATUS_CONFIG, ...config };
55737
+ this.swarmId = swarmId;
55738
+ this.sessionId = sessionId;
55739
+ this.startTime = Date.now();
55740
+ }
55741
+ getSwarmId() {
55742
+ return this.swarmId;
55743
+ }
55744
+ addListener(listener) {
55745
+ this.listeners.add(listener);
55746
+ return () => this.listeners.delete(listener);
55747
+ }
55748
+ emit(type, data) {
55749
+ const event = {
55750
+ type,
55751
+ swarmId: this.swarmId,
55752
+ data,
55753
+ timestamp: Date.now()
55754
+ };
55755
+ for (const listener of this.listeners) {
55756
+ try {
55757
+ listener(event);
55758
+ } catch {}
55759
+ }
55760
+ }
55761
+ updateFromState(state) {
55762
+ this.state = state;
55763
+ if (state.plan) {
55764
+ for (const task of state.plan.tasks) {
55765
+ this.updateTask(task);
55766
+ }
55767
+ }
55768
+ this.emit("progress", this.getProgress());
55769
+ }
55770
+ updateTask(task) {
55771
+ const isDispatchTask = "attempts" in task;
55772
+ const taskStatus = {
55773
+ id: isDispatchTask ? task.id : task.id,
55774
+ description: isDispatchTask ? task.task.description : task.description,
55775
+ role: isDispatchTask ? task.task.role : task.role,
55776
+ status: this.mapStatus(isDispatchTask ? task.status : task.status),
55777
+ progress: this.calculateTaskProgress(task),
55778
+ agentId: isDispatchTask ? task.agentId : task.assignedAgentId,
55779
+ durationMs: this.calculateDuration(task),
55780
+ error: isDispatchTask ? task.error : task.result?.error,
55781
+ dependsOn: isDispatchTask ? task.task.dependsOn : task.dependsOn,
55782
+ blockedBy: [],
55783
+ attempt: isDispatchTask ? task.attempts : 1,
55784
+ maxAttempts: 3
55785
+ };
55786
+ const prevStatus = this.tasks.get(taskStatus.id);
55787
+ this.tasks.set(taskStatus.id, taskStatus);
55788
+ if (prevStatus?.status !== "completed" && taskStatus.status === "completed") {
55789
+ if (taskStatus.durationMs) {
55790
+ this.completedTimes.push(taskStatus.durationMs);
55791
+ }
55792
+ }
55793
+ this.emit("task_update", taskStatus);
55794
+ }
55795
+ updateAgent(agent) {
55796
+ this.agents.set(agent.id, agent);
55797
+ this.emit("agent_update", agent);
55798
+ }
55799
+ addLog(taskId, level, message, data) {
55800
+ if (!this.logs.has(taskId)) {
55801
+ this.logs.set(taskId, []);
55802
+ }
55803
+ const logs = this.logs.get(taskId);
55804
+ logs.push({
55805
+ timestamp: Date.now(),
55806
+ level,
55807
+ message,
55808
+ data
55809
+ });
55810
+ while (logs.length > this.config.maxLogEntries) {
55811
+ logs.shift();
55812
+ }
55813
+ }
55814
+ getSummary() {
55815
+ const elapsedMs = Date.now() - this.startTime;
55816
+ const progress = this.getProgress();
55817
+ return {
55818
+ swarmId: this.swarmId,
55819
+ sessionId: this.sessionId,
55820
+ phase: this.state?.status || "idle",
55821
+ phaseDescription: this.getPhaseDescription(this.state?.status || "idle"),
55822
+ progress,
55823
+ activeAgents: Array.from(this.agents.values()).filter((a) => a.state === "running"),
55824
+ tasks: Array.from(this.tasks.values()),
55825
+ metrics: this.state?.metrics || this.getDefaultMetrics(),
55826
+ startedAt: this.startTime,
55827
+ elapsedMs,
55828
+ estimatedRemainingMs: this.config.estimateRemaining ? this.estimateRemaining(progress, elapsedMs) : undefined,
55829
+ errors: this.state?.errors || [],
55830
+ warnings: [],
55831
+ updatedAt: Date.now()
55832
+ };
55833
+ }
55834
+ getTaskDetail(taskId) {
55835
+ const task = this.tasks.get(taskId);
55836
+ if (!task)
55837
+ return null;
55838
+ return {
55839
+ taskId,
55840
+ task,
55841
+ logs: this.logs.get(taskId) || [],
55842
+ result: this.state?.taskResults.get(taskId)?.result,
55843
+ retryHistory: []
55844
+ };
55845
+ }
55846
+ getProgress() {
55847
+ if (this.tasks.size === 0)
55848
+ return 0;
55849
+ const completed = Array.from(this.tasks.values()).filter((t) => t.status === "completed").length;
55850
+ return Math.round(completed / this.tasks.size * 100);
55851
+ }
55852
+ formatProgress(style = "bar", width = 20) {
55853
+ const progress = this.getProgress();
55854
+ switch (style) {
55855
+ case "percent":
55856
+ return `${progress}%`;
55857
+ case "fraction": {
55858
+ const completed = Array.from(this.tasks.values()).filter((t) => t.status === "completed").length;
55859
+ return `${completed}/${this.tasks.size}`;
55860
+ }
55861
+ case "spinner": {
55862
+ const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
55863
+ const index = Math.floor(Date.now() / 100) % frames.length;
55864
+ return frames[index];
55865
+ }
55866
+ case "bar":
55867
+ default: {
55868
+ const filled = Math.round(progress / 100 * width);
55869
+ const empty = width - filled;
55870
+ const bar = "\u2588".repeat(filled) + "\u2591".repeat(empty);
55871
+ return `[${bar}] ${progress}%`;
55872
+ }
55873
+ }
55874
+ }
55875
+ formatForTerminal() {
55876
+ const summary = this.getSummary();
55877
+ const lines = [];
55878
+ lines.push(`\uD83D\uDC1D Swarm: ${summary.phase}`);
55879
+ lines.push(this.formatProgress("bar", 30));
55880
+ lines.push("");
55881
+ if (summary.activeAgents.length > 0) {
55882
+ lines.push("Active Agents:");
55883
+ for (const agent of summary.activeAgents) {
55884
+ const taskInfo = agent.currentTask ? ` \u2192 ${agent.currentTask.description.slice(0, 30)}...` : "";
55885
+ lines.push(` ${agent.name}${taskInfo}`);
55886
+ }
55887
+ lines.push("");
55888
+ }
55889
+ const completed = summary.tasks.filter((t) => t.status === "completed").length;
55890
+ const running = summary.tasks.filter((t) => t.status === "running").length;
55891
+ const pending = summary.tasks.filter((t) => t.status === "pending" || t.status === "waiting").length;
55892
+ const failed = summary.tasks.filter((t) => t.status === "failed").length;
55893
+ lines.push(`Tasks: \u2705 ${completed} | \u23F3 ${running} | \uD83D\uDCCB ${pending} | \u274C ${failed}`);
55894
+ const elapsed = this.formatDuration(summary.elapsedMs);
55895
+ if (summary.estimatedRemainingMs !== undefined) {
55896
+ const remaining = this.formatDuration(summary.estimatedRemainingMs);
55897
+ lines.push(`Time: ${elapsed} elapsed, ~${remaining} remaining`);
55898
+ } else {
55899
+ lines.push(`Time: ${elapsed}`);
55900
+ }
55901
+ if (summary.errors.length > 0) {
55902
+ lines.push("");
55903
+ lines.push("Errors:");
55904
+ for (const error of summary.errors.slice(-3)) {
55905
+ lines.push(` \u274C ${error}`);
55906
+ }
55907
+ }
55908
+ return lines.join(`
55909
+ `);
55910
+ }
55911
+ toJSON() {
55912
+ return this.getSummary();
55913
+ }
55914
+ mapStatus(status) {
55915
+ switch (status) {
55916
+ case "pending":
55917
+ case "queued":
55918
+ return "pending";
55919
+ case "waiting_deps":
55920
+ return "waiting";
55921
+ case "running":
55922
+ case "dispatching":
55923
+ return "running";
55924
+ case "completed":
55925
+ return "completed";
55926
+ case "failed":
55927
+ case "timeout":
55928
+ return "failed";
55929
+ case "cancelled":
55930
+ case "blocked":
55931
+ return "cancelled";
55932
+ default:
55933
+ return "pending";
55934
+ }
55935
+ }
55936
+ calculateTaskProgress(task) {
55937
+ const isDispatchTask = "attempts" in task;
55938
+ const status = isDispatchTask ? task.status : task.status;
55939
+ switch (status) {
55940
+ case "completed":
55941
+ return 100;
55942
+ case "running":
55943
+ case "dispatching":
55944
+ return 50;
55945
+ case "waiting_deps":
55946
+ return 10;
55947
+ case "failed":
55948
+ case "timeout":
55949
+ case "cancelled":
55950
+ return 0;
55951
+ default:
55952
+ return 0;
55953
+ }
55954
+ }
55955
+ calculateDuration(task) {
55956
+ const isDispatchTask = "queuedAt" in task;
55957
+ if (isDispatchTask) {
55958
+ const dt = task;
55959
+ if (dt.durationMs)
55960
+ return dt.durationMs;
55961
+ if (dt.startedAt)
55962
+ return Date.now() - dt.startedAt;
55963
+ return;
55964
+ }
55965
+ const st = task;
55966
+ if (st.completedAt && st.startedAt) {
55967
+ return st.completedAt - st.startedAt;
55968
+ }
55969
+ if (st.startedAt) {
55970
+ return Date.now() - st.startedAt;
55971
+ }
55972
+ return;
55973
+ }
55974
+ estimateRemaining(progress, elapsedMs) {
55975
+ if (progress === 0 || progress >= 100)
55976
+ return;
55977
+ if (this.completedTimes.length < 2)
55978
+ return;
55979
+ const avgTime = this.completedTimes.reduce((a, b) => a + b, 0) / this.completedTimes.length;
55980
+ const remaining = this.tasks.size - Array.from(this.tasks.values()).filter((t) => t.status === "completed").length;
55981
+ return Math.round(avgTime * remaining);
55982
+ }
55983
+ getPhaseDescription(phase) {
55984
+ switch (phase) {
55985
+ case "idle":
55986
+ return "Initializing...";
55987
+ case "planning":
55988
+ return "Creating execution plan...";
55989
+ case "executing":
55990
+ return "Executing tasks...";
55991
+ case "reviewing":
55992
+ return "Running critic review...";
55993
+ case "aggregating":
55994
+ return "Aggregating results...";
55995
+ case "completed":
55996
+ return "Completed";
55997
+ case "failed":
55998
+ return "Failed";
55999
+ case "cancelled":
56000
+ return "Cancelled";
56001
+ default:
56002
+ return phase;
56003
+ }
56004
+ }
56005
+ getDefaultMetrics() {
56006
+ return {
56007
+ totalTasks: this.tasks.size,
56008
+ completedTasks: Array.from(this.tasks.values()).filter((t) => t.status === "completed").length,
56009
+ failedTasks: Array.from(this.tasks.values()).filter((t) => t.status === "failed").length,
56010
+ runningTasks: Array.from(this.tasks.values()).filter((t) => t.status === "running").length,
56011
+ tokensUsed: 0,
56012
+ llmCalls: 0,
56013
+ toolCalls: 0,
56014
+ replans: 0
56015
+ };
56016
+ }
56017
+ formatDuration(ms) {
56018
+ if (ms < 1000)
56019
+ return `${ms}ms`;
56020
+ if (ms < 60000)
56021
+ return `${(ms / 1000).toFixed(1)}s`;
56022
+ const minutes = Math.floor(ms / 60000);
56023
+ const seconds = Math.round(ms % 60000 / 1000);
56024
+ return `${minutes}m ${seconds}s`;
56025
+ }
56026
+ }
56027
+ function createSwarmStatusProvider(swarmId, sessionId, config) {
56028
+ return new SwarmStatusProvider(swarmId, sessionId, config);
56029
+ }
56030
+ var DEFAULT_STATUS_CONFIG;
56031
+ var init_status = __esm(() => {
56032
+ DEFAULT_STATUS_CONFIG = {
56033
+ updateInterval: 500,
56034
+ maxLogEntries: 100,
56035
+ trackTaskProgress: true,
56036
+ estimateRemaining: true
56037
+ };
56038
+ });
56039
+
54944
56040
  // packages/core/src/swarm/index.ts
54945
56041
  var exports_swarm = {};
54946
56042
  __export(exports_swarm, {
54947
56043
  quickAggregate: () => quickAggregate,
56044
+ createSwarmStatusProvider: () => createSwarmStatusProvider,
56045
+ createSwarmPostback: () => createSwarmPostback,
54948
56046
  createSwarmMemoryTools: () => createSwarmMemoryTools,
54949
56047
  createSwarmDispatcher: () => createSwarmDispatcher,
56048
+ createSwarmCritic: () => createSwarmCritic,
54950
56049
  createSwarmAggregator: () => createSwarmAggregator,
54951
56050
  createSwarmAgentSelector: () => createSwarmAgentSelector,
54952
56051
  aggregateTaskResults: () => aggregateTaskResults,
54953
56052
  TaskGraphScheduler: () => TaskGraphScheduler,
54954
56053
  TaskGraphBuilder: () => TaskGraphBuilder,
54955
56054
  TaskGraph: () => TaskGraph,
56055
+ SwarmStatusProvider: () => SwarmStatusProvider,
54956
56056
  SwarmResultsAggregator: () => SwarmResultsAggregator,
56057
+ SwarmPostback: () => SwarmPostback,
54957
56058
  SwarmPolicyEnforcer: () => SwarmPolicyEnforcer,
54958
56059
  SwarmMemory: () => SwarmMemory,
54959
56060
  SwarmDispatcher: () => SwarmDispatcher,
54960
56061
  SwarmDecisionPolicy: () => SwarmDecisionPolicy,
56062
+ SwarmCritic: () => SwarmCritic,
54961
56063
  SwarmCoordinator: () => SwarmCoordinator,
54962
56064
  SwarmAgentSelector: () => SwarmAgentSelector,
54963
56065
  ROLE_SYSTEM_PROMPTS: () => ROLE_SYSTEM_PROMPTS,
54964
56066
  DEFAULT_SWARM_CONFIG: () => DEFAULT_SWARM_CONFIG,
56067
+ DEFAULT_STATUS_CONFIG: () => DEFAULT_STATUS_CONFIG,
54965
56068
  DEFAULT_SELECTOR_CONFIG: () => DEFAULT_SELECTOR_CONFIG,
54966
56069
  DEFAULT_SCHEDULER_OPTIONS: () => DEFAULT_SCHEDULER_OPTIONS,
56070
+ DEFAULT_POSTBACK_CONFIG: () => DEFAULT_POSTBACK_CONFIG,
54967
56071
  DEFAULT_DISPATCHER_CONFIG: () => DEFAULT_DISPATCHER_CONFIG,
54968
56072
  DEFAULT_DECISION_POLICY: () => DEFAULT_DECISION_POLICY,
56073
+ DEFAULT_CRITIC_CONFIG: () => DEFAULT_CRITIC_CONFIG,
54969
56074
  DEFAULT_BUILDER_OPTIONS: () => DEFAULT_BUILDER_OPTIONS,
54970
56075
  DEFAULT_AGGREGATOR_CONFIG: () => DEFAULT_AGGREGATOR_CONFIG
54971
56076
  });
@@ -54979,6 +56084,9 @@ var init_swarm = __esm(() => {
54979
56084
  init_agent_selector();
54980
56085
  init_dispatcher();
54981
56086
  init_aggregator();
56087
+ init_critic();
56088
+ init_postback();
56089
+ init_status();
54982
56090
  init_types3();
54983
56091
  });
54984
56092
 
@@ -133994,6 +135102,30 @@ import { homedir as homedir13, platform as platform2, release, arch as arch2 } f
133994
135102
  init_src2();
133995
135103
  await init_config();
133996
135104
  import { existsSync as existsSync12, mkdirSync as mkdirSync8, writeFileSync as writeFileSync9 } from "fs";
135105
+
135106
+ // packages/core/src/scheduler/format.ts
135107
+ function formatRelativeTime(timestamp, now2 = Date.now()) {
135108
+ if (!timestamp)
135109
+ return "n/a";
135110
+ const diff = timestamp - now2;
135111
+ const absDiff = Math.abs(diff);
135112
+ const isPast = diff < 0;
135113
+ const seconds = Math.floor(absDiff / 1000);
135114
+ const minutes = Math.floor(seconds / 60);
135115
+ const hours = Math.floor(minutes / 60);
135116
+ const days = Math.floor(hours / 24);
135117
+ let timeStr;
135118
+ if (days > 0) {
135119
+ timeStr = `${days}d ${hours % 24}h`;
135120
+ } else if (hours > 0) {
135121
+ timeStr = `${hours}h ${minutes % 60}m`;
135122
+ } else if (minutes > 0) {
135123
+ timeStr = `${minutes}m ${seconds % 60}s`;
135124
+ } else {
135125
+ timeStr = `${seconds}s`;
135126
+ }
135127
+ return isPast ? `${timeStr} ago` : `in ${timeStr}`;
135128
+ }
133997
135129
  // packages/core/src/jobs/job-manager.ts
133998
135130
  init_src2();
133999
135131
 
@@ -134893,7 +136025,7 @@ async function cancelRecurringTask(cwd, id) {
134893
136025
  return task;
134894
136026
  }
134895
136027
  // packages/core/src/commands/builtin.ts
134896
- var VERSION = "0.6.61";
136028
+ var VERSION = "0.6.62";
134897
136029
  function resolveAuthTimeout(resolve5) {
134898
136030
  resolve5({ exitCode: 1, stdout: { toString: () => "{}" } });
134899
136031
  }
@@ -140918,30 +142050,60 @@ Importing ${validMemories.length} valid entries (skipping ${errors.length} inval
140918
142050
  schedulesCommand() {
140919
142051
  return {
140920
142052
  name: "schedules",
140921
- description: "List scheduled commands",
142053
+ description: "Browse and manage scheduled commands",
140922
142054
  builtin: true,
140923
142055
  selfHandled: true,
140924
142056
  content: "",
140925
- handler: async (_args, context) => {
140926
- const schedules = await listSchedules(context.cwd);
140927
- if (schedules.length === 0) {
140928
- context.emit("text", `No schedules found.
140929
- `);
142057
+ handler: async (args, context) => {
142058
+ const trimmed = args.trim().toLowerCase();
142059
+ if (!trimmed || trimmed === "ui") {
140930
142060
  context.emit("done");
140931
- return { handled: true };
142061
+ return { handled: true, showPanel: "schedules" };
140932
142062
  }
140933
- const escapeCell = (value) => value.replace(/\|/g, "\\|").replace(/\s+/g, " ").trim();
140934
- let output = `
142063
+ if (trimmed === "list" || trimmed === "--list") {
142064
+ const schedules = await listSchedules(context.cwd);
142065
+ if (schedules.length === 0) {
142066
+ context.emit("text", `No schedules found.
142067
+ `);
142068
+ context.emit("done");
142069
+ return { handled: true };
142070
+ }
142071
+ const escapeCell = (value) => value.replace(/\|/g, "\\|").replace(/\s+/g, " ").trim();
142072
+ let output = `
140935
142073
  | ID | Status | Next Run | Command |
140936
142074
  `;
140937
- output += `|----|--------|----------|---------|
142075
+ output += `|----|--------|----------|---------|
140938
142076
  `;
140939
- for (const schedule of schedules.sort((a, b) => (a.nextRunAt || 0) - (b.nextRunAt || 0))) {
140940
- const next = schedule.nextRunAt ? new Date(schedule.nextRunAt).toISOString() : "n/a";
140941
- output += `| ${schedule.id} | ${schedule.status} | ${next} | ${escapeCell(schedule.command)} |
142077
+ for (const schedule of schedules.sort((a, b) => (a.nextRunAt || 0) - (b.nextRunAt || 0))) {
142078
+ const next = formatRelativeTime(schedule.nextRunAt);
142079
+ const cmd = escapeCell(schedule.command.slice(0, 40) + (schedule.command.length > 40 ? "..." : ""));
142080
+ output += `| ${schedule.id.slice(0, 8)} | ${schedule.status} | ${next} | ${cmd} |
140942
142081
  `;
142082
+ }
142083
+ context.emit("text", output);
142084
+ context.emit("done");
142085
+ return { handled: true };
140943
142086
  }
140944
- context.emit("text", output);
142087
+ context.emit("text", `
142088
+ **Schedules** - Manage scheduled commands
142089
+
142090
+ `);
142091
+ context.emit("text", `Usage:
142092
+ `);
142093
+ context.emit("text", ` /schedules Open interactive panel
142094
+ `);
142095
+ context.emit("text", ` /schedules ui Open interactive panel
142096
+ `);
142097
+ context.emit("text", ` /schedules list Show text table (scripting)
142098
+ `);
142099
+ context.emit("text", ` /schedule <time> <cmd> Create a schedule
142100
+ `);
142101
+ context.emit("text", ` /unschedule <id> Delete a schedule
142102
+ `);
142103
+ context.emit("text", ` /pause <id> Pause a schedule
142104
+ `);
142105
+ context.emit("text", ` /resume <id> Resume a schedule
142106
+ `);
140945
142107
  context.emit("done");
140946
142108
  return { handled: true };
140947
142109
  }
@@ -173433,7 +174595,7 @@ var import_react25 = __toESM(require_react(), 1);
173433
174595
  // node_modules/.pnpm/ink@6.6.0_@types+react@19.2.10_react-devtools-core@6.1.5_react@19.2.4/node_modules/ink/build/hooks/use-is-screen-reader-enabled.js
173434
174596
  var import_react26 = __toESM(require_react(), 1);
173435
174597
  // packages/terminal/src/components/App.tsx
173436
- var import_react45 = __toESM(require_react(), 1);
174598
+ var import_react46 = __toESM(require_react(), 1);
173437
174599
  init_src2();
173438
174600
 
173439
174601
  // packages/terminal/src/components/Input.tsx
@@ -178923,31 +180085,113 @@ function TasksPanel({
178923
180085
  }, undefined, false, undefined, this)
178924
180086
  ]
178925
180087
  }, undefined, true, undefined, this),
178926
- tasks2.length > 0 && selectedIndex < tasks2.length && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
178927
- marginTop: 1,
178928
- flexDirection: "column",
178929
- children: [
178930
- /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text3, {
178931
- dimColor: true,
178932
- wrap: "wrap",
178933
- children: tasks2[selectedIndex].description
178934
- }, undefined, false, undefined, this),
178935
- tasks2[selectedIndex].error && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text3, {
178936
- color: "red",
178937
- children: [
178938
- "Error: ",
178939
- tasks2[selectedIndex].error
178940
- ]
178941
- }, undefined, true, undefined, this),
178942
- tasks2[selectedIndex].result && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text3, {
178943
- color: "green",
178944
- children: [
178945
- "Result: ",
178946
- tasks2[selectedIndex].result
178947
- ]
178948
- }, undefined, true, undefined, this)
178949
- ]
178950
- }, undefined, true, undefined, this),
180088
+ tasks2.length > 0 && selectedIndex < tasks2.length && (() => {
180089
+ const task = tasks2[selectedIndex];
180090
+ const formatTime = (ts2) => ts2 ? new Date(ts2).toLocaleString() : "n/a";
180091
+ const getElapsed = () => {
180092
+ if (task.status !== "in_progress" || !task.startedAt)
180093
+ return null;
180094
+ const elapsed2 = Date.now() - task.startedAt;
180095
+ const secs = Math.floor(elapsed2 / 1000);
180096
+ const mins = Math.floor(secs / 60);
180097
+ const hrs = Math.floor(mins / 60);
180098
+ if (hrs > 0)
180099
+ return `${hrs}h ${mins % 60}m elapsed`;
180100
+ if (mins > 0)
180101
+ return `${mins}m ${secs % 60}s elapsed`;
180102
+ return `${secs}s elapsed`;
180103
+ };
180104
+ const elapsed = getElapsed();
180105
+ return /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
180106
+ marginTop: 1,
180107
+ flexDirection: "column",
180108
+ borderStyle: "single",
180109
+ borderColor: "gray",
180110
+ paddingX: 1,
180111
+ children: [
180112
+ /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text3, {
180113
+ bold: true,
180114
+ wrap: "wrap",
180115
+ children: task.description
180116
+ }, undefined, false, undefined, this),
180117
+ /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
180118
+ marginTop: 0,
180119
+ children: [
180120
+ /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text3, {
180121
+ dimColor: true,
180122
+ children: [
180123
+ "Created: ",
180124
+ formatTime(task.createdAt)
180125
+ ]
180126
+ }, undefined, true, undefined, this),
180127
+ elapsed && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text3, {
180128
+ color: "yellow",
180129
+ children: [
180130
+ " | ",
180131
+ elapsed
180132
+ ]
180133
+ }, undefined, true, undefined, this)
180134
+ ]
180135
+ }, undefined, true, undefined, this),
180136
+ task.startedAt && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text3, {
180137
+ dimColor: true,
180138
+ children: [
180139
+ "Started: ",
180140
+ formatTime(task.startedAt)
180141
+ ]
180142
+ }, undefined, true, undefined, this),
180143
+ task.completedAt && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text3, {
180144
+ dimColor: true,
180145
+ children: [
180146
+ "Completed: ",
180147
+ formatTime(task.completedAt)
180148
+ ]
180149
+ }, undefined, true, undefined, this),
180150
+ task.blockedBy && task.blockedBy.length > 0 && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text3, {
180151
+ dimColor: true,
180152
+ children: [
180153
+ "Blocked by: ",
180154
+ task.blockedBy.map((id) => getTaskLabel(id)).join(", ")
180155
+ ]
180156
+ }, undefined, true, undefined, this),
180157
+ task.blocks && task.blocks.length > 0 && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text3, {
180158
+ dimColor: true,
180159
+ children: [
180160
+ "Blocks: ",
180161
+ task.blocks.map((id) => getTaskLabel(id)).join(", ")
180162
+ ]
180163
+ }, undefined, true, undefined, this),
180164
+ task.assignee && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text3, {
180165
+ dimColor: true,
180166
+ children: [
180167
+ "Assignee: ",
180168
+ task.assignee
180169
+ ]
180170
+ }, undefined, true, undefined, this),
180171
+ task.projectId && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text3, {
180172
+ dimColor: true,
180173
+ children: [
180174
+ "Project: ",
180175
+ task.projectId
180176
+ ]
180177
+ }, undefined, true, undefined, this),
180178
+ task.error && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text3, {
180179
+ color: "red",
180180
+ children: [
180181
+ "Error: ",
180182
+ task.error
180183
+ ]
180184
+ }, undefined, true, undefined, this),
180185
+ task.result && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text3, {
180186
+ color: "green",
180187
+ children: [
180188
+ "Result: ",
180189
+ task.result
180190
+ ]
180191
+ }, undefined, true, undefined, this)
180192
+ ]
180193
+ }, undefined, true, undefined, this);
180194
+ })(),
178951
180195
  /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
178952
180196
  marginTop: 1,
178953
180197
  children: /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text3, {
@@ -182101,7 +183345,7 @@ function getVisibleRange2(selectedIndex, totalItems, maxVisible = MAX_VISIBLE_IT
182101
183345
  }
182102
183346
  };
182103
183347
  }
182104
- function formatRelativeTime(isoDate) {
183348
+ function formatRelativeTime2(isoDate) {
182105
183349
  const date = new Date(isoDate);
182106
183350
  const now2 = new Date;
182107
183351
  const diffMs = now2.getTime() - date.getTime();
@@ -182491,7 +183735,7 @@ function MessagesPanel({
182491
183735
  children: "Received: "
182492
183736
  }, undefined, false, undefined, this),
182493
183737
  /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
182494
- children: formatRelativeTime(detailMessage.createdAt)
183738
+ children: formatRelativeTime2(detailMessage.createdAt)
182495
183739
  }, undefined, false, undefined, this),
182496
183740
  /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text3, {
182497
183741
  dimColor: true,
@@ -182623,7 +183867,7 @@ function MessagesPanel({
182623
183867
  dimColor: true,
182624
183868
  children: [
182625
183869
  " ",
182626
- formatRelativeTime(msg.createdAt)
183870
+ formatRelativeTime2(msg.createdAt)
182627
183871
  ]
182628
183872
  }, undefined, true, undefined, this)
182629
183873
  ]
@@ -184675,8 +185919,566 @@ function AgentsPanel({
184675
185919
  }, undefined, true, undefined, this);
184676
185920
  }
184677
185921
 
184678
- // packages/terminal/src/components/App.tsx
185922
+ // packages/terminal/src/components/SchedulesPanel.tsx
185923
+ var import_react45 = __toESM(require_react(), 1);
184679
185924
  var jsx_dev_runtime23 = __toESM(require_jsx_dev_runtime(), 1);
185925
+ var STATUS_ICONS2 = {
185926
+ active: "\u25CF",
185927
+ paused: "\u25D0",
185928
+ completed: "\u2713",
185929
+ error: "\u2717"
185930
+ };
185931
+ var STATUS_COLORS2 = {
185932
+ active: "green",
185933
+ paused: "yellow",
185934
+ completed: "gray",
185935
+ error: "red"
185936
+ };
185937
+ var KIND_LABELS = {
185938
+ once: "One-time",
185939
+ cron: "Cron",
185940
+ random: "Random",
185941
+ interval: "Interval"
185942
+ };
185943
+ function formatRelativeTime3(timestamp) {
185944
+ if (!timestamp)
185945
+ return "n/a";
185946
+ const now2 = Date.now();
185947
+ const diff2 = timestamp - now2;
185948
+ const absDiff = Math.abs(diff2);
185949
+ const isPast = diff2 < 0;
185950
+ const seconds = Math.floor(absDiff / 1000);
185951
+ const minutes = Math.floor(seconds / 60);
185952
+ const hours = Math.floor(minutes / 60);
185953
+ const days = Math.floor(hours / 24);
185954
+ let timeStr;
185955
+ if (days > 0) {
185956
+ timeStr = `${days}d ${hours % 24}h`;
185957
+ } else if (hours > 0) {
185958
+ timeStr = `${hours}h ${minutes % 60}m`;
185959
+ } else if (minutes > 0) {
185960
+ timeStr = `${minutes}m`;
185961
+ } else {
185962
+ timeStr = `${seconds}s`;
185963
+ }
185964
+ return isPast ? `${timeStr} ago` : `in ${timeStr}`;
185965
+ }
185966
+ function formatAbsoluteTime2(timestamp) {
185967
+ if (!timestamp)
185968
+ return "n/a";
185969
+ return new Date(timestamp).toLocaleString();
185970
+ }
185971
+ function getScheduleDescription(schedule) {
185972
+ const { kind: kind2, cron, at: at4, interval, unit, minInterval, maxInterval } = schedule.schedule;
185973
+ switch (kind2) {
185974
+ case "once":
185975
+ return at4 ? `At ${at4}` : "One-time";
185976
+ case "cron":
185977
+ return cron || "Cron schedule";
185978
+ case "interval":
185979
+ return `Every ${interval} ${unit || "minutes"}`;
185980
+ case "random":
185981
+ return `Random ${minInterval}-${maxInterval} ${unit || "minutes"}`;
185982
+ default:
185983
+ return kind2;
185984
+ }
185985
+ }
185986
+ function SchedulesPanel({
185987
+ schedules,
185988
+ onPause,
185989
+ onResume,
185990
+ onDelete,
185991
+ onRun,
185992
+ onRefresh,
185993
+ onClose
185994
+ }) {
185995
+ const [selectedIndex, setSelectedIndex] = import_react45.useState(0);
185996
+ const [mode, setMode] = import_react45.useState("list");
185997
+ const [isSubmitting, setIsSubmitting] = import_react45.useState(false);
185998
+ const sortedSchedules = [...schedules].sort((a5, b8) => {
185999
+ if (a5.status === "active" && b8.status !== "active")
186000
+ return -1;
186001
+ if (b8.status === "active" && a5.status !== "active")
186002
+ return 1;
186003
+ const aNext = a5.nextRunAt || Infinity;
186004
+ const bNext = b8.nextRunAt || Infinity;
186005
+ return aNext - bNext;
186006
+ });
186007
+ import_react45.useEffect(() => {
186008
+ setSelectedIndex((prev) => Math.min(prev, Math.max(0, sortedSchedules.length - 1)));
186009
+ }, [sortedSchedules.length]);
186010
+ const selectedSchedule = sortedSchedules[selectedIndex];
186011
+ use_input_default((input, key) => {
186012
+ if (mode === "delete-confirm") {
186013
+ if (input === "y" || input === "Y") {
186014
+ if (selectedSchedule) {
186015
+ setIsSubmitting(true);
186016
+ onDelete(selectedSchedule.id).finally(() => {
186017
+ setIsSubmitting(false);
186018
+ setMode("list");
186019
+ });
186020
+ }
186021
+ return;
186022
+ }
186023
+ if (input === "n" || input === "N" || key.escape) {
186024
+ setMode("list");
186025
+ return;
186026
+ }
186027
+ return;
186028
+ }
186029
+ if (mode === "detail") {
186030
+ if (key.escape || input === "q") {
186031
+ setMode("list");
186032
+ return;
186033
+ }
186034
+ if (input === "p" || input === "P") {
186035
+ if (selectedSchedule && selectedSchedule.status === "active") {
186036
+ setIsSubmitting(true);
186037
+ onPause(selectedSchedule.id).finally(() => setIsSubmitting(false));
186038
+ }
186039
+ return;
186040
+ }
186041
+ if (input === "r" || input === "R") {
186042
+ if (selectedSchedule && selectedSchedule.status === "paused") {
186043
+ setIsSubmitting(true);
186044
+ onResume(selectedSchedule.id).finally(() => setIsSubmitting(false));
186045
+ } else if (selectedSchedule) {
186046
+ setIsSubmitting(true);
186047
+ onRun(selectedSchedule.id).finally(() => setIsSubmitting(false));
186048
+ }
186049
+ return;
186050
+ }
186051
+ if (input === "d" || input === "D") {
186052
+ setMode("delete-confirm");
186053
+ return;
186054
+ }
186055
+ return;
186056
+ }
186057
+ if (key.escape || input === "q") {
186058
+ onClose();
186059
+ return;
186060
+ }
186061
+ if (key.return) {
186062
+ if (sortedSchedules.length > 0) {
186063
+ setMode("detail");
186064
+ }
186065
+ return;
186066
+ }
186067
+ if (key.upArrow) {
186068
+ setSelectedIndex((prev) => prev === 0 ? sortedSchedules.length - 1 : prev - 1);
186069
+ return;
186070
+ }
186071
+ if (key.downArrow) {
186072
+ setSelectedIndex((prev) => prev === sortedSchedules.length - 1 ? 0 : prev + 1);
186073
+ return;
186074
+ }
186075
+ if (input === "p" || input === "P") {
186076
+ if (selectedSchedule && selectedSchedule.status === "active") {
186077
+ setIsSubmitting(true);
186078
+ onPause(selectedSchedule.id).finally(() => setIsSubmitting(false));
186079
+ }
186080
+ return;
186081
+ }
186082
+ if (input === "r" || input === "R") {
186083
+ if (selectedSchedule) {
186084
+ setIsSubmitting(true);
186085
+ if (selectedSchedule.status === "paused") {
186086
+ onResume(selectedSchedule.id).finally(() => setIsSubmitting(false));
186087
+ } else {
186088
+ onRun(selectedSchedule.id).finally(() => setIsSubmitting(false));
186089
+ }
186090
+ }
186091
+ return;
186092
+ }
186093
+ if (input === "d" || input === "D") {
186094
+ if (selectedSchedule) {
186095
+ setMode("delete-confirm");
186096
+ }
186097
+ return;
186098
+ }
186099
+ if (input === "f" || input === "F") {
186100
+ setIsSubmitting(true);
186101
+ onRefresh().finally(() => setIsSubmitting(false));
186102
+ return;
186103
+ }
186104
+ const num = parseInt(input, 10);
186105
+ if (!isNaN(num) && num >= 1 && num <= sortedSchedules.length) {
186106
+ setSelectedIndex(num - 1);
186107
+ return;
186108
+ }
186109
+ });
186110
+ if (mode === "delete-confirm") {
186111
+ return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186112
+ flexDirection: "column",
186113
+ paddingY: 1,
186114
+ children: [
186115
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186116
+ marginBottom: 1,
186117
+ children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186118
+ bold: true,
186119
+ color: "red",
186120
+ children: "Delete Schedule"
186121
+ }, undefined, false, undefined, this)
186122
+ }, undefined, false, undefined, this),
186123
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186124
+ marginBottom: 1,
186125
+ children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186126
+ children: [
186127
+ 'Delete schedule: "',
186128
+ selectedSchedule?.command.slice(0, 50),
186129
+ (selectedSchedule?.command.length || 0) > 50 ? "..." : "",
186130
+ '"?'
186131
+ ]
186132
+ }, undefined, true, undefined, this)
186133
+ }, undefined, false, undefined, this),
186134
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186135
+ marginTop: 1,
186136
+ children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186137
+ children: [
186138
+ "Press ",
186139
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186140
+ color: "green",
186141
+ bold: true,
186142
+ children: "y"
186143
+ }, undefined, false, undefined, this),
186144
+ " to confirm or",
186145
+ " ",
186146
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186147
+ color: "red",
186148
+ bold: true,
186149
+ children: "n"
186150
+ }, undefined, false, undefined, this),
186151
+ " to cancel"
186152
+ ]
186153
+ }, undefined, true, undefined, this)
186154
+ }, undefined, false, undefined, this)
186155
+ ]
186156
+ }, undefined, true, undefined, this);
186157
+ }
186158
+ if (mode === "detail" && selectedSchedule) {
186159
+ const s6 = selectedSchedule;
186160
+ const statusIcon = STATUS_ICONS2[s6.status];
186161
+ const statusColor = STATUS_COLORS2[s6.status];
186162
+ return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186163
+ flexDirection: "column",
186164
+ paddingY: 1,
186165
+ children: [
186166
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186167
+ marginBottom: 1,
186168
+ children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186169
+ bold: true,
186170
+ color: "cyan",
186171
+ children: "Schedule Details"
186172
+ }, undefined, false, undefined, this)
186173
+ }, undefined, false, undefined, this),
186174
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186175
+ flexDirection: "column",
186176
+ borderStyle: "round",
186177
+ borderColor: "gray",
186178
+ paddingX: 1,
186179
+ paddingY: 0,
186180
+ children: [
186181
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186182
+ children: [
186183
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186184
+ bold: true,
186185
+ children: "ID: "
186186
+ }, undefined, false, undefined, this),
186187
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186188
+ children: s6.id
186189
+ }, undefined, false, undefined, this)
186190
+ ]
186191
+ }, undefined, true, undefined, this),
186192
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186193
+ children: [
186194
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186195
+ bold: true,
186196
+ children: "Status: "
186197
+ }, undefined, false, undefined, this),
186198
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186199
+ color: statusColor,
186200
+ children: [
186201
+ statusIcon,
186202
+ " ",
186203
+ s6.status
186204
+ ]
186205
+ }, undefined, true, undefined, this)
186206
+ ]
186207
+ }, undefined, true, undefined, this),
186208
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186209
+ children: [
186210
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186211
+ bold: true,
186212
+ children: "Type: "
186213
+ }, undefined, false, undefined, this),
186214
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186215
+ children: KIND_LABELS[s6.schedule.kind] || s6.schedule.kind
186216
+ }, undefined, false, undefined, this)
186217
+ ]
186218
+ }, undefined, true, undefined, this),
186219
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186220
+ children: [
186221
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186222
+ bold: true,
186223
+ children: "Schedule: "
186224
+ }, undefined, false, undefined, this),
186225
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186226
+ children: getScheduleDescription(s6)
186227
+ }, undefined, false, undefined, this)
186228
+ ]
186229
+ }, undefined, true, undefined, this),
186230
+ s6.description && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186231
+ children: [
186232
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186233
+ bold: true,
186234
+ children: "Description: "
186235
+ }, undefined, false, undefined, this),
186236
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186237
+ children: s6.description
186238
+ }, undefined, false, undefined, this)
186239
+ ]
186240
+ }, undefined, true, undefined, this),
186241
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186242
+ marginTop: 1,
186243
+ children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186244
+ bold: true,
186245
+ children: "Command: "
186246
+ }, undefined, false, undefined, this)
186247
+ }, undefined, false, undefined, this),
186248
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186249
+ marginLeft: 2,
186250
+ children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186251
+ wrap: "wrap",
186252
+ color: "cyan",
186253
+ children: s6.command
186254
+ }, undefined, false, undefined, this)
186255
+ }, undefined, false, undefined, this),
186256
+ s6.message && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(jsx_dev_runtime23.Fragment, {
186257
+ children: [
186258
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186259
+ marginTop: 1,
186260
+ children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186261
+ bold: true,
186262
+ children: "Message: "
186263
+ }, undefined, false, undefined, this)
186264
+ }, undefined, false, undefined, this),
186265
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186266
+ marginLeft: 2,
186267
+ children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186268
+ wrap: "wrap",
186269
+ children: s6.message
186270
+ }, undefined, false, undefined, this)
186271
+ }, undefined, false, undefined, this)
186272
+ ]
186273
+ }, undefined, true, undefined, this),
186274
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186275
+ marginTop: 1,
186276
+ children: [
186277
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186278
+ bold: true,
186279
+ children: "Next Run: "
186280
+ }, undefined, false, undefined, this),
186281
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186282
+ color: s6.status === "active" ? "green" : undefined,
186283
+ children: [
186284
+ formatAbsoluteTime2(s6.nextRunAt),
186285
+ " (",
186286
+ formatRelativeTime3(s6.nextRunAt),
186287
+ ")"
186288
+ ]
186289
+ }, undefined, true, undefined, this)
186290
+ ]
186291
+ }, undefined, true, undefined, this),
186292
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186293
+ children: [
186294
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186295
+ bold: true,
186296
+ children: "Last Run: "
186297
+ }, undefined, false, undefined, this),
186298
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186299
+ children: formatAbsoluteTime2(s6.lastRunAt)
186300
+ }, undefined, false, undefined, this)
186301
+ ]
186302
+ }, undefined, true, undefined, this),
186303
+ s6.lastResult && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186304
+ children: [
186305
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186306
+ bold: true,
186307
+ children: "Last Result: "
186308
+ }, undefined, false, undefined, this),
186309
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186310
+ color: s6.lastResult.ok ? "green" : "red",
186311
+ children: s6.lastResult.ok ? "Success" : `Error: ${s6.lastResult.error}`
186312
+ }, undefined, false, undefined, this)
186313
+ ]
186314
+ }, undefined, true, undefined, this),
186315
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186316
+ children: [
186317
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186318
+ bold: true,
186319
+ children: "Created: "
186320
+ }, undefined, false, undefined, this),
186321
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186322
+ children: [
186323
+ formatAbsoluteTime2(s6.createdAt),
186324
+ " by ",
186325
+ s6.createdBy
186326
+ ]
186327
+ }, undefined, true, undefined, this)
186328
+ ]
186329
+ }, undefined, true, undefined, this)
186330
+ ]
186331
+ }, undefined, true, undefined, this),
186332
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186333
+ marginTop: 1,
186334
+ children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186335
+ dimColor: true,
186336
+ children: [
186337
+ s6.status === "active" ? "[p]ause" : s6.status === "paused" ? "[r]esume" : "",
186338
+ " ",
186339
+ "[r]un now | [d]elete | Esc back"
186340
+ ]
186341
+ }, undefined, true, undefined, this)
186342
+ }, undefined, false, undefined, this),
186343
+ isSubmitting && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186344
+ marginTop: 1,
186345
+ children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186346
+ color: "yellow",
186347
+ children: "Processing..."
186348
+ }, undefined, false, undefined, this)
186349
+ }, undefined, false, undefined, this)
186350
+ ]
186351
+ }, undefined, true, undefined, this);
186352
+ }
186353
+ const activeCount = schedules.filter((s6) => s6.status === "active").length;
186354
+ const pausedCount = schedules.filter((s6) => s6.status === "paused").length;
186355
+ const completedCount = schedules.filter((s6) => s6.status === "completed").length;
186356
+ const errorCount = schedules.filter((s6) => s6.status === "error").length;
186357
+ return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186358
+ flexDirection: "column",
186359
+ paddingY: 1,
186360
+ children: [
186361
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186362
+ marginBottom: 1,
186363
+ justifyContent: "space-between",
186364
+ children: [
186365
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186366
+ children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186367
+ bold: true,
186368
+ children: "Schedules"
186369
+ }, undefined, false, undefined, this)
186370
+ }, undefined, false, undefined, this),
186371
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186372
+ dimColor: true,
186373
+ children: "[p]ause [r]esume [d]elete [f]refresh"
186374
+ }, undefined, false, undefined, this)
186375
+ ]
186376
+ }, undefined, true, undefined, this),
186377
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186378
+ marginBottom: 1,
186379
+ children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186380
+ dimColor: true,
186381
+ children: [
186382
+ activeCount,
186383
+ " active, ",
186384
+ pausedCount,
186385
+ " paused, ",
186386
+ completedCount,
186387
+ " done, ",
186388
+ errorCount,
186389
+ " errors"
186390
+ ]
186391
+ }, undefined, true, undefined, this)
186392
+ }, undefined, false, undefined, this),
186393
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186394
+ flexDirection: "column",
186395
+ borderStyle: "round",
186396
+ borderColor: "gray",
186397
+ paddingX: 1,
186398
+ children: sortedSchedules.length === 0 ? /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186399
+ paddingY: 1,
186400
+ children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186401
+ dimColor: true,
186402
+ children: "No schedules. Use /schedule to create one."
186403
+ }, undefined, false, undefined, this)
186404
+ }, undefined, false, undefined, this) : sortedSchedules.map((schedule, index) => {
186405
+ const isSelected = index === selectedIndex;
186406
+ const statusIcon = STATUS_ICONS2[schedule.status];
186407
+ const statusColor = STATUS_COLORS2[schedule.status];
186408
+ const nextRun = formatRelativeTime3(schedule.nextRunAt);
186409
+ const command = schedule.command.slice(0, 35) + (schedule.command.length > 35 ? "..." : "");
186410
+ const kindLabel = KIND_LABELS[schedule.schedule.kind] || schedule.schedule.kind;
186411
+ return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186412
+ paddingY: 0,
186413
+ children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186414
+ inverse: isSelected,
186415
+ dimColor: !isSelected && schedule.status === "completed",
186416
+ children: [
186417
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186418
+ color: statusColor,
186419
+ children: statusIcon
186420
+ }, undefined, false, undefined, this),
186421
+ " ",
186422
+ index + 1,
186423
+ ". ",
186424
+ command.padEnd(37),
186425
+ " ",
186426
+ kindLabel.padEnd(10),
186427
+ " ",
186428
+ nextRun
186429
+ ]
186430
+ }, undefined, true, undefined, this)
186431
+ }, schedule.id, false, undefined, this);
186432
+ })
186433
+ }, undefined, false, undefined, this),
186434
+ sortedSchedules.length > 0 && selectedSchedule && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186435
+ marginTop: 1,
186436
+ flexDirection: "column",
186437
+ children: [
186438
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186439
+ dimColor: true,
186440
+ children: [
186441
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186442
+ bold: true,
186443
+ children: "Command:"
186444
+ }, undefined, false, undefined, this),
186445
+ " ",
186446
+ selectedSchedule.command
186447
+ ]
186448
+ }, undefined, true, undefined, this),
186449
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186450
+ dimColor: true,
186451
+ children: [
186452
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186453
+ bold: true,
186454
+ children: "Schedule:"
186455
+ }, undefined, false, undefined, this),
186456
+ " ",
186457
+ getScheduleDescription(selectedSchedule)
186458
+ ]
186459
+ }, undefined, true, undefined, this)
186460
+ ]
186461
+ }, undefined, true, undefined, this),
186462
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186463
+ marginTop: 1,
186464
+ children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186465
+ dimColor: true,
186466
+ children: "Enter view | \u2191/\u2193 navigate | Esc close"
186467
+ }, undefined, false, undefined, this)
186468
+ }, undefined, false, undefined, this),
186469
+ isSubmitting && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
186470
+ marginTop: 1,
186471
+ children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
186472
+ color: "yellow",
186473
+ children: "Processing..."
186474
+ }, undefined, false, undefined, this)
186475
+ }, undefined, false, undefined, this)
186476
+ ]
186477
+ }, undefined, true, undefined, this);
186478
+ }
186479
+
186480
+ // packages/terminal/src/components/App.tsx
186481
+ var jsx_dev_runtime24 = __toESM(require_jsx_dev_runtime(), 1);
184680
186482
  var SHOW_ERROR_CODES = process.env.ASSISTANTS_DEBUG === "1";
184681
186483
  function formatElapsedDuration(ms2) {
184682
186484
  const totalSeconds = Math.max(0, Math.floor(ms2 / 1000));
@@ -184708,84 +186510,86 @@ function App2({ cwd: cwd2, version: version3 }) {
184708
186510
  const { stdout } = use_stdout_default();
184709
186511
  const rows = stdout?.rows ?? 24;
184710
186512
  const columns = stdout?.columns ?? 80;
184711
- const [registry3] = import_react45.useState(() => new SessionRegistry);
184712
- const registryRef = import_react45.useRef(registry3);
184713
- const [activeSessionId, setActiveSessionId] = import_react45.useState(null);
184714
- const [isInitializing, setIsInitializing] = import_react45.useState(true);
184715
- const [showSessionSelector, setShowSessionSelector] = import_react45.useState(false);
184716
- const [recoverableSessions, setRecoverableSessions] = import_react45.useState([]);
184717
- const [showRecoveryPanel, setShowRecoveryPanel] = import_react45.useState(false);
184718
- const [showConnectorsPanel, setShowConnectorsPanel] = import_react45.useState(false);
184719
- const [connectorsPanelInitial, setConnectorsPanelInitial] = import_react45.useState();
184720
- const [connectors, setConnectors] = import_react45.useState([]);
184721
- const connectorBridgeRef = import_react45.useRef(null);
184722
- const [showTasksPanel, setShowTasksPanel] = import_react45.useState(false);
184723
- const [tasksList, setTasksList] = import_react45.useState([]);
184724
- const [tasksPaused, setTasksPaused] = import_react45.useState(false);
184725
- const [showAssistantsPanel, setShowAssistantsPanel] = import_react45.useState(false);
184726
- const [assistantsRefreshKey, setAssistantsRefreshKey] = import_react45.useState(0);
184727
- const [assistantError, setAssistantError] = import_react45.useState(null);
184728
- const [showHooksPanel, setShowHooksPanel] = import_react45.useState(false);
184729
- const [hooksConfig, setHooksConfig] = import_react45.useState({});
184730
- const hookStoreRef = import_react45.useRef(null);
184731
- const [showGuardrailsPanel, setShowGuardrailsPanel] = import_react45.useState(false);
184732
- const [guardrailsConfig, setGuardrailsConfig] = import_react45.useState(null);
184733
- const [guardrailsPolicies, setGuardrailsPolicies] = import_react45.useState([]);
184734
- const guardrailsStoreRef = import_react45.useRef(null);
184735
- const [showBudgetPanel, setShowBudgetPanel] = import_react45.useState(false);
184736
- const [budgetConfig, setBudgetConfig] = import_react45.useState(null);
184737
- const [sessionBudgetStatus, setSessionBudgetStatus] = import_react45.useState(null);
184738
- const [swarmBudgetStatus, setSwarmBudgetStatus] = import_react45.useState(null);
184739
- const budgetTrackerRef = import_react45.useRef(null);
184740
- const [showAgentsPanel, setShowAgentsPanel] = import_react45.useState(false);
184741
- const [agentsList, setAgentsList] = import_react45.useState([]);
184742
- const [registryStats, setRegistryStats] = import_react45.useState(null);
184743
- const [showConfigPanel, setShowConfigPanel] = import_react45.useState(false);
184744
- const [currentConfig, setCurrentConfig] = import_react45.useState(null);
184745
- const [userConfig, setUserConfig] = import_react45.useState(null);
184746
- const [projectConfig, setProjectConfig] = import_react45.useState(null);
184747
- const [localConfig, setLocalConfig] = import_react45.useState(null);
184748
- const [showMessagesPanel, setShowMessagesPanel] = import_react45.useState(false);
184749
- const [messagesPanelError, setMessagesPanelError] = import_react45.useState(null);
184750
- const [messagesList, setMessagesList] = import_react45.useState([]);
184751
- const sessionUIStates = import_react45.useRef(new Map);
184752
- const [messages2, setMessages] = import_react45.useState([]);
184753
- const [currentResponse, setCurrentResponse] = import_react45.useState("");
184754
- const [currentToolCall, setCurrentToolCall] = import_react45.useState();
184755
- const [isProcessing, setIsProcessing] = import_react45.useState(false);
184756
- const [error2, setError] = import_react45.useState(null);
184757
- const [messageQueue, setMessageQueue] = import_react45.useState([]);
184758
- const [inlinePending, setInlinePending] = import_react45.useState([]);
184759
- const [activityLog, setActivityLog] = import_react45.useState([]);
184760
- const [tokenUsage, setTokenUsage] = import_react45.useState();
184761
- const [energyState, setEnergyState] = import_react45.useState();
184762
- const [voiceState, setVoiceState] = import_react45.useState();
184763
- const [heartbeatState, setHeartbeatState] = import_react45.useState();
184764
- const [identityInfo, setIdentityInfo] = import_react45.useState();
184765
- const [verboseTools, setVerboseTools] = import_react45.useState(false);
184766
- const [askUserState, setAskUserState] = import_react45.useState(null);
184767
- const [processingStartTime, setProcessingStartTime] = import_react45.useState();
184768
- const [currentTurnTokens, setCurrentTurnTokens] = import_react45.useState(0);
184769
- const [lastWorkedFor, setLastWorkedFor] = import_react45.useState();
184770
- const [skills, setSkills] = import_react45.useState([]);
184771
- const [commands3, setCommands] = import_react45.useState([]);
184772
- const lastCtrlCRef = import_react45.useRef(0);
184773
- const [showExitHint, setShowExitHint] = import_react45.useState(false);
184774
- const responseRef = import_react45.useRef("");
184775
- const toolCallsRef = import_react45.useRef([]);
184776
- const toolResultsRef = import_react45.useRef([]);
184777
- const activityLogRef = import_react45.useRef([]);
184778
- const skipNextDoneRef = import_react45.useRef(false);
184779
- const isProcessingRef = import_react45.useRef(isProcessing);
184780
- const processingStartTimeRef = import_react45.useRef(processingStartTime);
184781
- const pendingSendsRef = import_react45.useRef([]);
184782
- const askUserStateRef = import_react45.useRef(new Map);
184783
- const [queueFlushTrigger, setQueueFlushTrigger] = import_react45.useState(0);
184784
- const clearPendingSend = import_react45.useCallback((id, sessionId) => {
186513
+ const [registry3] = import_react46.useState(() => new SessionRegistry);
186514
+ const registryRef = import_react46.useRef(registry3);
186515
+ const [activeSessionId, setActiveSessionId] = import_react46.useState(null);
186516
+ const [isInitializing, setIsInitializing] = import_react46.useState(true);
186517
+ const [showSessionSelector, setShowSessionSelector] = import_react46.useState(false);
186518
+ const [recoverableSessions, setRecoverableSessions] = import_react46.useState([]);
186519
+ const [showRecoveryPanel, setShowRecoveryPanel] = import_react46.useState(false);
186520
+ const [showConnectorsPanel, setShowConnectorsPanel] = import_react46.useState(false);
186521
+ const [connectorsPanelInitial, setConnectorsPanelInitial] = import_react46.useState();
186522
+ const [connectors, setConnectors] = import_react46.useState([]);
186523
+ const connectorBridgeRef = import_react46.useRef(null);
186524
+ const [showTasksPanel, setShowTasksPanel] = import_react46.useState(false);
186525
+ const [tasksList, setTasksList] = import_react46.useState([]);
186526
+ const [tasksPaused, setTasksPaused] = import_react46.useState(false);
186527
+ const [showSchedulesPanel, setShowSchedulesPanel] = import_react46.useState(false);
186528
+ const [schedulesList, setSchedulesList] = import_react46.useState([]);
186529
+ const [showAssistantsPanel, setShowAssistantsPanel] = import_react46.useState(false);
186530
+ const [assistantsRefreshKey, setAssistantsRefreshKey] = import_react46.useState(0);
186531
+ const [assistantError, setAssistantError] = import_react46.useState(null);
186532
+ const [showHooksPanel, setShowHooksPanel] = import_react46.useState(false);
186533
+ const [hooksConfig, setHooksConfig] = import_react46.useState({});
186534
+ const hookStoreRef = import_react46.useRef(null);
186535
+ const [showGuardrailsPanel, setShowGuardrailsPanel] = import_react46.useState(false);
186536
+ const [guardrailsConfig, setGuardrailsConfig] = import_react46.useState(null);
186537
+ const [guardrailsPolicies, setGuardrailsPolicies] = import_react46.useState([]);
186538
+ const guardrailsStoreRef = import_react46.useRef(null);
186539
+ const [showBudgetPanel, setShowBudgetPanel] = import_react46.useState(false);
186540
+ const [budgetConfig, setBudgetConfig] = import_react46.useState(null);
186541
+ const [sessionBudgetStatus, setSessionBudgetStatus] = import_react46.useState(null);
186542
+ const [swarmBudgetStatus, setSwarmBudgetStatus] = import_react46.useState(null);
186543
+ const budgetTrackerRef = import_react46.useRef(null);
186544
+ const [showAgentsPanel, setShowAgentsPanel] = import_react46.useState(false);
186545
+ const [agentsList, setAgentsList] = import_react46.useState([]);
186546
+ const [registryStats, setRegistryStats] = import_react46.useState(null);
186547
+ const [showConfigPanel, setShowConfigPanel] = import_react46.useState(false);
186548
+ const [currentConfig, setCurrentConfig] = import_react46.useState(null);
186549
+ const [userConfig, setUserConfig] = import_react46.useState(null);
186550
+ const [projectConfig, setProjectConfig] = import_react46.useState(null);
186551
+ const [localConfig, setLocalConfig] = import_react46.useState(null);
186552
+ const [showMessagesPanel, setShowMessagesPanel] = import_react46.useState(false);
186553
+ const [messagesPanelError, setMessagesPanelError] = import_react46.useState(null);
186554
+ const [messagesList, setMessagesList] = import_react46.useState([]);
186555
+ const sessionUIStates = import_react46.useRef(new Map);
186556
+ const [messages2, setMessages] = import_react46.useState([]);
186557
+ const [currentResponse, setCurrentResponse] = import_react46.useState("");
186558
+ const [currentToolCall, setCurrentToolCall] = import_react46.useState();
186559
+ const [isProcessing, setIsProcessing] = import_react46.useState(false);
186560
+ const [error2, setError] = import_react46.useState(null);
186561
+ const [messageQueue, setMessageQueue] = import_react46.useState([]);
186562
+ const [inlinePending, setInlinePending] = import_react46.useState([]);
186563
+ const [activityLog, setActivityLog] = import_react46.useState([]);
186564
+ const [tokenUsage, setTokenUsage] = import_react46.useState();
186565
+ const [energyState, setEnergyState] = import_react46.useState();
186566
+ const [voiceState, setVoiceState] = import_react46.useState();
186567
+ const [heartbeatState, setHeartbeatState] = import_react46.useState();
186568
+ const [identityInfo, setIdentityInfo] = import_react46.useState();
186569
+ const [verboseTools, setVerboseTools] = import_react46.useState(false);
186570
+ const [askUserState, setAskUserState] = import_react46.useState(null);
186571
+ const [processingStartTime, setProcessingStartTime] = import_react46.useState();
186572
+ const [currentTurnTokens, setCurrentTurnTokens] = import_react46.useState(0);
186573
+ const [lastWorkedFor, setLastWorkedFor] = import_react46.useState();
186574
+ const [skills, setSkills] = import_react46.useState([]);
186575
+ const [commands3, setCommands] = import_react46.useState([]);
186576
+ const lastCtrlCRef = import_react46.useRef(0);
186577
+ const [showExitHint, setShowExitHint] = import_react46.useState(false);
186578
+ const responseRef = import_react46.useRef("");
186579
+ const toolCallsRef = import_react46.useRef([]);
186580
+ const toolResultsRef = import_react46.useRef([]);
186581
+ const activityLogRef = import_react46.useRef([]);
186582
+ const skipNextDoneRef = import_react46.useRef(false);
186583
+ const isProcessingRef = import_react46.useRef(isProcessing);
186584
+ const processingStartTimeRef = import_react46.useRef(processingStartTime);
186585
+ const pendingSendsRef = import_react46.useRef([]);
186586
+ const askUserStateRef = import_react46.useRef(new Map);
186587
+ const [queueFlushTrigger, setQueueFlushTrigger] = import_react46.useState(0);
186588
+ const clearPendingSend = import_react46.useCallback((id, sessionId) => {
184785
186589
  pendingSendsRef.current = pendingSendsRef.current.filter((entry) => entry.id !== id || entry.sessionId !== sessionId);
184786
186590
  setInlinePending((prev) => prev.filter((msg) => msg.id !== id));
184787
186591
  }, []);
184788
- const beginAskUser = import_react45.useCallback((sessionId, request2) => {
186592
+ const beginAskUser = import_react46.useCallback((sessionId, request2) => {
184789
186593
  return new Promise((resolve5, reject) => {
184790
186594
  if (askUserStateRef.current.has(sessionId)) {
184791
186595
  reject(new Error("Another interview is already in progress for this session."));
@@ -184805,7 +186609,7 @@ function App2({ cwd: cwd2, version: version3 }) {
184805
186609
  }
184806
186610
  });
184807
186611
  }, [activeSessionId]);
184808
- const cancelAskUser = import_react45.useCallback((reason, sessionId) => {
186612
+ const cancelAskUser = import_react46.useCallback((reason, sessionId) => {
184809
186613
  const activeId = sessionId ?? activeSessionId;
184810
186614
  if (!activeId)
184811
186615
  return;
@@ -184818,7 +186622,7 @@ function App2({ cwd: cwd2, version: version3 }) {
184818
186622
  }
184819
186623
  current.reject(new Error(reason));
184820
186624
  }, [activeSessionId]);
184821
- const submitAskAnswer = import_react45.useCallback((answer) => {
186625
+ const submitAskAnswer = import_react46.useCallback((answer) => {
184822
186626
  setAskUserState((prev) => {
184823
186627
  if (!prev)
184824
186628
  return prev;
@@ -184839,24 +186643,24 @@ function App2({ cwd: cwd2, version: version3 }) {
184839
186643
  return nextState;
184840
186644
  });
184841
186645
  }, []);
184842
- const turnIdRef = import_react45.useRef(0);
184843
- const initStateRef = import_react45.useRef("idle");
184844
- const isMountedRef = import_react45.useRef(true);
184845
- const handlersRegisteredRef = import_react45.useRef(false);
184846
- import_react45.useEffect(() => {
186646
+ const turnIdRef = import_react46.useRef(0);
186647
+ const initStateRef = import_react46.useRef("idle");
186648
+ const isMountedRef = import_react46.useRef(true);
186649
+ const handlersRegisteredRef = import_react46.useRef(false);
186650
+ import_react46.useEffect(() => {
184847
186651
  isProcessingRef.current = isProcessing;
184848
186652
  }, [isProcessing]);
184849
- import_react45.useEffect(() => {
186653
+ import_react46.useEffect(() => {
184850
186654
  processingStartTimeRef.current = processingStartTime;
184851
186655
  }, [processingStartTime]);
184852
- import_react45.useEffect(() => {
186656
+ import_react46.useEffect(() => {
184853
186657
  if (isProcessing && !processingStartTime) {
184854
186658
  const now2 = Date.now();
184855
186659
  setProcessingStartTime(now2);
184856
186660
  processingStartTimeRef.current = now2;
184857
186661
  }
184858
186662
  }, [isProcessing, processingStartTime]);
184859
- const buildFullResponse = import_react45.useCallback(() => {
186663
+ const buildFullResponse = import_react46.useCallback(() => {
184860
186664
  const parts = activityLogRef.current.filter((entry) => entry.type === "text" && entry.content).map((entry) => entry.content);
184861
186665
  if (responseRef.current.trim()) {
184862
186666
  parts.push(responseRef.current);
@@ -184864,7 +186668,7 @@ function App2({ cwd: cwd2, version: version3 }) {
184864
186668
  return parts.join(`
184865
186669
  `).trim();
184866
186670
  }, []);
184867
- const loadSessionMetadata = import_react45.useCallback(async (session) => {
186671
+ const loadSessionMetadata = import_react46.useCallback(async (session) => {
184868
186672
  try {
184869
186673
  const [loadedSkills, loadedCommands] = await Promise.all([
184870
186674
  session.client.getSkills(),
@@ -184883,7 +186687,7 @@ function App2({ cwd: cwd2, version: version3 }) {
184883
186687
  setError(err instanceof Error ? err.message : String(err));
184884
186688
  }
184885
186689
  }, []);
184886
- const finalizeResponse2 = import_react45.useCallback((status) => {
186690
+ const finalizeResponse2 = import_react46.useCallback((status) => {
184887
186691
  const baseContent = buildFullResponse();
184888
186692
  const hasContent = baseContent.length > 0;
184889
186693
  const activityToolCalls = activityLogRef.current.filter((entry) => entry.type === "tool_call" && entry.toolCall).map((entry) => entry.toolCall);
@@ -184939,7 +186743,7 @@ function App2({ cwd: cwd2, version: version3 }) {
184939
186743
  ]);
184940
186744
  return true;
184941
186745
  }, [buildFullResponse]);
184942
- const resetTurnState = import_react45.useCallback(() => {
186746
+ const resetTurnState = import_react46.useCallback(() => {
184943
186747
  setCurrentResponse("");
184944
186748
  responseRef.current = "";
184945
186749
  toolCallsRef.current = [];
@@ -184950,7 +186754,7 @@ function App2({ cwd: cwd2, version: version3 }) {
184950
186754
  setProcessingStartTime(undefined);
184951
186755
  setCurrentTurnTokens(0);
184952
186756
  }, []);
184953
- const saveCurrentSessionState = import_react45.useCallback(() => {
186757
+ const saveCurrentSessionState = import_react46.useCallback(() => {
184954
186758
  if (activeSessionId) {
184955
186759
  sessionUIStates.current.set(activeSessionId, {
184956
186760
  messages: messages2,
@@ -184970,7 +186774,7 @@ function App2({ cwd: cwd2, version: version3 }) {
184970
186774
  });
184971
186775
  }
184972
186776
  }, [activeSessionId, messages2, tokenUsage, energyState, voiceState, heartbeatState, identityInfo, processingStartTime, currentTurnTokens, error2, lastWorkedFor]);
184973
- const loadSessionState = import_react45.useCallback((sessionId) => {
186777
+ const loadSessionState = import_react46.useCallback((sessionId) => {
184974
186778
  const state = sessionUIStates.current.get(sessionId);
184975
186779
  const askState = askUserStateRef.current.get(sessionId) || null;
184976
186780
  if (state) {
@@ -185013,7 +186817,7 @@ function App2({ cwd: cwd2, version: version3 }) {
185013
186817
  setAskUserState(askState);
185014
186818
  }
185015
186819
  }, []);
185016
- const handleChunk = import_react45.useCallback((chunk) => {
186820
+ const handleChunk = import_react46.useCallback((chunk) => {
185017
186821
  const isStartChunk = chunk.type === "text" || chunk.type === "tool_use";
185018
186822
  const isTerminalChunk = chunk.type === "error" || chunk.type === "done";
185019
186823
  if (!isProcessingRef.current && (isStartChunk || isTerminalChunk)) {
@@ -185158,6 +186962,11 @@ function App2({ cwd: cwd2, version: version3 }) {
185158
186962
  setShowTasksPanel(true);
185159
186963
  });
185160
186964
  });
186965
+ } else if (chunk.panel === "schedules") {
186966
+ listSchedules(cwd2).then((schedules) => {
186967
+ setSchedulesList(schedules);
186968
+ setShowSchedulesPanel(true);
186969
+ });
185161
186970
  } else if (chunk.panel === "assistants") {
185162
186971
  setShowAssistantsPanel(true);
185163
186972
  } else if (chunk.panel === "hooks") {
@@ -185227,7 +187036,7 @@ function App2({ cwd: cwd2, version: version3 }) {
185227
187036
  }
185228
187037
  }
185229
187038
  }, [registry3, exit, finalizeResponse2, resetTurnState, cwd2, activeSessionId]);
185230
- const loadConfigFiles = import_react45.useCallback(async () => {
187039
+ const loadConfigFiles = import_react46.useCallback(async () => {
185231
187040
  try {
185232
187041
  const config = await loadConfig(cwd2);
185233
187042
  setCurrentConfig(config);
@@ -185260,7 +187069,7 @@ function App2({ cwd: cwd2, version: version3 }) {
185260
187069
  console.error("Failed to load config:", err);
185261
187070
  }
185262
187071
  }, [cwd2]);
185263
- const createSessionFromRecovery = import_react45.useCallback(async (recoverSession) => {
187072
+ const createSessionFromRecovery = import_react46.useCallback(async (recoverSession) => {
185264
187073
  if (!handlersRegisteredRef.current) {
185265
187074
  handlersRegisteredRef.current = true;
185266
187075
  registry3.onChunk(handleChunk);
@@ -185313,7 +187122,7 @@ function App2({ cwd: cwd2, version: version3 }) {
185313
187122
  initStateRef.current = "done";
185314
187123
  setIsInitializing(false);
185315
187124
  }, [cwd2, registry3, handleChunk, finalizeResponse2, resetTurnState, loadSessionMetadata, beginAskUser]);
185316
- const handleRecover = import_react45.useCallback((session) => {
187125
+ const handleRecover = import_react46.useCallback((session) => {
185317
187126
  setShowRecoveryPanel(false);
185318
187127
  for (const s6 of recoverableSessions) {
185319
187128
  if (s6.sessionId !== session.sessionId) {
@@ -185325,7 +187134,7 @@ function App2({ cwd: cwd2, version: version3 }) {
185325
187134
  setIsInitializing(false);
185326
187135
  });
185327
187136
  }, [recoverableSessions, createSessionFromRecovery]);
185328
- const handleStartFresh = import_react45.useCallback(() => {
187137
+ const handleStartFresh = import_react46.useCallback(() => {
185329
187138
  for (const session of recoverableSessions) {
185330
187139
  clearRecoveryState(session.sessionId);
185331
187140
  }
@@ -185336,7 +187145,7 @@ function App2({ cwd: cwd2, version: version3 }) {
185336
187145
  setIsInitializing(false);
185337
187146
  });
185338
187147
  }, [recoverableSessions, createSessionFromRecovery]);
185339
- import_react45.useEffect(() => {
187148
+ import_react46.useEffect(() => {
185340
187149
  if (initStateRef.current === "done")
185341
187150
  return;
185342
187151
  if (initStateRef.current === "pending")
@@ -185368,14 +187177,14 @@ function App2({ cwd: cwd2, version: version3 }) {
185368
187177
  cancelled = true;
185369
187178
  };
185370
187179
  }, [cwd2, registry3, showRecoveryPanel, recoverableSessions, createSessionFromRecovery]);
185371
- import_react45.useEffect(() => {
187180
+ import_react46.useEffect(() => {
185372
187181
  isMountedRef.current = true;
185373
187182
  return () => {
185374
187183
  isMountedRef.current = false;
185375
187184
  registry3.closeAll();
185376
187185
  };
185377
187186
  }, [registry3]);
185378
- const processQueue = import_react45.useCallback(async () => {
187187
+ const processQueue = import_react46.useCallback(async () => {
185379
187188
  const activeSession2 = registryRef.current.getActiveSession();
185380
187189
  if (!activeSession2 || !activeSessionId)
185381
187190
  return;
@@ -185435,7 +187244,7 @@ function App2({ cwd: cwd2, version: version3 }) {
185435
187244
  }, [activeSessionId, clearPendingSend]);
185436
187245
  const activeQueue = activeSessionId ? messageQueue.filter((msg) => msg.sessionId === activeSessionId) : [];
185437
187246
  const activeInline = activeSessionId ? inlinePending.filter((msg) => msg.sessionId === activeSessionId) : [];
185438
- const queuedMessageIds = import_react45.useMemo(() => new Set(activeQueue.filter((msg) => msg.mode === "queued").map((msg) => msg.id)), [activeQueue]);
187247
+ const queuedMessageIds = import_react46.useMemo(() => new Set(activeQueue.filter((msg) => msg.mode === "queued").map((msg) => msg.id)), [activeQueue]);
185439
187248
  const sessions = registry3.listSessions();
185440
187249
  const activeSession = registry3.getActiveSession();
185441
187250
  const sessionIndex = activeSessionId ? registry3.getSessionIndex(activeSessionId) : 0;
@@ -185445,7 +187254,7 @@ function App2({ cwd: cwd2, version: version3 }) {
185445
187254
  const inlineCount = activeInline.length;
185446
187255
  const activeAskQuestion = askUserState && askUserState.sessionId === activeSessionId ? askUserState.request.questions[askUserState.index] : undefined;
185447
187256
  const askPlaceholder = activeAskQuestion?.placeholder || activeAskQuestion?.question || "Answer the question...";
185448
- const hasPendingTools = import_react45.useMemo(() => {
187257
+ const hasPendingTools = import_react46.useMemo(() => {
185449
187258
  const toolResultIds = new Set;
185450
187259
  for (const entry of activityLog) {
185451
187260
  if (entry.type === "tool_result" && entry.toolResult) {
@@ -185465,10 +187274,10 @@ function App2({ cwd: cwd2, version: version3 }) {
185465
187274
  const showWelcome = messages2.length === 0 && !isProcessing;
185466
187275
  const renderWidth = columns ? Math.max(1, columns - 2) : undefined;
185467
187276
  const wrapChars = renderWidth ?? MESSAGE_WRAP_CHARS;
185468
- const displayMessages = import_react45.useMemo(() => buildDisplayMessages(messages2, MESSAGE_CHUNK_LINES, wrapChars, { maxWidth: renderWidth }), [messages2, wrapChars, renderWidth]);
187277
+ const displayMessages = import_react46.useMemo(() => buildDisplayMessages(messages2, MESSAGE_CHUNK_LINES, wrapChars, { maxWidth: renderWidth }), [messages2, wrapChars, renderWidth]);
185469
187278
  const reservedLines = 12;
185470
187279
  const dynamicBudget = Math.max(6, rows - reservedLines);
185471
- const streamingTrim = import_react45.useMemo(() => {
187280
+ const streamingTrim = import_react46.useMemo(() => {
185472
187281
  if (!isProcessing || !currentResponse.trim()) {
185473
187282
  return { messages: [], trimmed: false };
185474
187283
  }
@@ -185483,17 +187292,17 @@ function App2({ cwd: cwd2, version: version3 }) {
185483
187292
  }, [currentResponse, isProcessing, wrapChars, renderWidth, dynamicBudget]);
185484
187293
  const streamingMessages = streamingTrim.messages;
185485
187294
  const streamingTrimmed = streamingTrim.trimmed;
185486
- const streamingLineCount = import_react45.useMemo(() => estimateDisplayMessagesLines(streamingMessages, renderWidth), [streamingMessages, renderWidth]);
185487
- const activityTrim = import_react45.useMemo(() => {
187295
+ const streamingLineCount = import_react46.useMemo(() => estimateDisplayMessagesLines(streamingMessages, renderWidth), [streamingMessages, renderWidth]);
187296
+ const activityTrim = import_react46.useMemo(() => {
185488
187297
  const activityBudget = Math.max(4, dynamicBudget - streamingLineCount);
185489
187298
  return trimActivityLogByLines(activityLog, wrapChars, renderWidth, activityBudget);
185490
187299
  }, [activityLog, wrapChars, renderWidth, dynamicBudget, streamingLineCount]);
185491
- import_react45.useEffect(() => {
187300
+ import_react46.useEffect(() => {
185492
187301
  if (!isBusy && activeQueue.length > 0 && activeInline.length === 0) {
185493
187302
  processQueue();
185494
187303
  }
185495
187304
  }, [isBusy, activeQueue.length, activeInline.length, processQueue, queueFlushTrigger]);
185496
- const handleSessionSwitch = import_react45.useCallback(async (sessionId) => {
187305
+ const handleSessionSwitch = import_react46.useCallback(async (sessionId) => {
185497
187306
  setShowSessionSelector(false);
185498
187307
  if (sessionId === activeSessionId) {
185499
187308
  return;
@@ -185513,7 +187322,7 @@ function App2({ cwd: cwd2, version: version3 }) {
185513
187322
  await registry3.switchSession(sessionId);
185514
187323
  setActiveSessionId(sessionId);
185515
187324
  }, [activeSessionId, registry3, saveCurrentSessionState, loadSessionState]);
185516
- const handleNewSession = import_react45.useCallback(async () => {
187325
+ const handleNewSession = import_react46.useCallback(async () => {
185517
187326
  setShowSessionSelector(false);
185518
187327
  try {
185519
187328
  saveCurrentSessionState();
@@ -185598,7 +187407,7 @@ function App2({ cwd: cwd2, version: version3 }) {
185598
187407
  }
185599
187408
  }
185600
187409
  }, { isActive: !showSessionSelector });
185601
- const handleSubmit = import_react45.useCallback(async (input, mode = "normal") => {
187410
+ const handleSubmit = import_react46.useCallback(async (input, mode = "normal") => {
185602
187411
  if (activeSessionId && askUserStateRef.current.has(activeSessionId)) {
185603
187412
  submitAskAnswer(input.trim());
185604
187413
  return;
@@ -185791,19 +187600,19 @@ function App2({ cwd: cwd2, version: version3 }) {
185791
187600
  clearPendingSend
185792
187601
  ]);
185793
187602
  if (isInitializing && !showRecoveryPanel) {
185794
- return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
187603
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
185795
187604
  flexDirection: "column",
185796
187605
  padding: 1,
185797
- children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Spinner2, {
187606
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Spinner2, {
185798
187607
  label: "Initializing..."
185799
187608
  }, undefined, false, undefined, this)
185800
187609
  }, undefined, false, undefined, this);
185801
187610
  }
185802
187611
  if (showRecoveryPanel && recoverableSessions.length > 0) {
185803
- return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
187612
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
185804
187613
  flexDirection: "column",
185805
187614
  padding: 1,
185806
- children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(RecoveryPanel, {
187615
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(RecoveryPanel, {
185807
187616
  sessions: recoverableSessions,
185808
187617
  onRecover: handleRecover,
185809
187618
  onStartFresh: handleStartFresh
@@ -185811,10 +187620,10 @@ function App2({ cwd: cwd2, version: version3 }) {
185811
187620
  }, undefined, false, undefined, this);
185812
187621
  }
185813
187622
  if (showSessionSelector) {
185814
- return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
187623
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
185815
187624
  flexDirection: "column",
185816
187625
  padding: 1,
185817
- children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(SessionSelector, {
187626
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(SessionSelector, {
185818
187627
  sessions,
185819
187628
  activeSessionId,
185820
187629
  onSelect: handleSessionSwitch,
@@ -185836,10 +187645,10 @@ function App2({ cwd: cwd2, version: version3 }) {
185836
187645
  }
185837
187646
  return connectorBridgeRef.current.getCommandHelp(connector, command);
185838
187647
  };
185839
- return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
187648
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
185840
187649
  flexDirection: "column",
185841
187650
  padding: 1,
185842
- children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(ConnectorsPanel, {
187651
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(ConnectorsPanel, {
185843
187652
  connectors,
185844
187653
  initialConnector: connectorsPanelInitial,
185845
187654
  onCheckAuth: handleCheckAuth,
@@ -185888,10 +187697,10 @@ When done, report the result.`);
185888
187697
  await updateTask(cwd2, id, { priority });
185889
187698
  setTasksList(await getTasks(cwd2));
185890
187699
  };
185891
- return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
187700
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
185892
187701
  flexDirection: "column",
185893
187702
  padding: 1,
185894
- children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(TasksPanel, {
187703
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(TasksPanel, {
185895
187704
  tasks: tasksList,
185896
187705
  paused: tasksPaused,
185897
187706
  onAdd: handleTasksAdd,
@@ -185905,6 +187714,54 @@ When done, report the result.`);
185905
187714
  }, undefined, false, undefined, this)
185906
187715
  }, undefined, false, undefined, this);
185907
187716
  }
187717
+ if (showSchedulesPanel) {
187718
+ const handleSchedulePause = async (id) => {
187719
+ await updateSchedule(cwd2, id, (schedule) => ({
187720
+ ...schedule,
187721
+ status: "paused",
187722
+ updatedAt: Date.now()
187723
+ }));
187724
+ setSchedulesList(await listSchedules(cwd2));
187725
+ };
187726
+ const handleScheduleResume = async (id) => {
187727
+ await updateSchedule(cwd2, id, (schedule) => {
187728
+ const nextRun = computeNextRun(schedule, Date.now());
187729
+ return {
187730
+ ...schedule,
187731
+ status: "active",
187732
+ updatedAt: Date.now(),
187733
+ nextRunAt: nextRun
187734
+ };
187735
+ });
187736
+ setSchedulesList(await listSchedules(cwd2));
187737
+ };
187738
+ const handleScheduleDelete = async (id) => {
187739
+ await deleteSchedule(cwd2, id);
187740
+ setSchedulesList(await listSchedules(cwd2));
187741
+ };
187742
+ const handleScheduleRun = async (id) => {
187743
+ const schedule = schedulesList.find((s6) => s6.id === id);
187744
+ if (schedule && activeSession) {
187745
+ await activeSession.client.send(schedule.command);
187746
+ }
187747
+ };
187748
+ const handleScheduleRefresh = async () => {
187749
+ setSchedulesList(await listSchedules(cwd2));
187750
+ };
187751
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
187752
+ flexDirection: "column",
187753
+ padding: 1,
187754
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(SchedulesPanel, {
187755
+ schedules: schedulesList,
187756
+ onPause: handleSchedulePause,
187757
+ onResume: handleScheduleResume,
187758
+ onDelete: handleScheduleDelete,
187759
+ onRun: handleScheduleRun,
187760
+ onRefresh: handleScheduleRefresh,
187761
+ onClose: () => setShowSchedulesPanel(false)
187762
+ }, undefined, false, undefined, this)
187763
+ }, undefined, false, undefined, this);
187764
+ }
185908
187765
  if (showAssistantsPanel) {
185909
187766
  const assistantManager = activeSession?.client.getAssistantManager?.();
185910
187767
  const assistantsList = assistantManager?.listAssistants() ?? [];
@@ -185965,10 +187822,10 @@ When done, report the result.`);
185965
187822
  throw err;
185966
187823
  }
185967
187824
  };
185968
- return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
187825
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
185969
187826
  flexDirection: "column",
185970
187827
  padding: 1,
185971
- children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(AssistantsPanel, {
187828
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(AssistantsPanel, {
185972
187829
  assistants: assistantsList,
185973
187830
  activeAssistantId,
185974
187831
  onSelect: handleAssistantSelect,
@@ -186013,10 +187870,10 @@ When done, report the result.`);
186013
187870
  nativeHookRegistry.setEnabled(hookId, enabled);
186014
187871
  };
186015
187872
  const nativeHooks = nativeHookRegistry.listFlat();
186016
- return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
187873
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
186017
187874
  flexDirection: "column",
186018
187875
  padding: 1,
186019
- children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(HooksPanel, {
187876
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(HooksPanel, {
186020
187877
  hooks: hooksConfig,
186021
187878
  nativeHooks,
186022
187879
  onToggle: handleHookToggle,
@@ -186060,10 +187917,10 @@ When done, report the result.`);
186060
187917
  setGuardrailsConfig(config);
186061
187918
  setGuardrailsPolicies(policies);
186062
187919
  };
186063
- return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
187920
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
186064
187921
  flexDirection: "column",
186065
187922
  padding: 1,
186066
- children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(GuardrailsPanel, {
187923
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(GuardrailsPanel, {
186067
187924
  config: guardrailsConfig,
186068
187925
  policies: guardrailsPolicies,
186069
187926
  onToggleEnabled: handleToggleEnabled,
@@ -186112,10 +187969,10 @@ When done, report the result.`);
186112
187969
  setSessionBudgetStatus(sessionStatus);
186113
187970
  setSwarmBudgetStatus(swarmStatus);
186114
187971
  };
186115
- return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
187972
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
186116
187973
  flexDirection: "column",
186117
187974
  padding: 1,
186118
- children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(BudgetPanel, {
187975
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(BudgetPanel, {
186119
187976
  config: budgetConfig,
186120
187977
  sessionStatus: sessionBudgetStatus,
186121
187978
  swarmStatus: swarmBudgetStatus,
@@ -186134,10 +187991,10 @@ When done, report the result.`);
186134
187991
  setAgentsList(agents);
186135
187992
  setRegistryStats(stats);
186136
187993
  };
186137
- return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
187994
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
186138
187995
  flexDirection: "column",
186139
187996
  padding: 1,
186140
- children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(AgentsPanel, {
187997
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(AgentsPanel, {
186141
187998
  agents: agentsList,
186142
187999
  stats: registryStats,
186143
188000
  onRefresh: handleAgentsRefresh,
@@ -186170,10 +188027,10 @@ When done, report the result.`);
186170
188027
  await writeFile13(configPath, JSON.stringify(newConfig, null, 2));
186171
188028
  await loadConfigFiles();
186172
188029
  };
186173
- return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
188030
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
186174
188031
  flexDirection: "column",
186175
188032
  padding: 1,
186176
- children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(ConfigPanel, {
188033
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(ConfigPanel, {
186177
188034
  config: currentConfig,
186178
188035
  userConfig,
186179
188036
  projectConfig,
@@ -186258,37 +188115,37 @@ ${msg.body || msg.preview}`);
186258
188115
  });
186259
188116
  };
186260
188117
  if (!messagesManager) {
186261
- return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
188118
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
186262
188119
  flexDirection: "column",
186263
188120
  padding: 1,
186264
188121
  children: [
186265
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
188122
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
186266
188123
  marginBottom: 1,
186267
- children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
188124
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
186268
188125
  bold: true,
186269
188126
  color: "cyan",
186270
188127
  children: "Messages"
186271
188128
  }, undefined, false, undefined, this)
186272
188129
  }, undefined, false, undefined, this),
186273
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
188130
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
186274
188131
  flexDirection: "column",
186275
188132
  borderStyle: "round",
186276
188133
  borderColor: "gray",
186277
188134
  paddingX: 1,
186278
188135
  paddingY: 1,
186279
188136
  children: [
186280
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
188137
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
186281
188138
  children: "Messages are not enabled."
186282
188139
  }, undefined, false, undefined, this),
186283
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
188140
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
186284
188141
  dimColor: true,
186285
188142
  children: "Configure messages in config.json to enable."
186286
188143
  }, undefined, false, undefined, this)
186287
188144
  ]
186288
188145
  }, undefined, true, undefined, this),
186289
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
188146
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
186290
188147
  marginTop: 1,
186291
- children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
188148
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
186292
188149
  dimColor: true,
186293
188150
  children: "q quit"
186294
188151
  }, undefined, false, undefined, this)
@@ -186296,10 +188153,10 @@ ${msg.body || msg.preview}`);
186296
188153
  ]
186297
188154
  }, undefined, true, undefined, this);
186298
188155
  }
186299
- return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
188156
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
186300
188157
  flexDirection: "column",
186301
188158
  padding: 1,
186302
- children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(MessagesPanel, {
188159
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(MessagesPanel, {
186303
188160
  messages: messagesList,
186304
188161
  onRead: handleMessagesRead,
186305
188162
  onDelete: handleMessagesDelete,
@@ -186315,18 +188172,18 @@ ${msg.body || msg.preview}`);
186315
188172
  return { toolCall: e6.toolCall, result };
186316
188173
  });
186317
188174
  const isThinking = isProcessing && !currentResponse && !currentToolCall && toolCallEntries.length === 0;
186318
- return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
188175
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
186319
188176
  flexDirection: "column",
186320
188177
  padding: 1,
186321
188178
  children: [
186322
- showWelcome && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(WelcomeBanner, {
188179
+ showWelcome && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(WelcomeBanner, {
186323
188180
  version: version3 ?? "unknown",
186324
188181
  model: activeSession?.client.getModel() ?? "unknown",
186325
188182
  directory: activeSession?.cwd || cwd2
186326
188183
  }, undefined, false, undefined, this),
186327
- backgroundProcessingCount > 0 && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
188184
+ backgroundProcessingCount > 0 && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
186328
188185
  marginBottom: 1,
186329
- children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
188186
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
186330
188187
  color: "yellow",
186331
188188
  children: [
186332
188189
  backgroundProcessingCount,
@@ -186336,9 +188193,9 @@ ${msg.body || msg.preview}`);
186336
188193
  ]
186337
188194
  }, undefined, true, undefined, this)
186338
188195
  }, undefined, false, undefined, this),
186339
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Static, {
188196
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Static, {
186340
188197
  items: displayMessages,
186341
- children: (message) => /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Messages5, {
188198
+ children: (message) => /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Messages5, {
186342
188199
  messages: [message],
186343
188200
  currentResponse: undefined,
186344
188201
  streamingMessages: [],
@@ -186349,23 +188206,23 @@ ${msg.body || msg.preview}`);
186349
188206
  verboseTools
186350
188207
  }, message.id, false, undefined, this)
186351
188208
  }, undefined, false, undefined, this),
186352
- isProcessing && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(jsx_dev_runtime23.Fragment, {
188209
+ isProcessing && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(jsx_dev_runtime24.Fragment, {
186353
188210
  children: [
186354
- streamingTrimmed && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
188211
+ streamingTrimmed && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
186355
188212
  marginBottom: 1,
186356
- children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
188213
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
186357
188214
  dimColor: true,
186358
188215
  children: "\u22EF showing latest output"
186359
188216
  }, undefined, false, undefined, this)
186360
188217
  }, undefined, false, undefined, this),
186361
- activityTrim.trimmed && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
188218
+ activityTrim.trimmed && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
186362
188219
  marginBottom: 1,
186363
- children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
188220
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
186364
188221
  dimColor: true,
186365
188222
  children: "\u22EF showing latest activity"
186366
188223
  }, undefined, false, undefined, this)
186367
188224
  }, undefined, false, undefined, this),
186368
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Messages5, {
188225
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Messages5, {
186369
188226
  messages: [],
186370
188227
  currentResponse: undefined,
186371
188228
  streamingMessages,
@@ -186377,31 +188234,31 @@ ${msg.body || msg.preview}`);
186377
188234
  }, "streaming", false, undefined, this)
186378
188235
  ]
186379
188236
  }, undefined, true, undefined, this),
186380
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(QueueIndicator, {
188237
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(QueueIndicator, {
186381
188238
  messages: [...activeInline, ...activeQueue],
186382
188239
  maxPreview: MAX_QUEUED_PREVIEW
186383
188240
  }, undefined, false, undefined, this),
186384
- askUserState && activeAskQuestion && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(AskUserPanel, {
188241
+ askUserState && activeAskQuestion && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(AskUserPanel, {
186385
188242
  sessionId: askUserState.sessionId,
186386
188243
  request: askUserState.request,
186387
188244
  question: activeAskQuestion,
186388
188245
  index: askUserState.index,
186389
188246
  total: askUserState.request.questions.length
186390
188247
  }, undefined, false, undefined, this),
186391
- error2 && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(ErrorBanner, {
188248
+ error2 && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(ErrorBanner, {
186392
188249
  error: error2,
186393
188250
  showErrorCodes: SHOW_ERROR_CODES
186394
188251
  }, undefined, false, undefined, this),
186395
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(ProcessingIndicator, {
188252
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(ProcessingIndicator, {
186396
188253
  isProcessing,
186397
188254
  startTime: processingStartTime,
186398
188255
  tokenCount: currentTurnTokens,
186399
188256
  isThinking
186400
188257
  }, undefined, false, undefined, this),
186401
- !isProcessing && lastWorkedFor && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
188258
+ !isProcessing && lastWorkedFor && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
186402
188259
  marginBottom: 0,
186403
188260
  marginLeft: 2,
186404
- children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
188261
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
186405
188262
  color: "gray",
186406
188263
  children: [
186407
188264
  "\u273B Worked for ",
@@ -186409,15 +188266,15 @@ ${msg.body || msg.preview}`);
186409
188266
  ]
186410
188267
  }, undefined, true, undefined, this)
186411
188268
  }, undefined, false, undefined, this),
186412
- showExitHint && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
188269
+ showExitHint && /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
186413
188270
  marginLeft: 2,
186414
188271
  marginBottom: 0,
186415
- children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text3, {
188272
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text3, {
186416
188273
  color: "yellow",
186417
188274
  children: "(Press Ctrl+C again to exit)"
186418
188275
  }, undefined, false, undefined, this)
186419
188276
  }, undefined, false, undefined, this),
186420
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Input, {
188277
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Input, {
186421
188278
  onSubmit: handleSubmit,
186422
188279
  isProcessing: isBusy,
186423
188280
  queueLength: activeQueue.length + inlineCount,
@@ -186427,7 +188284,7 @@ ${msg.body || msg.preview}`);
186427
188284
  askPlaceholder,
186428
188285
  allowBlankAnswer: activeAskQuestion?.required === false
186429
188286
  }, undefined, false, undefined, this),
186430
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Status, {
188287
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Status, {
186431
188288
  isProcessing: isBusy,
186432
188289
  cwd: activeSession?.cwd || cwd2,
186433
188290
  queueLength: activeQueue.length + inlineCount,
@@ -186868,9 +188725,9 @@ Interactive Mode:
186868
188725
  }
186869
188726
 
186870
188727
  // packages/terminal/src/index.tsx
186871
- var jsx_dev_runtime24 = __toESM(require_jsx_dev_runtime(), 1);
188728
+ var jsx_dev_runtime25 = __toESM(require_jsx_dev_runtime(), 1);
186872
188729
  setRuntime(bunRuntime);
186873
- var VERSION4 = "0.6.61";
188730
+ var VERSION4 = "0.6.62";
186874
188731
  var SYNC_START = "\x1B[?2026h";
186875
188732
  var SYNC_END = "\x1B[?2026l";
186876
188733
  function enableSynchronizedOutput() {
@@ -186993,7 +188850,7 @@ if (options.print !== null) {
186993
188850
  } else {
186994
188851
  const useSyncOutput = process.env.ASSISTANTS_NO_SYNC !== "1";
186995
188852
  const disableSyncOutput = useSyncOutput ? enableSynchronizedOutput() : () => {};
186996
- const { waitUntilExit } = render_default(/* @__PURE__ */ jsx_dev_runtime24.jsxDEV(App2, {
188853
+ const { waitUntilExit } = render_default(/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(App2, {
186997
188854
  cwd: options.cwd,
186998
188855
  version: VERSION4
186999
188856
  }, undefined, false, undefined, this), {
@@ -187010,4 +188867,4 @@ export {
187010
188867
  main
187011
188868
  };
187012
188869
 
187013
- //# debugId=BCC7A4D6FC1A376064756E2164756E21
188870
+ //# debugId=A9B10BFA70C2B51164756E2164756E21