arise-browser 0.1.0

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 (148) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +247 -0
  3. package/deploy/neko/CONTEXT.md +37 -0
  4. package/deploy/neko/arise-browser.service +13 -0
  5. package/deploy/neko/neko.yaml +12 -0
  6. package/deploy/neko/openbox.xml +763 -0
  7. package/deploy/neko/policies.json +28 -0
  8. package/deploy/neko/pulseaudio.pa +16 -0
  9. package/deploy/neko/setup.sh +308 -0
  10. package/deploy/neko/xorg.conf +118 -0
  11. package/dist/bin/arise-browser.d.ts +26 -0
  12. package/dist/bin/arise-browser.d.ts.map +1 -0
  13. package/dist/bin/arise-browser.js +224 -0
  14. package/dist/bin/arise-browser.js.map +1 -0
  15. package/dist/src/browser/action-executor.d.ts +98 -0
  16. package/dist/src/browser/action-executor.d.ts.map +1 -0
  17. package/dist/src/browser/action-executor.js +2726 -0
  18. package/dist/src/browser/action-executor.js.map +1 -0
  19. package/dist/src/browser/behavior-recorder.d.ts +61 -0
  20. package/dist/src/browser/behavior-recorder.d.ts.map +1 -0
  21. package/dist/src/browser/behavior-recorder.js +442 -0
  22. package/dist/src/browser/behavior-recorder.js.map +1 -0
  23. package/dist/src/browser/browser-session.d.ts +202 -0
  24. package/dist/src/browser/browser-session.d.ts.map +1 -0
  25. package/dist/src/browser/browser-session.js +1647 -0
  26. package/dist/src/browser/browser-session.js.map +1 -0
  27. package/dist/src/browser/config.d.ts +43 -0
  28. package/dist/src/browser/config.d.ts.map +1 -0
  29. package/dist/src/browser/config.js +59 -0
  30. package/dist/src/browser/config.js.map +1 -0
  31. package/dist/src/browser/page-snapshot.d.ts +38 -0
  32. package/dist/src/browser/page-snapshot.d.ts.map +1 -0
  33. package/dist/src/browser/page-snapshot.js +241 -0
  34. package/dist/src/browser/page-snapshot.js.map +1 -0
  35. package/dist/src/browser/scripts/behavior_tracker.js +424 -0
  36. package/dist/src/browser/scripts/unified_analyzer.js +1576 -0
  37. package/dist/src/index.d.ts +15 -0
  38. package/dist/src/index.d.ts.map +1 -0
  39. package/dist/src/index.js +15 -0
  40. package/dist/src/index.js.map +1 -0
  41. package/dist/src/lock.d.ts +11 -0
  42. package/dist/src/lock.d.ts.map +1 -0
  43. package/dist/src/lock.js +47 -0
  44. package/dist/src/lock.js.map +1 -0
  45. package/dist/src/logger.d.ts +17 -0
  46. package/dist/src/logger.d.ts.map +1 -0
  47. package/dist/src/logger.js +29 -0
  48. package/dist/src/logger.js.map +1 -0
  49. package/dist/src/server/middleware/auth.d.ts +6 -0
  50. package/dist/src/server/middleware/auth.d.ts.map +1 -0
  51. package/dist/src/server/middleware/auth.js +24 -0
  52. package/dist/src/server/middleware/auth.js.map +1 -0
  53. package/dist/src/server/route-utils.d.ts +15 -0
  54. package/dist/src/server/route-utils.d.ts.map +1 -0
  55. package/dist/src/server/route-utils.js +33 -0
  56. package/dist/src/server/route-utils.js.map +1 -0
  57. package/dist/src/server/routes/action.d.ts +5 -0
  58. package/dist/src/server/routes/action.d.ts.map +1 -0
  59. package/dist/src/server/routes/action.js +69 -0
  60. package/dist/src/server/routes/action.js.map +1 -0
  61. package/dist/src/server/routes/actions.d.ts +3 -0
  62. package/dist/src/server/routes/actions.d.ts.map +1 -0
  63. package/dist/src/server/routes/actions.js +53 -0
  64. package/dist/src/server/routes/actions.js.map +1 -0
  65. package/dist/src/server/routes/cookies.d.ts +3 -0
  66. package/dist/src/server/routes/cookies.d.ts.map +1 -0
  67. package/dist/src/server/routes/cookies.js +27 -0
  68. package/dist/src/server/routes/cookies.js.map +1 -0
  69. package/dist/src/server/routes/download.d.ts +3 -0
  70. package/dist/src/server/routes/download.d.ts.map +1 -0
  71. package/dist/src/server/routes/download.js +35 -0
  72. package/dist/src/server/routes/download.js.map +1 -0
  73. package/dist/src/server/routes/evaluate.d.ts +3 -0
  74. package/dist/src/server/routes/evaluate.d.ts.map +1 -0
  75. package/dist/src/server/routes/evaluate.js +27 -0
  76. package/dist/src/server/routes/evaluate.js.map +1 -0
  77. package/dist/src/server/routes/health.d.ts +3 -0
  78. package/dist/src/server/routes/health.d.ts.map +1 -0
  79. package/dist/src/server/routes/health.js +11 -0
  80. package/dist/src/server/routes/health.js.map +1 -0
  81. package/dist/src/server/routes/navigate.d.ts +3 -0
  82. package/dist/src/server/routes/navigate.d.ts.map +1 -0
  83. package/dist/src/server/routes/navigate.js +36 -0
  84. package/dist/src/server/routes/navigate.js.map +1 -0
  85. package/dist/src/server/routes/page-model.d.ts +3 -0
  86. package/dist/src/server/routes/page-model.d.ts.map +1 -0
  87. package/dist/src/server/routes/page-model.js +22 -0
  88. package/dist/src/server/routes/page-model.js.map +1 -0
  89. package/dist/src/server/routes/pdf.d.ts +3 -0
  90. package/dist/src/server/routes/pdf.d.ts.map +1 -0
  91. package/dist/src/server/routes/pdf.js +20 -0
  92. package/dist/src/server/routes/pdf.js.map +1 -0
  93. package/dist/src/server/routes/recording.d.ts +5 -0
  94. package/dist/src/server/routes/recording.d.ts.map +1 -0
  95. package/dist/src/server/routes/recording.js +217 -0
  96. package/dist/src/server/routes/recording.js.map +1 -0
  97. package/dist/src/server/routes/screenshot.d.ts +3 -0
  98. package/dist/src/server/routes/screenshot.d.ts.map +1 -0
  99. package/dist/src/server/routes/screenshot.js +32 -0
  100. package/dist/src/server/routes/screenshot.js.map +1 -0
  101. package/dist/src/server/routes/snapshot.d.ts +3 -0
  102. package/dist/src/server/routes/snapshot.d.ts.map +1 -0
  103. package/dist/src/server/routes/snapshot.js +454 -0
  104. package/dist/src/server/routes/snapshot.js.map +1 -0
  105. package/dist/src/server/routes/tab-lock.d.ts +3 -0
  106. package/dist/src/server/routes/tab-lock.d.ts.map +1 -0
  107. package/dist/src/server/routes/tab-lock.js +30 -0
  108. package/dist/src/server/routes/tab-lock.js.map +1 -0
  109. package/dist/src/server/routes/tab.d.ts +3 -0
  110. package/dist/src/server/routes/tab.d.ts.map +1 -0
  111. package/dist/src/server/routes/tab.js +47 -0
  112. package/dist/src/server/routes/tab.js.map +1 -0
  113. package/dist/src/server/routes/tabs.d.ts +3 -0
  114. package/dist/src/server/routes/tabs.d.ts.map +1 -0
  115. package/dist/src/server/routes/tabs.js +13 -0
  116. package/dist/src/server/routes/tabs.js.map +1 -0
  117. package/dist/src/server/routes/text.d.ts +3 -0
  118. package/dist/src/server/routes/text.d.ts.map +1 -0
  119. package/dist/src/server/routes/text.js +20 -0
  120. package/dist/src/server/routes/text.js.map +1 -0
  121. package/dist/src/server/routes/upload.d.ts +3 -0
  122. package/dist/src/server/routes/upload.d.ts.map +1 -0
  123. package/dist/src/server/routes/upload.js +38 -0
  124. package/dist/src/server/routes/upload.js.map +1 -0
  125. package/dist/src/server/server.d.ts +7 -0
  126. package/dist/src/server/server.d.ts.map +1 -0
  127. package/dist/src/server/server.js +69 -0
  128. package/dist/src/server/server.js.map +1 -0
  129. package/dist/src/types/index.d.ts +125 -0
  130. package/dist/src/types/index.d.ts.map +1 -0
  131. package/dist/src/types/index.js +5 -0
  132. package/dist/src/types/index.js.map +1 -0
  133. package/dist/src/virtual-display/manager.d.ts +37 -0
  134. package/dist/src/virtual-display/manager.d.ts.map +1 -0
  135. package/dist/src/virtual-display/manager.js +229 -0
  136. package/dist/src/virtual-display/manager.js.map +1 -0
  137. package/dist/src/virtual-display/process-runner.d.ts +43 -0
  138. package/dist/src/virtual-display/process-runner.d.ts.map +1 -0
  139. package/dist/src/virtual-display/process-runner.js +174 -0
  140. package/dist/src/virtual-display/process-runner.js.map +1 -0
  141. package/dist/tsconfig.tsbuildinfo +1 -0
  142. package/package.json +57 -0
  143. package/plugin/openclaw.plugin.json +148 -0
  144. package/skill/arise-browser/SKILL.md +275 -0
  145. package/skill/arise-browser/TRUST.md +42 -0
  146. package/skill/arise-browser/references/api.md +198 -0
  147. package/src/browser/scripts/behavior_tracker.js +424 -0
  148. package/src/browser/scripts/unified_analyzer.js +1576 -0
