@xenosystem/agent-interface-runtime 0.1.12
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/cloudOptions.d.ts +28 -0
- package/dist/cloudOptions.d.ts.map +1 -0
- package/dist/cloudOptions.js +37 -0
- package/dist/cloudOptions.js.map +1 -0
- package/dist/composeHost.d.ts +171 -0
- package/dist/composeHost.d.ts.map +1 -0
- package/dist/composeHost.js +877 -0
- package/dist/composeHost.js.map +1 -0
- package/dist/detachedHostEntry.d.ts +51 -0
- package/dist/detachedHostEntry.d.ts.map +1 -0
- package/dist/detachedHostEntry.js +185 -0
- package/dist/detachedHostEntry.js.map +1 -0
- package/dist/hostLanePolicy.d.ts +122 -0
- package/dist/hostLanePolicy.d.ts.map +1 -0
- package/dist/hostLanePolicy.js +86 -0
- package/dist/hostLanePolicy.js.map +1 -0
- package/dist/hostServices.d.ts +56 -0
- package/dist/hostServices.d.ts.map +1 -0
- package/dist/hostServices.js +74 -0
- package/dist/hostServices.js.map +1 -0
- package/dist/hostSupervisorAdapter.d.ts +31 -0
- package/dist/hostSupervisorAdapter.d.ts.map +1 -0
- package/dist/hostSupervisorAdapter.js +59 -0
- package/dist/hostSupervisorAdapter.js.map +1 -0
- package/dist/node.d.ts +7 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +7 -0
- package/dist/node.js.map +1 -0
- package/dist/observationConfig.d.ts +45 -0
- package/dist/observationConfig.d.ts.map +1 -0
- package/dist/observationConfig.js +78 -0
- package/dist/observationConfig.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The host services every composition must build the same way.
|
|
3
|
+
*
|
|
4
|
+
* ## ๐ด Why this module exists
|
|
5
|
+
*
|
|
6
|
+
* `composeHost.ts` is the shared composition ADE ยง9 step 3 is heading for, and
|
|
7
|
+
* `index.ts` โ the Electron main the user actually launches โ still builds its
|
|
8
|
+
* own `AgentHostCoordinator`. That fork is real and is being closed in one
|
|
9
|
+
* deliberate commit, not as a side effect of feature work.
|
|
10
|
+
*
|
|
11
|
+
* Meanwhile the four ยง5 services were mounted in `composeHost` only, which
|
|
12
|
+
* meant they reached the DETACHED host and nobody who starts the app. The gate
|
|
13
|
+
* in `packages/host/src/serviceMounting.test.ts` now asks the sharper question
|
|
14
|
+
* โ "does this reach the SHIPPED app" โ and named them as an adoption gap.
|
|
15
|
+
*
|
|
16
|
+
* Closing that gap by pasting the constructions into `index.ts` would answer
|
|
17
|
+
* the gate and create a worse defect: two spellings of the same decision, in
|
|
18
|
+
* the two files least likely to be read together. The ecosystem rule is that a
|
|
19
|
+
* rule belongs in the shared callee and there must be exactly ONE spelling of
|
|
20
|
+
* it, so the decisions live here and both compositions call this.
|
|
21
|
+
*
|
|
22
|
+
* ## What is a decision, and what is glue
|
|
23
|
+
*
|
|
24
|
+
* Only choices that must not diverge are here. `onRunActivity` is NOT: it binds
|
|
25
|
+
* to the coordinator that composition builds, so the two are genuinely
|
|
26
|
+
* different values rather than one rule written twice.
|
|
27
|
+
*/
|
|
28
|
+
import { AgentSessionService, CoordinationService, InMemoryWorkspaceKnowledgeStore, IntakeService, WorkspaceKnowledgeService, WorkspaceTodoIntakeSource, } from '@xenosystem/agent-interface-host/node';
|
|
29
|
+
export function createSharedHostServices(options) {
|
|
30
|
+
/**
|
|
31
|
+
* Workspace knowledge โ ADE ยง5.8.
|
|
32
|
+
*
|
|
33
|
+
* ๐ด `durable: false` is the TRUTH, not a placeholder. The only store that
|
|
34
|
+
* exists is in-memory, so facts are lost on quit โ and the panel's first line
|
|
35
|
+
* says so. Claiming durability here would make the surface lie on our behalf;
|
|
36
|
+
* the honest warning is what makes the feature safe to use at all.
|
|
37
|
+
*/
|
|
38
|
+
const knowledgeService = new WorkspaceKnowledgeService({
|
|
39
|
+
store: new InMemoryWorkspaceKnowledgeStore(),
|
|
40
|
+
durable: false,
|
|
41
|
+
});
|
|
42
|
+
/**
|
|
43
|
+
* Intake โ ADE ยง5.1.
|
|
44
|
+
*
|
|
45
|
+
* A repository-TODO source needs the user's project, and the only tree the
|
|
46
|
+
* host may read is one granted through a native dialog โ which is why the
|
|
47
|
+
* roots are resolved at POLL time, not here.
|
|
48
|
+
*
|
|
49
|
+
* With no grants yet this reports an empty inbox rather than a failure:
|
|
50
|
+
* correct for a fresh install, and different from "the source could not be
|
|
51
|
+
* read", which ยง5.1 requires to surface as an INCOMPLETE inbox.
|
|
52
|
+
*/
|
|
53
|
+
const intakeService = new IntakeService({
|
|
54
|
+
sources: [new WorkspaceTodoIntakeSource({ resolveRoots: options.resolveIntakeRoots })],
|
|
55
|
+
});
|
|
56
|
+
/**
|
|
57
|
+
* Sessions โ ADE ยง2.8.
|
|
58
|
+
*
|
|
59
|
+
* No native module is involved, which is why this is constructed here rather
|
|
60
|
+
* than behind a surface capability: `node-pty` becomes necessary only when
|
|
61
|
+
* the `native-tui` lane exists, and it does not.
|
|
62
|
+
*/
|
|
63
|
+
const sessionService = new AgentSessionService();
|
|
64
|
+
/** Coordination โ ADE ยง5.2b. */
|
|
65
|
+
const coordinationService = new CoordinationService();
|
|
66
|
+
const coordinationPort = {
|
|
67
|
+
send: (input) => coordinationService.send(input),
|
|
68
|
+
peers: (callerRunId) => coordinationService.peers(callerRunId),
|
|
69
|
+
runSummary: (callerRunId, targetRunId) => coordinationService.runSummary(callerRunId, targetRunId),
|
|
70
|
+
acquireClaim: (scope, runId) => coordinationService.acquireClaim(scope, runId),
|
|
71
|
+
};
|
|
72
|
+
return { knowledgeService, intakeService, sessionService, coordinationService, coordinationPort };
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=hostServices.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hostServices.js","sourceRoot":"","sources":["../src/hostServices.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,+BAA+B,EAC/B,aAAa,EACb,yBAAyB,EACzB,yBAAyB,GAE1B,MAAM,uCAAuC,CAAA;AA8B9C,MAAM,UAAU,wBAAwB,CACtC,OAAiC;IAEjC;;;;;;;OAOG;IACH,MAAM,gBAAgB,GAAG,IAAI,yBAAyB,CAAC;QACrD,KAAK,EAAE,IAAI,+BAA+B,EAAE;QAC5C,OAAO,EAAE,KAAK;KACf,CAAC,CAAA;IAEF;;;;;;;;;;OAUG;IACH,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC;QACtC,OAAO,EAAE,CAAC,IAAI,yBAAyB,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;KACvF,CAAC,CAAA;IAEF;;;;;;OAMG;IACH,MAAM,cAAc,GAAG,IAAI,mBAAmB,EAAE,CAAA;IAEhD,gCAAgC;IAChC,MAAM,mBAAmB,GAAG,IAAI,mBAAmB,EAAE,CAAA;IACrD,MAAM,gBAAgB,GAAyB;QAC7C,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC;QAChD,KAAK,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,mBAAmB,CAAC,KAAK,CAAC,WAAW,CAAC;QAC9D,UAAU,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,EAAE,CAAC,mBAAmB,CAAC,UAAU,CAAC,WAAW,EAAE,WAAW,CAAC;QAClG,YAAY,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,mBAAmB,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC;KAC/E,CAAA;IAED,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,cAAc,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,CAAA;AACnG,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { attachToLocalAgentHost, type LocalAgentHostAuthoritySession } from '@xenosystem/agent-interface-client/local';
|
|
2
|
+
import { superviseDetachedHost, type DetachedHostSupervisorHandle } from '@xenosystem/agent-interface-host/node';
|
|
3
|
+
export interface EnsureSharedAgentHostOptions {
|
|
4
|
+
homeDirectory: string;
|
|
5
|
+
hostVersion: string;
|
|
6
|
+
launcherInstanceId: string;
|
|
7
|
+
execPath: string;
|
|
8
|
+
entryPath: string;
|
|
9
|
+
hostRootDirectory?: string;
|
|
10
|
+
env?: NodeJS.ProcessEnv;
|
|
11
|
+
readyTimeoutMs?: number;
|
|
12
|
+
attachAttempts?: number;
|
|
13
|
+
attachRetryDelayMs?: number;
|
|
14
|
+
/** Test seam. Production callers leave this absent. */
|
|
15
|
+
attachFn?: typeof attachToLocalAgentHost;
|
|
16
|
+
/** Test seam. Production callers leave this absent. */
|
|
17
|
+
superviseFn?: typeof superviseDetachedHost;
|
|
18
|
+
}
|
|
19
|
+
export interface SharedAgentHostAttachment {
|
|
20
|
+
session: LocalAgentHostAuthoritySession;
|
|
21
|
+
/** True only when this launcher won the race to start the canonical host. */
|
|
22
|
+
launched: boolean;
|
|
23
|
+
/** Present for the launcher that started the host; ordinary surface disposal leaves it alive. */
|
|
24
|
+
supervisor?: DetachedHostSupervisorHandle;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Attach to the one per-user Agent host, starting the canonical detached runtime when absent.
|
|
28
|
+
* Two products may race here: the lease chooses one host and every loser joins that winner.
|
|
29
|
+
*/
|
|
30
|
+
export declare function ensureSharedAgentHost(options: EnsureSharedAgentHostOptions): Promise<SharedAgentHostAttachment>;
|
|
31
|
+
//# sourceMappingURL=hostSupervisorAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hostSupervisorAdapter.d.ts","sourceRoot":"","sources":["../src/hostSupervisorAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EAEtB,KAAK,8BAA8B,EACpC,MAAM,0CAA0C,CAAA;AACjD,OAAO,EACL,qBAAqB,EACrB,KAAK,4BAA4B,EAElC,MAAM,uCAAuC,CAAA;AAE9C,MAAM,WAAW,4BAA4B;IAC3C,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,uDAAuD;IACvD,QAAQ,CAAC,EAAE,OAAO,sBAAsB,CAAA;IACxC,uDAAuD;IACvD,WAAW,CAAC,EAAE,OAAO,qBAAqB,CAAA;CAC3C;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,8BAA8B,CAAA;IACvC,6EAA6E;IAC7E,QAAQ,EAAE,OAAO,CAAA;IACjB,iGAAiG;IACjG,UAAU,CAAC,EAAE,4BAA4B,CAAA;CAC1C;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,yBAAyB,CAAC,CAqDpC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { attachToLocalAgentHost, resolveLocalAgentHostRoot, } from '@xenosystem/agent-interface-client/local';
|
|
2
|
+
import { superviseDetachedHost, } from '@xenosystem/agent-interface-host/node';
|
|
3
|
+
/**
|
|
4
|
+
* Attach to the one per-user Agent host, starting the canonical detached runtime when absent.
|
|
5
|
+
* Two products may race here: the lease chooses one host and every loser joins that winner.
|
|
6
|
+
*/
|
|
7
|
+
export async function ensureSharedAgentHost(options) {
|
|
8
|
+
const attach = options.attachFn ?? attachToLocalAgentHost;
|
|
9
|
+
const supervise = options.superviseFn ?? superviseDetachedHost;
|
|
10
|
+
const rootDirectory = resolveLocalAgentHostRoot({
|
|
11
|
+
homeDirectory: options.homeDirectory,
|
|
12
|
+
...(options.hostRootDirectory ? { hostRootDirectory: options.hostRootDirectory } : {}),
|
|
13
|
+
});
|
|
14
|
+
const existing = await attach({ rootDirectory });
|
|
15
|
+
if (existing.attached)
|
|
16
|
+
return { session: existing.session, launched: false };
|
|
17
|
+
let supervisor;
|
|
18
|
+
let launchError;
|
|
19
|
+
try {
|
|
20
|
+
const launchOptions = {
|
|
21
|
+
execPath: options.execPath,
|
|
22
|
+
entryPath: options.entryPath,
|
|
23
|
+
env: {
|
|
24
|
+
...options.env,
|
|
25
|
+
XENO_AGENT_DETACHED_HOME: options.homeDirectory,
|
|
26
|
+
XENO_AGENT_DETACHED_VERSION: options.hostVersion,
|
|
27
|
+
XENO_AGENT_DETACHED_INSTANCE: `${options.launcherInstanceId}-host`,
|
|
28
|
+
...(options.hostRootDirectory ? { XENO_AGENT_HOST_ROOT: options.hostRootDirectory } : {}),
|
|
29
|
+
},
|
|
30
|
+
...(options.readyTimeoutMs === undefined ? {} : { readyTimeoutMs: options.readyTimeoutMs }),
|
|
31
|
+
};
|
|
32
|
+
supervisor = await supervise(launchOptions);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
// Another product may have won between our first attachment attempt and spawn.
|
|
36
|
+
launchError = error;
|
|
37
|
+
}
|
|
38
|
+
const attempts = Math.max(1, options.attachAttempts ?? 20);
|
|
39
|
+
const retryDelay = Math.max(0, options.attachRetryDelayMs ?? 100);
|
|
40
|
+
let detail = existing.detail;
|
|
41
|
+
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
42
|
+
const result = await attach({ rootDirectory });
|
|
43
|
+
if (result.attached) {
|
|
44
|
+
return {
|
|
45
|
+
session: result.session,
|
|
46
|
+
launched: supervisor !== undefined,
|
|
47
|
+
...(supervisor ? { supervisor } : {}),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
detail = result.detail;
|
|
51
|
+
if (attempt + 1 < attempts && retryDelay > 0) {
|
|
52
|
+
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
await supervisor?.stop().catch(() => undefined);
|
|
56
|
+
const reason = launchError instanceof Error ? launchError.message : String(launchError ?? detail);
|
|
57
|
+
throw new Error(`The canonical XENO Agent host could not be started or attached: ${reason}`);
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=hostSupervisorAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hostSupervisorAdapter.js","sourceRoot":"","sources":["../src/hostSupervisorAdapter.ts"],"names":[],"mappings":"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"}
|
package/dist/node.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './composeHost.js';
|
|
2
|
+
export * from './cloudOptions.js';
|
|
3
|
+
export * from './hostLanePolicy.js';
|
|
4
|
+
export * from './hostServices.js';
|
|
5
|
+
export * from './hostSupervisorAdapter.js';
|
|
6
|
+
export * from './observationConfig.js';
|
|
7
|
+
//# sourceMappingURL=node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AACjC,cAAc,qBAAqB,CAAA;AACnC,cAAc,mBAAmB,CAAA;AACjC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,wBAAwB,CAAA"}
|
package/dist/node.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './composeHost.js';
|
|
2
|
+
export * from './cloudOptions.js';
|
|
3
|
+
export * from './hostLanePolicy.js';
|
|
4
|
+
export * from './hostServices.js';
|
|
5
|
+
export * from './hostSupervisorAdapter.js';
|
|
6
|
+
export * from './observationConfig.js';
|
|
7
|
+
//# sourceMappingURL=node.js.map
|
package/dist/node.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AACjC,cAAc,qBAAqB,CAAA;AACnC,cAAc,mBAAmB,CAAA;AACjC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,wBAAwB,CAAA"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether this shared runtime observes runs, and against what.
|
|
3
|
+
*
|
|
4
|
+
* Pure and side-effect free, for the same reason `updaterPolicy.ts` is: the
|
|
5
|
+
* decision rules are the part worth testing, and a rule that lives inside the
|
|
6
|
+
* composition root can only be tested by booting Electron.
|
|
7
|
+
*
|
|
8
|
+
* ## Absent configuration means NO OBSERVATION โ never a fake one
|
|
9
|
+
*
|
|
10
|
+
* Tier-1 observation needs a running `xeno-use`. Most installations do not have
|
|
11
|
+
* one, and the honest answer there is that review is unavailable: the host
|
|
12
|
+
* mounts no observation service, `capabilityFor` drops below tier 1, and
|
|
13
|
+
* `mayLand` refuses for want of a diff. Every one of those behaviours already
|
|
14
|
+
* exists and is correct.
|
|
15
|
+
*
|
|
16
|
+
* The tempting alternative โ mount the service anyway so the wiring is "always
|
|
17
|
+
* there" โ produces a service that is registered and permanently empty, which
|
|
18
|
+
* is indistinguishable from a run that changed nothing. That is the false-clean
|
|
19
|
+
* diff the whole path exists to prevent, arrived at by way of tidiness.
|
|
20
|
+
*
|
|
21
|
+
* ## Half-configured is DISABLED, and says so
|
|
22
|
+
*
|
|
23
|
+
* A URL with no token authenticates nothing, so every call would 401 and every
|
|
24
|
+
* run would go unobserved anyway โ but silently, one failure per run, with no
|
|
25
|
+
* hint that the cause was configuration. Resolving it to `disabled` with a
|
|
26
|
+
* reason turns a recurring runtime mystery into one line at startup. This is
|
|
27
|
+
* the same failure electron-builder has with `CSC_LINK` set and
|
|
28
|
+
* `CSC_KEY_PASSWORD` missing, and the same answer: a half-configured route must
|
|
29
|
+
* fail loudly rather than quietly produce the wrong thing.
|
|
30
|
+
*/
|
|
31
|
+
export interface ObservationConfig {
|
|
32
|
+
enabled: boolean;
|
|
33
|
+
baseUrl?: string;
|
|
34
|
+
token?: string;
|
|
35
|
+
image?: string;
|
|
36
|
+
/** Present whenever observation is off for a reason worth telling an operator. */
|
|
37
|
+
reason?: string;
|
|
38
|
+
}
|
|
39
|
+
export interface ObservationEnv {
|
|
40
|
+
XENO_AGENT_USE_URL?: string | undefined;
|
|
41
|
+
XENO_AGENT_USE_TOKEN?: string | undefined;
|
|
42
|
+
XENO_AGENT_USE_IMAGE?: string | undefined;
|
|
43
|
+
}
|
|
44
|
+
export declare function resolveObservationConfig(env: ObservationEnv): ObservationConfig;
|
|
45
|
+
//# sourceMappingURL=observationConfig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observationConfig.d.ts","sourceRoot":"","sources":["../src/observationConfig.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,oBAAoB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACzC,oBAAoB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC1C;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,cAAc,GAAG,iBAAiB,CA4C/E"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether this shared runtime observes runs, and against what.
|
|
3
|
+
*
|
|
4
|
+
* Pure and side-effect free, for the same reason `updaterPolicy.ts` is: the
|
|
5
|
+
* decision rules are the part worth testing, and a rule that lives inside the
|
|
6
|
+
* composition root can only be tested by booting Electron.
|
|
7
|
+
*
|
|
8
|
+
* ## Absent configuration means NO OBSERVATION โ never a fake one
|
|
9
|
+
*
|
|
10
|
+
* Tier-1 observation needs a running `xeno-use`. Most installations do not have
|
|
11
|
+
* one, and the honest answer there is that review is unavailable: the host
|
|
12
|
+
* mounts no observation service, `capabilityFor` drops below tier 1, and
|
|
13
|
+
* `mayLand` refuses for want of a diff. Every one of those behaviours already
|
|
14
|
+
* exists and is correct.
|
|
15
|
+
*
|
|
16
|
+
* The tempting alternative โ mount the service anyway so the wiring is "always
|
|
17
|
+
* there" โ produces a service that is registered and permanently empty, which
|
|
18
|
+
* is indistinguishable from a run that changed nothing. That is the false-clean
|
|
19
|
+
* diff the whole path exists to prevent, arrived at by way of tidiness.
|
|
20
|
+
*
|
|
21
|
+
* ## Half-configured is DISABLED, and says so
|
|
22
|
+
*
|
|
23
|
+
* A URL with no token authenticates nothing, so every call would 401 and every
|
|
24
|
+
* run would go unobserved anyway โ but silently, one failure per run, with no
|
|
25
|
+
* hint that the cause was configuration. Resolving it to `disabled` with a
|
|
26
|
+
* reason turns a recurring runtime mystery into one line at startup. This is
|
|
27
|
+
* the same failure electron-builder has with `CSC_LINK` set and
|
|
28
|
+
* `CSC_KEY_PASSWORD` missing, and the same answer: a half-configured route must
|
|
29
|
+
* fail loudly rather than quietly produce the wrong thing.
|
|
30
|
+
*/
|
|
31
|
+
export function resolveObservationConfig(env) {
|
|
32
|
+
const baseUrl = (env.XENO_AGENT_USE_URL ?? '').trim();
|
|
33
|
+
const token = (env.XENO_AGENT_USE_TOKEN ?? '').trim();
|
|
34
|
+
const image = (env.XENO_AGENT_USE_IMAGE ?? '').trim();
|
|
35
|
+
// Nothing configured is the ordinary case and not a problem, so it carries no
|
|
36
|
+
// reason: an operator who never asked for observation should not be told
|
|
37
|
+
// every startup that they do not have it.
|
|
38
|
+
if (!baseUrl && !token)
|
|
39
|
+
return { enabled: false };
|
|
40
|
+
if (!baseUrl) {
|
|
41
|
+
return { enabled: false, reason: 'XENO_AGENT_USE_TOKEN is set but XENO_AGENT_USE_URL is not, so run observation is off.' };
|
|
42
|
+
}
|
|
43
|
+
if (!token) {
|
|
44
|
+
return { enabled: false, reason: 'XENO_AGENT_USE_URL is set but XENO_AGENT_USE_TOKEN is not, so run observation is off.' };
|
|
45
|
+
}
|
|
46
|
+
let parsed;
|
|
47
|
+
try {
|
|
48
|
+
parsed = new URL(baseUrl);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return { enabled: false, reason: `XENO_AGENT_USE_URL is not a valid URL, so run observation is off.` };
|
|
52
|
+
}
|
|
53
|
+
// ๐ด http: is allowed ONLY on the loopback interface. `xeno-use` is designed
|
|
54
|
+
// as a local sidecar, and its bearer token is the whole authorization โ over
|
|
55
|
+
// plaintext to another host that token is readable by anything on the path,
|
|
56
|
+
// and it authorizes creating containers with host directories mounted into
|
|
57
|
+
// them. A remote endpoint must be https.
|
|
58
|
+
if (parsed.protocol === 'http:' && !isLoopback(parsed.hostname)) {
|
|
59
|
+
return {
|
|
60
|
+
enabled: false,
|
|
61
|
+
reason: 'XENO_AGENT_USE_URL uses http: to a non-loopback host, which would send the bearer token in plaintext. Use https:, so run observation is off.',
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
|
|
65
|
+
return { enabled: false, reason: `XENO_AGENT_USE_URL must be http: or https:, so run observation is off.` };
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
enabled: true,
|
|
69
|
+
baseUrl: baseUrl.replace(/\/+$/, ''),
|
|
70
|
+
token,
|
|
71
|
+
...(image ? { image } : {}),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function isLoopback(hostname) {
|
|
75
|
+
const host = hostname.replace(/^\[|\]$/g, '').toLowerCase();
|
|
76
|
+
return host === 'localhost' || host === '127.0.0.1' || host === '::1' || host.startsWith('127.');
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=observationConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observationConfig.js","sourceRoot":"","sources":["../src/observationConfig.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAiBH,MAAM,UAAU,wBAAwB,CAAC,GAAmB;IAC1D,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IACrD,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,oBAAoB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IACrD,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,oBAAoB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IAErD,8EAA8E;IAC9E,yEAAyE;IACzE,0CAA0C;IAC1C,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;IAEjD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,uFAAuF,EAAE,CAAA;IAC5H,CAAC;IACD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,uFAAuF,EAAE,CAAA;IAC5H,CAAC;IAED,IAAI,MAAW,CAAA;IACf,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAA;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,mEAAmE,EAAE,CAAA;IACxG,CAAC;IACD,6EAA6E;IAC7E,6EAA6E;IAC7E,4EAA4E;IAC5E,2EAA2E;IAC3E,yCAAyC;IACzC,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChE,OAAO;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,8IAA8I;SACvJ,CAAA;IACH,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAChE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,wEAAwE,EAAE,CAAA;IAC7G,CAAC;IAED,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QACpC,KAAK;QACL,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5B,CAAA;AACH,CAAC;AAED,SAAS,UAAU,CAAC,QAAgB;IAClC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAA;IAC3D,OAAO,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;AAClG,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@xenosystem/agent-interface-runtime",
|
|
3
|
+
"version": "0.1.12",
|
|
4
|
+
"license": "UNLICENSED",
|
|
5
|
+
"description": "Canonical XENO Agent host composition and launchable detached runtime.",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/node.js",
|
|
8
|
+
"types": "./dist/node.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/node.d.ts",
|
|
12
|
+
"import": "./dist/node.js"
|
|
13
|
+
},
|
|
14
|
+
"./node": {
|
|
15
|
+
"types": "./dist/node.d.ts",
|
|
16
|
+
"import": "./dist/node.js"
|
|
17
|
+
},
|
|
18
|
+
"./detached-entry": {
|
|
19
|
+
"types": "./dist/detachedHostEntry.d.ts",
|
|
20
|
+
"import": "./dist/detachedHostEntry.js",
|
|
21
|
+
"default": "./dist/detachedHostEntry.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist"
|
|
26
|
+
],
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public"
|
|
29
|
+
},
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/XENO-CORPORATION/xeno-agent-interface.git",
|
|
33
|
+
"directory": "packages/runtime"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@xenosystem/acp-agent": "0.2.6",
|
|
37
|
+
"@xenosystem/agent-interface-client": "0.1.12",
|
|
38
|
+
"@xenosystem/agents-client": "0.1.12",
|
|
39
|
+
"@xenosystem/agent-interface-electron-host": "0.1.12",
|
|
40
|
+
"@xenosystem/agent-interface-host": "0.1.12",
|
|
41
|
+
"@xenosystem/agent-interface-contract": "0.1.12"
|
|
42
|
+
},
|
|
43
|
+
"scripts": {}
|
|
44
|
+
}
|