@puukis/core 0.1.0

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 (162) hide show
  1. package/LICENSE +21 -0
  2. package/dist/brain/Brain.d.ts +39 -0
  3. package/dist/brain/Brain.d.ts.map +1 -0
  4. package/dist/brain/Brain.js +284 -0
  5. package/dist/brain/Brain.js.map +1 -0
  6. package/dist/brain/index.d.ts +2 -0
  7. package/dist/brain/index.d.ts.map +1 -0
  8. package/dist/brain/index.js +2 -0
  9. package/dist/brain/index.js.map +1 -0
  10. package/dist/cli/argv.d.ts +8 -0
  11. package/dist/cli/argv.d.ts.map +1 -0
  12. package/dist/cli/argv.js +41 -0
  13. package/dist/cli/argv.js.map +1 -0
  14. package/dist/cli/codexInstall.d.ts +17 -0
  15. package/dist/cli/codexInstall.d.ts.map +1 -0
  16. package/dist/cli/codexInstall.js +106 -0
  17. package/dist/cli/codexInstall.js.map +1 -0
  18. package/dist/cli/commands/auth.d.ts +3 -0
  19. package/dist/cli/commands/auth.d.ts.map +1 -0
  20. package/dist/cli/commands/auth.js +66 -0
  21. package/dist/cli/commands/auth.js.map +1 -0
  22. package/dist/cli/commands/install.d.ts +3 -0
  23. package/dist/cli/commands/install.d.ts.map +1 -0
  24. package/dist/cli/commands/install.js +21 -0
  25. package/dist/cli/commands/install.js.map +1 -0
  26. package/dist/cli/commands/onboard.d.ts +3 -0
  27. package/dist/cli/commands/onboard.d.ts.map +1 -0
  28. package/dist/cli/commands/onboard.js +43 -0
  29. package/dist/cli/commands/onboard.js.map +1 -0
  30. package/dist/cli/commands/uninstall.d.ts +3 -0
  31. package/dist/cli/commands/uninstall.d.ts.map +1 -0
  32. package/dist/cli/commands/uninstall.js +193 -0
  33. package/dist/cli/commands/uninstall.js.map +1 -0
  34. package/dist/cli/commands/update.d.ts +3 -0
  35. package/dist/cli/commands/update.d.ts.map +1 -0
  36. package/dist/cli/commands/update.js +314 -0
  37. package/dist/cli/commands/update.js.map +1 -0
  38. package/dist/cli/index.d.ts +3 -0
  39. package/dist/cli/index.d.ts.map +1 -0
  40. package/dist/cli/index.js +60 -0
  41. package/dist/cli/index.js.map +1 -0
  42. package/dist/codex/CodexRpcClient.d.ts +65 -0
  43. package/dist/codex/CodexRpcClient.d.ts.map +1 -0
  44. package/dist/codex/CodexRpcClient.js +395 -0
  45. package/dist/codex/CodexRpcClient.js.map +1 -0
  46. package/dist/codex/codexModels.d.ts +33 -0
  47. package/dist/codex/codexModels.d.ts.map +1 -0
  48. package/dist/codex/codexModels.js +226 -0
  49. package/dist/codex/codexModels.js.map +1 -0
  50. package/dist/codex/index.d.ts +5 -0
  51. package/dist/codex/index.d.ts.map +1 -0
  52. package/dist/codex/index.js +3 -0
  53. package/dist/codex/index.js.map +1 -0
  54. package/dist/codex/types.d.ts +97 -0
  55. package/dist/codex/types.d.ts.map +1 -0
  56. package/dist/codex/types.js +2 -0
  57. package/dist/codex/types.js.map +1 -0
  58. package/dist/config/env.d.ts +8 -0
  59. package/dist/config/env.d.ts.map +1 -0
  60. package/dist/config/env.js +130 -0
  61. package/dist/config/env.js.map +1 -0
  62. package/dist/config/index.d.ts +2 -0
  63. package/dist/config/index.d.ts.map +1 -0
  64. package/dist/config/index.js +2 -0
  65. package/dist/config/index.js.map +1 -0
  66. package/dist/db/index.d.ts +48 -0
  67. package/dist/db/index.d.ts.map +1 -0
  68. package/dist/db/index.js +147 -0
  69. package/dist/db/index.js.map +1 -0
  70. package/dist/gateway/Gateway.d.ts +69 -0
  71. package/dist/gateway/Gateway.d.ts.map +1 -0
  72. package/dist/gateway/Gateway.js +239 -0
  73. package/dist/gateway/Gateway.js.map +1 -0
  74. package/dist/gateway/LaneQueue.d.ts +24 -0
  75. package/dist/gateway/LaneQueue.d.ts.map +1 -0
  76. package/dist/gateway/LaneQueue.js +59 -0
  77. package/dist/gateway/LaneQueue.js.map +1 -0
  78. package/dist/gateway/index.d.ts +3 -0
  79. package/dist/gateway/index.d.ts.map +1 -0
  80. package/dist/gateway/index.js +3 -0
  81. package/dist/gateway/index.js.map +1 -0
  82. package/dist/index.d.ts +13 -0
  83. package/dist/index.d.ts.map +1 -0
  84. package/dist/index.js +14 -0
  85. package/dist/index.js.map +1 -0
  86. package/dist/llm/GeminiProvider.d.ts +16 -0
  87. package/dist/llm/GeminiProvider.d.ts.map +1 -0
  88. package/dist/llm/GeminiProvider.js +172 -0
  89. package/dist/llm/GeminiProvider.js.map +1 -0
  90. package/dist/llm/OllamaProvider.d.ts +15 -0
  91. package/dist/llm/OllamaProvider.d.ts.map +1 -0
  92. package/dist/llm/OllamaProvider.js +108 -0
  93. package/dist/llm/OllamaProvider.js.map +1 -0
  94. package/dist/llm/OpenAICodexProvider.d.ts +51 -0
  95. package/dist/llm/OpenAICodexProvider.d.ts.map +1 -0
  96. package/dist/llm/OpenAICodexProvider.js +620 -0
  97. package/dist/llm/OpenAICodexProvider.js.map +1 -0
  98. package/dist/llm/OpenAIProvider.d.ts +16 -0
  99. package/dist/llm/OpenAIProvider.d.ts.map +1 -0
  100. package/dist/llm/OpenAIProvider.js +134 -0
  101. package/dist/llm/OpenAIProvider.js.map +1 -0
  102. package/dist/llm/index.d.ts +10 -0
  103. package/dist/llm/index.d.ts.map +1 -0
  104. package/dist/llm/index.js +30 -0
  105. package/dist/llm/index.js.map +1 -0
  106. package/dist/main.d.ts +7 -0
  107. package/dist/main.d.ts.map +1 -0
  108. package/dist/main.js +88 -0
  109. package/dist/main.js.map +1 -0
  110. package/dist/pipeline/index.d.ts +2 -0
  111. package/dist/pipeline/index.d.ts.map +1 -0
  112. package/dist/pipeline/index.js +2 -0
  113. package/dist/pipeline/index.js.map +1 -0
  114. package/dist/pipeline/normalize.d.ts +19 -0
  115. package/dist/pipeline/normalize.d.ts.map +1 -0
  116. package/dist/pipeline/normalize.js +34 -0
  117. package/dist/pipeline/normalize.js.map +1 -0
  118. package/dist/server/index.d.ts +28 -0
  119. package/dist/server/index.d.ts.map +1 -0
  120. package/dist/server/index.js +389 -0
  121. package/dist/server/index.js.map +1 -0
  122. package/dist/tools/ToolExecutor.d.ts +68 -0
  123. package/dist/tools/ToolExecutor.d.ts.map +1 -0
  124. package/dist/tools/ToolExecutor.js +177 -0
  125. package/dist/tools/ToolExecutor.js.map +1 -0
  126. package/dist/tools/builtin/browser.d.ts +27 -0
  127. package/dist/tools/builtin/browser.d.ts.map +1 -0
  128. package/dist/tools/builtin/browser.js +222 -0
  129. package/dist/tools/builtin/browser.js.map +1 -0
  130. package/dist/tools/builtin/filesystem.d.ts +22 -0
  131. package/dist/tools/builtin/filesystem.d.ts.map +1 -0
  132. package/dist/tools/builtin/filesystem.js +151 -0
  133. package/dist/tools/builtin/filesystem.js.map +1 -0
  134. package/dist/tools/builtin/index.d.ts +10 -0
  135. package/dist/tools/builtin/index.d.ts.map +1 -0
  136. package/dist/tools/builtin/index.js +21 -0
  137. package/dist/tools/builtin/index.js.map +1 -0
  138. package/dist/tools/builtin/sandbox.d.ts +11 -0
  139. package/dist/tools/builtin/sandbox.d.ts.map +1 -0
  140. package/dist/tools/builtin/sandbox.js +166 -0
  141. package/dist/tools/builtin/sandbox.js.map +1 -0
  142. package/dist/tools/builtin/search.d.ts +7 -0
  143. package/dist/tools/builtin/search.d.ts.map +1 -0
  144. package/dist/tools/builtin/search.js +76 -0
  145. package/dist/tools/builtin/search.js.map +1 -0
  146. package/dist/tools/builtin/shell.d.ts +7 -0
  147. package/dist/tools/builtin/shell.d.ts.map +1 -0
  148. package/dist/tools/builtin/shell.js +71 -0
  149. package/dist/tools/builtin/shell.js.map +1 -0
  150. package/dist/tools/index.d.ts +3 -0
  151. package/dist/tools/index.d.ts.map +1 -0
  152. package/dist/tools/index.js +3 -0
  153. package/dist/tools/index.js.map +1 -0
  154. package/dist/types.d.ts +167 -0
  155. package/dist/types.d.ts.map +1 -0
  156. package/dist/types.js +3 -0
  157. package/dist/types.js.map +1 -0
  158. package/dist/workspace/agentWorkspace.d.ts +24 -0
  159. package/dist/workspace/agentWorkspace.d.ts.map +1 -0
  160. package/dist/workspace/agentWorkspace.js +210 -0
  161. package/dist/workspace/agentWorkspace.js.map +1 -0
  162. package/package.json +45 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Puukis
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,39 @@
1
+ import type { Channel, CodexReasoningEffort, KeygateConfig, ProviderModelOption, Session } from '../types.js';
2
+ import type { ToolExecutor } from '../tools/ToolExecutor.js';
3
+ import type { Gateway } from '../gateway/Gateway.js';
4
+ /**
5
+ * Brain - The ReAct agent loop
6
+ *
7
+ * Implements: Reason → Tool → Observe → Respond
8
+ * Continues calling tools until LLM generates a final response
9
+ */
10
+ export declare class Brain {
11
+ private llm;
12
+ private config;
13
+ private toolExecutor;
14
+ private gateway;
15
+ private maxIterations;
16
+ constructor(config: KeygateConfig, toolExecutor: ToolExecutor, gateway: Gateway);
17
+ /**
18
+ * Run the agent loop for a session
19
+ */
20
+ run(session: Session, channel: Channel): Promise<string>;
21
+ /**
22
+ * Run the agent loop with streaming response
23
+ */
24
+ runStream(session: Session, channel: Channel): AsyncIterable<string>;
25
+ /**
26
+ * Execute a single tool call
27
+ */
28
+ private executeToolCall;
29
+ getLLMProviderName(): string;
30
+ getLLMModel(): string;
31
+ setLLMSelection(provider: KeygateConfig['llm']['provider'], model: string, reasoningEffort?: CodexReasoningEffort): Promise<void>;
32
+ listModels(): Promise<ProviderModelOption[]>;
33
+ private buildProviderOptions;
34
+ /**
35
+ * Get the system prompt with current context
36
+ */
37
+ private getSystemPrompt;
38
+ }
39
+ //# sourceMappingURL=Brain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Brain.d.ts","sourceRoot":"","sources":["../../src/brain/Brain.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EACP,oBAAoB,EACpB,aAAa,EAGb,mBAAmB,EACnB,OAAO,EAER,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AA4BrD;;;;;GAKG;AACH,qBAAa,KAAK;IAChB,OAAO,CAAC,GAAG,CAAc;IACzB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,aAAa,CAAM;gBAEf,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO;IAO/E;;OAEG;IACG,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAqD9D;;OAEG;IACI,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC;IAoE3E;;OAEG;YACW,eAAe;IAI7B,kBAAkB,IAAI,MAAM;IAI5B,WAAW,IAAI,MAAM;IAOf,eAAe,CACnB,QAAQ,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,EAC1C,KAAK,EAAE,MAAM,EACb,eAAe,CAAC,EAAE,oBAAoB,GACrC,OAAO,CAAC,IAAI,CAAC;IAgBV,UAAU,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAQlD,OAAO,CAAC,oBAAoB;IAW5B;;OAEG;YACW,eAAe;CAkE9B"}
@@ -0,0 +1,284 @@
1
+ import { createLLMProvider } from '../llm/index.js';
2
+ import { loadAgentWorkspaceState, } from '../workspace/agentWorkspace.js';
3
+ const BASE_SYSTEM_PROMPT = `You are Keygate, a capable AI assistant that can control the user's computer and online services.
4
+
5
+ You have access to various tools to help accomplish tasks:
6
+ - Filesystem operations (read, write, list files)
7
+ - Shell commands (run terminal commands)
8
+ - Code execution (run JavaScript/Python code in a sandbox)
9
+ - Web search (search the internet for information)
10
+ - Browser automation (navigate, click, screenshot)
11
+
12
+ When helping the user:
13
+ 1. Think step by step about what needs to be done.
14
+ 2. Use tools when needed to gather information or take actions.
15
+ 3. Be explicit about actions you are taking.
16
+ 4. Report results and errors plainly.
17
+ 5. Be genuinely helpful without filler intros.
18
+
19
+ Trust and safety:
20
+ - Be careful with external/public actions and ask when in doubt.
21
+ - Keep private information private.
22
+ - Never claim you completed an action unless a tool result confirms it.`;
23
+ /**
24
+ * Brain - The ReAct agent loop
25
+ *
26
+ * Implements: Reason → Tool → Observe → Respond
27
+ * Continues calling tools until LLM generates a final response
28
+ */
29
+ export class Brain {
30
+ llm;
31
+ config;
32
+ toolExecutor;
33
+ gateway;
34
+ maxIterations = 10;
35
+ constructor(config, toolExecutor, gateway) {
36
+ this.config = config;
37
+ this.llm = createLLMProvider(config);
38
+ this.toolExecutor = toolExecutor;
39
+ this.gateway = gateway;
40
+ }
41
+ /**
42
+ * Run the agent loop for a session
43
+ */
44
+ async run(session, channel) {
45
+ const systemPrompt = await this.getSystemPrompt(session);
46
+ // Build messages with system prompt
47
+ const messages = [
48
+ { role: 'system', content: systemPrompt },
49
+ ...session.messages,
50
+ ];
51
+ // Get tool definitions
52
+ const tools = this.toolExecutor.getToolDefinitions();
53
+ let iterations = 0;
54
+ while (iterations < this.maxIterations) {
55
+ iterations++;
56
+ // Call LLM with tools
57
+ const response = await this.llm.chat(messages, {
58
+ tools,
59
+ ...this.buildProviderOptions(session.id),
60
+ });
61
+ // If no tool calls, return the response content
62
+ if (!response.toolCalls || response.toolCalls.length === 0) {
63
+ return response.content;
64
+ }
65
+ // Add assistant message with tool calls
66
+ messages.push({
67
+ role: 'assistant',
68
+ content: response.content,
69
+ toolCalls: response.toolCalls,
70
+ });
71
+ // Execute each tool call
72
+ for (const toolCall of response.toolCalls) {
73
+ const result = await this.executeToolCall(toolCall, channel);
74
+ // Add tool result to messages
75
+ messages.push({
76
+ role: 'tool',
77
+ content: result.success
78
+ ? result.output
79
+ : `Error: ${result.error}`,
80
+ toolCallId: toolCall.id,
81
+ });
82
+ }
83
+ }
84
+ return 'Maximum iterations reached. Please try breaking down your request into smaller steps.';
85
+ }
86
+ /**
87
+ * Run the agent loop with streaming response
88
+ */
89
+ async *runStream(session, channel) {
90
+ const systemPrompt = await this.getSystemPrompt(session);
91
+ const messages = [
92
+ { role: 'system', content: systemPrompt },
93
+ ...session.messages,
94
+ ];
95
+ const tools = this.toolExecutor.getToolDefinitions();
96
+ let iterations = 0;
97
+ let pendingToolCalls = [];
98
+ while (iterations < this.maxIterations) {
99
+ iterations++;
100
+ // Stream LLM response
101
+ let fullContent = '';
102
+ for await (const chunk of this.llm.stream(messages, {
103
+ tools,
104
+ ...this.buildProviderOptions(session.id),
105
+ })) {
106
+ if (chunk.content) {
107
+ fullContent += chunk.content;
108
+ yield chunk.content;
109
+ }
110
+ if (chunk.toolCalls) {
111
+ pendingToolCalls = chunk.toolCalls;
112
+ }
113
+ if (chunk.done && pendingToolCalls.length === 0) {
114
+ return;
115
+ }
116
+ }
117
+ // If there are tool calls, execute them
118
+ if (pendingToolCalls.length > 0) {
119
+ messages.push({
120
+ role: 'assistant',
121
+ content: fullContent,
122
+ toolCalls: pendingToolCalls,
123
+ });
124
+ for (const toolCall of pendingToolCalls) {
125
+ yield `\n\n🔧 Executing: ${toolCall.name}...\n`;
126
+ const result = await this.executeToolCall(toolCall, channel);
127
+ yield result.success
128
+ ? `✅ ${result.output}\n`
129
+ : `❌ Error: ${result.error}\n`;
130
+ messages.push({
131
+ role: 'tool',
132
+ content: result.success ? result.output : `Error: ${result.error}`,
133
+ toolCallId: toolCall.id,
134
+ });
135
+ }
136
+ pendingToolCalls = [];
137
+ yield '\n';
138
+ }
139
+ }
140
+ yield '\n⚠️ Maximum iterations reached.';
141
+ }
142
+ /**
143
+ * Execute a single tool call
144
+ */
145
+ async executeToolCall(toolCall, channel) {
146
+ return this.toolExecutor.execute(toolCall, channel);
147
+ }
148
+ getLLMProviderName() {
149
+ return this.llm.name;
150
+ }
151
+ getLLMModel() {
152
+ if (typeof this.llm.getModel === 'function') {
153
+ return this.llm.getModel();
154
+ }
155
+ return this.config.llm.model;
156
+ }
157
+ async setLLMSelection(provider, model, reasoningEffort) {
158
+ const previousProvider = this.llm;
159
+ this.config.llm.provider = provider;
160
+ this.config.llm.model = model;
161
+ if (provider === 'openai-codex') {
162
+ this.config.llm.reasoningEffort = reasoningEffort ?? this.config.llm.reasoningEffort ?? 'medium';
163
+ }
164
+ this.llm = createLLMProvider(this.config);
165
+ if (typeof previousProvider.dispose === 'function') {
166
+ await previousProvider.dispose();
167
+ }
168
+ }
169
+ async listModels() {
170
+ if (typeof this.llm.listModels === 'function') {
171
+ return this.llm.listModels();
172
+ }
173
+ return getFallbackModels(this.config.llm.provider, this.config.llm.model);
174
+ }
175
+ buildProviderOptions(sessionId) {
176
+ return {
177
+ sessionId,
178
+ cwd: this.toolExecutor.getWorkspacePath(),
179
+ securityMode: this.gateway.getSecurityMode(),
180
+ onProviderEvent: (event) => {
181
+ this.gateway.emit('provider:event', { sessionId, event });
182
+ },
183
+ };
184
+ }
185
+ /**
186
+ * Get the system prompt with current context
187
+ */
188
+ async getSystemPrompt(session) {
189
+ const mode = this.gateway.getSecurityMode();
190
+ const workspace = this.toolExecutor.getWorkspacePath();
191
+ const workspaceState = await loadAgentWorkspaceState(workspace);
192
+ const userTurns = session.messages.filter((message) => message.role === 'user').length;
193
+ const isFirstUserTurn = userTurns === 1;
194
+ const shouldRunBootstrap = isFirstUserTurn && workspaceState.onboardingRequired;
195
+ let modeInfo = '';
196
+ if (mode === 'safe') {
197
+ modeInfo = `\n\nSECURITY: Safe Mode is active.
198
+ - Filesystem operations are limited to: ${workspace}
199
+ - Only allowed commands can be executed
200
+ - Write/execute actions require user confirmation`;
201
+ }
202
+ else {
203
+ modeInfo = `\n\n⚠️ SECURITY: SPICY MODE IS ACTIVE - Full system access enabled.`;
204
+ }
205
+ const workspaceFiles = `\n\nWORKSPACE CONTINUITY FILES
206
+ - SOUL.md: ${formatContextStatus(workspaceState.soul)}
207
+ - BOOTSTRAP.md: ${formatContextStatus(workspaceState.bootstrap)}
208
+ - IDENTITY.md: ${formatContextStatus(workspaceState.identity)}
209
+ - USER.md: ${formatContextStatus(workspaceState.user)}
210
+ - MEMORY.md: ${formatContextStatus(workspaceState.memoryIndex)}
211
+ - memory/today: ${formatContextStatus(workspaceState.todayMemory)}
212
+ - memory/yesterday: ${formatContextStatus(workspaceState.yesterdayMemory)}
213
+
214
+ Use relative workspace paths when calling filesystem tools (for example: IDENTITY.md, USER.md, memory/2026-02-06.md).`;
215
+ const bootstrapRules = shouldRunBootstrap
216
+ ? `\n\nFIRST CHAT BOOTSTRAP (REQUIRED NOW)
217
+ 1. Start with this exact sentence once: "Hey. I just came online. Who am I? Who are you?"
218
+ 2. Ask for identity fields:
219
+ - assistant name
220
+ - what kind of creature/assistant it is
221
+ - preferred vibe
222
+ - signature emoji
223
+ 3. After user answers, write or update IDENTITY.md.
224
+ 4. Ask what to call the user and their timezone, then update USER.md.
225
+ 5. Ask whether to tune SOUL.md together.
226
+ 6. Missing memory files are normal; do not treat ENOENT as a failure.
227
+ 7. If SOUL.md changes, explicitly tell the user.`
228
+ : `\n\nCONTINUITY RULES
229
+ - Treat SOUL.md, IDENTITY.md, USER.md, MEMORY.md, and memory/*.md as persistent memory.
230
+ - Be resourceful before asking questions that could be answered from those files.
231
+ - Keep responses concise by default, thorough when needed.
232
+ - If you change SOUL.md, explicitly tell the user.`;
233
+ const contextBlocks = [
234
+ formatContextBlock('SOUL.md', workspaceState.soul),
235
+ formatContextBlock('BOOTSTRAP.md', workspaceState.bootstrap),
236
+ formatContextBlock('IDENTITY.md', workspaceState.identity),
237
+ formatContextBlock('USER.md', workspaceState.user),
238
+ formatContextBlock('MEMORY.md', workspaceState.memoryIndex),
239
+ formatContextBlock('memory/today', workspaceState.todayMemory),
240
+ formatContextBlock('memory/yesterday', workspaceState.yesterdayMemory),
241
+ ]
242
+ .filter((value) => value !== null)
243
+ .join('\n\n');
244
+ const contextSection = contextBlocks
245
+ ? `\n\nWORKSPACE SNAPSHOT (READ-ONLY CONTEXT FOR THIS TURN)\n${contextBlocks}`
246
+ : '';
247
+ return BASE_SYSTEM_PROMPT + modeInfo + workspaceFiles + bootstrapRules + contextSection;
248
+ }
249
+ }
250
+ function formatContextStatus(file) {
251
+ if (!file.exists) {
252
+ return `missing (${file.path})`;
253
+ }
254
+ if (file.truncated) {
255
+ return `loaded and truncated (${file.path})`;
256
+ }
257
+ return `loaded (${file.path})`;
258
+ }
259
+ function formatContextBlock(label, file) {
260
+ if (!file.exists || !file.content) {
261
+ return null;
262
+ }
263
+ return `### ${label}
264
+ ${file.content}`;
265
+ }
266
+ function getFallbackModels(provider, currentModel) {
267
+ const defaults = {
268
+ openai: ['gpt-4o', 'gpt-4.1', 'o3-mini'],
269
+ gemini: ['gemini-1.5-pro', 'gemini-1.5-flash'],
270
+ ollama: ['llama3', 'qwen2.5-coder'],
271
+ 'openai-codex': ['openai-codex/gpt-5.3', 'openai-codex/gpt-5.2'],
272
+ };
273
+ const candidates = defaults[provider] ?? [currentModel];
274
+ const unique = provider === 'openai-codex'
275
+ ? Array.from(new Set(candidates))
276
+ : Array.from(new Set([currentModel, ...candidates]));
277
+ return unique.map((model, index) => ({
278
+ id: model,
279
+ provider,
280
+ displayName: model,
281
+ isDefault: index === 0,
282
+ }));
283
+ }
284
+ //# sourceMappingURL=Brain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Brain.js","sourceRoot":"","sources":["../../src/brain/Brain.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { Brain } from './Brain.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/brain/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { Brain } from './Brain.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/brain/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,8 @@
1
+ export interface ParsedArgs {
2
+ positional: string[];
3
+ flags: Record<string, string | boolean>;
4
+ }
5
+ export declare function parseArgs(argv: string[]): ParsedArgs;
6
+ export declare function getFlagString(flags: Record<string, string | boolean>, key: string, fallback?: string): string;
7
+ export declare function hasFlag(flags: Record<string, string | boolean>, key: string): boolean;
8
+ //# sourceMappingURL=argv.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"argv.d.ts","sourceRoot":"","sources":["../../src/cli/argv.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC;CACzC;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAiCpD;AAED,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,EACvC,GAAG,EAAE,MAAM,EACX,QAAQ,SAAK,GACZ,MAAM,CAWR;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAErF"}
@@ -0,0 +1,41 @@
1
+ export function parseArgs(argv) {
2
+ const positional = [];
3
+ const flags = {};
4
+ for (let i = 0; i < argv.length; i += 1) {
5
+ const token = argv[i];
6
+ if (!token.startsWith('--')) {
7
+ positional.push(token);
8
+ continue;
9
+ }
10
+ const withoutPrefix = token.slice(2);
11
+ const equalsIndex = withoutPrefix.indexOf('=');
12
+ if (equalsIndex >= 0) {
13
+ const key = withoutPrefix.slice(0, equalsIndex);
14
+ const value = withoutPrefix.slice(equalsIndex + 1);
15
+ flags[key] = value;
16
+ continue;
17
+ }
18
+ const next = argv[i + 1];
19
+ if (next && !next.startsWith('--')) {
20
+ flags[withoutPrefix] = next;
21
+ i += 1;
22
+ continue;
23
+ }
24
+ flags[withoutPrefix] = true;
25
+ }
26
+ return { positional, flags };
27
+ }
28
+ export function getFlagString(flags, key, fallback = '') {
29
+ const value = flags[key];
30
+ if (typeof value === 'string') {
31
+ return value;
32
+ }
33
+ if (value === true) {
34
+ return 'true';
35
+ }
36
+ return fallback;
37
+ }
38
+ export function hasFlag(flags, key) {
39
+ return Boolean(flags[key]);
40
+ }
41
+ //# sourceMappingURL=argv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"argv.js","sourceRoot":"","sources":["../../src/cli/argv.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,KAAK,GAAqC,EAAE,CAAC;IAEnD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;QAEvB,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvB,SAAS;QACX,CAAC;QAED,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,WAAW,GAAG,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAE/C,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;YACrB,MAAM,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;YAChD,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;YACnD,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACnB,SAAS;QACX,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACzB,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,KAAK,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;YAC5B,CAAC,IAAI,CAAC,CAAC;YACP,SAAS;QACX,CAAC;QAED,KAAK,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;IAC9B,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,KAAuC,EACvC,GAAW,EACX,QAAQ,GAAG,EAAE;IAEb,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,KAAuC,EAAE,GAAW;IAC1E,OAAO,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,17 @@
1
+ export type CodexInstallMethod = 'existing' | 'npm' | 'brew';
2
+ export interface EnsureCodexInstalledOptions {
3
+ autoInstall?: boolean;
4
+ preferBrewOnMac?: boolean;
5
+ }
6
+ export interface EnsureCodexInstalledResult {
7
+ installed: boolean;
8
+ method?: CodexInstallMethod;
9
+ version?: string;
10
+ attempts: string[];
11
+ error?: string;
12
+ }
13
+ export declare function isCodexInstalled(): boolean;
14
+ export declare function getCodexVersion(): string | null;
15
+ export declare function ensureCodexInstalled(options?: EnsureCodexInstalledOptions): Promise<EnsureCodexInstalledResult>;
16
+ export declare function getCodexInstallHelp(): string;
17
+ //# sourceMappingURL=codexInstall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codexInstall.d.ts","sourceRoot":"","sources":["../../src/cli/codexInstall.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,KAAK,GAAG,MAAM,CAAC;AAE7D,MAAM,WAAW,2BAA2B;IAC1C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,gBAAgB,IAAI,OAAO,CAG1C;AAED,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAgB/C;AAED,wBAAsB,oBAAoB,CACxC,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,0BAA0B,CAAC,CA8CrC;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAa5C"}
@@ -0,0 +1,106 @@
1
+ import { spawn, spawnSync } from 'node:child_process';
2
+ export function isCodexInstalled() {
3
+ const version = getCodexVersion();
4
+ return version !== null;
5
+ }
6
+ export function getCodexVersion() {
7
+ const result = spawnSync('codex', ['--version'], {
8
+ stdio: 'pipe',
9
+ encoding: 'utf8',
10
+ });
11
+ if (result.status !== 0) {
12
+ return null;
13
+ }
14
+ const output = `${result.stdout ?? ''}${result.stderr ?? ''}`.trim();
15
+ if (!output) {
16
+ return 'unknown';
17
+ }
18
+ return output.split(/\r?\n/g)[0] ?? 'unknown';
19
+ }
20
+ export async function ensureCodexInstalled(options = {}) {
21
+ const attempts = [];
22
+ const existingVersion = getCodexVersion();
23
+ if (existingVersion) {
24
+ return {
25
+ installed: true,
26
+ method: 'existing',
27
+ version: existingVersion,
28
+ attempts,
29
+ };
30
+ }
31
+ if (!options.autoInstall) {
32
+ return {
33
+ installed: false,
34
+ attempts,
35
+ error: 'Codex CLI is not installed',
36
+ };
37
+ }
38
+ const methods = getInstallMethods(options.preferBrewOnMac ?? false);
39
+ for (const method of methods) {
40
+ attempts.push(method.description);
41
+ const ok = await runCommand(method.command, method.args);
42
+ if (!ok) {
43
+ continue;
44
+ }
45
+ const version = getCodexVersion();
46
+ if (version) {
47
+ return {
48
+ installed: true,
49
+ method: method.id,
50
+ version,
51
+ attempts,
52
+ };
53
+ }
54
+ }
55
+ return {
56
+ installed: false,
57
+ attempts,
58
+ error: getCodexInstallHelp(),
59
+ };
60
+ }
61
+ export function getCodexInstallHelp() {
62
+ const lines = [
63
+ 'Install Codex CLI manually, then retry:',
64
+ '1. npm i -g @openai/codex',
65
+ ];
66
+ if (process.platform === 'darwin') {
67
+ lines.push('2. (optional macOS) brew install --cask codex');
68
+ }
69
+ lines.push('3. Verify with: codex --version');
70
+ return lines.join('\n');
71
+ }
72
+ function getInstallMethods(preferBrewOnMac) {
73
+ const npmMethod = {
74
+ id: 'npm',
75
+ description: 'npm i -g @openai/codex',
76
+ command: 'npm',
77
+ args: ['i', '-g', '@openai/codex'],
78
+ };
79
+ const brewMethod = {
80
+ id: 'brew',
81
+ description: 'brew install --cask codex',
82
+ command: 'brew',
83
+ args: ['install', '--cask', 'codex'],
84
+ };
85
+ if (process.platform !== 'darwin') {
86
+ return [npmMethod];
87
+ }
88
+ if (preferBrewOnMac) {
89
+ return [brewMethod, npmMethod];
90
+ }
91
+ return [npmMethod, brewMethod];
92
+ }
93
+ async function runCommand(command, args) {
94
+ return new Promise((resolve) => {
95
+ const child = spawn(command, args, {
96
+ stdio: 'inherit',
97
+ });
98
+ child.once('error', () => {
99
+ resolve(false);
100
+ });
101
+ child.once('exit', (code) => {
102
+ resolve(code === 0);
103
+ });
104
+ });
105
+ }
106
+ //# sourceMappingURL=codexInstall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codexInstall.js","sourceRoot":"","sources":["../../src/cli/codexInstall.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type ParsedArgs } from '../argv.js';
2
+ export declare function runAuthCommand(args: ParsedArgs): Promise<void>;
3
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/auth.ts"],"names":[],"mappings":"AAEA,OAAO,EAA0B,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAIrE,wBAAsB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAwDpE"}
@@ -0,0 +1,66 @@
1
+ import { OpenAICodexProvider } from '../../llm/OpenAICodexProvider.js';
2
+ import { ensureCodexInstalled, getCodexInstallHelp } from '../codexInstall.js';
3
+ import { getFlagString, hasFlag } from '../argv.js';
4
+ import { loadConfigFromEnv, updateEnvFile } from '../../config/env.js';
5
+ export async function runAuthCommand(args) {
6
+ const action = args.positional[1];
7
+ if (action !== 'login') {
8
+ throw new Error(`Unknown auth command: ${args.positional.slice(0, 2).join(' ')}`);
9
+ }
10
+ const provider = getFlagString(args.flags, 'provider', 'openai-codex');
11
+ if (provider !== 'openai-codex') {
12
+ throw new Error('Only --provider openai-codex is currently supported for auth login');
13
+ }
14
+ const codexStatus = await ensureCodexInstalled({ autoInstall: false });
15
+ if (!codexStatus.installed) {
16
+ throw new Error(`${codexStatus.error ?? 'Codex CLI is not installed'}\n${getCodexInstallHelp()}`);
17
+ }
18
+ const config = loadConfigFromEnv();
19
+ const initialModel = config.llm.provider === 'openai-codex'
20
+ ? config.llm.model
21
+ : 'openai-codex/gpt-5.3';
22
+ const codexProvider = new OpenAICodexProvider(initialModel, {
23
+ cwd: config.security.workspacePath,
24
+ });
25
+ try {
26
+ const forceDeviceAuth = hasFlag(args.flags, 'device-auth');
27
+ const noDeviceFallback = hasFlag(args.flags, 'no-device-fallback');
28
+ await codexProvider.login({
29
+ useDeviceAuth: forceDeviceAuth,
30
+ allowDeviceAuthFallback: !noDeviceFallback,
31
+ });
32
+ let selectedModel = initialModel;
33
+ try {
34
+ const models = await codexProvider.listModels();
35
+ selectedModel = pickDefaultProviderModel(models, initialModel);
36
+ }
37
+ catch {
38
+ // Keep configured model if model/list is unavailable in this environment.
39
+ }
40
+ await updateEnvFile({
41
+ LLM_PROVIDER: 'openai-codex',
42
+ LLM_MODEL: selectedModel,
43
+ LLM_API_KEY: '',
44
+ });
45
+ console.log('OpenAI Codex login complete.');
46
+ console.log(`Selected model: ${selectedModel}`);
47
+ }
48
+ finally {
49
+ await codexProvider.dispose();
50
+ }
51
+ }
52
+ function pickDefaultProviderModel(models, fallback) {
53
+ if (models.length === 0) {
54
+ return fallback;
55
+ }
56
+ const explicitDefault = models.find((model) => model.isDefault);
57
+ if (explicitDefault) {
58
+ return explicitDefault.id;
59
+ }
60
+ const preferred = models.find((model) => model.id === 'openai-codex/gpt-5.3');
61
+ if (preferred) {
62
+ return preferred.id;
63
+ }
64
+ return models[0].id;
65
+ }
66
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/cli/commands/auth.ts"],"names":[],"mappings":"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"}