panopticon-cli 0.3.7 → 0.4.4

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 (37) hide show
  1. package/README.md +1610 -121
  2. package/dist/agents-B5NRTVHK.js +40 -0
  3. package/dist/chunk-7HHDVXBM.js +349 -0
  4. package/dist/chunk-7HHDVXBM.js.map +1 -0
  5. package/dist/chunk-H45CLB7E.js +2044 -0
  6. package/dist/chunk-H45CLB7E.js.map +1 -0
  7. package/dist/{chunk-C6A7S65K.js → chunk-ITI4IC5A.js} +188 -43
  8. package/dist/chunk-ITI4IC5A.js.map +1 -0
  9. package/dist/cli/index.js +8007 -2781
  10. package/dist/cli/index.js.map +1 -1
  11. package/dist/dashboard/public/assets/index-BDd8hGYb.css +32 -0
  12. package/dist/dashboard/public/assets/index-sFwLPko-.js +556 -0
  13. package/dist/dashboard/public/index.html +3 -2
  14. package/dist/dashboard/server.js +39015 -69826
  15. package/dist/index.d.ts +136 -1
  16. package/dist/index.js +36 -4
  17. package/package.json +10 -3
  18. package/scripts/git-hooks/post-checkout +109 -0
  19. package/templates/claude-md/sections/beads.md +1 -2
  20. package/templates/claude-md/sections/warnings.md +46 -2
  21. package/templates/context/CLAUDE.md.template +22 -0
  22. package/templates/context/REOPEN_PROMPT.md.template +75 -0
  23. package/templates/docker/dotnet/docker-compose.yml +2 -0
  24. package/templates/docker/monorepo/docker-compose.yml +4 -0
  25. package/templates/docker/nextjs/docker-compose.yml +1 -0
  26. package/templates/docker/python-fastapi/docker-compose.yml +3 -0
  27. package/templates/docker/react-vite/docker-compose.yml +1 -0
  28. package/templates/docker/spring-boot/docker-compose.yml +3 -0
  29. package/dist/chunk-BH6BR26M.js +0 -173
  30. package/dist/chunk-BH6BR26M.js.map +0 -1
  31. package/dist/chunk-C6A7S65K.js.map +0 -1
  32. package/dist/chunk-P5TQ5C3J.js +0 -103
  33. package/dist/chunk-P5TQ5C3J.js.map +0 -1
  34. package/dist/dashboard/public/assets/index-CUoYoWX_.css +0 -32
  35. package/dist/dashboard/public/assets/index-CY0Ew5B9.js +0 -423
  36. package/dist/projects-54CV437J.js +0 -34
  37. /package/dist/{projects-54CV437J.js.map → agents-B5NRTVHK.js.map} +0 -0
