@agent-native/core 0.157.28 → 0.158.2
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/dist/cli/code-agent-executor.js +3 -0
- package/dist/coding-tools/index.js +64 -3
- package/dist/integrations/remote-browser-actions.js +14 -2
- package/dist/observability/routes.d.ts +3 -3
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/docs/content/authentication.mdx +8 -5
- package/docs/content/cross-app-sso.mdx +25 -2
- package/docs/content/portal.mdx +61 -0
- package/package.json +1 -1
|
@@ -647,6 +647,7 @@ function buildClaudeCliPrompt(run, prompt) {
|
|
|
647
647
|
const additionalSkillsRoot = process.env.AGENT_NATIVE_CODE_AGENT_SKILLS_ROOT?.trim();
|
|
648
648
|
return [
|
|
649
649
|
`You are running from Agent-Native Code in ${run.cwd || process.cwd()}.`,
|
|
650
|
+
`Treat ${run.cwd || process.cwd()} as the only project checkout for this run. Keep shell commands, file operations, git pushes, and pull requests rooted there; do not use absolute paths or .. to reach another checkout.`,
|
|
650
651
|
"Follow the repository AGENTS.md and any relevant skill instructions.",
|
|
651
652
|
...(additionalSkillsRoot
|
|
652
653
|
? [
|
|
@@ -1465,6 +1466,7 @@ function buildCodexCliPrompt(run, prompt) {
|
|
|
1465
1466
|
const additionalSkillsRoot = process.env.AGENT_NATIVE_CODE_AGENT_SKILLS_ROOT?.trim();
|
|
1466
1467
|
return [
|
|
1467
1468
|
`You are running from Agent-Native Code in ${run.cwd || process.cwd()}.`,
|
|
1469
|
+
`Treat ${run.cwd || process.cwd()} as the only project checkout for this run. Keep shell commands, file operations, git pushes, and pull requests rooted there; do not use absolute paths or .. to reach another checkout.`,
|
|
1468
1470
|
"Follow the repository AGENTS.md and any relevant skill instructions.",
|
|
1469
1471
|
...(additionalSkillsRoot
|
|
1470
1472
|
? [
|
|
@@ -2164,6 +2166,7 @@ You bring a senior engineer's judgment to the work, but you let it arrive throug
|
|
|
2164
2166
|
- When you search for text or files, reach first for \`rg\` or \`rg --files\`; they are much faster than \`grep\` or \`find\`. If \`rg\` is unavailable, use the next best tool without fuss.
|
|
2165
2167
|
- Parallelize independent read-only work (file reads, searches) so you gather context quickly. Keep mutating steps ordered.
|
|
2166
2168
|
- Read relevant files before editing them. Do not edit a file you have not actually read.
|
|
2169
|
+
- Treat ${cwd} as the only project checkout for this run. Keep shell commands, file operations, git pushes, and pull requests rooted there; do not use absolute paths or .. to reach another checkout.
|
|
2167
2170
|
|
|
2168
2171
|
# Engineering judgment
|
|
2169
2172
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import fs from "node:fs";
|
|
3
|
-
import os from "node:os";
|
|
4
3
|
import path from "node:path";
|
|
5
4
|
const DEFAULT_COMMAND_TIMEOUT_MS = 120_000;
|
|
6
5
|
const DEFAULT_MAX_OUTPUT_CHARS = 50_000;
|
|
@@ -63,6 +62,9 @@ export function createCodingToolRegistry(options = {}) {
|
|
|
63
62
|
if (!commandCwd) {
|
|
64
63
|
return "Error: cwd must stay inside the workspace.";
|
|
65
64
|
}
|
|
65
|
+
if (restrictToCwd && commandReferencesOutsideWorkspace(command, cwd)) {
|
|
66
|
+
return "Error: command paths must stay inside the workspace.";
|
|
67
|
+
}
|
|
66
68
|
const requestedTimeoutMs = Number(args.timeoutMs);
|
|
67
69
|
const timeoutMs = Number.isFinite(requestedTimeoutMs) && requestedTimeoutMs > 0
|
|
68
70
|
? Math.min(requestedTimeoutMs, 10 * 60_000)
|
|
@@ -367,7 +369,12 @@ export async function runCodingCommand(command, cwd, timeoutMs, options = {}) {
|
|
|
367
369
|
* calling registry).
|
|
368
370
|
*/
|
|
369
371
|
export function spawnBackgroundCommand(command, cwd) {
|
|
370
|
-
const
|
|
372
|
+
const logDirectory = resolveCodingPath(cwd, path.join(".agent-native", "background-logs"), { restrictToCwd: true });
|
|
373
|
+
if (!logDirectory) {
|
|
374
|
+
throw new Error("Background log path must stay inside the workspace.");
|
|
375
|
+
}
|
|
376
|
+
fs.mkdirSync(logDirectory, { recursive: true });
|
|
377
|
+
const logFile = path.join(logDirectory, `an-bg-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.log`);
|
|
371
378
|
const logFd = fs.openSync(logFile, "a");
|
|
372
379
|
const child = spawn(command, {
|
|
373
380
|
cwd,
|
|
@@ -464,11 +471,65 @@ function resolveCodingPath(cwd, value, options) {
|
|
|
464
471
|
: path.resolve(cwd, target);
|
|
465
472
|
if (!options.restrictToCwd)
|
|
466
473
|
return resolved;
|
|
467
|
-
const
|
|
474
|
+
const workspaceRoot = resolveRealPath(cwd);
|
|
475
|
+
const targetPath = resolveRealPathWithMissingTail(resolved);
|
|
476
|
+
if (!workspaceRoot || !targetPath)
|
|
477
|
+
return null;
|
|
478
|
+
const relative = path.relative(workspaceRoot, targetPath);
|
|
468
479
|
if (relative.startsWith("..") || path.isAbsolute(relative))
|
|
469
480
|
return null;
|
|
470
481
|
return resolved;
|
|
471
482
|
}
|
|
483
|
+
function resolveRealPath(value) {
|
|
484
|
+
try {
|
|
485
|
+
return fs.realpathSync(value);
|
|
486
|
+
}
|
|
487
|
+
catch {
|
|
488
|
+
// coercion-ok: an unreadable workspace cannot safely authorize a path.
|
|
489
|
+
return null;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
function resolveRealPathWithMissingTail(value) {
|
|
493
|
+
let candidate = value;
|
|
494
|
+
const missingTail = [];
|
|
495
|
+
while (true) {
|
|
496
|
+
try {
|
|
497
|
+
fs.lstatSync(candidate);
|
|
498
|
+
const existingPath = resolveRealPath(candidate);
|
|
499
|
+
return existingPath ? path.resolve(existingPath, ...missingTail) : null;
|
|
500
|
+
}
|
|
501
|
+
catch (error) {
|
|
502
|
+
if (error.code !== "ENOENT") {
|
|
503
|
+
// coercion-ok: an unreadable path cannot safely authorize a workspace path.
|
|
504
|
+
return null;
|
|
505
|
+
}
|
|
506
|
+
const parent = path.dirname(candidate);
|
|
507
|
+
if (parent === candidate)
|
|
508
|
+
return null;
|
|
509
|
+
missingTail.unshift(path.basename(candidate));
|
|
510
|
+
candidate = parent;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
function commandReferencesOutsideWorkspace(command, cwd) {
|
|
515
|
+
if (/(^|[\s"'=:(])\.\.(?:[/\s"';&|<>)]|$)/.test(command)) {
|
|
516
|
+
return true;
|
|
517
|
+
}
|
|
518
|
+
const workspaceRoot = resolveRealPath(cwd) ?? path.resolve(cwd);
|
|
519
|
+
const absolutePathPattern = /(?:^|[\s"'=:(])((?:\/(?!\/)|~(?:\/|$))[^\s"';&|<>)]*)/g;
|
|
520
|
+
for (const match of command.matchAll(absolutePathPattern)) {
|
|
521
|
+
const value = match[1];
|
|
522
|
+
if (!value || value.startsWith("~"))
|
|
523
|
+
return true;
|
|
524
|
+
const targetPath = resolveRealPathWithMissingTail(path.resolve(value));
|
|
525
|
+
if (!targetPath)
|
|
526
|
+
return true;
|
|
527
|
+
const relative = path.relative(workspaceRoot, targetPath);
|
|
528
|
+
if (relative.startsWith("..") || path.isAbsolute(relative))
|
|
529
|
+
return true;
|
|
530
|
+
}
|
|
531
|
+
return false;
|
|
532
|
+
}
|
|
472
533
|
function formatFileReadOutput(cwd, filePath, content, args) {
|
|
473
534
|
const lines = content.split("\n");
|
|
474
535
|
const offset = positiveInteger(args.offset, 1);
|
|
@@ -11,6 +11,7 @@ const CONTROL_ACTIONS = new Set([
|
|
|
11
11
|
"type",
|
|
12
12
|
"key",
|
|
13
13
|
"navigate",
|
|
14
|
+
"open-tab",
|
|
14
15
|
"scroll",
|
|
15
16
|
]);
|
|
16
17
|
const BROWSER_KEYS = new Set([
|
|
@@ -142,7 +143,7 @@ function buildReadAction(args) {
|
|
|
142
143
|
function buildControlAction(args) {
|
|
143
144
|
const action = readString(args, "action");
|
|
144
145
|
if (!action || (!CONTROL_ACTIONS.has(action) && action !== "stop")) {
|
|
145
|
-
throw new Error("Control action must be attach, click, type, key, navigate, scroll, or stop");
|
|
146
|
+
throw new Error("Control action must be attach, click, type, key, navigate, open-tab, scroll, or stop");
|
|
146
147
|
}
|
|
147
148
|
if (action === "attach") {
|
|
148
149
|
return {
|
|
@@ -201,6 +202,16 @@ function buildControlAction(args) {
|
|
|
201
202
|
input: { url },
|
|
202
203
|
};
|
|
203
204
|
}
|
|
205
|
+
if (action === "open-tab") {
|
|
206
|
+
const url = readString(args, "url");
|
|
207
|
+
if (!url)
|
|
208
|
+
throw new Error("url is required");
|
|
209
|
+
return {
|
|
210
|
+
type: "browser.open-tab",
|
|
211
|
+
target: null,
|
|
212
|
+
input: { url },
|
|
213
|
+
};
|
|
214
|
+
}
|
|
204
215
|
if (action === "scroll") {
|
|
205
216
|
return {
|
|
206
217
|
type: "browser.scroll",
|
|
@@ -388,7 +399,7 @@ export function createRemoteBrowserActionEntries(options) {
|
|
|
388
399
|
timeoutMs: 30_000,
|
|
389
400
|
needsApproval: (args) => args.action !== "stop",
|
|
390
401
|
tool: {
|
|
391
|
-
description: "Attach to and control a user-granted Chrome page. Attach once per conversation before observing or acting. Targets must come from the latest observation. Control actions require inline user approval.",
|
|
402
|
+
description: "Attach to and control a user-granted Chrome page. Attach once per conversation before observing or acting. Targets must come from the latest observation. The approved open-tab action creates an inactive same-origin tab and moves the lease without focusing Chrome. Control actions require inline user approval.",
|
|
392
403
|
parameters: {
|
|
393
404
|
type: "object",
|
|
394
405
|
properties: {
|
|
@@ -401,6 +412,7 @@ export function createRemoteBrowserActionEntries(options) {
|
|
|
401
412
|
"type",
|
|
402
413
|
"key",
|
|
403
414
|
"navigate",
|
|
415
|
+
"open-tab",
|
|
404
416
|
"scroll",
|
|
405
417
|
"stop",
|
|
406
418
|
],
|
|
@@ -42,22 +42,22 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
|
|
|
42
42
|
avgEvalScore: number;
|
|
43
43
|
} | {
|
|
44
44
|
error?: undefined;
|
|
45
|
+
ok?: undefined;
|
|
45
46
|
summary: import("./types.js").TraceSummary;
|
|
46
47
|
spans: import("./types.js").TraceSpan[];
|
|
47
48
|
id?: undefined;
|
|
48
|
-
ok?: undefined;
|
|
49
49
|
} | {
|
|
50
50
|
error?: undefined;
|
|
51
|
+
ok?: undefined;
|
|
51
52
|
summary?: undefined;
|
|
52
53
|
spans?: undefined;
|
|
53
54
|
id: string;
|
|
54
|
-
ok?: undefined;
|
|
55
55
|
} | {
|
|
56
|
+
ok?: undefined;
|
|
56
57
|
summary?: undefined;
|
|
57
58
|
spans?: undefined;
|
|
58
59
|
id?: undefined;
|
|
59
60
|
error: any;
|
|
60
|
-
ok?: undefined;
|
|
61
61
|
} | {
|
|
62
62
|
error?: undefined;
|
|
63
63
|
summary?: undefined;
|
|
@@ -48,8 +48,8 @@ export declare function handleUpdateResource(event: any): Promise<import("./stor
|
|
|
48
48
|
}>;
|
|
49
49
|
/** DELETE /_agent-native/resources/:id — delete a resource */
|
|
50
50
|
export declare function handleDeleteResource(event: any): Promise<{
|
|
51
|
-
error: string;
|
|
52
51
|
ok?: undefined;
|
|
52
|
+
error: string;
|
|
53
53
|
} | {
|
|
54
54
|
error?: undefined;
|
|
55
55
|
ok: boolean;
|
package/dist/secrets/routes.d.ts
CHANGED
|
@@ -34,37 +34,37 @@ export declare function createListSecretsHandler(): import("h3").EventHandlerWit
|
|
|
34
34
|
/** POST /_agent-native/secrets/:key — write a secret. */
|
|
35
35
|
export declare function createWriteSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
36
36
|
error: string;
|
|
37
|
-
status?: undefined;
|
|
38
37
|
ok?: undefined;
|
|
38
|
+
status?: undefined;
|
|
39
39
|
} | {
|
|
40
|
+
error?: undefined;
|
|
40
41
|
ok: boolean;
|
|
41
42
|
status: string;
|
|
42
|
-
error?: undefined;
|
|
43
43
|
} | {
|
|
44
|
+
ok?: undefined;
|
|
44
45
|
error: string;
|
|
45
46
|
removed?: undefined;
|
|
46
|
-
ok?: undefined;
|
|
47
47
|
} | {
|
|
48
|
+
error?: undefined;
|
|
48
49
|
ok: boolean;
|
|
49
50
|
removed: boolean;
|
|
50
|
-
error?: undefined;
|
|
51
51
|
}>>;
|
|
52
52
|
/**
|
|
53
53
|
* POST /_agent-native/secrets/:key/test — validate an optional candidate value
|
|
54
54
|
* or the current stored value without changing anything.
|
|
55
55
|
*/
|
|
56
56
|
export declare function createTestSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
57
|
+
ok?: undefined;
|
|
57
58
|
error: string;
|
|
58
59
|
note?: undefined;
|
|
59
|
-
ok?: undefined;
|
|
60
60
|
} | {
|
|
61
|
+
error?: undefined;
|
|
61
62
|
ok: boolean;
|
|
62
63
|
note?: undefined;
|
|
63
|
-
error?: undefined;
|
|
64
64
|
} | {
|
|
65
|
+
error?: undefined;
|
|
65
66
|
ok: boolean;
|
|
66
67
|
note: string;
|
|
67
|
-
error?: undefined;
|
|
68
68
|
} | {
|
|
69
69
|
note?: undefined;
|
|
70
70
|
ok: boolean;
|
|
@@ -95,11 +95,11 @@ export interface AdHocSecretPayload {
|
|
|
95
95
|
export declare function createAdHocSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<AdHocSecretPayload[] | {
|
|
96
96
|
error: string;
|
|
97
97
|
} | {
|
|
98
|
+
error?: undefined;
|
|
98
99
|
ok: boolean;
|
|
99
100
|
key: string;
|
|
100
|
-
error?: undefined;
|
|
101
101
|
} | {
|
|
102
|
+
error?: undefined;
|
|
102
103
|
ok: boolean;
|
|
103
104
|
removed: boolean;
|
|
104
|
-
error?: undefined;
|
|
105
105
|
}>>;
|
|
@@ -26,8 +26,8 @@ export declare function createRealtimeTokenHandler(): import("h3").EventHandlerW
|
|
|
26
26
|
expiresAt?: undefined;
|
|
27
27
|
ttlSeconds?: undefined;
|
|
28
28
|
} | {
|
|
29
|
+
error?: undefined;
|
|
29
30
|
token: string;
|
|
30
31
|
expiresAt: string;
|
|
31
32
|
ttlSeconds: number;
|
|
32
|
-
error?: undefined;
|
|
33
33
|
}>>;
|
|
@@ -179,14 +179,17 @@ flag state. Custom and third-party apps are excluded.
|
|
|
179
179
|
Canonical hosted apps recognize packaged Desktop requests without per-app
|
|
180
180
|
identity-hub environment configuration. Ordinary browsers and self-hosted apps
|
|
181
181
|
still require `AGENT_NATIVE_IDENTITY_HUB_URL` to opt in.
|
|
182
|
-
|
|
183
|
-
|
|
182
|
+
Every Desktop build may initialize the broker when the per-device
|
|
183
|
+
`desktopSsoEnabled` preference is true (the default); an explicit persisted
|
|
184
|
+
`false` remains an opt-out. The `desktop.workspace-sso` Dispatch flag must also
|
|
185
|
+
be enabled. The Canary user-agent marker no longer gates broker initialization;
|
|
186
|
+
it only identifies the update channel.
|
|
184
187
|
The Canary user-agent marker is an availability hint rather than remote
|
|
185
188
|
attestation. Authentication and authorization never trust it; supervised
|
|
186
189
|
acceptance binds the client through exact signed-artifact provenance.
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
+
For an eligible registered app, Desktop presents the workspace sign-in surface
|
|
191
|
+
over the app's sign-in flow. If the rollout is unavailable or the app is not
|
|
192
|
+
eligible, ordinary per-app sign-in remains available.
|
|
190
193
|
|
|
191
194
|
## QA Accounts {#qa-accounts}
|
|
192
195
|
|
|
@@ -37,6 +37,22 @@ cookie**. Each separately hosted app still creates and owns its own local
|
|
|
37
37
|
session. Dispatch proves the user's identity at the app's front door, and the
|
|
38
38
|
app then continues with its normal local auth and access checks.
|
|
39
39
|
|
|
40
|
+
## Mobile and app-scoped embed sessions {#mobile-embed-sessions}
|
|
41
|
+
|
|
42
|
+
Mobile chat and Dispatch panes use a different contract from MCP-hosted iframe
|
|
43
|
+
embeds. The mobile client first authenticates the parent session, then requests
|
|
44
|
+
an app-scoped, one-time embed ticket for the target workspace app. The ticket
|
|
45
|
+
is exchanged at the target app's embed-start endpoint for a short-lived local
|
|
46
|
+
embed session and is consumed once. It is not a reusable bearer token, is not
|
|
47
|
+
placed in a long-lived URL, and does not grant access to another app.
|
|
48
|
+
|
|
49
|
+
This flow lets a mobile WebView or Dispatch pane open a target app while the
|
|
50
|
+
target app still owns its session and authorization checks. A missing, expired,
|
|
51
|
+
replayed, or cross-app ticket must fail closed; it must not be treated as an
|
|
52
|
+
anonymous session or silently fall back to the parent bearer. The `embed
|
|
53
|
+
session` described in [MCP Apps](/docs/mcp-apps) is a separate MCP-host iframe
|
|
54
|
+
feature and is not this mobile handoff contract.
|
|
55
|
+
|
|
40
56
|
The packaged Desktop Canary is deliberately more explicit: it never intercepts
|
|
41
57
|
anonymous app sign-in navigation. The user chooses workspace sign-in once in
|
|
42
58
|
Desktop Settings; Desktop then provisions every currently eligible registered
|
|
@@ -352,14 +368,21 @@ Desktop leaves ordinary per-app sign-in, sign-out, and Settings unchanged.
|
|
|
352
368
|
Canonical hosted apps recognize the packaged Desktop request and ordinary web
|
|
353
369
|
browsers without requiring `AGENT_NATIVE_IDENTITY_HUB_URL` on every deployment;
|
|
354
370
|
self-hosted apps still require that explicit configuration.
|
|
355
|
-
|
|
356
|
-
|
|
371
|
+
Every Desktop build may initialize the broker when the per-device
|
|
372
|
+
`desktopSsoEnabled` preference is true (the default); an explicit persisted
|
|
373
|
+
`false` remains an opt-out. The `desktop.workspace-sso` Dispatch flag must also
|
|
374
|
+
be enabled. The Canary user-agent marker no longer gates broker initialization;
|
|
375
|
+
it only identifies the update channel.
|
|
357
376
|
The Canary user-agent marker is an availability hint, not remote attestation;
|
|
358
377
|
the server cannot infer code signature from HTTP. No authentication or
|
|
359
378
|
authorization decision trusts it. Supervised acceptance therefore binds the
|
|
360
379
|
tested client through the signed artifact's exact commit, manifest, hashes, and
|
|
361
380
|
notarization evidence.
|
|
362
381
|
|
|
382
|
+
For an eligible registered app, Desktop presents the workspace sign-in surface
|
|
383
|
+
over the app's sign-in flow. If the rollout is unavailable or the app is not
|
|
384
|
+
eligible, ordinary per-app sign-in remains available.
|
|
385
|
+
|
|
363
386
|
## Self-hosting {#self-hosting}
|
|
364
387
|
|
|
365
388
|
Any Dispatch deployment can serve as the identity hub — you are not limited to `dispatch.agent-native.com`. Set `AGENT_NATIVE_IDENTITY_HUB_URL` on each client app to point at your Dispatch instance:
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Portal"
|
|
3
|
+
description: "Pair a computer and continue Agent-Native work across devices with Portal."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Portal
|
|
7
|
+
|
|
8
|
+
Portal connects a phone or browser to a registered computer so an Agent-Native
|
|
9
|
+
workspace can continue work on the machine that owns the local tools. It is a
|
|
10
|
+
device handoff feature, not a second chat or a cloud runner.
|
|
11
|
+
|
|
12
|
+
## Pair a computer
|
|
13
|
+
|
|
14
|
+
In the app, open **Settings → Workspace** and choose **Pair or repair**. The
|
|
15
|
+
pairing flow shows a relay URL and workspace path. Open the URL on the computer
|
|
16
|
+
you want to pair and confirm the workspace path there. The computer registers
|
|
17
|
+
itself with the workspace through:
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
POST /_agent-native/integrations/remote/register
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The registration returns a device token. Store that token in the computer's
|
|
24
|
+
private `~/.agent-native/remote-device.json` file. Do not put it in source
|
|
25
|
+
control, a URL, or a client-visible application setting. If pairing is lost,
|
|
26
|
+
use **Pair or repair** again to replace the device registration.
|
|
27
|
+
|
|
28
|
+
## Execution modes
|
|
29
|
+
|
|
30
|
+
The chat composer can target the execution environment that fits the task:
|
|
31
|
+
|
|
32
|
+
- **Local** runs on the current app/runtime.
|
|
33
|
+
- **Computer** runs on a paired computer through Portal, so local files and
|
|
34
|
+
installed coding tools are available there.
|
|
35
|
+
- **Cloud** is a waitlisted execution mode. Until access is enabled, choosing
|
|
36
|
+
Cloud does not start a run; it only shows the waitlist state.
|
|
37
|
+
|
|
38
|
+
The selected mode is part of the run request. Pairing a computer does not copy
|
|
39
|
+
credentials or grant it access to unrelated workspaces; the device and
|
|
40
|
+
workspace registration remain scoped to the authenticated account.
|
|
41
|
+
|
|
42
|
+
## Troubleshooting
|
|
43
|
+
|
|
44
|
+
If Computer is unavailable, confirm the paired computer is online, the relay
|
|
45
|
+
URL is reachable, and the workspace path still exists. Repair the pairing when
|
|
46
|
+
the device token was rotated or the workspace moved. If Cloud is unavailable,
|
|
47
|
+
the run has not started - use Local or Computer instead of retrying a queued
|
|
48
|
+
cloud request.
|
|
49
|
+
|
|
50
|
+
## Environment variables
|
|
51
|
+
|
|
52
|
+
Self-hosted deployments can customize the Portal connection with:
|
|
53
|
+
|
|
54
|
+
| Variable | Purpose |
|
|
55
|
+
| ------------------------------------ | -------------------------------------------------------------------- |
|
|
56
|
+
| `WORKSPACE_GATEWAY_URL` | Public workspace gateway used for device handoff. |
|
|
57
|
+
| `AGENT_NATIVE_REMOTE_DEVICE_PATH` | Override the local device registration file path. |
|
|
58
|
+
| `AGENT_NATIVE_COMPUTER_BRIDGE_URL` | Computer bridge URL used by remote execution. |
|
|
59
|
+
| `AGENT_NATIVE_COMPUTER_BRIDGE_TOKEN` | Token used to authenticate with that bridge. |
|
|
60
|
+
| `AGENT_NATIVE_REMOTE_ENGINES` | Comma-separated remote execution engines available to the workspace. |
|
|
61
|
+
| `AGENT_NATIVE_IDENTITY_HUB_URL` | Optional Dispatch identity hub for self-hosted cross-app sign-in. |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.158.2",
|
|
4
4
|
"description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|