abtars 0.2.0 → 0.2.1-alpha.10

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 (146) hide show
  1. package/README.md +15 -18
  2. package/bundle/{_registry.generated-6GO2PAMD.js → _registry.generated-4P6KTBTH.js} +8 -8
  3. package/bundle/_registry.generated-G2FSGHNY.js +36 -0
  4. package/bundle/_registry.generated-G2FSGHNY.js.map +7 -0
  5. package/bundle/_registry.generated-N74SMTUJ.js +36 -0
  6. package/bundle/_registry.generated-N74SMTUJ.js.map +7 -0
  7. package/bundle/_registry.generated-Y4VT5MBX.js +36 -0
  8. package/bundle/_registry.generated-Y4VT5MBX.js.map +7 -0
  9. package/bundle/abtars-browser.js +0 -1
  10. package/bundle/abtars-browser.js.map +2 -2
  11. package/bundle/abtars-cli.js +589 -547
  12. package/bundle/abtars-cli.js.map +4 -4
  13. package/bundle/abtars-restart.js +1 -1
  14. package/bundle/abtars-rss.js +0 -1
  15. package/bundle/abtars-rss.js.map +2 -2
  16. package/bundle/abtars-task.js +1 -2
  17. package/bundle/abtars-task.js.map +2 -2
  18. package/bundle/abtars.js +58 -33
  19. package/bundle/abtars.js.map +2 -2
  20. package/bundle/{agent-registry-SYUFNSVB.js → agent-registry-TM7EISOV.js} +2 -2
  21. package/bundle/{browse-delivery-64GQIUHG.js → browse-delivery-VTLEAVYA.js} +4 -4
  22. package/bundle/{browser-5H2Q7GEC.js → browser-JQGYFZAG.js} +5 -5
  23. package/bundle/browser-M4KDLN75.js +19 -0
  24. package/bundle/browser-REIXOJ6S.js +19 -0
  25. package/bundle/browser-VG2GTEND.js +19 -0
  26. package/bundle/{chunk-KFENC7BM.js → chunk-4YOTNYAE.js} +2 -2
  27. package/bundle/{chunk-KWBGYWDO.js → chunk-7I5C2U3C.js} +1 -1
  28. package/bundle/chunk-7I5C2U3C.js.map +7 -0
  29. package/bundle/{chunk-7STAQF5O.js → chunk-CNWXVXGH.js} +4 -4
  30. package/bundle/{chunk-7STAQF5O.js.map → chunk-CNWXVXGH.js.map} +2 -2
  31. package/bundle/{chunk-JX3ZZU3O.js → chunk-CU3O53U3.js} +28 -14
  32. package/bundle/chunk-CU3O53U3.js.map +7 -0
  33. package/bundle/chunk-EZZBO2QK.js +85 -0
  34. package/bundle/chunk-EZZBO2QK.js.map +7 -0
  35. package/bundle/{chunk-XLLSPBBT.js → chunk-GPL57SRN.js} +2 -2
  36. package/bundle/chunk-GPL57SRN.js.map +7 -0
  37. package/bundle/{chunk-PQ62LZNA.js → chunk-HEHD3GG5.js} +2 -2
  38. package/bundle/{chunk-A5OJYQNU.js → chunk-HTGVYNPE.js} +4 -4
  39. package/bundle/{chunk-WUTCGJDZ.js → chunk-HZRUBJ4Q.js} +148 -9
  40. package/bundle/chunk-HZRUBJ4Q.js.map +7 -0
  41. package/bundle/{chunk-ZVDVNSXK.js → chunk-J7CFCY4U.js} +2 -2
  42. package/bundle/{chunk-HXJRZWKA.js → chunk-JRK3UFBS.js} +106 -58
  43. package/bundle/chunk-JRK3UFBS.js.map +7 -0
  44. package/bundle/{chunk-GZUQQWBZ.js → chunk-KJOCXWJ5.js} +3 -3
  45. package/bundle/chunk-KJOCXWJ5.js.map +7 -0
  46. package/bundle/{chunk-K7P74UNQ.js → chunk-LDKSCXGL.js} +3 -3
  47. package/bundle/{chunk-K7P74UNQ.js.map → chunk-LDKSCXGL.js.map} +2 -2
  48. package/bundle/chunk-MNKLPRGY.js +138 -0
  49. package/bundle/chunk-MNKLPRGY.js.map +7 -0
  50. package/bundle/chunk-O73EZGKR.js +135 -0
  51. package/bundle/chunk-O73EZGKR.js.map +7 -0
  52. package/bundle/{chunk-OZ4IZFV4.js → chunk-Q7F5R2LL.js} +1 -1
  53. package/bundle/{chunk-OZ4IZFV4.js.map → chunk-Q7F5R2LL.js.map} +2 -2
  54. package/bundle/{chunk-XOCP5BMO.js → chunk-URAQLQ2U.js} +2 -2
  55. package/bundle/chunk-URAQLQ2U.js.map +7 -0
  56. package/bundle/{chunk-PPSB2ZIN.js → chunk-VREI2GUO.js} +18 -7
  57. package/bundle/chunk-VREI2GUO.js.map +7 -0
  58. package/bundle/chunk-VYR25H37.js +135 -0
  59. package/bundle/chunk-VYR25H37.js.map +7 -0
  60. package/bundle/{commands-E3Y4QUNF.js → commands-J6JAZ7D2.js} +5 -5
  61. package/bundle/{deploy-lib-import-ODLDL2DB.js → deploy-lib-import-PJXUADPS.js} +18 -16
  62. package/bundle/{direct-api-transport-TRV45NO6.js → direct-api-transport-ZSJHKYBX.js} +1 -1
  63. package/bundle/direct-api-transport-ZSJHKYBX.js.map +7 -0
  64. package/bundle/{discord-adapter-5DS7UTBE.js → discord-adapter-OCWSJTJU.js} +8 -8
  65. package/bundle/{doctor-R54GZPKL.js → doctor-XOGVHA4W.js} +13 -2
  66. package/bundle/{doctor-R54GZPKL.js.map → doctor-XOGVHA4W.js.map} +2 -2
  67. package/bundle/{install-RSLOS3Q5.js → install-6H3APAIJ.js} +3 -3
  68. package/bundle/{irc-adapter-RKRUSZXB.js → irc-adapter-AIEP6OX6.js} +6 -2
  69. package/bundle/irc-adapter-AIEP6OX6.js.map +7 -0
  70. package/bundle/{message-pipeline-CFVO73CK.js → message-pipeline-TCPHRBAK.js} +5 -5
  71. package/bundle/meta.json +4005 -3868
  72. package/bundle/{phase-transport-FEZ4SIJJ.js → phase-transport-ME2XDRR2.js} +3 -3
  73. package/bundle/restore-UH2UE2K5.js +151 -0
  74. package/bundle/restore-UH2UE2K5.js.map +7 -0
  75. package/bundle/rollback-D7AYTC7Z.js +11 -0
  76. package/bundle/{sleep-BPWX3FCN.js → sleep-IOWYTSMK.js} +2 -2
  77. package/bundle/{soul-bundle-BRIUDEQ2.js → soul-bundle-AH5S3MVI.js} +2 -2
  78. package/bundle/{soul-loader-GBXJ7EBH.js → soul-loader-N5FA4I6C.js} +3 -3
  79. package/bundle/soul-loader-N5FA4I6C.js.map +7 -0
  80. package/bundle/{start-4IWBKLWO.js → start-CBVKNEAT.js} +1 -1
  81. package/bundle/{subagent-runtime-MDBO6LHS.js → subagent-runtime-OOJXCKJF.js} +2 -2
  82. package/bundle/subagent-runtime-OOJXCKJF.js.map +7 -0
  83. package/bundle/{system-status-WAY63BYC.js → system-status-4JP36OKC.js} +12 -5
  84. package/bundle/{system-status-WAY63BYC.js.map → system-status-4JP36OKC.js.map} +2 -2
  85. package/bundle/{task-store-KIBFZL5A.js → task-store-LC7ZMS72.js} +2 -2
  86. package/bundle/task-store-LC7ZMS72.js.map +7 -0
  87. package/bundle/{telegram-adapter-MVA33IO2.js → telegram-adapter-QXHJQLLX.js} +5 -5
  88. package/bundle/{update-check-O5MS6B3L.js → update-check-XVY2IK2L.js} +2 -2
  89. package/bundle/update-check-XVY2IK2L.js.map +7 -0
  90. package/core/skills/tools/rss/SKILL.md +51 -0
  91. package/install-manifest.json +4 -3
  92. package/package.json +3 -4
  93. package/scripts/abtars-daemon.service +1 -1
  94. package/scripts/abtars-watchdog.service +1 -1
  95. package/scripts/abtars.sh +3 -5
  96. package/scripts/abtars@.service +1 -1
  97. package/scripts/build-and-deploy.sh +6 -0
  98. package/scripts/com.abtars.daemon.plist +1 -1
  99. package/scripts/com.abtars.watchdog.plist +1 -1
  100. package/scripts/daily-backup.sh +1 -61
  101. package/scripts/doctor.sh +48 -33
  102. package/scripts/watchdog.sh +53 -8
  103. package/bundle/chunk-GZUQQWBZ.js.map +0 -7
  104. package/bundle/chunk-HXJRZWKA.js.map +0 -7
  105. package/bundle/chunk-JX3ZZU3O.js.map +0 -7
  106. package/bundle/chunk-KWBGYWDO.js.map +0 -7
  107. package/bundle/chunk-PPSB2ZIN.js.map +0 -7
  108. package/bundle/chunk-WUTCGJDZ.js.map +0 -7
  109. package/bundle/chunk-XLLSPBBT.js.map +0 -7
  110. package/bundle/chunk-XOCP5BMO.js.map +0 -7
  111. package/bundle/direct-api-transport-TRV45NO6.js.map +0 -7
  112. package/bundle/irc-adapter-RKRUSZXB.js.map +0 -7
  113. package/bundle/passwd-QSHZJ2CG.js +0 -134
  114. package/bundle/passwd-QSHZJ2CG.js.map +0 -7
  115. package/bundle/restore-ROJF22R2.js +0 -47
  116. package/bundle/restore-ROJF22R2.js.map +0 -7
  117. package/core/core_templates/SOUL.md +0 -24
  118. package/core/core_templates/agent_notes.md +0 -7
  119. package/core/core_templates/core_facts.md +0 -10
  120. package/core/core_templates/user_profile.md +0 -7
  121. package/core/skills/tools/fxtwitter/SKILL.md +0 -52
  122. package/core/skills/tools/twitterX/SKILL.md +0 -52
  123. package/core/skills/tools/twitterX/scripts/abtars-tweet.js +0 -532
  124. package/core/skills/tools/twitterX/scripts/package.json +0 -1
  125. /package/bundle/{_registry.generated-6GO2PAMD.js.map → _registry.generated-4P6KTBTH.js.map} +0 -0
  126. /package/bundle/{agent-registry-SYUFNSVB.js.map → agent-registry-TM7EISOV.js.map} +0 -0
  127. /package/bundle/{browse-delivery-64GQIUHG.js.map → browse-delivery-VTLEAVYA.js.map} +0 -0
  128. /package/bundle/{browser-5H2Q7GEC.js.map → browser-JQGYFZAG.js.map} +0 -0
  129. /package/bundle/{commands-E3Y4QUNF.js.map → browser-M4KDLN75.js.map} +0 -0
  130. /package/bundle/{deploy-lib-import-ODLDL2DB.js.map → browser-REIXOJ6S.js.map} +0 -0
  131. /package/bundle/{install-RSLOS3Q5.js.map → browser-VG2GTEND.js.map} +0 -0
  132. /package/bundle/{chunk-KFENC7BM.js.map → chunk-4YOTNYAE.js.map} +0 -0
  133. /package/bundle/{chunk-PQ62LZNA.js.map → chunk-HEHD3GG5.js.map} +0 -0
  134. /package/bundle/{chunk-A5OJYQNU.js.map → chunk-HTGVYNPE.js.map} +0 -0
  135. /package/bundle/{chunk-ZVDVNSXK.js.map → chunk-J7CFCY4U.js.map} +0 -0
  136. /package/bundle/{message-pipeline-CFVO73CK.js.map → commands-J6JAZ7D2.js.map} +0 -0
  137. /package/bundle/{phase-transport-FEZ4SIJJ.js.map → deploy-lib-import-PJXUADPS.js.map} +0 -0
  138. /package/bundle/{discord-adapter-5DS7UTBE.js.map → discord-adapter-OCWSJTJU.js.map} +0 -0
  139. /package/bundle/{sleep-BPWX3FCN.js.map → install-6H3APAIJ.js.map} +0 -0
  140. /package/bundle/{soul-bundle-BRIUDEQ2.js.map → message-pipeline-TCPHRBAK.js.map} +0 -0
  141. /package/bundle/{soul-loader-GBXJ7EBH.js.map → phase-transport-ME2XDRR2.js.map} +0 -0
  142. /package/bundle/{subagent-runtime-MDBO6LHS.js.map → rollback-D7AYTC7Z.js.map} +0 -0
  143. /package/bundle/{task-store-KIBFZL5A.js.map → sleep-IOWYTSMK.js.map} +0 -0
  144. /package/bundle/{update-check-O5MS6B3L.js.map → soul-bundle-AH5S3MVI.js.map} +0 -0
  145. /package/bundle/{start-4IWBKLWO.js.map → start-CBVKNEAT.js.map} +0 -0
  146. /package/bundle/{telegram-adapter-MVA33IO2.js.map → telegram-adapter-QXHJQLLX.js.map} +0 -0
