@poping/yome 0.0.2

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 (156) hide show
  1. package/README.md +54 -0
  2. package/bin/yome.js +2 -0
  3. package/dist/agent.d.ts +43 -0
  4. package/dist/agent.js +140 -0
  5. package/dist/agent.js.map +1 -0
  6. package/dist/config.d.ts +41 -0
  7. package/dist/config.js +108 -0
  8. package/dist/config.js.map +1 -0
  9. package/dist/context.d.ts +1 -0
  10. package/dist/context.js +101 -0
  11. package/dist/context.js.map +1 -0
  12. package/dist/index.d.ts +1 -0
  13. package/dist/index.js +65 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/llm.d.ts +13 -0
  16. package/dist/llm.js +317 -0
  17. package/dist/llm.js.map +1 -0
  18. package/dist/loops/chain.d.ts +15 -0
  19. package/dist/loops/chain.js +105 -0
  20. package/dist/loops/chain.js.map +1 -0
  21. package/dist/loops/evaluator.d.ts +12 -0
  22. package/dist/loops/evaluator.js +100 -0
  23. package/dist/loops/evaluator.js.map +1 -0
  24. package/dist/loops/index.d.ts +12 -0
  25. package/dist/loops/index.js +39 -0
  26. package/dist/loops/index.js.map +1 -0
  27. package/dist/loops/orchestrator.d.ts +13 -0
  28. package/dist/loops/orchestrator.js +107 -0
  29. package/dist/loops/orchestrator.js.map +1 -0
  30. package/dist/loops/parallel.d.ts +6 -0
  31. package/dist/loops/parallel.js +48 -0
  32. package/dist/loops/parallel.js.map +1 -0
  33. package/dist/loops/route.d.ts +13 -0
  34. package/dist/loops/route.js +88 -0
  35. package/dist/loops/route.js.map +1 -0
  36. package/dist/loops/simple.d.ts +6 -0
  37. package/dist/loops/simple.js +46 -0
  38. package/dist/loops/simple.js.map +1 -0
  39. package/dist/loops/types.d.ts +32 -0
  40. package/dist/loops/types.js +9 -0
  41. package/dist/loops/types.js.map +1 -0
  42. package/dist/permissions/checker.d.ts +18 -0
  43. package/dist/permissions/checker.js +89 -0
  44. package/dist/permissions/checker.js.map +1 -0
  45. package/dist/permissions/index.d.ts +4 -0
  46. package/dist/permissions/index.js +4 -0
  47. package/dist/permissions/index.js.map +1 -0
  48. package/dist/permissions/loader.d.ts +22 -0
  49. package/dist/permissions/loader.js +104 -0
  50. package/dist/permissions/loader.js.map +1 -0
  51. package/dist/permissions/ruleParser.d.ts +23 -0
  52. package/dist/permissions/ruleParser.js +59 -0
  53. package/dist/permissions/ruleParser.js.map +1 -0
  54. package/dist/permissions/types.d.ts +37 -0
  55. package/dist/permissions/types.js +2 -0
  56. package/dist/permissions/types.js.map +1 -0
  57. package/dist/sessions.d.ts +20 -0
  58. package/dist/sessions.js +119 -0
  59. package/dist/sessions.js.map +1 -0
  60. package/dist/skills/index.d.ts +2 -0
  61. package/dist/skills/index.js +2 -0
  62. package/dist/skills/index.js.map +1 -0
  63. package/dist/skills/loader.d.ts +4 -0
  64. package/dist/skills/loader.js +125 -0
  65. package/dist/skills/loader.js.map +1 -0
  66. package/dist/skills/types.d.ts +22 -0
  67. package/dist/skills/types.js +2 -0
  68. package/dist/skills/types.js.map +1 -0
  69. package/dist/subagent/agentTool.d.ts +7 -0
  70. package/dist/subagent/agentTool.js +121 -0
  71. package/dist/subagent/agentTool.js.map +1 -0
  72. package/dist/subagent/builtinAgents.d.ts +3 -0
  73. package/dist/subagent/builtinAgents.js +23 -0
  74. package/dist/subagent/builtinAgents.js.map +1 -0
  75. package/dist/subagent/index.d.ts +6 -0
  76. package/dist/subagent/index.js +5 -0
  77. package/dist/subagent/index.js.map +1 -0
  78. package/dist/subagent/loadAgents.d.ts +2 -0
  79. package/dist/subagent/loadAgents.js +98 -0
  80. package/dist/subagent/loadAgents.js.map +1 -0
  81. package/dist/subagent/runAgent.d.ts +18 -0
  82. package/dist/subagent/runAgent.js +115 -0
  83. package/dist/subagent/runAgent.js.map +1 -0
  84. package/dist/subagent/types.d.ts +20 -0
  85. package/dist/subagent/types.js +2 -0
  86. package/dist/subagent/types.js.map +1 -0
  87. package/dist/toggleState.d.ts +6 -0
  88. package/dist/toggleState.js +58 -0
  89. package/dist/toggleState.js.map +1 -0
  90. package/dist/tools/bash.d.ts +2 -0
  91. package/dist/tools/bash.js +78 -0
  92. package/dist/tools/bash.js.map +1 -0
  93. package/dist/tools/edit.d.ts +2 -0
  94. package/dist/tools/edit.js +103 -0
  95. package/dist/tools/edit.js.map +1 -0
  96. package/dist/tools/glob.d.ts +2 -0
  97. package/dist/tools/glob.js +44 -0
  98. package/dist/tools/glob.js.map +1 -0
  99. package/dist/tools/grep.d.ts +2 -0
  100. package/dist/tools/grep.js +89 -0
  101. package/dist/tools/grep.js.map +1 -0
  102. package/dist/tools/index.d.ts +15 -0
  103. package/dist/tools/index.js +99 -0
  104. package/dist/tools/index.js.map +1 -0
  105. package/dist/tools/ls.d.ts +2 -0
  106. package/dist/tools/ls.js +47 -0
  107. package/dist/tools/ls.js.map +1 -0
  108. package/dist/tools/read.d.ts +2 -0
  109. package/dist/tools/read.js +52 -0
  110. package/dist/tools/read.js.map +1 -0
  111. package/dist/tools/write.d.ts +2 -0
  112. package/dist/tools/write.js +46 -0
  113. package/dist/tools/write.js.map +1 -0
  114. package/dist/types.d.ts +82 -0
  115. package/dist/types.js +13 -0
  116. package/dist/types.js.map +1 -0
  117. package/dist/ui/AgentPicker.d.ts +12 -0
  118. package/dist/ui/AgentPicker.js +32 -0
  119. package/dist/ui/AgentPicker.js.map +1 -0
  120. package/dist/ui/App.d.ts +6 -0
  121. package/dist/ui/App.js +327 -0
  122. package/dist/ui/App.js.map +1 -0
  123. package/dist/ui/Banner.d.ts +1 -0
  124. package/dist/ui/Banner.js +14 -0
  125. package/dist/ui/Banner.js.map +1 -0
  126. package/dist/ui/InputBar.d.ts +17 -0
  127. package/dist/ui/InputBar.js +93 -0
  128. package/dist/ui/InputBar.js.map +1 -0
  129. package/dist/ui/Markdown.d.ts +4 -0
  130. package/dist/ui/Markdown.js +97 -0
  131. package/dist/ui/Markdown.js.map +1 -0
  132. package/dist/ui/MessageList.d.ts +17 -0
  133. package/dist/ui/MessageList.js +50 -0
  134. package/dist/ui/MessageList.js.map +1 -0
  135. package/dist/ui/ModelPicker.d.ts +9 -0
  136. package/dist/ui/ModelPicker.js +70 -0
  137. package/dist/ui/ModelPicker.js.map +1 -0
  138. package/dist/ui/PermissionPrompt.d.ts +10 -0
  139. package/dist/ui/PermissionPrompt.js +37 -0
  140. package/dist/ui/PermissionPrompt.js.map +1 -0
  141. package/dist/ui/SessionPicker.d.ts +8 -0
  142. package/dist/ui/SessionPicker.js +64 -0
  143. package/dist/ui/SessionPicker.js.map +1 -0
  144. package/dist/ui/Spinner.d.ts +3 -0
  145. package/dist/ui/Spinner.js +15 -0
  146. package/dist/ui/Spinner.js.map +1 -0
  147. package/dist/ui/TogglePicker.d.ts +16 -0
  148. package/dist/ui/TogglePicker.js +35 -0
  149. package/dist/ui/TogglePicker.js.map +1 -0
  150. package/dist/ui/ToolResult.d.ts +6 -0
  151. package/dist/ui/ToolResult.js +59 -0
  152. package/dist/ui/ToolResult.js.map +1 -0
  153. package/dist/utils/imagePaste.d.ts +12 -0
  154. package/dist/utils/imagePaste.js +54 -0
  155. package/dist/utils/imagePaste.js.map +1 -0
  156. package/package.json +44 -0
