atlas-terminal 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Chris Ispasou - Ispasa
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.
package/README.md ADDED
@@ -0,0 +1,127 @@
1
+ # ATLAS CLI šŸ¤–
2
+
3
+ A fast, lightweight AI assistant that lives in your terminal. Powered by Groq.
4
+
5
+ ![Version](https://img.shields.io/badge/version-1.0.0-blue?style=flat-square)
6
+ ![Node](https://img.shields.io/badge/node-18+-green?style=flat-square)
7
+ ![License](https://img.shields.io/badge/license-MIT-purple?style=flat-square)
8
+
9
+ ---
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ npm install -g atlas-cli
15
+ ```
16
+
17
+ ---
18
+
19
+ ## Quick Start
20
+
21
+ ### 1. Configure ATLAS with your Groq API key
22
+
23
+ ```bash
24
+ atlas config
25
+ ```
26
+
27
+ Get a free Groq API key at [console.groq.com](https://console.groq.com/keys)
28
+
29
+ ### 2. Start chatting
30
+
31
+ ```bash
32
+ atlas chat
33
+ ```
34
+
35
+ ---
36
+
37
+ ## Commands
38
+
39
+ ### `atlas chat`
40
+ Start a back and forth conversation with ATLAS. Conversation memory is maintained throughout the session.
41
+
42
+ ```bash
43
+ atlas chat
44
+ ```
45
+
46
+ ```
47
+ ──────────────────────────────────────────────────
48
+ ATLAS — type your message, or "exit" to quit
49
+ ──────────────────────────────────────────────────
50
+
51
+ You: what is a REST API?
52
+ ATLAS: A REST API is...
53
+
54
+ You: exit
55
+ ATLAS: Goodbye!
56
+ ```
57
+
58
+ ---
59
+
60
+ ### `atlas ask`
61
+ Ask a single question and get an answer immediately. Perfect for quick lookups without starting a full conversation.
62
+
63
+ ```bash
64
+ atlas ask "what is the difference between null and undefined in JavaScript?"
65
+ ```
66
+
67
+ Supports piping directly from the terminal:
68
+
69
+ ```bash
70
+ cat error.log | atlas ask "what is wrong here?"
71
+ echo "explain this code" | atlas ask --pipe < index.js
72
+ ```
73
+
74
+ ---
75
+
76
+ ### `atlas config`
77
+ First time setup. Saves your Groq API key securely on your machine.
78
+
79
+ ```bash
80
+ atlas config
81
+ ```
82
+
83
+ Your API key is stored locally at `~/.config/atlas-cli/config.json` and never sent anywhere except directly to Groq.
84
+
85
+ ---
86
+
87
+ ## Requirements
88
+
89
+ - Node.js 18 or higher
90
+ - A free Groq API key from [console.groq.com](https://console.groq.com/keys)
91
+
92
+ ---
93
+
94
+ ## Tech Stack
95
+
96
+ - **Node.js** — runtime
97
+ - **Commander.js** — CLI command handling
98
+ - **Groq SDK** — AI responses via llama-3.3-70b-versatile
99
+ - **Chalk** — terminal colors
100
+ - **Ora** — loading spinners
101
+ - **Inquirer** — interactive config prompts
102
+ - **Conf** — local config storage
103
+
104
+ ---
105
+
106
+ ## Roadmap
107
+
108
+ - [x] `atlas chat` — conversational mode
109
+ - [x] `atlas ask` — single question mode
110
+ - [x] `atlas config` — API key setup
111
+ - [ ] Streaming responses
112
+ - [ ] `atlas chat` with file context (`atlas chat --file index.js`)
113
+ - [ ] Web search tool
114
+ - [ ] Read and write files
115
+ - [ ] TTS voice mode
116
+ - [ ] User accounts and hosted backend
117
+ - [ ] Subscription tiers (Free / Pro / Ultimate)
118
+
119
+ ---
120
+
121
+ ## License
122
+
123
+ MIT — feel free to use and modify.
124
+
125
+ ---
126
+
127
+ Built by [Chris](https://github.com/PSGtatitos)
@@ -0,0 +1,53 @@
1
+ import chalk from 'chalk'
2
+ import ora from 'ora'
3
+ import { askGroq } from '../utils/groq.js'
4
+ import Conf from 'conf'
5
+
6
+ const config = new Conf({ projectName: 'atlas-cli' })
7
+
8
+ export async function askCommand(question) {
9
+ // Check config exists
10
+ if (!config.get('groqApiKey')) {
11
+ console.log(chalk.red('No API key found. Run atlas config first.'))
12
+ process.exit(1)
13
+ }
14
+
15
+ // Handle piped input
16
+ if (!question) {
17
+ const chunks = []
18
+ for await (const chunk of process.stdin) {
19
+ chunks.push(chunk)
20
+ }
21
+ question = Buffer.concat(chunks).toString().trim()
22
+ }
23
+
24
+ if (!question) {
25
+ console.log(chalk.red('No question provided.'))
26
+ process.exit(1)
27
+ }
28
+
29
+ const spinner = ora('Thinking...').start()
30
+
31
+ try {
32
+ spinner.stop()
33
+ process.stdout.write(chalk.blue('ATLAS: '))
34
+
35
+ const stream = await askGroq(question, [])
36
+
37
+ for await (const chunk of stream) {
38
+ const token = chunk.choices[0]?.delta?.content || ''
39
+ process.stdout.write(token)
40
+ }
41
+
42
+ console.log('\n')
43
+
44
+ } catch (error) {
45
+ spinner.stop()
46
+ if (error.message?.includes('API key')) {
47
+ console.log(chalk.red('Invalid API key. Run atlas config to update it.'))
48
+ } else {
49
+ console.log(chalk.red(`Error: ${error.message}`))
50
+ }
51
+ process.exit(1)
52
+ }
53
+ }
@@ -0,0 +1,109 @@
1
+ import readline from 'readline'
2
+ import chalk from 'chalk'
3
+ import { askGroq } from '../utils/groq.js'
4
+ import { handleSystemCommand } from '../utils/system.js'
5
+ import Conf from 'conf'
6
+
7
+ const config = new Conf({ projectName: 'atlas-cli' })
8
+
9
+ const STOP_PHRASES = [
10
+ 'goodbye atlas',
11
+ 'goodbye',
12
+ 'exit',
13
+ 'quit',
14
+ 'ok that is all for today',
15
+ "that's all for today",
16
+ "ok that's all"
17
+ ]
18
+
19
+ const NOISE_WORDS = new Set([
20
+ '', 'huh', 'uh', 'um', 'hmm',
21
+ 'ah', 'oh', 'eh', 'a', 'the', 'i', 'it'
22
+ ])
23
+
24
+ const MIN_INPUT_LENGTH = 2
25
+
26
+ export async function chatCommand() {
27
+ // Check config exists
28
+ if (!config.get('groqApiKey')) {
29
+ console.log(chalk.red('No API key found. Run atlas config first.'))
30
+ process.exit(1)
31
+ }
32
+
33
+ const conversationHistory = []
34
+
35
+ console.log(chalk.cyan('─'.repeat(50)))
36
+ console.log(chalk.cyan(' ATLAS — type your message, or "exit" to quit'))
37
+ console.log(chalk.cyan('─'.repeat(50)) + '\n')
38
+
39
+ const rl = readline.createInterface({
40
+ input: process.stdin,
41
+ output: process.stdout
42
+ })
43
+
44
+ const askQuestion = () => {
45
+ rl.question(chalk.green('You: '), async (input) => {
46
+ const userInput = input.trim()
47
+
48
+ // Empty input
49
+ if (!userInput) {
50
+ return askQuestion()
51
+ }
52
+
53
+ // Stop phrases
54
+ if (STOP_PHRASES.some(p => userInput.toLowerCase().includes(p))) {
55
+ console.log(chalk.cyan('\nATLAS: Goodbye!\n'))
56
+ rl.close()
57
+ return
58
+ }
59
+
60
+ // Noise/short input
61
+ if (
62
+ userInput.length < MIN_INPUT_LENGTH ||
63
+ NOISE_WORDS.has(userInput.toLowerCase())
64
+ ) {
65
+ console.log(chalk.gray('[Skipped] Input too short.\n'))
66
+ return askQuestion()
67
+ }
68
+
69
+ // System command check
70
+ const systemResponse = handleSystemCommand(userInput)
71
+ if (systemResponse) {
72
+ console.log(chalk.yellow(`System: ${systemResponse}\n`))
73
+ return askQuestion()
74
+ }
75
+
76
+ // Ask Groq
77
+ try {
78
+ process.stdout.write(chalk.blue('ATLAS: '))
79
+
80
+ const stream = await askGroq(userInput, conversationHistory)
81
+
82
+ let fullResponse = ''
83
+
84
+ for await (const chunk of stream) {
85
+ const token = chunk.choices[0]?.delta?.content || ''
86
+ process.stdout.write(token)
87
+ fullResponse += token
88
+ }
89
+
90
+ console.log('\n')
91
+
92
+ // Update conversation history
93
+ conversationHistory.push({ role: 'user', content: userInput })
94
+ conversationHistory.push({ role: 'assistant', content: fullResponse })
95
+
96
+ } catch (error) {
97
+ if (error.message?.includes('API key')) {
98
+ console.log(chalk.red('\nInvalid API key. Run atlas config to update it.\n'))
99
+ } else {
100
+ console.log(chalk.red(`\nError: ${error.message}\n`))
101
+ }
102
+ }
103
+
104
+ askQuestion()
105
+ })
106
+ }
107
+
108
+ askQuestion()
109
+ }
@@ -0,0 +1,47 @@
1
+ import inquirer from 'inquirer'
2
+ import chalk from 'chalk'
3
+ import Conf from 'conf'
4
+ import Groq from 'groq-sdk'
5
+
6
+ const config = new Conf({ projectName: 'atlas-cli' })
7
+
8
+ export async function configCommand() {
9
+ console.log(chalk.cyan('\nWelcome to ATLAS setup!\n'))
10
+
11
+ const existing = config.get('groqApiKey')
12
+ if (existing) {
13
+ console.log(chalk.gray(`Current API key: ${existing.slice(0, 8)}...\n`))
14
+ }
15
+
16
+ const answers = await inquirer.prompt([
17
+ {
18
+ type: 'password',
19
+ name: 'groqApiKey',
20
+ message: 'Enter your Groq API key (get one at console.groq.com):',
21
+ mask: '*',
22
+ validate: (val) => val.length > 0 ? true : 'API key cannot be empty'
23
+ }
24
+ ])
25
+
26
+ // Validate the key by making a test call
27
+ console.log(chalk.gray('\nValidating API key...'))
28
+
29
+ try {
30
+ const groq = new Groq({ apiKey: answers.groqApiKey })
31
+ await groq.chat.completions.create({
32
+ model: 'llama-3.3-70b-versatile',
33
+ messages: [{ role: 'user', content: 'hi' }],
34
+ max_tokens: 1
35
+ })
36
+
37
+ config.set('groqApiKey', answers.groqApiKey)
38
+
39
+ console.log(chalk.green('\nāœ“ API key valid'))
40
+ console.log(chalk.green('āœ“ ATLAS is ready'))
41
+ console.log(chalk.cyan('\nRun atlas chat to start.\n'))
42
+
43
+ } catch (error) {
44
+ console.log(chalk.red('\nāœ— Invalid API key. Please check and try again.\n'))
45
+ process.exit(1)
46
+ }
47
+ }
package/cli/index.js ADDED
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { program } from 'commander'
4
+ import { chatCommand } from './commands/chat.js'
5
+ import { askCommand } from './commands/ask.js'
6
+ import { configCommand } from './commands/config.js'
7
+
8
+ program
9
+ .name('atlas')
10
+ .description('AI assistant that lives in your terminal')
11
+ .version('1.0.0')
12
+
13
+ program
14
+ .command('chat')
15
+ .description('Start a conversation with ATLAS')
16
+ .action(chatCommand)
17
+
18
+ program
19
+ .command('ask <question>')
20
+ .description('Ask ATLAS a single question')
21
+ .action(askCommand)
22
+
23
+ program
24
+ .command('config')
25
+ .description('Configure ATLAS settings')
26
+ .action(configCommand)
27
+
28
+ program.parse()
@@ -0,0 +1,26 @@
1
+ // groq.js
2
+ import Groq from 'groq-sdk'
3
+ import Conf from 'conf'
4
+
5
+ const config = new Conf({ projectName: 'atlas-cli' })
6
+
7
+ export async function askGroq(text, conversationHistory) {
8
+ const groq = new Groq({
9
+ apiKey: config.get('groqApiKey')
10
+ })
11
+
12
+ const response = await groq.chat.completions.create({
13
+ model: 'llama-3.3-70b-versatile',
14
+ messages: [
15
+ {
16
+ role: 'system',
17
+ content: 'You are ATLAS, an AI assistant in the terminal.'
18
+ },
19
+ ...conversationHistory,
20
+ { role: 'user', content: text }
21
+ ],
22
+ stream: true // streaming so responses print token by token
23
+ })
24
+
25
+ return response
26
+ }
@@ -0,0 +1,32 @@
1
+ export function handleSystemCommand(text) {
2
+ const t = text.toLowerCase()
3
+
4
+ const commonSites = {
5
+ youtube: 'https://youtube.com',
6
+ google: 'https://google.com',
7
+ netflix: 'https://netflix.com',
8
+ github: 'https://github.com',
9
+ reddit: 'https://reddit.com',
10
+ twitter: 'https://twitter.com',
11
+ instagram: 'https://instagram.com',
12
+ gmail: 'https://gmail.com',
13
+ }
14
+
15
+ // Common site shortcuts
16
+ for (const [name, url] of Object.entries(commonSites)) {
17
+ if (t.includes(`open ${name}`)) {
18
+ // Will be handled by agent tool in Phase 2
19
+ return `Would open ${url} (system commands coming in v2)`
20
+ }
21
+ }
22
+
23
+ // Search
24
+ if (t.includes('search for') || t.includes('google search')) {
25
+ const query = t.includes('search for')
26
+ ? t.split('search for')[1].trim()
27
+ : t.split('google search')[1].trim()
28
+ return `Would search for "${query}" (system commands coming in v2)`
29
+ }
30
+
31
+ return null
32
+ }
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "atlas-terminal",
3
+ "version": "1.0.0",
4
+ "description": "AI assistant that lives in your terminal",
5
+ "main": "cli/index.js",
6
+ "bin": {
7
+ "atlas": "./cli/index.js"
8
+ },
9
+ "files": [
10
+ "cli/"
11
+ ],
12
+ "type": "module",
13
+ "scripts": {
14
+ "start": "node cli/index.js",
15
+ "dev": "node --watch cli/index.js"
16
+ },
17
+ "keywords": ["ai", "cli", "assistant", "terminal"],
18
+ "license": "MIT",
19
+ "dependencies": {
20
+ "commander": "^12.0.0",
21
+ "chalk": "^5.3.0",
22
+ "ora": "^8.0.0",
23
+ "inquirer": "^9.0.0",
24
+ "conf": "^12.0.0",
25
+ "groq-sdk": "^0.3.0"
26
+ }
27
+ }