aidevops 3.29.40 → 3.30.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 +1 -1
- package/VERSION +1 -1
- package/aidevops.sh +1 -1
- package/package.json +1 -1
- package/packages/gui-api/src/app.ts +154 -8
- package/packages/gui-api/src/status-pulse-workers-attention.ts +24 -0
- package/packages/gui-api/src/status-pulse-workers-classifiers.ts +99 -0
- package/packages/gui-api/src/status-pulse-workers-values.ts +59 -0
- package/packages/gui-api/src/status-pulse-workers.ts +92 -133
- package/packages/gui-desktop/scripts/install-macos-app.sh +217 -2
- package/packages/gui-shared/src/contracts.ts +76 -3
- package/packages/gui-shared/src/fixtures.ts +11 -0
- package/packages/gui-shared/src/tambo.ts +42 -12
- package/packages/gui-web/src/App.tsx +3 -26
- package/packages/gui-web/src/AppActionTerminal.tsx +12 -5
- package/packages/gui-web/src/DesktopStatusBar.tsx +28 -0
- package/packages/gui-web/src/GenUiCards.tsx +5 -4
- package/packages/gui-web/src/PulseWorkersSurface.tsx +112 -19
- package/packages/gui-web/src/ScreenshotCaptureNotification.tsx +51 -0
- package/packages/gui-web/src/app-model.ts +19 -1
- package/packages/gui-web/src/status-client.ts +2 -0
- package/packages/gui-web/src/styles.css +98 -11
- package/setup.sh +1 -1
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { type ReactElement, useEffect, useState } from "react";
|
|
2
|
+
|
|
3
|
+
export interface ScreenshotCapturedDetail {
|
|
4
|
+
path: string;
|
|
5
|
+
url: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface WebKitExternalLinkWindow extends Window {
|
|
9
|
+
webkit?: {
|
|
10
|
+
messageHandlers?: {
|
|
11
|
+
externalLink?: {
|
|
12
|
+
postMessage: (href: string) => void;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function ScreenshotCaptureNotification({ notification, onDismiss }: { notification: ScreenshotCapturedDetail; onDismiss: () => void }): ReactElement {
|
|
19
|
+
const revealScreenshot = () => {
|
|
20
|
+
const webkit = (window as WebKitExternalLinkWindow).webkit;
|
|
21
|
+
webkit?.messageHandlers?.externalLink?.postMessage(notification.url);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<div className="screenshot-capture-notification" role="status">
|
|
26
|
+
<div>
|
|
27
|
+
<strong>Screenshot captured</strong>
|
|
28
|
+
<span>Saved to <button onClick={revealScreenshot} type="button">{notification.path}</button>; path copied to clipboard.</span>
|
|
29
|
+
</div>
|
|
30
|
+
<button aria-label="Dismiss screenshot notification" onClick={onDismiss} type="button">×</button>
|
|
31
|
+
</div>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function ScreenshotCaptureNotificationHost(): ReactElement | null {
|
|
36
|
+
const [screenshotNotification, setScreenshotNotification] = useState<ScreenshotCapturedDetail | undefined>();
|
|
37
|
+
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
const showScreenshotNotification = (event: Event) => {
|
|
40
|
+
const detail = (event as CustomEvent<Partial<ScreenshotCapturedDetail>>).detail;
|
|
41
|
+
if (detail !== undefined && typeof detail.path === "string" && typeof detail.url === "string") {
|
|
42
|
+
setScreenshotNotification({ path: detail.path, url: detail.url });
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
window.addEventListener("aidevops:screenshot-captured", showScreenshotNotification);
|
|
47
|
+
return () => window.removeEventListener("aidevops:screenshot-captured", showScreenshotNotification);
|
|
48
|
+
}, []);
|
|
49
|
+
|
|
50
|
+
return screenshotNotification ? <ScreenshotCaptureNotification notification={screenshotNotification} onDismiss={() => setScreenshotNotification(undefined)} /> : null;
|
|
51
|
+
}
|
|
@@ -148,6 +148,13 @@ export interface InventorySurfaceConfig {
|
|
|
148
148
|
title: string;
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
+
export interface ChatPrimitiveStackDecision {
|
|
152
|
+
adopt: string[];
|
|
153
|
+
defer: string[];
|
|
154
|
+
foundation: string;
|
|
155
|
+
owner: "local_vite_shell";
|
|
156
|
+
}
|
|
157
|
+
|
|
151
158
|
export type SurfaceRecordCounts = Partial<Record<SurfaceId, number>>;
|
|
152
159
|
|
|
153
160
|
export const text = {
|
|
@@ -278,6 +285,8 @@ export const text = {
|
|
|
278
285
|
workersIntro: "Pulse & Workers brings worker sessions, event streams, outcomes, resources, and systemic fixes into one observability console so attention goes to exceptions, bottlenecks, and reusable improvements instead of raw noise.",
|
|
279
286
|
theme: "Theme",
|
|
280
287
|
appearance: "Appearance",
|
|
288
|
+
approvalExecutionDeferred: "Approval execution is deferred until audited approval tooling exists.",
|
|
289
|
+
devOpsCard: "DevOps card",
|
|
281
290
|
hue: "Hue",
|
|
282
291
|
reset: "Reset",
|
|
283
292
|
showBorders: "Show borders",
|
|
@@ -286,6 +295,8 @@ export const text = {
|
|
|
286
295
|
fontSize: "Font size",
|
|
287
296
|
truncated: "Preview truncated for safety.",
|
|
288
297
|
update: "Update",
|
|
298
|
+
tamboGenUiReadOnly: "Tambo GenUI · read-only",
|
|
299
|
+
unsupportedDevOpsCard: "Unsupported DevOps card",
|
|
289
300
|
vault: "Vault",
|
|
290
301
|
vaultAudit: "Audit Logs",
|
|
291
302
|
vaultBackups: "Backups & Recovery",
|
|
@@ -315,6 +326,13 @@ export const DEFAULT_CONTRAST: ContrastPreference = "low";
|
|
|
315
326
|
export const DEFAULT_FONT: FontPreference = "Inter";
|
|
316
327
|
export const DEFAULT_FONT_SIZE: FontSizePreference = "xs";
|
|
317
328
|
|
|
329
|
+
export const chatPrimitiveStackDecision: ChatPrimitiveStackDecision = {
|
|
330
|
+
owner: "local_vite_shell",
|
|
331
|
+
foundation: "Turbostarter AI patterns supply persistence, AI SDK transport, model selection, attachments, tool/reasoning panels, sharing, and session actions behind audited routes.",
|
|
332
|
+
adopt: ["MessageScroller", "Message", "Bubble", "Attachment", "Marker"],
|
|
333
|
+
defer: ["Tambo ordinary chat persistence", "Tambo channel transport", "React Joyride as chat infrastructure", "Next.js route ownership"],
|
|
334
|
+
};
|
|
335
|
+
|
|
318
336
|
export const contrastOptions: ContrastOption[] = [
|
|
319
337
|
{ value: "low", label: "Low" },
|
|
320
338
|
{ value: "medium", label: "Medium" },
|
|
@@ -368,7 +386,7 @@ export const navGroups: SurfaceNavGroup[] = [
|
|
|
368
386
|
mode: "devops",
|
|
369
387
|
items: [
|
|
370
388
|
plannedNavItem("aiSessions", text.aiSessions, "AI chat and OpenCode sessions", "terminal"),
|
|
371
|
-
|
|
389
|
+
{ id: "workers", label: text.workers, description: "Pulse, worker sessions, outcomes, and resources", icon: "activity" },
|
|
372
390
|
{ id: "git", label: text.localRepos, description: "~/Git explorer", icon: "folder" },
|
|
373
391
|
plannedNavItem("repos", text.repos, "Unified local and remote repo context", "git"),
|
|
374
392
|
{ id: "projects", label: text.projects, description: "repos.json summary", icon: "git" },
|
|
@@ -104,9 +104,11 @@ function normalizeStatusEnvelope(envelope: GuiResponseEnvelope<Partial<GuiStatus
|
|
|
104
104
|
...data.pulse_workers,
|
|
105
105
|
kpis: data.pulse_workers?.kpis ?? statusFixture.pulse_workers.kpis,
|
|
106
106
|
attention: data.pulse_workers?.attention ?? statusFixture.pulse_workers.attention,
|
|
107
|
+
insights: data.pulse_workers?.insights ?? statusFixture.pulse_workers.insights,
|
|
107
108
|
filters: { ...statusFixture.pulse_workers.filters, ...data.pulse_workers?.filters },
|
|
108
109
|
charts: data.pulse_workers?.charts ?? statusFixture.pulse_workers.charts,
|
|
109
110
|
events: data.pulse_workers?.events ?? statusFixture.pulse_workers.events,
|
|
111
|
+
actions: data.pulse_workers?.actions ?? statusFixture.pulse_workers.actions,
|
|
110
112
|
},
|
|
111
113
|
capabilities: data.capabilities ?? statusFixture.capabilities,
|
|
112
114
|
secrets: data.secrets ?? statusFixture.secrets,
|
|
@@ -50,10 +50,10 @@
|
|
|
50
50
|
--bg-primary: #0a0a0a;
|
|
51
51
|
--bg-secondary: #111111;
|
|
52
52
|
--bg-tertiary: #1a1a1a;
|
|
53
|
-
--border: color-mix(in srgb, rgb(255 255 255 /
|
|
54
|
-
--border-hover: color-mix(in srgb, rgb(255 255 255 /
|
|
53
|
+
--border: color-mix(in srgb, rgb(255 255 255 / 15%) 78%, rgb(255 255 255 / 32%));
|
|
54
|
+
--border-hover: color-mix(in srgb, rgb(255 255 255 / 28%) 76%, rgb(255 255 255 / 44%));
|
|
55
55
|
--code-bg: hsl(var(--accent-hue) 18% 6%);
|
|
56
|
-
--glass-panel-shadow: inset 0 1px 0 rgb(255 255 255 /
|
|
56
|
+
--glass-panel-shadow: inset 0 1px 0 rgb(255 255 255 / 13%), inset 0 -1px 0 rgb(0 0 0 / 28%), var(--shadow-soft);
|
|
57
57
|
--notification-error-bg: rgb(255 123 114 / 13%);
|
|
58
58
|
--notification-error-fg: #ff7b72;
|
|
59
59
|
--notification-info-bg: rgb(88 166 255 / 13%);
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
--notification-success-fg: #56d364;
|
|
63
63
|
--notification-warning-bg: rgb(210 153 34 / 15%);
|
|
64
64
|
--notification-warning-fg: #d29922;
|
|
65
|
-
--shadow-soft: 0
|
|
65
|
+
--shadow-soft: 0 26px 84px rgb(0 0 0 / 46%);
|
|
66
66
|
--surface-elevated: #151515;
|
|
67
67
|
--surface-muted: #202020;
|
|
68
68
|
--success-bg: hsl(var(--accent-hue) 74% 66% / 12%);
|
|
@@ -88,8 +88,10 @@
|
|
|
88
88
|
--bg-primary: #050505;
|
|
89
89
|
--bg-secondary: #0b0b0b;
|
|
90
90
|
--bg-tertiary: #141414;
|
|
91
|
-
--border: color-mix(in srgb, rgb(255 255 255 /
|
|
92
|
-
--border-hover: color-mix(in srgb, rgb(255 255 255 /
|
|
91
|
+
--border: color-mix(in srgb, rgb(255 255 255 / 24%) 80%, rgb(255 255 255 / 44%));
|
|
92
|
+
--border-hover: color-mix(in srgb, rgb(255 255 255 / 38%) 82%, rgb(255 255 255 / 52%));
|
|
93
|
+
--glass-panel-shadow: inset 0 1px 0 rgb(255 255 255 / 14%), inset 0 -1px 0 rgb(0 0 0 / 30%), var(--shadow-soft);
|
|
94
|
+
--shadow-soft: 0 28px 88px rgb(0 0 0 / 52%);
|
|
93
95
|
--surface-elevated: #101010;
|
|
94
96
|
--surface-muted: #181818;
|
|
95
97
|
--text-muted: rgb(255 255 255 / 58%);
|
|
@@ -205,13 +207,36 @@ body {
|
|
|
205
207
|
background:
|
|
206
208
|
radial-gradient(ellipse at top left, color-mix(in srgb, var(--accent) 16%, transparent) 0%, transparent 36%),
|
|
207
209
|
var(--bg-secondary);
|
|
210
|
+
background-attachment: fixed;
|
|
211
|
+
background-repeat: no-repeat;
|
|
208
212
|
color: var(--text-primary);
|
|
209
213
|
font-family: var(--font-family-app);
|
|
210
214
|
line-height: 1.6;
|
|
211
215
|
margin: 0;
|
|
216
|
+
min-height: 100vh;
|
|
212
217
|
font-size: var(--font-size-app);
|
|
213
218
|
}
|
|
214
219
|
|
|
220
|
+
:root[data-theme="dark"] body {
|
|
221
|
+
background-image:
|
|
222
|
+
radial-gradient(ellipse 78% 64% at top left,
|
|
223
|
+
hsl(var(--accent-hue) 96% 22% / 62%) 0%,
|
|
224
|
+
hsl(var(--accent-hue) 92% 18% / 34%) 34%,
|
|
225
|
+
transparent 58%),
|
|
226
|
+
radial-gradient(ellipse 72% 62% at bottom right,
|
|
227
|
+
hsl(var(--accent-hue) 90% 16% / 38%) 0%,
|
|
228
|
+
hsl(var(--accent-hue) 84% 12% / 20%) 38%,
|
|
229
|
+
transparent 66%),
|
|
230
|
+
radial-gradient(ellipse 66% 54% at bottom left,
|
|
231
|
+
hsl(var(--accent-hue) 90% 15% / 30%) 0%,
|
|
232
|
+
hsl(var(--accent-hue) 80% 11% / 16%) 38%,
|
|
233
|
+
transparent 68%),
|
|
234
|
+
linear-gradient(135deg,
|
|
235
|
+
color-mix(in srgb, hsl(var(--accent-hue) 92% 16%) 44%, var(--bg-secondary)) 0%,
|
|
236
|
+
color-mix(in srgb, hsl(var(--accent-hue) 80% 12%) 14%, var(--bg-secondary)) 48%,
|
|
237
|
+
color-mix(in srgb, var(--accent) 6%, var(--bg-primary)) 100%);
|
|
238
|
+
}
|
|
239
|
+
|
|
215
240
|
button,
|
|
216
241
|
input,
|
|
217
242
|
select {
|
|
@@ -273,6 +298,68 @@ code {
|
|
|
273
298
|
z-index: 20;
|
|
274
299
|
}
|
|
275
300
|
|
|
301
|
+
.screenshot-capture-notification {
|
|
302
|
+
align-items: center;
|
|
303
|
+
background: color-mix(in srgb, var(--surface-elevated) 94%, transparent);
|
|
304
|
+
border: 1px solid var(--border-accent);
|
|
305
|
+
border-radius: 999px;
|
|
306
|
+
box-shadow: var(--glass-panel-shadow);
|
|
307
|
+
color: var(--text-secondary);
|
|
308
|
+
display: flex;
|
|
309
|
+
gap: 12px;
|
|
310
|
+
left: 50%;
|
|
311
|
+
max-width: min(720px, calc(100vw - 48px));
|
|
312
|
+
padding: 8px 10px 8px 14px;
|
|
313
|
+
position: fixed;
|
|
314
|
+
top: calc(var(--desktop-titlebar-height) + 10px);
|
|
315
|
+
transform: translateX(-50%);
|
|
316
|
+
z-index: 40;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.screenshot-capture-notification > div {
|
|
320
|
+
display: grid;
|
|
321
|
+
gap: 1px;
|
|
322
|
+
min-width: 0;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
.screenshot-capture-notification strong {
|
|
326
|
+
color: var(--text-primary);
|
|
327
|
+
font-size: 0.78rem;
|
|
328
|
+
line-height: 1.2;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.screenshot-capture-notification span {
|
|
332
|
+
font-size: 0.74rem;
|
|
333
|
+
line-height: 1.25;
|
|
334
|
+
overflow: hidden;
|
|
335
|
+
text-overflow: ellipsis;
|
|
336
|
+
white-space: nowrap;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
.screenshot-capture-notification button {
|
|
340
|
+
background: transparent;
|
|
341
|
+
border: 0;
|
|
342
|
+
color: var(--accent);
|
|
343
|
+
font: inherit;
|
|
344
|
+
padding: 0;
|
|
345
|
+
text-decoration: underline;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
.screenshot-capture-notification > button {
|
|
349
|
+
align-items: center;
|
|
350
|
+
background: var(--surface-muted);
|
|
351
|
+
border: 1px solid transparent;
|
|
352
|
+
border-radius: 999px;
|
|
353
|
+
color: var(--text-secondary);
|
|
354
|
+
display: inline-flex;
|
|
355
|
+
flex: 0 0 auto;
|
|
356
|
+
font-size: 1rem;
|
|
357
|
+
height: 24px;
|
|
358
|
+
justify-content: center;
|
|
359
|
+
line-height: 1;
|
|
360
|
+
width: 24px;
|
|
361
|
+
}
|
|
362
|
+
|
|
276
363
|
.machine-rail,
|
|
277
364
|
.app-sidebar,
|
|
278
365
|
.app-inset {
|
|
@@ -1721,7 +1808,7 @@ code {
|
|
|
1721
1808
|
|
|
1722
1809
|
.hero-panel {
|
|
1723
1810
|
background:
|
|
1724
|
-
linear-gradient(135deg, color-mix(in srgb, var(--accent)
|
|
1811
|
+
linear-gradient(135deg, color-mix(in srgb, var(--accent) 11%, transparent), transparent 58%),
|
|
1725
1812
|
var(--surface-elevated);
|
|
1726
1813
|
padding: clamp(24px, 5vw, 42px);
|
|
1727
1814
|
}
|
|
@@ -1849,7 +1936,7 @@ code {
|
|
|
1849
1936
|
|
|
1850
1937
|
.notifications-hero {
|
|
1851
1938
|
background:
|
|
1852
|
-
linear-gradient(135deg, var(--notification-bg, color-mix(in srgb, var(--accent)
|
|
1939
|
+
linear-gradient(135deg, var(--notification-bg, color-mix(in srgb, var(--accent) 10%, transparent)), transparent 62%),
|
|
1853
1940
|
var(--surface-elevated);
|
|
1854
1941
|
}
|
|
1855
1942
|
|
|
@@ -2228,7 +2315,7 @@ code {
|
|
|
2228
2315
|
|
|
2229
2316
|
.pulse-hero {
|
|
2230
2317
|
background:
|
|
2231
|
-
linear-gradient(135deg, color-mix(in srgb, var(--accent)
|
|
2318
|
+
linear-gradient(135deg, color-mix(in srgb, var(--accent) 12%, transparent), transparent 64%),
|
|
2232
2319
|
var(--surface-elevated);
|
|
2233
2320
|
}
|
|
2234
2321
|
|
|
@@ -3149,8 +3236,8 @@ button.managed-toggle:focus-visible {
|
|
|
3149
3236
|
.recommended-app-card:hover,
|
|
3150
3237
|
.recommended-app-card:focus-within {
|
|
3151
3238
|
background:
|
|
3152
|
-
linear-gradient(135deg, color-mix(in srgb, var(--accent)
|
|
3153
|
-
color-mix(in srgb, var(--accent)
|
|
3239
|
+
linear-gradient(135deg, color-mix(in srgb, var(--accent) 11%, transparent), transparent 42%),
|
|
3240
|
+
color-mix(in srgb, var(--accent) 5%, var(--surface-muted));
|
|
3154
3241
|
border-color: var(--border-accent);
|
|
3155
3242
|
box-shadow: 0 18px 46px color-mix(in srgb, var(--accent) 10%, transparent);
|
|
3156
3243
|
transform: translateY(-1px);
|
package/setup.sh
CHANGED
|
@@ -12,7 +12,7 @@ shopt -s inherit_errexit 2>/dev/null || true
|
|
|
12
12
|
# AI Assistant Server Access Framework Setup Script
|
|
13
13
|
# Helps developers set up the framework for their infrastructure
|
|
14
14
|
#
|
|
15
|
-
# Version: 3.
|
|
15
|
+
# Version: 3.30.0
|
|
16
16
|
#
|
|
17
17
|
# Quick Install:
|
|
18
18
|
# npm install -g aidevops && aidevops update (recommended)
|