@runfusion/fusion 0.43.0 → 0.43.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/bin.js +167 -27
  2. package/dist/client/.vite/manifest.json +70 -70
  3. package/dist/client/assets/AgentDetailView-BGN03dyz.css +1 -0
  4. package/dist/client/assets/{AgentDetailView-FUKwQxBP.js → AgentDetailView-DKMz3r04.js} +1 -1
  5. package/dist/client/assets/{AgentPermissionPolicyEditor-DMDUhF1n.js → AgentPermissionPolicyEditor-BiY1a4KR.js} +1 -1
  6. package/dist/client/assets/{AgentsView-BrQLd-yI.js → AgentsView-Co-k4vjh.js} +3 -3
  7. package/dist/client/assets/{ChatView-Wz_0goif.js → ChatView-BkAG99bj.js} +1 -1
  8. package/dist/client/assets/{DevServerView-DRqQpHsc.js → DevServerView-C6DC0URX.js} +1 -1
  9. package/dist/client/assets/{DirectoryPicker-BFot4CVM.js → DirectoryPicker-CkcGjyv0.js} +1 -1
  10. package/dist/client/assets/{DocumentsView-hamhUcvL.js → DocumentsView-OCK1Vsw_.js} +1 -1
  11. package/dist/client/assets/{EvalsView-DAXqDqn2.js → EvalsView-CUfyj5GW.js} +1 -1
  12. package/dist/client/assets/{ExperimentalAgentOnboardingModal-B4aZ1y0n.js → ExperimentalAgentOnboardingModal-Dau9RTU_.js} +1 -1
  13. package/dist/client/assets/{GoalsView-2QOp9DA0.js → GoalsView-CNLTn0rX.js} +1 -1
  14. package/dist/client/assets/{InsightsView-D5fzFy-F.js → InsightsView-BQPxHxKI.js} +1 -1
  15. package/dist/client/assets/{MemoryView-B082KoR-.js → MemoryView-D3xQIFjj.js} +1 -1
  16. package/dist/client/assets/{NodesView-BA3pKMZu.js → NodesView-CSMvGwDU.js} +1 -1
  17. package/dist/client/assets/{PiExtensionsManager-C4I11iKm.js → PiExtensionsManager-BtqXF3fl.js} +1 -1
  18. package/dist/client/assets/{PluginManager-BzTzTMXZ.js → PluginManager-CSSDb3VO.js} +1 -1
  19. package/dist/client/assets/{PullRequestView-11xJ565q.js → PullRequestView-Bjyfffdu.js} +1 -1
  20. package/dist/client/assets/{ReliabilityView-CpELpGqw.js → ReliabilityView-QKMUDebT.js} +1 -1
  21. package/dist/client/assets/{ResearchView-BHiXfjzE.js → ResearchView-CRU_NPho.js} +1 -1
  22. package/dist/client/assets/{SecretsView-CC5OYoCn.js → SecretsView-Bs8ySyC5.js} +1 -1
  23. package/dist/client/assets/SecretsView-Djo1rahi.css +1 -0
  24. package/dist/client/assets/{SessionTerminal-G70Jwkzs.js → SessionTerminal-Dk1NgmN2.js} +1 -1
  25. package/dist/client/assets/{SettingsModal-C0M1CqOu.js → SettingsModal-JCaNvdAb.js} +3 -3
  26. package/dist/client/assets/{SettingsModal-BKEbtdqR.js → SettingsModal-Nw5cTKAK.js} +1 -1
  27. package/dist/client/assets/{SetupWizardModal-CBfItlP6.js → SetupWizardModal-CE79myEy.js} +1 -1
  28. package/dist/client/assets/{SkillsView-DbcW87-E.js → SkillsView-Dc8YskAX.js} +1 -1
  29. package/dist/client/assets/{StashRecoveryView-CH9RPtzX.js → StashRecoveryView-CqKOFiXT.js} +1 -1
  30. package/dist/client/assets/{TodoView-ToviJ0SV.js → TodoView-BqIRwcZw.js} +1 -1
  31. package/dist/client/assets/{WorkflowNodeEditor-BTu0D9c5.js → WorkflowNodeEditor-2jDuk2FR.js} +1 -1
  32. package/dist/client/assets/{dashboard-view-DtgLZ_LM.js → dashboard-view-BhbN8LPh.js} +1 -1
  33. package/dist/client/assets/{folder-open-BlPyIWyf.js → folder-open-Bw1mxVfa.js} +1 -1
  34. package/dist/client/assets/{index-bZCpHtGq.js → index-CpTBp1RG.js} +192 -192
  35. package/dist/client/assets/{upload-B-qmm1NH.js → upload-BCmd-1I0.js} +1 -1
  36. package/dist/client/assets/{users-D6C5TXf2.js → users-DO_t3V1p.js} +1 -1
  37. package/dist/client/index.html +1 -1
  38. package/dist/client/version.json +1 -1
  39. package/dist/droid-cli/package.json +1 -1
  40. package/dist/extension.js +166 -27
  41. package/dist/pi-claude-cli/package.json +1 -1
  42. package/dist/plugin-sdk/index.d.ts +2 -0
  43. package/dist/plugins/fusion-plugin-acp-runtime/package.json +1 -1
  44. package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
  45. package/dist/plugins/fusion-plugin-compound-engineering/package.json +1 -1
  46. package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
  47. package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
  48. package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
  49. package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
  50. package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
  51. package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
  52. package/dist/plugins/fusion-plugin-reports/package.json +1 -1
  53. package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
  54. package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
  55. package/package.json +1 -1
  56. package/dist/automation-store-EKXXEE2S.js +0 -10
  57. package/dist/automation-store-PLNG3X72.js +0 -10
  58. package/dist/automation-store-RDDYZFUJ.js +0 -10
  59. package/dist/chunk-2JI3F6MG.js +0 -948
  60. package/dist/chunk-4L6CLWJC.js +0 -8345
  61. package/dist/chunk-4VNS5WPM.js +0 -42
  62. package/dist/chunk-5RGECGQL.js +0 -1139
  63. package/dist/chunk-6JDLN7IL.js +0 -409
  64. package/dist/chunk-AICJATVW.js +0 -948
  65. package/dist/chunk-AWKNRUOR.js +0 -1148
  66. package/dist/chunk-BHM3UYWS.js +0 -4651
  67. package/dist/chunk-BMUXDSBF.js +0 -4647
  68. package/dist/chunk-GETECT6V.js +0 -353
  69. package/dist/chunk-GUV4QQT3.js +0 -1143
  70. package/dist/chunk-JKQO7YYZ.js +0 -8369
  71. package/dist/chunk-LYZVU6UV.js +0 -409
  72. package/dist/chunk-MAN4WYHO.js +0 -353
  73. package/dist/chunk-MCUG2Z7M.js +0 -4651
  74. package/dist/chunk-PSDYB45U.js +0 -948
  75. package/dist/chunk-RR2HM46R.js +0 -8345
  76. package/dist/chunk-RXMQ5OMY.js +0 -9226
  77. package/dist/chunk-S2EVJUY3.js +0 -353
  78. package/dist/chunk-UXR5XZFZ.js +0 -409
  79. package/dist/client/assets/AgentDetailView-DiWELtb1.css +0 -1
  80. package/dist/client/assets/SecretsView-D5bHZ-wM.css +0 -1
  81. package/dist/extract-zip-WL55Z3AU.js +0 -2497
  82. package/dist/index.min-CHQ3ABYJ.js +0 -2926
  83. package/dist/memory-dreams-7USISKVE.js +0 -32
  84. package/dist/memory-dreams-PBPISUDD.js +0 -32
  85. package/dist/memory-dreams-XNO2B2QF.js +0 -32
  86. package/dist/migration-EH2YOCYQ.js +0 -15
  87. package/dist/migration-PLGTTKL5.js +0 -15
  88. package/dist/migration-WZEZK22R.js +0 -15
  89. package/dist/routine-store-GIJ6MXWY.js +0 -10
  90. package/dist/routine-store-HTVC2PUQ.js +0 -10
  91. package/dist/routine-store-KGHZBPDF.js +0 -10
