@tickernelz/paperclip-pro-plugin-kubernetes 2026.925.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +180 -0
  3. package/dist/adapter-defaults.d.ts +29 -0
  4. package/dist/adapter-defaults.d.ts.map +1 -0
  5. package/dist/adapter-defaults.js +98 -0
  6. package/dist/adapter-defaults.js.map +1 -0
  7. package/dist/adapter-registry.d.ts +64 -0
  8. package/dist/adapter-registry.d.ts.map +1 -0
  9. package/dist/adapter-registry.js +25 -0
  10. package/dist/adapter-registry.js.map +1 -0
  11. package/dist/cilium-network-policy.d.ts +12 -0
  12. package/dist/cilium-network-policy.d.ts.map +1 -0
  13. package/dist/cilium-network-policy.js +60 -0
  14. package/dist/cilium-network-policy.js.map +1 -0
  15. package/dist/file-sync.d.ts +73 -0
  16. package/dist/file-sync.d.ts.map +1 -0
  17. package/dist/file-sync.js +752 -0
  18. package/dist/file-sync.js.map +1 -0
  19. package/dist/image-allowlist.d.ts +18 -0
  20. package/dist/image-allowlist.d.ts.map +1 -0
  21. package/dist/image-allowlist.js +39 -0
  22. package/dist/image-allowlist.js.map +1 -0
  23. package/dist/index.d.ts +3 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +3 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/job-orchestrator.d.ts +24 -0
  28. package/dist/job-orchestrator.d.ts.map +1 -0
  29. package/dist/job-orchestrator.js +90 -0
  30. package/dist/job-orchestrator.js.map +1 -0
  31. package/dist/kube-client.d.ts +15 -0
  32. package/dist/kube-client.d.ts.map +1 -0
  33. package/dist/kube-client.js +23 -0
  34. package/dist/kube-client.js.map +1 -0
  35. package/dist/lease-lifecycle.d.ts +62 -0
  36. package/dist/lease-lifecycle.d.ts.map +1 -0
  37. package/dist/lease-lifecycle.js +155 -0
  38. package/dist/lease-lifecycle.js.map +1 -0
  39. package/dist/manifest.d.ts +4 -0
  40. package/dist/manifest.d.ts.map +1 -0
  41. package/dist/manifest.js +108 -0
  42. package/dist/manifest.js.map +1 -0
  43. package/dist/network-policy.d.ts +22 -0
  44. package/dist/network-policy.d.ts.map +1 -0
  45. package/dist/network-policy.js +116 -0
  46. package/dist/network-policy.js.map +1 -0
  47. package/dist/plugin.d.ts +3 -0
  48. package/dist/plugin.d.ts.map +1 -0
  49. package/dist/plugin.js +820 -0
  50. package/dist/plugin.js.map +1 -0
  51. package/dist/pod-exec.d.ts +67 -0
  52. package/dist/pod-exec.d.ts.map +1 -0
  53. package/dist/pod-exec.js +401 -0
  54. package/dist/pod-exec.js.map +1 -0
  55. package/dist/pod-spec-builder.d.ts +25 -0
  56. package/dist/pod-spec-builder.d.ts.map +1 -0
  57. package/dist/pod-spec-builder.js +82 -0
  58. package/dist/pod-spec-builder.js.map +1 -0
  59. package/dist/sandbox-cr-builder.d.ts +40 -0
  60. package/dist/sandbox-cr-builder.d.ts.map +1 -0
  61. package/dist/sandbox-cr-builder.js +123 -0
  62. package/dist/sandbox-cr-builder.js.map +1 -0
  63. package/dist/sandbox-cr-orchestrator.d.ts +62 -0
  64. package/dist/sandbox-cr-orchestrator.d.ts.map +1 -0
  65. package/dist/sandbox-cr-orchestrator.js +248 -0
  66. package/dist/sandbox-cr-orchestrator.js.map +1 -0
  67. package/dist/sandbox-orchestrator.d.ts +39 -0
  68. package/dist/sandbox-orchestrator.d.ts.map +1 -0
  69. package/dist/sandbox-orchestrator.js +2 -0
  70. package/dist/sandbox-orchestrator.js.map +1 -0
  71. package/dist/scoped-network-egress.d.ts +19 -0
  72. package/dist/scoped-network-egress.d.ts.map +1 -0
  73. package/dist/scoped-network-egress.js +86 -0
  74. package/dist/scoped-network-egress.js.map +1 -0
  75. package/dist/secret-manager.d.ts +14 -0
  76. package/dist/secret-manager.d.ts.map +1 -0
  77. package/dist/secret-manager.js +39 -0
  78. package/dist/secret-manager.js.map +1 -0
  79. package/dist/tenant-orchestrator.d.ts +35 -0
  80. package/dist/tenant-orchestrator.d.ts.map +1 -0
  81. package/dist/tenant-orchestrator.js +263 -0
  82. package/dist/tenant-orchestrator.js.map +1 -0
  83. package/dist/types.d.ts +279 -0
  84. package/dist/types.d.ts.map +1 -0
  85. package/dist/types.js +65 -0
  86. package/dist/types.js.map +1 -0
  87. package/dist/upload-interceptor.d.ts +44 -0
  88. package/dist/upload-interceptor.d.ts.map +1 -0
  89. package/dist/upload-interceptor.js +114 -0
  90. package/dist/upload-interceptor.js.map +1 -0
  91. package/dist/utils.d.ts +11 -0
  92. package/dist/utils.d.ts.map +1 -0
  93. package/dist/utils.js +51 -0
  94. package/dist/utils.js.map +1 -0
  95. package/dist/worker.d.ts +3 -0
  96. package/dist/worker.d.ts.map +1 -0
  97. package/dist/worker.js +5 -0
  98. package/dist/worker.js.map +1 -0
  99. package/manifests/operator-prerequisites.yaml +22 -0
  100. package/package.json +47 -0
