@swarmclawai/swarmclaw 1.9.2 → 1.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -3
- package/electron-dist/main.js +218 -0
- package/package.json +2 -2
- package/src/app/api/extensions/managed-resources/route.test.ts +117 -0
- package/src/app/api/extensions/managed-resources/route.ts +116 -0
- package/src/app/api/gateways/[id]/environments/[environmentId]/route.ts +16 -0
- package/src/app/api/gateways/[id]/environments/route.ts +13 -0
- package/src/app/api/gateways/topology-route.test.ts +30 -0
- package/src/app/api/tasks/task-workspace-route.test.ts +4 -0
- package/src/cli/index.js +4 -0
- package/src/cli/spec.js +4 -0
- package/src/components/providers/provider-list.tsx +34 -1
- package/src/components/tasks/task-sheet.tsx +50 -0
- package/src/features/gateways/queries.ts +3 -0
- package/src/lib/server/extension-managed-resources.test.ts +159 -0
- package/src/lib/server/extension-managed-resources.ts +905 -0
- package/src/lib/server/extensions.ts +113 -2
- package/src/lib/server/gateways/gateway-profile-service.ts +2 -0
- package/src/lib/server/gateways/gateway-topology.test.ts +59 -3
- package/src/lib/server/gateways/gateway-topology.ts +129 -3
- package/src/lib/server/operations/operation-pulse.test.ts +29 -0
- package/src/lib/server/operations/operation-pulse.ts +9 -0
- package/src/lib/server/session-tools/extension-creator.ts +50 -0
- package/src/lib/server/tasks/task-execution-workspace.test.ts +14 -0
- package/src/lib/server/tasks/task-execution-workspace.ts +133 -6
- package/src/types/agent.ts +2 -0
- package/src/types/app-settings.ts +8 -0
- package/src/types/extension.ts +132 -0
- package/src/types/misc.ts +31 -0
- package/src/types/schedule.ts +3 -0
- package/src/types/task.ts +30 -0
- package/src/views/settings/extension-manager.tsx +157 -1
|
@@ -66,10 +66,24 @@ describe('task execution workspaces', () => {
|
|
|
66
66
|
assert.match(patch.executionWorkspace.path, /task-alpha-launch-qa-preview/)
|
|
67
67
|
assert.equal(fs.existsSync(patch.executionWorkspace.path), true)
|
|
68
68
|
assert.equal(fs.existsSync(patch.executionWorkspace.readmePath || ''), true)
|
|
69
|
+
assert.equal(fs.existsSync(patch.executionWorkspace.contextPath || ''), true)
|
|
70
|
+
assert.equal(fs.existsSync(patch.executionWorkspace.envPath || ''), true)
|
|
69
71
|
assert.equal(patch.executionWorkspace.sourceCwd, '/repo/source')
|
|
72
|
+
assert.equal(patch.executionWorkspace.context?.taskId, 'task-alpha')
|
|
73
|
+
assert.equal(patch.executionWorkspace.context?.workspacePath, patch.executionWorkspace.path)
|
|
74
|
+
assert.equal(patch.executionWorkspace.envHints?.some((hint) => hint.key === 'WORKSPACE_CWD'), true)
|
|
75
|
+
assert.equal(patch.executionWorkspace.envHints?.some((hint) => hint.key === 'KANBAN_TASK_ID'), true)
|
|
70
76
|
assert.equal(patch.executionWorkspace.previewLinks[0]?.label, 'Local preview')
|
|
71
77
|
assert.equal(patch.previewLinks[0]?.url, 'http://127.0.0.1:3456')
|
|
72
78
|
assert.equal(patch.runtimeServices[0]?.status, 'planned')
|
|
79
|
+
|
|
80
|
+
const context = JSON.parse(fs.readFileSync(patch.executionWorkspace.contextPath || '', 'utf8'))
|
|
81
|
+
assert.equal(context.taskId, 'task-alpha')
|
|
82
|
+
assert.equal(context.previewLinks[0]?.url, 'http://127.0.0.1:3456')
|
|
83
|
+
const envFile = fs.readFileSync(patch.executionWorkspace.envPath || '', 'utf8')
|
|
84
|
+
assert.equal(envFile.includes('SWARMCLAW_TASK_ID="task-alpha"'), true)
|
|
85
|
+
assert.equal(envFile.includes('WORKSPACE_SOURCE="/repo/source"'), true)
|
|
86
|
+
assert.equal(envFile.includes('KANBAN_WORKSPACE='), true)
|
|
73
87
|
})
|
|
74
88
|
|
|
75
89
|
it('deduplicates preview URLs and computes blocked, stale, and retrying liveness', () => {
|
|
@@ -7,6 +7,8 @@ import type {
|
|
|
7
7
|
TaskExecutionWorkspace,
|
|
8
8
|
TaskLivenessSnapshot,
|
|
9
9
|
TaskPreviewLink,
|
|
10
|
+
TaskRuntimeContextPacket,
|
|
11
|
+
TaskRuntimeEnvHint,
|
|
10
12
|
TaskRuntimeService,
|
|
11
13
|
} from '@/types'
|
|
12
14
|
|
|
@@ -182,11 +184,106 @@ function writeWorkspaceReadme(task: BoardTask, workspacePath: string, now: numbe
|
|
|
182
184
|
]
|
|
183
185
|
if (task.projectId) lines.push(`Project ID: ${task.projectId}`)
|
|
184
186
|
if (task.cwd) lines.push(`Source cwd: ${task.cwd}`)
|
|
185
|
-
lines.push(
|
|
187
|
+
lines.push(
|
|
188
|
+
'',
|
|
189
|
+
'Runtime context: ./context.json',
|
|
190
|
+
'Environment hints: ./.env.swarmclaw',
|
|
191
|
+
'',
|
|
192
|
+
'Use this directory for task-local notes, generated artifacts, and preview handoff files.',
|
|
193
|
+
)
|
|
186
194
|
fs.writeFileSync(readmePath, `${lines.join('\n')}\n`, 'utf8')
|
|
187
195
|
return readmePath
|
|
188
196
|
}
|
|
189
197
|
|
|
198
|
+
function addEnvHint(out: TaskRuntimeEnvHint[], key: string, value: unknown, description?: string) {
|
|
199
|
+
if (typeof value !== 'string' || !value) return
|
|
200
|
+
out.push({ key, value, ...(description ? { description } : {}) })
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function buildRuntimeEnvHints(params: {
|
|
204
|
+
task: BoardTask
|
|
205
|
+
workspacePath: string
|
|
206
|
+
sourceCwd?: string | null
|
|
207
|
+
mode: TaskExecutionWorkspace['mode']
|
|
208
|
+
contextPath: string
|
|
209
|
+
envPath: string
|
|
210
|
+
}): TaskRuntimeEnvHint[] {
|
|
211
|
+
const { task, workspacePath, sourceCwd, mode, contextPath, envPath } = params
|
|
212
|
+
const hints: TaskRuntimeEnvHint[] = []
|
|
213
|
+
const workspaceId = taskWorkspaceSlug(task)
|
|
214
|
+
addEnvHint(hints, 'SWARMCLAW_TASK_ID', task.id, 'SwarmClaw task id')
|
|
215
|
+
addEnvHint(hints, 'SWARMCLAW_TASK_TITLE', task.title || 'Task', 'SwarmClaw task title')
|
|
216
|
+
addEnvHint(hints, 'SWARMCLAW_TASK_STATUS', task.status, 'SwarmClaw task status')
|
|
217
|
+
addEnvHint(hints, 'SWARMCLAW_TASK_AGENT_ID', task.agentId, 'Assigned SwarmClaw agent id')
|
|
218
|
+
addEnvHint(hints, 'SWARMCLAW_WORKSPACE_ID', workspaceId, 'Stable task workspace id')
|
|
219
|
+
addEnvHint(hints, 'SWARMCLAW_WORKSPACE_CWD', workspacePath, 'Task workspace directory')
|
|
220
|
+
addEnvHint(hints, 'SWARMCLAW_WORKSPACE_MODE', mode, 'Task workspace mode')
|
|
221
|
+
addEnvHint(hints, 'SWARMCLAW_WORKSPACE_CONTEXT', contextPath, 'Runtime context packet path')
|
|
222
|
+
addEnvHint(hints, 'SWARMCLAW_WORKSPACE_ENV', envPath, 'Reusable runtime env file')
|
|
223
|
+
addEnvHint(hints, 'SWARMCLAW_PROJECT_ID', task.projectId || '', 'SwarmClaw project id')
|
|
224
|
+
addEnvHint(hints, 'SWARMCLAW_SOURCE_CWD', sourceCwd || '', 'Original source directory')
|
|
225
|
+
addEnvHint(hints, 'AGENT_HOME', workspacePath, 'Agent-local home directory')
|
|
226
|
+
addEnvHint(hints, 'TASK_ID', task.id, 'Portable task id')
|
|
227
|
+
addEnvHint(hints, 'TASK_TITLE', task.title || 'Task', 'Portable task title')
|
|
228
|
+
addEnvHint(hints, 'WORKSPACE_ID', workspaceId, 'Portable workspace id')
|
|
229
|
+
addEnvHint(hints, 'WORKSPACE_CWD', workspacePath, 'Portable workspace cwd')
|
|
230
|
+
addEnvHint(hints, 'WORKSPACE_SOURCE', sourceCwd || workspacePath, 'Portable source path')
|
|
231
|
+
addEnvHint(
|
|
232
|
+
hints,
|
|
233
|
+
'WORKSPACE_STRATEGY',
|
|
234
|
+
mode === 'project' ? 'project-task-workspace' : 'task-workspace',
|
|
235
|
+
'Portable workspace strategy',
|
|
236
|
+
)
|
|
237
|
+
addEnvHint(hints, 'KANBAN_TASK_ID', task.id, 'Portable board task id')
|
|
238
|
+
addEnvHint(hints, 'KANBAN_WORKSPACE', workspacePath, 'Portable board workspace path')
|
|
239
|
+
return hints
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function envLine(hint: TaskRuntimeEnvHint): string {
|
|
243
|
+
return `${hint.key}=${JSON.stringify(hint.value)}`
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function writeWorkspaceEnv(envPath: string, hints: TaskRuntimeEnvHint[]) {
|
|
247
|
+
const lines = [
|
|
248
|
+
'# Generated by SwarmClaw. Contains task context only, not secrets.',
|
|
249
|
+
...hints.map(envLine),
|
|
250
|
+
]
|
|
251
|
+
fs.writeFileSync(envPath, `${lines.join('\n')}\n`, 'utf8')
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function buildTaskRuntimeContext(params: {
|
|
255
|
+
task: BoardTask
|
|
256
|
+
executionWorkspace: Omit<TaskExecutionWorkspace, 'context'>
|
|
257
|
+
previewLinks: TaskPreviewLink[]
|
|
258
|
+
runtimeServices: TaskRuntimeService[]
|
|
259
|
+
generatedAt: number
|
|
260
|
+
}): TaskRuntimeContextPacket {
|
|
261
|
+
const { task, executionWorkspace, previewLinks, runtimeServices, generatedAt } = params
|
|
262
|
+
return {
|
|
263
|
+
taskId: task.id,
|
|
264
|
+
title: task.title || 'Task',
|
|
265
|
+
description: task.description || undefined,
|
|
266
|
+
status: task.status,
|
|
267
|
+
agentId: task.agentId,
|
|
268
|
+
projectId: executionWorkspace.projectId || null,
|
|
269
|
+
workspacePath: executionWorkspace.path,
|
|
270
|
+
sourceCwd: executionWorkspace.sourceCwd || null,
|
|
271
|
+
mode: executionWorkspace.mode,
|
|
272
|
+
preparedAt: executionWorkspace.preparedAt,
|
|
273
|
+
generatedAt,
|
|
274
|
+
previewLinks,
|
|
275
|
+
runtimeServices,
|
|
276
|
+
blockedBy: task.blockedBy,
|
|
277
|
+
blocks: task.blocks,
|
|
278
|
+
tags: task.tags,
|
|
279
|
+
upstreamResults: task.upstreamResults,
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function writeWorkspaceContext(contextPath: string, context: TaskRuntimeContextPacket) {
|
|
284
|
+
fs.writeFileSync(contextPath, `${JSON.stringify(context, null, 2)}\n`, 'utf8')
|
|
285
|
+
}
|
|
286
|
+
|
|
190
287
|
export function computeTaskLiveness(
|
|
191
288
|
task: BoardTask,
|
|
192
289
|
tasks: Record<string, BoardTask> = {},
|
|
@@ -284,6 +381,8 @@ export function prepareTaskExecutionWorkspace(
|
|
|
284
381
|
const existing = task.executionWorkspace || null
|
|
285
382
|
const workspacePath = existing?.path || path.join(taskWorkspaceRoot(task, workspaceRoot), taskWorkspaceSlug(task))
|
|
286
383
|
fs.mkdirSync(workspacePath, { recursive: true })
|
|
384
|
+
const contextPath = path.join(workspacePath, 'context.json')
|
|
385
|
+
const envPath = path.join(workspacePath, '.env.swarmclaw')
|
|
287
386
|
const readmePath = writeWorkspaceReadme(task, workspacePath, now)
|
|
288
387
|
const previewLinks = normalizeTaskPreviewLinks(
|
|
289
388
|
task.previewLinks || existing?.previewLinks,
|
|
@@ -295,17 +394,45 @@ export function prepareTaskExecutionWorkspace(
|
|
|
295
394
|
options.runtimeServices,
|
|
296
395
|
now,
|
|
297
396
|
)
|
|
298
|
-
const
|
|
397
|
+
const mode: TaskExecutionWorkspace['mode'] = task.projectId ? 'project' : 'task'
|
|
398
|
+
const sourceCwd = task.cwd || existing?.sourceCwd || null
|
|
399
|
+
const projectId = task.projectId || existing?.projectId || null
|
|
400
|
+
const preparedAt = existing?.preparedAt || now
|
|
401
|
+
const envHints = buildRuntimeEnvHints({
|
|
402
|
+
task,
|
|
403
|
+
workspacePath,
|
|
404
|
+
sourceCwd,
|
|
405
|
+
mode,
|
|
406
|
+
contextPath,
|
|
407
|
+
envPath,
|
|
408
|
+
})
|
|
409
|
+
const executionWorkspaceBase: Omit<TaskExecutionWorkspace, 'context'> = {
|
|
299
410
|
path: workspacePath,
|
|
300
|
-
mode
|
|
301
|
-
sourceCwd
|
|
302
|
-
projectId
|
|
303
|
-
preparedAt
|
|
411
|
+
mode,
|
|
412
|
+
sourceCwd,
|
|
413
|
+
projectId,
|
|
414
|
+
preparedAt,
|
|
304
415
|
preparedBy: options.actor || existing?.preparedBy || null,
|
|
305
416
|
readmePath,
|
|
417
|
+
contextPath,
|
|
418
|
+
envPath,
|
|
419
|
+
envHints,
|
|
306
420
|
previewLinks,
|
|
307
421
|
runtimeServices,
|
|
308
422
|
}
|
|
423
|
+
const context = buildTaskRuntimeContext({
|
|
424
|
+
task,
|
|
425
|
+
executionWorkspace: executionWorkspaceBase,
|
|
426
|
+
previewLinks,
|
|
427
|
+
runtimeServices,
|
|
428
|
+
generatedAt: now,
|
|
429
|
+
})
|
|
430
|
+
writeWorkspaceContext(contextPath, context)
|
|
431
|
+
writeWorkspaceEnv(envPath, envHints)
|
|
432
|
+
const executionWorkspace: TaskExecutionWorkspace = {
|
|
433
|
+
...executionWorkspaceBase,
|
|
434
|
+
context,
|
|
435
|
+
}
|
|
309
436
|
const taskForLiveness = {
|
|
310
437
|
...task,
|
|
311
438
|
executionWorkspace,
|
package/src/types/agent.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { ProviderId, ProviderType, OllamaMode } from './provider'
|
|
|
2
2
|
import type { SessionResetMode, IdentityContinuityState } from './session'
|
|
3
3
|
import type { SkillAllowlistMode } from './skill'
|
|
4
4
|
import type { DreamConfig } from './dream'
|
|
5
|
+
import type { ExtensionManagedResourceMarker } from './extension'
|
|
5
6
|
|
|
6
7
|
// --- SwarmFeed Heartbeat ---
|
|
7
8
|
|
|
@@ -237,6 +238,7 @@ export interface Agent {
|
|
|
237
238
|
swarmfeedLastAutoPostAt?: number | null
|
|
238
239
|
origin?: 'swarmdock' | 'swarmfeed' | 'swarmclaw' | 'external'
|
|
239
240
|
swarmfeedHeartbeat?: SwarmFeedHeartbeatConfig | null
|
|
241
|
+
managedByExtension?: ExtensionManagedResourceMarker | null
|
|
240
242
|
|
|
241
243
|
// SwarmDock (marketplace integration)
|
|
242
244
|
swarmdockEnabled?: boolean
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { SessionResetMode } from './session'
|
|
2
|
+
import type { ExtensionManagedLocalFolderDeclaration } from './extension'
|
|
2
3
|
|
|
3
4
|
// --- App Settings ---
|
|
4
5
|
export type LoopMode = 'bounded' | 'ongoing'
|
|
@@ -150,6 +151,13 @@ export interface AppSettings {
|
|
|
150
151
|
toolLoopCircuitBreaker?: number
|
|
151
152
|
// Per-extension settings (keyed by extensionId)
|
|
152
153
|
extensionSettings?: Record<string, Record<string, unknown>>
|
|
154
|
+
// Extension-managed resource settings such as trusted local folder roots.
|
|
155
|
+
extensionManagedResources?: Record<string, {
|
|
156
|
+
localFolders?: Record<string, ExtensionManagedLocalFolderDeclaration & {
|
|
157
|
+
path?: string | null
|
|
158
|
+
updatedAt?: number
|
|
159
|
+
}>
|
|
160
|
+
}>
|
|
153
161
|
// Approval policies — opt-in governance gates for sensitive operations
|
|
154
162
|
approvalPolicies?: {
|
|
155
163
|
requireApprovalForAgentCreate?: boolean
|
package/src/types/extension.ts
CHANGED
|
@@ -251,6 +251,125 @@ export interface ExtensionUIDefinition {
|
|
|
251
251
|
}>
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
+
export type ExtensionManagedResourceKind = 'agent' | 'schedule' | 'local_folder'
|
|
255
|
+
|
|
256
|
+
export interface ExtensionManagedResourceRef {
|
|
257
|
+
extensionId?: string
|
|
258
|
+
resourceKind: 'agent' | 'schedule'
|
|
259
|
+
resourceKey: string
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export interface ExtensionManagedResourceMarker {
|
|
263
|
+
extensionId: string
|
|
264
|
+
extensionName?: string | null
|
|
265
|
+
resourceKind: ExtensionManagedResourceKind
|
|
266
|
+
resourceKey: string
|
|
267
|
+
declarationHash?: string | null
|
|
268
|
+
reconciledAt: number
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export interface ExtensionManagedAgentDeclaration {
|
|
272
|
+
agentKey: string
|
|
273
|
+
displayName: string
|
|
274
|
+
description?: string | null
|
|
275
|
+
systemPrompt?: string | null
|
|
276
|
+
instructions?: {
|
|
277
|
+
content?: string | null
|
|
278
|
+
entryFile?: string | null
|
|
279
|
+
assetPath?: string | null
|
|
280
|
+
} | null
|
|
281
|
+
provider?: ProviderId | string | null
|
|
282
|
+
model?: string | null
|
|
283
|
+
apiEndpoint?: string | null
|
|
284
|
+
credentialId?: string | null
|
|
285
|
+
fallbackCredentialIds?: string[]
|
|
286
|
+
gatewayProfileId?: string | null
|
|
287
|
+
preferredGatewayTags?: string[]
|
|
288
|
+
preferredGatewayUseCase?: string | null
|
|
289
|
+
capabilities?: string[] | string | null
|
|
290
|
+
tools?: string[]
|
|
291
|
+
extensions?: string[]
|
|
292
|
+
skills?: string[]
|
|
293
|
+
skillIds?: string[]
|
|
294
|
+
mcpServerIds?: string[]
|
|
295
|
+
monthlyBudget?: number | null
|
|
296
|
+
dailyBudget?: number | null
|
|
297
|
+
hourlyBudget?: number | null
|
|
298
|
+
disabled?: boolean
|
|
299
|
+
heartbeatEnabled?: boolean
|
|
300
|
+
planningMode?: 'off' | 'strict' | null
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
export interface ExtensionManagedScheduleTrigger {
|
|
304
|
+
kind?: 'schedule' | 'api' | 'webhook'
|
|
305
|
+
label?: string | null
|
|
306
|
+
enabled?: boolean
|
|
307
|
+
cronExpression?: string | null
|
|
308
|
+
timezone?: string | null
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
export interface ExtensionManagedScheduleDeclaration {
|
|
312
|
+
scheduleKey?: string
|
|
313
|
+
routineKey?: string
|
|
314
|
+
displayName?: string
|
|
315
|
+
title?: string
|
|
316
|
+
description?: string | null
|
|
317
|
+
taskPrompt?: string | null
|
|
318
|
+
message?: string | null
|
|
319
|
+
taskMode?: 'task' | 'wake_only' | 'protocol'
|
|
320
|
+
agentId?: string | null
|
|
321
|
+
agentRef?: ExtensionManagedResourceRef | null
|
|
322
|
+
assigneeRef?: ExtensionManagedResourceRef | null
|
|
323
|
+
scheduleType?: 'cron' | 'interval' | 'once'
|
|
324
|
+
cron?: string | null
|
|
325
|
+
intervalMs?: number | null
|
|
326
|
+
runAt?: number | null
|
|
327
|
+
timezone?: string | null
|
|
328
|
+
status?: 'active' | 'paused' | 'completed' | 'failed' | 'archived'
|
|
329
|
+
priority?: string | null
|
|
330
|
+
triggers?: ExtensionManagedScheduleTrigger[]
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
export interface ExtensionManagedLocalFolderDeclaration {
|
|
334
|
+
folderKey: string
|
|
335
|
+
displayName: string
|
|
336
|
+
description?: string | null
|
|
337
|
+
access?: 'read' | 'readWrite'
|
|
338
|
+
requiredDirectories?: string[]
|
|
339
|
+
requiredFiles?: string[]
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
export interface ExtensionGatewayPlatformDeclaration {
|
|
343
|
+
platformKey: string
|
|
344
|
+
displayName: string
|
|
345
|
+
description?: string | null
|
|
346
|
+
transport?: 'http' | 'ws' | 'stdio' | 'cli' | 'gateway' | 'custom'
|
|
347
|
+
endpoint?: string | null
|
|
348
|
+
authMode?: 'none' | 'bearer' | 'api_key' | 'oauth' | 'custom'
|
|
349
|
+
setupCheckKey?: string | null
|
|
350
|
+
capabilities?: string[]
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
export interface ExtensionSetupCheckDeclaration {
|
|
354
|
+
checkKey: string
|
|
355
|
+
displayName: string
|
|
356
|
+
description?: string | null
|
|
357
|
+
kind: 'env' | 'command' | 'url' | 'manual'
|
|
358
|
+
target?: string | null
|
|
359
|
+
required?: boolean
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
export interface ExtensionManagedResources {
|
|
363
|
+
agents?: ExtensionManagedAgentDeclaration[]
|
|
364
|
+
schedules?: ExtensionManagedScheduleDeclaration[]
|
|
365
|
+
/** Paperclip-compatible alias. SwarmClaw reconciles routines as managed schedules. */
|
|
366
|
+
routines?: ExtensionManagedScheduleDeclaration[]
|
|
367
|
+
localFolders?: ExtensionManagedLocalFolderDeclaration[]
|
|
368
|
+
/** Hermes-style gateway/platform declaration metadata for setup and diagnostics surfaces. */
|
|
369
|
+
gatewayPlatforms?: ExtensionGatewayPlatformDeclaration[]
|
|
370
|
+
setupChecks?: ExtensionSetupCheckDeclaration[]
|
|
371
|
+
}
|
|
372
|
+
|
|
254
373
|
export interface ExtensionProviderDefinition {
|
|
255
374
|
id: string
|
|
256
375
|
name: string
|
|
@@ -300,6 +419,14 @@ export interface Extension {
|
|
|
300
419
|
ui?: ExtensionUIDefinition
|
|
301
420
|
providers?: ExtensionProviderDefinition[]
|
|
302
421
|
connectors?: ExtensionConnectorDefinition[]
|
|
422
|
+
managedResources?: ExtensionManagedResources
|
|
423
|
+
/** Paperclip-compatible top-level aliases. Prefer managedResources for new SwarmClaw extensions. */
|
|
424
|
+
agents?: ExtensionManagedAgentDeclaration[]
|
|
425
|
+
schedules?: ExtensionManagedScheduleDeclaration[]
|
|
426
|
+
routines?: ExtensionManagedScheduleDeclaration[]
|
|
427
|
+
localFolders?: ExtensionManagedLocalFolderDeclaration[]
|
|
428
|
+
gatewayPlatforms?: ExtensionGatewayPlatformDeclaration[]
|
|
429
|
+
setupChecks?: ExtensionSetupCheckDeclaration[]
|
|
303
430
|
}
|
|
304
431
|
|
|
305
432
|
export interface ExtensionMeta {
|
|
@@ -325,6 +452,11 @@ export interface ExtensionMeta {
|
|
|
325
452
|
hasUI?: boolean
|
|
326
453
|
providerCount?: number
|
|
327
454
|
connectorCount?: number
|
|
455
|
+
managedAgentCount?: number
|
|
456
|
+
managedScheduleCount?: number
|
|
457
|
+
localFolderCount?: number
|
|
458
|
+
gatewayPlatformCount?: number
|
|
459
|
+
setupCheckCount?: number
|
|
328
460
|
createdByAgentId?: string | null
|
|
329
461
|
settingsFields?: ExtensionSettingsField[]
|
|
330
462
|
hasDependencyManifest?: boolean
|
package/src/types/misc.ts
CHANGED
|
@@ -672,6 +672,8 @@ export interface OpenClawGatewayStats {
|
|
|
672
672
|
externalRuntimeCount?: number
|
|
673
673
|
sessionCount?: number
|
|
674
674
|
presenceCount?: number
|
|
675
|
+
environmentCount?: number
|
|
676
|
+
availableEnvironmentCount?: number
|
|
675
677
|
lastTopologyCheckedAt?: number
|
|
676
678
|
lastTopologyErrorCount?: number
|
|
677
679
|
lastTopologyError?: string | null
|
|
@@ -803,7 +805,19 @@ export interface OpenClawGatewayPresenceEntry {
|
|
|
803
805
|
updatedAt?: number | null
|
|
804
806
|
}
|
|
805
807
|
|
|
808
|
+
export type OpenClawEnvironmentStatus = 'available' | 'unavailable' | 'starting' | 'stopping' | 'error'
|
|
809
|
+
|
|
810
|
+
export interface OpenClawEnvironmentSummary {
|
|
811
|
+
id: string
|
|
812
|
+
type: string
|
|
813
|
+
label?: string | null
|
|
814
|
+
status: OpenClawEnvironmentStatus
|
|
815
|
+
capabilities?: string[]
|
|
816
|
+
}
|
|
817
|
+
|
|
806
818
|
export interface OpenClawGatewayTopologyStats extends OpenClawGatewayStats {
|
|
819
|
+
environmentCount: number
|
|
820
|
+
availableEnvironmentCount: number
|
|
807
821
|
pendingPairingCount: number
|
|
808
822
|
hasErrors: boolean
|
|
809
823
|
}
|
|
@@ -819,6 +833,23 @@ export interface OpenClawGatewayTopology {
|
|
|
819
833
|
pairedDevices: OpenClawPairedDevice[]
|
|
820
834
|
sessions: OpenClawGatewaySession[]
|
|
821
835
|
presence: OpenClawGatewayPresenceEntry[]
|
|
836
|
+
environments: OpenClawEnvironmentSummary[]
|
|
837
|
+
errors: OpenClawGatewayRpcError[]
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
export interface OpenClawGatewayEnvironmentList {
|
|
841
|
+
profile: GatewayProfile
|
|
842
|
+
connected: boolean
|
|
843
|
+
refreshedAt: number
|
|
844
|
+
environments: OpenClawEnvironmentSummary[]
|
|
845
|
+
errors: OpenClawGatewayRpcError[]
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
export interface OpenClawGatewayEnvironmentStatusSnapshot {
|
|
849
|
+
profile: GatewayProfile
|
|
850
|
+
connected: boolean
|
|
851
|
+
refreshedAt: number
|
|
852
|
+
environment: OpenClawEnvironmentSummary | null
|
|
822
853
|
errors: OpenClawGatewayRpcError[]
|
|
823
854
|
}
|
|
824
855
|
|
package/src/types/schedule.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { ExtensionManagedResourceMarker } from './extension'
|
|
2
|
+
|
|
1
3
|
export type ScheduleType = 'cron' | 'interval' | 'once'
|
|
2
4
|
export type ScheduleStatus = 'active' | 'paused' | 'completed' | 'failed' | 'archived'
|
|
3
5
|
export type ScheduleTaskMode = 'task' | 'wake_only' | 'protocol'
|
|
@@ -54,6 +56,7 @@ export interface Schedule {
|
|
|
54
56
|
followupThreadId?: string | null
|
|
55
57
|
followupSenderId?: string | null
|
|
56
58
|
followupSenderName?: string | null
|
|
59
|
+
managedByExtension?: ExtensionManagedResourceMarker | null
|
|
57
60
|
createdAt: number
|
|
58
61
|
updatedAt?: number
|
|
59
62
|
}
|
package/src/types/task.ts
CHANGED
|
@@ -43,6 +43,32 @@ export interface TaskRuntimeService {
|
|
|
43
43
|
updatedAt: number
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
export interface TaskRuntimeEnvHint {
|
|
47
|
+
key: string
|
|
48
|
+
value: string
|
|
49
|
+
description?: string
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface TaskRuntimeContextPacket {
|
|
53
|
+
taskId: string
|
|
54
|
+
title: string
|
|
55
|
+
description?: string
|
|
56
|
+
status: BoardTaskStatus
|
|
57
|
+
agentId: string
|
|
58
|
+
projectId?: string | null
|
|
59
|
+
workspacePath: string
|
|
60
|
+
sourceCwd?: string | null
|
|
61
|
+
mode: TaskExecutionWorkspaceMode
|
|
62
|
+
preparedAt: number
|
|
63
|
+
generatedAt: number
|
|
64
|
+
previewLinks: TaskPreviewLink[]
|
|
65
|
+
runtimeServices: TaskRuntimeService[]
|
|
66
|
+
blockedBy?: string[]
|
|
67
|
+
blocks?: string[]
|
|
68
|
+
tags?: string[]
|
|
69
|
+
upstreamResults?: BoardTask['upstreamResults']
|
|
70
|
+
}
|
|
71
|
+
|
|
46
72
|
export interface TaskExecutionWorkspace {
|
|
47
73
|
path: string
|
|
48
74
|
mode: TaskExecutionWorkspaceMode
|
|
@@ -51,6 +77,10 @@ export interface TaskExecutionWorkspace {
|
|
|
51
77
|
preparedAt: number
|
|
52
78
|
preparedBy?: string | null
|
|
53
79
|
readmePath?: string | null
|
|
80
|
+
contextPath?: string | null
|
|
81
|
+
envPath?: string | null
|
|
82
|
+
envHints?: TaskRuntimeEnvHint[]
|
|
83
|
+
context?: TaskRuntimeContextPacket
|
|
54
84
|
previewLinks: TaskPreviewLink[]
|
|
55
85
|
runtimeServices: TaskRuntimeService[]
|
|
56
86
|
}
|