clarity-ai 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.
Files changed (44) hide show
  1. package/README.md +108 -0
  2. package/bin/clarity.js +2 -0
  3. package/package.json +51 -0
  4. package/scripts/postinstall.js +53 -0
  5. package/src/agents/BaseAgent.js +54 -0
  6. package/src/agents/CodeAgent.js +57 -0
  7. package/src/agents/FileAgent.js +39 -0
  8. package/src/agents/MonitorAgent.js +54 -0
  9. package/src/agents/ShellAgent.js +31 -0
  10. package/src/agents/WebAgent.js +39 -0
  11. package/src/agents/manager.js +116 -0
  12. package/src/commands/index.js +725 -0
  13. package/src/config/keys.js +104 -0
  14. package/src/config/paths.js +22 -0
  15. package/src/config/settings.js +28 -0
  16. package/src/index.js +86 -0
  17. package/src/memory/context.js +38 -0
  18. package/src/memory/store.js +54 -0
  19. package/src/providers/claude.js +61 -0
  20. package/src/providers/deepseek.js +53 -0
  21. package/src/providers/gemini.js +48 -0
  22. package/src/providers/groq.js +52 -0
  23. package/src/providers/index.js +39 -0
  24. package/src/providers/openai.js +52 -0
  25. package/src/providers/openrouter.js +52 -0
  26. package/src/tools/bash.js +25 -0
  27. package/src/tools/code.js +52 -0
  28. package/src/tools/files.js +62 -0
  29. package/src/tools/git.js +67 -0
  30. package/src/tools/index.js +40 -0
  31. package/src/tools/pkg.js +46 -0
  32. package/src/tools/search.js +29 -0
  33. package/src/tools/system.js +29 -0
  34. package/src/tools/web.js +24 -0
  35. package/src/ui/banner.js +15 -0
  36. package/src/ui/blocks.js +55 -0
  37. package/src/ui/chatbox.js +126 -0
  38. package/src/ui/colors.js +22 -0
  39. package/src/ui/prompt.js +49 -0
  40. package/src/ui/spinner.js +43 -0
  41. package/src/utils/logger.js +40 -0
  42. package/src/utils/markdown.js +25 -0
  43. package/src/utils/termux.js +38 -0
  44. package/src/utils/version-check.js +66 -0
