loopsy 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +190 -0
- package/README.md +425 -0
- package/dist/cli/commands/connect.d.ts +2 -0
- package/dist/cli/commands/connect.d.ts.map +1 -0
- package/dist/cli/commands/connect.js +120 -0
- package/dist/cli/commands/connect.js.map +1 -0
- package/dist/cli/commands/context.d.ts +2 -0
- package/dist/cli/commands/context.d.ts.map +1 -0
- package/dist/cli/commands/context.js +39 -0
- package/dist/cli/commands/context.js.map +1 -0
- package/dist/cli/commands/daemon.d.ts +4 -0
- package/dist/cli/commands/daemon.d.ts.map +1 -0
- package/dist/cli/commands/daemon.js +55 -0
- package/dist/cli/commands/daemon.js.map +1 -0
- package/dist/cli/commands/dashboard.d.ts +2 -0
- package/dist/cli/commands/dashboard.d.ts.map +1 -0
- package/dist/cli/commands/dashboard.js +24 -0
- package/dist/cli/commands/dashboard.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +2 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +130 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/exec.d.ts +2 -0
- package/dist/cli/commands/exec.d.ts.map +1 -0
- package/dist/cli/commands/exec.js +34 -0
- package/dist/cli/commands/exec.js.map +1 -0
- package/dist/cli/commands/init.d.ts +2 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +71 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/key.d.ts +2 -0
- package/dist/cli/commands/key.d.ts.map +1 -0
- package/dist/cli/commands/key.js +39 -0
- package/dist/cli/commands/key.js.map +1 -0
- package/dist/cli/commands/logs.d.ts +2 -0
- package/dist/cli/commands/logs.d.ts.map +1 -0
- package/dist/cli/commands/logs.js +26 -0
- package/dist/cli/commands/logs.js.map +1 -0
- package/dist/cli/commands/mcp.d.ts +4 -0
- package/dist/cli/commands/mcp.d.ts.map +1 -0
- package/dist/cli/commands/mcp.js +70 -0
- package/dist/cli/commands/mcp.js.map +1 -0
- package/dist/cli/commands/pair.d.ts +6 -0
- package/dist/cli/commands/pair.d.ts.map +1 -0
- package/dist/cli/commands/pair.js +208 -0
- package/dist/cli/commands/pair.js.map +1 -0
- package/dist/cli/commands/peers.d.ts +2 -0
- package/dist/cli/commands/peers.d.ts.map +1 -0
- package/dist/cli/commands/peers.js +29 -0
- package/dist/cli/commands/peers.js.map +1 -0
- package/dist/cli/commands/service/linux.d.ts +7 -0
- package/dist/cli/commands/service/linux.d.ts.map +1 -0
- package/dist/cli/commands/service/linux.js +86 -0
- package/dist/cli/commands/service/linux.js.map +1 -0
- package/dist/cli/commands/service/macos.d.ts +7 -0
- package/dist/cli/commands/service/macos.d.ts.map +1 -0
- package/dist/cli/commands/service/macos.js +83 -0
- package/dist/cli/commands/service/macos.js.map +1 -0
- package/dist/cli/commands/service/windows.d.ts +7 -0
- package/dist/cli/commands/service/windows.d.ts.map +1 -0
- package/dist/cli/commands/service/windows.js +52 -0
- package/dist/cli/commands/service/windows.js.map +1 -0
- package/dist/cli/commands/service.d.ts +4 -0
- package/dist/cli/commands/service.d.ts.map +1 -0
- package/dist/cli/commands/service.js +68 -0
- package/dist/cli/commands/service.js.map +1 -0
- package/dist/cli/commands/session.d.ts +8 -0
- package/dist/cli/commands/session.d.ts.map +1 -0
- package/dist/cli/commands/session.js +270 -0
- package/dist/cli/commands/session.js.map +1 -0
- package/dist/cli/commands/transfer.d.ts +3 -0
- package/dist/cli/commands/transfer.d.ts.map +1 -0
- package/dist/cli/commands/transfer.js +57 -0
- package/dist/cli/commands/transfer.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +89 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/package-root.d.ts +27 -0
- package/dist/cli/package-root.d.ts.map +1 -0
- package/dist/cli/package-root.js +54 -0
- package/dist/cli/package-root.js.map +1 -0
- package/dist/cli/utils.d.ts +11 -0
- package/dist/cli/utils.d.ts.map +1 -0
- package/dist/cli/utils.js +48 -0
- package/dist/cli/utils.js.map +1 -0
- package/dist/daemon/config.d.ts +4 -0
- package/dist/daemon/config.d.ts.map +1 -0
- package/dist/daemon/config.js +58 -0
- package/dist/daemon/config.js.map +1 -0
- package/dist/daemon/hooks/permission-hook.mjs +108 -0
- package/dist/daemon/index.d.ts +3 -0
- package/dist/daemon/index.d.ts.map +1 -0
- package/dist/daemon/index.js +3 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/daemon/main.d.ts +3 -0
- package/dist/daemon/main.d.ts.map +1 -0
- package/dist/daemon/main.js +28 -0
- package/dist/daemon/main.js.map +1 -0
- package/dist/daemon/middleware/auth.d.ts +3 -0
- package/dist/daemon/middleware/auth.d.ts.map +1 -0
- package/dist/daemon/middleware/auth.js +22 -0
- package/dist/daemon/middleware/auth.js.map +1 -0
- package/dist/daemon/routes/ai-tasks.d.ts +4 -0
- package/dist/daemon/routes/ai-tasks.d.ts.map +1 -0
- package/dist/daemon/routes/ai-tasks.js +146 -0
- package/dist/daemon/routes/ai-tasks.js.map +1 -0
- package/dist/daemon/routes/context.d.ts +4 -0
- package/dist/daemon/routes/context.d.ts.map +1 -0
- package/dist/daemon/routes/context.js +49 -0
- package/dist/daemon/routes/context.js.map +1 -0
- package/dist/daemon/routes/execute.d.ts +4 -0
- package/dist/daemon/routes/execute.d.ts.map +1 -0
- package/dist/daemon/routes/execute.js +74 -0
- package/dist/daemon/routes/execute.js.map +1 -0
- package/dist/daemon/routes/health.d.ts +15 -0
- package/dist/daemon/routes/health.d.ts.map +1 -0
- package/dist/daemon/routes/health.js +38 -0
- package/dist/daemon/routes/health.js.map +1 -0
- package/dist/daemon/routes/pair.d.ts +11 -0
- package/dist/daemon/routes/pair.d.ts.map +1 -0
- package/dist/daemon/routes/pair.js +149 -0
- package/dist/daemon/routes/pair.js.map +1 -0
- package/dist/daemon/routes/peers.d.ts +5 -0
- package/dist/daemon/routes/peers.d.ts.map +1 -0
- package/dist/daemon/routes/peers.js +69 -0
- package/dist/daemon/routes/peers.js.map +1 -0
- package/dist/daemon/routes/transfer.d.ts +4 -0
- package/dist/daemon/routes/transfer.d.ts.map +1 -0
- package/dist/daemon/routes/transfer.js +135 -0
- package/dist/daemon/routes/transfer.js.map +1 -0
- package/dist/daemon/server.d.ts +8 -0
- package/dist/daemon/server.d.ts.map +1 -0
- package/dist/daemon/server.js +170 -0
- package/dist/daemon/server.js.map +1 -0
- package/dist/daemon/services/ai-task-manager.d.ts +56 -0
- package/dist/daemon/services/ai-task-manager.d.ts.map +1 -0
- package/dist/daemon/services/ai-task-manager.js +491 -0
- package/dist/daemon/services/ai-task-manager.js.map +1 -0
- package/dist/daemon/services/audit-logger.d.ts +16 -0
- package/dist/daemon/services/audit-logger.d.ts.map +1 -0
- package/dist/daemon/services/audit-logger.js +23 -0
- package/dist/daemon/services/audit-logger.js.map +1 -0
- package/dist/daemon/services/context-store.d.ts +17 -0
- package/dist/daemon/services/context-store.d.ts.map +1 -0
- package/dist/daemon/services/context-store.js +97 -0
- package/dist/daemon/services/context-store.js.map +1 -0
- package/dist/daemon/services/job-manager.d.ts +19 -0
- package/dist/daemon/services/job-manager.d.ts.map +1 -0
- package/dist/daemon/services/job-manager.js +92 -0
- package/dist/daemon/services/job-manager.js.map +1 -0
- package/dist/daemon/services/tls-manager.d.ts +33 -0
- package/dist/daemon/services/tls-manager.d.ts.map +1 -0
- package/dist/daemon/services/tls-manager.js +114 -0
- package/dist/daemon/services/tls-manager.js.map +1 -0
- package/dist/daemon/utils/which.d.ts +2 -0
- package/dist/daemon/utils/which.d.ts.map +1 -0
- package/dist/daemon/utils/which.js +18 -0
- package/dist/daemon/utils/which.js.map +1 -0
- package/dist/dashboard/config.d.ts +8 -0
- package/dist/dashboard/config.d.ts.map +1 -0
- package/dist/dashboard/config.js +22 -0
- package/dist/dashboard/config.js.map +1 -0
- package/dist/dashboard/public/app.js +120 -0
- package/dist/dashboard/public/icon-192.png +0 -0
- package/dist/dashboard/public/icon-512.png +0 -0
- package/dist/dashboard/public/index.html +85 -0
- package/dist/dashboard/public/manifest.json +12 -0
- package/dist/dashboard/public/style.css +784 -0
- package/dist/dashboard/public/sw.js +31 -0
- package/dist/dashboard/public/views/ai-tasks.js +679 -0
- package/dist/dashboard/public/views/context.js +167 -0
- package/dist/dashboard/public/views/messages.js +263 -0
- package/dist/dashboard/public/views/overview.js +228 -0
- package/dist/dashboard/public/views/peers.js +136 -0
- package/dist/dashboard/public/views/terminal.js +153 -0
- package/dist/dashboard/routes/ai-tasks.d.ts +3 -0
- package/dist/dashboard/routes/ai-tasks.d.ts.map +1 -0
- package/dist/dashboard/routes/ai-tasks.js +193 -0
- package/dist/dashboard/routes/ai-tasks.js.map +1 -0
- package/dist/dashboard/routes/messages.d.ts +3 -0
- package/dist/dashboard/routes/messages.d.ts.map +1 -0
- package/dist/dashboard/routes/messages.js +137 -0
- package/dist/dashboard/routes/messages.js.map +1 -0
- package/dist/dashboard/routes/peer-utils.d.ts +17 -0
- package/dist/dashboard/routes/peer-utils.d.ts.map +1 -0
- package/dist/dashboard/routes/peer-utils.js +193 -0
- package/dist/dashboard/routes/peer-utils.js.map +1 -0
- package/dist/dashboard/routes/peers-all.d.ts +3 -0
- package/dist/dashboard/routes/peers-all.d.ts.map +1 -0
- package/dist/dashboard/routes/peers-all.js +8 -0
- package/dist/dashboard/routes/peers-all.js.map +1 -0
- package/dist/dashboard/routes/proxy.d.ts +3 -0
- package/dist/dashboard/routes/proxy.d.ts.map +1 -0
- package/dist/dashboard/routes/proxy.js +59 -0
- package/dist/dashboard/routes/proxy.js.map +1 -0
- package/dist/dashboard/routes/sessions.d.ts +3 -0
- package/dist/dashboard/routes/sessions.d.ts.map +1 -0
- package/dist/dashboard/routes/sessions.js +64 -0
- package/dist/dashboard/routes/sessions.js.map +1 -0
- package/dist/dashboard/routes/sse.d.ts +3 -0
- package/dist/dashboard/routes/sse.d.ts.map +1 -0
- package/dist/dashboard/routes/sse.js +49 -0
- package/dist/dashboard/routes/sse.js.map +1 -0
- package/dist/dashboard/routes/status.d.ts +3 -0
- package/dist/dashboard/routes/status.d.ts.map +1 -0
- package/dist/dashboard/routes/status.js +38 -0
- package/dist/dashboard/routes/status.js.map +1 -0
- package/dist/dashboard/server.d.ts +3 -0
- package/dist/dashboard/server.d.ts.map +1 -0
- package/dist/dashboard/server.js +77 -0
- package/dist/dashboard/server.js.map +1 -0
- package/dist/dashboard/session-manager.d.ts +17 -0
- package/dist/dashboard/session-manager.d.ts.map +1 -0
- package/dist/dashboard/session-manager.js +225 -0
- package/dist/dashboard/session-manager.js.map +1 -0
- package/dist/discovery/health-checker.d.ts +15 -0
- package/dist/discovery/health-checker.d.ts.map +1 -0
- package/dist/discovery/health-checker.js +47 -0
- package/dist/discovery/health-checker.js.map +1 -0
- package/dist/discovery/index.d.ts +4 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.js +4 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/discovery/mdns.d.ts +21 -0
- package/dist/discovery/mdns.d.ts.map +1 -0
- package/dist/discovery/mdns.js +83 -0
- package/dist/discovery/mdns.js.map +1 -0
- package/dist/discovery/peer-registry.d.ts +18 -0
- package/dist/discovery/peer-registry.d.ts.map +1 -0
- package/dist/discovery/peer-registry.js +81 -0
- package/dist/discovery/peer-registry.js.map +1 -0
- package/dist/mcp-server/daemon-client.d.ts +69 -0
- package/dist/mcp-server/daemon-client.d.ts.map +1 -0
- package/dist/mcp-server/daemon-client.js +281 -0
- package/dist/mcp-server/daemon-client.js.map +1 -0
- package/dist/mcp-server/index.d.ts +3 -0
- package/dist/mcp-server/index.d.ts.map +1 -0
- package/dist/mcp-server/index.js +406 -0
- package/dist/mcp-server/index.js.map +1 -0
- package/dist/protocol/constants.d.ts +66 -0
- package/dist/protocol/constants.d.ts.map +1 -0
- package/dist/protocol/constants.js +66 -0
- package/dist/protocol/constants.js.map +1 -0
- package/dist/protocol/errors.d.ts +47 -0
- package/dist/protocol/errors.d.ts.map +1 -0
- package/dist/protocol/errors.js +62 -0
- package/dist/protocol/errors.js.map +1 -0
- package/dist/protocol/index.d.ts +5 -0
- package/dist/protocol/index.d.ts.map +1 -0
- package/dist/protocol/index.js +5 -0
- package/dist/protocol/index.js.map +1 -0
- package/dist/protocol/schemas.d.ts +209 -0
- package/dist/protocol/schemas.d.ts.map +1 -0
- package/dist/protocol/schemas.js +115 -0
- package/dist/protocol/schemas.js.map +1 -0
- package/dist/protocol/types.d.ts +302 -0
- package/dist/protocol/types.d.ts.map +1 -0
- package/dist/protocol/types.js +2 -0
- package/dist/protocol/types.js.map +1 -0
- package/package.json +50 -0
- package/scripts/postinstall.mjs +42 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves paths to sibling packages (daemon, mcp-server, dashboard).
|
|
3
|
+
*
|
|
4
|
+
* Supports two layouts:
|
|
5
|
+
*
|
|
6
|
+
* 1. Monorepo (dev):
|
|
7
|
+
* packages/cli/dist/package-root.js → __dirname = packages/cli/dist/
|
|
8
|
+
* Sibling packages at: ../../daemon/dist/, ../../mcp-server/dist/, etc.
|
|
9
|
+
*
|
|
10
|
+
* 2. Flat npm package:
|
|
11
|
+
* dist/cli/package-root.js → __dirname = dist/cli/
|
|
12
|
+
* Sibling packages at: ../daemon/, ../mcp-server/, etc.
|
|
13
|
+
*
|
|
14
|
+
* Detection: check if ../../daemon/dist/main.js exists (monorepo) or
|
|
15
|
+
* ../daemon/main.js exists (flat package).
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Root directory containing all package dist outputs.
|
|
19
|
+
* - Monorepo: packages/ (so packages/daemon/dist/main.js works)
|
|
20
|
+
* - Flat: dist/ (so dist/daemon/main.js works)
|
|
21
|
+
*/
|
|
22
|
+
export declare const PACKAGES_ROOT: string;
|
|
23
|
+
export declare function daemonMainPath(): string;
|
|
24
|
+
export declare function mcpServerPath(): string;
|
|
25
|
+
export declare function dashboardServerPath(): string;
|
|
26
|
+
export declare function hookScriptPath(): string;
|
|
27
|
+
//# sourceMappingURL=package-root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-root.d.ts","sourceRoot":"","sources":["../src/package-root.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAeH;;;;GAIG;AACH,eAAO,MAAM,aAAa,QAEE,CAAC;AAE7B,wBAAgB,cAAc,IAAI,MAAM,CAIvC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAItC;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAI5C;AAED,wBAAgB,cAAc,IAAI,MAAM,CAIvC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves paths to sibling packages (daemon, mcp-server, dashboard).
|
|
3
|
+
*
|
|
4
|
+
* Supports two layouts:
|
|
5
|
+
*
|
|
6
|
+
* 1. Monorepo (dev):
|
|
7
|
+
* packages/cli/dist/package-root.js → __dirname = packages/cli/dist/
|
|
8
|
+
* Sibling packages at: ../../daemon/dist/, ../../mcp-server/dist/, etc.
|
|
9
|
+
*
|
|
10
|
+
* 2. Flat npm package:
|
|
11
|
+
* dist/cli/package-root.js → __dirname = dist/cli/
|
|
12
|
+
* Sibling packages at: ../daemon/, ../mcp-server/, etc.
|
|
13
|
+
*
|
|
14
|
+
* Detection: check if ../../daemon/dist/main.js exists (monorepo) or
|
|
15
|
+
* ../daemon/main.js exists (flat package).
|
|
16
|
+
*/
|
|
17
|
+
import { dirname, join, resolve } from 'node:path';
|
|
18
|
+
import { fileURLToPath } from 'node:url';
|
|
19
|
+
import { existsSync } from 'node:fs';
|
|
20
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
21
|
+
const __dirname = dirname(__filename);
|
|
22
|
+
// Detect layout by probing for daemon entry point
|
|
23
|
+
const monorepoCandidate = resolve(__dirname, '..', '..', 'daemon', 'dist', 'main.js');
|
|
24
|
+
const flatCandidate = resolve(__dirname, '..', 'daemon', 'main.js');
|
|
25
|
+
const isMonorepo = existsSync(monorepoCandidate);
|
|
26
|
+
/**
|
|
27
|
+
* Root directory containing all package dist outputs.
|
|
28
|
+
* - Monorepo: packages/ (so packages/daemon/dist/main.js works)
|
|
29
|
+
* - Flat: dist/ (so dist/daemon/main.js works)
|
|
30
|
+
*/
|
|
31
|
+
export const PACKAGES_ROOT = isMonorepo
|
|
32
|
+
? resolve(__dirname, '..', '..') // packages/cli/dist/ → packages/
|
|
33
|
+
: resolve(__dirname, '..'); // dist/cli/ → dist/
|
|
34
|
+
export function daemonMainPath() {
|
|
35
|
+
return isMonorepo
|
|
36
|
+
? join(PACKAGES_ROOT, 'daemon', 'dist', 'main.js')
|
|
37
|
+
: join(PACKAGES_ROOT, 'daemon', 'main.js');
|
|
38
|
+
}
|
|
39
|
+
export function mcpServerPath() {
|
|
40
|
+
return isMonorepo
|
|
41
|
+
? join(PACKAGES_ROOT, 'mcp-server', 'dist', 'index.js')
|
|
42
|
+
: join(PACKAGES_ROOT, 'mcp-server', 'index.js');
|
|
43
|
+
}
|
|
44
|
+
export function dashboardServerPath() {
|
|
45
|
+
return isMonorepo
|
|
46
|
+
? join(PACKAGES_ROOT, 'dashboard', 'dist', 'server.js')
|
|
47
|
+
: join(PACKAGES_ROOT, 'dashboard', 'server.js');
|
|
48
|
+
}
|
|
49
|
+
export function hookScriptPath() {
|
|
50
|
+
return isMonorepo
|
|
51
|
+
? join(PACKAGES_ROOT, 'daemon', 'dist', 'hooks', 'permission-hook.mjs')
|
|
52
|
+
: join(PACKAGES_ROOT, 'daemon', 'hooks', 'permission-hook.mjs');
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=package-root.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-root.js","sourceRoot":"","sources":["../src/package-root.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,kDAAkD;AAClD,MAAM,iBAAiB,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;AACtF,MAAM,aAAa,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;AAEpE,MAAM,UAAU,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC;AAEjD;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU;IACrC,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAG,iCAAiC;IACpE,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAQ,oBAAoB;AAEzD,MAAM,UAAU,cAAc;IAC5B,OAAO,UAAU;QACf,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC;QAClD,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,UAAU;QACf,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,CAAC;QACvD,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,OAAO,UAAU;QACf,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,CAAC;QACvD,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,UAAU;QACf,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,CAAC;QACvE,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,OAAO,EAAE,qBAAqB,CAAC,CAAC;AACpE,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare function loadCliConfig(dataDir?: string): Promise<{
|
|
2
|
+
apiKey: string;
|
|
3
|
+
port: number;
|
|
4
|
+
}>;
|
|
5
|
+
export declare function loadApiKey(): Promise<string>;
|
|
6
|
+
export declare function parsePeerAddress(peer: string): {
|
|
7
|
+
address: string;
|
|
8
|
+
port: number;
|
|
9
|
+
};
|
|
10
|
+
export declare function daemonRequest(path: string, opts?: RequestInit, dataDir?: string): Promise<any>;
|
|
11
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAMA,wBAAsB,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAa/F;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAGlD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAMhF;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAexG"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { parse as parseYaml } from 'yaml';
|
|
5
|
+
import { DEFAULT_PORT, CONFIG_DIR, CONFIG_FILE } from '@loopsy/protocol';
|
|
6
|
+
export async function loadCliConfig(dataDir) {
|
|
7
|
+
try {
|
|
8
|
+
const dir = dataDir ?? join(homedir(), CONFIG_DIR);
|
|
9
|
+
const configPath = join(dir, CONFIG_FILE);
|
|
10
|
+
const raw = await readFile(configPath, 'utf-8');
|
|
11
|
+
const config = parseYaml(raw);
|
|
12
|
+
return {
|
|
13
|
+
apiKey: config?.auth?.apiKey ?? '',
|
|
14
|
+
port: config?.server?.port ?? DEFAULT_PORT,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return { apiKey: '', port: DEFAULT_PORT };
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export async function loadApiKey() {
|
|
22
|
+
const { apiKey } = await loadCliConfig();
|
|
23
|
+
return apiKey;
|
|
24
|
+
}
|
|
25
|
+
export function parsePeerAddress(peer) {
|
|
26
|
+
const parts = peer.split(':');
|
|
27
|
+
return {
|
|
28
|
+
address: parts[0],
|
|
29
|
+
port: parts.length > 1 ? parseInt(parts[1], 10) : DEFAULT_PORT,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export async function daemonRequest(path, opts = {}, dataDir) {
|
|
33
|
+
const { apiKey, port } = await loadCliConfig(dataDir);
|
|
34
|
+
const res = await fetch(`http://127.0.0.1:${port}/api/v1${path}`, {
|
|
35
|
+
...opts,
|
|
36
|
+
headers: {
|
|
37
|
+
'Content-Type': 'application/json',
|
|
38
|
+
Authorization: `Bearer ${apiKey}`,
|
|
39
|
+
...opts.headers,
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
if (!res.ok) {
|
|
43
|
+
const body = await res.json().catch(() => ({}));
|
|
44
|
+
throw new Error(body.error?.message ?? `HTTP ${res.status}`);
|
|
45
|
+
}
|
|
46
|
+
return res.json();
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEzE,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAgB;IAClD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAC1C,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAQ,CAAC;QACrC,OAAO;YACL,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,EAAE;YAClC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,IAAI,YAAY;SAC3C,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IAC5C,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,EAAE,CAAC;IACzC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;QACjB,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY;KAC/D,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAY,EAAE,OAAoB,EAAE,EAAE,OAAgB;IACxF,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oBAAoB,IAAI,UAAU,IAAI,EAAE,EAAE;QAChE,GAAG,IAAI;QACP,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,UAAU,MAAM,EAAE;YACjC,GAAG,IAAI,CAAC,OAAO;SAChB;KACF,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAQ,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,IAAI,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAKrD,wBAAgB,aAAa,IAAI,YAAY,CAqB5C;AAED,wBAAsB,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAcxE"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { parse as parseYaml } from 'yaml';
|
|
5
|
+
import { randomBytes } from 'node:crypto';
|
|
6
|
+
import { CONFIG_DIR, CONFIG_FILE, DEFAULT_PORT, MAX_FILE_SIZE, MAX_CONCURRENT_JOBS, DEFAULT_EXEC_TIMEOUT, RATE_LIMITS } from '@loopsy/protocol';
|
|
7
|
+
const DEFAULT_DATA_DIR = join(homedir(), CONFIG_DIR);
|
|
8
|
+
export function defaultConfig() {
|
|
9
|
+
return {
|
|
10
|
+
server: { port: DEFAULT_PORT, host: '0.0.0.0' },
|
|
11
|
+
auth: {
|
|
12
|
+
apiKey: randomBytes(32).toString('hex'),
|
|
13
|
+
allowedKeys: {},
|
|
14
|
+
},
|
|
15
|
+
execution: {
|
|
16
|
+
denylist: ['rm', 'rmdir', 'format', 'mkfs', 'dd', 'shutdown', 'reboot'],
|
|
17
|
+
maxConcurrent: MAX_CONCURRENT_JOBS,
|
|
18
|
+
defaultTimeout: DEFAULT_EXEC_TIMEOUT,
|
|
19
|
+
},
|
|
20
|
+
transfer: {
|
|
21
|
+
allowedPaths: [homedir()],
|
|
22
|
+
deniedPaths: [join(homedir(), '.ssh'), join(homedir(), '.gnupg')],
|
|
23
|
+
maxFileSize: MAX_FILE_SIZE,
|
|
24
|
+
},
|
|
25
|
+
rateLimits: { ...RATE_LIMITS },
|
|
26
|
+
discovery: { enabled: true, manualPeers: [] },
|
|
27
|
+
logging: { level: 'info' },
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export async function loadConfig(dataDir) {
|
|
31
|
+
const dir = dataDir ?? DEFAULT_DATA_DIR;
|
|
32
|
+
const configPath = join(dir, CONFIG_FILE);
|
|
33
|
+
const defaults = defaultConfig();
|
|
34
|
+
try {
|
|
35
|
+
const raw = await readFile(configPath, 'utf-8');
|
|
36
|
+
const parsed = parseYaml(raw);
|
|
37
|
+
const config = deepMerge(defaults, parsed);
|
|
38
|
+
config.server.dataDir = dir;
|
|
39
|
+
return config;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
defaults.server.dataDir = dir;
|
|
43
|
+
return defaults;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function deepMerge(target, source) {
|
|
47
|
+
const result = { ...target };
|
|
48
|
+
for (const key of Object.keys(source)) {
|
|
49
|
+
if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
|
|
50
|
+
result[key] = deepMerge(result[key] ?? {}, source[key]);
|
|
51
|
+
}
|
|
52
|
+
else if (source[key] !== undefined) {
|
|
53
|
+
result[key] = source[key];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Loopsy PreToolUse Hook for Claude Code
|
|
4
|
+
//
|
|
5
|
+
// This script is invoked by Claude Code's PreToolUse hook mechanism.
|
|
6
|
+
// It fires before every tool use (including in -p mode), registers the
|
|
7
|
+
// permission request with the Loopsy daemon, and polls until the human
|
|
8
|
+
// approves/denies via the dashboard.
|
|
9
|
+
//
|
|
10
|
+
// Exit codes:
|
|
11
|
+
// 0 + JSON stdout → allow or deny (via permissionDecision in hookSpecificOutput)
|
|
12
|
+
//
|
|
13
|
+
// Usage (command-line args embedded by daemon in per-task settings):
|
|
14
|
+
// node permission-hook.mjs <taskId> <port> <apiKey>
|
|
15
|
+
|
|
16
|
+
// Support both CLI args and env vars
|
|
17
|
+
const taskId = process.argv[2] || process.env.LOOPSY_TASK_ID;
|
|
18
|
+
const port = process.argv[3] || process.env.LOOPSY_DAEMON_PORT || '19532';
|
|
19
|
+
const apiKey = process.argv[4] || process.env.LOOPSY_API_KEY;
|
|
20
|
+
const baseUrl = `http://127.0.0.1:${port}`;
|
|
21
|
+
|
|
22
|
+
function allow() {
|
|
23
|
+
process.stdout.write(JSON.stringify({
|
|
24
|
+
hookSpecificOutput: {
|
|
25
|
+
hookEventName: 'PreToolUse',
|
|
26
|
+
permissionDecision: 'allow',
|
|
27
|
+
permissionDecisionReason: 'Approved via Loopsy dashboard',
|
|
28
|
+
},
|
|
29
|
+
}));
|
|
30
|
+
process.exit(0);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function deny(reason) {
|
|
34
|
+
process.stdout.write(JSON.stringify({
|
|
35
|
+
hookSpecificOutput: {
|
|
36
|
+
hookEventName: 'PreToolUse',
|
|
37
|
+
permissionDecision: 'deny',
|
|
38
|
+
permissionDecisionReason: reason || 'Denied via Loopsy dashboard',
|
|
39
|
+
},
|
|
40
|
+
}));
|
|
41
|
+
process.exit(0);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// If no task ID, this is a normal Claude session — no-op (allow all)
|
|
45
|
+
if (!taskId) {
|
|
46
|
+
process.stdout.write('{}');
|
|
47
|
+
process.exit(0);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let input = '';
|
|
51
|
+
process.stdin.on('data', (chunk) => { input += chunk; });
|
|
52
|
+
process.stdin.on('end', async () => {
|
|
53
|
+
try {
|
|
54
|
+
const hookInput = JSON.parse(input);
|
|
55
|
+
const toolName = hookInput.tool_name || 'unknown';
|
|
56
|
+
const requestId = `${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
|
57
|
+
|
|
58
|
+
// Register permission request with the daemon
|
|
59
|
+
const registerRes = await fetch(`${baseUrl}/api/v1/ai-tasks/${taskId}/permission-request`, {
|
|
60
|
+
method: 'POST',
|
|
61
|
+
headers: {
|
|
62
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
63
|
+
'Content-Type': 'application/json',
|
|
64
|
+
},
|
|
65
|
+
body: JSON.stringify({
|
|
66
|
+
requestId,
|
|
67
|
+
toolName,
|
|
68
|
+
toolInput: hookInput.tool_input || {},
|
|
69
|
+
description: `Claude wants to use: ${toolName}`,
|
|
70
|
+
}),
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
if (!registerRes.ok) {
|
|
74
|
+
deny('Failed to register permission request with daemon');
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Poll for decision (100ms interval, 5min timeout)
|
|
79
|
+
const deadline = Date.now() + 300_000;
|
|
80
|
+
while (Date.now() < deadline) {
|
|
81
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
const res = await fetch(
|
|
85
|
+
`${baseUrl}/api/v1/ai-tasks/${taskId}/permission-response?requestId=${requestId}`,
|
|
86
|
+
{ headers: { 'Authorization': `Bearer ${apiKey}` } },
|
|
87
|
+
);
|
|
88
|
+
if (!res.ok) continue;
|
|
89
|
+
|
|
90
|
+
const data = await res.json();
|
|
91
|
+
if (data.resolved) {
|
|
92
|
+
if (data.approved) {
|
|
93
|
+
allow();
|
|
94
|
+
} else {
|
|
95
|
+
deny(data.message || 'Denied by user');
|
|
96
|
+
}
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
} catch {
|
|
100
|
+
// Network error during poll — keep trying
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
deny('Permission request timed out (5 minutes)');
|
|
105
|
+
} catch (err) {
|
|
106
|
+
deny(`Hook error: ${err.message}`);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAqB,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { loadConfig } from './config.js';
|
|
3
|
+
import { createDaemon } from './server.js';
|
|
4
|
+
function parseArgs() {
|
|
5
|
+
const args = process.argv.slice(2);
|
|
6
|
+
const idx = args.indexOf('--data-dir');
|
|
7
|
+
if (idx !== -1 && args[idx + 1]) {
|
|
8
|
+
return { dataDir: args[idx + 1] };
|
|
9
|
+
}
|
|
10
|
+
return {};
|
|
11
|
+
}
|
|
12
|
+
async function main() {
|
|
13
|
+
const { dataDir } = parseArgs();
|
|
14
|
+
const config = await loadConfig(dataDir);
|
|
15
|
+
const daemon = await createDaemon(config);
|
|
16
|
+
const shutdown = async () => {
|
|
17
|
+
await daemon.stop();
|
|
18
|
+
process.exit(0);
|
|
19
|
+
};
|
|
20
|
+
process.on('SIGINT', shutdown);
|
|
21
|
+
process.on('SIGTERM', shutdown);
|
|
22
|
+
await daemon.start();
|
|
23
|
+
}
|
|
24
|
+
main().catch((err) => {
|
|
25
|
+
console.error('Failed to start Loopsy daemon:', err);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,SAAS,SAAS;IAChB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACvC,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC;QAChC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC;IACpC,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;IAE1C,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAEhC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;AACvB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,GAAG,CAAC,CAAC;IACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG5D,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAGlE,SAAS,cAAc,EAAE,OAAO,YAAY,mBAkB3D"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { LoopsyError, LoopsyErrorCode } from '@loopsy/protocol';
|
|
2
|
+
export function createAuthHook(ownKey, allowedKeys) {
|
|
3
|
+
const validKeys = new Set([ownKey, ...Object.values(allowedKeys)]);
|
|
4
|
+
return async (request, reply) => {
|
|
5
|
+
// Skip auth for health endpoint
|
|
6
|
+
if (request.url === '/api/v1/health')
|
|
7
|
+
return;
|
|
8
|
+
const authHeader = request.headers.authorization;
|
|
9
|
+
if (!authHeader) {
|
|
10
|
+
const err = new LoopsyError(LoopsyErrorCode.AUTH_MISSING_KEY, 'Missing Authorization header');
|
|
11
|
+
reply.code(401).send(err.toJSON());
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const key = authHeader.replace(/^Bearer\s+/i, '');
|
|
15
|
+
if (!validKeys.has(key)) {
|
|
16
|
+
const err = new LoopsyError(LoopsyErrorCode.AUTH_INVALID_KEY, 'Invalid API key');
|
|
17
|
+
reply.code(403).send(err.toJSON());
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEhE,MAAM,UAAU,cAAc,CAAC,MAAc,EAAE,WAAmC;IAChF,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAEnE,OAAO,KAAK,EAAE,OAAuB,EAAE,KAAmB,EAAE,EAAE;QAC5D,gCAAgC;QAChC,IAAI,OAAO,CAAC,GAAG,KAAK,gBAAgB;YAAE,OAAO;QAE7C,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC;QACjD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,GAAG,GAAG,IAAI,WAAW,CAAC,eAAe,CAAC,gBAAgB,EAAE,8BAA8B,CAAC,CAAC;YAC9F,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;YACnC,OAAO;QACT,CAAC;QAED,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QAClD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,GAAG,GAAG,IAAI,WAAW,CAAC,eAAe,CAAC,gBAAgB,EAAE,iBAAiB,CAAC,CAAC;YACjF,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;YACnC,OAAO;QACT,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-tasks.d.ts","sourceRoot":"","sources":["../../src/routes/ai-tasks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAGpE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,QAyKtF"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { AiTaskParamsSchema, AiTaskApprovalResponseSchema, PermissionRequestBodySchema } from '@loopsy/protocol';
|
|
2
|
+
export function registerAiTaskRoutes(app, aiTaskManager) {
|
|
3
|
+
// Dispatch a new AI task
|
|
4
|
+
app.post('/api/v1/ai-tasks', async (request, reply) => {
|
|
5
|
+
const params = AiTaskParamsSchema.parse(request.body);
|
|
6
|
+
const fromNodeId = request.headers['x-loopsy-node-id'] || 'remote';
|
|
7
|
+
try {
|
|
8
|
+
const info = await aiTaskManager.dispatch(params, fromNodeId);
|
|
9
|
+
reply.code(201);
|
|
10
|
+
return info;
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
if (err.code === 6002) {
|
|
14
|
+
reply.code(429);
|
|
15
|
+
return { error: err.message };
|
|
16
|
+
}
|
|
17
|
+
if (err.code === 6006) {
|
|
18
|
+
reply.code(500);
|
|
19
|
+
return { error: err.message };
|
|
20
|
+
}
|
|
21
|
+
throw err;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
// List all tasks (active + recent)
|
|
25
|
+
app.get('/api/v1/ai-tasks', async () => {
|
|
26
|
+
return { tasks: aiTaskManager.getAllTasks() };
|
|
27
|
+
});
|
|
28
|
+
// Get a single task
|
|
29
|
+
app.get('/api/v1/ai-tasks/:taskId', async (request, reply) => {
|
|
30
|
+
const info = aiTaskManager.getTask(request.params.taskId);
|
|
31
|
+
if (!info) {
|
|
32
|
+
reply.code(404);
|
|
33
|
+
return { error: 'Task not found' };
|
|
34
|
+
}
|
|
35
|
+
return info;
|
|
36
|
+
});
|
|
37
|
+
// SSE stream for a task
|
|
38
|
+
app.get('/api/v1/ai-tasks/:taskId/stream', async (request, reply) => {
|
|
39
|
+
const { taskId } = request.params;
|
|
40
|
+
reply.raw.writeHead(200, {
|
|
41
|
+
'Content-Type': 'text/event-stream',
|
|
42
|
+
'Cache-Control': 'no-cache',
|
|
43
|
+
'Connection': 'keep-alive',
|
|
44
|
+
'X-Accel-Buffering': 'no',
|
|
45
|
+
});
|
|
46
|
+
// Send buffered events first (for reconnecting clients)
|
|
47
|
+
const since = request.query.since ? parseInt(request.query.since, 10) : 0;
|
|
48
|
+
const buffer = aiTaskManager.getEventBuffer(taskId);
|
|
49
|
+
for (const event of buffer) {
|
|
50
|
+
if (event.timestamp > since) {
|
|
51
|
+
reply.raw.write(`data: ${JSON.stringify(event)}\n\n`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Subscribe to live events
|
|
55
|
+
const unsubscribe = aiTaskManager.subscribe(taskId, (event) => {
|
|
56
|
+
if (!reply.raw.destroyed) {
|
|
57
|
+
reply.raw.write(`data: ${JSON.stringify(event)}\n\n`);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
if (!unsubscribe) {
|
|
61
|
+
// Task not active — check if it's a recent completed task
|
|
62
|
+
const info = aiTaskManager.getTask(taskId);
|
|
63
|
+
if (info) {
|
|
64
|
+
reply.raw.write(`data: ${JSON.stringify({ type: 'status', taskId, timestamp: Date.now(), data: { status: info.status } })}\n\n`);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
reply.raw.write(`data: ${JSON.stringify({ type: 'error', taskId, timestamp: Date.now(), data: 'Task not found' })}\n\n`);
|
|
68
|
+
}
|
|
69
|
+
reply.raw.end();
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
// Clean up on disconnect
|
|
73
|
+
request.raw.on('close', () => {
|
|
74
|
+
unsubscribe();
|
|
75
|
+
});
|
|
76
|
+
// Keep connection open until task completes or client disconnects
|
|
77
|
+
// The 'exit' event from the task will trigger the subscriber, and the client
|
|
78
|
+
// can close the EventSource after receiving it.
|
|
79
|
+
});
|
|
80
|
+
// Register a permission request from the hook script
|
|
81
|
+
// Called by permission-hook.mjs when Claude wants to use a tool
|
|
82
|
+
app.post('/api/v1/ai-tasks/:taskId/permission-request', async (request, reply) => {
|
|
83
|
+
const { taskId } = request.params;
|
|
84
|
+
const body = PermissionRequestBodySchema.parse(request.body);
|
|
85
|
+
const success = aiTaskManager.registerPermissionRequest(taskId, {
|
|
86
|
+
requestId: body.requestId,
|
|
87
|
+
toolName: body.toolName,
|
|
88
|
+
toolInput: body.toolInput,
|
|
89
|
+
description: body.description,
|
|
90
|
+
});
|
|
91
|
+
if (!success) {
|
|
92
|
+
reply.code(404);
|
|
93
|
+
return { error: 'Task not found' };
|
|
94
|
+
}
|
|
95
|
+
return { success: true, requestId: body.requestId };
|
|
96
|
+
});
|
|
97
|
+
// Poll for permission response (called by hook script)
|
|
98
|
+
app.get('/api/v1/ai-tasks/:taskId/permission-response', async (request, reply) => {
|
|
99
|
+
const { taskId } = request.params;
|
|
100
|
+
const { requestId } = request.query;
|
|
101
|
+
if (!requestId) {
|
|
102
|
+
reply.code(400);
|
|
103
|
+
return { error: 'requestId query parameter required' };
|
|
104
|
+
}
|
|
105
|
+
const response = aiTaskManager.getPermissionResponse(taskId, requestId);
|
|
106
|
+
if (!response) {
|
|
107
|
+
return { resolved: false };
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
resolved: true,
|
|
111
|
+
approved: response.approved,
|
|
112
|
+
message: response.message || '',
|
|
113
|
+
};
|
|
114
|
+
});
|
|
115
|
+
// Approve/deny a permission request (called by dashboard)
|
|
116
|
+
app.post('/api/v1/ai-tasks/:taskId/approve', async (request, reply) => {
|
|
117
|
+
const { taskId } = request.params;
|
|
118
|
+
const response = AiTaskApprovalResponseSchema.parse(request.body);
|
|
119
|
+
const success = aiTaskManager.approve(taskId, response);
|
|
120
|
+
if (!success) {
|
|
121
|
+
reply.code(400);
|
|
122
|
+
return { error: 'No pending permission request found for this task' };
|
|
123
|
+
}
|
|
124
|
+
return { success: true, taskId };
|
|
125
|
+
});
|
|
126
|
+
// Get event buffer for a task (for debugging and catch-up)
|
|
127
|
+
app.get('/api/v1/ai-tasks/:taskId/events', async (request, reply) => {
|
|
128
|
+
const events = aiTaskManager.getEventBuffer(request.params.taskId);
|
|
129
|
+
return { events, count: events.length };
|
|
130
|
+
});
|
|
131
|
+
// Cancel a running task
|
|
132
|
+
app.delete('/api/v1/ai-tasks/:taskId', async (request, reply) => {
|
|
133
|
+
const success = aiTaskManager.cancel(request.params.taskId);
|
|
134
|
+
if (!success) {
|
|
135
|
+
// Maybe it's a completed task — try deleting from recent
|
|
136
|
+
const deleted = aiTaskManager.deleteTask(request.params.taskId);
|
|
137
|
+
if (!deleted) {
|
|
138
|
+
reply.code(404);
|
|
139
|
+
return { error: 'Task not found' };
|
|
140
|
+
}
|
|
141
|
+
return { success: true, taskId: request.params.taskId, deleted: true };
|
|
142
|
+
}
|
|
143
|
+
return { success: true, taskId: request.params.taskId };
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=ai-tasks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-tasks.js","sourceRoot":"","sources":["../../src/routes/ai-tasks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/routes/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEjE,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,QAgDrF"}
|