You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
pai-workspace skill + hardened POSIX wrappers bin/pai-workspace-{ingest,search}: keyword ingest/search over a curated knowledge base (ripgrep + pdftotext fallback, SHA-256 dedup, append-only JSONL manifest).
CLAUDE.md "Wrapper safety" hard constraint: every bin/ wrapper must treat its args as untrusted — bind patterns with -e/--, reject a leading -, confine every resolved path under its allowed root, and build JSON via jq --arg / explicit escaping.
pai-workspace-search — argv flag injection / ripgrep --pre RCE closed: the query was passed positionally to rg/grep, so a value like --pre=<cmd> was interpreted as a flag and could execute a preprocessor command. Now rejects any query beginning with - and binds the pattern with -e … -- on all three search invocations (ripgrep, grep fallback, PDF grep).
pai-workspace-ingest — path traversal closed: the caller-supplied domain hint (and source path) could resolve outside ${PAI_WORKSPACE_DIR}; the resolved target is now containment-checked, and manifest fields are JSON-escaped.
pai-pulse-send: correct bracketed-IPv6 (http://[::1]:…) host parsing in the loopback-only SSRF guard.
.gitignore secret safety-net (*.key, *.cred, *.pem, .env, mem0.json) so credential material can never be committed.
Self-hosted Mem0 is deliberately not shipped: its bootstrap handles OpenAI/JWT/API-key secrets — outside this glue package's zero-secret-surface charter. Documented as a manual how-to instead.
Fixed
pai-doctor documented a fabricated probe suite: ~29 invented probe names plus a non-existent pai-anywhere doctor --fix flag. Regenerated against the installed binary — 18 host checks (pai-anywhere doctor) and 15 install-integrity probes (--post-install / verify), every id verified against --json. The same --fix references and Summary: format were corrected in pai-statusline-banner and README.
pai-workspace-searchset -e footgun: ((count++)) returns exit 1 when count is 0, aborting the emit loop after the first result (a successful search dropped all but one match and exited non-zero). Uses count=$((count+1)).
cost_check.py cache path/schema: defaults to ~/.claude/MEMORY/STATE/usage-cache.json with a legacy-path fallback, and handles both the wrapped (rate_limits) and current top-level usage-cache schemas.
Changed
Portability: stripped all machine-specific /home/dev paths from skills, bins, and references; install.sh records PAI_HERMES_ROOT in pai-hermes.env and skills source it. Every SKILL.md trimmed under the 120-LOC limit.
Test suite expanded to 30 bats — real ingest / dedup / traversal / argv-injection coverage replacing a no-op placeholder test.