@agent-native/core 0.72.4 → 0.73.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/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +28 -0
- package/corpus/core/docs/content/skills-guide.md +14 -0
- package/corpus/core/docs/content/template-clips.md +7 -1
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/durable-background.ts +25 -12
- package/corpus/core/src/cli/create.ts +1 -1
- package/corpus/core/src/cli/skills.ts +450 -19
- package/corpus/core/src/server/auth.ts +7 -0
- package/corpus/core/src/server/onboarding-html.ts +95 -9
- package/corpus/core/src/templates/default/AGENTS.md +4 -0
- package/corpus/core/src/templates/default/package.json +2 -1
- package/corpus/core/src/templates/headless/AGENTS.md +4 -0
- package/corpus/core/src/templates/headless/package.json +1 -0
- package/corpus/core/src/templates/workspace-root/AGENTS.md +4 -0
- package/corpus/core/src/templates/workspace-root/README.md +4 -0
- package/corpus/core/src/templates/workspace-root/package.json +1 -0
- package/corpus/templates/analytics/actions/update-dashboard.ts +3 -4
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +144 -40
- package/corpus/templates/analytics/app/global.css +15 -13
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +9 -32
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +0 -26
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +0 -23
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/pivot.ts +65 -2
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +3 -4
- package/corpus/templates/analytics/changelog/2026-06-24-dashboard-charts-now-fill-sparse-template-time-series-suppor.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-24-dashboard-rows-now-auto-fit-panels-so-one-two-or-three-chart.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-24-dashboard-traffic-tables-now-show-top-urls-and-shared-clips-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-24-first-party-signup-and-pageview-panels-now-honor-dashboard-filters.md +5 -0
- package/corpus/templates/analytics/changelog/2026-06-24-first-party-template-dashboards-now-include-repeat-users-ret.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-24-retention-charts-now-break-out-1-day-and-7-day-return-rates-.md +6 -0
- package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +256 -44
- package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +7 -2
- package/corpus/templates/analytics/server/lib/first-party-analytics.ts +35 -8
- package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +287 -42
- package/corpus/templates/calendar/changelog/2026-06-23-added-a-heads-up-explaining-google-s-app-not-verified-screen.md +1 -1
- package/corpus/templates/calendar/server/plugins/auth.ts +12 -0
- package/corpus/templates/clips/.agents/skills/recording/SKILL.md +7 -7
- package/corpus/templates/clips/AGENTS.md +6 -2
- package/corpus/templates/clips/app/components/capture-install-options.tsx +20 -4
- package/corpus/templates/clips/app/components/player/player-controls.tsx +62 -32
- package/corpus/templates/clips/app/lib/capture-install-options.ts +39 -5
- package/corpus/templates/clips/app/routes/download.tsx +2 -2
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +1 -1
- package/corpus/templates/clips/changelog/2026-06-24-inline-slack-playback-controls-no-longer-shift-when-adjustin.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-24-shared-clips-now-expose-their-full-console-log-stream-all-le.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-24-shared-clips-now-expose-their-full-fetch-xhr-network-request.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-24-the-chrome-extension-option-now-only-appears-on-supported-hosts.md +5 -0
- package/corpus/templates/clips/chrome-extension/STORE_DRAFT.md +13 -8
- package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -1
- package/corpus/templates/clips/chrome-extension/scripts/package.ts +15 -2
- package/corpus/templates/clips/chrome-extension/src/overlay.css +4 -25
- package/corpus/templates/clips/chrome-extension/src/overlay.ts +1 -3
- package/corpus/templates/clips/server/lib/public-agent-context.ts +67 -24
- package/corpus/templates/mail/server/plugins/auth.ts +4 -1
- package/corpus/templates/plan/app/pages/PlansPage.tsx +271 -197
- package/corpus/templates/plan/server/plan-content.ts +45 -2
- package/dist/agent/durable-background.d.ts +9 -4
- package/dist/agent/durable-background.d.ts.map +1 -1
- package/dist/agent/durable-background.js +24 -11
- package/dist/agent/durable-background.js.map +1 -1
- package/dist/cli/create.js +1 -1
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +361 -19
- package/dist/cli/skills.js.map +1 -1
- package/dist/server/auth.d.ts +7 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +1 -0
- package/dist/server/auth.js.map +1 -1
- package/dist/server/onboarding-html.d.ts +15 -0
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +73 -9
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/templates/default/AGENTS.md +4 -0
- package/dist/templates/default/package.json +2 -1
- package/dist/templates/headless/AGENTS.md +4 -0
- package/dist/templates/headless/package.json +1 -0
- package/dist/templates/workspace-root/AGENTS.md +4 -0
- package/dist/templates/workspace-root/README.md +4 -0
- package/dist/templates/workspace-root/package.json +1 -0
- package/docs/content/skills-guide.md +14 -0
- package/docs/content/template-clips.md +7 -1
- package/package.json +1 -1
- package/src/templates/default/AGENTS.md +4 -0
- package/src/templates/default/package.json +2 -1
- package/src/templates/headless/AGENTS.md +4 -0
- package/src/templates/headless/package.json +1 -0
- package/src/templates/workspace-root/AGENTS.md +4 -0
- package/src/templates/workspace-root/README.md +4 -0
- package/src/templates/workspace-root/package.json +1 -0
|
@@ -73,6 +73,8 @@ export interface PanelFormValues {
|
|
|
73
73
|
title: string;
|
|
74
74
|
chartType: ChartType;
|
|
75
75
|
source: DataSourceType;
|
|
76
|
+
/** Legacy storage field retained for existing dashboards. Row widths are
|
|
77
|
+
* now inferred from how many panels share the row. */
|
|
76
78
|
width: number;
|
|
77
79
|
/** Section panels only: number of grid columns the panels following this
|
|
78
80
|
* section should use. Ignored when `chartType` is not `"section"`. */
|
|
@@ -226,7 +228,8 @@ function PanelEditorContent({
|
|
|
226
228
|
`If no source can answer, report the exact unavailable/error result instead of saving a panel with guessed schema or metrics. ` +
|
|
227
229
|
`Use the \`update-dashboard\` action with ops=[{op:'insert', path:'/panels/-', value: <panel>}] ` +
|
|
228
230
|
`to append, or an appropriate index to place the panel in the right spot. ` +
|
|
229
|
-
`Panel shape: { id (unique slug), title, sql, source ('bigquery'|'ga4'|'amplitude'|'first-party'|'demo'|'prometheus'), chartType ('line'|'area'|'bar'|'metric'|'table'|'pie'|'section'), width (
|
|
231
|
+
`Panel shape: { id (unique slug), title, sql, source ('bigquery'|'ga4'|'amplitude'|'first-party'|'demo'|'prometheus'), chartType ('line'|'area'|'bar'|'metric'|'table'|'pie'|'section'), width (legacy integer 1..6; set to 1 unless editing existing data), tab? (use 'Group / Tab' for grouped tabs), columns? (section panels only - 1..6 max panels per row for panels following this section), config? }. ` +
|
|
232
|
+
`Visible layout auto-fits by row: one panel in a row spans the row, two split it, three split it into thirds, up to the section column limit. ` +
|
|
230
233
|
`For amplitude panels, sql is a JSON descriptor: {"event":"event name","groupBy":"property","days":30}. ` +
|
|
231
234
|
`For first-party panels, sql is read-only SQL over analytics_events only; use source 'first-party' and do not call db-query for this datasource. ` +
|
|
232
235
|
`For demo panels, sql uses the same Prometheus JSON descriptor shape as source 'prometheus': {"promql":"rate(http_requests_total[5m])","mode":"range","range":"1h","step":"30s"}. ` +
|
|
@@ -310,11 +313,9 @@ function PanelEditorContent({
|
|
|
310
313
|
</Select>
|
|
311
314
|
</div>
|
|
312
315
|
|
|
313
|
-
|
|
314
|
-
<
|
|
315
|
-
|
|
316
|
-
</Label>
|
|
317
|
-
{form.chartType === "section" ? (
|
|
316
|
+
{form.chartType === "section" ? (
|
|
317
|
+
<div className="grid gap-1.5">
|
|
318
|
+
<Label>Section columns</Label>
|
|
318
319
|
<ToggleGroup
|
|
319
320
|
type="single"
|
|
320
321
|
value={String(form.columns)}
|
|
@@ -338,32 +339,8 @@ function PanelEditorContent({
|
|
|
338
339
|
</ToggleGroupItem>
|
|
339
340
|
))}
|
|
340
341
|
</ToggleGroup>
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
type="single"
|
|
344
|
-
value={String(form.width)}
|
|
345
|
-
onValueChange={(v) => {
|
|
346
|
-
if (!v) return;
|
|
347
|
-
const next = clampPanelWidth(Number(v), MAX_DASHBOARD_COLUMNS);
|
|
348
|
-
setForm((f) => ({ ...f, width: next }));
|
|
349
|
-
}}
|
|
350
|
-
className="justify-start h-9"
|
|
351
|
-
>
|
|
352
|
-
{Array.from(
|
|
353
|
-
{ length: MAX_DASHBOARD_COLUMNS },
|
|
354
|
-
(_, i) => i + 1,
|
|
355
|
-
).map((n) => (
|
|
356
|
-
<ToggleGroupItem
|
|
357
|
-
key={n}
|
|
358
|
-
value={String(n)}
|
|
359
|
-
className="h-9 w-9 px-0 text-xs"
|
|
360
|
-
>
|
|
361
|
-
{n}
|
|
362
|
-
</ToggleGroupItem>
|
|
363
|
-
))}
|
|
364
|
-
</ToggleGroup>
|
|
365
|
-
)}
|
|
366
|
-
</div>
|
|
342
|
+
</div>
|
|
343
|
+
) : null}
|
|
367
344
|
</div>
|
|
368
345
|
|
|
369
346
|
<div className="grid gap-1.5">
|
|
@@ -2,8 +2,6 @@ import { useCallback, useEffect, useRef, useState } from "react";
|
|
|
2
2
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
3
3
|
import {
|
|
4
4
|
IconGripVertical,
|
|
5
|
-
IconArrowsMaximize,
|
|
6
|
-
IconArrowsMinimize,
|
|
7
5
|
IconDotsVertical,
|
|
8
6
|
IconMaximize,
|
|
9
7
|
IconPencil,
|
|
@@ -49,13 +47,6 @@ interface SqlChartCardProps {
|
|
|
49
47
|
panel: SqlPanel;
|
|
50
48
|
resolvedSql?: string;
|
|
51
49
|
onRemove: () => void;
|
|
52
|
-
/** Toggle between "span 1 column" and "span all columns of the current
|
|
53
|
-
* section". Optional because section panels never expose this control. */
|
|
54
|
-
onToggleWidth?: () => void;
|
|
55
|
-
/** Number of columns in the section this panel currently lives in. Used to
|
|
56
|
-
* decide the toggle label / icon: when the panel already spans the full
|
|
57
|
-
* row, we offer to shrink; otherwise we offer to expand. */
|
|
58
|
-
gridColumns?: number;
|
|
59
50
|
onEdit?: () => void;
|
|
60
51
|
/** Persist a SQL-only edit from the inline View SQL popover. Should throw on
|
|
61
52
|
* validation failure so the popover can stay open and surface the error. */
|
|
@@ -67,8 +58,6 @@ export function SqlChartCard({
|
|
|
67
58
|
panel,
|
|
68
59
|
resolvedSql,
|
|
69
60
|
onRemove,
|
|
70
|
-
onToggleWidth,
|
|
71
|
-
gridColumns,
|
|
72
61
|
onEdit,
|
|
73
62
|
onSaveSql,
|
|
74
63
|
editable = true,
|
|
@@ -300,21 +289,6 @@ export function SqlChartCard({
|
|
|
300
289
|
</DropdownMenuItem>
|
|
301
290
|
</ViewSqlPopover>
|
|
302
291
|
) : null}
|
|
303
|
-
{editable && onToggleWidth && (gridColumns ?? 2) > 1 && (
|
|
304
|
-
<DropdownMenuItem onSelect={onToggleWidth}>
|
|
305
|
-
{panel.width >= (gridColumns ?? 2) ? (
|
|
306
|
-
<>
|
|
307
|
-
<IconArrowsMinimize className="h-4 w-4 mr-2" />
|
|
308
|
-
Span 1 column
|
|
309
|
-
</>
|
|
310
|
-
) : (
|
|
311
|
-
<>
|
|
312
|
-
<IconArrowsMaximize className="h-4 w-4 mr-2" />
|
|
313
|
-
Span full row
|
|
314
|
-
</>
|
|
315
|
-
)}
|
|
316
|
-
</DropdownMenuItem>
|
|
317
|
-
)}
|
|
318
292
|
{editable ? <DropdownMenuSeparator /> : null}
|
|
319
293
|
{editable && onEdit && (
|
|
320
294
|
<DropdownMenuItem onSelect={() => onEdit()}>
|
|
@@ -79,7 +79,6 @@ import { ViewsMenu } from "./ViewsMenu";
|
|
|
79
79
|
import BlankDashboard from "../BlankDashboard";
|
|
80
80
|
import {
|
|
81
81
|
clampDashboardColumns,
|
|
82
|
-
clampPanelWidth,
|
|
83
82
|
DEFAULT_DASHBOARD_COLUMNS,
|
|
84
83
|
type SqlDashboardConfig,
|
|
85
84
|
type SqlPanel,
|
|
@@ -632,22 +631,6 @@ export default function SqlDashboardPage() {
|
|
|
632
631
|
[dashboard, persist],
|
|
633
632
|
);
|
|
634
633
|
|
|
635
|
-
const toggleWidth = useCallback(
|
|
636
|
-
(panelId: string, gridColumns: number) => {
|
|
637
|
-
if (!dashboard) return;
|
|
638
|
-
const max = clampDashboardColumns(gridColumns);
|
|
639
|
-
persist({
|
|
640
|
-
...dashboard,
|
|
641
|
-
panels: dashboard.panels.map((p) => {
|
|
642
|
-
if (p.id !== panelId) return p;
|
|
643
|
-
const current = clampPanelWidth(p.width, max);
|
|
644
|
-
return { ...p, width: current >= max ? 1 : max };
|
|
645
|
-
}),
|
|
646
|
-
});
|
|
647
|
-
},
|
|
648
|
-
[dashboard, persist],
|
|
649
|
-
);
|
|
650
|
-
|
|
651
634
|
const handleSavePanel = useCallback(
|
|
652
635
|
async (panel: SqlPanel) => {
|
|
653
636
|
if (!dashboard) return;
|
|
@@ -1349,14 +1332,12 @@ export default function SqlDashboardPage() {
|
|
|
1349
1332
|
}
|
|
1350
1333
|
: panel;
|
|
1351
1334
|
const remoteEditor = remoteEditingPanels.get(panel.id);
|
|
1352
|
-
const span = clampPanelWidth(panel.width, group.columns);
|
|
1353
1335
|
return (
|
|
1354
1336
|
<div
|
|
1355
1337
|
key={panel.id}
|
|
1356
1338
|
className="dashboard-grid-cell relative h-full"
|
|
1357
1339
|
style={
|
|
1358
1340
|
{
|
|
1359
|
-
"--panel-span": span,
|
|
1360
1341
|
...(remoteEditor
|
|
1361
1342
|
? {
|
|
1362
1343
|
outline: `2px solid ${remoteEditor.color}`,
|
|
@@ -1384,11 +1365,7 @@ export default function SqlDashboardPage() {
|
|
|
1384
1365
|
serializePanelSql(panel.sql),
|
|
1385
1366
|
vars,
|
|
1386
1367
|
)}
|
|
1387
|
-
gridColumns={group.columns}
|
|
1388
1368
|
onRemove={() => removePanel(panel.id)}
|
|
1389
|
-
onToggleWidth={() =>
|
|
1390
|
-
toggleWidth(panel.id, group.columns)
|
|
1391
|
-
}
|
|
1392
1369
|
onEdit={() => openEditPanel(panel)}
|
|
1393
1370
|
onSaveSql={(sql) => handleSavePanel({ ...panel, sql })}
|
|
1394
1371
|
editable={canEdit}
|
|
@@ -15,6 +15,66 @@ export interface PivotResult {
|
|
|
15
15
|
seriesKeys: string[];
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
const ISO_DAY_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
19
|
+
const MAX_DAILY_GAP_FILL_DAYS = 800;
|
|
20
|
+
|
|
21
|
+
function dayToUtcMs(day: string): number | null {
|
|
22
|
+
if (!ISO_DAY_RE.test(day)) return null;
|
|
23
|
+
const [year, month, date] = day.split("-").map(Number);
|
|
24
|
+
const ms = Date.UTC(year, month - 1, date);
|
|
25
|
+
return Number.isFinite(ms) ? ms : null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function utcMsToDay(ms: number): string {
|
|
29
|
+
return new Date(ms).toISOString().slice(0, 10);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function fillMissingSeries(
|
|
33
|
+
row: Record<string, unknown>,
|
|
34
|
+
seriesKeys: string[],
|
|
35
|
+
): Record<string, unknown> {
|
|
36
|
+
for (const key of seriesKeys) {
|
|
37
|
+
if (!(key in row)) row[key] = 0;
|
|
38
|
+
}
|
|
39
|
+
return row;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function fillMissingDailyRows(
|
|
43
|
+
rows: Record<string, unknown>[],
|
|
44
|
+
xKey: string,
|
|
45
|
+
seriesKeys: string[],
|
|
46
|
+
): Record<string, unknown>[] {
|
|
47
|
+
if (rows.length < 2 || seriesKeys.length === 0) return rows;
|
|
48
|
+
|
|
49
|
+
const first = rows[0]?.[xKey];
|
|
50
|
+
const last = rows[rows.length - 1]?.[xKey];
|
|
51
|
+
if (typeof first !== "string" || typeof last !== "string") return rows;
|
|
52
|
+
|
|
53
|
+
const startMs = dayToUtcMs(first);
|
|
54
|
+
const endMs = dayToUtcMs(last);
|
|
55
|
+
if (startMs == null || endMs == null || endMs < startMs) return rows;
|
|
56
|
+
|
|
57
|
+
const dayCount = Math.floor((endMs - startMs) / 86_400_000) + 1;
|
|
58
|
+
if (dayCount > MAX_DAILY_GAP_FILL_DAYS) return rows;
|
|
59
|
+
|
|
60
|
+
const byDay = new Map<string, Record<string, unknown>>();
|
|
61
|
+
for (const row of rows) {
|
|
62
|
+
const day = row[xKey];
|
|
63
|
+
if (typeof day === "string" && ISO_DAY_RE.test(day)) {
|
|
64
|
+
byDay.set(day, row);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const filled: Record<string, unknown>[] = [];
|
|
69
|
+
for (let ms = startMs; ms <= endMs; ms += 86_400_000) {
|
|
70
|
+
const day = utcMsToDay(ms);
|
|
71
|
+
filled.push(
|
|
72
|
+
fillMissingSeries(byDay.get(day) ?? { [xKey]: day }, seriesKeys),
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
return filled;
|
|
76
|
+
}
|
|
77
|
+
|
|
18
78
|
export function pivotRows(
|
|
19
79
|
rows: Record<string, unknown>[],
|
|
20
80
|
config: PivotConfig,
|
|
@@ -52,8 +112,11 @@ export function pivotRows(
|
|
|
52
112
|
if (emitted.has(x)) continue;
|
|
53
113
|
emitted.add(x);
|
|
54
114
|
const bucket = byX.get(x);
|
|
55
|
-
if (bucket) orderedRows.push(bucket);
|
|
115
|
+
if (bucket) orderedRows.push(fillMissingSeries(bucket, seriesKeys));
|
|
56
116
|
}
|
|
57
117
|
|
|
58
|
-
return {
|
|
118
|
+
return {
|
|
119
|
+
rows: fillMissingDailyRows(orderedRows, xKey, seriesKeys),
|
|
120
|
+
seriesKeys,
|
|
121
|
+
};
|
|
59
122
|
}
|
|
@@ -88,10 +88,9 @@ export interface SqlPanel {
|
|
|
88
88
|
source: DataSourceType;
|
|
89
89
|
chartType: ChartType;
|
|
90
90
|
/**
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
* column regardless of this value.
|
|
91
|
+
* Legacy layout field retained for existing dashboards and action payloads.
|
|
92
|
+
* The renderer now auto-fits rows from panel order: one card in a row spans
|
|
93
|
+
* the row, two cards split it, and so on up to the section column count.
|
|
95
94
|
*/
|
|
96
95
|
width: number;
|
|
97
96
|
/**
|