@swarmclawai/swarmclaw 1.5.70 → 1.6.0
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 +18 -0
- package/package.json +2 -2
- package/scripts/run-next-build.mjs +29 -0
- package/src/app/home/page.tsx +11 -3
- package/src/app/quality/page.tsx +7 -0
- package/src/components/home/home-launchpad.tsx +32 -0
- package/src/components/layout/sidebar-rail.tsx +6 -0
- package/src/components/quality/quality-workspace.tsx +632 -0
- package/src/components/runs/run-list.tsx +53 -2
- package/src/components/shared/command-palette.tsx +1 -0
- package/src/lib/app/navigation.ts +1 -0
- package/src/lib/app/view-constants.test.ts +8 -1
- package/src/lib/app/view-constants.ts +9 -1
- package/src/lib/quality/quality-summary.test.ts +122 -0
- package/src/lib/quality/quality-summary.ts +150 -0
- package/src/lib/server/missions/mission-templates.test.ts +22 -0
- package/src/lib/server/missions/mission-templates.ts +116 -0
- package/src/lib/server/session-tools/web-browser-config.test.ts +5 -0
- package/src/lib/server/session-tools/web-utils.ts +3 -0
- package/src/types/session.ts +1 -1
package/README.md
CHANGED
|
@@ -399,6 +399,24 @@ Operational docs: https://swarmclaw.ai/docs/observability
|
|
|
399
399
|
|
|
400
400
|
## Releases
|
|
401
401
|
|
|
402
|
+
### v1.6.0 Highlights
|
|
403
|
+
|
|
404
|
+
Operator Quality Center release for builders running autonomous agents in production-like workflows.
|
|
405
|
+
|
|
406
|
+
- **New Quality workspace.** `/quality` brings run health, failed/running counts, pending approvals, latest eval scores, and attention shortcuts into one operator surface.
|
|
407
|
+
- **Eval Lab and Approval Desk.** Existing eval and approval APIs are now exposed through a practical UI for running scenarios/suites, reviewing score evidence, and approving or denying human-loop/tool/connector/skill requests.
|
|
408
|
+
- **Run Review upgrades.** The run history now has source filtering and search across run id, source, errors, results, and ownership fields while keeping the existing replay/evidence sheet.
|
|
409
|
+
- **Release-ready mission templates.** New templates cover Release Candidate QA, Agent Cost Audit, Connector Smoke Test, Failed Run Triage, and Weekly Agent Quality Report using the existing mission budget/report model.
|
|
410
|
+
- **Home launchpad quality actions.** First-run users can jump straight to evals, approvals, failed runs, and release QA missions from the operational launchpad.
|
|
411
|
+
|
|
412
|
+
### v1.5.71 Highlights
|
|
413
|
+
|
|
414
|
+
Fast-follow release for [#60](https://github.com/swarmclawai/swarmclaw/pull/60) by [@borislavnnikolov](https://github.com/borislavnnikolov). Thanks Borislav!
|
|
415
|
+
|
|
416
|
+
- **Browser MCP works from standalone builds again.** The Next standalone output now includes the Playwright MCP runtime packages required by packaged SwarmClaw builds.
|
|
417
|
+
- **Host browser launches use cached Chromium.** Local Playwright MCP startup now selects Chromium explicitly instead of depending on a system Chrome install.
|
|
418
|
+
- **Standalone repair is more robust.** The build repair step now fills partially traced Playwright MCP package directories, and the packaging and browser startup paths are covered by regression tests.
|
|
419
|
+
|
|
402
420
|
### v1.5.70 Highlights
|
|
403
421
|
|
|
404
422
|
Fast-follow release for [#56](https://github.com/swarmclawai/swarmclaw/pull/56) by [@latentwill](https://github.com/latentwill). Thanks latentwill!
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@swarmclawai/swarmclaw",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Build and run autonomous AI agents with OpenClaw, Hermes, multiple model providers, orchestration, delegation, memory, skills, schedules, and chat connectors.",
|
|
5
5
|
"main": "electron-dist/main.js",
|
|
6
6
|
"license": "MIT",
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"test:cli": "node --test src/cli/*.test.js bin/*.test.js scripts/postinstall.test.mjs scripts/run-next-build.test.mjs scripts/run-next-typegen.test.mjs",
|
|
88
88
|
"test:setup": "tsx --test src/app/api/setup/check-provider/route.test.ts src/lib/server/provider-model-discovery.test.ts src/components/auth/setup-wizard/utils.test.ts src/components/auth/setup-wizard/types.test.ts src/hooks/setup-done-detection.test.ts src/lib/setup-defaults.test.ts src/lib/server/storage-auth.test.ts src/lib/server/storage-auth-docker.test.ts",
|
|
89
89
|
"test:openclaw": "tsx --test src/lib/openclaw/openclaw-agent-id.test.ts src/lib/openclaw/openclaw-endpoint.test.ts src/lib/server/agents/agent-runtime-config.test.ts src/lib/server/build-llm.test.ts src/lib/server/connectors/connector-routing.test.ts src/lib/server/connectors/openclaw.test.ts src/lib/server/connectors/swarmdock.test.ts src/lib/server/gateway/protocol.test.ts src/lib/server/llm-response-cache.test.ts src/lib/server/mcp-conformance.test.ts src/lib/server/openclaw/agent-resolver.test.ts src/lib/server/openclaw/deploy.test.ts src/lib/server/openclaw/skills-normalize.test.ts src/lib/server/session-tools/openclaw-nodes.test.ts src/lib/server/session-tools/swarmdock.test.ts src/lib/server/tasks/task-quality-gate.test.ts src/lib/server/tasks/task-validation.test.ts src/lib/server/tool-capability-policy.test.ts src/lib/providers/openai.test.ts src/lib/providers/openclaw-exports.test.ts src/app/api/openclaw/dashboard-url/route.test.ts",
|
|
90
|
-
"test:runtime": "tsx --test src/lib/server/mcp-gateway-runtime.test.ts src/lib/server/mcp-connection-pool.test.ts src/lib/server/knowledge-sources.test.ts src/lib/server/chat-execution/chat-execution-grounding.test.ts src/lib/server/chat-execution/chat-turn-preparation.test.ts src/lib/server/chat-execution/iteration-timers.test.ts src/lib/server/chat-execution/post-stream-finalization.test.ts src/lib/server/chats/clear-undo-snapshots.test.ts src/lib/server/connectors/email.test.ts src/lib/server/protocols/protocol-service.test.ts src/lib/server/runtime/run-ledger.test.ts src/lib/server/observability/otel-config.test.ts src/lib/server/safe-parse-body.test.ts src/lib/app/view-constants.test.ts src/app/api/approvals/route.test.ts src/app/api/agents/agents-route.test.ts src/app/api/tasks/tasks-route.test.ts src/app/api/chats/chat-route.test.ts src/app/api/chats/clear-route.test.ts src/app/api/chats/compact-route.test.ts src/app/api/chats/context-status-route.test.ts src/app/api/connectors/connector-doctor-route.test.ts src/app/api/healthz/route.test.ts src/app/api/logs/route.test.ts src/app/api/providers/[id]/route.test.ts src/app/api/tts/route.test.ts",
|
|
90
|
+
"test:runtime": "tsx --test src/lib/server/mcp-gateway-runtime.test.ts src/lib/server/mcp-connection-pool.test.ts src/lib/server/knowledge-sources.test.ts src/lib/server/chat-execution/chat-execution-grounding.test.ts src/lib/server/chat-execution/chat-turn-preparation.test.ts src/lib/server/chat-execution/iteration-timers.test.ts src/lib/server/chat-execution/post-stream-finalization.test.ts src/lib/server/chats/clear-undo-snapshots.test.ts src/lib/server/connectors/email.test.ts src/lib/server/protocols/protocol-service.test.ts src/lib/server/runtime/run-ledger.test.ts src/lib/server/observability/otel-config.test.ts src/lib/server/safe-parse-body.test.ts src/lib/server/missions/mission-templates.test.ts src/lib/app/view-constants.test.ts src/lib/quality/quality-summary.test.ts src/app/api/approvals/route.test.ts src/app/api/agents/agents-route.test.ts src/app/api/tasks/tasks-route.test.ts src/app/api/chats/chat-route.test.ts src/app/api/chats/clear-route.test.ts src/app/api/chats/compact-route.test.ts src/app/api/chats/context-status-route.test.ts src/app/api/connectors/connector-doctor-route.test.ts src/app/api/healthz/route.test.ts src/app/api/logs/route.test.ts src/app/api/providers/[id]/route.test.ts src/app/api/tts/route.test.ts",
|
|
91
91
|
"test:builder": "tsx --test src/features/protocols/builder/utils/nodes-to-template.test.ts src/features/protocols/builder/utils/template-to-nodes.test.ts src/features/protocols/builder/validators/dag-validator.test.ts",
|
|
92
92
|
"test:e2e": "tsx .workbench/browser-e2e/run.ts",
|
|
93
93
|
"test:mcp:conformance": "node --import tsx ./scripts/mcp-conformance-check.ts",
|
|
@@ -35,6 +35,11 @@ export const REQUIRED_NEXT_METADATA_FILES = [
|
|
|
35
35
|
'get-metadata-route.js',
|
|
36
36
|
'is-metadata-route.js',
|
|
37
37
|
]
|
|
38
|
+
export const REQUIRED_STANDALONE_BROWSER_PACKAGES = [
|
|
39
|
+
'@playwright/mcp',
|
|
40
|
+
'playwright',
|
|
41
|
+
'playwright-core',
|
|
42
|
+
]
|
|
38
43
|
|
|
39
44
|
function parsePositiveInteger(value) {
|
|
40
45
|
const parsed = Number.parseInt(String(value ?? '').trim(), 10)
|
|
@@ -187,6 +192,27 @@ export function repairStandaloneCssTreeData(cwd = process.cwd()) {
|
|
|
187
192
|
return repaired
|
|
188
193
|
}
|
|
189
194
|
|
|
195
|
+
export function repairStandaloneBrowserMcpRuntime(cwd = process.cwd()) {
|
|
196
|
+
const standaloneDir = path.join(cwd, '.next', 'standalone')
|
|
197
|
+
if (!fs.existsSync(standaloneDir)) return false
|
|
198
|
+
|
|
199
|
+
let repaired = false
|
|
200
|
+
const standaloneNodeModules = path.join(standaloneDir, 'node_modules')
|
|
201
|
+
for (const packageName of REQUIRED_STANDALONE_BROWSER_PACKAGES) {
|
|
202
|
+
const sourceDir = path.join(cwd, 'node_modules', ...packageName.split('/'))
|
|
203
|
+
const targetDir = path.join(standaloneNodeModules, ...packageName.split('/'))
|
|
204
|
+
if (!fs.existsSync(sourceDir)) {
|
|
205
|
+
throw new Error(`Missing required browser MCP runtime package under ${sourceDir}.`)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
fs.mkdirSync(path.dirname(targetDir), { recursive: true })
|
|
209
|
+
fs.cpSync(sourceDir, targetDir, { recursive: true, force: true })
|
|
210
|
+
repaired = true
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return repaired
|
|
214
|
+
}
|
|
215
|
+
|
|
190
216
|
export function repairStandaloneNextMetadata(cwd = process.cwd()) {
|
|
191
217
|
const standaloneDir = path.join(cwd, '.next', 'standalone')
|
|
192
218
|
if (!fs.existsSync(standaloneDir)) return false
|
|
@@ -248,6 +274,9 @@ function main() {
|
|
|
248
274
|
if (result.status === 0 && repairStandaloneCssTreeData(process.cwd())) {
|
|
249
275
|
console.error('Copied css-tree/data/ into standalone build output.')
|
|
250
276
|
}
|
|
277
|
+
if (result.status === 0 && repairStandaloneBrowserMcpRuntime(process.cwd())) {
|
|
278
|
+
console.error('Copied Playwright MCP runtime packages into standalone build output.')
|
|
279
|
+
}
|
|
251
280
|
process.exit(result.status)
|
|
252
281
|
}
|
|
253
282
|
if (result.signal) {
|
package/src/app/home/page.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
|
-
import { useEffect, useMemo, useState } from 'react'
|
|
3
|
+
import { useEffect, useMemo, useRef, useState } from 'react'
|
|
4
4
|
import { useRouter } from 'next/navigation'
|
|
5
5
|
import { AreaChart, Area, ResponsiveContainer, Tooltip } from 'recharts'
|
|
6
6
|
import { useAppStore } from '@/stores/use-app-store'
|
|
@@ -109,6 +109,7 @@ export default function HomePage() {
|
|
|
109
109
|
const [localhostBrowser, setLocalhostBrowser] = useState(false)
|
|
110
110
|
const [pageReady, setPageReady] = useState(false)
|
|
111
111
|
const [launchpadFlag, setLaunchpadFlag] = useState(false)
|
|
112
|
+
const launchpadFlagConsumedRef = useRef(false)
|
|
112
113
|
const mountedRef = useMountedRef()
|
|
113
114
|
|
|
114
115
|
useEffect(() => {
|
|
@@ -116,9 +117,12 @@ export default function HomePage() {
|
|
|
116
117
|
}, [])
|
|
117
118
|
|
|
118
119
|
useEffect(() => {
|
|
120
|
+
if (launchpadFlagConsumedRef.current) return
|
|
119
121
|
const hasFlag = safeStorageGet(HOME_LAUNCHPAD_AFTER_SETUP_KEY) === '1'
|
|
120
|
-
|
|
121
|
-
|
|
122
|
+
if (!hasFlag) return
|
|
123
|
+
launchpadFlagConsumedRef.current = true
|
|
124
|
+
setLaunchpadFlag(true)
|
|
125
|
+
safeStorageRemove(HOME_LAUNCHPAD_AFTER_SETUP_KEY)
|
|
122
126
|
}, [])
|
|
123
127
|
|
|
124
128
|
const allAgents = Object.values(agents).filter((a) => !a.trashedAt)
|
|
@@ -279,6 +283,10 @@ export default function HomePage() {
|
|
|
279
283
|
onOpenBuilder={openBuilder}
|
|
280
284
|
onOpenConnectors={() => navigateTo('connectors')}
|
|
281
285
|
onOpenUsage={() => navigateTo('usage')}
|
|
286
|
+
onRunEvalSuite={() => navigateTo('quality')}
|
|
287
|
+
onReviewApprovals={() => navigateTo('quality')}
|
|
288
|
+
onInspectFailedRuns={() => navigateTo('quality')}
|
|
289
|
+
onStartReleaseQaMission={() => navigateTo('missions')}
|
|
282
290
|
/>
|
|
283
291
|
</div>
|
|
284
292
|
</MainContent>
|
|
@@ -27,6 +27,10 @@ type Props = {
|
|
|
27
27
|
onOpenBuilder: () => void
|
|
28
28
|
onOpenConnectors: () => void
|
|
29
29
|
onOpenUsage: () => void
|
|
30
|
+
onRunEvalSuite: () => void
|
|
31
|
+
onReviewApprovals: () => void
|
|
32
|
+
onInspectFailedRuns: () => void
|
|
33
|
+
onStartReleaseQaMission: () => void
|
|
30
34
|
}
|
|
31
35
|
|
|
32
36
|
export function HomeLaunchpad({
|
|
@@ -42,6 +46,10 @@ export function HomeLaunchpad({
|
|
|
42
46
|
onOpenBuilder,
|
|
43
47
|
onOpenConnectors,
|
|
44
48
|
onOpenUsage,
|
|
49
|
+
onRunEvalSuite,
|
|
50
|
+
onReviewApprovals,
|
|
51
|
+
onInspectFailedRuns,
|
|
52
|
+
onStartReleaseQaMission,
|
|
45
53
|
}: Props) {
|
|
46
54
|
return (
|
|
47
55
|
<div className="max-w-[980px] mx-auto px-6 py-10">
|
|
@@ -120,6 +128,30 @@ export function HomeLaunchpad({
|
|
|
120
128
|
actionLabel="Open Usage"
|
|
121
129
|
onClick={onOpenUsage}
|
|
122
130
|
/>
|
|
131
|
+
<LaunchActionCard
|
|
132
|
+
title="Run Eval Suite"
|
|
133
|
+
description="Open the Quality Center and run scenario or suite checks against an agent before shipping."
|
|
134
|
+
actionLabel="Open Eval Lab"
|
|
135
|
+
onClick={onRunEvalSuite}
|
|
136
|
+
/>
|
|
137
|
+
<LaunchActionCard
|
|
138
|
+
title="Review Approvals"
|
|
139
|
+
description="Clear pending human-loop, tool, connector, skill, agent, and budget requests from one desk."
|
|
140
|
+
actionLabel="Open Approvals"
|
|
141
|
+
onClick={onReviewApprovals}
|
|
142
|
+
/>
|
|
143
|
+
<LaunchActionCard
|
|
144
|
+
title="Inspect Failed Runs"
|
|
145
|
+
description="Filter recent run failures and open replay evidence without leaving the operator workflow."
|
|
146
|
+
actionLabel="Open Run Review"
|
|
147
|
+
onClick={onInspectFailedRuns}
|
|
148
|
+
/>
|
|
149
|
+
<LaunchActionCard
|
|
150
|
+
title="Start Release QA Mission"
|
|
151
|
+
description="Use a budgeted mission template to collect release readiness evidence and quality notes."
|
|
152
|
+
actionLabel="Open Missions"
|
|
153
|
+
onClick={onStartReleaseQaMission}
|
|
154
|
+
/>
|
|
123
155
|
</div>
|
|
124
156
|
|
|
125
157
|
<div className="mt-8 grid gap-3 md:grid-cols-2 xl:grid-cols-3">
|
|
@@ -305,6 +305,12 @@ export function SidebarRail({
|
|
|
305
305
|
<polyline points="22 12 18 12 15 21 9 3 6 12 2 12" />
|
|
306
306
|
</svg>
|
|
307
307
|
</NavItem>
|
|
308
|
+
<NavItem view="quality" label="Quality" expanded={railExpanded} isActive={isNavActive('quality')} onClick={() => handleNavClick('quality')}>
|
|
309
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
310
|
+
<path d="M9 12l2 2 4-4" />
|
|
311
|
+
<path d="M12 3l7 4v5c0 4.4-2.9 8.5-7 9-4.1-.5-7-4.6-7-9V7l7-4z" />
|
|
312
|
+
</svg>
|
|
313
|
+
</NavItem>
|
|
308
314
|
</div>
|
|
309
315
|
|
|
310
316
|
<div className={`flex flex-col gap-0.5 ${railExpanded ? '' : 'items-center'}`}>
|