Commit graph

44 commits

Author SHA1 Message Date
Aron Prins
724893ad5b fix claude instruction sibling path hint 2026-04-10 14:22:48 +02:00
dotta
0ff262ca0f fix: preserve claude instructions on resume fallback 2026-04-08 06:57:21 -05:00
lempkey
e3804f792d fix: gate instructions file I/O and commandNotes on fresh sessions only
On resumed sessions, skipping --append-system-prompt-file (the original
fix) left two secondary issues:
- commandNotes still claimed the flag was injected, producing misleading
  onMeta logs on every resumed heartbeat
- The instructions file was still read from disk and a combined temp file
  written on every resume, even though effectiveInstructionsFilePath was
  never consumed

Hoist canResumeSession before the I/O block and gate both the disk
operations and commandNotes construction on !canResumeSession / !sessionId.

Adds three regression tests: commandNotes is populated on fresh sessions,
empty on resume; and no agent-instructions.md is written on resume.
2026-04-08 06:57:21 -05:00
lempkey
3cfbc350a0 fix: skip --append-system-prompt-file on resumed claude sessions
On resumed sessions the agent instructions are already present in the
session cache. Unconditionally passing --append-system-prompt-file
re-injects 5-10K redundant tokens per heartbeat and may be rejected by
the Claude CLI when combined with --resume.

Guard the flag behind `!resumeSessionId` so it is only appended on
fresh session starts.

Fixes: #2848
2026-04-08 06:57:21 -05:00
kimnamu
07987d75ad feat(claude-local): add Bedrock model selection support
Previously, --model was completely skipped for Bedrock users, so the
model dropdown selection was silently ignored and the CLI always used
its default model.  Selecting Haiku would still run Opus.

- Add listClaudeModels() that returns Bedrock-native model IDs
  (us.anthropic.*) when Bedrock env is detected
- Register listModels on claude_local adapter so the UI dropdown
  shows Bedrock models instead of Anthropic API names
- Allow --model to pass through when the ID is a Bedrock-native
  identifier (us.anthropic.* or ARN)
- Add isBedrockModelId() helper shared by execute.ts and test.ts

