AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Octowiz Doctowiz

skill-raelli-octowiz-octowiz-doctowiz · by raelli

>

No reviews yet
0 installs
22 views
0.0% view→install

Install

$ agentstack add skill-raelli-octowiz-octowiz-doctowiz

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-raelli-octowiz-octowiz-doctowiz)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Octowiz Doctowiz? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Doctowiz — Octowiz + AELLI Doctor

The Octowiz doctor. Diagnoses the full octowiz + AELLI integration stack, interprets every failure with a plain-language explanation and a concrete fix command, monitors live activity, and guides setup from scratch.

Mode detection

Read the user's invocation text (or context of the conversation) to pick the mode:

| Trigger words | Mode | |---|---| | (nothing / "diagnose" / "check" / "health") | Diagnose (default) | | "monitor" / "watch" / "tail" / "live" | Monitor | | "setup" / "install" / "configure" / "start fresh" | Setup guide | | "update" / "upgrade" / "migrate" / "I'm on 0.5" / "old version" | Update helper (Mode 4) | | "fix " / describes a specific error | Targeted fix (Mode 5) |

When uncertain, run Diagnose — it gives the most complete picture.


Mode 1 — Diagnose (default)

Run the full diagnostic, interpret every non-passing check, and offer guided fixes.

Step 1: Version inventory

Before running the diagnostic, collect version information:

# Octowiz plugin version
node -e "const p=require('$CLAUDE_PLUGIN_ROOT/package.json'); console.log('octowiz', p.version)"

# Installed plugin cache version
ls -1 ~/.claude/plugins/cache/integrahub/octowiz/ 2>/dev/null | tail -1

# AELLI version (if running locally)
node -e "try{const p=require(require('os').homedir()+'/Documents/aelli/package.json'); console.log('aelli', p.version)}catch(e){console.log('aelli not found locally')}"

# LiteLLM / AELLI env vars
echo "AELLI_BASE_URL:       ${AELLI_BASE_URL:-(not set)}"
echo "AELLI_AUTH_TOKEN:     ${AELLI_AUTH_TOKEN:-(not set)}"
echo "AELLI_LITELLM_BASE:   ${AELLI_LITELLM_BASE:-(not set)}"
echo "AELLI_ROUTER_URL:     ${AELLI_ROUTER_URL:-(not set)}"
echo "OCTOWIZ_ALLOWED_ROOTS:${OCTOWIZ_ALLOWED_ROOTS:-(not set)}"

# Local Python A2A server version (public /health since 0.9.16)
curl -s -m 3 "http://localhost:${OCTOWIZ_A2A_PORT:-8765}/health" 2>/dev/null \
  || echo "A2A server: not reachable (starts on next session open)"

# AELLI gateway health
[ -n "$AELLI_BASE_URL" ] && curl -s "$AELLI_BASE_URL/health" \
  -H "Authorization: Bearer $AELLI_AUTH_TOKEN" \
  | python3 -c "import sys,json; d=json.load(sys.stdin); print('aelli/litellm', d.get('status','?'))" 2>/dev/null \
  || echo "AELLI gateway: not reachable (expected if remote)"

Show a version summary before the diagnostic table. Flag:

  • Plugin cache version ≠ source ($CLAUDE_PLUGIN_ROOT) → stale cache, run claude plugins install octowiz --force
  • A2A /health version ≠ plugin version → stale Python server. Since 0.9.18 the

session-start hook restarts it automatically (it verifies the recorded pid is the uvicorn on the configured port before killing); on older plugins use the aelli_python fix below.

  • A2A /health returns {"error":"Unauthorized"} → the running server predates

0.9.16 (when /health became public) — definitely stale, same fix.

  • AELLI_BASE_URL missing → queue subscription and hook delivery both broken
  • AELLI_AUTH_TOKEN missing → all AELLI requests will get 401
  • OCTOWIZ_ALLOWED_ROOTS missing → daemon will refuse to start

Step 2: Service pre-flight

Check the three background services in parallel:

# Node daemon (launchd service)
launchctl list de.integrahub.octowiz-daemon 2>/dev/null

# Python A2A server — /health gives status AND version in one probe
curl -s -m 3 "http://localhost:${OCTOWIZ_A2A_PORT:-8765}/health" 2>/dev/null && echo " a2a:up" || echo "a2a:down"