@@ -0,0 +1,82 @@
1
+ export function buildJobManifest(input) {
2
+ const podLabels = {
3
+ ...input.labels,
4
+ "paperclip.io/role": "agent",
5
+ };
6
+ return {
7
+ apiVersion: "batch/v1",
8
+ kind: "Job",
9
+ metadata: {
10
+ name: input.jobName,
11
+ namespace: input.namespace,
12
+ labels: { ...input.labels },
13
+ },
14
+ spec: {
15
+ backoffLimit: 0,
16
+ ttlSecondsAfterFinished: input.ttlSecondsAfterFinished,
17
+ activeDeadlineSeconds: input.activeDeadlineSec,
18
+ template: {
19
+ metadata: { labels: podLabels },
20
+ spec: {
21
+ serviceAccountName: input.serviceAccountName,
22
+ // Agent containers call back to paperclip-server via HTTPS egress;
23
+ // they never call the Kubernetes API, so mounting an SA token is
24
+ // unnecessary attack surface.
25
+ automountServiceAccountToken: false,
26
+ restartPolicy: "Never",
27
+ ...(input.runtimeClassName ? { runtimeClassName: input.runtimeClassName } : {}),
28
+ ...(input.imagePullSecrets && input.imagePullSecrets.length > 0
29
+ ? { imagePullSecrets: input.imagePullSecrets.map((name) => ({ name })) }
30
+ : {}),
31
+ securityContext: {
32
+ runAsNonRoot: true,
33
+ runAsUser: 1000,
34
+ runAsGroup: 1000,
35
+ fsGroup: 1000,
36
+ fsGroupChangePolicy: "OnRootMismatch",
37
+ seccompProfile: { type: "RuntimeDefault" },
38
+ },
39
+ containers: [
40
+ {
41
+ name: "agent",
42
+ image: input.image,
43
+ imagePullPolicy: "IfNotPresent",
44
+ command: ["/usr/bin/tini", "--", "/usr/local/bin/paperclip-agent-shim"],
45
+ // HOME must point at a writable mount; the image's default
46
+ // HOME is inside the readOnly root filesystem. Agent runtimes
47
+ // can silently exit with code 0 and no output when HOME is
48
+ // unwritable, so set this explicitly.
49
+ env: [{ name: "HOME", value: "/home/paperclip" }],
50
+ envFrom: [{ secretRef: { name: input.envSecretName } }],
51
+ securityContext: {
52
+ runAsNonRoot: true,
53
+ runAsUser: 1000,
54
+ runAsGroup: 1000,
55
+ readOnlyRootFilesystem: true,
56
+ allowPrivilegeEscalation: false,
57
+ capabilities: { drop: ["ALL"] },
58
+ },
59
+ resources: {
60
+ requests: input.resources.requests ?? { cpu: "250m", memory: "512Mi" },
61
+ limits: input.resources.limits ?? { cpu: "2", memory: "4Gi" },
62
+ },
63
+ volumeMounts: [
64
+ { name: "workspace", mountPath: "/workspace" },
65
+ { name: "home", mountPath: "/home/paperclip" },
66
+ { name: "cache", mountPath: "/home/paperclip/.cache" },
67
+ { name: "tmp", mountPath: "/tmp" },
68
+ ],
69
+ },
70
+ ],
71
+ volumes: [
72
+ { name: "workspace", emptyDir: { sizeLimit: "8Gi" } },
73
+ { name: "home", emptyDir: { sizeLimit: "1Gi" } },
74
+ { name: "cache", emptyDir: { sizeLimit: "1Gi" } },
75
+ { name: "tmp", emptyDir: { sizeLimit: "2Gi" } },
76
+ ],
77
+ },
78
+ },
79
+ },
80
+ };
81
+ }
82
+ //# sourceMappingURL=pod-spec-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pod-spec-builder.js","sourceRoot":"","sources":["../src/pod-spec-builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Builds a kubernetes-sigs/agent-sandbox Sandbox CR manifest.
3
+ *
4
+ * The Sandbox CR creates a long-lived pod (sleep infinity entrypoint) into
5
+ * which paperclip-server can exec arbitrary commands. This solves the
6
+ * architectural mismatch with the batch/v1 Job backend, which only supports
7
+ * a single one-shot entrypoint — not the multi-command adapter-install pattern
8
+ * used by paperclip-server.
9
+ *
10
+ * Security baseline is identical to buildJobManifest (pod-spec-builder.ts):
11
+ * non-root, drop ALL caps, read-only rootFS, Tini PID 1, seccomp
12
+ * RuntimeDefault, fsGroupChangePolicy OnRootMismatch, automountSAToken=false.
13
+ *
14
+ * NOTE: paperclip-server runs OUTSIDE the cluster, so we cannot set ownerReferences
15
+ * on the Sandbox CR (the owner would need to be an in-cluster resource). The
16
+ * release path is explicit delete via sandboxCrOrchestrator.release().
17
+ */
18
+ export interface BuildSandboxCrManifestInput {
19
+ namespace: string;
20
+ sandboxName: string;
21
+ adapterType: string;
22
+ image: string;
23
+ envSecretName: string;
24
+ serviceAccountName: string;
25
+ labels: Record<string, string>;
26
+ resources: {
27
+ requests?: {
28
+ cpu?: string;
29
+ memory?: string;
30
+ };
31
+ limits?: {
32
+ cpu?: string;
33
+ memory?: string;
34
+ };
35
+ };
36
+ runtimeClassName?: string;
37
+ imagePullSecrets?: string[];
38
+ }
39
+ export declare function buildSandboxCrManifest(input: BuildSandboxCrManifestInput): Record<string, unknown>;
40
+ //# sourceMappingURL=sandbox-cr-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-cr-builder.d.ts","sourceRoot":"","sources":["../src/sandbox-cr-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,SAAS,EAAE;QACT,QAAQ,CAAC,EAAE;YAAE,GAAG,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAC7C,MAAM,CAAC,EAAE;YAAE,GAAG,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC5C,CAAC;IACF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,2BAA2B,GACjC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAwGzB"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Builds a kubernetes-sigs/agent-sandbox Sandbox CR manifest.
3
+ *
4
+ * The Sandbox CR creates a long-lived pod (sleep infinity entrypoint) into
5
+ * which paperclip-server can exec arbitrary commands. This solves the
6
+ * architectural mismatch with the batch/v1 Job backend, which only supports
7
+ * a single one-shot entrypoint — not the multi-command adapter-install pattern
8
+ * used by paperclip-server.
9
+ *
10
+ * Security baseline is identical to buildJobManifest (pod-spec-builder.ts):
11
+ * non-root, drop ALL caps, read-only rootFS, Tini PID 1, seccomp
12
+ * RuntimeDefault, fsGroupChangePolicy OnRootMismatch, automountSAToken=false.
13
+ *
14
+ * NOTE: paperclip-server runs OUTSIDE the cluster, so we cannot set ownerReferences
15
+ * on the Sandbox CR (the owner would need to be an in-cluster resource). The
16
+ * release path is explicit delete via sandboxCrOrchestrator.release().
17
+ */
18
+ export function buildSandboxCrManifest(input) {
19
+ const podLabels = {
20
+ ...input.labels,
21
+ "paperclip.io/role": "agent",
22
+ };
23
+ return {
24
+ apiVersion: "agents.x-k8s.io/v1alpha1",
25
+ kind: "Sandbox",
26
+ metadata: {
27
+ name: input.sandboxName,
28
+ namespace: input.namespace,
29
+ labels: { ...input.labels },
30
+ // No ownerReferences: paperclip-server is out-of-cluster. Release is
31
+ // explicit delete.
32
+ },
33
+ spec: {
34
+ podTemplate: {
35
+ metadata: {
36
+ labels: podLabels,
37
+ },
38
+ spec: {
39
+ serviceAccountName: input.serviceAccountName,
40
+ // Agent containers call back to paperclip-server via HTTPS egress;
41
+ // they never call the Kubernetes API, so mounting an SA token is
42
+ // unnecessary attack surface.
43
+ automountServiceAccountToken: false,
44
+ // Sandbox controller requires restartPolicy: Always so the pod
45
+ // stays running between exec calls.
46
+ restartPolicy: "Always",
47
+ ...(input.runtimeClassName
48
+ ? { runtimeClassName: input.runtimeClassName }
49
+ : {}),
50
+ ...(input.imagePullSecrets && input.imagePullSecrets.length > 0
51
+ ? {
52
+ imagePullSecrets: input.imagePullSecrets.map((name) => ({
53
+ name,
54
+ })),
55
+ }
56
+ : {}),
57
+ securityContext: {
58
+ runAsNonRoot: true,
59
+ runAsUser: 1000,
60
+ runAsGroup: 1000,
61
+ fsGroup: 1000,
62
+ fsGroupChangePolicy: "OnRootMismatch",
63
+ seccompProfile: { type: "RuntimeDefault" },
64
+ },
65
+ containers: [
66
+ {
67
+ name: "agent",
68
+ image: input.image,
69
+ imagePullPolicy: "IfNotPresent",
70
+ // sleep infinity keeps the pod running; paperclip-server execs
71
+ // commands into it via Kubernetes exec API. Tini as PID 1 for
72
+ // proper signal forwarding and zombie reaping.
73
+ command: [
74
+ "/usr/bin/tini",
75
+ "--",
76
+ "/bin/sh",
77
+ "-c",
78
+ "sleep infinity",
79
+ ],
80
+ // HOME must point at a writable mount; the image's default
81
+ // HOME=/home/node is inside the readOnly root filesystem.
82
+ // Claude (and most agent runtimes) silently exit with code 0
83
+ // and no output when HOME is unwritable, so set this explicitly.
84
+ env: [{ name: "HOME", value: "/home/paperclip" }],
85
+ envFrom: [{ secretRef: { name: input.envSecretName } }],
86
+ securityContext: {
87
+ runAsNonRoot: true,
88
+ runAsUser: 1000,
89
+ runAsGroup: 1000,
90
+ readOnlyRootFilesystem: true,
91
+ allowPrivilegeEscalation: false,
92
+ capabilities: { drop: ["ALL"] },
93
+ },
94
+ resources: {
95
+ requests: input.resources.requests ?? {
96
+ cpu: "250m",
97
+ memory: "512Mi",
98
+ },
99
+ limits: input.resources.limits ?? {
100
+ cpu: "2",
101
+ memory: "4Gi",
102
+ },
103
+ },
104
+ volumeMounts: [
105
+ { name: "workspace", mountPath: "/workspace" },
106
+ { name: "home", mountPath: "/home/paperclip" },
107
+ { name: "cache", mountPath: "/home/paperclip/.cache" },
108
+ { name: "tmp", mountPath: "/tmp" },
109
+ ],
110
+ },
111
+ ],
112
+ volumes: [
113
+ { name: "workspace", emptyDir: { sizeLimit: "8Gi" } },
114
+ { name: "home", emptyDir: { sizeLimit: "1Gi" } },
115
+ { name: "cache", emptyDir: { sizeLimit: "1Gi" } },
116
+ { name: "tmp", emptyDir: { sizeLimit: "2Gi" } },
117
+ ],
118
+ },
119
+ },
120
+ },
121
+ };
122
+ }
123
+ //# sourceMappingURL=sandbox-cr-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-cr-builder.js","sourceRoot":"","sources":["../src/sandbox-cr-builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * SandboxOrchestrator implementation backed by the kubernetes-sigs/agent-sandbox
3
+ * Sandbox CRD (agents.x-k8s.io/v1alpha1).
4
+ *
5
+ * The Sandbox CR creates a long-lived pod that paperclip-server can exec into
6
+ * for multi-command adapter-install workflows — the key architectural win over
7
+ * the batch/v1 Job backend.
8
+ *
9
+ * Key semantic differences from jobOrchestrator:
10
+ * - claim() creates a Sandbox CR via CustomObjectsApi instead of a batch Job
11
+ * - getStatus() maps Sandbox phase (Pending|Ready|Terminating|Failed) to SandboxStatus
12
+ * - findPod() reads status.podName from the Sandbox CR (falls back to label query)
13
+ * - waitForCompletion() means "wait until pod is Ready to exec" NOT "wait until
14
+ * workload finishes". The Sandbox pod runs sleep infinity; execution completion
15
+ * is tracked by the individual execInPod() calls.
16
+ * - release() deletes the Sandbox CR with Foreground propagation (controller
17
+ * tears down the underlying pod).
18
+ *
19
+ * NOTE: streamLogs() is provided for interface conformance but is limited —
20
+ * the sleep-infinity pod has no meaningful stdout. Callers in execute mode
21
+ * should use execInPod() and capture its stdout/stderr directly.
22
+ */
23
+ import type { KubeClients } from "./kube-client.js";
24
+ import type { SandboxOrchestrator, SandboxStatus } from "./sandbox-orchestrator.js";
25
+ export declare class SandboxCrTimeoutError extends Error {
26
+ constructor(namespace: string, name: string, timeoutMs: number);
27
+ }
28
+ export declare function createSandboxCr(clients: KubeClients, namespace: string, manifest: Record<string, unknown>): Promise<{
29
+ uid: string;
30
+ }>;
31
+ export declare function getSandboxCrStatus(clients: KubeClients, namespace: string, name: string): Promise<SandboxStatus>;
32
+ /**
33
+ * Returns the pod name backing a Sandbox CR.
34
+ * Primary: read status.podName from the CR (set by the controller once ready).
35
+ * Fallback: list pods in the namespace filtered by the paperclip.io/managed-by
36
+ * label and the sandbox name label set on the pod template.
37
+ */
38
+ export declare function findPodForSandbox(clients: KubeClients, namespace: string, name: string): Promise<string | null>;
39
+ export declare function streamSandboxLogs(clients: KubeClients, namespace: string, podName: string, onChunk: (stream: "stdout" | "stderr", text: string) => Promise<void>): Promise<void>;
40
+ export declare function deleteSandboxCr(clients: KubeClients, namespace: string, name: string): Promise<void>;
41
+ /**
42
+ * Wait until the Sandbox CR's pod reaches Ready phase (i.e., the pod is up and
43
+ * exec-able). This is NOT waiting for a workload to finish — the Sandbox pod
44
+ * runs sleep infinity indefinitely. Execution completion is tracked by the
45
+ * individual execInPod() calls.
46
+ *
47
+ * Throws SandboxCrTimeoutError if Ready is not reached within timeoutMs.
48
+ * Throws if the Sandbox transitions to Failed.
49
+ */
50
+ export declare function waitForSandboxReady(clients: KubeClients, namespace: string, name: string, opts?: {
51
+ timeoutMs: number;
52
+ pollMs?: number;
53
+ }): Promise<SandboxStatus>;
54
+ /**
55
+ * Sandbox CR-backed conformance to SandboxOrchestrator.
56
+ *
57
+ * waitForCompletion semantics change: for this backend, "completion" means
58
+ * "pod is up and Ready to exec into" — NOT "workload finished". The actual
59
+ * command execution and its completion is handled by execInPod().
60
+ */
61
+ export declare const sandboxCrOrchestrator: SandboxOrchestrator;
62
+ //# sourceMappingURL=sandbox-cr-orchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-cr-orchestrator.d.ts","sourceRoot":"","sources":["../src/sandbox-cr-orchestrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAMpF,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAM/D;AA2DD,wBAAsB,eAAe,CACnC,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAW1B;AAED,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,aAAa,CAAC,CASxB;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiExB;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GACpE,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAGzC,GACA,OAAO,CAAC,aAAa,CAAC,CA6CxB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,EAAE,mBAOnC,CAAC"}
@@ -0,0 +1,248 @@
1
+ /**
2
+ * SandboxOrchestrator implementation backed by the kubernetes-sigs/agent-sandbox
3
+ * Sandbox CRD (agents.x-k8s.io/v1alpha1).
4
+ *
5
+ * The Sandbox CR creates a long-lived pod that paperclip-server can exec into
6
+ * for multi-command adapter-install workflows — the key architectural win over
7
+ * the batch/v1 Job backend.
8
+ *
9
+ * Key semantic differences from jobOrchestrator:
10
+ * - claim() creates a Sandbox CR via CustomObjectsApi instead of a batch Job
11
+ * - getStatus() maps Sandbox phase (Pending|Ready|Terminating|Failed) to SandboxStatus
12
+ * - findPod() reads status.podName from the Sandbox CR (falls back to label query)
13
+ * - waitForCompletion() means "wait until pod is Ready to exec" NOT "wait until
14
+ * workload finishes". The Sandbox pod runs sleep infinity; execution completion
15
+ * is tracked by the individual execInPod() calls.
16
+ * - release() deletes the Sandbox CR with Foreground propagation (controller
17
+ * tears down the underlying pod).
18
+ *
19
+ * NOTE: streamLogs() is provided for interface conformance but is limited —
20
+ * the sleep-infinity pod has no meaningful stdout. Callers in execute mode
21
+ * should use execInPod() and capture its stdout/stderr directly.
22
+ */
23
+ const SANDBOX_GROUP = "agents.x-k8s.io";
24
+ const SANDBOX_VERSION = "v1alpha1";
25
+ const SANDBOX_PLURAL = "sandboxes";
26
+ export class SandboxCrTimeoutError extends Error {
27
+ constructor(namespace, name, timeoutMs) {
28
+ super(`Sandbox ${namespace}/${name} did not reach Ready phase within ${timeoutMs}ms`);
29
+ this.name = "SandboxCrTimeoutError";
30
+ }
31
+ }
32
+ function sleep(ms) {
33
+ return new Promise((resolve) => setTimeout(resolve, ms));
34
+ }
35
+ /**
36
+ * Map a Sandbox CR status.phase value to our SandboxStatus shape.
37
+ * Sandbox phases: Pending | Ready | Terminating | Failed
38
+ */
39
+ function mapSandboxPhase(cr) {
40
+ const status = cr.status ?? {};
41
+ const phase = status.phase ?? "Pending";
42
+ switch (phase) {
43
+ case "Ready":
44
+ return {
45
+ phase: "Running", // SandboxStatus.phase uses Job semantics; "Running" = active pod
46
+ complete: false,
47
+ active: 1,
48
+ succeeded: 0,
49
+ failed: 0,
50
+ };
51
+ case "Terminating":
52
+ return {
53
+ phase: "Running",
54
+ complete: false,
55
+ active: 0,
56
+ succeeded: 0,
57
+ failed: 0,
58
+ reason: "Terminating",
59
+ };
60
+ case "Failed": {
61
+ const conditions = status.conditions ?? [];
62
+ const failedCond = conditions.find((c) => c.type === "Failed");
63
+ return {
64
+ phase: "Failed",
65
+ complete: false,
66
+ active: 0,
67
+ succeeded: 0,
68
+ failed: 1,
69
+ reason: failedCond?.reason,
70
+ message: failedCond?.message,
71
+ };
72
+ }
73
+ default:
74
+ // "Pending" or unknown
75
+ return {
76
+ phase: "Pending",
77
+ complete: false,
78
+ active: 0,
79
+ succeeded: 0,
80
+ failed: 0,
81
+ };
82
+ }
83
+ }
84
+ export async function createSandboxCr(clients, namespace, manifest) {
85
+ const result = await clients.custom.createNamespacedCustomObject({
86
+ group: SANDBOX_GROUP,
87
+ version: SANDBOX_VERSION,
88
+ namespace,
89
+ plural: SANDBOX_PLURAL,
90
+ body: manifest,
91
+ });
92
+ const uid = result.metadata?.uid;
93
+ if (!uid)
94
+ throw new Error("Sandbox CR created without a UID");
95
+ return { uid };
96
+ }
97
+ export async function getSandboxCrStatus(clients, namespace, name) {
98
+ const result = await clients.custom.getNamespacedCustomObject({
99
+ group: SANDBOX_GROUP,
100
+ version: SANDBOX_VERSION,
101
+ namespace,
102
+ plural: SANDBOX_PLURAL,
103
+ name,
104
+ });
105
+ return mapSandboxPhase(result);
106
+ }
107
+ /**
108
+ * Returns the pod name backing a Sandbox CR.
109
+ * Primary: read status.podName from the CR (set by the controller once ready).
110
+ * Fallback: list pods in the namespace filtered by the paperclip.io/managed-by
111
+ * label and the sandbox name label set on the pod template.
112
+ */
113
+ export async function findPodForSandbox(clients, namespace, name) {
114
+ // Primary: read status.podName from the Sandbox CR
115
+ const cr = await clients.custom.getNamespacedCustomObject({
116
+ group: SANDBOX_GROUP,
117
+ version: SANDBOX_VERSION,
118
+ namespace,
119
+ plural: SANDBOX_PLURAL,
120
+ name,
121
+ });
122
+ const status = cr.status ?? {};
123
+ const podName = status.podName;
124
+ if (podName && podName.trim().length > 0) {
125
+ return podName;
126
+ }
127
+ // Secondary: the agent-sandbox controller (v0.4.x) names the backing pod
128
+ // EXACTLY after the Sandbox CR and labels it only with
129
+ // agents.x-k8s.io/sandbox-name-hash (a hash, not the full name), so the
130
+ // full-name label selector below matches nothing on that controller. An
131
+ // exact-name GET is collision-free (unlike name-prefix matching, which
132
+ // could hit a concurrent sandbox sharing a prefix) and resolves the pod on
133
+ // every controller version that keeps pod name == sandbox name.
134
+ try {
135
+ const pod = (await clients.core.readNamespacedPod({ namespace, name }));
136
+ if (pod?.metadata?.name) {
137
+ return pod.metadata.name;
138
+ }
139
+ }
140
+ catch (err) {
141
+ const code = err.code ??
142
+ err.statusCode;
143
+ if (code !== 404)
144
+ throw err;
145
+ }
146
+ // Fallback: list pods by a full-name sandbox label, for controller versions
147
+ // that label pods with the sandbox name. A broader managed-by selector plus
148
+ // name-prefix narrowing could match a concurrent sandbox whose generated
149
+ // name shares a prefix, and exec would target the wrong lease's pod.
150
+ const result = await clients.core.listNamespacedPod({
151
+ namespace,
152
+ labelSelector: `agents.x-k8s.io/sandbox-name=${name}`,
153
+ });
154
+ const items = (result.items) ?? [];
155
+ // The label selector already scopes to exactly this sandbox's pod(s); keep a
156
+ // defensive re-check on the label value only (no name-prefix matching).
157
+ const matching = items.filter((p) => (p.metadata?.labels ?? {})["agents.x-k8s.io/sandbox-name"] === name);
158
+ const running = matching.find((p) => p.status?.phase === "Running");
159
+ return (running ?? matching[0])?.metadata?.name ?? null;
160
+ }
161
+ export async function streamSandboxLogs(clients, namespace, podName, onChunk) {
162
+ // V1 limitation: readNamespacedPodLog returns combined stdout. The
163
+ // sleep-infinity pod will have minimal output; this is provided for interface
164
+ // conformance. For actual command output, use execInPod() directly.
165
+ const result = await clients.core.readNamespacedPodLog({
166
+ namespace,
167
+ name: podName,
168
+ });
169
+ const text = result ?? "";
170
+ if (text.length > 0)
171
+ await onChunk("stdout", text);
172
+ }
173
+ export async function deleteSandboxCr(clients, namespace, name) {
174
+ await clients.custom.deleteNamespacedCustomObject({
175
+ group: SANDBOX_GROUP,
176
+ version: SANDBOX_VERSION,
177
+ namespace,
178
+ plural: SANDBOX_PLURAL,
179
+ name,
180
+ propagationPolicy: "Foreground",
181
+ });
182
+ }
183
+ /**
184
+ * Wait until the Sandbox CR's pod reaches Ready phase (i.e., the pod is up and
185
+ * exec-able). This is NOT waiting for a workload to finish — the Sandbox pod
186
+ * runs sleep infinity indefinitely. Execution completion is tracked by the
187
+ * individual execInPod() calls.
188
+ *
189
+ * Throws SandboxCrTimeoutError if Ready is not reached within timeoutMs.
190
+ * Throws if the Sandbox transitions to Failed.
191
+ */
192
+ export async function waitForSandboxReady(clients, namespace, name, opts = {
193
+ timeoutMs: 120_000,
194
+ pollMs: 2000,
195
+ }) {
196
+ const deadline = Date.now() + opts.timeoutMs;
197
+ const pollMs = opts.pollMs ?? 2000;
198
+ while (Date.now() < deadline) {
199
+ const cr = await clients.custom.getNamespacedCustomObject({
200
+ group: SANDBOX_GROUP,
201
+ version: SANDBOX_VERSION,
202
+ namespace,
203
+ plural: SANDBOX_PLURAL,
204
+ name,
205
+ });
206
+ const status = cr.status ?? {};
207
+ // agent-sandbox v1alpha1 uses status.conditions[type=Ready,status=True],
208
+ // not status.phase. Fall back to phase for forward-compat.
209
+ const conditions = Array.isArray(status.conditions) ? status.conditions : [];
210
+ const readyCondition = conditions.find((c) => c.type === "Ready");
211
+ const failedCondition = conditions.find((c) => c.type === "Failed" || (c.type === "Ready" && c.status === "False" && typeof c.reason === "string" && /failed/i.test(c.reason)));
212
+ const phase = status.phase ?? "";
213
+ if (readyCondition?.status === "True" || phase === "Ready") {
214
+ return mapSandboxPhase(cr);
215
+ }
216
+ if (failedCondition?.status === "True" || phase === "Failed") {
217
+ const mapped = mapSandboxPhase(cr);
218
+ throw new Error(`Sandbox ${namespace}/${name} failed: ${mapped.reason ?? failedCondition?.reason ?? "unknown reason"} — ${mapped.message ?? failedCondition?.message ?? ""}`);
219
+ }
220
+ if (phase === "Terminating") {
221
+ // A Sandbox being torn down will never transition to Ready. Polling
222
+ // until the deadline would burn the full timeoutMs (potentially
223
+ // 30+ minutes) before throwing a generic timeout. Fail fast instead
224
+ // so the caller can surface a clear "the lease is being released"
225
+ // error and decide whether to retry against a fresh Sandbox.
226
+ throw new Error(`Sandbox ${namespace}/${name} is Terminating — cannot wait for Ready`);
227
+ }
228
+ // Pending — keep polling
229
+ await sleep(pollMs);
230
+ }
231
+ throw new SandboxCrTimeoutError(namespace, name, opts.timeoutMs);
232
+ }
233
+ /**
234
+ * Sandbox CR-backed conformance to SandboxOrchestrator.
235
+ *
236
+ * waitForCompletion semantics change: for this backend, "completion" means
237
+ * "pod is up and Ready to exec into" — NOT "workload finished". The actual
238
+ * command execution and its completion is handled by execInPod().
239
+ */
240
+ export const sandboxCrOrchestrator = {
241
+ claim: createSandboxCr,
242
+ getStatus: getSandboxCrStatus,
243
+ findPod: findPodForSandbox,
244
+ streamLogs: streamSandboxLogs,
245
+ release: deleteSandboxCr,
246
+ waitForCompletion: waitForSandboxReady,
247
+ };
248
+ //# sourceMappingURL=sandbox-cr-orchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-cr-orchestrator.js","sourceRoot":"","sources":["../src/sandbox-cr-orchestrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import type { KubeClients } from "./kube-client.js";
2
+ export interface SandboxStatus {
3
+ phase: "Pending" | "Running" | "Succeeded" | "Failed";
4
+ complete: boolean;
5
+ active: number;
6
+ succeeded: number;
7
+ failed: number;
8
+ reason?: string;
9
+ message?: string;
10
+ }
11
+ /**
12
+ * Abstract interface over a sandbox runtime backend. The current implementation
13
+ * is Job-backed (job-orchestrator.ts). Future backends slot in by exporting an
14
+ * object conforming to this shape — e.g. a Kata-FC warm-pool backend that
15
+ * additionally implements the optional pause/resume slots, or a CRD-backed
16
+ * backend on kubernetes-sigs/agent-sandbox once it reaches Beta.
17
+ */
18
+ export interface SandboxOrchestrator {
19
+ /** Provision the sandbox. Returns the runtime's stable UID. */
20
+ claim(clients: KubeClients, namespace: string, manifest: Record<string, unknown>): Promise<{
21
+ uid: string;
22
+ }>;
23
+ /** Read current lifecycle phase. */
24
+ getStatus(clients: KubeClients, namespace: string, name: string): Promise<SandboxStatus>;
25
+ /** Locate the pod backing this sandbox (or null if none exists yet). */
26
+ findPod(clients: KubeClients, namespace: string, name: string): Promise<string | null>;
27
+ /** Read logs from the sandbox's pod. V1: post-completion read. */
28
+ streamLogs(clients: KubeClients, namespace: string, podName: string, onChunk: (stream: "stdout" | "stderr", text: string) => Promise<void>): Promise<void>;
29
+ /** Tear down the sandbox. Implementations MUST cascade-delete child resources. */
30
+ release(clients: KubeClients, namespace: string, name: string): Promise<void>;
31
+ /** Block until phase is Succeeded or Failed, or throw on timeout. */
32
+ waitForCompletion(clients: KubeClients, namespace: string, name: string, opts: {
33
+ timeoutMs: number;
34
+ pollMs?: number;
35
+ }): Promise<SandboxStatus>;
36
+ pause?(clients: KubeClients, namespace: string, name: string): Promise<void>;
37
+ resume?(clients: KubeClients, namespace: string, name: string): Promise<void>;
38
+ }
39
+ //# sourceMappingURL=sandbox-orchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-orchestrator.d.ts","sourceRoot":"","sources":["../src/sandbox-orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;IACtD,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,+DAA+D;IAC/D,KAAK,CACH,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAE5B,oCAAoC;IACpC,SAAS,CACP,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,aAAa,CAAC,CAAC;IAE1B,wEAAwE;IACxE,OAAO,CACL,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAE1B,kEAAkE;IAClE,UAAU,CACR,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GACpE,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB,kFAAkF;IAClF,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9E,qEAAqE;IACrE,iBAAiB,CACf,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAC3C,OAAO,CAAC,aAAa,CAAC,CAAC;IAO1B,KAAK,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E,MAAM,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/E"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sandbox-orchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-orchestrator.js","sourceRoot":"","sources":["../src/sandbox-orchestrator.ts"],"names":[],"mappings":""}