aidevops 3.29.1 → 3.29.3
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-shared/src/contracts.ts +110 -0
- package/packages/gui-web/src/AppWorkspace.tsx +7 -1
- package/packages/gui-web/src/app-model.ts +29 -0
- package/packages/gui-web/src/dashboard.ts +3 -3
- package/setup.sh +1 -1
package/README.md
CHANGED
|
@@ -58,7 +58,7 @@ The result: an AI operations platform that manages projects across every busines
|
|
|
58
58
|
[](https://github.com/marcusquinn)
|
|
59
59
|
|
|
60
60
|
<!-- Release & Version Info -->
|
|
61
|
-
[](https://github.com/marcusquinn/aidevops/releases)
|
|
62
62
|
[](https://www.npmjs.com/package/aidevops)
|
|
63
63
|
[](https://github.com/marcusquinn/homebrew-tap)
|
|
64
64
|
[](https://github.com/marcusquinn/aidevops)
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.29.
|
|
1
|
+
3.29.3
|
package/aidevops.sh
CHANGED
package/package.json
CHANGED
|
@@ -185,6 +185,100 @@ export interface GuiOpenCodeSessionRegistrySummary {
|
|
|
185
185
|
sessions: GuiOpenCodeSessionSummary[];
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
+
export type GuiConversationType = "ai_session" | "channel" | "dm" | "group_dm" | "worker_thread";
|
|
189
|
+
|
|
190
|
+
export type GuiConversationParticipantKind = "human" | "ai_assistant" | "worker" | "system_bot";
|
|
191
|
+
|
|
192
|
+
export type GuiConversationMessageSenderKind = GuiConversationParticipantKind | "system";
|
|
193
|
+
|
|
194
|
+
export type GuiConversationMessagePartKind = "text" | "file" | "tool_call" | "source" | "tambo_component" | "approval_prompt" | "event_marker";
|
|
195
|
+
|
|
196
|
+
export interface GuiConversationScope {
|
|
197
|
+
tenant_ref: string;
|
|
198
|
+
workspace_ref: string;
|
|
199
|
+
repo_ref: string | null;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export interface GuiConversation {
|
|
203
|
+
id: string;
|
|
204
|
+
type: GuiConversationType;
|
|
205
|
+
title: string;
|
|
206
|
+
scope: GuiConversationScope;
|
|
207
|
+
source_ref: string;
|
|
208
|
+
status: "active" | "archived" | "read_only";
|
|
209
|
+
created_at: string;
|
|
210
|
+
updated_at: string;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export interface GuiConversationParticipant {
|
|
214
|
+
id: string;
|
|
215
|
+
conversation_id: string;
|
|
216
|
+
kind: GuiConversationParticipantKind;
|
|
217
|
+
display_name: string;
|
|
218
|
+
identity_ref: string | null;
|
|
219
|
+
agent_ref: string | null;
|
|
220
|
+
worker_ref: string | null;
|
|
221
|
+
membership_state: "active" | "invited" | "left" | "removed";
|
|
222
|
+
joined_at: string;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export interface GuiConversationUsageMetadata {
|
|
226
|
+
provider_ref: string | null;
|
|
227
|
+
model_ref: string | null;
|
|
228
|
+
input_tokens: number;
|
|
229
|
+
output_tokens: number;
|
|
230
|
+
total_tokens: number;
|
|
231
|
+
cost_ref: string | null;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export interface GuiConversationMessage {
|
|
235
|
+
id: string;
|
|
236
|
+
conversation_id: string;
|
|
237
|
+
sender_participant_id: string | null;
|
|
238
|
+
sender_kind: GuiConversationMessageSenderKind;
|
|
239
|
+
sequence: number;
|
|
240
|
+
status: "draft" | "sent" | "delivered" | "failed" | "redacted";
|
|
241
|
+
usage: GuiConversationUsageMetadata | null;
|
|
242
|
+
created_at: string;
|
|
243
|
+
edited_at: string | null;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export interface GuiConversationMessagePart {
|
|
247
|
+
id: string;
|
|
248
|
+
message_id: string;
|
|
249
|
+
kind: GuiConversationMessagePartKind;
|
|
250
|
+
ordinal: number;
|
|
251
|
+
text: string | null;
|
|
252
|
+
payload_json: Record<string, unknown> | null;
|
|
253
|
+
file_ref: string | null;
|
|
254
|
+
source_ref: string | null;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export interface GuiConversationReaction {
|
|
258
|
+
id: string;
|
|
259
|
+
message_id: string;
|
|
260
|
+
participant_id: string;
|
|
261
|
+
reaction: string;
|
|
262
|
+
created_at: string;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export interface GuiConversationReadState {
|
|
266
|
+
conversation_id: string;
|
|
267
|
+
participant_id: string;
|
|
268
|
+
last_read_message_id: string | null;
|
|
269
|
+
last_read_sequence: number;
|
|
270
|
+
updated_at: string;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export interface GuiConversationThread {
|
|
274
|
+
conversation: GuiConversation;
|
|
275
|
+
participants: GuiConversationParticipant[];
|
|
276
|
+
messages: GuiConversationMessage[];
|
|
277
|
+
parts: GuiConversationMessagePart[];
|
|
278
|
+
reactions: GuiConversationReaction[];
|
|
279
|
+
read_states: GuiConversationReadState[];
|
|
280
|
+
}
|
|
281
|
+
|
|
188
282
|
export type GuiAiProviderId = "anthropic" | "openai" | "cursor" | "google";
|
|
189
283
|
|
|
190
284
|
export interface GuiOAuthPoolAccountSummary {
|
|
@@ -499,3 +593,19 @@ export function assertNoSecretSentinels(value: unknown): void {
|
|
|
499
593
|
export function isReadOnlyManifest(manifest: GuiRouteManifest): boolean {
|
|
500
594
|
return manifest.method === "GET" && manifest.classification === "read";
|
|
501
595
|
}
|
|
596
|
+
|
|
597
|
+
export function sortConversationMessages<TMessage extends Pick<GuiConversationMessage, "sequence" | "created_at">>(messages: TMessage[]): TMessage[] {
|
|
598
|
+
return [...messages].sort((left, right) => left.sequence - right.sequence || left.created_at.localeCompare(right.created_at));
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
export function sortConversationMessageParts<TPart extends Pick<GuiConversationMessagePart, "ordinal">>(parts: TPart[]): TPart[] {
|
|
602
|
+
return [...parts].sort((left, right) => left.ordinal - right.ordinal);
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
export function participantCanReadConversation(thread: GuiConversationThread, participantId: string): boolean {
|
|
606
|
+
return thread.participants.some((participant) => participant.id === participantId && participant.membership_state === "active");
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
export function conversationHasScope(thread: GuiConversationThread, scope: GuiConversationScope): boolean {
|
|
610
|
+
return thread.conversation.scope.tenant_ref === scope.tenant_ref && thread.conversation.scope.workspace_ref === scope.workspace_ref && thread.conversation.scope.repo_ref === scope.repo_ref;
|
|
611
|
+
}
|
|
@@ -129,7 +129,7 @@ function WorkspaceHeader({ activeItem, activeSectionLabel, activeSurface, canGoB
|
|
|
129
129
|
</div>
|
|
130
130
|
<div className="header-actions">
|
|
131
131
|
<div className="header-action-menu">
|
|
132
|
-
<button aria-label="Open help" className="header-icon-button" onClick={() => openItem({ surface: "help" })} title="
|
|
132
|
+
<button aria-label="Open signposts and help" className="header-icon-button" onClick={() => openItem({ surface: "help" })} title="Signposts and help (?)" type="button">
|
|
133
133
|
<FiHelpCircle aria-hidden="true" />
|
|
134
134
|
</button>
|
|
135
135
|
<button aria-expanded={notificationsOpen} aria-label="Open notifications" className="header-icon-button" onClick={() => { setNotificationsOpen((current) => !current); setProfileOpen(false); }} type="button">
|
|
@@ -283,6 +283,12 @@ function SurfaceContent({ activeItem, activeSurface, fileRoot, status }: {
|
|
|
283
283
|
notifications: <NotificationsSurface />,
|
|
284
284
|
admin: <AdminSurface />,
|
|
285
285
|
vault: <VaultSurface status={status} />,
|
|
286
|
+
aiSessions: <PlannedSurface label={text.aiSessions} detail={text.aiSessionsIntro} />,
|
|
287
|
+
channels: <PlannedSurface label={text.channels} detail={text.channelsIntro} />,
|
|
288
|
+
directMessages: <PlannedSurface label={text.directMessages} detail={text.directMessagesIntro} />,
|
|
289
|
+
workers: <PlannedSurface label={text.workers} detail={text.workersIntro} />,
|
|
290
|
+
repos: <PlannedSurface label={text.repos} detail={text.reposIntro} />,
|
|
291
|
+
deployments: <PlannedSurface label={text.deployments} detail={text.deploymentsIntro} />,
|
|
286
292
|
routines: <PlannedSurface label={text.routines} detail={text.routineDetail} />,
|
|
287
293
|
devices: <PlannedSurface label={text.devices} detail={text.devicesIntro} />,
|
|
288
294
|
vpnsProxies: <PlannedSurface label={text.vpnsProxies} detail={text.vpnsProxiesIntro} />,
|
|
@@ -59,6 +59,12 @@ export const surfaceIds = [
|
|
|
59
59
|
"config",
|
|
60
60
|
"localSetup",
|
|
61
61
|
"git",
|
|
62
|
+
"aiSessions",
|
|
63
|
+
"channels",
|
|
64
|
+
"directMessages",
|
|
65
|
+
"workers",
|
|
66
|
+
"repos",
|
|
67
|
+
"deployments",
|
|
62
68
|
"routines",
|
|
63
69
|
"devices",
|
|
64
70
|
"vpnsProxies",
|
|
@@ -163,6 +169,10 @@ export const text = {
|
|
|
163
169
|
hostsIntro: "Recommended and user-owned hosting providers with setup notes later.",
|
|
164
170
|
addRow: "Add row",
|
|
165
171
|
channel: "Channel",
|
|
172
|
+
channels: "Channels",
|
|
173
|
+
channelsIntro: "Team channels use the unified conversation model. Message payloads stay read-only placeholders until encrypted transport and audited write routes land.",
|
|
174
|
+
deployments: "Deployments",
|
|
175
|
+
deploymentsIntro: "Deployment activity, environments, releases, and rollout checks will collect here after repo/deploy adapters land.",
|
|
166
176
|
installation: "Installation",
|
|
167
177
|
installationIntro: "Optional aidevops setup/update components. Toggles are shown as planned controls until writes are enabled.",
|
|
168
178
|
install: "Install",
|
|
@@ -220,15 +230,20 @@ export const text = {
|
|
|
220
230
|
newSession: "New Session",
|
|
221
231
|
sessionHistory: "Session history",
|
|
222
232
|
opencodeSessions: "OpenCode sessions",
|
|
233
|
+
aiSessions: "AI Sessions",
|
|
234
|
+
aiSessionsIntro: "AI sessions bridge OpenCode metadata today and will adopt Turbostarter AI persistence, transport, attachments, tools, and history behind audited routes.",
|
|
223
235
|
simplexReady: "SimpleX transport placeholder: encrypted channel adapters will mount here behind Vault and trust-boundary checks.",
|
|
224
236
|
teams: "Teams",
|
|
225
237
|
directMessages: "Direct Messages",
|
|
238
|
+
directMessagesIntro: "Direct and group DM threads share the unified conversation model while protected payloads remain gated by Vault policy.",
|
|
226
239
|
chatInputPlaceholder: "Write a message when audited session write routes are enabled.",
|
|
227
240
|
localRepoSelector: "Local repo selector",
|
|
228
241
|
performance: "Performance",
|
|
229
242
|
projectWorkIntro: "Document folders for inboxes, campaigns, cases, configuration, feedback, knowledge, maintenance, performance, and reports are planned.",
|
|
230
243
|
projectWork: "Documents",
|
|
231
244
|
projects: "Remote Repos",
|
|
245
|
+
repos: "Repos",
|
|
246
|
+
reposIntro: "Unified repo context for local worktrees, remote repo metadata, worker threads, and future deploy context.",
|
|
232
247
|
readOnly: "Read-only",
|
|
233
248
|
registrars: "Registrars",
|
|
234
249
|
registrarsIntro: "Recommended and user-owned domain registrars.",
|
|
@@ -251,6 +266,8 @@ export const text = {
|
|
|
251
266
|
socialMedia: "Social Media",
|
|
252
267
|
socialMediaIntro: "Social profiles, pages, handles, audience notes, and channel ownership are planned.",
|
|
253
268
|
tasks: "Tasks",
|
|
269
|
+
workers: "Workers",
|
|
270
|
+
workersIntro: "Worker activity, task handoffs, event threads, and status transitions will render here as conversation events and workflow summaries.",
|
|
254
271
|
theme: "Theme",
|
|
255
272
|
appearance: "Appearance",
|
|
256
273
|
hue: "Hue",
|
|
@@ -309,13 +326,21 @@ export const fontSizeOptions: FontSizeOption[] = (["xs", "s", "m", "lg", "xl"] a
|
|
|
309
326
|
cssSize: `${14 + index}px`,
|
|
310
327
|
}));
|
|
311
328
|
|
|
329
|
+
function plannedNavItem(id: SurfaceId, label: string, description: string, icon: SurfaceIconName): SurfaceNavItem {
|
|
330
|
+
return { id, label, description, icon, badge: text.planned };
|
|
331
|
+
}
|
|
332
|
+
|
|
312
333
|
export const navGroups: SurfaceNavGroup[] = [
|
|
313
334
|
{
|
|
314
335
|
label: text.development,
|
|
315
336
|
mode: "devops",
|
|
316
337
|
items: [
|
|
338
|
+
plannedNavItem("aiSessions", text.aiSessions, "AI chat and OpenCode sessions", "terminal"),
|
|
339
|
+
plannedNavItem("workers", text.workers, "Worker activity and event threads", "users"),
|
|
317
340
|
{ id: "git", label: text.localRepos, description: "~/Git explorer", icon: "folder" },
|
|
341
|
+
plannedNavItem("repos", text.repos, "Unified local and remote repo context", "git"),
|
|
318
342
|
{ id: "projects", label: text.projects, description: "repos.json summary", icon: "git" },
|
|
343
|
+
plannedNavItem("deployments", text.deployments, "Release and deployment activity", "download"),
|
|
319
344
|
{ id: "security", label: text.secrets, description: "Secret references and trust boundary", icon: "shield" },
|
|
320
345
|
{ id: "aiProviders", label: text.aiProviders, description: "OAuth account pools", icon: "users" },
|
|
321
346
|
],
|
|
@@ -367,6 +392,8 @@ export const navGroups: SurfaceNavGroup[] = [
|
|
|
367
392
|
label: text.management,
|
|
368
393
|
mode: "comms",
|
|
369
394
|
items: [
|
|
395
|
+
plannedNavItem("channels", text.channels, "Team channels", "hash"),
|
|
396
|
+
plannedNavItem("directMessages", text.directMessages, "Direct and group DMs", "message"),
|
|
370
397
|
{ id: "emailAccounts", label: text.emailAccounts, description: "Mail account sync", icon: "mail", badge: text.planned },
|
|
371
398
|
{ id: "messagingAccounts", label: text.messagingAccounts, description: "Messaging account sync", icon: "message", badge: text.planned },
|
|
372
399
|
{ id: "events", label: text.calendars, description: "CalDAV calendar sync", icon: "calendar", badge: text.planned },
|
|
@@ -573,6 +600,7 @@ export function surfaceRecordCounts(status: GuiStatusData): SurfaceRecordCounts
|
|
|
573
600
|
return {
|
|
574
601
|
agents: status.capabilities.length,
|
|
575
602
|
aiProviders: oauthAccounts,
|
|
603
|
+
aiSessions: status.opencode_sessions.sessions.length,
|
|
576
604
|
apps: status.managed_apps.length || status.ai_apps.length,
|
|
577
605
|
config: status.settings.key_count || status.settings.keys.length,
|
|
578
606
|
git: status.local_repos.total || status.local_repos.repos.length,
|
|
@@ -580,6 +608,7 @@ export function surfaceRecordCounts(status: GuiStatusData): SurfaceRecordCounts
|
|
|
580
608
|
installation: installationRows.length,
|
|
581
609
|
localSetup: status.paths.length,
|
|
582
610
|
projects: status.repos.total || status.repos.repos.length,
|
|
611
|
+
repos: (status.local_repos.total || status.local_repos.repos.length) + (status.repos.total || status.repos.repos.length),
|
|
583
612
|
registrars: populatedInventoryRowCount("registrars"),
|
|
584
613
|
security: status.secrets.length,
|
|
585
614
|
servers: populatedInventoryRowCount("servers"),
|
|
@@ -37,13 +37,13 @@ export function renderDashboardHtml(status: GuiResponseEnvelope<GuiStatusData>):
|
|
|
37
37
|
.map((capability) => `<li>${escapeHtml(capability.label)}: ${escapeHtml(capability.status)}</li>`)
|
|
38
38
|
.join("");
|
|
39
39
|
const navSections = [
|
|
40
|
-
{ heading: "Development", items: ["Local Repos", "Remote Repos", "Secrets", "AI Providers"] },
|
|
40
|
+
{ heading: "Development", items: ["AI Sessions", "Workers", "Local Repos", "Repos", "Remote Repos", "Deployments", "Secrets", "AI Providers"] },
|
|
41
41
|
{ heading: "Account", items: ["Help", "Settings", "Notifications", "Admin"] },
|
|
42
42
|
{ heading: "Operations", items: ["Dashboard", "Vault", "Agents file explorer", "Config", "Local Setup", "Routines"] },
|
|
43
43
|
{ heading: "Infrastructure", items: ["Devices", "VPNs & Proxies", "Apps", "Installation", "Registrars", "Hosts", "Servers"] },
|
|
44
44
|
{ heading: "Identities", items: ["Brands", "Domains", "Personas"] },
|
|
45
45
|
{ heading: "Sites", items: ["Websites", "Forums", "Social Media", "Marketplaces"] },
|
|
46
|
-
{ heading: "Management", items: ["Email Accounts", "Messaging Accounts", "Calendars", "Addressbooks", "Tasks", "Notebooks", "Bookmarks"] },
|
|
46
|
+
{ heading: "Management", items: ["Channels", "Direct Messages", "Email Accounts", "Messaging Accounts", "Calendars", "Addressbooks", "Tasks", "Notebooks", "Bookmarks"] },
|
|
47
47
|
{ heading: "Documents", items: ["Inbox", "Campaigns", "Cases", "Config", "Feedback", "Knowledge", "Maintenance", "Performance", "Reports"] },
|
|
48
48
|
];
|
|
49
49
|
const renderedNavSections = navSections
|
|
@@ -55,7 +55,7 @@ export function renderDashboardHtml(status: GuiResponseEnvelope<GuiStatusData>):
|
|
|
55
55
|
`<h1>aidevops app interface</h1>`,
|
|
56
56
|
`<p>Made for creators.</p>`,
|
|
57
57
|
`<p>AI-assisted development workflows, code quality, and deployment automation.</p>`,
|
|
58
|
-
`<p>Theme follows system preferences with light and dark overrides. Sidebar modes: DevOps and Comms. Appearance controls can be hidden or shown, and include editable Hue, icon Reset, Show borders toggle, Show counts toggle, Font size choices xs, s, m, lg, xl, and Font options: IBM Plex Mono, IBM Plex Sans, IBM Plex Serif, Inter, Menlo (default), Playpen Sans, Poppins, Source Sans, Source Serif, Tilt Neon, Ubuntu Mono. The workspace header includes a command palette, notifications menu, AI Assistant panel, and profile menu with Settings, Theme, Language, Community, Admin, and Logout entries. A desktop status bar shows local readiness, repo totals, secret reference count, provider accounts, and update state.</p>`,
|
|
58
|
+
`<p>Theme follows system preferences with light and dark overrides. Sidebar modes: DevOps and Comms. Appearance controls can be hidden or shown, and include editable Hue, icon Reset, Show borders toggle, Show counts toggle, Font size choices xs, s, m, lg, xl, and Font options: IBM Plex Mono, IBM Plex Sans, IBM Plex Serif, Inter, Menlo (default), Playpen Sans, Poppins, Source Sans, Source Serif, Tilt Neon, Ubuntu Mono. The workspace header includes a command palette, reserved signposts/help slot immediately left of notifications, notifications menu, AI Assistant panel, and profile menu with Settings, Theme, Language, Community, Admin, and Logout entries. A desktop status bar shows local readiness, repo totals, secret reference count, provider accounts, and update state.</p>`,
|
|
59
59
|
`<p>Secret references stay read-only and redacted.</p>`,
|
|
60
60
|
`<p>Vault surfaces show padlock indicators. Encrypted by aidevops Vault; contents visible only when unlocked through app or authorised vault commands.</p>`,
|
|
61
61
|
`<p>${escapeHtml(status.data.update.message)}</p>`,
|
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.29.
|
|
15
|
+
# Version: 3.29.3
|
|
16
16
|
#
|
|
17
17
|
# Quick Install:
|
|
18
18
|
# npm install -g aidevops && aidevops update (recommended)
|