@@ -0,0 +1,135 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __bundleCreateRequire } from 'node:module'; import { fileURLToPath as __bundleFileURLToPath } from 'node:url'; import { dirname as __bundleDirname } from 'node:path'; const require = __bundleCreateRequire(import.meta.url); const __chunk_filename = __bundleFileURLToPath(import.meta.url); const __chunk_dirname = __bundleDirname(__chunk_filename);
3
+ import {
4
+ checkBrowseTasks,
5
+ deliverBrowseResult,
6
+ readPendingBrowse,
7
+ writePendingBrowse
8
+ } from "./chunk-LDKSCXGL.js";
9
+ import {
10
+ BrowserIpcServer,
11
+ BrowserManager,
12
+ BrowserTool,
13
+ DomainAllowlist
14
+ } from "./chunk-KSEIWT4T.js";
15
+ import {
16
+ getEnv,
17
+ init_env_schema
18
+ } from "./chunk-PZE3J7ER.js";
19
+ import {
20
+ init_logger,
21
+ logError,
22
+ logInfo,
23
+ logWarn
24
+ } from "./chunk-2BY6I4P5.js";
25
+ import {
26
+ abtarsHome,
27
+ init_paths
28
+ } from "./chunk-MJ6PHMOK.js";
29
+ import {
30
+ __export
31
+ } from "./chunk-7K2YZTLD.js";
32
+
33
+ // src/capabilities/browser/index.ts
34
+ var browser_exports = {};
35
+ __export(browser_exports, {
36
+ register: () => register
37
+ });
38
+ init_env_schema();
39
+ init_logger();
40
+ init_paths();
41
+ import * as net from "node:net";
42
+ import { join } from "node:path";
43
+ import { unlinkSync, mkdirSync, chmodSync } from "node:fs";
44
+ function register(api) {
45
+ const browserManager = new BrowserManager();
46
+ const allowlist = DomainAllowlist.fromEnv();
47
+ const browserTool = new BrowserTool(browserManager, allowlist);
48
+ let browserIpc = null;
49
+ const ensureBrowserIpc = async () => {
50
+ if (browserIpc || getEnv().browserDocker) return;
51
+ browserIpc = new BrowserIpcServer(browserTool);
52
+ await browserIpc.start();
53
+ logInfo("browser", `\u{1F50C} Browser IPC listening on ${browserIpc.socketPath}`);
54
+ };
55
+ const spawnSocketPath = join(abtarsHome(), "browser-socket", "browse-spawn.sock");
56
+ try {
57
+ mkdirSync(join(abtarsHome(), "browser-socket"), { recursive: true, mode: 448 });
58
+ try {
59
+ unlinkSync(spawnSocketPath);
60
+ } catch {
61
+ }
62
+ try {
63
+ chmodSync(join(abtarsHome(), "browser-socket"), 448);
64
+ } catch {
65
+ }
66
+ const spawnServer = net.createServer((conn) => {
67
+ let buf = "";
68
+ conn.on("data", (chunk) => {
69
+ buf += chunk.toString();
70
+ const nl = buf.indexOf("\n");
71
+ if (nl === -1) return;
72
+ const line = buf.slice(0, nl);
73
+ buf = buf.slice(nl + 1);
74
+ try {
75
+ const { taskId, task, prompt, chatId, threadId, timeoutMs } = JSON.parse(line);
76
+ const entry = {
77
+ taskId,
78
+ task,
79
+ chatId,
80
+ threadId,
81
+ pid: process.pid,
82
+ // bridge pid — runtime manages the actual transport
83
+ startedAt: Date.now(),
84
+ timeoutMs,
85
+ logFile: ""
86
+ // no log file — result comes from callback
87
+ };
88
+ const entries = readPendingBrowse();
89
+ entries.push(entry);
90
+ writePendingBrowse(entries);
91
+ api.runtime.spawn("browsie", prompt, {
92
+ timeoutMs,
93
+ onComplete: (_id, result) => {
94
+ deliverBrowseResult(entry, result);
95
+ const remaining = readPendingBrowse().filter((e) => e.taskId !== taskId);
96
+ writePendingBrowse(remaining);
97
+ },
98
+ onError: (_id, err) => {
99
+ logWarn("browser", `Browsie spawn failed for ${taskId}: ${err.message}`);
100
+ deliverBrowseResult(entry, `Browse task failed: ${err.message}`);
101
+ const remaining = readPendingBrowse().filter((e) => e.taskId !== taskId);
102
+ writePendingBrowse(remaining);
103
+ }
104
+ }).then(({ taskId: spawnId }) => {
105
+ conn.write(JSON.stringify({ ok: true, taskId, spawnId, status: "spawned" }) + "\n");
106
+ }).catch((err) => {
107
+ conn.write(JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }) + "\n");
108
+ });
109
+ } catch (err) {
110
+ conn.write(JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }) + "\n");
111
+ }
112
+ });
113
+ conn.on("error", () => {
114
+ });
115
+ });
116
+ spawnServer.listen(spawnSocketPath, () => {
117
+ logInfo("browser", `\u{1F50C} Browse spawn IPC listening on ${spawnSocketPath}`);
118
+ });
119
+ } catch (err) {
120
+ logError("browser", `\u26A0\uFE0F Browse-spawn IPC failed \u2014 browser disabled: ${err instanceof Error ? err.message : String(err)}`);
121
+ }
122
+ api.registerHeartbeatTask({
123
+ name: "browse-checker",
124
+ execute: async () => {
125
+ await ensureBrowserIpc();
126
+ checkBrowseTasks();
127
+ }
128
+ });
129
+ }
130
+
131
+ export {
132
+ register,
133
+ browser_exports
134
+ };
135
+ //# sourceMappingURL=chunk-O73EZGKR.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/capabilities/browser/index.ts"],
4
+ "sourcesContent": ["import { logAndSwallow } from \"../../components/log-and-swallow.js\";\nimport { getEnv } from \"../../components/env-schema.js\";\n/**\n * Browser capability \u2014 browse-spawn IPC + browse-checker heartbeat.\n * Level 1 (lightpanda fetch) is handled by the agent via skill \u2014 no bridge code needed.\n * Level 2 (Browsie) uses runtime.spawn() via IPC socket.\n */\n\nimport { BrowserManager } from \"./browser-manager.js\";\nimport { BrowserTool } from \"./browser-tool.js\";\nimport { BrowserIpcServer } from \"./browser-ipc-server.js\";\nimport { DomainAllowlist } from \"./domain-allowlist.js\";\nimport { checkBrowseTasks, deliverBrowseResult } from \"./browse-delivery.js\";\nimport { readPendingBrowse, writePendingBrowse } from \"./abtars-browse.js\";\nimport type { PendingBrowseEntry } from \"./abtars-browse.js\";\nimport { logInfo, logWarn, logError } from \"../../components/logger.js\";\nimport { abtarsHome } from \"../../paths.js\";\nimport type { CapabilityApi } from \"../capability.js\";\nimport * as net from \"node:net\";\nimport { join } from \"node:path\";\nimport { unlinkSync, mkdirSync, chmodSync } from \"node:fs\";\n\nexport function register(api: CapabilityApi): void {\n const browserManager = new BrowserManager();\n const allowlist = DomainAllowlist.fromEnv();\n const browserTool = new BrowserTool(browserManager, allowlist);\n let browserIpc: BrowserIpcServer | null = null;\n\n const ensureBrowserIpc = async (): Promise<void> => {\n if (browserIpc || getEnv().browserDocker) return;\n browserIpc = new BrowserIpcServer(browserTool);\n await browserIpc.start();\n logInfo(\"browser\", `\uD83D\uDD0C Browser IPC listening on ${browserIpc.socketPath}`);\n };\n\n // Browse-spawn IPC \u2014 CLI sends task, bridge spawns via runtime\n const spawnSocketPath = join(abtarsHome(), \"browser-socket\", \"browse-spawn.sock\");\n try {\n mkdirSync(join(abtarsHome(), \"browser-socket\"), { recursive: true, mode: 0o700 });\n try { unlinkSync(spawnSocketPath); } catch { /* doesn't exist \u2014 fine */ }\n try { chmodSync(join(abtarsHome(), \"browser-socket\"), 0o700); } catch { /* best effort */ }\n\n const spawnServer = net.createServer((conn) => {\n let buf = \"\";\n conn.on(\"data\", (chunk) => {\n buf += chunk.toString();\n const nl = buf.indexOf(\"\\n\");\n if (nl === -1) return;\n const line = buf.slice(0, nl);\n buf = buf.slice(nl + 1);\n\n try {\n const { taskId, task, prompt, chatId, threadId, timeoutMs } = JSON.parse(line);\n\n const entry: PendingBrowseEntry = {\n taskId, task, chatId, threadId,\n pid: process.pid, // bridge pid \u2014 runtime manages the actual transport\n startedAt: Date.now(), timeoutMs,\n logFile: \"\", // no log file \u2014 result comes from callback\n };\n const entries = readPendingBrowse();\n entries.push(entry);\n writePendingBrowse(entries);\n\n // Fire-and-forget via runtime\n api.runtime.spawn(\"browsie\", prompt, {\n timeoutMs,\n onComplete: (_id: string, result: string) => {\n deliverBrowseResult(entry, result);\n const remaining = readPendingBrowse().filter(e => e.taskId !== taskId);\n writePendingBrowse(remaining);\n },\n onError: (_id: string, err: Error) => {\n logWarn(\"browser\", `Browsie spawn failed for ${taskId}: ${err.message}`);\n deliverBrowseResult(entry, `Browse task failed: ${err.message}`);\n const remaining = readPendingBrowse().filter(e => e.taskId !== taskId);\n writePendingBrowse(remaining);\n },\n }).then(({ taskId: spawnId }) => {\n conn.write(JSON.stringify({ ok: true, taskId, spawnId, status: \"spawned\" }) + \"\\n\");\n }).catch((err) => {\n conn.write(JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }) + \"\\n\");\n });\n } catch (err) {\n conn.write(JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }) + \"\\n\");\n }\n });\n conn.on(\"error\", () => {});\n });\n\n spawnServer.listen(spawnSocketPath, () => {\n logInfo(\"browser\", `\uD83D\uDD0C Browse spawn IPC listening on ${spawnSocketPath}`);\n });\n } catch (err) {\n logError(\"browser\", `\u26A0\uFE0F Browse-spawn IPC failed \u2014 browser disabled: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n api.registerHeartbeatTask({\n name: \"browse-checker\",\n execute: async () => { await ensureBrowserIpc(); checkBrowseTasks(); },\n });\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -123,4 +123,4 @@ ${lines.join("\n")}`);
123
123
  export {
124
124
  buildSoulBundle
125
125
  };
126
- //# sourceMappingURL=chunk-OZ4IZFV4.js.map
126
+ //# sourceMappingURL=chunk-Q7F5R2LL.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/components/soul-bundle.ts"],
4
- "sourcesContent": ["/**\n * soul-bundle.ts \u2014 Unified SOUL bundle builder for all session types.\n * One function, one matrix. Replaces scattered injection logic.\n */\nimport { logAndSwallow } from \"./log-and-swallow.js\";\nimport { getEnv } from \"./env-schema.js\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { logInfo, logDebug, logWarn } from \"./logger.js\";\nimport { abtarsHome } from \"../paths.js\";\nimport { loadUsers, buildUsersBlock } from \"./user-registry.js\";\nimport type { MemoryManager } from \"abmind\";\nimport type { SessionType } from \"./session-manager.js\";\n\nconst TAG = \"soul-bundle\";\nconst HOST_CORE_DIR = join(abtarsHome(), \"core\");\n\nfunction readOr(path: string): string {\n try { return existsSync(path) ? readFileSync(path, \"utf-8\").trim() : \"\"; } catch { return \"\"; }\n}\n\n/** Type identity \u2014 hardcoded one-liners for non-Main sessions. */\nconst TYPE_IDENTITY: Record<SessionType, string | null> = {\n A: null, // uses full SOUL.md\n B: \"I am a browse agent. I fetch web content and return results. No memory access.\",\n C: \"I am a coding agent. I write and fix code. Be concise.\",\n T: \"I am a task agent. I execute scheduled tasks. Write all output to $WORKSPACE.\",\n S: \"I am the self-healing agent. I diagnose and fix system failures. If unfixable, state: Requires human intervention.\",\n P: \"I am responding to a peer agent request. Be precise and technical.\",\n};\n\nfunction buildModelInstructions(): string {\n const lines: string[] = [];\n if (getEnv().primingModelTopics) {\n lines.push(\"End each response with [TOPICS: kw1, kw2, kw3] \u2014 your top 3 topics from this exchange. Keep them English, lowercase, concise.\");\n }\n return lines.length > 0 ? `# Model Instructions\\n\\n${lines.join(\"\\n\")}` : \"\";\n}\n\nfunction buildCurrentTime(): string {\n const now = new Date();\n const days = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\n return `[CURRENT TIME] ${now.toLocaleDateString(\"en-GB\")} ${days[now.getDay()]}, ${now.toLocaleTimeString(\"en-GB\", { hour: \"2-digit\", minute: \"2-digit\" })}`;\n}\n\n/**\n * Build the SOUL bundle for any session type.\n *\n * Main (A): full 9-part bundle (identity, tools, profile, notes, facts, skills, model-instructions, emotional, users, time)\n * Others: identity one-liner + core facts + skills + time\n */\nexport function buildSoulBundle(type: SessionType, memory?: MemoryManager | null): string | null {\n const parts: string[] = [];\n\n if (type === \"A\") {\n // Full Main bundle\n let bundle: { soul: string; profile: string; notes: string; memoryTools: string; coreFacts: string } | null = null;\n try { bundle = memory?.getSessionBundle() ?? null; } catch (err) { logAndSwallow(TAG, \"op\", err); }\n\n const soul = bundle?.soul || readOr(join(HOST_CORE_DIR, \"SOUL.md\"));\n const memoryTools = bundle?.profile || readOr(join(HOST_CORE_DIR, \"user_profile.md\"));\n const userProfile = bundle?.notes || readOr(join(HOST_CORE_DIR, \"agent_notes.md\"));\n const agentNotes = bundle?.memoryTools || readOr(join(HOST_CORE_DIR, \"TOOLS.md\"));\n const coreFacts = bundle?.coreFacts || readOr(join(HOST_CORE_DIR, \"core_facts.md\"));\n\n if (soul) parts.push(soul);\n if (memoryTools) parts.push(memoryTools);\n if (userProfile) parts.push(userProfile);\n if (agentNotes) parts.push(agentNotes);\n if (coreFacts) parts.push(coreFacts);\n\n const skillsCatalog = readOr(join(HOST_CORE_DIR, \"skills_catalog.md\"));\n if (skillsCatalog) parts.push(skillsCatalog);\n\n const modelInstructions = buildModelInstructions();\n if (modelInstructions) parts.push(modelInstructions);\n\n try {\n const arcs = memory?.getEmotionalArcs() ?? [];\n if (arcs.length > 0) {\n const ARC_LABELS: Record<string, string> = { \"\u2191\": \"user sentiment improving\", \"\u2193\": \"user sentiment worsening \u2014 be careful\", \"\u2195\": \"volatile \u2014 user feelings fluctuate\", \"\u2192\": \"stable\" };\n const lines = arcs.map(a => `- ${a.topic}: ${a.arc} (${ARC_LABELS[a.arc] ?? \"unknown\"})`);\n parts.push(`[EMOTIONAL CONTEXT]\\n${lines.join(\"\\n\")}`);\n }\n } catch (err) { logAndSwallow(TAG, \"op\", err); }\n\n try {\n const registry = loadUsers();\n if (registry.users.length > 0) parts.push(buildUsersBlock(registry));\n } catch (err) { logAndSwallow(TAG, \"op\", err); }\n } else {\n // Lightweight bundle: identity + core facts + skills\n const identity = TYPE_IDENTITY[type];\n if (identity) parts.push(identity);\n\n const coreFacts = readOr(join(HOST_CORE_DIR, \"core_facts.md\"));\n if (coreFacts) parts.push(coreFacts);\n\n const skillsCatalog = readOr(join(HOST_CORE_DIR, \"skills_catalog.md\"));\n if (skillsCatalog) parts.push(skillsCatalog);\n }\n\n parts.push(buildCurrentTime());\n\n if (parts.length === 0) {\n logWarn(TAG, \"No bundle parts generated\");\n return null;\n }\n\n logInfo(TAG, `Bundle [${type}]: ${parts.length} parts`);\n logDebug(TAG, `Parts: ${parts.map((p, i) => `${i}:${p.length}ch`).join(\", \")}`);\n return parts.join(\"\\n\\n---\\n\\n\");\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * soul-bundle.ts \u2014 Unified SOUL bundle builder for all session types.\n * One function, one matrix. Replaces scattered injection logic.\n */\nimport { logAndSwallow } from \"./log-and-swallow.js\";\nimport { getEnv } from \"./env-schema.js\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { logInfo, logDebug, logWarn } from \"./logger.js\";\nimport { abtarsHome } from \"../paths.js\";\nimport { loadUsers, buildUsersBlock } from \"./user-registry.js\";\nimport type { MemoryManager } from \"abmind\";\nimport type { SessionType } from \"./session-manager.js\";\n\nconst TAG = \"soul-bundle\";\nconst HOST_CORE_DIR = join(abtarsHome(), \"core\");\n\nfunction readOr(path: string): string {\n try { return existsSync(path) ? readFileSync(path, \"utf-8\").trim() : \"\"; } catch { return \"\"; }\n}\n\n/** Type identity \u2014 hardcoded one-liners for non-Main sessions. */\nconst TYPE_IDENTITY: Record<SessionType, string | null> = {\n A: null, // uses full SOUL.md\n B: \"I am a browse agent. I fetch web content and return results. No memory access.\",\n C: \"I am a coding agent. I write and fix code. Be concise.\",\n T: \"I am a task agent. I execute scheduled tasks. Write all output to $WORKSPACE.\",\n S: \"I am the self-healing agent. I diagnose and fix system failures. If unfixable, state: Requires human intervention.\",\n P: \"I am responding to a peer agent request. Be precise and technical.\",\n};\n\nfunction buildModelInstructions(): string {\n const lines: string[] = [];\n if (getEnv().primingModelTopics) {\n lines.push(\"End each response with [TOPICS: kw1, kw2, kw3] \u2014 your top 3 topics from this exchange. Keep them English, lowercase, concise.\");\n }\n return lines.length > 0 ? `# Model Instructions\\n\\n${lines.join(\"\\n\")}` : \"\";\n}\n\nfunction buildCurrentTime(): string {\n const now = new Date();\n const days = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\n return `[CURRENT TIME] ${now.toLocaleDateString(\"en-GB\")} ${days[now.getDay()]}, ${now.toLocaleTimeString(\"en-GB\", { hour: \"2-digit\", minute: \"2-digit\" })}`;\n}\n\n/**\n * Build the SOUL bundle for any session type.\n *\n * Main (A): full 9-part bundle (identity, tools, profile, notes, facts, skills, model-instructions, emotional, users, time)\n * Others: identity one-liner + core facts + skills + time\n */\nexport function buildSoulBundle(type: SessionType, memory?: MemoryManager | null): string | null {\n const parts: string[] = [];\n\n if (type === \"A\") {\n // Full Main bundle\n let bundle: { soul: string; profile: string; notes: string; memoryTools: string; coreFacts: string } | null = null;\n try { bundle = memory?.getSessionBundle() ?? null; } catch (err) { logAndSwallow(TAG, \"op\", err); }\n\n const soul = bundle?.soul || readOr(join(HOST_CORE_DIR, \"SOUL.md\"));\n const memoryTools = bundle?.profile || readOr(join(HOST_CORE_DIR, \"user_profile.md\"));\n const userProfile = bundle?.notes || readOr(join(HOST_CORE_DIR, \"agent_notes.md\"));\n const agentNotes = bundle?.memoryTools || readOr(join(HOST_CORE_DIR, \"TOOLS.md\"));\n const coreFacts = bundle?.coreFacts || readOr(join(HOST_CORE_DIR, \"core_facts.md\"));\n\n if (soul) parts.push(soul);\n if (memoryTools) parts.push(memoryTools);\n if (userProfile) parts.push(userProfile);\n if (agentNotes) parts.push(agentNotes);\n if (coreFacts) parts.push(coreFacts);\n\n const skillsCatalog = readOr(join(HOST_CORE_DIR, \"skills_catalog.md\"));\n if (skillsCatalog) parts.push(skillsCatalog);\n\n const modelInstructions = buildModelInstructions();\n if (modelInstructions) parts.push(modelInstructions);\n\n try {\n const arcs = memory?.getEmotionalArcs() ?? [];\n if (arcs.length > 0) {\n const ARC_LABELS: Record<string, string> = { \"\u2191\": \"user sentiment improving\", \"\u2193\": \"user sentiment worsening \u2014 be careful\", \"\u2195\": \"volatile \u2014 user feelings fluctuate\", \"\u2192\": \"stable\" };\n const lines = arcs.map((a: { topic: string; arc: string }) => `- ${a.topic}: ${a.arc} (${ARC_LABELS[a.arc] ?? \"unknown\"})`);\n parts.push(`[EMOTIONAL CONTEXT]\\n${lines.join(\"\\n\")}`);\n }\n } catch (err) { logAndSwallow(TAG, \"op\", err); }\n\n try {\n const registry = loadUsers();\n if (registry.users.length > 0) parts.push(buildUsersBlock(registry));\n } catch (err) { logAndSwallow(TAG, \"op\", err); }\n } else {\n // Lightweight bundle: identity + core facts + skills\n const identity = TYPE_IDENTITY[type];\n if (identity) parts.push(identity);\n\n const coreFacts = readOr(join(HOST_CORE_DIR, \"core_facts.md\"));\n if (coreFacts) parts.push(coreFacts);\n\n const skillsCatalog = readOr(join(HOST_CORE_DIR, \"skills_catalog.md\"));\n if (skillsCatalog) parts.push(skillsCatalog);\n }\n\n parts.push(buildCurrentTime());\n\n if (parts.length === 0) {\n logWarn(TAG, \"No bundle parts generated\");\n return null;\n }\n\n logInfo(TAG, `Bundle [${type}]: ${parts.length} parts`);\n logDebug(TAG, `Parts: ${parts.map((p, i) => `${i}:${p.length}ch`).join(\", \")}`);\n return parts.join(\"\\n\\n---\\n\\n\");\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;AAIA;AACA;AAGA;AACA;AAHA,SAAS,YAAY,oBAAoB;AACzC,SAAS,YAAY;AAOrB,IAAM,MAAM;AACZ,IAAM,gBAAgB,KAAK,WAAW,GAAG,MAAM;AAE/C,SAAS,OAAO,MAAsB;AACpC,MAAI;AAAE,WAAO,WAAW,IAAI,IAAI,aAAa,MAAM,OAAO,EAAE,KAAK,IAAI;AAAA,EAAI,QAAQ;AAAE,WAAO;AAAA,EAAI;AAChG;AAGA,IAAM,gBAAoD;AAAA,EACxD,GAAG;AAAA;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAEA,SAAS,yBAAiC;AACxC,QAAM,QAAkB,CAAC;AACzB,MAAI,OAAO,EAAE,oBAAoB;AAC/B,UAAM,KAAK,oIAA+H;AAAA,EAC5I;AACA,SAAO,MAAM,SAAS,IAAI;AAAA;AAAA,EAA2B,MAAM,KAAK,IAAI,CAAC,KAAK;AAC5E;AAEA,SAAS,mBAA2B;AAClC,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,OAAO,CAAC,UAAU,UAAU,WAAW,aAAa,YAAY,UAAU,UAAU;AAC1F,SAAO,kBAAkB,IAAI,mBAAmB,OAAO,CAAC,IAAI,KAAK,IAAI,OAAO,CAAC,CAAC,KAAK,IAAI,mBAAmB,SAAS,EAAE,MAAM,WAAW,QAAQ,UAAU,CAAC,CAAC;AAC5J;AAQO,SAAS,gBAAgB,MAAmB,QAA8C;AAC/F,QAAM,QAAkB,CAAC;AAEzB,MAAI,SAAS,KAAK;AAEhB,QAAI,SAA0G;AAC9G,QAAI;AAAE,eAAS,QAAQ,iBAAiB,KAAK;AAAA,IAAM,SAAS,KAAK;AAAE,oBAAc,KAAK,MAAM,GAAG;AAAA,IAAG;AAElG,UAAM,OAAO,QAAQ,QAAQ,OAAO,KAAK,eAAe,SAAS,CAAC;AAClE,UAAM,cAAc,QAAQ,WAAW,OAAO,KAAK,eAAe,iBAAiB,CAAC;AACpF,UAAM,cAAc,QAAQ,SAAS,OAAO,KAAK,eAAe,gBAAgB,CAAC;AACjF,UAAM,aAAa,QAAQ,eAAe,OAAO,KAAK,eAAe,UAAU,CAAC;AAChF,UAAM,YAAY,QAAQ,aAAa,OAAO,KAAK,eAAe,eAAe,CAAC;AAElF,QAAI,KAAM,OAAM,KAAK,IAAI;AACzB,QAAI,YAAa,OAAM,KAAK,WAAW;AACvC,QAAI,YAAa,OAAM,KAAK,WAAW;AACvC,QAAI,WAAY,OAAM,KAAK,UAAU;AACrC,QAAI,UAAW,OAAM,KAAK,SAAS;AAEnC,UAAM,gBAAgB,OAAO,KAAK,eAAe,mBAAmB,CAAC;AACrE,QAAI,cAAe,OAAM,KAAK,aAAa;AAE3C,UAAM,oBAAoB,uBAAuB;AACjD,QAAI,kBAAmB,OAAM,KAAK,iBAAiB;AAEnD,QAAI;AACF,YAAM,OAAO,QAAQ,iBAAiB,KAAK,CAAC;AAC5C,UAAI,KAAK,SAAS,GAAG;AACnB,cAAM,aAAqC,EAAE,UAAK,4BAA4B,UAAK,8CAAyC,UAAK,2CAAsC,UAAK,SAAS;AACrL,cAAM,QAAQ,KAAK,IAAI,CAAC,MAAsC,KAAK,EAAE,KAAK,KAAK,EAAE,GAAG,KAAK,WAAW,EAAE,GAAG,KAAK,SAAS,GAAG;AAC1H,cAAM,KAAK;AAAA,EAAwB,MAAM,KAAK,IAAI,CAAC,EAAE;AAAA,MACvD;AAAA,IACF,SAAS,KAAK;AAAE,oBAAc,KAAK,MAAM,GAAG;AAAA,IAAG;AAE/C,QAAI;AACF,YAAM,WAAW,UAAU;AAC3B,UAAI,SAAS,MAAM,SAAS,EAAG,OAAM,KAAK,gBAAgB,QAAQ,CAAC;AAAA,IACrE,SAAS,KAAK;AAAE,oBAAc,KAAK,MAAM,GAAG;AAAA,IAAG;AAAA,EACjD,OAAO;AAEL,UAAM,WAAW,cAAc,IAAI;AACnC,QAAI,SAAU,OAAM,KAAK,QAAQ;AAEjC,UAAM,YAAY,OAAO,KAAK,eAAe,eAAe,CAAC;AAC7D,QAAI,UAAW,OAAM,KAAK,SAAS;AAEnC,UAAM,gBAAgB,OAAO,KAAK,eAAe,mBAAmB,CAAC;AACrE,QAAI,cAAe,OAAM,KAAK,aAAa;AAAA,EAC7C;AAEA,QAAM,KAAK,iBAAiB,CAAC;AAE7B,MAAI,MAAM,WAAW,GAAG;AACtB,YAAQ,KAAK,2BAA2B;AACxC,WAAO;AAAA,EACT;AAEA,UAAQ,KAAK,WAAW,IAAI,MAAM,MAAM,MAAM,QAAQ;AACtD,WAAS,KAAK,UAAU,MAAM,IAAI,CAAC,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,IAAI,EAAE,KAAK,IAAI,CAAC,EAAE;AAC9E,SAAO,MAAM,KAAK,aAAa;AACjC;",
6
6
  "names": []
7
7
  }
@@ -59,7 +59,7 @@ function killPortHolder(port) {
59
59
  }
60
60
  async function spawnLauncher(home, argv) {
61
61
  const { spawn } = await import("node:child_process");
62
- const launcher = join(home, "abtars.sh");
62
+ const launcher = join(home, "scripts", "abtars.sh");
63
63
  if (!existsSync(launcher)) {
64
64
  process.stderr.write(`Launcher not found: ${launcher}
65
65
  `);
@@ -158,4 +158,4 @@ async function restart(opts) {
158
158
  export {
159
159
  restart
160
160
  };
161
- //# sourceMappingURL=chunk-XOCP5BMO.js.map
161
+ //# sourceMappingURL=chunk-URAQLQ2U.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/cli/commands/restart.ts"],
4
+ "sourcesContent": ["/**\n * abtars restart [--cold] \u2014 unified restart command.\n * Warm (default): writeRestartRequested \u2192 main.ts internal loop restarts.\n * Cold (--cold): kill process + spawn new launcher. Always, both modes.\n */\n\nimport { logAndSwallow } from \"../../components/log-and-swallow.js\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { execSync } from \"node:child_process\";\nimport { join } from \"node:path\";\n\nfunction abtarsHome(): string {\n return process.env[\"ABTARS_HOME\"] ?? join(process.env[\"HOME\"] ?? \"\", \".abtars\");\n}\n\nfunction readJsonField(file: string, field: string): unknown {\n try {\n const data = JSON.parse(readFileSync(file, \"utf-8\"));\n return data[field];\n } catch { return undefined; }\n}\n\nfunction pidAlive(pid: number): boolean {\n try { process.kill(pid, 0); return true; } catch { return false; }\n}\n\n/** #686: Kill any process holding port 3100 before spawning a new bridge. */\nfunction killPortHolder(port: number): void {\n try {\n const pid = execSync(`lsof -ti :${port}`, { encoding: \"utf-8\", timeout: 3000 }).trim();\n if (!pid) return;\n process.stdout.write(`\uD83D\uDED1 Killing stale process on port ${port} (pid ${pid})...\\n`);\n try { execSync(`kill ${pid}`, { timeout: 3000, stdio: \"pipe\" }); } catch { /* */ }\n for (let i = 0; i < 5; i++) {\n try { execSync(`lsof -ti :${port}`, { stdio: \"pipe\", timeout: 1000 }); } catch { return; }\n try { execSync(\"sleep 1\", { timeout: 2000, stdio: \"pipe\" }); } catch { /* */ }\n }\n try { execSync(`kill -9 ${pid}`, { timeout: 1000, stdio: \"pipe\" }); } catch { /* */ }\n } catch { /* no process on port \u2014 good */ }\n}\n\nasync function spawnLauncher(home: string, argv: string[]): Promise<number> {\n const { spawn } = await import(\"node:child_process\");\n const launcher = join(home, \"scripts\", \"abtars.sh\");\n if (!existsSync(launcher)) {\n process.stderr.write(`Launcher not found: ${launcher}\\n`);\n return 1;\n }\n const child = spawn(launcher, argv, { detached: true, stdio: \"ignore\", cwd: home });\n child.unref();\n process.stdout.write(`\u267B\uFE0F Bridge starting (args: ${argv.join(\" \")})...\\n`);\n return 0;\n}\n\nasync function killBridge(pid: number): Promise<void> {\n // Verify PID is actually the bridge (Linux /proc, fallback: skip check)\n try {\n const cmdline = readFileSync(`/proc/${pid}/cmdline`, \"utf-8\");\n if (!cmdline.includes(\"abtars\") && !cmdline.includes(\"main.js\") && !cmdline.includes(\"bundle\")) {\n process.stdout.write(`\u26A0\uFE0F PID ${pid} is not abtars \u2014 stale PID file\\n`);\n return;\n }\n } catch (err) { logAndSwallow(\"restart\", \"op\", err); }\n\n try { process.kill(pid, \"SIGTERM\"); } catch { return; }\n process.stdout.write(`\uD83D\uDED1 Killing bridge (PID ${pid})...\\n`);\n\n for (let i = 0; i < 20; i++) {\n await new Promise(r => setTimeout(r, 500));\n if (!pidAlive(pid)) return;\n }\n try { process.kill(pid, \"SIGKILL\"); } catch (err) { logAndSwallow(\"restart\", \"op\", err); }\n await new Promise(r => setTimeout(r, 1000));\n}\n\nexport async function restart(opts: { cold?: boolean }): Promise<number> {\n const home = abtarsHome();\n const lockFile = join(home, \"bridge.lock\");\n const cold = opts.cold ?? false;\n\n const bridgePid = readJsonField(lockFile, \"pid\") as number | undefined;\n const bridgeAlive = bridgePid != null && bridgePid > 0 && pidAlive(bridgePid);\n\n if (cold) {\n // Under supervised-daemon, cold restart requires sudo \u2014 refuse and print instructions\n const manifestPath = join(home, \"manifest.json\");\n const installMode = readJsonField(manifestPath, \"installMode\") as string | undefined;\n if (!installMode) {\n process.stderr.write(\"\u274C installMode not set in manifest.json. Run 'abtars install' first.\\n\");\n return 1;\n }\n if (installMode === \"supervised-daemon\") {\n const platform = process.platform;\n if (platform === \"darwin\") {\n process.stderr.write(`Cold restart under supervised-daemon requires sudo:\\n sudo -k launchctl kickstart -k system/com.abtars.daemon\\n`);\n } else {\n process.stderr.write(`Cold restart under supervised-daemon requires sudo:\\n sudo -k systemctl restart abtars\\n`);\n }\n return 1;\n }\n\n // Run doctor before spawning\n const doctorPath = join(home, \"scripts\", \"doctor.sh\");\n if (existsSync(doctorPath)) {\n process.stdout.write(\"\uD83E\uDE7A Health check...\\n\");\n try {\n const { execSync } = await import(\"node:child_process\");\n execSync(`bash \"${doctorPath}\" --fix`, { stdio: \"inherit\", timeout: 30_000 });\n } catch (err) {\n process.stderr.write(`\u26A0\uFE0F doctor --fix failed: ${err instanceof Error ? err.message : String(err)}\\n`);\n }\n }\n\n if (bridgeAlive) await killBridge(bridgePid!);\n killPortHolder(3100);\n // Clear stale restart requests so the new bridge doesn't restart again (#731)\n const { updateBridgeLockField } = await import(\"../../components/transport/bridge-lock-transport.js\");\n updateBridgeLockField(\"restartRequested\", null);\n const argv: string[] = []; // #534: env is SSoT \u2014 no CLI args needed\n return spawnLauncher(home, argv);\n }\n\n // Warm restart\n if (bridgeAlive) {\n const { writeRestartRequested } = await import(\"../../components/transport/bridge-lock-transport.js\");\n writeRestartRequested(\"restart\");\n process.stdout.write(`\u267B\uFE0F Restart requested (PID ${bridgePid}) \u2014 bridge will restart within 30s\\n`);\n return 0;\n }\n\n process.stdout.write(\"Bridge not running. Use --cold to start.\\n\");\n return 1;\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["execSync"]
7
+ }
@@ -6,7 +6,7 @@ import {
6
6
  readManifest,
7
7
  resolveUserBinDir,
8
8
  writeManifest
9
- } from "./chunk-HXJRZWKA.js";
9
+ } from "./chunk-JRK3UFBS.js";
10
10
 
11
11
  // src/cli/commands/install.ts
12
12
  import { mkdir, readFile, stat, symlink, writeFile } from "node:fs/promises";
@@ -181,6 +181,18 @@ Use 'abtars update' to upgrade, or --force to re-seed missing config.
181
181
  );
182
182
  return 2;
183
183
  }
184
+ try {
185
+ const { execSync: execSync2 } = await import("node:child_process");
186
+ execSync2("systemctl is-active abtars 2>/dev/null", { stdio: "ignore" });
187
+ execSync2("sudo -n systemctl stop abtars 2>/dev/null", { stdio: "ignore" });
188
+ execSync2("sudo -n systemctl disable abtars 2>/dev/null", { stdio: "ignore" });
189
+ } catch {
190
+ }
191
+ try {
192
+ const { execSync: execSync2 } = await import("node:child_process");
193
+ execSync2("pkill -f 'watchdog.sh' 2>/dev/null", { stdio: "ignore" });
194
+ } catch {
195
+ }
184
196
  await createSkeleton(home, opts.dryRun);
185
197
  process.stdout.write(`\u2713 skeleton at ${home}
186
198
  `);
@@ -260,10 +272,10 @@ Use 'abtars update' to upgrade, or --force to re-seed missing config.
260
272
  PATH symlink conflicts:
261
273
  ${refused.join("\n ")}
262
274
  `);
263
- return 4;
264
- }
265
- process.stdout.write(`\u2713 PATH symlinks in ${userBinDir}
275
+ } else {
276
+ process.stdout.write(`\u2713 PATH symlinks in ${userBinDir}
266
277
  `);
278
+ }
267
279
  if (!isPathOnPATH(userBinDir)) {
268
280
  process.stderr.write(
269
281
  `
@@ -276,8 +288,7 @@ Warning: ${userBinDir} is not on $PATH. Add to your shell config:
276
288
  if (manifestAfter === null && !opts.dryRun) {
277
289
  await writeManifest(paths.manifest, {
278
290
  ...emptyManifest("abtars", hostname()),
279
- version: "",
280
- preMigrationBackup: null
291
+ version: ""
281
292
  });
282
293
  process.stdout.write(`\u2713 manifest initialized at ${paths.manifest}
283
294
  `);
@@ -397,4 +408,4 @@ export {
397
408
  writeWrapper,
398
409
  install
399
410
  };
400
- //# sourceMappingURL=chunk-PPSB2ZIN.js.map
411
+ //# sourceMappingURL=chunk-VREI2GUO.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/cli/commands/install.ts"],
4
+ "sourcesContent": ["/**\n * `abtars install [--force]` \u2014 first-time setup.\n *\n * - No existing ~/.abtars: create dirs, seed config/ from .env.example,\n * create PATH symlinks. Does NOT run onboard (Phase 3).\n * - Existing ~/.abtars: refuse unless --force (which\n * re-seeds missing config and reconciles symlinks, no code changes).\n */\n\nimport { mkdir, readFile, stat, symlink, writeFile } from 'node:fs/promises';\nimport { existsSync, readFileSync, readdirSync, copyFileSync, mkdirSync } from 'node:fs';\nimport { hostname, homedir as _homedir } from 'node:os';\nimport { execSync } from 'node:child_process';\nimport { basename, dirname, join } from 'node:path';\nimport { emptyManifest, packagePaths, readManifest, resolveUserBinDir, writeManifest } from '../deploy-lib-import.js';\n\n/** Resolve real user home even under sudo. */\nfunction homedir(): string {\n const sudoUser = process.env['SUDO_USER'];\n if (sudoUser) {\n try { return execSync(`getent passwd ${sudoUser}`, { encoding: 'utf-8' }).split(':')[5]!.trim(); }\n catch { /* fall through */ }\n }\n return _homedir();\n}\n\nexport interface InstallOptions {\n readonly restore?: string;\n readonly force: boolean;\n readonly dryRun: boolean;\n readonly mode?: \"simple\" | \"supervised\";\n}\n\n// CLI wrappers are read from install-manifest.json at runtime.\n// Each is a thin wrapper that invokes `node current/dist/cli/<name>.js \"$@\"`.\n// Regenerated on every install / flat-to-releases migration.\n\nasync function exists(p: string): Promise<boolean> {\n try {\n await stat(p);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * True if `p` exists as any filesystem entry \u2014 regular file, directory,\n * symlink (including dangling). Use this for collision checks in\n * reconcilePathLink, where a dangling symlink still occupies the inode\n * and would cause EEXIST on symlink(). `exists()` above uses stat() which\n * follows symlinks and returns false on dangling ones; that's wrong for\n * collision detection.\n */\nasync function existsAny(p: string): Promise<boolean> {\n try {\n const { lstat } = await import('node:fs/promises');\n await lstat(p);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function isSymlink(p: string): Promise<boolean> {\n try {\n const { lstat } = await import('node:fs/promises');\n const s = await lstat(p);\n return s.isSymbolicLink();\n } catch {\n return false;\n }\n}\n\nasync function createSkeleton(home: string, dryRun: boolean): Promise<void> {\n const { loadManifest } = await import('../install-manifest.js');\n const manifest = loadManifest();\n const dirs = manifest.directories.map(d => join(home, d.path));\n if (dryRun) {\n process.stdout.write(`[dry-run] mkdir -p:\\n ${dirs.join('\\n ')}\\n`);\n return;\n }\n for (const d of manifest.directories) {\n await mkdir(join(home, d.path), { recursive: true, mode: d.mode ? parseInt(d.mode, 8) : undefined });\n }\n}\n\nasync function seedConfig(repoRoot: string, _configDir: string, dryRun: boolean, home: string): Promise<readonly string[]> {\n const { loadManifest } = await import('../install-manifest.js');\n const manifest = loadManifest(repoRoot);\n const seeded: string[] = [];\n for (const seed of manifest.configSeeds) {\n const src = join(repoRoot, seed.source);\n const dst = join(home, seed.dest);\n if (!(await exists(src))) continue;\n if (await exists(dst)) continue;\n if (dryRun) {\n seeded.push(`[dry-run] cp ${src} ${dst}`);\n continue;\n }\n const content = await readFile(src, 'utf-8');\n await mkdir(dirname(dst), { recursive: true });\n await writeFile(dst, content, { mode: seed.mode ? parseInt(seed.mode, 8) : 0o644 });\n seeded.push(basename(dst));\n }\n return seeded;\n}\n\n/**\n * Reconcile a single PATH symlink at ~/.local/bin/<name>.\n * Policy (plan \u00A7\"PATH symlink collision\"):\n * - Missing \u2192 create\n * - Symlink pointing into our own ~/.abtars/bin/ \u2192 overwrite\n * - Anything else \u2192 refuse with message, unless force\n */\nasync function reconcilePathLink(\n binDir: string,\n userBinDir: string,\n name: string,\n force: boolean,\n dryRun: boolean,\n): Promise<{ action: string; message?: string }> {\n const linkPath = join(userBinDir, name);\n const targetPath = join(binDir, name);\n const linkExists = await existsAny(linkPath);\n if (!linkExists) {\n if (dryRun) return { action: `[dry-run] ln -s ${targetPath} ${linkPath}` };\n await symlink(targetPath, linkPath);\n return { action: `created ${linkPath}` };\n }\n if (await isSymlink(linkPath)) {\n const { readlink, unlink } = await import('node:fs/promises');\n const current = await readlink(linkPath);\n // \"We own it\" means: points at THIS install's bin dir, not a fuzzy match\n // on any path containing /.abtars/bin/. A smoke-test install at\n // ABTARS_HOME=~/.cache/ab-smoke-.../ must not clobber the real\n // ~/.abtars symlinks. Compare absolute paths directly.\n const ownsIt = current === targetPath;\n if (ownsIt) {\n if (dryRun) return { action: `[dry-run] overwrite ${linkPath} (we own it)` };\n await unlink(linkPath);\n await symlink(targetPath, linkPath);\n return { action: `updated ${linkPath}` };\n }\n if (force) {\n if (dryRun) return { action: `[dry-run] --force overwrite ${linkPath} (currently -> ${current})` };\n await unlink(linkPath);\n await symlink(targetPath, linkPath);\n return { action: `forced overwrite ${linkPath} (was -> ${current})` };\n }\n return {\n action: 'refused',\n message: `${linkPath} is a symlink to ${current} (not ours). Pass --force to overwrite.`,\n };\n }\n if (force) {\n if (dryRun) return { action: `[dry-run] --force overwrite ${linkPath} (regular file)` };\n const { unlink } = await import('node:fs/promises');\n await unlink(linkPath);\n await symlink(targetPath, linkPath);\n return { action: `forced overwrite ${linkPath} (was regular file)` };\n }\n return {\n action: 'refused',\n message: `${linkPath} exists as a regular file (not our symlink). Pass --force to overwrite.`,\n };\n}\n\nexport async function writeWrapper(binDir: string, name: string, currentLink: string, dryRun: boolean): Promise<void> {\n const bundleFile = name === 'abtars' ? 'abtars-cli.js' : `${name}.js`;\n const target = join(currentLink, 'bundle', bundleFile);\n // Fallback: pre-bundle dist/ layout (tsc build) for installs that haven't migrated yet.\n const distFile = name === 'abtars' ? 'abtars.js' : `${name}.js`;\n const fallback = join(currentLink, 'dist', 'cli', distFile);\n const content = `#!/usr/bin/env bash\nif [ -f \"${target}\" ]; then\n exec node \"${target}\" \"$@\"\nelif [ -f \"${fallback}\" ]; then\n exec node \"${fallback}\" \"$@\"\nelse\n # No local release \u2014 fall through to npm global binary\n GLOBAL_BIN=\"$(npm root -g 2>/dev/null)/abtars/bundle/${bundleFile}\"\n if [ -f \"$GLOBAL_BIN\" ]; then\n exec node \"$GLOBAL_BIN\" \"$@\"\n fi\n echo \"abtars: no release staged. Run 'abtars install' first.\" >&2\n exit 1\nfi\n`;\n const path = join(binDir, name);\n if (dryRun) {\n process.stdout.write(`[dry-run] write wrapper ${path} -> node ${target} (fallback: ${fallback})\\n`);\n return;\n }\n await writeFile(path, content, { mode: 0o755 });\n}\n\nfunction isPathOnPATH(userBinDir: string): boolean {\n const PATH = process.env['PATH'] ?? '';\n return PATH.split(':').some((p) => p === userBinDir);\n}\n\nexport async function install(opts: InstallOptions): Promise<number> {\n const paths = packagePaths('abtars');\n const home = paths.home;\n const userBinDir = resolveUserBinDir();\n const repoRoot = process.cwd();\n\n // Install log (#718)\n const { initInstallLog, logInstall, logInstallHeader } = await import(\"../install-log.js\");\n initInstallLog(home);\n logInstallHeader(\"install\");\n const _origWrite = process.stdout.write.bind(process.stdout);\n process.stdout.write = ((chunk: any, ...args: any[]) => {\n if (typeof chunk === \"string\" && (chunk.startsWith(\"\u2713\") || chunk.startsWith(\"\u26A0\"))) logInstall(chunk.trimEnd());\n return _origWrite(chunk, ...args);\n }) as typeof process.stdout.write;\n\n const homeExists = await exists(home);\n const manifest = homeExists ? await readManifest(paths.manifest) : null;\n\n if (homeExists && manifest && !opts.force && !opts.restore) {\n process.stderr.write(\n `~/.abtars already installed at version ${manifest.version || '(unset)'}.\\nUse 'abtars update' to upgrade, or --force to re-seed missing config.\\n`,\n );\n return 2;\n }\n\n // Kill stale daemon/watchdog from previous install (#771)\n try {\n const { execSync } = await import(\"node:child_process\");\n execSync(\"systemctl is-active abtars 2>/dev/null\", { stdio: \"ignore\" });\n execSync(\"sudo -n systemctl stop abtars 2>/dev/null\", { stdio: \"ignore\" });\n execSync(\"sudo -n systemctl disable abtars 2>/dev/null\", { stdio: \"ignore\" });\n } catch { /* not running or no sudo \u2014 fine */ }\n try {\n const { execSync } = await import(\"node:child_process\");\n execSync(\"pkill -f 'watchdog.sh' 2>/dev/null\", { stdio: \"ignore\" });\n } catch { /* no watchdog \u2014 fine */ }\n\n // Create skeleton (idempotent)\n await createSkeleton(home, opts.dryRun);\n process.stdout.write(`\u2713 skeleton at ${home}\\n`);\n\n // Core templates: abmind seeds its own on first boot (#427 ensureInitialized).\n // No longer seeded by abtars install.\n\n // Create kiro-cli agent config \u2014 ACP transport needs ~/.kiro/agents/professor.json\n const kiroAgentsDir = join(homedir(), '.kiro', 'agents');\n const professorJson = join(kiroAgentsDir, 'professor.json');\n if (!opts.dryRun) {\n await mkdir(kiroAgentsDir, { recursive: true });\n if (!(await exists(professorJson))) {\n await writeFile(professorJson, JSON.stringify({\n name: \"professor\",\n description: \"Abtars bridge agent\",\n tools: [\"*\"],\n allowedTools: [\"@builtin\"],\n toolsSettings: { shell: { autoAllowReadonly: true } },\n includeMcpJson: true,\n }, null, 2) + '\\n');\n process.stdout.write(`\u2713 kiro agent: ${professorJson}\\n`);\n }\n } else {\n process.stdout.write(`[dry-run] create ${professorJson}\\n`);\n }\n\n // Generate Ed25519 identity keypair (skip if already exists)\n const identityKey = join(paths.config, 'identity.key');\n const identityPub = join(paths.config, 'identity.pub');\n if (!opts.dryRun && !(await exists(identityKey))) {\n const { generateKeyPairSync } = await import('node:crypto');\n const { privateKey, publicKey } = generateKeyPairSync('ed25519');\n await writeFile(identityKey, privateKey.export({ format: 'der', type: 'pkcs8' }).toString('base64'));\n await writeFile(identityPub, publicKey.export({ format: 'der', type: 'spki' }).toString('base64'));\n const { chmodSync } = await import('node:fs');\n chmodSync(identityKey, 0o600);\n process.stdout.write(`\u2713 identity keypair generated\\n`);\n }\n\n // Generate self-signed Ed25519 TLS certificate (skip if already exists)\n const identityCrt = join(paths.config, 'identity.crt');\n const identityTlsKey = join(paths.config, 'identity.tls.key');\n if (!opts.dryRun && !(await exists(identityCrt))) {\n const { execSync } = await import('node:child_process');\n const { chmodSync } = await import('node:fs');\n const agentName = hostname();\n try {\n execSync(`openssl req -x509 -newkey ed25519 -keyout identity.tls.key -out identity.crt -days 3650 -nodes -subj \"/CN=${agentName}\"`, { cwd: paths.config, stdio: 'ignore' });\n chmodSync(identityTlsKey, 0o600);\n process.stdout.write(`\u2713 TLS certificate generated (Ed25519, 10yr)\\n`);\n } catch (err) {\n process.stderr.write(`\u26A0 TLS cert generation failed (openssl not found?). Agent-api will start without TLS.\\n`);\n }\n }\n\n // Seed config from examples (only missing ones)\n const seeded = await seedConfig(repoRoot, paths.config, opts.dryRun, home);\n if (seeded.length > 0) {\n process.stdout.write(`\u2713 seeded config: ${seeded.join(', ')}\\n`);\n }\n\n // Write wrappers (always overwrite \u2014 they're regenerable thin shims)\n const { loadManifest: loadInstallManifest } = await import('../install-manifest.js');\n const installManifest = loadInstallManifest(repoRoot);\n if (!opts.dryRun) {\n await mkdir(paths.bin, { recursive: true });\n }\n for (const name of installManifest.cliWrappers) {\n await writeWrapper(paths.bin, name, paths.current, opts.dryRun);\n }\n process.stdout.write(`\u2713 wrappers in ${paths.bin}\\n`);\n\n // Reconcile PATH symlinks\n if (!opts.dryRun) await mkdir(userBinDir, { recursive: true });\n const refused: string[] = [];\n for (const name of installManifest.cliWrappers) {\n const r = await reconcilePathLink(paths.bin, userBinDir, name, opts.force, opts.dryRun);\n if (r.action === 'refused') {\n refused.push(r.message ?? name);\n }\n }\n if (refused.length > 0) {\n process.stderr.write(`\\nPATH symlink conflicts:\\n ${refused.join('\\n ')}\\n`);\n } else {\n process.stdout.write(`\u2713 PATH symlinks in ${userBinDir}\\n`);\n }\n\n // Warn if ~/.local/bin not on PATH\n if (!isPathOnPATH(userBinDir)) {\n process.stderr.write(\n `\\nWarning: ${userBinDir} is not on $PATH. Add to your shell config:\\n export PATH=\"${userBinDir}:$PATH\"\\n`,\n );\n }\n\n // Initialize manifest if brand-new install AND migration didn't write one.\n // (Migration 003 writes a manifest mid-flow with version + migration record;\n // we must not clobber it here.)\n const manifestAfter = await readManifest(paths.manifest);\n if (manifestAfter === null && !opts.dryRun) {\n await writeManifest(paths.manifest, {\n ...emptyManifest('abtars', hostname()),\n version: '',\n });\n process.stdout.write(`\u2713 manifest initialized at ${paths.manifest}\\n`);\n }\n\n // Write install mode to manifest. Priority:\n // 1. --mode flag (explicit) \u2014 always wins\n // 2. existing manifest installMode \u2014 preserved (don't clobber on --force)\n // 3. default: supervised\n const manifestForMode = await readManifest(paths.manifest);\n const existingMode = manifestForMode?.installMode;\n const mode = opts.mode ?? existingMode ?? \"supervised\";\n if (manifestForMode) {\n await writeManifest(paths.manifest, { ...manifestForMode, installMode: mode });\n }\n process.stdout.write(`\u2713 install mode: ${mode}\\n`);\n\n // Release staging is handled by `abtars update` (auto-detects npm vs git source)\n\n // Restore from backup zip\n if (opts.restore) {\n const { spawnSync } = await import('node:child_process');\n const { existsSync: fileExists } = await import('node:fs');\n const zipPath = opts.restore;\n if (!fileExists(zipPath)) {\n process.stderr.write(`error: backup file not found: ${zipPath}\\n`);\n return 1;\n }\n // Extract to temp dir\n const tmpDir = join(process.env['TMPDIR'] ?? '/tmp', `abtars-restore-${Date.now()}`);\n const is7z = zipPath.endsWith('.7z');\n const extractCmd = is7z\n ? spawnSync('7z', ['x', zipPath, `-o${tmpDir}`, '-y'], { encoding: 'utf-8' })\n : spawnSync('unzip', ['-o', zipPath, '-d', tmpDir], { encoding: 'utf-8' });\n if (extractCmd.status !== 0) {\n process.stderr.write(`error: extract failed: ${extractCmd.stderr}\\n`);\n return 1;\n }\n // Copy abtars files \u2014 overwrite everything EXCEPT binaries (releases/, current, bin/)\n const abSrc = join(tmpDir, 'abtars');\n if (fileExists(abSrc)) {\n const skipSet = new Set(['releases', 'current', 'bin']);\n for (const f of readdirSync(abSrc)) {\n if (skipSet.has(f)) continue;\n spawnSync('cp', ['-r', join(abSrc, f), home], { stdio: 'inherit' });\n }\n process.stdout.write(`\u2713 restored abtars data\\n`);\n }\n // Copy abmind files\n const abmindHome = process.env['ABMIND_HOME'] ?? join(dirname(home), '.abmind');\n const abmindSrc = join(tmpDir, 'abmind');\n if (fileExists(abmindSrc)) {\n spawnSync('cp', ['-r', ...readdirSync(abmindSrc).map(f => join(abmindSrc, f)), abmindHome], { stdio: 'inherit' });\n process.stdout.write(`\u2713 restored abmind data\\n`);\n }\n // Cleanup + resync\n spawnSync('rm', ['-rf', tmpDir]);\n process.stdout.write(`\\n\u2713 Restore complete. Run 'abtars update' to resync.\\n`);\n return 0;\n }\n\n // --- supervised: load user-scope watchdog (LaunchAgent / systemd user) ---\n if (mode === 'supervised') {\n const { execSync } = await import('node:child_process');\n if (process.platform === 'darwin') {\n const plistSrc = join(home, 'scripts', 'com.abtars.watchdog.plist');\n const plistDst = join(homedir(), 'Library', 'LaunchAgents', 'com.abtars.watchdog.plist');\n if (existsSync(plistSrc)) {\n const content = readFileSync(plistSrc, 'utf-8').replaceAll('{{HOME}}', homedir());\n const { writeFileSync } = await import('node:fs');\n writeFileSync(plistDst, content);\n try { execSync(`launchctl load \"${plistDst}\"`, { stdio: 'ignore' }); } catch { /* already loaded */ }\n process.stdout.write(`\u2713 watchdog LaunchAgent loaded\\n`);\n }\n } else if (process.platform === 'linux') {\n const unitSrc = join(home, 'scripts', 'abtars-watchdog.service');\n const unitDir = join(homedir(), '.config', 'systemd', 'user');\n if (existsSync(unitSrc)) {\n mkdirSync(unitDir, { recursive: true });\n copyFileSync(unitSrc, join(unitDir, 'abtars-watchdog.service'));\n try { execSync('systemctl --user daemon-reload && systemctl --user enable --now abtars-watchdog', { stdio: 'ignore' }); } catch { /* may fail in chroot */ }\n process.stdout.write(`\u2713 watchdog systemd user service enabled\\n`);\n }\n }\n }\n\n process.stdout.write(`\\nInstall complete.\\n`);\n if (!manifestAfter || manifestAfter.version === '') {\n process.stdout.write(`Next: 'abtars update' to build and activate the first release.\\n`);\n } else {\n process.stdout.write(`\\n\u2500\u2500 Next steps \u2500\u2500\\n`);\n process.stdout.write(` 1. Run 'abtars onboard' to configure Telegram token + model provider\\n`);\n process.stdout.write(` 2. (Optional) Install Ollama for memory embeddings: curl -fsSL https://ollama.com/install.sh | sh\\n`);\n process.stdout.write(` 3. Start the bridge: 'abtars restart' or use the watchdog\\n\\n`);\n }\n\n const { printHealthSummary } = await import('./health-check.js');\n printHealthSummary(paths.home);\n\n // #334: Post-install healthcheck \u2014 validate operator channel exists (only on --restore)\n if (!opts.dryRun && opts.restore) {\n const { validateMinimumViability, formatValidationError } = await import('./install-validate.js');\n const validation = validateMinimumViability(paths.config);\n if (!validation.ok) {\n const invocation = `abtars install --restore ${opts.restore}`;\n process.stderr.write(\"\\n\" + formatValidationError(validation, invocation) + \"\\n\");\n return 1;\n }\n }\n\n return 0;\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["execSync"]
7
+ }
@@ -0,0 +1,135 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __bundleCreateRequire } from 'node:module'; import { fileURLToPath as __bundleFileURLToPath } from 'node:url'; import { dirname as __bundleDirname } from 'node:path'; const require = __bundleCreateRequire(import.meta.url); const __chunk_filename = __bundleFileURLToPath(import.meta.url); const __chunk_dirname = __bundleDirname(__chunk_filename);
3
+ import {
4
+ checkBrowseTasks,
5
+ deliverBrowseResult,
6
+ readPendingBrowse,
7
+ writePendingBrowse
8
+ } from "./chunk-LDKSCXGL.js";
9
+ import {
10
+ BrowserIpcServer,
11
+ BrowserManager,
12
+ BrowserTool,
13
+ DomainAllowlist
14
+ } from "./chunk-KSEIWT4T.js";
15
+ import {
16
+ getEnv,
17
+ init_env_schema
18
+ } from "./chunk-PZE3J7ER.js";
19
+ import {
20
+ init_logger,
21
+ logError,
22
+ logInfo,
23
+ logWarn
24
+ } from "./chunk-2BY6I4P5.js";
25
+ import {
26
+ abtarsHome,
27
+ init_paths
28
+ } from "./chunk-MJ6PHMOK.js";
29
+ import {
30
+ __export
31
+ } from "./chunk-7K2YZTLD.js";
32
+
33
+ // src/capabilities/browser/index.ts
34
+ var browser_exports = {};
35
+ __export(browser_exports, {
36
+ register: () => register
37
+ });
38
+ init_logger();
39
+ init_env_schema();
40
+ init_paths();
41
+ import * as net from "node:net";
42
+ import { join } from "node:path";
43
+ import { unlinkSync, mkdirSync, chmodSync } from "node:fs";
44
+ function register(api) {
45
+ const browserManager = new BrowserManager();
46
+ const allowlist = DomainAllowlist.fromEnv();
47
+ const browserTool = new BrowserTool(browserManager, allowlist);
48
+ let browserIpc = null;
49
+ const ensureBrowserIpc = async () => {
50
+ if (browserIpc || getEnv().browserDocker) return;
51
+ browserIpc = new BrowserIpcServer(browserTool);
52
+ await browserIpc.start();
53
+ logInfo("browser", `\u{1F50C} Browser IPC listening on ${browserIpc.socketPath}`);
54
+ };
55
+ const spawnSocketPath = join(abtarsHome(), "browser-socket", "browse-spawn.sock");
56
+ try {
57
+ mkdirSync(join(abtarsHome(), "browser-socket"), { recursive: true, mode: 448 });
58
+ try {
59
+ unlinkSync(spawnSocketPath);
60
+ } catch {
61
+ }
62
+ try {
63
+ chmodSync(join(abtarsHome(), "browser-socket"), 448);
64
+ } catch {
65
+ }
66
+ const spawnServer = net.createServer((conn) => {
67
+ let buf = "";
68
+ conn.on("data", (chunk) => {
69
+ buf += chunk.toString();
70
+ const nl = buf.indexOf("\n");
71
+ if (nl === -1) return;
72
+ const line = buf.slice(0, nl);
73
+ buf = buf.slice(nl + 1);
74
+ try {
75
+ const { taskId, task, prompt, chatId, threadId, timeoutMs } = JSON.parse(line);
76
+ const entry = {
77
+ taskId,
78
+ task,
79
+ chatId,
80
+ threadId,
81
+ pid: process.pid,
82
+ // bridge pid — runtime manages the actual transport
83
+ startedAt: Date.now(),
84
+ timeoutMs,
85
+ logFile: ""
86
+ // no log file — result comes from callback
87
+ };
88
+ const entries = readPendingBrowse();
89
+ entries.push(entry);
90
+ writePendingBrowse(entries);
91
+ api.runtime.spawn("browsie", prompt, {
92
+ timeoutMs,
93
+ onComplete: (_id, result) => {
94
+ deliverBrowseResult(entry, result);
95
+ const remaining = readPendingBrowse().filter((e) => e.taskId !== taskId);
96
+ writePendingBrowse(remaining);
97
+ },
98
+ onError: (_id, err) => {
99
+ logWarn("browser", `Browsie spawn failed for ${taskId}: ${err.message}`);
100
+ deliverBrowseResult(entry, `Browse task failed: ${err.message}`);
101
+ const remaining = readPendingBrowse().filter((e) => e.taskId !== taskId);
102
+ writePendingBrowse(remaining);
103
+ }
104
+ }).then(({ taskId: spawnId }) => {
105
+ conn.write(JSON.stringify({ ok: true, taskId, spawnId, status: "spawned" }) + "\n");
106
+ }).catch((err) => {
107
+ conn.write(JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }) + "\n");
108
+ });
109
+ } catch (err) {
110
+ conn.write(JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }) + "\n");
111
+ }
112
+ });
113
+ conn.on("error", () => {
114
+ });
115
+ });
116
+ spawnServer.listen(spawnSocketPath, () => {
117
+ logInfo("browser", `\u{1F50C} Browse spawn IPC listening on ${spawnSocketPath}`);
118
+ });
119
+ } catch (err) {
120
+ logError("browser", `\u26A0\uFE0F Browse-spawn IPC failed \u2014 browser disabled: ${err instanceof Error ? err.message : String(err)}`);
121
+ }
122
+ api.registerHeartbeatTask({
123
+ name: "browse-checker",
124
+ execute: async () => {
125
+ await ensureBrowserIpc();
126
+ checkBrowseTasks();
127
+ }
128
+ });
129
+ }
130
+
131
+ export {
132
+ register,
133
+ browser_exports
134
+ };
135
+ //# sourceMappingURL=chunk-VYR25H37.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/capabilities/browser/index.ts"],
4
+ "sourcesContent": ["import { logInfo, logWarn, logError } from \"../../components/logger.js\";\nimport { getEnv } from \"../../components/env-schema.js\";\n/**\n * Browser capability \u2014 browse-spawn IPC + browse-checker heartbeat.\n * Level 1 (lightpanda fetch) is handled by the agent via skill \u2014 no bridge code needed.\n * Level 2 (Browsie) uses runtime.spawn() via IPC socket.\n */\n\nimport { BrowserManager } from \"./browser-manager.js\";\nimport { BrowserTool } from \"./browser-tool.js\";\nimport { BrowserIpcServer } from \"./browser-ipc-server.js\";\nimport { DomainAllowlist } from \"./domain-allowlist.js\";\nimport { checkBrowseTasks, deliverBrowseResult } from \"./browse-delivery.js\";\nimport { readPendingBrowse, writePendingBrowse } from \"./abtars-browse.js\";\nimport type { PendingBrowseEntry } from \"./abtars-browse.js\";\nimport { abtarsHome } from \"../../paths.js\";\nimport type { CapabilityApi } from \"../capability.js\";\nimport * as net from \"node:net\";\nimport { join } from \"node:path\";\nimport { unlinkSync, mkdirSync, chmodSync } from \"node:fs\";\n\nexport function register(api: CapabilityApi): void {\n const browserManager = new BrowserManager();\n const allowlist = DomainAllowlist.fromEnv();\n const browserTool = new BrowserTool(browserManager, allowlist);\n let browserIpc: BrowserIpcServer | null = null;\n\n const ensureBrowserIpc = async (): Promise<void> => {\n if (browserIpc || getEnv().browserDocker) return;\n browserIpc = new BrowserIpcServer(browserTool);\n await browserIpc.start();\n logInfo(\"browser\", `\uD83D\uDD0C Browser IPC listening on ${browserIpc.socketPath}`);\n };\n\n // Browse-spawn IPC \u2014 CLI sends task, bridge spawns via runtime\n const spawnSocketPath = join(abtarsHome(), \"browser-socket\", \"browse-spawn.sock\");\n try {\n mkdirSync(join(abtarsHome(), \"browser-socket\"), { recursive: true, mode: 0o700 });\n try { unlinkSync(spawnSocketPath); } catch { /* doesn't exist \u2014 fine */ }\n try { chmodSync(join(abtarsHome(), \"browser-socket\"), 0o700); } catch { /* best effort */ }\n\n const spawnServer = net.createServer((conn) => {\n let buf = \"\";\n conn.on(\"data\", (chunk) => {\n buf += chunk.toString();\n const nl = buf.indexOf(\"\\n\");\n if (nl === -1) return;\n const line = buf.slice(0, nl);\n buf = buf.slice(nl + 1);\n\n try {\n const { taskId, task, prompt, chatId, threadId, timeoutMs } = JSON.parse(line);\n\n const entry: PendingBrowseEntry = {\n taskId, task, chatId, threadId,\n pid: process.pid, // bridge pid \u2014 runtime manages the actual transport\n startedAt: Date.now(), timeoutMs,\n logFile: \"\", // no log file \u2014 result comes from callback\n };\n const entries = readPendingBrowse();\n entries.push(entry);\n writePendingBrowse(entries);\n\n // Fire-and-forget via runtime\n api.runtime.spawn(\"browsie\", prompt, {\n timeoutMs,\n onComplete: (_id: string, result: string) => {\n deliverBrowseResult(entry, result);\n const remaining = readPendingBrowse().filter(e => e.taskId !== taskId);\n writePendingBrowse(remaining);\n },\n onError: (_id: string, err: Error) => {\n logWarn(\"browser\", `Browsie spawn failed for ${taskId}: ${err.message}`);\n deliverBrowseResult(entry, `Browse task failed: ${err.message}`);\n const remaining = readPendingBrowse().filter(e => e.taskId !== taskId);\n writePendingBrowse(remaining);\n },\n }).then(({ taskId: spawnId }) => {\n conn.write(JSON.stringify({ ok: true, taskId, spawnId, status: \"spawned\" }) + \"\\n\");\n }).catch((err) => {\n conn.write(JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }) + \"\\n\");\n });\n } catch (err) {\n conn.write(JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }) + \"\\n\");\n }\n });\n conn.on(\"error\", () => {});\n });\n\n spawnServer.listen(spawnSocketPath, () => {\n logInfo(\"browser\", `\uD83D\uDD0C Browse spawn IPC listening on ${spawnSocketPath}`);\n });\n } catch (err) {\n logError(\"browser\", `\u26A0\uFE0F Browse-spawn IPC failed \u2014 browser disabled: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n api.registerHeartbeatTask({\n name: \"browse-checker\",\n execute: async () => { await ensureBrowserIpc(); checkBrowseTasks(); },\n });\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAcA;AAEA,YAAY,SAAS;AACrB,SAAS,YAAY;AACrB,SAAS,YAAY,WAAW,iBAAiB;AAE1C,SAAS,SAAS,KAA0B;AACjD,QAAM,iBAAiB,IAAI,eAAe;AAC1C,QAAM,YAAY,gBAAgB,QAAQ;AAC1C,QAAM,cAAc,IAAI,YAAY,gBAAgB,SAAS;AAC7D,MAAI,aAAsC;AAE1C,QAAM,mBAAmB,YAA2B;AAClD,QAAI,cAAc,OAAO,EAAE,cAAe;AAC1C,iBAAa,IAAI,iBAAiB,WAAW;AAC7C,UAAM,WAAW,MAAM;AACvB,YAAQ,WAAW,sCAA+B,WAAW,UAAU,EAAE;AAAA,EAC3E;AAGA,QAAM,kBAAkB,KAAK,WAAW,GAAG,kBAAkB,mBAAmB;AAChF,MAAI;AACF,cAAU,KAAK,WAAW,GAAG,gBAAgB,GAAG,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AAChF,QAAI;AAAE,iBAAW,eAAe;AAAA,IAAG,QAAQ;AAAA,IAA6B;AACxE,QAAI;AAAE,gBAAU,KAAK,WAAW,GAAG,gBAAgB,GAAG,GAAK;AAAA,IAAG,QAAQ;AAAA,IAAoB;AAE5F,UAAM,cAAkB,iBAAa,CAAC,SAAS;AAC7C,UAAI,MAAM;AACV,WAAK,GAAG,QAAQ,CAAC,UAAU;AACzB,eAAO,MAAM,SAAS;AACtB,cAAM,KAAK,IAAI,QAAQ,IAAI;AAC3B,YAAI,OAAO,GAAI;AACf,cAAM,OAAO,IAAI,MAAM,GAAG,EAAE;AAC5B,cAAM,IAAI,MAAM,KAAK,CAAC;AAEtB,YAAI;AACF,gBAAM,EAAE,QAAQ,MAAM,QAAQ,QAAQ,UAAU,UAAU,IAAI,KAAK,MAAM,IAAI;AAE7E,gBAAM,QAA4B;AAAA,YAChC;AAAA,YAAQ;AAAA,YAAM;AAAA,YAAQ;AAAA,YACtB,KAAK,QAAQ;AAAA;AAAA,YACb,WAAW,KAAK,IAAI;AAAA,YAAG;AAAA,YACvB,SAAS;AAAA;AAAA,UACX;AACA,gBAAM,UAAU,kBAAkB;AAClC,kBAAQ,KAAK,KAAK;AAClB,6BAAmB,OAAO;AAG1B,cAAI,QAAQ,MAAM,WAAW,QAAQ;AAAA,YACnC;AAAA,YACA,YAAY,CAAC,KAAa,WAAmB;AAC3C,kCAAoB,OAAO,MAAM;AACjC,oBAAM,YAAY,kBAAkB,EAAE,OAAO,OAAK,EAAE,WAAW,MAAM;AACrE,iCAAmB,SAAS;AAAA,YAC9B;AAAA,YACA,SAAS,CAAC,KAAa,QAAe;AACpC,sBAAQ,WAAW,4BAA4B,MAAM,KAAK,IAAI,OAAO,EAAE;AACvE,kCAAoB,OAAO,uBAAuB,IAAI,OAAO,EAAE;AAC/D,oBAAM,YAAY,kBAAkB,EAAE,OAAO,OAAK,EAAE,WAAW,MAAM;AACrE,iCAAmB,SAAS;AAAA,YAC9B;AAAA,UACF,CAAC,EAAE,KAAK,CAAC,EAAE,QAAQ,QAAQ,MAAM;AAC/B,iBAAK,MAAM,KAAK,UAAU,EAAE,IAAI,MAAM,QAAQ,SAAS,QAAQ,UAAU,CAAC,IAAI,IAAI;AAAA,UACpF,CAAC,EAAE,MAAM,CAAC,QAAQ;AAChB,iBAAK,MAAM,KAAK,UAAU,EAAE,IAAI,OAAO,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EAAE,CAAC,IAAI,IAAI;AAAA,UAC1G,CAAC;AAAA,QACH,SAAS,KAAK;AACZ,eAAK,MAAM,KAAK,UAAU,EAAE,IAAI,OAAO,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EAAE,CAAC,IAAI,IAAI;AAAA,QAC1G;AAAA,MACF,CAAC;AACD,WAAK,GAAG,SAAS,MAAM;AAAA,MAAC,CAAC;AAAA,IAC3B,CAAC;AAED,gBAAY,OAAO,iBAAiB,MAAM;AACxC,cAAQ,WAAW,2CAAoC,eAAe,EAAE;AAAA,IAC1E,CAAC;AAAA,EACD,SAAS,KAAK;AACZ,aAAS,WAAW,iEAAkD,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,EAC1H;AAEA,MAAI,sBAAsB;AAAA,IACxB,MAAM;AAAA,IACN,SAAS,YAAY;AAAE,YAAM,iBAAiB;AAAG,uBAAiB;AAAA,IAAG;AAAA,EACvE,CAAC;AACH;",
6
+ "names": []
7
+ }
@@ -6,17 +6,17 @@ import {
6
6
  registerCommand,
7
7
  triggerNewSession,
8
8
  triggerResetSession
9
- } from "./chunk-WUTCGJDZ.js";
9
+ } from "./chunk-HZRUBJ4Q.js";
10
10
  import "./chunk-NIRYBWUW.js";
