thufir 2.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.
@@ -0,0 +1,12 @@
1
+ export declare function printBanner(): void;
2
+ export declare function printStepHeader(step: number, total: number, title: string): void;
3
+ export declare function printRealignScreen(): void;
4
+ export declare function printMergeScreen(): void;
5
+ export declare function printCommitScreen(colleagueName: string, action: 'install' | 'realign' | 'reconfigure'): void;
6
+ export declare function printCompleteScreen(colleagueName: string): void;
7
+ export declare function printGetStarted(colleagueName: string): void;
8
+ export declare function printNavHint(): void;
9
+ export declare function printNavHintSimple(): void;
10
+ export declare function printProgressBar(step: number, total: number): void;
11
+ export declare function printDesertLine(): void;
12
+ export declare const STEP_TITLES: Record<number, string>;
@@ -0,0 +1,205 @@
1
+ import gradient from 'gradient-string';
2
+ import pc from 'picocolors';
3
+ import cfonts from 'cfonts';
4
+ // ═══════════════════════════════════════════════════════
5
+ // PALETTE — desert warmth, restrained
6
+ // ═══════════════════════════════════════════════════════
7
+ const dune = gradient(['#FFD700', '#E8A317', '#8B4513']);
8
+ const sand = gradient(['#DEB887', '#CD853F', '#B8860B']);
9
+ // ═══════════════════════════════════════════════════════
10
+ // WELCOME — the grand entrance
11
+ // ═══════════════════════════════════════════════════════
12
+ export function printBanner() {
13
+ console.clear();
14
+ console.log();
15
+ cfonts.say('THUFIR', {
16
+ font: 'block',
17
+ gradient: ['#FFD700', '#8B4513'],
18
+ transitionGradient: true,
19
+ space: false,
20
+ });
21
+ console.log(sand(' AI Colleague · Naib of Sietch Repository'));
22
+ console.log();
23
+ console.log();
24
+ console.log();
25
+ console.log(pc.dim(' "God created Arrakis to train the faithful.'));
26
+ console.log(pc.dim(' I create structure to train your agents."'));
27
+ console.log();
28
+ console.log();
29
+ divider();
30
+ nav(false);
31
+ console.log();
32
+ }
33
+ // ═══════════════════════════════════════════════════════
34
+ // STEP HEADERS — compact, clear
35
+ // ═══════════════════════════════════════════════════════
36
+ export function printStepHeader(step, total, title) {
37
+ console.clear();
38
+ console.log();
39
+ cfonts.say('THUFIR', { font: 'tiny', colors: ['#E8A317'], space: false });
40
+ console.log();
41
+ // Progress
42
+ const w = 30;
43
+ const f = Math.round((step / total) * w);
44
+ console.log(pc.yellow(' ' + '━'.repeat(f)) + pc.dim('━'.repeat(w - f)) + pc.dim(` ${step}/${total}`));
45
+ console.log();
46
+ console.log(pc.yellow(' ' + title));
47
+ console.log();
48
+ console.log();
49
+ const isMultiselect = step === 4 || step === 5 || step === 6;
50
+ nav(isMultiselect);
51
+ console.log();
52
+ }
53
+ // ═══════════════════════════════════════════════════════
54
+ // MODE SCREENS
55
+ // ═══════════════════════════════════════════════════════
56
+ export function printRealignScreen() {
57
+ console.clear();
58
+ console.log();
59
+ cfonts.say('THUFIR', { font: 'tiny', colors: ['#E8A317'], space: false });
60
+ console.log();
61
+ console.log(pc.yellow(' Realignment Protocol'));
62
+ console.log();
63
+ console.log();
64
+ console.log(pc.dim(' "The troops have drifted from the path.'));
65
+ console.log(pc.dim(' I will bring them back into formation."'));
66
+ console.log();
67
+ console.log();
68
+ divider();
69
+ nav(false);
70
+ console.log();
71
+ }
72
+ export function printMergeScreen() {
73
+ console.clear();
74
+ console.log();
75
+ cfonts.say('THUFIR', { font: 'tiny', colors: ['#E8A317'], space: false });
76
+ console.log();
77
+ console.log(pc.yellow(' Merge Mode'));
78
+ console.log();
79
+ console.log();
80
+ console.log(pc.dim(' "A new sietch to organize. Show me what you'));
81
+ console.log(pc.dim(' have, and I will bring order to this place."'));
82
+ console.log();
83
+ console.log();
84
+ divider();
85
+ nav(false);
86
+ console.log();
87
+ }
88
+ // ═══════════════════════════════════════════════════════
89
+ // COMMIT SCREEN — the heavy moment
90
+ // ═══════════════════════════════════════════════════════
91
+ export function printCommitScreen(colleagueName, action) {
92
+ console.clear();
93
+ console.log();
94
+ cfonts.say('THUFIR', { font: 'tiny', colors: ['#E8A317'], space: false });
95
+ console.log();
96
+ console.log();
97
+ divider();
98
+ console.log();
99
+ console.log();
100
+ if (action === 'install') {
101
+ console.log(pc.white(' This will initialize ') + pc.yellow(pc.bold(colleagueName)) + pc.white(' as your AI colleague.'));
102
+ console.log();
103
+ console.log(pc.dim(' · Write AGENTS.md — your colleague\'s brain'));
104
+ console.log(pc.dim(' · Create CLAUDE.md + .cursorrules'));
105
+ console.log(pc.dim(' · Set up docs/ structure'));
106
+ console.log(pc.dim(' · Create initial git commit'));
107
+ }
108
+ else if (action === 'realign') {
109
+ console.log(pc.white(' This will realign ') + pc.yellow(pc.bold(colleagueName)) + pc.white(' to the latest Thufir.'));
110
+ console.log();
111
+ console.log(pc.dim(' · Overwrite AGENTS.md with latest template'));
112
+ console.log(pc.dim(' · Update CLAUDE.md + .cursorrules'));
113
+ console.log(pc.dim(' · Refresh docs/ indexes'));
114
+ console.log(pc.dim(' · Preserve your decisions, plans, and content'));
115
+ }
116
+ else {
117
+ console.log(pc.white(' This will reconfigure ') + pc.yellow(pc.bold(colleagueName)) + pc.white(' with new settings.'));
118
+ console.log();
119
+ console.log(pc.dim(' · Rewrite AGENTS.md with new traits & triggers'));
120
+ console.log(pc.dim(' · Update CLAUDE.md + .cursorrules'));
121
+ console.log(pc.dim(' · Refresh docs/ indexes'));
122
+ console.log(pc.dim(' · Preserve your decisions, plans, and content'));
123
+ }
124
+ console.log();
125
+ console.log();
126
+ console.log();
127
+ }
128
+ // ═══════════════════════════════════════════════════════
129
+ // COMPLETE — celebration
130
+ // ═══════════════════════════════════════════════════════
131
+ export function printCompleteScreen(colleagueName) {
132
+ console.log();
133
+ cfonts.say('DONE', { font: 'shade', colors: ['#E8A317', '#8B4513'], space: false });
134
+ console.log();
135
+ console.log(pc.green(' ✓ ') + pc.white(pc.bold(colleagueName)) + pc.white(' stands ready.'));
136
+ console.log();
137
+ console.log(pc.dim(' "The sietch is prepared. The spice flows.'));
138
+ console.log(pc.dim(' The troops await your command."'));
139
+ console.log();
140
+ console.log();
141
+ }
142
+ export function printGetStarted(colleagueName) {
143
+ divider();
144
+ console.log();
145
+ console.log();
146
+ console.log(pc.white(pc.bold(' What\'s next')));
147
+ console.log();
148
+ console.log();
149
+ console.log(pc.white(' Open this project and say hello to ') + pc.yellow(pc.bold(colleagueName)) + pc.white(':'));
150
+ console.log();
151
+ console.log(pc.dim(' Claude Code') + ' ' + pc.cyan('claude'));
152
+ console.log(pc.dim(' Cursor') + ' ' + pc.cyan('cursor .'));
153
+ console.log();
154
+ console.log();
155
+ console.log(pc.dim(' Just talk naturally. Long messages get the'));
156
+ console.log(pc.dim(' full brain-dump treatment — everything captured.'));
157
+ console.log();
158
+ console.log();
159
+ divider();
160
+ console.log();
161
+ }
162
+ // ═══════════════════════════════════════════════════════
163
+ // NAVIGATION — elegant, always visible
164
+ // ═══════════════════════════════════════════════════════
165
+ function nav(showToggle) {
166
+ console.log();
167
+ if (showToggle) {
168
+ console.log(pc.dim(' ') +
169
+ pc.yellow('‹') + pc.dim(' esc ') + pc.dim('retreat') +
170
+ pc.dim(' ') +
171
+ pc.dim('space ') + pc.dim('select') +
172
+ pc.dim(' ') +
173
+ pc.dim('enter ') + pc.dim('advance') + pc.yellow(' ›'));
174
+ }
175
+ else {
176
+ console.log(pc.dim(' ') +
177
+ pc.yellow('‹') + pc.dim(' esc ') + pc.dim('retreat') +
178
+ pc.dim(' ') +
179
+ pc.dim('enter ') + pc.dim('advance') + pc.yellow(' ›'));
180
+ }
181
+ }
182
+ // Keep exports for compatibility
183
+ export function printNavHint() { nav(true); console.log(); }
184
+ export function printNavHintSimple() { nav(false); console.log(); }
185
+ // ═══════════════════════════════════════════════════════
186
+ // DECORATIONS — minimal, purposeful
187
+ // ═══════════════════════════════════════════════════════
188
+ function divider() {
189
+ console.log(pc.dim(' · · · · · · · · · · · · · · · · ·'));
190
+ }
191
+ export function printProgressBar(step, total) {
192
+ const w = 30;
193
+ const f = Math.round((step / total) * w);
194
+ console.log(pc.yellow(' ' + '━'.repeat(f)) + pc.dim('━'.repeat(w - f)) + pc.dim(` ${step}/${total}`));
195
+ }
196
+ export function printDesertLine() { divider(); }
197
+ export const STEP_TITLES = {
198
+ 1: 'The Spice Must Flow',
199
+ 2: 'Tell Me Your Name',
200
+ 3: 'Describe Your Sietch',
201
+ 4: 'Choose Your Ways',
202
+ 5: 'Arm Your Troops',
203
+ 6: 'Sharpen Your Blades',
204
+ 7: 'The Council Decides',
205
+ };
@@ -0,0 +1,2 @@
1
+ export declare function showVersionCheck(): Promise<void>;
2
+ export declare function getCurrentVersion(): string;
@@ -0,0 +1,27 @@
1
+ import pc from 'picocolors';
2
+ import { checkVersion } from './api.js';
3
+ import { readFileSync } from 'node:fs';
4
+ import { join, dirname } from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+ const __dirname = dirname(fileURLToPath(import.meta.url));
7
+ function getPackageVersion() {
8
+ try {
9
+ const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));
10
+ return pkg.version;
11
+ }
12
+ catch {
13
+ return '1.0.0';
14
+ }
15
+ }
16
+ export async function showVersionCheck() {
17
+ const version = getPackageVersion();
18
+ const { updateAvailable, latest } = await checkVersion(version);
19
+ if (updateAvailable) {
20
+ console.log(` ${pc.cyan('ℹ')} Thufir ${pc.bold(`v${latest}`)} is available (you have v${version})`);
21
+ console.log(` Run: ${pc.bold('npx thufir@latest init')}`);
22
+ console.log();
23
+ }
24
+ }
25
+ export function getCurrentVersion() {
26
+ return getPackageVersion();
27
+ }
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "thufir",
3
+ "version": "2.1.0",
4
+ "description": "AI Colleague — give your repository a brain",
5
+ "type": "module",
6
+ "bin": {
7
+ "thufir": "dist/index.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc && rm -rf dist/templates && cp -r src/templates dist/templates",
11
+ "dev": "tsc --watch",
12
+ "start": "node dist/index.js"
13
+ },
14
+ "keywords": [
15
+ "ai",
16
+ "agent",
17
+ "claude",
18
+ "cursor",
19
+ "colleague"
20
+ ],
21
+ "author": "Krisztian Lipcsei",
22
+ "license": "MIT",
23
+ "dependencies": {
24
+ "@clack/prompts": "^1.1.0",
25
+ "cfonts": "^3.3.1",
26
+ "figlet": "^1.8.0",
27
+ "gradient-string": "^3.0.0",
28
+ "picocolors": "^1.1.0"
29
+ },
30
+ "devDependencies": {
31
+ "@types/figlet": "^1.7.0",
32
+ "@types/node": "^22.0.0",
33
+ "typescript": "^5.7.0"
34
+ },
35
+ "engines": {
36
+ "node": ">=18"
37
+ }
38
+ }