@sheepbun/yips 0.1.1 → 0.1.46

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 (103) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +52 -0
  3. package/bin/yips.js +15 -0
  4. package/package.json +21 -128
  5. package/postinstall.js +50 -0
  6. package/dist/agent/commands/command-catalog.js +0 -243
  7. package/dist/agent/commands/commands.js +0 -418
  8. package/dist/agent/conductor.js +0 -118
  9. package/dist/agent/context/code-context.js +0 -68
  10. package/dist/agent/context/memory-store.js +0 -159
  11. package/dist/agent/context/session-store.js +0 -211
  12. package/dist/agent/protocol/tool-protocol.js +0 -160
  13. package/dist/agent/skills/skills.js +0 -327
  14. package/dist/agent/tools/tool-executor.js +0 -415
  15. package/dist/agent/tools/tool-safety.js +0 -52
  16. package/dist/app/index.js +0 -35
  17. package/dist/app/repl.js +0 -105
  18. package/dist/app/update-check.js +0 -132
  19. package/dist/app/version.js +0 -51
  20. package/dist/code-context.js +0 -68
  21. package/dist/colors.js +0 -204
  22. package/dist/command-catalog.js +0 -242
  23. package/dist/commands.js +0 -350
  24. package/dist/conductor.js +0 -94
  25. package/dist/config/config.js +0 -335
  26. package/dist/config/hooks.js +0 -187
  27. package/dist/config.js +0 -335
  28. package/dist/downloader-state.js +0 -302
  29. package/dist/downloader-ui.js +0 -289
  30. package/dist/gateway/adapters/discord.js +0 -108
  31. package/dist/gateway/adapters/formatting.js +0 -96
  32. package/dist/gateway/adapters/telegram.js +0 -106
  33. package/dist/gateway/adapters/types.js +0 -2
  34. package/dist/gateway/adapters/whatsapp.js +0 -124
  35. package/dist/gateway/auth-policy.js +0 -66
  36. package/dist/gateway/core.js +0 -87
  37. package/dist/gateway/headless-conductor.js +0 -328
  38. package/dist/gateway/message-router.js +0 -23
  39. package/dist/gateway/rate-limiter.js +0 -48
  40. package/dist/gateway/runtime/backend-policy.js +0 -18
  41. package/dist/gateway/runtime/discord-bot.js +0 -104
  42. package/dist/gateway/runtime/discord-main.js +0 -69
  43. package/dist/gateway/session-manager.js +0 -77
  44. package/dist/gateway/types.js +0 -2
  45. package/dist/hardware.js +0 -92
  46. package/dist/hooks.js +0 -187
  47. package/dist/index.js +0 -34
  48. package/dist/input-engine.js +0 -250
  49. package/dist/llama-client.js +0 -227
  50. package/dist/llama-server.js +0 -620
  51. package/dist/llm/llama-client.js +0 -227
  52. package/dist/llm/llama-server.js +0 -620
  53. package/dist/llm/token-counter.js +0 -47
  54. package/dist/memory-store.js +0 -159
  55. package/dist/messages.js +0 -59
  56. package/dist/model-downloader.js +0 -382
  57. package/dist/model-manager-state.js +0 -118
  58. package/dist/model-manager-ui.js +0 -194
  59. package/dist/model-manager.js +0 -190
  60. package/dist/models/hardware.js +0 -92
  61. package/dist/models/model-downloader.js +0 -382
  62. package/dist/models/model-manager.js +0 -190
  63. package/dist/prompt-box.js +0 -78
  64. package/dist/prompt-composer.js +0 -498
  65. package/dist/repl.js +0 -105
  66. package/dist/session-store.js +0 -211
  67. package/dist/spinner.js +0 -76
  68. package/dist/title-box.js +0 -388
  69. package/dist/token-counter.js +0 -47
  70. package/dist/tool-executor.js +0 -415
  71. package/dist/tool-protocol.js +0 -121
  72. package/dist/tool-safety.js +0 -52
  73. package/dist/tui/app.js +0 -2553
  74. package/dist/tui/startup.js +0 -56
  75. package/dist/tui-input-routing.js +0 -53
  76. package/dist/tui.js +0 -51
  77. package/dist/types/app-types.js +0 -2
  78. package/dist/types.js +0 -2
  79. package/dist/ui/colors.js +0 -204
  80. package/dist/ui/downloader/downloader-state.js +0 -302
  81. package/dist/ui/downloader/downloader-ui.js +0 -289
  82. package/dist/ui/input/input-engine.js +0 -250
  83. package/dist/ui/input/tui-input-routing.js +0 -53
  84. package/dist/ui/input/vt-session.js +0 -168
  85. package/dist/ui/messages.js +0 -59
  86. package/dist/ui/model-manager/model-manager-state.js +0 -118
  87. package/dist/ui/model-manager/model-manager-ui.js +0 -194
  88. package/dist/ui/prompt/prompt-box.js +0 -78
  89. package/dist/ui/prompt/prompt-composer.js +0 -498
  90. package/dist/ui/spinner.js +0 -76
  91. package/dist/ui/title-box.js +0 -388
  92. package/dist/ui/tui/app.js +0 -6
  93. package/dist/ui/tui/autocomplete.js +0 -85
  94. package/dist/ui/tui/constants.js +0 -18
  95. package/dist/ui/tui/history.js +0 -29
  96. package/dist/ui/tui/layout.js +0 -341
  97. package/dist/ui/tui/runtime-core.js +0 -2584
  98. package/dist/ui/tui/runtime-utils.js +0 -53
  99. package/dist/ui/tui/start-tui.js +0 -54
  100. package/dist/ui/tui/startup.js +0 -56
  101. package/dist/version.js +0 -51
  102. package/dist/vt-session.js +0 -168
  103. package/install.sh +0 -457
