htpx-cli 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.
- package/README.md +274 -0
- package/dist/cli/commands/clear.d.ts +3 -0
- package/dist/cli/commands/clear.d.ts.map +1 -0
- package/dist/cli/commands/clear.js +30 -0
- package/dist/cli/commands/clear.js.map +1 -0
- package/dist/cli/commands/init.d.ts +9 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +25 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/intercept.d.ts +8 -0
- package/dist/cli/commands/intercept.d.ts.map +1 -0
- package/dist/cli/commands/intercept.js +59 -0
- package/dist/cli/commands/intercept.js.map +1 -0
- package/dist/cli/commands/project.d.ts +3 -0
- package/dist/cli/commands/project.d.ts.map +1 -0
- package/dist/cli/commands/project.js +13 -0
- package/dist/cli/commands/project.js.map +1 -0
- package/dist/cli/commands/status.d.ts +3 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +36 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/stop.d.ts +3 -0
- package/dist/cli/commands/stop.d.ts.map +1 -0
- package/dist/cli/commands/stop.js +27 -0
- package/dist/cli/commands/stop.js.map +1 -0
- package/dist/cli/commands/tui.d.ts +3 -0
- package/dist/cli/commands/tui.d.ts.map +1 -0
- package/dist/cli/commands/tui.js +27 -0
- package/dist/cli/commands/tui.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +20 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/tui/App.d.ts +10 -0
- package/dist/cli/tui/App.d.ts.map +1 -0
- package/dist/cli/tui/App.js +96 -0
- package/dist/cli/tui/App.js.map +1 -0
- package/dist/cli/tui/components/BodyView.d.ts +14 -0
- package/dist/cli/tui/components/BodyView.d.ts.map +1 -0
- package/dist/cli/tui/components/BodyView.js +39 -0
- package/dist/cli/tui/components/BodyView.js.map +1 -0
- package/dist/cli/tui/components/HeadersView.d.ts +13 -0
- package/dist/cli/tui/components/HeadersView.d.ts.map +1 -0
- package/dist/cli/tui/components/HeadersView.js +8 -0
- package/dist/cli/tui/components/HeadersView.js.map +1 -0
- package/dist/cli/tui/components/RequestDetails.d.ts +13 -0
- package/dist/cli/tui/components/RequestDetails.d.ts.map +1 -0
- package/dist/cli/tui/components/RequestDetails.js +19 -0
- package/dist/cli/tui/components/RequestDetails.js.map +1 -0
- package/dist/cli/tui/components/RequestList.d.ts +15 -0
- package/dist/cli/tui/components/RequestList.d.ts.map +1 -0
- package/dist/cli/tui/components/RequestList.js +17 -0
- package/dist/cli/tui/components/RequestList.js.map +1 -0
- package/dist/cli/tui/components/RequestListItem.d.ts +13 -0
- package/dist/cli/tui/components/RequestListItem.d.ts.map +1 -0
- package/dist/cli/tui/components/RequestListItem.js +53 -0
- package/dist/cli/tui/components/RequestListItem.js.map +1 -0
- package/dist/cli/tui/components/StatusBar.d.ts +10 -0
- package/dist/cli/tui/components/StatusBar.d.ts.map +1 -0
- package/dist/cli/tui/components/StatusBar.js +18 -0
- package/dist/cli/tui/components/StatusBar.js.map +1 -0
- package/dist/cli/tui/hooks/useExport.d.ts +18 -0
- package/dist/cli/tui/hooks/useExport.d.ts.map +1 -0
- package/dist/cli/tui/hooks/useExport.js +58 -0
- package/dist/cli/tui/hooks/useExport.js.map +1 -0
- package/dist/cli/tui/hooks/useRequests.d.ts +20 -0
- package/dist/cli/tui/hooks/useRequests.d.ts.map +1 -0
- package/dist/cli/tui/hooks/useRequests.js +85 -0
- package/dist/cli/tui/hooks/useRequests.js.map +1 -0
- package/dist/cli/tui/hooks/useStdoutDimensions.d.ts +11 -0
- package/dist/cli/tui/hooks/useStdoutDimensions.d.ts.map +1 -0
- package/dist/cli/tui/hooks/useStdoutDimensions.js +29 -0
- package/dist/cli/tui/hooks/useStdoutDimensions.js.map +1 -0
- package/dist/cli/tui/utils/curl.d.ts +9 -0
- package/dist/cli/tui/utils/curl.d.ts.map +1 -0
- package/dist/cli/tui/utils/curl.js +47 -0
- package/dist/cli/tui/utils/curl.js.map +1 -0
- package/dist/cli/tui/utils/formatters.d.ts +36 -0
- package/dist/cli/tui/utils/formatters.d.ts.map +1 -0
- package/dist/cli/tui/utils/formatters.js +108 -0
- package/dist/cli/tui/utils/formatters.js.map +1 -0
- package/dist/cli/tui/utils/har.d.ts +75 -0
- package/dist/cli/tui/utils/har.d.ts.map +1 -0
- package/dist/cli/tui/utils/har.js +139 -0
- package/dist/cli/tui/utils/har.js.map +1 -0
- package/dist/daemon/control.d.ts +63 -0
- package/dist/daemon/control.d.ts.map +1 -0
- package/dist/daemon/control.js +260 -0
- package/dist/daemon/control.js.map +1 -0
- package/dist/daemon/index.d.ts +3 -0
- package/dist/daemon/index.d.ts.map +1 -0
- package/dist/daemon/index.js +107 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/daemon/proxy.d.ts +19 -0
- package/dist/daemon/proxy.d.ts.map +1 -0
- package/dist/daemon/proxy.js +89 -0
- package/dist/daemon/proxy.js.map +1 -0
- package/dist/daemon/storage.d.ts +60 -0
- package/dist/daemon/storage.d.ts.map +1 -0
- package/dist/daemon/storage.js +215 -0
- package/dist/daemon/storage.js.map +1 -0
- package/dist/shared/daemon.d.ts +14 -0
- package/dist/shared/daemon.d.ts.map +1 -0
- package/dist/shared/daemon.js +161 -0
- package/dist/shared/daemon.js.map +1 -0
- package/dist/shared/project.d.ts +61 -0
- package/dist/shared/project.d.ts.map +1 -0
- package/dist/shared/project.js +143 -0
- package/dist/shared/project.js.map +1 -0
- package/dist/shared/types.d.ts +32 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/types.js +5 -0
- package/dist/shared/types.js.map +1 -0
- package/package.json +89 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import Database from "better-sqlite3";
|
|
2
|
+
import { v4 as uuidv4 } from "uuid";
|
|
3
|
+
const SCHEMA = `
|
|
4
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
5
|
+
id TEXT PRIMARY KEY,
|
|
6
|
+
label TEXT,
|
|
7
|
+
pid INTEGER NOT NULL,
|
|
8
|
+
started_at INTEGER NOT NULL
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
CREATE TABLE IF NOT EXISTS requests (
|
|
12
|
+
id TEXT PRIMARY KEY,
|
|
13
|
+
session_id TEXT NOT NULL,
|
|
14
|
+
label TEXT,
|
|
15
|
+
timestamp INTEGER NOT NULL,
|
|
16
|
+
method TEXT NOT NULL,
|
|
17
|
+
url TEXT NOT NULL,
|
|
18
|
+
host TEXT NOT NULL,
|
|
19
|
+
path TEXT NOT NULL,
|
|
20
|
+
request_headers TEXT,
|
|
21
|
+
request_body BLOB,
|
|
22
|
+
response_status INTEGER,
|
|
23
|
+
response_headers TEXT,
|
|
24
|
+
response_body BLOB,
|
|
25
|
+
duration_ms INTEGER,
|
|
26
|
+
created_at INTEGER DEFAULT (unixepoch()),
|
|
27
|
+
FOREIGN KEY (session_id) REFERENCES sessions(id)
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
CREATE INDEX IF NOT EXISTS idx_requests_timestamp ON requests(timestamp DESC);
|
|
31
|
+
CREATE INDEX IF NOT EXISTS idx_requests_session ON requests(session_id);
|
|
32
|
+
CREATE INDEX IF NOT EXISTS idx_requests_label ON requests(label);
|
|
33
|
+
`;
|
|
34
|
+
export class RequestRepository {
|
|
35
|
+
db;
|
|
36
|
+
constructor(dbPath) {
|
|
37
|
+
this.db = new Database(dbPath);
|
|
38
|
+
this.db.pragma("journal_mode = WAL");
|
|
39
|
+
this.db.exec(SCHEMA);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Register a new session.
|
|
43
|
+
*/
|
|
44
|
+
registerSession(label, pid = process.pid) {
|
|
45
|
+
const session = {
|
|
46
|
+
id: uuidv4(),
|
|
47
|
+
label,
|
|
48
|
+
pid,
|
|
49
|
+
startedAt: Date.now(),
|
|
50
|
+
};
|
|
51
|
+
const stmt = this.db.prepare(`
|
|
52
|
+
INSERT INTO sessions (id, label, pid, started_at)
|
|
53
|
+
VALUES (?, ?, ?, ?)
|
|
54
|
+
`);
|
|
55
|
+
stmt.run(session.id, session.label ?? null, session.pid, session.startedAt);
|
|
56
|
+
return session;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get a session by ID.
|
|
60
|
+
*/
|
|
61
|
+
getSession(id) {
|
|
62
|
+
const stmt = this.db.prepare(`
|
|
63
|
+
SELECT id, label, pid, started_at as startedAt
|
|
64
|
+
FROM sessions
|
|
65
|
+
WHERE id = ?
|
|
66
|
+
`);
|
|
67
|
+
const row = stmt.get(id);
|
|
68
|
+
if (!row) {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
id: row.id,
|
|
73
|
+
label: row.label ?? undefined,
|
|
74
|
+
pid: row.pid,
|
|
75
|
+
startedAt: row.startedAt,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* List all sessions.
|
|
80
|
+
*/
|
|
81
|
+
listSessions() {
|
|
82
|
+
const stmt = this.db.prepare(`
|
|
83
|
+
SELECT id, label, pid, started_at as startedAt
|
|
84
|
+
FROM sessions
|
|
85
|
+
ORDER BY started_at DESC
|
|
86
|
+
`);
|
|
87
|
+
const rows = stmt.all();
|
|
88
|
+
return rows.map((row) => ({
|
|
89
|
+
id: row.id,
|
|
90
|
+
label: row.label ?? undefined,
|
|
91
|
+
pid: row.pid,
|
|
92
|
+
startedAt: row.startedAt,
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Save a captured request. Returns the generated ID.
|
|
97
|
+
*/
|
|
98
|
+
saveRequest(request) {
|
|
99
|
+
const id = uuidv4();
|
|
100
|
+
const stmt = this.db.prepare(`
|
|
101
|
+
INSERT INTO requests (
|
|
102
|
+
id, session_id, label, timestamp, method, url, host, path,
|
|
103
|
+
request_headers, request_body, response_status, response_headers,
|
|
104
|
+
response_body, duration_ms
|
|
105
|
+
)
|
|
106
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
107
|
+
`);
|
|
108
|
+
stmt.run(id, request.sessionId, request.label ?? null, request.timestamp, request.method, request.url, request.host, request.path, request.requestHeaders ? JSON.stringify(request.requestHeaders) : null, request.requestBody ?? null, request.responseStatus ?? null, request.responseHeaders ? JSON.stringify(request.responseHeaders) : null, request.responseBody ?? null, request.durationMs ?? null);
|
|
109
|
+
return id;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Update a request with response data.
|
|
113
|
+
*/
|
|
114
|
+
updateRequestResponse(id, response) {
|
|
115
|
+
const stmt = this.db.prepare(`
|
|
116
|
+
UPDATE requests
|
|
117
|
+
SET response_status = ?, response_headers = ?, response_body = ?, duration_ms = ?
|
|
118
|
+
WHERE id = ?
|
|
119
|
+
`);
|
|
120
|
+
stmt.run(response.status, JSON.stringify(response.headers), response.body ?? null, response.durationMs, id);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Get a request by ID.
|
|
124
|
+
*/
|
|
125
|
+
getRequest(id) {
|
|
126
|
+
const stmt = this.db.prepare(`
|
|
127
|
+
SELECT * FROM requests WHERE id = ?
|
|
128
|
+
`);
|
|
129
|
+
const row = stmt.get(id);
|
|
130
|
+
return row ? this.rowToRequest(row) : undefined;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* List requests, optionally filtered by session or label.
|
|
134
|
+
*/
|
|
135
|
+
listRequests(options = {}) {
|
|
136
|
+
const conditions = [];
|
|
137
|
+
const params = [];
|
|
138
|
+
if (options.sessionId) {
|
|
139
|
+
conditions.push("session_id = ?");
|
|
140
|
+
params.push(options.sessionId);
|
|
141
|
+
}
|
|
142
|
+
if (options.label) {
|
|
143
|
+
conditions.push("label = ?");
|
|
144
|
+
params.push(options.label);
|
|
145
|
+
}
|
|
146
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
147
|
+
const limit = options.limit ?? 1000;
|
|
148
|
+
const offset = options.offset ?? 0;
|
|
149
|
+
const stmt = this.db.prepare(`
|
|
150
|
+
SELECT * FROM requests
|
|
151
|
+
${whereClause}
|
|
152
|
+
ORDER BY timestamp DESC
|
|
153
|
+
LIMIT ? OFFSET ?
|
|
154
|
+
`);
|
|
155
|
+
params.push(limit, offset);
|
|
156
|
+
const rows = stmt.all(...params);
|
|
157
|
+
return rows.map((row) => this.rowToRequest(row));
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Count requests, optionally filtered by session or label.
|
|
161
|
+
*/
|
|
162
|
+
countRequests(options = {}) {
|
|
163
|
+
const conditions = [];
|
|
164
|
+
const params = [];
|
|
165
|
+
if (options.sessionId) {
|
|
166
|
+
conditions.push("session_id = ?");
|
|
167
|
+
params.push(options.sessionId);
|
|
168
|
+
}
|
|
169
|
+
if (options.label) {
|
|
170
|
+
conditions.push("label = ?");
|
|
171
|
+
params.push(options.label);
|
|
172
|
+
}
|
|
173
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
174
|
+
const stmt = this.db.prepare(`
|
|
175
|
+
SELECT COUNT(*) as count FROM requests ${whereClause}
|
|
176
|
+
`);
|
|
177
|
+
const result = stmt.get(...params);
|
|
178
|
+
return result.count;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Delete all requests (useful for cleanup).
|
|
182
|
+
*/
|
|
183
|
+
clearRequests() {
|
|
184
|
+
this.db.exec("DELETE FROM requests");
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Close the database connection.
|
|
188
|
+
*/
|
|
189
|
+
close() {
|
|
190
|
+
this.db.close();
|
|
191
|
+
}
|
|
192
|
+
rowToRequest(row) {
|
|
193
|
+
return {
|
|
194
|
+
id: row.id,
|
|
195
|
+
sessionId: row.session_id,
|
|
196
|
+
label: row.label ?? undefined,
|
|
197
|
+
timestamp: row.timestamp,
|
|
198
|
+
method: row.method,
|
|
199
|
+
url: row.url,
|
|
200
|
+
host: row.host,
|
|
201
|
+
path: row.path,
|
|
202
|
+
requestHeaders: row.request_headers
|
|
203
|
+
? JSON.parse(row.request_headers)
|
|
204
|
+
: {},
|
|
205
|
+
requestBody: row.request_body ?? undefined,
|
|
206
|
+
responseStatus: row.response_status ?? undefined,
|
|
207
|
+
responseHeaders: row.response_headers
|
|
208
|
+
? JSON.parse(row.response_headers)
|
|
209
|
+
: undefined,
|
|
210
|
+
responseBody: row.response_body ?? undefined,
|
|
211
|
+
durationMs: row.duration_ms ?? undefined,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/daemon/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if the daemon is running for a project.
|
|
3
|
+
*/
|
|
4
|
+
export declare function isDaemonRunning(projectRoot: string): Promise<boolean>;
|
|
5
|
+
/**
|
|
6
|
+
* Start the daemon for a project.
|
|
7
|
+
* Returns the proxy port.
|
|
8
|
+
*/
|
|
9
|
+
export declare function startDaemon(projectRoot: string): Promise<number>;
|
|
10
|
+
/**
|
|
11
|
+
* Stop the daemon for a project.
|
|
12
|
+
*/
|
|
13
|
+
export declare function stopDaemon(projectRoot: string): Promise<void>;
|
|
14
|
+
//# sourceMappingURL=daemon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/shared/daemon.ts"],"names":[],"mappings":"AAmBA;;GAEG;AACH,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAY3E;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAqCtE;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBnE"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { spawn } from "node:child_process";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { getHtpxPaths, readDaemonPid, isProcessRunning, ensureHtpxDir } from "./project.js";
|
|
6
|
+
import { ControlClient } from "../daemon/control.js";
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
/**
|
|
10
|
+
* Get the path to the daemon entry point.
|
|
11
|
+
*/
|
|
12
|
+
function getDaemonPath() {
|
|
13
|
+
// This is relative to dist/shared/daemon.js
|
|
14
|
+
// The daemon entry point is at dist/daemon/index.js
|
|
15
|
+
return path.resolve(__dirname, "..", "daemon", "index.js");
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Check if the daemon is running for a project.
|
|
19
|
+
*/
|
|
20
|
+
export async function isDaemonRunning(projectRoot) {
|
|
21
|
+
const paths = getHtpxPaths(projectRoot);
|
|
22
|
+
// Check PID file first
|
|
23
|
+
const pid = readDaemonPid(projectRoot);
|
|
24
|
+
if (!pid || !isProcessRunning(pid)) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
// Verify the daemon is actually responding
|
|
28
|
+
const client = new ControlClient(paths.controlSocketFile);
|
|
29
|
+
return client.ping();
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Start the daemon for a project.
|
|
33
|
+
* Returns the proxy port.
|
|
34
|
+
*/
|
|
35
|
+
export async function startDaemon(projectRoot) {
|
|
36
|
+
// Check if already running
|
|
37
|
+
if (await isDaemonRunning(projectRoot)) {
|
|
38
|
+
const paths = getHtpxPaths(projectRoot);
|
|
39
|
+
const portContent = fs.readFileSync(paths.proxyPortFile, "utf-8").trim();
|
|
40
|
+
return parseInt(portContent, 10);
|
|
41
|
+
}
|
|
42
|
+
// Ensure .htpx directory exists
|
|
43
|
+
ensureHtpxDir(projectRoot);
|
|
44
|
+
const daemonPath = getDaemonPath();
|
|
45
|
+
const paths = getHtpxPaths(projectRoot);
|
|
46
|
+
// Spawn daemon as detached background process
|
|
47
|
+
// Clear the log file first so we only see errors from this attempt
|
|
48
|
+
const logFile = path.join(paths.htpxDir, "daemon.log");
|
|
49
|
+
fs.writeFileSync(logFile, "");
|
|
50
|
+
const out = fs.openSync(logFile, "a");
|
|
51
|
+
const err = fs.openSync(logFile, "a");
|
|
52
|
+
const child = spawn("node", [daemonPath], {
|
|
53
|
+
env: {
|
|
54
|
+
...process.env,
|
|
55
|
+
PROJECT_ROOT: projectRoot,
|
|
56
|
+
},
|
|
57
|
+
detached: true,
|
|
58
|
+
stdio: ["ignore", out, err],
|
|
59
|
+
});
|
|
60
|
+
// Detach from parent process
|
|
61
|
+
child.unref();
|
|
62
|
+
// Wait for daemon to start and write port file
|
|
63
|
+
const port = await waitForDaemon(projectRoot, 10000);
|
|
64
|
+
return port;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Stop the daemon for a project.
|
|
68
|
+
*/
|
|
69
|
+
export async function stopDaemon(projectRoot) {
|
|
70
|
+
const pid = readDaemonPid(projectRoot);
|
|
71
|
+
if (!pid) {
|
|
72
|
+
return; // Already stopped
|
|
73
|
+
}
|
|
74
|
+
if (!isProcessRunning(pid)) {
|
|
75
|
+
// PID file exists but process is dead - clean up
|
|
76
|
+
const paths = getHtpxPaths(projectRoot);
|
|
77
|
+
cleanupDaemonFiles(paths);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
// Send SIGTERM to daemon
|
|
81
|
+
process.kill(pid, "SIGTERM");
|
|
82
|
+
// Wait for daemon to stop
|
|
83
|
+
await waitForDaemonStop(pid, 5000);
|
|
84
|
+
// Clean up any remaining files
|
|
85
|
+
const paths = getHtpxPaths(projectRoot);
|
|
86
|
+
cleanupDaemonFiles(paths);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Wait for the daemon to start and return the proxy port.
|
|
90
|
+
*/
|
|
91
|
+
async function waitForDaemon(projectRoot, timeoutMs) {
|
|
92
|
+
const paths = getHtpxPaths(projectRoot);
|
|
93
|
+
const startTime = Date.now();
|
|
94
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
95
|
+
// Check if port file exists
|
|
96
|
+
if (fs.existsSync(paths.proxyPortFile)) {
|
|
97
|
+
const portContent = fs.readFileSync(paths.proxyPortFile, "utf-8").trim();
|
|
98
|
+
const port = parseInt(portContent, 10);
|
|
99
|
+
if (!isNaN(port)) {
|
|
100
|
+
// Verify daemon is responding
|
|
101
|
+
const client = new ControlClient(paths.controlSocketFile);
|
|
102
|
+
if (await client.ping()) {
|
|
103
|
+
return port;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Wait a bit before checking again
|
|
108
|
+
await sleep(100);
|
|
109
|
+
}
|
|
110
|
+
// On timeout, check daemon.log for errors to surface to the user
|
|
111
|
+
const logPath = path.join(paths.htpxDir, "daemon.log");
|
|
112
|
+
let logTail = "";
|
|
113
|
+
if (fs.existsSync(logPath)) {
|
|
114
|
+
const content = fs.readFileSync(logPath, "utf-8");
|
|
115
|
+
const lines = content.trim().split("\n");
|
|
116
|
+
logTail = lines.slice(-20).join("\n"); // Last 20 lines
|
|
117
|
+
}
|
|
118
|
+
if (logTail) {
|
|
119
|
+
throw new Error(`Daemon failed to start. Log output:\n${logTail}`);
|
|
120
|
+
}
|
|
121
|
+
throw new Error("Daemon failed to start within timeout (no log output)");
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Wait for daemon process to stop.
|
|
125
|
+
*/
|
|
126
|
+
async function waitForDaemonStop(pid, timeoutMs) {
|
|
127
|
+
const startTime = Date.now();
|
|
128
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
129
|
+
if (!isProcessRunning(pid)) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
await sleep(100);
|
|
133
|
+
}
|
|
134
|
+
// Force kill if still running
|
|
135
|
+
try {
|
|
136
|
+
process.kill(pid, "SIGKILL");
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
// Process may have already exited
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Clean up daemon files (socket, port file, pid file).
|
|
144
|
+
*/
|
|
145
|
+
function cleanupDaemonFiles(paths) {
|
|
146
|
+
const files = [paths.controlSocketFile, paths.proxyPortFile, paths.pidFile];
|
|
147
|
+
for (const file of files) {
|
|
148
|
+
if (fs.existsSync(file)) {
|
|
149
|
+
try {
|
|
150
|
+
fs.unlinkSync(file);
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
// Ignore errors during cleanup
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function sleep(ms) {
|
|
159
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=daemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/shared/daemon.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Find the project root by looking for .htpx directory or .git directory.
|
|
3
|
+
* Walks up the directory tree from the current working directory.
|
|
4
|
+
* Returns undefined if no project root is found.
|
|
5
|
+
*/
|
|
6
|
+
export declare function findProjectRoot(startDir?: string): string | undefined;
|
|
7
|
+
/**
|
|
8
|
+
* Determine the project root, creating .htpx if needed.
|
|
9
|
+
* - If .htpx exists anywhere in the tree, use that directory
|
|
10
|
+
* - If .git exists, use the git root
|
|
11
|
+
* - Otherwise, use the current working directory
|
|
12
|
+
*/
|
|
13
|
+
export declare function findOrCreateProjectRoot(startDir?: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Get the .htpx directory path for a project root.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getHtpxDir(projectRoot: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Ensure the .htpx directory exists, creating it if necessary.
|
|
20
|
+
* Returns the path to the .htpx directory.
|
|
21
|
+
*/
|
|
22
|
+
export declare function ensureHtpxDir(projectRoot: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Get paths to various files within the .htpx directory.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getHtpxPaths(projectRoot: string): {
|
|
27
|
+
htpxDir: string;
|
|
28
|
+
proxyPortFile: string;
|
|
29
|
+
controlSocketFile: string;
|
|
30
|
+
databaseFile: string;
|
|
31
|
+
caKeyFile: string;
|
|
32
|
+
caCertFile: string;
|
|
33
|
+
pidFile: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Read the proxy port from the .htpx directory.
|
|
37
|
+
* Returns undefined if the file doesn't exist.
|
|
38
|
+
*/
|
|
39
|
+
export declare function readProxyPort(projectRoot: string): number | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* Write the proxy port to the .htpx directory.
|
|
42
|
+
*/
|
|
43
|
+
export declare function writeProxyPort(projectRoot: string, port: number): void;
|
|
44
|
+
/**
|
|
45
|
+
* Read the daemon PID from the .htpx directory.
|
|
46
|
+
* Returns undefined if the file doesn't exist.
|
|
47
|
+
*/
|
|
48
|
+
export declare function readDaemonPid(projectRoot: string): number | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Write the daemon PID to the .htpx directory.
|
|
51
|
+
*/
|
|
52
|
+
export declare function writeDaemonPid(projectRoot: string, pid: number): void;
|
|
53
|
+
/**
|
|
54
|
+
* Remove the daemon PID file.
|
|
55
|
+
*/
|
|
56
|
+
export declare function removeDaemonPid(projectRoot: string): void;
|
|
57
|
+
/**
|
|
58
|
+
* Check if a process with the given PID is running.
|
|
59
|
+
*/
|
|
60
|
+
export declare function isProcessRunning(pid: number): boolean;
|
|
61
|
+
//# sourceMappingURL=project.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/shared/project.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,GAAG,SAAS,CAmBpF;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,CAqBhF;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAQzD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM;;;;;;;;EAY/C;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAWrE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAGtE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAWrE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAGrE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAMzD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAQrD"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
const HTPX_DIR = ".htpx";
|
|
4
|
+
/**
|
|
5
|
+
* Find the project root by looking for .htpx directory or .git directory.
|
|
6
|
+
* Walks up the directory tree from the current working directory.
|
|
7
|
+
* Returns undefined if no project root is found.
|
|
8
|
+
*/
|
|
9
|
+
export function findProjectRoot(startDir = process.cwd()) {
|
|
10
|
+
let currentDir = path.resolve(startDir);
|
|
11
|
+
const root = path.parse(currentDir).root;
|
|
12
|
+
while (currentDir !== root) {
|
|
13
|
+
// Check for .htpx directory first
|
|
14
|
+
if (fs.existsSync(path.join(currentDir, HTPX_DIR))) {
|
|
15
|
+
return currentDir;
|
|
16
|
+
}
|
|
17
|
+
// Check for .git directory as fallback
|
|
18
|
+
if (fs.existsSync(path.join(currentDir, ".git"))) {
|
|
19
|
+
return currentDir;
|
|
20
|
+
}
|
|
21
|
+
currentDir = path.dirname(currentDir);
|
|
22
|
+
}
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Determine the project root, creating .htpx if needed.
|
|
27
|
+
* - If .htpx exists anywhere in the tree, use that directory
|
|
28
|
+
* - If .git exists, use the git root
|
|
29
|
+
* - Otherwise, use the current working directory
|
|
30
|
+
*/
|
|
31
|
+
export function findOrCreateProjectRoot(startDir = process.cwd()) {
|
|
32
|
+
let currentDir = path.resolve(startDir);
|
|
33
|
+
const root = path.parse(currentDir).root;
|
|
34
|
+
let gitRoot;
|
|
35
|
+
while (currentDir !== root) {
|
|
36
|
+
// Check for .htpx directory first - this takes priority
|
|
37
|
+
if (fs.existsSync(path.join(currentDir, HTPX_DIR))) {
|
|
38
|
+
return currentDir;
|
|
39
|
+
}
|
|
40
|
+
// Remember the git root if we find one
|
|
41
|
+
if (!gitRoot && fs.existsSync(path.join(currentDir, ".git"))) {
|
|
42
|
+
gitRoot = currentDir;
|
|
43
|
+
}
|
|
44
|
+
currentDir = path.dirname(currentDir);
|
|
45
|
+
}
|
|
46
|
+
// If we found a git root, use that; otherwise use cwd
|
|
47
|
+
return gitRoot ?? process.cwd();
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get the .htpx directory path for a project root.
|
|
51
|
+
*/
|
|
52
|
+
export function getHtpxDir(projectRoot) {
|
|
53
|
+
return path.join(projectRoot, HTPX_DIR);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Ensure the .htpx directory exists, creating it if necessary.
|
|
57
|
+
* Returns the path to the .htpx directory.
|
|
58
|
+
*/
|
|
59
|
+
export function ensureHtpxDir(projectRoot) {
|
|
60
|
+
const htpxDir = getHtpxDir(projectRoot);
|
|
61
|
+
if (!fs.existsSync(htpxDir)) {
|
|
62
|
+
fs.mkdirSync(htpxDir, { recursive: true });
|
|
63
|
+
}
|
|
64
|
+
return htpxDir;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get paths to various files within the .htpx directory.
|
|
68
|
+
*/
|
|
69
|
+
export function getHtpxPaths(projectRoot) {
|
|
70
|
+
const htpxDir = getHtpxDir(projectRoot);
|
|
71
|
+
return {
|
|
72
|
+
htpxDir,
|
|
73
|
+
proxyPortFile: path.join(htpxDir, "proxy.port"),
|
|
74
|
+
controlSocketFile: path.join(htpxDir, "control.sock"),
|
|
75
|
+
databaseFile: path.join(htpxDir, "requests.db"),
|
|
76
|
+
caKeyFile: path.join(htpxDir, "ca-key.pem"),
|
|
77
|
+
caCertFile: path.join(htpxDir, "ca.pem"),
|
|
78
|
+
pidFile: path.join(htpxDir, "daemon.pid"),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Read the proxy port from the .htpx directory.
|
|
83
|
+
* Returns undefined if the file doesn't exist.
|
|
84
|
+
*/
|
|
85
|
+
export function readProxyPort(projectRoot) {
|
|
86
|
+
const { proxyPortFile } = getHtpxPaths(projectRoot);
|
|
87
|
+
if (!fs.existsSync(proxyPortFile)) {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
const content = fs.readFileSync(proxyPortFile, "utf-8").trim();
|
|
91
|
+
const port = parseInt(content, 10);
|
|
92
|
+
return isNaN(port) ? undefined : port;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Write the proxy port to the .htpx directory.
|
|
96
|
+
*/
|
|
97
|
+
export function writeProxyPort(projectRoot, port) {
|
|
98
|
+
const { proxyPortFile } = getHtpxPaths(projectRoot);
|
|
99
|
+
fs.writeFileSync(proxyPortFile, port.toString(), "utf-8");
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Read the daemon PID from the .htpx directory.
|
|
103
|
+
* Returns undefined if the file doesn't exist.
|
|
104
|
+
*/
|
|
105
|
+
export function readDaemonPid(projectRoot) {
|
|
106
|
+
const { pidFile } = getHtpxPaths(projectRoot);
|
|
107
|
+
if (!fs.existsSync(pidFile)) {
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
const content = fs.readFileSync(pidFile, "utf-8").trim();
|
|
111
|
+
const pid = parseInt(content, 10);
|
|
112
|
+
return isNaN(pid) ? undefined : pid;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Write the daemon PID to the .htpx directory.
|
|
116
|
+
*/
|
|
117
|
+
export function writeDaemonPid(projectRoot, pid) {
|
|
118
|
+
const { pidFile } = getHtpxPaths(projectRoot);
|
|
119
|
+
fs.writeFileSync(pidFile, pid.toString(), "utf-8");
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Remove the daemon PID file.
|
|
123
|
+
*/
|
|
124
|
+
export function removeDaemonPid(projectRoot) {
|
|
125
|
+
const { pidFile } = getHtpxPaths(projectRoot);
|
|
126
|
+
if (fs.existsSync(pidFile)) {
|
|
127
|
+
fs.unlinkSync(pidFile);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Check if a process with the given PID is running.
|
|
132
|
+
*/
|
|
133
|
+
export function isProcessRunning(pid) {
|
|
134
|
+
try {
|
|
135
|
+
// Sending signal 0 checks if the process exists without actually sending a signal
|
|
136
|
+
process.kill(pid, 0);
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/shared/project.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core types for htpx
|
|
3
|
+
*/
|
|
4
|
+
export interface CapturedRequest {
|
|
5
|
+
id: string;
|
|
6
|
+
sessionId: string;
|
|
7
|
+
label?: string;
|
|
8
|
+
timestamp: number;
|
|
9
|
+
method: string;
|
|
10
|
+
url: string;
|
|
11
|
+
host: string;
|
|
12
|
+
path: string;
|
|
13
|
+
requestHeaders: Record<string, string>;
|
|
14
|
+
requestBody?: Buffer;
|
|
15
|
+
responseStatus?: number;
|
|
16
|
+
responseHeaders?: Record<string, string>;
|
|
17
|
+
responseBody?: Buffer;
|
|
18
|
+
durationMs?: number;
|
|
19
|
+
}
|
|
20
|
+
export interface Session {
|
|
21
|
+
id: string;
|
|
22
|
+
label?: string;
|
|
23
|
+
pid: number;
|
|
24
|
+
startedAt: number;
|
|
25
|
+
}
|
|
26
|
+
export interface DaemonStatus {
|
|
27
|
+
running: boolean;
|
|
28
|
+
proxyPort?: number;
|
|
29
|
+
sessionCount: number;
|
|
30
|
+
requestCount: number;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB"}
|