agent-termo 0.0.0-stage → 1.0.1

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 (56) hide show
  1. package/.claude/agents/backend-architecture-designer.md +1250 -0
  2. package/.claude/agents/backend-expert.md +1731 -0
  3. package/.claude/agents/deployment-expert.md +1126 -0
  4. package/.claude/agents/dev-environment-initiator.md +788 -0
  5. package/.claude/agents/frontend-expert.md +1343 -0
  6. package/.claude/agents/frontend-planner.md +1044 -0
  7. package/.claude/agents/git-manager.md +811 -0
  8. package/.claude/agents/project-manager.md +843 -0
  9. package/.claude/agents/security-expert.md +835 -0
  10. package/.claude/agents/tech-stack-expert.md +1357 -0
  11. package/.claude/agents/test-agent.md +1372 -0
  12. package/.claude/agents/uiux-designer.md +955 -0
  13. package/.claude/commands/build.md +5 -0
  14. package/.claude/commands/deploy.md +3 -0
  15. package/.claude/commands/feature.md +3 -0
  16. package/.claude/commands/fix.md +3 -0
  17. package/.claude/skills/pdf-reader/.skillfish.json +10 -0
  18. package/.claude/skills/pdf-reader/SKILL.md +94 -0
  19. package/.claude/skills/pdf-reader/pdf-reader +203 -0
  20. package/README.md +163 -3
  21. package/dist/.claude/agents/backend-architecture-designer.md +1250 -0
  22. package/dist/.claude/agents/backend-expert.md +1731 -0
  23. package/dist/.claude/agents/deployment-expert.md +1126 -0
  24. package/dist/.claude/agents/dev-environment-initiator.md +788 -0
  25. package/dist/.claude/agents/frontend-expert.md +1343 -0
  26. package/dist/.claude/agents/frontend-planner.md +1044 -0
  27. package/dist/.claude/agents/git-manager.md +811 -0
  28. package/dist/.claude/agents/project-manager.md +843 -0
  29. package/dist/.claude/agents/security-expert.md +835 -0
  30. package/dist/.claude/agents/tech-stack-expert.md +1357 -0
  31. package/dist/.claude/agents/test-agent.md +1372 -0
  32. package/dist/.claude/agents/uiux-designer.md +955 -0
  33. package/dist/.claude/commands/build.md +5 -0
  34. package/dist/.claude/commands/deploy.md +3 -0
  35. package/dist/.claude/commands/feature.md +3 -0
  36. package/dist/.claude/commands/fix.md +3 -0
  37. package/dist/.claude/skills/pdf-reader/.skillfish.json +10 -0
  38. package/dist/.claude/skills/pdf-reader/SKILL.md +94 -0
  39. package/dist/.claude/skills/pdf-reader/pdf-reader +203 -0
  40. package/dist/cli.js +210 -0
  41. package/dist/cli.js.map +7 -0
  42. package/dist/main.js +173 -0
  43. package/dist/main.js.map +7 -0
  44. package/package.json +90 -6
  45. package/src/agents/index.ts +94 -0
  46. package/src/cli.ts +155 -0
  47. package/src/diff/index.ts +255 -0
  48. package/src/llm/client.ts +192 -0
  49. package/src/llm/tools.ts +206 -0
  50. package/src/main.ts +427 -0
  51. package/src/memory/index.ts +130 -0
  52. package/src/tools/index.ts +371 -0
  53. package/src/types/index.ts +151 -0
  54. package/src/ui/index.ts +519 -0
  55. package/src/utils/ansi.ts +134 -0
  56. package/src/utils/config.ts +118 -0
