From 4cdad8eee99cb13e70140a9697fc64e24f5d7759 Mon Sep 17 00:00:00 2001 From: William Valentin Date: Sun, 15 Feb 2026 21:44:40 -0800 Subject: [PATCH] fix(tools): clear timeout timers and update audit state --- .../2026-02-16-codebase-audit-report.md | 7 + docs/plans/state.json | 1059 +++++++++-------- src/tools/executor.test.ts | 18 +- src/tools/executor.ts | 14 +- 4 files changed, 607 insertions(+), 491 deletions(-) diff --git a/docs/plans/analysis/2026-02-16-codebase-audit-report.md b/docs/plans/analysis/2026-02-16-codebase-audit-report.md index 1bdafab..d8d2047 100644 --- a/docs/plans/analysis/2026-02-16-codebase-audit-report.md +++ b/docs/plans/analysis/2026-02-16-codebase-audit-report.md @@ -3,6 +3,13 @@ Date: 2026-02-16 Scope: Production-risk-first audit of bugs, code improvements, and feature opportunities. +## Remediation Status (2026-02-16) + +- ✅ F-001 addressed: chat markdown rendering now sanitizes HTML before DOM insertion in `src/gateway/ui/pages/chat.js` (and legacy `src/gateway/ui/chat.html`). +- ✅ F-006 addressed: inbound HTTP request bodies now enforce a configurable max-size limit (`server.max_request_body_bytes`) with `413 Payload Too Large` responses. +- ✅ F-007 addressed: `ToolExecutor` timeout timer handles are now cleared in `finally`, preventing orphan timers on fast/failed tool calls. +- ✅ F-016 partially addressed: gateway + webhook body readers were consolidated into shared utility `src/utils/httpBody.ts` with size-limit enforcement. + ## Executive Summary Current health snapshot: diff --git a/docs/plans/state.json b/docs/plans/state.json index 1d0fd6e..b0a5b1d 100644 --- a/docs/plans/state.json +++ b/docs/plans/state.json @@ -2,7 +2,6 @@ "version": "1.0", "updated_at": "2026-02-16", "description": "Tracks the status of all Flynn plans and implementation phases", - "plans": { "docs-agent-oriented-diagrams-pass": { "status": "completed", @@ -42,7 +41,6 @@ ], "test_status": "pnpm test:run + pnpm typecheck passing" }, - "zai-auth-resolution-and-401-hints": { "status": "completed", "date": "2026-02-16", @@ -56,7 +54,6 @@ ], "test_status": "pnpm test:run src/daemon/clientFactory.test.ts src/models/openai.test.ts + pnpm typecheck passing (updated to cover textual 401 without status field)" }, - "tui-model-provider-switch-activates-tier": { "status": "completed", "date": "2026-02-16", @@ -68,7 +65,6 @@ ], "test_status": "pnpm test:run src/frontends/tui/minimal.test.ts src/models/openai.test.ts src/daemon/clientFactory.test.ts + pnpm typecheck passing" }, - "zai-auth-reauthenticate-confirmation": { "status": "completed", "date": "2026-02-16", @@ -80,7 +76,6 @@ ], "test_status": "pnpm test:run src/cli/zai-auth.test.ts + pnpm typecheck passing" }, - "auth-commands-reauthenticate-confirmation": { "status": "completed", "date": "2026-02-16", @@ -96,7 +91,6 @@ ], "test_status": "pnpm test:run src/cli/openai-key.test.ts src/cli/anthropic-auth.test.ts src/cli/openai-auth.test.ts src/cli/zai-auth.test.ts + pnpm typecheck passing" }, - "cli-suppress-punycode-deprecation-warning": { "status": "completed", "date": "2026-02-16", @@ -109,7 +103,6 @@ ], "test_status": "pnpm test:run src/cli/suppressNodeWarnings.test.ts src/cli/index.test.ts + pnpm typecheck + pnpm build passing" }, - "zai-auth-mode-selection-api-vs-plan": { "status": "completed", "date": "2026-02-16", @@ -122,7 +115,6 @@ ], "test_status": "pnpm test:run src/cli/zai-auth.test.ts src/frontends/tui/minimal.test.ts + pnpm typecheck passing" }, - "tui-login-reauth-confirmation-all-providers": { "status": "completed", "date": "2026-02-16", @@ -134,7 +126,6 @@ ], "test_status": "pnpm test:run src/frontends/tui/minimal.login.test.ts src/frontends/tui/minimal.test.ts + pnpm typecheck passing" }, - "anthropic-auth-mode-flag": { "status": "completed", "date": "2026-02-16", @@ -146,7 +137,6 @@ ], "test_status": "pnpm test:run src/cli/anthropic-auth.test.ts src/cli/index.test.ts + pnpm typecheck passing" }, - "deployment-port-env-override": { "status": "completed", "date": "2026-02-16", @@ -158,7 +148,6 @@ ], "test_status": "pnpm test:run + pnpm typecheck passing" }, - "deployment-targets-nix": { "file": "2026-02-16-deployment-targets.md", "status": "completed", @@ -178,7 +167,6 @@ ], "test_status": "nix build dependency hash resolved (fetchPnpmDeps hash pinned from build output); run nix build .#flynn to verify end-to-end in host environment" }, - "deployment-targets-paas": { "file": "2026-02-16-deployment-targets.md", "status": "completed", @@ -200,7 +188,6 @@ ], "test_status": "pnpm typecheck passing (no runtime code changes)" }, - "openclaw-gap-roadmap": { "file": "2026-02-15-openclaw-gap-roadmap.md", "status": "completed", @@ -372,7 +359,6 @@ ], "test_status": "pnpm typecheck + pnpm test:run passing" }, - "elevated-mode": { "status": "completed", "date": "2026-02-16", @@ -394,7 +380,6 @@ ], "test_status": "pnpm typecheck + pnpm test:run passing" }, - "matrix-channel-adapter": { "file": "2026-02-15-matrix-channel-adapter.md", "status": "completed", @@ -611,7 +596,10 @@ "priority": "P0", "status": "completed", "description": "Persistent memory with file-based storage, memory tools, auto-extraction after compaction", - "depends_on": ["phase_0", "phase_1"], + "depends_on": [ + "phase_0", + "phase_1" + ], "files_created": [ "src/memory/store.ts", "src/memory/store.test.ts", @@ -664,7 +652,9 @@ "src/daemon/index.ts", "package.json" ], - "new_dependencies": ["@slack/bolt"], + "new_dependencies": [ + "@slack/bolt" + ], "test_status": "22/22 passing", "notes": "Socket Mode only (HTTP fallback deferred). Slash commands deferred. User ID used as senderName (display name resolution is a follow-up)." }, @@ -682,7 +672,9 @@ "src/daemon/index.ts", "package.json" ], - "new_dependencies": ["whatsapp-web.js"], + "new_dependencies": [ + "whatsapp-web.js" + ], "test_status": "25/25 passing", "notes": "QR code auth via LocalAuth. Session persistence via data_dir. Group messages filtered (DM only). Phone number allowlist. Headless Chrome with Puppeteer." } @@ -748,7 +740,12 @@ "src/tools/builtin/web-fetch.ts", "src/tools/builtin/web-fetch.test.ts" ], - "new_dependencies": ["turndown", "linkedom", "@mozilla/readability", "@types/turndown"], + "new_dependencies": [ + "turndown", + "linkedom", + "@mozilla/readability", + "@types/turndown" + ], "test_status": "10/10 passing" } } @@ -953,22 +950,30 @@ "telegram": { "status": "completed", "description": "Handle message:photo (largest size, download via getFile API, base64) and image message:document events with caption text", - "files_modified": ["src/channels/telegram/adapter.ts"] + "files_modified": [ + "src/channels/telegram/adapter.ts" + ] }, "discord": { "status": "completed", "description": "Extract image attachments from message.attachments Collection, pass Discord CDN URLs directly", - "files_modified": ["src/channels/discord/adapter.ts"] + "files_modified": [ + "src/channels/discord/adapter.ts" + ] }, "slack": { "status": "completed", "description": "Download image files via url_private_download with bot token auth, base64 encode", - "files_modified": ["src/channels/slack/adapter.ts"] + "files_modified": [ + "src/channels/slack/adapter.ts" + ] }, "whatsapp": { "status": "completed", "description": "Use downloadMedia() from whatsapp-web.js (returns base64 natively)", - "files_modified": ["src/channels/whatsapp/adapter.ts"] + "files_modified": [ + "src/channels/whatsapp/adapter.ts" + ] }, "webchat": { "status": "completed", @@ -1250,12 +1255,13 @@ "src/daemon/index.ts", "package.json" ], - "new_dependencies": ["googleapis"], + "new_dependencies": [ + "googleapis" + ], "test_status": "16/16 passing" } } }, - "gmail-push-revisit": { "status": "completed", "date": "2026-02-13", @@ -1278,10 +1284,11 @@ "package.json", "pnpm-lock.yaml" ], - "new_dependencies": ["@google-cloud/pubsub"], + "new_dependencies": [ + "@google-cloud/pubsub" + ], "test_status": "pnpm typecheck + pnpm test:run passing" }, - "openai-oauth-codex": { "status": "completed", "date": "2026-02-13", @@ -1304,7 +1311,6 @@ ], "test_status": "pnpm typecheck + pnpm test:run passing" }, - "zai-glm-4.7-credential-integration": { "status": "completed", "date": "2026-02-13", @@ -1566,7 +1572,9 @@ "status": "completed", "date": "2026-02-09", "summary": "Configurable log-level system to suppress noisy fallback debug output in TUI. Replaces console.debug/log/warn with structured logger respecting config log_level (default: info).", - "files_created": ["src/logger.ts"], + "files_created": [ + "src/logger.ts" + ], "files_modified": [ "src/models/router.ts", "src/models/retry.ts", @@ -1915,471 +1923,548 @@ "test_status": "pnpm typecheck + pnpm test:run (1597/1597) + pnpm build passing" }, "skills_infrastructure": { - "file": "2026-02-11-skills-infrastructure-plan.md", - "status": "completed", - "date": "2026-02-11", - "summary": "Three-phase plan to improve skills system: Command Dispatch (P0), Skills Watcher (P1), Installer Specs (P1). Infrastructure-first approach before integrating ClawHub skills. Estimated 8-11 hours total. Model strategy: glm-4.7-flash for mechanical tasks, glm-4.7 for complex/orchestration tasks.", - "phases": { - "phase_1_command_dispatch": { - "priority": "P0", - "status": "completed", - "description": "flynn skills CLI commands (list/info/install/uninstall/refresh) with doctor enhancement", - "effort": "2-3 hours", - "sub_slices": { - "skills_list_command": { - "status": "completed", - "description": "Added `flynn skills list` command dispatch with table/JSON output and CLI registration", - "files_created": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "files_modified": [ - "src/cli/index.ts", - "src/cli/index.test.ts" - ], - "test_status": "typecheck + targeted skills/index CLI tests + full test suite + lint (warnings only, 0 errors) + build passing" - }, - "skills_info_command": { - "status": "completed", - "description": "Added `flynn skills info ` command dispatch with human-readable and JSON output for discovered skills", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "typecheck + targeted skills CLI tests + full test suite + lint (warnings only, 0 errors) + build passing" - }, - "skills_install_command_local": { - "status": "completed", - "description": "Added `flynn skills install ` local-directory command dispatch using SkillInstaller with config-aware managed_dir resolution", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "typecheck + targeted skills CLI tests + full test suite + lint (warnings only, 0 errors) + build passing" - }, - "skills_uninstall_command": { - "status": "completed", - "description": "Added `flynn skills uninstall ` command dispatch with --yes confirmation guard and managed-tier uninstall protection", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "typecheck + targeted skills CLI tests + full test suite + lint (warnings only, 0 errors) + build passing" - }, - "skills_refresh_command": { - "status": "completed", - "description": "Added `flynn skills refresh` command dispatch with human-readable and JSON summary output for current skill discovery", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "typecheck + targeted skills CLI tests + full test suite + lint (warnings only, 0 errors) + build passing" - }, - "doctor_skills_diagnostics": { - "status": "completed", - "description": "Enhanced `flynn doctor` skills diagnostics to report availability counts and warn on missing configured skill directories", - "files_modified": [ - "src/cli/doctor.ts", - "src/cli/doctor.test.ts" - ], - "test_status": "typecheck + targeted doctor tests + full test suite + lint (warnings only, 0 errors) + build passing" + "file": "2026-02-11-skills-infrastructure-plan.md", + "status": "completed", + "date": "2026-02-11", + "summary": "Three-phase plan to improve skills system: Command Dispatch (P0), Skills Watcher (P1), Installer Specs (P1). Infrastructure-first approach before integrating ClawHub skills. Estimated 8-11 hours total. Model strategy: glm-4.7-flash for mechanical tasks, glm-4.7 for complex/orchestration tasks.", + "phases": { + "phase_1_command_dispatch": { + "priority": "P0", + "status": "completed", + "description": "flynn skills CLI commands (list/info/install/uninstall/refresh) with doctor enhancement", + "effort": "2-3 hours", + "sub_slices": { + "skills_list_command": { + "status": "completed", + "description": "Added `flynn skills list` command dispatch with table/JSON output and CLI registration", + "files_created": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "files_modified": [ + "src/cli/index.ts", + "src/cli/index.test.ts" + ], + "test_status": "typecheck + targeted skills/index CLI tests + full test suite + lint (warnings only, 0 errors) + build passing" + }, + "skills_info_command": { + "status": "completed", + "description": "Added `flynn skills info ` command dispatch with human-readable and JSON output for discovered skills", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "typecheck + targeted skills CLI tests + full test suite + lint (warnings only, 0 errors) + build passing" + }, + "skills_install_command_local": { + "status": "completed", + "description": "Added `flynn skills install ` local-directory command dispatch using SkillInstaller with config-aware managed_dir resolution", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "typecheck + targeted skills CLI tests + full test suite + lint (warnings only, 0 errors) + build passing" + }, + "skills_uninstall_command": { + "status": "completed", + "description": "Added `flynn skills uninstall ` command dispatch with --yes confirmation guard and managed-tier uninstall protection", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "typecheck + targeted skills CLI tests + full test suite + lint (warnings only, 0 errors) + build passing" + }, + "skills_refresh_command": { + "status": "completed", + "description": "Added `flynn skills refresh` command dispatch with human-readable and JSON summary output for current skill discovery", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "typecheck + targeted skills CLI tests + full test suite + lint (warnings only, 0 errors) + build passing" + }, + "doctor_skills_diagnostics": { + "status": "completed", + "description": "Enhanced `flynn doctor` skills diagnostics to report availability counts and warn on missing configured skill directories", + "files_modified": [ + "src/cli/doctor.ts", + "src/cli/doctor.test.ts" + ], + "test_status": "typecheck + targeted doctor tests + full test suite + lint (warnings only, 0 errors) + build passing" + } } - } - }, - "phase_2_skills_watcher": { - "priority": "P1", - "status": "completed", - "description": "Auto-reload skills with chokidar file watcher, configurable debounce", - "effort": "3-4 hours", - "sub_slices": { - "watcher_bootstrap": { - "status": "completed", - "description": "Added core `SkillsWatcher` class with debounced change batching, lifecycle controls, and foundational tests", - "files_created": [ - "src/skills/watcher.ts", - "src/skills/watcher.test.ts" - ], - "files_modified": [ - "src/skills/index.ts" - ], - "test_status": "typecheck + targeted watcher tests + full test suite + lint (warnings only, 0 errors) + build passing" - }, - "watcher_daemon_wiring": { - "status": "completed", - "description": "Wired SkillsWatcher into daemon skills initialization and shutdown lifecycle behind config toggle with debounce settings", - "files_created": [ - "src/daemon/services.test.ts" - ], - "files_modified": [ - "src/config/schema.ts", - "src/config/schema.test.ts", - "src/daemon/services.ts", - "src/daemon/index.ts", - "src/skills/index.ts" - ], - "test_status": "typecheck + targeted schema/services tests + full test suite + lint (warnings only, 0 errors) + build passing" - }, - "watcher_callback_full_reload": { - "status": "completed", - "description": "Implemented watcher callback behavior to fully reload skills from disk and repopulate SkillRegistry on debounced change events", - "files_modified": [ - "src/daemon/services.ts", - "src/daemon/services.test.ts", - "src/skills/registry.ts", - "src/skills/registry.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/daemon/services.test.ts src/skills/registry.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "watcher_targeted_skill_updates": { - "status": "completed", - "description": "Optimized watcher callback to perform targeted skill add/update/remove by mapped path, with safe fallback to full reload for ambiguous paths", - "files_modified": [ - "src/daemon/services.ts", - "src/daemon/services.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/daemon/services.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "watcher_observability_polish": { - "status": "completed", - "description": "Improved watcher event logs with explicit mode/reason and per-event counters for upsert/remove/shadowed updates versus fallback reloads", - "files_modified": [ - "src/daemon/services.ts", - "src/daemon/services.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/daemon/services.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "phase_2_skills_watcher": { + "priority": "P1", + "status": "completed", + "description": "Auto-reload skills with chokidar file watcher, configurable debounce", + "effort": "3-4 hours", + "sub_slices": { + "watcher_bootstrap": { + "status": "completed", + "description": "Added core `SkillsWatcher` class with debounced change batching, lifecycle controls, and foundational tests", + "files_created": [ + "src/skills/watcher.ts", + "src/skills/watcher.test.ts" + ], + "files_modified": [ + "src/skills/index.ts" + ], + "test_status": "typecheck + targeted watcher tests + full test suite + lint (warnings only, 0 errors) + build passing" + }, + "watcher_daemon_wiring": { + "status": "completed", + "description": "Wired SkillsWatcher into daemon skills initialization and shutdown lifecycle behind config toggle with debounce settings", + "files_created": [ + "src/daemon/services.test.ts" + ], + "files_modified": [ + "src/config/schema.ts", + "src/config/schema.test.ts", + "src/daemon/services.ts", + "src/daemon/index.ts", + "src/skills/index.ts" + ], + "test_status": "typecheck + targeted schema/services tests + full test suite + lint (warnings only, 0 errors) + build passing" + }, + "watcher_callback_full_reload": { + "status": "completed", + "description": "Implemented watcher callback behavior to fully reload skills from disk and repopulate SkillRegistry on debounced change events", + "files_modified": [ + "src/daemon/services.ts", + "src/daemon/services.test.ts", + "src/skills/registry.ts", + "src/skills/registry.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/daemon/services.test.ts src/skills/registry.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "watcher_targeted_skill_updates": { + "status": "completed", + "description": "Optimized watcher callback to perform targeted skill add/update/remove by mapped path, with safe fallback to full reload for ambiguous paths", + "files_modified": [ + "src/daemon/services.ts", + "src/daemon/services.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/daemon/services.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "watcher_observability_polish": { + "status": "completed", + "description": "Improved watcher event logs with explicit mode/reason and per-event counters for upsert/remove/shadowed updates versus fallback reloads", + "files_modified": [ + "src/daemon/services.ts", + "src/daemon/services.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/daemon/services.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + } } - } - }, - "phase_3_installer_specs": { - "priority": "P1", - "status": "completed", - "description": "Auto-install dependencies (brew/node/go/download) with package manager detection", - "effort": "3-4 hours", - "sub_slices": { - "manifest_installers_type_validation": { - "status": "completed", - "description": "Added manifest installers type definitions and loader validation for brew/node/go/download installer specs with focused tests", - "files_modified": [ - "src/skills/types.ts", - "src/skills/index.ts", - "src/skills/loader.ts", - "src/skills/loader.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/skills/loader.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "installer_dry_run_planning_surface": { - "status": "completed", - "description": "Added dry-run installer planning with package-manager selection rules and surfaced planned/skipped installer steps in skills info output", - "files_created": [ - "src/skills/planner.ts", - "src/skills/planner.test.ts" - ], - "files_modified": [ - "src/skills/index.ts", - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/skills/planner.test.ts src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "installer_plan_command_json_output": { - "status": "completed", - "description": "Added dedicated skills plan command surface with reusable installer plan view and JSON/text rendering helpers for automation consumption", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "installer_preflight_preview_in_install": { - "status": "completed", - "description": "Wired dry-run installer preflight preview into skills install flow with optional JSON output for automation clients", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "install_preflight_only_mode": { - "status": "completed", - "description": "Added --preflight-only mode to skills install for plan-only previews without performing installation, including JSON output path", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "installer_execution_stub_command": { - "status": "completed", - "description": "Added skills execute command that consumes installer plans and reports stub execution output without running package-manager commands", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "shared_install_action_modes": { - "status": "completed", - "description": "Centralized install action handling into shared plan-only/stub/install modes and wired install command options through the shared flow while keeping real installer execution disabled", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "installer_safety_confirmation_receipts": { - "status": "completed", - "description": "Added explicit --confirm semantics and stable no-op execution receipt fields for plan-only/stub/install JSON outputs while keeping installer command execution disabled", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "installer_execution_policy_gate_checks": { - "status": "completed", - "description": "Added explicit execution policy gate evaluation for install/stub modes and surfaced policy reasons (including confirmation_required) in no-op execution receipts while preserving disabled command execution", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "installer_runner_interface_noop": { - "status": "completed", - "description": "Added a pluggable installer command runner interface with policy-gated dispatch and a default no-op runner, preserving execution-disabled behavior while preparing a future real runner", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "installer_step_execution_envelopes_noop": { - "status": "completed", - "description": "Added structured per-step execution envelopes (`attempted` + `results`) to install/plan/stub JSON receipts with policy-derived blocked/skipped statuses while keeping command execution disabled", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "installer_runner_terminal_status_mapping": { - "status": "completed", - "description": "Extended step result envelopes to support real-runner terminal statuses (`succeeded`/`failed`) and added runner-to-envelope mapping helpers while retaining execution-disabled defaults", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "installer_optional_shell_runner": { - "status": "completed", - "description": "Added an optional concrete shell-based installer command runner that emits structured succeeded/failed command results with machine-readable reasons, while default flow remains policy-gated and no-op", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "installer_cli_runner_opt_in_wiring": { - "status": "completed", - "description": "Added explicit install CLI opt-in wiring for execution (`--execute`) and runner selection (`--runner noop|shell`) with strict confirmation gating, preserving execution-disabled defaults unless explicitly requested", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "skills_execute_opt_in_runner_wiring": { - "status": "completed", - "description": "Extended `skills execute ` with explicit execution opt-in and runner selection (`--execute`, `--runner noop|shell`), wired through shared policy/result envelope logic with safe defaults and confirmation gating", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "skills_cli_option_parsing_integration_tests": { - "status": "completed", - "description": "Added CLI-level integration tests for `skills install`/`skills execute` option parsing and failure modes around `--execute`, `--runner`, and `--confirm`, validating command wiring through commander actions", - "files_modified": [ - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "skills_execute_without_confirm_guardrails": { - "status": "completed", - "description": "Added explicit user-facing CLI guardrails for invalid execution opt-in (`--execute` without `--confirm`) on both install and execute commands, with deterministic error messaging and exit status coverage", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "installer_receipt_edge_case_tests": { - "status": "completed", - "description": "Added edge-case coverage for execution receipt mapping: partial/empty runner results, deterministic fallback reasons, and commander-path JSON fallback statuses for install/execute flows", - "files_modified": [ - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "installer_execution_global_policy_gate": { - "status": "completed", - "description": "Added a global skills execution policy gate (`skills.installation_execution`) with default disabled behavior, wiring install/execute CLI flows to return deterministic `execution_policy_disabled` receipts unless config explicitly enables execution", - "files_modified": [ - "src/config/schema.ts", - "src/config/schema.test.ts", - "src/cli/skills.ts", - "src/cli/skills.test.ts", - "config/default.yaml" - ], - "test_status": "pnpm typecheck + pnpm test:run src/config/schema.test.ts src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "installer_execution_policy_help_text": { - "status": "completed", - "description": "Improved user-facing execution guidance by documenting config gate requirements in CLI option help text and adding explicit render output when policy blocks installer execution", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "shell_runner_rollout_controls": { - "status": "completed", - "description": "Added explicit config-gated rollout control for shell runner usage (`skills.allow_shell_runner` default false), with deterministic CLI guard errors for install/execute when `--runner shell` is requested without policy enablement", - "files_modified": [ - "src/config/schema.ts", - "src/config/schema.test.ts", - "src/cli/skills.ts", - "src/cli/skills.test.ts", - "config/default.yaml" - ], - "test_status": "pnpm typecheck + pnpm test:run src/config/schema.test.ts src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "shell_runner_command_allowlist": { - "status": "completed", - "description": "Added command-level shell runner allowlisting via `skills.shell_runner_allowlist` patterns, wiring install/execute shell runs to block non-matching commands with deterministic `allowlist_blocked` receipt reasons", - "files_modified": [ - "src/config/schema.ts", - "src/config/schema.test.ts", - "src/cli/skills.ts", - "src/cli/skills.test.ts", - "config/default.yaml" - ], - "test_status": "pnpm typecheck + pnpm test:run src/config/schema.test.ts src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "shell_runner_audit_telemetry": { - "status": "completed", - "description": "Added deterministic shell-runner audit telemetry hooks using existing audit tool events, emitting policy denials and per-command outcomes for install/execute shell flows via `emitShellRunnerAuditEvents(...)`", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/config/schema.test.ts src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "skills_installer_dedicated_audit_events": { - "status": "completed", - "description": "Added dedicated audit event types (`skills.installer.execution_blocked`, `skills.installer.command_result`) and migrated shell-runner telemetry emission from generic tool events to richer skills installer event contracts", - "files_modified": [ - "src/audit/types.ts", - "src/audit/logger.ts", - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "skills_installer_audit_command_redaction_hashing": { - "status": "completed", - "description": "Hardened skills installer audit payload safety by hashing command strings and sanitizing potentially sensitive spawn-error reason details before emitting shell-runner command-result telemetry", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint + pnpm build passing" - }, - "shell_runner_rollout_status_and_guardrails": { - "status": "completed", - "description": "Added `skills rollout-status` with phased recommendation output (`locked|guarded_observe|guarded_review|expand_candidate`), guardrail checks for execution/audit/allowlist posture, and audit-window telemetry summary including hashed-command coverage", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint + pnpm build passing" - }, - "shell_runner_governance_workflow_operationalization": { - "status": "completed", - "description": "Operationalized shell-runner allowlist governance by adding explicit config-backed ownership/review/promotion criteria (`skills.shell_runner_governance`) and wiring `skills rollout-status` to enforce owner presence when shell runner is enabled", - "files_modified": [ - "src/config/schema.ts", - "src/config/schema.test.ts", - "config/default.yaml", - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/config/schema.test.ts src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "shell_runner_rollout_status_export_output": { - "status": "completed", - "description": "Extended `skills rollout-status` with `--out ` export support so governance and recommendation payloads can be saved as machine-readable JSON artifacts for review workflows", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "shell_runner_rollout_trend_snapshot": { - "status": "completed", - "description": "Added historical trend snapshots to `skills rollout-status` by comparing current and previous equal-duration windows, including deltas for failures, allowlist blocks, and hashed-command coverage in both console and JSON payloads", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "shell_runner_rollout_promotion_policy_checks": { - "status": "completed", - "description": "Added promotion-policy evaluation to `skills rollout-status` using governance thresholds (`review_cadence_days`, `promotion_min_success_rate`) and trend deltas, with structured blockers/recommendation in JSON and console output", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" - }, - "shell_runner_promotion_contract_output": { - "status": "completed", - "description": "Added dedicated machine-readable promotion contract output for `skills rollout-status` (`--contract`) with stable schema, CI-friendly gate/exit code semantics, and optional `--out` export support", - "files_modified": [ - "src/cli/skills.ts", - "src/cli/skills.test.ts" - ], - "test_status": "pnpm test:run src/cli/skills.test.ts + pnpm typecheck + pnpm build passing" + }, + "phase_3_installer_specs": { + "priority": "P1", + "status": "completed", + "description": "Auto-install dependencies (brew/node/go/download) with package manager detection", + "effort": "3-4 hours", + "sub_slices": { + "manifest_installers_type_validation": { + "status": "completed", + "description": "Added manifest installers type definitions and loader validation for brew/node/go/download installer specs with focused tests", + "files_modified": [ + "src/skills/types.ts", + "src/skills/index.ts", + "src/skills/loader.ts", + "src/skills/loader.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/skills/loader.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "installer_dry_run_planning_surface": { + "status": "completed", + "description": "Added dry-run installer planning with package-manager selection rules and surfaced planned/skipped installer steps in skills info output", + "files_created": [ + "src/skills/planner.ts", + "src/skills/planner.test.ts" + ], + "files_modified": [ + "src/skills/index.ts", + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/skills/planner.test.ts src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "installer_plan_command_json_output": { + "status": "completed", + "description": "Added dedicated skills plan command surface with reusable installer plan view and JSON/text rendering helpers for automation consumption", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "installer_preflight_preview_in_install": { + "status": "completed", + "description": "Wired dry-run installer preflight preview into skills install flow with optional JSON output for automation clients", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "install_preflight_only_mode": { + "status": "completed", + "description": "Added --preflight-only mode to skills install for plan-only previews without performing installation, including JSON output path", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "installer_execution_stub_command": { + "status": "completed", + "description": "Added skills execute command that consumes installer plans and reports stub execution output without running package-manager commands", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "shared_install_action_modes": { + "status": "completed", + "description": "Centralized install action handling into shared plan-only/stub/install modes and wired install command options through the shared flow while keeping real installer execution disabled", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "installer_safety_confirmation_receipts": { + "status": "completed", + "description": "Added explicit --confirm semantics and stable no-op execution receipt fields for plan-only/stub/install JSON outputs while keeping installer command execution disabled", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "installer_execution_policy_gate_checks": { + "status": "completed", + "description": "Added explicit execution policy gate evaluation for install/stub modes and surfaced policy reasons (including confirmation_required) in no-op execution receipts while preserving disabled command execution", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "installer_runner_interface_noop": { + "status": "completed", + "description": "Added a pluggable installer command runner interface with policy-gated dispatch and a default no-op runner, preserving execution-disabled behavior while preparing a future real runner", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "installer_step_execution_envelopes_noop": { + "status": "completed", + "description": "Added structured per-step execution envelopes (`attempted` + `results`) to install/plan/stub JSON receipts with policy-derived blocked/skipped statuses while keeping command execution disabled", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "installer_runner_terminal_status_mapping": { + "status": "completed", + "description": "Extended step result envelopes to support real-runner terminal statuses (`succeeded`/`failed`) and added runner-to-envelope mapping helpers while retaining execution-disabled defaults", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "installer_optional_shell_runner": { + "status": "completed", + "description": "Added an optional concrete shell-based installer command runner that emits structured succeeded/failed command results with machine-readable reasons, while default flow remains policy-gated and no-op", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "installer_cli_runner_opt_in_wiring": { + "status": "completed", + "description": "Added explicit install CLI opt-in wiring for execution (`--execute`) and runner selection (`--runner noop|shell`) with strict confirmation gating, preserving execution-disabled defaults unless explicitly requested", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "skills_execute_opt_in_runner_wiring": { + "status": "completed", + "description": "Extended `skills execute ` with explicit execution opt-in and runner selection (`--execute`, `--runner noop|shell`), wired through shared policy/result envelope logic with safe defaults and confirmation gating", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "skills_cli_option_parsing_integration_tests": { + "status": "completed", + "description": "Added CLI-level integration tests for `skills install`/`skills execute` option parsing and failure modes around `--execute`, `--runner`, and `--confirm`, validating command wiring through commander actions", + "files_modified": [ + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "skills_execute_without_confirm_guardrails": { + "status": "completed", + "description": "Added explicit user-facing CLI guardrails for invalid execution opt-in (`--execute` without `--confirm`) on both install and execute commands, with deterministic error messaging and exit status coverage", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "installer_receipt_edge_case_tests": { + "status": "completed", + "description": "Added edge-case coverage for execution receipt mapping: partial/empty runner results, deterministic fallback reasons, and commander-path JSON fallback statuses for install/execute flows", + "files_modified": [ + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "installer_execution_global_policy_gate": { + "status": "completed", + "description": "Added a global skills execution policy gate (`skills.installation_execution`) with default disabled behavior, wiring install/execute CLI flows to return deterministic `execution_policy_disabled` receipts unless config explicitly enables execution", + "files_modified": [ + "src/config/schema.ts", + "src/config/schema.test.ts", + "src/cli/skills.ts", + "src/cli/skills.test.ts", + "config/default.yaml" + ], + "test_status": "pnpm typecheck + pnpm test:run src/config/schema.test.ts src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "installer_execution_policy_help_text": { + "status": "completed", + "description": "Improved user-facing execution guidance by documenting config gate requirements in CLI option help text and adding explicit render output when policy blocks installer execution", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "shell_runner_rollout_controls": { + "status": "completed", + "description": "Added explicit config-gated rollout control for shell runner usage (`skills.allow_shell_runner` default false), with deterministic CLI guard errors for install/execute when `--runner shell` is requested without policy enablement", + "files_modified": [ + "src/config/schema.ts", + "src/config/schema.test.ts", + "src/cli/skills.ts", + "src/cli/skills.test.ts", + "config/default.yaml" + ], + "test_status": "pnpm typecheck + pnpm test:run src/config/schema.test.ts src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "shell_runner_command_allowlist": { + "status": "completed", + "description": "Added command-level shell runner allowlisting via `skills.shell_runner_allowlist` patterns, wiring install/execute shell runs to block non-matching commands with deterministic `allowlist_blocked` receipt reasons", + "files_modified": [ + "src/config/schema.ts", + "src/config/schema.test.ts", + "src/cli/skills.ts", + "src/cli/skills.test.ts", + "config/default.yaml" + ], + "test_status": "pnpm typecheck + pnpm test:run src/config/schema.test.ts src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "shell_runner_audit_telemetry": { + "status": "completed", + "description": "Added deterministic shell-runner audit telemetry hooks using existing audit tool events, emitting policy denials and per-command outcomes for install/execute shell flows via `emitShellRunnerAuditEvents(...)`", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/config/schema.test.ts src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "skills_installer_dedicated_audit_events": { + "status": "completed", + "description": "Added dedicated audit event types (`skills.installer.execution_blocked`, `skills.installer.command_result`) and migrated shell-runner telemetry emission from generic tool events to richer skills installer event contracts", + "files_modified": [ + "src/audit/types.ts", + "src/audit/logger.ts", + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "skills_installer_audit_command_redaction_hashing": { + "status": "completed", + "description": "Hardened skills installer audit payload safety by hashing command strings and sanitizing potentially sensitive spawn-error reason details before emitting shell-runner command-result telemetry", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint + pnpm build passing" + }, + "shell_runner_rollout_status_and_guardrails": { + "status": "completed", + "description": "Added `skills rollout-status` with phased recommendation output (`locked|guarded_observe|guarded_review|expand_candidate`), guardrail checks for execution/audit/allowlist posture, and audit-window telemetry summary including hashed-command coverage", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint + pnpm build passing" + }, + "shell_runner_governance_workflow_operationalization": { + "status": "completed", + "description": "Operationalized shell-runner allowlist governance by adding explicit config-backed ownership/review/promotion criteria (`skills.shell_runner_governance`) and wiring `skills rollout-status` to enforce owner presence when shell runner is enabled", + "files_modified": [ + "src/config/schema.ts", + "src/config/schema.test.ts", + "config/default.yaml", + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/config/schema.test.ts src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "shell_runner_rollout_status_export_output": { + "status": "completed", + "description": "Extended `skills rollout-status` with `--out ` export support so governance and recommendation payloads can be saved as machine-readable JSON artifacts for review workflows", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "shell_runner_rollout_trend_snapshot": { + "status": "completed", + "description": "Added historical trend snapshots to `skills rollout-status` by comparing current and previous equal-duration windows, including deltas for failures, allowlist blocks, and hashed-command coverage in both console and JSON payloads", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "shell_runner_rollout_promotion_policy_checks": { + "status": "completed", + "description": "Added promotion-policy evaluation to `skills rollout-status` using governance thresholds (`review_cadence_days`, `promotion_min_success_rate`) and trend deltas, with structured blockers/recommendation in JSON and console output", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm typecheck + pnpm test:run src/cli/skills.test.ts + pnpm test:run + pnpm lint (warnings only, 0 errors) + pnpm build passing" + }, + "shell_runner_promotion_contract_output": { + "status": "completed", + "description": "Added dedicated machine-readable promotion contract output for `skills rollout-status` (`--contract`) with stable schema, CI-friendly gate/exit code semantics, and optional `--out` export support", + "files_modified": [ + "src/cli/skills.ts", + "src/cli/skills.test.ts" + ], + "test_status": "pnpm test:run src/cli/skills.test.ts + pnpm typecheck + pnpm build passing" + } } } } + }, + "earlier_plans": { + "plans": [ + { + "file": "2026-02-02-flynn-design.md", + "status": "completed" + }, + { + "file": "2026-02-02-flynn-phase1-implementation.md", + "status": "completed" + }, + { + "file": "2026-02-02-flynn-phase2-implementation.md", + "status": "completed" + }, + { + "file": "2026-02-05-flynn-phase3-implementation.md", + "status": "completed" + }, + { + "file": "2026-02-05-tui-redesign.md", + "status": "completed" + }, + { + "file": "2026-02-05-tui-redesign-implementation.md", + "status": "completed" + }, + { + "file": "2026-02-05-llamacpp-integration-design.md", + "status": "completed" + }, + { + "file": "2026-02-05-llamacpp-implementation.md", + "status": "completed" + }, + { + "file": "2026-02-05-backend-switch-design.md", + "status": "completed" + }, + { + "file": "2026-02-05-backend-switch-implementation.md", + "status": "completed" + }, + { + "file": "2026-02-05-openclaw-parity-design.md", + "status": "completed" + }, + { + "file": "2026-02-05-phase1-tool-framework.md", + "status": "completed" + }, + { + "file": "2026-02-05-phase2-websocket-gateway.md", + "status": "completed" + }, + { + "file": "2026-02-05-phase3-channel-adapters.md", + "status": "completed" + }, + { + "file": "2026-02-05-phase5-cli-cron-doctor-design.md", + "status": "completed" + }, + { + "file": "2026-02-05-phase5a-implementation.md", + "status": "completed" + } + ] + }, + "audit-hardening-xss-body-limits-timeout-leak": { + "status": "completed", + "date": "2026-02-16", + "updated": "2026-02-16", + "summary": "Addressed high-priority codebase audit findings by hardening gateway chat markdown rendering (sanitization before DOM insertion), adding configurable inbound HTTP body-size limits for gateway/webhooks with 413 responses, centralizing body parsing utility, and fixing ToolExecutor timeout timer cleanup to avoid orphaned timers.", + "files_created": [ + "src/gateway/ui/lib/markdown.js", + "src/gateway/ui/lib/markdown.test.ts", + "src/utils/httpBody.ts", + "src/utils/httpBody.test.ts" + ], + "files_modified": [ + "src/gateway/ui/pages/chat.js", + "src/gateway/ui/chat.html", + "src/gateway/server.ts", + "src/gateway/server.test.ts", + "src/automation/webhooks.ts", + "src/automation/webhooks.test.ts", + "src/config/schema.ts", + "src/config/schema.test.ts", + "config/default.yaml", + "src/daemon/services.ts", + "src/daemon/channels.ts", + "src/tools/executor.ts", + "src/tools/executor.test.ts", + "README.md", + "docs/deployment/PRODUCTION.md" + ], + "test_status": "targeted: pnpm test:run src/gateway/server.test.ts src/automation/webhooks.test.ts src/tools/executor.test.ts src/config/schema.test.ts src/gateway/ui/lib/markdown.test.ts src/utils/httpBody.test.ts + pnpm typecheck" } }, - "earlier_plans": { - "plans": [ - { "file": "2026-02-02-flynn-design.md", "status": "completed" }, - { "file": "2026-02-02-flynn-phase1-implementation.md", "status": "completed" }, - { "file": "2026-02-02-flynn-phase2-implementation.md", "status": "completed" }, - { "file": "2026-02-05-flynn-phase3-implementation.md", "status": "completed" }, - { "file": "2026-02-05-tui-redesign.md", "status": "completed" }, - { "file": "2026-02-05-tui-redesign-implementation.md", "status": "completed" }, - { "file": "2026-02-05-llamacpp-integration-design.md", "status": "completed" }, - { "file": "2026-02-05-llamacpp-implementation.md", "status": "completed" }, - { "file": "2026-02-05-backend-switch-design.md", "status": "completed" }, - { "file": "2026-02-05-backend-switch-implementation.md", "status": "completed" }, - { "file": "2026-02-05-openclaw-parity-design.md", "status": "completed" }, - { "file": "2026-02-05-phase1-tool-framework.md", "status": "completed" }, - { "file": "2026-02-05-phase2-websocket-gateway.md", "status": "completed" }, - { "file": "2026-02-05-phase3-channel-adapters.md", "status": "completed" }, - { "file": "2026-02-05-phase5-cli-cron-doctor-design.md", "status": "completed" }, - { "file": "2026-02-05-phase5a-implementation.md", "status": "completed" } - ] - } - }, - "overall_progress": { "total_test_count": 1703, "all_tests_passing": true, diff --git a/src/tools/executor.test.ts b/src/tools/executor.test.ts index d1c6ba1..7689411 100644 --- a/src/tools/executor.test.ts +++ b/src/tools/executor.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; import { ToolExecutor } from './executor.js'; import { ToolRegistry } from './registry.js'; import { HookEngine } from '../hooks/engine.js'; @@ -98,6 +98,22 @@ describe('ToolExecutor', () => { expect(result.output).toContain('[truncated]'); }); + it('clears timeout timer after fast tool completion', async () => { + vi.useFakeTimers(); + try { + const registry = new ToolRegistry(); + registry.register(echoTool); + const hooks = new HookEngine({ confirm: [], log: [], silent: [] }); + const executor = new ToolExecutor(registry, hooks, { defaultTimeoutMs: 30_000 }); + + const result = await executor.execute('test.echo', { text: 'hello' }); + expect(result.success).toBe(true); + expect(vi.getTimerCount()).toBe(0); + } finally { + vi.useRealTimers(); + } + }); + it('blocks on confirm hook and resolves when approved', async () => { const registry = new ToolRegistry(); registry.register(echoTool); diff --git a/src/tools/executor.ts b/src/tools/executor.ts index cb670ec..80a6f15 100644 --- a/src/tools/executor.ts +++ b/src/tools/executor.ts @@ -224,6 +224,7 @@ export class ToolExecutor { agent_tier: context?.tier, }); + let timeoutHandle: NodeJS.Timeout | undefined; try { const result = await Promise.race([ (async () => { @@ -239,9 +240,12 @@ export class ToolExecutor { } return tool.execute(args); })(), - new Promise((_, reject) => - setTimeout(() => reject(new Error(`Tool '${toolName}' timed out after ${this.defaultTimeoutMs}ms`)), this.defaultTimeoutMs), - ), + new Promise((_, reject) => { + timeoutHandle = setTimeout( + () => reject(new Error(`Tool '${toolName}' timed out after ${this.defaultTimeoutMs}ms`)), + this.defaultTimeoutMs, + ); + }), ]); const duration = Date.now() - startTime; @@ -286,6 +290,10 @@ export class ToolExecutor { output: '', error: String(errorRedaction.value), }; + } finally { + if (timeoutHandle) { + clearTimeout(timeoutHandle); + } } }