@photon-cli/flux 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -41,19 +41,6 @@ bun add @photon-cli/flux
41
41
 
42
42
  ---
43
43
 
44
- ## Testing
45
-
46
- ### 1. Validate the agent (run from your project directory)
47
- bun /Users/garygao/flux/src/cli.ts validate
48
-
49
- ## 2. Test locally (interactive mode - no server needed)
50
- bun /Users/garygao/flux/src/cli.ts run --local
51
-
52
- ### 3. Login and run connected to bridge
53
- bun /Users/garygao/flux/src/cli.ts login
54
- bun /Users/garygao/flux/src/cli.ts run --prod
55
-
56
- ---
57
44
  ## Requirements
58
45
 
59
46
  - **Node.js** 18+ (for the CLI)
@@ -1,37 +1,61 @@
1
1
  #!/usr/bin/env node
2
- import { Service, server, bidi, client, createGrpcClient } from 'better-grpc';
3
- import { renderChatUI } from '@photon-ai/rapid/cli-chat';
4
- import * as fs from 'fs';
5
- import * as path from 'path';
6
- import * as readline from 'readline';
7
- import { pathToFileURL } from 'url';
2
+ 'use strict';
3
+
4
+ var betterGrpc = require('better-grpc');
5
+ var cliChat = require('@photon-ai/rapid/cli-chat');
6
+ var fs = require('fs');
7
+ var path = require('path');
8
+ var readline = require('readline');
9
+ var url = require('url');
10
+
11
+ function _interopNamespace(e) {
12
+ if (e && e.__esModule) return e;
13
+ var n = Object.create(null);
14
+ if (e) {
15
+ Object.keys(e).forEach(function (k) {
16
+ if (k !== 'default') {
17
+ var d = Object.getOwnPropertyDescriptor(e, k);
18
+ Object.defineProperty(n, k, d.get ? d : {
19
+ enumerable: true,
20
+ get: function () { return e[k]; }
21
+ });
22
+ }
23
+ });
24
+ }
25
+ n.default = e;
26
+ return Object.freeze(n);
27
+ }
28
+
29
+ var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
30
+ var path__namespace = /*#__PURE__*/_interopNamespace(path);
31
+ var readline__namespace = /*#__PURE__*/_interopNamespace(readline);
8
32
 
9
33
  var GRPC_SERVER_ADDRESS = process.env.FLUX_SERVER_ADDRESS || "localhost:50051";
10
- var CONFIG_DIR = path.join(process.env.HOME || "~", ".flux");
11
- var CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
34
+ var CONFIG_DIR = path__namespace.join(process.env.HOME || "~", ".flux");
35
+ var CONFIG_FILE = path__namespace.join(CONFIG_DIR, "config.json");
12
36
  var AGENT_FILE_NAME = "agent.ts";
