Commit Graph

765 Commits

Author SHA1 Message Date
Chris Farhood 2e522c9b37 fix(skills): auto-detach agents when pruned skill is in use during repo sync
During a repo sync (scan button), if a skill was removed from the source
and is still assigned to agents, the skill is now automatically detached
from those agents before deletion, rather than leaving it attached.
Manual delete-by-source is unchanged (still blocks if in use).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 00:45:34 +00:00
Chris Farhood ba44667ae3 fix(skills): handle prune type mismatch by using warnings for agent-attached skills
GitHub/sks_sh pruned skills don't have project/workspace context needed for
the CompanySkillProjectScanConflict/Skipped types. Orphaned skills are
silently deleted; skills still used by agents emit a warning instead of
a conflict entry.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 00:45:34 +00:00
Chris Farhood 9f15436e05 test(skills): add scan-projects route test for skipped/conflicts return
Verifies the scan endpoint returns skipped and conflicts arrays in the
response, covering the prune path where removed skills are either
skipped (orphaned) or added to conflicts (still used by agents).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 00:45:34 +00:00
Chris Farhood 3144df70d6 fix(skills): prune skills removed from GitHub/sks_sh sources on re-scan
When re-scanning existing sources, diff skills in the DB against the
current source manifest. Skills no longer in the source are either:
- Added to conflicts (if still used by agents)
- Deleted via deleteSkill (if orphaned), added to skipped

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 00:45:34 +00:00
Chris Farhood 268806ff1c test(skills): add route test for scan-projects endpoint
Verifies that agents with canCreateAgents permission can call the
scan-projects endpoint and that scanProjectWorkspaces is invoked.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 00:45:34 +00:00
Chris Farhood a77fc31dc1 fix(skills): simplify source locator collection; remove redundant key derivation
- Use Set<string> instead of Map for tracking unique source locators
- Remove dead skillsAtSource destructuring from loop
- Remove redundant deriveCanonicalSkillKey call (already set by readUrlSkillImports)
- Invert slug check to continue guard for cleaner flow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 00:45:33 +00:00
Chris Farhood aed1a886a9 Address Greptile review: trim version, remove redundant fs/promises import, use fixed .tmp suffix 2026-04-12 14:22:05 -04:00
Pawla Abdul ddf36667f9 Auto-reinstall adapter packages missing from disk on reload and boot
Adapters installed with the old --no-save flag are not tracked in
package.json and get pruned when another adapter is installed. This
adds ensurePackageOnDisk() which detects missing packages and
reinstalls them from npm before reload or server boot attempts to
import them, fixing ENOENT errors for previously-pruned adapters.

Fixes FAR-47

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-12 16:38:19 +00:00
Pawla Abdul e2af316b3e Fix adapter install pruning other plugins by removing --no-save
npm install --no-save does not record dependencies in package.json,
so when a second adapter is installed, npm prunes the first as
extraneous. Removing --no-save ensures all installed adapters are
tracked in the managed package.json and persist across installs.

Fixes FAR-47

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-12 16:16:44 +00:00
Pawla Abdul 92afa0fb67 Fix adapter plugin conflicts caused by concurrent install/reload/delete operations
Add an async mutex (promise-chain FIFO queue) to serialise all adapter
mutation routes (install, reinstall, reload, delete) so that concurrent
requests cannot race on npm, the adapter-plugins.json store, or the
in-memory adapter registry.

Also switch adapter-plugin-store file writes to atomic write-tmp-then-rename
to prevent partial/corrupted reads from concurrent processes.

Includes the packageName.trim() fix for whitespace-induced npm failures.