11
11
  import "./chunk-3MO2MDXJ.js";
12
12
  import "./chunk-RV54J75Q.js";
13
- import "./chunk-KFENC7BM.js";
14
- import "./chunk-OZ4IZFV4.js";
13
+ import "./chunk-4YOTNYAE.js";
14
+ import "./chunk-Q7F5R2LL.js";
15
15
  import "./chunk-GBBTK6H2.js";
16
16
  import "./chunk-JAJ3DUQ2.js";
17
17
  import "./chunk-G6IXMYIO.js";
18
18
  import "./chunk-UDZIZB5F.js";
19
- import "./chunk-XLLSPBBT.js";
19
+ import "./chunk-GPL57SRN.js";
20
20
  import "./chunk-MZWMYN4O.js";
21
21
  import "./chunk-EX2SRTUE.js";
22
22
  import "./chunk-PZE3J7ER.js";
@@ -30,4 +30,4 @@ export {
30
30
  triggerNewSession,
31
31
  triggerResetSession
32
32
  };
33
- //# sourceMappingURL=commands-E3Y4QUNF.js.map
33
+ //# sourceMappingURL=commands-J6JAZ7D2.js.map
@@ -2,49 +2,51 @@
2
2
  import { createRequire as __bundleCreateRequire } from 'node:module'; import { fileURLToPath as __bundleFileURLToPath } from 'node:url'; import { dirname as __bundleDirname } from 'node:path'; const require = __bundleCreateRequire(import.meta.url); const __chunk_filename = __bundleFileURLToPath(import.meta.url); const __chunk_dirname = __bundleDirname(__chunk_filename);
