Skip to content

Commit 3d57ae5

Browse files
committed
update everything, add autonomy config
1 parent fa4111f commit 3d57ae5

File tree

13 files changed

+497
-100
lines changed

13 files changed

+497
-100
lines changed

apps/code/src/renderer/api/posthogClient.ts

Lines changed: 154 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ import type {
1414
SignalReportStatus,
1515
SignalReportsQueryParams,
1616
SignalReportsResponse,
17+
SignalReportTask,
18+
SignalTeamConfig,
19+
SignalUserAutonomyConfig,
1720
SuggestedReviewersArtefact,
1821
Task,
1922
TaskRun,
@@ -51,6 +54,7 @@ export interface SignalSourceConfig {
5154
| "issue_spiking";
5255
enabled: boolean;
5356
config: Record<string, unknown>;
57+
status?: string | null;
5458
created_at: string;
5559
updated_at: string;
5660
}
@@ -408,7 +412,7 @@ export class PostHogAPIClient {
408412
async listSignalSourceConfigs(
409413
projectId: number,
410414
): Promise<SignalSourceConfig[]> {
411-
const urlPath = `/api/projects/${projectId}/signal_source_configs/`;
415+
const urlPath = `/api/projects/${projectId}/signals/source_configs/`;
412416
const url = new URL(`${this.api.baseUrl}${urlPath}`);
413417
const response = await this.api.fetcher.fetch({
414418
method: "get",
@@ -435,7 +439,7 @@ export class PostHogAPIClient {
435439
config?: Record<string, unknown>;
436440
},
437441
): Promise<SignalSourceConfig> {
438-
const urlPath = `/api/projects/${projectId}/signal_source_configs/`;
442+
const urlPath = `/api/projects/${projectId}/signals/source_configs/`;
439443
const url = new URL(`${this.api.baseUrl}${urlPath}`);
440444
const response = await this.api.fetcher.fetch({
441445
method: "post",
@@ -462,7 +466,7 @@ export class PostHogAPIClient {
462466
configId: string,
463467
updates: { enabled: boolean },
464468
): Promise<SignalSourceConfig> {
465-
const urlPath = `/api/projects/${projectId}/signal_source_configs/${configId}/`;
469+
const urlPath = `/api/projects/${projectId}/signals/source_configs/${configId}/`;
466470
const url = new URL(`${this.api.baseUrl}${urlPath}`);
467471
const response = await this.api.fetcher.fetch({
468472
method: "patch",
@@ -1176,7 +1180,7 @@ export class PostHogAPIClient {
11761180
): Promise<SignalReportsResponse> {
11771181
const teamId = await this.getTeamId();
11781182
const url = new URL(
1179-
`${this.api.baseUrl}/api/projects/${teamId}/signal_reports/`,
1183+
`${this.api.baseUrl}/api/projects/${teamId}/signals/reports/`,
11801184
);
11811185

11821186
if (params?.limit != null) {
@@ -1201,7 +1205,7 @@ export class PostHogAPIClient {
12011205
const response = await this.api.fetcher.fetch({
12021206
method: "get",
12031207
url,
1204-
path: `/api/projects/${teamId}/signal_reports/`,
1208+
path: `/api/projects/${teamId}/signals/reports/`,
12051209
});
12061210

12071211
if (!response.ok) {
@@ -1218,9 +1222,9 @@ export class PostHogAPIClient {
12181222
async getSignalProcessingState(): Promise<SignalProcessingStateResponse> {
12191223
const teamId = await this.getTeamId();
12201224
const url = new URL(
1221-
`${this.api.baseUrl}/api/projects/${teamId}/signal_processing/`,
1225+
`${this.api.baseUrl}/api/projects/${teamId}/signals/processing/`,
12221226
);
1223-
const path = `/api/projects/${teamId}/signal_processing/`;
1227+
const path = `/api/projects/${teamId}/signals/processing/`;
12241228

12251229
const response = await this.api.fetcher.fetch({
12261230
method: "get",
@@ -1246,9 +1250,9 @@ export class PostHogAPIClient {
12461250
): Promise<AvailableSuggestedReviewersResponse> {
12471251
const teamId = await this.getTeamId();
12481252
const url = new URL(
1249-
`${this.api.baseUrl}/api/projects/${teamId}/signal_reports/available_reviewers/`,
1253+
`${this.api.baseUrl}/api/projects/${teamId}/signals/reports/available_reviewers/`,
12501254
);
1251-
const path = `/api/projects/${teamId}/signal_reports/available_reviewers/`;
1255+
const path = `/api/projects/${teamId}/signals/reports/available_reviewers/`;
12521256

12531257
if (query?.trim()) {
12541258
url.searchParams.set("query", query.trim());
@@ -1275,12 +1279,12 @@ export class PostHogAPIClient {
12751279
try {
12761280
const teamId = await this.getTeamId();
12771281
const url = new URL(
1278-
`${this.api.baseUrl}/api/projects/${teamId}/signal_reports/${reportId}/signals/`,
1282+
`${this.api.baseUrl}/api/projects/${teamId}/signals/reports/${reportId}/signals/`,
12791283
);
12801284
const response = await this.api.fetcher.fetch({
12811285
method: "get",
12821286
url,
1283-
path: `/api/projects/${teamId}/signal_reports/${reportId}/signals/`,
1287+
path: `/api/projects/${teamId}/signals/reports/${reportId}/signals/`,
12841288
});
12851289

12861290
if (!response.ok) {
@@ -1307,9 +1311,9 @@ export class PostHogAPIClient {
13071311
): Promise<SignalReportArtefactsResponse> {
13081312
const teamId = await this.getTeamId();
13091313
const url = new URL(
1310-
`${this.api.baseUrl}/api/projects/${teamId}/signal_reports/${reportId}/artefacts/`,
1314+
`${this.api.baseUrl}/api/projects/${teamId}/signals/reports/${reportId}/artefacts/`,
13111315
);
1312-
const path = `/api/projects/${teamId}/signal_reports/${reportId}/artefacts/`;
1316+
const path = `/api/projects/${teamId}/signals/reports/${reportId}/artefacts/`;
13131317

13141318
try {
13151319
const response = await this.api.fetcher.fetch({
@@ -1374,9 +1378,9 @@ export class PostHogAPIClient {
13741378
): Promise<SignalReport> {
13751379
const teamId = await this.getTeamId();
13761380
const url = new URL(
1377-
`${this.api.baseUrl}/api/projects/${teamId}/signal_reports/${reportId}/state/`,
1381+
`${this.api.baseUrl}/api/projects/${teamId}/signals/reports/${reportId}/state/`,
13781382
);
1379-
const path = `/api/projects/${teamId}/signal_reports/${reportId}/state/`;
1383+
const path = `/api/projects/${teamId}/signals/reports/${reportId}/state/`;
13801384

13811385
const response = await this.api.fetcher.fetch({
13821386
method: "post",
@@ -1401,9 +1405,9 @@ export class PostHogAPIClient {
14011405
}> {
14021406
const teamId = await this.getTeamId();
14031407
const url = new URL(
1404-
`${this.api.baseUrl}/api/projects/${teamId}/signal_reports/${reportId}/`,
1408+
`${this.api.baseUrl}/api/projects/${teamId}/signals/reports/${reportId}/`,
14051409
);
1406-
const path = `/api/projects/${teamId}/signal_reports/${reportId}/`;
1410+
const path = `/api/projects/${teamId}/signals/reports/${reportId}/`;
14071411

14081412
const response = await this.api.fetcher.fetch({
14091413
method: "delete",
@@ -1428,9 +1432,9 @@ export class PostHogAPIClient {
14281432
}> {
14291433
const teamId = await this.getTeamId();
14301434
const url = new URL(
1431-
`${this.api.baseUrl}/api/projects/${teamId}/signal_reports/${reportId}/reingest/`,
1435+
`${this.api.baseUrl}/api/projects/${teamId}/signals/reports/${reportId}/reingest/`,
14321436
);
1433-
const path = `/api/projects/${teamId}/signal_reports/${reportId}/reingest/`;
1437+
const path = `/api/projects/${teamId}/signals/reports/${reportId}/reingest/`;
14341438

14351439
const response = await this.api.fetcher.fetch({
14361440
method: "post",
@@ -1449,6 +1453,137 @@ export class PostHogAPIClient {
14491453
};
14501454
}
14511455

1456+
async getSignalReportTasks(
1457+
reportId: string,
1458+
options?: { relationship?: SignalReportTask["relationship"] },
1459+
): Promise<SignalReportTask[]> {
1460+
const teamId = await this.getTeamId();
1461+
const url = new URL(
1462+
`${this.api.baseUrl}/api/projects/${teamId}/signals/reports/${reportId}/tasks/`,
1463+
);
1464+
if (options?.relationship) {
1465+
url.searchParams.set("relationship", options.relationship);
1466+
}
1467+
const path = `/api/projects/${teamId}/signals/reports/${reportId}/tasks/`;
1468+
1469+
const response = await this.api.fetcher.fetch({
1470+
method: "get",
1471+
url,
1472+
path,
1473+
});
1474+
1475+
if (!response.ok) {
1476+
throw new Error(
1477+
`Failed to fetch signal report tasks: ${response.statusText}`,
1478+
);
1479+
}
1480+
1481+
const data = await response.json();
1482+
return data.results ?? [];
1483+
}
1484+
1485+
async getSignalTeamConfig(): Promise<SignalTeamConfig> {
1486+
const teamId = await this.getTeamId();
1487+
const url = new URL(
1488+
`${this.api.baseUrl}/api/projects/${teamId}/signals/config/`,
1489+
);
1490+
const path = `/api/projects/${teamId}/signals/config/`;
1491+
1492+
const response = await this.api.fetcher.fetch({
1493+
method: "get",
1494+
url,
1495+
path,
1496+
});
1497+
1498+
if (!response.ok) {
1499+
throw new Error(
1500+
`Failed to fetch signal team config: ${response.statusText}`,
1501+
);
1502+
}
1503+
1504+
return (await response.json()) as SignalTeamConfig;
1505+
}
1506+
1507+
async updateSignalTeamConfig(updates: {
1508+
default_autostart_priority: string;
1509+
}): Promise<SignalTeamConfig> {
1510+
const teamId = await this.getTeamId();
1511+
const url = new URL(
1512+
`${this.api.baseUrl}/api/projects/${teamId}/signals/config/`,
1513+
);
1514+
const path = `/api/projects/${teamId}/signals/config/`;
1515+
1516+
const response = await this.api.fetcher.fetch({
1517+
method: "post",
1518+
url,
1519+
path,
1520+
overrides: {
1521+
body: JSON.stringify(updates),
1522+
},
1523+
});
1524+
1525+
if (!response.ok) {
1526+
throw new Error(
1527+
`Failed to update signal team config: ${response.statusText}`,
1528+
);
1529+
}
1530+
1531+
return (await response.json()) as SignalTeamConfig;
1532+
}
1533+
1534+
async getSignalUserAutonomyConfig(): Promise<SignalUserAutonomyConfig | null> {
1535+
const url = new URL(`${this.api.baseUrl}/api/users/@me/signal_autonomy/`);
1536+
const path = "/api/users/@me/signal_autonomy/";
1537+
1538+
const response = await this.api.fetcher.fetch({
1539+
method: "get",
1540+
url,
1541+
path,
1542+
});
1543+
1544+
return (await response.json()) as SignalUserAutonomyConfig;
1545+
}
1546+
1547+
async updateSignalUserAutonomyConfig(updates: {
1548+
autostart_priority: string | null;
1549+
}): Promise<SignalUserAutonomyConfig> {
1550+
const url = new URL(`${this.api.baseUrl}/api/users/@me/signal_autonomy/`);
1551+
const path = "/api/users/@me/signal_autonomy/";
1552+
1553+
const response = await this.api.fetcher.fetch({
1554+
method: "post",
1555+
url,
1556+
path,
1557+
overrides: {
1558+
body: JSON.stringify(updates),
1559+
},
1560+
});
1561+
1562+
if (!response.ok) {
1563+
throw new Error(
1564+
`Failed to update signal user autonomy config: ${response.statusText}`,
1565+
);
1566+
}
1567+
return (await response.json()) as SignalUserAutonomyConfig;
1568+
}
1569+
1570+
async deleteSignalUserAutonomyConfig(): Promise<void> {
1571+
const url = new URL(`${this.api.baseUrl}/api/users/@me/signal_autonomy/`);
1572+
const path = "/api/users/@me/signal_autonomy/";
1573+
1574+
const response = await this.api.fetcher.fetch({
1575+
method: "delete",
1576+
url,
1577+
path,
1578+
});
1579+
1580+
if (!response.ok) {
1581+
throw new Error(
1582+
`Failed to delete signal user autonomy config: ${response.statusText}`,
1583+
);
1584+
}
1585+
}
1586+
14521587
async getMcpServers(): Promise<McpRecommendedServer[]> {
14531588
const teamId = await this.getTeamId();
14541589
const url = new URL(

apps/code/src/renderer/features/inbox/components/SignalSourceToggles.tsx

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,24 @@ interface SignalSourceToggleCardProps {
3737
requiresSetup?: boolean;
3838
onSetup?: () => void;
3939
loading?: boolean;
40+
syncStatus?: string | null;
41+
}
42+
43+
function syncStatusLabel(status: string | null | undefined): {
44+
text: string;
45+
color: string;
46+
} | null {
47+
if (!status) return null;
48+
switch (status) {
49+
case "running":
50+
return { text: "Syncing…", color: "var(--amber-11)" };
51+
case "completed":
52+
return { text: "Synced", color: "var(--green-11)" };
53+
case "failed":
54+
return { text: "Sync failed", color: "var(--red-11)" };
55+
default:
56+
return null;
57+
}
4058
}
4159

4260
const SignalSourceToggleCard = memo(function SignalSourceToggleCard({
@@ -49,7 +67,10 @@ const SignalSourceToggleCard = memo(function SignalSourceToggleCard({
4967
requiresSetup,
5068
onSetup,
5169
loading,
70+
syncStatus,
5271
}: SignalSourceToggleCardProps) {
72+
const statusInfo = checked ? syncStatusLabel(syncStatus) : null;
73+
5374
return (
5475
<Box
5576
p="4"
@@ -71,9 +92,20 @@ const SignalSourceToggleCard = memo(function SignalSourceToggleCard({
7192
<Flex align="center" gap="3">
7293
<Box style={{ color: "var(--gray-11)", flexShrink: 0 }}>{icon}</Box>
7394
<Flex direction="column" gap="1">
74-
<Text size="2" weight="medium" style={{ color: "var(--gray-12)" }}>
75-
{label}
76-
</Text>
95+
<Flex align="center" gap="2">
96+
<Text
97+
size="2"
98+
weight="medium"
99+
style={{ color: "var(--gray-12)" }}
100+
>
101+
{label}
102+
</Text>
103+
{statusInfo && (
104+
<Text size="1" style={{ color: statusInfo.color }}>
105+
{statusInfo.text}
106+
</Text>
107+
)}
108+
</Flex>
77109
<Text size="1" style={{ color: "var(--gray-11)" }}>
78110
{description}
79111
</Text>
@@ -217,7 +249,7 @@ interface SignalSourceTogglesProps {
217249
sourceStates?: Partial<
218250
Record<
219251
keyof SignalSourceValues,
220-
{ requiresSetup: boolean; loading: boolean }
252+
{ requiresSetup: boolean; loading: boolean; syncStatus?: string | null }
221253
>
222254
>;
223255
onSetup?: (source: keyof SignalSourceValues) => void;
@@ -269,6 +301,7 @@ export function SignalSourceToggles({
269301
checked={value.session_replay}
270302
onCheckedChange={toggleSessionReplay}
271303
disabled={disabled}
304+
syncStatus={sourceStates?.session_replay?.syncStatus}
272305
/>
273306
<SignalSourceToggleCard
274307
icon={<BugIcon size={20} />}
@@ -277,6 +310,7 @@ export function SignalSourceToggles({
277310
checked={value.error_tracking}
278311
onCheckedChange={toggleErrorTracking}
279312
disabled={disabled}
313+
syncStatus={sourceStates?.error_tracking?.syncStatus}
280314
/>
281315
{evaluations && evaluationsUrl && onToggleEvaluation && (
282316
<EvaluationsSection
@@ -295,6 +329,7 @@ export function SignalSourceToggles({
295329
requiresSetup={sourceStates?.github?.requiresSetup}
296330
onSetup={setupGithub}
297331
loading={sourceStates?.github?.loading}
332+
syncStatus={sourceStates?.github?.syncStatus}
298333
/>
299334
<SignalSourceToggleCard
300335
icon={<KanbanIcon size={20} />}
@@ -306,6 +341,7 @@ export function SignalSourceToggles({
306341
requiresSetup={sourceStates?.linear?.requiresSetup}
307342
onSetup={setupLinear}
308343
loading={sourceStates?.linear?.loading}
344+
syncStatus={sourceStates?.linear?.syncStatus}
309345
/>
310346
<SignalSourceToggleCard
311347
icon={<TicketIcon size={20} />}
@@ -317,6 +353,7 @@ export function SignalSourceToggles({
317353
requiresSetup={sourceStates?.zendesk?.requiresSetup}
318354
onSetup={setupZendesk}
319355
loading={sourceStates?.zendesk?.loading}
356+
syncStatus={sourceStates?.zendesk?.syncStatus}
320357
/>
321358
</Flex>
322359
);

0 commit comments

Comments
 (0)