@dev-anywhere/proxy 0.1.1 → 0.1.2
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/dist/serve.js +70 -23
- package/dist/serve.js.map +1 -1
- package/package.json +3 -3
package/dist/serve.js
CHANGED
|
@@ -2060,7 +2060,7 @@ function terminateSessionByOwnership(deps, sessionId) {
|
|
|
2060
2060
|
}
|
|
2061
2061
|
|
|
2062
2062
|
// src/serve/clipboard-image-upload.ts
|
|
2063
|
-
import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
2063
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync5, statSync, writeFileSync as writeFileSync4 } from "fs";
|
|
2064
2064
|
import { isAbsolute as isAbsolute3, join as join5, relative, resolve } from "path";
|
|
2065
2065
|
import { nanoid as nanoid3 } from "nanoid";
|
|
2066
2066
|
var MAX_CLIPBOARD_IMAGE_BYTES = 10 * 1024 * 1024;
|
|
@@ -2093,15 +2093,50 @@ function decodeBase64Image(dataBase64) {
|
|
|
2093
2093
|
}
|
|
2094
2094
|
return buffer;
|
|
2095
2095
|
}
|
|
2096
|
-
function
|
|
2097
|
-
const root = resolve(
|
|
2098
|
-
const uploadDir = resolve(root,
|
|
2096
|
+
function resolveChildDir(rootPath, ...segments) {
|
|
2097
|
+
const root = resolve(rootPath);
|
|
2098
|
+
const uploadDir = resolve(root, ...segments);
|
|
2099
2099
|
const relativePath = relative(root, uploadDir);
|
|
2100
2100
|
if (!relativePath || relativePath.startsWith("..") || isAbsolute3(relativePath)) {
|
|
2101
2101
|
throw new Error("\u4F1A\u8BDD\u8DEF\u5F84\u65E0\u6548");
|
|
2102
2102
|
}
|
|
2103
2103
|
return uploadDir;
|
|
2104
2104
|
}
|
|
2105
|
+
function resolveSessionClipboardDir(dataDir, sessionId) {
|
|
2106
|
+
return resolveChildDir(dataDir, sessionId, "clipboard");
|
|
2107
|
+
}
|
|
2108
|
+
function normalizeGitignoreLine(line) {
|
|
2109
|
+
return line.trim().replace(/^\/+/, "").replace(/\/+$/, "");
|
|
2110
|
+
}
|
|
2111
|
+
function ensureProjectClipboardIgnored(cwd) {
|
|
2112
|
+
const gitignorePath = join5(cwd, ".gitignore");
|
|
2113
|
+
if (!existsSync5(gitignorePath)) return;
|
|
2114
|
+
try {
|
|
2115
|
+
const current = readFileSync5(gitignorePath, "utf-8");
|
|
2116
|
+
const alreadyIgnored = current.split(/\r?\n/).some((line) => normalizeGitignoreLine(line) === ".dev-anywhere");
|
|
2117
|
+
if (alreadyIgnored) return;
|
|
2118
|
+
const separator = current.length > 0 && !current.endsWith("\n") ? "\n" : "";
|
|
2119
|
+
writeFileSync4(gitignorePath, `${current}${separator}.dev-anywhere/
|
|
2120
|
+
`);
|
|
2121
|
+
} catch {
|
|
2122
|
+
}
|
|
2123
|
+
}
|
|
2124
|
+
function trySaveProjectClipboardImage(options) {
|
|
2125
|
+
if (!options.cwd) return null;
|
|
2126
|
+
try {
|
|
2127
|
+
const cwd = resolve(options.cwd);
|
|
2128
|
+
if (!statSync(cwd).isDirectory()) return null;
|
|
2129
|
+
const clipboardRoot = resolve(cwd, ".dev-anywhere", "clipboard");
|
|
2130
|
+
const uploadDir = resolveChildDir(clipboardRoot, options.sessionId);
|
|
2131
|
+
const path = join5(uploadDir, options.fileName);
|
|
2132
|
+
mkdirSync4(uploadDir, { recursive: true });
|
|
2133
|
+
writeFileSync4(path, options.buffer, { mode: 384 });
|
|
2134
|
+
ensureProjectClipboardIgnored(cwd);
|
|
2135
|
+
return { success: true, path: relative(cwd, path) };
|
|
2136
|
+
} catch {
|
|
2137
|
+
return null;
|
|
2138
|
+
}
|
|
2139
|
+
}
|
|
2105
2140
|
function saveClipboardImageUpload(request, options = {}) {
|
|
2106
2141
|
const extension = IMAGE_EXTENSIONS.get(request.mimeType);
|
|
2107
2142
|
if (!extension) {
|
|
@@ -2113,12 +2148,19 @@ function saveClipboardImageUpload(request, options = {}) {
|
|
|
2113
2148
|
};
|
|
2114
2149
|
}
|
|
2115
2150
|
try {
|
|
2116
|
-
const dataDir = options.dataDir ?? DATA_DIR;
|
|
2117
|
-
const uploadDir = resolveSessionClipboardDir(dataDir, request.sessionId);
|
|
2118
2151
|
const buffer = decodeBase64Image(request.dataBase64);
|
|
2119
2152
|
const now = options.now ?? Date.now;
|
|
2120
2153
|
const suffix = options.randomSuffix?.() ?? nanoid3(6);
|
|
2121
2154
|
const fileName = `pasted-${formatTimestamp(now())}-${suffix}.${extension}`;
|
|
2155
|
+
const projectResult = trySaveProjectClipboardImage({
|
|
2156
|
+
cwd: options.cwd,
|
|
2157
|
+
sessionId: request.sessionId,
|
|
2158
|
+
fileName,
|
|
2159
|
+
buffer
|
|
2160
|
+
});
|
|
2161
|
+
if (projectResult) return projectResult;
|
|
2162
|
+
const dataDir = options.dataDir ?? DATA_DIR;
|
|
2163
|
+
const uploadDir = resolveSessionClipboardDir(dataDir, request.sessionId);
|
|
2122
2164
|
const path = join5(uploadDir, fileName);
|
|
2123
2165
|
mkdirSync4(uploadDir, { recursive: true });
|
|
2124
2166
|
writeFileSync4(path, buffer, { mode: 384 });
|
|
@@ -2226,12 +2268,17 @@ var RelayInputHandlers = class {
|
|
|
2226
2268
|
serviceLogger.warn({ sessionId }, "Clipboard image upload rejected: session not found");
|
|
2227
2269
|
return;
|
|
2228
2270
|
}
|
|
2229
|
-
const result = saveClipboardImageUpload(
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2271
|
+
const result = saveClipboardImageUpload(
|
|
2272
|
+
{
|
|
2273
|
+
sessionId,
|
|
2274
|
+
mimeType: typeof msg.mimeType === "string" ? msg.mimeType : "",
|
|
2275
|
+
dataBase64: typeof msg.dataBase64 === "string" ? msg.dataBase64 : "",
|
|
2276
|
+
fileName: typeof msg.fileName === "string" ? msg.fileName : void 0
|
|
2277
|
+
},
|
|
2278
|
+
{
|
|
2279
|
+
cwd: session.cwd
|
|
2280
|
+
}
|
|
2281
|
+
);
|
|
2235
2282
|
this.deps.relayConnection.sendRaw(
|
|
2236
2283
|
JSON.stringify({
|
|
2237
2284
|
type: "clipboard_image_upload_response",
|
|
@@ -2441,14 +2488,14 @@ var RelayPermissionHandlers = class {
|
|
|
2441
2488
|
|
|
2442
2489
|
// src/serve/relay-resource-handlers.ts
|
|
2443
2490
|
import { homedir as homedir4 } from "os";
|
|
2444
|
-
import { accessSync, constants, statSync } from "fs";
|
|
2491
|
+
import { accessSync, constants, statSync as statSync2 } from "fs";
|
|
2445
2492
|
function errorMessage(err) {
|
|
2446
2493
|
return err instanceof Error ? err.message : String(err);
|
|
2447
2494
|
}
|
|
2448
2495
|
function validateExecutablePath(path) {
|
|
2449
2496
|
const normalized = path.trim();
|
|
2450
2497
|
if (!normalized.startsWith("/")) throw new Error("CLI \u8DEF\u5F84\u5FC5\u987B\u662F\u7EDD\u5BF9\u8DEF\u5F84");
|
|
2451
|
-
const stat2 =
|
|
2498
|
+
const stat2 = statSync2(normalized);
|
|
2452
2499
|
if (!stat2.isFile()) throw new Error("CLI \u8DEF\u5F84\u4E0D\u662F\u53EF\u6267\u884C\u6587\u4EF6");
|
|
2453
2500
|
accessSync(normalized, constants.X_OK);
|
|
2454
2501
|
return normalized;
|
|
@@ -2557,7 +2604,7 @@ var RelayResourceHandlers = class {
|
|
|
2557
2604
|
};
|
|
2558
2605
|
|
|
2559
2606
|
// src/serve/relay-session-create-handler.ts
|
|
2560
|
-
import { rmSync, statSync as
|
|
2607
|
+
import { rmSync, statSync as statSync3 } from "fs";
|
|
2561
2608
|
import { isAbsolute as isAbsolute4 } from "path";
|
|
2562
2609
|
import { nanoid as nanoid4 } from "nanoid";
|
|
2563
2610
|
|
|
@@ -2852,7 +2899,7 @@ function validateSessionCwd(cwd) {
|
|
|
2852
2899
|
return { message: "\u5DE5\u4F5C\u76EE\u5F55\u5FC5\u987B\u662F\u7EDD\u5BF9\u8DEF\u5F84", code: ControlErrorCode.INVALID_PATH };
|
|
2853
2900
|
}
|
|
2854
2901
|
try {
|
|
2855
|
-
const stat2 =
|
|
2902
|
+
const stat2 = statSync3(trimmed);
|
|
2856
2903
|
return stat2.isDirectory() ? null : { message: "\u5DE5\u4F5C\u76EE\u5F55\u4E0D\u662F\u76EE\u5F55", code: ControlErrorCode.PATH_NOT_DIRECTORY };
|
|
2857
2904
|
} catch (err) {
|
|
2858
2905
|
return {
|
|
@@ -3648,7 +3695,7 @@ function touchSessionActivity(sessionManager, relay, sessionId, now = Date.now()
|
|
|
3648
3695
|
|
|
3649
3696
|
// src/serve/service-files.ts
|
|
3650
3697
|
import { execSync } from "child_process";
|
|
3651
|
-
import { existsSync as
|
|
3698
|
+
import { existsSync as existsSync6, readFileSync as readFileSync6, unlinkSync as unlinkSync2 } from "fs";
|
|
3652
3699
|
import { hostname } from "os";
|
|
3653
3700
|
import { connect as connect2 } from "net";
|
|
3654
3701
|
function tryConnectSocket(sockPath) {
|
|
@@ -3667,7 +3714,7 @@ function isProcessAlive(pid) {
|
|
|
3667
3714
|
}
|
|
3668
3715
|
}
|
|
3669
3716
|
async function cleanupStaleResources() {
|
|
3670
|
-
if (
|
|
3717
|
+
if (existsSync6(SOCK_PATH)) {
|
|
3671
3718
|
const existing = await tryConnectSocket(SOCK_PATH);
|
|
3672
3719
|
if (existing) {
|
|
3673
3720
|
existing.destroy();
|
|
@@ -3679,8 +3726,8 @@ async function cleanupStaleResources() {
|
|
|
3679
3726
|
unlinkSync2(SOCK_PATH);
|
|
3680
3727
|
serviceLogger.info("Removed stale socket file");
|
|
3681
3728
|
}
|
|
3682
|
-
if (
|
|
3683
|
-
const pidStr =
|
|
3729
|
+
if (existsSync6(PID_PATH)) {
|
|
3730
|
+
const pidStr = readFileSync6(PID_PATH, "utf-8").trim();
|
|
3684
3731
|
const pid = parseInt(pidStr, 10);
|
|
3685
3732
|
if (!isNaN(pid) && isProcessAlive(pid)) {
|
|
3686
3733
|
const msg = `Another service is already running with PID ${pid}`;
|
|
@@ -4055,7 +4102,7 @@ function handleTerminalConnection(socket, deps) {
|
|
|
4055
4102
|
|
|
4056
4103
|
// src/serve/hook-registry.ts
|
|
4057
4104
|
import { createHash, randomBytes } from "crypto";
|
|
4058
|
-
import { existsSync as
|
|
4105
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync7, renameSync as renameSync2, writeFileSync as writeFileSync5 } from "fs";
|
|
4059
4106
|
import { dirname as dirname4 } from "path";
|
|
4060
4107
|
import { z } from "zod";
|
|
4061
4108
|
var PersistedHookSessionBindingSchema = z.object({
|
|
@@ -4116,10 +4163,10 @@ var HookRegistry = class {
|
|
|
4116
4163
|
}
|
|
4117
4164
|
}
|
|
4118
4165
|
load() {
|
|
4119
|
-
if (!this.persistPath || !
|
|
4166
|
+
if (!this.persistPath || !existsSync7(this.persistPath)) return;
|
|
4120
4167
|
try {
|
|
4121
4168
|
const parsed = PersistedHookRegistrySchema.parse(
|
|
4122
|
-
JSON.parse(
|
|
4169
|
+
JSON.parse(readFileSync7(this.persistPath, "utf8"))
|
|
4123
4170
|
);
|
|
4124
4171
|
this.bindingsBySession.clear();
|
|
4125
4172
|
for (const binding of parsed.bindings) {
|