# Allowed-roots coverage for current cwd
node -e "
const roots = (process.env.OCTOWIZ_ALLOWED_ROOTS || '').split(':').filter(Boolean);
const cwd = process.cwd();
const ok = roots.some(r => cwd.startsWith(r));
console.log(ok ? 'roots:ok' : 'roots:missing — cwd=' + cwd);
" 2>/dev/null || echo "roots:unknown"

Interpret:

  • Daemon PID missing or - → daemon not running; fix: daemon_start
  • a2a:down → Python A2A server not up; fix: aelli_python
  • roots:missing → current repo not in OCTOWIZ_ALLOWED_ROOTS; fix: allowed_roots

Step 3: Memory and doctrine health

Check whether octowiz-cache is functional and memories are seeded:

octowiz-cache check 2>&1

Parse the JSON. If hard_gaps is non-empty, note them — they explain why the workflow may route incorrectly even when the pipeline itself is healthy.

Then verify the routing bundle is reachable:

octowiz-cache get --role routing --namespace "${OCTOWIZ_NAMESPACE:-allspark}" > /dev/null 2>&1 \
  && echo "routing bundle: OK" \
  || echo "routing bundle: UNREACHABLE"

Step 4: Run the diagnostic script

node "$CLAUDE_PLUGIN_ROOT/apps/doctowiz/index.js"

Wait for it to complete (3–8 seconds — the pipeline live tests make real AELLI requests).

Step 5: Interpret results

Display the full markdown output from the script. Then, for every FAIL or WARN check, add an interpretation block below the table:

[Check name] — plain-language explanation of what this means for the developer and why it matters, followed by the exact fix command from the Fix reference section below.

Override the script's built-in fix hint for "Octowiz daemon" failures — the daemon is now a launchd service, not a manual node invocation. Use daemon_start fix.

After all failures and warnings are explained, summarise the overall health:

  • HEALTHY: "All systems nominal. The full hook → AELLI pipeline is working."
  • DEGRADED: "The core pipeline is working but [N] warnings need attention. Advisories will still arrive — but [specific risk from the warning]."
  • UNHEALTHY: "The pipeline has [N] hard failures. Advisories will not arrive until these are fixed."

Then ask: "Want me to fix any of these now?" If the user says yes, run the fix command(s) inline and re-run the diagnostic to confirm.

Step 6: Session activity

After the diagnostic, show a quick session snapshot:

# Recent hook activity — last 10 lines from the bridge log
tail -10 ~/.cache/aelli-cc/aelli-cc.log 2>/dev/null || echo "(no log file yet — no hooks have fired)"

# Daemon log — last 10 lines
tail -10 ~/.cache/aelli-cc/octowiz-daemon.log 2>/dev/null || echo "(no daemon log yet)"

# Active sessions in cache dir
ls ~/.cache/aelli-cc/ 2>/dev/null

Summarise: when the last hook fired and whether the daemon is actively processing or idle. If the log is empty and everything is HEALTHY, note: "Setup looks correct but no hooks have fired yet — open a Claude Code session and edit a file to trigger the first hook."


Mode 2 — Monitor (activity snapshot)

When the user wants to see what octowiz + AELLI have been doing. This is a snapshot, not a blocking tail — it shows the most recent activity from both logs and lets the user re-run it after triggering actions in another window.

Tell the user: "Here's a snapshot of recent octowiz + AELLI activity. Trigger some actions in a Claude Code session (edit a file, submit a prompt), then re-run /octowiz:doctowiz monitor to see what came through."

echo "=== Octowiz daemon — launchd status ==="
launchctl list de.integrahub.octowiz-daemon 2>/dev/null || echo "(service not loaded)"

echo ""
echo "=== Octowiz daemon log (last 20 lines) ==="
tail -20 ~/.cache/aelli-cc/octowiz-daemon.log 2>/dev/null || echo "(daemon log not found)"

echo ""
echo "=== Bridge / AELLI hook log (last 20 lines) ==="
tail -20 ~/.cache/aelli-cc/aelli-cc.log 2>/dev/null || echo "(hook log not found — no hooks have fired yet)"

Interpret lines visible in the output:

