symfonia-ai-tools 1.1.0 → 1.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/cli.mjs +46 -9
- package/lib/installer.mjs +4 -4
- package/lib/ui.mjs +3 -3
- package/lib/utils.mjs +7 -7
- package/package.json +1 -1
package/bin/cli.mjs
CHANGED
|
@@ -4,21 +4,58 @@ import { fileURLToPath } from 'node:url';
|
|
|
4
4
|
import { dirname, join } from 'node:path';
|
|
5
5
|
import { askQuestions } from '../lib/questions.mjs';
|
|
6
6
|
import { install } from '../lib/installer.mjs';
|
|
7
|
-
import {
|
|
7
|
+
import { green, dim, red, yellow } from '../lib/ui.mjs';
|
|
8
8
|
|
|
9
9
|
const __filename = fileURLToPath(import.meta.url);
|
|
10
10
|
const __dirname = dirname(__filename);
|
|
11
11
|
const ROOT = join(__dirname, '..');
|
|
12
12
|
|
|
13
|
+
// Symfonia logo — # = filled pixel, * = green dot (always green)
|
|
14
|
+
// Icon (cols 0-19) → green, Text (cols 20+) → bold white, * → always green
|
|
15
|
+
const LOGO_RAW = [
|
|
16
|
+
' ############### ##',
|
|
17
|
+
' ############# #######',
|
|
18
|
+
'########### ###',
|
|
19
|
+
'####### ### ######## ### ## ############### ####### ######## ######### #### #########',
|
|
20
|
+
' ############# ### # ### ## ### #### ### ### ### ### ### ### ## ### ###',
|
|
21
|
+
' ############# ######## ### ## ### *## ### ### ## ### ## ## ## ### ##',
|
|
22
|
+
' ########### # ###### ### ### ### ### ### ### ## ## ## ## ### ###',
|
|
23
|
+
' ########### ######### ######## ### ### ### ### ######## ## ## ## #########',
|
|
24
|
+
' ############# ## ### ###',
|
|
25
|
+
' *############## ######## ###',
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
const ICON_W = 20;
|
|
29
|
+
const G = '\x1b[38;2;0;220;0m'; // green (matching Symfonia brand)
|
|
30
|
+
const W = '\x1b[1;97m'; // bold white
|
|
31
|
+
const R = '\x1b[0m'; // reset
|
|
32
|
+
|
|
33
|
+
function printLogo() {
|
|
34
|
+
for (const line of LOGO_RAW) {
|
|
35
|
+
let out = ' ';
|
|
36
|
+
let cur = '';
|
|
37
|
+
for (let i = 0; i < line.length; i++) {
|
|
38
|
+
const ch = line[i];
|
|
39
|
+
if (ch === '#' || ch === '*') {
|
|
40
|
+
const color = (ch === '*' || i < ICON_W) ? G : W;
|
|
41
|
+
if (color !== cur) { out += color; cur = color; }
|
|
42
|
+
out += '\u2588';
|
|
43
|
+
} else {
|
|
44
|
+
if (cur) { out += R; cur = ''; }
|
|
45
|
+
out += ch;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (cur) out += R;
|
|
49
|
+
console.log(out);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
console.log('');
|
|
54
|
+
printLogo();
|
|
55
|
+
console.log(`${' '.repeat(68)}${dim('AI Tools')}`)
|
|
13
56
|
console.log('');
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
'',
|
|
17
|
-
cyan(' Claude Code · GitHub Copilot · Cursor'),
|
|
18
|
-
cyan(' Gemini · Junie · GSD'),
|
|
19
|
-
'',
|
|
20
|
-
dim(' Jeden konfigurator — wszystkie agenty gotowe'),
|
|
21
|
-
]);
|
|
57
|
+
console.log(` ${green('Claude Code · GitHub Copilot · Cursor · Gemini · Junie · GSD')}`);
|
|
58
|
+
console.log(` ${dim('Jeden konfigurator — wszystkie agenty gotowe')}`);
|
|
22
59
|
console.log('');
|
|
23
60
|
|
|
24
61
|
try {
|
package/lib/installer.mjs
CHANGED
|
@@ -447,14 +447,14 @@ function printNextSteps(answers, mode) {
|
|
|
447
447
|
const steps = [];
|
|
448
448
|
let n = 1;
|
|
449
449
|
if (!answers.installGsd) {
|
|
450
|
-
steps.push(` ${
|
|
450
|
+
steps.push(` ${boldGreen(`${n++}.`)} Zainstaluj GSD ${dim('(wymagane)')}\n ${gray('npx get-shit-done-cc@latest')}`);
|
|
451
451
|
}
|
|
452
|
-
steps.push(` ${
|
|
452
|
+
steps.push(` ${boldGreen(`${n++}.`)} Przejrzyj ${cyan('.ai/guidelines.md')} i dostosuj do projektu`);
|
|
453
453
|
if (answers.toolClaude && (answers.mcpJira || answers.mcpBitbucket || answers.mcpFigma || answers.mcpContext7)) {
|
|
454
|
-
steps.push(` ${
|
|
454
|
+
steps.push(` ${boldGreen(`${n++}.`)} Sprawdz MCP\n ${gray('claude mcp list')}`);
|
|
455
455
|
}
|
|
456
456
|
if (!answers.toolClaude) {
|
|
457
|
-
steps.push(` ${
|
|
457
|
+
steps.push(` ${boldGreen(`${n++}.`)} Rozpocznij prace z GSD\n ${gray('/gsd:new-project')}`);
|
|
458
458
|
}
|
|
459
459
|
console.log(` ${bold('Nastepne kroki:')}\n`);
|
|
460
460
|
console.log(steps.join('\n\n'));
|
package/lib/ui.mjs
CHANGED
|
@@ -33,7 +33,7 @@ export const bgMagenta = (s) => `${esc(45)}${esc(97)}${s}${reset}`;
|
|
|
33
33
|
export const success = (s) => green(` ✓ ${s}`);
|
|
34
34
|
export const error = (s) => red(` ✗ ${s}`);
|
|
35
35
|
export const warn = (s) => yellow(` ⚠ ${s}`);
|
|
36
|
-
export const info = (s) =>
|
|
36
|
+
export const info = (s) => green(` ℹ ${s}`);
|
|
37
37
|
export const file = (s) => ` ${green('+')} ${gray(s)}`;
|
|
38
38
|
export const fileSkip = (s) => ` ${yellow('~')} ${gray(s)} ${dim('(pominieto)')}`;
|
|
39
39
|
export const fileMirror = (s) => ` ${blue('»')} ${gray(s)} ${dim('(mirror)')}`;
|
|
@@ -41,12 +41,12 @@ export const fileMirror = (s) => ` ${blue('»')} ${gray(s)} ${dim('(mirror)')}`
|
|
|
41
41
|
// Section header
|
|
42
42
|
export function section(title) {
|
|
43
43
|
console.log('');
|
|
44
|
-
console.log(` ${
|
|
44
|
+
console.log(` ${boldGreen('─── ' + title + ' ───')}`);
|
|
45
45
|
console.log('');
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
// Box with border
|
|
49
|
-
export function box(lines, color =
|
|
49
|
+
export function box(lines, color = boldGreen) {
|
|
50
50
|
const maxLen = Math.max(...lines.map(l => stripAnsi(l).length));
|
|
51
51
|
const pad = (s) => s + ' '.repeat(maxLen - stripAnsi(s).length);
|
|
52
52
|
const border = color('┌─' + '─'.repeat(maxLen + 2) + '─┐');
|
package/lib/utils.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as readline from 'node:readline/promises';
|
|
2
2
|
import { stdin as input, stdout as output } from 'node:process';
|
|
3
|
-
import { bold, cyan, dim, green, yellow,
|
|
3
|
+
import { bold, cyan, dim, green, yellow, boldGreen, boldWhite, gray } from './ui.mjs';
|
|
4
4
|
|
|
5
5
|
let rl = null;
|
|
6
6
|
|
|
@@ -21,7 +21,7 @@ export function closeRL() {
|
|
|
21
21
|
export async function ask(question, defaultValue) {
|
|
22
22
|
const r = getRL();
|
|
23
23
|
const suffix = defaultValue ? ` ${dim(`[${defaultValue}]`)}` : '';
|
|
24
|
-
const answer = await r.question(` ${
|
|
24
|
+
const answer = await r.question(` ${green('?')} ${question}${suffix}${dim(':')} `);
|
|
25
25
|
if (answer.toLowerCase() === 'q') throw new Error('USER_ABORT');
|
|
26
26
|
return answer || defaultValue || '';
|
|
27
27
|
}
|
|
@@ -31,7 +31,7 @@ export async function askYN(question, defaultYes = true) {
|
|
|
31
31
|
const hint = defaultYes
|
|
32
32
|
? `${green('T')}${dim('/')}${dim('n')}`
|
|
33
33
|
: `${dim('t')}${dim('/')}${green('N')}`;
|
|
34
|
-
const answer = await r.question(` ${
|
|
34
|
+
const answer = await r.question(` ${green('?')} ${question} ${dim('[')}${hint}${dim(']')}${dim(':')} `);
|
|
35
35
|
if (answer.toLowerCase() === 'q') throw new Error('USER_ABORT');
|
|
36
36
|
if (!answer) return defaultYes;
|
|
37
37
|
return answer.toLowerCase().startsWith('t') || answer.toLowerCase().startsWith('y');
|
|
@@ -58,12 +58,12 @@ export async function askChoice(question, choices, labels, defaultIdx = 0) {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
const lines = [];
|
|
61
|
-
lines.push(` ${
|
|
61
|
+
lines.push(` ${green('?')} ${bold(question)}`);
|
|
62
62
|
lines.push('');
|
|
63
63
|
|
|
64
64
|
for (let i = 0; i < choices.length; i++) {
|
|
65
65
|
const radio = i === cursor ? green(' ● ') : dim(' ○ ');
|
|
66
|
-
const pointer = i === cursor ?
|
|
66
|
+
const pointer = i === cursor ? green('❯') : ' ';
|
|
67
67
|
const label = labels ? labels[i] : choices[i];
|
|
68
68
|
const text = i === cursor ? boldWhite(label) : label;
|
|
69
69
|
lines.push(` ${pointer}${radio}${text}`);
|
|
@@ -150,12 +150,12 @@ export async function askCheckbox(question, options) {
|
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
const lines = [];
|
|
153
|
-
lines.push(` ${
|
|
153
|
+
lines.push(` ${green('?')} ${bold(question)}`);
|
|
154
154
|
lines.push('');
|
|
155
155
|
|
|
156
156
|
for (let i = 0; i < items.length; i++) {
|
|
157
157
|
const box = items[i].checked ? green(' ■ ') : dim(' □ ');
|
|
158
|
-
const pointer = i === cursor ?
|
|
158
|
+
const pointer = i === cursor ? green('❯') : ' ';
|
|
159
159
|
const label = i === cursor ? boldWhite(items[i].label) : items[i].label;
|
|
160
160
|
lines.push(` ${pointer}${box}${label}`);
|
|
161
161
|
}
|