9 new tests covering mutex serialisation, error recovery, FIFO ordering,
and atomic store operations.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-12 16:03:48 +00:00
Chris Farhood 9c7a17e16c Reapply "fix(server): respect externally set PAPERCLIP_API_URL env var"
This reverts commit 119bf6336e.
2026-04-12 09:07:31 -04:00
Chris Farhood 119bf6336e Revert "fix(server): respect externally set PAPERCLIP_API_URL env var"
This reverts commit 6b30178766.
2026-04-12 09:03:29 -04:00
Chris Farhood 6b30178766 fix(server): respect externally set PAPERCLIP_API_URL env var
Previously the server unconditionally overwrote PAPERCLIP_API_URL on
startup, clobbering any value set externally (e.g., via Kubernetes
ConfigMap). Now only sets the default if the env var is not already set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-12 09:02:42 -04:00
Chris Farhood a1343ea4f5 fix(skills): use acceptedSkills instead of listFull; cross-source slug check
- Replace redundant listFull() call with acceptedSkills to avoid extra DB round-trip
- Check slug conflicts against full acceptedSkills list instead of just same-source skills
- Call upsertAcceptedSkill after persisting to keep in-memory list current

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 07:34:26 -04:00
Chris Farhood e454277d10 feat(skills): scan button re-scans existing GitHub/sks_sh sources for new skills
When "Scan project workspaces for skills" runs, now also iterates all
existing GitHub/sks_sh skills and re-fetches their source repos to
detect newly added skills. New skills are upserted automatically.
Skips sources that fail, logged as warnings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 07:34:26 -04:00
Chris Farhood b672ebb540 fix(skills): delete secret row when PAT is cleared via updateSkillAuth
When updateSkillAuth(null) is called, the underlying secret row was
left orphaned. Now deletes the secret via secretsSvc.remove() before
clearing sourceAuthSecretId from metadata.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 17:31:36 -04:00
Chris Farhood 1956ccd7b5 fix: add companyId filter to metadata update + export CompanySkillUpdateAuth type
- Scope metadata update WHERE clause to companyId for defence-in-depth
- Add CompanySkillUpdateAuth inferred type export to match other schemas

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 16:03:33 -04:00
Chris Farhood 89909db27c fix(skills): atomic deleteBySource + PAT secret cleanup on skill deletion
- Pre-check all skills for agent usage before deleting any in deleteBySource
  to prevent partial/failed deletions