13
37
  function loadConfig() {
14
38
  try {
15
- if (fs.existsSync(CONFIG_FILE)) {
16
- return JSON.parse(fs.readFileSync(CONFIG_FILE, "utf-8"));
39
+ if (fs__namespace.existsSync(CONFIG_FILE)) {
40
+ return JSON.parse(fs__namespace.readFileSync(CONFIG_FILE, "utf-8"));
17
41
  }
18
42
  } catch {
19
43
  }
20
44
  return {};
21
45
  }
22
46
  function saveConfig(config) {
23
- if (!fs.existsSync(CONFIG_DIR)) {
24
- fs.mkdirSync(CONFIG_DIR, { recursive: true });
47
+ if (!fs__namespace.existsSync(CONFIG_DIR)) {
48
+ fs__namespace.mkdirSync(CONFIG_DIR, { recursive: true });
25
49
  }
26
- fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
50
+ fs__namespace.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
27
51
  }
28
52
  function clearConfig() {
29
- if (fs.existsSync(CONFIG_FILE)) {
30
- fs.unlinkSync(CONFIG_FILE);
53
+ if (fs__namespace.existsSync(CONFIG_FILE)) {
54
+ fs__namespace.unlinkSync(CONFIG_FILE);
31
55
  }
32
56
  }
33
57
  async function prompt(question) {
34
- const rl = readline.createInterface({
58
+ const rl = readline__namespace.createInterface({
35
59
  input: process.stdin,
36
60
  output: process.stdout
37
61
  });
@@ -55,7 +79,7 @@ async function login() {
55
79
  return { received: true };
56
80
  }
57
81
  });
58
- const client2 = await createGrpcClient(GRPC_SERVER_ADDRESS, clientImpl);
82
+ const client2 = await betterGrpc.createGrpcClient(GRPC_SERVER_ADDRESS, clientImpl);
59
83
  const result = await client2.FluxService.validateUser(phoneNumber);
60
84
  if (result.error) {
61
85
  console.error(`[FLUX] Login failed: ${result.error}`);
@@ -89,19 +113,19 @@ async function getPhoneNumber() {
89
113
  }
90
114
  function findAgentFile() {
91
115
  const cwd = process.cwd();
92
- const agentPath = path.join(cwd, AGENT_FILE_NAME);
93
- if (fs.existsSync(agentPath)) {
116
+ const agentPath = path__namespace.join(cwd, AGENT_FILE_NAME);
117
+ if (fs__namespace.existsSync(agentPath)) {
94
118
  return agentPath;
95
119
  }
96
- const jsPath = path.join(cwd, "agent.js");
97
- if (fs.existsSync(jsPath)) {
120
+ const jsPath = path__namespace.join(cwd, "agent.js");
121
+ if (fs__namespace.existsSync(jsPath)) {
98
122
  return jsPath;
99
123
  }
100
124
  return null;
101
125
  }
102
126
  async function validateAgentFile(agentPath) {
103
127
  try {
104
- const moduleUrl = pathToFileURL(agentPath).href;
128
+ const moduleUrl = url.pathToFileURL(agentPath).href;
105
129
  const agentModule = await import(moduleUrl);
106
130
  if (!agentModule.default) {
107
131
  return { valid: false, error: "No default export found. Use `export default agent`" };
@@ -116,18 +140,18 @@ async function validateAgentFile(agentPath) {
116
140
  }
117
141
  }
118
142
  async function loadAgent(agentPath) {
119
- const moduleUrl = pathToFileURL(agentPath).href;
143
+ const moduleUrl = url.pathToFileURL(agentPath).href;
120
144
  const agentModule = await import(moduleUrl);
121
145
  return agentModule.default;
122
146
  }
123
- var FluxService = class extends Service("FluxService") {
124
- sendMessage = server();
125
- messageStream = bidi();
126
- registerAgent = server();
127
- unregisterAgent = server();
128
- onIncomingMessage = client();
147
+ var FluxService = class extends betterGrpc.Service("FluxService") {
148
+ sendMessage = betterGrpc.server();
149
+ messageStream = betterGrpc.bidi();
150
+ registerAgent = betterGrpc.server();
151
+ unregisterAgent = betterGrpc.server();
152
+ onIncomingMessage = betterGrpc.client();
129
153
  // Login validation - checks if user exists in Firebase
130
- validateUser = server();
154
+ validateUser = betterGrpc.server();
131
155
  };
132
156
  var FluxClient = class {
133
157
  client = null;
@@ -143,7 +167,7 @@ var FluxClient = class {
143
167
  return { received: true };
144
168
  }
145
169
  });
146
- this.client = await createGrpcClient(GRPC_SERVER_ADDRESS, clientImpl);
170
+ this.client = await betterGrpc.createGrpcClient(GRPC_SERVER_ADDRESS, clientImpl);
147
171
  console.log(`[FLUX] Connected to server at ${GRPC_SERVER_ADDRESS}`);
148
172
  }
149
173
  async register() {
@@ -200,7 +224,7 @@ async function validateCommand() {
200
224
  console.error("[FLUX] Create an agent.ts file with `export default agent`");
201
225
  return false;
202
226
  }
203
- console.log(`[FLUX] Validating ${path.basename(agentPath)}...`);
227
+ console.log(`[FLUX] Validating ${path__namespace.basename(agentPath)}...`);
204
228
  const result = await validateAgentFile(agentPath);
205
229
  if (result.valid) {
206
230
  console.log("[FLUX] \u2713 Agent is valid!");
@@ -223,7 +247,7 @@ async function runLocal() {
223
247
  process.exit(1);
224
248
  }
225
249
  const agent = await loadAgent(agentPath);
226
- const chat = renderChatUI();
250
+ const chat = cliChat.renderChatUI();
227
251
  chat.sendMessage("Welcome to Flux! Your agent is loaded. Type a message to test it.");
228
252
  chat.onInput(async (input) => {
229
253
  chat.sendMessage("Thinking...");
@@ -254,7 +278,7 @@ async function runProd() {
254
278
  console.error(`[FLUX] Agent validation failed: ${validation.error}`);
255
279
  process.exit(1);
256
280
  }
257
- console.log(`[FLUX] Loading agent from ${path.basename(agentPath)}...`);
281
+ console.log(`[FLUX] Loading agent from ${path__namespace.basename(agentPath)}...`);
258
282
  const agent = await loadAgent(agentPath);
259
283
  console.log("[FLUX] Agent loaded successfully!");
260
284
  const flux = new FluxClient(phoneNumber, async (message) => {
@@ -330,6 +354,6 @@ async function main() {
330
354
  }
331
355
  main().catch(console.error);
332
356
 
333
- export { FluxClient };
334
- //# sourceMappingURL=cli.mjs.map
335
- //# sourceMappingURL=cli.mjs.map
357
+ exports.FluxClient = FluxClient;
358
+ //# sourceMappingURL=cli.cjs.map
359
+ //# sourceMappingURL=cli.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli.ts"],"names":["path","fs","readline","client","createGrpcClient","pathToFileURL","Service","server","bidi","renderChatUI"],"mappings":"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","file":"cli.cjs","sourcesContent":["/**\n * Flux CLI - gRPC Client for iMessage Bridge\n * ==========================================\n * This code connects the Flux CLI to the Flux Server's iMessage bridge.\n * Users define their LangChain agent in agent.ts with `export default agent`\n */\n\nimport { Service, server, client, bidi, createGrpcClient } from \"better-grpc\";\nimport { renderChatUI } from \"@photon-ai/rapid/cli-chat\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as readline from \"readline\";\nimport { pathToFileURL } from \"url\";\n\n// --- Configuration ---\nconst GRPC_SERVER_ADDRESS = process.env.FLUX_SERVER_ADDRESS || \"localhost:50051\";\nconst CONFIG_DIR = path.join(process.env.HOME || \"~\", \".flux\");\nconst CONFIG_FILE = path.join(CONFIG_DIR, \"config.json\");\nconst AGENT_FILE_NAME = \"agent.ts\";\n\n// --- Auth Storage ---\n\ninterface FluxConfig {\n phoneNumber?: string;\n}\n\nfunction loadConfig(): FluxConfig {\n try {\n if (fs.existsSync(CONFIG_FILE)) {\n return JSON.parse(fs.readFileSync(CONFIG_FILE, \"utf-8\"));\n }\n } catch {}\n return {};\n}\n\nfunction saveConfig(config: FluxConfig): void {\n if (!fs.existsSync(CONFIG_DIR)) {\n fs.mkdirSync(CONFIG_DIR, { recursive: true });\n }\n fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));\n}\n\nfunction clearConfig(): void {\n if (fs.existsSync(CONFIG_FILE)) {\n fs.unlinkSync(CONFIG_FILE);\n }\n}\n\nasync function prompt(question: string): Promise<string> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\nasync function login(): Promise<string> {\n const phoneNumber = await prompt(\"Enter your phone number (e.g. +15551234567): \");\n if (!phoneNumber.match(/^\\+?[0-9]{10,15}$/)) {\n console.error(\"Invalid phone number format.\");\n process.exit(1);\n }\n\n // Validate with server (checks/creates user in Firebase)\n console.log(\"[FLUX] Validating with server...\");\n try {\n const clientImpl = FluxService.Client({\n async onIncomingMessage() {\n return { received: true };\n },\n });\n const client = await createGrpcClient(GRPC_SERVER_ADDRESS, clientImpl);\n const result = await client.FluxService.validateUser(phoneNumber);\n\n if (result.error) {\n console.error(`[FLUX] Login failed: ${result.error}`);\n process.exit(1);\n }\n\n if (result.created) {\n console.log(`[FLUX] New account created for ${phoneNumber}`);\n } else if (result.exists) {\n console.log(`[FLUX] Welcome back, ${phoneNumber}`);\n }\n\n saveConfig({ phoneNumber });\n console.log(`[FLUX] Logged in as ${phoneNumber}`);\n return phoneNumber;\n } catch (error: any) {\n console.error(`[FLUX] Failed to connect to server: ${error.message}`);\n console.error(`[FLUX] Make sure the Flux server is running at ${GRPC_SERVER_ADDRESS}`);\n process.exit(1);\n }\n}\n\nfunction logout(): void {\n clearConfig();\n console.log(\"[FLUX] Logged out.\");\n}\n\nasync function getPhoneNumber(): Promise<string> {\n const config = loadConfig();\n if (config.phoneNumber) {\n return config.phoneNumber;\n }\n console.log(\"[FLUX] Not logged in.\");\n return await login();\n}\n\n// --- Agent Types ---\n\n/**\n * FluxAgent interface - users must export default an object matching this interface\n * The agent receives a message and returns a response string\n */\nexport interface FluxAgent {\n invoke: (input: { message: string; userPhoneNumber: string; imageBase64?: string }) => Promise<string>;\n}\n\n// --- Agent Loader ---\n\n/**\n * Find agent.ts in the current working directory\n */\nfunction findAgentFile(): string | null {\n const cwd = process.cwd();\n const agentPath = path.join(cwd, AGENT_FILE_NAME);\n\n if (fs.existsSync(agentPath)) {\n return agentPath;\n }\n\n // Also check for agent.js\n const jsPath = path.join(cwd, \"agent.js\");\n if (fs.existsSync(jsPath)) {\n return jsPath;\n }\n\n return null;\n}\n\n/**\n * Validate that the agent file exports a default agent with invoke method\n */\nasync function validateAgentFile(agentPath: string): Promise<{ valid: boolean; error?: string }> {\n try {\n const moduleUrl = pathToFileURL(agentPath).href;\n const agentModule = await import(moduleUrl);\n\n if (!agentModule.default) {\n return { valid: false, error: \"No default export found. Use `export default agent`\" };\n }\n\n const agent = agentModule.default;\n\n if (typeof agent.invoke !== \"function\") {\n return { valid: false, error: \"Agent must have an `invoke` method\" };\n }\n\n return { valid: true };\n } catch (error: any) {\n return { valid: false, error: `Failed to load agent: ${error.message}` };\n }\n}\n\n/**\n * Load the agent from agent.ts\n */\nasync function loadAgent(agentPath: string): Promise<FluxAgent> {\n const moduleUrl = pathToFileURL(agentPath).href;\n const agentModule = await import(moduleUrl);\n return agentModule.default as FluxAgent;\n}\n\n// --- Message Types ---\n\nexport interface IncomingMessage {\n userPhoneNumber: string;\n text: string;\n imageBase64?: string;\n chatGuid: string;\n messageGuid: string;\n}\n\nexport interface OutgoingMessage {\n userPhoneNumber: string;\n text: string;\n chatGuid?: string;\n}\n\n// --- FluxService Definition (must match server) ---\n\nabstract class FluxService extends Service(\"FluxService\") {\n sendMessage = server<(message: OutgoingMessage) => { success: boolean; error?: string }>();\n messageStream = bidi<(message: IncomingMessage | { ack: string }) => void>();\n registerAgent = server<(phoneNumber: string) => { success: boolean; error?: string }>();\n unregisterAgent = server<(phoneNumber: string) => { success: boolean }>();\n onIncomingMessage = client<(message: IncomingMessage) => { received: boolean }>();\n // Login validation - checks if user exists in Firebase\n validateUser = server<(phoneNumber: string) => { exists: boolean; created: boolean; error?: string }>();\n}\n\n// --- FluxClient Class ---\n\nexport class FluxClient {\n private client: Awaited<ReturnType<typeof createGrpcClient>> | null = null;\n private phoneNumber: string;\n private onMessage: (message: IncomingMessage) => Promise<string | void>;\n\n constructor(\n phoneNumber: string,\n onMessage: (message: IncomingMessage) => Promise<string | void>\n ) {\n this.phoneNumber = phoneNumber.replace(/[\\s\\-\\(\\)]/g, \"\");\n this.onMessage = onMessage;\n }\n\n async connect(): Promise<void> {\n const clientImpl = FluxService.Client({\n async onIncomingMessage(message: IncomingMessage) {\n return { received: true };\n },\n });\n\n this.client = await createGrpcClient(GRPC_SERVER_ADDRESS, clientImpl);\n console.log(`[FLUX] Connected to server at ${GRPC_SERVER_ADDRESS}`);\n }\n\n async register(): Promise<boolean> {\n if (!this.client) throw new Error(\"Not connected. Call connect() first.\");\n\n const result = await this.client.FluxService.registerAgent(this.phoneNumber);\n if (result.success) {\n console.log(`[FLUX] Registered agent for ${this.phoneNumber}`);\n this.startMessageStream();\n } else {\n console.error(`[FLUX] Registration failed: ${result.error}`);\n }\n return result.success;\n }\n\n private async startMessageStream(): Promise<void> {\n if (!this.client) return;\n\n (async () => {\n for await (const [message] of this.client!.FluxService.messageStream) {\n if (\"ack\" in message) {\n console.log(`[FLUX] Received ack: ${message.ack}`);\n } else {\n console.log(`[FLUX] Incoming message from ${message.userPhoneNumber}: ${message.text}`);\n\n // Acknowledge receipt\n await this.client!.FluxService.messageStream({ ack: message.messageGuid });\n\n // Process with user's agent and get response\n const response = await this.onMessage(message);\n\n // Send response if agent returned one\n if (response) {\n await this.sendMessage(message.userPhoneNumber, response, message.chatGuid);\n }\n }\n }\n })();\n }\n\n async sendMessage(to: string, text: string, chatGuid?: string): Promise<boolean> {\n if (!this.client) throw new Error(\"Not connected. Call connect() first.\");\n\n const result = await this.client.FluxService.sendMessage({\n userPhoneNumber: to,\n text,\n chatGuid,\n });\n\n if (!result.success) {\n console.error(`[FLUX] Send failed: ${result.error}`);\n }\n return result.success;\n }\n\n async disconnect(): Promise<void> {\n if (!this.client) return;\n\n await this.client.FluxService.unregisterAgent(this.phoneNumber);\n console.log(`[FLUX] Unregistered agent for ${this.phoneNumber}`);\n this.client = null;\n }\n}\n\n// --- CLI Commands ---\n\n/**\n * Validate command - checks if agent.ts exports correctly\n */\nasync function validateCommand(): Promise<boolean> {\n const agentPath = findAgentFile();\n\n if (!agentPath) {\n console.error(\"[FLUX] No agent.ts or agent.js found in current directory.\");\n console.error(\"[FLUX] Create an agent.ts file with `export default agent`\");\n return false;\n }\n\n console.log(`[FLUX] Validating ${path.basename(agentPath)}...`);\n const result = await validateAgentFile(agentPath);\n\n if (result.valid) {\n console.log(\"[FLUX] ✓ Agent is valid!\");\n return true;\n } else {\n console.error(`[FLUX] ✗ Validation failed: ${result.error}`);\n return false;\n }\n}\n\n/**\n * Run agent locally (for testing without connecting to bridge)\n * Uses the Rapid TUI chat interface\n */\nasync function runLocal() {\n const agentPath = findAgentFile();\n\n if (!agentPath) {\n console.error(\"[FLUX] No agent.ts or agent.js found in current directory.\");\n console.error(\"[FLUX] Create an agent.ts file with `export default agent`\");\n process.exit(1);\n }\n\n // Validate first\n const validation = await validateAgentFile(agentPath);\n if (!validation.valid) {\n console.error(`[FLUX] Agent validation failed: ${validation.error}`);\n process.exit(1);\n }\n\n // Load the agent\n const agent = await loadAgent(agentPath);\n\n // Start the TUI chat interface\n const chat = renderChatUI();\n\n chat.sendMessage(\"Welcome to Flux! Your agent is loaded. Type a message to test it.\");\n\n chat.onInput(async (input) => {\n chat.sendMessage(\"Thinking...\");\n\n try {\n const response = await agent.invoke({\n message: input,\n userPhoneNumber: \"+1234567890\", // Mock phone number for local testing\n });\n chat.sendMessage(response);\n } catch (error: any) {\n chat.sendMessage(`Error: ${error.message}`);\n }\n });\n\n // Keep the Ink app alive. Press Ctrl+C to exit.\n await new Promise(() => {});\n}\n\n/**\n * Run agent in production mode (connected to bridge)\n */\nasync function runProd() {\n const phoneNumber = await getPhoneNumber();\n const agentPath = findAgentFile();\n\n if (!agentPath) {\n console.error(\"[FLUX] No agent.ts or agent.js found in current directory.\");\n console.error(\"[FLUX] Create an agent.ts file with `export default agent`\");\n process.exit(1);\n }\n\n // Validate first\n const validation = await validateAgentFile(agentPath);\n if (!validation.valid) {\n console.error(`[FLUX] Agent validation failed: ${validation.error}`);\n process.exit(1);\n }\n\n // Load the agent\n console.log(`[FLUX] Loading agent from ${path.basename(agentPath)}...`);\n const agent = await loadAgent(agentPath);\n console.log(\"[FLUX] Agent loaded successfully!\");\n\n // Create client with the user's agent as the message handler\n const flux = new FluxClient(phoneNumber, async (message) => {\n console.log(`[FLUX] Processing message from ${message.userPhoneNumber}: ${message.text}`);\n\n try {\n const response = await agent.invoke({\n message: message.text,\n userPhoneNumber: message.userPhoneNumber,\n imageBase64: message.imageBase64,\n });\n console.log(`[FLUX] Agent response: ${response}`);\n return response;\n } catch (error: any) {\n console.error(`[FLUX] Agent error: ${error.message}`);\n return \"Sorry, I encountered an error processing your message.\";\n }\n });\n\n // Connect and register\n await flux.connect();\n await flux.register();\n\n console.log(\"[FLUX] Agent running in production mode. Press Ctrl+C to stop.\");\n console.log(`[FLUX] Messages to ${phoneNumber} will be processed by your agent.\\n`);\n\n // Handle shutdown\n process.on(\"SIGINT\", async () => {\n console.log(\"\\n[FLUX] Shutting down...\");\n await flux.disconnect();\n process.exit(0);\n });\n\n // Keep alive\n await new Promise(() => {});\n}\n\nasync function main() {\n const command = process.argv[2];\n const flag = process.argv[3];\n\n switch (command) {\n case \"login\":\n await login();\n break;\n case \"logout\":\n logout();\n break;\n case \"run\":\n if (flag === \"--local\") {\n await runLocal();\n } else if (flag === \"--prod\" || !flag) {\n // Default to prod mode\n await runProd();\n } else {\n console.error(`[FLUX] Unknown flag: ${flag}`);\n console.log(\"Usage: flux run [--local | --prod]\");\n }\n break;\n case \"validate\":\n await validateCommand();\n break;\n case \"whoami\":\n const config = loadConfig();\n if (config.phoneNumber) {\n console.log(`[FLUX] Logged in as ${config.phoneNumber}`);\n } else {\n console.log(\"[FLUX] Not logged in.\");\n }\n break;\n default:\n console.log(\"Flux CLI - Connect LangChain agents to iMessage\\n\");\n console.log(\"Commands:\");\n console.log(\" flux login - Log in with your phone number\");\n console.log(\" flux logout - Log out\");\n console.log(\" flux validate - Check if agent.ts exports correctly\");\n console.log(\" flux run --local - Test agent locally (no server connection)\");\n console.log(\" flux run --prod - Run agent connected to bridge (default)\");\n console.log(\" flux whoami - Show current logged in user\");\n break;\n }\n}\n\nmain().catch(console.error);"]}
package/dist/cli.js CHANGED
@@ -1,61 +1,37 @@
1
1
  #!/usr/bin/env node
2
- 'use strict';
3
-
4
- var betterGrpc = require('better-grpc');
5
- var cliChat = require('@photon-ai/rapid/cli-chat');
6
- var fs = require('fs');
7
- var path = require('path');
8
- var readline = require('readline');
9
- var url = require('url');
10
-
11
- function _interopNamespace(e) {
12
- if (e && e.__esModule) return e;
13
- var n = Object.create(null);
14
- if (e) {
15
- Object.keys(e).forEach(function (k) {
16
- if (k !== 'default') {
17
- var d = Object.getOwnPropertyDescriptor(e, k);
18
- Object.defineProperty(n, k, d.get ? d : {
19
- enumerable: true,
20
- get: function () { return e[k]; }
21
- });
22
- }
23
- });
24
- }
25
- n.default = e;
26
- return Object.freeze(n);
27
- }
28
-
29
- var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
30
- var path__namespace = /*#__PURE__*/_interopNamespace(path);
31
- var readline__namespace = /*#__PURE__*/_interopNamespace(readline);
2
+ import { Service, server, bidi, client, createGrpcClient } from 'better-grpc';
3
+ import { renderChatUI } from '@photon-ai/rapid/cli-chat';
4
+ import * as fs from 'fs';
5
+ import * as path from 'path';
6
+ import * as readline from 'readline';
7
+ import { pathToFileURL } from 'url';
32
8
 
33
9
  var GRPC_SERVER_ADDRESS = process.env.FLUX_SERVER_ADDRESS || "localhost:50051";
34
- var CONFIG_DIR = path__namespace.join(process.env.HOME || "~", ".flux");
35
- var CONFIG_FILE = path__namespace.join(CONFIG_DIR, "config.json");
10
+ var CONFIG_DIR = path.join(process.env.HOME || "~", ".flux");
11
+ var CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
36
12
  var AGENT_FILE_NAME = "agent.ts";
37
13
  function loadConfig() {
38
14
  try {
39
- if (fs__namespace.existsSync(CONFIG_FILE)) {
40
- return JSON.parse(fs__namespace.readFileSync(CONFIG_FILE, "utf-8"));
15
+ if (fs.existsSync(CONFIG_FILE)) {
16
+ return JSON.parse(fs.readFileSync(CONFIG_FILE, "utf-8"));
41
17
  }
42
18
  } catch {
43
19
  }
44
20
  return {};
45
21
  }
46
22
  function saveConfig(config) {
47
- if (!fs__namespace.existsSync(CONFIG_DIR)) {
48
- fs__namespace.mkdirSync(CONFIG_DIR, { recursive: true });
23
+ if (!fs.existsSync(CONFIG_DIR)) {
24
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
49
25
  }
50
- fs__namespace.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
26
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
51
27
  }
52
28
  function clearConfig() {
53
- if (fs__namespace.existsSync(CONFIG_FILE)) {
54
- fs__namespace.unlinkSync(CONFIG_FILE);
29
+ if (fs.existsSync(CONFIG_FILE)) {
30
+ fs.unlinkSync(CONFIG_FILE);
55
31
  }
56
32
  }
57
33
  async function prompt(question) {
58
- const rl = readline__namespace.createInterface({
34
+ const rl = readline.createInterface({
59
35
  input: process.stdin,
60
36
  output: process.stdout
61
37
  });
@@ -79,7 +55,7 @@ async function login() {
79
55
  return { received: true };
80
56
  }
81
57
  });
82
- const client2 = await betterGrpc.createGrpcClient(GRPC_SERVER_ADDRESS, clientImpl);
58
+ const client2 = await createGrpcClient(GRPC_SERVER_ADDRESS, clientImpl);
83
59
  const result = await client2.FluxService.validateUser(phoneNumber);
84
60
  if (result.error) {
85
61
  console.error(`[FLUX] Login failed: ${result.error}`);
@@ -113,19 +89,19 @@ async function getPhoneNumber() {
113
89
  }
114
90
  function findAgentFile() {
115
91
  const cwd = process.cwd();
116
- const agentPath = path__namespace.join(cwd, AGENT_FILE_NAME);
117
- if (fs__namespace.existsSync(agentPath)) {
92
+ const agentPath = path.join(cwd, AGENT_FILE_NAME);
93
+ if (fs.existsSync(agentPath)) {
118
94
  return agentPath;
119
95
  }
120
- const jsPath = path__namespace.join(cwd, "agent.js");
121
- if (fs__namespace.existsSync(jsPath)) {
96
+ const jsPath = path.join(cwd, "agent.js");
97
+ if (fs.existsSync(jsPath)) {
122
98
  return jsPath;
123
99
  }
124
100
  return null;
125
101
  }
126
102
  async function validateAgentFile(agentPath) {
127
103
  try {
128
- const moduleUrl = url.pathToFileURL(agentPath).href;
104
+ const moduleUrl = pathToFileURL(agentPath).href;
129
105
  const agentModule = await import(moduleUrl);
130
106
  if (!agentModule.default) {
131
107
  return { valid: false, error: "No default export found. Use `export default agent`" };
@@ -140,18 +116,18 @@ async function validateAgentFile(agentPath) {
140
116
  }
141
117
  }
142
118
  async function loadAgent(agentPath) {
143
- const moduleUrl = url.pathToFileURL(agentPath).href;
119
+ const moduleUrl = pathToFileURL(agentPath).href;
144
120
  const agentModule = await import(moduleUrl);
145
121
  return agentModule.default;
146
122
  }
147
- var FluxService = class extends betterGrpc.Service("FluxService") {
148
- sendMessage = betterGrpc.server();
149
- messageStream = betterGrpc.bidi();
150
- registerAgent = betterGrpc.server();
151
- unregisterAgent = betterGrpc.server();
152
- onIncomingMessage = betterGrpc.client();
123
+ var FluxService = class extends Service("FluxService") {
124
+ sendMessage = server();
125
+ messageStream = bidi();
126
+ registerAgent = server();
127
+ unregisterAgent = server();
128
+ onIncomingMessage = client();
153
129
  // Login validation - checks if user exists in Firebase
154
- validateUser = betterGrpc.server();
130
+ validateUser = server();
155
131
  };
156
132
  var FluxClient = class {
157
133
  client = null;
@@ -167,7 +143,7 @@ var FluxClient = class {
167
143
  return { received: true };
168
144
  }
169
145
  });
170
- this.client = await betterGrpc.createGrpcClient(GRPC_SERVER_ADDRESS, clientImpl);
146
+ this.client = await createGrpcClient(GRPC_SERVER_ADDRESS, clientImpl);
171
147
  console.log(`[FLUX] Connected to server at ${GRPC_SERVER_ADDRESS}`);
172
148
  }
173
149
  async register() {
@@ -224,7 +200,7 @@ async function validateCommand() {
224
200
  console.error("[FLUX] Create an agent.ts file with `export default agent`");
225
201
  return false;
226
202
  }
227
- console.log(`[FLUX] Validating ${path__namespace.basename(agentPath)}...`);
203
+ console.log(`[FLUX] Validating ${path.basename(agentPath)}...`);
228
204
  const result = await validateAgentFile(agentPath);
229
205
  if (result.valid) {
230
206
  console.log("[FLUX] \u2713 Agent is valid!");
@@ -247,7 +223,7 @@ async function runLocal() {
247
223
  process.exit(1);
248
224
  }
249
225
  const agent = await loadAgent(agentPath);
250
- const chat = cliChat.renderChatUI();
226
+ const chat = renderChatUI();
251
227
  chat.sendMessage("Welcome to Flux! Your agent is loaded. Type a message to test it.");
252
228
  chat.onInput(async (input) => {
253
229
  chat.sendMessage("Thinking...");
@@ -278,7 +254,7 @@ async function runProd() {
278
254
  console.error(`[FLUX] Agent validation failed: ${validation.error}`);
279
255
  process.exit(1);
280
256
  }
281
- console.log(`[FLUX] Loading agent from ${path__namespace.basename(agentPath)}...`);
257
+ console.log(`[FLUX] Loading agent from ${path.basename(agentPath)}...`);
282
258
  const agent = await loadAgent(agentPath);
283
259
  console.log("[FLUX] Agent loaded successfully!");
284
260
  const flux = new FluxClient(phoneNumber, async (message) => {
@@ -354,6 +330,6 @@ async function main() {
354
330
  }
355
331
  main().catch(console.error);
356
332
 
357
- exports.FluxClient = FluxClient;
333
+ export { FluxClient };
358
334
  //# sourceMappingURL=cli.js.map
359
335
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts"],"names":["path","fs","readline","client","createGrpcClient","pathToFileURL","Service","server","bidi","renderChatUI"],"mappings":"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","file":"cli.js","sourcesContent":["/**\n * Flux CLI - gRPC Client for iMessage Bridge\n * ==========================================\n * This code connects the Flux CLI to the Flux Server's iMessage bridge.\n * Users define their LangChain agent in agent.ts with `export default agent`\n */\n\nimport { Service, server, client, bidi, createGrpcClient } from \"better-grpc\";\nimport { renderChatUI } from \"@photon-ai/rapid/cli-chat\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as readline from \"readline\";\nimport { pathToFileURL } from \"url\";\n\n// --- Configuration ---\nconst GRPC_SERVER_ADDRESS = process.env.FLUX_SERVER_ADDRESS || \"localhost:50051\";\nconst CONFIG_DIR = path.join(process.env.HOME || \"~\", \".flux\");\nconst CONFIG_FILE = path.join(CONFIG_DIR, \"config.json\");\nconst AGENT_FILE_NAME = \"agent.ts\";\n\n// --- Auth Storage ---\n\ninterface FluxConfig {\n phoneNumber?: string;\n}\n\nfunction loadConfig(): FluxConfig {\n try {\n if (fs.existsSync(CONFIG_FILE)) {\n return JSON.parse(fs.readFileSync(CONFIG_FILE, \"utf-8\"));\n }\n } catch {}\n return {};\n}\n\nfunction saveConfig(config: FluxConfig): void {\n if (!fs.existsSync(CONFIG_DIR)) {\n fs.mkdirSync(CONFIG_DIR, { recursive: true });\n }\n fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));\n}\n\nfunction clearConfig(): void {\n if (fs.existsSync(CONFIG_FILE)) {\n fs.unlinkSync(CONFIG_FILE);\n }\n}\n\nasync function prompt(question: string): Promise<string> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\nasync function login(): Promise<string> {\n const phoneNumber = await prompt(\"Enter your phone number (e.g. +15551234567): \");\n if (!phoneNumber.match(/^\\+?[0-9]{10,15}$/)) {\n console.error(\"Invalid phone number format.\");\n process.exit(1);\n }\n\n // Validate with server (checks/creates user in Firebase)\n console.log(\"[FLUX] Validating with server...\");\n try {\n const clientImpl = FluxService.Client({\n async onIncomingMessage() {\n return { received: true };\n },\n });\n const client = await createGrpcClient(GRPC_SERVER_ADDRESS, clientImpl);\n const result = await client.FluxService.validateUser(phoneNumber);\n\n if (result.error) {\n console.error(`[FLUX] Login failed: ${result.error}`);\n process.exit(1);\n }\n\n if (result.created) {\n console.log(`[FLUX] New account created for ${phoneNumber}`);\n } else if (result.exists) {\n console.log(`[FLUX] Welcome back, ${phoneNumber}`);\n }\n\n saveConfig({ phoneNumber });\n console.log(`[FLUX] Logged in as ${phoneNumber}`);\n return phoneNumber;\n } catch (error: any) {\n console.error(`[FLUX] Failed to connect to server: ${error.message}`);\n console.error(`[FLUX] Make sure the Flux server is running at ${GRPC_SERVER_ADDRESS}`);\n process.exit(1);\n }\n}\n\nfunction logout(): void {\n clearConfig();\n console.log(\"[FLUX] Logged out.\");\n}\n\nasync function getPhoneNumber(): Promise<string> {\n const config = loadConfig();\n if (config.phoneNumber) {\n return config.phoneNumber;\n }\n console.log(\"[FLUX] Not logged in.\");\n return await login();\n}\n\n// --- Agent Types ---\n\n/**\n * FluxAgent interface - users must export default an object matching this interface\n * The agent receives a message and returns a response string\n */\nexport interface FluxAgent {\n invoke: (input: { message: string; userPhoneNumber: string; imageBase64?: string }) => Promise<string>;\n}\n\n// --- Agent Loader ---\n\n/**\n * Find agent.ts in the current working directory\n */\nfunction findAgentFile(): string | null {\n const cwd = process.cwd();\n const agentPath = path.join(cwd, AGENT_FILE_NAME);\n\n if (fs.existsSync(agentPath)) {\n return agentPath;\n }\n\n // Also check for agent.js\n const jsPath = path.join(cwd, \"agent.js\");\n if (fs.existsSync(jsPath)) {\n return jsPath;\n }\n\n return null;\n}\n\n/**\n * Validate that the agent file exports a default agent with invoke method\n */\nasync function validateAgentFile(agentPath: string): Promise<{ valid: boolean; error?: string }> {\n try {\n const moduleUrl = pathToFileURL(agentPath).href;\n const agentModule = await import(moduleUrl);\n\n if (!agentModule.default) {\n return { valid: false, error: \"No default export found. Use `export default agent`\" };\n }\n\n const agent = agentModule.default;\n\n if (typeof agent.invoke !== \"function\") {\n return { valid: false, error: \"Agent must have an `invoke` method\" };\n }\n\n return { valid: true };\n } catch (error: any) {\n return { valid: false, error: `Failed to load agent: ${error.message}` };\n }\n}\n\n/**\n * Load the agent from agent.ts\n */\nasync function loadAgent(agentPath: string): Promise<FluxAgent> {\n const moduleUrl = pathToFileURL(agentPath).href;\n const agentModule = await import(moduleUrl);\n return agentModule.default as FluxAgent;\n}\n\n// --- Message Types ---\n\nexport interface IncomingMessage {\n userPhoneNumber: string;\n text: string;\n imageBase64?: string;\n chatGuid: string;\n messageGuid: string;\n}\n\nexport interface OutgoingMessage {\n userPhoneNumber: string;\n text: string;\n chatGuid?: string;\n}\n\n// --- FluxService Definition (must match server) ---\n\nabstract class FluxService extends Service(\"FluxService\") {\n sendMessage = server<(message: OutgoingMessage) => { success: boolean; error?: string }>();\n messageStream = bidi<(message: IncomingMessage | { ack: string }) => void>();\n registerAgent = server<(phoneNumber: string) => { success: boolean; error?: string }>();\n unregisterAgent = server<(phoneNumber: string) => { success: boolean }>();\n onIncomingMessage = client<(message: IncomingMessage) => { received: boolean }>();\n // Login validation - checks if user exists in Firebase\n validateUser = server<(phoneNumber: string) => { exists: boolean; created: boolean; error?: string }>();\n}\n\n// --- FluxClient Class ---\n\nexport class FluxClient {\n private client: Awaited<ReturnType<typeof createGrpcClient>> | null = null;\n private phoneNumber: string;\n private onMessage: (message: IncomingMessage) => Promise<string | void>;\n\n constructor(\n phoneNumber: string,\n onMessage: (message: IncomingMessage) => Promise<string | void>\n ) {\n this.phoneNumber = phoneNumber.replace(/[\\s\\-\\(\\)]/g, \"\");\n this.onMessage = onMessage;\n }\n\n async connect(): Promise<void> {\n const clientImpl = FluxService.Client({\n async onIncomingMessage(message: IncomingMessage) {\n return { received: true };\n },\n });\n\n this.client = await createGrpcClient(GRPC_SERVER_ADDRESS, clientImpl);\n console.log(`[FLUX] Connected to server at ${GRPC_SERVER_ADDRESS}`);\n }\n\n async register(): Promise<boolean> {\n if (!this.client) throw new Error(\"Not connected. Call connect() first.\");\n\n const result = await this.client.FluxService.registerAgent(this.phoneNumber);\n if (result.success) {\n console.log(`[FLUX] Registered agent for ${this.phoneNumber}`);\n this.startMessageStream();\n } else {\n console.error(`[FLUX] Registration failed: ${result.error}`);\n }\n return result.success;\n }\n\n private async startMessageStream(): Promise<void> {\n if (!this.client) return;\n\n (async () => {\n for await (const [message] of this.client!.FluxService.messageStream) {\n if (\"ack\" in message) {\n console.log(`[FLUX] Received ack: ${message.ack}`);\n } else {\n console.log(`[FLUX] Incoming message from ${message.userPhoneNumber}: ${message.text}`);\n\n // Acknowledge receipt\n await this.client!.FluxService.messageStream({ ack: message.messageGuid });\n\n // Process with user's agent and get response\n const response = await this.onMessage(message);\n\n // Send response if agent returned one\n if (response) {\n await this.sendMessage(message.userPhoneNumber, response, message.chatGuid);\n }\n }\n }\n })();\n }\n\n async sendMessage(to: string, text: string, chatGuid?: string): Promise<boolean> {\n if (!this.client) throw new Error(\"Not connected. Call connect() first.\");\n\n const result = await this.client.FluxService.sendMessage({\n userPhoneNumber: to,\n text,\n chatGuid,\n });\n\n if (!result.success) {\n console.error(`[FLUX] Send failed: ${result.error}`);\n }\n return result.success;\n }\n\n async disconnect(): Promise<void> {\n if (!this.client) return;\n\n await this.client.FluxService.unregisterAgent(this.phoneNumber);\n console.log(`[FLUX] Unregistered agent for ${this.phoneNumber}`);\n this.client = null;\n }\n}\n\n// --- CLI Commands ---\n\n/**\n * Validate command - checks if agent.ts exports correctly\n */\nasync function validateCommand(): Promise<boolean> {\n const agentPath = findAgentFile();\n\n if (!agentPath) {\n console.error(\"[FLUX] No agent.ts or agent.js found in current directory.\");\n console.error(\"[FLUX] Create an agent.ts file with `export default agent`\");\n return false;\n }\n\n console.log(`[FLUX] Validating ${path.basename(agentPath)}...`);\n const result = await validateAgentFile(agentPath);\n\n if (result.valid) {\n console.log(\"[FLUX] ✓ Agent is valid!\");\n return true;\n } else {\n console.error(`[FLUX] ✗ Validation failed: ${result.error}`);\n return false;\n }\n}\n\n/**\n * Run agent locally (for testing without connecting to bridge)\n * Uses the Rapid TUI chat interface\n */\nasync function runLocal() {\n const agentPath = findAgentFile();\n\n if (!agentPath) {\n console.error(\"[FLUX] No agent.ts or agent.js found in current directory.\");\n console.error(\"[FLUX] Create an agent.ts file with `export default agent`\");\n process.exit(1);\n }\n\n // Validate first\n const validation = await validateAgentFile(agentPath);\n if (!validation.valid) {\n console.error(`[FLUX] Agent validation failed: ${validation.error}`);\n process.exit(1);\n }\n\n // Load the agent\n const agent = await loadAgent(agentPath);\n\n // Start the TUI chat interface\n const chat = renderChatUI();\n\n chat.sendMessage(\"Welcome to Flux! Your agent is loaded. Type a message to test it.\");\n\n chat.onInput(async (input) => {\n chat.sendMessage(\"Thinking...\");\n\n try {\n const response = await agent.invoke({\n message: input,\n userPhoneNumber: \"+1234567890\", // Mock phone number for local testing\n });\n chat.sendMessage(response);\n } catch (error: any) {\n chat.sendMessage(`Error: ${error.message}`);\n }\n });\n\n // Keep the Ink app alive. Press Ctrl+C to exit.\n await new Promise(() => {});\n}\n\n/**\n * Run agent in production mode (connected to bridge)\n */\nasync function runProd() {\n const phoneNumber = await getPhoneNumber();\n const agentPath = findAgentFile();\n\n if (!agentPath) {\n console.error(\"[FLUX] No agent.ts or agent.js found in current directory.\");\n console.error(\"[FLUX] Create an agent.ts file with `export default agent`\");\n process.exit(1);\n }\n\n // Validate first\n const validation = await validateAgentFile(agentPath);\n if (!validation.valid) {\n console.error(`[FLUX] Agent validation failed: ${validation.error}`);\n process.exit(1);\n }\n\n // Load the agent\n console.log(`[FLUX] Loading agent from ${path.basename(agentPath)}...`);\n const agent = await loadAgent(agentPath);\n console.log(\"[FLUX] Agent loaded successfully!\");\n\n // Create client with the user's agent as the message handler\n const flux = new FluxClient(phoneNumber, async (message) => {\n console.log(`[FLUX] Processing message from ${message.userPhoneNumber}: ${message.text}`);\n\n try {\n const response = await agent.invoke({\n message: message.text,\n userPhoneNumber: message.userPhoneNumber,\n imageBase64: message.imageBase64,\n });\n console.log(`[FLUX] Agent response: ${response}`);\n return response;\n } catch (error: any) {\n console.error(`[FLUX] Agent error: ${error.message}`);\n return \"Sorry, I encountered an error processing your message.\";\n }\n });\n\n // Connect and register\n await flux.connect();\n await flux.register();\n\n console.log(\"[FLUX] Agent running in production mode. Press Ctrl+C to stop.\");\n console.log(`[FLUX] Messages to ${phoneNumber} will be processed by your agent.\\n`);\n\n // Handle shutdown\n process.on(\"SIGINT\", async () => {\n console.log(\"\\n[FLUX] Shutting down...\");\n await flux.disconnect();\n process.exit(0);\n });\n\n // Keep alive\n await new Promise(() => {});\n}\n\nasync function main() {\n const command = process.argv[2];\n const flag = process.argv[3];\n\n switch (command) {\n case \"login\":\n await login();\n break;\n case \"logout\":\n logout();\n break;\n case \"run\":\n if (flag === \"--local\") {\n await runLocal();\n } else if (flag === \"--prod\" || !flag) {\n // Default to prod mode\n await runProd();\n } else {\n console.error(`[FLUX] Unknown flag: ${flag}`);\n console.log(\"Usage: flux run [--local | --prod]\");\n }\n break;\n case \"validate\":\n await validateCommand();\n break;\n case \"whoami\":\n const config = loadConfig();\n if (config.phoneNumber) {\n console.log(`[FLUX] Logged in as ${config.phoneNumber}`);\n } else {\n console.log(\"[FLUX] Not logged in.\");\n }\n break;\n default:\n console.log(\"Flux CLI - Connect LangChain agents to iMessage\\n\");\n console.log(\"Commands:\");\n console.log(\" flux login - Log in with your phone number\");\n console.log(\" flux logout - Log out\");\n console.log(\" flux validate - Check if agent.ts exports correctly\");\n console.log(\" flux run --local - Test agent locally (no server connection)\");\n console.log(\" flux run --prod - Run agent connected to bridge (default)\");\n console.log(\" flux whoami - Show current logged in user\");\n break;\n }\n}\n\nmain().catch(console.error);"]}
1
+ {"version":3,"sources":["../src/cli.ts"],"names":["client"],"mappings":"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","file":"cli.js","sourcesContent":["/**\n * Flux CLI - gRPC Client for iMessage Bridge\n * ==========================================\n * This code connects the Flux CLI to the Flux Server's iMessage bridge.\n * Users define their LangChain agent in agent.ts with `export default agent`\n */\n\nimport { Service, server, client, bidi, createGrpcClient } from \"better-grpc\";\nimport { renderChatUI } from \"@photon-ai/rapid/cli-chat\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as readline from \"readline\";\nimport { pathToFileURL } from \"url\";\n\n// --- Configuration ---\nconst GRPC_SERVER_ADDRESS = process.env.FLUX_SERVER_ADDRESS || \"localhost:50051\";\nconst CONFIG_DIR = path.join(process.env.HOME || \"~\", \".flux\");\nconst CONFIG_FILE = path.join(CONFIG_DIR, \"config.json\");\nconst AGENT_FILE_NAME = \"agent.ts\";\n\n// --- Auth Storage ---\n\ninterface FluxConfig {\n phoneNumber?: string;\n}\n\nfunction loadConfig(): FluxConfig {\n try {\n if (fs.existsSync(CONFIG_FILE)) {\n return JSON.parse(fs.readFileSync(CONFIG_FILE, \"utf-8\"));\n }\n } catch {}\n return {};\n}\n\nfunction saveConfig(config: FluxConfig): void {\n if (!fs.existsSync(CONFIG_DIR)) {\n fs.mkdirSync(CONFIG_DIR, { recursive: true });\n }\n fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));\n}\n\nfunction clearConfig(): void {\n if (fs.existsSync(CONFIG_FILE)) {\n fs.unlinkSync(CONFIG_FILE);\n }\n}\n\nasync function prompt(question: string): Promise<string> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\nasync function login(): Promise<string> {\n const phoneNumber = await prompt(\"Enter your phone number (e.g. +15551234567): \");\n if (!phoneNumber.match(/^\\+?[0-9]{10,15}$/)) {\n console.error(\"Invalid phone number format.\");\n process.exit(1);\n }\n\n // Validate with server (checks/creates user in Firebase)\n console.log(\"[FLUX] Validating with server...\");\n try {\n const clientImpl = FluxService.Client({\n async onIncomingMessage() {\n return { received: true };\n },\n });\n const client = await createGrpcClient(GRPC_SERVER_ADDRESS, clientImpl);\n const result = await client.FluxService.validateUser(phoneNumber);\n\n if (result.error) {\n console.error(`[FLUX] Login failed: ${result.error}`);\n process.exit(1);\n }\n\n if (result.created) {\n console.log(`[FLUX] New account created for ${phoneNumber}`);\n } else if (result.exists) {\n console.log(`[FLUX] Welcome back, ${phoneNumber}`);\n }\n\n saveConfig({ phoneNumber });\n console.log(`[FLUX] Logged in as ${phoneNumber}`);\n return phoneNumber;\n } catch (error: any) {\n console.error(`[FLUX] Failed to connect to server: ${error.message}`);\n console.error(`[FLUX] Make sure the Flux server is running at ${GRPC_SERVER_ADDRESS}`);\n process.exit(1);\n }\n}\n\nfunction logout(): void {\n clearConfig();\n console.log(\"[FLUX] Logged out.\");\n}\n\nasync function getPhoneNumber(): Promise<string> {\n const config = loadConfig();\n if (config.phoneNumber) {\n return config.phoneNumber;\n }\n console.log(\"[FLUX] Not logged in.\");\n return await login();\n}\n\n// --- Agent Types ---\n\n/**\n * FluxAgent interface - users must export default an object matching this interface\n * The agent receives a message and returns a response string\n */\nexport interface FluxAgent {\n invoke: (input: { message: string; userPhoneNumber: string; imageBase64?: string }) => Promise<string>;\n}\n\n// --- Agent Loader ---\n\n/**\n * Find agent.ts in the current working directory\n */\nfunction findAgentFile(): string | null {\n const cwd = process.cwd();\n const agentPath = path.join(cwd, AGENT_FILE_NAME);\n\n if (fs.existsSync(agentPath)) {\n return agentPath;\n }\n\n // Also check for agent.js\n const jsPath = path.join(cwd, \"agent.js\");\n if (fs.existsSync(jsPath)) {\n return jsPath;\n }\n\n return null;\n}\n\n/**\n * Validate that the agent file exports a default agent with invoke method\n */\nasync function validateAgentFile(agentPath: string): Promise<{ valid: boolean; error?: string }> {\n try {\n const moduleUrl = pathToFileURL(agentPath).href;\n const agentModule = await import(moduleUrl);\n\n if (!agentModule.default) {\n return { valid: false, error: \"No default export found. Use `export default agent`\" };\n }\n\n const agent = agentModule.default;\n\n if (typeof agent.invoke !== \"function\") {\n return { valid: false, error: \"Agent must have an `invoke` method\" };\n }\n\n return { valid: true };\n } catch (error: any) {\n return { valid: false, error: `Failed to load agent: ${error.message}` };\n }\n}\n\n/**\n * Load the agent from agent.ts\n */\nasync function loadAgent(agentPath: string): Promise<FluxAgent> {\n const moduleUrl = pathToFileURL(agentPath).href;\n const agentModule = await import(moduleUrl);\n return agentModule.default as FluxAgent;\n}\n\n// --- Message Types ---\n\nexport interface IncomingMessage {\n userPhoneNumber: string;\n text: string;\n imageBase64?: string;\n chatGuid: string;\n messageGuid: string;\n}\n\nexport interface OutgoingMessage {\n userPhoneNumber: string;\n text: string;\n chatGuid?: string;\n}\n\n// --- FluxService Definition (must match server) ---\n\nabstract class FluxService extends Service(\"FluxService\") {\n sendMessage = server<(message: OutgoingMessage) => { success: boolean; error?: string }>();\n messageStream = bidi<(message: IncomingMessage | { ack: string }) => void>();\n registerAgent = server<(phoneNumber: string) => { success: boolean; error?: string }>();\n unregisterAgent = server<(phoneNumber: string) => { success: boolean }>();\n onIncomingMessage = client<(message: IncomingMessage) => { received: boolean }>();\n // Login validation - checks if user exists in Firebase\n validateUser = server<(phoneNumber: string) => { exists: boolean; created: boolean; error?: string }>();\n}\n\n// --- FluxClient Class ---\n\nexport class FluxClient {\n private client: Awaited<ReturnType<typeof createGrpcClient>> | null = null;\n private phoneNumber: string;\n private onMessage: (message: IncomingMessage) => Promise<string | void>;\n\n constructor(\n phoneNumber: string,\n onMessage: (message: IncomingMessage) => Promise<string | void>\n ) {\n this.phoneNumber = phoneNumber.replace(/[\\s\\-\\(\\)]/g, \"\");\n this.onMessage = onMessage;\n }\n\n async connect(): Promise<void> {\n const clientImpl = FluxService.Client({\n async onIncomingMessage(message: IncomingMessage) {\n return { received: true };\n },\n });\n\n this.client = await createGrpcClient(GRPC_SERVER_ADDRESS, clientImpl);\n console.log(`[FLUX] Connected to server at ${GRPC_SERVER_ADDRESS}`);\n }\n\n async register(): Promise<boolean> {\n if (!this.client) throw new Error(\"Not connected. Call connect() first.\");\n\n const result = await this.client.FluxService.registerAgent(this.phoneNumber);\n if (result.success) {\n console.log(`[FLUX] Registered agent for ${this.phoneNumber}`);\n this.startMessageStream();\n } else {\n console.error(`[FLUX] Registration failed: ${result.error}`);\n }\n return result.success;\n }\n\n private async startMessageStream(): Promise<void> {\n if (!this.client) return;\n\n (async () => {\n for await (const [message] of this.client!.FluxService.messageStream) {\n if (\"ack\" in message) {\n console.log(`[FLUX] Received ack: ${message.ack}`);\n } else {\n console.log(`[FLUX] Incoming message from ${message.userPhoneNumber}: ${message.text}`);\n\n // Acknowledge receipt\n await this.client!.FluxService.messageStream({ ack: message.messageGuid });\n\n // Process with user's agent and get response\n const response = await this.onMessage(message);\n\n // Send response if agent returned one\n if (response) {\n await this.sendMessage(message.userPhoneNumber, response, message.chatGuid);\n }\n }\n }\n })();\n }\n\n async sendMessage(to: string, text: string, chatGuid?: string): Promise<boolean> {\n if (!this.client) throw new Error(\"Not connected. Call connect() first.\");\n\n const result = await this.client.FluxService.sendMessage({\n userPhoneNumber: to,\n text,\n chatGuid,\n });\n\n if (!result.success) {\n console.error(`[FLUX] Send failed: ${result.error}`);\n }\n return result.success;\n }\n\n async disconnect(): Promise<void> {\n if (!this.client) return;\n\n await this.client.FluxService.unregisterAgent(this.phoneNumber);\n console.log(`[FLUX] Unregistered agent for ${this.phoneNumber}`);\n this.client = null;\n }\n}\n\n// --- CLI Commands ---\n\n/**\n * Validate command - checks if agent.ts exports correctly\n */\nasync function validateCommand(): Promise<boolean> {\n const agentPath = findAgentFile();\n\n if (!agentPath) {\n console.error(\"[FLUX] No agent.ts or agent.js found in current directory.\");\n console.error(\"[FLUX] Create an agent.ts file with `export default agent`\");\n return false;\n }\n\n console.log(`[FLUX] Validating ${path.basename(agentPath)}...`);\n const result = await validateAgentFile(agentPath);\n\n if (result.valid) {\n console.log(\"[FLUX] ✓ Agent is valid!\");\n return true;\n } else {\n console.error(`[FLUX] ✗ Validation failed: ${result.error}`);\n return false;\n }\n}\n\n/**\n * Run agent locally (for testing without connecting to bridge)\n * Uses the Rapid TUI chat interface\n */\nasync function runLocal() {\n const agentPath = findAgentFile();\n\n if (!agentPath) {\n console.error(\"[FLUX] No agent.ts or agent.js found in current directory.\");\n console.error(\"[FLUX] Create an agent.ts file with `export default agent`\");\n process.exit(1);\n }\n\n // Validate first\n const validation = await validateAgentFile(agentPath);\n if (!validation.valid) {\n console.error(`[FLUX] Agent validation failed: ${validation.error}`);\n process.exit(1);\n }\n\n // Load the agent\n const agent = await loadAgent(agentPath);\n\n // Start the TUI chat interface\n const chat = renderChatUI();\n\n chat.sendMessage(\"Welcome to Flux! Your agent is loaded. Type a message to test it.\");\n\n chat.onInput(async (input) => {\n chat.sendMessage(\"Thinking...\");\n\n try {\n const response = await agent.invoke({\n message: input,\n userPhoneNumber: \"+1234567890\", // Mock phone number for local testing\n });\n chat.sendMessage(response);\n } catch (error: any) {\n chat.sendMessage(`Error: ${error.message}`);\n }\n });\n\n // Keep the Ink app alive. Press Ctrl+C to exit.\n await new Promise(() => {});\n}\n\n/**\n * Run agent in production mode (connected to bridge)\n */\nasync function runProd() {\n const phoneNumber = await getPhoneNumber();\n const agentPath = findAgentFile();\n\n if (!agentPath) {\n console.error(\"[FLUX] No agent.ts or agent.js found in current directory.\");\n console.error(\"[FLUX] Create an agent.ts file with `export default agent`\");\n process.exit(1);\n }\n\n // Validate first\n const validation = await validateAgentFile(agentPath);\n if (!validation.valid) {\n console.error(`[FLUX] Agent validation failed: ${validation.error}`);\n process.exit(1);\n }\n\n // Load the agent\n console.log(`[FLUX] Loading agent from ${path.basename(agentPath)}...`);\n const agent = await loadAgent(agentPath);\n console.log(\"[FLUX] Agent loaded successfully!\");\n\n // Create client with the user's agent as the message handler\n const flux = new FluxClient(phoneNumber, async (message) => {\n console.log(`[FLUX] Processing message from ${message.userPhoneNumber}: ${message.text}`);\n\n try {\n const response = await agent.invoke({\n message: message.text,\n userPhoneNumber: message.userPhoneNumber,\n imageBase64: message.imageBase64,\n });\n console.log(`[FLUX] Agent response: ${response}`);\n return response;\n } catch (error: any) {\n console.error(`[FLUX] Agent error: ${error.message}`);\n return \"Sorry, I encountered an error processing your message.\";\n }\n });\n\n // Connect and register\n await flux.connect();\n await flux.register();\n\n console.log(\"[FLUX] Agent running in production mode. Press Ctrl+C to stop.\");\n console.log(`[FLUX] Messages to ${phoneNumber} will be processed by your agent.\\n`);\n\n // Handle shutdown\n process.on(\"SIGINT\", async () => {\n console.log(\"\\n[FLUX] Shutting down...\");\n await flux.disconnect();\n process.exit(0);\n });\n\n // Keep alive\n await new Promise(() => {});\n}\n\nasync function main() {\n const command = process.argv[2];\n const flag = process.argv[3];\n\n switch (command) {\n case \"login\":\n await login();\n break;\n case \"logout\":\n logout();\n break;\n case \"run\":\n if (flag === \"--local\") {\n await runLocal();\n } else if (flag === \"--prod\" || !flag) {\n // Default to prod mode\n await runProd();\n } else {\n console.error(`[FLUX] Unknown flag: ${flag}`);\n console.log(\"Usage: flux run [--local | --prod]\");\n }\n break;\n case \"validate\":\n await validateCommand();\n break;\n case \"whoami\":\n const config = loadConfig();\n if (config.phoneNumber) {\n console.log(`[FLUX] Logged in as ${config.phoneNumber}`);\n } else {\n console.log(\"[FLUX] Not logged in.\");\n }\n break;\n default:\n console.log(\"Flux CLI - Connect LangChain agents to iMessage\\n\");\n console.log(\"Commands:\");\n console.log(\" flux login - Log in with your phone number\");\n console.log(\" flux logout - Log out\");\n console.log(\" flux validate - Check if agent.ts exports correctly\");\n console.log(\" flux run --local - Test agent locally (no server connection)\");\n console.log(\" flux run --prod - Run agent connected to bridge (default)\");\n console.log(\" flux whoami - Show current logged in user\");\n break;\n }\n}\n\nmain().catch(console.error);"]}
package/package.json CHANGED
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "name": "@photon-cli/flux",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Flux CLI - Connect LangChain agents to iMessage",
5
5
  "main": "dist/cli.cjs",
6
6
  "bin": {
7
7
  "flux": "./dist/cli.cjs"
8
8
  },
9
+ "type": "module",
10
+ "files": [
11
+ "dist"
12
+ ],
9
13
  "scripts": {
10
14
  "flux": "bun src/cli.ts",
11
15
  "build": "tsup",
@@ -1,8 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(npm view:*)",
5
- "Bash(cat:*)"
6
- ]
7
- }
8
- }
package/assets/banner.png DELETED
Binary file