package/README.md ADDED
@@ -0,0 +1,54 @@
1
+ # Yome CLI
2
+
3
+ AI coding agent in your terminal.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -g @sobers/yome
9
+ ```
10
+
11
+ Or run directly with npx:
12
+
13
+ ```bash
14
+ npx @sobers/yome
15
+ ```
16
+
17
+ ## Configuration
18
+
19
+ ### Environment Variables
20
+
21
+ ```bash
22
+ export YOME_BASE_URL=https://dashscope.aliyuncs.com/apps/anthropic
23
+ export YOME_API_KEY=sk-
24
+ export YOME_MODEL=qwen-plus
25
+ ```
26
+
27
+ | Variable | Description | Default |
28
+ |---|---|---|
29
+ | `YOME_API_KEY` | API key | - |
30
+ | `YOME_BASE_URL` | API base URL | `https://zenmux.ai/api` |
31
+ | `YOME_MODEL` | Model name | - |
32
+ | `YOME_PROVIDER` | API provider: `anthropic` or `openai` | auto-detected |
33
+
34
+ ### CLI Flags
35
+
36
+ ```bash
37
+ yome --key sk-xxx --base-url https://api.anthropic.com
38
+ yome --model qwen-plus --provider openai
39
+ ```
40
+
41
+ Flags will be saved to `~/.yome/config.json` for future use.
42
+
43
+ ## Usage
44
+
45
+ ```bash
46
+ # Interactive mode
47
+ yome
48
+
49
+ # With a prompt
50
+ yome "help me read package.json"
51
+
52
+ # Set config and run
53
+ yome --key sk-xxx --base-url https://dashscope.aliyuncs.com/apps/anthropic
54
+ ```
package/bin/yome.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import '../dist/index.js';
@@ -0,0 +1,43 @@
1
+ import type { ToolPermissionContext, PermissionMode } from './permissions/types.js';
2
+ import type { Skill } from './skills/index.js';
3
+ import type { AgentDefinition } from './subagent/index.js';
4
+ import type { AgentMessage } from './types.js';
5
+ import type { YomeConfig, ModelEntry } from './config.js';
6
+ import type { AgentLoopCallbacks } from './loops/index.js';
7
+ import type { PastedImage } from './utils/imagePaste.js';
8
+ export interface AgentCallbacks extends AgentLoopCallbacks {
9
+ onLoopChanged?: (name: string) => void;
10
+ onAskPermission?: (toolName: string, message: string, input: Record<string, unknown>) => Promise<boolean>;
11
+ }
12
+ export declare class Agent {
13
+ private config;
14
+ private messages;
15
+ private systemPrompt;
16
+ private skills;
17
+ private loopRegistry;
18
+ private currentLoopName;
19
+ private permissionContext;
20
+ private sessionId;
21
+ constructor(config: YomeConfig);
22
+ getSessionId(): string;
23
+ getPermissionContext(): ToolPermissionContext;
24
+ getConfig(): YomeConfig;
25
+ switchModel(entry: ModelEntry): void;
26
+ switchPermissionMode(mode: PermissionMode): void;
27
+ resetContext(): void;
28
+ restoreSession(sessionId: string): void;
29
+ getMessages(): AgentMessage[];
30
+ persistMessage(message: AgentMessage): void;
31
+ persistTitle(title: string): void;
32
+ getSkills(): Skill[];
33
+ getAgents(): AgentDefinition[];
34
+ reloadSkills(): void;
35
+ getCurrentLoopName(): string;
36
+ getAvailableLoops(): {
37
+ name: string;
38
+ description: string;
39
+ }[];
40
+ switchLoop(name: string): boolean;
41
+ private parseSkillInvocation;
42
+ run(userMessage: string, callbacks: AgentCallbacks, images?: PastedImage[]): Promise<void>;
43
+ }
package/dist/agent.js ADDED
@@ -0,0 +1,140 @@
1
+ import { buildSystemPrompt } from './context.js';
2
+ import { getAnthropicTools, executeTool, registerTool, setPermissionContext, setAskPermissionHandler } from './tools/index.js';
3
+ import { loadAllSkills } from './skills/index.js';
4
+ import { createLoopRegistry } from './loops/index.js';
5
+ import { createAgentTool, clearAgentCache, getAllAgents } from './subagent/index.js';
6
+ import { initializePermissionContext } from './permissions/loader.js';
7
+ import { modelEntryToConfig } from './config.js';
8
+ import { createSessionId, appendMessage, loadSessionMessages, setSessionTitle } from './sessions.js';
9
+ export class Agent {
10
+ config;
11
+ messages = [];
12
+ systemPrompt;
13
+ skills = [];
14
+ loopRegistry = createLoopRegistry();
15
+ currentLoopName = 'simple';
16
+ permissionContext;
17
+ sessionId;
18
+ constructor(config) {
19
+ this.config = config;
20
+ this.systemPrompt = buildSystemPrompt();
21
+ this.skills = loadAllSkills();
22
+ registerTool(createAgentTool(config));
23
+ this.permissionContext = initializePermissionContext();
24
+ setPermissionContext(this.permissionContext);
25
+ this.sessionId = createSessionId();
26
+ }
27
+ getSessionId() {
28
+ return this.sessionId;
29
+ }
30
+ getPermissionContext() {
31
+ return this.permissionContext;
32
+ }
33
+ getConfig() {
34
+ return this.config;
35
+ }
36
+ switchModel(entry) {
37
+ this.config = modelEntryToConfig(entry);
38
+ }
39
+ switchPermissionMode(mode) {
40
+ this.permissionContext = { ...this.permissionContext, mode };
41
+ setPermissionContext(this.permissionContext);
42
+ }
43
+ resetContext() {
44
+ this.messages = [];
45
+ this.systemPrompt = buildSystemPrompt();
46
+ this.skills = loadAllSkills();
47
+ clearAgentCache();
48
+ registerTool(createAgentTool(this.config));
49
+ this.sessionId = createSessionId();
50
+ }
51
+ restoreSession(sessionId) {
52
+ this.sessionId = sessionId;
53
+ this.messages = loadSessionMessages(sessionId);
54
+ this.systemPrompt = buildSystemPrompt();
55
+ this.skills = loadAllSkills();
56
+ clearAgentCache();
57
+ registerTool(createAgentTool(this.config));
58
+ }
59
+ getMessages() {
60
+ return this.messages;
61
+ }
62
+ persistMessage(message) {
63
+ appendMessage(this.sessionId, message);
64
+ }
65
+ persistTitle(title) {
66
+ setSessionTitle(this.sessionId, title);
67
+ }
68
+ getSkills() {
69
+ return loadAllSkills(true);
70
+ }
71
+ getAgents() {
72
+ return getAllAgents();
73
+ }
74
+ reloadSkills() {
75
+ this.skills = loadAllSkills();
76
+ this.systemPrompt = buildSystemPrompt();
77
+ clearAgentCache();
78
+ registerTool(createAgentTool(this.config));
79
+ }
80
+ getCurrentLoopName() {
81
+ return this.currentLoopName;
82
+ }
83
+ getAvailableLoops() {
84
+ return this.loopRegistry.list().map((l) => ({ name: l.name, description: l.description }));
85
+ }
86
+ switchLoop(name) {
87
+ const loop = this.loopRegistry.get(name);
88
+ if (!loop)
89
+ return false;
90
+ this.currentLoopName = name;
91
+ return true;
92
+ }
93
+ parseSkillInvocation(input) {
94
+ const trimmed = input.trim();
95
+ if (!trimmed.startsWith('/'))
96
+ return null;
97
+ const spaceIdx = trimmed.indexOf(' ');
98
+ const name = spaceIdx === -1 ? trimmed.slice(1) : trimmed.slice(1, spaceIdx);
99
+ const args = spaceIdx === -1 ? '' : trimmed.slice(spaceIdx + 1).trim();
100
+ const skill = this.skills.find((s) => s.name === name);
101
+ if (!skill)
102
+ return null;
103
+ return { skill, args };
104
+ }
105
+ async run(userMessage, callbacks, images) {
106
+ if (callbacks.onAskPermission) {
107
+ setAskPermissionHandler(callbacks.onAskPermission);
108
+ }
109
+ // Handle skill invocation
110
+ const skillInvocation = this.parseSkillInvocation(userMessage);
111
+ let effectiveMessage = userMessage;
112
+ if (skillInvocation) {
113
+ const { skill, args } = skillInvocation;
114
+ effectiveMessage = `[Skill: /${skill.name}]\n\n${skill.getPrompt(args)}`;
115
+ }
116
+ // Build user input: plain string or content blocks with images
117
+ let userInput;
118
+ if (images && images.length > 0) {
119
+ const blocks = images.map((img) => ({
120
+ type: 'image',
121
+ source: { type: 'base64', media_type: img.mediaType, data: img.base64 },
122
+ }));
123
+ blocks.push({ type: 'text', text: effectiveMessage });
124
+ userInput = blocks;
125
+ }
126
+ else {
127
+ userInput = effectiveMessage;
128
+ }
129
+ const loop = this.loopRegistry.get(this.currentLoopName) ?? this.loopRegistry.default();
130
+ const tools = getAnthropicTools();
131
+ await loop.run(userInput, {
132
+ config: this.config,
133
+ systemPrompt: this.systemPrompt,
134
+ messages: this.messages,
135
+ tools,
136
+ executeTool,
137
+ }, callbacks);
138
+ }
139
+ }
140
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ export interface YomeConfig {
2
+ apiKey: string;
3
+ baseUrl: string;
4
+ model?: string;
5
+ provider: 'anthropic' | 'openai';
6
+ }
7
+ export interface ModelEntry {
8
+ id: string;
9
+ displayName: string;
10
+ model: string;
11
+ baseUrl: string;
12
+ apiKey: string;
13
+ provider: 'anthropic' | 'openai';
14
+ maxOutputTokens?: number;
15
+ }
16
+ interface StoredConfig {
17
+ apiKey?: string;
18
+ baseUrl?: string;
19
+ model?: string;
20
+ provider?: 'anthropic' | 'openai';
21
+ }
22
+ export declare function loadStoredConfig(): StoredConfig;
23
+ export declare function saveStoredConfig(updates: Partial<StoredConfig>): void;
24
+ export declare const CONFIG_PATH: string;
25
+ export declare function detectProvider(baseUrl: string): 'anthropic' | 'openai';
26
+ export declare function resolveConfig(flags: {
27
+ key?: string;
28
+ baseUrl?: string;
29
+ model?: string;
30
+ provider?: string;
31
+ }): YomeConfig;
32
+ export declare function getVersion(): string;
33
+ /**
34
+ * Load custom model entries from ~/.yome/settings.json.
35
+ */
36
+ export declare function loadModelEntries(): ModelEntry[];
37
+ /**
38
+ * Convert a ModelEntry to a YomeConfig (for hot-swapping).
39
+ */
40
+ export declare function modelEntryToConfig(entry: ModelEntry): YomeConfig;
41
+ export {};
package/dist/config.js ADDED
@@ -0,0 +1,108 @@
1
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { homedir } from 'os';
4
+ import { resolve } from 'path';
5
+ const CONFIG_DIR = join(homedir(), '.yome');
6
+ const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
7
+ export function loadStoredConfig() {
8
+ try {
9
+ return JSON.parse(readFileSync(CONFIG_FILE, 'utf-8'));
10
+ }
11
+ catch {
12
+ return {};
13
+ }
14
+ }
15
+ export function saveStoredConfig(updates) {
16
+ mkdirSync(CONFIG_DIR, { recursive: true });
17
+ const existing = loadStoredConfig();
18
+ const merged = { ...existing, ...updates };
19
+ writeFileSync(CONFIG_FILE, JSON.stringify(merged, null, 2), 'utf-8');
20
+ }
21
+ export const CONFIG_PATH = CONFIG_FILE;
22
+ const DEFAULT_BASE_URL = 'https://zenmux.ai/api';
23
+ const OPENAI_COMPATIBLE_HOSTS = [
24
+ 'api.openai.com', 'api.deepseek.com', 'api.groq.com',
25
+ 'api.together.xyz', 'openrouter.ai',
26
+ ];
27
+ const OPENAI_COMPATIBLE_PATHS = ['/compatible-mode', '/v1/chat'];
28
+ export function detectProvider(baseUrl) {
29
+ try {
30
+ const url = new URL(baseUrl);
31
+ const isOpenAIHost = OPENAI_COMPATIBLE_HOSTS.some((h) => url.hostname.includes(h));
32
+ const isOpenAIPath = OPENAI_COMPATIBLE_PATHS.some((p) => url.pathname.includes(p));
33
+ if (isOpenAIHost || isOpenAIPath)
34
+ return 'openai';
35
+ }
36
+ catch { /* invalid URL */ }
37
+ return 'anthropic';
38
+ }
39
+ export function resolveConfig(flags) {
40
+ const stored = loadStoredConfig();
41
+ const apiKey = flags.key || process.env.YOME_API_KEY || stored.apiKey || '';
42
+ const baseUrl = (flags.baseUrl || process.env.YOME_BASE_URL || stored.baseUrl || DEFAULT_BASE_URL).replace(/\/+$/, '');
43
+ const model = flags.model || process.env.YOME_MODEL || stored.model;
44
+ const providerRaw = flags.provider || process.env.YOME_PROVIDER || stored.provider;
45
+ let provider;
46
+ if (providerRaw === 'openai' || providerRaw === 'anthropic') {
47
+ provider = providerRaw;
48
+ }
49
+ else {
50
+ provider = detectProvider(baseUrl);
51
+ }
52
+ return { apiKey, baseUrl, model, provider };
53
+ }
54
+ let _pkgVersion;
55
+ export function getVersion() {
56
+ if (_pkgVersion)
57
+ return _pkgVersion;
58
+ try {
59
+ const pkg = JSON.parse(readFileSync(resolve(__dirname, '../package.json'), 'utf-8'));
60
+ _pkgVersion = pkg.version || '0.1.0';
61
+ }
62
+ catch {
63
+ _pkgVersion = '0.1.0';
64
+ }
65
+ return _pkgVersion;
66
+ }
67
+ const SETTINGS_FILE = join(CONFIG_DIR, 'settings.json');
68
+ /**
69
+ * Load custom model entries from ~/.yome/settings.json.
70
+ */
71
+ export function loadModelEntries() {
72
+ try {
73
+ if (!existsSync(SETTINGS_FILE))
74
+ return [];
75
+ const raw = readFileSync(SETTINGS_FILE, 'utf-8').trim();
76
+ if (!raw)
77
+ return [];
78
+ const data = JSON.parse(raw);
79
+ if (!Array.isArray(data.customModels))
80
+ return [];
81
+ return data.customModels
82
+ .filter((m) => m.model && m.baseUrl && m.apiKey)
83
+ .map((m) => ({
84
+ id: m.id ?? m.model,
85
+ displayName: m.displayName ?? m.model,
86
+ model: m.model,
87
+ baseUrl: m.baseUrl.replace(/\/+$/, ''),
88
+ apiKey: m.apiKey,
89
+ provider: (m.provider === 'openai' ? 'openai' : 'anthropic'),
90
+ maxOutputTokens: m.maxOutputTokens,
91
+ }));
92
+ }
93
+ catch {
94
+ return [];
95
+ }
96
+ }
97
+ /**
98
+ * Convert a ModelEntry to a YomeConfig (for hot-swapping).
99
+ */
100
+ export function modelEntryToConfig(entry) {
101
+ return {
102
+ apiKey: entry.apiKey,
103
+ baseUrl: entry.baseUrl,
104
+ model: entry.model,
105
+ provider: entry.provider,
106
+ };
107
+ }
108
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAE7B,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;AAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AA0BpD,MAAM,UAAU,gBAAgB;IAC9B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAA8B;IAC7D,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,gBAAgB,EAAE,CAAC;IACpC,MAAM,MAAM,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,OAAO,EAAE,CAAC;IAC3C,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,WAAW,CAAC;AAEvC,MAAM,gBAAgB,GAAG,uBAAuB,CAAC;AAEjD,MAAM,uBAAuB,GAAG;IAC9B,gBAAgB,EAAE,kBAAkB,EAAE,cAAc;IACpD,kBAAkB,EAAE,eAAe;CACpC,CAAC;AACF,MAAM,uBAAuB,GAAG,CAAC,kBAAkB,EAAE,UAAU,CAAC,CAAC;AAEjE,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;QAC7B,MAAM,YAAY,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QACnF,MAAM,YAAY,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QACnF,IAAI,YAAY,IAAI,YAAY;YAAE,OAAO,QAAQ,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;IAC7B,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAK7B;IACC,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAElC,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;IAC5E,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,MAAM,CAAC,OAAO,IAAI,gBAAgB,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACvH,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,MAAM,CAAC,KAAK,CAAC;IAEpE,MAAM,WAAW,GAAG,KAAK,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,MAAM,CAAC,QAAQ,CAAC;IACnF,IAAI,QAAgC,CAAC;IACrC,IAAI,WAAW,KAAK,QAAQ,IAAI,WAAW,KAAK,WAAW,EAAE,CAAC;QAC5D,QAAQ,GAAG,WAAW,CAAC;IACzB,CAAC;SAAM,CAAC;QACN,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AAC9C,CAAC;AAED,IAAI,WAA+B,CAAC;AACpC,MAAM,UAAU,UAAU;IACxB,IAAI,WAAW;QAAE,OAAO,WAAW,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;QACrF,WAAW,GAAG,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,WAAW,GAAG,OAAO,CAAC;IACxB,CAAC;IACD,OAAO,WAAY,CAAC;AACtB,CAAC;AAED,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;AAexD;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;YAAE,OAAO,EAAE,CAAC;QAC1C,MAAM,GAAG,GAAG,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QACxD,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,GAAiB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC;YAAE,OAAO,EAAE,CAAC;QAEjD,OAAO,IAAI,CAAC,YAAY;aACrB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,CAAC;aAC/C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACX,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAM;YACpB,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,KAAM;YACtC,KAAK,EAAE,CAAC,CAAC,KAAM;YACf,OAAO,EAAE,CAAC,CAAC,OAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YACvC,MAAM,EAAE,CAAC,CAAC,MAAO;YACjB,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAA2B;YACtF,eAAe,EAAE,CAAC,CAAC,eAAe;SACnC,CAAC,CAAC,CAAC;IACR,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAiB;IAClD,OAAO;QACL,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ;KACzB,CAAC;AACJ,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function buildSystemPrompt(): string;
@@ -0,0 +1,101 @@
1
+ import { execSync } from 'child_process';
2
+ import { readdirSync } from 'fs';
3
+ import { join, basename } from 'path';
4
+ import { loadAllSkills } from './skills/index.js';
5
+ function safeExec(cmd, cwd) {
6
+ try {
7
+ return execSync(cmd, { cwd, timeout: 5000, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
8
+ }
9
+ catch {
10
+ return null;
11
+ }
12
+ }
13
+ function getFileTree(dir, depth = 2, prefix = '') {
14
+ if (depth < 0)
15
+ return '';
16
+ const lines = [];
17
+ try {
18
+ const entries = readdirSync(dir, { withFileTypes: true });
19
+ const filtered = entries.filter((e) => !e.name.startsWith('.') && e.name !== 'node_modules' && e.name !== '__pycache__');
20
+ for (const entry of filtered.slice(0, 30)) {
21
+ const isDir = entry.isDirectory();
22
+ lines.push(`${prefix}${entry.name}${isDir ? '/' : ''}`);
23
+ if (isDir && depth > 0) {
24
+ lines.push(getFileTree(join(dir, entry.name), depth - 1, prefix + ' '));
25
+ }
26
+ }
27
+ if (filtered.length > 30)
28
+ lines.push(`${prefix}... (${filtered.length - 30} more)`);
29
+ }
30
+ catch { /* ignore */ }
31
+ return lines.filter(Boolean).join('\n');
32
+ }
33
+ export function buildSystemPrompt() {
34
+ const cwd = process.cwd();
35
+ const projectName = basename(cwd);
36
+ const now = new Date();
37
+ const dateStr = now.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric', weekday: 'long' });
38
+ const gitBranch = safeExec('git rev-parse --abbrev-ref HEAD', cwd);
39
+ const gitStatus = safeExec('git status --porcelain', cwd);
40
+ const isGit = gitBranch !== null;
41
+ const tree = getFileTree(cwd);
42
+ let prompt = `You are Yome, an AI coding assistant running in the user's terminal.
43
+ You help with software engineering tasks: reading code, writing code, debugging, refactoring, and running commands.
44
+
45
+ ## Environment
46
+ - Date: ${dateStr}
47
+ - Working directory: ${cwd}
48
+ - Project: ${projectName}
49
+ - OS: ${process.platform} ${process.arch}
50
+ - Node: ${process.version}
51
+ `;
52
+ if (isGit) {
53
+ prompt += `- Git branch: ${gitBranch}\n`;
54
+ if (gitStatus) {
55
+ const statusLines = gitStatus.split('\n').slice(0, 20);
56
+ prompt += `- Git status:\n${statusLines.map((l) => ` ${l}`).join('\n')}\n`;
57
+ }
58
+ }
59
+ if (tree) {
60
+ prompt += `\n## Project Structure\n\`\`\`\n${tree}\n\`\`\`\n`;
61
+ }
62
+ prompt += `
63
+ ## Guidelines
64
+ - Use absolute paths when calling tools.
65
+ - Read files before editing them.
66
+ - Be concise in responses.
67
+ - When editing code, preserve the existing style and patterns.
68
+ - NEVER wrap your response in \`\`\`markdown fences. Output markdown directly — the terminal renders it natively.
69
+ - Verify changes work before reporting completion.
70
+ - Never expose secrets or API keys.
71
+
72
+ ## Available Tools
73
+ You have these tools: Read, Edit, Write, Bash, Glob, Grep, LS.
74
+ - Use Read to view file contents.
75
+ - Use Edit to modify existing files (find & replace with old_string/new_string).
76
+ - Use Write to create new files.
77
+ - Use Bash to run shell commands.
78
+ - Use Glob to find files by pattern.
79
+ - Use Grep to search file contents.
80
+ - Use LS to list directory contents.
81
+ `;
82
+ const skills = loadAllSkills();
83
+ if (skills.length > 0) {
84
+ prompt += buildSkillsSection(skills);
85
+ }
86
+ return prompt;
87
+ }
88
+ function buildSkillsSection(skills) {
89
+ let section = `\n## Available Skills\nThe user can invoke skills with \`/skill-name [args]\`. You can also invoke them when appropriate.\n\n`;
90
+ for (const skill of skills) {
91
+ section += `### /${skill.name}\n`;
92
+ section += `${skill.description}\n`;
93
+ if (skill.whenToUse)
94
+ section += `When to use: ${skill.whenToUse}\n`;
95
+ if (skill.argumentHint)
96
+ section += `Usage: /${skill.name} ${skill.argumentHint}\n`;
97
+ section += `Source: ${skill.source}\n\n`;
98
+ }
99
+ return section;
100
+ }
101
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,65 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { render } from 'ink';
3
+ import meow from 'meow';
4
+ import { App } from './ui/App.js';
5
+ import { resolveConfig, saveStoredConfig, CONFIG_PATH } from './config.js';
6
+ const cli = meow(`
7
+ Usage
8
+ $ yome [prompt]
9
+
10
+ Options
11
+ --key, -k Set API key (saved to ~/.yome/config.json)
12
+ --base-url, -b Set API base URL (saved to ~/.yome/config.json)
13
+ --model, -m Set model name
14
+ --provider, -p API provider: "anthropic" or "openai" (auto-detected from base URL)
15
+
16
+ Environment Variables
17
+ YOME_API_KEY API key
18
+ YOME_BASE_URL API base URL (default: https://zenmux.ai/api)
19
+ YOME_MODEL Model name
20
+ YOME_PROVIDER API provider: "anthropic" or "openai"
21
+
22
+ Examples
23
+ $ yome "help me read package.json"
24
+ $ yome --key sk-xxx --base-url https://api.anthropic.com
25
+ $ yome --base-url https://dashscope.aliyuncs.com/compatible-mode/v1 --provider openai --model qwen-plus
26
+ $ yome
27
+ `, {
28
+ importMeta: import.meta,
29
+ flags: {
30
+ key: { type: 'string', shortFlag: 'k' },
31
+ baseUrl: { type: 'string', shortFlag: 'b' },
32
+ model: { type: 'string', shortFlag: 'm' },
33
+ provider: { type: 'string', shortFlag: 'p' },
34
+ },
35
+ });
36
+ // Persist config flags
37
+ if (cli.flags.key || cli.flags.baseUrl || cli.flags.provider) {
38
+ const updates = {};
39
+ if (cli.flags.key)
40
+ updates.apiKey = cli.flags.key;
41
+ if (cli.flags.baseUrl)
42
+ updates.baseUrl = cli.flags.baseUrl;
43
+ if (cli.flags.model)
44
+ updates.model = cli.flags.model;
45
+ if (cli.flags.provider)
46
+ updates.provider = cli.flags.provider;
47
+ saveStoredConfig(updates);
48
+ console.log(`Config saved to ${CONFIG_PATH}`);
49
+ if (!cli.input.length)
50
+ process.exit(0);
51
+ }
52
+ const config = resolveConfig(cli.flags);
53
+ if (!config.apiKey) {
54
+ console.error('No API key found.');
55
+ console.error('Set via: yome --key sk-xxx');
56
+ console.error('Or set YOME_API_KEY environment variable.');
57
+ process.exit(1);
58
+ }
59
+ const initialPrompt = cli.input.join(' ') || undefined;
60
+ // Pass initial prompt through config (avoids extra prop drilling)
61
+ const appConfig = initialPrompt
62
+ ? Object.assign({}, config, { __initialPrompt: initialPrompt })
63
+ : config;
64
+ render(_jsx(App, { config: appConfig }));
65
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE3E,MAAM,GAAG,GAAG,IAAI,CACd;;;;;;;;;;;;;;;;;;;;;CAqBD,EACC;IACE,UAAU,EAAE,MAAM,CAAC,IAAI;IACvB,KAAK,EAAE;QACL,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE;QACvC,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE;QAC3C,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE;QACzC,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE;KAC7C;CACF,CACF,CAAC;AAEF,uBAAuB;AACvB,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC7D,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG;QAAE,OAAO,CAAC,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;IAClD,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO;QAAE,OAAO,CAAC,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC;IAC3D,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK;QAAE,OAAO,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC;IACrD,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ;QAAE,OAAO,CAAC,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC9D,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC1B,OAAO,CAAC,GAAG,CAAC,mBAAmB,WAAW,EAAE,CAAC,CAAC;IAC9C,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAExC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACnC,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAC5C,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,aAAa,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC;AAEvD,kEAAkE;AAClE,MAAM,SAAS,GAAG,aAAa;IAC7B,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,eAAe,EAAE,aAAa,EAAE,CAAC;IAC/D,CAAC,CAAC,MAAM,CAAC;AAEX,MAAM,CAAC,KAAC,GAAG,IAAC,MAAM,EAAE,SAAS,GAAI,CAAC,CAAC"}
package/dist/llm.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ import type { YomeConfig } from './config.js';
2
+ import type { AgentMessage, AnthropicTool, AnthropicResponse } from './types.js';
3
+ type StreamCallback = (event: {
4
+ type: 'text_delta' | 'tool_use_start' | 'tool_input_delta' | 'content_block_stop' | 'message_stop';
5
+ text?: string;
6
+ index?: number;
7
+ toolUseId?: string;
8
+ toolName?: string;
9
+ }) => void;
10
+ export declare function callLLMStream(config: YomeConfig, systemPrompt: string, messages: AgentMessage[], tools: AnthropicTool[], onEvent: StreamCallback): Promise<AnthropicResponse>;
11
+ export declare function callLLM(config: YomeConfig, systemPrompt: string, messages: AgentMessage[], tools?: AnthropicTool[]): Promise<AnthropicResponse>;
12
+ export declare function extractText(response: AnthropicResponse): string;
13
+ export {};