primocode 1.0.1 → 4.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.
package/lib/ui.js CHANGED
@@ -1,132 +1,104 @@
1
- // UI PrimoCode — minimalista e profissional
2
-
3
- 'use strict';
4
-
5
- const os = require('os');
6
- const path = require('path');
7
-
8
- const supportsColor = process.stdout.isTTY && process.env.TERM !== 'dumb' && !process.env.NO_COLOR;
9
- const wrap = (open, close) => (s) => supportsColor ? `\x1b[${open}m${s}\x1b[${close}m` : String(s);
10
-
11
- const c = {
12
- reset: '\x1b[0m',
13
- brand: wrap('38;5;51', '39'),
14
- brandDim: wrap('38;5;44', '39'),
15
- accent: wrap('38;5;123', '39'),
16
- bold: wrap('1', '22'),
17
- dim: wrap('2', '22'),
18
- italic: wrap('3', '23'),
19
- ok: wrap('38;5;42', '39'),
20
- warn: wrap('38;5;220', '39'),
21
- err: wrap('38;5;203', '39'),
22
- muted: wrap('38;5;244', '39'),
23
- white: wrap('97', '39'),
24
- magenta: wrap('38;5;177', '39'),
25
- };
26
-
27
- function stripAnsi(s) { return String(s).replace(/\x1b\[[0-9;]*m/g, ''); }
28
-
29
- function welcomeBox(config) {
30
- const width = Math.min((process.stdout.columns || 80) - 2, 76);
31
- const inner = width - 4;
32
- const home = os.homedir();
33
- let cwd = process.cwd();
34
- if (cwd.startsWith(home)) cwd = '~' + cwd.slice(home.length);
35
- if (cwd.length > inner - 6) cwd = '...' + cwd.slice(-(inner - 7));
36
-
37
- const lines = [
38
- `${c.brand('◆')} ${c.bold('PrimoCode')}`,
39
- ``,
40
- `${c.muted('/help · /mode Conecta Primo AI | Chat | JARVIS')}`,
41
- `${c.muted('Diretorio')} ${c.dim(cwd)}`,
42
- ];
43
- const pad = (s) => {
44
- const raw = stripAnsi(s);
45
- return ' ' + s + ' '.repeat(Math.max(1, inner - raw.length + 1));
46
- };
47
- const top = c.brandDim(`╭${'─'.repeat(width - 2)}╮`);
48
- const bottom = c.brandDim(`╰${'─'.repeat(width - 2)}╯`);
49
- const body = lines.map(l => c.brandDim('│') + pad(l) + c.brandDim('│')).join('\n');
50
- return `\n${top}\n${body}\n${bottom}\n`;
51
- }
52
-
53
- function hr() {
54
- const w = Math.min(process.stdout.columns || 80, 72);
55
- return c.dim(c.muted('─'.repeat(w)));
56
- }
57
-
58
- class Spinner {
59
- constructor(text = '') {
60
- this.frames = ['⠋','⠙','⠹','⠸','⠼','⠴','⠦','⠧','⠇','⠏'];
61
- this.i = 0;
62
- this.text = text;
63
- this.timer = null;
64
- this.active = false;
65
- }
66
- start(text) {
67
- if (text !== undefined) this.text = text;
68
- if (!process.stdout.isTTY) {
69
- if (this.text) process.stdout.write(c.muted(` ${this.text}...\n`));
70
- return this;
71
- }
72
- this.active = true;
73
- process.stdout.write('\x1b[?25l');
74
- this.timer = setInterval(() => {
75
- process.stdout.write(`\r ${c.brand(this.frames[this.i])} ${c.muted(this.text)} `);
76
- this.i = (this.i + 1) % this.frames.length;
77
- }, 80);
78
- return this;
79
- }
80
- update(text) { this.text = text; return this; }
81
- stop(finalText) {
82
- if (this.timer) clearInterval(this.timer);
83
- this.timer = null;
84
- if (this.active && process.stdout.isTTY) {
85
- process.stdout.write('\r\x1b[2K\x1b[?25h');
86
- }
87
- this.active = false;
88
- if (finalText) process.stdout.write(finalText + '\n');
89
- return this;
90
- }
91
- }
92
-
93
- function renderMarkdown(md) {
94
- if (!md) return '';
95
- let out = String(md);
96
- out = out.replace(/```([\w+.-]*)\n([\s\S]*?)```/g, (_, lang, code) => {
97
- const lines = code.replace(/\n$/, '').split('\n');
98
- const body = lines.map(l => c.brandDim(' ') + c.white(l)).join('\n');
99
- return `\n${body}\n`;
100
- });
101
- out = out.replace(/`([^`\n]+)`/g, (_, x) => c.accent(x));
102
- out = out.replace(/^###\s+(.+)$/gm, (_, x) => c.bold(x));
103
- out = out.replace(/^##\s+(.+)$/gm, (_, x) => c.bold(x));
104
- out = out.replace(/^#\s+(.+)$/gm, (_, x) => c.bold(x));
105
- out = out.replace(/^\s*[-*]\s+/gm, c.brand(' · '));
106
- out = out.replace(/\*\*([^*]+)\*\*/g, (_, x) => c.bold(x));
107
- return out;
108
- }
109
-
110
- function preview(s, maxLines = 6, maxCols = 76) {
111
- if (!s) return c.muted('(vazio)');
112
- const lines = String(s).replace(/\r/g, '').split('\n');
113
- const shown = lines.slice(0, maxLines).map(l => (l.length > maxCols ? l.slice(0, maxCols - 1) + '...' : l));
114
- const suffix = lines.length > maxLines ? c.muted(`\n ... +${lines.length - maxLines} linhas`) : '';
115
- return shown.join('\n') + suffix;
116
- }
117
-
118
- function toolLine(name, args) {
119
- return `${c.brand('●')} ${c.bold(name)}${c.muted('(')}${c.muted(args || '')}${c.muted(')')}`;
120
- }
121
-
122
- function toolResult(text) {
123
- if (!text) return '';
124
- const lines = String(text).split('\n');
125
- return lines.map(l => c.muted(' ⎿ ') + c.muted(l)).join('\n');
126
- }
127
-
128
- function actionHeader(icon, name, detail) {
129
- return toolLine(name, detail || '');
130
- }
131
-
132
- module.exports = { c, welcomeBox, hr, Spinner, stripAnsi, renderMarkdown, preview, actionHeader, toolLine, toolResult, supportsColor };
1
+ // UI PrimoCode — minimalista e profissional
2
+
3
+ 'use strict';
4
+
5
+ const os = require('os');
6
+ const path = require('path');
7
+
8
+ const supportsColor = process.stdout.isTTY && process.env.TERM !== 'dumb' && !process.env.NO_COLOR;
9
+ const wrap = (open, close) => (s) => supportsColor ? `\x1b[${open}m${s}\x1b[${close}m` : String(s);
10
+
11
+ const c = {
12
+ reset: '\x1b[0m',
13
+ brand: wrap('38;5;51', '39'),
14
+ brandDim: wrap('38;5;44', '39'),
15
+ accent: wrap('38;5;123', '39'),
16
+ bold: wrap('1', '22'),
17
+ dim: wrap('2', '22'),
18
+ italic: wrap('3', '23'),
19
+ ok: wrap('38;5;42', '39'),
20
+ warn: wrap('38;5;220', '39'),
21
+ err: wrap('38;5;203', '39'),
22
+ muted: wrap('38;5;244', '39'),
23
+ white: wrap('97', '39'),
24
+ magenta: wrap('38;5;177', '39'),
25
+ };
26
+
27
+ function stripAnsi(s) { return String(s).replace(/\x1b\[[0-9;]*m/g, ''); }
28
+
29
+ function welcomeBox(config) {
30
+ const width = Math.min((process.stdout.columns || 80) - 2, 76);
31
+ const inner = width - 4;
32
+ const home = os.homedir();
33
+ let cwd = process.cwd();
34
+ if (cwd.startsWith(home)) cwd = '~' + cwd.slice(home.length);
35
+ if (cwd.length > inner - 6) cwd = '...' + cwd.slice(-(inner - 7));
36
+
37
+ const mode = config.mode || 'Primo Code';
38
+
39
+ const lines = [
40
+ `${c.brand('◆')} ${c.bold('PrimoCode')}`,
41
+ ``,
42
+ `${c.muted('/help · /mode Primo Code | Chat')}`,
43
+ `${c.muted('Diretorio')} ${c.dim(cwd)}`,
44
+ `${c.muted('Modo')} ${c.dim(mode)}`,
45
+ ];
46
+ const pad = (s) => {
47
+ const raw = stripAnsi(s);
48
+ return ' ' + s + ' '.repeat(Math.max(1, inner - raw.length + 1));
49
+ };
50
+ const top = c.brandDim(`╭${'─'.repeat(width - 2)}╮`);
51
+ const bottom = c.brandDim(`╰${'─'.repeat(width - 2)}╯`);
52
+ const body = lines.map(l => c.brandDim('│') + pad(l) + c.brandDim('│')).join('\n');
53
+ return `\n${top}\n${body}\n${bottom}\n`;
54
+ }
55
+
56
+ function hr() {
57
+ const w = Math.min(process.stdout.columns || 80, 72);
58
+ return c.dim(c.muted('─'.repeat(w)));
59
+ }
60
+
61
+ class Spinner {
62
+ constructor(text = '') {
63
+ this.frames = ['⠋','⠙','⠹','⠸','⠼','⠴','⠦','⠧','⠇','⠏'];
64
+ this.i = 0;
65
+ this.text = text;
66
+ this.timer = null;
67
+ this.active = false;
68
+ }
69
+ start(text) {
70
+ if (text !== undefined) this.text = text;
71
+ if (!process.stdout.isTTY) {
72
+ if (this.text) process.stdout.write(c.muted(` ${this.text}...\n`));
73
+ return this;
74
+ }
75
+ this.active = true;
76
+ process.stdout.write('\x1b[?25l');
77
+ this.timer = setInterval(() => {
78
+ process.stdout.write(`\r ${c.brand(this.frames[this.i])} ${c.muted(this.text)} `);
79
+ this.i = (this.i + 1) % this.frames.length;
80
+ }, 80);
81
+ return this;
82
+ }
83
+ update(text) { this.text = text; return this; }
84
+ stop(finalText) {
85
+ if (this.timer) clearInterval(this.timer);
86
+ this.timer = null;
87
+ if (this.active && process.stdout.isTTY) {
88
+ process.stdout.write('\r\x1b[2K\x1b[?25h');
89
+ }
90
+ this.active = false;
91
+ if (finalText) process.stdout.write(c.muted(` ${finalText}\n`));
92
+ return this;
93
+ }
94
+ }
95
+
96
+ function actionHeader(name, detail) {
97
+ return `${c.brand('▶')} ${c.bold(name)} ${c.muted(detail || '')}`;
98
+ }
99
+
100
+ function toolLine(name, detail) {
101
+ return `${c.brand('▶')} ${c.bold(name)} ${c.muted(detail || '')}`;
102
+ }
103
+
104
+ module.exports = { c, welcomeBox, hr, Spinner, actionHeader, toolLine, stripAnsi };
package/package.json CHANGED
@@ -1,31 +1,32 @@
1
- {
2
- "name": "primocode",
3
- "version": "1.0.1",
4
- "description": "PrimoCode — assistente de engenharia com IA. Conecta Primo AI para engenharia completa, Chat para conversa direta, JARVIS para voz e visao.",
5
- "main": "bin/primocode.js",
6
- "bin": {
7
- "primocode": "bin/primocode.js"
8
- },
9
- "scripts": {
10
- "start": "node bin/primocode.js"
11
- },
12
- "engines": {
13
- "node": ">=18.17.0"
14
- },
15
- "keywords": ["cli", "ai", "coding-assistant", "agent", "primocode"],
16
- "author": "ConectaPrimoAI <conectaprimoai@gmail.com>",
17
- "license": "MIT",
18
- "repository": {
19
- "type": "git",
20
- "url": "git+https://github.com/ConectaPrimoAI/primocode.git"
21
- },
22
- "bugs": {
23
- "url": "https://github.com/ConectaPrimoAI/primocode/issues"
24
- },
25
- "homepage": "https://github.com/ConectaPrimoAI/primocode#readme",
26
- "files": [
27
- "bin/",
28
- "lib/",
29
- "README.md"
30
- ]
31
- }
1
+ {
2
+ "name": "primocode",
3
+ "version": "4.1.0",
4
+ "description": "PrimoCode v4.1 — assistente de engenharia com IA multi-agente. Funciona em Windows, macOS, Linux e Termux (Android).",
5
+ "main": "bin/primocode.js",
6
+ "bin": {
7
+ "primocode": "bin/primocode.js"
8
+ },
9
+ "scripts": {
10
+ "start": "node bin/primocode.js"
11
+ },
12
+ "engines": {
13
+ "node": ">=18.17.0"
14
+ },
15
+ "dependencies": {},
16
+ "keywords": ["cli", "ai", "coding-assistant", "agent", "primocode", "termux", "android"],
17
+ "author": "ConectaPrimoAI <conectaprimoai@gmail.com>",
18
+ "license": "MIT",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/ConectaPrimoAI/primocode.git"
22
+ },
23
+ "bugs": {
24
+ "url": "https://github.com/ConectaPrimoAI/primocode/issues"
25
+ },
26
+ "homepage": "https://github.com/ConectaPrimoAI/primocode#readme",
27
+ "files": [
28
+ "bin/",
29
+ "lib/",
30
+ "README.md"
31
+ ]
32
+ }