- Delete (rotate to empty) the skill-pat:<skillId> secret when a skill is
  deleted to prevent orphaned PAT secrets

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 15:58:30 -04:00
Chris Farhood d9341795b0 feat(skills): GitHub PAT support for private skill repos + delete by source
- Add optional authToken to skill import for GitHub private repos
- Store PAT as encrypted company secret (skill-pat:{skillId})
- Thread auth token through ghFetch, fetchText, fetchJson, and all GitHub resolution functions
- Add PATCH /companies/:companyId/skills/:skillId/auth for managing PAT per skill
- Add DELETE /companies/:companyId/skills/by-source for bulk deleting skills from a repo
- Preserve sourceAuthSecretId across skill re-imports/updates
- UI: Add PAT input field in import form for GitHub URLs
- UI: Add SkillAuthSection with ShieldCheck icon for viewing/updating/removing PAT
- UI: Add trash icon next to source label for delete-by-source

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 15:53:45 -04:00
dotta 5d021583be Add draft routine defaults and run-time overrides 2026-04-09 10:19:52 -05:00
dotta da251e5eab Merge public/master into pap-1239-server-test-isolation 2026-04-09 09:40:44 -05:00
Dotta 0191fabdc6 Merge pull request #3203 from cryppadotta/pap-1239-tooling-docs
chore(dev): refresh worktree tooling and contributor docs
2026-04-09 09:11:52 -05:00
dotta c7bf2661c9 Remove workspace link package preflight hooks
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 08:35:41 -05:00
dotta d607ca0089 Scope workspace link preflight to linked worktrees
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 08:19:19 -05:00
dotta 61ed4ef90c fix(server): reject non-participant stage mutations 2026-04-09 07:29:56 -05:00
dotta 11c3eee66b test(server): align isolated route specs with current behavior 2026-04-09 07:07:08 -05:00
dotta fe21ab324b test(server): isolate route modules in endpoint tests 2026-04-09 06:25:41 -05:00
dotta 27ec1e0c8b Fix execution policy edits on in-review issues 2026-04-09 06:16:41 -05:00
dotta 3baebee2df Track blocker and review activity events 2026-04-09 06:16:41 -05:00
dotta 8894520ed0 comment wake batching test 2026-04-09 06:16:05 -05:00
dotta ec75cabcd8 Enforce execution-policy stage handoffs 2026-04-09 06:16:05 -05:00
dotta 844b061267 Disable timer heartbeats by default for new agents 2026-04-09 06:16:05 -05:00
dotta 5640d29ab0 Persist non-issue inbox dismissals 2026-04-09 06:16:05 -05:00
dotta 1de5fb9316 Support routine variables in titles 2026-04-09 06:16:05 -05:00
Devin Foley 3264f9c1f6 Fix typing lag in long comment threads (PAPA-63) (#3163)
## Thinking Path

> - Paperclip orchestrates AI agents for zero-human companies
> - The issue detail page displays comment threads with rich timeline
rendering
> - Long threads (100+ items) cause severe typing lag in the comment
composer because every keystroke re-renders the entire timeline
> - CDP tracing confirmed 110ms avg key→paint latency and 60 long tasks
blocking the main thread for 3.7s total
> - This pull request memoizes the timeline, stabilizes callback props,
debounces editor observers, and reduces idle polling frequency
> - The benefit is responsive typing (21ms avg, 5.3× faster) even on
threads with 100+ timeline items

## What Changed

- **CommentThread.tsx**: Memoize `TimelineList` with `useMemo` so typing
state changes don't re-render 143 timeline items; extract
`handleFeedbackVote` to `useCallback`; added missing deps
(`pendingApprovalAction`, `onApproveApproval`, `onRejectApproval`) to
useMemo array
- **IssueDetail.tsx**: Extract inline callbacks (`handleCommentAdd`,
`handleCommentVote`, `handleCommentImageUpload`,
`handleCommentAttachImage`, `handleInterruptQueued`) to `useCallback`
with `.mutateAsync` deps (not full mutation objects) for stable
references; add conditional polling intervals (3s active / 30s idle) for
`liveRuns`, `activeRun`, `linkedRuns`, and timeline queries
- **MarkdownEditor.tsx**: Debounce `MutationObserver` and
`selectionchange` handlers via `requestAnimationFrame` coalescing
- **LiveRunWidget.tsx**: Accept optional `liveRunsData` and
`activeRunData` props to reuse parent-fetched data instead of duplicate
polling

## Verification

- Navigated to [IP address]:3105/PAPA/issues/PAPA-32 (thread with 100+
items)
- Typed in comment composer — lag eliminated, characters appear
instantly
- CDP trace test script (`test-typing-lag.mjs`) confirmed: avg 21ms
key→paint (was 110ms), 5 long tasks (was 60), 0.5s blocking (was 3.7s)
- Ran `pnpm test:run` locally — all tests pass

## Risks

- Low risk. All changes are additive memoization and callback
stabilization — no behavioral changes. Polling intervals are only
reduced for idle state; active runs still poll at 3–5s.

## Model Used

- Claude Opus 4.6 (`claude-opus-4-6`) via Claude Code CLI, with tool use
and extended context

## 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: Paperclip <noreply@paperclip.ing>
2026-04-08 17:54:03 -07:00
Daniel Luca b7a7dacfa3 fix: remove hardcoded JWT secret fallback from createBetterAuthInstance 2026-04-08 17:51:21 +03: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
Dotta 9cfa37fce3 Merge pull request #1961 from antonio-mello-ai/fix/webhook-github-sentry-signing-modes
feat(server): add github_hmac and none webhook signing modes
2026-04-07 22:58:14 -05:00
Dotta 943b851a5e Merge pull request #2643 from chrisschwer/fix/stale-execution-lock-lifecycle
fix: stale execution lock lifecycle (PIP-002)
2026-04-07 22:55:53 -05:00
Dotta 54f93c1f27 Merge pull request #2441 from DanielSousa/skill-removal-ui
feat(company-skills): implement skill deletion (UI) with agent usage check
2026-04-07 21:51:51 -05:00
Dotta f55a5e557d Merge pull request #2866 from ergonaworks/fix/agent-auth-jwt-better-auth-secret-fallback
fix(agent-auth): fall back to BETTER_AUTH_SECRET when PAPERCLIP_AGENT_JWT_SECRET is absent
2026-04-07 21:49:28 -05:00
Dotta 50a36beec5 Merge pull request #3033 from kimnamu/feat/bedrock-model-selection
fix(claude-local): respect model selection for Bedrock users
2026-04-07 21:48:29 -05:00
dotta b0b85e6ba3 Stabilize onboarding e2e cleanup paths 2026-04-07 18:20:35 -05:00
dotta cb705c9856 Fix signoff PR follow-up tests 2026-04-07 17:56:39 -05:00
dotta bce58d353d fix execution policy decision persistence 2026-04-07 17:43:10 -05:00
dotta a0333f3e9d Stabilize heartbeat comment batching assertion 2026-04-07 17:43:10 -05:00
dotta 2e31fb7c91 Add comprehensive e2e tests for signoff execution policy
Expands the execution policy test suite from 3 to 34 tests covering:
- Full happy path (executor → review → approval → done)
- Changes requested flow with re-submission
- Review-only and approval-only policy variants
- Access control (non-participant cannot advance stages)
- Comment requirements (empty, whitespace-only, null)
- Policy removal mid-flow with state cleanup
- Reopening done/cancelled issues clears execution state
- Multi-participant stage selection and exclusion
- User-type reviewer participants
- No-op transitions and edge cases

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-07 17:43:10 -05:00
dotta b3e0c31239 Add issue review policy and comment retry
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-07 17:43:10 -05:00