@paperclipai/plugin-kubernetes 0.1.0 → 2026.620.0-canary.10

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 (90) hide show
  1. package/LICENSE +21 -0
  2. package/dist/adapter-defaults.d.ts +29 -0
  3. package/dist/adapter-defaults.d.ts.map +1 -0
  4. package/dist/adapter-defaults.js +104 -0
  5. package/dist/adapter-defaults.js.map +1 -0
  6. package/dist/adapter-registry.d.ts +64 -0
  7. package/dist/adapter-registry.d.ts.map +1 -0
  8. package/dist/adapter-registry.js +25 -0
  9. package/dist/adapter-registry.js.map +1 -0
  10. package/dist/cilium-network-policy.d.ts +8 -0
  11. package/dist/cilium-network-policy.d.ts.map +1 -0
  12. package/dist/cilium-network-policy.js +57 -0
  13. package/dist/cilium-network-policy.js.map +1 -0
  14. package/dist/image-allowlist.d.ts +18 -0
  15. package/dist/image-allowlist.d.ts.map +1 -0
  16. package/dist/image-allowlist.js +39 -0
  17. package/dist/image-allowlist.js.map +1 -0
  18. package/dist/index.d.ts +3 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +3 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/job-orchestrator.d.ts +24 -0
  23. package/dist/job-orchestrator.d.ts.map +1 -0
  24. package/dist/job-orchestrator.js +90 -0
  25. package/dist/job-orchestrator.js.map +1 -0
  26. package/dist/kube-client.d.ts +15 -0
  27. package/dist/kube-client.d.ts.map +1 -0
  28. package/dist/kube-client.js +23 -0
  29. package/dist/kube-client.js.map +1 -0
  30. package/dist/lease-lifecycle.d.ts +62 -0
  31. package/dist/lease-lifecycle.d.ts.map +1 -0
  32. package/dist/lease-lifecycle.js +155 -0
  33. package/dist/lease-lifecycle.js.map +1 -0
  34. package/dist/manifest.d.ts +4 -0
  35. package/dist/manifest.d.ts.map +1 -0
  36. package/dist/manifest.js +108 -0
  37. package/dist/manifest.js.map +1 -0
  38. package/dist/network-policy.d.ts +18 -0
  39. package/dist/network-policy.d.ts.map +1 -0
  40. package/dist/network-policy.js +113 -0
  41. package/dist/network-policy.js.map +1 -0
  42. package/dist/plugin.d.ts +3 -0
  43. package/dist/plugin.d.ts.map +1 -0
  44. package/dist/plugin.js +687 -0
  45. package/dist/plugin.js.map +1 -0
  46. package/dist/pod-exec.d.ts +28 -0
  47. package/dist/pod-exec.d.ts.map +1 -0
  48. package/dist/pod-exec.js +164 -0
  49. package/dist/pod-exec.js.map +1 -0
  50. package/dist/pod-spec-builder.d.ts +25 -0
  51. package/dist/pod-spec-builder.d.ts.map +1 -0
  52. package/dist/pod-spec-builder.js +82 -0
  53. package/dist/pod-spec-builder.js.map +1 -0
  54. package/dist/sandbox-cr-builder.d.ts +40 -0
  55. package/dist/sandbox-cr-builder.d.ts.map +1 -0
  56. package/dist/sandbox-cr-builder.js +123 -0
  57. package/dist/sandbox-cr-builder.js.map +1 -0
  58. package/dist/sandbox-cr-orchestrator.d.ts +62 -0
  59. package/dist/sandbox-cr-orchestrator.d.ts.map +1 -0
  60. package/dist/sandbox-cr-orchestrator.js +248 -0
  61. package/dist/sandbox-cr-orchestrator.js.map +1 -0
  62. package/dist/sandbox-orchestrator.d.ts +39 -0
  63. package/dist/sandbox-orchestrator.d.ts.map +1 -0
  64. package/dist/sandbox-orchestrator.js +2 -0
  65. package/dist/sandbox-orchestrator.js.map +1 -0
  66. package/dist/secret-manager.d.ts +14 -0
  67. package/dist/secret-manager.d.ts.map +1 -0
  68. package/dist/secret-manager.js +39 -0
  69. package/dist/secret-manager.js.map +1 -0
  70. package/dist/tenant-orchestrator.d.ts +35 -0
  71. package/dist/tenant-orchestrator.d.ts.map +1 -0
  72. package/dist/tenant-orchestrator.js +263 -0
  73. package/dist/tenant-orchestrator.js.map +1 -0
  74. package/dist/types.d.ts +264 -0
  75. package/dist/types.d.ts.map +1 -0
  76. package/dist/types.js +65 -0
  77. package/dist/types.js.map +1 -0
  78. package/dist/upload-interceptor.d.ts +44 -0
  79. package/dist/upload-interceptor.d.ts.map +1 -0
  80. package/dist/upload-interceptor.js +114 -0
  81. package/dist/upload-interceptor.js.map +1 -0
  82. package/dist/utils.d.ts +11 -0
  83. package/dist/utils.d.ts.map +1 -0
  84. package/dist/utils.js +51 -0
  85. package/dist/utils.js.map +1 -0
  86. package/dist/worker.d.ts +3 -0
  87. package/dist/worker.d.ts.map +1 -0
  88. package/dist/worker.js +5 -0
  89. package/dist/worker.js.map +1 -0
  90. package/package.json +4 -12
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Paperclip AI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,29 @@
1
+ import type { AdapterRegistryEntry } from "./adapter-registry.js";
2
+ export interface AdapterDefaults {
3
+ runtimeImage: string;
4
+ envKeys: string[];
5
+ allowFqdns: string[];
6
+ probeCommand: string[];
7
+ /** Non-secret env injected as the base layer for the Job (process-env wins on top). */
8
+ defaultEnv?: Record<string, string>;
9
+ }
10
+ export declare const KNOWN_ADAPTER_TYPES: ReadonlySet<string>;
11
+ /**
12
+ * Resolve the runtime defaults for an adapter. When a `registry` is supplied it
13
+ * is authoritative (replace semantics): the type MUST be present and complete,
14
+ * else this throws. With no registry, falls back to the built-in REGISTRY.
15
+ */
16
+ export declare function getAdapterDefaults(adapterType: string, registry?: readonly AdapterRegistryEntry[]): AdapterDefaults;
17
+ /**
18
+ * Resolve the adapter type for a single run: prefer the run's adapter (the agent's,
19
+ * from the lease params) so one environment can serve mixed harnesses; fall back to
20
+ * the environment's configured default adapter when the run does not specify one.
21
+ */
22
+ export declare function resolveRunAdapterType(runAdapterType: string | null | undefined, configAdapterType: string): string;
23
+ /**
24
+ * Build the per-run env for the Job: the non-secret `defaultEnv` is the base
25
+ * and the process-env values (the secret API keys named by `envKeys`) override
26
+ * it. Pure for testability.
27
+ */
28
+ export declare function buildAdapterEnv(defaults: AdapterDefaults, processEnv?: NodeJS.ProcessEnv): Record<string, string>;
29
+ //# sourceMappingURL=adapter-defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-defaults.d.ts","sourceRoot":"","sources":["../src/adapter-defaults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAElE,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,uFAAuF;IACvF,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AA+CD,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAAkC,CAAC;AAqBvF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,SAAS,oBAAoB,EAAE,GACzC,eAAe,CAajB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,cAAc,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACzC,iBAAiB,EAAE,MAAM,GACxB,MAAM,CAGR;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,eAAe,EACzB,UAAU,GAAE,MAAM,CAAC,UAAwB,GAC1C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOxB"}
@@ -0,0 +1,104 @@
1
+ const REGISTRY = {
2
+ claude_local: {
3
+ runtimeImage: "ghcr.io/paperclipai/agent-runtime-claude:v1",
4
+ envKeys: ["ANTHROPIC_API_KEY"],
5
+ allowFqdns: ["api.anthropic.com"],
6
+ probeCommand: ["claude", "--version"],
7
+ },
8
+ codex_local: {
9
+ runtimeImage: "ghcr.io/paperclipai/agent-runtime-codex:v1",
10
+ envKeys: ["OPENAI_API_KEY"],
11
+ allowFqdns: ["api.openai.com"],
12
+ probeCommand: ["codex", "--version"],
13
+ },
14
+ gemini_local: {
15
+ runtimeImage: "ghcr.io/paperclipai/agent-runtime-gemini:v1",
16
+ envKeys: ["GOOGLE_API_KEY", "GEMINI_API_KEY"],
17
+ allowFqdns: ["generativelanguage.googleapis.com"],
18
+ probeCommand: ["gemini", "--version"],
19
+ },
20
+ cursor_local: {
21
+ runtimeImage: "ghcr.io/paperclipai/agent-runtime-cursor:v1",
22
+ envKeys: ["ANTHROPIC_API_KEY", "OPENAI_API_KEY"],
23
+ allowFqdns: ["api.anthropic.com", "api.openai.com"],
24
+ probeCommand: ["cursor-agent", "--version"],
25
+ },
26
+ opencode_local: {
27
+ runtimeImage: "ghcr.io/paperclipai/agent-runtime-opencode:v1",
28
+ envKeys: ["ANTHROPIC_API_KEY", "OPENAI_API_KEY", "OPENROUTER_API_KEY"],
29
+ allowFqdns: ["api.anthropic.com", "api.openai.com", "openrouter.ai"],
30
+ probeCommand: ["opencode", "--version"],
31
+ },
32
+ acpx_local: {
33
+ runtimeImage: "ghcr.io/paperclipai/agent-runtime-acpx:v1",
34
+ envKeys: ["ANTHROPIC_API_KEY", "OPENAI_API_KEY"],
35
+ allowFqdns: ["api.anthropic.com", "api.openai.com"],
36
+ probeCommand: ["acpx", "--version"],
37
+ },
38
+ pi_local: {
39
+ runtimeImage: "ghcr.io/paperclipai/agent-runtime-pi:v1",
40
+ envKeys: ["ANTHROPIC_API_KEY"],
41
+ allowFqdns: ["api.anthropic.com"],
42
+ probeCommand: ["pi", "--version"],
43
+ },
44
+ };
45
+ export const KNOWN_ADAPTER_TYPES = new Set(Object.keys(REGISTRY));
46
+ function fromRegistryEntry(entry) {
47
+ // Only runtimeImage is strictly required. The array fields are optional and
48
+ // default to []: the operator emits them with `omitempty`, so a genuinely
49
+ // empty allowFqdns/envKeys/probeCommand arrives as undefined, which is valid
50
+ // (no extra egress / no forwarded secrets / no probe), NOT an error.
51
+ if (!entry.runtimeImage) {
52
+ throw new Error(`Adapter "${entry.adapterType}" is missing required runtime field: runtimeImage`);
53
+ }
54
+ return {
55
+ runtimeImage: entry.runtimeImage,
56
+ envKeys: entry.envKeys ?? [],
57
+ allowFqdns: entry.allowFqdns ?? [],
58
+ probeCommand: entry.probeCommand ?? [],
59
+ defaultEnv: entry.defaultEnv,
60
+ };
61
+ }
62
+ /**
63
+ * Resolve the runtime defaults for an adapter. When a `registry` is supplied it
64
+ * is authoritative (replace semantics): the type MUST be present and complete,
65
+ * else this throws. With no registry, falls back to the built-in REGISTRY.
66
+ */
67
+ export function getAdapterDefaults(adapterType, registry) {
68
+ if (registry && registry.length > 0) {
69
+ const entry = registry.find((e) => e.adapterType === adapterType);
70
+ if (!entry) {
71
+ throw new Error(`Adapter "${adapterType}" is not in the configured adapter registry`);
72
+ }
73
+ return fromRegistryEntry(entry);
74
+ }
75
+ const defaults = REGISTRY[adapterType];
76
+ if (!defaults) {
77
+ throw new Error(`Unknown adapter type: ${adapterType}`);
78
+ }
79
+ return defaults;
80
+ }
81
+ /**
82
+ * Resolve the adapter type for a single run: prefer the run's adapter (the agent's,
83
+ * from the lease params) so one environment can serve mixed harnesses; fall back to
84
+ * the environment's configured default adapter when the run does not specify one.
85
+ */
86
+ export function resolveRunAdapterType(runAdapterType, configAdapterType) {
87
+ const trimmed = typeof runAdapterType === "string" ? runAdapterType.trim() : "";
88
+ return trimmed.length > 0 ? trimmed : configAdapterType;
89
+ }
90
+ /**
91
+ * Build the per-run env for the Job: the non-secret `defaultEnv` is the base
92
+ * and the process-env values (the secret API keys named by `envKeys`) override
93
+ * it. Pure for testability.
94
+ */
95
+ export function buildAdapterEnv(defaults, processEnv = process.env) {
96
+ const out = { ...(defaults.defaultEnv ?? {}) };
97
+ for (const k of defaults.envKeys) {
98
+ const v = processEnv[k];
99
+ if (v)
100
+ out[k] = v;
101
+ }
102
+ return out;
103
+ }
104
+ //# sourceMappingURL=adapter-defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-defaults.js","sourceRoot":"","sources":["../src/adapter-defaults.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * One declarative agent-harness ("adapter") entry. Governs picker availability
4
+ * and, for sandboxed (Kubernetes) runs, the runtime wiring.
5
+ *
6
+ * NOTE: this shape is intentionally duplicated across the package boundary. It
7
+ * MUST stay structurally in sync with:
8
+ * - server `@paperclipai/shared` `adapterRegistryEntrySchema` (the parser side)
9
+ * - operator `AdapterRegistryEntry` Go struct (PAPERCLIP_ADAPTERS emitter)
10
+ * The duplication is deliberate: this plugin is standalone-installable and must
11
+ * not pull in heavy workspace packages at runtime.
12
+ */
13
+ export declare const adapterRegistryEntrySchema: z.ZodObject<{
14
+ adapterType: z.ZodString;
15
+ enabled: z.ZodDefault<z.ZodBoolean>;
16
+ runtimeImage: z.ZodOptional<z.ZodString>;
17
+ envKeys: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
18
+ allowFqdns: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
19
+ probeCommand: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
20
+ defaultEnv: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
21
+ }, "strict", z.ZodTypeAny, {
22
+ adapterType: string;
23
+ enabled: boolean;
24
+ runtimeImage?: string | undefined;
25
+ envKeys?: string[] | undefined;
26
+ allowFqdns?: string[] | undefined;
27
+ probeCommand?: string[] | undefined;
28
+ defaultEnv?: Record<string, string> | undefined;
29
+ }, {
30
+ adapterType: string;
31
+ enabled?: boolean | undefined;
32
+ runtimeImage?: string | undefined;
33
+ envKeys?: string[] | undefined;
34
+ allowFqdns?: string[] | undefined;
35
+ probeCommand?: string[] | undefined;
36
+ defaultEnv?: Record<string, string> | undefined;
37
+ }>;
38
+ export declare const adapterRegistrySchema: z.ZodArray<z.ZodObject<{
39
+ adapterType: z.ZodString;
40
+ enabled: z.ZodDefault<z.ZodBoolean>;
41
+ runtimeImage: z.ZodOptional<z.ZodString>;
42
+ envKeys: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
43
+ allowFqdns: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
44
+ probeCommand: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
45
+ defaultEnv: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
46
+ }, "strict", z.ZodTypeAny, {
47
+ adapterType: string;
48
+ enabled: boolean;
49
+ runtimeImage?: string | undefined;
50
+ envKeys?: string[] | undefined;
51
+ allowFqdns?: string[] | undefined;
52
+ probeCommand?: string[] | undefined;
53
+ defaultEnv?: Record<string, string> | undefined;
54
+ }, {
55
+ adapterType: string;
56
+ enabled?: boolean | undefined;
57
+ runtimeImage?: string | undefined;
58
+ envKeys?: string[] | undefined;
59
+ allowFqdns?: string[] | undefined;
60
+ probeCommand?: string[] | undefined;
61
+ defaultEnv?: Record<string, string> | undefined;
62
+ }>, "many">;
63
+ export type AdapterRegistryEntry = z.infer<typeof adapterRegistryEntrySchema>;
64
+ //# sourceMappingURL=adapter-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-registry.d.ts","sourceRoot":"","sources":["../src/adapter-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;GAUG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;EAU5B,CAAC;AAEZ,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;WAAsC,CAAC;AAEzE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * One declarative agent-harness ("adapter") entry. Governs picker availability
4
+ * and, for sandboxed (Kubernetes) runs, the runtime wiring.
5
+ *
6
+ * NOTE: this shape is intentionally duplicated across the package boundary. It
7
+ * MUST stay structurally in sync with:
8
+ * - server `@paperclipai/shared` `adapterRegistryEntrySchema` (the parser side)
9
+ * - operator `AdapterRegistryEntry` Go struct (PAPERCLIP_ADAPTERS emitter)
10
+ * The duplication is deliberate: this plugin is standalone-installable and must
11
+ * not pull in heavy workspace packages at runtime.
12
+ */
13
+ export const adapterRegistryEntrySchema = z
14
+ .object({
15
+ adapterType: z.string().min(1),
16
+ enabled: z.boolean().default(true),
17
+ runtimeImage: z.string().optional(),
18
+ envKeys: z.array(z.string()).optional(),
19
+ allowFqdns: z.array(z.string()).optional(),
20
+ probeCommand: z.array(z.string()).optional(),
21
+ defaultEnv: z.record(z.string()).optional(),
22
+ })
23
+ .strict();
24
+ export const adapterRegistrySchema = z.array(adapterRegistryEntrySchema);
25
+ //# sourceMappingURL=adapter-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-registry.js","sourceRoot":"","sources":["../src/adapter-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC;KACxC,MAAM,CAAC;IACN,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAClC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACnC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACvC,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IAC1C,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IAC5C,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CAC5C,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ export interface BuildCiliumNetworkPolicyInput {
2
+ namespace: string;
3
+ paperclipServerNamespace: string;
4
+ egressAllowFqdns: string[];
5
+ egressAllowCidrs: string[];
6
+ }
7
+ export declare function buildCiliumNetworkPolicyManifest(input: BuildCiliumNetworkPolicyInput): Record<string, unknown>;
8
+ //# sourceMappingURL=cilium-network-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cilium-network-policy.d.ts","sourceRoot":"","sources":["../src/cilium-network-policy.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,6BAA6B;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,wBAAwB,EAAE,MAAM,CAAC;IACjC,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAMD,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,6BAA6B,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAwD9G"}
@@ -0,0 +1,57 @@
1
+ // Design note: no ingress rules are defined here. Paperclip-server does NOT
2
+ // push to agent pods — agents make outbound (egress) callbacks to
3
+ // paperclip-server on port 3100. If server→agent push is ever needed, add a
4
+ // targeted ingress rule scoped to the paperclip-server endpoint selector.
5
+ export function buildCiliumNetworkPolicyManifest(input) {
6
+ const egress = [];
7
+ egress.push({
8
+ toEndpoints: [
9
+ { matchLabels: { "k8s:io.kubernetes.pod.namespace": "kube-system", "k8s-app": "kube-dns" } },
10
+ ],
11
+ toPorts: [
12
+ {
13
+ ports: [
14
+ { port: "53", protocol: "UDP" },
15
+ { port: "53", protocol: "TCP" },
16
+ ],
17
+ rules: { dns: [{ matchPattern: "*" }] },
18
+ },
19
+ ],
20
+ });
21
+ if (input.egressAllowFqdns.length > 0) {
22
+ egress.push({
23
+ toFQDNs: input.egressAllowFqdns.map((fqdn) => ({ matchName: fqdn })),
24
+ toPorts: [{ ports: [{ port: "443", protocol: "TCP" }] }],
25
+ });
26
+ }
27
+ egress.push({
28
+ toEndpoints: [
29
+ {
30
+ matchLabels: {
31
+ "k8s:io.kubernetes.pod.namespace": input.paperclipServerNamespace,
32
+ app: "paperclip-server",
33
+ },
34
+ },
35
+ ],
36
+ toPorts: [{ ports: [{ port: "3100", protocol: "TCP" }] }],
37
+ });
38
+ if (input.egressAllowCidrs.length > 0) {
39
+ egress.push({
40
+ toCIDRSet: input.egressAllowCidrs.map((cidr) => ({ cidr })),
41
+ });
42
+ }
43
+ return {
44
+ apiVersion: "cilium.io/v2",
45
+ kind: "CiliumNetworkPolicy",
46
+ metadata: {
47
+ name: "paperclip-egress-fqdn",
48
+ namespace: input.namespace,
49
+ labels: { "paperclip.io/managed-by": "paperclip-k8s-plugin" },
50
+ },
51
+ spec: {
52
+ endpointSelector: { matchLabels: { "paperclip.io/role": "agent" } },
53
+ egress,
54
+ },
55
+ };
56
+ }
57
+ //# sourceMappingURL=cilium-network-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cilium-network-policy.js","sourceRoot":"","sources":["../src/cilium-network-policy.ts"],"names":[],"mappings":"AAOA,4EAA4E;AAC5E,kEAAkE;AAClE,4EAA4E;AAC5E,0EAA0E;AAC1E,MAAM,UAAU,gCAAgC,CAAC,KAAoC;IACnF,MAAM,MAAM,GAA8B,EAAE,CAAC;IAE7C,MAAM,CAAC,IAAI,CAAC;QACV,WAAW,EAAE;YACX,EAAE,WAAW,EAAE,EAAE,iCAAiC,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE;SAC7F;QACD,OAAO,EAAE;YACP;gBACE,KAAK,EAAE;oBACL,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE;oBAC/B,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE;iBAChC;gBACD,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,EAAE;aACxC;SACF;KACF,CAAC,CAAC;IAEH,IAAI,KAAK,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtC,MAAM,CAAC,IAAI,CAAC;YACV,OAAO,EAAE,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACpE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;SACzD,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,IAAI,CAAC;QACV,WAAW,EAAE;YACX;gBACE,WAAW,EAAE;oBACX,iCAAiC,EAAE,KAAK,CAAC,wBAAwB;oBACjE,GAAG,EAAE,kBAAkB;iBACxB;aACF;SACF;QACD,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;KAC1D,CAAC,CAAC;IAEH,IAAI,KAAK,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtC,MAAM,CAAC,IAAI,CAAC;YACV,SAAS,EAAE,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;SAC5D,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,UAAU,EAAE,cAAc;QAC1B,IAAI,EAAE,qBAAqB;QAC3B,QAAQ,EAAE;YACR,IAAI,EAAE,uBAAuB;YAC7B,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,MAAM,EAAE,EAAE,yBAAyB,EAAE,sBAAsB,EAAE;SAC9D;QACD,IAAI,EAAE;YACJ,gBAAgB,EAAE,EAAE,WAAW,EAAE,EAAE,mBAAmB,EAAE,OAAO,EAAE,EAAE;YACnE,MAAM;SACP;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Glob matching for image references.
3
+ * - `*` matches any sequence of characters EXCEPT `/` (so a wildcard doesn't span path segments)
4
+ * - `?` matches exactly one character (excluding `/`)
5
+ */
6
+ export declare function globMatch(pattern: string, value: string): boolean;
7
+ export interface ResolveImageInput {
8
+ imageOverride?: string | null;
9
+ }
10
+ export interface ResolveImageDefaults {
11
+ runtimeImage: string;
12
+ }
13
+ export interface ResolveImageConfig {
14
+ imageAllowList: string[];
15
+ imageRegistry?: string;
16
+ }
17
+ export declare function resolveImage(target: ResolveImageInput, defaults: ResolveImageDefaults, config: ResolveImageConfig): string;
18
+ //# sourceMappingURL=image-allowlist.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-allowlist.d.ts","sourceRoot":"","sources":["../src/image-allowlist.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAUjE;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,iBAAiB,EACzB,QAAQ,EAAE,oBAAoB,EAC9B,MAAM,EAAE,kBAAkB,GACzB,MAAM,CAWR"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Glob matching for image references.
3
+ * - `*` matches any sequence of characters EXCEPT `/` (so a wildcard doesn't span path segments)
4
+ * - `?` matches exactly one character (excluding `/`)
5
+ */
6
+ export function globMatch(pattern, value) {
7
+ const re = new RegExp("^" +
8
+ pattern
9
+ .replace(/[.+^${}()|[\]\\]/g, "\\$&")
10
+ .replace(/\*/g, "[^/]*")
11
+ .replace(/\?/g, "[^/]") +
12
+ "$");
13
+ return re.test(value);
14
+ }
15
+ export function resolveImage(target, defaults, config) {
16
+ if (target.imageOverride) {
17
+ if (!config.imageAllowList.some((p) => globMatch(p, target.imageOverride))) {
18
+ throw new Error(`Image override "${target.imageOverride}" is not in allowlist`);
19
+ }
20
+ return target.imageOverride;
21
+ }
22
+ if (config.imageRegistry) {
23
+ return rewriteRegistry(defaults.runtimeImage, config.imageRegistry);
24
+ }
25
+ return defaults.runtimeImage;
26
+ }
27
+ function rewriteRegistry(image, registry) {
28
+ // image is like "ghcr.io/paperclipai/agent-runtime-claude:v1"
29
+ // we want to replace the first two path segments (host + org) with `registry`
30
+ const cleanRegistry = registry.replace(/\/+$/, "");
31
+ const colonIdx = image.lastIndexOf(":");
32
+ const tag = colonIdx >= 0 ? image.slice(colonIdx) : "";
33
+ const path = colonIdx >= 0 ? image.slice(0, colonIdx) : image;
34
+ const segments = path.split("/");
35
+ // Strip the host+org (first two segments), keep the image name
36
+ const imageName = segments.slice(2).join("/") || segments[segments.length - 1];
37
+ return `${cleanRegistry}/${imageName}${tag}`;
38
+ }
39
+ //# sourceMappingURL=image-allowlist.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-allowlist.js","sourceRoot":"","sources":["../src/image-allowlist.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,OAAe,EAAE,KAAa;IACtD,MAAM,EAAE,GAAG,IAAI,MAAM,CACnB,GAAG;QACD,OAAO;aACJ,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC;aACpC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC;aACvB,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC;QACzB,GAAG,CACN,CAAC;IACF,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACxB,CAAC;AAeD,MAAM,UAAU,YAAY,CAC1B,MAAyB,EACzB,QAA8B,EAC9B,MAA0B;IAE1B,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,aAAc,CAAC,CAAC,EAAE,CAAC;YAC5E,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,CAAC,aAAa,uBAAuB,CAAC,CAAC;QAClF,CAAC;QACD,OAAO,MAAM,CAAC,aAAa,CAAC;IAC9B,CAAC;IACD,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;QACzB,OAAO,eAAe,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,QAAQ,CAAC,YAAY,CAAC;AAC/B,CAAC;AAED,SAAS,eAAe,CAAC,KAAa,EAAE,QAAgB;IACtD,8DAA8D;IAC9D,8EAA8E;IAC9E,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACvD,MAAM,IAAI,GAAG,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,+DAA+D;IAC/D,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC/E,OAAO,GAAG,aAAa,IAAI,SAAS,GAAG,GAAG,EAAE,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { default as manifest } from "./manifest.js";
2
+ export { default as plugin } from "./plugin.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { default as manifest } from "./manifest.js";
2
+ export { default as plugin } from "./plugin.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { KubeClients } from "./kube-client.js";
2
+ import type { SandboxOrchestrator, SandboxStatus } from "./sandbox-orchestrator.js";
3
+ export declare class JobTimeoutError extends Error {
4
+ constructor(namespace: string, name: string, timeoutMs: number);
5
+ }
6
+ export declare function createJob(clients: KubeClients, namespace: string, manifest: Record<string, unknown>): Promise<{
7
+ uid: string;
8
+ }>;
9
+ export type JobStatus = SandboxStatus;
10
+ export declare function getJobStatus(clients: KubeClients, namespace: string, name: string): Promise<JobStatus>;
11
+ export declare function findPodForJob(clients: KubeClients, namespace: string, jobName: string): Promise<string | null>;
12
+ export declare function streamPodLogs(clients: KubeClients, namespace: string, podName: string, onChunk: (stream: "stdout" | "stderr", text: string) => Promise<void>): Promise<void>;
13
+ export declare function deleteJob(clients: KubeClients, namespace: string, name: string): Promise<void>;
14
+ export declare function waitForJobCompletion(clients: KubeClients, namespace: string, name: string, opts?: {
15
+ timeoutMs: number;
16
+ pollMs?: number;
17
+ }): Promise<JobStatus>;
18
+ /**
19
+ * Job-backed conformance to SandboxOrchestrator. Plugin.ts imports THIS value
20
+ * (the swap point) — to use a different backend, swap this import for another
21
+ * module exposing a SandboxOrchestrator-shaped default export.
22
+ */
23
+ export declare const jobOrchestrator: SandboxOrchestrator;
24
+ //# sourceMappingURL=job-orchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"job-orchestrator.d.ts","sourceRoot":"","sources":["../src/job-orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAEpF,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAI/D;AAED,wBAAsB,SAAS,CAC7B,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,CAK1B;AAED,MAAM,MAAM,SAAS,GAAG,aAAa,CAAC;AAEtC,wBAAsB,YAAY,CAChC,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,SAAS,CAAC,CAoBpB;AAED,wBAAsB,aAAa,CACjC,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQxB;AAED,wBAAsB,aAAa,CACjC,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,SAAS,CAC7B,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAMf;AAED,wBAAsB,oBAAoB,CACxC,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;CAAyC,GAClF,OAAO,CAAC,SAAS,CAAC,CASpB;AAMD;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,mBAO7B,CAAC"}
@@ -0,0 +1,90 @@
1
+ export class JobTimeoutError extends Error {
2
+ constructor(namespace, name, timeoutMs) {
3
+ super(`Job ${namespace}/${name} did not complete within ${timeoutMs}ms`);
4
+ this.name = "JobTimeoutError";
5
+ }
6
+ }
7
+ export async function createJob(clients, namespace, manifest) {
8
+ const result = await clients.batch.createNamespacedJob({ namespace, body: manifest });
9
+ const uid = result.metadata?.uid;
10
+ if (!uid)
11
+ throw new Error("Job created without a UID");
12
+ return { uid };
13
+ }
14
+ export async function getJobStatus(clients, namespace, name) {
15
+ const result = await clients.batch.readNamespacedJobStatus({ namespace, name });
16
+ const body = result ?? {};
17
+ const status = body.status ?? {};
18
+ const active = status.active ?? 0;
19
+ const succeeded = status.succeeded ?? 0;
20
+ const failed = status.failed ?? 0;
21
+ const conditions = status.conditions ?? [];
22
+ const completed = conditions.find((c) => c.type === "Complete" && c.status === "True");
23
+ const failedCond = conditions.find((c) => c.type === "Failed" && c.status === "True");
24
+ if (failedCond || failed > 0) {
25
+ return { phase: "Failed", complete: false, active, succeeded, failed, reason: failedCond?.reason, message: failedCond?.message };
26
+ }
27
+ if (completed || succeeded > 0) {
28
+ return { phase: "Succeeded", complete: true, active, succeeded, failed };
29
+ }
30
+ if (active > 0) {
31
+ return { phase: "Running", complete: false, active, succeeded, failed };
32
+ }
33
+ return { phase: "Pending", complete: false, active, succeeded, failed };
34
+ }
35
+ export async function findPodForJob(clients, namespace, jobName) {
36
+ const result = await clients.core.listNamespacedPod({
37
+ namespace,
38
+ labelSelector: `job-name=${jobName}`,
39
+ });
40
+ const items = (result.items) ?? [];
41
+ const running = items.find((p) => p.status?.phase === "Running");
42
+ return (running ?? items[0])?.metadata?.name ?? null;
43
+ }
44
+ export async function streamPodLogs(clients, namespace, podName, onChunk) {
45
+ // V1 limitation: readNamespacedPodLog returns combined stdout (the kubectl-style
46
+ // log view). stderr is not separately exposed via this API path — agent
47
+ // containers that need stderr/stdout separation should use a sidecar log
48
+ // scraper or wrap their CLI to emit structured output on stdout. We always
49
+ // emit chunks as "stdout"; the "stderr" callback slot in SandboxOrchestrator
50
+ // is unused by the Job-backed implementation.
51
+ const result = await clients.core.readNamespacedPodLog({ namespace, name: podName });
52
+ const text = result ?? "";
53
+ if (text.length > 0)
54
+ await onChunk("stdout", text);
55
+ }
56
+ export async function deleteJob(clients, namespace, name) {
57
+ await clients.batch.deleteNamespacedJob({
58
+ namespace,
59
+ name,
60
+ propagationPolicy: "Foreground",
61
+ });
62
+ }
63
+ export async function waitForJobCompletion(clients, namespace, name, opts = { timeoutMs: 120_000, pollMs: 2000 }) {
64
+ const deadline = Date.now() + opts.timeoutMs;
65
+ const pollMs = opts.pollMs ?? 2000;
66
+ while (Date.now() < deadline) {
67
+ const status = await getJobStatus(clients, namespace, name);
68
+ if (status.phase === "Succeeded" || status.phase === "Failed")
69
+ return status;
70
+ await sleep(pollMs);
71
+ }
72
+ throw new JobTimeoutError(namespace, name, opts.timeoutMs);
73
+ }
74
+ function sleep(ms) {
75
+ return new Promise((resolve) => setTimeout(resolve, ms));
76
+ }
77
+ /**
78
+ * Job-backed conformance to SandboxOrchestrator. Plugin.ts imports THIS value
79
+ * (the swap point) — to use a different backend, swap this import for another
80
+ * module exposing a SandboxOrchestrator-shaped default export.
81
+ */
82
+ export const jobOrchestrator = {
83
+ claim: createJob,
84
+ getStatus: getJobStatus,
85
+ findPod: findPodForJob,
86
+ streamLogs: streamPodLogs,
87
+ release: deleteJob,
88
+ waitForCompletion: waitForJobCompletion,
89
+ };
90
+ //# sourceMappingURL=job-orchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"job-orchestrator.js","sourceRoot":"","sources":["../src/job-orchestrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { KubeConfig, CoreV1Api, BatchV1Api, CustomObjectsApi, NetworkingV1Api, RbacAuthorizationV1Api } from "@kubernetes/client-node";
2
+ export interface CreateKubeConfigInput {
3
+ inCluster?: boolean;
4
+ kubeconfig?: string;
5
+ }
6
+ export declare function createKubeConfig(input: CreateKubeConfigInput): KubeConfig;
7
+ export interface KubeClients {
8
+ core: CoreV1Api;
9
+ batch: BatchV1Api;
10
+ custom: CustomObjectsApi;
11
+ networking: NetworkingV1Api;
12
+ rbac: RbacAuthorizationV1Api;
13
+ }
14
+ export declare function makeKubeClients(kc: KubeConfig): KubeClients;
15
+ //# sourceMappingURL=kube-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kube-client.d.ts","sourceRoot":"","sources":["../src/kube-client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,SAAS,EACT,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,sBAAsB,EACvB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,UAAU,CAWzE;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,UAAU,CAAC;IAClB,MAAM,EAAE,gBAAgB,CAAC;IACzB,UAAU,EAAE,eAAe,CAAC;IAC5B,IAAI,EAAE,sBAAsB,CAAC;CAC9B;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,UAAU,GAAG,WAAW,CAQ3D"}
@@ -0,0 +1,23 @@
1
+ import { KubeConfig, CoreV1Api, BatchV1Api, CustomObjectsApi, NetworkingV1Api, RbacAuthorizationV1Api, } from "@kubernetes/client-node";
2
+ export function createKubeConfig(input) {
3
+ const kc = new KubeConfig();
4
+ if (input.inCluster) {
5
+ kc.loadFromCluster();
6
+ return kc;
7
+ }
8
+ if (input.kubeconfig && input.kubeconfig.trim().length > 0) {
9
+ kc.loadFromString(input.kubeconfig);
10
+ return kc;
11
+ }
12
+ throw new Error("createKubeConfig requires either inCluster=true or a kubeconfig string");
13
+ }
14
+ export function makeKubeClients(kc) {
15
+ return {
16
+ core: kc.makeApiClient(CoreV1Api),
17
+ batch: kc.makeApiClient(BatchV1Api),
18
+ custom: kc.makeApiClient(CustomObjectsApi),
19
+ networking: kc.makeApiClient(NetworkingV1Api),
20
+ rbac: kc.makeApiClient(RbacAuthorizationV1Api),
21
+ };
22
+ }
23
+ //# sourceMappingURL=kube-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kube-client.js","sourceRoot":"","sources":["../src/kube-client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,SAAS,EACT,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AAOjC,MAAM,UAAU,gBAAgB,CAAC,KAA4B;IAC3D,MAAM,EAAE,GAAG,IAAI,UAAU,EAAE,CAAC;IAC5B,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACpB,EAAE,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3D,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACpC,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;AAC5F,CAAC;AAUD,MAAM,UAAU,eAAe,CAAC,EAAc;IAC5C,OAAO;QACL,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC;QACjC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,UAAU,CAAC;QACnC,MAAM,EAAE,EAAE,CAAC,aAAa,CAAC,gBAAgB,CAAC;QAC1C,UAAU,EAAE,EAAE,CAAC,aAAa,CAAC,eAAe,CAAC;QAC7C,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,sBAAsB,CAAC;KAC/C,CAAC;AACJ,CAAC"}