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

@mariocairone/paperclip-kiro-adapter

v0.3.0

Published

ACP-first Paperclip adapter for Kiro CLI

Readme

Paperclip Kiro ACP adapter

ACP-first Paperclip adapter for Kiro CLI.

  • Adapter type: kiro_acp
  • Display name: Kiro ACP
  • Package: @mariocairone/paperclip-kiro-adapter 0.3.0 (public)
  • Execution: local Kiro CLI only; remote execution targets and legacy remote transports fail closed before host probes or filesystem/process work

Requirements

  • Node.js >=24.11.0 (required by pinned @paperclipai/adapter-utils 2026.831.1); .nvmrc selects the Node 26 line used for local validation
  • Paperclip external-adapter support
  • kiro-cli available to the Paperclip server user
  • A completed Kiro login for that user
  • Kiro CLI with kiro-cli acp for the ACP lane
kiro-cli login --use-device-flow
kiro-cli acp --help

Build a local checkout with:

npm ci
npm run build

This package is published publicly on npm as @mariocairone/paperclip-kiro-adapter. A local checkout can also be installed through Paperclip's local-adapter path for development and validation.

Architecture

execute() resolves one of two lanes:

  1. ACP lane (default): @paperclipai/adapter-utils/acpx-engine starts kiro-cli acp over stdio. Session identity and tool events come from typed ACP/acpx metadata. No terminal transcript parsing and no chat --list-sessions heuristic are used.
  2. CLI compatibility lane: the original kiro-cli chat --no-interactive wrapper remains available. It preserves prompt assembly, profile handling, output sanitization, timeout behavior, session lookup/resume, loopback API access, runtime MCP, skills, and base-agent inheritance. Its per-run profile uses the shared atomic mode-0600 writer and is removed after every post-write success or failure.

Both lanes are local-only. An executionTarget with kind: "remote" or a legacy remote execution transport is rejected before capability probing, profile creation, filesystem access, or process launch. Environment tests return the same restriction as a structured failure rather than probing the Paperclip host.

Engine resolution

| engine | Behavior | |---|---| | auto (default) | Use ACP. Fall back to CLI only when kiro-cli acp --help explicitly reports that the acp subcommand is unavailable. Missing binaries, auth failures, timeouts, and ambiguous probe failures do not trigger fallback. | | acp | Require ACP. A missing subcommand fails closed with no CLI fallback. | | cli | Always use the compatibility wrapper. |

The capability probe is read-only, cached for five minutes, and starts no ACP session.

ACP profile lifecycle

Kiro receives trusted system context through an agent profile. The ACP profile:

  • has a deterministic name derived from the Paperclip agent ID;
  • is written into the worktree's .kiro/agents when the repository ignores that path, so the profile shares the lifetime of the worktree Paperclip created; otherwise into $KIRO_HOME/agents. The check queries the file the adapter would write, because a .kiro/ directory pattern does not match the bare path before the directory exists. A profile carries the full system prompt, so it is never written where it would appear as untracked work;
  • is written atomically with mode 0600;
  • is rewritten per heartbeat and fingerprinted into the acpx session identity, so persona, instructions, skills, MCP, model, or tool-policy changes start a compatible new ACP session;
  • is retained because a warm ACP server outlives one heartbeat;
  • is cleaned only by a safe sweep restricted to regular, adapter-owned paperclip-*.json files. Other profiles of the same agent are collected after 30 minutes, other agents' profiles after 24 hours. Neither window is zero: a concurrent run of the same agent with a different effective configuration owns its own profile path and rewrites it every heartbeat, so a recent file is treated as possibly in use. Foreign files and symlinks are untouched.

The trusted system prompt is base persona + managed instructions. Assigned skills are delivered as skill:// resources instead, and per-wake Paperclip context remains in the acpx turn prompt.

Where the Kiro profile comes from

