vibe-coding-master 0.3.3 → 0.3.4

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.
@@ -33,16 +33,22 @@ export function createNodePtyTerminalRuntime(deps) {
33
33
  startedAt: now(),
34
34
  exitCode: null
35
35
  };
36
+ const logWriter = createTerminalLogWriter(deps.fs, input.logPath, deps.onLogWriteError ?? defaultLogWriteErrorHandler);
36
37
  const entry = {
37
38
  input,
38
39
  session,
39
40
  process: child,
40
- listeners: new Set()
41
+ listeners: new Set(),
42
+ logWriter,
43
+ disposed: false
41
44
  };
42
45
  entries.set(session.id, entry);
43
46
  child.onData((data) => {
47
+ if (entry.disposed) {
48
+ return;
49
+ }
44
50
  entry.session.lastOutputAt = now();
45
- void deps.fs.appendText(input.logPath, data);
51
+ entry.logWriter.append(data);
46
52
  emit(entry, {
47
53
  sessionId: session.id,
48
54
  taskSlug: input.taskSlug,
@@ -52,8 +58,13 @@ export function createNodePtyTerminalRuntime(deps) {
52
58
  });
53
59
  });
54
60
  child.onExit(({ exitCode }) => {
61
+ if (entry.disposed) {
62
+ return;
63
+ }
64
+ entry.disposed = true;
55
65
  entry.session.status = exitCode === 0 ? "exited" : "crashed";
56
66
  entry.session.exitCode = exitCode;
67
+ void entry.logWriter.close();
57
68
  emit(entry, {
58
69
  sessionId: session.id,
59
70
  taskSlug: input.taskSlug,
@@ -102,12 +113,16 @@ export function createNodePtyTerminalRuntime(deps) {
102
113
  },
103
114
  async stop(sessionId) {
104
115
  const entry = getEntry(entries, sessionId);
116
+ entry.disposed = true;
105
117
  entry.session.status = "exited";
106
118
  entry.process.kill();
119
+ await entry.logWriter.close();
107
120
  },
108
121
  async restart(sessionId) {
109
122
  const entry = getEntry(entries, sessionId);
123
+ entry.disposed = true;
110
124
  entry.process.kill();
125
+ await entry.logWriter.close();
111
126
  return create(entry.input, sessionId);
112
127
  },
113
128
  subscribe(sessionId, listener, options = {}) {
@@ -139,12 +154,40 @@ export function createNodePtyTerminalRuntime(deps) {
139
154
  }
140
155
  };
141
156
  }
157
+ export function createTerminalLogWriter(fs, logPath, onError) {
158
+ let closed = false;
159
+ let pending = Promise.resolve();
160
+ return {
161
+ append(data) {
162
+ if (closed || !data) {
163
+ return;
164
+ }
165
+ pending = pending
166
+ .then(() => fs.appendText(logPath, data))
167
+ .catch((error) => {
168
+ try {
169
+ onError(error, logPath);
170
+ }
171
+ catch {
172
+ // Logging must never break terminal output delivery or future log writes.
173
+ }
174
+ });
175
+ },
176
+ async close() {
177
+ closed = true;
178
+ await pending.catch(() => undefined);
179
+ }
180
+ };
181
+ }
142
182
  async function readTerminalReplayText(fs, logPath) {
143
183
  const data = fs.readTextTail
144
184
  ? await fs.readTextTail(logPath, TERMINAL_REPLAY_TAIL_LIMIT_BYTES)
145
185
  : tailTerminalReplay(await fs.readText(logPath));
146
186
  return tailTerminalReplay(data);
147
187
  }
188
+ function defaultLogWriteErrorHandler(error, logPath) {
189
+ console.warn(`[VCM] Failed to append terminal log: ${logPath}`, error);
190
+ }
148
191
  export function tailTerminalReplay(data, limitBytes = TERMINAL_REPLAY_TAIL_LIMIT_BYTES) {
149
192
  if (limitBytes <= 0 || Buffer.byteLength(data, "utf8") <= limitBytes) {
150
193
  return data;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibe-coding-master",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "Local GUI session cockpit for Claude Code role sessions.",
5
5
  "type": "module",
6
6
  "files": [