@@ -1,1139 +0,0 @@
1
- // ../core/dist/settings-schema.js
2
- var DEFAULT_GLOBAL_SETTINGS = {
3
- themeMode: "dark",
4
- colorTheme: "default",
5
- dashboardFontScalePct: 100,
6
- language: void 0,
7
- defaultProvider: void 0,
8
- defaultModelId: void 0,
9
- testMode: void 0,
10
- mergeRequestContractShadowEnabled: false,
11
- fallbackProvider: void 0,
12
- fallbackModelId: void 0,
13
- defaultThinkingLevel: void 0,
14
- ntfyEnabled: false,
15
- ntfyTopic: void 0,
16
- ntfyBaseUrl: void 0,
17
- ntfyAccessToken: void 0,
18
- ntfyEvents: [
19
- "in-review",
20
- "merged",
21
- "failed",
22
- "awaiting-approval",
23
- "awaiting-user-review",
24
- "planning-awaiting-input",
25
- "message:agent-to-user",
26
- "message:agent-to-agent",
27
- "message:room",
28
- "gridlock",
29
- "board-stall-unrecovered",
30
- "fallback-used",
31
- "memory-dreams-processed",
32
- "token-budget"
33
- ],
34
- ntfyDashboardHost: void 0,
35
- taskTokenBudget: void 0,
36
- failureNotificationDelayMs: 3e4,
37
- failureNotificationMode: "sticky-only",
38
- webhookEnabled: false,
39
- webhookUrl: void 0,
40
- webhookFormat: "generic",
41
- webhookEvents: [],
42
- notificationProviders: [],
43
- customProviders: [],
44
- defaultProjectId: void 0,
45
- setupComplete: void 0,
46
- cliOnboardingCompletedAt: void 0,
47
- favoriteProviders: void 0,
48
- favoriteModels: void 0,
49
- openrouterModelSync: true,
50
- openrouterAppAttribution: void 0,
51
- openrouterModelFilters: void 0,
52
- openrouterProviderPreferences: void 0,
53
- opencodeGoModelSync: true,
54
- updateCheckEnabled: true,
55
- fnBinaryCheckEnabled: true,
56
- updateCheckFrequency: "daily",
57
- autoReloadOnVersionChange: true,
58
- githubTrackingDefaultRepo: void 0,
59
- modelOnboardingComplete: void 0,
60
- useClaudeCli: void 0,
61
- useDroidCli: void 0,
62
- useLlamaCpp: void 0,
63
- // Global baseline lanes for per-role model selection
64
- executionGlobalProvider: void 0,
65
- executionGlobalModelId: void 0,
66
- planningGlobalProvider: void 0,
67
- planningGlobalModelId: void 0,
68
- validatorGlobalProvider: void 0,
69
- validatorGlobalModelId: void 0,
70
- titleSummarizerGlobalProvider: void 0,
71
- titleSummarizerGlobalModelId: void 0,
72
- // Daemon mode settings
73
- daemonToken: void 0,
74
- daemonPort: 4040,
75
- daemonHost: "127.0.0.1",
76
- // Node settings sync
77
- settingsSyncEnabled: false,
78
- settingsSyncAuth: false,
79
- settingsSyncInterval: 9e5,
80
- settingsSyncConflictResolution: "last-write-wins",
81
- // Dashboard session state (persisted to global settings for PWA/offline restore)
82
- dashboardCurrentNodeId: void 0,
83
- dashboardCurrentProjectIdByNode: void 0,
84
- // Dashboard TUI memory guard
85
- vitestAutoKillEnabled: true,
86
- vitestKillThresholdPct: 90,
87
- // Agent log persistence controls
88
- persistAgentToolOutput: true,
89
- persistAgentThinkingLogPermanent: false,
90
- persistAgentThinkingLogEphemeral: false,
91
- persistAgentThinkingLog: false,
92
- agentMemoryInclusionMode: "full",
93
- secretsAccessPolicy: void 0,
94
- secretsSyncPassphraseConfigured: false,
95
- researchGlobalDefaults: {
96
- searchProvider: void 0,
97
- synthesisProvider: void 0,
98
- synthesisModelId: void 0,
99
- enabledSources: {
100
- webSearch: true,
101
- pageFetch: true,
102
- github: false,
103
- localDocs: true,
104
- llmSynthesis: true
105
- },
106
- maxSourcesPerRun: 20,
107
- defaultExportFormat: "markdown"
108
- },
109
- researchGlobalEnabled: true,
110
- researchGlobalMaxConcurrentRuns: 3,
111
- researchGlobalDefaultTimeout: 3e5,
112
- researchGlobalMaxSourcesPerRun: 20,
113
- researchGlobalMaxSynthesisRounds: 2,
114
- researchGlobalWebSearchProvider: "builtin",
115
- researchGlobalSearxngUrl: void 0,
116
- researchGlobalBraveApiKey: void 0,
117
- researchGlobalGoogleSearchApiKey: void 0,
118
- researchGlobalGoogleSearchCx: void 0,
119
- researchGlobalTavilyApiKey: void 0,
120
- researchGlobalGitHubEnabled: false,
121
- researchGlobalLocalDocsEnabled: true,
122
- researchGlobalMaxSearchResults: 10,
123
- researchGlobalFetchTimeoutMs: 3e4,
124
- researchGlobalUserAgent: "FusionResearchBot/1.0",
125
- remoteAccess: {
126
- activeProvider: null,
127
- providers: {
128
- tailscale: {
129
- enabled: false,
130
- hostname: "",
131
- targetPort: 0,
132
- acceptRoutes: false
133
- },
134
- cloudflare: {
135
- enabled: false,
136
- quickTunnel: true,
137
- tunnelName: "",
138
- tunnelToken: null,
139
- ingressUrl: ""
140
- }
141
- },
142
- tokenStrategy: {
143
- persistent: {
144
- enabled: true,
145
- token: null
146
- },
147
- shortLived: {
148
- enabled: false,
149
- ttlMs: 9e5,
150
- maxTtlMs: 864e5
151
- }
152
- },
153
- lifecycle: {
154
- rememberLastRunning: false,
155
- wasRunningOnShutdown: false,
156
- lastRunningProvider: null
157
- }
158
- },
159
- worktrunk: {
160
- enabled: false,
161
- binaryPath: void 0,
162
- installedBinaryPath: void 0,
163
- onFailure: "fail"
164
- },
165
- owningNodeHandoffPolicy: "reassign-to-local",
166
- experimentalFeatures: {},
167
- cliAgents: {}
168
- };
169
- var DEFAULT_PROJECT_SETTINGS = {
170
- globalPause: false,
171
- globalPauseReason: void 0,
172
- defaultWorkflowId: void 0,
173
- approvedWorkflowCliCommands: void 0,
174
- approvedCliAutonomyAdapters: void 0,
175
- enginePaused: false,
176
- maxConcurrent: 2,
177
- maxTriageConcurrent: 2,
178
- globalMaxConcurrent: 4,
179
- maxWorktrees: 4,
180
- pollIntervalMs: 15e3,
181
- heartbeatMultiplier: 1,
182
- autoClaimCandidatesInPrompt: 5,
183
- tombstoneStickyWindowDays: 7,
184
- heartbeatScopeDiscipline: "strict",
185
- heartbeatPromptTemplate: "default",
186
- groupOverlappingFiles: true,
187
- overlapIgnorePaths: [],
188
- autoMerge: true,
189
- testMode: void 0,
190
- mergeRequestContractShadowEnabled: false,
191
- mergeStrategy: "direct",
192
- directMergeCommitStrategy: "always-squash",
193
- mergeIntegrationWorktree: "reuse-task-worktree",
194
- mergeAdvanceAutoSync: "stash-and-ff",
195
- integrationBranch: void 0,
196
- // `requirePrApproval` MOVED to workflow settings (U4) — see MOVED_SETTINGS_KEYS.
197
- pushAfterMerge: false,
198
- pushRemote: "origin",
199
- unavailableNodePolicy: "block",
200
- owningNodeHandoffPolicy: "reassign-to-local",
201
- defaultNodeId: void 0,
202
- secretsEnv: void 0,
203
- worktreeInitCommand: void 0,
204
- testCommand: void 0,
205
- buildCommand: void 0,
206
- recycleWorktrees: false,
207
- executorAllowSiblingBranchRename: false,
208
- worktreeNaming: "random",
209
- worktrunk: {
210
- enabled: false,
211
- binaryPath: void 0,
212
- installedBinaryPath: void 0,
213
- onFailure: "fail"
214
- },
215
- worktreesDir: void 0,
216
- taskPrefix: "FN",
217
- taskAttributionTrailerNames: ["Fusion-Task-Id"],
218
- commitMsgHookEnabled: true,
219
- includeTaskIdInCommit: true,
220
- commitAuthorEnabled: true,
221
- commitAuthorName: "Fusion",
222
- commitAuthorEmail: "noreply@runfusion.ai",
223
- // Per-phase model lanes (planning/execution/validator) MOVED to workflow
224
- // settings (U4) — see MOVED_SETTINGS_KEYS. The GLOBAL baseline lanes
225
- // (executionGlobalProvider etc.) stay global; project default overrides stay.
226
- // Project-level default override (NOT moved — stays project-scoped)
227
- defaultProviderOverride: void 0,
228
- defaultModelIdOverride: void 0,
229
- modelPresets: [],
230
- autoSelectModelPreset: false,
231
- completionDocumentationMode: "off",
232
- defaultPresetBySize: {},
233
- autoResolveConflicts: true,
234
- smartConflictResolution: true,
235
- mergerAutostashMaxAgeHours: 24,
236
- worktreeRebaseBeforeMerge: true,
237
- worktreeRebaseRemote: "",
238
- worktreeRebaseLocalBase: true,
239
- prerebaseAutoEnabled: true,
240
- prerebaseHotFiles: [
241
- "AGENTS.md",
242
- "packages/core/src/store.ts",
243
- "packages/core/src/db.ts",
244
- "packages/engine/src/executor.ts",
245
- "packages/engine/src/scheduler.ts",
246
- "packages/engine/src/merger.ts",
247
- "packages/dashboard/app/styles.css"
248
- ],
249
- prerebaseDivergenceThreshold: 50,
250
- mergeConflictStrategy: "smart-prefer-main",
251
- merger: { mode: "ai", maxReviewPasses: 3, allowDirtyLocalCheckoutSync: false },
252
- mergeDiffVolumeMinLines: void 0,
253
- mergeDiffVolumeThreshold: void 0,
254
- mergeDiffVolumeAllowlist: void 0,
255
- mergeStrategyOverlapBehavior: "flip-to-prefer-branch",
256
- postMergeAuditMode: "warn",
257
- mergeAuditAutoRecovery: "ai-assisted",
258
- autoRecovery: {
259
- mode: "deterministic-only",
260
- maxRetries: 3
261
- },
262
- reliabilityStatsResetAt: void 0,
263
- // Step-execution knobs (workflowStepTimeoutMs, workflowStepScopeEnforcement,
264
- // planOnlyScopeLeakEnforcement, workflowRevisionForkOnScopeMismatch,
265
- // strictScopeEnforcement, buildRetryCount, verificationFixRetries,
266
- // requirePlanApproval) MOVED to workflow settings (U4) — see
267
- // MOVED_SETTINGS_KEYS. `buildTimeoutMs` is NOT moved (no engine reader) and
268
- // stays a plain project setting:
269
- buildTimeoutMs: 3e5,
270
- ephemeralAgentsEnabled: true,
271
- agentProvisioning: {},
272
- sandboxProvisioning: {},
273
- defaultAgentPermissionPolicy: void 0,
274
- specStalenessEnabled: false,
275
- specStalenessMaxAgeMs: 6 * 60 * 60 * 1e3,
276
- taskStuckTimeoutMs: 6e5,
277
- /** Number of rapid todo↔in-progress cycles allowed before auto-pausing the task. */
278
- dispatchOscillationThreshold: 5,
279
- /** Sliding time window used to count rapid todo↔in-progress cycles. */
280
- dispatchOscillationWindowMs: 6e4,
281
- /** Delay before scheduler may re-dispatch an engine-requeued todo task. */
282
- dispatchOscillationSettleMs: 5e3,
283
- runtimeStopDrainMs: 2e3,
284
- engineActiveSinceMs: void 0,
285
- engineActivationGraceMs: 5 * 6e4,
286
- inReviewStallDeadlockThreshold: 3,
287
- stalePausedReviewThresholdMs: 24 * 60 * 6e4,
288
- inReviewStalledThresholdMs: 24 * 60 * 6e4,
289
- stalePausedTodoThresholdMs: 24 * 60 * 6e4,
290
- pausedScopeDecayMs: 30 * 6e4,
291
- metaTaskStallAutoCloseMs: 2 * 60 * 6e4,
292
- metaTaskActiveExecutionGraceMs: 30 * 6e4,
293
- boardStallSweepWindowMs: 2 * 60 * 6e4,
294
- boardStallBlockedGrowthThreshold: 3,
295
- // Capacity risk warning default: only warn once todo is meaningfully backlogged.
296
- capacityRiskBannerEnabled: false,
297
- capacityRiskTodoThreshold: 20,
298
- backlogPressureAlertEnabled: true,
299
- backlogPressureRatioThreshold: 10,
300
- backlogPressureMinTodoCount: 5,
301
- backlogPressureAlertCooldownMs: 24 * 60 * 6e4,
302
- dependencyBlockedTodoReportEnabled: true,
303
- dependencyBlockedTodoFreshAgeMs: 30 * 6e4,
304
- dependencyBlockedTodoStaleAgeMs: 4 * 60 * 6e4,
305
- dependencyBlockedTodoMinCount: 1,
306
- dependencyBlockedTodoReportCooldownMs: 6 * 60 * 6e4,
307
- staleHighFanoutBlockerAgeThresholdMs: 2 * 60 * 60 * 1e3,
308
- staleInProgressWarningMs: 4 * 60 * 6e4,
309
- staleInProgressCriticalMs: 24 * 60 * 6e4,
310
- staleInReviewWarningMs: 24 * 60 * 6e4,
311
- staleInReviewCriticalMs: 3 * 24 * 60 * 6e4,
312
- aiSessionTtlMs: 7 * 24 * 60 * 60 * 1e3,
313
- aiSessionCleanupIntervalMs: 60 * 60 * 1e3,
314
- autoUnpauseEnabled: true,
315
- autoUnpauseBaseDelayMs: 3e5,
316
- autoUnpauseMaxDelayMs: 36e5,
317
- maxStuckKills: 6,
318
- maxBranchConflictRecoveries: 5,
319
- // maxReviewerContextRetries / maxReviewerFallbackRetries MOVED to workflow
320
- // settings (U4) — see MOVED_SETTINGS_KEYS.
321
- maxTotalRetriesBeforeFail: 25,
322
- preserveProgressOnStuckRequeue: true,
323
- // maxPostReviewFixes MOVED to workflow settings (U4).
324
- maxSpawnedAgentsPerParent: 5,
325
- maxSpawnedAgentsGlobal: 20,
326
- // Run maintenance (including WAL checkpointing) every 5 minutes by default.
327
- maintenanceIntervalMs: 3e5,
328
- autoArchiveDoneTasksEnabled: true,
329
- autoArchiveDoneAfterMs: 48 * 60 * 60 * 1e3,
330
- doneAutoArchiveDays: 0,
331
- archiveAgentLogMode: "compact",
332
- autoUpdatePrStatus: false,
333
- githubCommentOnDone: false,
334
- githubCommentTemplate: void 0,
335
- githubCloseSourceIssueOnDone: false,
336
- githubTrackingEnabledByDefault: false,
337
- githubTrackingDefaultRepo: void 0,
338
- githubTrackingDedupEnabled: true,
339
- githubAuthMode: "gh-cli",
340
- githubAuthToken: void 0,
341
- autoBackupEnabled: false,
342
- autoBackupSchedule: "0 2 * * *",
343
- autoBackupRetention: 7,
344
- autoBackupDir: ".fusion/backups",
345
- memoryBackupEnabled: false,
346
- memoryBackupSchedule: "0 3 * * *",
347
- memoryBackupRetention: 14,
348
- memoryBackupDir: ".fusion/backups/memory",
349
- memoryBackupScope: "all",
350
- autoSummarizeTitles: false,
351
- useAiMergeCommitSummary: true,
352
- // Title-summarizer model lanes MOVED to workflow settings (U4) —
353
- // see MOVED_SETTINGS_KEYS.
354
- scripts: void 0,
355
- setupScript: void 0,
356
- insightExtractionEnabled: false,
357
- insightExtractionSchedule: "0 2 * * *",
358
- insightExtractionMinIntervalMs: 864e5,
359
- taskEvaluationEnabled: false,
360
- taskEvaluationSchedule: "0 5 * * *",
361
- taskEvaluationProvider: void 0,
362
- taskEvaluationModelId: void 0,
363
- taskEvaluationFollowUpPolicy: "off",
364
- taskEvaluationRetention: void 0,
365
- memoryEnabled: true,
366
- memoryBackendType: "qmd",
367
- memoryAutoSummarizeEnabled: false,
368
- memoryAutoSummarizeThresholdChars: 5e4,
369
- memoryAutoSummarizeSchedule: "0 3 * * *",
370
- memoryDreamsEnabled: false,
371
- memoryDreamsSchedule: "0 4 * * *",
372
- tokenCap: void 0,
373
- taskTokenBudget: void 0,
374
- // runStepsInNewSessions / maxParallelSteps MOVED to workflow settings (U4) —
375
- // see MOVED_SETTINGS_KEYS.
376
- missionStaleThresholdMs: 6e5,
377
- missionMaxTaskRetries: 3,
378
- missionHealthCheckIntervalMs: 3e5,
379
- agentPrompts: void 0,
380
- promptOverrides: void 0,
381
- // reflectionEnabled MOVED to workflow settings (U4). reflectionIntervalMs /
382
- // reflectionAfterTask have no engine reader, so they STAY plain project
383
- // settings (catalog-shrink rule) and are NOT in MOVED_SETTINGS_KEYS.
384
- reflectionIntervalMs: 36e5,
385
- reflectionAfterTask: true,
386
- // reviewHandoffPolicy MOVED to workflow settings (U4) — see MOVED_SETTINGS_KEYS.
387
- showQuickChatFAB: false,
388
- chatAutoCleanupDays: 0,
389
- mailAutoCleanupDays: 0,
390
- operationalLogRetentionDays: 30,
391
- agentLogFileRetentionDays: 0,
392
- chatRoomRecentVerbatimMessages: 25,
393
- chatRoomCompactionFetchLimit: 200,
394
- chatRoomSummaryMaxChars: 3e3,
395
- researchSettings: {
396
- enabled: true,
397
- searchProvider: void 0,
398
- synthesisProvider: void 0,
399
- synthesisModelId: void 0,
400
- enabledSources: {
401
- webSearch: true,
402
- pageFetch: true,
403
- github: false,
404
- localDocs: true,
405
- llmSynthesis: true
406
- },
407
- limits: {
408
- maxConcurrentRuns: 3,
409
- maxSourcesPerRun: 20,
410
- maxDurationMs: 3e5,
411
- requestTimeoutMs: 3e4
412
- }
413
- },
414
- sandbox: {
415
- backend: "native",
416
- policy: {
417
- allowNetwork: true,
418
- allowedPaths: []
419
- },
420
- failureMode: "fail-hard"
421
- },
422
- evalSettings: {
423
- enabled: false,
424
- intervalMs: 864e5,
425
- evaluatorProvider: void 0,
426
- evaluatorModelId: void 0,
427
- followUpPolicy: "suggest-only",
428
- retentionDays: 30
429
- },
430
- researchEnabled: true,
431
- researchMaxConcurrentRuns: 3,
432
- researchDefaultTimeout: 3e5,
433
- researchMaxSourcesPerRun: 20,
434
- researchMaxSynthesisRounds: 2
435
- };
436
- var DEFAULT_SETTINGS = {
437
- ...DEFAULT_GLOBAL_SETTINGS,
438
- ...DEFAULT_PROJECT_SETTINGS
439
- };
440
- var GLOBAL_SETTINGS_KEYS = Object.freeze(Object.keys(DEFAULT_GLOBAL_SETTINGS));
441
- var PROJECT_SETTINGS_KEYS = Object.freeze(Object.keys(DEFAULT_PROJECT_SETTINGS));
442
- function isGlobalSettingsKey(key) {
443
- return GLOBAL_SETTINGS_KEYS.includes(key);
444
- }
445
- function isProjectSettingsKey(key) {
446
- return PROJECT_SETTINGS_KEYS.includes(key);
447
- }
448
- function isGlobalOnlySettingsKey(key) {
449
- return isGlobalSettingsKey(key) && !isProjectSettingsKey(key);
450
- }
451
- var CLI_AGENT_ADAPTER_IDS = Object.freeze([
452
- "claude-code",
453
- "codex",
454
- "droid",
455
- "pi",
456
- "generic"
457
- ]);
458
- var CLI_AGENT_AUTONOMY_MODES = Object.freeze(["default", "elevated"]);
459
- function sanitizeStringArray(value) {
460
- if (!Array.isArray(value))
461
- return void 0;
462
- const cleaned = value.filter((v) => typeof v === "string").map((v) => v.trim()).filter((v) => v.length > 0);
463
- return cleaned.length > 0 ? cleaned : void 0;
464
- }
465
- function sanitizeCliAgentSettings(value) {
466
- if (!value || typeof value !== "object" || Array.isArray(value))
467
- return void 0;
468
- const input = value;
469
- const out = {};
470
- if (typeof input.commandOverride === "string") {
471
- const trimmed = input.commandOverride.trim();
472
- if (trimmed.length > 0)
473
- out.commandOverride = trimmed;
474
- }
475
- const extraArgs = sanitizeStringArray(input.extraArgs);
476
- if (extraArgs)
477
- out.extraArgs = extraArgs;
478
- const envAdditions = sanitizeStringArray(input.envAdditions);
479
- if (envAdditions)
480
- out.envAdditions = envAdditions;
481
- if (typeof input.autonomyMode === "string" && CLI_AGENT_AUTONOMY_MODES.includes(input.autonomyMode)) {
482
- out.autonomyMode = input.autonomyMode;
483
- }
484
- return Object.keys(out).length > 0 ? out : void 0;
485
- }
486
- function sanitizeCliAgentsSettings(value) {
487
- if (!value || typeof value !== "object" || Array.isArray(value))
488
- return {};
489
- const input = value;
490
- const out = {};
491
- for (const adapterId of CLI_AGENT_ADAPTER_IDS) {
492
- if (!(adapterId in input))
493
- continue;
494
- const entry = sanitizeCliAgentSettings(input[adapterId]);
495
- if (entry)
496
- out[adapterId] = entry;
497
- }
498
- return out;
499
- }
500
-
501
- // ../core/dist/error-message.js
502
- function getErrorMessage(err) {
503
- if (err instanceof Error)
504
- return err.message;
505
- if (typeof err === "string")
506
- return err;
507
- try {
508
- return JSON.stringify(err);
509
- } catch {
510
- return String(err);
511
- }
512
- }
513
-
514
- // ../core/dist/model-resolution.js
515
- var TEST_MODE_RESOLVED = { provider: "mock", modelId: "scripted" };
516
- function isTestModeActive(settings) {
517
- return settings?.testMode === true || settings?.defaultProvider?.trim().toLowerCase() === "mock";
518
- }
519
- function applyTestModeOverrides(resolved, settings) {
520
- return isTestModeActive(settings) ? TEST_MODE_RESOLVED : resolved;
521
- }
522
- function hasCompleteModelPair(pair) {
523
- return Boolean(pair?.provider && pair?.modelId);
524
- }
525
- function pickFirstModelPair(...pairs) {
526
- for (const pair of pairs) {
527
- if (hasCompleteModelPair(pair)) {
528
- return { provider: pair.provider, modelId: pair.modelId };
529
- }
530
- }
531
- return {};
532
- }
533
- function resolveProjectDefaultModel(settings) {
534
- return applyTestModeOverrides(pickFirstModelPair({
535
- provider: settings?.defaultProviderOverride,
536
- modelId: settings?.defaultModelIdOverride
537
- }, {
538
- provider: settings?.defaultProvider,
539
- modelId: settings?.defaultModelId
540
- }), settings);
541
- }
542
- function resolveTitleSummarizerSettingsModel(settings) {
543
- return applyTestModeOverrides(pickFirstModelPair({
544
- provider: settings?.titleSummarizerProvider,
545
- modelId: settings?.titleSummarizerModelId
546
- }, {
547
- provider: settings?.titleSummarizerGlobalProvider,
548
- modelId: settings?.titleSummarizerGlobalModelId
549
- }, {
550
- provider: settings?.planningProvider,
551
- modelId: settings?.planningModelId
552
- }, resolveProjectDefaultModel(settings)), settings);
553
- }
554
-
555
- // ../core/dist/experimental-features.js
556
- var LEGACY_EXPERIMENTAL_FEATURE_ALIASES = {
557
- devServer: "devServerView"
558
- };
559
- function isExperimentalFeatureEnabled(settings, key) {
560
- const features = settings?.experimentalFeatures;
561
- if (!features)
562
- return false;
563
- const canonicalKey = LEGACY_EXPERIMENTAL_FEATURE_ALIASES[key] ?? key;
564
- if (features[canonicalKey] === true)
565
- return true;
566
- for (const [legacyKey, aliasCanonical] of Object.entries(LEGACY_EXPERIMENTAL_FEATURE_ALIASES)) {
567
- if (aliasCanonical === canonicalKey && features[legacyKey] === true) {
568
- return true;
569
- }
570
- }
571
- return false;
572
- }
573
-
574
- // ../core/dist/types.js
575
- var COLUMNS = ["triage", "todo", "in-progress", "in-review", "done", "archived"];
576
- var TASK_PRIORITIES = ["low", "normal", "high", "urgent"];
577
- var DEFAULT_TASK_PRIORITY = "normal";
578
- var STALE_HIGH_FANOUT_BLOCKER_AGE_THRESHOLD_MS = 2 * 60 * 60 * 1e3;
579
- var SUPPORTED_LOCALES = ["en", "zh-CN", "zh-TW", "fr", "es", "ko"];
580
- function isLocale(value) {
581
- return typeof value === "string" && SUPPORTED_LOCALES.includes(value);
582
- }
583
- var WORKFLOW_STEP_TEMPLATES = [
584
- {
585
- id: "documentation-review",
586
- name: "Documentation Review",
587
- description: "Verify all public APIs, functions, and complex logic have appropriate documentation",
588
- category: "Quality",
589
- icon: "file-text",
590
- toolMode: "readonly",
591
- prompt: `You are a documentation reviewer. Review the completed task and verify documentation quality.
592
-
593
- Review Criteria:
594
- 1. All new public functions, classes, and modules have JSDoc comments or equivalent documentation
595
- 2. Complex logic has inline comments explaining the "why" not just the "what"
596
- 3. README files are updated if the task changes user-facing behavior
597
- 4. CHANGELOG or release notes are considered for significant changes
598
- 5. Type definitions are documented for public APIs
599
-
600
- Files to Review:
601
- - Review all files modified in the task worktree
602
- - Focus on public API surface area
603
- - Check test files for test documentation
604
-
605
- Output Requirements:
606
- - Fast-bail: if Diff Scope contains no documentation-relevant files, output {"verdict":"APPROVE","notes":"out of scope: documentation"} immediately.
607
- - APPROVE: documentation is adequate; use empty or brief notes.
608
- - APPROVE_WITH_NOTES: documentation is adequate with advisory improvements; include concise suggestions in notes.
609
- - REVISE: documentation is missing or incorrect; include actionable file paths/functions in notes.
610
- - Final output: output exactly one trailing JSON object on the final line (no markdown fences, no surrounding prose):
611
- {"verdict":"APPROVE|APPROVE_WITH_NOTES|REVISE","notes":"..."}`
612
- },
613
- {
614
- id: "qa-check",
615
- name: "QA Check",
616
- description: "Run lint, tests, and typecheck; verify they pass and check for obvious bugs",
617
- category: "Quality",
618
- icon: "check-circle",
619
- toolMode: "coding",
620
- prompt: `You are a QA tester. Verify the task implementation by running lint, tests, and typecheck, and checking for bugs.
621
-
622
- Quality Gate Execution (all three must pass):
623
- 1. Run the project's lint command (e.g. \`pnpm lint\`, \`npm run lint\`)
624
- 2. Run the project's test suite (e.g. \`pnpm test\`, \`npm test\`, or the configured test command)
625
- 3. Run the project's typecheck command if one exists (e.g. \`pnpm typecheck\`, \`tsc --noEmit\`)
626
- 4. Verify lint, tests, and typecheck all pass
627
- 5. If any gate fails, analyze whether failures are related to the task changes
628
-
629
- Code Review:
630
- 1. Review the changes for obvious bugs or edge cases
631
- 2. Check error handling is appropriate
632
- 3. Verify input validation is present where needed
633
- 4. Look for common issues: null pointer risks, off-by-one errors, race conditions
634
-
635
- Output Requirements:
636
- - Fast-bail: if Diff Scope contains no QA-relevant files, output {"verdict":"APPROVE","notes":"out of scope: QA"} immediately.
637
- - APPROVE: lint/tests/typecheck pass and no actionable bugs.
638
- - APPROVE_WITH_NOTES: quality gates pass but include non-blocking advisories in notes.
639
- - REVISE: any gate fails or actionable bugs are found; include failing commands and affected file paths in notes.
640
- - Final output: output exactly one trailing JSON object on the final line (no markdown fences, no surrounding prose):
641
- {"verdict":"APPROVE|APPROVE_WITH_NOTES|REVISE","notes":"..."}`
642
- },
643
- {
644
- id: "security-audit",
645
- name: "Security Audit",
646
- description: "Check for common security vulnerabilities and anti-patterns",
647
- category: "Security",
648
- icon: "shield",
649
- toolMode: "readonly",
650
- prompt: `You are a security auditor. Review the task changes for common security vulnerabilities.
651
-
652
- Security Checklist:
653
- 1. **Injection vulnerabilities** \u2014 Check for SQL injection, command injection, XSS via unsanitized user input
654
- 2. **Secrets and credentials** \u2014 Ensure no hardcoded passwords, API keys, tokens, or private keys
655
- 3. **Unsafe eval** \u2014 Check for eval(), new Function(), or similar dangerous patterns
656
- 4. **Path traversal** \u2014 Verify file path handling prevents directory traversal attacks
657
- 5. **Insecure deserialization** \u2014 Check for unsafe parsing of untrusted data
658
- 6. **Authentication/Authorization** \u2014 Verify access controls are properly implemented
659
- 7. **Dependency risks** \u2014 Note any new dependencies that might have known vulnerabilities
660
-
661
- Files to Review:
662
- - All modified files in the task
663
- - Configuration files that might contain secrets
664
- - Areas handling user input or external data
665
-
666
- Output Requirements:
667
- - Fast-bail: if Diff Scope contains no security-relevant files, output {"verdict":"APPROVE","notes":"out of scope: security"} immediately.
668
- - APPROVE: no security issues found.
669
- - APPROVE_WITH_NOTES: no blocking issues, but include advisory hardening opportunities in notes.
670
- - REVISE: vulnerabilities require changes; include file paths, severity, and remediation guidance in notes.
671
- - Final output: output exactly one trailing JSON object on the final line (no markdown fences, no surrounding prose):
672
- {"verdict":"APPROVE|APPROVE_WITH_NOTES|REVISE","notes":"..."}`
673
- },
674
- {
675
- id: "performance-review",
676
- name: "Performance Review",
677
- description: "Check for performance anti-patterns and optimization opportunities",
678
- category: "Quality",
679
- icon: "zap",
680
- toolMode: "readonly",
681
- prompt: `You are a performance reviewer. Analyze the task changes for performance implications.
682
-
683
- Performance Checklist:
684
- 1. **Algorithmic complexity** \u2014 Check for O(n\xB2) or worse patterns that could bottleneck
685
- 2. **N+1 queries** \u2014 Look for database queries in loops
686
- 3. **Memory leaks** \u2014 Check for unclosed resources, event listeners, or accumulating caches
687
- 4. **Unnecessary re-renders** \u2014 For UI code, check for inefficient React/Angular/Vue patterns
688
- 5. **Bundle size** \u2014 Note if large dependencies are added unnecessarily
689
- 6. **Async patterns** \u2014 Verify proper use of async/await, Promise.all for parallel work
690
- 7. **Caching opportunities** \u2014 Identify where caching could improve performance
691
-
692
- Files to Review:
693
- - All modified files, focusing on hot paths and frequently executed code
694
- - Database query files
695
- - API endpoints and route handlers
696
-
697
- Output Requirements:
698
- - Fast-bail: if Diff Scope contains no performance-relevant files, output {"verdict":"APPROVE","notes":"out of scope: performance"} immediately.
699
- - APPROVE: performance impact is acceptable.
700
- - APPROVE_WITH_NOTES: acceptable overall, but include optimization advisories in notes.
701
- - REVISE: performance risks require changes; include actionable file paths and optimization guidance in notes.
702
- - Final output: output exactly one trailing JSON object on the final line (no markdown fences, no surrounding prose):
703
- {"verdict":"APPROVE|APPROVE_WITH_NOTES|REVISE","notes":"..."}`
704
- },
705
- {
706
- id: "accessibility-check",
707
- name: "Accessibility Check",
708
- description: "Verify UI changes meet accessibility standards (WCAG 2.1)",
709
- category: "Quality",
710
- icon: "eye",
711
- toolMode: "readonly",
712
- prompt: `You are an accessibility reviewer. Check UI changes for WCAG 2.1 compliance.
713
-
714
- Accessibility Checklist:
715
- 1. **Keyboard navigation** \u2014 Ensure all interactive elements are keyboard accessible
716
- 2. **ARIA labels** \u2014 Check that screen reader announcements are appropriate
717
- 3. **Color contrast** \u2014 Verify text meets minimum contrast ratios (4.5:1 for normal text)
718
- 4. **Focus indicators** \u2014 Ensure visible focus states for keyboard navigation
719
- 5. **Alt text** \u2014 Check that images have meaningful alternative text
720
- 6. **Form labels** \u2014 Verify all inputs have associated labels
721
- 7. **Semantic HTML** \u2014 Check that proper HTML elements are used (buttons not divs)
722
-
723
- Files to Review:
724
- - Modified UI components
725
- - CSS/styling changes
726
- - New HTML templates or JSX
727
-
728
- Output Requirements:
729
- - Fast-bail: if Diff Scope contains no accessibility-relevant UI files, output {"verdict":"APPROVE","notes":"out of scope: accessibility"} immediately.
730
- - APPROVE: accessibility requirements are met.
731
- - APPROVE_WITH_NOTES: compliant overall, with advisory improvements in notes.
732
- - REVISE: accessibility issues require changes; include file paths, WCAG references, and remediation steps in notes.
733
- - Final output: output exactly one trailing JSON object on the final line (no markdown fences, no surrounding prose):
734
- {"verdict":"APPROVE|APPROVE_WITH_NOTES|REVISE","notes":"..."}`
735
- },
736
- {
737
- id: "browser-verification",
738
- name: "Browser Verification",
739
- description: "Verify web application functionality using browser automation",
740
- category: "Quality",
741
- icon: "globe",
742
- toolMode: "coding",
743
- prompt: `You are a browser verification specialist. Verify web application functionality after task implementation using the agent-browser CLI tool.
744
-
745
- ## Prerequisites
746
- First, determine the URL to verify. Check the task PROMPT.md for any URLs mentioned, or look at the code changes to identify the local development server URL (typically http://localhost:3000, http://localhost:5173, http://localhost:8080, etc.).
747
-
748
- ## Verification Commands
749
- Use these agent-browser commands for verification:
750
- - \`agent-browser open <url>\` \u2014 Navigate to the page
751
- - \`agent-browser snapshot -i\` \u2014 Get interactive elements with refs (@e1, @e2, etc.)
752
- - \`agent-browser click @e1\` \u2014 Click an element
753
- - \`agent-browser fill @e1 "text"\` \u2014 Fill an input field
754
- - \`agent-browser get text @e1\` \u2014 Get element text content
755
- - \`agent-browser screenshot\` \u2014 Capture screenshot to file
756
- - \`agent-browser wait --load networkidle\` \u2014 Wait for page to fully load
757
-
758
- ## Verification Checklist
759
- 1. Page loads without JavaScript errors or blank screens
760
- 2. Navigation between pages/sections works
761
- 3. Forms accept input and submit correctly
762
- 4. Interactive elements (buttons, links) respond to clicks
763
- 5. Error states are handled gracefully
764
- 6. Screenshots capture expected content
765
-
766
- ## Output Requirements
767
- - Fast-bail: if Diff Scope contains no browser-verification-relevant UI files, output {"verdict":"APPROVE","notes":"out of scope: browser verification"} immediately.
768
- - APPROVE: verification succeeds.
769
- - APPROVE_WITH_NOTES: verification succeeds with non-blocking advisory findings; include evidence references in notes.
770
- - REVISE: verification failures or regressions require changes; include failing behavior and actionable file paths in notes.
771
- - Screenshots/artifacts referenced in notes are evidence only; verdict must be conveyed by the final JSON line.
772
- - Final output: output exactly one trailing JSON object on the final line (no markdown fences, no surrounding prose):
773
- {"verdict":"APPROVE|APPROVE_WITH_NOTES|REVISE","notes":"..."}
774
-
775
- Note: Refs (@e1, @e2) are invalidated after page navigation. Re-snapshot after clicking links or form submissions.`
776
- },
777
- {
778
- id: "frontend-ux-design",
779
- name: "Frontend UX Design",
780
- description: "Verify visual polish and consistency with existing UI patterns and design tokens",
781
- category: "Quality",
782
- icon: "layout-grid",
783
- toolMode: "readonly",
784
- prompt: `You are a UX design reviewer. Verify frontend changes maintain visual polish and consistency with existing UI patterns and design tokens.
785
-
786
- ## Step 1: Scope Check (MANDATORY FIRST)
787
-
788
- The task harness provides a "Diff Scope" listing files this task actually changed.
789
-
790
- If the Diff Scope contains ZERO frontend/UI files (no .tsx/.jsx/.ts/.js component files, no .css/.scss/.sass/.styl, no .html/.vue/.svelte/.astro, no design-token/theme files), output ONLY:
791
- {"verdict":"APPROVE","notes":"out of scope: frontend UX design"}
792
- Then STOP. Do not browse the worktree. Do not read any files.
793
-
794
- If there ARE frontend/UI files in scope, proceed to Step 2.
795
-
796
- ## Step 2: Design Review
797
-
798
- Restrict your review to ONLY the UI files in the diff scope.
799
-
800
- Check:
801
- 1. **Visual Hierarchy** \u2014 heading levels, content flow, information architecture
802
- 2. **Spacing and Typography** \u2014 consistent margins, padding, gaps, type scale
803
- 3. **Color and Token Consistency** \u2014 CSS custom properties and design tokens used; no hardcoded colors
804
- 4. **Component Reuse** \u2014 existing components reused; no one-off styling or duplication
805
- 5. **Responsive Behavior** \u2014 layouts adapt across viewports
806
- 6. **Fit with Design Language** \u2014 border radius, shadows, transitions, icon style match patterns
807
-
808
- ## Output Format
809
-
810
- - APPROVE: visual quality is acceptable; use empty or brief notes.
811
- - APPROVE_WITH_NOTES: acceptable with non-blocking polish advisories; include specific notes.
812
- - REVISE: issues require code changes; include specific files and required changes in notes.
813
- - Final output: output exactly one trailing JSON object on the final line (no markdown fences, no surrounding prose):
814
- {"verdict":"APPROVE|APPROVE_WITH_NOTES|REVISE","notes":"..."}
815
-
816
- Prioritize: layout breaks > visual inconsistency > style preferences.
817
- Do NOT spend time on nits when no real issues exist.`
818
- }
819
- ];
820
- var DOCUMENT_KEY_RE = /^[a-zA-Z0-9_-]{1,64}$/;
821
- function validateDocumentKey(key) {
822
- if (!DOCUMENT_KEY_RE.test(key)) {
823
- throw new Error(`Invalid document key: "${key}". Must be 1-64 characters: letters, digits, hyphens, or underscores.`);
824
- }
825
- }
826
- var CheckoutConflictError = class extends Error {
827
- taskId;
828
- currentHolderId;
829
- requestedById;
830
- constructor(taskId, currentHolderId, requestedById) {
831
- super(`Task ${taskId} is already checked out by agent ${currentHolderId}`);
832
- this.taskId = taskId;
833
- this.currentHolderId = currentHolderId;
834
- this.requestedById = requestedById;
835
- this.name = "CheckoutConflictError";
836
- }
837
- };
838
- var SHARED_STATE_SNAPSHOT_VERSION = 1;
839
- var VALID_TRANSITIONS = {
840
- // FN-4892: intake-side heuristics may cold-archive tasks before execution starts.
841
- triage: ["todo", "archived"],
842
- // FN-4892: allow direct archival for newly specified intake tasks.
843
- todo: ["in-progress", "triage", "archived"],
844
- // NOTE: "in-progress" → "done" is enabled for mission validation tasks that complete directly.
845
- // Regular implementation tasks should move through "in-review" before "done".
846
- "in-progress": ["in-review", "todo", "triage", "done"],
847
- "in-review": ["done", "in-progress", "todo", "triage"],
848
- done: ["todo", "triage", "archived"],
849
- archived: ["done"]
850
- };
851
- function validateDockerNodeConfig(config) {
852
- const errors = [];
853
- if (!config || typeof config !== "object" || Array.isArray(config)) {
854
- return { valid: false, errors: ["config must be an object"] };
855
- }
856
- const candidate = config;
857
- if (typeof candidate.image !== "string" || !candidate.image.trim()) {
858
- errors.push("image must be a non-empty string");
859
- }
860
- if (!Array.isArray(candidate.volumeMounts)) {
861
- errors.push("volumeMounts must be an array");
862
- } else {
863
- candidate.volumeMounts.forEach((mount, index) => {
864
- if (!mount || typeof mount !== "object" || Array.isArray(mount)) {
865
- errors.push(`volumeMounts[${index}] must be an object`);
866
- return;
867
- }
868
- const mountCandidate = mount;
869
- if (typeof mountCandidate.hostPath !== "string") {
870
- errors.push(`volumeMounts[${index}].hostPath must be a string`);
871
- }
872
- if (typeof mountCandidate.containerPath !== "string") {
873
- errors.push(`volumeMounts[${index}].containerPath must be a string`);
874
- }
875
- if (mountCandidate.mode !== void 0 && mountCandidate.mode !== "rw" && mountCandidate.mode !== "ro") {
876
- errors.push(`volumeMounts[${index}].mode must be "rw" or "ro"`);
877
- }
878
- if (mountCandidate.type !== void 0 && mountCandidate.type !== "volume" && mountCandidate.type !== "bind") {
879
- errors.push(`volumeMounts[${index}].type must be "volume" or "bind"`);
880
- }
881
- });
882
- }
883
- if (!candidate.environment || typeof candidate.environment !== "object" || Array.isArray(candidate.environment)) {
884
- errors.push("environment must be an object");
885
- } else {
886
- for (const [key, value] of Object.entries(candidate.environment)) {
887
- if (typeof key !== "string" || typeof value !== "string") {
888
- errors.push(`environment.${key} must be a string value`);
889
- }
890
- }
891
- }
892
- if (typeof candidate.configVersion !== "number" || !Number.isFinite(candidate.configVersion) || candidate.configVersion < 1) {
893
- errors.push("configVersion must be a number >= 1");
894
- }
895
- const validateOptionalObject = (fieldName, value, validators) => {
896
- if (value === void 0)
897
- return;
898
- if (!value || typeof value !== "object" || Array.isArray(value)) {
899
- errors.push(`${fieldName} must be an object`);
900
- return;
901
- }
902
- const typed = value;
903
- for (const [prop, test, message] of validators) {
904
- if (typed[prop] !== void 0 && !test(typed[prop])) {
905
- errors.push(`${fieldName}.${prop} ${message}`);
906
- }
907
- }
908
- };
909
- validateOptionalObject("resources", candidate.resources, [
910
- ["memoryBytes", (value) => typeof value === "number" && Number.isFinite(value), "must be a number"],
911
- ["cpuCount", (value) => typeof value === "number" && Number.isFinite(value), "must be a number"],
912
- ["pidsLimit", (value) => typeof value === "number" && Number.isFinite(value), "must be a number"]
913
- ]);
914
- validateOptionalObject("host", candidate.host, [
915
- ["contextName", (value) => typeof value === "string", "must be a string"],
916
- ["dockerHost", (value) => typeof value === "string", "must be a string"],
917
- ["tlsCaCert", (value) => typeof value === "string", "must be a string"],
918
- ["tlsCert", (value) => typeof value === "string", "must be a string"],
919
- ["tlsKey", (value) => typeof value === "string", "must be a string"],
920
- ["tlsVerify", (value) => typeof value === "boolean", "must be a boolean"]
921
- ]);
922
- validateOptionalObject("persistence", candidate.persistence, [
923
- ["volumeName", (value) => typeof value === "string", "must be a string"],
924
- ["retainOnDelete", (value) => typeof value === "boolean", "must be a boolean"]
925
- ]);
926
- if (candidate.extraClis !== void 0) {
927
- if (!Array.isArray(candidate.extraClis) || candidate.extraClis.some((item) => typeof item !== "string")) {
928
- errors.push("extraClis must be an array of strings");
929
- }
930
- }
931
- if (candidate.containerName !== void 0 && typeof candidate.containerName !== "string") {
932
- errors.push("containerName must be a string");
933
- }
934
- if (candidate.lastUpdated !== void 0 && typeof candidate.lastUpdated !== "string") {
935
- errors.push("lastUpdated must be a string");
936
- }
937
- if (errors.length > 0) {
938
- return { valid: false, errors };
939
- }
940
- return { valid: true, config: candidate };
941
- }
942
- var AGENT_VALID_TRANSITIONS = {
943
- idle: ["active"],
944
- active: ["idle", "running", "paused", "error"],
945
- running: ["idle", "active", "paused", "error"],
946
- paused: ["idle", "active"],
947
- error: ["idle", "active"]
948
- };
949
- function isEphemeralAgent(agent) {
950
- const metadata = agent.metadata ?? {};
951
- if (metadata.agentKind === "task-worker")
952
- return true;
953
- if (metadata.taskWorker === true)
954
- return true;
955
- if (metadata.managedBy === "task-executor")
956
- return true;
957
- if (metadata.type === "spawned")
958
- return true;
959
- if (metadata.internal === true)
960
- return true;
961
- if (agent.role === "executor" && typeof agent.name === "string" && agent.name.startsWith("executor-") && agent.reportsTo == null) {
962
- return true;
963
- }
964
- if (agent.role === "executor" && agent.name === "verification-agent" && agent.reportsTo == null) {
965
- return true;
966
- }
967
- return false;
968
- }
969
- var AGENT_PERMISSIONS = [
970
- "tasks:assign",
971
- // Assign tasks to agents
972
- "tasks:create",
973
- // Create new tasks
974
- "tasks:execute",
975
- // Execute/run tasks
976
- "tasks:review",
977
- // Review task output (code, specs)
978
- "tasks:merge",
979
- // Merge completed task branches
980
- "tasks:delete",
981
- // Delete tasks
982
- "tasks:archive",
983
- // Archive/unarchive tasks
984
- "agents:create",
985
- // Create new agents
986
- "agents:update",
987
- // Update agent configuration
988
- "agents:delete",
989
- // Delete agents
990
- "agents:view",
991
- // View agent details and logs
992
- "settings:read",
993
- // Read project settings
994
- "settings:update",
995
- // Modify project settings
996
- "workflows:manage",
997
- // Create/edit/delete workflow steps
998
- "missions:manage",
999
- // Create/edit/delete missions and slices
1000
- "automations:manage",
1001
- // Create/edit/delete scheduled automations
1002
- "messages:send",
1003
- // Send messages to agents/users
1004
- "messages:read"
1005
- // Read mailbox messages
1006
- ];
1007
- var AGENT_PERMISSION_POLICY_ACTION_CATEGORIES = [
1008
- "git_write",
1009
- "file_write_delete",
1010
- "command_execution",
1011
- "network_api",
1012
- "task_agent_mutation"
1013
- ];
1014
- var AGENT_PERMISSION_POLICY_PRESET_IDS = ["unrestricted", "approval-required", "locked-down", "custom"];
1015
- var DEFAULT_HEARTBEAT_PROCEDURE_PATH = ".fusion/HEARTBEAT.md";
1016
- function slugifyAgentAssetSegment(value) {
1017
- return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
1018
- }
1019
- function getSafeAgentAssetIdSegment(agentId) {
1020
- const slug = slugifyAgentAssetSegment(agentId);
1021
- return slug || "agent";
1022
- }
1023
- function getCanonicalAgentAssetDirectoryName(agentName, agentId) {
1024
- if (!agentId || typeof agentId !== "string") {
1025
- throw new Error("getCanonicalAgentAssetDirectoryName requires a non-empty agentId");
1026
- }
1027
- const safeId = getSafeAgentAssetIdSegment(agentId);
1028
- const nameSlug = slugifyAgentAssetSegment(agentName ?? "");
1029
- const prefix = nameSlug || safeId;
1030
- return `${prefix}-${safeId}`;
1031
- }
1032
- function getLegacyAgentAssetDirectoryName(agentId) {
1033
- if (!agentId || typeof agentId !== "string") {
1034
- throw new Error("getLegacyAgentAssetDirectoryName requires a non-empty agentId");
1035
- }
1036
- return agentId;
1037
- }
1038
- function getCanonicalAgentInstructionsBundleDirName(agentName, agentId) {
1039
- return `${getCanonicalAgentAssetDirectoryName(agentName, agentId)}-instructions`;
1040
- }
1041
- function getLegacyAgentInstructionsBundleDirName(agentId) {
1042
- return `${getLegacyAgentAssetDirectoryName(agentId)}-instructions`;
1043
- }
1044
- function getDefaultHeartbeatProcedurePath(agentId, agentName) {
1045
- if (!agentId || typeof agentId !== "string") {
1046
- throw new Error("getDefaultHeartbeatProcedurePath requires a non-empty agentId");
1047
- }
1048
- const directory = agentName ? getCanonicalAgentAssetDirectoryName(agentName, agentId) : getLegacyAgentAssetDirectoryName(agentId);
1049
- return `.fusion/agents/${directory}/HEARTBEAT.md`;
1050
- }
1051
- function agentToConfigSnapshot(agent) {
1052
- return {
1053
- name: agent.name,
1054
- role: agent.role,
1055
- title: agent.title,
1056
- icon: agent.icon,
1057
- imageUrl: agent.imageUrl,
1058
- reportsTo: agent.reportsTo,
1059
- runtimeConfig: agent.runtimeConfig ? { ...agent.runtimeConfig } : void 0,
1060
- permissions: agent.permissions ? { ...agent.permissions } : void 0,
1061
- permissionPolicy: agent.permissionPolicy ? {
1062
- presetId: agent.permissionPolicy.presetId,
1063
- rules: { ...agent.permissionPolicy.rules }
1064
- } : void 0,
1065
- instructionsPath: agent.instructionsPath,
1066
- instructionsText: agent.instructionsText,
1067
- soul: agent.soul,
1068
- memory: agent.memory,
1069
- bundleConfig: agent.bundleConfig ? {
1070
- ...agent.bundleConfig,
1071
- files: [...agent.bundleConfig.files]
1072
- } : void 0,
1073
- heartbeatProcedurePath: agent.heartbeatProcedurePath,
1074
- metadata: { ...agent.metadata }
1075
- };
1076
- }
1077
- function diffConfigSnapshots(before, after) {
1078
- const trackedFields = [
1079
- "name",
1080
- "role",
1081
- "title",
1082
- "icon",
1083
- "imageUrl",
1084
- "reportsTo",
1085
- "runtimeConfig",
1086
- "permissions",
1087
- "permissionPolicy",
1088
- "instructionsPath",
1089
- "instructionsText",
1090
- "soul",
1091
- "memory",
1092
- "bundleConfig",
1093
- "heartbeatProcedurePath",
1094
- "metadata"
1095
- ];
1096
- const diffs = [];
1097
- for (const field of trackedFields) {
1098
- const oldVal = before[field];
1099
- const newVal = after[field];
1100
- if (JSON.stringify(oldVal) !== JSON.stringify(newVal)) {
1101
- diffs.push({ field, oldValue: oldVal, newValue: newVal });
1102
- }
1103
- }
1104
- return diffs;
1105
- }
1106
-
1107
- export {
1108
- DEFAULT_GLOBAL_SETTINGS,
1109
- DEFAULT_PROJECT_SETTINGS,
1110
- DEFAULT_SETTINGS,
1111
- isGlobalOnlySettingsKey,
1112
- sanitizeCliAgentsSettings,
1113
- getErrorMessage,
1114
- resolveTitleSummarizerSettingsModel,
1115
- isExperimentalFeatureEnabled,
1116
- COLUMNS,
1117
- TASK_PRIORITIES,
1118
- DEFAULT_TASK_PRIORITY,
1119
- isLocale,
1120
- WORKFLOW_STEP_TEMPLATES,
1121
- validateDocumentKey,
1122
- CheckoutConflictError,
1123
- SHARED_STATE_SNAPSHOT_VERSION,
1124
- VALID_TRANSITIONS,
1125
- validateDockerNodeConfig,
1126
- AGENT_VALID_TRANSITIONS,
1127
- isEphemeralAgent,
1128
- AGENT_PERMISSIONS,
1129
- AGENT_PERMISSION_POLICY_ACTION_CATEGORIES,
1130
- AGENT_PERMISSION_POLICY_PRESET_IDS,
1131
- DEFAULT_HEARTBEAT_PROCEDURE_PATH,
1132
- getSafeAgentAssetIdSegment,
1133
- getLegacyAgentAssetDirectoryName,
1134
- getCanonicalAgentInstructionsBundleDirName,
1135
- getLegacyAgentInstructionsBundleDirName,
1136
- getDefaultHeartbeatProcedurePath,
1137
- agentToConfigSnapshot,
1138
- diffConfigSnapshots
1139
- };