wotann 0.5.93 → 0.5.94

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.
@@ -7,9 +7,13 @@
7
7
  * escalation, agent config persistence, hardcoded secrets, and invisible text.
8
8
  */
9
9
  import { createHash } from "node:crypto";
10
- import { existsSync, lstatSync, readFileSync, readdirSync, realpathSync, } from "node:fs";
10
+ import { existsSync, lstatSync, readFileSync, readdirSync, realpathSync } from "node:fs";
11
11
  import { extname, isAbsolute, join, relative, resolve } from "node:path";
12
- export const TRUSTED_SKILL_REPOS = new Set(["openai/skills", "anthropics/skills", "huggingface/skills"]);
12
+ export const TRUSTED_SKILL_REPOS = new Set([
13
+ "openai/skills",
14
+ "anthropics/skills",
15
+ "huggingface/skills",
16
+ ]);
13
17
  export const INSTALL_POLICY = {
14
18
  builtin: ["allow", "allow", "allow"],
15
19
  trusted: ["allow", "allow", "block"],
@@ -405,7 +409,14 @@ export function contentHash(path) {
405
409
  return `sha256:${h.digest("hex").slice(0, 16)}`;
406
410
  }
407
411
  function p(pattern, patternId, severity, category, description, recommendation) {
408
- return { regex: new RegExp(pattern, "i"), patternId, severity, category, description, recommendation };
412
+ return {
413
+ regex: new RegExp(pattern, "i"),
414
+ patternId,
415
+ severity,
416
+ category,
417
+ description,
418
+ recommendation,
419
+ };
409
420
  }
410
421
  function buildScanResult(input) {
411
422
  const issues = deduplicateIssues(input.findings);
@@ -489,7 +500,17 @@ function checkStructure(skillDir) {
489
500
  return findings;
490
501
  }
491
502
  function structuralIssue(patternId, severity, category, file, match, description, recommendation) {
492
- return { pattern: category, patternId, category, file, line: 0, match, severity, description, recommendation };
503
+ return {
504
+ pattern: category,
505
+ patternId,
506
+ category,
507
+ file,
508
+ line: 0,
509
+ match,
510
+ severity,
511
+ description,
512
+ recommendation,
513
+ };
493
514
  }
494
515
  function listFiles(root) {
495
516
  return listEntries(root).filter((entry) => {
@@ -524,7 +545,7 @@ function isInside(child, parent) {
524
545
  function worstSeverity(issues) {
525
546
  if (issues.length === 0)
526
547
  return "info";
527
- return issues.reduce((worst, issue) => (SEVERITY_ORDER[issue.severity] < SEVERITY_ORDER[worst] ? issue.severity : worst), "info");
548
+ return issues.reduce((worst, issue) => SEVERITY_ORDER[issue.severity] < SEVERITY_ORDER[worst] ? issue.severity : worst, "info");
528
549
  }
529
550
  function compareIssueSeverity(a, b) {
530
551
  return SEVERITY_ORDER[a.severity] - SEVERITY_ORDER[b.severity];
@@ -38,6 +38,20 @@ export interface RawModeStream {
38
38
  * state is preserved when it works) inside a try/catch. If it throws
39
39
  * here, the resolver falls through to `/dev/tty` or refuses cleanly
40
40
  * instead of mounting Ink into the silent loop.
41
+ *
42
+ * Node 25 `_handle` exception (added 2026-05-28 — empirical evidence
43
+ * from user diagnostic): on Node v25.x, the probe call throws
44
+ * "Cannot read properties of undefined (reading '_handle')"
45
+ * because the libuv TTY binding (`this._handle`) isn't initialized at
46
+ * probe time — Node 25 lazily binds it on first I/O. The same
47
+ * `setRawMode` call AT INK'S RENDER COMMIT succeeds because by then
48
+ * Ink has read from the stream and the binding is live. Treating
49
+ * this specific error as "passes" (optimistic) lets the mount
50
+ * proceed; the `mount-interactive-ink` Ink-throw backstop catches
51
+ * any genuine failure at render time and writes the same actionable
52
+ * guidance. False-positive cost: a runtime error message instead of
53
+ * a guard refusal — same end UX. True-positive value: working TUI
54
+ * under Node 25, which is the user's current default.
41
55
  */
42
56
  export declare function isRawModeCapable(stream: unknown): boolean;
43
57
  export interface ResolveStdinOptions {
@@ -35,6 +35,20 @@ import { ReadStream } from "node:tty";
35
35
  * state is preserved when it works) inside a try/catch. If it throws
36
36
  * here, the resolver falls through to `/dev/tty` or refuses cleanly
37
37
  * instead of mounting Ink into the silent loop.
38
+ *
39
+ * Node 25 `_handle` exception (added 2026-05-28 — empirical evidence
40
+ * from user diagnostic): on Node v25.x, the probe call throws
41
+ * "Cannot read properties of undefined (reading '_handle')"
42
+ * because the libuv TTY binding (`this._handle`) isn't initialized at
43
+ * probe time — Node 25 lazily binds it on first I/O. The same
44
+ * `setRawMode` call AT INK'S RENDER COMMIT succeeds because by then
45
+ * Ink has read from the stream and the binding is live. Treating
46
+ * this specific error as "passes" (optimistic) lets the mount
47
+ * proceed; the `mount-interactive-ink` Ink-throw backstop catches
48
+ * any genuine failure at render time and writes the same actionable
49
+ * guidance. False-positive cost: a runtime error message instead of
50
+ * a guard refusal — same end UX. True-positive value: working TUI
51
+ * under Node 25, which is the user's current default.
38
52
  */
39
53
  export function isRawModeCapable(stream) {
40
54
  if (stream === null || typeof stream !== "object")
@@ -48,10 +62,22 @@ export function isRawModeCapable(stream) {
48
62
  setRawMode(currentIsRaw);
49
63
  return true;
50
64
  }
51
- catch {
52
- return false;
65
+ catch (e) {
66
+ return isNode25HandleInitDefer(e);
53
67
  }
54
68
  }
69
+ /**
70
+ * Detect the Node 25+ "_handle is undefined at probe time" pattern.
71
+ * Matches both the literal `_handle` reference and the broader libuv
72
+ * binding init-order race that surfaces under the same wording. Kept
73
+ * separate from `isRawModeCapable` so the rationale lives next to
74
+ * the matcher and the same logic can drive `probeStdinDetail`.
75
+ */
76
+ function isNode25HandleInitDefer(e) {
77
+ if (!(e instanceof Error))
78
+ return false;
79
+ return e.message.includes("_handle");
80
+ }
55
81
  /**
56
82
  * Open the controlling terminal as a raw-capable input stream, or
57
83
  * `null` if there is none (Windows without a console, detached
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wotann",
3
- "version": "0.5.93",
3
+ "version": "0.5.94",
4
4
  "description": "WOTANN — The All-Father of AI Agent Harnesses",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",