@@ -1,18 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GATEWAY_BACKEND_ENV_VAR = exports.DEFAULT_GATEWAY_BACKEND = void 0;
4
- exports.resolveGatewayBackendFromEnv = resolveGatewayBackendFromEnv;
5
- exports.DEFAULT_GATEWAY_BACKEND = "llamacpp";
6
- exports.GATEWAY_BACKEND_ENV_VAR = "YIPS_GATEWAY_BACKEND";
7
- function resolveGatewayBackendFromEnv(rawValue) {
8
- const trimmed = rawValue?.trim();
9
- if (!trimmed) {
10
- return exports.DEFAULT_GATEWAY_BACKEND;
11
- }
12
- const normalized = trimmed.toLowerCase();
13
- if (normalized === "llamacpp") {
14
- return "llamacpp";
15
- }
16
- throw new Error(`Unsupported ${exports.GATEWAY_BACKEND_ENV_VAR} value '${trimmed}'. ` +
17
- "Gateway headless mode currently supports backend 'llamacpp' only.");
18
- }
@@ -1,104 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DiscordGatewayRuntime = void 0;
4
- exports.createDiscordGatewayRuntime = createDiscordGatewayRuntime;
5
- const discord_1 = require("#gateway/adapters/discord");
6
- function defaultLoadDiscordModule() {
7
- return import("discord.js");
8
- }
9
- function toRequestList(request) {
10
- if (!request) {
11
- return [];
12
- }
13
- return Array.isArray(request) ? request : [request];
14
- }
15
- function defaultFetchImpl(input, init) {
16
- return fetch(input, init);
17
- }
18
- class DiscordGatewayRuntime {
19
- botToken;
20
- gateway;
21
- adapter;
22
- fetchImpl;
23
- loadDiscordModule;
24
- onError;
25
- client = null;
26
- constructor(options) {
27
- this.botToken = options.botToken.trim();
28
- this.gateway = options.gateway;
29
- this.adapter = options.adapter ?? new discord_1.DiscordAdapter({ botToken: this.botToken });
30
- this.fetchImpl = options.fetchImpl ?? defaultFetchImpl;
31
- this.loadDiscordModule = options.loadDiscordModule ?? defaultLoadDiscordModule;
32
- this.onError = options.onError ?? ((error) => console.error("[gateway/discord]", error));
33
- }
34
- async start() {
35
- if (this.client) {
36
- return;
37
- }
38
- const discord = await this.loadDiscordModule();
39
- const intents = discord.GatewayIntentBits ?? {};
40
- const partials = discord.Partials ?? {};
41
- const client = new discord.Client({
42
- intents: [
43
- intents.Guilds,
44
- intents.GuildMessages,
45
- intents.DirectMessages,
46
- intents.MessageContent
47
- ].filter((value) => typeof value === "number"),
48
- partials: [partials.Channel].filter((value) => typeof value === "number")
49
- });
50
- client.on("messageCreate", (message) => {
51
- void this.handleDiscordMessage(message);
52
- });
53
- await client.login(this.botToken);
54
- this.client = client;
55
- }
56
- async stop() {
57
- if (!this.client) {
58
- return;
59
- }
60
- this.client.destroy();
61
- this.client = null;
62
- }
63
- async handleDiscordMessage(payload) {
64
- try {
65
- const inboundMessages = this.adapter.parseInbound(payload);
66
- for (const inbound of inboundMessages) {
67
- const result = await this.gateway.dispatch(inbound);
68
- if (!result.response) {
69
- continue;
70
- }
71
- const context = {
72
- session: {
73
- id: result.sessionId ?? `discord.${inbound.senderId}.${inbound.channelId ?? "direct"}`,
74
- platform: "discord",
75
- senderId: inbound.senderId,
76
- channelId: inbound.channelId ?? "direct",
77
- createdAt: new Date(),
78
- updatedAt: new Date(),
79
- messageCount: 1
80
- },
81
- message: inbound
82
- };
83
- const requests = toRequestList(this.adapter.formatOutbound(context, result.response));
84
- for (const request of requests) {
85
- const response = await this.fetchImpl(request.endpoint, {
86
- method: request.method,
87
- headers: request.headers,
88
- body: request.body ? JSON.stringify(request.body) : undefined
89
- });
90
- if (!response.ok) {
91
- throw new Error(`discord send failed (${response.status})`);
92
- }
93
- }
94
- }
95
- }
96
- catch (error) {
97
- this.onError(error);
98
- }
99
- }
100
- }
101
- exports.DiscordGatewayRuntime = DiscordGatewayRuntime;
102
- function createDiscordGatewayRuntime(options) {
103
- return new DiscordGatewayRuntime(options);
104
- }
@@ -1,69 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const core_1 = require("#gateway/core");
4
- const discord_bot_1 = require("#gateway/runtime/discord-bot");
5
- const config_1 = require("#config/config");
6
- const headless_conductor_1 = require("#gateway/headless-conductor");
7
- const backend_policy_1 = require("#gateway/runtime/backend-policy");
8
- function readRequiredEnv(name) {
9
- const value = process.env[name]?.trim();
10
- if (!value) {
11
- throw new Error(`Missing required environment variable: ${name}`);
12
- }
13
- return value;
14
- }
15
- function readAllowedSenders() {
16
- const raw = process.env.YIPS_GATEWAY_ALLOWED_SENDERS;
17
- if (!raw) {
18
- return [];
19
- }
20
- return raw
21
- .split(",")
22
- .map((value) => value.trim())
23
- .filter((value) => value.length > 0);
24
- }
25
- function readOptionalEnv(name) {
26
- const value = process.env[name]?.trim();
27
- return value && value.length > 0 ? value : undefined;
28
- }
29
- async function main() {
30
- const botToken = readRequiredEnv("YIPS_DISCORD_BOT_TOKEN");
31
- const allowedSenderIds = readAllowedSenders();
32
- const passphrase = readOptionalEnv("YIPS_GATEWAY_PASSPHRASE");
33
- const gatewayBackend = (0, backend_policy_1.resolveGatewayBackendFromEnv)(process.env.YIPS_GATEWAY_BACKEND);
34
- const configResult = await (0, config_1.loadConfig)();
35
- if (configResult.warning) {
36
- console.error(`[warning] ${configResult.warning}`);
37
- }
38
- const headless = await (0, headless_conductor_1.createGatewayHeadlessMessageHandler)({
39
- config: configResult.config,
40
- username: "Gateway User",
41
- gatewayBackend
42
- });
43
- const gateway = new core_1.GatewayCore({
44
- allowedSenderIds: allowedSenderIds.length > 0 ? allowedSenderIds : undefined,
45
- passphrase,
46
- handleMessage: headless.handleMessage
47
- });
48
- const runtime = (0, discord_bot_1.createDiscordGatewayRuntime)({
49
- botToken,
50
- gateway
51
- });
52
- await runtime.start();
53
- const shutdown = async () => {
54
- await runtime.stop();
55
- headless.dispose();
56
- process.exit(0);
57
- };
58
- process.once("SIGINT", () => {
59
- void shutdown();
60
- });
61
- process.once("SIGTERM", () => {
62
- void shutdown();
63
- });
64
- }
65
- void main().catch((error) => {
66
- const message = error instanceof Error ? (error.stack ?? error.message) : String(error);
67
- console.error(`[fatal] ${message}`);
68
- process.exitCode = 1;
69
- });
@@ -1,77 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GatewaySessionManager = void 0;
4
- exports.toConversationKey = toConversationKey;
5
- exports.toSessionId = toSessionId;
6
- const DIRECT_CHANNEL = "direct";
7
- function sanitizeIdPart(value) {
8
- const normalized = value.trim().toLowerCase().replace(/[^a-z0-9._-]/g, "-");
9
- return normalized.length > 0 ? normalized : "unknown";
10
- }
11
- function toConversationKey(message) {
12
- const channelId = message.channelId ?? DIRECT_CHANNEL;
13
- return `${message.platform}:${message.senderId}:${channelId}`;
14
- }
15
- function toSessionId(message) {
16
- const channelId = message.channelId ?? DIRECT_CHANNEL;
17
- return [
18
- sanitizeIdPart(message.platform),
19
- sanitizeIdPart(message.senderId),
20
- sanitizeIdPart(channelId)
21
- ].join(".");
22
- }
23
- class GatewaySessionManager {
24
- sessionsByKey = new Map();
25
- now;
26
- constructor(now = () => new Date()) {
27
- this.now = now;
28
- }
29
- getOrCreateSession(message) {
30
- const key = toConversationKey(message);
31
- const existing = this.sessionsByKey.get(key);
32
- if (existing) {
33
- existing.messageCount += 1;
34
- existing.updatedAt = this.now();
35
- return existing;
36
- }
37
- const now = this.now();
38
- const created = {
39
- id: toSessionId(message),
40
- platform: message.platform,
41
- senderId: message.senderId,
42
- channelId: message.channelId ?? DIRECT_CHANNEL,
43
- createdAt: now,
44
- updatedAt: now,
45
- messageCount: 1
46
- };
47
- this.sessionsByKey.set(key, created);
48
- return created;
49
- }
50
- listSessions() {
51
- return Array.from(this.sessionsByKey.values()).sort((a, b) => b.updatedAt.valueOf() - a.updatedAt.valueOf());
52
- }
53
- removeSession(sessionId) {
54
- for (const [key, session] of this.sessionsByKey) {
55
- if (session.id === sessionId) {
56
- this.sessionsByKey.delete(key);
57
- return true;
58
- }
59
- }
60
- return false;
61
- }
62
- pruneIdleSessions(maxIdleMs) {
63
- if (maxIdleMs <= 0) {
64
- return 0;
65
- }
66
- const cutoff = this.now().valueOf() - maxIdleMs;
67
- let removed = 0;
68
- for (const [key, session] of this.sessionsByKey) {
69
- if (session.updatedAt.valueOf() < cutoff) {
70
- this.sessionsByKey.delete(key);
71
- removed += 1;
72
- }
73
- }
74
- return removed;
75
- }
76
- }
77
- exports.GatewaySessionManager = GatewaySessionManager;
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
package/dist/hardware.js DELETED
@@ -1,92 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getSystemSpecs = getSystemSpecs;
4
- exports.clearSystemSpecsCache = clearSystemSpecsCache;
5
- const node_child_process_1 = require("node:child_process");
6
- const node_fs_1 = require("node:fs");
7
- const node_fs_2 = require("node:fs");
8
- const node_os_1 = require("node:os");
9
- const node_path_1 = require("node:path");
10
- const node_fs_3 = require("node:fs");
11
- function roundOne(value) {
12
- return Math.round(value * 10) / 10;
13
- }
14
- function getRamGb() {
15
- return roundOne((0, node_os_1.totalmem)() / (1024 ** 3));
16
- }
17
- function getNvidiaVramGb() {
18
- try {
19
- const result = (0, node_child_process_1.execFileSync)("nvidia-smi", ["--query-gpu=memory.total", "--format=csv,noheader,nounits"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
20
- const totalMb = result
21
- .split(/\r?\n/u)
22
- .map((line) => line.trim())
23
- .filter((line) => line.length > 0)
24
- .map((line) => Number(line))
25
- .filter((value) => Number.isFinite(value) && value > 0)
26
- .reduce((sum, value) => sum + value, 0);
27
- return totalMb > 0 ? roundOne(totalMb / 1024) : 0;
28
- }
29
- catch {
30
- return 0;
31
- }
32
- }
33
- function getAmdVramGb() {
34
- try {
35
- const paths = (0, node_fs_2.globSync)("/sys/class/drm/card*/device/mem_info_vram_total");
36
- if (paths.length === 0) {
37
- return 0;
38
- }
39
- const totalBytes = paths
40
- .map((path) => (0, node_fs_1.readFileSync)(path, "utf8").trim())
41
- .map((value) => Number(value))
42
- .filter((value) => Number.isFinite(value) && value > 0)
43
- .reduce((sum, value) => sum + value, 0);
44
- return totalBytes > 0 ? roundOne(totalBytes / (1024 ** 3)) : 0;
45
- }
46
- catch {
47
- return 0;
48
- }
49
- }
50
- function getModelsDir() {
51
- const override = process.env["YIPS_MODELS_DIR"]?.trim();
52
- if (override && override.length > 0) {
53
- return override;
54
- }
55
- return (0, node_path_1.join)((0, node_os_1.homedir)(), ".yips", "models");
56
- }
57
- function getDiskFreeGb(path) {
58
- try {
59
- const fsStats = (0, node_fs_3.statfsSync)(path);
60
- const blockSize = Number(fsStats.bsize);
61
- const available = Number(fsStats.bavail);
62
- if (!Number.isFinite(blockSize) || !Number.isFinite(available) || blockSize <= 0 || available < 0) {
63
- return 0;
64
- }
65
- return roundOne((blockSize * available) / (1024 ** 3));
66
- }
67
- catch {
68
- return 0;
69
- }
70
- }
71
- let cachedSpecs = null;
72
- function getSystemSpecs() {
73
- if (cachedSpecs) {
74
- return cachedSpecs;
75
- }
76
- const ramGb = getRamGb();
77
- const nvidiaVramGb = getNvidiaVramGb();
78
- const amdVramGb = nvidiaVramGb > 0 ? 0 : getAmdVramGb();
79
- const vramGb = nvidiaVramGb > 0 ? nvidiaVramGb : amdVramGb;
80
- const gpuType = nvidiaVramGb > 0 ? "nvidia" : amdVramGb > 0 ? "amd" : "unknown";
81
- cachedSpecs = {
82
- ramGb,
83
- vramGb,
84
- totalMemoryGb: roundOne(ramGb + vramGb),
85
- diskFreeGb: getDiskFreeGb(getModelsDir()),
86
- gpuType
87
- };
88
- return cachedSpecs;
89
- }
90
- function clearSystemSpecsCache() {
91
- cachedSpecs = null;
92
- }
package/dist/hooks.js DELETED
@@ -1,187 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.formatHookFailure = formatHookFailure;
4
- exports.runHook = runHook;
5
- const node_child_process_1 = require("node:child_process");
6
- const DEFAULT_TIMEOUT_MS = 10_000;
7
- const MAX_TIMEOUT_MS = 120_000;
8
- const SHUTDOWN_GRACE_MS = 500;
9
- function resolveHookCommand(config, hook) {
10
- const configured = config.hooks[hook]?.command;
11
- if (typeof configured !== "string") {
12
- return null;
13
- }
14
- const trimmed = configured.trim();
15
- return trimmed.length > 0 ? trimmed : null;
16
- }
17
- function resolveHookTimeoutMs(config, hook) {
18
- const configured = config.hooks[hook]?.timeoutMs;
19
- if (typeof configured !== "number" || !Number.isInteger(configured) || configured <= 0) {
20
- return DEFAULT_TIMEOUT_MS;
21
- }
22
- return Math.min(configured, MAX_TIMEOUT_MS);
23
- }
24
- function createEventId() {
25
- return `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
26
- }
27
- function toErrorMessage(error) {
28
- return error instanceof Error ? error.message : String(error);
29
- }
30
- function extractFilePath(payload) {
31
- const path = payload["path"];
32
- if (typeof path === "string" && path.trim().length > 0) {
33
- return path.trim();
34
- }
35
- const filePath = payload["filePath"];
36
- if (typeof filePath === "string" && filePath.trim().length > 0) {
37
- return filePath.trim();
38
- }
39
- return null;
40
- }
41
- function formatHookFailure(result) {
42
- const base = `[hook:${result.hook}] ${result.message}`;
43
- if (result.status === "timeout") {
44
- return base;
45
- }
46
- if (result.exitCode !== null) {
47
- return `${base} (exit ${result.exitCode})`;
48
- }
49
- return base;
50
- }
51
- async function runHook(config, hook, payload, context = {}) {
52
- const cwd = context.cwd ?? process.cwd();
53
- const eventId = createEventId();
54
- const timestamp = new Date().toISOString();
55
- const command = resolveHookCommand(config, hook);
56
- if (!command) {
57
- return {
58
- hook,
59
- status: "skipped",
60
- command: null,
61
- cwd,
62
- message: `No hook configured for ${hook}.`,
63
- durationMs: 0,
64
- eventId,
65
- timestamp,
66
- stdout: "",
67
- stderr: "",
68
- exitCode: null,
69
- signal: null,
70
- timedOut: false
71
- };
72
- }
73
- const timeoutMs = resolveHookTimeoutMs(config, hook);
74
- const filePath = extractFilePath(payload);
75
- const startedAt = Date.now();
76
- const envelope = {
77
- hook,
78
- eventId,
79
- timestamp,
80
- cwd,
81
- sessionName: context.sessionName ?? null,
82
- data: payload
83
- };
84
- return await new Promise((resolveResult) => {
85
- let stdout = "";
86
- let stderr = "";
87
- let settled = false;
88
- let timedOut = false;
89
- let killTimer = null;
90
- const child = (0, node_child_process_1.spawn)("sh", ["-lc", command], {
91
- cwd,
92
- env: {
93
- ...process.env,
94
- ...context.env,
95
- YIPS_HOOK_NAME: hook,
96
- YIPS_HOOK_EVENT_ID: eventId,
97
- YIPS_HOOK_TIMESTAMP: timestamp,
98
- YIPS_HOOK_CWD: cwd,
99
- YIPS_HOOK_SESSION_NAME: context.sessionName ?? "",
100
- YIPS_HOOK_FILE_PATH: filePath ?? ""
101
- },
102
- stdio: ["pipe", "pipe", "pipe"]
103
- });
104
- const settle = (result) => {
105
- if (settled) {
106
- return;
107
- }
108
- settled = true;
109
- if (killTimer) {
110
- clearTimeout(killTimer);
111
- }
112
- resolveResult({
113
- hook,
114
- eventId,
115
- timestamp,
116
- cwd,
117
- ...result
118
- });
119
- };
120
- child.stdout.on("data", (chunk) => {
121
- stdout += chunk.toString("utf8");
122
- });
123
- child.stderr.on("data", (chunk) => {
124
- stderr += chunk.toString("utf8");
125
- });
126
- child.on("error", (error) => {
127
- settle({
128
- status: "error",
129
- command,
130
- message: `Hook execution failed: ${toErrorMessage(error)}`,
131
- durationMs: Math.max(0, Date.now() - startedAt),
132
- stdout,
133
- stderr,
134
- exitCode: null,
135
- signal: null,
136
- timedOut
137
- });
138
- });
139
- child.on("close", (code, signal) => {
140
- if (timedOut) {
141
- settle({
142
- status: "timeout",
143
- command,
144
- message: `Hook timed out after ${timeoutMs}ms.`,
145
- durationMs: Math.max(0, Date.now() - startedAt),
146
- stdout,
147
- stderr,
148
- exitCode: code,
149
- signal,
150
- timedOut: true
151
- });
152
- return;
153
- }
154
- const success = code === 0;
155
- settle({
156
- status: success ? "ok" : "error",
157
- command,
158
- message: success ? "Hook completed successfully." : "Hook exited with a non-zero status.",
159
- durationMs: Math.max(0, Date.now() - startedAt),
160
- stdout,
161
- stderr,
162
- exitCode: code,
163
- signal,
164
- timedOut: false
165
- });
166
- });
167
- killTimer = setTimeout(() => {
168
- if (settled) {
169
- return;
170
- }
171
- timedOut = true;
172
- child.kill("SIGTERM");
173
- setTimeout(() => {
174
- if (!settled) {
175
- child.kill("SIGKILL");
176
- }
177
- }, SHUTDOWN_GRACE_MS);
178
- }, timeoutMs);
179
- const stdinPayload = `${JSON.stringify(envelope)}\n`;
180
- child.stdin.write(stdinPayload, "utf8", (error) => {
181
- if (error) {
182
- stderr += `stdin write failed: ${toErrorMessage(error)}\n`;
183
- }
184
- child.stdin.end();
185
- });
186
- });
187
- }
package/dist/index.js DELETED
@@ -1,34 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.main = main;
4
- const node_process_1 = require("node:process");
5
- const config_1 = require("./config");
6
- const repl_1 = require("./repl");
7
- const tui_1 = require("./tui");
8
- function isTTY() {
9
- return Boolean(node_process_1.stdin.isTTY && node_process_1.stdout.isTTY);
10
- }
11
- function hasFlag(flag) {
12
- return process.argv.includes(flag);
13
- }
14
- async function main() {
15
- for (;;) {
16
- const configResult = await (0, config_1.loadConfig)();
17
- if (configResult.warning) {
18
- console.error(`[warning] ${configResult.warning}`);
19
- }
20
- const result = hasFlag("--no-tui") || !isTTY()
21
- ? await (0, repl_1.startRepl)({ config: configResult.config })
22
- : await (0, tui_1.startTui)({ config: configResult.config });
23
- if (result !== "restart") {
24
- break;
25
- }
26
- }
27
- }
28
- if (require.main === module) {
29
- void main().catch((error) => {
30
- const message = error instanceof Error ? (error.stack ?? error.message) : String(error);
31
- console.error(`[fatal] ${message}`);
32
- process.exitCode = 1;
33
- });
34
- }