Follows up on #2793 which added basic Bedrock auth detection.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 23:16:57 +09:00
Lucas Kim
b6e40fec54
feat: add AWS Bedrock auth support on "claude-local" (#2793)
Closes #2412
Related: #2681, #498, #128

## Thinking Path

> - Paperclip orchestrates AI agents for zero-human companies
> - The Claude Code adapter spawns the `claude` CLI to run agent tasks
> - The adapter detects auth mode by checking for `ANTHROPIC_API_KEY` —
recognizing only "api" and "subscription" modes
> - But users running Claude Code via **AWS Bedrock**
(`CLAUDE_CODE_USE_BEDROCK=1`) fall through to the "subscription" path
> - This causes a misleading "ANTHROPIC_API_KEY is not set;
subscription-based auth can be used" message in the environment check
> - Additionally, the hello probe passes `--model claude-opus-4-6` which
is **not a valid Bedrock model identifier**, causing `400 The provided
model identifier is invalid` and a probe failure
> - This pull request adds Bedrock auth detection, skips the
Anthropic-style `--model` flag for Bedrock, and returns the correct
billing type
> - The benefit is that Bedrock users get a working environment check
and correct cost tracking out of the box

---

## Pain Point

Many enterprise teams use **Claude Code through AWS Bedrock** rather
than Anthropic's direct API — for compliance, billing consolidation, or
VPC requirements. Currently, these users hit a **hard wall during
onboarding**:

| Problem | Impact |
|---|---|
|  Adapter environment check **always fails** | Users cannot create
their first agent — blocked at step 1 |
|  `--model claude-opus-4-6` is **invalid on Bedrock** (requires
`us.anthropic.*` format) | Hello probe exits with code 1: `400 The
provided model identifier is invalid` |
|  Auth shown as _"subscription-based"_ | Misleading — Bedrock is
neither subscription nor API-key auth |
|  Quota polling hits Anthropic OAuth endpoint | Fails silently for
Bedrock users who have no Anthropic subscription |

> **Bottom line**: Paperclip is completely unusable for Bedrock users
out of the box.

## Why Bedrock Matters

AWS Bedrock is a major deployment path for Claude in enterprise
environments:

- **Enterprise compliance** — data stays within the customer's AWS
account and VPC
- **Unified billing** — Claude usage appears on the existing AWS
invoice, no separate Anthropic billing
- **IAM integration** — access controlled through AWS IAM roles and
policies
- **Regional deployment** — models run in the customer's preferred AWS
region

Supporting Bedrock unlocks Paperclip for organizations that **cannot**
use Anthropic's direct API due to procurement, security, or regulatory
constraints.

---

## What Changed

- **`execute.ts`**: Added `isBedrockAuth()` helper that checks
`CLAUDE_CODE_USE_BEDROCK` and `ANTHROPIC_BEDROCK_BASE_URL` env vars.
`resolveClaudeBillingType()` now returns `"metered_api"` for Bedrock.
Biller set to `"aws_bedrock"`. Skips `--model` flag when Bedrock is
active (Anthropic-style model IDs are invalid on Bedrock; the CLI uses
its own configured model).
- **`test.ts`**: Environment check now detects Bedrock env vars (from
adapter config or server env) and shows `"AWS Bedrock auth detected.
Claude will use Bedrock for inference."` instead of the misleading
subscription message. Also skips `--model` in the hello probe for
Bedrock.
- **`quota.ts`**: Early return with `{ ok: true, windows: [] }` when
Bedrock is active — Bedrock usage is billed through AWS, not Anthropic's
subscription quota system.
- **`ui/src/lib/utils.ts`**: Added `"aws_bedrock"` → `"AWS Bedrock"` to
`providerDisplayName()` and `quotaSourceDisplayName()`.

## Verification

1. `pnpm -r typecheck` — all packages pass
2. Unit tests added and passing (6/6)
3. Environment check with Bedrock env vars:

| | Before | After |
|---|---|---|
| **Status** | 🔴 Failed |  Passed |
| **Auth message** | `ANTHROPIC_API_KEY is not set; subscription-based
auth can be used if Claude is logged in.` | `AWS Bedrock auth detected.
Claude will use Bedrock for inference.` |
| **Hello probe** | `ERROR · Claude hello probe failed.` (exit code 1 —
`--model claude-opus-4-6` is invalid on Bedrock) | `INFO · Claude hello
probe succeeded.` |
| **Screenshot** | <img height="500" alt="Screenshot 2026-04-05 at 8 25
27 AM"
src="https://github.com/user-attachments/assets/476431f6-6139-425a-8abc-97875d653657"
/> | <img height="500" alt="Screenshot 2026-04-05 at 8 31 58 AM"
src="https://github.com/user-attachments/assets/d388ce87-c5e6-4574-b8d2-fd8b86135299"
/> |

4. Existing API key / subscription paths are completely untouched unless
Bedrock env vars are present

## Risks

- **Low risk.** All changes are additive — existing "api" and
"subscription" code paths are only entered when Bedrock env vars are
absent.
- When Bedrock is active, the `--model` flag is skipped, so the
Paperclip model dropdown selection is ignored in favor of the Claude
CLI's own model config. This is intentional since Bedrock requires
different model identifiers.

## Model Used

- Claude Opus 4.6 (`claude-opus-4-6`, 1M context window) via Claude Code
CLI

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-04-06 13:15:18 -07:00
dotta
b9b2bf3b5b Trim resumed comment wake prompts 2026-04-04 18:14:19 -05:00
dotta
91e040a696 Batch inline comment wake payloads
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-04 18:14:19 -05:00
HenkDz
14d59da316 feat(adapters): external adapter plugin system with dynamic UI parser
- Plugin loader: install/reload/remove/reinstall external adapters
  from npm packages or local directories
- Plugin store persisted at ~/.paperclip/adapter-plugins.json
- Self-healing UI parser resolution with version caching
- UI: Adapter Manager page, dynamic loader, display registry
  with humanized names for unknown adapter types
- Dev watch: exclude adapter-plugins dir from tsx watcher
  to prevent mid-request server restarts during reinstall
- All consumer fallbacks use getAdapterLabel() for consistent display
- AdapterTypeDropdown uses controlled open state for proper close behavior
- Remove hermes-local from built-in UI (externalized to plugin)
- Add docs for external adapters and UI parser contract
2026-04-03 21:11:20 +01:00
dotta
cadfcd1bc6 Log resolved adapter command in run metadata
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-29 10:55:26 -05:00
dotta
67841a0c6d Remove noisy "Loaded agent instructions file" log from all adapters
Loading an instructions file is normal, expected behavior — not worth
logging to stdout/stderr on every run. Warning logs for failed reads
are preserved.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-24 11:48:43 -05:00
Dotta
fdb20d5d08
Merge pull request #550 from mvanhorn/osc/529-fix-missing-agents-md-fallback
fix: graceful fallback when AGENTS.md is missing in claude-local adapter
2026-03-21 11:17:35 -05:00
dotta
d07d86f778 Merge public-gh/master into paperclip-company-import-export 2026-03-20 06:25:24 -05:00
dotta
c844ca1a40 Improve orphaned local heartbeat recovery
Persist child-process metadata for local adapter runs, keep detached runs alive when their pid still exists, queue a single automatic retry when the pid is confirmed dead, and clear detached warnings when the original run reports activity again.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-20 06:05:15 -05:00
dotta
58a3cbd654 Route non-fatal adapter notices to stdout
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-20 06:05:14 -05:00
Dotta
5890b318c4 Namespace company skill identities
Persist canonical namespaced skill keys, split adapter runtime names from skill keys, and update portability/import flows to carry the canonical identity end-to-end.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-16 18:27:20 -05:00
Dotta
cca086b863 Merge public-gh/master into paperclip-company-import-export 2026-03-16 17:02:39 -05:00
Dotta
76e6cc08a6 feat(costs): add billing, quota, and budget control plane 2026-03-16 15:11:01 -05:00
Dotta
7675fd0856 Fix runtime skill injection across adapters 2026-03-15 07:05:01 -05:00
Dotta
2c35be0212 Merge public-gh/master into paperclip-company-import-export 2026-03-14 21:45:54 -05:00
Matt Van Horn
280536092e fix(adapters): add success log when agent instructions file is loaded
Matches the pattern in codex-local and cursor-local adapters,
giving operators consistent feedback about whether instructions
were actually loaded.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 09:07:26 -07:00
Devin Foley
d671a59306 fix: set AGENT_HOME env var for agent processes
The $AGENT_HOME environment variable was referenced by skills (e.g.
para-memory-files) but never actually set, causing runtime errors like
"/HEARTBEAT.md: No such file or directory" when agents tried to resolve
paths relative to their home directory.

Add agentHome to the paperclipWorkspace context in the heartbeat service
and propagate it as the AGENT_HOME env var in all local adapters.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-14 00:36:53 -07:00
Dotta
56a34a8f8a Add adapter skill sync for codex and claude 2026-03-13 22:49:42 -05:00
Dotta
7d1748b3a7 feat: optimize heartbeat token usage
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-13 09:40:43 -05:00
Matt Van Horn
b41c00a9ef fix: graceful fallback when AGENTS.md is missing in claude-local adapter
The codex-local and cursor-local adapters already wrap the
instructionsFilePath read in try/catch, logging a warning and
continuing without instructions. The claude-local adapter was missing
this handling, causing ENOENT crashes when the instructions file
doesn't exist.

Fixes #529

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 16:46:48 -07:00
Dotta
3120c72372 Add worktree-aware workspace runtime support 2026-03-10 10:58:38 -05:00
Dotta
f4a5b00116 fix: bundle skills directory into npm packages for runtime discovery
The claude-local, codex-local adapters and the server all resolve a
skills/ directory using __dirname-relative paths that only work inside
the monorepo.  When installed from npm the paths point outside the
package and cause ENOENT on readdir/readFile.

- Update both adapter execute.ts files to try a published-path
  candidate (../../skills from dist/) before falling back to the
  monorepo dev path (../../../../../skills from src/).
- Update server readSkillMarkdown() to try the published path first.
- Add "skills" to the files array in server, claude-local, and
  codex-local package.json so npm includes them.
- Update release.sh to copy the repo-root skills/ into each package
  before publish, and clean up after.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 16:06:12 -06:00
Dotta
8351f7f1bd Auto-create missing cwd for claude_local and codex_local 2026-03-03 12:29:32 -06:00
Dotta
f60c1001ec refactor: rename packages to @paperclipai and CLI binary to paperclipai
Rename all workspace packages from @paperclip/* to @paperclipai/* and
the CLI binary from `paperclip` to `paperclipai` in preparation for
npm publishing. Bump CLI version to 0.1.0 and add package metadata
(description, keywords, license, repository, files). Update all
imports, documentation, user-facing messages, and tests accordingly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 08:45:26 -06:00
Dotta
83be94361c feat(core): merge backup core changes with post-split functionality 2026-03-02 16:43:59 -06:00
Dotta
e9cc1fb8d9 fix(adapter): combine instructions file and path directive into single temp file
Claude CLI forbids using both --append-system-prompt-file and
--append-system-prompt simultaneously. Write a merged temp file instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 16:08:55 -06:00
Forgotten
a63e1fd2db feat(adapter): agent instructions file support and docs:dev script
Add instructionsFilePath config to Claude and Codex adapters, allowing
agents to load external instruction files appended to the system prompt.
Claude uses --append-system-prompt-file; Codex prepends file contents
to the prompt. Add docs:dev script for local Mintlify preview.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 16:34:15 -06:00
Forgotten
9e89ca4a9e feat(adapter): claude local chrome flag and max-turns session handling
Add --chrome flag support for Claude adapter. Detect max-turns
exhaustion (via subtype, stop_reason, or result text) and clear
the session to prevent stale session re-use. Add unit tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 16:33:10 -06:00
Forgotten
45c4df7b8a feat: add billing type tracking and cost enhancements
Add AdapterBillingType (api/subscription/unknown) to adapter execution results
so the system can distinguish API-billed vs subscription-billed runs. Enhance
cost service to aggregate subscription vs API run counts and token breakdowns.
Add limit param to heartbeat runs list API and client.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 21:35:44 -06:00
Forgotten
9f049aa4f3 feat: resolve agent workspace from session/project/fallback
Heartbeat service resolves cwd from task session, project primary
workspace, or agent home directory (~/.paperclip/instances/.../workspaces/).
Adapters receive workspace context and forward it as env vars and
session params. cwd is now optional in adapter config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 08:38:58 -06:00
Forgotten
2ddf6213fd feat(adapter): detect claude-login-required errors and expose errorCode/errorMeta
Add detectClaudeLoginRequired and extractClaudeLoginUrl to parse module.
Extract buildClaudeRuntimeConfig for reuse by both execute and the new
runClaudeLogin helper. Include errorCode: "claude_auth_required" and
errorMeta: { loginUrl } in execution results when login is needed.
Export runClaudeLogin from the package index.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 14:40:44 -06:00
Forgotten
2c3c2cf724 feat: adapter model discovery, reasoning effort, and improved codex formatting
Add dynamic OpenAI model list fetching for codex adapter with caching,
async listModels interface, reasoning effort support for both claude and
codex adapters, optional timeouts (default to unlimited), wakeCommentId
context propagation, and richer codex stdout event parsing/formatting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 10:32:07 -06:00
Forgotten
6e335b3fd0 Improve codex-local adapter: skill injection, stdin piping, and error parsing
Codex adapter now auto-injects Paperclip skills into ~/.codex/skills,
pipes prompts via stdin instead of passing as CLI args, filters out noisy
rollout stderr warnings, and extracts error/turn.failed messages from
JSONL output. Also broadens stale session detection for rollout path
errors. Claude-local adapter gets the same template vars (agentId,
companyId, runId) that codex-local already had.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 14:39:37 -06:00
Forgotten
d56618e9fe Add adapter session codecs with cwd-aware resume and unknown-session retry
Introduce AdapterSessionCodec interface for structured session serialization,
deserialization, and display ID extraction. Implement codecs for claude_local
and codex_local adapters with cwd validation — sessions saved for a different
working directory are not resumed. Both adapters now return sessionParams and
sessionDisplayId alongside legacy sessionId.

Add isCodexUnknownSessionError detection and automatic retry with fresh session
for codex_local (matching existing claude_local behavior). Inject approval
context env vars (PAPERCLIP_APPROVAL_ID, PAPERCLIP_APPROVAL_STATUS,
PAPERCLIP_LINKED_ISSUE_IDS) into adapter environments.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 14:01:58 -06:00
Forgotten
0d73e1b407 Add adapter config docs, approval context env vars, and paperclip-create-agent skill
Export agentConfigurationDoc from all adapters for LLM reflection. Inject
PAPERCLIP_APPROVAL_ID, PAPERCLIP_APPROVAL_STATUS, and PAPERCLIP_LINKED_ISSUE_IDS
into local adapter environments. Update SKILL.md with approval handling procedure,
issue-approval linking, and config revision documentation. Add new
paperclip-create-agent skill for CEO-driven agent hiring workflows.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 13:02:53 -06:00
Forgotten
224d150d86 Inject run context env vars into local adapters and update SKILL.md
Inject PAPERCLIP_RUN_ID, PAPERCLIP_TASK_ID, and PAPERCLIP_WAKE_REASON into
local adapter environments so agents know their run context and wake trigger.
Update SKILL.md to document new env vars and require X-Paperclip-Run-Id header
on all mutating API requests for audit trail linkage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 09:09:50 -06:00
Forgotten
fe6a8687c1 Implement local agent JWT authentication for adapters
Add HS256 JWT-based authentication for local adapters (claude_local, codex_local)
so agents authenticate automatically without manual API key configuration. The
server mints short-lived JWTs per heartbeat run and injects them as PAPERCLIP_API_KEY.
The auth middleware verifies JWTs alongside existing static API keys.

Includes: CLI onboard/doctor JWT secret management, env command for deployment,
config path resolution from ancestor directories, dotenv loading on server startup,
event payload secret redaction, multi-status issue filtering, and adapter transcript
parsing for thinking/user message kinds.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 16:46:45 -06:00
Forgotten
35880c8a1e Improve claude-local adapter execution and shared utils
Enhance claude-local server executor with better process management
and output handling. Improve stdout parser for UI transcript display.
Update adapter-utils types and server utilities.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:29:24 -06:00
Forgotten
631c859b89 Move adapter implementations into shared workspace packages
Extract claude-local and codex-local adapter code from cli/server/ui
into packages/adapters/ and packages/adapter-utils/. CLI, server, and
UI now import shared adapter logic instead of duplicating it. Removes
~1100 lines of duplicated code across packages. Register new packages
in pnpm workspace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 14:23:16 -06:00
Renamed from server/src/adapters/claude-local/execute.ts (Browse further)