@agent-native/core 0.109.1 → 0.109.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/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +15 -0
- package/corpus/core/docs/content/integrations.mdx +87 -253
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/cli/create.ts +18 -12
- package/corpus/core/src/client/blocks/library/diagram.config.ts +10 -1
- package/corpus/core/src/client/blocks/library/diagram.tsx +9 -4
- package/corpus/core/src/client/require-session.tsx +19 -3
- package/corpus/core/src/client/use-action.ts +145 -2
- package/corpus/core/src/client/use-session.ts +79 -48
- package/corpus/core/src/db/client.ts +13 -7
- package/corpus/core/src/db/create-get-db.ts +20 -13
- package/corpus/core/src/db/request-telemetry.ts +154 -0
- package/corpus/core/src/deploy/build.ts +63 -3
- package/corpus/core/src/integrations/index.ts +1 -0
- package/corpus/core/src/integrations/plugin.ts +9 -3
- package/corpus/core/src/integrations/remote-push-delivery-job.ts +48 -0
- package/corpus/core/src/integrations/remote-push-delivery.ts +370 -0
- package/corpus/core/src/integrations/remote-push-store.ts +275 -26
- package/corpus/core/src/server/better-auth-instance.ts +11 -3
- package/corpus/core/src/server/core-routes-plugin.ts +36 -14
- package/corpus/core/src/server/framework-request-handler.ts +11 -1
- package/corpus/core/src/server/http-response-telemetry.ts +233 -31
- package/corpus/core/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +19 -0
- package/corpus/templates/clips/.agents/skills/dictate/SKILL.md +28 -5
- package/corpus/templates/clips/.agents/skills/meetings/SKILL.md +7 -0
- package/corpus/templates/clips/.agents/skills/recording/SKILL.md +23 -0
- package/corpus/templates/clips/AGENTS.md +10 -0
- package/corpus/templates/clips/actions/create-dictation.ts +29 -4
- package/corpus/templates/clips/actions/finalize-recording.ts +1 -1
- package/corpus/templates/clips/actions/get-recording-player-data.ts +16 -6
- package/corpus/templates/clips/actions/set-mobile-capture-state.ts +40 -0
- package/corpus/templates/clips/actions/update-dictation.ts +9 -1
- package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -6
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +13 -2
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +13 -2
- package/corpus/templates/clips/changelog/2026-07-17-capture-dictation-background-meeting-audio-and-camera-videos.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-delayed-upload-verification-keeps-local-backups-retryable.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-18-new-recording-is-now-emphasized-as-the-primary-action-in-the.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-18-recordings-now-remain-safely-recoverable-until-the-stored-me.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +17 -0
- package/corpus/templates/clips/desktop/src/lib/processing-backup-recovery.ts +19 -0
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +60 -35
- package/corpus/templates/clips/desktop/src/lib/upload-verification.ts +12 -0
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +1 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +14 -0
- package/corpus/templates/clips/server/db/schema.ts +9 -1
- package/corpus/templates/clips/server/lib/builder-media-compression.ts +59 -7
- package/corpus/templates/clips/server/lib/media-verification-state.ts +17 -0
- package/corpus/templates/clips/server/routes/api/public-recording.get.ts +7 -0
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/reset-chunks.post.ts +22 -1
- package/corpus/templates/plan/changelog/2026-07-17-diagrams-can-opt-into-a-polished-clean-rendering-mode-withou.md +6 -0
- package/corpus/templates/plan/shared/plan-content.ts +3 -0
- package/corpus/templates/tasks/AGENTS.md +3 -0
- package/corpus/templates/tasks/actions/render-task-list-inline.ts +202 -0
- package/corpus/templates/tasks/changelog/2026-07-18-task-lists-can-now-appear-as-interactive-widgets-inline-in-c.md +6 -0
- package/corpus/templates/tasks/docs/features/f8-chat.mdx +2 -0
- package/corpus/templates/tasks/server/plugins/agent-chat.ts +2 -0
- package/dist/cli/create.d.ts +10 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +17 -13
- package/dist/cli/create.js.map +1 -1
- package/dist/client/blocks/library/diagram.config.d.ts +2 -0
- package/dist/client/blocks/library/diagram.config.d.ts.map +1 -1
- package/dist/client/blocks/library/diagram.config.js +8 -1
- package/dist/client/blocks/library/diagram.config.js.map +1 -1
- package/dist/client/blocks/library/diagram.d.ts.map +1 -1
- package/dist/client/blocks/library/diagram.js +9 -4
- package/dist/client/blocks/library/diagram.js.map +1 -1
- package/dist/client/require-session.d.ts.map +1 -1
- package/dist/client/require-session.js +6 -3
- package/dist/client/require-session.js.map +1 -1
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +117 -1
- package/dist/client/use-action.js.map +1 -1
- package/dist/client/use-session.d.ts.map +1 -1
- package/dist/client/use-session.js +72 -50
- package/dist/client/use-session.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +7 -1
- package/dist/db/client.js.map +1 -1
- package/dist/db/create-get-db.d.ts +3 -6
- package/dist/db/create-get-db.d.ts.map +1 -1
- package/dist/db/create-get-db.js +9 -2
- package/dist/db/create-get-db.js.map +1 -1
- package/dist/db/request-telemetry.d.ts +23 -0
- package/dist/db/request-telemetry.d.ts.map +1 -0
- package/dist/db/request-telemetry.js +95 -0
- package/dist/db/request-telemetry.js.map +1 -0
- package/dist/deploy/build.d.ts +3 -0
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +45 -1
- package/dist/deploy/build.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/integrations/index.d.ts +1 -0
- package/dist/integrations/index.d.ts.map +1 -1
- package/dist/integrations/index.js +1 -0
- package/dist/integrations/index.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +8 -3
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/integrations/remote-push-delivery-job.d.ts +4 -0
- package/dist/integrations/remote-push-delivery-job.d.ts.map +1 -0
- package/dist/integrations/remote-push-delivery-job.js +44 -0
- package/dist/integrations/remote-push-delivery-job.js.map +1 -0
- package/dist/integrations/remote-push-delivery.d.ts +11 -0
- package/dist/integrations/remote-push-delivery.d.ts.map +1 -0
- package/dist/integrations/remote-push-delivery.js +265 -0
- package/dist/integrations/remote-push-delivery.js.map +1 -0
- package/dist/integrations/remote-push-store.d.ts +33 -0
- package/dist/integrations/remote-push-store.d.ts.map +1 -1
- package/dist/integrations/remote-push-store.js +195 -26
- package/dist/integrations/remote-push-store.js.map +1 -1
- package/dist/observability/routes.d.ts +5 -5
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/server/better-auth-instance.js +7 -3
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts +8 -0
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +23 -8
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/framework-request-handler.d.ts.map +1 -1
- package/dist/server/framework-request-handler.js +9 -1
- package/dist/server/framework-request-handler.js.map +1 -1
- package/dist/server/http-response-telemetry.d.ts +3 -2
- package/dist/server/http-response-telemetry.d.ts.map +1 -1
- package/dist/server/http-response-telemetry.js +160 -27
- package/dist/server/http-response-telemetry.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +19 -0
- package/docs/content/integrations.mdx +87 -253
- package/package.json +1 -1
- package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +19 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
|
|
3
|
+
export type DatabaseOperationKind = "connect" | "query";
|
|
4
|
+
|
|
5
|
+
export interface DatabaseRequestTelemetry {
|
|
6
|
+
operationCount: number;
|
|
7
|
+
queryCount: number;
|
|
8
|
+
connectCount: number;
|
|
9
|
+
retryCount: number;
|
|
10
|
+
errorCount: number;
|
|
11
|
+
timeoutCount: number;
|
|
12
|
+
operationTotalMs: number;
|
|
13
|
+
operationWallMs: number;
|
|
14
|
+
queryTotalMs: number;
|
|
15
|
+
connectTotalMs: number;
|
|
16
|
+
slowestOperationMs: number;
|
|
17
|
+
activeOperationCount: number;
|
|
18
|
+
activeWindowStartedAt?: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const STORAGE_KEY = Symbol.for(
|
|
22
|
+
"@agent-native/core/db.request-telemetry-storage",
|
|
23
|
+
);
|
|
24
|
+
const STARTUP_STATE_KEY = Symbol.for(
|
|
25
|
+
"@agent-native/core/db.startup-telemetry-state",
|
|
26
|
+
);
|
|
27
|
+
const STARTUP_CAPTURE_WINDOW_MS = 120_000;
|
|
28
|
+
interface StartupDatabaseTelemetryState {
|
|
29
|
+
captureUntil: number;
|
|
30
|
+
claimed: boolean;
|
|
31
|
+
telemetry: DatabaseRequestTelemetry;
|
|
32
|
+
}
|
|
33
|
+
type GlobalWithDatabaseTelemetry = typeof globalThis & {
|
|
34
|
+
[STORAGE_KEY]?: AsyncLocalStorage<DatabaseRequestTelemetry>;
|
|
35
|
+
[STARTUP_STATE_KEY]?: StartupDatabaseTelemetryState;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const globalRef = globalThis as GlobalWithDatabaseTelemetry;
|
|
39
|
+
const storage =
|
|
40
|
+
globalRef[STORAGE_KEY] ??
|
|
41
|
+
(globalRef[STORAGE_KEY] = new AsyncLocalStorage<DatabaseRequestTelemetry>());
|
|
42
|
+
|
|
43
|
+
export function createDatabaseRequestTelemetry(): DatabaseRequestTelemetry {
|
|
44
|
+
return {
|
|
45
|
+
operationCount: 0,
|
|
46
|
+
queryCount: 0,
|
|
47
|
+
connectCount: 0,
|
|
48
|
+
retryCount: 0,
|
|
49
|
+
errorCount: 0,
|
|
50
|
+
timeoutCount: 0,
|
|
51
|
+
operationTotalMs: 0,
|
|
52
|
+
operationWallMs: 0,
|
|
53
|
+
queryTotalMs: 0,
|
|
54
|
+
connectTotalMs: 0,
|
|
55
|
+
slowestOperationMs: 0,
|
|
56
|
+
activeOperationCount: 0,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const startupState =
|
|
61
|
+
globalRef[STARTUP_STATE_KEY] ??
|
|
62
|
+
(globalRef[STARTUP_STATE_KEY] = {
|
|
63
|
+
captureUntil: Date.now() + STARTUP_CAPTURE_WINDOW_MS,
|
|
64
|
+
claimed: false,
|
|
65
|
+
telemetry: createDatabaseRequestTelemetry(),
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
function currentDatabaseTelemetry(): DatabaseRequestTelemetry | undefined {
|
|
69
|
+
const requestTelemetry = storage.getStore();
|
|
70
|
+
if (requestTelemetry) return requestTelemetry;
|
|
71
|
+
if (!startupState.claimed && Date.now() <= startupState.captureUntil) {
|
|
72
|
+
return startupState.telemetry;
|
|
73
|
+
}
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function claimStartupDatabaseTelemetry():
|
|
78
|
+
| DatabaseRequestTelemetry
|
|
79
|
+
| undefined {
|
|
80
|
+
if (startupState.claimed) return undefined;
|
|
81
|
+
startupState.claimed = true;
|
|
82
|
+
return startupState.telemetry;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function runWithDatabaseRequestTelemetry<T>(
|
|
86
|
+
telemetry: DatabaseRequestTelemetry,
|
|
87
|
+
fn: () => T,
|
|
88
|
+
): T {
|
|
89
|
+
return storage.run(telemetry, fn);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function enterDatabaseRequestTelemetry(
|
|
93
|
+
telemetry: DatabaseRequestTelemetry,
|
|
94
|
+
): void {
|
|
95
|
+
storage.enterWith(telemetry);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function beginDatabaseOperation(
|
|
99
|
+
operation: DatabaseOperationKind,
|
|
100
|
+
): (outcome: "success" | "error" | "timeout") => void {
|
|
101
|
+
const telemetry = currentDatabaseTelemetry();
|
|
102
|
+
if (!telemetry) return () => {};
|
|
103
|
+
|
|
104
|
+
const startedAt = Date.now();
|
|
105
|
+
if (telemetry.activeOperationCount === 0) {
|
|
106
|
+
telemetry.activeWindowStartedAt = startedAt;
|
|
107
|
+
}
|
|
108
|
+
telemetry.activeOperationCount += 1;
|
|
109
|
+
let completed = false;
|
|
110
|
+
|
|
111
|
+
return (outcome) => {
|
|
112
|
+
if (completed) return;
|
|
113
|
+
completed = true;
|
|
114
|
+
const completedAt = Date.now();
|
|
115
|
+
const duration = Math.max(0, completedAt - startedAt);
|
|
116
|
+
telemetry.operationCount += 1;
|
|
117
|
+
telemetry.operationTotalMs += duration;
|
|
118
|
+
telemetry.slowestOperationMs = Math.max(
|
|
119
|
+
telemetry.slowestOperationMs,
|
|
120
|
+
duration,
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
if (operation === "connect") {
|
|
124
|
+
telemetry.connectCount += 1;
|
|
125
|
+
telemetry.connectTotalMs += duration;
|
|
126
|
+
} else {
|
|
127
|
+
telemetry.queryCount += 1;
|
|
128
|
+
telemetry.queryTotalMs += duration;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (outcome !== "success") telemetry.errorCount += 1;
|
|
132
|
+
if (outcome === "timeout") telemetry.timeoutCount += 1;
|
|
133
|
+
|
|
134
|
+
telemetry.activeOperationCount = Math.max(
|
|
135
|
+
0,
|
|
136
|
+
telemetry.activeOperationCount - 1,
|
|
137
|
+
);
|
|
138
|
+
if (
|
|
139
|
+
telemetry.activeOperationCount === 0 &&
|
|
140
|
+
telemetry.activeWindowStartedAt !== undefined
|
|
141
|
+
) {
|
|
142
|
+
telemetry.operationWallMs += Math.max(
|
|
143
|
+
0,
|
|
144
|
+
completedAt - telemetry.activeWindowStartedAt,
|
|
145
|
+
);
|
|
146
|
+
telemetry.activeWindowStartedAt = undefined;
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function recordDatabaseRetry(): void {
|
|
152
|
+
const telemetry = currentDatabaseTelemetry();
|
|
153
|
+
if (telemetry) telemetry.retryCount += 1;
|
|
154
|
+
}
|
|
@@ -138,6 +138,14 @@ export const CLOUDFLARE_WORKER_STUB_MODULES: Record<string, string> = {
|
|
|
138
138
|
"export default { Resvg };",
|
|
139
139
|
"",
|
|
140
140
|
].join("\n"),
|
|
141
|
+
playwright: [
|
|
142
|
+
"const unavailable = async () => { throw new Error('playwright unavailable in Cloudflare Pages worker'); };",
|
|
143
|
+
"export const chromium = { launch: unavailable, connect: unavailable, connectOverCDP: unavailable };",
|
|
144
|
+
"export const firefox = { launch: unavailable, connect: unavailable };",
|
|
145
|
+
"export const webkit = { launch: unavailable, connect: unavailable };",
|
|
146
|
+
"export default { chromium, firefox, webkit };",
|
|
147
|
+
"",
|
|
148
|
+
].join("\n"),
|
|
141
149
|
"playwright-core": [
|
|
142
150
|
"const unavailable = async () => { throw new Error('playwright-core unavailable in Cloudflare Pages worker'); };",
|
|
143
151
|
"export const chromium = { launch: unavailable };",
|
|
@@ -187,6 +195,50 @@ export const CLOUDFLARE_WORKER_STUB_MODULES: Record<string, string> = {
|
|
|
187
195
|
"export default async () => ({ elements: [], files: {} });\n",
|
|
188
196
|
};
|
|
189
197
|
|
|
198
|
+
export const CLOUDFLARE_WORKER_STUB_SUBPATH_MODULES: Record<string, string> = {
|
|
199
|
+
"pdf-parse/worker": [
|
|
200
|
+
"const unavailable = async () => { throw new Error('pdf-parse/worker unavailable in Cloudflare Pages worker'); };",
|
|
201
|
+
"export class CanvasFactory {}",
|
|
202
|
+
"export const getData = unavailable;",
|
|
203
|
+
"export default { CanvasFactory, getData };",
|
|
204
|
+
"",
|
|
205
|
+
].join("\n"),
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
export function cloudflareWorkerStubAliasArgs(stubDir: string): string[] {
|
|
209
|
+
const subpathAliases = Object.keys(CLOUDFLARE_WORKER_STUB_SUBPATH_MODULES)
|
|
210
|
+
.sort((a, b) => b.length - a.length)
|
|
211
|
+
.map(
|
|
212
|
+
(mod) =>
|
|
213
|
+
`--alias:${mod}=${path.join(stubDir, `${mod.replace(/\//g, "__")}.js`)}`,
|
|
214
|
+
);
|
|
215
|
+
const packageAliases = Object.keys(CLOUDFLARE_WORKER_STUB_MODULES)
|
|
216
|
+
.sort((a, b) => b.length - a.length)
|
|
217
|
+
.map((mod) => `--alias:${mod}=${path.join(stubDir, mod, "index.js")}`);
|
|
218
|
+
return [...subpathAliases, ...packageAliases];
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export function assertNoCloudflareWorkerStubDynamicImports(
|
|
222
|
+
code: string,
|
|
223
|
+
sourceName: string,
|
|
224
|
+
): void {
|
|
225
|
+
const stubbedModules = [
|
|
226
|
+
...Object.keys(CLOUDFLARE_WORKER_STUB_SUBPATH_MODULES),
|
|
227
|
+
...Object.keys(CLOUDFLARE_WORKER_STUB_MODULES),
|
|
228
|
+
];
|
|
229
|
+
const pattern = stubbedModules
|
|
230
|
+
.sort((a, b) => b.length - a.length)
|
|
231
|
+
.map((moduleName) => moduleName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"))
|
|
232
|
+
.join("|");
|
|
233
|
+
const unresolvedImport = code.match(
|
|
234
|
+
new RegExp(`\\bimport\\s*\\(\\s*(["'])(${pattern})\\1\\s*\\)`),
|
|
235
|
+
);
|
|
236
|
+
if (!unresolvedImport) return;
|
|
237
|
+
throw new Error(
|
|
238
|
+
`Cloudflare worker output ${sourceName} retained a dynamic import for stubbed module "${unresolvedImport[2]}". Use a literal import so the worker bundler can apply its fail-closed stub.`,
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
|
|
190
242
|
function cloudflareNodeBuiltinStubSource(
|
|
191
243
|
moduleName: string,
|
|
192
244
|
namedExports: string[],
|
|
@@ -1666,9 +1718,15 @@ async function buildCloudflarePages() {
|
|
|
1666
1718
|
JSON.stringify({ name: mod, main: "index.js", type: "module" }),
|
|
1667
1719
|
);
|
|
1668
1720
|
}
|
|
1669
|
-
const
|
|
1670
|
-
|
|
1671
|
-
)
|
|
1721
|
+
for (const [mod, source] of Object.entries(
|
|
1722
|
+
CLOUDFLARE_WORKER_STUB_SUBPATH_MODULES,
|
|
1723
|
+
)) {
|
|
1724
|
+
fs.writeFileSync(
|
|
1725
|
+
path.join(stubDir, `${mod.replace(/\//g, "__")}.js`),
|
|
1726
|
+
source,
|
|
1727
|
+
);
|
|
1728
|
+
}
|
|
1729
|
+
const stubAliases = cloudflareWorkerStubAliasArgs(stubDir);
|
|
1672
1730
|
const nodeBuiltinStubDir = path.join(tmpDir, "node-builtin-stubs");
|
|
1673
1731
|
fs.mkdirSync(nodeBuiltinStubDir, { recursive: true });
|
|
1674
1732
|
const nodeBuiltinStubAliases: string[] = [];
|
|
@@ -1850,6 +1908,8 @@ async function buildCloudflarePages() {
|
|
|
1850
1908
|
);
|
|
1851
1909
|
}
|
|
1852
1910
|
|
|
1911
|
+
assertNoCloudflareWorkerStubDynamicImports(code, jsFile);
|
|
1912
|
+
|
|
1853
1913
|
fs.writeFileSync(jsFile, code);
|
|
1854
1914
|
}
|
|
1855
1915
|
|
|
@@ -84,6 +84,7 @@ export {
|
|
|
84
84
|
unregisterRemotePushRegistrationForOwner,
|
|
85
85
|
upsertRemotePushRegistration,
|
|
86
86
|
} from "./remote-push-store.js";
|
|
87
|
+
export { deliverPendingRemotePushNotifications } from "./remote-push-delivery.js";
|
|
87
88
|
export type {
|
|
88
89
|
ComputerApprovalScope,
|
|
89
90
|
ComputerCommandAction,
|
|
@@ -109,6 +109,7 @@ import {
|
|
|
109
109
|
unregisterRemoteDevice,
|
|
110
110
|
updateRemoteDeviceDetails,
|
|
111
111
|
} from "./remote-devices-store.js";
|
|
112
|
+
import { startRemotePushDeliveryJob } from "./remote-push-delivery-job.js";
|
|
112
113
|
import {
|
|
113
114
|
listRemotePushNotificationsForOwner,
|
|
114
115
|
listRemotePushRegistrationsForOwner,
|
|
@@ -579,7 +580,6 @@ function mountedPathParts(event: any, mountSuffix: string): string[] {
|
|
|
579
580
|
function remoteCommandPushPayload(
|
|
580
581
|
command: RemoteCommand,
|
|
581
582
|
): Record<string, unknown> {
|
|
582
|
-
const result = readObject(command.result);
|
|
583
583
|
const status = command.status;
|
|
584
584
|
const title =
|
|
585
585
|
status === "completed"
|
|
@@ -587,14 +587,19 @@ function remoteCommandPushPayload(
|
|
|
587
587
|
: status === "failed"
|
|
588
588
|
? "Remote run failed"
|
|
589
589
|
: "Remote run updated";
|
|
590
|
+
const body =
|
|
591
|
+
status === "completed"
|
|
592
|
+
? "Open Agent Native to review the result."
|
|
593
|
+
: status === "failed"
|
|
594
|
+
? "Open Agent Native to review the failure."
|
|
595
|
+
: "Open Agent Native to review the latest status.";
|
|
590
596
|
return {
|
|
591
597
|
title,
|
|
592
|
-
body
|
|
598
|
+
body,
|
|
593
599
|
commandId: command.id,
|
|
594
600
|
hostId: command.deviceId,
|
|
595
601
|
kind: command.kind,
|
|
596
602
|
status,
|
|
597
|
-
result: command.result,
|
|
598
603
|
updatedAt: command.updatedAt,
|
|
599
604
|
};
|
|
600
605
|
}
|
|
@@ -2897,6 +2902,7 @@ export function createIntegrationsPlugin(
|
|
|
2897
2902
|
});
|
|
2898
2903
|
startA2AContinuationRetryJob(adapterMap);
|
|
2899
2904
|
startRemoteCommandsRetryJob();
|
|
2905
|
+
startRemotePushDeliveryJob();
|
|
2900
2906
|
|
|
2901
2907
|
// ─── Start Google Docs poller/push ────────────────────────────
|
|
2902
2908
|
if (adapterMap.has("google-docs")) {
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { deliverPendingRemotePushNotifications } from "./remote-push-delivery.js";
|
|
2
|
+
|
|
3
|
+
const DELIVERY_INTERVAL_MS = 60_000;
|
|
4
|
+
|
|
5
|
+
let retryInterval: ReturnType<typeof setInterval> | null = null;
|
|
6
|
+
let initialTimer: ReturnType<typeof setTimeout> | null = null;
|
|
7
|
+
let running = false;
|
|
8
|
+
|
|
9
|
+
export async function runRemotePushDelivery(): Promise<void> {
|
|
10
|
+
if (running) return;
|
|
11
|
+
running = true;
|
|
12
|
+
try {
|
|
13
|
+
await deliverPendingRemotePushNotifications();
|
|
14
|
+
} catch (error) {
|
|
15
|
+
console.error("[integrations] Remote push delivery failed", {
|
|
16
|
+
error: error instanceof Error ? error.name : "UnknownError",
|
|
17
|
+
});
|
|
18
|
+
} finally {
|
|
19
|
+
running = false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function startRemotePushDeliveryJob(): void {
|
|
24
|
+
if (retryInterval) return;
|
|
25
|
+
initialTimer = setTimeout(() => void runRemotePushDelivery(), 10_000);
|
|
26
|
+
unrefTimer(initialTimer);
|
|
27
|
+
retryInterval = setInterval(
|
|
28
|
+
() => void runRemotePushDelivery(),
|
|
29
|
+
DELIVERY_INTERVAL_MS,
|
|
30
|
+
);
|
|
31
|
+
unrefTimer(retryInterval);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function stopRemotePushDeliveryJob(): void {
|
|
35
|
+
if (initialTimer) {
|
|
36
|
+
clearTimeout(initialTimer);
|
|
37
|
+
initialTimer = null;
|
|
38
|
+
}
|
|
39
|
+
if (retryInterval) {
|
|
40
|
+
clearInterval(retryInterval);
|
|
41
|
+
retryInterval = null;
|
|
42
|
+
}
|
|
43
|
+
running = false;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function unrefTimer(timer: ReturnType<typeof setInterval>): void {
|
|
47
|
+
(timer as unknown as { unref?: () => void }).unref?.();
|
|
48
|
+
}
|