Commit Graph

48 Commits

Author SHA1 Message Date
Chris Farhood 83e105393c 0.1.51 2026-04-26 21:24:15 +00:00
Chris Farhood dae9e18659 0.1.50 2026-04-26 21:19:03 +00:00
Chris Farhood d184a1732b 0.1.49 2026-04-26 21:06:19 +00:00
Chris Farhood d9928030d6 0.1.48 2026-04-26 14:48:22 +00:00
Chris Farhood 3169f49f23 0.1.47 2026-04-26 13:04:54 +00:00
Chris Farhood 4e2c36319d 0.1.46 2026-04-26 01:57:43 +00:00
Chris Farhood 88896eddcf 0.1.45 2026-04-26 01:54:48 +00:00
Chris Farhood 986f2fc7fa test: add coverage for deletionTimestamp concurrency guard bypass (FAR-34)
Verifies that a terminating K8s job (deletionTimestamp set, no
Complete/Failed condition) is skipped by the concurrency guard so
subsequent heartbeat runs are not incorrectly blocked.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-24 19:57:10 +00:00
Chris Farhood 357f035418 fix: skip K8s jobs with deletionTimestamp in concurrency guard (FAR-34)
Jobs being deleted via kubectl enter a Terminating state where
deletionTimestamp is set but no Complete/Failed condition is added.
The concurrency guard previously treated these as running, blocking
all subsequent heartbeat runs for the agent until the job fully
disappeared from the K8s API.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-24 18:36:19 +00:00
Chris Farhood f340ce52ee 0.1.42 2026-04-24 17:56:14 +00:00
Chris Farhood f9ba77527a 0.1.41 2026-04-24 17:43:16 +00:00
Chris Farhood 727d9494da 0.1.40 2026-04-24 17:35:08 +00:00
Chris Farhood e611f26d32 0.1.39 2026-04-24 15:20:59 +00:00
Chris Farhood c55d6c61fc feat: declare hasOutOfProcessLiveness and remove onSpawn workarounds (FAR-24)
- Add `hasOutOfProcessLiveness: true` to createServerAdapter() so the
  reaper skips local PID checks and uses the staleness window instead.
- Remove the initial onSpawn call and all periodic keepalive onSpawn
  refreshes that were compensating for the missing flag.
- Remove POST_TERMINAL_KEEPALIVE_MS constant and keepaliveTick counter
  that backed those workarounds.
- Cast required: adapter-utils ServerAdapterModule type predates this field.
- Bump to 0.1.38.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-24 14:14:10 +00:00
Chris Farhood 32d6308eae 0.1.37 2026-04-24 13:11:13 +00:00
Chris Farhood abdce817f3 0.1.36
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-24 12:36:21 +00:00
Chris Farhood e310ba4156 0.1.35 2026-04-24 00:44:59 +00:00
Gandalf the Greybeard e86b14a677 0.1.34 2026-04-23 23:35:02 +00:00
Gandalf the Greybeard 9f79efdf36 0.1.33 2026-04-23 22:45:37 +00:00
Hugh Commit baf7e2d44d 0.1.32: port prepareClaudePromptBundle to claude_k8s (FAR-12)
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-23 19:47:26 +00:00
Gandalf the Greybeard c7706d742f 0.1.31: harden streamPodLogsOnce with Promise.race bail (FAR-10)
Defensive follow-up to the FAR-10 fix.  The original patch aborts the
in-flight follow stream by destroying the Writable once stopSignal
fires, and relies on the @kubernetes/client-node library propagating
that destroy into an abort of the underlying HTTP request.  If that
propagation ever fails (e.g. the client is awaiting a response that
never arrives), logApi.log() can still hang forever.

Adds a Promise.race with a 3s bail timer that starts when stopSignal
fires.  In the happy path (destroy-propagation works), logApi.log()
resolves first and the bail timer is cleared.  In the failure path,
the bail timer fires and streamPodLogsOnce returns with whatever
chunks were captured — preventing the hang from reaching execute().

No test change: existing 267 tests pass and the race path needs a k8s
mock to exercise end-to-end; validated by monitoring real runs.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-23 16:36:51 +00:00
Gandalf the Greybeard 8937fb2804 chore: fix repo org farhoodliquor→farhoodlabs; wire NPM_TOKEN for publish
- Update repository, bugs, and homepage URLs in package.json to use
  the correct farhoodlabs GitHub org
- Add NODE_AUTH_TOKEN: NPM_TOKEN to the CI publish step so the newly
  added NPM_TOKEN secret is picked up for authentication

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-23 16:20:48 +00:00
Gandalf the Greybeard 683ea2d8b1 0.1.30
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-23 16:08:22 +00:00
Test User 78fd702ccb 0.1.29 2026-04-23 02:48:58 +00:00
Test User a4631ac756 0.1.28
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-22 19:52:51 +00:00
Test User 20e7ec43ce 0.1.27 2026-04-22 17:08:48 +00:00
Paperclip 31328dd85b chore: unscope package name to paperclip-adapter-claude-k8s
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-21 10:26:43 +00:00
Test User b45cc29787 chore: bump version to 0.1.25 for PR #3
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-20 19:40:26 +00:00
Test User c35253ddd4 0.1.24 2026-04-20 18:03:53 +00:00
Test User 465a947e1d 0.1.23
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-20 16:10:40 +00:00
Test User b14ec960ae 0.1.22 2026-04-17 02:58:08 +00:00
Chris Farhood 20b85b8391 feat: add serviceAccountName field to config schema
Surface SA assignment in the Kubernetes section of the adapter UI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 20:06:43 -04:00
Test User ac18cc3ec3 chore: bump version to 0.1.20
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 21:56:44 +00:00
Test User d53559e58b fix: correct Bedrock Opus 4.7 model ID to us.anthropic.claude-opus-4-7
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 17:51:47 +00:00
Test User 335b7b50b5 chore: bump version to 0.1.18
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 17:07:08 +00:00
Chris Farhood 9a85842add chore: bump version for CI publish
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 11:52:02 -04:00
Chris Farhood b8ba457790 fix: don't delete job when returning state-mismatch error to keep UI in sync
When waitForJobCompletion threw and the job was still not terminal, we
were returning an error but still deleting the job in the finally block.
This left the UI holding an error while the job (still alive) would be
cleaned up by Kubernetes, causing the next heartbeat to find nothing and
think it was safe to retry — spawning a concurrent pod.