The profile is resolved in this order:

  1. kiro-agent.json (or kiro-agent.md) in the agent's Paperclip instructions bundle.
  2. baseAgent on disk, for installations configured that way.
  3. A minimal isolated default, modelled on Kiro's own agent_config.json.example with one deliberate difference: includeMcpJson is false. An agent with no configuration must not inherit the machine's global MCP servers.

A malformed bundled profile fails the run instead of silently falling back, so a typo is visible instead of quietly changing which tools an agent has.

The bundled profile

Paperclip's instructions bundle accepts arbitrary files next to AGENTS.md and exports them with the company, so the complete Kiro profile can live with the agent record: per-role, editable where the instructions are edited, and versioned in a company export. There is no file picker and no path to configure — the adapter reads the file from the bundle directory Paperclip already passes as instructionsRootPath:

<paperclip-data>/companies/<companyId>/agents/<agentId>/instructions/
├── AGENTS.md         # role instructions (bundle entry file)
└── kiro-agent.json   # this agent's Kiro profile

The file is a Kiro agent profile, so it takes Kiro's own fields rather than adapter-specific ones — prompt, model, tools, allowedTools, mcpServers, resources, toolAliases, toolsSettings, includeMcpJson, requireMcpStartup. A new Kiro field works without an adapter change. Two fields are read but not used at run time: name, because the adapter derives the run profile name from the agent id and content fingerprint, and description, which is useful to say what the profile is for.

{
  "description": "Kiro tool substrate for this role",
  "prompt": "Shared operating context for the role.",
  "tools": ["*", "delegate", "@engineering-memory"],
  "allowedTools": ["*", "delegate", "@engineering-memory"],
  "mcpServers": {
    "engineering-memory": {
      "command": "/usr/local/bin/basic-memory",
      "args": ["mcp", "--project", "my-project"]
    }
  },
  "resources": ["file://AGENTS.md", "file://README*"],
  "includeMcpJson": false,
  "requireMcpStartup": true
}

Write or replace it through the Paperclip API or CLI, the same way AGENTS.md is managed:

# read
curl "$PAPERCLIP/api/agents/$AGENT_ID/instructions-bundle/file?path=kiro-agent.json"

# write
curl -X PUT "$PAPERCLIP/api/agents/$AGENT_ID/instructions-bundle/file" \
  -H 'Content-Type: application/json' \
  -d "$(jq -n --arg c "$(cat kiro-agent.json)" '{path:"kiro-agent.json", content:$c}')"

# remove, falling back to baseAgent or the minimal default
curl -X DELETE "$PAPERCLIP/api/agents/$AGENT_ID/instructions-bundle/file?path=kiro-agent.json"

The effective run prompt is bundled profile prompt + Paperclip role instructions. Assigned skills are not part of it; they arrive as resources.

Skills as resources

Assigned Paperclip skills become one skill://<runtime path>/SKILL.md resource each, appended to the profile's own resources. Kiro loads a skill:// resource on demand — name and description enter the prompt, the body only on use — so a role can carry long skills without paying for them on every run, and a skill's bundled references/ stay reachable because the agent knows the directory. Selection remains per-agent: the runtime paths come from Paperclip's paperclipRuntimeSkills filtered by that agent's desiredSkills. An assigned skill that Paperclip did not materialize is reported as a run warning. The CLI compatibility lane keeps inlining skills, since it builds a single prompt string and has no resource list.

Base agents

baseAgent is the on-disk fallback, used only when the agent has no bundled profile. It resolves, in order:

  1. <cwd>/.kiro/agents/<name>.md or .json
  2. $KIRO_HOME/agents/<name>.md or .json
  3. ~/.kiro/agents/<name>.md or .json when KIRO_HOME is unset

Markdown frontmatter and JSON profiles inherit:

  • prompt
  • model
  • tools and allowedTools
  • mcpServers
  • resources
  • toolAliases
  • toolsSettings
  • includeMcpJson
  • requireMcpStartup

