@xenosystem/agent-interface-runtime 0.1.25 → 0.1.26

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.
Files changed (60) hide show
  1. package/dist/accountWorkerConfiguration.d.ts +10 -0
  2. package/dist/accountWorkerConfiguration.d.ts.map +1 -0
  3. package/dist/accountWorkerConfiguration.js +19 -0
  4. package/dist/accountWorkerConfiguration.js.map +1 -0
  5. package/dist/browser/BrowserAuthorityResources.d.ts +33 -0
  6. package/dist/browser/BrowserAuthorityResources.d.ts.map +1 -0
  7. package/dist/browser/BrowserAuthorityResources.js +35 -0
  8. package/dist/browser/BrowserAuthorityResources.js.map +1 -0
  9. package/dist/browser/BrowserCommandPreparationStore.d.ts +46 -0
  10. package/dist/browser/BrowserCommandPreparationStore.d.ts.map +1 -0
  11. package/dist/browser/BrowserCommandPreparationStore.js +135 -0
  12. package/dist/browser/BrowserCommandPreparationStore.js.map +1 -0
  13. package/dist/browser/BrowserConsentController.d.ts +38 -0
  14. package/dist/browser/BrowserConsentController.d.ts.map +1 -0
  15. package/dist/browser/BrowserConsentController.js +46 -0
  16. package/dist/browser/BrowserConsentController.js.map +1 -0
  17. package/dist/browser/BrowserInteractiveConsent.d.ts +24 -0
  18. package/dist/browser/BrowserInteractiveConsent.d.ts.map +1 -0
  19. package/dist/browser/BrowserInteractiveConsent.js +45 -0
  20. package/dist/browser/BrowserInteractiveConsent.js.map +1 -0
  21. package/dist/browser/OwnedBrowserHostServices.d.ts +38 -0
  22. package/dist/browser/OwnedBrowserHostServices.d.ts.map +1 -0
  23. package/dist/browser/OwnedBrowserHostServices.js +31 -0
  24. package/dist/browser/OwnedBrowserHostServices.js.map +1 -0
  25. package/dist/browser/PersistedBrowserPolicyResolver.d.ts +22 -0
  26. package/dist/browser/PersistedBrowserPolicyResolver.d.ts.map +1 -0
  27. package/dist/browser/PersistedBrowserPolicyResolver.js +62 -0
  28. package/dist/browser/PersistedBrowserPolicyResolver.js.map +1 -0
  29. package/dist/browser/SdkBrowserCommandAuthority.d.ts +152 -0
  30. package/dist/browser/SdkBrowserCommandAuthority.d.ts.map +1 -0
  31. package/dist/browser/SdkBrowserCommandAuthority.js +181 -0
  32. package/dist/browser/SdkBrowserCommandAuthority.js.map +1 -0
  33. package/dist/browser/createSdkBrowserAuthority.d.ts +14 -0
  34. package/dist/browser/createSdkBrowserAuthority.d.ts.map +1 -0
  35. package/dist/browser/createSdkBrowserAuthority.js +43 -0
  36. package/dist/browser/createSdkBrowserAuthority.js.map +1 -0
  37. package/dist/browser/managedBrowserConfiguration.d.ts +22 -0
  38. package/dist/browser/managedBrowserConfiguration.d.ts.map +1 -0
  39. package/dist/browser/managedBrowserConfiguration.js +70 -0
  40. package/dist/browser/managedBrowserConfiguration.js.map +1 -0
  41. package/dist/composeHost.d.ts +18 -0
  42. package/dist/composeHost.d.ts.map +1 -1
  43. package/dist/composeHost.js +275 -67
  44. package/dist/composeHost.js.map +1 -1
  45. package/dist/detachedHostEntry.d.ts.map +1 -1
  46. package/dist/detachedHostEntry.js +5 -1
  47. package/dist/detachedHostEntry.js.map +1 -1
  48. package/dist/hostServices.d.ts +2 -1
  49. package/dist/hostServices.d.ts.map +1 -1
  50. package/dist/hostServices.js +5 -7
  51. package/dist/hostServices.js.map +1 -1
  52. package/dist/node.d.ts +6 -0
  53. package/dist/node.d.ts.map +1 -1
  54. package/dist/node.js +3 -0
  55. package/dist/node.js.map +1 -1
  56. package/dist/notificationSecretSurface.d.ts +12 -0
  57. package/dist/notificationSecretSurface.d.ts.map +1 -0
  58. package/dist/notificationSecretSurface.js +72 -0
  59. package/dist/notificationSecretSurface.js.map +1 -0
  60. package/package.json +9 -7
