kubeagent 0.1.15 → 0.1.17

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.
package/dist/auth.js CHANGED
@@ -1,4 +1,4 @@
1
- import { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync } from "node:fs";
1
+ import { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync, chmodSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  import { createServer } from "node:http";
4
4
  import { randomBytes } from "node:crypto";
@@ -31,8 +31,18 @@ export function loadAuth() {
31
31
  export function saveAuth(auth) {
32
32
  const dir = configDir();
33
33
  if (!existsSync(dir))
34
- mkdirSync(dir, { recursive: true });
35
- writeFileSync(authPath(), JSON.stringify(auth, null, 2));
34
+ mkdirSync(dir, { recursive: true, mode: 0o700 });
35
+ const path = authPath();
36
+ // Write with mode 0600 so only the owning user can read the file.
37
+ // This is the fallback for platforms where a system keychain is unavailable.
38
+ // To use the OS keychain instead (recommended for production), install `keytar`
39
+ // and store auth.token and auth.apiKey there, keeping only non-secret fields here.
40
+ writeFileSync(path, JSON.stringify(auth, null, 2), { mode: 0o600 });
41
+ // Ensure permissions even if the file already existed with looser permissions.
42
+ try {
43
+ chmodSync(path, 0o600);
44
+ }
45
+ catch { /* non-POSIX platforms ignore this */ }
36
46
  }
37
47
  export function clearAuth() {
38
48
  const path = authPath();
package/dist/cli.js CHANGED
@@ -16,7 +16,6 @@ import { startMonitor } from "./monitor/index.js";
16
16
  import { handleIssues } from "./orchestrator.js";
17
17
  import { sendResolve } from "./notify/index.js";
18
18
  import { diagnose } from "./diagnoser/index.js";
19
- import { buildSystemPrompt } from "./kb/loader.js";
20
19
  import { join } from "node:path";
21
20
  import { loadAuth, loginBrowser, loginDevice, createApiKey, showAccount, clearAuth } from "./auth.js";
22
21
  import { fetchSlackWebhook } from "./proxy-client.js";
@@ -440,9 +439,6 @@ program
440
439
  program.help();
441
440
  return;
442
441
  }
443
- const context = opts.context;
444
- const kbDir = join(configDir(), "clusters", context ?? "default");
445
- const systemPrompt = buildSystemPrompt(kbDir);
446
442
  const auth = loadAuth();
447
443
  if (!auth?.apiKey) {
448
444
  console.error(chalk.red("Not logged in. Run 'kubeagent login' to get started."));
@@ -450,10 +446,7 @@ program
450
446
  }
451
447
  const { proxyRequest } = await import("./proxy-client.js");
452
448
  const result = await proxyRequest(auth, {
453
- model: "claude-sonnet-4-6",
454
449
  max_tokens: 16000,
455
- system: systemPrompt,
456
- thinking: { type: "adaptive" },
457
450
  messages: [{ role: "user", content: prompt.join(" ") }],
458
451
  });
459
452
  const response = result;
@@ -1,26 +1,10 @@
1
1
  import chalk from "chalk";
2
2
  import readline from "node:readline";
3
- import { buildSystemPrompt } from "../kb/loader.js";
4
3
  import { loadAuth } from "../auth.js";
5
4
  import { proxyRequest } from "../proxy-client.js";
6
- import { dbg } from "../debug.js";
7
5
  import { getLogs, describeResource, restartPod, rolloutRestart, scaleDeployment, getEvents, setResources, kubectlGetLogsSchema, kubectlDescribeSchema, restartPodSchema, rolloutRestartSchema, scaleDeploymentSchema, getEventsSchema, setResourcesSchema, } from "./tools.js";
8
6
  import { zodToJsonSchema } from "zod-to-json-schema";
9
7
  const MAX_TOOL_OUTPUT_CHARS = 8000;
10
- const HAIKU = "claude-haiku-4-5-20251001";
11
- const SONNET = "claude-sonnet-4-6";
12
- function selectModel(issues) {
13
- if (issues.some((i) => i.kind === "node_not_ready" || i.kind === "node_pressure"))
14
- return SONNET;
15
- if (issues.length >= 3)
16
- return SONNET;
17
- const maxRestarts = Math.max(0, ...issues.map((i) => i.details.restartCount ?? 0));
18
- if (maxRestarts > 20)
19
- return SONNET;
20
- if (issues.filter((i) => i.kind === "pod_oom").length >= 2)
21
- return SONNET;
22
- return HAIKU;
23
- }
24
8
  async function createMessage(params) {
25
9
  const auth = loadAuth();
26
10
  if (!auth?.apiKey) {
@@ -138,7 +122,6 @@ function makeToolExecutors(noInteractive, onQuestion) {
138
122
  };
139
123
  }
140
124
  export async function diagnose(issues, kbDir, clusterContext, options) {
141
- const systemPrompt = buildSystemPrompt(kbDir);
142
125
  const tools = makeToolDefs();
143
126
  const issuesSummary = issues
144
127
  .map((i) => `[${i.severity}] ${i.kind}: ${i.message}`)
@@ -166,22 +149,14 @@ If it requires a risky action (rollback, delete, scale to zero), propose it but
166
149
  ...(options?.safeActions ?? []),
167
150
  ]);
168
151
  let appliedAction;
169
- const model = selectModel(issues);
170
- dbg("model", `selected ${model} for ${issues.length} issue(s): ${issues.map(i => i.kind).join(", ")}`);
171
- // Agentic loop
152
+ // Agentic loop — model is selected server-side based on plan tier
172
153
  let lastResponse;
173
154
  for (let turn = 0; turn < 10; turn++) {
174
155
  const params = {
175
- model,
176
156
  max_tokens: 16000,
177
- system: systemPrompt,
178
157
  tools,
179
158
  messages,
180
159
  };
181
- // adaptive thinking only supported on Sonnet+, not Haiku
182
- if (model === SONNET) {
183
- params.thinking = { type: "adaptive" };
184
- }
185
160
  const response = await createMessage(params);
186
161
  lastResponse = response;
187
162
  if (response.stop_reason === "end_turn")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kubeagent",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "AI-powered Kubernetes management CLI",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",