3
3
  import {
4
4
  LockHeldError,
5
- RETENTION,
6
5
  acquireLock,
7
- activate,
6
+ atomicSwap,
7
+ cleanStaleStaging,
8
+ clearSentinel,
9
+ configSnapshot,
8
10
  emptyManifest,
9
11
  hashFile,
12
+ healthProbe,
10
13
  inspectLock,
11
14
  isUnsafeRemovalTarget,
12
- listReleases,
13
15
  packagePaths,
14
16
  planRemoval,
15
- pruneReleases,
16
- readCurrent,
17
17
  readManifest,
18
- releaseExists,
18
+ readSentinel,
19
19
  removePath,
20
20
  resolveAbmindHome,
21
21
  resolveAbtarsHome,
22
22
  resolveUserBinDir,
23
23
  safeCopyTree,
24
- writeManifest
25
- } from "./chunk-HXJRZWKA.js";
24
+ writeManifest,
25
+ writeSentinel
26
+ } from "./chunk-JRK3UFBS.js";
26
27
  import "./chunk-7K2YZTLD.js";
27
28
  export {
28
29
  LockHeldError,
29
- RETENTION,
30
30
  acquireLock,
31
- activate,
31
+ atomicSwap,
32
+ cleanStaleStaging,
33
+ clearSentinel,
34
+ configSnapshot,
32
35
  emptyManifest,
33
36
  hashFile,
37
+ healthProbe,
34
38
  inspectLock,
35
39
  isUnsafeRemovalTarget,
36
- listReleases,
37
40
  packagePaths,
38
41
  planRemoval,
39
- pruneReleases,
40
- readCurrent,
41
42
  readManifest,
42
- releaseExists,
43
+ readSentinel,
43
44
  removePath,
44
45
  resolveAbmindHome,
45
46
  resolveAbtarsHome,
46
47
  resolveUserBinDir,
47
48
  safeCopyTree,
48
- writeManifest
49
+ writeManifest,
50
+ writeSentinel
49
51
  };
50
- //# sourceMappingURL=deploy-lib-import-ODLDL2DB.js.map
52
+ //# sourceMappingURL=deploy-lib-import-PJXUADPS.js.map