@@ -0,0 +1,3 @@
1
+ import type { FastifyInstance } from "fastify";
2
+ export declare function registerUploadRoute(app: FastifyInstance): void;
3
+ //# sourceMappingURL=upload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../../src/server/routes/upload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAC;AAW/D,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,eAAe,QAyCvD"}
@@ -0,0 +1,38 @@
1
+ import { getTabWriteConflict, sendRouteError, sendTabLocked } from "../route-utils.js";
2
+ export function registerUploadRoute(app) {
3
+ app.post("/upload", async (request, reply) => {
4
+ const session = app.session;
5
+ const { ref, filePath, tabId, owner } = request.body || {};
6
+ if (!ref || !filePath) {
7
+ return reply.code(400).send({ error: "ref and filePath are required" });
8
+ }
9
+ const conflict = getTabWriteConflict(session, { tabId, owner });
10
+ if (conflict) {
11
+ return sendTabLocked(reply, conflict);
12
+ }
13
+ try {
14
+ const page = await session.getPageForTab(tabId);
15
+ if (!page || page.isClosed()) {
16
+ return reply.code(400).send({ error: "No active page" });
17
+ }
18
+ const target = `[aria-ref='${ref.replace(/['"\\]/g, "")}']`;
19
+ const fileInput = page.locator(target);
20
+ if ((await fileInput.count()) === 0) {
21
+ return reply.code(404).send({ error: "File input element not found" });
22
+ }
23
+ const inputMeta = await fileInput.first().evaluate((node) => ({
24
+ tagName: node.tagName.toLowerCase(),
25
+ inputType: node instanceof HTMLInputElement ? node.type.toLowerCase() : "",
26
+ }));
27
+ if (inputMeta.tagName !== "input" || inputMeta.inputType !== "file") {
28
+ return reply.code(400).send({ error: "Target element is not an <input type=\"file\">" });
29
+ }
30
+ await fileInput.setInputFiles(filePath);
31
+ return { success: true, ref, filePath, tabId };
32
+ }
33
+ catch (e) {
34
+ return sendRouteError(reply, e, "Upload failed");
35
+ }
36
+ });
37
+ }
38
+ //# sourceMappingURL=upload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.js","sourceRoot":"","sources":["../../../../src/server/routes/upload.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AASvF,MAAM,UAAU,mBAAmB,CAAC,GAAoB;IACtD,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,OAA6C,EAAE,KAAK,EAAE,EAAE;QACjF,MAAM,OAAO,GAAI,GAAW,CAAC,OAAyB,CAAC;QACvD,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,IAAI,IAAI,EAAgB,CAAC;QAEzE,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YACtB,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,+BAA+B,EAAE,CAAC,CAAC;QAC1E,CAAC;QAED,MAAM,QAAQ,GAAG,mBAAmB,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QAChE,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QACxC,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAChD,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;gBAC7B,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;YAC3D,CAAC;YAED,MAAM,MAAM,GAAG,cAAc,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC;YAC5D,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAEvC,IAAI,CAAC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;gBACpC,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAC,CAAC;YACzE,CAAC;YAED,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAa,EAAE,EAAE,CAAC,CAAC;gBACrE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE;gBACnC,SAAS,EAAE,IAAI,YAAY,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE;aAC3E,CAAC,CAAC,CAAC;YACJ,IAAI,SAAS,CAAC,OAAO,KAAK,OAAO,IAAI,SAAS,CAAC,SAAS,KAAK,MAAM,EAAE,CAAC;gBACpE,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gDAAgD,EAAE,CAAC,CAAC;YAC3F,CAAC;YAED,MAAM,SAAS,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YACxC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;QACjD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,cAAc,CAAC,KAAK,EAAE,CAAC,EAAE,eAAe,CAAC,CAAC;QACnD,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * AriseBrowser HTTP server — Fastify-based, Pinchtab-compatible API.
3
+ */
4
+ import { type FastifyInstance } from "fastify";
5
+ import type { AriseBrowserConfig, ServerConfig } from "../types/index.js";
6
+ export declare function createServer(browserConfig: AriseBrowserConfig, serverConfig?: ServerConfig): Promise<FastifyInstance>;
7
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/server/server.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,SAAS,CAAC;AAGxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAsB1E,wBAAsB,YAAY,CAChC,aAAa,EAAE,kBAAkB,EACjC,YAAY,GAAE,YAAiB,GAC9B,OAAO,CAAC,eAAe,CAAC,CA+C1B"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * AriseBrowser HTTP server — Fastify-based, Pinchtab-compatible API.
3
+ */
4
+ import { randomUUID } from "node:crypto";
5
+ import Fastify from "fastify";
6
+ import { BrowserSession } from "../browser/browser-session.js";
7
+ import { createLogger } from "../logger.js";
8
+ import { registerHealthRoute } from "./routes/health.js";
9
+ import { registerTabsRoute } from "./routes/tabs.js";
10
+ import { registerNavigateRoute } from "./routes/navigate.js";
11
+ import { registerSnapshotRoute } from "./routes/snapshot.js";
12
+ import { registerActionRoute } from "./routes/action.js";
13
+ import { registerActionsRoute } from "./routes/actions.js";
14
+ import { registerTextRoute } from "./routes/text.js";
15
+ import { registerPageModelRoute } from "./routes/page-model.js";
16
+ import { registerScreenshotRoute } from "./routes/screenshot.js";
17
+ import { registerPdfRoute } from "./routes/pdf.js";
18
+ import { registerEvaluateRoute } from "./routes/evaluate.js";
19
+ import { registerTabRoute } from "./routes/tab.js";
20
+ import { registerTabLockRoute } from "./routes/tab-lock.js";
21
+ import { registerCookiesRoute } from "./routes/cookies.js";
22
+ import { registerUploadRoute } from "./routes/upload.js";
23
+ import { registerDownloadRoute } from "./routes/download.js";
24
+ import { registerRecordingRoutes } from "./routes/recording.js";
25
+ import { authMiddleware } from "./middleware/auth.js";
26
+ const logger = createLogger("server");
27
+ export async function createServer(browserConfig, serverConfig = {}) {
28
+ const app = Fastify({ logger: false });
29
+ // Auth middleware
30
+ const token = serverConfig.token
31
+ || process.env.ARISE_BROWSER_TOKEN
32
+ || process.env.BRIDGE_TOKEN;
33
+ if (token) {
34
+ app.addHook("onRequest", authMiddleware(token));
35
+ }
36
+ else {
37
+ logger.warn("No auth token configured — all endpoints are unauthenticated. Set ARISE_BROWSER_TOKEN to enable auth.");
38
+ }
39
+ // Create and attach browser session
40
+ const session = BrowserSession.create(browserConfig, `server:${randomUUID()}`);
41
+ await session.ensureBrowser();
42
+ // Decorate with session reference
43
+ app.decorate("session", session);
44
+ // Register routes
45
+ registerHealthRoute(app);
46
+ registerTabsRoute(app);
47
+ registerNavigateRoute(app);
48
+ registerSnapshotRoute(app);
49
+ registerActionRoute(app);
50
+ registerActionsRoute(app);
51
+ registerTextRoute(app);
52
+ registerPageModelRoute(app);
53
+ registerScreenshotRoute(app);
54
+ registerPdfRoute(app);
55
+ registerEvaluateRoute(app);
56
+ registerTabRoute(app);
57
+ registerTabLockRoute(app);
58
+ registerCookiesRoute(app);
59
+ registerUploadRoute(app);
60
+ registerDownloadRoute(app);
61
+ registerRecordingRoutes(app);
62
+ // Cleanup on close
63
+ app.addHook("onClose", async () => {
64
+ logger.info("Shutting down browser session");
65
+ await session.close();
66
+ });
67
+ return app;
68
+ }
69
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/server/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * AriseBrowser public type definitions.
3
+ */
4
+ export interface AriseBrowserConfig {
5
+ /** Connection mode:
6
+ * - 'standalone': Launch new Chromium (default)
7
+ * - 'cdp': Connect to existing browser via CDP
8
+ * - 'managed': Persistent browser profile
9
+ */
10
+ mode: "standalone" | "cdp" | "managed";
11
+ /** CDP endpoint URL (required for 'cdp' mode) */
12
+ cdpUrl?: string;
13
+ /** Run headless (standalone/managed mode, default true) */
14
+ headless?: boolean;
15
+ /** Profile directory (managed mode) */
16
+ profileDir?: string;
17
+ /** Viewport size */
18
+ viewport?: {
19
+ width: number;
20
+ height: number;
21
+ };
22
+ /** Custom user agent */
23
+ userAgent?: string;
24
+ /** Apply safe stealth context options (default true) */
25
+ stealthHeaders?: boolean;
26
+ /** Virtual display mode (Linux server) */
27
+ virtualDisplay?: {
28
+ enabled: boolean;
29
+ display?: string;
30
+ screen?: string;
31
+ nekoPort?: number;
32
+ nekoPassword?: string;
33
+ nekoAdminPassword?: string;
34
+ chromeDebugPort?: number;
35
+ chromePath?: string;
36
+ };
37
+ }
38
+ export type ActionDict = Record<string, unknown>;
39
+ export interface ActionResult {
40
+ success: boolean;
41
+ message: string;
42
+ details: Record<string, unknown>;
43
+ }
44
+ export interface TabInfo {
45
+ tab_id: string;
46
+ url: string;
47
+ title: string;
48
+ is_current: boolean;
49
+ }
50
+ export interface SessionRef {
51
+ getTabInfo(): Promise<TabInfo[]>;
52
+ switchToTab(tabId: string): Promise<boolean>;
53
+ }
54
+ export interface RecordedOperation {
55
+ type: string;
56
+ timestamp: string;
57
+ url?: string;
58
+ ref?: string;
59
+ text?: string;
60
+ role?: string;
61
+ value?: string;
62
+ tab_id?: string;
63
+ direction?: string;
64
+ amount?: number;
65
+ request_url?: string;
66
+ method?: string;
67
+ status?: number;
68
+ [key: string]: unknown;
69
+ }
70
+ export interface RecordingResult {
71
+ session_id: string;
72
+ operations: RecordedOperation[];
73
+ operations_count: number;
74
+ snapshots: Record<string, SnapshotRecord>;
75
+ }
76
+ export interface SnapshotRecord {
77
+ url: string;
78
+ snapshot_text?: string;
79
+ simple?: Record<string, unknown>;
80
+ captured_at: string;
81
+ }
82
+ export interface SnapshotResult {
83
+ snapshotText: string;
84
+ elements: Record<string, unknown>;
85
+ metadata?: {
86
+ refDebug?: {
87
+ weakmapHit?: number;
88
+ ariaRefHit?: number;
89
+ signatureHit?: number;
90
+ newRef?: number;
91
+ evicted?: number;
92
+ };
93
+ refCounterValue?: number;
94
+ totalMappedRefs?: number;
95
+ };
96
+ }
97
+ export interface ServerConfig {
98
+ port?: number;
99
+ host?: string;
100
+ token?: string;
101
+ }
102
+ export interface TabLock {
103
+ owner: string;
104
+ expiresAt: number;
105
+ }
106
+ export interface LearnData {
107
+ type: "browser_workflow";
108
+ task: string;
109
+ success: boolean;
110
+ source: string;
111
+ domain: string;
112
+ steps: LearnStep[];
113
+ metadata: {
114
+ duration_ms: number;
115
+ page_count: number;
116
+ recorded_at: string;
117
+ };
118
+ }
119
+ export interface LearnStep {
120
+ url: string;
121
+ action: string;
122
+ target?: string;
123
+ value?: string;
124
+ }
125
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * AriseBrowser public type definitions.
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * VirtualDisplayManager — manages Xvfb, PulseAudio, Openbox, Chrome, and Neko
3
+ * as child processes for Linux cloud server deployment.
4
+ *
5
+ * arise-browser is the single entry process; no supervisord needed.
6
+ */
7
+ export interface VirtualDisplayConfig {
8
+ /** X11 display number (default ":99") */
9
+ display: string;
10
+ /** Screen resolution+depth (default "1920x1080x24") */
11
+ screen: string;
12
+ /** Neko HTTP/WS port (default 6090) */
13
+ nekoPort: number;
14
+ /** Neko user password (default "neko") */
15
+ nekoPassword: string;
16
+ /** Neko admin password (default "admin") */
17
+ nekoAdminPassword: string;
18
+ /** Chrome remote debugging port (default 9222) */
19
+ chromeDebugPort: number;
20
+ /** Path to Chrome binary (auto-detected if omitted) */
21
+ chromePath: string;
22
+ }
23
+ export declare class VirtualDisplayManager {
24
+ private _xvfb;
25
+ private _pulseaudio;
26
+ private _openbox;
27
+ private _chrome;
28
+ private _neko;
29
+ private _started;
30
+ private readonly _config;
31
+ constructor(config?: Partial<VirtualDisplayConfig>);
32
+ get config(): VirtualDisplayConfig;
33
+ isRunning(): boolean;
34
+ start(): Promise<void>;
35
+ stop(): Promise<void>;
36
+ }
37
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/virtual-display/manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwBH,MAAM,WAAW,oBAAoB;IACnC,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,0CAA0C;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kDAAkD;IAClD,eAAe,EAAE,MAAM,CAAC;IACxB,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;CACpB;AAmCD,qBAAa,qBAAqB;IAChC,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;gBAEnC,MAAM,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC;IAOlD,IAAI,MAAM,IAAI,oBAAoB,CAEjC;IAED,SAAS,IAAI,OAAO;IAId,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAuItB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAiC5B"}
@@ -0,0 +1,229 @@
1
+ /**
2
+ * VirtualDisplayManager — manages Xvfb, PulseAudio, Openbox, Chrome, and Neko
3
+ * as child processes for Linux cloud server deployment.
4
+ *
5
+ * arise-browser is the single entry process; no supervisord needed.
6
+ */
7
+ import { existsSync } from "node:fs";
8
+ import { resolve, dirname, join } from "node:path";
9
+ import { fileURLToPath } from "node:url";
10
+ import { createLogger } from "../logger.js";
11
+ import { ProcessRunner } from "./process-runner.js";
12
+ const __dirname = dirname(fileURLToPath(import.meta.url));
13
+ /**
14
+ * Find the package root by walking up from __dirname to find package.json.
15
+ * Works both in src/ (dev) and dist/ (compiled).
16
+ */
17
+ function findPackageRoot() {
18
+ let dir = __dirname;
19
+ for (let i = 0; i < 5; i++) {
20
+ if (existsSync(join(dir, "package.json")))
21
+ return dir;
22
+ dir = dirname(dir);
23
+ }
24
+ // Fallback: assume 2 levels up from src/virtual-display or dist/src/virtual-display
25
+ return resolve(__dirname, "../..");
26
+ }
27
+ const DEFAULT_CONFIG = {
28
+ display: ":99",
29
+ screen: "1920x1080x24",
30
+ nekoPort: 6090,
31
+ nekoPassword: "neko",
32
+ nekoAdminPassword: "admin",
33
+ chromeDebugPort: 9222,
34
+ chromePath: "",
35
+ };
36
+ const CHROME_CANDIDATES = [
37
+ "/usr/bin/google-chrome-stable",
38
+ "/usr/bin/google-chrome",
39
+ "/usr/bin/chromium-browser",
40
+ "/usr/bin/chromium",
41
+ ];
42
+ function findChrome() {
43
+ for (const candidate of CHROME_CANDIDATES) {
44
+ if (existsSync(candidate))
45
+ return candidate;
46
+ }
47
+ throw new Error(`Chrome not found. Tried: ${CHROME_CANDIDATES.join(", ")}. Install Chrome or set chromePath.`);
48
+ }
49
+ /** Resolve path to deploy/neko/ config files */
50
+ function deployPath(filename) {
51
+ return resolve(findPackageRoot(), "deploy/neko", filename);
52
+ }
53
+ const log = createLogger("virtual-display");
54
+ export class VirtualDisplayManager {
55
+ _xvfb = null;
56
+ _pulseaudio = null;
57
+ _openbox = null;
58
+ _chrome = null;
59
+ _neko = null;
60
+ _started = false;
61
+ _config;
62
+ constructor(config) {
63
+ this._config = { ...DEFAULT_CONFIG, ...config };
64
+ if (!this._config.chromePath) {
65
+ this._config.chromePath = findChrome();
66
+ }
67
+ }
68
+ get config() {
69
+ return { ...this._config };
70
+ }
71
+ isRunning() {
72
+ return this._started;
73
+ }
74
+ async start() {
75
+ if (this._started)
76
+ return;
77
+ const { display, screen, nekoPort, nekoPassword, nekoAdminPassword, chromeDebugPort, chromePath } = this._config;
78
+ // Extract display number: ":99" → "99", ":99.0" → "99"
79
+ const displayNum = display.replace(/^:/, "").split(".")[0];
80
+ const displayEnv = { DISPLAY: display };
81
+ log.info(`Starting virtual display environment (display=${display}, chrome=${chromePath}, neko=:${nekoPort})`);
82
+ try {
83
+ // 1. Xvfb
84
+ const xorgConf = deployPath("xorg.conf");
85
+ const xvfbArgs = [display, "-screen", "0", screen, "-nolisten", "tcp"];
86
+ if (existsSync(xorgConf)) {
87
+ xvfbArgs.push("-config", xorgConf);
88
+ }
89
+ this._xvfb = new ProcessRunner({
90
+ name: "xvfb",
91
+ command: "/usr/bin/Xvfb",
92
+ args: xvfbArgs,
93
+ readiness: {
94
+ type: "file",
95
+ target: `/tmp/.X11-unix/X${displayNum}`,
96
+ timeoutMs: 10_000,
97
+ },
98
+ });
99
+ await this._xvfb.start();
100
+ // 2. PulseAudio
101
+ const pulseConf = deployPath("pulseaudio.pa");
102
+ this._pulseaudio = new ProcessRunner({
103
+ name: "pulseaudio",
104
+ command: "/usr/bin/pulseaudio",
105
+ args: [
106
+ "--disallow-exit",
107
+ "--disallow-module-loading",
108
+ "-n",
109
+ "-F",
110
+ pulseConf,
111
+ "--exit-idle-time=-1",
112
+ ],
113
+ readiness: {
114
+ type: "file",
115
+ target: "/tmp/pulseaudio.socket",
116
+ timeoutMs: 10_000,
117
+ },
118
+ });
119
+ await this._pulseaudio.start();
120
+ // 3. Openbox
121
+ const openboxConf = deployPath("openbox.xml");
122
+ this._openbox = new ProcessRunner({
123
+ name: "openbox",
124
+ command: "/usr/bin/openbox",
125
+ args: existsSync(openboxConf)
126
+ ? ["--config-file", openboxConf]
127
+ : [],
128
+ env: displayEnv,
129
+ });
130
+ await this._openbox.start();
131
+ // Small delay for window manager to initialize
132
+ await new Promise((r) => setTimeout(r, 500));
133
+ // 4. Chrome
134
+ this._chrome = new ProcessRunner({
135
+ name: "chrome",
136
+ command: chromePath,
137
+ args: [
138
+ `--remote-debugging-port=${chromeDebugPort}`,
139
+ `--display=${display}`,
140
+ "--window-position=0,0",
141
+ "--no-first-run",
142
+ "--start-maximized",
143
+ "--bwsi",
144
+ "--force-dark-mode",
145
+ "--disable-file-system",
146
+ "--disable-gpu",
147
+ "--disable-software-rasterizer",
148
+ "--disable-dev-shm-usage",
149
+ "--no-sandbox",
150
+ "--disable-setuid-sandbox",
151
+ ],
152
+ env: {
153
+ ...displayEnv,
154
+ PULSE_SERVER: "unix:/tmp/pulseaudio.socket",
155
+ },
156
+ readiness: {
157
+ type: "http",
158
+ target: `http://localhost:${chromeDebugPort}/json/version`,
159
+ timeoutMs: 15_000,
160
+ },
161
+ });
162
+ await this._chrome.start();
163
+ // 5. Neko Server
164
+ this._neko = new ProcessRunner({
165
+ name: "neko",
166
+ command: "/usr/local/bin/neko",
167
+ args: ["serve", "--bind", `0.0.0.0:${nekoPort}`],
168
+ env: {
169
+ ...displayEnv,
170
+ PULSE_SERVER: "unix:/tmp/pulseaudio.socket",
171
+ // Convert Xvfb format "1920x1080x24" → Neko format "1920x1080@30"
172
+ NEKO_DESKTOP_SCREEN: screen.replace(/x\d+$/, "@30"),
173
+ NEKO_MEMBER_PROVIDER: "multiuser",
174
+ NEKO_MEMBER_MULTIUSER_ADMIN_PASSWORD: nekoAdminPassword,
175
+ NEKO_MEMBER_MULTIUSER_USER_PASSWORD: nekoPassword,
176
+ NEKO_SESSION_IMPLICIT_HOSTING: "true",
177
+ NEKO_SESSION_MERCIFUL_RECONNECT: "true",
178
+ },
179
+ readiness: {
180
+ type: "http",
181
+ target: `http://localhost:${nekoPort}/health`,
182
+ timeoutMs: 15_000,
183
+ intervalMs: 500,
184
+ },
185
+ });
186
+ await this._neko.start();
187
+ this._started = true;
188
+ log.info("Virtual display environment started successfully");
189
+ }
190
+ catch (err) {
191
+ // Clean up any processes that started before the failure
192
+ log.error({ err }, "Failed to start virtual display environment, cleaning up");
193
+ this._started = true; // Allow stop() to run
194
+ await this.stop();
195
+ throw err;
196
+ }
197
+ }
198
+ async stop() {
199
+ if (!this._started)
200
+ return;
201
+ log.info("Stopping virtual display environment...");
202
+ // Stop in reverse order
203
+ const processes = [
204
+ this._neko,
205
+ this._chrome,
206
+ this._openbox,
207
+ this._pulseaudio,
208
+ this._xvfb,
209
+ ];
210
+ for (const proc of processes) {
211
+ if (proc) {
212
+ try {
213
+ await proc.stop();
214
+ }
215
+ catch (err) {
216
+ log.error({ err }, "Error stopping process");
217
+ }
218
+ }
219
+ }
220
+ this._neko = null;
221
+ this._chrome = null;
222
+ this._openbox = null;
223
+ this._pulseaudio = null;
224
+ this._xvfb = null;
225
+ this._started = false;
226
+ log.info("Virtual display environment stopped");
227
+ }
228
+ }
229
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../src/virtual-display/manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Child process runner with auto-restart, readiness detection,
3
+ * log integration, and graceful shutdown.
4
+ */
5
+ export interface ReadinessCheck {
6
+ /** Wait for a file/socket to appear */
7
+ type: "file" | "http";
8
+ /** File path or HTTP URL */
9
+ target: string;
10
+ /** Max wait time in ms (default 10000) */
11
+ timeoutMs?: number;
12
+ /** Poll interval in ms (default 200) */
13
+ intervalMs?: number;
14
+ }
15
+ export interface ProcessRunnerConfig {
16
+ name: string;
17
+ command: string;
18
+ args?: string[];
19
+ env?: Record<string, string>;
20
+ readiness?: ReadinessCheck;
21
+ maxRestarts?: number;
22
+ backoffMs?: number;
23
+ shutdownTimeoutMs?: number;
24
+ }
25
+ export declare class ProcessRunner {
26
+ private _process;
27
+ private _running;
28
+ private _restartCount;
29
+ private _intentionalStop;
30
+ private _restartScheduled;
31
+ private readonly _log;
32
+ private readonly _config;
33
+ constructor(config: ProcessRunnerConfig);
34
+ get running(): boolean;
35
+ get pid(): number | undefined;
36
+ start(): Promise<void>;
37
+ stop(): Promise<void>;
38
+ private _spawn;
39
+ private _maybeRestart;
40
+ private _waitReady;
41
+ private _killProcess;
42
+ }
43
+ //# sourceMappingURL=process-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-runner.d.ts","sourceRoot":"","sources":["../../../src/virtual-display/process-runner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,cAAc;IAC7B,uCAAuC;IACvC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;gBAElC,MAAM,EAAE,mBAAmB;IAKvC,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,GAAG,IAAI,MAAM,GAAG,SAAS,CAE5B;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAStB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAYb,MAAM;IAoDpB,OAAO,CAAC,aAAa;YA+BP,UAAU;YA0CV,YAAY;CAyC3B"}