@tryfridayai/cli 0.2.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.
package/bin/friday.js ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * friday — CLI entry point
5
+ *
6
+ * Usage:
7
+ * friday chat [--workspace <path>] Interactive conversation
8
+ * friday serve [--port <port>] Start HTTP/WebSocket server
9
+ * friday --help Show help
10
+ */
11
+
12
+ import { run } from '../src/cli.js';
13
+ run(process.argv.slice(2));
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * postinstall — friendly welcome after npm install -g friday-ai
5
+ *
6
+ * Shows a brief message so the user knows what to do next.
7
+ * Skips output in CI environments to avoid noise.
8
+ */
9
+
10
+ if (process.env.CI || process.env.CONTINUOUS_INTEGRATION) {
11
+ process.exit(0);
12
+ }
13
+
14
+ const PURPLE = '\x1b[38;5;141m';
15
+ const TEAL = '\x1b[38;5;43m';
16
+ const DIM = '\x1b[2m';
17
+ const BOLD = '\x1b[1m';
18
+ const RESET = '\x1b[0m';
19
+
20
+ console.log('');
21
+ console.log(` ${PURPLE}${BOLD}Friday AI${RESET} installed successfully.`);
22
+ console.log('');
23
+ console.log(` Get started:`);
24
+ console.log(` ${TEAL}friday${RESET} Open chat`);
25
+ console.log(` ${TEAL}friday setup${RESET} First-time setup (API key, workspace)`);
26
+ console.log(` ${TEAL}friday --help${RESET} See all commands`);
27
+ console.log('');
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@tryfridayai/cli",
3
+ "publishConfig": {
4
+ "access": "public"
5
+ },
6
+ "version": "0.2.0",
7
+ "description": "Friday AI — autonomous agent for your terminal. Chat, build apps, research, automate tasks.",
8
+ "type": "module",
9
+ "bin": {
10
+ "friday": "./bin/friday.js"
11
+ },
12
+ "main": "src/cli.js",
13
+ "files": [
14
+ "bin/",
15
+ "src/"
16
+ ],
17
+ "scripts": {
18
+ "start": "node bin/friday.js chat",
19
+ "test": "node --test tests/*.test.mjs",
20
+ "postinstall": "node bin/postinstall.js"
21
+ },
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "https://github.com/tryfridayai/friday_cli.git",
25
+ "directory": "packages/cli"
26
+ },
27
+ "homepage": "https://tryfriday.ai",
28
+ "keywords": [
29
+ "ai",
30
+ "cli",
31
+ "claude",
32
+ "agent",
33
+ "friday",
34
+ "terminal",
35
+ "chat",
36
+ "autonomous",
37
+ "mcp"
38
+ ],
39
+ "author": "Friday AI <hello@tryfriday.ai>",
40
+ "dependencies": {
41
+ "friday-runtime": "^0.2.0"
42
+ },
43
+ "engines": {
44
+ "node": ">=18.0.0"
45
+ },
46
+ "license": "MIT"
47
+ }
package/src/cli.js ADDED
@@ -0,0 +1,132 @@
1
+ /**
2
+ * CLI command router
3
+ *
4
+ * Parses argv and dispatches to the appropriate command handler.
5
+ * Keeps things simple — no framework dependency (no commander/yargs).
6
+ */
7
+
8
+ import fs from 'fs';
9
+ import path from 'path';
10
+ import os from 'os';
11
+ import { fileURLToPath } from 'url';
12
+
13
+ const __filename = fileURLToPath(import.meta.url);
14
+ const __dirname = path.dirname(__filename);
15
+ const pkgJson = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8'));
16
+
17
+ const CONFIG_DIR = process.env.FRIDAY_CONFIG_DIR || path.join(os.homedir(), '.friday');
18
+ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
19
+
20
+ const COMMANDS = {
21
+ chat: () => import('./commands/chat.js'),
22
+ serve: () => import('./commands/serve.js'),
23
+ setup: () => import('./commands/setup.js'),
24
+ install: () => import('./commands/install.js'),
25
+ uninstall: () => import('./commands/uninstall.js'),
26
+ plugins: () => import('./commands/plugins.js'),
27
+ schedule: () => import('./commands/schedule.js'),
28
+ };
29
+
30
+ function parseArgs(argv) {
31
+ const result = { _: [] };
32
+ for (let i = 0; i < argv.length; i++) {
33
+ const arg = argv[i];
34
+ if (arg === '--help' || arg === '-h') {
35
+ result.help = true;
36
+ } else if (arg === '--verbose' || arg === '-v') {
37
+ result.verbose = true;
38
+ } else if (arg === '--version' || arg === '-V') {
39
+ result.version = true;
40
+ } else if (arg.startsWith('--')) {
41
+ const key = arg.slice(2);
42
+ const next = argv[i + 1];
43
+ if (!next || next.startsWith('--')) {
44
+ result[key] = true;
45
+ } else {
46
+ result[key] = next;
47
+ i++;
48
+ }
49
+ } else {
50
+ result._.push(arg);
51
+ }
52
+ }
53
+ return result;
54
+ }
55
+
56
+ function printHelp() {
57
+ console.log(`
58
+ friday — AI agent runtime
59
+
60
+ Usage:
61
+ friday <command> [options]
62
+
63
+ Commands:
64
+ chat Interactive conversation with Friday (default)
65
+ setup Guided onboarding wizard
66
+ install Install a plugin (e.g. friday install github)
67
+ uninstall Remove a plugin
68
+ plugins List installed and available plugins
69
+ schedule Manage scheduled agents
70
+ serve Start HTTP/WebSocket server for remote clients
71
+
72
+ Options:
73
+ --workspace <path> Working directory for the agent (default: ~/FridayWorkspace)
74
+ --port <port> Server port for 'serve' command (default: 8787)
75
+ --verbose Show debug output
76
+ --version Show version
77
+ --help, -h Show this help message
78
+
79
+ Examples:
80
+ friday Start interactive chat
81
+ friday setup First-time setup
82
+ friday install github Install GitHub plugin
83
+ friday plugins See all plugins
84
+ friday chat --workspace ./myproject
85
+ friday serve --port 3000
86
+ `);
87
+ }
88
+
89
+ function isFirstRun() {
90
+ try {
91
+ if (fs.existsSync(CONFIG_FILE)) {
92
+ const config = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'));
93
+ return !config.setupComplete;
94
+ }
95
+ } catch {
96
+ // ignore
97
+ }
98
+ return true;
99
+ }
100
+
101
+ export async function run(argv) {
102
+ const args = parseArgs(argv);
103
+
104
+ if (args.version) {
105
+ console.log(`friday v${pkgJson.version}`);
106
+ process.exit(0);
107
+ }
108
+
109
+ if (args.help && args._.length === 0) {
110
+ printHelp();
111
+ process.exit(0);
112
+ }
113
+
114
+ let commandName = args._[0] || 'chat';
115
+
116
+ // First-run detection: if no setup done and user runs chat, prompt setup first
117
+ if (commandName === 'chat' && isFirstRun() && !process.env.ANTHROPIC_API_KEY) {
118
+ console.log('');
119
+ console.log(' Looks like this is your first time. Running setup...');
120
+ console.log('');
121
+ commandName = 'setup';
122
+ }
123
+
124
+ if (!COMMANDS[commandName]) {
125
+ console.error(`Unknown command: ${commandName}`);
126
+ console.error(`Run 'friday --help' for usage.`);
127
+ process.exit(1);
128
+ }
129
+
130
+ const mod = await COMMANDS[commandName]();
131
+ await mod.default(args);
132
+ }