61 Commits

Author SHA1 Message Date
Chris Farhood 160d6b49e9 0.2.5 2026-04-30 09:06:19 -04:00
Chris Farhood 9007762390 chore(deps): bump @paperclipai/adapter-utils from canary.7 pin to ^2026.428.0
The peerDep floor and devDep were pinned to a pre-release canary from
April 15, 13 days behind the current stable. Move both to the latest
stable 2026.428.0. All 328 tests pass against the new types; the
imported surface (asString, parseObject, runChildProcess,
AdapterExecutionContext, etc.) is unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 09:06:12 -04:00
Chris Farhood 506007984c 0.2.4 2026-04-30 08:46:57 -04:00
Chris Farhood 7a6d1a44f2 fix(ui-parser): restore esbuild CJS bundle step lost in PR #11 merge
Commit 0e43811 added an esbuild step to bundle src/ui-parser.ts as CJS
because the UI's sandboxed worker can't evaluate ESM `export` syntax.
PR #11 (filesystem-log-tail) was based on a commit predating that fix,
so the merge clobbered both the build:ui-parser script and the esbuild
devDependency. Every release since has shipped a tsc-emitted ESM
ui-parser.js that the worker silently fails to load — parseStdoutLine
never registers and the run transcript falls back to dumping raw
stream-json lines as plain text instead of rendering structured
assistant/thinking/tool_call/tool_result entries.

Restore the script and dep verbatim from 0e43811.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 08:46:46 -04:00
Chris Farhood cc942ca818 0.2.3 2026-04-30 08:03:08 -04:00
Chris Farhood c8429cfde1 fix: write logs to /paperclip/instances/default/data/run-logs/ to match server PVC layout
v0.2.1 introduced filesystem-tail log delivery with buildPodLogPath()
returning /paperclip/instances/default/run-logs/... but the paperclip
server creates and tails from /paperclip/instances/default/data/run-logs/
on the shared PVC. The missing /data/ segment meant:

  1. The init container's mkdir -p /paperclip/instances/... ran in a
     directory busybox UID 1000 can't write to — it's the init
     container's ephemeral rootfs, since the PVC is only mounted in
     the main container. Init exited 1, the && short-circuited, and
     the prompt copy never happened. Job failed with "Init container
     'write-prompt' failed with exit code 1".
  2. Even if the mkdir had worked, the main container's tee would
     have written to a path the server doesn't tail.

Fix: drop the misplaced mkdir from both init container variants and
correct buildPodLogPath() to include /data/. The directory already
exists on the PVC because the paperclip server creates it; both
containers run as UID 1000 with fsGroup 1000, so the main container's
tee writes to the pre-existing path with no setup needed.

Bump to 0.2.2.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 22:15:15 -04:00
Chris Farhood 8bd5042b5d feat: replace k8s log API streaming with filesystem tailing
Replaces K8s log API streaming (which was dropping every ~3 seconds at
production scale) with filesystem tailing via tee to a pod log file on
the shared PVC.

Core changes:
- Add tee to claudeInvocation to write pod log file
- Add mkdir -p to init container to create log directory
- Add assertSafePathComponent and buildPodLogPath helper
- Add tailPodLogFile function with adaptive 250ms/1s polling
- Replace k8s log streaming with tailPodLogFile in Promise.allSettled
- Delete log-dedup.ts (RTK output truncation no longer needed)
- Update config-schema.ts and index.ts to remove RTK references
- Clean up log file in cleanupJob when retainJobs=false

Note: 14 tests in execute.test.ts test the obsolete k8s log streaming
approach and need to be rewritten or deleted (streamPodLogsOnce tests).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-27 22:13:39 -04:00
Chris Farhood 568f571d8c fix(models): inline static model list in index.ts to break circular dep with server/models
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 09:16:35 -04:00
Chris Farhood 8a9376b40e chore: bump to 0.1.56
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 08:05:29 -04:00
Chris Farhood 1d894f104f fix(models): expose static models list so UI renders entries before listModels resolves
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 07:42:44 -04:00
Chris Farhood fc3866924a 0.1.54 2026-04-27 00:38:06 +00:00
Chris Farhood 34756f8215 0.1.53 2026-04-27 00:28:45 +00:00
Chris Farhood fd7dce7239 0.1.52 2026-04-27 00:00:57 +00:00
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