@@ -0,0 +1,10 @@
1
+ import { type StandaloneAccountWorkerConfiguration } from '@xenosystem/agent-interface-host/node';
2
+ export declare const STANDALONE_ACCOUNT_SCOPES: readonly string[];
3
+ /** The production standalone/detached authority. All values are fixed source
4
+ * policy; no renderer field, ambient URL, token, or selected workspace can
5
+ * widen them. Isolated host roots keep test credentials out of the real profile. */
6
+ export declare function canonicalStandaloneAccountWorkerConfiguration(options: {
7
+ homeDirectory: string;
8
+ hostRootDirectory?: string;
9
+ }): StandaloneAccountWorkerConfiguration;
10
+ //# sourceMappingURL=accountWorkerConfiguration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accountWorkerConfiguration.d.ts","sourceRoot":"","sources":["../src/accountWorkerConfiguration.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,KAAK,oCAAoC,EAAE,MAAM,uCAAuC,CAAA;AAE7H,eAAO,MAAM,yBAAyB,mBAEpC,CAAA;AAEF;;oFAEoF;AACpF,wBAAgB,6CAA6C,CAAC,OAAO,EAAE;IACrE,aAAa,EAAE,MAAM,CAAA;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B,GAAG,oCAAoC,CAUvC"}
@@ -0,0 +1,19 @@
1
+ import { resolveLocalAgentHostPaths } from '@xenosystem/agent-interface-host/node';
2
+ export const STANDALONE_ACCOUNT_SCOPES = Object.freeze([
3
+ 'openid', 'profile', 'email', 'offline_access', 'team:read', 'team:manage', 'collaboration:use', 'workforce:read', 'workforce:manage',
4
+ ]);
5
+ /** The production standalone/detached authority. All values are fixed source
6
+ * policy; no renderer field, ambient URL, token, or selected workspace can
7
+ * widen them. Isolated host roots keep test credentials out of the real profile. */
8
+ export function canonicalStandaloneAccountWorkerConfiguration(options) {
9
+ const paths = resolveLocalAgentHostPaths(options);
10
+ return {
11
+ clientId: 'xeno-agent-interface',
12
+ issuer: 'https://xenostudio.ai',
13
+ apiBase: 'https://api.xenostudio.ai',
14
+ scopes: [...STANDALONE_ACCOUNT_SCOPES],
15
+ protectedStateRoot: paths.stateRepositoryRoot,
16
+ persistencePolicy: 'require-protected',
17
+ };
18
+ }
19
+ //# sourceMappingURL=accountWorkerConfiguration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accountWorkerConfiguration.js","sourceRoot":"","sources":["../src/accountWorkerConfiguration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAA6C,MAAM,uCAAuC,CAAA;AAE7H,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC,MAAM,CAAC;IACrD,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,aAAa,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,kBAAkB;CACtI,CAAC,CAAA;AAEF;;oFAEoF;AACpF,MAAM,UAAU,6CAA6C,CAAC,OAG7D;IACC,MAAM,KAAK,GAAG,0BAA0B,CAAC,OAAO,CAAC,CAAA;IACjD,OAAO;QACL,QAAQ,EAAE,sBAAsB;QAChC,MAAM,EAAE,uBAAuB;QAC/B,OAAO,EAAE,2BAA2B;QACpC,MAAM,EAAE,CAAC,GAAG,yBAAyB,CAAC;QACtC,kBAAkB,EAAE,KAAK,CAAC,mBAAmB;QAC7C,iBAAiB,EAAE,mBAAmB;KACvC,CAAA;AACH,CAAC"}
@@ -0,0 +1,33 @@
1
+ import type { XenoArtifactRepository } from '@xenosystem/agent-sdk';
2
+ import { SqliteBrowserPreparationStore } from './BrowserCommandPreparationStore.js';
3
+ import type { BrowserAuthoritySdk, BrowserCapabilityPersistence, BrowserExecutionJournal } from './SdkBrowserCommandAuthority.js';
4
+ export interface BrowserResourceSdk extends BrowserAuthoritySdk {
5
+ openSqliteCapabilityLeasePersistence(path: string): Promise<BrowserCapabilityPersistence & {
6
+ close(): void;
7
+ }>;
8
+ openSqliteAutomationExecutionJournal(path: string): Promise<BrowserExecutionJournal & {
9
+ close(): void;
10
+ }>;
11
+ FileXenoArtifactRepository: new (options: {
12
+ directory: string;
13
+ }) => XenoArtifactRepository;
14
+ }
15
+ /** Opens canonical persistence on host-private paths. This is not an encryption claim: evidence
16
+ * retention and OS-protected directory authority must be supplied by the native host owner. */
17
+ export declare function openBrowserAuthorityResources(options: {
18
+ sdk: BrowserResourceSdk;
19
+ directory: string;
20
+ assertPrivateDirectory(path: string): Promise<void>;
21
+ }): Promise<{
22
+ preparations: SqliteBrowserPreparationStore;
23
+ capabilities: BrowserCapabilityPersistence & {
24
+ close(): void;
25
+ };
26
+ journal: BrowserExecutionJournal & {
27
+ close(): void;
28
+ };
29
+ artifacts: XenoArtifactRepository;
30
+ /** Caller MUST first confirm registry close/active command settlement. A stop request is not settlement. */
31
+ close(): void;
32
+ }>;
33
+ //# sourceMappingURL=BrowserAuthorityResources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BrowserAuthorityResources.d.ts","sourceRoot":"","sources":["../../src/browser/BrowserAuthorityResources.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,uBAAuB,CAAA;AACjE,OAAO,EAAC,6BAA6B,EAAC,MAAM,qCAAqC,CAAA;AACjF,OAAO,KAAK,EAAC,mBAAmB,EAAC,4BAA4B,EAAC,uBAAuB,EAAC,MAAM,iCAAiC,CAAA;AAE7H,MAAM,WAAW,kBAAmB,SAAQ,mBAAmB;IAC7D,oCAAoC,CAAC,IAAI,EAAC,MAAM,GAAE,OAAO,CAAC,4BAA4B,GAAC;QAAC,KAAK,IAAG,IAAI,CAAA;KAAC,CAAC,CAAA;IACtG,oCAAoC,CAAC,IAAI,EAAC,MAAM,GAAE,OAAO,CAAC,uBAAuB,GAAC;QAAC,KAAK,IAAG,IAAI,CAAA;KAAC,CAAC,CAAA;IACjG,0BAA0B,EAAC,KAAI,OAAO,EAAC;QAAC,SAAS,EAAC,MAAM,CAAA;KAAC,KAAG,sBAAsB,CAAA;CACnF;AACD;+FAC+F;AAC/F,wBAAsB,6BAA6B,CAAC,OAAO,EAAC;IAAC,GAAG,EAAC,kBAAkB,CAAC;IAAA,SAAS,EAAC,MAAM,CAAC;IAAA,sBAAsB,CAAC,IAAI,EAAC,MAAM,GAAE,OAAO,CAAC,IAAI,CAAC,CAAA;CAAC;;;iBAIxC,IAAI;;;iBAAuD,IAAI;;;IASxK,4GAA4G;;GAIjH"}
@@ -0,0 +1,35 @@
1
+ import { isAbsolute, join } from 'node:path';
2
+ import { DatabaseSync } from 'node:sqlite';
3
+ import { SqliteBrowserPreparationStore } from './BrowserCommandPreparationStore.js';
4
+ /** Opens canonical persistence on host-private paths. This is not an encryption claim: evidence
5
+ * retention and OS-protected directory authority must be supplied by the native host owner. */
6
+ export async function openBrowserAuthorityResources(options) {
7
+ if (!isAbsolute(options.directory))
8
+ throw Error('Browser authority needs an absolute host-private directory');
9
+ for (const key of ['openSqliteCapabilityLeasePersistence', 'openSqliteAutomationExecutionJournal', 'FileXenoArtifactRepository', 'runDurableAutomation'])
10
+ if (typeof options.sdk[key] !== 'function')
11
+ throw Error('Qualified durable Browser SDK storage is unavailable');
12
+ await options.assertPrivateDirectory(options.directory);
13
+ let preparations, capabilities, journal;
14
+ try {
15
+ preparations = new SqliteBrowserPreparationStore(new DatabaseSync(join(options.directory, 'preparations.sqlite')));
16
+ capabilities = await options.sdk.openSqliteCapabilityLeasePersistence(join(options.directory, 'capabilities.sqlite'));
17
+ journal = await options.sdk.openSqliteAutomationExecutionJournal(join(options.directory, 'operations.sqlite'));
18
+ const artifactDirectory = join(options.directory, 'artifacts');
19
+ await options.assertPrivateDirectory(artifactDirectory);
20
+ const artifacts = new options.sdk.FileXenoArtifactRepository({ directory: artifactDirectory });
21
+ let closed = false;
22
+ return { preparations, capabilities, journal, artifacts,
23
+ /** Caller MUST first confirm registry close/active command settlement. A stop request is not settlement. */
24
+ close() { if (closed)
25
+ return; preparations.close(); capabilities.close(); journal.close(); closed = true; },
26
+ };
27
+ }
28
+ catch (error) {
29
+ preparations?.close();
30
+ capabilities?.close();
31
+ journal?.close();
32
+ throw error;
33
+ }
34
+ }
35
+ //# sourceMappingURL=BrowserAuthorityResources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BrowserAuthorityResources.js","sourceRoot":"","sources":["../../src/browser/BrowserAuthorityResources.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AACzC,OAAO,EAAC,YAAY,EAAC,MAAM,aAAa,CAAA;AAExC,OAAO,EAAC,6BAA6B,EAAC,MAAM,qCAAqC,CAAA;AAQjF;+FAC+F;AAC/F,MAAM,CAAC,KAAK,UAAU,6BAA6B,CAAC,OAAmG;IACrJ,IAAG,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC;QAAC,MAAM,KAAK,CAAC,4DAA4D,CAAC,CAAA;IAC3G,KAAI,MAAM,GAAG,IAAI,CAAC,sCAAsC,EAAC,sCAAsC,EAAC,4BAA4B,EAAC,sBAAsB,CAAU;QAAC,IAAG,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAG,UAAU;YAAC,MAAM,KAAK,CAAC,sDAAsD,CAAC,CAAA;IACzQ,MAAM,OAAO,CAAC,sBAAsB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IACvD,IAAI,YAAoD,EAAC,YAAoE,EAAC,OAA0D,CAAA;IACxL,IAAI,CAAC;QACH,YAAY,GAAC,IAAI,6BAA6B,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAC,qBAAqB,CAAC,CAAC,CAAC,CAAA;QAC/G,YAAY,GAAC,MAAM,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAC,qBAAqB,CAAC,CAAC,CAAA;QAClH,OAAO,GAAC,MAAM,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAC,mBAAmB,CAAC,CAAC,CAAA;QAC3G,MAAM,iBAAiB,GAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAC,WAAW,CAAC,CAAC;QAAA,MAAM,OAAO,CAAC,sBAAsB,CAAC,iBAAiB,CAAC,CAAA;QACnH,MAAM,SAAS,GAAC,IAAI,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,EAAC,SAAS,EAAC,iBAAiB,EAAC,CAAC,CAAA;QACzF,IAAI,MAAM,GAAC,KAAK,CAAA;QAChB,OAAO,EAAC,YAAY,EAAC,YAAY,EAAC,OAAO,EAAC,SAAS;YACjD,4GAA4G;YAC5G,KAAK,KAAG,IAAG,MAAM;gBAAC,OAAO,CAAA,YAAa,CAAC,KAAK,EAAE,CAAC,CAAA,YAAa,CAAC,KAAK,EAAE,CAAC,CAAA,OAAQ,CAAC,KAAK,EAAE,CAAC,CAAA,MAAM,GAAC,IAAI,CAAA,CAAA,CAAC;SACnG,CAAA;IACH,CAAC;IAAC,OAAM,KAAK,EAAC,CAAC;QAAA,YAAY,EAAE,KAAK,EAAE,CAAC;QAAA,YAAY,EAAE,KAAK,EAAE,CAAC;QAAA,OAAO,EAAE,KAAK,EAAE,CAAC;QAAA,MAAM,KAAK,CAAA;IAAA,CAAC;AAC1F,CAAC"}
@@ -0,0 +1,46 @@
1
+ import type { DatabaseSync } from 'node:sqlite';
2
+ import type { OwnedBrowserScope } from '@xenosystem/agent-interface-host/node';
3
+ /** No action parameters, typed text, full URL, credentials or native dialog content. */
4
+ export interface BrowserCommandPreparation {
5
+ schemaVersion: 1;
6
+ version: number;
7
+ operationId: string;
8
+ inputFingerprint: string;
9
+ scope: OwnedBrowserScope & {
10
+ teamId?: string;
11
+ agentId?: string;
12
+ };
13
+ sessionId: string;
14
+ tabId: string;
15
+ origin: string;
16
+ targetFingerprint: string;
17
+ principalId: string;
18
+ requestedAt: string;
19
+ leaseId: string;
20
+ profileFingerprint: string;
21
+ contractId: string;
22
+ contractFingerprint: string;
23
+ phase: 'prepared' | 'consent-pending' | 'consent-accepted' | 'approved' | 'denied';
24
+ leaseVersion?: number;
25
+ challengeHash?: string;
26
+ consentOwner?: string;
27
+ consentReceiptId?: string;
28
+ }
29
+ export interface BrowserPreparationStore {
30
+ get(operationId: string): Promise<BrowserCommandPreparation | undefined>;
31
+ create(value: BrowserCommandPreparation): Promise<BrowserCommandPreparation>;
32
+ update(value: BrowserCommandPreparation, expectedVersion: number): Promise<BrowserCommandPreparation>;
33
+ }
34
+ export declare class SqliteBrowserPreparationStore implements BrowserPreparationStore {
35
+ private readonly database;
36
+ private closed;
37
+ /** Host supplies its own private database connection; this object owns that connection. */
38
+ constructor(database: DatabaseSync);
39
+ get(id: string): Promise<BrowserCommandPreparation | undefined>;
40
+ create(value: BrowserCommandPreparation): Promise<BrowserCommandPreparation>;
41
+ update(value: BrowserCommandPreparation, expectedVersion: number): Promise<BrowserCommandPreparation>;
42
+ close(): void;
43
+ private read;
44
+ private transaction;
45
+ }
46
+ //# sourceMappingURL=BrowserCommandPreparationStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BrowserCommandPreparationStore.d.ts","sourceRoot":"","sources":["../../src/browser/BrowserCommandPreparationStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAA;AAC7C,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,uCAAuC,CAAA;AAE5E,wFAAwF;AACxF,MAAM,WAAW,yBAAyB;IACxC,aAAa,EAAC,CAAC,CAAC;IAAA,OAAO,EAAC,MAAM,CAAC;IAAA,WAAW,EAAC,MAAM,CAAC;IAAA,gBAAgB,EAAC,MAAM,CAAC;IAAA,KAAK,EAAC,iBAAiB,GAAC;QAAC,MAAM,CAAC,EAAC,MAAM,CAAC;QAAA,OAAO,CAAC,EAAC,MAAM,CAAA;KAAC,CAAA;IAClI,SAAS,EAAC,MAAM,CAAC;IAAA,KAAK,EAAC,MAAM,CAAC;IAAA,MAAM,EAAC,MAAM,CAAC;IAAA,iBAAiB,EAAC,MAAM,CAAC;IAAA,WAAW,EAAC,MAAM,CAAA;IACvF,WAAW,EAAC,MAAM,CAAC;IAAA,OAAO,EAAC,MAAM,CAAC;IAAA,kBAAkB,EAAC,MAAM,CAAC;IAAA,UAAU,EAAC,MAAM,CAAC;IAAA,mBAAmB,EAAC,MAAM,CAAA;IACxG,KAAK,EAAC,UAAU,GAAC,iBAAiB,GAAC,kBAAkB,GAAC,UAAU,GAAC,QAAQ,CAAA;IACzE,YAAY,CAAC,EAAC,MAAM,CAAC;IAAA,aAAa,CAAC,EAAC,MAAM,CAAC;IAAA,YAAY,CAAC,EAAC,MAAM,CAAC;IAAA,gBAAgB,CAAC,EAAC,MAAM,CAAA;CACzF;AACD,MAAM,WAAW,uBAAuB;IACtC,GAAG,CAAC,WAAW,EAAC,MAAM,GAAE,OAAO,CAAC,yBAAyB,GAAC,SAAS,CAAC,CAAA;IACpE,MAAM,CAAC,KAAK,EAAC,yBAAyB,GAAE,OAAO,CAAC,yBAAyB,CAAC,CAAA;IAC1E,MAAM,CAAC,KAAK,EAAC,yBAAyB,EAAC,eAAe,EAAC,MAAM,GAAE,OAAO,CAAC,yBAAyB,CAAC,CAAA;CAClG;AAED,qBAAa,6BAA8B,YAAW,uBAAuB;IAG/D,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAFrC,OAAO,CAAC,MAAM,CAAM;IACpB,2FAA2F;gBAC9D,QAAQ,EAAC,YAAY;IAOlD,GAAG,CAAC,EAAE,EAAC,MAAM;IACb,MAAM,CAAC,KAAK,EAAC,yBAAyB;IAItC,MAAM,CAAC,KAAK,EAAC,yBAAyB,EAAC,eAAe,EAAC,MAAM;IAO7D,KAAK;IACL,OAAO,CAAC,IAAI;YACE,WAAW;CAC1B"}
@@ -0,0 +1,135 @@
1
+ const KEYS = ['schemaVersion', 'version', 'operationId', 'inputFingerprint', 'scope', 'sessionId', 'tabId', 'origin', 'targetFingerprint', 'principalId', 'requestedAt', 'leaseId', 'profileFingerprint', 'contractId', 'contractFingerprint', 'phase', 'leaseVersion', 'challengeHash', 'consentOwner', 'consentReceiptId'];
2
+ export class SqliteBrowserPreparationStore {
3
+ database;
4
+ closed = false;
5
+ /** Host supplies its own private database connection; this object owns that connection. */
6
+ constructor(database) {
7
+ this.database = database;
8
+ try {
9
+ database.exec('PRAGMA busy_timeout=0; PRAGMA synchronous=FULL; CREATE TABLE IF NOT EXISTS browser_preparation_schema(id INTEGER PRIMARY KEY CHECK(id=1),version INTEGER NOT NULL); INSERT OR IGNORE INTO browser_preparation_schema VALUES(1,1)');
10
+ if (database.prepare('SELECT version FROM browser_preparation_schema WHERE id=1').get()?.version !== 1)
11
+ throw Error('Unsupported Browser preparation schema');
12
+ database.exec('CREATE TABLE IF NOT EXISTS browser_preparations(id TEXT PRIMARY KEY,version INTEGER NOT NULL,body TEXT NOT NULL)');
13
+ }
14
+ catch (error) {
15
+ database.close();
16
+ this.closed = true;
17
+ throw error;
18
+ }
19
+ }
20
+ get(id) { checkText(id); return this.transaction(() => this.read(id)); }
21
+ create(value) {
22
+ value = structuredClone(value);
23
+ validate(value);
24
+ if (value.version !== 1 || value.phase !== 'prepared')
25
+ throw Error('Browser preparation must begin at version one');
26
+ return this.transaction(() => {
27
+ const prior = this.read(value.operationId);
28
+ if (prior) {
29
+ if (prior.inputFingerprint !== value.inputFingerprint)
30
+ throw Error('Browser operation was reused for different input');
31
+ return prior;
32
+ }
33
+ const count = this.database.prepare('SELECT COUNT(*) AS count FROM browser_preparations').get()?.count;
34
+ if (typeof count !== 'number' || count >= 100000)
35
+ throw Error('Browser preparation capacity reached');
36
+ this.database.prepare('INSERT INTO browser_preparations(id,version,body) VALUES(?,?,?)').run(value.operationId, value.version, encode(value));
37
+ return structuredClone(value);
38
+ });
39
+ }
40
+ update(value, expectedVersion) {
41
+ value = structuredClone(value);
42
+ validate(value);
43
+ if (value.version !== expectedVersion + 1)
44
+ throw Error('Browser preparation version must advance once');
45
+ return this.transaction(() => {
46
+ const prior = this.read(value.operationId);
47
+ if (!prior || prior.version !== expectedVersion)
48
+ throw Error('Browser preparation changed');
49
+ const mutable = new Set(['phase', 'version', 'leaseVersion', 'challengeHash', 'consentOwner', 'consentReceiptId']);
50
+ for (const key of KEYS)
51
+ if (!mutable.has(key) && JSON.stringify(prior[key]) !== JSON.stringify(value[key]))
52
+ throw Error('Browser preparation immutable identity changed');
53
+ const transitions = { prepared: ['consent-pending'], 'consent-pending': ['consent-accepted', 'denied'], 'consent-accepted': ['approved'], approved: [], denied: [] };
54
+ if (!transitions[prior.phase].includes(value.phase))
55
+ throw Error('Browser preparation phase cannot be replayed');
56
+ this.database.prepare('UPDATE browser_preparations SET version=?,body=? WHERE id=?').run(value.version, encode(value), value.operationId);
57
+ return structuredClone(value);
58
+ });
59
+ }
60
+ close() { if (!this.closed) {
61
+ this.closed = true;
62
+ this.database.close();
63
+ } }
64
+ read(id) { const row = this.database.prepare('SELECT CASE WHEN length(body)<=262144 THEN body ELSE NULL END AS body FROM browser_preparations WHERE id=?').get(id); if (!row)
65
+ return undefined; if (typeof row.body !== 'string')
66
+ throw Error('Browser preparation is corrupt'); const value = JSON.parse(row.body); validate(value); if (value.operationId !== id)
67
+ throw Error('Browser preparation identity differs'); return value; }
68
+ async transaction(call) { const deadline = Date.now() + 1000; for (;;) {
69
+ if (this.closed)
70
+ throw Error('Browser preparation store closed');
71
+ let began = false;
72
+ try {
73
+ this.database.exec('BEGIN IMMEDIATE');
74
+ began = true;
75
+ const value = call();
76
+ this.database.exec('COMMIT');
77
+ return value;
78
+ }
79
+ catch (error) {
80
+ if (began)
81
+ try {
82
+ this.database.exec('ROLLBACK');
83
+ }
84
+ catch { }
85
+ if (Date.now() >= deadline || !/SQLITE_BUSY|database is locked/.test(String(error)))
86
+ throw error;
87
+ await new Promise(resolve => setTimeout(resolve, 10));
88
+ }
89
+ } }
90
+ }
91
+ function checkText(value) { if (typeof value !== 'string' || !value.trim() || value.length > 1024)
92
+ throw Error('Invalid Browser preparation identity'); }
93
+ function validate(value) {
94
+ if (!value || typeof value !== 'object' || Array.isArray(value) || Object.keys(value).some(key => !KEYS.includes(key)))
95
+ throw Error('Unexpected Browser preparation fields');
96
+ const v = value;
97
+ for (const text of [v.operationId, v.sessionId, v.tabId, v.principalId, v.leaseId, v.requestedAt, v.contractId])
98
+ checkText(text);
99
+ if (v.schemaVersion !== 1 || !Number.isSafeInteger(v.version) || v.version < 1 || !['prepared', 'consent-pending', 'consent-accepted', 'approved', 'denied'].includes(v.phase))
100
+ throw Error('Invalid Browser preparation schema');
101
+ for (const hash of [v.inputFingerprint, v.targetFingerprint, v.profileFingerprint, v.contractFingerprint])
102
+ if (!/^[a-f0-9]{64}$/.test(hash))
103
+ throw Error('Invalid Browser preparation fingerprint');
104
+ const origin = new URL(v.origin);
105
+ if (!['http:', 'https:'].includes(origin.protocol) || origin.origin !== v.origin)
106
+ throw Error('Browser preparation requires an exact web origin');
107
+ if (!v.scope || !Number.isFinite(Date.parse(v.requestedAt)))
108
+ throw Error('Browser preparation scope or time is missing');
109
+ if (Object.keys(v.scope).some(key => !['workspaceId', 'workspaceIncarnation', 'conversationId', 'clientInstanceId', 'teamId', 'agentId'].includes(key)))
110
+ throw Error('Unexpected Browser scope fields');
111
+ for (const text of [v.scope.workspaceId, v.scope.workspaceIncarnation, v.scope.conversationId, v.scope.clientInstanceId])
112
+ checkText(text);
113
+ if (v.scope.teamId !== undefined)
114
+ checkText(v.scope.teamId);
115
+ if (v.scope.agentId !== undefined)
116
+ checkText(v.scope.agentId);
117
+ if (v.phase === 'prepared') {
118
+ if (v.leaseVersion !== undefined || v.challengeHash !== undefined || v.consentOwner !== undefined || v.consentReceiptId !== undefined)
119
+ throw Error('Unapproved preparation contains consent fields');
120
+ }
121
+ else {
122
+ if (!Number.isSafeInteger(v.leaseVersion) || v.leaseVersion < 1 || !v.challengeHash || !/^[a-f0-9]{64}$/.test(v.challengeHash))
123
+ throw Error('Invalid consent binding');
124
+ checkText(v.consentOwner);
125
+ if (v.phase === 'consent-pending') {
126
+ if (v.consentReceiptId !== undefined)
127
+ throw Error('Pending consent contains a receipt');
128
+ }
129
+ else
130
+ checkText(v.consentReceiptId);
131
+ }
132
+ }
133
+ function encode(value) { const text = JSON.stringify(value); if (text.length > 262144)
134
+ throw Error('Browser preparation exceeds bound'); return text; }
135
+ //# sourceMappingURL=BrowserCommandPreparationStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BrowserCommandPreparationStore.js","sourceRoot":"","sources":["../../src/browser/BrowserCommandPreparationStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { BrowserCommandPreparation, BrowserPreparationStore } from './BrowserCommandPreparationStore.js';
2
+ export interface BrowserConsentChallenge {
3
+ operationId: string;
4
+ inputFingerprint: string;
5
+ targetFingerprint: string;
6
+ challengeHash: string;
7
+ principalId: string;
8
+ workspaceId: string;
9
+ workspaceIncarnation: string;
10
+ clientInstanceId: string;
11
+ sessionId: string;
12
+ tabId: string;
13
+ origin: string;
14
+ leaseId: string;
15
+ leaseVersion: number;
16
+ operation: string;
17
+ }
18
+ export interface BrowserPrincipalConsentPort {
19
+ /** An authenticated native surface, not a Boolean copied from renderer IPC. */
20
+ available(): boolean;
21
+ request(challenge: Readonly<BrowserConsentChallenge>, signal: AbortSignal): Promise<{
22
+ decision: 'approve' | 'deny';
23
+ challengeHash: string;
24
+ principalId: string;
25
+ receiptId: string;
26
+ }>;
27
+ }
28
+ export declare class BrowserConsentController {
29
+ private readonly store;
30
+ private readonly port;
31
+ private readonly assertCurrent;
32
+ private readonly timeoutMs;
33
+ private readonly abort;
34
+ cancel(): void;
35
+ constructor(store: BrowserPreparationStore, port: BrowserPrincipalConsentPort, assertCurrent: () => Promise<void>, timeoutMs?: number);
36
+ obtain(record: BrowserCommandPreparation, leaseVersion: number, operation: string): Promise<BrowserCommandPreparation>;
37
+ }
38
+ //# sourceMappingURL=BrowserConsentController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BrowserConsentController.d.ts","sourceRoot":"","sources":["../../src/browser/BrowserConsentController.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,yBAAyB,EAAC,uBAAuB,EAAC,MAAM,qCAAqC,CAAA;AAC1G,MAAM,WAAW,uBAAuB;IAAE,WAAW,EAAC,MAAM,CAAC;IAAA,gBAAgB,EAAC,MAAM,CAAC;IAAA,iBAAiB,EAAC,MAAM,CAAC;IAAA,aAAa,EAAC,MAAM,CAAC;IAAA,WAAW,EAAC,MAAM,CAAC;IAAA,WAAW,EAAC,MAAM,CAAC;IAAA,oBAAoB,EAAC,MAAM,CAAC;IAAA,gBAAgB,EAAC,MAAM,CAAC;IAAA,SAAS,EAAC,MAAM,CAAC;IAAA,KAAK,EAAC,MAAM,CAAC;IAAA,MAAM,EAAC,MAAM,CAAC;IAAA,OAAO,EAAC,MAAM,CAAC;IAAA,YAAY,EAAC,MAAM,CAAC;IAAA,SAAS,EAAC,MAAM,CAAA;CAAC;AAC7T,MAAM,WAAW,2BAA2B;IAC1C,+EAA+E;IAC/E,SAAS,IAAG,OAAO,CAAA;IACnB,OAAO,CAAC,SAAS,EAAC,QAAQ,CAAC,uBAAuB,CAAC,EAAC,MAAM,EAAC,WAAW,GAAE,OAAO,CAAC;QAAC,QAAQ,EAAC,SAAS,GAAC,MAAM,CAAC;QAAA,aAAa,EAAC,MAAM,CAAC;QAAA,WAAW,EAAC,MAAM,CAAC;QAAA,SAAS,EAAC,MAAM,CAAA;KAAC,CAAC,CAAA;CACtK;AACD,qBAAa,wBAAwB;IAGvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAAyB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAA6B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAAmB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAFxL,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAsB;IAC5C,MAAM;gBACuB,KAAK,EAAC,uBAAuB,EAAkB,IAAI,EAAC,2BAA2B,EAAkB,aAAa,EAAC,MAAI,OAAO,CAAC,IAAI,CAAC,EAAkB,SAAS,SAAO;IACzL,MAAM,CAAC,MAAM,EAAC,yBAAyB,EAAC,YAAY,EAAC,MAAM,EAAC,SAAS,EAAC,MAAM,GAAE,OAAO,CAAC,yBAAyB,CAAC;CAgBvH"}
@@ -0,0 +1,46 @@
1
+ import { createHash, randomUUID } from 'node:crypto';
2
+ export class BrowserConsentController {
3
+ store;
4
+ port;
5
+ assertCurrent;
6
+ timeoutMs;
7
+ abort = new AbortController();
8
+ cancel() { this.abort.abort(); }
9
+ constructor(store, port, assertCurrent, timeoutMs = 120000) {
10
+ this.store = store;
11
+ this.port = port;
12
+ this.assertCurrent = assertCurrent;
13
+ this.timeoutMs = timeoutMs;
14
+ if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 10 || timeoutMs > 120000)
15
+ throw Error('Invalid consent timeout');
16
+ }
17
+ async obtain(record, leaseVersion, operation) {
18
+ if (record.phase !== 'prepared')
19
+ throw Error('Browser consent is already pending or decided');
20
+ await this.assertCurrent();
21
+ if (!this.port.available())
22
+ throw Error('An authenticated native consent surface is unavailable');
23
+ const challengeData = { operationId: record.operationId, inputFingerprint: record.inputFingerprint, targetFingerprint: record.targetFingerprint, principalId: record.principalId, workspaceId: record.scope.workspaceId, workspaceIncarnation: record.scope.workspaceIncarnation, clientInstanceId: record.scope.clientInstanceId, sessionId: record.sessionId, tabId: record.tabId, origin: record.origin, leaseId: record.leaseId, leaseVersion, operation };
24
+ const challengeHash = createHash('sha256').update(JSON.stringify(challengeData)).digest('hex'), challenge = Object.freeze({ ...challengeData, challengeHash });
25
+ const pending = await this.store.update({ ...record, version: record.version + 1, phase: 'consent-pending', leaseVersion, challengeHash, consentOwner: randomUUID() }, record.version);
26
+ const controller = this.abort;
27
+ let timer;
28
+ let onAbort;
29
+ try {
30
+ if (controller.signal.aborted)
31
+ throw Error('Browser consent response remains pending');
32
+ const cancelled = new Promise((_, reject) => { onAbort = () => reject(Error('Browser consent response remains pending')); controller.signal.addEventListener('abort', onAbort, { once: true }); timer = setTimeout(() => controller.abort(), this.timeoutMs); });
33
+ const response = await Promise.race([this.port.request(challenge, controller.signal), cancelled]);
34
+ await this.assertCurrent();
35
+ if (response.challengeHash !== challengeHash || response.principalId !== record.principalId || !['approve', 'deny'].includes(response.decision) || typeof response.receiptId !== 'string' || !response.receiptId.trim() || response.receiptId.length > 1024)
36
+ throw Error('Browser consent receipt did not match its authenticated challenge');
37
+ return await this.store.update({ ...pending, version: pending.version + 1, phase: response.decision === 'approve' ? 'consent-accepted' : 'denied', consentReceiptId: response.receiptId }, pending.version);
38
+ }
39
+ finally {
40
+ clearTimeout(timer);
41
+ if (onAbort)
42
+ controller.signal.removeEventListener('abort', onAbort);
43
+ }
44
+ }
45
+ }
46
+ //# sourceMappingURL=BrowserConsentController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BrowserConsentController.js","sourceRoot":"","sources":["../../src/browser/BrowserConsentController.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { BrowserPrincipalConsentPort, BrowserConsentChallenge } from './BrowserConsentController.js';
2
+ export interface BrowserPermissionAnswer {
3
+ permissionId: string;
4
+ granted: boolean;
5
+ }
6
+ /** Host-owned adapter onto the existing native permission event/answer surface.
7
+ * A renderer can answer an existing opaque id; it cannot choose the principal,
8
+ * challenge binding, receipt identity or operation being approved. */
9
+ export declare class BrowserInteractiveConsent implements BrowserPrincipalConsentPort {
10
+ private readonly send?;
11
+ private readonly pending;
12
+ constructor(send?: ((channel: string, payload: Record<string, unknown>) => boolean | void) | undefined);
13
+ available(): boolean;
14
+ request(challenge: Readonly<BrowserConsentChallenge>, signal: AbortSignal): Promise<{
15
+ decision: 'approve' | 'deny';
16
+ challengeHash: string;
17
+ principalId: string;
18
+ receiptId: string;
19
+ }>;
20
+ answer(answer: BrowserPermissionAnswer): {
21
+ handled: boolean;
22
+ };
23
+ }
24
+ //# sourceMappingURL=BrowserInteractiveConsent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BrowserInteractiveConsent.d.ts","sourceRoot":"","sources":["../../src/browser/BrowserInteractiveConsent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,2BAA2B,EAAC,uBAAuB,EAAC,MAAM,+BAA+B,CAAA;AAEtG,MAAM,WAAW,uBAAuB;IAAE,YAAY,EAAC,MAAM,CAAC;IAAA,OAAO,EAAC,OAAO,CAAA;CAAC;AAG9E;;sEAEsE;AACtE,qBAAa,yBAA0B,YAAW,2BAA2B;IAE/D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;IADlC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;gBACrB,IAAI,CAAC,GAAE,CAAC,OAAO,EAAC,MAAM,EAAC,OAAO,EAAC,MAAM,CAAC,MAAM,EAAC,OAAO,CAAC,KAAG,OAAO,GAAC,IAAI,aAAA;IACjG,SAAS,IAAG,OAAO;IACnB,OAAO,CAAC,SAAS,EAAC,QAAQ,CAAC,uBAAuB,CAAC,EAAC,MAAM,EAAC,WAAW,GAAE,OAAO,CAAC;QAAC,QAAQ,EAAC,SAAS,GAAC,MAAM,CAAC;QAAA,aAAa,EAAC,MAAM,CAAC;QAAA,WAAW,EAAC,MAAM,CAAC;QAAA,SAAS,EAAC,MAAM,CAAA;KAAC,CAAC;IAYrK,MAAM,CAAC,MAAM,EAAC,uBAAuB,GAAE;QAAC,OAAO,EAAC,OAAO,CAAA;KAAC;CAQzD"}
@@ -0,0 +1,45 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ /** Host-owned adapter onto the existing native permission event/answer surface.
3
+ * A renderer can answer an existing opaque id; it cannot choose the principal,
4
+ * challenge binding, receipt identity or operation being approved. */
5
+ export class BrowserInteractiveConsent {
6
+ send;
7
+ pending = new Map();
8
+ constructor(send) {
9
+ this.send = send;
10
+ }
11
+ available() { return typeof this.send === 'function'; }
12
+ request(challenge, signal) {
13
+ if (!this.send)
14
+ throw Error('An authenticated native consent surface is unavailable');
15
+ const permissionId = 'browser-permission-' + challenge.challengeHash;
16
+ if (this.pending.has(permissionId))
17
+ throw Error('Browser consent challenge is already pending');
18
+ return new Promise((resolve, reject) => {
19
+ const abort = () => { if (this.pending.delete(permissionId))
20
+ reject(Error('Browser consent response remains pending')); };
21
+ const entry = { challenge, resolve, reject, abort, signal };
22
+ this.pending.set(permissionId, entry);
23
+ signal.addEventListener('abort', abort, { once: true });
24
+ try {
25
+ if (this.send('agent:permission-request', { requestId: challenge.operationId, permissionId, source: 'owned-browser', sessionId: challenge.sessionId, toolName: `Browser ${challenge.operation}`, toolKind: challenge.operation, path: challenge.origin, directory: '', browserOrigin: challenge.origin }) === false)
26
+ throw Error('An authenticated native consent surface is unavailable');
27
+ }
28
+ catch (error) {
29
+ this.pending.delete(permissionId);
30
+ signal.removeEventListener('abort', abort);
31
+ reject(error instanceof Error ? error : Error('Browser consent surface is unavailable'));
32
+ }
33
+ });
34
+ }
35
+ answer(answer) {
36
+ const entry = this.pending.get(answer.permissionId);
37
+ if (!entry)
38
+ return { handled: false };
39
+ this.pending.delete(answer.permissionId);
40
+ entry.signal.removeEventListener('abort', entry.abort);
41
+ entry.resolve({ decision: answer.granted ? 'approve' : 'deny', challengeHash: entry.challenge.challengeHash, principalId: entry.challenge.principalId, receiptId: 'browser-consent-' + randomUUID() });
42
+ return { handled: true };
43
+ }
44
+ }
45
+ //# sourceMappingURL=BrowserInteractiveConsent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BrowserInteractiveConsent.js","sourceRoot":"","sources":["../../src/browser/BrowserInteractiveConsent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { AgentHostClientIdentity } from '@xenosystem/agent-interface-contract';
2
+ import { BrowserScopeResolver, OwnedBrowserSessionRegistry, OwnedBrowserSessionService, OwnedBrowserCommandService, type BrowserScopeRepository, type BrowserAdmissionRepository, type BrowserCommandAuthority, type PackedBrowserLauncherPort, type OwnedBrowserSessionRegistryOptions } from '@xenosystem/agent-interface-host/node';
3
+ export interface OwnedBrowserAuthorityOwner extends BrowserCommandAuthority {
4
+ assertConsumption: OwnedBrowserSessionRegistryOptions['assertConsumption'];
5
+ /** Cancel prompts and settle active executor calls before closing owned journals. */
6
+ close(): Promise<void>;
7
+ }
8
+ export interface OwnedBrowserAuthorityContext {
9
+ repository: BrowserScopeRepository;
10
+ scopes: BrowserScopeResolver;
11
+ sessions: Pick<OwnedBrowserSessionRegistry, 'resolveSession'>;
12
+ principal(clientInstanceId: string): Promise<string>;
13
+ consent: import('./BrowserConsentController.js').BrowserPrincipalConsentPort;
14
+ }
15
+ /** Privileged composition configuration, never a renderer DTO. The launcher is
16
+ * backed by the qualified /owned package and the authority by canonical SDK
17
+ * policy/lease/artifact stores. Neither can be substituted by a UI Boolean. */
18
+ export interface OwnedBrowserHostConfiguration {
19
+ launcher: PackedBrowserLauncherPort;
20
+ createAuthority(context: OwnedBrowserAuthorityContext): Promise<OwnedBrowserAuthorityOwner>;
21
+ }
22
+ export declare function createOwnedBrowserHostServices(options: OwnedBrowserHostConfiguration & {
23
+ hostInstanceId: string;
24
+ assertHostOwner(): Promise<void>;
25
+ repository: BrowserScopeRepository & BrowserAdmissionRepository;
26
+ assertClient(client: AgentHostClientIdentity): Promise<void>;
27
+ principal(clientInstanceId: string): Promise<string>;
28
+ consent: import('./BrowserConsentController.js').BrowserPrincipalConsentPort;
29
+ }): Promise<{
30
+ commandService: OwnedBrowserCommandService;
31
+ sessionService: OwnedBrowserSessionService;
32
+ owner: {
33
+ quiesceScope: (scope: import("@xenosystem/agent-interface-contract").AgentWorkspaceLifecycleScope) => Promise<void>;
34
+ quiesceClient: (instanceId: string) => Promise<void>;
35
+ close(): Promise<void>;
36
+ };
37
+ }>;
38
+ //# sourceMappingURL=OwnedBrowserHostServices.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OwnedBrowserHostServices.d.ts","sourceRoot":"","sources":["../../src/browser/OwnedBrowserHostServices.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,uBAAuB,EAAC,MAAM,sCAAsC,CAAA;AACjF,OAAO,EACL,oBAAoB,EAAC,2BAA2B,EAAC,0BAA0B,EAAC,0BAA0B,EACtG,KAAK,sBAAsB,EAAC,KAAK,0BAA0B,EAAC,KAAK,uBAAuB,EACxF,KAAK,yBAAyB,EAAC,KAAK,kCAAkC,EACvE,MAAM,uCAAuC,CAAA;AAE9C,MAAM,WAAW,0BAA2B,SAAQ,uBAAuB;IACzE,iBAAiB,EAAC,kCAAkC,CAAC,mBAAmB,CAAC,CAAA;IACzE,qFAAqF;IACrF,KAAK,IAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACtB;AACD,MAAM,WAAW,4BAA4B;IAC3C,UAAU,EAAC,sBAAsB,CAAA;IACjC,MAAM,EAAC,oBAAoB,CAAA;IAC3B,QAAQ,EAAC,IAAI,CAAC,2BAA2B,EAAC,gBAAgB,CAAC,CAAA;IAC3D,SAAS,CAAC,gBAAgB,EAAC,MAAM,GAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IAClD,OAAO,EAAC,OAAO,+BAA+B,EAAE,2BAA2B,CAAA;CAC5E;AACD;;+EAE+E;AAC/E,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,EAAC,yBAAyB,CAAA;IAClC,eAAe,CAAC,OAAO,EAAC,4BAA4B,GAAE,OAAO,CAAC,0BAA0B,CAAC,CAAA;CAC1F;AACD,wBAAsB,8BAA8B,CAAC,OAAO,EAAC,6BAA6B,GAAG;IAC3F,cAAc,EAAC,MAAM,CAAA;IACrB,eAAe,IAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/B,UAAU,EAAC,sBAAsB,GAAG,0BAA0B,CAAA;IAC9D,YAAY,CAAC,MAAM,EAAC,uBAAuB,GAAE,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1D,SAAS,CAAC,gBAAgB,EAAC,MAAM,GAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IAClD,OAAO,EAAC,OAAO,+BAA+B,EAAE,2BAA2B,CAAA;CAC5E;;;;;;iBAcW,OAAO,CAAC,IAAI,CAAC;;GASxB"}
@@ -0,0 +1,31 @@
1
+ import { BrowserScopeResolver, OwnedBrowserSessionRegistry, OwnedBrowserSessionService, OwnedBrowserCommandService, createBrowserAdmissionLedger, } from '@xenosystem/agent-interface-host/node';
2
+ export async function createOwnedBrowserHostServices(options) {
3
+ const scopes = new BrowserScopeResolver({ repository: options.repository, assertHostOwner: options.assertHostOwner, assertClient: options.assertClient });
4
+ let authority;
5
+ const registry = new OwnedBrowserSessionRegistry({ hostInstanceId: options.hostInstanceId, scopes, launcher: options.launcher,
6
+ admissions: createBrowserAdmissionLedger(options.repository),
7
+ assertConsumption: async (...args) => { if (!authority)
8
+ throw Error('Browser authority is unavailable'); await authority.assertConsumption(...args); },
9
+ });
10
+ authority = await options.createAuthority({ scopes, sessions: registry, repository: options.repository, principal: options.principal, consent: options.consent });
11
+ const commandService = new OwnedBrowserCommandService({ resolveScope: request => scopes.resolve(request), resolveSession: id => registry.resolveSession(id), authority });
12
+ const sessionService = new OwnedBrowserSessionService(registry);
13
+ let closeAttempt, closed = false;
14
+ return { commandService, sessionService, owner: {
15
+ quiesceScope: registry.quiesceScope.bind(registry),
16
+ quiesceClient: registry.quiesceClient.bind(registry),
17
+ close() {
18
+ if (closed)
19
+ return Promise.resolve();
20
+ if (closeAttempt)
21
+ return closeAttempt;
22
+ // Process ownership and durable admissions remain available when close
23
+ // fails. A retry does not lose the authority or its journals.
24
+ const attempt = (async () => { await registry.close(); await authority.close(); closed = true; })().finally(() => { if (closeAttempt === attempt)
25
+ closeAttempt = undefined; });
26
+ closeAttempt = attempt;
27
+ return attempt;
28
+ },
29
+ } };
30
+ }
31
+ //# sourceMappingURL=OwnedBrowserHostServices.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OwnedBrowserHostServices.js","sourceRoot":"","sources":["../../src/browser/OwnedBrowserHostServices.ts"],"names":[],"mappings":"AACA,OAAO,EACL,oBAAoB,EAAC,2BAA2B,EAAC,0BAA0B,EAAC,0BAA0B,EAAC,4BAA4B,GAGpI,MAAM,uCAAuC,CAAA;AAqB9C,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAAC,OAOpD;IACC,MAAM,MAAM,GAAC,IAAI,oBAAoB,CAAC,EAAC,UAAU,EAAC,OAAO,CAAC,UAAU,EAAC,eAAe,EAAC,OAAO,CAAC,eAAe,EAAC,YAAY,EAAC,OAAO,CAAC,YAAY,EAAC,CAAC,CAAA;IAChJ,IAAI,SAA8C,CAAA;IAClD,MAAM,QAAQ,GAAC,IAAI,2BAA2B,CAAC,EAAC,cAAc,EAAC,OAAO,CAAC,cAAc,EAAC,MAAM,EAAC,QAAQ,EAAC,OAAO,CAAC,QAAQ;QACpH,UAAU,EAAC,4BAA4B,CAAC,OAAO,CAAC,UAAU,CAAC;QAC3D,iBAAiB,EAAC,KAAK,EAAC,GAAG,IAAI,EAAC,EAAE,GAAC,IAAG,CAAC,SAAS;YAAC,MAAM,KAAK,CAAC,kCAAkC,CAAC,CAAC,CAAA,MAAM,SAAS,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAAC,CAAA,CAAA,CAAC;KAC7I,CAAC,CAAA;IACF,SAAS,GAAC,MAAM,OAAO,CAAC,eAAe,CAAC,EAAC,MAAM,EAAC,QAAQ,EAAC,QAAQ,EAAC,UAAU,EAAC,OAAO,CAAC,UAAU,EAAC,SAAS,EAAC,OAAO,CAAC,SAAS,EAAC,OAAO,EAAC,OAAO,CAAC,OAAO,EAAC,CAAC,CAAA;IACrJ,MAAM,cAAc,GAAC,IAAI,0BAA0B,CAAC,EAAC,YAAY,EAAC,OAAO,CAAA,EAAE,CAAA,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAC,cAAc,EAAC,EAAE,CAAA,EAAE,CAAA,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,EAAC,SAAS,EAAC,CAAC,CAAA;IAC7J,MAAM,cAAc,GAAC,IAAI,0BAA0B,CAAC,QAAQ,CAAC,CAAA;IAC7D,IAAI,YAAoC,EAAC,MAAM,GAAC,KAAK,CAAA;IACrD,OAAO,EAAC,cAAc,EAAC,cAAc,EAAC,KAAK,EAAC;YAC1C,YAAY,EAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC;YACjD,aAAa,EAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC;YACnD,KAAK;gBACH,IAAG,MAAM;oBAAC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;gBAClC,IAAG,YAAY;oBAAC,OAAO,YAAY,CAAA;gBACnC,uEAAuE;gBACvE,8DAA8D;gBAC9D,MAAM,OAAO,GAAC,CAAC,KAAK,IAAE,EAAE,GAAC,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA,MAAM,SAAU,CAAC,KAAK,EAAE,CAAC,CAAA,MAAM,GAAC,IAAI,CAAA,CAAA,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAE,EAAE,GAAC,IAAG,YAAY,KAAG,OAAO;oBAAC,YAAY,GAAC,SAAS,CAAA,CAAA,CAAC,CAAC,CAAA;gBACxJ,YAAY,GAAC,OAAO,CAAC;gBAAA,OAAO,OAAO,CAAA;YACrC,CAAC;SACF,EAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { BrowserScopeResolver, type BrowserScopeRepository } from '@xenosystem/agent-interface-host/node';
2
+ import type { SdkBrowserAuthorityOptions } from './SdkBrowserCommandAuthority.js';
3
+ export interface BrowserPolicySdk {
4
+ compileAgentProfile: typeof import('@xenosystem/agent-sdk').compileAgentProfile;
5
+ resolveBuiltInAgentProfile: typeof import('@xenosystem/agent-sdk').resolveBuiltInAgentProfile;
6
+ buildXenoSecureExecutionContract: typeof import('@xenosystem/agent-sdk').buildXenoSecureExecutionContract;
7
+ }
8
+ export interface PersistedBrowserPolicyOptions {
9
+ sdk: BrowserPolicySdk;
10
+ repository: BrowserScopeRepository;
11
+ scopes: BrowserScopeResolver;
12
+ /** Resolves the actual native user's identity from connected-client custody, never IPC input. */
13
+ principal(clientInstanceId: string): Promise<string>;
14
+ assertOwnedTab(command: Parameters<SdkBrowserAuthorityOptions['resolve']>[0]): Promise<void>;
15
+ /** Actual owning Browser metadata endpoint, never a renderer URL or arbitrary active tab.
16
+ * Undefined refuses non-navigation work. Navigation bootstraps via its explicitly requested URL. */
17
+ currentOrigin(command: Parameters<SdkBrowserAuthorityOptions['resolve']>[0]): Promise<string | undefined>;
18
+ }
19
+ /** Current schema has tool/capability and permission-profile policy, not a browser-domain allowlist.
20
+ * Consent may narrow an enabled Browser to one origin; it never overrides persisted denies. */
21
+ export declare function createPersistedBrowserPolicyResolver(options: PersistedBrowserPolicyOptions): SdkBrowserAuthorityOptions['resolve'];
22
+ //# sourceMappingURL=PersistedBrowserPolicyResolver.d.ts.map