With Paperclip model: auto, the base model wins. An explicit Paperclip model wins over the base model.

MCP

MCP servers are combined from Kiro's global/workspace mcp.json, the base agent, and Paperclip runtime connections. Every server is added to the Kiro tools/allowedTools list as @name; "*" alone covers only built-in tools. Runtime names are sanitized. Base-agent MCP definitions win collisions, followed by existing Kiro MCP definitions; runtime connections cannot replace either. Bearer tokens are written only to the mode-0600 profile and are never logged.

requireMcpStartup: true fails before launch if no MCP server is configured and is copied to the Kiro profile for Kiro versions that support that field.

Configuration

Paperclip already renders command, model, standard thinking effort, cwd, instructions, prompt template, and extraArgs. Adapter-specific fields are:

| Field | Default | Description | |---|---:|---| | engine | auto | auto, acp, or cli; semantics above | | baseAgent | — | Kiro agent on disk, used only when the agent has no kiro-agent.json in its Paperclip instructions bundle | | kiroHome | — | KIRO_HOME for this agent. Kiro resolves agents, skills, steering and settings against it, so a dedicated directory keeps the operator's personal skill library out of agent runs and generated profiles out of the personal home. Wins over an env.KIRO_HOME binding; falls back to it, then to the user's home | | effort | — | Standard Paperclip thinking-effort field. The adapter accepts low, medium, high, xhigh, and max at runtime; see the UI compatibility note below. | | trustTools | unset | Comma-separated string or string array for --trust-tools; unset uses --trust-all-tools; an explicit empty list emits no Kiro trust flag | | requireMcpStartup | false | Require configured MCP and request Kiro profile startup enforcement | | preferConfiguredCwd | false | Make configured cwd override Paperclip's workspace | | permissionMode | approve-all | acpx client policy: approve-all, approve-reads, or deny-all | | nonInteractivePermissions | deny | deny or fail | | timeoutSec | 0 | ACP/CLI run timeout; 0 means no adapter timeout | | graceSec | 20 | CLI fallback SIGTERM grace period | | logLineLimit | 2000 | CLI fallback log-line truncation; 0 disables it |

Model and effort are session-fixed

Kiro CLI does not support the model/effort configuration methods used by generic ACP clients. The adapter therefore passes both on the process command:

kiro-cli acp --agent <profile> --model <model> --effort <effort>

It removes all model/effort keys from the acpx-engine config, preventing session/set_config_option. A model or effort change changes the command/session fingerprint and applies to a new ACP session.

Effort precedence is explicit:

  1. effort (standard Paperclip field)
  2. thinkingEffort
  3. reasoningEffort
  4. modelReasoningEffort
  5. legacy kiroEffort (read-only migration compatibility)

Values outside low, medium, high, xhigh, max fail the environment check and are omitted with a run warning.

Thinking effort UI compatibility

The adapter accepts all five values in saved/API configuration, including xhigh and max. With pinned @paperclipai/adapter-utils 2026.831.1, an external adapter cannot extend Paperclip's host-owned Thinking effort picker: AdapterConfigSchema only defines independent adapter fields, while CreateConfigValues.thinkingEffort is an unenumerated host form value. To offer xhigh and max in that standard picker, Paperclip must add both values to its host UI option enumeration or extend the external-adapter contract with an adapter-supplied option extension for thinkingEffort. Until then, use saved/API configuration for those two Kiro values; do not add a duplicate adapter field.

Reserved extraArgs

The adapter owns these flags and rejects both --flag value and --flag=value forms in extraArgs:

  • --agent
  • --agent-engine
  • --model
  • --effort
  • --resume-id
  • --output-format
  • --no-interactive

This prevents caller arguments from breaking profile, session, or typed-output guarantees.

