@xenosystem/agent-interface-electron-host 0.1.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/LICENSE +67 -0
- package/dist/headless.d.ts +26 -0
- package/dist/headless.d.ts.map +1 -0
- package/dist/headless.js +26 -0
- package/dist/headless.js.map +1 -0
- package/dist/headlessAgentSurface.d.ts +97 -0
- package/dist/headlessAgentSurface.d.ts.map +1 -0
- package/dist/headlessAgentSurface.js +80 -0
- package/dist/headlessAgentSurface.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/permissionIpc.d.ts +38 -0
- package/dist/permissionIpc.d.ts.map +1 -0
- package/dist/permissionIpc.js +101 -0
- package/dist/permissionIpc.js.map +1 -0
- package/dist/sdkAgent.d.ts +232 -0
- package/dist/sdkAgent.d.ts.map +1 -0
- package/dist/sdkAgent.js +5268 -0
- package/dist/sdkAgent.js.map +1 -0
- package/dist/sdkAgentSurface.d.ts +45 -0
- package/dist/sdkAgentSurface.d.ts.map +1 -0
- package/dist/sdkAgentSurface.js +2 -0
- package/dist/sdkAgentSurface.js.map +1 -0
- package/dist/sdkNativeHeadlessRunner.d.ts +45 -0
- package/dist/sdkNativeHeadlessRunner.d.ts.map +1 -0
- package/dist/sdkNativeHeadlessRunner.js +101 -0
- package/dist/sdkNativeHeadlessRunner.js.map +1 -0
- package/dist/sdkNativeRunner.d.ts +11 -0
- package/dist/sdkNativeRunner.d.ts.map +1 -0
- package/dist/sdkNativeRunner.js +93 -0
- package/dist/sdkNativeRunner.js.map +1 -0
- package/dist/surfaceRuntimeBridge.d.ts +59 -0
- package/dist/surfaceRuntimeBridge.d.ts.map +1 -0
- package/dist/surfaceRuntimeBridge.js +64 -0
- package/dist/surfaceRuntimeBridge.js.map +1 -0
- package/dist/workspaceStateBridge.d.ts +18 -0
- package/dist/workspaceStateBridge.d.ts.map +1 -0
- package/dist/workspaceStateBridge.js +22 -0
- package/dist/workspaceStateBridge.js.map +1 -0
- package/package.json +37 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
XENO Agent — Proprietary Software License
|
|
2
|
+
Copyright © 2026 XENO Corporation. All rights reserved.
|
|
3
|
+
|
|
4
|
+
This software, including its source code, compiled binaries, published packages,
|
|
5
|
+
assets, and accompanying documentation (collectively, the "Software"), is the
|
|
6
|
+
proprietary and confidential property of XENO Corporation ("XENO"). The Software
|
|
7
|
+
is licensed for use, not sold, and no title to or ownership of the Software is
|
|
8
|
+
transferred to any user.
|
|
9
|
+
|
|
10
|
+
1. GRANT OF USE
|
|
11
|
+
Subject to a separate written agreement and/or the terms of service published
|
|
12
|
+
at https://xenostudio.ai, XENO grants the end user a limited, non-exclusive,
|
|
13
|
+
non-transferable, revocable license to install and use the Software for its
|
|
14
|
+
intended purpose. The standalone desktop application ("the Agent") may be used
|
|
15
|
+
locally at no charge; connected platform features — hosted agent runs, model
|
|
16
|
+
inference, credits, and account services — are governed by the applicable
|
|
17
|
+
subscription and the XENO terms of service.
|
|
18
|
+
|
|
19
|
+
2. PACKAGE DISTRIBUTION
|
|
20
|
+
The `@xeno-corporation/xeno-agent-interface-*` and
|
|
21
|
+
`@xeno-corporation/xeno-agents-client` packages are published to a PRIVATE
|
|
22
|
+
registry and are licensed for use solely by XENO products and by parties
|
|
23
|
+
holding a separate written agreement with XENO. Access credentials to that
|
|
24
|
+
registry do not grant redistribution rights. Publication of any package in
|
|
25
|
+
this repository to a public registry is prohibited without written
|
|
26
|
+
authorization from XENO.
|
|
27
|
+
|
|
28
|
+
3. RESTRICTIONS
|
|
29
|
+
Except to the extent expressly permitted by applicable law or by a separate
|
|
30
|
+
written agreement with XENO, you may NOT: (a) copy, redistribute, sell, rent,
|
|
31
|
+
lease, sublicense, or otherwise transfer the Software; (b) modify, adapt,
|
|
32
|
+
translate, or create derivative works of the Software; (c) reverse-engineer,
|
|
33
|
+
decompile, or disassemble the Software, or attempt to derive its source code;
|
|
34
|
+
(d) remove, obscure, or alter any proprietary notices; or (e) use the Software
|
|
35
|
+
to build a competing product.
|
|
36
|
+
|
|
37
|
+
4. RESERVATION OF RIGHTS
|
|
38
|
+
All rights not expressly granted are reserved by XENO Corporation. The Software
|
|
39
|
+
is protected by copyright and other intellectual-property laws and treaties.
|
|
40
|
+
|
|
41
|
+
5. DISCLAIMER OF WARRANTY
|
|
42
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND "AS AVAILABLE", WITHOUT WARRANTY OF ANY
|
|
43
|
+
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
44
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THE
|
|
45
|
+
SOFTWARE EXECUTES AGENT-DIRECTED OPERATIONS AGAINST A USER-SELECTED WORKSPACE,
|
|
46
|
+
INCLUDING FILE AND PROCESS ACTIONS; THE USER IS RESPONSIBLE FOR THE WORKSPACES
|
|
47
|
+
AND PERMISSIONS THEY GRANT IT.
|
|
48
|
+
|
|
49
|
+
6. LIMITATION OF LIABILITY
|
|
50
|
+
TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL XENO CORPORATION BE
|
|
51
|
+
LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, OR PUNITIVE
|
|
52
|
+
DAMAGES, OR ANY LOSS OF PROFITS OR DATA, ARISING FROM OR RELATED TO THE USE OF
|
|
53
|
+
OR INABILITY TO USE THE SOFTWARE.
|
|
54
|
+
|
|
55
|
+
7. THIRD-PARTY COMPONENTS
|
|
56
|
+
The Software includes third-party open-source components, each licensed under
|
|
57
|
+
its own terms; those terms govern those components and are not superseded by
|
|
58
|
+
this license. It also composes third-party agent providers over the Agent
|
|
59
|
+
Client Protocol and hosted APIs; use of those providers is governed by their
|
|
60
|
+
own terms.
|
|
61
|
+
|
|
62
|
+
For licensing inquiries, contact: legal@xenostudio.ai
|
|
63
|
+
|
|
64
|
+
NOTE TO OPERATOR: confirm the exact legal entity name and notice/contact details
|
|
65
|
+
with counsel before public distribution and code-signing (the code-signing
|
|
66
|
+
publisher name must match the registered entity). No public distribution of this
|
|
67
|
+
product is authorized by this file — see docs/PRODUCT_STATUS.md.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Electron-free entry point: everything a host can run WITHOUT a renderer.
|
|
3
|
+
*
|
|
4
|
+
* 🔴 Splitting `sdkAgent.ts` from `permissionIpc.ts` was necessary and not sufficient. The
|
|
5
|
+
* package's only export was `.`, whose barrel re-exports the IPC module — so a headless host
|
|
6
|
+
* importing `@xenosystem/agent-interface-electron-host` would still have loaded `electron`
|
|
7
|
+
* transitively and failed, with the loop itself entirely innocent. The module boundary and the
|
|
8
|
+
* PACKAGE boundary have to agree, or the fix is invisible to every real consumer.
|
|
9
|
+
*
|
|
10
|
+
* So this subpath is the one a headless composition imports. The root export keeps its full
|
|
11
|
+
* surface, including the IPC registration, for the Electron app.
|
|
12
|
+
*
|
|
13
|
+
* ⚠️ Nothing added here may value-import `electron`, directly or transitively.
|
|
14
|
+
* `headlessLoadability.test.ts` loads this exact built file in a clean `node` subprocess and
|
|
15
|
+
* fails if it does — and keeps the root barrel as the opposite-result control, so the gate cannot
|
|
16
|
+
* pass by accident.
|
|
17
|
+
*
|
|
18
|
+
* ⚠️ The package NAME is now wrong for half its contents, and that is deliberate for the moment:
|
|
19
|
+
* renaming a published package is a coordinated change across every consumer, and doing it in the
|
|
20
|
+
* same commit as the split would confuse a mechanical move with a distribution change. It is
|
|
21
|
+
* recorded rather than quietly tolerated.
|
|
22
|
+
*/
|
|
23
|
+
export * from './sdkAgent.js';
|
|
24
|
+
export * from './headlessAgentSurface.js';
|
|
25
|
+
export * from './sdkNativeHeadlessRunner.js';
|
|
26
|
+
//# sourceMappingURL=headless.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headless.d.ts","sourceRoot":"","sources":["../src/headless.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,cAAc,eAAe,CAAA;AAC7B,cAAc,2BAA2B,CAAA;AACzC,cAAc,8BAA8B,CAAA"}
|
package/dist/headless.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Electron-free entry point: everything a host can run WITHOUT a renderer.
|
|
3
|
+
*
|
|
4
|
+
* 🔴 Splitting `sdkAgent.ts` from `permissionIpc.ts` was necessary and not sufficient. The
|
|
5
|
+
* package's only export was `.`, whose barrel re-exports the IPC module — so a headless host
|
|
6
|
+
* importing `@xenosystem/agent-interface-electron-host` would still have loaded `electron`
|
|
7
|
+
* transitively and failed, with the loop itself entirely innocent. The module boundary and the
|
|
8
|
+
* PACKAGE boundary have to agree, or the fix is invisible to every real consumer.
|
|
9
|
+
*
|
|
10
|
+
* So this subpath is the one a headless composition imports. The root export keeps its full
|
|
11
|
+
* surface, including the IPC registration, for the Electron app.
|
|
12
|
+
*
|
|
13
|
+
* ⚠️ Nothing added here may value-import `electron`, directly or transitively.
|
|
14
|
+
* `headlessLoadability.test.ts` loads this exact built file in a clean `node` subprocess and
|
|
15
|
+
* fails if it does — and keeps the root barrel as the opposite-result control, so the gate cannot
|
|
16
|
+
* pass by accident.
|
|
17
|
+
*
|
|
18
|
+
* ⚠️ The package NAME is now wrong for half its contents, and that is deliberate for the moment:
|
|
19
|
+
* renaming a published package is a coordinated change across every consumer, and doing it in the
|
|
20
|
+
* same commit as the split would confuse a mechanical move with a distribution change. It is
|
|
21
|
+
* recorded rather than quietly tolerated.
|
|
22
|
+
*/
|
|
23
|
+
export * from './sdkAgent.js';
|
|
24
|
+
export * from './headlessAgentSurface.js';
|
|
25
|
+
export * from './sdkNativeHeadlessRunner.js';
|
|
26
|
+
//# sourceMappingURL=headless.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headless.js","sourceRoot":"","sources":["../src/headless.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,cAAc,eAAe,CAAA;AAC7B,cAAc,2BAA2B,CAAA;AACzC,cAAc,8BAA8B,CAAA"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { SdkAgentSurface } from './sdkAgentSurface.js';
|
|
2
|
+
/**
|
|
3
|
+
* The SDK agent loop's surface for a host with no renderer.
|
|
4
|
+
*
|
|
5
|
+
* ## What this had to establish before it could be written
|
|
6
|
+
*
|
|
7
|
+
* The loop sends ten channels. It would be easy to assume a headless host must reimplement all
|
|
8
|
+
* ten, and wrong: measured at the emission site, `emitRuntimeEvent` **persists the event to the
|
|
9
|
+
* runtime store and calls `onPersistedRuntimeEvent` FIRST**, and only then forwards the same
|
|
10
|
+
* enriched event to the renderer. The window traffic is DERIVED from the runtime-event stream,
|
|
11
|
+
* not parallel to it.
|
|
12
|
+
*
|
|
13
|
+
* So a host that consumes `onPersistedRuntimeEvent` — which every composition already does —
|
|
14
|
+
* receives everything the renderer receives, for display purposes, with no window involved. The
|
|
15
|
+
* ten channels split cleanly:
|
|
16
|
+
*
|
|
17
|
+
* | channels | what a headless host owes them |
|
|
18
|
+
* |---|---|
|
|
19
|
+
* | `agent:runtime-event`, `agent:text-chunk`, `agent:done`, `agent:error`, `agent:tool-start`, `agent:tool-end`, `agent:task-event`, `workspaceStorage:changed` | **nothing** — the same facts already reached the host through the runtime-event stream |
|
|
20
|
+
* | `agent:permission-request`, `agent:ask-user-request` | **a real path to a human**, because nobody else can answer them |
|
|
21
|
+
*
|
|
22
|
+
* 🔴 That second row is why this class forwards rather than swallows, and why `onInteraction` is
|
|
23
|
+
* REQUIRED rather than optional. A permission request that goes nowhere does not degrade the
|
|
24
|
+
* turn — it hangs it, silently, because the loop is waiting for `grantSdkAccess` /
|
|
25
|
+
* `denySdkAccess` / `answerSdkAskUser` to be called by whoever displayed the prompt. A surface
|
|
26
|
+
* that quietly dropped those would produce an agent that appears to think forever, which is
|
|
27
|
+
* exactly the class of failure this repo keeps finding: a capability that reports nothing rather
|
|
28
|
+
* than failing.
|
|
29
|
+
*
|
|
30
|
+
* ⚠️ This does NOT answer permission requests. It carries them to the composition, which is the
|
|
31
|
+
* only layer that knows whether a human is reachable — a host serving an attached CLI can prompt
|
|
32
|
+
* through that client's elicitation channel; an unattended one must refuse rather than invent an
|
|
33
|
+
* answer. Deciding here would bake one of those choices in for both.
|
|
34
|
+
*/
|
|
35
|
+
/** The channels that require a human, and therefore a real route out of the host. */
|
|
36
|
+
export declare const INTERACTIVE_AGENT_CHANNELS: readonly ["agent:permission-request", "agent:ask-user-request"];
|
|
37
|
+
export type InteractiveAgentChannel = typeof INTERACTIVE_AGENT_CHANNELS[number];
|
|
38
|
+
export declare function isInteractiveAgentChannel(channel: string): channel is InteractiveAgentChannel;
|
|
39
|
+
export interface HeadlessAgentSurfaceOptions {
|
|
40
|
+
/**
|
|
41
|
+
* Called for every channel the loop emits, with `interactive` already classified so a
|
|
42
|
+
* composition cannot accidentally treat a permission prompt as a display update.
|
|
43
|
+
*
|
|
44
|
+
* Required, and deliberately not defaulted: see the note above on hangs.
|
|
45
|
+
*
|
|
46
|
+
* 🔴 Returns whether the message REACHED anyone. A headless host publishes to whatever clients
|
|
47
|
+
* are attached, and that set can be empty — a detached host running with nobody connected is a
|
|
48
|
+
* normal state, not an error.
|
|
49
|
+
*/
|
|
50
|
+
onEvent(message: {
|
|
51
|
+
channel: string;
|
|
52
|
+
payload: Record<string, unknown> | undefined;
|
|
53
|
+
interactive: boolean;
|
|
54
|
+
}): HeadlessDelivery;
|
|
55
|
+
/**
|
|
56
|
+
* Called when an INTERACTIVE message reached nobody.
|
|
57
|
+
*
|
|
58
|
+
* 🔴 Required, because this is the difference between a safe headless host and one that wedges.
|
|
59
|
+
* `requestSurfacePermission` has NO TIMEOUT — measured, not assumed: it returns a promise that
|
|
60
|
+
* settles only when `grantSdkAccess` or `denySdkAccess` is called with the matching
|
|
61
|
+
* `permissionId`. Publish a prompt to zero subscribers and the turn waits forever, holding its
|
|
62
|
+
* tool call open, with the agent appearing to think.
|
|
63
|
+
*
|
|
64
|
+
* The loop already encodes the correct direction for the reachable-but-gone case:
|
|
65
|
+
* `if (!mainWindow || mainWindow.isDestroyed()) return false` — *a prompt nobody can answer
|
|
66
|
+
* must not resolve as an approval*. This extends the same rule to "nobody received it", which
|
|
67
|
+
* is the only version a headless host can actually be in.
|
|
68
|
+
*
|
|
69
|
+
* The composition performs the denial (it owns `denySdkAccess`), because this module must not
|
|
70
|
+
* import the loop it reports to.
|
|
71
|
+
*/
|
|
72
|
+
onUnanswerableInteraction(message: {
|
|
73
|
+
channel: InteractiveAgentChannel;
|
|
74
|
+
payload: Record<string, unknown> | undefined;
|
|
75
|
+
}): void;
|
|
76
|
+
/**
|
|
77
|
+
* Whether the host still has anywhere to send. Defaults to "yes, always" — a headless host has
|
|
78
|
+
* no window to be destroyed, and its lifetime is the process's.
|
|
79
|
+
*/
|
|
80
|
+
isGone?(): boolean;
|
|
81
|
+
}
|
|
82
|
+
/** Whether a forwarded message reached at least one recipient. */
|
|
83
|
+
export interface HeadlessDelivery {
|
|
84
|
+
delivered: boolean;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Build a surface for a host with no renderer.
|
|
88
|
+
*
|
|
89
|
+
* Errors from `onEvent` are contained: the loop calls `send` from inside tool execution and
|
|
90
|
+
* streaming callbacks, where an exception would abort a turn that is otherwise fine. A broken
|
|
91
|
+
* consumer must not be able to kill the run it is merely observing — but it must not be silent
|
|
92
|
+
* either, so failures are reported through `onEventError` when supplied.
|
|
93
|
+
*/
|
|
94
|
+
export declare function createHeadlessAgentSurface(options: HeadlessAgentSurfaceOptions & {
|
|
95
|
+
onEventError?: (error: unknown, channel: string) => void;
|
|
96
|
+
}): SdkAgentSurface;
|
|
97
|
+
//# sourceMappingURL=headlessAgentSurface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headlessAgentSurface.d.ts","sourceRoot":"","sources":["../src/headlessAgentSurface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAE3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,qFAAqF;AACrF,eAAO,MAAM,0BAA0B,iEAG7B,CAAA;AAEV,MAAM,MAAM,uBAAuB,GAAG,OAAO,0BAA0B,CAAC,MAAM,CAAC,CAAA;AAE/E,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,IAAI,uBAAuB,CAE7F;AAED,MAAM,WAAW,2BAA2B;IAC1C;;;;;;;;;OASG;IACH,OAAO,CAAC,OAAO,EAAE;QACf,OAAO,EAAE,MAAM,CAAA;QACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAA;QAC5C,WAAW,EAAE,OAAO,CAAA;KACrB,GAAG,gBAAgB,CAAA;IAEpB;;;;;;;;;;;;;;;;OAgBG;IACH,yBAAyB,CAAC,OAAO,EAAE;QACjC,OAAO,EAAE,uBAAuB,CAAA;QAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAA;KAC7C,GAAG,IAAI,CAAA;IAER;;;OAGG;IACH,MAAM,CAAC,IAAI,OAAO,CAAA;CACnB;AAED,kEAAkE;AAClE,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,OAAO,CAAA;CACnB;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,2BAA2B,GAAG;IAAE,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,GAClG,eAAe,CA0BjB"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The SDK agent loop's surface for a host with no renderer.
|
|
3
|
+
*
|
|
4
|
+
* ## What this had to establish before it could be written
|
|
5
|
+
*
|
|
6
|
+
* The loop sends ten channels. It would be easy to assume a headless host must reimplement all
|
|
7
|
+
* ten, and wrong: measured at the emission site, `emitRuntimeEvent` **persists the event to the
|
|
8
|
+
* runtime store and calls `onPersistedRuntimeEvent` FIRST**, and only then forwards the same
|
|
9
|
+
* enriched event to the renderer. The window traffic is DERIVED from the runtime-event stream,
|
|
10
|
+
* not parallel to it.
|
|
11
|
+
*
|
|
12
|
+
* So a host that consumes `onPersistedRuntimeEvent` — which every composition already does —
|
|
13
|
+
* receives everything the renderer receives, for display purposes, with no window involved. The
|
|
14
|
+
* ten channels split cleanly:
|
|
15
|
+
*
|
|
16
|
+
* | channels | what a headless host owes them |
|
|
17
|
+
* |---|---|
|
|
18
|
+
* | `agent:runtime-event`, `agent:text-chunk`, `agent:done`, `agent:error`, `agent:tool-start`, `agent:tool-end`, `agent:task-event`, `workspaceStorage:changed` | **nothing** — the same facts already reached the host through the runtime-event stream |
|
|
19
|
+
* | `agent:permission-request`, `agent:ask-user-request` | **a real path to a human**, because nobody else can answer them |
|
|
20
|
+
*
|
|
21
|
+
* 🔴 That second row is why this class forwards rather than swallows, and why `onInteraction` is
|
|
22
|
+
* REQUIRED rather than optional. A permission request that goes nowhere does not degrade the
|
|
23
|
+
* turn — it hangs it, silently, because the loop is waiting for `grantSdkAccess` /
|
|
24
|
+
* `denySdkAccess` / `answerSdkAskUser` to be called by whoever displayed the prompt. A surface
|
|
25
|
+
* that quietly dropped those would produce an agent that appears to think forever, which is
|
|
26
|
+
* exactly the class of failure this repo keeps finding: a capability that reports nothing rather
|
|
27
|
+
* than failing.
|
|
28
|
+
*
|
|
29
|
+
* ⚠️ This does NOT answer permission requests. It carries them to the composition, which is the
|
|
30
|
+
* only layer that knows whether a human is reachable — a host serving an attached CLI can prompt
|
|
31
|
+
* through that client's elicitation channel; an unattended one must refuse rather than invent an
|
|
32
|
+
* answer. Deciding here would bake one of those choices in for both.
|
|
33
|
+
*/
|
|
34
|
+
/** The channels that require a human, and therefore a real route out of the host. */
|
|
35
|
+
export const INTERACTIVE_AGENT_CHANNELS = [
|
|
36
|
+
'agent:permission-request',
|
|
37
|
+
'agent:ask-user-request',
|
|
38
|
+
];
|
|
39
|
+
export function isInteractiveAgentChannel(channel) {
|
|
40
|
+
return INTERACTIVE_AGENT_CHANNELS.includes(channel);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Build a surface for a host with no renderer.
|
|
44
|
+
*
|
|
45
|
+
* Errors from `onEvent` are contained: the loop calls `send` from inside tool execution and
|
|
46
|
+
* streaming callbacks, where an exception would abort a turn that is otherwise fine. A broken
|
|
47
|
+
* consumer must not be able to kill the run it is merely observing — but it must not be silent
|
|
48
|
+
* either, so failures are reported through `onEventError` when supplied.
|
|
49
|
+
*/
|
|
50
|
+
export function createHeadlessAgentSurface(options) {
|
|
51
|
+
return {
|
|
52
|
+
send(channel, payload) {
|
|
53
|
+
const interactive = isInteractiveAgentChannel(channel);
|
|
54
|
+
let delivered = false;
|
|
55
|
+
try {
|
|
56
|
+
delivered = options.onEvent({ channel, payload, interactive }).delivered;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
options.onEventError?.(error, channel);
|
|
60
|
+
// A consumer that threw did not deliver. Treating a failed send as delivered would let
|
|
61
|
+
// the very error path this guard exists for produce the hang it is preventing.
|
|
62
|
+
delivered = false;
|
|
63
|
+
}
|
|
64
|
+
if (!interactive || delivered)
|
|
65
|
+
return;
|
|
66
|
+
try {
|
|
67
|
+
options.onUnanswerableInteraction({ channel: channel, payload });
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
// Nothing left to fall back to, so surface it rather than lose it: the turn is now very
|
|
71
|
+
// likely to hang and this is the only trace of why.
|
|
72
|
+
options.onEventError?.(error, channel);
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
isDestroyed() {
|
|
76
|
+
return options.isGone?.() ?? false;
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=headlessAgentSurface.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headlessAgentSurface.js","sourceRoot":"","sources":["../src/headlessAgentSurface.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,qFAAqF;AACrF,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,0BAA0B;IAC1B,wBAAwB;CAChB,CAAA;AAIV,MAAM,UAAU,yBAAyB,CAAC,OAAe;IACvD,OAAQ,0BAAgD,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;AAC5E,CAAC;AAqDD;;;;;;;GAOG;AACH,MAAM,UAAU,0BAA0B,CACxC,OAAmG;IAEnG,OAAO;QACL,IAAI,CAAC,OAAO,EAAE,OAAO;YACnB,MAAM,WAAW,GAAG,yBAAyB,CAAC,OAAO,CAAC,CAAA;YACtD,IAAI,SAAS,GAAG,KAAK,CAAA;YACrB,IAAI,CAAC;gBACH,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,SAAS,CAAA;YAC1E,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,YAAY,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;gBACtC,uFAAuF;gBACvF,+EAA+E;gBAC/E,SAAS,GAAG,KAAK,CAAA;YACnB,CAAC;YACD,IAAI,CAAC,WAAW,IAAI,SAAS;gBAAE,OAAM;YACrC,IAAI,CAAC;gBACH,OAAO,CAAC,yBAAyB,CAAC,EAAE,OAAO,EAAE,OAAkC,EAAE,OAAO,EAAE,CAAC,CAAA;YAC7F,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,wFAAwF;gBACxF,oDAAoD;gBACpD,OAAO,CAAC,YAAY,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;YACxC,CAAC;QACH,CAAC;QACD,WAAW;YACT,OAAO,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,KAAK,CAAA;QACpC,CAAC;KACF,CAAA;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from './sdkAgent.js';
|
|
2
|
+
export * from './headlessAgentSurface.js';
|
|
3
|
+
export * from './sdkNativeHeadlessRunner.js';
|
|
4
|
+
/**
|
|
5
|
+
* The Electron IPC surface, split out of `sdkAgent.js` so the agent loop no longer value-imports
|
|
6
|
+
* `electron` and can therefore be loaded by a headless host. Re-exported here so every existing
|
|
7
|
+
* `setupPermissionIPC` import keeps working — the move is structural, not a contract change.
|
|
8
|
+
*/
|
|
9
|
+
export * from './permissionIpc.js';
|
|
10
|
+
export * from './sdkNativeRunner.js';
|
|
11
|
+
export * from './surfaceRuntimeBridge.js';
|
|
12
|
+
export * from './workspaceStateBridge.js';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,2BAA2B,CAAA;AACzC,cAAc,8BAA8B,CAAA;AAC5C;;;;GAIG;AACH,cAAc,oBAAoB,CAAA;AAClC,cAAc,sBAAsB,CAAA;AACpC,cAAc,2BAA2B,CAAA;AACzC,cAAc,2BAA2B,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from './sdkAgent.js';
|
|
2
|
+
export * from './headlessAgentSurface.js';
|
|
3
|
+
export * from './sdkNativeHeadlessRunner.js';
|
|
4
|
+
/**
|
|
5
|
+
* The Electron IPC surface, split out of `sdkAgent.js` so the agent loop no longer value-imports
|
|
6
|
+
* `electron` and can therefore be loaded by a headless host. Re-exported here so every existing
|
|
7
|
+
* `setupPermissionIPC` import keeps working — the move is structural, not a contract change.
|
|
8
|
+
*/
|
|
9
|
+
export * from './permissionIpc.js';
|
|
10
|
+
export * from './sdkNativeRunner.js';
|
|
11
|
+
export * from './surfaceRuntimeBridge.js';
|
|
12
|
+
export * from './workspaceStateBridge.js';
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,2BAA2B,CAAA;AACzC,cAAc,8BAA8B,CAAA;AAC5C;;;;GAIG;AACH,cAAc,oBAAoB,CAAA;AAClC,cAAc,sBAAsB,CAAA;AACpC,cAAc,2BAA2B,CAAA;AACzC,cAAc,2BAA2B,CAAA"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Electron IPC surface for the SDK-native agent — split out of `sdkAgent.ts` 2026-08-17.
|
|
3
|
+
*
|
|
4
|
+
* 🔴 This exists so the AGENT LOOP can run without Electron.
|
|
5
|
+
*
|
|
6
|
+
* `sdkAgent.ts` is 6,000+ lines and looked deeply Electron-coupled. It was not: measured, the
|
|
7
|
+
* whole runtime dependency was `dialog` (imported, NEVER used), one `app.isPackaged` read, and
|
|
8
|
+
* these `ipcMain.handle` registrations — all of which lived in this single function at the
|
|
9
|
+
* bottom of the file. The loop itself uses `mainWindow` purely as an outbound event channel
|
|
10
|
+
* (`webContents.send`) plus a liveness check (`isDestroyed`).
|
|
11
|
+
*
|
|
12
|
+
* A module-level `import { ipcMain } from 'electron'` is enough to make the whole module
|
|
13
|
+
* unloadable in a plain Node process, so moving these 90 lines is what lets a headless host
|
|
14
|
+
* import the loop at all. That is the blocker for ADE step 5: `xeno-agent-cli` cannot become a
|
|
15
|
+
* pure surface while the only sdk-native lane needs a renderer window, and the CLI already runs
|
|
16
|
+
* this same loop headless today — so the work is RELOCATION, not new capability.
|
|
17
|
+
*
|
|
18
|
+
*
|
|
19
|
+
* @unwired-by-design Nothing in this repo calls it, and nothing ever has — verified against the
|
|
20
|
+
* pre-split tree, so this is not fallout from the 2026-08-17 refactor. It is a PUBLISHED export of
|
|
21
|
+
* `@xenosystem/agent-interface-electron-host` (0.1.2, ships `dist`) for an Electron composition
|
|
22
|
+
* that drives the SDK loop DIRECTLY over these `agent:*` channels.
|
|
23
|
+
*
|
|
24
|
+
* The standalone app deliberately does not: `apps/desktop/src/main/composeHost.ts` answers
|
|
25
|
+
* permissions through `sdkControlService`, i.e. over the host protocol, which is the direction
|
|
26
|
+
* the ADE spec takes every surface. Confirmed in the BUILT output as well as the source — the
|
|
27
|
+
* bundled chunk contains the declaration and the export, and no call.
|
|
28
|
+
*
|
|
29
|
+
* ⚠️ Do not read that as "superseded, delete it". Whether Hub adopts this repo through these
|
|
30
|
+
* channels or through the host protocol is an OPEN question owned by the Hub landing, and this is
|
|
31
|
+
* a published contract: removing an export is a breaking change to a package other compositions
|
|
32
|
+
* may already import. It stays until that adoption decides, and then it is retired deliberately
|
|
33
|
+
* with a major bump — not quietly, as tidying.
|
|
34
|
+
* ⚠️ What stays here is correctly Electron-resident: this is the renderer's IPC surface, and a
|
|
35
|
+
* headless host has no renderer to serve.
|
|
36
|
+
*/
|
|
37
|
+
export declare function setupPermissionIPC(): void;
|
|
38
|
+
//# sourceMappingURL=permissionIpc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissionIpc.d.ts","sourceRoot":"","sources":["../src/permissionIpc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAgBH,wBAAgB,kBAAkB,IAAI,IAAI,CAsFzC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Electron IPC surface for the SDK-native agent — split out of `sdkAgent.ts` 2026-08-17.
|
|
3
|
+
*
|
|
4
|
+
* 🔴 This exists so the AGENT LOOP can run without Electron.
|
|
5
|
+
*
|
|
6
|
+
* `sdkAgent.ts` is 6,000+ lines and looked deeply Electron-coupled. It was not: measured, the
|
|
7
|
+
* whole runtime dependency was `dialog` (imported, NEVER used), one `app.isPackaged` read, and
|
|
8
|
+
* these `ipcMain.handle` registrations — all of which lived in this single function at the
|
|
9
|
+
* bottom of the file. The loop itself uses `mainWindow` purely as an outbound event channel
|
|
10
|
+
* (`webContents.send`) plus a liveness check (`isDestroyed`).
|
|
11
|
+
*
|
|
12
|
+
* A module-level `import { ipcMain } from 'electron'` is enough to make the whole module
|
|
13
|
+
* unloadable in a plain Node process, so moving these 90 lines is what lets a headless host
|
|
14
|
+
* import the loop at all. That is the blocker for ADE step 5: `xeno-agent-cli` cannot become a
|
|
15
|
+
* pure surface while the only sdk-native lane needs a renderer window, and the CLI already runs
|
|
16
|
+
* this same loop headless today — so the work is RELOCATION, not new capability.
|
|
17
|
+
*
|
|
18
|
+
*
|
|
19
|
+
* @unwired-by-design Nothing in this repo calls it, and nothing ever has — verified against the
|
|
20
|
+
* pre-split tree, so this is not fallout from the 2026-08-17 refactor. It is a PUBLISHED export of
|
|
21
|
+
* `@xenosystem/agent-interface-electron-host` (0.1.2, ships `dist`) for an Electron composition
|
|
22
|
+
* that drives the SDK loop DIRECTLY over these `agent:*` channels.
|
|
23
|
+
*
|
|
24
|
+
* The standalone app deliberately does not: `apps/desktop/src/main/composeHost.ts` answers
|
|
25
|
+
* permissions through `sdkControlService`, i.e. over the host protocol, which is the direction
|
|
26
|
+
* the ADE spec takes every surface. Confirmed in the BUILT output as well as the source — the
|
|
27
|
+
* bundled chunk contains the declaration and the export, and no call.
|
|
28
|
+
*
|
|
29
|
+
* ⚠️ Do not read that as "superseded, delete it". Whether Hub adopts this repo through these
|
|
30
|
+
* channels or through the host protocol is an OPEN question owned by the Hub landing, and this is
|
|
31
|
+
* a published contract: removing an export is a breaking change to a package other compositions
|
|
32
|
+
* may already import. It stays until that adoption decides, and then it is retired deliberately
|
|
33
|
+
* with a major bump — not quietly, as tidying.
|
|
34
|
+
* ⚠️ What stays here is correctly Electron-resident: this is the renderer's IPC surface, and a
|
|
35
|
+
* headless host has no renderer to serve.
|
|
36
|
+
*/
|
|
37
|
+
import { ipcMain } from 'electron';
|
|
38
|
+
import { answerChooseDirectoryRequest, answerWorkspacePlacementRequest, pendingChooseDirectoryRequestCount, pendingWorkspacePlacementRequestCount, } from '@xenosystem/agent-interface-host/node';
|
|
39
|
+
import { answerSdkAskUser, createSdkNativeControlService, denySdkAccess, grantSdkAccess, logAgentDebug, } from './sdkAgent.js';
|
|
40
|
+
export function setupPermissionIPC() {
|
|
41
|
+
const sdkControl = createSdkNativeControlService();
|
|
42
|
+
ipcMain.handle('agent:grant-access', async (_, params) => grantSdkAccess(params));
|
|
43
|
+
ipcMain.handle('agent:deny-access', async (_, params) => denySdkAccess(params));
|
|
44
|
+
ipcMain.handle('agent:answer-ask-user', async (_, params) => answerSdkAskUser(params));
|
|
45
|
+
ipcMain.handle('agent:answer-choose-directory', async (_, params) => {
|
|
46
|
+
const result = answerChooseDirectoryRequest(params);
|
|
47
|
+
if (!result.success) {
|
|
48
|
+
logAgentDebug('ChooseDirectory answer failed: no pending request', {
|
|
49
|
+
chooseDirectoryId: result.chooseDirectoryId || null,
|
|
50
|
+
requestId: result.requestId || null,
|
|
51
|
+
pendingCount: pendingChooseDirectoryRequestCount(),
|
|
52
|
+
});
|
|
53
|
+
return { success: false, error: result.error || 'No pending ChooseDirectory request found' };
|
|
54
|
+
}
|
|
55
|
+
logAgentDebug('ChooseDirectory answer resolved', {
|
|
56
|
+
chooseDirectoryId: result.chooseDirectoryId,
|
|
57
|
+
requestId: result.requestId,
|
|
58
|
+
cancelled: result.cancelled,
|
|
59
|
+
selectedDirectory: result.path || null,
|
|
60
|
+
error: result.responseError || null,
|
|
61
|
+
});
|
|
62
|
+
return { success: true };
|
|
63
|
+
});
|
|
64
|
+
ipcMain.handle('agent:answer-workspace-placement', async (_, params) => {
|
|
65
|
+
const result = answerWorkspacePlacementRequest(params);
|
|
66
|
+
if (!result.success) {
|
|
67
|
+
logAgentDebug('ChooseWorkspacePlacement answer failed: no pending request', {
|
|
68
|
+
workspacePlacementId: result.workspacePlacementId || null,
|
|
69
|
+
requestId: result.requestId || null,
|
|
70
|
+
pendingCount: pendingWorkspacePlacementRequestCount(),
|
|
71
|
+
error: result.error || null,
|
|
72
|
+
});
|
|
73
|
+
return { success: false, error: result.error || 'No pending ChooseWorkspacePlacement request found' };
|
|
74
|
+
}
|
|
75
|
+
logAgentDebug('ChooseWorkspacePlacement answer resolved', {
|
|
76
|
+
workspacePlacementId: result.workspacePlacementId,
|
|
77
|
+
requestId: result.requestId,
|
|
78
|
+
choice: result.response?.choice || null,
|
|
79
|
+
directory: result.response?.directory || null,
|
|
80
|
+
workspaceName: result.response?.workspaceName || null,
|
|
81
|
+
cancelled: result.response?.cancelled === true,
|
|
82
|
+
error: result.response?.error || null,
|
|
83
|
+
});
|
|
84
|
+
return { success: true };
|
|
85
|
+
});
|
|
86
|
+
ipcMain.handle('agent:sdk-session-list', async (_, params) => (sdkControl.listSessions(asSdkControlParams(params))));
|
|
87
|
+
ipcMain.handle('agent:sdk-session-show', async (_, params) => (sdkControl.showSession(asSdkControlParams(params))));
|
|
88
|
+
ipcMain.handle('agent:sdk-session-attach', async (_, params) => (sdkControl.attachSession(asSdkControlParams(params))));
|
|
89
|
+
ipcMain.handle('agent:sdk-session-detach', async (_, params) => (sdkControl.detachSession(asSdkControlParams(params))));
|
|
90
|
+
ipcMain.handle('agent:sdk-session-delete', async (_, params) => (sdkControl.deleteSession(asSdkControlParams(params))));
|
|
91
|
+
ipcMain.handle('agent:sdk-session-clean', async (_, params) => (sdkControl.cleanSessions(asSdkControlParams(params))));
|
|
92
|
+
ipcMain.handle('agent:sdk-checkpoint-list', async (_, params) => (sdkControl.listCheckpoints(asSdkControlParams(params))));
|
|
93
|
+
ipcMain.handle('agent:sdk-checkpoint-restore', async (_, params) => (sdkControl.restoreCheckpoint(asSdkControlParams(params))));
|
|
94
|
+
ipcMain.handle('agent:sdk-checkpoint-delete', async (_, params) => (sdkControl.deleteCheckpoint(asSdkControlParams(params))));
|
|
95
|
+
ipcMain.handle('agent:sdk-task-output', async (_, params) => (sdkControl.readTaskOutput(asSdkControlParams(params))));
|
|
96
|
+
ipcMain.handle('agent:sdk-task-stop', async (_, params) => (sdkControl.stopTask(asSdkControlParams(params))));
|
|
97
|
+
}
|
|
98
|
+
function asSdkControlParams(params) {
|
|
99
|
+
return (params && typeof params === 'object' ? params : {});
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=permissionIpc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissionIpc.js","sourceRoot":"","sources":["../src/permissionIpc.ts"],"names":[],"mappings":"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"}
|