Now we set skipCleanup=true when returning the mismatch error, so the
job is retained and the heartbeat can still find and wait on it.

Also removes a duplicate empty-stdout fallback block.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 11:29:42 -04:00
Chris Farhood efbbfbc299 fix: re-check job state when completion waiter throws to prevent UI staleness
When waitForJobCompletion threw a transient error (API disconnect, etc.),
the code fell through with jobTimedOut=true and returned a result even
though the job was still running. This caused the UI to think the run
was complete while the job kept running, resulting in concurrency errors.

Now when completion throws, we re-check the job's actual state. If still
not terminal, we return a k8s_job_state_mismatch error so the UI knows
the run is not done.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 07:26:10 -04:00
Chris Farhood 710cf37f5e chore: rebuild dist files 2026-04-15 19:03:06 -04:00
Chris Farhood 6f85a068f4 chore: bump version to trigger CI publish
Verify upstream canary has adapter-utils exports

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 17:59:18 -04:00
Test User 3db5229407 feat: declare adapter plugin capabilities on ServerAdapterModule
Adds supportsInstructionsBundle, instructionsPathKey, and
requiresMaterializedRuntimeSkills flags so the UI renders the
bundle editor for claude_k8s agents. Bumps adapter-utils peer
dep to the canary that includes the capability type fields.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-15 21:45:08 +00:00
Pawla Abdul 77ba40d9bf Reconnect K8s log stream on silent API disconnects
The adapter opened a single follow-stream to the K8s API for pod logs.
If that TCP connection silently dropped (API server hiccup, network
timeout, load-balancer idle cut), streamPodLogs returned early and no
more real Claude output reached the UI — only keepalive pings.  The
pod kept running and producing logs (visible via kubectl), but the
adapter never reconnected.

Splits streamPodLogs into streamPodLogsOnce (single follow attempt) and
a reconnecting wrapper that retries with sinceSeconds until a shared
stop signal fires when waitForJobCompletion resolves.  On reconnect,
requests logs from the original stream start time (+5s overlap) so no
output is lost; the UI deduplicates chunks.

Bumps version to 0.1.12.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-13 10:34:41 +00:00
Pawla Abdul e760bf9386 Add keepalive pings during job execution to prevent UI timeout desync
The adapter had no mechanism to signal liveness while a K8s Job was
running. When Claude entered long thinking phases with no log output,
the Paperclip UI could lose sync and consider the run stuck even though
the pod was still actively working.

Adds a 15-second interval keepalive that sends status messages via
onLog during execution. The keepalive tracks time since last real log
output and reports it, keeping the connection alive. The timer is
cleaned up in the finally block to prevent leaks on any exit path.

Bumps version to 0.1.11.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-12 18:44:09 +00:00
Pawla Abdul e75a62b329 Fix CI publish failures and add missing config schema fields
- CI publish job failed because it tried to re-publish existing versions
  (npm returns 404 for scoped packages on duplicate version). Added a
  version-exists check before npm publish to skip gracefully.
- Also fixed the auth env var from NPM_TOKEN to NODE_AUTH_TOKEN which
  is what actions/setup-node's registry-url option expects.
- Added missing core and operational fields to getConfigSchema() so the
  Paperclip UI surfaces model, effort, maxTurnsPerRun, skipPermissions,
  instructionsFilePath, timeoutSec, and graceSec alongside existing K8s
  infrastructure fields.
- Bumped version to 0.1.10.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-12 15:02:54 +00:00
Chris Farhood f5fa41fb3a Fix getConfigSchema to use flat fields array with correct hint keys
The Paperclip AdapterConfigSchema type expects a flat fields array, not
nested sections. Also maps description -> hint per the schema type.
Defines types locally since @paperclipai/adapter-utils@0.3.1 on npm
does not yet export AdapterConfigSchema/ConfigFieldSchema (those exist
in the monorepo but aren't released to npm yet).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-12 10:43:31 -04:00
Chris Farhood 75ba66e504 Add getConfigSchema to surface K8s fields in Paperclip UI
Adds AdapterConfigSchema with three sections (Kubernetes, Resource Limits,
Scheduling) exposing: namespace, image, imagePullPolicy, kubeconfig,
resources.{requests,limits}.{cpu,memory}, nodeSelector, tolerations,
labels, ttlSecondsAfterFinished, retainJobs.

Paperclip's server fetches GET /api/adapters/:type/config-schema and
caches the result, automatically assigning ConfigFields to external
adapters. The adapter now wires getConfigSchema into createServerAdapter().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-12 10:31:55 -04:00
Chris Farhood 4b0baaf05c Add .gitignore and bump version for npm publishing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 23:43:19 -04:00
Chris Farhood 9dbb5f337e Initial commit: Paperclip adapter for Claude Code on Kubernetes
Adapter plugin that runs Claude Code agents as Kubernetes Jobs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 23:16:31 -04:00