@@ -0,0 +1,49 @@
1
+ import readline from 'readline';
2
+ import { createReadStream, createWriteStream, existsSync } from 'fs';
3
+ import paths from '../config/paths.js';
4
+ import c from './colors.js';
5
+
6
+ const HISTORY_FILE = paths.history;
7
+ const MAX_HISTORY = 500;
8
+
9
+ let history = [];
10
+
11
+ function loadHistory() {
12
+ try {
13
+ if (existsSync(HISTORY_FILE)) {
14
+ const data = require('fs').readFileSync(HISTORY_FILE, 'utf8');
15
+ history = data.split('\n').filter(Boolean).slice(-MAX_HISTORY);
16
+ }
17
+ } catch {}
18
+ }
19
+
20
+ function saveHistory() {
21
+ try {
22
+ const dir = require('path').dirname(HISTORY_FILE);
23
+ if (!existsSync(dir)) require('fs').mkdirSync(dir, { recursive: true });
24
+ require('fs').writeFileSync(HISTORY_FILE, history.slice(-MAX_HISTORY).join('\n'));
25
+ } catch {}
26
+ }
27
+
28
+ function addToHistory(line) {
29
+ if (line && line !== history[history.length - 1]) {
30
+ history.push(line);
31
+ if (history.length > MAX_HISTORY) history = history.slice(-MAX_HISTORY);
32
+ saveHistory();
33
+ }
34
+ }
35
+
36
+ function createPrompt(onselect) {
37
+ const rl = readline.createInterface({
38
+ input: process.stdin,
39
+ output: process.stdout,
40
+ history: history,
41
+ historySize: MAX_HISTORY,
42
+ terminal: true,
43
+ prompt: c.user('┃ you › '),
44
+ });
45
+
46
+ return rl;
47
+ }
48
+
49
+ export { createPrompt, loadHistory, addToHistory, history };
@@ -0,0 +1,43 @@
1
+ import ora from 'ora';
2
+ import { isTermux } from '../utils/termux.js';
3
+
4
+ const useUnicode = !isTermux() || process.env.TERMUX_VERSION !== undefined;
5
+ const spinnerFrames = useUnicode
6
+ ? ['⣾','⣽','⣻','⢿','⡿','⣟','⣯','⣷']
7
+ : ['|','/','-','\\'];
8
+
9
+ let spinner = null;
10
+
11
+ const spin = {
12
+ start(text) {
13
+ if (spinner) spinner.stop();
14
+ spinner = ora({ text, spinner: { frames: spinnerFrames, interval: 80 } }).start();
15
+ return spin;
16
+ },
17
+ stop() {
18
+ if (spinner) { spinner.stop(); spinner = null; }
19
+ return spin;
20
+ },
21
+ succeed(text) {
22
+ if (spinner) { spinner.succeed(text); spinner = null; }
23
+ return spin;
24
+ },
25
+ fail(text) {
26
+ if (spinner) { spinner.fail(text); spinner = null; }
27
+ return spin;
28
+ },
29
+ info(text) {
30
+ if (spinner) { spinner.info(text); spinner = null; }
31
+ return spin;
32
+ },
33
+ warn(text) {
34
+ if (spinner) { spinner.warn(text); spinner = null; }
35
+ return spin;
36
+ },
37
+ update(text) {
38
+ if (spinner) spinner.text = text;
39
+ return spin;
40
+ }
41
+ };
42
+
43
+ export default spin;
@@ -0,0 +1,40 @@
1
+ import chalk from 'chalk';
2
+ import { isTermux } from './termux.js';
3
+
4
+ const logLevels = { debug: 0, info: 1, warn: 2, error: 3 };
5
+ let currentLevel = 'info';
6
+
7
+ function setLevel(level) {
8
+ if (logLevels[level] !== undefined) currentLevel = level;
9
+ }
10
+
11
+ function shouldLog(level) {
12
+ return logLevels[level] >= logLevels[currentLevel];
13
+ }
14
+
15
+ function timestamp() {
16
+ return new Date().toISOString().replace('T', ' ').slice(0, 19);
17
+ }
18
+
19
+ function debug(...args) {
20
+ if (!shouldLog('debug')) return;
21
+ console.error(chalk.dim(`[${timestamp()}] [DEBUG]`), ...args);
22
+ }
23
+
24
+ function info(...args) {
25
+ if (!shouldLog('info')) return;
26
+ console.error(chalk.hex('#44aaff')(`[${timestamp()}] [INFO]`), ...args);
27
+ }
28
+
29
+ function warn(...args) {
30
+ if (!shouldLog('warn')) return;
31
+ console.error(chalk.hex('#ffcc00')(`[${timestamp()}] [WARN]`), ...args);
32
+ }
33
+
34
+ function error(...args) {
35
+ if (!shouldLog('error')) return;
36
+ console.error(chalk.hex('#ff4466')(`[${timestamp()}] [ERROR]`), ...args);
37
+ }
38
+
39
+ const logger = { setLevel, debug, info, warn, error };
40
+ export default logger;
@@ -0,0 +1,25 @@
1
+ import chalk from 'chalk';
2
+ import { marked } from 'marked';
3
+ import { markedTerminal } from 'marked-terminal';
4
+ import cliTable3 from 'cli-table3';
5
+ import stripAnsi from 'strip-ansi';
6
+ import wrapAnsi from 'wrap-ansi';
7
+
8
+ marked.use(markedTerminal({
9
+ heading: chalk.bold.hex('#f0f0ff'),
10
+ code: chalk.hex('#aaffcc'),
11
+ blockquote: chalk.dim,
12
+ hr: chalk.dim('─'),
13
+ strong: chalk.bold.hex('#f0f0ff'),
14
+ em: chalk.dim.italic,
15
+ link: chalk.hex('#00d2ff').underline,
16
+ listitem: chalk.hex('#7b2ff7'),
17
+ table: cliTable3,
18
+ tableOptions: { style: { head: ['#00d2ff'], border: ['#555577'] } }
19
+ }));
20
+
21
+ function renderMarkdown(text) {
22
+ return marked.parse(text);
23
+ }
24
+
25
+ export { renderMarkdown };
@@ -0,0 +1,38 @@
1
+ function isTermux() {
2
+ return process.env.PREFIX?.includes('com.termux') ||
3
+ process.env.TERMUX_VERSION !== undefined ||
4
+ process.env.HOME?.includes('com.termux');
5
+ }
6
+
7
+ function getTermuxInfo() {
8
+ return {
9
+ isTermux: isTermux(),
10
+ version: process.env.TERMUX_VERSION || 'unknown',
11
+ prefix: process.env.PREFIX || '/usr',
12
+ home: process.env.HOME,
13
+ storage: process.env.HOME ? `${process.env.HOME}/storage` : null
14
+ };
15
+ }
16
+
17
+ async function openURL(url) {
18
+ if (isTermux()) {
19
+ const { execSync } = await import('child_process');
20
+ execSync(`termux-open-url "${url}"`);
21
+ } else {
22
+ const { default: open } = await import('open');
23
+ await open(url);
24
+ }
25
+ }
26
+
27
+ function hasTermuxAPI() {
28
+ if (!isTermux()) return false;
29
+ try {
30
+ const { execSync } = require('child_process');
31
+ execSync('which termux-notification', { stdio: 'ignore' });
32
+ return true;
33
+ } catch {
34
+ return false;
35
+ }
36
+ }
37
+
38
+ export { isTermux, getTermuxInfo, openURL, hasTermuxAPI };
@@ -0,0 +1,66 @@
1
+ import chalk from 'chalk';
2
+ import boxen from 'boxen';
3
+ import semver from 'semver';
4
+ import { isTermux } from './termux.js';
5
+
6
+ const MIN_NODE = '18.0.0';
7
+
8
+ function checkNodeVersion() {
9
+ const current = process.versions.node;
10
+ if (!semver.satisfies(current, `>=${MIN_NODE}`)) {
11
+ console.error(boxen(
12
+ chalk.hex('#ff4466').bold(`[ERROR] Node.js ${MIN_NODE}+ required. You have v${current}\n`) +
13
+ chalk.hex('#ffcc00')(isTermux() ? 'Termux: pkg install nodejs-lts' : 'Install Node.js 18+ from https://nodejs.org'),
14
+ { padding: 1, borderColor: 'red', borderStyle: 'round' }
15
+ ));
16
+ process.exit(1);
17
+ }
18
+ }
19
+
20
+ async function checkDependencies(pkgDir) {
21
+ const { readFileSync, existsSync } = await import('fs');
22
+ const { resolve } = await import('path');
23
+ const pkgPath = resolve(pkgDir, 'package.json');
24
+ if (!existsSync(pkgPath)) return true;
25
+
26
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
27
+ const deps = { ...pkg.dependencies, ...pkg.peerDependencies };
28
+ const missing = [];
29
+
30
+ for (const dep of Object.keys(deps || {})) {
31
+ try {
32
+ await import(dep);
33
+ } catch {
34
+ missing.push(dep);
35
+ }
36
+ }
37
+
38
+ if (missing.length > 0) {
39
+ console.warn(boxen(
40
+ chalk.hex('#ffcc00').bold('Missing dependencies: ') + missing.join(', ') + '\n' +
41
+ chalk.dim('Auto-installing...'),
42
+ { padding: 1, borderColor: 'yellow', borderStyle: 'round' }
43
+ ));
44
+ const { execSync } = await import('child_process');
45
+ execSync('npm install', { cwd: pkgDir, stdio: 'inherit' });
46
+ }
47
+ return true;
48
+ }
49
+
50
+ async function checkUpdates() {
51
+ try {
52
+ const pkg = await import('../../package.json', { assert: { type: 'json' } });
53
+ const current = pkg.default.version;
54
+ const res = await fetch('https://registry.npmjs.org/clarity-ai/latest');
55
+ const data = await res.json();
56
+ if (data.version && semver.gt(data.version, current)) {
57
+ console.log(boxen(
58
+ chalk.hex('#00d2ff').bold(`clarity-ai v${current} → v${data.version}\n`) +
59
+ chalk.hex('#7b2ff7')('Run: npm install -g clarity-ai'),
60
+ { padding: 1, borderColor: 'cyan', borderStyle: 'round' }
61
+ ));
62
+ }
63
+ } catch {}
64
+ }
65
+
66
+ export { checkNodeVersion, checkDependencies, checkUpdates };