@lathly/dsh-phone-access 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/README.md +85 -0
- package/lib/index.js +134 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/lib/types/index.d.ts +30 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +123 -0
- package/lib/types/index.js.map +1 -0
- package/package.json +32 -0
- package/src/index.ts +149 -0
package/README.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# @deepseek-ai/dsh-phone-access
|
|
2
|
+
|
|
3
|
+
DSH phone access token trampoline — HTTP redirect service for remote phone access to DSH Web UI via Tailscale or any network proxy.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This plugin provides an HTTP redirect service that allows remote phone access to the DSH Web UI without manual token management. The trampoline reads the current DSH web-launch-token file on each request and issues fresh token-authenticated redirect URLs.
|
|
8
|
+
|
|
9
|
+
## Phone access path
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
phone bookmark → trampoline (this plugin) → 302 → DSH token URL
|
|
13
|
+
→ DSH validates token → sets cookie → 303 → DSH Web UI
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
Install the plugin package:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pnpm add @deepseek-ai/dsh-phone-access
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Enable it in your DSH configuration (e.g., `~/.dsh/profiles/default/cordis.yml`):
|
|
25
|
+
|
|
26
|
+
```yaml
|
|
27
|
+
plugins:
|
|
28
|
+
- id: phone-access
|
|
29
|
+
name: "@deepseek-ai/dsh-phone-access"
|
|
30
|
+
config:
|
|
31
|
+
port: 3090
|
|
32
|
+
tokenFile: "/home/andré/.dsh/web-launch-token"
|
|
33
|
+
targetUrl: "https://pop-os.taildc49b0.ts.net"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Configuration
|
|
37
|
+
|
|
38
|
+
| Option | Type | Default | Description |
|
|
39
|
+
|--------|------|---------|-------------|
|
|
40
|
+
| `port` | `number` | `3090` | Port for the trampoline HTTP server |
|
|
41
|
+
| `tokenFile` | `string` | `~/.dsh/web-launch-token` | Path to the DSH web-launch-token file |
|
|
42
|
+
| `targetUrl` | `string` | `https://pop-os.taildc49b0.ts.net` | Target URL for redirects (DSH Web UI base URL) |
|
|
43
|
+
|
|
44
|
+
## Phone bookmark
|
|
45
|
+
|
|
46
|
+
Bookmark the trampoline URL on your phone:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
http://pop-os.taildc49b0.ts.net:3090/dsh
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The trampoline performs a fresh token exchange on every hit, so the bookmark works whether the cookie is fresh, expired, or never issued — including right after a DSH restart.
|
|
53
|
+
|
|
54
|
+
## Agent tools
|
|
55
|
+
|
|
56
|
+
This plugin registers two DSH tools:
|
|
57
|
+
|
|
58
|
+
- **`phone_access_status`** — Query the phone access trampoline status and configuration.
|
|
59
|
+
- **`phone_access_url`** — Get the current phone access URL (with fresh token).
|
|
60
|
+
|
|
61
|
+
## Endpoints
|
|
62
|
+
|
|
63
|
+
| Endpoint | Description |
|
|
64
|
+
|----------|-------------|
|
|
65
|
+
| `/` | Token-authenticated redirect to DSH Web UI |
|
|
66
|
+
| `/dsh` | Same as `/` (alias) |
|
|
67
|
+
| `/dsh-url` | Plain text: current token-authenticated DSH URL |
|
|
68
|
+
| `/health` | JSON: `{"status": "ok", "target": "..."}` |
|
|
69
|
+
|
|
70
|
+
## Requirements
|
|
71
|
+
|
|
72
|
+
- DSH running locally on port 3080 (or custom configured port)
|
|
73
|
+
- Tailscale serve configured to proxy port 443 to localhost:3080
|
|
74
|
+
- Tailscale network access for the phone
|
|
75
|
+
- DSH web-launch-token file readable by the plugin
|
|
76
|
+
|
|
77
|
+
## Troubleshooting
|
|
78
|
+
|
|
79
|
+
- **Page renders, no conversations** — The DSH browser-trust fence is rejecting API calls. Add your tailnet DNS name to `trustedHosts` in your DSH web configuration. See `scripts/README-phone-access.md` in the DSH repo.
|
|
80
|
+
- **Bookmark unreachable** — Check that the trampoline service is running: `systemctl --user status dsh-web-redirect`
|
|
81
|
+
- **Cookie not set** — Verify that DSH is writing the web-launch-token file and that the plugin can read it
|
|
82
|
+
|
|
83
|
+
## License
|
|
84
|
+
|
|
85
|
+
MIT
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { createServer } from "node:http";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { defineTool } from "@deepseek-ai/dsh-tools";
|
|
5
|
+
//#region lib/types/index.js
|
|
6
|
+
/**
|
|
7
|
+
* @deepseek-ai/dsh-phone-access — DSH phone access token trampoline
|
|
8
|
+
*
|
|
9
|
+
* Provides an HTTP redirect service that allows remote phone access to the
|
|
10
|
+
* DSH Web UI via Tailscale or any network proxy. The trampoline reads the
|
|
11
|
+
* current DSH web-launch-token file on each request and issues fresh
|
|
12
|
+
* token-authenticated redirect URLs, enabling phone access that survives
|
|
13
|
+
* DSH restarts without manual URL updates.
|
|
14
|
+
*
|
|
15
|
+
* Phone access path:
|
|
16
|
+
* phone bookmark → trampoline (this plugin) → 302 → DSH token URL
|
|
17
|
+
* → DSH validates token → sets cookie → 303 → DSH Web UI
|
|
18
|
+
*
|
|
19
|
+
* @module @deepseek-ai/dsh-phone-access
|
|
20
|
+
*/
|
|
21
|
+
const name = "phone-access";
|
|
22
|
+
const inject = [];
|
|
23
|
+
let server = null;
|
|
24
|
+
let serverPort = 0;
|
|
25
|
+
let tokenFilePath = "";
|
|
26
|
+
let targetUrl = "";
|
|
27
|
+
function defaultConfig() {
|
|
28
|
+
return {
|
|
29
|
+
port: 3090,
|
|
30
|
+
tokenFile: `${homedir()}/.dsh/web-launch-token`,
|
|
31
|
+
targetUrl: "https://pop-os.taildc49b0.ts.net"
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
async function readToken(path) {
|
|
35
|
+
return (await readFile(path, "utf-8")).trim();
|
|
36
|
+
}
|
|
37
|
+
async function handleRequest(req, res, config) {
|
|
38
|
+
const url = new URL(req.url || "/", `http://${req.headers.host || "localhost"}`);
|
|
39
|
+
try {
|
|
40
|
+
if (url.pathname === "/health") {
|
|
41
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
42
|
+
res.end(JSON.stringify({
|
|
43
|
+
status: "ok",
|
|
44
|
+
target: config.targetUrl
|
|
45
|
+
}));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (url.pathname === "/dsh-url" || url.pathname === "/url") {
|
|
49
|
+
const token = await readToken(config.tokenFile);
|
|
50
|
+
res.writeHead(200, { "Content-Type": "text/plain" });
|
|
51
|
+
res.end(`${config.targetUrl}/?token=${token}`);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const token = await readToken(config.tokenFile);
|
|
55
|
+
const redirectUrl = `${config.targetUrl}/?token=${token}`;
|
|
56
|
+
res.writeHead(302, { "Location": redirectUrl });
|
|
57
|
+
res.end();
|
|
58
|
+
} catch (err) {
|
|
59
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
60
|
+
res.end(JSON.stringify({
|
|
61
|
+
status: "error",
|
|
62
|
+
message: err instanceof Error ? err.message : String(err)
|
|
63
|
+
}));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** Register the phone-access trampoline plugin. */
|
|
67
|
+
function apply(ctx, config = {}) {
|
|
68
|
+
const cfg = {
|
|
69
|
+
...defaultConfig(),
|
|
70
|
+
...config
|
|
71
|
+
};
|
|
72
|
+
serverPort = cfg.port;
|
|
73
|
+
tokenFilePath = cfg.tokenFile;
|
|
74
|
+
targetUrl = cfg.targetUrl;
|
|
75
|
+
ctx.logger.info("phone-access", `registering trampoline on port ${cfg.port}`);
|
|
76
|
+
server = createServer((req, res) => {
|
|
77
|
+
handleRequest(req, res, cfg);
|
|
78
|
+
});
|
|
79
|
+
server.listen(cfg.port, () => {
|
|
80
|
+
ctx.logger.info("phone-access", `trampoline listening on :${cfg.port}`);
|
|
81
|
+
});
|
|
82
|
+
ctx.tools.register(defineTool({
|
|
83
|
+
name: "phone_access_status",
|
|
84
|
+
description: "Query the phone access trampoline status and configuration.",
|
|
85
|
+
parameters: {},
|
|
86
|
+
output: {
|
|
87
|
+
schema: { type: "json" },
|
|
88
|
+
render: (_args, value) => [{
|
|
89
|
+
type: "text",
|
|
90
|
+
text: JSON.stringify(value, null, 2)
|
|
91
|
+
}]
|
|
92
|
+
},
|
|
93
|
+
execute: async () => {
|
|
94
|
+
return {
|
|
95
|
+
status: server?.listening ? "running" : "stopped",
|
|
96
|
+
port: serverPort,
|
|
97
|
+
target: targetUrl,
|
|
98
|
+
tokenFile: tokenFilePath
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}));
|
|
102
|
+
ctx.tools.register(defineTool({
|
|
103
|
+
name: "phone_access_url",
|
|
104
|
+
description: "Get the current phone access URL (with fresh token).",
|
|
105
|
+
parameters: {},
|
|
106
|
+
output: {
|
|
107
|
+
schema: { type: "json" },
|
|
108
|
+
render: (_args, value) => [{
|
|
109
|
+
type: "text",
|
|
110
|
+
text: JSON.stringify(value, null, 2)
|
|
111
|
+
}]
|
|
112
|
+
},
|
|
113
|
+
execute: async () => {
|
|
114
|
+
try {
|
|
115
|
+
const token = await readToken(tokenFilePath);
|
|
116
|
+
return {
|
|
117
|
+
url: `${targetUrl}/?token=${token}`,
|
|
118
|
+
bookmark: `http://localhost:${serverPort}/dsh`
|
|
119
|
+
};
|
|
120
|
+
} catch (err) {
|
|
121
|
+
return { error: err instanceof Error ? err.message : String(err) };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}));
|
|
125
|
+
ctx.effect(() => {
|
|
126
|
+
return () => {
|
|
127
|
+
ctx.logger.info("phone-access", "shutting down trampoline");
|
|
128
|
+
server?.close();
|
|
129
|
+
server = null;
|
|
130
|
+
};
|
|
131
|
+
}, "phone-access: shutdown");
|
|
132
|
+
}
|
|
133
|
+
//#endregion
|
|
134
|
+
export { apply, inject, name };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"fileNames":["../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es5.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2015.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2016.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2017.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2018.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2019.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2020.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2021.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2022.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2023.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2024.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.dom.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.dom.iterable.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.dom.asynciterable.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.webworker.importscripts.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.scripthost.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2015.core.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2015.collection.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2015.generator.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2015.promise.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2016.intl.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2017.date.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2017.object.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2017.string.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2017.intl.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2018.intl.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2018.promise.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2019.array.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2019.object.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2019.string.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2019.intl.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2020.date.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2020.promise.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2020.string.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2020.intl.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2020.number.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2021.promise.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2021.string.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2021.intl.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2022.array.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2022.error.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2022.intl.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2022.object.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2022.string.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2023.array.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2023.collection.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2023.intl.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2024.collection.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2024.object.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2024.promise.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2024.regexp.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2024.string.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.decorators.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../../../node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2024.full.d.ts","../../../../vendor/cosmokit/lib/types/array.d.ts","../../../../vendor/cosmokit/lib/types/types.d.ts","../../../../vendor/cosmokit/lib/types/misc.d.ts","../../../../vendor/cosmokit/lib/types/string.d.ts","../../../../vendor/cosmokit/lib/types/time.d.ts","../../../../vendor/cosmokit/lib/types/index.d.ts","../../../../node_modules/.pnpm/@standard-schema+spec@1.1.0/node_modules/@standard-schema/spec/dist/index.d.ts","../../../../vendor/cordis/lib/types/utils.d.ts","../../../../vendor/cordis/lib/types/registry.d.ts","../../../../vendor/cordis/lib/types/reflect.d.ts","../../../../vendor/cordis/lib/types/fiber.d.ts","../../../../vendor/cordis/lib/types/events.d.ts","../../../../vendor/cordis/lib/types/logger.d.ts","../../../../vendor/cordis/lib/types/context.d.ts","../../../../vendor/cordis/lib/types/service.d.ts","../../../../vendor/cordis/lib/types/index.d.ts","../../../../vendor/schemastery/lib/types/index.d.ts","../../../core/scope/lib/types/store.d.ts","../../../core/scope/lib/types/index.d.ts","../../../typert/protocol/lib/types/remote-error.d.ts","../../../typert/protocol/lib/types/types.d.ts","../../../typert/protocol/lib/types/index.d.ts","../../../util/brand/lib/types/index.d.ts","../../../attachment/attachment/lib/types/error.d.ts","../../../attachment/attachment/lib/types/brand.d.ts","../../../attachment/attachment/lib/types/types.d.ts","../../../attachment/attachment/lib/types/admission.d.ts","../../../attachment/attachment/lib/types/request-projection.d.ts","../../../attachment/attachment/lib/types/index.d.ts","../../../llm/llm/lib/types/brand.d.ts","../../../llm/llm/lib/types/message.d.ts","../../../llm/llm/lib/types/types.d.ts","../../../llm/llm/lib/types/retry-policy.d.ts","../../../llm/llm/lib/types/call-config.d.ts","../../../llm/llm/lib/types/error.d.ts","../../../llm/llm/lib/types/attribution.d.ts","../../../llm/llm/lib/types/api-key.d.ts","../../../llm/llm/lib/types/content.d.ts","../../../llm/llm/lib/types/assembler.d.ts","../../../llm/llm/lib/types/assistant-stream.d.ts","../../../llm/llm/lib/types/index.d.ts","../../../util/values/lib/types/index.d.ts","../../../core/session/lib/types/types.d.ts","../../../core/session/lib/types/surface.d.ts","../../../core/session/lib/types/preparation.d.ts","../../../core/session/lib/types/repair.d.ts","../../../core/session/lib/types/request-header.d.ts","../../../core/session/lib/types/known-event-types.d.ts","../../../core/session/lib/types/seq-ranges.d.ts","../../../core/session/lib/types/index.d.ts","../../../core/agent/lib/types/types.d.ts","../../../core/agent/lib/types/runtime-types.d.ts","../../../core/agent/lib/types/projection.d.ts","../../../core/agent/lib/types/consumed-work.d.ts","../../../core/agent/lib/types/model-selection.d.ts","../../../core/system-prompt/lib/types/index.d.ts","../../../core/agent/lib/types/dispatch.d.ts","../../../core/agent/lib/types/index.d.ts","../../../core/tools/lib/types/presentation.d.ts","../../../core/tools/lib/types/json-schema.d.ts","../../../core/tools/lib/types/schema.d.ts","../../../core/tools/lib/types/types.d.ts","../../../code-runtime/code-runtime/lib/types/types.d.ts","../../../code-runtime/code-runtime/lib/types/index.d.ts","../../../core/tools/lib/types/ptc.d.ts","../../../core/tools/lib/types/ts-types.d.ts","../../../core/tools/lib/types/py-types.d.ts","../../../core/tools/lib/types/testing.d.ts","../../../core/tools/lib/types/index.d.ts","../src/index.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/compatibility/disposable.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/compatibility/indexable.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/compatibility/iterators.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/compatibility/index.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/globals.typedarray.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/buffer.buffer.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/globals.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/web-globals/abortcontroller.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/web-globals/domexception.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/web-globals/events.d.ts","../../../../node_modules/.pnpm/buffer@5.7.1/node_modules/buffer/index.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/header.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/readable.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/file.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/fetch.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/formdata.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/connector.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/client.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/errors.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/dispatcher.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/global-dispatcher.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/global-origin.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/pool-stats.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/pool.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/handlers.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/balanced-pool.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/agent.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/mock-interceptor.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/mock-agent.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/mock-client.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/mock-pool.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/mock-errors.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/proxy-agent.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/env-http-proxy-agent.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/retry-handler.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/retry-agent.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/api.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/interceptors.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/util.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/cookies.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/patch.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/websocket.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/eventsource.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/filereader.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/diagnostics-channel.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/content-type.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/cache.d.ts","../../../../node_modules/.pnpm/undici-types@6.21.0/node_modules/undici-types/index.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/web-globals/fetch.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/web-globals/navigator.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/web-globals/storage.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/web-globals/streams.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/assert.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/assert/strict.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/async_hooks.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/buffer.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/child_process.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/cluster.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/console.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/constants.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/crypto.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/dgram.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/diagnostics_channel.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/dns.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/dns/promises.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/domain.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/events.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/fs.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/fs/promises.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/http.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/http2.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/https.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/inspector.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/inspector.generated.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/module.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/net.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/os.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/path.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/perf_hooks.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/process.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/punycode.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/querystring.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/readline.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/readline/promises.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/repl.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/sea.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/sqlite.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/stream.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/stream/promises.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/stream/consumers.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/stream/web.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/string_decoder.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/test.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/timers.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/timers/promises.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/tls.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/trace_events.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/tty.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/url.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/util.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/v8.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/vm.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/wasi.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/worker_threads.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/zlib.d.ts","../../../../node_modules/.pnpm/@types+node@22.20.0/node_modules/@types/node/index.d.ts"],"fileIdsList":[[151,201,218,219],[151,198,199,201,218,219],[151,200,201,218,219],[201,218,219],[151,201,206,218,219,236],[151,201,202,207,212,218,219,221,233,244],[151,201,202,203,212,218,219,221],[146,147,148,151,201,218,219],[151,201,204,218,219,245],[151,201,205,206,213,218,219,222],[151,201,206,218,219,233,241],[151,201,207,209,212,218,219,221],[151,200,201,208,218,219],[151,201,209,210,218,219],[151,201,211,212,218,219],[151,200,201,212,218,219],[151,201,212,213,214,218,219,233,244],[151,201,212,213,214,218,219,228,233,236],[151,193,201,209,212,215,218,219,221,233,244],[151,201,212,213,215,216,218,219,221,233,241,244],[151,201,215,217,218,219,233,241,244],[149,150,151,152,153,154,155,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250],[151,201,212,218,219],[151,201,218,219,220,244],[151,201,209,212,218,219,221,233],[151,201,218,219,222],[151,201,218,219,223],[151,200,201,218,219,224],[151,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250],[151,201,218,219,226],[151,201,218,219,227],[151,201,212,218,219,228,229],[151,201,218,219,228,230,245,247],[151,201,213,218,219],[151,201,212,218,219,233,234,236],[151,201,218,219,235,236],[151,201,218,219,233,234],[151,201,218,219,236],[151,201,218,219,237],[151,198,201,218,219,233,238,244],[151,201,212,218,219,239,240],[151,201,218,219,239,240],[151,201,206,218,219,221,233,241],[151,201,218,219,242],[151,201,218,219,221,243],[151,201,215,218,219,227,244],[151,201,206,218,219,245],[151,201,218,219,233,246],[151,201,218,219,220,247],[151,201,218,219,248],[151,193,201,218,219],[151,193,201,212,214,218,219,224,233,236,244,246,247,249],[151,201,218,219,233,250],[151,165,169,201,218,219,244],[151,165,201,218,219,233,244],[151,160,201,218,219],[151,162,165,201,218,219,241,244],[151,201,218,219,221,241],[151,201,218,219,251],[151,160,201,218,219,251],[151,162,165,201,218,219,221,244],[151,157,158,161,164,201,212,218,219,233,244],[151,165,172,201,218,219],[151,157,163,201,218,219],[151,165,186,187,201,218,219],[151,161,165,201,218,219,236,244,251],[151,186,201,218,219,251],[151,159,160,201,218,219,251],[151,165,201,218,219],[151,159,160,161,162,163,164,165,166,167,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,187,188,189,190,191,192,201,218,219],[151,165,180,201,218,219],[151,165,172,173,201,218,219],[151,163,165,173,174,201,218,219],[151,164,201,218,219],[151,157,160,165,201,218,219],[151,165,169,173,174,201,218,219],[151,169,201,218,219],[151,163,165,168,201,218,219,244],[151,157,162,165,172,201,218,219],[151,201,218,219,233],[151,160,165,186,201,218,219,249,251],[101,104,151,201,218,219],[98,151,201,218,219],[91,96,99,100,101,102,103,104,107,116,125,127,131,133,139,144,151,201,218,219],[100,151,201,218,219],[91,96,104,107,116,125,127,131,133,138,139,144,151,201,218,219],[125,151,201,218,219],[91,94,96,104,107,116,125,126,127,131,133,139,144,151,201,218,219],[91,96,104,107,116,125,126,127,128,129,130,131,132,133,139,144,151,201,218,219],[91,96,104,107,116,125,127,131,133,139,144,151,201,218,219],[126,127,151,201,218,219],[97,107,117,118,125,126,137,151,201,218,219],[91,93,96,104,107,116,125,127,131,133,139,144,151,201,218,219],[91,94,96,104,107,116,125,127,131,133,139,144,151,201,218,219],[91,94,96,97,104,107,116,118,119,120,121,122,123,124,125,126,127,131,133,137,139,144,151,201,218,219],[118,126,137,151,201,218,219],[116,118,126,137,151,201,218,219],[97,98,107,116,117,125,126,151,201,218,219],[91,92,94,96,104,107,116,125,127,131,133,139,144,151,201,218,219],[91,92,94,96,104,107,116,117,125,127,131,133,134,135,136,137,139,140,141,142,143,144,151,201,218,219],[116,117,151,201,218,219],[116,151,201,218,219],[116,139,144,151,201,218,219],[141,151,201,218,219],[116,117,134,135,144,151,201,218,219],[116,136,144,151,201,218,219],[116,135,151,201,218,219],[105,107,118,126,151,201,218,219],[91,96,104,107,116,117,125,127,131,133,139,144,151,201,214,215,218,219,222],[106,107,151,201,218,219],[105,107,114,151,201,218,219],[105,107,151,201,218,219],[104,106,107,151,201,218,219],[91,96,97,104,105,106,107,108,109,110,111,112,113,114,115,116,118,125,126,127,131,133,139,144,151,201,218,219],[92,151,201,218,219],[91,96,97,98,104,105,106,116,118,125,126,127,131,133,139,144,151,201,218,219],[91,95,96,104,107,116,125,127,131,133,139,144,151,201,218,219],[96,151,201,218,219],[81,83,84,85,86,87,88,151,201,218,219],[81,84,85,86,87,88,89,151,201,218,219],[81,82,83,84,85,86,87,88,89,151,201,218,219],[83,84,85,86,87,88,89,90,151,201,218,219],[83,84,85,86,87,88,89,151,201,218,219],[76,77,78,79,80,151,201,218,219],[81,82,151,201,218,219]],"fileInfos":[{"version":"bcd24271a113971ba9eb71ff8cb01bc6b0f872a85c23fdbe5d93065b375933cd","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f88bedbeb09c6f5a6645cb24c7c55f1aa22d19ae96c8e6959cbd8b85a707bc6","impliedFormat":1},{"version":"7fe93b39b810eadd916be8db880dd7f0f7012a5cc6ffb62de8f62a2117fa6f1f","impliedFormat":1},{"version":"bb0074cc08b84a2374af33d8bf044b80851ccc9e719a5e202eacf40db2c31600","impliedFormat":1},{"version":"1a7daebe4f45fb03d9ec53d60008fbf9ac45a697fdc89e4ce218bc94b94f94d6","impliedFormat":1},{"version":"f94b133a3cb14a288803be545ac2683e0d0ff6661bcd37e31aaaec54fc382aed","impliedFormat":1},{"version":"f59d0650799f8782fd74cf73c19223730c6d1b9198671b1c5b3a38e1188b5953","impliedFormat":1},{"version":"8a15b4607d9a499e2dbeed9ec0d3c0d7372c850b2d5f1fb259e8f6d41d468a84","impliedFormat":1},{"version":"26e0fe14baee4e127f4365d1ae0b276f400562e45e19e35fd2d4c296684715e6","impliedFormat":1},{"version":"1e9332c23e9a907175e0ffc6a49e236f97b48838cc8aec9ce7e4cec21e544b65","impliedFormat":1},{"version":"3753fbc1113dc511214802a2342280a8b284ab9094f6420e7aa171e868679f91","impliedFormat":1},{"version":"d6b1eba8496bdd0eed6fc8a685768fe01b2da4a0388b5fe7df558290bffcf32f","affectsGlobalScope":true,"impliedFormat":1},{"version":"7f57fc4404ff020bc45b9c620aff2b40f700b95fe31164024c453a5e3c163c54","impliedFormat":1},{"version":"7f57fc4404ff020bc45b9c620aff2b40f700b95fe31164024c453a5e3c163c54","impliedFormat":1},{"version":"2a2de5b9459b3fc44decd9ce6100b72f1b002ef523126c1d3d8b2a4a63d74d78","affectsGlobalScope":true,"impliedFormat":1},{"version":"f13f4b465c99041e912db5c44129a94588e1aafee35a50eab51044833f50b4ee","affectsGlobalScope":true,"impliedFormat":1},{"version":"eadcffda2aa84802c73938e589b9e58248d74c59cb7fcbca6474e3435ac15504","affectsGlobalScope":true,"impliedFormat":1},{"version":"105ba8ff7ba746404fe1a2e189d1d3d2e0eb29a08c18dded791af02f29fb4711","affectsGlobalScope":true,"impliedFormat":1},{"version":"00343ca5b2e3d48fa5df1db6e32ea2a59afab09590274a6cccb1dbae82e60c7c","affectsGlobalScope":true,"impliedFormat":1},{"version":"ebd9f816d4002697cb2864bea1f0b70a103124e18a8cd9645eeccc09bdf80ab4","affectsGlobalScope":true,"impliedFormat":1},{"version":"2c1afac30a01772cd2a9a298a7ce7706b5892e447bb46bdbeef720f7b5da77ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"7b0225f483e4fa685625ebe43dd584bb7973bbd84e66a6ba7bbe175ee1048b4f","affectsGlobalScope":true,"impliedFormat":1},{"version":"c0a4b8ac6ce74679c1da2b3795296f5896e31c38e888469a8e0f99dc3305de60","affectsGlobalScope":true,"impliedFormat":1},{"version":"3084a7b5f569088e0146533a00830e206565de65cae2239509168b11434cd84f","affectsGlobalScope":true,"impliedFormat":1},{"version":"c5079c53f0f141a0698faa903e76cb41cd664e3efb01cc17a5c46ec2eb0bef42","affectsGlobalScope":true,"impliedFormat":1},{"version":"32cafbc484dea6b0ab62cf8473182bbcb23020d70845b406f80b7526f38ae862","affectsGlobalScope":true,"impliedFormat":1},{"version":"fca4cdcb6d6c5ef18a869003d02c9f0fd95df8cfaf6eb431cd3376bc034cad36","affectsGlobalScope":true,"impliedFormat":1},{"version":"b93ec88115de9a9dc1b602291b85baf825c85666bf25985cc5f698073892b467","affectsGlobalScope":true,"impliedFormat":1},{"version":"f5c06dcc3fe849fcb297c247865a161f995cc29de7aa823afdd75aaaddc1419b","affectsGlobalScope":true,"impliedFormat":1},{"version":"b77e16112127a4b169ef0b8c3a4d730edf459c5f25fe52d5e436a6919206c4d7","affectsGlobalScope":true,"impliedFormat":1},{"version":"fbffd9337146eff822c7c00acbb78b01ea7ea23987f6c961eba689349e744f8c","affectsGlobalScope":true,"impliedFormat":1},{"version":"a995c0e49b721312f74fdfb89e4ba29bd9824c770bbb4021d74d2bf560e4c6bd","affectsGlobalScope":true,"impliedFormat":1},{"version":"c7b3542146734342e440a84b213384bfa188835537ddbda50d30766f0593aff9","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce6180fa19b1cccd07ee7f7dbb9a367ac19c0ed160573e4686425060b6df7f57","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f02e2476bccb9dbe21280d6090f0df17d2f66b74711489415a8aa4df73c9675","affectsGlobalScope":true,"impliedFormat":1},{"version":"45e3ab34c1c013c8ab2dc1ba4c80c780744b13b5676800ae2e3be27ae862c40c","affectsGlobalScope":true,"impliedFormat":1},{"version":"805c86f6cca8d7702a62a844856dbaa2a3fd2abef0536e65d48732441dde5b5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"e42e397f1a5a77994f0185fd1466520691456c772d06bf843e5084ceb879a0ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"f4c2b41f90c95b1c532ecc874bd3c111865793b23aebcc1c3cbbabcd5d76ffb0","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab26191cfad5b66afa11b8bf935ef1cd88fabfcb28d30b2dfa6fad877d050332","affectsGlobalScope":true,"impliedFormat":1},{"version":"2088bc26531e38fb05eedac2951480db5309f6be3fa4a08d2221abb0f5b4200d","affectsGlobalScope":true,"impliedFormat":1},{"version":"cb9d366c425fea79716a8fb3af0d78e6b22ebbab3bd64d25063b42dc9f531c1e","affectsGlobalScope":true,"impliedFormat":1},{"version":"500934a8089c26d57ebdb688fc9757389bb6207a3c8f0674d68efa900d2abb34","affectsGlobalScope":true,"impliedFormat":1},{"version":"689da16f46e647cef0d64b0def88910e818a5877ca5379ede156ca3afb780ac3","affectsGlobalScope":true,"impliedFormat":1},{"version":"bc21cc8b6fee4f4c2440d08035b7ea3c06b3511314c8bab6bef7a92de58a2593","affectsGlobalScope":true,"impliedFormat":1},{"version":"7ca53d13d2957003abb47922a71866ba7cb2068f8d154877c596d63c359fed25","affectsGlobalScope":true,"impliedFormat":1},{"version":"54725f8c4df3d900cb4dac84b64689ce29548da0b4e9b7c2de61d41c79293611","affectsGlobalScope":true,"impliedFormat":1},{"version":"e5594bc3076ac29e6c1ebda77939bc4c8833de72f654b6e376862c0473199323","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f3eb332c2d73e729f3364fcc0c2b375e72a121e8157d25a82d67a138c83a95c","affectsGlobalScope":true,"impliedFormat":1},{"version":"6f4427f9642ce8d500970e4e69d1397f64072ab73b97e476b4002a646ac743b1","affectsGlobalScope":true,"impliedFormat":1},{"version":"48915f327cd1dea4d7bd358d9dc7732f58f9e1626a29cc0c05c8c692419d9bb7","affectsGlobalScope":true,"impliedFormat":1},{"version":"b7bf9377723203b5a6a4b920164df22d56a43f593269ba6ae1fdc97774b68855","affectsGlobalScope":true,"impliedFormat":1},{"version":"db9709688f82c9e5f65a119c64d835f906efe5f559d08b11642d56eb85b79357","affectsGlobalScope":true,"impliedFormat":1},{"version":"4b25b8c874acd1a4cf8444c3617e037d444d19080ac9f634b405583fd10ce1f7","affectsGlobalScope":true,"impliedFormat":1},{"version":"37be57d7c90cf1f8112ee2636a068d8fd181289f82b744160ec56a7dc158a9f5","affectsGlobalScope":true,"impliedFormat":1},{"version":"a917a49ac94cd26b754ab84e113369a75d1a47a710661d7cd25e961cc797065f","affectsGlobalScope":true,"impliedFormat":1},{"version":"6d3261badeb7843d157ef3e6f5d1427d0eeb0af0cf9df84a62cfd29fd47ac86e","affectsGlobalScope":true,"impliedFormat":1},{"version":"195daca651dde22f2167ac0d0a05e215308119a3100f5e6268e8317d05a92526","affectsGlobalScope":true,"impliedFormat":1},{"version":"8b11e4285cd2bb164a4dc09248bdec69e9842517db4ca47c1ba913011e44ff2f","affectsGlobalScope":true,"impliedFormat":1},{"version":"0508571a52475e245b02bc50fa1394065a0a3d05277fbf5120c3784b85651799","affectsGlobalScope":true,"impliedFormat":1},{"version":"8f9af488f510c3015af3cc8c267a9e9d96c4dd38a1fdff0e11dc5a544711415b","affectsGlobalScope":true,"impliedFormat":1},{"version":"fc611fea8d30ea72c6bbfb599c9b4d393ce22e2f5bfef2172534781e7d138104","affectsGlobalScope":true,"impliedFormat":1},{"version":"0bd714129fca875f7d4c477a1a392200b0bcd13fb2e80928cd334b63830ea047","affectsGlobalScope":true,"impliedFormat":1},{"version":"e2c9037ae6cd2c52d80ceef0b3c5ffdb488627d71529cf4f63776daf11161c9a","affectsGlobalScope":true,"impliedFormat":1},{"version":"135d5cf4d345f59f1a9caadfafcd858d3d9cc68290db616cc85797224448cccc","affectsGlobalScope":true,"impliedFormat":1},{"version":"bc238c3f81c2984751932b6aab223cd5b830e0ac6cad76389e5e9d2ffc03287d","affectsGlobalScope":true,"impliedFormat":1},{"version":"4a07f9b76d361f572620927e5735b77d6d2101c23cdd94383eb5b706e7b36357","affectsGlobalScope":true,"impliedFormat":1},{"version":"7c4e8dc6ab834cc6baa0227e030606d29e3e8449a9f67cdf5605ea5493c4db29","affectsGlobalScope":true,"impliedFormat":1},{"version":"de7ba0fd02e06cd9a5bd4ab441ed0e122735786e67dde1e849cced1cd8b46b78","affectsGlobalScope":true,"impliedFormat":1},{"version":"6148e4e88d720a06855071c3db02069434142a8332cf9c182cda551adedf3156","affectsGlobalScope":true,"impliedFormat":1},{"version":"d63dba625b108316a40c95a4425f8d4294e0deeccfd6c7e59d819efa19e23409","affectsGlobalScope":true,"impliedFormat":1},{"version":"0568d6befee03dd435bed4fc25c4e46865b24bdcb8c563fdc21f580a2c301904","affectsGlobalScope":true,"impliedFormat":1},{"version":"1ce14b81c5cc821994aa8ec1d42b220dd41b27fcc06373bce3958af7421b77d4","affectsGlobalScope":true,"impliedFormat":1},{"version":"b3a048b3e9302ef9a34ef4ebb9aecfb28b66abb3bce577206a79fee559c230da","affectsGlobalScope":true,"impliedFormat":1},{"version":"b9f65879de79a7647ad2e5b8089277c215911fa99d4b858d78014df6ba2852f3","impliedFormat":1},"fb6f2007d60e8b519a2ef0c5a27026ddfe06418ae6261c4eb0cb670cca5e1bc2","a48f1b69ec0b94b16c7ece2cf6d6003cc8d0c329538117c1c364d8525a100850","cd5713ac354e4869fdf837e12d24d3ae14fd9d94a5bb2d340df63b899b74e6ca","56210599298d6eca6285eab99c7e9333d7e275c3a73a7f401b3055e8d55c67e8","2845576622e416da9871e1f3c788ba41dc4f24eb764362b10eceeb0dbaa67208","f0421e04e2a5238754cf444bf2a56fe7e7a94a08c14c1f9d063ff51c85825823",{"version":"bdd14f07b4eca0b4b5203b85b8dbc4d084c749fa590bee5ea613e1641dcd3b29","impliedFormat":99},"967b227fad024ba8a7c32127534089bce5adc800840b0288f44d41c4c849278e","ffd229492af3cb444c01e8e51a78dfdbed670940bac40dde083675d57d6984fc","57cdef8252cb041b4b646cc9e80dcb27d2180bb78fcf95761136d99be4079cb3","eb5fd8d19b0330da4dccb6cab3eae0304f056ac8fbd5bd9589ce48f0920bff78","db565a086622cbe616a950186dc90e82a74060864b9cd1d0f25285860daea9b4","71087395cc862f52662ab2629a0f3838f8f2aaf84eb40c97f4f4004f2fcbbed6","1e2e6cfcab26ae01d7f2dd1f78a1d25ddb7f3b2e27f50c9eb3b54ee206a87884","489ec23ef8dc0e869cf3d8d77a39ba83ab24e5e71362320f5662491b3dc5bd04","c93dd79fae382105510c69cc8eef95a96c8c43e50b47e16efa98a3f9e76f304b",{"version":"bb2f86815e0ffd28aff945931828a38ab6e6b1eb33b93cbb108315c2e94f8b2b","affectsGlobalScope":true},"7e39ec51a9b5df26b5e7e9c37992c90654d859017c9fb41fcbdb4c3c3a27ff9e","fd320d8bcafb6707284ca545fc93ffd25ad68663afe37f7060c5f6e2baee122b","db5c5149222e2a6aa8bb1e57221c84eeb539ec4d1c33cbe3e0e4ae3d41c0f900","5ae55305450060b36bfc0540503fcf12fa943fb042b91425c6f27214d8913eb7","020935b467371dbcbb37f04b16d78eb81151f3bb8e32c8eb9e6e31e1dc9c39e1","233a1203b6c93a2a56870f5a09c3d94ef899edc6cb4ae93ae93a40cd76653af1","3244ad5cb1ca32eb9dce7517675013ed2dc9abd4773c93edd014da3ee515eb79","8311e5e89b0bbfe25bc3ceade9fb2e0540e030dc54b0dff16d0acf03612b6fb6","7e7ec02f2d2678e50825c4dd518eb275f5b0f64ac743a103760497db73bb2a64","1fe57cbfd29bfca344e8492ebbda7b95421567520c8cc29efd6959aef4be7787","cb3857fe98ef2a74c01c6f51c4d0ab5cb897446b8996a2e7b966fd2f778ad119","8b7fb3797be69673854f5ff15875d83c7de2b6f0cf85629b2428c02f9a288a65","852fa334ecb9986c8c1ddb0931aa3ce4975bfdaaed13995230a0c3ad19133db0","532cb29f3e7bbe0195f48310ff711a17357053e7a610f6d765618eaf64bd028a","f72b39a73d497914f0c44e98dadbf0a31b6302642c24f5ec77e1e65be52efc7f","8fcd1d7a60d4f123f9c9242e565a8df5fe7eb2562edf176ec1c7575f729a0b2b","6f98290a2699d19f03a2d2633a2535a3639b23aa6cfdb0f4e9852766eda8f35a","4abfc87dc2dccc299f7cb0aa039632aad2374013bca5bc424bd858316c81b132","c3c6223f2d64f73b6a0a145b968764301335856a66292c3f31f9d488ba429c9c","36fe909bb584c7be20fb9d2b60dbb0f0460b27938bcd7b922446dd7480c0fd31","3b98b940e995506ff74aed79dbf1dd7852ea6e9f735fe183052214c237b0a65d","aeb7c18a61c3976a09f59bc8b1bf9e0f8574eb281630d33a8cd198af8a1c962a","222880b378df79a18413e3381ee16f3f17758f30cfbffd55f05e21e768e33d2d","db66b1586e31fbaa30000997dfa6c5da72e3650512c2797b5b370c7fdb175ae2","644797eb565b1349d96093f2ee700da31be9f682a484b44b75e93318926f100b","53c7c1c2c9f7284e719977f42c429a51edfd559984fc6c84ff6b65001c30b7ce","b7fea6e2de185f12e9fea68b5a4c15ad9908c5f6164a6ba9eafeca43cf55bc5b","de7e63725939d31ddfda7aa38cb9cba8d6d71a1653b34ba784a7d66bb45cb43f","97d48d7e667fd8ef259ab08687a4c851b1d61c150dca676cf57dd92bc6ff202f","4220ce437a955b509d9faab7946effbd436ad0d14e8580e14783f99e5e0c4c02","732c9f83716d9f7d90975dd997e72257e68ed2a548b4a147fc1775056bebc978","144ac638deb06f3e11b5354e7334c4e6f163e966259d13eae3bbdc2f8c1f5181","563e5ad2ecbd6e9f6632c7d505cc856cdef6c613332aa90fde46fffbb4950e60","712f093f1df0338cefe89e7bf809db514e165834858e60222a7bcc4d6b1bb0c7","7493c670f5572cc9bf4a165c6f74ddbed2de5734dd96c85576800d4247985564","779048317ce2e65cb1d67300bfbbe1e2e3b16982beee682b510643675f6d2615","3ffce582c2e44b0a1d52449325c3282bf0ee822fcd1daac2988a4060f4ac43a4","e43aa0d5bc2d2f40c6725a174f8842ce357c2fb922c4ab3b75dd57d7b5d0fe63","4346075cabb6c4c1d995f6e68f5ec2ed869c03b35883e04c03ab4007d32dfd7d","262107b570d819f43dc72f6c0164b0d1e2530aab491a254e5fdc6017997b3afe","b299cfcebcf920f59b27d04564a9da8e524b2ceb36a15f41502c610071f4f8bf","bd37789e4e28a495dfd85f2f02c42d47a8e62d485a29cf3ef88635c9ee3c989d","7703b3a083ab1d515cf212a3c7a7ae3d03b7eeaf571204649ba4595863ab6fcd","3fe15dc7f48fc88d70c6614fd8582576fee1c30f49201adf108841222f6d2542","979e096ed9c2c6e673ffa7ef03daeb7c4a1e5dd95a6d75c1c9f58e60cde039ae","f697937fd206e360755d2452fed48695513a7ae1a041768de2f8c14d42e3fd9a","a88de311d12309c4c329639b44b0a23d4756168908a9515f0ec732eab48cc530","d339f4b6e03f899f54bf54f78ed86914dbc0114718a4923c8c5578e3f238f21c","68d0000da28067ecda7a039d1e1baeeb1a983df578d2f22e5139447727916559","b554ce2cc981b9f2fad3fb255bbc2480bc09f79c656ed105f7844e2fbe6affae","0815bb3e7047125b185e43035b8c1f537653ea8712d4ed27e416666c9cb411d0","2442e863890d7f4266532f0df1d0e4db8d521afacf13bf17d7c20c0d5349d5b7",{"version":"bb6ebbef9dc17f688727b7d709d5fa6fcc3f03f7437432f8ffc4811b1942e0dc","signature":"7c619a6a54f1b79891912ec06523c1bfecda0ade9991d8f1d8fdcde4d7a8499b"},{"version":"6c7176368037af28cb72f2392010fa1cef295d6d6744bca8cfb54985f3a18c3e","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab41ef1f2cdafb8df48be20cd969d875602483859dc194e9c97c8a576892c052","affectsGlobalScope":true,"impliedFormat":1},{"version":"437e20f2ba32abaeb7985e0afe0002de1917bc74e949ba585e49feba65da6ca1","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"98cffbf06d6bab333473c70a893770dbe990783904002c4f1a960447b4b53dca","affectsGlobalScope":true,"impliedFormat":1},{"version":"3af97acf03cc97de58a3a4bc91f8f616408099bc4233f6d0852e72a8ffb91ac9","affectsGlobalScope":true,"impliedFormat":1},{"version":"808069bba06b6768b62fd22429b53362e7af342da4a236ed2d2e1c89fcca3b4a","affectsGlobalScope":true,"impliedFormat":1},{"version":"1db0b7dca579049ca4193d034d835f6bfe73096c73663e5ef9a0b5779939f3d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"f26b11d8d8e4b8028f1c7d618b22274c892e4b0ef5b3678a8ccbad85419aef43","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e9c23ba78aabc2e0a27033f18737a6df754067731e69dc5f52823957d60a4b6","impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"763fe0f42b3d79b440a9b6e51e9ba3f3f91352469c1e4b3b67bfa4ff6352f3f4","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"7f182617db458e98fc18dfb272d40aa2fff3a353c44a89b2c0ccb3937709bfb5","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"b52476feb4a0cbcb25e5931b930fc73cb6643fb1a5060bf8a3dda0eeae5b4b68","affectsGlobalScope":true,"impliedFormat":1},{"version":"f9501cc13ce624c72b61f12b3963e84fad210fbdf0ffbc4590e08460a3f04eba","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d97fb21da858fb18b8ae72c314e9743fd52f73ebe2764e12af1db32fc03f853f","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fa06ada475b910e2106c98c68b10483dc8811d0c14a8a8dd36efb2672485b29","impliedFormat":1},{"version":"33e5e9aba62c3193d10d1d33ae1fa75c46a1171cf76fef750777377d53b0303f","impliedFormat":1},{"version":"2b06b93fd01bcd49d1a6bd1f9b65ddcae6480b9a86e9061634d6f8e354c1468f","impliedFormat":1},{"version":"6a0cd27e5dc2cfbe039e731cf879d12b0e2dded06d1b1dedad07f7712de0d7f4","affectsGlobalScope":true,"impliedFormat":1},{"version":"13f5c844119c43e51ce777c509267f14d6aaf31eafb2c2b002ca35584cd13b29","impliedFormat":1},{"version":"e60477649d6ad21542bd2dc7e3d9ff6853d0797ba9f689ba2f6653818999c264","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"4c829ab315f57c5442c6667b53769975acbf92003a66aef19bce151987675bd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"b2ade7657e2db96d18315694789eff2ddd3d8aea7215b181f8a0b303277cc579","impliedFormat":1},{"version":"78dbea00e90d2df8ea3dbef0cc379d95b8be9b71cd6bde4c28728f306811803b","impliedFormat":1},{"version":"4d631b81fa2f07a0e63a9a143d6a82c25c5f051298651a9b69176ba28930756d","impliedFormat":1},{"version":"836a356aae992ff3c28a0212e3eabcb76dd4b0cc06bcb9607aeef560661b860d","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"41670ee38943d9cbb4924e436f56fc19ee94232bc96108562de1a734af20dc2c","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e1e46d0a9837ee058c100501080c920fa98081ea3956af0374308ba6f22a33e","impliedFormat":1},{"version":"22295e8103f1d6d8ea4b5d6211e43421fe4564e34d0dd8e09e520e452d89e659","impliedFormat":1},{"version":"fa7834c715d5357e4540cee40ce96c3250ddb67a7b879a6b7fa0e86d6696f121","impliedFormat":1},{"version":"22dfb07a7ab15b66ac043829056fe70124844636ae719551812ac631ba04985b","impliedFormat":1},{"version":"a10f0e1854f3316d7ee437b79649e5a6ae3ae14ffe6322b02d4987071a95362e","impliedFormat":1},{"version":"e208f73ef6a980104304b0d2ca5f6bf1b85de6009d2c7e404028b875020fa8f2","impliedFormat":1},{"version":"d163b6bc2372b4f07260747cbc6c0a6405ab3fbcea3852305e98ac43ca59f5bc","impliedFormat":1},{"version":"e6fa9ad47c5f71ff733744a029d1dc472c618de53804eae08ffc243b936f87ff","affectsGlobalScope":true,"impliedFormat":1},{"version":"a6f137d651076822d4fe884287e68fd61785a0d3d1fdb250a5059b691fa897db","impliedFormat":1},{"version":"24826ed94a78d5c64bd857570fdbd96229ad41b5cb654c08d75a9845e3ab7dde","impliedFormat":1},{"version":"8b479a130ccb62e98f11f136d3ac80f2984fdc07616516d29881f3061f2dd472","impliedFormat":1},{"version":"928af3d90454bf656a52a48679f199f64c1435247d6189d1caf4c68f2eaf921f","affectsGlobalScope":true,"impliedFormat":1},{"version":"bceb58df66ab8fb00170df20cd813978c5ab84be1d285710c4eb005d8e9d8efb","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"933921f0bb0ec12ef45d1062a1fc0f27635318f4d294e4d99de9a5493e618ca2","impliedFormat":1},{"version":"71a0f3ad612c123b57239a7749770017ecfe6b66411488000aba83e4546fde25","impliedFormat":1},{"version":"77fbe5eecb6fac4b6242bbf6eebfc43e98ce5ccba8fa44e0ef6a95c945ff4d98","impliedFormat":1},{"version":"4f9d8ca0c417b67b69eeb54c7ca1bedd7b56034bb9bfd27c5d4f3bc4692daca7","impliedFormat":1},{"version":"0cb167c371eaa8c869f8a7656a7296f2e4fae43b4d8b803a680236b24794e5f9","impliedFormat":1},{"version":"0a839dba0287cc0481ad4beedd48a1c64acf1e212ae865d1315f7007ca215161","impliedFormat":1},{"version":"38dc4655376cd1a4bd6bb3763d92949233e33d38d3dd3cbea7bbf218175a38ef","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"45650f47bfb376c8a8ed39d4bcda5902ab899a3150029684ee4c10676d9fbaee","impliedFormat":1},{"version":"d61e0a64cd175208ac0b83670151a9a6b5916f0d1ffcdc5c29c90b1cebfc5045","affectsGlobalScope":true,"impliedFormat":1},{"version":"18fd40412d102c5564136f29735e5d1c3b455b8a37f920da79561f1fde068208","impliedFormat":1},{"version":"48a679952eefe4cb776d5a0e1ccba2d3eb53b57448bbb7abc1fcebcbd5440188","impliedFormat":1},{"version":"f0be1b8078cd549d91f37c30c222c2a187ac1cf981d994fb476a1adc61387b14","affectsGlobalScope":true,"impliedFormat":1},{"version":"0aaed1d72199b01234152f7a60046bc947f1f37d78d182e9ae09c4289e06a592","impliedFormat":1},{"version":"2d14da6ecb49bf828d83948765ec2d3a579d476bbb9645e749610baa6ec880ca","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"5b7aa3c4c1a5d81b411e8cb302b45507fea9358d3569196b27eb1a27ae3a90ef","affectsGlobalScope":true,"impliedFormat":1},{"version":"5987a903da92c7462e0b35704ce7da94d7fdc4b89a984871c0e2b87a8aae9e69","affectsGlobalScope":true,"impliedFormat":1},{"version":"ea08a0345023ade2b47fbff5a76d0d0ed8bff10bc9d22b83f40858a8e941501c","impliedFormat":1},{"version":"0aef708fb4c7a6b915e8305cbfac40cd207b032dbaabe9a01889a5fff3254681","impliedFormat":1},{"version":"ae062ce7d9510060c5d7e7952ae379224fb3f8f2dd74e88959878af2057c143b","impliedFormat":1},{"version":"ad9bdafb4e7abf14cc53ce7970486a84c87831e62891e5dfe798ddcd55e84701","affectsGlobalScope":true,"impliedFormat":1},{"version":"358765d5ea8afd285d4fd1532e78b88273f18cb3f87403a9b16fef61ac9fdcfe","impliedFormat":1},{"version":"71d3ae6a5e73ca4130762560425e00984ebaff64d5353a3333d1bb7eb86ef336","impliedFormat":1}],"root":[145],"options":{"allowImportingTsExtensions":true,"composite":true,"declaration":true,"declarationMap":true,"esModuleInterop":true,"exactOptionalPropertyTypes":true,"module":99,"noFallthroughCasesInSwitch":true,"noImplicitOverride":true,"noUncheckedIndexedAccess":true,"noUnusedLocals":true,"noUnusedParameters":true,"outDir":"./types","rewriteRelativeImportExtensions":true,"rootDir":"../src","skipLibCheck":true,"sourceMap":true,"strict":true,"target":11,"verbatimModuleSyntax":false},"referencedMap":[[82,1],[198,2],[199,2],[200,3],[151,4],[201,5],[202,6],[203,7],[146,1],[149,8],[147,1],[148,1],[204,9],[205,10],[206,11],[207,12],[208,13],[209,14],[210,14],[211,15],[212,16],[213,17],[214,18],[152,1],[150,1],[215,19],[216,20],[217,21],[251,22],[218,23],[219,1],[220,24],[221,25],[222,26],[223,27],[224,28],[225,29],[226,30],[227,31],[228,32],[229,32],[230,33],[231,1],[232,34],[233,35],[235,36],[234,37],[236,38],[237,39],[238,40],[239,41],[240,42],[241,43],[242,44],[243,45],[244,46],[245,47],[246,48],[247,49],[248,50],[153,1],[154,1],[155,1],[194,51],[195,1],[196,1],[197,38],[249,52],[250,53],[156,1],[73,1],[74,1],[14,1],[12,1],[13,1],[18,1],[17,1],[2,1],[19,1],[20,1],[21,1],[22,1],[23,1],[24,1],[25,1],[26,1],[3,1],[27,1],[28,1],[4,1],[29,1],[33,1],[30,1],[31,1],[32,1],[34,1],[35,1],[36,1],[5,1],[37,1],[38,1],[39,1],[40,1],[6,1],[44,1],[41,1],[42,1],[43,1],[45,1],[7,1],[46,1],[51,1],[52,1],[47,1],[48,1],[49,1],[50,1],[8,1],[56,1],[53,1],[54,1],[55,1],[57,1],[9,1],[58,1],[59,1],[60,1],[62,1],[61,1],[63,1],[64,1],[10,1],[65,1],[66,1],[67,1],[11,1],[75,1],[68,1],[69,1],[70,1],[71,1],[72,1],[1,1],[16,1],[15,1],[172,54],[182,55],[171,54],[192,56],[163,57],[162,58],[191,59],[185,60],[190,61],[165,62],[179,63],[164,64],[188,65],[160,66],[159,59],[189,67],[161,68],[166,69],[167,1],[170,69],[157,1],[193,70],[183,71],[174,72],[175,73],[177,74],[173,75],[176,76],[186,59],[168,77],[169,78],[178,79],[158,80],[181,71],[180,69],[184,1],[187,81],[102,82],[100,83],[99,1],[104,84],[103,1],[101,85],[139,86],[138,1],[129,87],[132,88],[133,89],[130,90],[128,91],[127,88],[126,92],[94,93],[93,94],[125,95],[123,1],[120,87],[121,96],[122,96],[124,96],[119,97],[118,98],[131,99],[144,100],[135,101],[134,102],[140,103],[142,104],[136,105],[143,106],[141,107],[137,108],[145,109],[112,1],[114,110],[115,111],[111,1],[105,83],[109,112],[113,113],[110,1],[116,114],[106,112],[108,115],[107,116],[97,117],[95,118],[96,117],[98,1],[117,1],[89,119],[87,120],[86,121],[91,122],[88,123],[85,120],[84,121],[90,123],[83,90],[76,1],[81,124],[78,1],[79,1],[80,1],[77,1],[92,125]],"latestChangedDtsFile":"./types/index.d.ts","version":"6.0.3"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @deepseek-ai/dsh-phone-access — DSH phone access token trampoline
|
|
3
|
+
*
|
|
4
|
+
* Provides an HTTP redirect service that allows remote phone access to the
|
|
5
|
+
* DSH Web UI via Tailscale or any network proxy. The trampoline reads the
|
|
6
|
+
* current DSH web-launch-token file on each request and issues fresh
|
|
7
|
+
* token-authenticated redirect URLs, enabling phone access that survives
|
|
8
|
+
* DSH restarts without manual URL updates.
|
|
9
|
+
*
|
|
10
|
+
* Phone access path:
|
|
11
|
+
* phone bookmark → trampoline (this plugin) → 302 → DSH token URL
|
|
12
|
+
* → DSH validates token → sets cookie → 303 → DSH Web UI
|
|
13
|
+
*
|
|
14
|
+
* @module @deepseek-ai/dsh-phone-access
|
|
15
|
+
*/
|
|
16
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
17
|
+
export declare const name = "phone-access";
|
|
18
|
+
export declare const inject: string[];
|
|
19
|
+
/** Plugin configuration. */
|
|
20
|
+
export interface Config {
|
|
21
|
+
/** Port for the trampoline HTTP server. */
|
|
22
|
+
port?: number;
|
|
23
|
+
/** Path to the DSH web-launch-token file. */
|
|
24
|
+
tokenFile?: string;
|
|
25
|
+
/** Target URL for redirects (DSH Web UI base URL). */
|
|
26
|
+
targetUrl?: string;
|
|
27
|
+
}
|
|
28
|
+
/** Register the phone-access trampoline plugin. */
|
|
29
|
+
export declare function apply(ctx: Context, config?: Config): void;
|
|
30
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAIlD,eAAO,MAAM,IAAI,iBAAiB,CAAA;AAClC,eAAO,MAAM,MAAM,EAAE,MAAM,EAAO,CAAA;AAElC,4BAA4B;AAC5B,MAAM,WAAW,MAAM;IACrB,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAmDD,mDAAmD;AACnD,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,GAAE,MAAW,GAAG,IAAI,CA8D7D"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @deepseek-ai/dsh-phone-access — DSH phone access token trampoline
|
|
3
|
+
*
|
|
4
|
+
* Provides an HTTP redirect service that allows remote phone access to the
|
|
5
|
+
* DSH Web UI via Tailscale or any network proxy. The trampoline reads the
|
|
6
|
+
* current DSH web-launch-token file on each request and issues fresh
|
|
7
|
+
* token-authenticated redirect URLs, enabling phone access that survives
|
|
8
|
+
* DSH restarts without manual URL updates.
|
|
9
|
+
*
|
|
10
|
+
* Phone access path:
|
|
11
|
+
* phone bookmark → trampoline (this plugin) → 302 → DSH token URL
|
|
12
|
+
* → DSH validates token → sets cookie → 303 → DSH Web UI
|
|
13
|
+
*
|
|
14
|
+
* @module @deepseek-ai/dsh-phone-access
|
|
15
|
+
*/
|
|
16
|
+
import { createServer } from 'node:http';
|
|
17
|
+
import { readFile } from 'node:fs/promises';
|
|
18
|
+
import { homedir } from 'node:os';
|
|
19
|
+
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
20
|
+
export const name = 'phone-access';
|
|
21
|
+
export const inject = [];
|
|
22
|
+
let server = null;
|
|
23
|
+
let serverPort = 0;
|
|
24
|
+
let tokenFilePath = '';
|
|
25
|
+
let targetUrl = '';
|
|
26
|
+
function defaultConfig() {
|
|
27
|
+
return {
|
|
28
|
+
port: 3090,
|
|
29
|
+
tokenFile: `${homedir()}/.dsh/web-launch-token`,
|
|
30
|
+
targetUrl: 'https://pop-os.taildc49b0.ts.net',
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
async function readToken(path) {
|
|
34
|
+
const content = await readFile(path, 'utf-8');
|
|
35
|
+
return content.trim();
|
|
36
|
+
}
|
|
37
|
+
async function handleRequest(req, res, config) {
|
|
38
|
+
const url = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`);
|
|
39
|
+
try {
|
|
40
|
+
if (url.pathname === '/health') {
|
|
41
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
42
|
+
res.end(JSON.stringify({ status: 'ok', target: config.targetUrl }));
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (url.pathname === '/dsh-url' || url.pathname === '/url') {
|
|
46
|
+
const token = await readToken(config.tokenFile);
|
|
47
|
+
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
|
48
|
+
res.end(`${config.targetUrl}/?token=${token}`);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
// Default: token-authenticated redirect
|
|
52
|
+
const token = await readToken(config.tokenFile);
|
|
53
|
+
const redirectUrl = `${config.targetUrl}/?token=${token}`;
|
|
54
|
+
res.writeHead(302, { 'Location': redirectUrl });
|
|
55
|
+
res.end();
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
59
|
+
res.end(JSON.stringify({
|
|
60
|
+
status: 'error',
|
|
61
|
+
message: err instanceof Error ? err.message : String(err),
|
|
62
|
+
}));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/** Register the phone-access trampoline plugin. */
|
|
66
|
+
export function apply(ctx, config = {}) {
|
|
67
|
+
const cfg = { ...defaultConfig(), ...config };
|
|
68
|
+
serverPort = cfg.port;
|
|
69
|
+
tokenFilePath = cfg.tokenFile;
|
|
70
|
+
targetUrl = cfg.targetUrl;
|
|
71
|
+
ctx.logger.info('phone-access', `registering trampoline on port ${cfg.port}`);
|
|
72
|
+
server = createServer((req, res) => {
|
|
73
|
+
handleRequest(req, res, cfg);
|
|
74
|
+
});
|
|
75
|
+
server.listen(cfg.port, () => {
|
|
76
|
+
ctx.logger.info('phone-access', `trampoline listening on :${cfg.port}`);
|
|
77
|
+
});
|
|
78
|
+
// Register a tool for the agent to query the trampoline status
|
|
79
|
+
ctx.tools.register(defineTool({
|
|
80
|
+
name: 'phone_access_status',
|
|
81
|
+
description: 'Query the phone access trampoline status and configuration.',
|
|
82
|
+
parameters: {},
|
|
83
|
+
output: {
|
|
84
|
+
schema: { type: 'json' },
|
|
85
|
+
render: (_args, value) => [{ type: 'text', text: JSON.stringify(value, null, 2) }],
|
|
86
|
+
},
|
|
87
|
+
execute: async () => {
|
|
88
|
+
return {
|
|
89
|
+
status: server?.listening ? 'running' : 'stopped',
|
|
90
|
+
port: serverPort,
|
|
91
|
+
target: targetUrl,
|
|
92
|
+
tokenFile: tokenFilePath,
|
|
93
|
+
};
|
|
94
|
+
},
|
|
95
|
+
}));
|
|
96
|
+
// Register a tool to get the current phone access URL
|
|
97
|
+
ctx.tools.register(defineTool({
|
|
98
|
+
name: 'phone_access_url',
|
|
99
|
+
description: 'Get the current phone access URL (with fresh token).',
|
|
100
|
+
parameters: {},
|
|
101
|
+
output: {
|
|
102
|
+
schema: { type: 'json' },
|
|
103
|
+
render: (_args, value) => [{ type: 'text', text: JSON.stringify(value, null, 2) }],
|
|
104
|
+
},
|
|
105
|
+
execute: async () => {
|
|
106
|
+
try {
|
|
107
|
+
const token = await readToken(tokenFilePath);
|
|
108
|
+
return { url: `${targetUrl}/?token=${token}`, bookmark: `http://localhost:${serverPort}/dsh` };
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
return { error: err instanceof Error ? err.message : String(err) };
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
}));
|
|
115
|
+
ctx.effect(() => {
|
|
116
|
+
return () => {
|
|
117
|
+
ctx.logger.info('phone-access', 'shutting down trampoline');
|
|
118
|
+
server?.close();
|
|
119
|
+
server = null;
|
|
120
|
+
};
|
|
121
|
+
}, 'phone-access: shutdown');
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lathly/dsh-phone-access",
|
|
3
|
+
"description": "DSH phone access token trampoline — HTTP redirect service for remote phone access via Tailscale",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/Lathly/dsh-phone-access.git"
|
|
9
|
+
},
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/Lathly/dsh-phone-access/issues"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://github.com/Lathly/dsh-phone-access#readme",
|
|
14
|
+
"type": "module",
|
|
15
|
+
"main": "lib/index.js",
|
|
16
|
+
"types": "lib/types/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./lib/types/index.d.ts",
|
|
20
|
+
"default": "./lib/index.js"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"lib/",
|
|
25
|
+
"src/",
|
|
26
|
+
"README.md"
|
|
27
|
+
],
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@deepseek-ai/cordis": "^0.1.0",
|
|
30
|
+
"@deepseek-ai/dsh-tools": "^0.1.0"
|
|
31
|
+
}
|
|
32
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @deepseek-ai/dsh-phone-access — DSH phone access token trampoline
|
|
3
|
+
*
|
|
4
|
+
* Provides an HTTP redirect service that allows remote phone access to the
|
|
5
|
+
* DSH Web UI via Tailscale or any network proxy. The trampoline reads the
|
|
6
|
+
* current DSH web-launch-token file on each request and issues fresh
|
|
7
|
+
* token-authenticated redirect URLs, enabling phone access that survives
|
|
8
|
+
* DSH restarts without manual URL updates.
|
|
9
|
+
*
|
|
10
|
+
* Phone access path:
|
|
11
|
+
* phone bookmark → trampoline (this plugin) → 302 → DSH token URL
|
|
12
|
+
* → DSH validates token → sets cookie → 303 → DSH Web UI
|
|
13
|
+
*
|
|
14
|
+
* @module @deepseek-ai/dsh-phone-access
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { createServer, type IncomingMessage, type ServerResponse } from 'node:http'
|
|
18
|
+
import { readFile } from 'node:fs/promises'
|
|
19
|
+
import { homedir } from 'node:os'
|
|
20
|
+
import type { Context } from '@deepseek-ai/cordis'
|
|
21
|
+
import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
22
|
+
import type { JsonValue } from '@deepseek-ai/dsh-util-values'
|
|
23
|
+
|
|
24
|
+
export const name = 'phone-access'
|
|
25
|
+
export const inject: string[] = []
|
|
26
|
+
|
|
27
|
+
/** Plugin configuration. */
|
|
28
|
+
export interface Config {
|
|
29
|
+
/** Port for the trampoline HTTP server. */
|
|
30
|
+
port?: number
|
|
31
|
+
/** Path to the DSH web-launch-token file. */
|
|
32
|
+
tokenFile?: string
|
|
33
|
+
/** Target URL for redirects (DSH Web UI base URL). */
|
|
34
|
+
targetUrl?: string
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let server: ReturnType<typeof createServer> | null = null
|
|
38
|
+
let serverPort = 0
|
|
39
|
+
let tokenFilePath = ''
|
|
40
|
+
let targetUrl = ''
|
|
41
|
+
|
|
42
|
+
function defaultConfig(): Required<Config> {
|
|
43
|
+
return {
|
|
44
|
+
port: 3090,
|
|
45
|
+
tokenFile: `${homedir()}/.dsh/web-launch-token`,
|
|
46
|
+
targetUrl: 'https://pop-os.taildc49b0.ts.net',
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function readToken(path: string): Promise<string> {
|
|
51
|
+
const content = await readFile(path, 'utf-8')
|
|
52
|
+
return content.trim()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async function handleRequest(req: IncomingMessage, res: ServerResponse, config: Required<Config>) {
|
|
56
|
+
const url = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`)
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
if (url.pathname === '/health') {
|
|
60
|
+
res.writeHead(200, { 'Content-Type': 'application/json' })
|
|
61
|
+
res.end(JSON.stringify({ status: 'ok', target: config.targetUrl }))
|
|
62
|
+
return
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (url.pathname === '/dsh-url' || url.pathname === '/url') {
|
|
66
|
+
const token = await readToken(config.tokenFile)
|
|
67
|
+
res.writeHead(200, { 'Content-Type': 'text/plain' })
|
|
68
|
+
res.end(`${config.targetUrl}/?token=${token}`)
|
|
69
|
+
return
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Default: token-authenticated redirect
|
|
73
|
+
const token = await readToken(config.tokenFile)
|
|
74
|
+
const redirectUrl = `${config.targetUrl}/?token=${token}`
|
|
75
|
+
res.writeHead(302, { 'Location': redirectUrl })
|
|
76
|
+
res.end()
|
|
77
|
+
} catch (err) {
|
|
78
|
+
res.writeHead(500, { 'Content-Type': 'application/json' })
|
|
79
|
+
res.end(JSON.stringify({
|
|
80
|
+
status: 'error',
|
|
81
|
+
message: err instanceof Error ? err.message : String(err),
|
|
82
|
+
}))
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Register the phone-access trampoline plugin. */
|
|
87
|
+
export function apply(ctx: Context, config: Config = {}): void {
|
|
88
|
+
const cfg: Required<Config> = { ...defaultConfig(), ...config }
|
|
89
|
+
|
|
90
|
+
serverPort = cfg.port
|
|
91
|
+
tokenFilePath = cfg.tokenFile
|
|
92
|
+
targetUrl = cfg.targetUrl
|
|
93
|
+
|
|
94
|
+
ctx.logger.info('phone-access', `registering trampoline on port ${cfg.port}`)
|
|
95
|
+
|
|
96
|
+
server = createServer((req, res) => {
|
|
97
|
+
handleRequest(req, res, cfg)
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
server.listen(cfg.port, () => {
|
|
101
|
+
ctx.logger.info('phone-access', `trampoline listening on :${cfg.port}`)
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
// Register a tool for the agent to query the trampoline status
|
|
105
|
+
ctx.tools.register(defineTool({
|
|
106
|
+
name: 'phone_access_status',
|
|
107
|
+
description: 'Query the phone access trampoline status and configuration.',
|
|
108
|
+
parameters: {},
|
|
109
|
+
output: {
|
|
110
|
+
schema: { type: 'json' },
|
|
111
|
+
render: (_args, value) => [{ type: 'text', text: JSON.stringify(value, null, 2) }],
|
|
112
|
+
},
|
|
113
|
+
execute: async (): Promise<JsonValue> => {
|
|
114
|
+
return {
|
|
115
|
+
status: server?.listening ? 'running' : 'stopped',
|
|
116
|
+
port: serverPort,
|
|
117
|
+
target: targetUrl,
|
|
118
|
+
tokenFile: tokenFilePath,
|
|
119
|
+
} as unknown as JsonValue
|
|
120
|
+
},
|
|
121
|
+
}))
|
|
122
|
+
|
|
123
|
+
// Register a tool to get the current phone access URL
|
|
124
|
+
ctx.tools.register(defineTool({
|
|
125
|
+
name: 'phone_access_url',
|
|
126
|
+
description: 'Get the current phone access URL (with fresh token).',
|
|
127
|
+
parameters: {},
|
|
128
|
+
output: {
|
|
129
|
+
schema: { type: 'json' },
|
|
130
|
+
render: (_args, value) => [{ type: 'text', text: JSON.stringify(value, null, 2) }],
|
|
131
|
+
},
|
|
132
|
+
execute: async (): Promise<JsonValue> => {
|
|
133
|
+
try {
|
|
134
|
+
const token = await readToken(tokenFilePath)
|
|
135
|
+
return { url: `${targetUrl}/?token=${token}`, bookmark: `http://localhost:${serverPort}/dsh` } as unknown as JsonValue
|
|
136
|
+
} catch (err) {
|
|
137
|
+
return { error: err instanceof Error ? err.message : String(err) } as unknown as JsonValue
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
}))
|
|
141
|
+
|
|
142
|
+
ctx.effect(() => {
|
|
143
|
+
return () => {
|
|
144
|
+
ctx.logger.info('phone-access', 'shutting down trampoline')
|
|
145
|
+
server?.close()
|
|
146
|
+
server = null
|
|
147
|
+
}
|
|
148
|
+
}, 'phone-access: shutdown')
|
|
149
|
+
}
|