| Log pattern | Meaning | |---|---| | advisory delivered | Hook fired and AELLI responded — pipeline working | | delivery failed | Hook fired but AELLI rejected it — check auth token | | fail-open | Bridge hit an error and silently let the hook pass through | | subscribed to | Daemon picked up a new task from AELLI | | spec-deviation | AELLI noticed a file edited outside the plan — informational | | no capability handler | Daemon received a task type it doesn't recognise | | [start] AELLI_AUTH_TOKEN not set | Hook started without auth — delivery disabled | | cwd … not within an allowed root | Task rejected — cwd not in OCTOWIZ_ALLOWED_ROOTS | | [start] daemon path mismatch … restarting | Node daemon was stale — auto-restarted via launchd plist (0.9.17+) | | [start] A2A server version skew … restarting pid | Python A2A server was stale — auto-restarted (0.9.18+) | | [start] port … serves a non-octowiz service | Something else owns the A2A port — auto-restart refused to touch it | | [start] not restarting A2A server | Recorded pid failed identity check (not the uvicorn on that port) — no kill |

If both logs are empty or missing:

> "No activity yet. Make sure a Claude Code session with octowiz is running, > then trigger a hook by editing a file or submitting a prompt. Re-run > /octowiz:doctowiz monitor to see the output."

If the hook log has entries but the daemon log is empty, note: the hook pipeline is working but the daemon launchd service may not be loaded — tasks won't be dispatched. Check with launchctl list de.integrahub.octowiz-daemon.


Mode 3 — Setup guide

When the user is doing a fresh install or reconfiguring from scratch. Walk through these phases in order, confirming each before moving on.

Phase 1 — Plugin installed?

ls ~/.claude/plugins/cache/integrahub/octowiz/ 2>/dev/null | tail -1

If missing: claude plugins install octowiz

After install, remind the user to restart Claude Code so $CLAUDE_PLUGIN_ROOT is set correctly in the new session.

Phase 2 — Dependencies installed?

ls ~/.claude/plugins/cache/*/superpowers/ 2>/dev/null | head -1
ls ~/.claude/plugins/cache/*/mattpocock-skills/ 2>/dev/null | head -1

If either is missing:

claude plugins install superpowers
claude plugins install mattpocock-skills

superpowers provides workflow discipline skills (TDD, brainstorming, worktrees). mattpocock-skills provides issue management and domain documentation skills.

Phase 3 — Environment variables set?

All required vars should be in ~/.claude/settings.json under "env":

echo "AELLI_BASE_URL:        ${AELLI_BASE_URL:-(NOT SET)}"
echo "AELLI_AUTH_TOKEN:      ${AELLI_AUTH_TOKEN:-(NOT SET)}"
echo "AELLI_LITELLM_BASE:    ${AELLI_LITELLM_BASE:-(NOT SET)}"
echo "AELLI_ROUTER_URL:      ${AELLI_ROUTER_URL:-(not set — optional)}"
echo "OCTOWIZ_ALLOWED_ROOTS: ${OCTOWIZ_ALLOWED_ROOTS:-(NOT SET)}"

Guide the user to add all to ~/.claude/settings.json:

{
  "env": {
    "AELLI_BASE_URL":        "https://llm.integrahub.de",
    "AELLI_AUTH_TOKEN":      "your-bearer-token",
    "AELLI_LITELLM_BASE":    "https://llm.integrahub.de",
    "AELLI_ROUTER_URL":      "https://llm.integrahub.de/a2a/aelli-router/message/send",
    "OCTOWIZ_ALLOWED_ROOTS": "/Users/you/Documents/myproject:/Users/you/Documents/other"
  }
}

AELLI_BASE_URL and AELLI_LITELLM_BASE are typically the same value. OCTOWIZ_ALLOWED_ROOTS is a colon-separated list of absolute paths the daemon is allowed to operate in — the daemon exits at startup if this is not set.

Phase 4 — Background services running?

The daemon is a launchd service (auto-starts at login). The Python A2A server is auto-started by the Claude Code session hook.

# Check daemon
launchctl list de.integrahub.octowiz-daemon 2>/dev/null || echo "not loaded"

# Check Python A2A server
nc -z 127.0.0.1 8765 2>/dev/null && echo "a2a:up" || echo "a2a:down"

If daemon not loaded:

# First time — create the launchd service
# Plist at: ~/Library/LaunchAgents/de.integrahub.octowiz-daemon.plist
# (see fix reference daemon_start for plist content)
launchctl load ~/Library/LaunchAgents/de.integrahub.octowiz-daemon.plist

If Python A2A server down — start manually:

cd ~/Documents/octowiz/apps/a2a-agent
python3 -m uvicorn main:app --host 127.0.0.1 --port 8765 &

