@yagni-app/code-staging 1.1.4-staging.1420.1 → 1.1.4-staging.1422.1

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.
@@ -73,7 +73,7 @@ interface ExecResult {
73
73
  durationMs: number;
74
74
  }
75
75
  /** Execute a hook command with stdin JSON, timeout, and fail-soft. */
76
- declare function execHook(command: string, inputJson: string, cwd: string, timeoutMs?: number, env?: NodeJS.ProcessEnv): Promise<ExecResult>;
76
+ export declare function execHook(command: string, inputJson: string, cwd: string, timeoutMs?: number, env?: NodeJS.ProcessEnv): Promise<ExecResult>;
77
77
  /** Extract permissionDecision from PreToolUse stdout JSON. */
78
78
  export declare function parsePreToolUseOutput(stdout: string): PreToolUseHookResult;
79
79
  /** Extract decision from PermissionRequest stdout JSON. */
@@ -132,7 +132,7 @@ export function matchesMatcher(matcher, input) {
132
132
  }
133
133
  const DEFAULT_TIMEOUT_MS = 10_000;
134
134
  /** Execute a hook command with stdin JSON, timeout, and fail-soft. */
135
- function execHook(command, inputJson, cwd, timeoutMs = DEFAULT_TIMEOUT_MS, env) {
135
+ export function execHook(command, inputJson, cwd, timeoutMs = DEFAULT_TIMEOUT_MS, env) {
136
136
  return new Promise((resolve) => {
137
137
  const started = Date.now();
138
138
  let child;
@@ -157,6 +157,17 @@ function execHook(command, inputJson, cwd, timeoutMs = DEFAULT_TIMEOUT_MS, env)
157
157
  let stdout = "";
158
158
  let stderr = "";
159
159
  let timedOut = false;
160
+ // An EPIPE on a large async stdin write surfaces as an 'error' EVENT on
161
+ // the stdin stream (WriteWrap.onWriteComplete), not a synchronous throw
162
+ // — the try/catch below cannot catch it, and without a listener it
163
+ // escalates to uncaughtException and kills the session. A hook child
164
+ // that exits before draining stdin is a failed hook, never a dead host.
165
+ let stdinError = null;
166
+ child.stdin?.on("error", (err) => { stdinError = err; });
167
+ const stdinErrorCode = () => {
168
+ const code = stdinError?.code;
169
+ return typeof code === "string" ? code : null;
170
+ };
160
171
  const timer = setTimeout(() => {
161
172
  timedOut = true;
162
173
  try {
@@ -178,11 +189,24 @@ function execHook(command, inputJson, cwd, timeoutMs = DEFAULT_TIMEOUT_MS, env)
178
189
  });
179
190
  child.on("close", (code) => {
180
191
  clearTimeout(timer);
192
+ // close fires after the stdio streams settled, so stdinError is
193
+ // final here. A stdin failure means the hook's input was NOT
194
+ // delivered — the hook did not receive the payload it was promised,
195
+ // so it reports failed even with a zero exit code. The errno code
196
+ // (EPIPE) rides the message for filterability. A timeout remains the
197
+ // more specific diagnosis when both apply.
198
+ let error = null;
199
+ if (timedOut) {
200
+ error = `hook timed out after ${Math.round(timeoutMs / 1000)}s`;
201
+ }
202
+ else if (stdinError !== null) {
203
+ error = `hook stdin write failed: ${stdinErrorCode() ?? stdinError.message}`;
204
+ }
181
205
  resolve({
182
206
  exitCode: code,
183
207
  stdout,
184
208
  stderr,
185
- error: timedOut ? `hook timed out after ${Math.round(timeoutMs / 1000)}s` : null,
209
+ error,
186
210
  durationMs: Date.now() - started,
187
211
  });
188
212
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yagni-app/code-staging",
3
- "version": "1.1.4-staging.1420.1",
3
+ "version": "1.1.4-staging.1422.1",
4
4
  "description": "YAGNI Code: a terminal coding agent that already knows your company. One YAGNI login routes the model and grounds the agent in your team's context.",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "author": "YAGNI, Inc. <jack@yagni.app> (https://yagni.app)",
@@ -58,5 +58,5 @@
58
58
  "turndown": "^7.2.4",
59
59
  "typebox": "^1.3.15"
60
60
  },
61
- "yagniSourceSha": "651ed1d5bda0a76c0ce1257e0dc1a47769e2fe5c"
61
+ "yagniSourceSha": "708eff198d4e1268db1a212ebcd03bf9434bff88"
62
62
  }