@cryptiklemur/lattice 1.2.0 → 1.4.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/.serena/project.yml +138 -0
- package/bun.lock +705 -2
- package/client/index.html +1 -13
- package/client/package.json +6 -1
- package/client/src/App.tsx +2 -0
- package/client/src/commands.ts +36 -0
- package/client/src/components/chat/AttachmentChips.tsx +116 -0
- package/client/src/components/chat/ChatInput.tsx +250 -73
- package/client/src/components/chat/ChatView.tsx +242 -10
- package/client/src/components/chat/CommandPalette.tsx +162 -0
- package/client/src/components/chat/Message.tsx +23 -2
- package/client/src/components/chat/PromptQuestion.tsx +271 -0
- package/client/src/components/chat/TodoCard.tsx +57 -0
- package/client/src/components/chat/ToolResultRenderer.tsx +2 -1
- package/client/src/components/chat/VoiceRecorder.tsx +85 -0
- package/client/src/components/project-settings/ProjectClaude.tsx +14 -0
- package/client/src/components/project-settings/ProjectMemory.tsx +12 -2
- package/client/src/components/project-settings/ProjectNotifications.tsx +48 -0
- package/client/src/components/project-settings/ProjectRules.tsx +10 -1
- package/client/src/components/project-settings/ProjectSettingsView.tsx +6 -0
- package/client/src/components/settings/Appearance.tsx +1 -0
- package/client/src/components/settings/ClaudeSettings.tsx +24 -0
- package/client/src/components/settings/Editor.tsx +123 -0
- package/client/src/components/settings/GlobalMcp.tsx +10 -1
- package/client/src/components/settings/GlobalMemory.tsx +19 -0
- package/client/src/components/settings/GlobalRules.tsx +149 -0
- package/client/src/components/settings/GlobalSkills.tsx +10 -0
- package/client/src/components/settings/Notifications.tsx +88 -0
- package/client/src/components/settings/SettingsView.tsx +12 -0
- package/client/src/components/settings/skill-shared.tsx +2 -1
- package/client/src/components/setup/SetupWizard.tsx +1 -1
- package/client/src/components/sidebar/AddProjectModal.tsx +3 -2
- package/client/src/components/sidebar/NodeSettingsModal.tsx +23 -1
- package/client/src/components/sidebar/ProjectDropdown.tsx +176 -27
- package/client/src/components/sidebar/SettingsSidebar.tsx +11 -1
- package/client/src/components/sidebar/Sidebar.tsx +35 -2
- package/client/src/components/sidebar/UserIsland.tsx +18 -7
- package/client/src/components/ui/UpdatePrompt.tsx +47 -0
- package/client/src/components/workspace/FileBrowser.tsx +174 -0
- package/client/src/components/workspace/FileTree.tsx +129 -0
- package/client/src/components/workspace/FileViewer.tsx +211 -0
- package/client/src/components/workspace/NoteCard.tsx +119 -0
- package/client/src/components/workspace/NotesView.tsx +102 -0
- package/client/src/components/workspace/ScheduledTasksView.tsx +117 -0
- package/client/src/components/workspace/SplitPane.tsx +81 -0
- package/client/src/components/workspace/TabBar.tsx +185 -0
- package/client/src/components/workspace/TaskCard.tsx +158 -0
- package/client/src/components/workspace/TaskEditModal.tsx +114 -0
- package/client/src/components/{panels/Terminal.tsx → workspace/TerminalInstance.tsx} +50 -7
- package/client/src/components/workspace/TerminalView.tsx +110 -0
- package/client/src/components/workspace/WorkspaceView.tsx +116 -0
- package/client/src/hooks/useAttachments.ts +280 -0
- package/client/src/hooks/useEditorConfig.ts +28 -0
- package/client/src/hooks/useIdleDetection.ts +44 -0
- package/client/src/hooks/useInstallPrompt.ts +53 -0
- package/client/src/hooks/useNotifications.ts +54 -0
- package/client/src/hooks/useOnline.ts +6 -0
- package/client/src/hooks/useSession.ts +110 -4
- package/client/src/hooks/useSpinnerVerb.ts +36 -0
- package/client/src/hooks/useSwipeDrawer.ts +275 -0
- package/client/src/hooks/useVoiceRecorder.ts +123 -0
- package/client/src/hooks/useWorkspace.ts +48 -0
- package/client/src/providers/WebSocketProvider.tsx +18 -0
- package/client/src/router.tsx +48 -20
- package/client/src/stores/session.ts +136 -0
- package/client/src/stores/sidebar.ts +3 -2
- package/client/src/stores/workspace.ts +254 -0
- package/client/src/styles/global.css +131 -0
- package/client/src/utils/editorUrl.ts +62 -0
- package/client/vite.config.ts +53 -1
- package/package.json +1 -1
- package/server/src/daemon.ts +11 -1
- package/server/src/features/scheduler.ts +23 -0
- package/server/src/features/sticky-notes.ts +5 -3
- package/server/src/handlers/attachment.ts +172 -0
- package/server/src/handlers/chat.ts +43 -2
- package/server/src/handlers/editor.ts +40 -0
- package/server/src/handlers/fs.ts +10 -2
- package/server/src/handlers/memory.ts +3 -0
- package/server/src/handlers/notes.ts +4 -2
- package/server/src/handlers/scheduler.ts +18 -1
- package/server/src/handlers/session.ts +14 -8
- package/server/src/handlers/settings.ts +37 -2
- package/server/src/handlers/terminal.ts +13 -6
- package/server/src/project/pty-worker.cjs +83 -0
- package/server/src/project/sdk-bridge.ts +266 -11
- package/server/src/project/terminal.ts +78 -34
- package/shared/src/messages.ts +145 -4
- package/shared/src/models.ts +27 -1
- package/shared/src/project-settings.ts +1 -1
- package/tp.js +19 -0
- package/client/public/manifest.json +0 -24
- package/client/public/sw.js +0 -61
- package/client/src/components/panels/FileBrowser.tsx +0 -241
- package/client/src/components/panels/StickyNotes.tsx +0 -187
|
@@ -21,7 +21,11 @@ export function clearActiveProject(clientId: string): void {
|
|
|
21
21
|
registerHandler("fs", function (clientId: string, message: ClientMessage) {
|
|
22
22
|
if (message.type === "fs:list") {
|
|
23
23
|
var listMsg = message as FsListMessage;
|
|
24
|
-
var projectSlug = activeProjectByClient.get(clientId);
|
|
24
|
+
var projectSlug = activeProjectByClient.get(clientId) || listMsg.projectSlug;
|
|
25
|
+
if (listMsg.projectSlug) {
|
|
26
|
+
setActiveProject(clientId, listMsg.projectSlug);
|
|
27
|
+
projectSlug = listMsg.projectSlug;
|
|
28
|
+
}
|
|
25
29
|
if (!projectSlug) {
|
|
26
30
|
sendTo(clientId, { type: "chat:error", message: "No active project for fs:list" });
|
|
27
31
|
return;
|
|
@@ -40,7 +44,11 @@ registerHandler("fs", function (clientId: string, message: ClientMessage) {
|
|
|
40
44
|
|
|
41
45
|
if (message.type === "fs:read") {
|
|
42
46
|
var readMsg = message as FsReadMessage;
|
|
43
|
-
var projectSlugRead = activeProjectByClient.get(clientId);
|
|
47
|
+
var projectSlugRead = activeProjectByClient.get(clientId) || readMsg.projectSlug;
|
|
48
|
+
if (readMsg.projectSlug) {
|
|
49
|
+
setActiveProject(clientId, readMsg.projectSlug);
|
|
50
|
+
projectSlugRead = readMsg.projectSlug;
|
|
51
|
+
}
|
|
44
52
|
if (!projectSlugRead) {
|
|
45
53
|
sendTo(clientId, { type: "chat:error", message: "No active project for fs:read" });
|
|
46
54
|
return;
|
|
@@ -7,6 +7,9 @@ import { sendTo } from "../ws/broadcast";
|
|
|
7
7
|
import { loadConfig } from "../config";
|
|
8
8
|
|
|
9
9
|
function getMemoryDir(projectSlug: string): string | null {
|
|
10
|
+
if (projectSlug === "__global__") {
|
|
11
|
+
return join(homedir(), ".claude", "memory");
|
|
12
|
+
}
|
|
10
13
|
var config = loadConfig();
|
|
11
14
|
var project = config.projects.find(function (p) { return p.slug === projectSlug; });
|
|
12
15
|
if (!project) return null;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
ClientMessage,
|
|
3
|
+
NotesListMessage,
|
|
3
4
|
NotesCreateMessage,
|
|
4
5
|
NotesUpdateMessage,
|
|
5
6
|
NotesDeleteMessage,
|
|
@@ -10,13 +11,14 @@ import { listNotes, createNote, updateNote, deleteNote } from "../features/stick
|
|
|
10
11
|
|
|
11
12
|
registerHandler("notes", function (clientId: string, message: ClientMessage) {
|
|
12
13
|
if (message.type === "notes:list") {
|
|
13
|
-
|
|
14
|
+
var listMsg = message as NotesListMessage;
|
|
15
|
+
sendTo(clientId, { type: "notes:list_result", notes: listNotes(listMsg.projectSlug) });
|
|
14
16
|
return;
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
if (message.type === "notes:create") {
|
|
18
20
|
var createMsg = message as NotesCreateMessage;
|
|
19
|
-
var note = createNote(createMsg.content);
|
|
21
|
+
var note = createNote(createMsg.content, createMsg.projectSlug);
|
|
20
22
|
broadcast({ type: "notes:created", note });
|
|
21
23
|
return;
|
|
22
24
|
}
|
|
@@ -3,10 +3,11 @@ import type {
|
|
|
3
3
|
SchedulerCreateMessage,
|
|
4
4
|
SchedulerDeleteMessage,
|
|
5
5
|
SchedulerToggleMessage,
|
|
6
|
+
SchedulerUpdateMessage,
|
|
6
7
|
} from "@lattice/shared";
|
|
7
8
|
import { registerHandler } from "../ws/router";
|
|
8
9
|
import { sendTo } from "../ws/broadcast";
|
|
9
|
-
import { listTasks, createTask, deleteTask, toggleTask } from "../features/scheduler";
|
|
10
|
+
import { listTasks, createTask, deleteTask, toggleTask, updateTask } from "../features/scheduler";
|
|
10
11
|
|
|
11
12
|
registerHandler("scheduler", function (clientId: string, message: ClientMessage) {
|
|
12
13
|
if (message.type === "scheduler:list") {
|
|
@@ -44,4 +45,20 @@ registerHandler("scheduler", function (clientId: string, message: ClientMessage)
|
|
|
44
45
|
sendTo(clientId, { type: "scheduler:tasks", tasks: listTasks() });
|
|
45
46
|
return;
|
|
46
47
|
}
|
|
48
|
+
|
|
49
|
+
if (message.type === "scheduler:update") {
|
|
50
|
+
var updateMsg = message as SchedulerUpdateMessage;
|
|
51
|
+
var updated = updateTask(updateMsg.taskId, {
|
|
52
|
+
name: updateMsg.name,
|
|
53
|
+
prompt: updateMsg.prompt,
|
|
54
|
+
cron: updateMsg.cron,
|
|
55
|
+
});
|
|
56
|
+
if (!updated) {
|
|
57
|
+
sendTo(clientId, { type: "chat:error", message: "Failed to update task" });
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
sendTo(clientId, { type: "scheduler:task_updated", task: updated });
|
|
61
|
+
sendTo(clientId, { type: "scheduler:tasks", tasks: listTasks() });
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
47
64
|
});
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
import { getContextBreakdown } from "../project/context-breakdown";
|
|
23
23
|
import { setActiveSession } from "./chat";
|
|
24
24
|
import { setActiveProject } from "./fs";
|
|
25
|
-
import { wasSessionInterrupted, clearInterruptedFlag } from "../project/sdk-bridge";
|
|
25
|
+
import { wasSessionInterrupted, clearInterruptedFlag, isSessionBusy, watchSessionLock, stopExternalSession } from "../project/sdk-bridge";
|
|
26
26
|
|
|
27
27
|
registerHandler("session", function (clientId: string, message: ClientMessage) {
|
|
28
28
|
if (message.type === "session:list_request") {
|
|
@@ -62,13 +62,6 @@ registerHandler("session", function (clientId: string, message: ClientMessage) {
|
|
|
62
62
|
var createMsg = message as SessionCreateMessage;
|
|
63
63
|
var session = createSession(createMsg.projectSlug);
|
|
64
64
|
sendTo(clientId, { type: "session:created", session });
|
|
65
|
-
void listSessions(createMsg.projectSlug).then(function (sessions) {
|
|
66
|
-
sendTo(clientId, {
|
|
67
|
-
type: "session:list",
|
|
68
|
-
projectSlug: createMsg.projectSlug,
|
|
69
|
-
sessions,
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
65
|
return;
|
|
73
66
|
}
|
|
74
67
|
|
|
@@ -76,6 +69,7 @@ registerHandler("session", function (clientId: string, message: ClientMessage) {
|
|
|
76
69
|
var activateMsg = message as SessionActivateMessage;
|
|
77
70
|
setActiveSession(clientId, activateMsg.projectSlug, activateMsg.sessionId);
|
|
78
71
|
setActiveProject(clientId, activateMsg.projectSlug);
|
|
72
|
+
watchSessionLock(activateMsg.sessionId);
|
|
79
73
|
void Promise.all([
|
|
80
74
|
loadSessionHistory(activateMsg.projectSlug, activateMsg.sessionId),
|
|
81
75
|
getSessionTitle(activateMsg.projectSlug, activateMsg.sessionId),
|
|
@@ -86,6 +80,7 @@ registerHandler("session", function (clientId: string, message: ClientMessage) {
|
|
|
86
80
|
if (interrupted) {
|
|
87
81
|
clearInterruptedFlag(activateMsg.sessionId);
|
|
88
82
|
}
|
|
83
|
+
var busy = isSessionBusy(activateMsg.sessionId);
|
|
89
84
|
sendTo(clientId, {
|
|
90
85
|
type: "session:history",
|
|
91
86
|
projectSlug: activateMsg.projectSlug,
|
|
@@ -93,6 +88,7 @@ registerHandler("session", function (clientId: string, message: ClientMessage) {
|
|
|
93
88
|
messages: results[0],
|
|
94
89
|
title: results[1],
|
|
95
90
|
interrupted: interrupted || undefined,
|
|
91
|
+
busy: busy || undefined,
|
|
96
92
|
});
|
|
97
93
|
var usage = results[2];
|
|
98
94
|
if (usage) {
|
|
@@ -156,4 +152,14 @@ registerHandler("session", function (clientId: string, message: ClientMessage) {
|
|
|
156
152
|
});
|
|
157
153
|
});
|
|
158
154
|
}
|
|
155
|
+
|
|
156
|
+
if (message.type === "session:stop_external") {
|
|
157
|
+
var stopMsg = message as { type: string; sessionId: string };
|
|
158
|
+
var stopped = stopExternalSession(stopMsg.sessionId);
|
|
159
|
+
if (stopped) {
|
|
160
|
+
console.log("[lattice] Sent SIGINT to external CLI process for session " + stopMsg.sessionId);
|
|
161
|
+
} else {
|
|
162
|
+
sendTo(clientId, { type: "chat:error", message: "No external process found for this session." });
|
|
163
|
+
}
|
|
164
|
+
}
|
|
159
165
|
});
|
|
@@ -7,7 +7,21 @@ import type { LatticeConfig } from "@lattice/shared";
|
|
|
7
7
|
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
8
8
|
import { join } from "node:path";
|
|
9
9
|
import { homedir } from "node:os";
|
|
10
|
-
import { readGlobalMcpServers, writeGlobalMcpServers, readGlobalSkills } from "../project/project-files";
|
|
10
|
+
import { readGlobalMcpServers, writeGlobalMcpServers, readGlobalSkills, readGlobalRules } from "../project/project-files";
|
|
11
|
+
|
|
12
|
+
function detectIdeProjectName(projectPath: string): string | undefined {
|
|
13
|
+
try {
|
|
14
|
+
var ideDir = join(projectPath, ".idea");
|
|
15
|
+
if (!existsSync(ideDir)) return undefined;
|
|
16
|
+
var ideNameFile = join(ideDir, ".name");
|
|
17
|
+
if (existsSync(ideNameFile)) {
|
|
18
|
+
var name = readFileSync(ideNameFile, "utf-8").trim();
|
|
19
|
+
if (name) return name;
|
|
20
|
+
}
|
|
21
|
+
return projectPath.split("/").pop() || undefined;
|
|
22
|
+
} catch {}
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
11
25
|
import { loadOrCreateIdentity } from "../identity";
|
|
12
26
|
|
|
13
27
|
function loadGlobalClaudeMd(): string {
|
|
@@ -28,6 +42,21 @@ function saveGlobalClaudeMd(content: string): void {
|
|
|
28
42
|
writeFileSync(join(claudeDir, "CLAUDE.md"), content, "utf-8");
|
|
29
43
|
}
|
|
30
44
|
|
|
45
|
+
function loadSpinnerVerbs(): string[] {
|
|
46
|
+
var claudeSettingsPath = join(homedir(), ".claude", "settings.json");
|
|
47
|
+
var defaultVerbs = ["Thinking", "Analyzing", "Processing", "Computing", "Evaluating", "Considering", "Examining", "Reviewing"];
|
|
48
|
+
try {
|
|
49
|
+
var claudeSettings = JSON.parse(readFileSync(claudeSettingsPath, "utf-8"));
|
|
50
|
+
if (claudeSettings.spinnerVerbs) {
|
|
51
|
+
if (claudeSettings.spinnerVerbs.mode === "replace") {
|
|
52
|
+
return claudeSettings.spinnerVerbs.verbs || [];
|
|
53
|
+
}
|
|
54
|
+
return [...defaultVerbs, ...(claudeSettings.spinnerVerbs.verbs || [])];
|
|
55
|
+
}
|
|
56
|
+
} catch {}
|
|
57
|
+
return defaultVerbs;
|
|
58
|
+
}
|
|
59
|
+
|
|
31
60
|
registerHandler("settings", function (clientId: string, message: ClientMessage) {
|
|
32
61
|
if (message.type === "settings:get") {
|
|
33
62
|
var config = loadConfig();
|
|
@@ -38,11 +67,14 @@ registerHandler("settings", function (clientId: string, message: ClientMessage)
|
|
|
38
67
|
config: configWithClaudeMd,
|
|
39
68
|
mcpServers: readGlobalMcpServers() as Record<string, import("@lattice/shared").McpServerConfig>,
|
|
40
69
|
globalSkills: readGlobalSkills(),
|
|
70
|
+
globalRules: readGlobalRules(),
|
|
71
|
+
spinnerVerbs: loadSpinnerVerbs(),
|
|
72
|
+
wslDistro: process.env.WSL_DISTRO_NAME || undefined,
|
|
41
73
|
});
|
|
42
74
|
sendTo(clientId, {
|
|
43
75
|
type: "projects:list",
|
|
44
76
|
projects: config.projects.map(function (p) {
|
|
45
|
-
return { slug: p.slug, path: p.path, title: p.title, nodeId: identity.id, nodeName: config.name, isRemote: false };
|
|
77
|
+
return { slug: p.slug, path: p.path, title: p.title, nodeId: identity.id, nodeName: config.name, isRemote: false, ideProjectName: detectIdeProjectName(p.path) };
|
|
46
78
|
}),
|
|
47
79
|
});
|
|
48
80
|
return;
|
|
@@ -93,6 +125,9 @@ registerHandler("settings", function (clientId: string, message: ClientMessage)
|
|
|
93
125
|
config: updatedWithClaudeMd,
|
|
94
126
|
mcpServers: readGlobalMcpServers() as Record<string, import("@lattice/shared").McpServerConfig>,
|
|
95
127
|
globalSkills: readGlobalSkills(),
|
|
128
|
+
globalRules: readGlobalRules(),
|
|
129
|
+
spinnerVerbs: loadSpinnerVerbs(),
|
|
130
|
+
wslDistro: process.env.WSL_DISTRO_NAME || undefined,
|
|
96
131
|
});
|
|
97
132
|
var updatedIdentity = loadOrCreateIdentity();
|
|
98
133
|
broadcast({
|
|
@@ -29,14 +29,21 @@ export function cleanupClientTerminals(clientId: string): void {
|
|
|
29
29
|
|
|
30
30
|
registerHandler("terminal", function(clientId: string, message: ClientMessage) {
|
|
31
31
|
if (message.type === "terminal:create") {
|
|
32
|
-
var
|
|
32
|
+
var createMsg = message as TerminalCreateMessage;
|
|
33
33
|
var cwd = homedir();
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
if (createMsg.projectSlug) {
|
|
36
|
+
var slugProject = getProjectBySlug(createMsg.projectSlug);
|
|
37
|
+
if (slugProject) {
|
|
38
|
+
cwd = slugProject.path;
|
|
39
|
+
}
|
|
40
|
+
} else {
|
|
41
|
+
var active = getActiveSession(clientId);
|
|
42
|
+
if (active) {
|
|
43
|
+
var project = getProjectBySlug(active.projectSlug);
|
|
44
|
+
if (project) {
|
|
45
|
+
cwd = project.path;
|
|
46
|
+
}
|
|
40
47
|
}
|
|
41
48
|
}
|
|
42
49
|
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// Worker that runs node-pty in a subprocess, communicating via stdin/stdout JSON messages.
|
|
2
|
+
// Running node-pty in a separate process avoids SIGHUP issues with Bun's --watch mode.
|
|
3
|
+
var pty = require("node-pty");
|
|
4
|
+
|
|
5
|
+
var term = null;
|
|
6
|
+
|
|
7
|
+
process.stdin.setEncoding("utf-8");
|
|
8
|
+
var buffer = "";
|
|
9
|
+
|
|
10
|
+
process.stdin.on("data", function (chunk) {
|
|
11
|
+
buffer += chunk;
|
|
12
|
+
var lines = buffer.split("\n");
|
|
13
|
+
buffer = lines.pop();
|
|
14
|
+
for (var i = 0; i < lines.length; i++) {
|
|
15
|
+
if (!lines[i].trim()) continue;
|
|
16
|
+
try {
|
|
17
|
+
handleMessage(JSON.parse(lines[i]));
|
|
18
|
+
} catch (e) {
|
|
19
|
+
// ignore parse errors
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
function send(msg) {
|
|
25
|
+
process.stdout.write(JSON.stringify(msg) + "\n");
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function handleMessage(msg) {
|
|
29
|
+
if (msg.type === "create") {
|
|
30
|
+
var shell = process.env.SHELL || "bash";
|
|
31
|
+
term = pty.spawn(shell, [], {
|
|
32
|
+
name: "xterm-256color",
|
|
33
|
+
cols: msg.cols || 80,
|
|
34
|
+
rows: msg.rows || 24,
|
|
35
|
+
cwd: msg.cwd || process.env.HOME,
|
|
36
|
+
env: process.env,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
term.onData(function (data) {
|
|
40
|
+
send({ type: "data", data: data });
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
term.onExit(function (e) {
|
|
44
|
+
send({ type: "exit", code: e.exitCode || 0 });
|
|
45
|
+
process.exit(0);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
send({ type: "ready", pid: term.pid });
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (msg.type === "input" && term) {
|
|
52
|
+
term.write(msg.data);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (msg.type === "resize" && term) {
|
|
56
|
+
try {
|
|
57
|
+
term.resize(msg.cols, msg.rows);
|
|
58
|
+
} catch (e) {
|
|
59
|
+
// ignore resize errors
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (msg.type === "kill") {
|
|
64
|
+
if (term) {
|
|
65
|
+
try { term.kill(); } catch (e) { /* already dead */ }
|
|
66
|
+
}
|
|
67
|
+
process.exit(0);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
process.on("SIGTERM", function () {
|
|
72
|
+
if (term) {
|
|
73
|
+
try { term.kill(); } catch (e) { /* already dead */ }
|
|
74
|
+
}
|
|
75
|
+
process.exit(0);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
process.on("SIGHUP", function () {
|
|
79
|
+
if (term) {
|
|
80
|
+
try { term.kill(); } catch (e) { /* already dead */ }
|
|
81
|
+
}
|
|
82
|
+
process.exit(0);
|
|
83
|
+
});
|