npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@self-deprecated/pi-agent-tick

v1.3.1

Published

Agent Tick control-plane integration for Pi: remote decisions, approvals, and session status updates

Readme

pi-agent-tick

Agent Tick support for Pi: remote human decisions, approval gates, and lifecycle status updates for coding-agent sessions.

This package replaces the generic ask_user experience with an Agent Tick-first tool named agent_tick_ask_user, while keeping a local Pi prompt and a compatibility ask_user alias.

What is Agent Tick?

Agent Tick is a least-permission approval layer for agent work. It lets an agent send Steering, a Sanction, or a Status Update to a user outside the terminal — for example in the Native App or Personal Console — then wait for the user's response before continuing when a response is required.

In this package, Agent Tick is used only as a decision/approval/status layer. It does not execute shell commands or tools remotely.

How answering works

When Agent Tick config is available, each agent_tick_ask_user prompt appears in two places at the same time:

  1. the local Pi ask_user TUI on the machine running the agent
  2. the Agent Tick app/web UI with the same question and choices

Answer from whichever place is convenient for that request. The first valid answer wins, and the other pending prompt is resolved. That means you can answer one decision from the terminal, the next from your phone, and switch back and forth per request.

What this package does

  • Registers agent_tick_ask_user, a Pi tool for asking exactly one focused question.
  • Shows the local Pi ask_user TUI and the Agent Tick app/web request simultaneously when agent-tick login config is available.
  • Uses whichever side answers first, then resolves the other pending prompt.
  • Sends single-select, multi-select, comments, and recommended-option flags to Agent Tick.
  • Keeps a local overlay/inline Pi prompt so sessions still work without Agent Tick.
  • Optionally gates risky bash tool calls with local and/or Agent Tick approval.
  • Optionally sends lifecycle status updates such as working, waiting, blocked, done, or failed.
  • Bundles an agent-tick-decision-gate skill for high-impact or ambiguous decisions.

Install

pi install npm:@self-deprecated/pi-agent-tick

For local development or unreleased changes:

pi install git:github.com/self-deprecated/pi-agent-tick

Run Agent Tick login to enable remote phone/web mirroring:

agent-tick login

If no Agent Tick config is found, the same tool still opens the local Pi prompt. If config is found, you get both the local prompt and the remote Agent Tick request for each question.

Quick example

Ask Pi to use agent_tick_ask_user at a decision boundary. A good call includes a short context summary and one focused question:

{
  "question": "Which deploy target should I use?",
  "context": "The branch has passed tests locally. Staging is reversible; production affects customers immediately.",
  "options": [
    { "title": "staging", "description": "Safer, reversible validation path", "flags": ["favorite", "safest"] },
    { "title": "production", "description": "Customer-facing deploy" }
  ],
  "allowFreeform": false,
  "choiceInteractionMode": "select-then-submit"
}

Tool names

Canonical tool:

  • agent_tick_ask_user

Compatibility alias:

  • ask_user

Installing this together with the original pi-ask-user package is not recommended because both provide an ask_user tool.

Agent Tick configuration

Agent Tick auth/config follows the Agent Tick CLI:

  1. AGENT_TICK_CONFIG, or ~/.config/agent-tick/config.json
  2. AGENT_TICK_SERVER and/or AGENT_TICK_TOKEN environment overrides

Useful environment variables:

| Variable | Purpose | | --- | --- | | PI_AGENT_TICK_DISABLED=1 | Disable remote Agent Tick mirroring even when config exists. | | PI_AGENT_TICK_TIMEOUT_MS | Remote wait timeout. Defaults to unlimited (0). | | PI_AGENT_TICK_CHOICE_INTERACTION_MODE | click-to-submit or select-then-submit. | | PI_AGENT_TICK_OPTION_PLACEMENT | sticky-bottom or inline-after-content. | | PI_AGENT_TICK_CONFIRM_BEFORE_SUBMIT | always/never or boolean-ish values. | | AGENT_TICK_FEATURES_CONFIG | Explicit feature config path. | | AGENT_TICK_SESSION_ID | Optional externally supplied Session ID. If omitted, Agent Tick uses Pi's persisted chat/session ID when available. If no real Pi chat ID is available, it should omit explicit sessionId rather than generate a random fallback; Agent Tick groups best-effort by source metadata. | | AGENT_TICK_SESSION_TITLE | Optional user-facing Session title/label. If omitted, Agent Tick may use the task summary for the current chat. Titles are labels only and do not group Activity. |

Agent feature configuration

Feature config is separate from Agent Tick auth. Use the generic Agent Tick CLI surface:

agent-tick features show
agent-tick features tui
agent-tick features enable message-mirroring
agent-tick features disable heartbeat

agent-tick features and agent-tick features tui open an interactive selector: move with ↑/↓ or j/k, toggle with Space or Enter, press s to show JSON, and q to quit.

Pi currently consumes the shared feature config. It resolves in this order:

  1. built-in defaults
  2. global Agent Tick feature config: ~/.config/agent-tick/features.json
  3. project-local Agent Tick feature config: .agent-tick/features.json
  4. explicit config path: AGENT_TICK_FEATURES_CONFIG=/path/to/config.json

