agent-dir 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +223 -2
  3. package/dist/bin/agent-dir.d.ts +3 -0
  4. package/dist/bin/agent-dir.d.ts.map +1 -0
  5. package/dist/bin/agent-dir.js +201 -0
  6. package/dist/bin/agent-dir.js.map +1 -0
  7. package/dist/src/auth.d.ts +3 -0
  8. package/dist/src/auth.d.ts.map +1 -0
  9. package/dist/src/auth.js +18 -0
  10. package/dist/src/auth.js.map +1 -0
  11. package/dist/src/config.d.ts +6 -0
  12. package/dist/src/config.d.ts.map +1 -0
  13. package/dist/src/config.js +80 -0
  14. package/dist/src/config.js.map +1 -0
  15. package/dist/src/logging.d.ts +16 -0
  16. package/dist/src/logging.d.ts.map +1 -0
  17. package/dist/src/logging.js +199 -0
  18. package/dist/src/logging.js.map +1 -0
  19. package/dist/src/mcp.d.ts +9 -0
  20. package/dist/src/mcp.d.ts.map +1 -0
  21. package/dist/src/mcp.js +824 -0
  22. package/dist/src/mcp.js.map +1 -0
  23. package/dist/src/server.d.ts +7 -0
  24. package/dist/src/server.d.ts.map +1 -0
  25. package/dist/src/server.js +343 -0
  26. package/dist/src/server.js.map +1 -0
  27. package/dist/src/tools/code.d.ts +27 -0
  28. package/dist/src/tools/code.d.ts.map +1 -0
  29. package/dist/src/tools/code.js +147 -0
  30. package/dist/src/tools/code.js.map +1 -0
  31. package/dist/src/tools/commands.d.ts +8 -0
  32. package/dist/src/tools/commands.d.ts.map +1 -0
  33. package/dist/src/tools/commands.js +61 -0
  34. package/dist/src/tools/commands.js.map +1 -0
  35. package/dist/src/tools/diagnostics.d.ts +9 -0
  36. package/dist/src/tools/diagnostics.d.ts.map +1 -0
  37. package/dist/src/tools/diagnostics.js +83 -0
  38. package/dist/src/tools/diagnostics.js.map +1 -0
  39. package/dist/src/tools/files.d.ts +39 -0
  40. package/dist/src/tools/files.d.ts.map +1 -0
  41. package/dist/src/tools/files.js +142 -0
  42. package/dist/src/tools/files.js.map +1 -0
  43. package/dist/src/tools/git.d.ts +15 -0
  44. package/dist/src/tools/git.d.ts.map +1 -0
  45. package/dist/src/tools/git.js +104 -0
  46. package/dist/src/tools/git.js.map +1 -0
  47. package/dist/src/tools/metadata.d.ts +20 -0
  48. package/dist/src/tools/metadata.d.ts.map +1 -0
  49. package/dist/src/tools/metadata.js +101 -0
  50. package/dist/src/tools/metadata.js.map +1 -0
  51. package/dist/src/tools/npm.d.ts +3 -0
  52. package/dist/src/tools/npm.d.ts.map +1 -0
  53. package/dist/src/tools/npm.js +76 -0
  54. package/dist/src/tools/npm.js.map +1 -0
  55. package/dist/src/tools/skills.d.ts +33 -0
  56. package/dist/src/tools/skills.d.ts.map +1 -0
  57. package/dist/src/tools/skills.js +240 -0
  58. package/dist/src/tools/skills.js.map +1 -0
  59. package/dist/src/tunnel.d.ts +3 -0
  60. package/dist/src/tunnel.d.ts.map +1 -0
  61. package/dist/src/tunnel.js +114 -0
  62. package/dist/src/tunnel.js.map +1 -0
  63. package/dist/src/types.d.ts +45 -0
  64. package/dist/src/types.d.ts.map +1 -0
  65. package/dist/src/types.js +2 -0
  66. package/dist/src/types.js.map +1 -0
  67. package/package.json +51 -4
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 agent-dir contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,224 @@
1
- # Temporary Holding Version
1
+ <div align="center">
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ <img src="assets/agent-dir-banner.svg" alt="AGENT-DIR — Expose a local project to AI agents through authenticated MCP." width="100%">
4
+
5
+ </div>
6
+
7
+ > **`agent-dir` turns a trusted local project directory into a controlled, authenticated MCP endpoint for AI agents.**
8
+
9
+ `agent-dir` is a cross-platform TypeScript CLI that exposes a local project to an AI agent through an authenticated MCP server. It provides controlled file access, targeted file patches, and explicitly allowlisted development commands, with optional tunneling through [Wormhole](https://wormhole.bar/).
10
+
11
+ > **Security:** this is a remote-control development tool. Only expose directories you trust, keep the authentication token private, and allow only commands you actually need.
12
+
13
+ ## Requirements
14
+
15
+ - Node.js 24 LTS or newer
16
+ - npm
17
+ - Wormhole CLI if remote access is needed
18
+
19
+ Node.js 24 is the supported LTS baseline. The project currently tracks TypeScript 7 and Biome 2.5.
20
+
21
+ ## Quick start
22
+
23
+ ```bash
24
+ npm install -g agent-dir
25
+ agent-dir .
26
+ ```
27
+
28
+ Or run it without a global install:
29
+
30
+ ```bash
31
+ npx agent-dir .
32
+ ```
33
+
34
+ For remote MCP access with Wormhole:
35
+
36
+ ```bash
37
+ agent-dir . --tunnel wormhole --subdomain my-project-x7k4m2
38
+ ```
39
+
40
+ ### Wormhole domains
41
+
42
+ When using a custom Wormhole subdomain, choose a distinctive name such as `my-project-x7k4m2`. Avoid generic names such as `project`, `test`, `dev`, or `scriptr` to reduce collisions and make the public endpoint less predictable.
43
+
44
+ The Wormhole URL is only the transport endpoint. `agent-dir` authentication is enforced by the local HTTP server; Wormhole does not provide the Bearer-token authentication described below.
45
+
46
+ > **Wormhole subdomain limit:** Wormhole limits how many subdomains a user can have registered/active at once. If you see an error such as `Subdomain limit reached (max 3 per user)`, the tunnel is being rejected by Wormhole, not by `agent-dir`. Release an existing Wormhole subdomain or use `--random` to let Wormhole choose a temporary random URL.
47
+ >
48
+ > A subdomain can remain registered while another `wormhole` process is still running, so stop unused Wormhole tunnels before creating another one. If a configured subdomain is unavailable, `agent-dir` will report the Wormhole registration failure instead of silently starting without a tunnel.
49
+
50
+ ## Profiles
51
+
52
+ Profiles save settings you use repeatedly: project directory, tunnel, Wormhole subdomain, port, npm scripts, and allowed non-npm commands.
53
+
54
+ ```bash
55
+ agent-dir config add my-project \
56
+ --directory ~/src/my-project \
57
+ --tunnel wormhole \
58
+ --subdomain my-project-x7k4m2 \
59
+ --npm typecheck,lint,format,test,build \
60
+ --command grep,find,rg,git
61
+ ```
62
+
63
+ Then:
64
+
65
+ ```bash
66
+ agent-dir my-project
67
+ ```
68
+
69
+ Manage profiles with:
70
+
71
+ ```bash
72
+ agent-dir config list
73
+ agent-dir config show my-project
74
+ agent-dir config remove my-project
75
+ ```
76
+
77
+ Profiles are stored per-user at `~/.config/agent-dir/config.json`, not in the project repository. The config directory and file are written with user-only permissions. Command-line options can override saved values for one run.
78
+
79
+ ## MCP tools
80
+
81
+ The HTTP MCP transport implements the modern MCP `2026-07-28` stateless lifecycle over authenticated `POST /mcp`. There is no initialize handshake and no `Mcp-Session-Id`; every request carries its protocol version and client capabilities in `_meta`. The server implements `server/discover`, standard modern HTTP headers, cursor pagination, `subscriptions/listen`, cache metadata, and modern `resultType`/structured tool results.
82
+
83
+ | Tool | Purpose |
84
+ |---|---|
85
+ | `list_files` | Recursive project discovery |
86
+ | `list_dirs` | Direct directory discovery for one or more directories |
87
+ | `read_range` | Read a bounded line range from one UTF-8 file |
88
+ | `read_files` | Read one or more UTF-8 files in one call |
89
+ | `write_files` | Create or replace one or more files in one call |
90
+ | `patch_files` | Apply targeted text replacements to one or more files |
91
+ | `delete_files` | Delete one or more files in one call |
92
+ | `search_files` / `find_files` | Search file contents or find paths by glob |
93
+ | `search_code` | Search source-like files |
94
+ | `find_symbol` / `find_definition` | Locate likely symbol definitions |
95
+ | `find_references` | Locate symbol references |
96
+ | `find_imports` / `find_exports` | Inspect source dependencies and exports |
97
+ | `git_status` / `git_diff` / `git_log` | Git inspection |
98
+ | `git_stage` / `git_unstage` | Stage or unstage paths |
99
+ | `git_commit` | Commit staged changes |
100
+ | `git_restore` | Restore paths, discarding unstaged changes |
101
+ | `git_push` | Push the current branch to a remote |
102
+ | `project_overview` | Project structure, languages, package managers, and Git state |
103
+ | `package_info` / `file_info` | Project and filesystem metadata |
104
+ | `diagnostics` | Project-independent diagnostics; does not run tests, lint, or typecheck |
105
+ | `run_npm_batch` | Run one or more explicitly allowlisted npm scripts sequentially |
106
+ | `run_command_batch` | Run one or more explicitly allowlisted executables sequentially without a shell |
107
+
108
+ Batch operations execute sequentially and stop on the first failed command. Tool calls return modern `structuredContent` alongside a serialized text representation, and tools that return structured data advertise an `outputSchema`. List-style protocol methods use opaque cursors when more than 50 entries are available.
109
+
110
+ Modern `subscriptions/listen` replaces the legacy GET/SSE notification model. Clients can subscribe to tool, prompt, resource-list, and resource-specific change events; filesystem mutations publish resource-change events to active subscribers.
111
+
112
+ ### Command permissions
113
+
114
+ npm scripts must be explicitly enabled:
115
+
116
+ ```text
117
+ --npm typecheck,lint,format,test,build
118
+ ```
119
+
120
+ Normal executables use a separate allowlist:
121
+
122
+ ```text
123
+ --command grep,find,rg,git
124
+ ```
125
+
126
+ Commands are launched with `shell: false`; the MCP client supplies the executable and arguments separately. An executable that is not in the allowlist is rejected.
127
+
128
+ Avoid allowing `sh`, `bash`, `zsh`, `cmd`, `node`, or `python` unless you intentionally want to grant a much broader execution capability.
129
+
130
+ ## Agent Skills
131
+
132
+ The server implements the stable MCP Skills extension (`io.modelcontextprotocol/skills`) over the standard Resources primitive. It discovers project-local `SKILL.md` files under:
133
+
134
+ ```text
135
+ skills/
136
+ .agents/skills/
137
+ .claude/skills/
138
+ .github/skills/
139
+ ```
140
+
141
+ Skills are exposed through `skills/list`, `skills/get`, `resources/list`, and `resources/read`. Skill entries contain parsed frontmatter plus SHA-256 digests and byte sizes for every served file. Skill manifests enforce the 512-resource and 16 MiB limits. Binary supporting files are returned as MCP blobs. `resources/directory/read` lists direct children of a skill resource directory. The extension advertises `directoryRead: true`.
142
+
143
+ ## Authentication
144
+
145
+ By default, `agent-dir` generates a random Bearer token when the server starts. The token protects both the MCP endpoint and the HTTP file API.
146
+
147
+ Clients should authenticate with:
148
+
149
+ ```http
150
+ Authorization: Bearer <token>
151
+ ```
152
+
153
+ The CLI also supports explicitly configured profile tokens and the `--token` option. There is no `--no-auth` option; authentication cannot be disabled through the CLI. Keep the token secret and do not commit it to a repository or publish it alongside a tunnel URL.
154
+
155
+ For clients that cannot send an `Authorization` header, the HTTP server also accepts the token as a query parameter:
156
+
157
+ ```text
158
+ https://your-subdomain.wormhole.bar/mcp?token=<token>
159
+ ```
160
+
161
+ Query-string tokens may be exposed in URL logs and should be treated as less secure than the Authorization header.
162
+
163
+ ## REST API
164
+
165
+ The MCP server is the primary interface, but the HTTP server also exposes:
166
+
167
+ ```text
168
+ GET /__tree
169
+ GET /path/to/file
170
+ PUT /path/to/file
171
+ DELETE /path/to/file
172
+ POST /mcp
173
+ ```
174
+
175
+ All HTTP endpoints are authenticated by default.
176
+
177
+ ## Development
178
+
179
+ The application source and tests are fully TypeScript. JavaScript is generated into `dist/` for execution and publishing. The published package contains only the built CLI/runtime, README, and license; development sources and tests are excluded from the npm tarball.
180
+
181
+ ```bash
182
+ npm run build
183
+ npm run typecheck
184
+ npm test
185
+ npm run format
186
+ npm run lint
187
+ npm run check
188
+ ```
189
+
190
+ `npm run check` runs Biome plus TypeScript. Before publishing:
191
+
192
+ ```bash
193
+ npm run check
194
+ npm test
195
+ npm pack --dry-run
196
+ ```
197
+
198
+ Review the `npm pack --dry-run` file list before publishing to confirm no local configuration, credentials, source-only files, or development artifacts are included.
199
+
200
+ ## Toolchain
201
+
202
+ - **Node.js:** 24 LTS baseline
203
+ - **TypeScript:** 7.x
204
+ - **Biome:** 2.5.x
205
+ - **Module system:** native Node ESM with `NodeNext`
206
+ - **Formatting/linting:** Biome with strict recommended rules and import organization
207
+
208
+ The TypeScript configuration uses strict checking, exact optional properties, unchecked indexed access, isolated modules, explicit Node typings, and consistent module resolution.
209
+
210
+ ## Security model
211
+
212
+ File access is rooted at the shared directory and resolves existing paths through their real filesystem targets, preventing symlinks from escaping the exposed root. HTTP request bodies are limited to 10 MiB. npm scripts and external executables use explicit allowlists, and external commands are not passed through a shell.
213
+
214
+ Because file writes, deletion, command execution, and Git write operations can modify a project or remote repository, expose only directories and capabilities you intend an AI agent to control. Git write tools are intentionally explicit: staging, unstaging, committing, restoring, and pushing are separate operations. `git_restore` discards unstaged changes, and `git_push` can modify a remote repository. If you do not want Git mutation, do not use the Git write tools and do not allow `git` through the generic command allowlist.
215
+
216
+ The diagnostics tool is deliberately project-independent. It checks conditions such as invalid JSON, broken symlinks, and unresolved merge-conflict markers instead of assuming a particular test runner, linter, compiler, or package ecosystem. Never share directories containing credentials, SSH keys, private certificates, production secrets, or unrelated personal data.
217
+
218
+ ## Credits
219
+
220
+ Remote tunneling support is provided through [Wormhole](https://wormhole.bar/), a project of the Wormhole team. `agent-dir` invokes the Wormhole CLI and does not provide the tunneling service itself.
221
+
222
+ ## License
223
+
224
+ MIT
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=agent-dir.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-dir.d.ts","sourceRoot":"","sources":["../../bin/agent-dir.ts"],"names":[],"mappings":""}
@@ -0,0 +1,201 @@
1
+ #!/usr/bin/env node
2
+ import { randomBytes } from "node:crypto";
3
+ import { resolve } from "node:path";
4
+ import { parseArgs } from "node:util";
5
+ import { configPath, loadConfig, mergeProfile, saveConfig } from "../src/config.js";
6
+ import { printBanner, printHelp, printRequestHeader } from "../src/logging.js";
7
+ import { startServer } from "../src/server.js";
8
+ import { startTunnel } from "../src/tunnel.js";
9
+ function fail(message) {
10
+ console.error(`Error: ${message}`);
11
+ process.exit(1);
12
+ }
13
+ function parseList(value) {
14
+ if (value === undefined)
15
+ return undefined;
16
+ return value
17
+ .split(",")
18
+ .map((item) => item.trim())
19
+ .filter(Boolean);
20
+ }
21
+ function parsePort(value, fallback) {
22
+ const port = Number(value ?? fallback);
23
+ if (!Number.isInteger(port) || port < 1 || port > 65_535) {
24
+ fail("port must be an integer between 1 and 65535.");
25
+ }
26
+ return port;
27
+ }
28
+ const { values, positionals } = parseArgs({
29
+ options: {
30
+ help: { type: "boolean", short: "h" },
31
+ directory: { type: "string", short: "d" },
32
+ port: { type: "string", short: "p" },
33
+ tunnel: { type: "string", short: "t" },
34
+ subdomain: { type: "string", short: "s" },
35
+ npm: { type: "string" },
36
+ command: { type: "string" },
37
+ token: { type: "string" },
38
+ "no-tunnel": { type: "boolean" },
39
+ random: { type: "boolean" },
40
+ },
41
+ allowPositionals: true,
42
+ strict: true,
43
+ });
44
+ if (values.help) {
45
+ printHelp();
46
+ process.exit(0);
47
+ }
48
+ const config = await loadConfig();
49
+ const command = positionals[0];
50
+ if (command === "config") {
51
+ const action = positionals[1];
52
+ if (action === "list") {
53
+ const names = Object.keys(config.profiles);
54
+ console.log(names.length ? names.join("\n") : "No profiles configured.");
55
+ process.exit(0);
56
+ }
57
+ if (action === "show") {
58
+ const name = positionals[2];
59
+ if (!name || !config.profiles[name])
60
+ fail(`Profile not found: ${name}`);
61
+ const profile = structuredClone(config.profiles[name]);
62
+ if (profile.token)
63
+ profile.token = "<configured>";
64
+ console.log(JSON.stringify(profile, null, 2));
65
+ process.exit(0);
66
+ }
67
+ if (action === "remove") {
68
+ const name = positionals[2];
69
+ if (!name || !config.profiles[name])
70
+ fail(`Profile not found: ${name}`);
71
+ delete config.profiles[name];
72
+ await saveConfig(config);
73
+ console.log(`✓ Removed profile '${name}'.`);
74
+ process.exit(0);
75
+ }
76
+ if (action === "token") {
77
+ const name = positionals[2];
78
+ if (!name || !config.profiles[name])
79
+ fail(`Profile not found: ${name}`);
80
+ config.profiles[name].token = randomBytes(24).toString("hex");
81
+ await saveConfig(config);
82
+ console.log(`✓ Rotated token for '${name}'.`);
83
+ console.log(` Config: ${configPath()}`);
84
+ process.exit(0);
85
+ }
86
+ if (action === "add") {
87
+ const name = positionals[2];
88
+ if (!name)
89
+ fail("Usage: agent-dir config add <name> [options]");
90
+ if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(name))
91
+ fail("Profile names may contain letters, numbers, dots, underscores, and hyphens.");
92
+ const tunnel = values.tunnel ?? "none";
93
+ if (tunnel !== "none" && tunnel !== "wormhole")
94
+ fail(`Unsupported tunnel provider: ${tunnel}`);
95
+ const profile = {
96
+ directory: resolve(values.directory ?? "."),
97
+ port: parsePort(values.port, 3002),
98
+ tunnel,
99
+ token: values.token ?? randomBytes(24).toString("hex"),
100
+ };
101
+ if (values.subdomain)
102
+ profile.subdomain = values.subdomain;
103
+ const npm = parseList(values.npm);
104
+ if (npm !== undefined)
105
+ profile.npm = { allowedScripts: npm };
106
+ const commands = parseList(values.command);
107
+ if (commands !== undefined)
108
+ profile.commands = commands;
109
+ if (profile.tunnel === "wormhole" && !profile.subdomain && !values.random) {
110
+ fail("Wormhole profiles require --subdomain <name>, or use --random.");
111
+ }
112
+ config.profiles[name] = profile;
113
+ await saveConfig(config);
114
+ console.log(`✓ Saved profile '${name}'.`);
115
+ console.log(` Config: ${configPath()}`);
116
+ process.exit(0);
117
+ }
118
+ fail("Usage: agent-dir config {add|list|show|remove|token}");
119
+ }
120
+ const profile = command ? config.profiles[command] : undefined;
121
+ if (command && command !== "config" && !profile && command.startsWith("-")) {
122
+ fail(`Unknown command: ${command}`);
123
+ }
124
+ const positionalDirectory = profile ? positionals[1] : positionals[0];
125
+ const directory = resolve(values.directory ?? profile?.directory ?? positionalDirectory ?? ".");
126
+ const port = parsePort(values.port, profile?.port ?? 3002);
127
+ const tunnelValue = values["no-tunnel"] ? "none" : (values.tunnel ?? profile?.tunnel ?? "none");
128
+ if (tunnelValue !== "none" && tunnelValue !== "wormhole") {
129
+ fail(`Unsupported tunnel provider: ${tunnelValue}`);
130
+ }
131
+ const tunnel = tunnelValue;
132
+ const randomTunnel = values.random === true;
133
+ const subdomain = randomTunnel ? undefined : (values.subdomain ?? profile?.subdomain);
134
+ if (tunnel === "wormhole" && !subdomain && !randomTunnel) {
135
+ fail("Wormhole requires --subdomain <name>, or use --random.");
136
+ }
137
+ if (randomTunnel && tunnel === "none") {
138
+ fail("--random requires --tunnel wormhole.");
139
+ }
140
+ const token = values.token ?? profile?.token ?? randomBytes(24).toString("hex");
141
+ const npm = parseList(values.npm);
142
+ const commands = parseList(values.command);
143
+ const overrides = {};
144
+ if (npm !== undefined)
145
+ overrides.npm = { allowedScripts: npm };
146
+ if (commands !== undefined)
147
+ overrides.commands = commands;
148
+ const commandConfig = mergeProfile(profile ?? { directory, port, tunnel }, overrides);
149
+ const bannerOptions = {
150
+ root: directory,
151
+ port,
152
+ tunnel,
153
+ token,
154
+ };
155
+ const npmScripts = commandConfig.npm?.allowedScripts;
156
+ const allowedCommands = commandConfig.commands;
157
+ if (profile && command)
158
+ bannerOptions.profileName = command;
159
+ if (subdomain)
160
+ bannerOptions.subdomain = subdomain;
161
+ if (npmScripts)
162
+ bannerOptions.npmScripts = npmScripts;
163
+ if (allowedCommands)
164
+ bannerOptions.commands = allowedCommands;
165
+ printBanner(bannerOptions);
166
+ const server = await startServer({ root: directory, port, token, commandConfig });
167
+ let tunnelResult;
168
+ console.log(" ✓ SERVER ONLINE");
169
+ console.log(` Local target : http://127.0.0.1:${port}`);
170
+ console.log(" Auth : Bearer token");
171
+ console.log(` Token : ${token}`);
172
+ if (tunnel !== "none") {
173
+ try {
174
+ tunnelResult = await startTunnel({
175
+ provider: "wormhole",
176
+ port,
177
+ random: randomTunnel,
178
+ ...(subdomain && !randomTunnel ? { subdomain } : {}),
179
+ });
180
+ }
181
+ catch (error) {
182
+ console.error(` ✖ TUNNEL ERROR ${error instanceof Error ? error.message : String(error)}`);
183
+ await server.close();
184
+ process.exit(1);
185
+ }
186
+ }
187
+ printRequestHeader();
188
+ let shuttingDown = false;
189
+ const shutdown = async () => {
190
+ if (shuttingDown)
191
+ return;
192
+ shuttingDown = true;
193
+ console.log("\n Stopping agent-dir...");
194
+ if (tunnelResult?.child && !tunnelResult.child.killed)
195
+ tunnelResult.child.kill("SIGTERM");
196
+ await server.close();
197
+ process.exit(0);
198
+ };
199
+ process.on("SIGINT", shutdown);
200
+ process.on("SIGTERM", shutdown);
201
+ //# sourceMappingURL=agent-dir.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-dir.js","sourceRoot":"","sources":["../../bin/agent-dir.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function authenticate(request: Request, token: string): boolean;
2
+ export declare function unauthorized(): Response;
3
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/auth.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAMrE;AAED,wBAAgB,YAAY,IAAI,QAAQ,CASvC"}
@@ -0,0 +1,18 @@
1
+ export function authenticate(request, token) {
2
+ const authorization = request.headers.get("authorization");
3
+ if (authorization === `Bearer ${token}`)
4
+ return true;
5
+ const url = new URL(request.url);
6
+ return url.searchParams.get("token") === token;
7
+ }
8
+ export function unauthorized() {
9
+ return new Response(JSON.stringify({ error: "Unauthorized" }), {
10
+ status: 401,
11
+ headers: {
12
+ "content-type": "application/json; charset=utf-8",
13
+ "www-authenticate": "Bearer",
14
+ "cache-control": "no-store",
15
+ },
16
+ });
17
+ }
18
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/auth.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,YAAY,CAAC,OAAgB,EAAE,KAAa;IAC1D,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC3D,IAAI,aAAa,KAAK,UAAU,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAErD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,OAAO,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,EAAE;QAC7D,MAAM,EAAE,GAAG;QACX,OAAO,EAAE;YACP,cAAc,EAAE,iCAAiC;YACjD,kBAAkB,EAAE,QAAQ;YAC5B,eAAe,EAAE,UAAU;SAC5B;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { AgentConfig, CommandConfig, Profile } from "./types.js";
2
+ export declare function loadConfig(): Promise<AgentConfig>;
3
+ export declare function saveConfig(config: AgentConfig): Promise<void>;
4
+ export declare function configPath(): string;
5
+ export declare function mergeProfile(profile: Profile, overrides?: CommandConfig): CommandConfig;
6
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAUtE,wBAAsB,UAAU,IAAI,OAAO,CAAC,WAAW,CAAC,CASvD;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAOnE;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,GAAE,aAAkB,GAAG,aAAa,CAM3F"}
@@ -0,0 +1,80 @@
1
+ import { chmod, mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { homedir } from "node:os";
3
+ import { dirname, join } from "node:path";
4
+ const CONFIG_DIR = join(homedir(), ".config", "agent-dir");
5
+ const CONFIG_FILE = join(CONFIG_DIR, "config.json");
6
+ const DEFAULT_CONFIG = { version: 1, profiles: {} };
7
+ export async function loadConfig() {
8
+ try {
9
+ const parsed = JSON.parse(await readFile(CONFIG_FILE, "utf8"));
10
+ if (!isAgentConfig(parsed))
11
+ throw new Error("Invalid configuration format.");
12
+ return parsed;
13
+ }
14
+ catch (error) {
15
+ if (error.code === "ENOENT")
16
+ return structuredClone(DEFAULT_CONFIG);
17
+ throw new Error(`Unable to read config ${CONFIG_FILE}: ${error.message}`);
18
+ }
19
+ }
20
+ export async function saveConfig(config) {
21
+ await mkdir(dirname(CONFIG_FILE), { recursive: true, mode: 0o700 });
22
+ await writeFile(CONFIG_FILE, `${JSON.stringify(config, null, 2)}\n`, {
23
+ encoding: "utf8",
24
+ mode: 0o600,
25
+ });
26
+ await chmod(CONFIG_FILE, 0o600);
27
+ }
28
+ export function configPath() {
29
+ return CONFIG_FILE;
30
+ }
31
+ export function mergeProfile(profile, overrides = {}) {
32
+ return {
33
+ ...profile,
34
+ ...overrides,
35
+ npm: { ...(profile.npm ?? { allowedScripts: [] }), ...(overrides.npm ?? {}) },
36
+ };
37
+ }
38
+ function isAgentConfig(value) {
39
+ if (!value || typeof value !== "object")
40
+ return false;
41
+ const config = value;
42
+ if (config.version !== 1 || !config.profiles || typeof config.profiles !== "object")
43
+ return false;
44
+ for (const [name, profile] of Object.entries(config.profiles)) {
45
+ if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(name) || !isProfile(profile))
46
+ return false;
47
+ }
48
+ return true;
49
+ }
50
+ function isProfile(value) {
51
+ if (!value || typeof value !== "object")
52
+ return false;
53
+ const profile = value;
54
+ const port = profile.port;
55
+ if (typeof profile.directory !== "string" || typeof port !== "number" || !Number.isInteger(port))
56
+ return false;
57
+ if (port < 1 || port > 65_535)
58
+ return false;
59
+ if (profile.tunnel !== "none" && profile.tunnel !== "wormhole")
60
+ return false;
61
+ if (profile.subdomain !== undefined && typeof profile.subdomain !== "string")
62
+ return false;
63
+ if (profile.token !== undefined && typeof profile.token !== "string")
64
+ return false;
65
+ if (profile.npm !== undefined) {
66
+ if (!profile.npm || typeof profile.npm !== "object")
67
+ return false;
68
+ const npm = profile.npm;
69
+ if (!Array.isArray(npm.allowedScripts) ||
70
+ npm.allowedScripts.some((item) => typeof item !== "string"))
71
+ return false;
72
+ }
73
+ if (profile.commands !== undefined) {
74
+ if (!Array.isArray(profile.commands) ||
75
+ profile.commands.some((item) => typeof item !== "string"))
76
+ return false;
77
+ }
78
+ return true;
79
+ }
80
+ //# 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,16 @@
1
+ import type { RequestLog } from "./types.js";
2
+ export declare function printHelp(): void;
3
+ export declare function printBanner(options: {
4
+ root: string;
5
+ port: number;
6
+ tunnel: string;
7
+ profileName?: string;
8
+ subdomain?: string;
9
+ token?: string;
10
+ npmScripts?: string[];
11
+ commands?: string[];
12
+ }): void;
13
+ export declare function printRequestLog(entry: RequestLog): void;
14
+ export declare function logRequest(entry: RequestLog): void;
15
+ export declare function printRequestHeader(): void;
16
+ //# sourceMappingURL=logging.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../../src/logging.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAyF7C,wBAAgB,SAAS,IAAI,IAAI,CAuBhC;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB,GAAG,IAAI,CA+DP;AAMD,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAsBvD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAElD;AAED,wBAAgB,kBAAkB,IAAI,IAAI,CAKzC"}