It will also be auto-started on the next Claude Code session open.

Note on AELLI (port 3456): AELLI runs on the remote integra42 server, not localhost. Port 3456 being closed locally is expected. The daemon connects to AELLI_BASE_URL (remote) via the task queue — it does not need a local AELLI.

Phase 5 — Memory seeded?

octowiz-cache check 2>&1
octowiz-cache seed 2>&1

If octowiz-cache is not found, install the Python package from the plugin root:

pip install -e "$CLAUDE_PLUGIN_ROOT"

Phase 6 — End-to-end verification

Run the diagnostic to confirm everything is wired up:

node "$CLAUDE_PLUGIN_ROOT/apps/doctowiz/index.js"

All checks should be green. If any remain red, use the targeted fix commands below.


Mode 4 — Update helper

When the user is on an older version and needs to upgrade. This mode auto-detects what's stale, explains each breaking change, and walks through the steps in order. Run it once after a claude plugins install octowiz --force.

Step 1: Detect installed version

# Version reported by the running plugin
node -e "try{const p=require('$CLAUDE_PLUGIN_ROOT/package.json'); console.log(p.version)}catch(e){console.log('unknown')}"

# Version in the plugin cache
ls -1 ~/.claude/plugins/cache/integrahub/octowiz/ 2>/dev/null | sort -V | tail -1

If the cache still shows a version older than current, reinstall:

claude plugins install octowiz --force

Then restart Claude Code before continuing.

Step 2: Breaking change — env vars renamed (0.5.x → 0.8.0)

echo "Old (0.5.x) — should be EMPTY now:"
echo "  OCTOWIZ_A2A_URL:        ${OCTOWIZ_A2A_URL:-(not set — good)}"
echo "  OCTOWIZ_INBOUND_SECRET: ${OCTOWIZ_INBOUND_SECRET:-(not set — good)}"
echo ""
echo "New (0.9.x) — must be set:"
echo "  AELLI_AUTH_TOKEN:    ${AELLI_AUTH_TOKEN:-(NOT SET — fix required)}"
echo "  AELLI_BASE_URL:      ${AELLI_BASE_URL:-${AELLI_LITELLM_BASE:-(NOT SET — fix required)}}"

Why this changed: In v0.5.x, bridge.py POSTed hook events directly to the Octowiz A2A server (OCTOWIZ_A2A_URL). From v0.6.0 (PR #67, single advisory path), it routes through the LiteLLM gateway, which handles routing to the right AELLI service. The auth secret became a standard Bearer token (AELLI_AUTH_TOKEN).

If the old vars are still set and the new ones are missing:

Remove from settings.json:

"OCTOWIZ_A2A_URL": "...",
"OCTOWIZ_INBOUND_SECRET": "..."

Add to settings.json:

"AELLI_AUTH_TOKEN": "your-bearer-token",
"AELLI_BASE_URL":   "https://llm.integrahub.de"

Step 3: OCTOWIZALLOWEDROOTS (new in 0.9.x)

The daemon now requires OCTOWIZ_ALLOWED_ROOTS to be set at startup (it exits immediately if missing). Add it to settings.json AND to the launchd plist:

"OCTOWIZ_ALLOWED_ROOTS": "/Users/you/Documents/repo1:/Users/you/Documents/repo2"

Then reload the launchd service:

launchctl unload ~/Library/LaunchAgents/de.integrahub.octowiz-daemon.plist
launchctl load  ~/Library/LaunchAgents/de.integrahub.octowiz-daemon.plist

Step 4: Daemon is now a launchd service (0.9.4+)

The daemon previously had to be started manually (node index.js). From 0.9.4 it runs as a launchd service — auto-starts at login and restarts on crash.

If upgrading from a manual setup, stop the old process and load the service:

pkill -f "octowiz/index.js" 2>/dev/null || true
launchctl load ~/Library/LaunchAgents/de.integrahub.octowiz-daemon.plist

Step 5: Clean up stale session-subscribers

v0.5.x spawned a long-lived session-subscriber process per session. Clean up:

pkill -f session-subscriber.js 2>/dev/null && echo "cleaned" || echo "none running"

Step 6: Rebuild memory bundles

octowiz-cache build --all --namespace "${OCTOWIZ_NAMESPACE:-allspark}"

Step 7: Verify with the full diagnostic

node "$CLAUDE_PLUGIN_ROOT/apps/doctowiz/index.js"

What changed at each version (referenc

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.