@@ -0,0 +1,40 @@
1
+ import {
2
+ appendActivity,
3
+ autoRecoverAgents,
4
+ detectCrashedAgents,
5
+ getActivity,
6
+ getAgentDir,
7
+ getAgentRuntimeState,
8
+ getAgentState,
9
+ getSessionId,
10
+ listRunningAgents,
11
+ messageAgent,
12
+ recoverAgent,
13
+ resumeAgent,
14
+ saveAgentRuntimeState,
15
+ saveAgentState,
16
+ saveSessionId,
17
+ spawnAgent,
18
+ stopAgent
19
+ } from "./chunk-H45CLB7E.js";
20
+ import "./chunk-7HHDVXBM.js";
21
+ export {
22
+ appendActivity,
23
+ autoRecoverAgents,
24
+ detectCrashedAgents,
25
+ getActivity,
26
+ getAgentDir,
27
+ getAgentRuntimeState,
28
+ getAgentState,
29
+ getSessionId,
30
+ listRunningAgents,
31
+ messageAgent,
32
+ recoverAgent,
33
+ resumeAgent,
34
+ saveAgentRuntimeState,
35
+ saveAgentState,
36
+ saveSessionId,
37
+ spawnAgent,
38
+ stopAgent
39
+ };
40
+ //# sourceMappingURL=agents-B5NRTVHK.js.map
@@ -0,0 +1,349 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ // src/lib/paths.ts
9
+ import { homedir } from "os";
10
+ import { join } from "path";
11
+ import { existsSync } from "fs";
12
+ import { fileURLToPath } from "url";
13
+ import { dirname } from "path";
14
+ var PANOPTICON_HOME = process.env.PANOPTICON_HOME || join(homedir(), ".panopticon");
15
+ var CONFIG_DIR = PANOPTICON_HOME;
16
+ var SKILLS_DIR = join(PANOPTICON_HOME, "skills");
17
+ var COMMANDS_DIR = join(PANOPTICON_HOME, "commands");
18
+ var AGENTS_DIR = join(PANOPTICON_HOME, "agents");
19
+ var BIN_DIR = join(PANOPTICON_HOME, "bin");
20
+ var BACKUPS_DIR = join(PANOPTICON_HOME, "backups");
21
+ var COSTS_DIR = join(PANOPTICON_HOME, "costs");
22
+ var HEARTBEATS_DIR = join(PANOPTICON_HOME, "heartbeats");
23
+ var TRAEFIK_DIR = join(PANOPTICON_HOME, "traefik");
24
+ var TRAEFIK_DYNAMIC_DIR = join(TRAEFIK_DIR, "dynamic");
25
+ var TRAEFIK_CERTS_DIR = join(TRAEFIK_DIR, "certs");
26
+ var CERTS_DIR = join(PANOPTICON_HOME, "certs");
27
+ var CONFIG_FILE = join(CONFIG_DIR, "config.toml");
28
+ var SETTINGS_FILE = join(CONFIG_DIR, "settings.json");
29
+ var CLAUDE_DIR = join(homedir(), ".claude");
30
+ var CODEX_DIR = join(homedir(), ".codex");
31
+ var CURSOR_DIR = join(homedir(), ".cursor");
32
+ var GEMINI_DIR = join(homedir(), ".gemini");
33
+ var SYNC_TARGETS = {
34
+ claude: {
35
+ skills: join(CLAUDE_DIR, "skills"),
36
+ commands: join(CLAUDE_DIR, "commands"),
37
+ agents: join(CLAUDE_DIR, "agents")
38
+ },
39
+ codex: {
40
+ skills: join(CODEX_DIR, "skills"),
41
+ commands: join(CODEX_DIR, "commands"),
42
+ agents: join(CODEX_DIR, "agents")
43
+ },
44
+ cursor: {
45
+ skills: join(CURSOR_DIR, "skills"),
46
+ commands: join(CURSOR_DIR, "commands"),
47
+ agents: join(CURSOR_DIR, "agents")
48
+ },
49
+ gemini: {
50
+ skills: join(GEMINI_DIR, "skills"),
51
+ commands: join(GEMINI_DIR, "commands"),
52
+ agents: join(GEMINI_DIR, "agents")
53
+ }
54
+ };
55
+ var TEMPLATES_DIR = join(PANOPTICON_HOME, "templates");
56
+ var CLAUDE_MD_TEMPLATES = join(TEMPLATES_DIR, "claude-md", "sections");
57
+ var currentFile = fileURLToPath(import.meta.url);
58
+ var currentDir = dirname(currentFile);
59
+ var packageRoot;
60
+ if (currentDir.includes("/src/")) {
61
+ packageRoot = dirname(dirname(currentDir));
62
+ } else {
63
+ packageRoot = currentDir.endsWith("/lib") ? dirname(dirname(currentDir)) : dirname(currentDir);
64
+ }
65
+ var SOURCE_TEMPLATES_DIR = join(packageRoot, "templates");
66
+ var SOURCE_TRAEFIK_TEMPLATES = join(SOURCE_TEMPLATES_DIR, "traefik");
67
+ var SOURCE_SCRIPTS_DIR = join(packageRoot, "scripts");
68
+ var SOURCE_SKILLS_DIR = join(packageRoot, "skills");
69
+ var SOURCE_DEV_SKILLS_DIR = join(packageRoot, "dev-skills");
70
+ function isDevMode() {
71
+ try {
72
+ return existsSync(SOURCE_DEV_SKILLS_DIR);
73
+ } catch {
74
+ return false;
75
+ }
76
+ }
77
+ var INIT_DIRS = [
78
+ PANOPTICON_HOME,
79
+ SKILLS_DIR,
80
+ COMMANDS_DIR,
81
+ AGENTS_DIR,
82
+ BIN_DIR,
83
+ BACKUPS_DIR,
84
+ COSTS_DIR,
85
+ HEARTBEATS_DIR,
86
+ TEMPLATES_DIR,
87
+ CLAUDE_MD_TEMPLATES,
88
+ CERTS_DIR,
89
+ TRAEFIK_DIR,
90
+ TRAEFIK_DYNAMIC_DIR,
91
+ TRAEFIK_CERTS_DIR
92
+ ];
93
+
94
+ // src/lib/settings.ts
95
+ import { readFileSync, writeFileSync, existsSync as existsSync2 } from "fs";
96
+ var DEFAULT_SETTINGS = {
97
+ models: {
98
+ specialists: {
99
+ review_agent: "kimi-k2.5",
100
+ test_agent: "kimi-k2.5",
101
+ merge_agent: "kimi-k2.5"
102
+ },
103
+ planning_agent: "kimi-k2.5",
104
+ complexity: {
105
+ trivial: "kimi-k2.5",
106
+ simple: "kimi-k2.5",
107
+ medium: "kimi-k2.5",
108
+ complex: "kimi-k2.5",
109
+ expert: "kimi-k2.5"
110
+ }
111
+ },
112
+ api_keys: {}
113
+ };
114
+ function deepMerge(defaults, overrides) {
115
+ const result = { ...defaults };
116
+ for (const key of Object.keys(overrides)) {
117
+ const defaultVal = defaults[key];
118
+ const overrideVal = overrides[key];
119
+ if (overrideVal === void 0) continue;
120
+ if (typeof defaultVal === "object" && defaultVal !== null && !Array.isArray(defaultVal) && typeof overrideVal === "object" && overrideVal !== null && !Array.isArray(overrideVal)) {
121
+ result[key] = deepMerge(defaultVal, overrideVal);
122
+ } else {
123
+ result[key] = overrideVal;
124
+ }
125
+ }
126
+ return result;
127
+ }
128
+ function loadSettings() {
129
+ let settings;
130
+ if (!existsSync2(SETTINGS_FILE)) {
131
+ settings = getDefaultSettings();
132
+ } else {
133
+ try {
134
+ const content = readFileSync(SETTINGS_FILE, "utf8");
135
+ const parsed = JSON.parse(content);
136
+ settings = deepMerge(DEFAULT_SETTINGS, parsed);
137
+ } catch (error) {
138
+ console.error("Warning: Failed to parse settings.json, using defaults");
139
+ settings = getDefaultSettings();
140
+ }
141
+ }
142
+ const envApiKeys = {};
143
+ if (process.env.OPENAI_API_KEY) envApiKeys.openai = process.env.OPENAI_API_KEY;
144
+ if (process.env.GOOGLE_API_KEY) envApiKeys.google = process.env.GOOGLE_API_KEY;
145
+ if (process.env.ZAI_API_KEY) envApiKeys.zai = process.env.ZAI_API_KEY;
146
+ if (process.env.KIMI_API_KEY) envApiKeys.kimi = process.env.KIMI_API_KEY;
147
+ settings.api_keys = {
148
+ ...envApiKeys,
149
+ ...settings.api_keys
150
+ };
151
+ return settings;
152
+ }
153
+ function saveSettings(settings) {
154
+ const content = JSON.stringify(settings, null, 2);
155
+ writeFileSync(SETTINGS_FILE, content, "utf8");
156
+ }
157
+ function validateSettings(settings) {
158
+ if (!settings.models) {
159
+ return "Missing models configuration";
160
+ }
161
+ if (!settings.models.specialists) {
162
+ return "Missing specialists configuration";
163
+ }
164
+ const specialists = settings.models.specialists;
165
+ if (!specialists.review_agent || !specialists.test_agent || !specialists.merge_agent) {
166
+ return "Missing specialist agent model configuration";
167
+ }
168
+ if (!settings.models.planning_agent) {
169
+ return "Missing planning_agent configuration";
170
+ }
171
+ if (!settings.models.complexity) {
172
+ return "Missing complexity configuration";
173
+ }
174
+ const complexity = settings.models.complexity;
175
+ const requiredLevels = ["trivial", "simple", "medium", "complex", "expert"];
176
+ for (const level of requiredLevels) {
177
+ if (!complexity[level]) {
178
+ return `Missing complexity level: ${level}`;
179
+ }
180
+ }
181
+ if (!settings.api_keys) {
182
+ return "Missing api_keys configuration";
183
+ }
184
+ return null;
185
+ }
186
+ function getDefaultSettings() {
187
+ return JSON.parse(JSON.stringify(DEFAULT_SETTINGS));
188
+ }
189
+ function getAvailableModels(settings) {
190
+ const anthropicModels = [
191
+ "claude-opus-4-5",
192
+ "claude-sonnet-4-5",
193
+ "claude-haiku-4-5"
194
+ ];
195
+ const openaiModels = settings.api_keys.openai ? ["gpt-5.2-codex", "o3-deep-research", "gpt-4o", "gpt-4o-mini"] : [];
196
+ const googleModels = settings.api_keys.google ? ["gemini-3-pro-preview", "gemini-3-flash-preview"] : [];
197
+ const zaiModels = settings.api_keys.zai ? ["glm-4.7", "glm-4.7-flash"] : [];
198
+ const kimiModels = settings.api_keys.kimi ? ["kimi-k2", "kimi-k2.5"] : [];
199
+ return {
200
+ anthropic: anthropicModels,
201
+ openai: openaiModels,
202
+ google: googleModels,
203
+ zai: zaiModels,
204
+ kimi: kimiModels
205
+ };
206
+ }
207
+
208
+ // src/lib/providers.ts
209
+ var PROVIDERS = {
210
+ anthropic: {
211
+ name: "anthropic",
212
+ displayName: "Anthropic",
213
+ compatibility: "direct",
214
+ models: ["claude-opus-4-5", "claude-sonnet-4-5", "claude-haiku-4-5"],
215
+ tested: true,
216
+ description: "Native Claude API"
217
+ },
218
+ kimi: {
219
+ name: "kimi",
220
+ displayName: "Kimi (Moonshot AI)",
221
+ compatibility: "direct",
222
+ baseUrl: "https://api.kimi.com/coding/",
223
+ models: [],
224
+ // Kimi uses same model names as Anthropic
225
+ tested: true,
226
+ description: "Anthropic-compatible API, tested 2026-01-28"
227
+ },
228
+ zai: {
229
+ name: "zai",
230
+ displayName: "Z.AI (GLM)",
231
+ compatibility: "direct",
232
+ baseUrl: "https://api.z.ai/api/anthropic",
233
+ models: ["glm-4.7", "glm-4.7-flash"],
234
+ tested: true,
235
+ description: "Anthropic-compatible API, tested 2026-01-28"
236
+ },
237
+ openai: {
238
+ name: "openai",
239
+ displayName: "OpenAI",
240
+ compatibility: "router",
241
+ models: ["gpt-5.2-codex", "o3-deep-research", "gpt-4o", "gpt-4o-mini"],
242
+ tested: false,
243
+ description: "Requires claude-code-router for API translation"
244
+ },
245
+ google: {
246
+ name: "google",
247
+ displayName: "Google (Gemini)",
248
+ compatibility: "router",
249
+ models: ["gemini-3-pro-preview", "gemini-3-flash-preview"],
250
+ tested: false,
251
+ description: "Requires claude-code-router for API translation"
252
+ }
253
+ };
254
+ function getProviderForModel(modelId) {
255
+ if (["claude-opus-4-5", "claude-sonnet-4-5", "claude-haiku-4-5"].includes(modelId)) {
256
+ return PROVIDERS.anthropic;
257
+ }
258
+ if (["gpt-5.2-codex", "o3-deep-research", "gpt-4o", "gpt-4o-mini"].includes(modelId)) {
259
+ return PROVIDERS.openai;
260
+ }
261
+ if (["gemini-3-pro-preview", "gemini-3-flash-preview"].includes(modelId)) {
262
+ return PROVIDERS.google;
263
+ }
264
+ if (["glm-4.7", "glm-4.7-flash"].includes(modelId)) {
265
+ return PROVIDERS.zai;
266
+ }
267
+ if (["kimi-k2", "kimi-k2.5"].includes(modelId)) {
268
+ return PROVIDERS.kimi;
269
+ }
270
+ return PROVIDERS.anthropic;
271
+ }
272
+ function requiresRouter(provider) {
273
+ return PROVIDERS[provider].compatibility === "router";
274
+ }
275
+ function getRouterProviders() {
276
+ return Object.values(PROVIDERS).filter((p) => p.compatibility === "router");
277
+ }
278
+ function getDirectProviders() {
279
+ return Object.values(PROVIDERS).filter((p) => p.compatibility === "direct");
280
+ }
281
+ function needsRouter(apiKeys) {
282
+ return !!(apiKeys.openai || apiKeys.google);
283
+ }
284
+ function getProviderEnv(provider, apiKey) {
285
+ if (provider.compatibility === "direct") {
286
+ const env = {};
287
+ if (provider.baseUrl) {
288
+ env.ANTHROPIC_BASE_URL = provider.baseUrl;
289
+ }
290
+ if (provider.name !== "anthropic") {
291
+ env.ANTHROPIC_AUTH_TOKEN = apiKey;
292
+ }
293
+ if (provider.name === "zai") {
294
+ env.API_TIMEOUT_MS = "300000";
295
+ }
296
+ return env;
297
+ } else {
298
+ return {
299
+ ANTHROPIC_BASE_URL: "http://localhost:3456",
300
+ ANTHROPIC_AUTH_TOKEN: "router-managed"
301
+ };
302
+ }
303
+ }
304
+
305
+ export {
306
+ __require,
307
+ PANOPTICON_HOME,
308
+ CONFIG_DIR,
309
+ SKILLS_DIR,
310
+ COMMANDS_DIR,
311
+ AGENTS_DIR,
312
+ BIN_DIR,
313
+ BACKUPS_DIR,
314
+ COSTS_DIR,
315
+ HEARTBEATS_DIR,
316
+ TRAEFIK_DIR,
317
+ TRAEFIK_DYNAMIC_DIR,
318
+ TRAEFIK_CERTS_DIR,
319
+ CERTS_DIR,
320
+ CONFIG_FILE,
321
+ SETTINGS_FILE,
322
+ CLAUDE_DIR,
323
+ CODEX_DIR,
324
+ CURSOR_DIR,
325
+ GEMINI_DIR,
326
+ SYNC_TARGETS,
327
+ TEMPLATES_DIR,
328
+ CLAUDE_MD_TEMPLATES,
329
+ SOURCE_TEMPLATES_DIR,
330
+ SOURCE_TRAEFIK_TEMPLATES,
331
+ SOURCE_SCRIPTS_DIR,
332
+ SOURCE_SKILLS_DIR,
333
+ SOURCE_DEV_SKILLS_DIR,
334
+ isDevMode,
335
+ INIT_DIRS,
336
+ loadSettings,
337
+ saveSettings,
338
+ validateSettings,
339
+ getDefaultSettings,
340
+ getAvailableModels,
341
+ PROVIDERS,
342
+ getProviderForModel,
343
+ requiresRouter,
344
+ getRouterProviders,
345
+ getDirectProviders,
346
+ needsRouter,
347
+ getProviderEnv
348
+ };
349
+ //# sourceMappingURL=chunk-7HHDVXBM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/paths.ts","../src/lib/settings.ts","../src/lib/providers.ts"],"sourcesContent":["import { homedir } from 'os';\nimport { join } from 'path';\nimport { existsSync } from 'fs';\n\n// Panopticon home directory (can be overridden for testing)\nexport const PANOPTICON_HOME = process.env.PANOPTICON_HOME || join(homedir(), '.panopticon');\n\n// Subdirectories\nexport const CONFIG_DIR = PANOPTICON_HOME;\nexport const SKILLS_DIR = join(PANOPTICON_HOME, 'skills');\nexport const COMMANDS_DIR = join(PANOPTICON_HOME, 'commands');\nexport const AGENTS_DIR = join(PANOPTICON_HOME, 'agents');\nexport const BIN_DIR = join(PANOPTICON_HOME, 'bin');\nexport const BACKUPS_DIR = join(PANOPTICON_HOME, 'backups');\nexport const COSTS_DIR = join(PANOPTICON_HOME, 'costs');\nexport const HEARTBEATS_DIR = join(PANOPTICON_HOME, 'heartbeats');\n\n// Traefik directories\nexport const TRAEFIK_DIR = join(PANOPTICON_HOME, 'traefik');\nexport const TRAEFIK_DYNAMIC_DIR = join(TRAEFIK_DIR, 'dynamic');\nexport const TRAEFIK_CERTS_DIR = join(TRAEFIK_DIR, 'certs');\n\n// Legacy certs directory (for backwards compatibility)\nexport const CERTS_DIR = join(PANOPTICON_HOME, 'certs');\n\n// Config files\nexport const CONFIG_FILE = join(CONFIG_DIR, 'config.toml');\nexport const SETTINGS_FILE = join(CONFIG_DIR, 'settings.json');\n\n// AI tool directories\nexport const CLAUDE_DIR = join(homedir(), '.claude');\nexport const CODEX_DIR = join(homedir(), '.codex');\nexport const CURSOR_DIR = join(homedir(), '.cursor');\nexport const GEMINI_DIR = join(homedir(), '.gemini');\n\n// Target sync locations\nexport const SYNC_TARGETS = {\n claude: {\n skills: join(CLAUDE_DIR, 'skills'),\n commands: join(CLAUDE_DIR, 'commands'),\n agents: join(CLAUDE_DIR, 'agents'),\n },\n codex: {\n skills: join(CODEX_DIR, 'skills'),\n commands: join(CODEX_DIR, 'commands'),\n agents: join(CODEX_DIR, 'agents'),\n },\n cursor: {\n skills: join(CURSOR_DIR, 'skills'),\n commands: join(CURSOR_DIR, 'commands'),\n agents: join(CURSOR_DIR, 'agents'),\n },\n gemini: {\n skills: join(GEMINI_DIR, 'skills'),\n commands: join(GEMINI_DIR, 'commands'),\n agents: join(GEMINI_DIR, 'agents'),\n },\n} as const;\n\nexport type Runtime = keyof typeof SYNC_TARGETS;\n\n// Templates directory (in user's ~/.panopticon)\nexport const TEMPLATES_DIR = join(PANOPTICON_HOME, 'templates');\nexport const CLAUDE_MD_TEMPLATES = join(TEMPLATES_DIR, 'claude-md', 'sections');\n\n// Source templates directory (bundled with the package)\n// This is resolved at runtime from the package root\nimport { fileURLToPath } from 'url';\nimport { dirname } from 'path';\n\nconst currentFile = fileURLToPath(import.meta.url);\nconst currentDir = dirname(currentFile);\n\n// Handle both development (src/lib/) and production (dist/) modes\n// In dev: /path/to/panopticon/src/lib/paths.ts -> /path/to/panopticon\n// In prod: /path/to/panopticon/dist/lib/paths.js -> /path/to/panopticon\nlet packageRoot: string;\nif (currentDir.includes('/src/')) {\n // Development mode - go up from src/lib to package root\n packageRoot = dirname(dirname(currentDir));\n} else {\n // Production mode - go up from dist (or dist/lib) to package root\n packageRoot = currentDir.endsWith('/lib')\n ? dirname(dirname(currentDir))\n : dirname(currentDir);\n}\n\nexport const SOURCE_TEMPLATES_DIR = join(packageRoot, 'templates');\nexport const SOURCE_TRAEFIK_TEMPLATES = join(SOURCE_TEMPLATES_DIR, 'traefik');\nexport const SOURCE_SCRIPTS_DIR = join(packageRoot, 'scripts');\nexport const SOURCE_SKILLS_DIR = join(packageRoot, 'skills');\nexport const SOURCE_DEV_SKILLS_DIR = join(packageRoot, 'dev-skills');\n\n/**\n * Detect if running in development mode (from npm link or panopticon repo)\n *\n * Dev mode is detected if:\n * 1. Running from the panopticon source directory (npm link)\n * 2. The SOURCE_DEV_SKILLS_DIR exists (only present in repo, not in npm package)\n */\nexport function isDevMode(): boolean {\n try {\n // Check if dev-skills directory exists - this is only in the repo, not npm package\n return existsSync(SOURCE_DEV_SKILLS_DIR);\n } catch {\n return false;\n }\n}\n\n// All directories to create on init\nexport const INIT_DIRS = [\n PANOPTICON_HOME,\n SKILLS_DIR,\n COMMANDS_DIR,\n AGENTS_DIR,\n BIN_DIR,\n BACKUPS_DIR,\n COSTS_DIR,\n HEARTBEATS_DIR,\n TEMPLATES_DIR,\n CLAUDE_MD_TEMPLATES,\n CERTS_DIR,\n TRAEFIK_DIR,\n TRAEFIK_DYNAMIC_DIR,\n TRAEFIK_CERTS_DIR,\n];\n","import { readFileSync, writeFileSync, existsSync } from 'fs';\nimport { SETTINGS_FILE } from './paths.js';\n\n// Model identifiers\nexport type AnthropicModel = 'claude-opus-4-5' | 'claude-sonnet-4-5' | 'claude-haiku-4-5';\nexport type OpenAIModel = 'gpt-5.2-codex' | 'o3-deep-research' | 'gpt-4o' | 'gpt-4o-mini';\nexport type GoogleModel = 'gemini-3-pro-preview' | 'gemini-3-flash-preview' | 'gemini-2.5-pro' | 'gemini-2.5-flash';\nexport type ZAIModel = 'glm-4.7' | 'glm-4.7-flash';\nexport type KimiModel = 'kimi-k2' | 'kimi-k2.5';\nexport type ModelId = AnthropicModel | OpenAIModel | GoogleModel | ZAIModel | KimiModel;\n\n// Task complexity levels\nexport type ComplexityLevel = 'trivial' | 'simple' | 'medium' | 'complex' | 'expert';\n\n// Specialist agent types\nexport interface SpecialistModels {\n review_agent: ModelId;\n test_agent: ModelId;\n merge_agent: ModelId;\n}\n\n// Complexity-based model mapping\nexport type ComplexityModels = {\n [K in ComplexityLevel]: ModelId;\n};\n\n// All model configuration\nexport interface ModelsConfig {\n specialists: SpecialistModels;\n planning_agent: ModelId;\n complexity: ComplexityModels;\n}\n\n// API keys for external providers\nexport interface ApiKeysConfig {\n openai?: string;\n google?: string;\n zai?: string;\n kimi?: string;\n}\n\n// Complete settings structure\nexport interface SettingsConfig {\n models: ModelsConfig;\n api_keys: ApiKeysConfig;\n}\n\n// Default settings (Kimi K2.5 for all work types)\nconst DEFAULT_SETTINGS: SettingsConfig = {\n models: {\n specialists: {\n review_agent: 'kimi-k2.5',\n test_agent: 'kimi-k2.5',\n merge_agent: 'kimi-k2.5',\n },\n planning_agent: 'kimi-k2.5',\n complexity: {\n trivial: 'kimi-k2.5',\n simple: 'kimi-k2.5',\n medium: 'kimi-k2.5',\n complex: 'kimi-k2.5',\n expert: 'kimi-k2.5',\n },\n },\n api_keys: {},\n};\n\n/**\n * Deep merge utility that recursively merges objects.\n * - Recursively merges nested objects\n * - User values take precedence over defaults\n */\nfunction deepMerge<T extends object>(defaults: T, overrides: Partial<T>): T {\n const result = { ...defaults };\n\n for (const key of Object.keys(overrides) as (keyof T)[]) {\n const defaultVal = defaults[key];\n const overrideVal = overrides[key];\n\n // Skip undefined values in overrides\n if (overrideVal === undefined) continue;\n\n // Deep merge if both values are non-array objects\n if (\n typeof defaultVal === 'object' &&\n defaultVal !== null &&\n !Array.isArray(defaultVal) &&\n typeof overrideVal === 'object' &&\n overrideVal !== null &&\n !Array.isArray(overrideVal)\n ) {\n result[key] = deepMerge(defaultVal, overrideVal as any);\n } else {\n // For primitives or null - override wins\n result[key] = overrideVal as T[keyof T];\n }\n }\n\n return result;\n}\n\n/**\n * Load settings from ~/.panopticon/settings.json\n * Returns default settings if file doesn't exist or is invalid\n * Also loads API keys from environment variables as fallback\n */\nexport function loadSettings(): SettingsConfig {\n let settings: SettingsConfig;\n\n if (!existsSync(SETTINGS_FILE)) {\n settings = getDefaultSettings();\n } else {\n try {\n const content = readFileSync(SETTINGS_FILE, 'utf8');\n const parsed = JSON.parse(content) as Partial<SettingsConfig>;\n settings = deepMerge(DEFAULT_SETTINGS, parsed);\n } catch (error) {\n console.error('Warning: Failed to parse settings.json, using defaults');\n settings = getDefaultSettings();\n }\n }\n\n // Load API keys from environment variables as fallback\n // This allows using ~/.panopticon.env for API keys\n const envApiKeys: ApiKeysConfig = {};\n if (process.env.OPENAI_API_KEY) envApiKeys.openai = process.env.OPENAI_API_KEY;\n if (process.env.GOOGLE_API_KEY) envApiKeys.google = process.env.GOOGLE_API_KEY;\n if (process.env.ZAI_API_KEY) envApiKeys.zai = process.env.ZAI_API_KEY;\n if (process.env.KIMI_API_KEY) envApiKeys.kimi = process.env.KIMI_API_KEY;\n\n // Merge env vars as fallback (settings.json takes precedence)\n settings.api_keys = {\n ...envApiKeys,\n ...settings.api_keys,\n };\n\n return settings;\n}\n\n/**\n * Save settings to ~/.panopticon/settings.json\n * Writes with pretty formatting (2-space indent)\n */\nexport function saveSettings(settings: SettingsConfig): void {\n const content = JSON.stringify(settings, null, 2);\n writeFileSync(SETTINGS_FILE, content, 'utf8');\n}\n\n/**\n * Validate settings structure and model IDs\n * Returns error message if invalid, null if valid\n */\nexport function validateSettings(settings: SettingsConfig): string | null {\n // Validate models structure\n if (!settings.models) {\n return 'Missing models configuration';\n }\n\n // Validate specialists\n if (!settings.models.specialists) {\n return 'Missing specialists configuration';\n }\n const specialists = settings.models.specialists;\n if (!specialists.review_agent || !specialists.test_agent || !specialists.merge_agent) {\n return 'Missing specialist agent model configuration';\n }\n\n // Validate planning agent\n if (!settings.models.planning_agent) {\n return 'Missing planning_agent configuration';\n }\n\n // Validate complexity levels\n if (!settings.models.complexity) {\n return 'Missing complexity configuration';\n }\n const complexity = settings.models.complexity;\n const requiredLevels: ComplexityLevel[] = ['trivial', 'simple', 'medium', 'complex', 'expert'];\n for (const level of requiredLevels) {\n if (!complexity[level]) {\n return `Missing complexity level: ${level}`;\n }\n }\n\n // Validate api_keys structure (optional keys)\n if (!settings.api_keys) {\n return 'Missing api_keys configuration';\n }\n\n return null;\n}\n\n/**\n * Get a deep copy of the default settings\n */\nexport function getDefaultSettings(): SettingsConfig {\n return JSON.parse(JSON.stringify(DEFAULT_SETTINGS));\n}\n\n/**\n * Get available models for a provider based on configured API keys\n * Returns empty array if provider API key is not configured\n */\nexport function getAvailableModels(settings: SettingsConfig): {\n anthropic: AnthropicModel[];\n openai: OpenAIModel[];\n google: GoogleModel[];\n zai: ZAIModel[];\n kimi: KimiModel[];\n} {\n const anthropicModels: AnthropicModel[] = [\n 'claude-opus-4-5',\n 'claude-sonnet-4-5',\n 'claude-haiku-4-5',\n ];\n\n const openaiModels: OpenAIModel[] = settings.api_keys.openai\n ? ['gpt-5.2-codex', 'o3-deep-research', 'gpt-4o', 'gpt-4o-mini']\n : [];\n\n const googleModels: GoogleModel[] = settings.api_keys.google\n ? ['gemini-3-pro-preview', 'gemini-3-flash-preview']\n : [];\n\n const zaiModels: ZAIModel[] = settings.api_keys.zai\n ? ['glm-4.7', 'glm-4.7-flash']\n : [];\n\n const kimiModels: KimiModel[] = settings.api_keys.kimi\n ? ['kimi-k2', 'kimi-k2.5']\n : [];\n\n return {\n anthropic: anthropicModels,\n openai: openaiModels,\n google: googleModels,\n zai: zaiModels,\n kimi: kimiModels,\n };\n}\n","/**\r\n * Provider Configuration and Compatibility\r\n *\r\n * Defines which LLM providers are compatible with Claude Code's API format.\r\n * - Direct providers: Implement Anthropic-compatible API (no router needed)\r\n * - Router providers: Require claude-code-router for API translation\r\n */\r\n\r\nimport type { ModelId, AnthropicModel, OpenAIModel, GoogleModel, ZAIModel } from './settings.js';\r\n\r\nexport type ProviderName = 'anthropic' | 'kimi' | 'openai' | 'google' | 'zai';\r\n\r\n/**\r\n * Provider compatibility types\r\n * - direct: Anthropic-compatible API, use ANTHROPIC_BASE_URL directly\r\n * - router: Incompatible API, requires claude-code-router for translation\r\n */\r\nexport type ProviderCompatibility = 'direct' | 'router';\r\n\r\n/**\r\n * Provider configuration\r\n */\r\nexport interface ProviderConfig {\r\n name: ProviderName;\r\n displayName: string;\r\n compatibility: ProviderCompatibility;\r\n baseUrl?: string; // For direct providers\r\n models: ModelId[];\r\n tested: boolean; // Whether compatibility has been verified\r\n description: string;\r\n}\r\n\r\n/**\r\n * All provider configurations\r\n */\r\nexport const PROVIDERS: Record<ProviderName, ProviderConfig> = {\r\n anthropic: {\r\n name: 'anthropic',\r\n displayName: 'Anthropic',\r\n compatibility: 'direct',\r\n models: ['claude-opus-4-5', 'claude-sonnet-4-5', 'claude-haiku-4-5'],\r\n tested: true,\r\n description: 'Native Claude API',\r\n },\r\n\r\n kimi: {\r\n name: 'kimi',\r\n displayName: 'Kimi (Moonshot AI)',\r\n compatibility: 'direct',\r\n baseUrl: 'https://api.kimi.com/coding/',\r\n models: [], // Kimi uses same model names as Anthropic\r\n tested: true,\r\n description: 'Anthropic-compatible API, tested 2026-01-28',\r\n },\r\n\r\n zai: {\r\n name: 'zai',\r\n displayName: 'Z.AI (GLM)',\r\n compatibility: 'direct',\r\n baseUrl: 'https://api.z.ai/api/anthropic',\r\n models: ['glm-4.7', 'glm-4.7-flash'],\r\n tested: true,\r\n description: 'Anthropic-compatible API, tested 2026-01-28',\r\n },\r\n\r\n openai: {\r\n name: 'openai',\r\n displayName: 'OpenAI',\r\n compatibility: 'router',\r\n models: ['gpt-5.2-codex', 'o3-deep-research', 'gpt-4o', 'gpt-4o-mini'],\r\n tested: false,\r\n description: 'Requires claude-code-router for API translation',\r\n },\r\n\r\n google: {\r\n name: 'google',\r\n displayName: 'Google (Gemini)',\r\n compatibility: 'router',\r\n models: ['gemini-3-pro-preview', 'gemini-3-flash-preview'],\r\n tested: false,\r\n description: 'Requires claude-code-router for API translation',\r\n },\r\n};\r\n\r\n/**\r\n * Get provider for a given model ID\r\n */\r\nexport function getProviderForModel(modelId: ModelId): ProviderConfig {\r\n // Check Anthropic models\r\n if (['claude-opus-4-5', 'claude-sonnet-4-5', 'claude-haiku-4-5'].includes(modelId)) {\r\n return PROVIDERS.anthropic;\r\n }\r\n\r\n // Check OpenAI models\r\n if (['gpt-5.2-codex', 'o3-deep-research', 'gpt-4o', 'gpt-4o-mini'].includes(modelId)) {\r\n return PROVIDERS.openai;\r\n }\r\n\r\n // Check Google models\r\n if (['gemini-3-pro-preview', 'gemini-3-flash-preview'].includes(modelId)) {\r\n return PROVIDERS.google;\r\n }\r\n\r\n // Check Z.AI models\r\n if (['glm-4.7', 'glm-4.7-flash'].includes(modelId)) {\r\n return PROVIDERS.zai;\r\n }\r\n\r\n // Check Kimi models\r\n if (['kimi-k2', 'kimi-k2.5'].includes(modelId)) {\r\n return PROVIDERS.kimi;\r\n }\r\n\r\n // Default to Anthropic if unknown\r\n return PROVIDERS.anthropic;\r\n}\r\n\r\n/**\r\n * Check if a provider requires claude-code-router\r\n */\r\nexport function requiresRouter(provider: ProviderName): boolean {\r\n return PROVIDERS[provider].compatibility === 'router';\r\n}\r\n\r\n/**\r\n * Get all providers that require router (have router compatibility)\r\n */\r\nexport function getRouterProviders(): ProviderConfig[] {\r\n return Object.values(PROVIDERS).filter(p => p.compatibility === 'router');\r\n}\r\n\r\n/**\r\n * Get all direct-compatible providers\r\n */\r\nexport function getDirectProviders(): ProviderConfig[] {\r\n return Object.values(PROVIDERS).filter(p => p.compatibility === 'direct');\r\n}\r\n\r\n/**\r\n * Check if any configured providers require router\r\n * Used to determine if router installation is needed\r\n */\r\nexport function needsRouter(apiKeys: { openai?: string; google?: string; zai?: string }): boolean {\r\n return !!(apiKeys.openai || apiKeys.google);\r\n}\r\n\r\n/**\r\n * Get environment variables for spawning agent with specific provider\r\n */\r\nexport function getProviderEnv(\r\n provider: ProviderConfig,\r\n apiKey: string\r\n): Record<string, string> {\r\n if (provider.compatibility === 'direct') {\r\n // Direct providers use ANTHROPIC_BASE_URL\r\n const env: Record<string, string> = {};\r\n\r\n if (provider.baseUrl) {\r\n env.ANTHROPIC_BASE_URL = provider.baseUrl;\r\n }\r\n\r\n if (provider.name !== 'anthropic') {\r\n // Non-Anthropic providers need auth token\r\n env.ANTHROPIC_AUTH_TOKEN = apiKey;\r\n }\r\n\r\n // Z.AI recommends longer timeout\r\n if (provider.name === 'zai') {\r\n env.API_TIMEOUT_MS = '300000';\r\n }\r\n\r\n return env;\r\n } else {\r\n // Router providers use local router proxy\r\n return {\r\n ANTHROPIC_BASE_URL: 'http://localhost:3456',\r\n ANTHROPIC_AUTH_TOKEN: 'router-managed',\r\n };\r\n }\r\n}\r\n"],"mappings":"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","names":["existsSync","existsSync"]}