Project-local config overrides global config. Rule maps are keyed by ID, so a local config can disable or change one global rule without copying every rule.

Optional status updates

Status updates are best-effort and only send when Agent Tick config is present and status config is enabled. Use the Agent Tick CLI to inspect and change the shared feature config:

agent-tick features show
agent-tick features tui
agent-tick features enable message-mirroring
agent-tick features disable heartbeat
agent-tick features set status.heartbeat.intervalMs 15000

The built-in defaults send start, finish, and long-running heartbeat Status Updates; turn-end, shutdown, full message mirroring, structured Tool Activity, detailed tool disclosure, and Sanction approval gates are off until enabled.

{
  "status": {
    "enabled": true,
    "hooks": {
      "before_agent_start": { "send": true, "state": "working", "message": "task-summary" },
      "turn_end": { "send": false, "state": "working", "message": "none" },
      "agent_end": { "send": true, "state": "waiting", "message": "Finished; waiting" },
      "session_shutdown": { "send": false, "state": "done", "message": "none" }
    },
    "heartbeat": { "enabled": true, "intervalMs": 285000, "message": "Still working" },
    "messageMirroring": { "enabled": false, "contentMode": "private", "sendAssistant": "final-only" },
    "toolActivity": {
      "enabled": false,
      "visibility": "off",
      "detailContentMode": "private",
      "maxDetailChars": 2000
    }
  }
}

messageMirroring.includeToolUseTurns only allows assistant text messages whose stop reason is tool-use; it does not mirror tool call arguments or tool results. Use status.toolActivity.visibility for structured Tool Activity: off sends nothing, names sends tool identifiers/events only, summaries adds safe summaries, and details sends redacted tool detail only as encrypted private content. Enable Native App → Settings → General → Private encryption before using details.

{
  "status": {
    "toolActivity": {
      "enabled": true,
      "visibility": "summaries"
    }
  }
}
{
  "status": {
    "toolActivity": {
      "enabled": true,
      "visibility": "details",
      "detailContentMode": "private",
      "maxDetailChars": 2000
    }
  }
}

Optional bash approval gates

Sanctions are opt-in. By default there are no allow/deny rules and no command approval gate is applied.

Example: allow everything except matching risky commands, which require approval:

{
  "sanctions": {
    "enabled": true,
    "policy": "allow-by-default",
    "tools": {
      "bash": {
        "deny": {
          "rm-rf": {
            "command": "rm",
            "argsRegex": "(^|\\s)-[A-Za-z]*r[A-Za-z]*f",
            "riskClass": "destructive-filesystem",
            "reason": "recursive forced remove"
          },
          "push": {
            "commandRegex": "^(git|jj)$",
            "argsRegex": "\\bpush\\b",
            "riskClass": "vcs-push",
            "reason": "VCS push"
          }
        }
      }
    }
  }
}

Example: require approval by default, but allow known-safe commands:

{
  "sanctions": {
    "enabled": true,
    "policy": "approve-by-default",
    "tools": {
      "bash": {
        "allow": {
          "jj-status": { "command": "jj", "argsRegex": "^st(atus)?$" },
          "safe-tests": { "commandRegex": "^(bun|npm)$", "argsRegex": "\\btest\\b" }
        }
      }
    }
  }
}

If allow and deny rules both match, deny wins. Remote Sanction request bodies are redacted before disclosure. Agent Tick returns only the Sanction decision; Pi still owns local tool execution.

agent_tick_ask_user parameters

| Parameter | Type | Default | Description | | --- | --- | --- | --- | | question | string | required | The one focused question to ask. | | context | string? | — | Short summary of relevant findings or trade-offs. | | options | (string \| {title, description?, flags?})[]? | [] | Multiple-choice options. Use flags: ["favorite"] for the recommended option. | | allowMultiple | boolean? | false | Enable multi-select mode. | | allowFreeform | boolean? | true | Add a freeform answer path. | | allowComment | boolean? | false | Let the user attach optional extra context to a selection. | | displayMode | "overlay" \| "inline"? | env or "overlay" | Local Pi rendering mode. | | overlayToggleKey | string? | env or "alt+o" | Hide/show local overlay while it is open. Pass "off" to disable. | | commentToggleKey | string? | env or "ctrl+g" | Toggle optional comment row. Pass "off" to disable. | | timeout | number? | — | Auto-dismiss local UI and use the same remote wait timeout. | | choiceInteractionMode | "click-to-submit" \| "select-then-submit"? | env or "click-to-submit" | Remote Agent Tick choice behavior. | | optionPlacement | "sticky-bottom" \| "inline-after-content"? | env or "inline-after-content" | Remote Agent Tick option placement. | | confirmBeforeSubmit | boolean? | env or true | Ask Agent Tick to confirm direct clickable submissions. |

Contributing

Contribution and public mirror policy is in CONTRIBUTING.md.

Attribution

This package is based on Enzo Lucchesi's edlsh/pi-ask-user, an MIT-licensed Pi package for interactive prompts. The local Pi prompt implementation remains derived from that project, and the original copyright/license notice is preserved in LICENSE.