--agent-engine is reserved because the adapter targets the Kiro v2 agent engine. The v3 engine rejects --agent, --model, --effort, --trust-all-tools, and --trust-tools on kiro-cli acp, so an extraArgs attempt to switch engines produces a command Kiro refuses to start rather than a working v3 session. Selecting v3 requires adapter support for its own configuration surface (ACP session modes instead of --agent, config options instead of --model), which this version does not implement.

Network and Paperclip instructions

The agent receives Paperclip runtime environment, managed instructions, selected skills, runtime MCP, and the loopback API URL. Public Paperclip origins are replaced for the ACP worker by setting both PAPERCLIP_API_URL and PAPERCLIP_RUNTIME_API_URL to loopback (or PAPERCLIP_LOCAL_API_URL) in the run-scoped config and ACP child command, while NO_PROXY/no_proxy include localhost, 127.0.0.1, and ::1. The host process.env is never mutated.

Endpoint selection is trusted only from the Paperclip server's own environment. Per-agent env configuration may still set ordinary process variables, but it cannot move the API endpoint that receives the run token off this machine: a configured PAPERCLIP_LOCAL_API_URL, PAPERCLIP_LISTEN_HOST, or related setting is honoured only when it resolves to a loopback address. Anything else is ignored with a run warning, the host-resolved endpoint is used, and the rejected PAPERCLIP_LOCAL_API_URL is not forwarded to the child. Only an operator's host-level PAPERCLIP_LOCAL_API_URL may name a non-local bridge. Both lanes apply the same rule; the reserved run-identity variables (PAPERCLIP_API_KEY, PAPERCLIP_RUN_ID, PAPERCLIP_TASK_ID, and related fields) are likewise always taken from the current run, never from configuration.

The server subpath still exports the deprecated forceLocalPaperclipApiUrlForEngine(env?) compatibility helper. New callers should use buildKiroAcpRunEnvironment; the deprecated helper mutates only an explicitly supplied environment object, and no-argument calls now operate on an isolated object instead of global process state.

Paperclip capability surface

The server module declares the following optional ServerAdapterModule capabilities from @paperclipai/adapter-utils 2026.831.1:

| Capability | Status | Notes | |---|---|---| | listModels / refreshModels | Supported | Live catalog from kiro-cli chat --list-models -f json, cached per executable/cwd/environment hash for 60 seconds in a bounded LRU cache (32 contexts). Static ids are the fallback only when the live query fails. | | sessionManagement | Supported | supportsSessionResume: true, nativeContextManagement: "unknown", Paperclip threshold compaction (maxSessionRuns: 200, maxRawInputTokens: 2_000_000, maxSessionAgeHours: 72). No native Kiro compaction is claimed. | | getQuotaWindows | Supported | One credit window from the strict read-only /usage parser against the host-default kiro-cli. Unavailable or malformed output returns ok: false with no windows; credits are never reported as tokens or as zero usage. | | detectModel | Not supported | Kiro exposes the available catalog, not a locally configured current model. | | modelProfiles | Not supported | The live catalog carries no cost class, so no model is labelled cheap. | | loginCapability | Not supported | Login stays manual (kiro-cli login --use-device-flow); no device-flow output grammar is parsed or stored. |

Sessions and output

ACP session parameters are serialized by the pinned acpx-engine session codec and retain sessionKey, acpSessionId, agentSessionId, runtime session name, cwd, mode, and config fingerprint. CLI session params remain { sessionId, cwd }. The combined codec round-trips both formats.

ACP emits JSON log events such as acpx.session, acpx.text_delta, acpx.tool_call, acpx.status, and acpx.result. The CLI fallback keeps the existing ANSI/redraw sanitizer and UI parser. The shipped UI module exports only the stateful createStdoutParser factory so Paperclip preserves CLI continuation and tool call/result pairing across lines.

