Compare commits
2 Commits
master
...
feat/rtk-hooks
| Author | SHA1 | Date | |
|---|---|---|---|
| 77e4a13644 | |||
| b24f849198 |
Generated
+25
-24
@@ -1,19 +1,19 @@
|
|||||||
{
|
{
|
||||||
"name": "@farhoodliquor/paperclip-adapter-claude-k8s",
|
"name": "@farhoodliquor/paperclip-adapter-claude-k8s",
|
||||||
"version": "0.1.9",
|
"version": "0.1.12",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@farhoodliquor/paperclip-adapter-claude-k8s",
|
"name": "@farhoodliquor/paperclip-adapter-claude-k8s",
|
||||||
"version": "0.1.9",
|
"version": "0.1.12",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@kubernetes/client-node": "^1.0.0",
|
"@kubernetes/client-node": "^1.0.0",
|
||||||
"picocolors": "^1.1.1"
|
"picocolors": "^1.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@paperclipai/adapter-utils": "^0.3.0",
|
"@paperclipai/adapter-utils": "^2026.415.0-canary.7",
|
||||||
"@types/node": "^24.6.0",
|
"@types/node": "^24.6.0",
|
||||||
"@vitest/coverage-v8": "^4.1.4",
|
"@vitest/coverage-v8": "^4.1.4",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.7.3",
|
||||||
@@ -194,9 +194,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@napi-rs/wasm-runtime": {
|
"node_modules/@napi-rs/wasm-runtime": {
|
||||||
"version": "1.1.3",
|
"version": "1.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz",
|
||||||
"integrity": "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ==",
|
"integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
@@ -223,10 +223,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@paperclipai/adapter-utils": {
|
"node_modules/@paperclipai/adapter-utils": {
|
||||||
"version": "0.3.1",
|
"version": "2026.415.0-canary.7",
|
||||||
"resolved": "https://registry.npmjs.org/@paperclipai/adapter-utils/-/adapter-utils-0.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@paperclipai/adapter-utils/-/adapter-utils-2026.415.0-canary.7.tgz",
|
||||||
"integrity": "sha512-W66k+hJkQE8ma0asM/Sd90AC8HHy/BLG/sd0aOC+rDWw+gOasQyUkTnDoPv1zhQuTyKEEvLFV6ByOOKqEiAz/A==",
|
"integrity": "sha512-VNzIZmu1lrK6QM8Ad9WkOihZItfkj21NHKQf+artDcbwFT2hHbDAD9hdW2W9NMVxYdFvvnws3w76FI/BUbCMbQ==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-android-arm64": {
|
"node_modules/@rolldown/binding-android-arm64": {
|
||||||
"version": "1.0.0-rc.15",
|
"version": "1.0.0-rc.15",
|
||||||
@@ -803,9 +804,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/bare-fs": {
|
"node_modules/bare-fs": {
|
||||||
"version": "4.7.0",
|
"version": "4.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.1.tgz",
|
||||||
"integrity": "sha512-xzqKsCFxAek9aezYhjJuJRXBIaYlg/0OGDTZp+T8eYmYMlm66cs6cYko02drIyjN2CBbi+I6L7YfXyqpqtKRXA==",
|
"integrity": "sha512-WDRsyVN52eAx/lBamKD6uyw8H4228h/x0sGGGegOamM2cd7Pag88GfMQalobXI+HaEUxpCkbKQUDOQqt9wawRw==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bare-events": "^2.5.4",
|
"bare-events": "^2.5.4",
|
||||||
@@ -1767,13 +1768,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/openid-client": {
|
"node_modules/openid-client": {
|
||||||
"version": "6.8.2",
|
"version": "6.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/openid-client/-/openid-client-6.8.2.tgz",
|
"resolved": "https://registry.npmjs.org/openid-client/-/openid-client-6.8.3.tgz",
|
||||||
"integrity": "sha512-uOvTCndr4udZsKihJ68H9bUICrriHdUVJ6Az+4Ns6cW55rwM5h0bjVIzDz2SxgOI84LKjFyjOFvERLzdTUROGA==",
|
"integrity": "sha512-AoY/NaN9esS3+xvHInFSK0g3skSfeE0uqQAKRj4rB6/GsBIvzwTUaYo9+HcqpKIaP0dP85p5W07hayKgS4GAeA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jose": "^6.1.3",
|
"jose": "^6.2.2",
|
||||||
"oauth4webapi": "^3.8.4"
|
"oauth4webapi": "^3.8.5"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/panva"
|
"url": "https://github.com/sponsors/panva"
|
||||||
@@ -1806,9 +1807,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.5.9",
|
"version": "8.5.10",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.9.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz",
|
||||||
"integrity": "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==",
|
"integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -1960,9 +1961,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/std-env": {
|
"node_modules/std-env": {
|
||||||
"version": "4.0.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/std-env/-/std-env-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz",
|
||||||
"integrity": "sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==",
|
"integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
|||||||
+2
-2
@@ -37,10 +37,10 @@
|
|||||||
"picocolors": "^1.1.1"
|
"picocolors": "^1.1.1"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@paperclipai/adapter-utils": ">=0.3.0"
|
"@paperclipai/adapter-utils": ">=2026.415.0-canary.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@paperclipai/adapter-utils": "^0.3.0",
|
"@paperclipai/adapter-utils": "2026.415.0-canary.7",
|
||||||
"@types/node": "^24.6.0",
|
"@types/node": "^24.6.0",
|
||||||
"@vitest/coverage-v8": "^4.1.4",
|
"@vitest/coverage-v8": "^4.1.4",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.7.3",
|
||||||
|
|||||||
@@ -38,6 +38,11 @@ Kubernetes fields:
|
|||||||
- ttlSecondsAfterFinished (number, optional): auto-cleanup delay; default 300
|
- ttlSecondsAfterFinished (number, optional): auto-cleanup delay; default 300
|
||||||
- retainJobs (boolean, optional): skip cleanup on completion for debugging
|
- retainJobs (boolean, optional): skip cleanup on completion for debugging
|
||||||
|
|
||||||
|
RTK fields (token optimization):
|
||||||
|
- enableRtk (boolean, optional): enable RTK to reduce token usage by filtering CLI output. Configures Claude Code PreToolUse/PostToolUse hooks automatically via project-level settings. Adds an init container to download the RTK binary.
|
||||||
|
- rtkVersion (string, optional): RTK version to install; defaults to "latest"
|
||||||
|
- rtkImage (string, optional): container image for the RTK download init container; defaults to "curlimages/curl:8.12.1"
|
||||||
|
|
||||||
Operational fields:
|
Operational fields:
|
||||||
- timeoutSec (number, optional): run timeout in seconds; 0 means no timeout
|
- timeoutSec (number, optional): run timeout in seconds; 0 means no timeout
|
||||||
- graceSec (number, optional): additional grace before adapter gives up after Job deadline
|
- graceSec (number, optional): additional grace before adapter gives up after Job deadline
|
||||||
|
|||||||
@@ -108,6 +108,26 @@ export function getConfigSchema(): AdapterConfigSchema {
|
|||||||
label: "Memory Limit",
|
label: "Memory Limit",
|
||||||
hint: "Memory limit for Job pods (e.g. 128Mi, 512Mi, 1Gi).",
|
hint: "Memory limit for Job pods (e.g. 128Mi, 512Mi, 1Gi).",
|
||||||
},
|
},
|
||||||
|
// RTK (token optimization)
|
||||||
|
{
|
||||||
|
type: "toggle",
|
||||||
|
key: "enableRtk",
|
||||||
|
label: "Enable RTK",
|
||||||
|
hint: "Install and enable RTK (rtk-ai/rtk) to reduce token usage by filtering CLI output through PreToolUse/PostToolUse hooks. Adds an init container to download the RTK binary.",
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
key: "rtkVersion",
|
||||||
|
label: "RTK Version",
|
||||||
|
hint: "RTK version to install (e.g. '0.5.0'). Defaults to 'latest'.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
key: "rtkImage",
|
||||||
|
label: "RTK Installer Image",
|
||||||
|
hint: "Container image for the RTK download init container. Defaults to curlimages/curl:8.12.1.",
|
||||||
|
},
|
||||||
// Scheduling
|
// Scheduling
|
||||||
{
|
{
|
||||||
type: "textarea",
|
type: "textarea",
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ export function createServerAdapter(): ServerAdapterModule {
|
|||||||
listSkills: listK8sSkills,
|
listSkills: listK8sSkills,
|
||||||
syncSkills: syncK8sSkills,
|
syncSkills: syncK8sSkills,
|
||||||
supportsLocalAgentJwt: true,
|
supportsLocalAgentJwt: true,
|
||||||
|
supportsInstructionsBundle: true,
|
||||||
|
instructionsPathKey: "instructionsFilePath",
|
||||||
|
requiresMaterializedRuntimeSkills: false,
|
||||||
agentConfigurationDoc,
|
agentConfigurationDoc,
|
||||||
getConfigSchema,
|
getConfigSchema,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -497,6 +497,116 @@ describe("buildJobManifest", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("RTK integration", () => {
|
||||||
|
it("does not add RTK init container by default", () => {
|
||||||
|
const { job } = buildJobManifest({ ctx, selfPod });
|
||||||
|
const inits = job.spec?.template?.spec?.initContainers ?? [];
|
||||||
|
expect(inits).toHaveLength(1);
|
||||||
|
expect(inits[0]?.name).toBe("write-prompt");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("adds install-rtk init container when enableRtk is true", () => {
|
||||||
|
ctx.config = { enableRtk: true };
|
||||||
|
const { job } = buildJobManifest({ ctx, selfPod });
|
||||||
|
const inits = job.spec?.template?.spec?.initContainers ?? [];
|
||||||
|
expect(inits).toHaveLength(2);
|
||||||
|
expect(inits[1]?.name).toBe("install-rtk");
|
||||||
|
expect(inits[1]?.image).toBe("curlimages/curl:8.12.1");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("uses custom rtkImage for init container", () => {
|
||||||
|
ctx.config = { enableRtk: true, rtkImage: "my-registry/rtk-installer:v1" };
|
||||||
|
const { job } = buildJobManifest({ ctx, selfPod });
|
||||||
|
const inits = job.spec?.template?.spec?.initContainers ?? [];
|
||||||
|
const rtkInit = inits.find((c) => c.name === "install-rtk");
|
||||||
|
expect(rtkInit?.image).toBe("my-registry/rtk-installer:v1");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("adds rtk-bin emptyDir volume when enableRtk is true", () => {
|
||||||
|
ctx.config = { enableRtk: true };
|
||||||
|
const { job } = buildJobManifest({ ctx, selfPod });
|
||||||
|
const rtkVol = job.spec?.template?.spec?.volumes?.find((v) => v.name === "rtk-bin");
|
||||||
|
expect(rtkVol?.emptyDir).toEqual({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("mounts rtk-bin in main container when enableRtk is true", () => {
|
||||||
|
ctx.config = { enableRtk: true };
|
||||||
|
const { job } = buildJobManifest({ ctx, selfPod });
|
||||||
|
const rtkMount = job.spec?.template?.spec?.containers[0]?.volumeMounts?.find(
|
||||||
|
(vm) => vm.name === "rtk-bin",
|
||||||
|
);
|
||||||
|
expect(rtkMount?.mountPath).toBe("/tmp/rtk-bin");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("prepends rtk setup to main command with project-level settings isolation", () => {
|
||||||
|
ctx.config = { enableRtk: true };
|
||||||
|
const { job } = buildJobManifest({ ctx, selfPod });
|
||||||
|
const command = job.spec?.template?.spec?.containers[0]?.command;
|
||||||
|
expect(command?.[2]).toContain('export PATH="/tmp/rtk-bin:$PATH"');
|
||||||
|
expect(command?.[2]).toContain("rtk install claude-code");
|
||||||
|
expect(command?.[2]).toContain("settings.local.json");
|
||||||
|
expect(command?.[2]).toContain("export HOME=/paperclip");
|
||||||
|
expect(command?.[2]).toContain("cat /tmp/prompt/prompt.txt | claude");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not prepend rtk setup when enableRtk is false", () => {
|
||||||
|
ctx.config = { enableRtk: false };
|
||||||
|
const { job } = buildJobManifest({ ctx, selfPod });
|
||||||
|
const command = job.spec?.template?.spec?.containers[0]?.command;
|
||||||
|
expect(command?.[2]).not.toContain("rtk");
|
||||||
|
expect(command?.[2]).toMatch(/^cat \/tmp\/prompt\/prompt\.txt/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not add rtk-bin volume when enableRtk is false", () => {
|
||||||
|
ctx.config = { enableRtk: false };
|
||||||
|
const { job } = buildJobManifest({ ctx, selfPod });
|
||||||
|
expect(job.spec?.template?.spec?.volumes?.find((v) => v.name === "rtk-bin")).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("sets RTK_NO_TELEMETRY env var when enableRtk is true", () => {
|
||||||
|
ctx.config = { enableRtk: true };
|
||||||
|
const { job } = buildJobManifest({ ctx, selfPod });
|
||||||
|
const rtkTelemetry = job.spec?.template?.spec?.containers[0]?.env?.find(
|
||||||
|
(e) => e.name === "RTK_NO_TELEMETRY",
|
||||||
|
);
|
||||||
|
expect(rtkTelemetry?.value).toBe("1");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not set RTK_NO_TELEMETRY when enableRtk is false", () => {
|
||||||
|
const { job } = buildJobManifest({ ctx, selfPod });
|
||||||
|
const rtkTelemetry = job.spec?.template?.spec?.containers[0]?.env?.find(
|
||||||
|
(e) => e.name === "RTK_NO_TELEMETRY",
|
||||||
|
);
|
||||||
|
expect(rtkTelemetry).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("uses custom rtkVersion in install command", () => {
|
||||||
|
ctx.config = { enableRtk: true, rtkVersion: "0.5.0" };
|
||||||
|
const { job } = buildJobManifest({ ctx, selfPod });
|
||||||
|
const inits = job.spec?.template?.spec?.initContainers ?? [];
|
||||||
|
const rtkInit = inits.find((c) => c.name === "install-rtk");
|
||||||
|
expect(rtkInit?.command?.[2]).toContain("RTK_VERSION=0.5.0");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("mounts rtk-bin in install-rtk init container", () => {
|
||||||
|
ctx.config = { enableRtk: true };
|
||||||
|
const { job } = buildJobManifest({ ctx, selfPod });
|
||||||
|
const inits = job.spec?.template?.spec?.initContainers ?? [];
|
||||||
|
const rtkInit = inits.find((c) => c.name === "install-rtk");
|
||||||
|
expect(rtkInit?.volumeMounts).toContainEqual({ name: "rtk-bin", mountPath: "/tmp/rtk-bin" });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("writes hooks to workspace .claude/settings.local.json not global settings", () => {
|
||||||
|
ctx.context = { paperclipWorkspace: { cwd: "/paperclip/workspaces/agent-abc" } };
|
||||||
|
ctx.config = { enableRtk: true };
|
||||||
|
const { job } = buildJobManifest({ ctx, selfPod });
|
||||||
|
const command = job.spec?.template?.spec?.containers[0]?.command;
|
||||||
|
expect(command?.[2]).toContain("/paperclip/workspaces/agent-abc/.claude");
|
||||||
|
expect(command?.[2]).toContain("settings.local.json");
|
||||||
|
expect(command?.[2]).not.toMatch(/HOME="\/paperclip".*rtk install/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("return value", () => {
|
describe("return value", () => {
|
||||||
it("returns job, jobName, namespace, prompt, claudeArgs, promptMetrics", () => {
|
it("returns job, jobName, namespace, prompt, claudeArgs, promptMetrics", () => {
|
||||||
const result = buildJobManifest({ ctx, selfPod });
|
const result = buildJobManifest({ ctx, selfPod });
|
||||||
|
|||||||
@@ -148,6 +148,10 @@ function buildEnvVars(
|
|||||||
// HOME must be /paperclip to match PVC mount and enable session resume
|
// HOME must be /paperclip to match PVC mount and enable session resume
|
||||||
merged.HOME = "/paperclip";
|
merged.HOME = "/paperclip";
|
||||||
|
|
||||||
|
if (asBoolean(config.enableRtk, false)) {
|
||||||
|
merged.RTK_NO_TELEMETRY = "1";
|
||||||
|
}
|
||||||
|
|
||||||
// Convert to V1EnvVar array
|
// Convert to V1EnvVar array
|
||||||
const envVars: k8s.V1EnvVar[] = Object.entries(merged).map(([name, value]) => ({
|
const envVars: k8s.V1EnvVar[] = Object.entries(merged).map(([name, value]) => ({
|
||||||
name,
|
name,
|
||||||
@@ -171,6 +175,9 @@ export function buildJobManifest(input: JobBuildInput): JobBuildResult {
|
|||||||
// K8s Job pods are always unattended — no one to approve permission prompts
|
// K8s Job pods are always unattended — no one to approve permission prompts
|
||||||
const dangerouslySkipPermissions = asBoolean(config.dangerouslySkipPermissions, true);
|
const dangerouslySkipPermissions = asBoolean(config.dangerouslySkipPermissions, true);
|
||||||
const extraArgs = asStringArray(config.extraArgs);
|
const extraArgs = asStringArray(config.extraArgs);
|
||||||
|
const enableRtk = asBoolean(config.enableRtk, false);
|
||||||
|
const rtkVersion = asString(config.rtkVersion, "latest");
|
||||||
|
const rtkImage = asString(config.rtkImage, "curlimages/curl:8.12.1");
|
||||||
const timeoutSec = asNumber(config.timeoutSec, 0);
|
const timeoutSec = asNumber(config.timeoutSec, 0);
|
||||||
const ttlSeconds = asNumber(config.ttlSecondsAfterFinished, 300);
|
const ttlSeconds = asNumber(config.ttlSecondsAfterFinished, 300);
|
||||||
const resources = parseObject(config.resources);
|
const resources = parseObject(config.resources);
|
||||||
@@ -282,6 +289,11 @@ export function buildJobManifest(input: JobBuildInput): JobBuildResult {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if (enableRtk) {
|
||||||
|
volumes.push({ name: "rtk-bin", emptyDir: {} });
|
||||||
|
volumeMounts.push({ name: "rtk-bin", mountPath: "/tmp/rtk-bin" });
|
||||||
|
}
|
||||||
|
|
||||||
// Mount shared PVC for /paperclip (session state, workspaces, data)
|
// Mount shared PVC for /paperclip (session state, workspaces, data)
|
||||||
if (selfPod.pvcClaimName) {
|
if (selfPod.pvcClaimName) {
|
||||||
volumes.push({
|
volumes.push({
|
||||||
@@ -326,7 +338,10 @@ export function buildJobManifest(input: JobBuildInput): JobBuildResult {
|
|||||||
|
|
||||||
// Build the claude command string for the main container
|
// Build the claude command string for the main container
|
||||||
const claudeArgsEscaped = claudeArgs.map((a) => `'${a.replace(/'/g, "'\\''")}'`).join(" ");
|
const claudeArgsEscaped = claudeArgs.map((a) => `'${a.replace(/'/g, "'\\''")}'`).join(" ");
|
||||||
const mainCommand = `cat /tmp/prompt/prompt.txt | claude ${claudeArgsEscaped}`;
|
const claudeCommand = `cat /tmp/prompt/prompt.txt | claude ${claudeArgsEscaped}`;
|
||||||
|
const mainCommand = enableRtk
|
||||||
|
? `export PATH="/tmp/rtk-bin:$PATH" && _RTK_HOME=$(mktemp -d) && HOME="$_RTK_HOME" rtk install claude-code 2>/dev/null && mkdir -p '${workingDir}/.claude' && mv "$_RTK_HOME/.claude/settings.json" '${workingDir}/.claude/settings.local.json' 2>/dev/null; rm -rf "$_RTK_HOME"; export HOME=/paperclip && ${claudeCommand}`
|
||||||
|
: claudeCommand;
|
||||||
|
|
||||||
const job: k8s.V1Job = {
|
const job: k8s.V1Job = {
|
||||||
apiVersion: "batch/v1",
|
apiVersion: "batch/v1",
|
||||||
@@ -368,6 +383,28 @@ export function buildJobManifest(input: JobBuildInput): JobBuildResult {
|
|||||||
limits: { cpu: "100m", memory: "64Mi" },
|
limits: { cpu: "100m", memory: "64Mi" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
...(enableRtk
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
name: "install-rtk",
|
||||||
|
image: rtkImage,
|
||||||
|
imagePullPolicy: "IfNotPresent" as const,
|
||||||
|
command: [
|
||||||
|
"sh",
|
||||||
|
"-c",
|
||||||
|
rtkVersion === "latest"
|
||||||
|
? "curl -fsSL https://raw.githubusercontent.com/rtk-ai/rtk/refs/heads/master/install.sh | RTK_INSTALL_DIR=/tmp/rtk-bin sh"
|
||||||
|
: `curl -fsSL https://raw.githubusercontent.com/rtk-ai/rtk/refs/heads/master/install.sh | RTK_INSTALL_DIR=/tmp/rtk-bin RTK_VERSION=${rtkVersion} sh`,
|
||||||
|
],
|
||||||
|
volumeMounts: [{ name: "rtk-bin", mountPath: "/tmp/rtk-bin" }],
|
||||||
|
securityContext,
|
||||||
|
resources: {
|
||||||
|
requests: { cpu: "10m", memory: "32Mi" },
|
||||||
|
limits: { cpu: "200m", memory: "128Mi" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
],
|
],
|
||||||
containers: [
|
containers: [
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user