@akira-tl/forgerelay 0.1.0 → 0.2.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.
@@ -0,0 +1,47 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { mkdirSync } from "node:fs";
3
+ import { resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+
6
+ export const repoRoot = resolve(fileURLToPath(new URL("../..", import.meta.url)));
7
+ export const debugConfigDir = resolve(repoRoot, "scripts", "debug");
8
+ export const debugRoot = resolve(repoRoot, ".forgerelay-debug");
9
+ export const debugHookRecorder = resolve(debugConfigDir, "hook-recorder.mjs");
10
+ export const debugHookLog = resolve(debugRoot, "hooks.jsonl");
11
+ export const debugBaseUrl = "http://127.0.0.1:7677";
12
+ export const debugMcpUrl = `${debugBaseUrl}/mcp`;
13
+
14
+ export function createDebugOwnerToken() {
15
+ return randomBytes(32).toString("base64url");
16
+ }
17
+
18
+ export function createDebugEnvironment({
19
+ ownerToken,
20
+ stateDir = resolve(debugRoot, "state"),
21
+ worktreeRoot = resolve(debugRoot, "worktrees"),
22
+ hookLog = debugHookLog,
23
+ } = {}) {
24
+ const token = ownerToken ?? process.env.FORGERELAY_DEBUG_OWNER_TOKEN ?? createDebugOwnerToken();
25
+ mkdirSync(debugRoot, { recursive: true });
26
+
27
+ return {
28
+ ownerToken: token,
29
+ env: {
30
+ ...process.env,
31
+ HOST: "127.0.0.1",
32
+ PORT: "7677",
33
+ FORGERELAY_CONFIG_DIR: debugConfigDir,
34
+ FORGERELAY_PUBLIC_BASE_URL: debugBaseUrl,
35
+ FORGERELAY_ALLOWED_ROOTS: repoRoot,
36
+ FORGERELAY_STATE_DIR: stateDir,
37
+ FORGERELAY_WORKTREE_ROOT: worktreeRoot,
38
+ FORGERELAY_OAUTH_OWNER_TOKEN: token,
39
+ FORGERELAY_TOOL_MODE: "full",
40
+ FORGERELAY_WIDGETS: "off",
41
+ FORGERELAY_LOG_LEVEL: process.env.FORGERELAY_LOG_LEVEL ?? "info",
42
+ FORGERELAY_LOG_FORMAT: process.env.FORGERELAY_LOG_FORMAT ?? "pretty",
43
+ FORGERELAY_DEBUG_HOOK_RECORDER: debugHookRecorder,
44
+ FORGERELAY_DEBUG_HOOK_LOG: hookLog,
45
+ },
46
+ };
47
+ }
@@ -0,0 +1,37 @@
1
+ import { spawn } from "node:child_process";
2
+ import { createDebugEnvironment, debugBaseUrl, debugConfigDir, debugHookLog, debugMcpUrl, repoRoot } from "./runtime.mjs";
3
+
4
+ const { ownerToken, env } = createDebugEnvironment();
5
+
6
+ console.error("[forgerelay:debug] local debug server");
7
+ console.error(`[forgerelay:debug] config: ${debugConfigDir}/config.json`);
8
+ console.error(`[forgerelay:debug] health: ${debugBaseUrl}/healthz`);
9
+ console.error(`[forgerelay:debug] MCP: ${debugMcpUrl}`);
10
+ console.error(`[forgerelay:debug] hook log: ${debugHookLog}`);
11
+ console.error(`[forgerelay:debug] Owner password: ${ownerToken}`);
12
+ console.error("[forgerelay:debug] all runtime state is under .forgerelay-debug/");
13
+
14
+ const child = spawn(process.execPath, ["scripts/dev-server.mjs"], {
15
+ cwd: repoRoot,
16
+ env,
17
+ stdio: "inherit",
18
+ });
19
+
20
+ let stopping = false;
21
+ function stop(signal = "SIGTERM") {
22
+ if (stopping) return;
23
+ stopping = true;
24
+ child.kill(signal);
25
+ }
26
+
27
+ for (const signal of ["SIGINT", "SIGTERM"]) {
28
+ process.on(signal, () => stop(signal));
29
+ }
30
+
31
+ child.on("exit", (code, signal) => {
32
+ if (signal) {
33
+ process.kill(process.pid, signal);
34
+ return;
35
+ }
36
+ process.exitCode = code ?? 1;
37
+ });
@@ -19,7 +19,7 @@ function log(message) {
19
19
 
20
20
  function start() {
21
21
  stoppingForRestart = false;
22
- child = spawn("npx", ["tsx", "src/cli.ts", "serve"], {
22
+ child = spawn(process.execPath, ["--import", "tsx", "src/cli.ts", "serve"], {
23
23
  cwd: repoRoot,
24
24
  env: process.env,
25
25
  stdio: "inherit",