For compatibility with Paperclip 2026.831.1, the parser also repairs one narrowly identified framing defect: a missing JSON quote escape immediately after Paperclip's literal ***REDACTED*** marker inside an ACPX event. Recovery runs only after normal JSON parsing fails, only for acpx.* input, and only when the repaired payload becomes valid JSON. It never reconstructs redacted data; every other malformed line remains visible as untrusted stdout. Because recovery happens at render time, previously stored affected runs can render cleanly after the updated parser is loaded.

Credit and cost accounting

Kiro reports usage in credits, not tokens. The ACP lane wraps kiro-cli acp with the packaged acp-metering-proxy.cjs process. The proxy forwards ACP stdio unchanged and persists only a sanitized projection of _kiro.dev/metadata.meteringUsage (sessionId, credits, duration, timestamp) in a mode-0600 per-task journal. It never stores prompts, responses, tool payloads, or arbitrary private metadata.

Before and after a metered turn, the adapter runs the read-only kiro-cli chat --no-interactive "/usage" command and strictly parses:

  • plan tier and monthly plan price;
  • credits consumed and credits included;
  • utilization percentage and reset date.

Accounting rules:

  • credits are returned as resultJson.kiroUsage; they are never converted to token fields;
  • KIRO FREE is recorded with a $0 monthly plan cost and never produces overage cost;
  • paid-plan usage ending at or below 100% is subscription_included with incremental costUsd: 0;
  • paid-plan usage above 100% is subscription_overage at $0.04 per billable credit;
  • a turn crossing the boundary bills only the over-plan portion; when the pre/post global delta reveals unrelated concurrent account usage, the project allocation is marked estimated and is not published as billed costUsd;
  • if /usage is unavailable or malformed, credits remain attributed to the run/project but costUsd stays null and billingType is unknown.

The fixed monthly plan price is recorded under resultJson.kiroPlan.planMonthlyCostUsd for reconciliation. It is not repeatedly charged to every run. Paperclip's token usageJson remains null unless the ACP runtime independently provides real token usage.

Migration from kiro_local

This adapter intentionally uses the new type kiro_acp; it does not claim the baseline kiro_local type.

  1. Install/build this adapter as a separate local package.
  2. Change each intended Paperclip agent's adapter type from kiro_local to kiro_acp.
  3. Keep existing command, model, cwd, baseAgent, skills, instructions, MCP, timeout, and environment configuration.
  4. Start with engine: auto. Use engine: acp after confirming kiro-cli acp --help works and fail-closed behavior is desired.
  5. Use the standard Paperclip Thinking effort field; legacy kiroEffort is read only for migration compatibility.
  6. Remove reserved flags from extraArgs.

There is no Git-history import, live adapter installation, remote creation, or Paperclip system mutation in this repository.

Limitations

  • Local execution only; remote/sandbox Kiro provisioning is not implemented.
  • Kiro login is manual.
  • Model and effort cannot change inside a live ACP session.
  • requireMcpStartup depends on Kiro profile support; the adapter can guarantee the local “at least one MCP configured” precondition, not behavior in older Kiro builds that ignore the profile field.
  • Credit attribution is exact per metered ACP turn. The included-versus-overage split for the single turn that crosses 100% is estimated when unrelated concurrent account usage lands in the same interval; /usage is an account-wide snapshot.
  • Base-agent-scoped MCP is visible only when present in the inherited profile; unrelated agent profiles are not scanned.
  • Reloading an already imported Node ESM package may require a Paperclip server restart.

Development and validation

npm run typecheck
npm test
npm run build
npm pack --dry-run

A read-only smoke test can use kiro-cli acp --help and the bundled acpx client. Do not install the adapter into a live Paperclip instance merely to validate the package.

Attribution and license

MIT licensed. The initial CLI baseline was adapted from Schapat/paperclip-kiro-adapter, and its public feat-acp-engine work was consulted as a technical reference. Copyright and attribution details are in LICENSE and NOTICE. This repository has an independent Git history and is not affiliated with Paperclip Labs or Kiro.