@@ -0,0 +1,118 @@
1
+ // =============================================================================
2
+ // Config Management
3
+ // =============================================================================
4
+
5
+ import { chmodSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
6
+ import { resolve, dirname } from 'node:path';
7
+ import { fileURLToPath } from 'node:url';
8
+ import type { AppConfig } from '../types/index.js';
9
+
10
+ // Find project root reliably (works even when cwd != project dir)
11
+ function getProjectRoot(): string {
12
+ // Try import.meta.url first (ESM)
13
+ try {
14
+ const thisFile = fileURLToPath(import.meta.url);
15
+ return dirname(dirname(thisFile)); // src/utils/ → src/ → project root
16
+ } catch {
17
+ // Fall back to process.cwd()
18
+ return process.cwd();
19
+ }
20
+ }
21
+
22
+ // Load .env files at startup
23
+ function loadEnvFile(envPath: string): void {
24
+ try {
25
+ const content = readFileSync(envPath, 'utf-8');
26
+ for (const line of content.split('\n')) {
27
+ const trimmed = line.trim();
28
+ if (!trimmed || trimmed.startsWith('#')) continue;
29
+ const eqIdx = trimmed.indexOf('=');
30
+ if (eqIdx === -1 || eqIdx === trimmed.length - 1) continue;
31
+ const key = trimmed.slice(0, eqIdx).trim();
32
+ const value = trimmed.slice(eqIdx + 1).trim().replace(/^["']|["']$/g, '');
33
+ if (!process.env[key]) process.env[key] = value;
34
+ }
35
+ } catch {
36
+ // file not found — continue silently
37
+ }
38
+ }
39
+
40
+ // Load .env from project root and current directory
41
+ const PROJECT_ROOT = getProjectRoot();
42
+ loadEnvFile(resolve(PROJECT_ROOT, '.env'));
43
+ loadEnvFile(resolve('.env')); // also try cwd
44
+
45
+ export { PROJECT_ROOT };
46
+
47
+ export function getAgentTermoDir(): string {
48
+ const envDir = process.env.AGENT_TERMO_DIR;
49
+ if (envDir) {
50
+ return resolve(process.env.HOME || process.env.USERPROFILE || '.', envDir);
51
+ }
52
+ return resolve(process.env.HOME || process.env.USERPROFILE || '.', '.agent-termo');
53
+ }
54
+
55
+ function loadStoredNimApiKey(): void {
56
+ if (process.env.NIM_API_KEY) return;
57
+
58
+ try {
59
+ const stored = JSON.parse(
60
+ readFileSync(resolve(getAgentTermoDir(), 'config.json'), 'utf-8'),
61
+ ) as { nimApiKey?: unknown };
62
+
63
+ if (typeof stored.nimApiKey === 'string' && stored.nimApiKey.trim()) {
64
+ process.env.NIM_API_KEY = stored.nimApiKey;
65
+ }
66
+ } catch {
67
+ // No saved user configuration yet.
68
+ }
69
+ }
70
+
71
+ export function saveNimApiKey(apiKey: string): void {
72
+ const configDir = getAgentTermoDir();
73
+ const configPath = resolve(configDir, 'config.json');
74
+ let storedConfig: Record<string, unknown> = {};
75
+
76
+ try {
77
+ const existing: unknown = JSON.parse(readFileSync(configPath, 'utf-8'));
78
+ if (existing && typeof existing === 'object' && !Array.isArray(existing)) {
79
+ storedConfig = existing as Record<string, unknown>;
80
+ }
81
+ } catch {
82
+ // Create a new configuration file when one does not exist.
83
+ }
84
+
85
+ storedConfig.nimApiKey = apiKey;
86
+ mkdirSync(configDir, { recursive: true, mode: 0o700 });
87
+ writeFileSync(configPath, `${JSON.stringify(storedConfig, null, 2)}\n`, {
88
+ encoding: 'utf-8',
89
+ mode: 0o600,
90
+ });
91
+
92
+ // Restrict permissions even when updating an existing file on Unix.
93
+ if (process.platform !== 'win32') chmodSync(configPath, 0o600);
94
+ }
95
+
96
+ loadStoredNimApiKey();
97
+
98
+ export function getConfig(projectRoot: string): AppConfig {
99
+ loadEnvFile(resolve(projectRoot, '.env'));
100
+
101
+ return {
102
+ nimApiKey: process.env.NIM_API_KEY ?? '',
103
+ nimBaseUrl: process.env.NIM_BASE_URL ?? 'https://integrate.api.nvidia.com/v1',
104
+ nimModel: process.env.NIM_MODEL ?? 'stepfun-ai/step-3.7-flash',
105
+ agentTermoDir: process.env.AGENT_TERMO_DIR ?? '.claude',
106
+ logLevel: (process.env.LOG_LEVEL as AppConfig['logLevel']) || 'info',
107
+ confirmDestructive: process.env.CONFIRM_DESTRUCTIVE !== 'false',
108
+ allowedCommands: (
109
+ process.env.ALLOWED_COMMANDS ?? 'git,npm,node,pnpm,yarn,tsx,tsc,npx'
110
+ ).split(','),
111
+ llmTimeout: parseInt(process.env.LLM_TIMEOUT ?? '120000', 10),
112
+ bashTimeout: parseInt(process.env.BASH_TIMEOUT ?? '300000', 10),
113
+ };
114
+ }
115
+
116
+ export function resolveProjectRoot(cwd?: string): string {
117
+ return cwd || PROJECT_ROOT;
118
+ }