aibroker 0.2.6 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +164 -4
- package/dist/adapters/iterm/core.d.ts +2 -0
- package/dist/adapters/iterm/core.d.ts.map +1 -1
- package/dist/adapters/iterm/core.js +13 -5
- package/dist/adapters/iterm/core.js.map +1 -1
- package/dist/adapters/kokoro/media.d.ts +2 -1
- package/dist/adapters/kokoro/media.d.ts.map +1 -1
- package/dist/adapters/kokoro/media.js +51 -3
- package/dist/adapters/kokoro/media.js.map +1 -1
- package/dist/adapters/pailot/gateway.d.ts +49 -0
- package/dist/adapters/pailot/gateway.d.ts.map +1 -0
- package/dist/adapters/pailot/gateway.js +502 -0
- package/dist/adapters/pailot/gateway.js.map +1 -0
- package/dist/backend/api.d.ts +5 -1
- package/dist/backend/api.d.ts.map +1 -1
- package/dist/backend/api.js +74 -3
- package/dist/backend/api.js.map +1 -1
- package/dist/core/hybrid.d.ts +5 -0
- package/dist/core/hybrid.d.ts.map +1 -1
- package/dist/core/hybrid.js +25 -0
- package/dist/core/hybrid.js.map +1 -1
- package/dist/core/state.d.ts +3 -0
- package/dist/core/state.d.ts.map +1 -1
- package/dist/core/state.js +4 -0
- package/dist/core/state.js.map +1 -1
- package/dist/daemon/adapter-registry.d.ts +58 -0
- package/dist/daemon/adapter-registry.d.ts.map +1 -0
- package/dist/daemon/adapter-registry.js +179 -0
- package/dist/daemon/adapter-registry.js.map +1 -0
- package/dist/daemon/cli.d.ts +13 -0
- package/dist/daemon/cli.d.ts.map +1 -0
- package/dist/daemon/cli.js +58 -0
- package/dist/daemon/cli.js.map +1 -0
- package/dist/daemon/core-handlers.d.ts +24 -0
- package/dist/daemon/core-handlers.d.ts.map +1 -0
- package/dist/daemon/core-handlers.js +146 -0
- package/dist/daemon/core-handlers.js.map +1 -0
- package/dist/daemon/create-adapter.d.ts +22 -0
- package/dist/daemon/create-adapter.d.ts.map +1 -0
- package/dist/daemon/create-adapter.js +152 -0
- package/dist/daemon/create-adapter.js.map +1 -0
- package/dist/daemon/index.d.ts +12 -0
- package/dist/daemon/index.d.ts.map +1 -0
- package/dist/daemon/index.js +83 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/daemon/pai-projects.d.ts +68 -0
- package/dist/daemon/pai-projects.d.ts.map +1 -0
- package/dist/daemon/pai-projects.js +174 -0
- package/dist/daemon/pai-projects.js.map +1 -0
- package/dist/index.d.ts +11 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/ipc/client.d.ts +4 -1
- package/dist/ipc/client.d.ts.map +1 -1
- package/dist/ipc/client.js +10 -1
- package/dist/ipc/client.js.map +1 -1
- package/dist/types/adapter.d.ts +41 -0
- package/dist/types/adapter.d.ts.map +1 -0
- package/dist/types/adapter.js +2 -0
- package/dist/types/adapter.js.map +1 -0
- package/dist/types/backend.d.ts +29 -1
- package/dist/types/backend.d.ts.map +1 -1
- package/dist/types/broker.d.ts +45 -0
- package/dist/types/broker.d.ts.map +1 -0
- package/dist/types/broker.js +21 -0
- package/dist/types/broker.js.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -1
- package/package.json +9 -2
- package/templates/adapter/ONBOARDING_PROMPT.md +287 -0
- package/templates/adapter/README.md.tmpl +98 -0
- package/templates/adapter/package.json.tmpl +23 -0
- package/templates/adapter/src/watcher/cli.ts.tmpl +12 -0
- package/templates/adapter/src/watcher/commands.ts.tmpl +146 -0
- package/templates/adapter/src/watcher/connection.ts.tmpl +59 -0
- package/templates/adapter/src/watcher/index.ts.tmpl +177 -0
- package/templates/adapter/src/watcher/ipc-server.ts.tmpl +226 -0
- package/templates/adapter/src/watcher/send.ts.tmpl +62 -0
- package/templates/adapter/src/watcher/state.ts.tmpl +39 -0
- package/templates/adapter/tsconfig.json.tmpl +14 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* daemon/core-handlers.ts — Hub-level IPC handlers.
|
|
3
|
+
*
|
|
4
|
+
* Registers the core methods that any adapter or MCP client can call
|
|
5
|
+
* on the hub socket. Transport-specific methods (send, contacts, history)
|
|
6
|
+
* are NOT registered here — adapters handle those on their own sockets.
|
|
7
|
+
*
|
|
8
|
+
* Phase 1 methods:
|
|
9
|
+
* register_adapter — adapter announces itself to the hub
|
|
10
|
+
* unregister_adapter
|
|
11
|
+
* adapter_list — list connected adapters
|
|
12
|
+
* sessions — list hybrid sessions
|
|
13
|
+
* switch — switch active session
|
|
14
|
+
* end_session — end a hybrid session
|
|
15
|
+
* broadcast_status — push status to all PAILot clients
|
|
16
|
+
* voice_config — get/set TTS config
|
|
17
|
+
* status — hub health/connection summary
|
|
18
|
+
*/
|
|
19
|
+
import { broadcastStatus } from "../adapters/pailot/gateway.js";
|
|
20
|
+
import { saveVoiceConfig } from "../core/persistence.js";
|
|
21
|
+
import { voiceConfig, setVoiceConfig } from "../core/state.js";
|
|
22
|
+
import { listPaiProjects, findPaiProject, launchPaiProject } from "./pai-projects.js";
|
|
23
|
+
export function registerCoreHandlers(server, registry, _apiBackend, manager) {
|
|
24
|
+
server.on("register_adapter", async (req) => {
|
|
25
|
+
const { name, socketPath } = req.params;
|
|
26
|
+
if (!name || !socketPath)
|
|
27
|
+
return { ok: false, error: "name and socketPath required" };
|
|
28
|
+
registry.register({ name, socketPath, registeredAt: Date.now() });
|
|
29
|
+
return { ok: true, result: { registered: true } };
|
|
30
|
+
});
|
|
31
|
+
server.on("unregister_adapter", async (req) => {
|
|
32
|
+
const { name } = req.params;
|
|
33
|
+
registry.unregister(name);
|
|
34
|
+
return { ok: true, result: { unregistered: true } };
|
|
35
|
+
});
|
|
36
|
+
server.on("adapter_list", async (_req) => {
|
|
37
|
+
return { ok: true, result: { adapters: registry.list() } };
|
|
38
|
+
});
|
|
39
|
+
server.on("sessions", async (_req) => {
|
|
40
|
+
const sessions = manager.listSessions().map((s, i) => ({
|
|
41
|
+
index: i + 1,
|
|
42
|
+
name: s.name,
|
|
43
|
+
kind: s.kind,
|
|
44
|
+
active: manager.activeSession?.id === s.id,
|
|
45
|
+
}));
|
|
46
|
+
return { ok: true, result: { sessions } };
|
|
47
|
+
});
|
|
48
|
+
server.on("switch", async (req) => {
|
|
49
|
+
const { target } = req.params;
|
|
50
|
+
const index = typeof target === "number" ? target : parseInt(String(target), 10);
|
|
51
|
+
const session = manager.switchToIndex(index);
|
|
52
|
+
if (!session)
|
|
53
|
+
return { ok: false, error: `Session ${target} not found` };
|
|
54
|
+
return { ok: true, result: { switched: true, name: session.name } };
|
|
55
|
+
});
|
|
56
|
+
server.on("end_session", async (req) => {
|
|
57
|
+
const { target } = req.params;
|
|
58
|
+
const index = typeof target === "number" ? target : parseInt(String(target), 10);
|
|
59
|
+
const session = manager.removeByIndex(index);
|
|
60
|
+
if (!session)
|
|
61
|
+
return { ok: false, error: `Session ${target} not found` };
|
|
62
|
+
return { ok: true, result: { ended: true, name: session.name } };
|
|
63
|
+
});
|
|
64
|
+
server.on("broadcast_status", async (req) => {
|
|
65
|
+
const { status } = req.params;
|
|
66
|
+
broadcastStatus(status);
|
|
67
|
+
return { ok: true, result: { status } };
|
|
68
|
+
});
|
|
69
|
+
server.on("voice_config", async (req) => {
|
|
70
|
+
const { action, ...updates } = req.params;
|
|
71
|
+
if (action === "get") {
|
|
72
|
+
return { ok: true, result: { config: voiceConfig } };
|
|
73
|
+
}
|
|
74
|
+
const merged = { ...voiceConfig, ...updates };
|
|
75
|
+
setVoiceConfig(merged);
|
|
76
|
+
saveVoiceConfig(merged);
|
|
77
|
+
return { ok: true, result: { success: true, config: merged } };
|
|
78
|
+
});
|
|
79
|
+
server.on("status", async (_req) => {
|
|
80
|
+
const adapterHealth = {};
|
|
81
|
+
for (const [name, health] of registry.getAllHealth()) {
|
|
82
|
+
adapterHealth[name] = health;
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
ok: true,
|
|
86
|
+
result: {
|
|
87
|
+
version: "1.0.0",
|
|
88
|
+
adapters: registry.list().map(a => a.name),
|
|
89
|
+
activeSessions: manager.listSessions().length,
|
|
90
|
+
activeSession: manager.activeSession?.name ?? null,
|
|
91
|
+
adapterHealth,
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
});
|
|
95
|
+
// ── PAI Named Sessions ──
|
|
96
|
+
server.on("pai_projects", async (_req) => {
|
|
97
|
+
const projects = await listPaiProjects();
|
|
98
|
+
return { ok: true, result: { projects } };
|
|
99
|
+
});
|
|
100
|
+
server.on("pai_find", async (req) => {
|
|
101
|
+
const { name } = req.params;
|
|
102
|
+
if (!name)
|
|
103
|
+
return { ok: false, error: "name is required" };
|
|
104
|
+
const project = await findPaiProject(name);
|
|
105
|
+
if (!project)
|
|
106
|
+
return { ok: false, error: `Project "${name}" not found` };
|
|
107
|
+
return { ok: true, result: { project } };
|
|
108
|
+
});
|
|
109
|
+
server.on("pai_launch", async (req) => {
|
|
110
|
+
const { name } = req.params;
|
|
111
|
+
if (!name)
|
|
112
|
+
return { ok: false, error: "name is required" };
|
|
113
|
+
let itermSessionId;
|
|
114
|
+
let sessionId;
|
|
115
|
+
try {
|
|
116
|
+
({ itermSessionId, sessionId } = await launchPaiProject(name));
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
120
|
+
}
|
|
121
|
+
// Register the visual session with HybridSessionManager
|
|
122
|
+
const project = await findPaiProject(name);
|
|
123
|
+
const displayName = project?.displayName || project?.name || name;
|
|
124
|
+
manager.registerVisualSession(displayName, project?.rootPath ?? "", itermSessionId);
|
|
125
|
+
return { ok: true, result: { itermSessionId, sessionId, name } };
|
|
126
|
+
});
|
|
127
|
+
// ── Phase 2: Message Routing ──
|
|
128
|
+
/**
|
|
129
|
+
* route_message — Adapters send messages to the hub for routing.
|
|
130
|
+
*
|
|
131
|
+
* The hub inspects the BrokerMessage target and type, then delivers
|
|
132
|
+
* to the appropriate adapter via its IPC socket ("deliver" method).
|
|
133
|
+
*/
|
|
134
|
+
server.on("route_message", async (req) => {
|
|
135
|
+
const { message } = req.params;
|
|
136
|
+
if (!message || !message.source || !message.type) {
|
|
137
|
+
return { ok: false, error: "Invalid BrokerMessage: source and type are required" };
|
|
138
|
+
}
|
|
139
|
+
const result = await registry.route(message);
|
|
140
|
+
if (result.ok) {
|
|
141
|
+
return { ok: true, result: result };
|
|
142
|
+
}
|
|
143
|
+
return { ok: false, error: result.error ?? "Routing failed" };
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=core-handlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core-handlers.js","sourceRoot":"","sources":["../../src/daemon/core-handlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* daemon/create-adapter.ts — Adapter scaffold generator.
|
|
3
|
+
*
|
|
4
|
+
* Copies the templates/adapter/ directory to an output location, replacing
|
|
5
|
+
* {{ADAPTER_NAME}} and {{DISPLAY_NAME}} placeholders and stripping .tmpl
|
|
6
|
+
* extensions.
|
|
7
|
+
*
|
|
8
|
+
* Template source resolution order:
|
|
9
|
+
* 1. Alongside the running dist/daemon/cli.js → ../../templates/adapter/
|
|
10
|
+
* (works for: npm link, local dev, global install via npm pack)
|
|
11
|
+
* 2. Alongside package root (fallback for non-standard setups)
|
|
12
|
+
*/
|
|
13
|
+
export interface CreateAdapterOptions {
|
|
14
|
+
adapterName: string;
|
|
15
|
+
displayName?: string;
|
|
16
|
+
outputDir?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Scaffold a new adapter from the built-in template.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createAdapter(options: CreateAdapterOptions): Promise<void>;
|
|
22
|
+
//# sourceMappingURL=create-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-adapter.d.ts","sourceRoot":"","sources":["../../src/daemon/create-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAUH,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4DhF"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* daemon/create-adapter.ts — Adapter scaffold generator.
|
|
3
|
+
*
|
|
4
|
+
* Copies the templates/adapter/ directory to an output location, replacing
|
|
5
|
+
* {{ADAPTER_NAME}} and {{DISPLAY_NAME}} placeholders and stripping .tmpl
|
|
6
|
+
* extensions.
|
|
7
|
+
*
|
|
8
|
+
* Template source resolution order:
|
|
9
|
+
* 1. Alongside the running dist/daemon/cli.js → ../../templates/adapter/
|
|
10
|
+
* (works for: npm link, local dev, global install via npm pack)
|
|
11
|
+
* 2. Alongside package root (fallback for non-standard setups)
|
|
12
|
+
*/
|
|
13
|
+
import { readFileSync, writeFileSync, mkdirSync, readdirSync, statSync } from "node:fs";
|
|
14
|
+
import { join, dirname, relative, resolve } from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
import { homedir } from "node:os";
|
|
17
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
18
|
+
const __dirname = dirname(__filename);
|
|
19
|
+
/**
|
|
20
|
+
* Scaffold a new adapter from the built-in template.
|
|
21
|
+
*/
|
|
22
|
+
export async function createAdapter(options) {
|
|
23
|
+
const { adapterName } = options;
|
|
24
|
+
// Derive display name from adapter name if not provided
|
|
25
|
+
// "my-signal" -> "My Signal"
|
|
26
|
+
const displayName = options.displayName
|
|
27
|
+
?? adapterName
|
|
28
|
+
.split("-")
|
|
29
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
30
|
+
.join(" ");
|
|
31
|
+
// Resolve output directory
|
|
32
|
+
const outputDir = options.outputDir
|
|
33
|
+
? resolvePath(options.outputDir)
|
|
34
|
+
: resolve(process.cwd(), adapterName);
|
|
35
|
+
// Locate template directory
|
|
36
|
+
const templateDir = findTemplateDir();
|
|
37
|
+
if (!templateDir) {
|
|
38
|
+
console.error("Error: Could not find the templates/adapter/ directory.");
|
|
39
|
+
console.error("This is a bug in the aibroker package. Please report it.");
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
console.log(`Creating adapter "${adapterName}" (display name: "${displayName}")`);
|
|
43
|
+
console.log(` Template: ${templateDir}`);
|
|
44
|
+
console.log(` Output: ${outputDir}`);
|
|
45
|
+
console.log();
|
|
46
|
+
// Collect all template files
|
|
47
|
+
const templateFiles = walkDir(templateDir);
|
|
48
|
+
// Process each file
|
|
49
|
+
for (const absTemplatePath of templateFiles) {
|
|
50
|
+
const relPath = relative(templateDir, absTemplatePath);
|
|
51
|
+
// Strip .tmpl extension for the output path, but also apply name substitution
|
|
52
|
+
// to the path itself (no placeholders in paths currently, but future-safe)
|
|
53
|
+
const relOutputPath = relPath
|
|
54
|
+
.replace(/\.tmpl$/, "")
|
|
55
|
+
.replace(/\{\{ADAPTER_NAME\}\}/g, adapterName)
|
|
56
|
+
.replace(/\{\{DISPLAY_NAME\}\}/g, displayName);
|
|
57
|
+
const outputPath = join(outputDir, relOutputPath);
|
|
58
|
+
// Read, substitute, write
|
|
59
|
+
const raw = readFileSync(absTemplatePath, "utf8");
|
|
60
|
+
const processed = raw
|
|
61
|
+
.replace(/\{\{ADAPTER_NAME\}\}/g, adapterName)
|
|
62
|
+
.replace(/\{\{DISPLAY_NAME\}\}/g, displayName);
|
|
63
|
+
// Ensure parent directory exists
|
|
64
|
+
mkdirSync(dirname(outputPath), { recursive: true });
|
|
65
|
+
writeFileSync(outputPath, processed, "utf8");
|
|
66
|
+
console.log(` + ${relOutputPath}`);
|
|
67
|
+
}
|
|
68
|
+
console.log();
|
|
69
|
+
printNextSteps(adapterName, displayName, outputDir);
|
|
70
|
+
}
|
|
71
|
+
// ── Template directory resolution ─────────────────────────────────────────────
|
|
72
|
+
/**
|
|
73
|
+
* Find the templates/adapter/ directory relative to the running script.
|
|
74
|
+
*
|
|
75
|
+
* The compiled CLI lives at dist/daemon/cli.js.
|
|
76
|
+
* The templates live at templates/adapter/ (two levels up from dist/daemon/).
|
|
77
|
+
*
|
|
78
|
+
* For a globally installed npm package the layout is:
|
|
79
|
+
* node_modules/aibroker/dist/daemon/cli.js
|
|
80
|
+
* node_modules/aibroker/templates/adapter/
|
|
81
|
+
*
|
|
82
|
+
* This function walks up from __dirname until it finds the templates/ dir.
|
|
83
|
+
*/
|
|
84
|
+
function findTemplateDir() {
|
|
85
|
+
// Walk up from __dirname to find a directory containing templates/adapter/
|
|
86
|
+
let dir = __dirname;
|
|
87
|
+
for (let i = 0; i < 6; i++) {
|
|
88
|
+
const candidate = join(dir, "templates", "adapter");
|
|
89
|
+
try {
|
|
90
|
+
const stat = statSync(candidate);
|
|
91
|
+
if (stat.isDirectory())
|
|
92
|
+
return candidate;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
// Not found at this level, keep walking up
|
|
96
|
+
}
|
|
97
|
+
const parent = dirname(dir);
|
|
98
|
+
if (parent === dir)
|
|
99
|
+
break; // filesystem root
|
|
100
|
+
dir = parent;
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
// ── Utilities ─────────────────────────────────────────────────────────────────
|
|
105
|
+
/**
|
|
106
|
+
* Recursively collect all file paths within a directory.
|
|
107
|
+
*/
|
|
108
|
+
function walkDir(dir) {
|
|
109
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
110
|
+
const files = [];
|
|
111
|
+
for (const entry of entries) {
|
|
112
|
+
const full = join(dir, entry.name);
|
|
113
|
+
if (entry.isDirectory()) {
|
|
114
|
+
files.push(...walkDir(full));
|
|
115
|
+
}
|
|
116
|
+
else if (entry.isFile()) {
|
|
117
|
+
files.push(full);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return files;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Resolve a path that may start with ~ (home directory).
|
|
124
|
+
*/
|
|
125
|
+
function resolvePath(p) {
|
|
126
|
+
if (p.startsWith("~/") || p === "~") {
|
|
127
|
+
return join(homedir(), p.slice(2));
|
|
128
|
+
}
|
|
129
|
+
return resolve(p);
|
|
130
|
+
}
|
|
131
|
+
// ── Next-steps instructions ───────────────────────────────────────────────────
|
|
132
|
+
function printNextSteps(adapterName, displayName, outputDir) {
|
|
133
|
+
console.log("Done! Next steps:");
|
|
134
|
+
console.log();
|
|
135
|
+
console.log(` 1. cd ${outputDir}`);
|
|
136
|
+
console.log(` 2. npm install`);
|
|
137
|
+
console.log();
|
|
138
|
+
console.log(` 3. Implement the upstream connection:`);
|
|
139
|
+
console.log(` src/watcher/connection.ts — connectWatcher()`);
|
|
140
|
+
console.log();
|
|
141
|
+
console.log(` 4. Implement outbound delivery:`);
|
|
142
|
+
console.log(` src/watcher/send.ts — sendText(), sendVoice(), sendFile()`);
|
|
143
|
+
console.log();
|
|
144
|
+
console.log(` 5. Build and run:`);
|
|
145
|
+
console.log(` npm run build`);
|
|
146
|
+
console.log(` npm run watch`);
|
|
147
|
+
console.log();
|
|
148
|
+
console.log(` The adapter will auto-detect the AIBroker hub if it is running.`);
|
|
149
|
+
console.log(` IPC socket: /tmp/${adapterName}-watcher.sock`);
|
|
150
|
+
console.log();
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=create-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-adapter.js","sourceRoot":"","sources":["../../src/daemon/create-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* daemon/index.ts — AIBroker standalone daemon entry point.
|
|
3
|
+
*
|
|
4
|
+
* Starts the hub: IPC server, PAILot WebSocket gateway, HybridSessionManager,
|
|
5
|
+
* APIBackend, TTS, persistence. Adapters connect via the hub IPC socket.
|
|
6
|
+
*/
|
|
7
|
+
export declare const DAEMON_SOCKET_PATH = "/tmp/aibroker.sock";
|
|
8
|
+
export declare function startDaemon(options?: {
|
|
9
|
+
appDir?: string;
|
|
10
|
+
socketPath?: string;
|
|
11
|
+
}): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/daemon/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAgBH,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAEvD,wBAAsB,WAAW,CAAC,OAAO,CAAC,EAAE;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+DhB"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* daemon/index.ts — AIBroker standalone daemon entry point.
|
|
3
|
+
*
|
|
4
|
+
* Starts the hub: IPC server, PAILot WebSocket gateway, HybridSessionManager,
|
|
5
|
+
* APIBackend, TTS, persistence. Adapters connect via the hub IPC socket.
|
|
6
|
+
*/
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
import { homedir } from "node:os";
|
|
9
|
+
import { unlinkSync } from "node:fs";
|
|
10
|
+
import { setLogPrefix } from "../core/log.js";
|
|
11
|
+
import { setAppDir } from "../core/persistence.js";
|
|
12
|
+
import { IpcServer } from "../ipc/server.js";
|
|
13
|
+
import { AdapterRegistry } from "./adapter-registry.js";
|
|
14
|
+
import { registerCoreHandlers } from "./core-handlers.js";
|
|
15
|
+
import { startWsGateway, stopWsGateway } from "../adapters/pailot/gateway.js";
|
|
16
|
+
import { APIBackend } from "../backend/api.js";
|
|
17
|
+
import { HybridSessionManager, setHybridManager } from "../core/hybrid.js";
|
|
18
|
+
import { router } from "../core/router.js";
|
|
19
|
+
import { loadSessionRegistry, loadVoiceConfig } from "../core/persistence.js";
|
|
20
|
+
export const DAEMON_SOCKET_PATH = "/tmp/aibroker.sock";
|
|
21
|
+
export async function startDaemon(options) {
|
|
22
|
+
setLogPrefix("aibroker");
|
|
23
|
+
const appDir = options?.appDir ?? join(homedir(), ".aibroker");
|
|
24
|
+
const socketPath = options?.socketPath ?? DAEMON_SOCKET_PATH;
|
|
25
|
+
setAppDir(appDir);
|
|
26
|
+
// Initialize session management
|
|
27
|
+
const apiBackend = new APIBackend({
|
|
28
|
+
type: "api",
|
|
29
|
+
provider: "anthropic",
|
|
30
|
+
model: process.env.AIBROKER_MODEL ?? "sonnet",
|
|
31
|
+
cwd: process.env.AIBROKER_CWD,
|
|
32
|
+
maxTurns: Number(process.env.AIBROKER_MAX_TURNS) || 30,
|
|
33
|
+
maxBudgetUsd: Number(process.env.AIBROKER_MAX_BUDGET) || 1.0,
|
|
34
|
+
permissionMode: process.env.AIBROKER_PERMISSION_MODE ?? "acceptEdits",
|
|
35
|
+
skipDefaultSession: true,
|
|
36
|
+
});
|
|
37
|
+
const manager = new HybridSessionManager(apiBackend);
|
|
38
|
+
setHybridManager(manager);
|
|
39
|
+
router.setDefaultBackend(apiBackend);
|
|
40
|
+
// Restore persisted state
|
|
41
|
+
loadSessionRegistry();
|
|
42
|
+
loadVoiceConfig();
|
|
43
|
+
// Adapter registry (Phase 2 will expand this)
|
|
44
|
+
const adapterRegistry = new AdapterRegistry();
|
|
45
|
+
// IPC server on the hub socket
|
|
46
|
+
const ipcServer = new IpcServer(socketPath);
|
|
47
|
+
registerCoreHandlers(ipcServer, adapterRegistry, apiBackend, manager);
|
|
48
|
+
ipcServer.start();
|
|
49
|
+
adapterRegistry.startHealthPolling();
|
|
50
|
+
// PAILot WebSocket gateway
|
|
51
|
+
startWsGateway((text, timestamp) => {
|
|
52
|
+
adapterRegistry.dispatchIncoming("pailot", text, timestamp);
|
|
53
|
+
});
|
|
54
|
+
console.log(`AIBroker daemon started`);
|
|
55
|
+
console.log(` Socket: ${socketPath}`);
|
|
56
|
+
console.log(` AppDir: ${appDir}`);
|
|
57
|
+
// Graceful shutdown — ensure socket cleanup even on abrupt exit
|
|
58
|
+
const shutdown = (signal) => {
|
|
59
|
+
console.log(`\n[aibroker] ${signal} received. Stopping.`);
|
|
60
|
+
adapterRegistry.stopHealthPolling();
|
|
61
|
+
stopWsGateway();
|
|
62
|
+
ipcServer.stop();
|
|
63
|
+
// Belt-and-suspenders: remove socket in case ipcServer.stop() didn't
|
|
64
|
+
try {
|
|
65
|
+
unlinkSync(socketPath);
|
|
66
|
+
}
|
|
67
|
+
catch { /* already gone */ }
|
|
68
|
+
process.exit(0);
|
|
69
|
+
};
|
|
70
|
+
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
71
|
+
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
72
|
+
// Clean up on uncaught exceptions too
|
|
73
|
+
process.on("uncaughtException", (err) => {
|
|
74
|
+
console.error(`[aibroker] Uncaught exception:`, err);
|
|
75
|
+
try {
|
|
76
|
+
unlinkSync(socketPath);
|
|
77
|
+
}
|
|
78
|
+
catch { /* ignore */ }
|
|
79
|
+
process.exit(1);
|
|
80
|
+
});
|
|
81
|
+
await new Promise(() => { });
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/daemon/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* daemon/pai-projects.ts — PAI named session integration.
|
|
3
|
+
*
|
|
4
|
+
* Shells out to the `pai` CLI to list and launch named Claude project sessions.
|
|
5
|
+
* Results are cached for 30 seconds to avoid hammering the CLI on every request.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* const projects = await listPaiProjects();
|
|
9
|
+
* const project = await findPaiProject("whazaa");
|
|
10
|
+
* const { pid, sessionId } = await launchPaiProject("whazaa");
|
|
11
|
+
*/
|
|
12
|
+
export interface PaiProject {
|
|
13
|
+
name: string;
|
|
14
|
+
names: string[];
|
|
15
|
+
slug: string;
|
|
16
|
+
displayName: string;
|
|
17
|
+
rootPath: string;
|
|
18
|
+
sessionCount: number;
|
|
19
|
+
lastActive: string;
|
|
20
|
+
sessionConfig?: {
|
|
21
|
+
permission?: string;
|
|
22
|
+
flags?: string;
|
|
23
|
+
env?: Record<string, string>;
|
|
24
|
+
autoStart?: boolean;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/** Invalidate the project list cache (e.g. after launching a project). */
|
|
28
|
+
export declare function invalidatePaiProjectCache(): void;
|
|
29
|
+
/**
|
|
30
|
+
* Return all named PAI projects.
|
|
31
|
+
* Results are cached for 30 seconds.
|
|
32
|
+
*/
|
|
33
|
+
export declare function listPaiProjects(): Promise<PaiProject[]>;
|
|
34
|
+
/**
|
|
35
|
+
* Find a project by any of its names or aliases.
|
|
36
|
+
* Matching is case-insensitive.
|
|
37
|
+
*/
|
|
38
|
+
export declare function findPaiProject(name: string): Promise<PaiProject | undefined>;
|
|
39
|
+
/**
|
|
40
|
+
* Get the effective (merged) config for a PAI project.
|
|
41
|
+
*
|
|
42
|
+
* Calls `pai project config <name> --json` which returns project config,
|
|
43
|
+
* global defaults, and the merged effective config. We use `effective`
|
|
44
|
+
* because it respects the resolution order: project overrides globals.
|
|
45
|
+
*/
|
|
46
|
+
export declare function getEffectiveConfig(name: string): Promise<{
|
|
47
|
+
permission?: string;
|
|
48
|
+
flags?: string;
|
|
49
|
+
env?: Record<string, string>;
|
|
50
|
+
autoStart?: boolean;
|
|
51
|
+
} | undefined>;
|
|
52
|
+
/**
|
|
53
|
+
* Launch Claude in the named project's directory as a visual iTerm2 tab.
|
|
54
|
+
*
|
|
55
|
+
* Uses `pai project config <name> --json` to get the effective (merged)
|
|
56
|
+
* config, then builds a shell command that:
|
|
57
|
+
* 1. cd's to the project directory
|
|
58
|
+
* 2. Exports any env vars from the config
|
|
59
|
+
* 3. Runs `claude` with the configured flags
|
|
60
|
+
*
|
|
61
|
+
* Opens a new iTerm2 tab via AppleScript and types the command into it.
|
|
62
|
+
* Returns the iTerm2 session ID for registration with HybridSessionManager.
|
|
63
|
+
*/
|
|
64
|
+
export declare function launchPaiProject(name: string): Promise<{
|
|
65
|
+
itermSessionId: string;
|
|
66
|
+
sessionId: string;
|
|
67
|
+
}>;
|
|
68
|
+
//# sourceMappingURL=pai-projects.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pai-projects.d.ts","sourceRoot":"","sources":["../../src/daemon/pai-projects.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE;QACd,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC7B,SAAS,CAAC,EAAE,OAAO,CAAC;KACrB,CAAC;CACH;AAiBD,0EAA0E;AAC1E,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD;AA8DD;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAS7D;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CASlF;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,GAAG,SAAS,CAAC,CAWb;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAqCxD"}
|