get-noesisgen-light 0.1.1
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 +21 -0
- package/README.md +153 -0
- package/assets/banner.txt +9 -0
- package/assets/bonjour.cast +17 -0
- package/assets/bonjour.gif +0 -0
- package/assets/demo-output.sh +257 -0
- package/assets/install.cast +27 -0
- package/assets/install.gif +0 -0
- package/assets/setup-deep.cast +39 -0
- package/assets/setup-deep.gif +0 -0
- package/assets/setup-express.cast +24 -0
- package/assets/setup-express.gif +0 -0
- package/assets/tapes/bonjour.tape +27 -0
- package/assets/tapes/demo-wrapper.sh +13 -0
- package/assets/tapes/install.tape +26 -0
- package/bin/index.js +375 -0
- package/package.json +35 -0
- package/template/.claude/settings.local.json +16 -0
- package/template/.claude/skills/bonjour/SKILL.md +79 -0
- package/template/.claude/skills/deepwork/SKILL.md +96 -0
- package/template/.claude/skills/profile-deep/SKILL.md +74 -0
- package/template/.claude/skills/recap/SKILL.md +80 -0
- package/template/.claude/skills/status/SKILL.md +71 -0
- package/template/.claude/skills/sync/SKILL.md +58 -0
- package/template/.claude/skills/task/SKILL.md +44 -0
- package/template/CLAUDE-final.md.template +158 -0
- package/template/CLAUDE.md +262 -0
- package/template/launchagents/com.noesis.daily-digest.plist.template +31 -0
- package/template/launchagents/com.noesis.inbox-watcher.plist.template +28 -0
- package/template/launchagents/com.noesis.maintenance.plist.template +33 -0
- package/template/launchagents/com.noesis.session-auto.plist.template +31 -0
- package/template/scripts/noesis-daily-digest.sh +107 -0
- package/template/scripts/noesis-inbox-watcher.sh +64 -0
- package/template/scripts/noesis-maintenance.sh +62 -0
- package/template/scripts/noesis-notify.sh +15 -0
- package/template/scripts/noesis-session-auto.sh +68 -0
- package/template/subagents/analyzer-CLAUDE.md +45 -0
- package/template/subagents/voice-analyzer-CLAUDE.md +34 -0
- package/template/vault/SHARED.ENV/daily-notes/template-daily.md +39 -0
- package/template/vault/SHARED.ENV/gamification/config.md +87 -0
- package/template/vault/SHARED.ENV/gamification/xp-tracker.md +23 -0
- package/template/vault/SHARED.ENV/queue/pending.md +18 -0
- package/template/vault/SHARED.ENV/registres/momentum.md +41 -0
- package/template/vault/SHARED.ENV/registres/patterns-recurrents.md +43 -0
- package/template/vault/SHARED.ENV/registres/projets-actifs.md +35 -0
- package/template/vault/USER.ENV/objectifs/annuel.md +47 -0
- package/template/vault/USER.ENV/objectifs/trimestriel.md +33 -0
- package/template/vault/USER.ENV/portrait.md +55 -0
- package/template/vault/USER.ENV/profil.md +54 -0
- package/template/vault/USER.ENV/voice-dna.md +73 -0
package/bin/index.js
ADDED
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readFileSync, readdirSync, cpSync, chmodSync, existsSync, mkdirSync } from 'fs';
|
|
4
|
+
import { resolve, dirname, join } from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import { createInterface } from 'readline';
|
|
7
|
+
import { execFileSync } from 'child_process';
|
|
8
|
+
import { homedir, platform } from 'os';
|
|
9
|
+
|
|
10
|
+
// Detect system language (macOS: AppleLanguages, Linux: $LANG)
|
|
11
|
+
function getSystemLang() {
|
|
12
|
+
try {
|
|
13
|
+
if (platform() === 'darwin') {
|
|
14
|
+
const out = execFileSync('defaults', ['read', '-g', 'AppleLanguages'], { encoding: 'utf8' });
|
|
15
|
+
const match = out.match(/"?([a-z]{2})/i);
|
|
16
|
+
if (match) return match[1].toLowerCase();
|
|
17
|
+
}
|
|
18
|
+
} catch {}
|
|
19
|
+
const lang = process.env.LANG || process.env.LANGUAGE || process.env.LC_ALL || '';
|
|
20
|
+
const match = lang.match(/^([a-z]{2})/i);
|
|
21
|
+
return match ? match[1].toLowerCase() : 'en';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// i18n strings
|
|
25
|
+
const strings = {
|
|
26
|
+
en: {
|
|
27
|
+
preflight: 'Preflight checks',
|
|
28
|
+
whereLive: 'Where should NOESIS Light live?',
|
|
29
|
+
choices: ['Desktop/Noesis', 'Documents/Noesis', 'Custom path'],
|
|
30
|
+
chooseLocation: 'Choose a location:',
|
|
31
|
+
customPath: 'Enter path:',
|
|
32
|
+
alreadyExists: 'already exists. Overwrite? (y/N)',
|
|
33
|
+
cancelled: 'Installation cancelled.',
|
|
34
|
+
installing: 'Installing NOESIS Light',
|
|
35
|
+
creatingVault: 'Creating vault structure...',
|
|
36
|
+
vaultDone: 'Vault structure created (USER.ENV / SHARED.ENV / AI.ENV)',
|
|
37
|
+
settingScripts: 'Setting up background scripts...',
|
|
38
|
+
scriptsDone: (n) => `${n} background scripts ready`,
|
|
39
|
+
installingSkills: 'Installing skills...',
|
|
40
|
+
skillsDone: (n) => `${n} skills installed (/bonjour /status /recap /sync /task /deepwork /profile-deep)`,
|
|
41
|
+
configuringSubs: 'Configuring subagents...',
|
|
42
|
+
subsDone: '2 subagents configured (analyzer, voice-analyzer)',
|
|
43
|
+
preparingAgents: 'Preparing background agents...',
|
|
44
|
+
agentsDone: '4 background agent templates ready (digest, session, watcher, maintenance)',
|
|
45
|
+
settingGamif: 'Setting up gamification...',
|
|
46
|
+
gamifDone: 'Gamification ready (18 levels, 3 acts, 48h grace period)',
|
|
47
|
+
installedTo: (dest) => `NOESIS Light installed to ${dest}`,
|
|
48
|
+
setupWill: 'Everything is ready. The setup agent will personalize it for you:',
|
|
49
|
+
setupItems: [
|
|
50
|
+
'Your profile, portrait, and voice analysis',
|
|
51
|
+
'Your projects (detected from your files)',
|
|
52
|
+
'Background agents (scheduled to your rhythm)',
|
|
53
|
+
"Your system's name and shell aliases",
|
|
54
|
+
],
|
|
55
|
+
next: 'Next:',
|
|
56
|
+
copied: 'Copied to clipboard — just paste and press Enter.',
|
|
57
|
+
sayHello: 'Then just say hello — the setup agent will guide you from there.',
|
|
58
|
+
},
|
|
59
|
+
fr: {
|
|
60
|
+
preflight: 'Vérifications préliminaires',
|
|
61
|
+
whereLive: 'Où installer NOESIS Light ?',
|
|
62
|
+
choices: ['Desktop/Noesis', 'Documents/Noesis', 'Chemin personnalisé'],
|
|
63
|
+
chooseLocation: 'Choisir un emplacement :',
|
|
64
|
+
customPath: 'Entrer le chemin :',
|
|
65
|
+
alreadyExists: 'existe déjà. Écraser ? (o/N)',
|
|
66
|
+
cancelled: 'Installation annulée.',
|
|
67
|
+
installing: 'Installation de NOESIS Light',
|
|
68
|
+
creatingVault: 'Création de la structure vault...',
|
|
69
|
+
vaultDone: 'Structure vault créée (USER.ENV / SHARED.ENV / AI.ENV)',
|
|
70
|
+
settingScripts: 'Configuration des scripts...',
|
|
71
|
+
scriptsDone: (n) => `${n} scripts prêts`,
|
|
72
|
+
installingSkills: 'Installation des skills...',
|
|
73
|
+
skillsDone: (n) => `${n} skills installés (/bonjour /status /recap /sync /task /deepwork /profile-deep)`,
|
|
74
|
+
configuringSubs: 'Configuration des subagents...',
|
|
75
|
+
subsDone: '2 subagents configurés (analyzer, voice-analyzer)',
|
|
76
|
+
preparingAgents: 'Préparation des agents de fond...',
|
|
77
|
+
agentsDone: '4 agents de fond prêts (digest, session, watcher, maintenance)',
|
|
78
|
+
settingGamif: 'Configuration de la gamification...',
|
|
79
|
+
gamifDone: 'Gamification prête (18 niveaux, 3 actes, période de grâce 48h)',
|
|
80
|
+
installedTo: (dest) => `NOESIS Light installé dans ${dest}`,
|
|
81
|
+
setupWill: "Tout est prêt. L'agent de setup va tout personnaliser :",
|
|
82
|
+
setupItems: [
|
|
83
|
+
'Ton profil, portrait et analyse vocale',
|
|
84
|
+
'Tes projets (détectés depuis tes fichiers)',
|
|
85
|
+
'Les agents de fond (calés sur ton rythme)',
|
|
86
|
+
'Le nom et les alias shell de ton système',
|
|
87
|
+
],
|
|
88
|
+
next: 'Suite :',
|
|
89
|
+
copied: 'Copié dans le presse-papiers — colle et appuie sur Entrée.',
|
|
90
|
+
sayHello: "Puis dis simplement bonjour — l'agent de setup prend le relais.",
|
|
91
|
+
},
|
|
92
|
+
es: {
|
|
93
|
+
preflight: 'Verificaciones previas',
|
|
94
|
+
whereLive: '¿Dónde instalar NOESIS Light?',
|
|
95
|
+
choices: ['Desktop/Noesis', 'Documents/Noesis', 'Ruta personalizada'],
|
|
96
|
+
chooseLocation: 'Elige una ubicación:',
|
|
97
|
+
customPath: 'Introduce la ruta:',
|
|
98
|
+
alreadyExists: 'ya existe. ¿Sobrescribir? (s/N)',
|
|
99
|
+
cancelled: 'Instalación cancelada.',
|
|
100
|
+
installing: 'Instalando NOESIS Light',
|
|
101
|
+
creatingVault: 'Creando estructura del vault...',
|
|
102
|
+
vaultDone: 'Estructura del vault creada (USER.ENV / SHARED.ENV / AI.ENV)',
|
|
103
|
+
settingScripts: 'Configurando scripts...',
|
|
104
|
+
scriptsDone: (n) => `${n} scripts listos`,
|
|
105
|
+
installingSkills: 'Instalando skills...',
|
|
106
|
+
skillsDone: (n) => `${n} skills instalados (/bonjour /status /recap /sync /task /deepwork /profile-deep)`,
|
|
107
|
+
configuringSubs: 'Configurando subagentes...',
|
|
108
|
+
subsDone: '2 subagentes configurados (analyzer, voice-analyzer)',
|
|
109
|
+
preparingAgents: 'Preparando agentes de fondo...',
|
|
110
|
+
agentsDone: '4 agentes de fondo listos (digest, session, watcher, maintenance)',
|
|
111
|
+
settingGamif: 'Configurando gamificación...',
|
|
112
|
+
gamifDone: 'Gamificación lista (18 niveles, 3 actos, período de gracia 48h)',
|
|
113
|
+
installedTo: (dest) => `NOESIS Light instalado en ${dest}`,
|
|
114
|
+
setupWill: 'Todo listo. El agente de setup lo personalizará todo:',
|
|
115
|
+
setupItems: [
|
|
116
|
+
'Tu perfil, retrato y análisis vocal',
|
|
117
|
+
'Tus proyectos (detectados en tus archivos)',
|
|
118
|
+
'Agentes de fondo (ajustados a tu ritmo)',
|
|
119
|
+
'El nombre y los alias shell de tu sistema',
|
|
120
|
+
],
|
|
121
|
+
next: 'Siguiente:',
|
|
122
|
+
copied: 'Copiado al portapapeles — pega y presiona Enter.',
|
|
123
|
+
sayHello: 'Luego simplemente di hola — el agente de setup te guiará.',
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
function t(lang) {
|
|
128
|
+
return strings[lang] || strings.en;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
132
|
+
const __dirname = dirname(__filename);
|
|
133
|
+
const TEMPLATE_DIR = resolve(__dirname, '..', 'template');
|
|
134
|
+
|
|
135
|
+
// Colors (with NO_COLOR support)
|
|
136
|
+
const nc = !process.env.NO_COLOR && process.stdout.isTTY;
|
|
137
|
+
const c = {
|
|
138
|
+
reset: nc ? '\x1b[0m' : '',
|
|
139
|
+
bold: nc ? '\x1b[1m' : '',
|
|
140
|
+
dim: nc ? '\x1b[2m' : '',
|
|
141
|
+
green: nc ? '\x1b[32m' : '',
|
|
142
|
+
cyan: nc ? '\x1b[36m' : '',
|
|
143
|
+
yellow: nc ? '\x1b[33m' : '',
|
|
144
|
+
red: nc ? '\x1b[31m' : '',
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
function getVersion() {
|
|
148
|
+
try {
|
|
149
|
+
const pkg = JSON.parse(readFileSync(resolve(__dirname, '..', 'package.json'), 'utf8'));
|
|
150
|
+
return pkg.version;
|
|
151
|
+
} catch {
|
|
152
|
+
return '0.1.0';
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function getBanner(version) {
|
|
157
|
+
try {
|
|
158
|
+
const banner = readFileSync(resolve(__dirname, '..', 'assets', 'banner.txt'), 'utf8');
|
|
159
|
+
return `${c.cyan}${banner}${c.reset}${c.dim} v${version}${c.reset}\n`;
|
|
160
|
+
} catch {
|
|
161
|
+
return `${c.cyan}${c.bold}NOESIS Light${c.reset} ${c.dim}v${version}${c.reset}\n Your cognitive operating system starter kit.\n`;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function fail(msg) {
|
|
166
|
+
console.error(`\n${c.red}✗ ${msg}${c.reset}\n`);
|
|
167
|
+
process.exit(1);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function ok(msg) {
|
|
171
|
+
console.log(`${c.green}✓${c.reset} ${msg}`);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Animated spinner for a step
|
|
175
|
+
function spinner(label) {
|
|
176
|
+
const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
177
|
+
let i = 0;
|
|
178
|
+
const interval = setInterval(() => {
|
|
179
|
+
process.stdout.write(`\r\x1b[K${c.cyan}${frames[i % frames.length]}${c.reset} ${label}`);
|
|
180
|
+
i++;
|
|
181
|
+
}, 80);
|
|
182
|
+
|
|
183
|
+
return {
|
|
184
|
+
done(msg) {
|
|
185
|
+
clearInterval(interval);
|
|
186
|
+
process.stdout.write(`\r\x1b[K${c.green}✓${c.reset} ${msg || label}\n`);
|
|
187
|
+
},
|
|
188
|
+
fail(msg) {
|
|
189
|
+
clearInterval(interval);
|
|
190
|
+
process.stdout.write(`\r\x1b[K${c.red}✗${c.reset} ${msg || label}\n`);
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Delay helper
|
|
196
|
+
function wait(ms) {
|
|
197
|
+
return new Promise(r => setTimeout(r, ms));
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Preflight checks
|
|
201
|
+
function preflight() {
|
|
202
|
+
const p = platform();
|
|
203
|
+
if (p !== 'darwin' && p !== 'linux') {
|
|
204
|
+
fail(`NOESIS Light requires macOS or Linux. Detected: ${p}`);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const nodeVersion = parseInt(process.version.slice(1));
|
|
208
|
+
if (nodeVersion < 18) {
|
|
209
|
+
fail(`Node.js 18+ required. You have ${process.version}`);
|
|
210
|
+
}
|
|
211
|
+
ok(`Node.js ${process.version}`);
|
|
212
|
+
|
|
213
|
+
try {
|
|
214
|
+
execFileSync('which', ['claude'], { stdio: 'ignore' });
|
|
215
|
+
ok('Claude CLI found');
|
|
216
|
+
} catch {
|
|
217
|
+
fail(`Claude CLI not found.\n\n Install it: https://docs.anthropic.com/en/docs/claude-code\n\n Then run this installer again.`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Prompt user for input
|
|
222
|
+
function ask(question, defaultValue) {
|
|
223
|
+
return new Promise((resolve) => {
|
|
224
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
225
|
+
const prompt = defaultValue
|
|
226
|
+
? `${question} ${c.dim}(${defaultValue})${c.reset} `
|
|
227
|
+
: `${question} `;
|
|
228
|
+
rl.question(prompt, (answer) => {
|
|
229
|
+
rl.close();
|
|
230
|
+
resolve(answer.trim() || defaultValue || '');
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Choose from numbered list
|
|
236
|
+
async function choose(question, options) {
|
|
237
|
+
console.log(`\n${question}`);
|
|
238
|
+
for (let i = 0; i < options.length; i++) {
|
|
239
|
+
console.log(` ${c.cyan}${i + 1}.${c.reset} ${options[i]}`);
|
|
240
|
+
}
|
|
241
|
+
const answer = await ask(`\n${c.dim}(1-${options.length})${c.reset}`, '1');
|
|
242
|
+
const idx = parseInt(answer) - 1;
|
|
243
|
+
return idx >= 0 && idx < options.length ? idx : 0;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Main
|
|
247
|
+
async function main() {
|
|
248
|
+
const version = getVersion();
|
|
249
|
+
const lang = getSystemLang();
|
|
250
|
+
const s18n = t(lang);
|
|
251
|
+
|
|
252
|
+
console.log(getBanner(version));
|
|
253
|
+
|
|
254
|
+
// Preflight
|
|
255
|
+
console.log(`${c.bold}${s18n.preflight}${c.reset}`);
|
|
256
|
+
preflight();
|
|
257
|
+
console.log();
|
|
258
|
+
|
|
259
|
+
// Destination path with choices
|
|
260
|
+
const home = homedir();
|
|
261
|
+
const pathOptions = [
|
|
262
|
+
join(home, 'Desktop', 'Noesis'),
|
|
263
|
+
join(home, 'Documents', 'Noesis'),
|
|
264
|
+
];
|
|
265
|
+
|
|
266
|
+
const choice = await choose(s18n.chooseLocation, [
|
|
267
|
+
...s18n.choices.slice(0, 2).map((label, i) => `${label} ${c.dim}(${pathOptions[i]})${c.reset}`),
|
|
268
|
+
s18n.choices[2],
|
|
269
|
+
]);
|
|
270
|
+
|
|
271
|
+
let dest;
|
|
272
|
+
if (choice < 2) {
|
|
273
|
+
dest = pathOptions[choice];
|
|
274
|
+
} else {
|
|
275
|
+
const customInput = await ask(s18n.customPath);
|
|
276
|
+
dest = resolve(customInput.replace(/^~/, home));
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Check if exists
|
|
280
|
+
if (existsSync(dest)) {
|
|
281
|
+
const confirmChar = lang === 'fr' ? 'o' : lang === 'es' ? 's' : 'y';
|
|
282
|
+
const overwrite = await ask(`${dest} ${s18n.alreadyExists}`, 'N');
|
|
283
|
+
if (overwrite.toLowerCase() !== confirmChar && overwrite.toLowerCase() !== 'y') {
|
|
284
|
+
console.log(`\n${c.dim}${s18n.cancelled}${c.reset}`);
|
|
285
|
+
process.exit(0);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
console.log(`\n${c.bold}${s18n.installing}${c.reset}\n`);
|
|
290
|
+
|
|
291
|
+
// Step 1: Vault structure
|
|
292
|
+
let s = spinner(s18n.creatingVault);
|
|
293
|
+
mkdirSync(dest, { recursive: true });
|
|
294
|
+
cpSync(TEMPLATE_DIR, dest, { recursive: true });
|
|
295
|
+
await wait(400);
|
|
296
|
+
s.done(s18n.vaultDone);
|
|
297
|
+
|
|
298
|
+
// Step 2: Scripts
|
|
299
|
+
s = spinner(s18n.settingScripts);
|
|
300
|
+
const scriptsDir = join(dest, 'scripts');
|
|
301
|
+
let scriptCount = 0;
|
|
302
|
+
if (existsSync(scriptsDir)) {
|
|
303
|
+
try {
|
|
304
|
+
const scripts = readdirSync(scriptsDir).filter(f => f.endsWith('.sh'));
|
|
305
|
+
for (const script of scripts) {
|
|
306
|
+
chmodSync(join(scriptsDir, script), 0o755);
|
|
307
|
+
}
|
|
308
|
+
scriptCount = scripts.length;
|
|
309
|
+
} catch {}
|
|
310
|
+
}
|
|
311
|
+
await wait(300);
|
|
312
|
+
s.done(s18n.scriptsDone(scriptCount));
|
|
313
|
+
|
|
314
|
+
// Step 3: Skills
|
|
315
|
+
s = spinner(s18n.installingSkills);
|
|
316
|
+
const skillsDir = join(dest, '.claude', 'skills');
|
|
317
|
+
let skillCount = 0;
|
|
318
|
+
if (existsSync(skillsDir)) {
|
|
319
|
+
try {
|
|
320
|
+
skillCount = readdirSync(skillsDir).filter(d => {
|
|
321
|
+
return existsSync(join(skillsDir, d, 'SKILL.md'));
|
|
322
|
+
}).length;
|
|
323
|
+
} catch {}
|
|
324
|
+
}
|
|
325
|
+
await wait(350);
|
|
326
|
+
s.done(s18n.skillsDone(skillCount));
|
|
327
|
+
|
|
328
|
+
// Step 4: Subagents
|
|
329
|
+
s = spinner(s18n.configuringSubs);
|
|
330
|
+
await wait(250);
|
|
331
|
+
s.done(s18n.subsDone);
|
|
332
|
+
|
|
333
|
+
// Step 5: LaunchAgent templates
|
|
334
|
+
s = spinner(s18n.preparingAgents);
|
|
335
|
+
await wait(300);
|
|
336
|
+
s.done(s18n.agentsDone);
|
|
337
|
+
|
|
338
|
+
// Step 6: Gamification
|
|
339
|
+
s = spinner(s18n.settingGamif);
|
|
340
|
+
await wait(200);
|
|
341
|
+
s.done(s18n.gamifDone);
|
|
342
|
+
|
|
343
|
+
// Copy next command to clipboard
|
|
344
|
+
const nextCmd = `cd ${dest} && claude`;
|
|
345
|
+
try {
|
|
346
|
+
if (platform() === 'darwin') {
|
|
347
|
+
execFileSync('pbcopy', { input: nextCmd, stdio: ['pipe', 'ignore', 'ignore'] });
|
|
348
|
+
} else {
|
|
349
|
+
execFileSync('xclip', ['-selection', 'clipboard'], { input: nextCmd, stdio: ['pipe', 'ignore', 'ignore'] });
|
|
350
|
+
}
|
|
351
|
+
} catch {}
|
|
352
|
+
|
|
353
|
+
const copied = s18n.copied || 'Copied to clipboard — just paste and press Enter.';
|
|
354
|
+
|
|
355
|
+
// Summary
|
|
356
|
+
const items = s18n.setupItems.map(item => ` ${c.dim}•${c.reset} ${item}`).join('\n');
|
|
357
|
+
console.log(`
|
|
358
|
+
${c.green}${c.bold}✓ ${s18n.installedTo(dest)}${c.reset}
|
|
359
|
+
|
|
360
|
+
${c.dim}${s18n.setupWill}${c.reset}
|
|
361
|
+
${items}
|
|
362
|
+
|
|
363
|
+
${c.bold}${s18n.next}${c.reset}
|
|
364
|
+
|
|
365
|
+
${c.cyan}${nextCmd}${c.reset}
|
|
366
|
+
${c.dim}${copied}${c.reset}
|
|
367
|
+
|
|
368
|
+
${c.dim}${s18n.sayHello}${c.reset}
|
|
369
|
+
`);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
main().catch((err) => {
|
|
373
|
+
console.error(`\n${c.red}Error: ${err.message}${c.reset}`);
|
|
374
|
+
process.exit(1);
|
|
375
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "get-noesisgen-light",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "NOESIS Light — Your cognitive operating system starter kit. Install a personalized AI-powered second brain via Claude Code.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"get-noesisgen-light": "bin/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/",
|
|
11
|
+
"template/",
|
|
12
|
+
"assets/"
|
|
13
|
+
],
|
|
14
|
+
"keywords": [
|
|
15
|
+
"noesis",
|
|
16
|
+
"claude-code",
|
|
17
|
+
"cognitive-system",
|
|
18
|
+
"second-brain",
|
|
19
|
+
"productivity",
|
|
20
|
+
"ai-assistant"
|
|
21
|
+
],
|
|
22
|
+
"author": "Gino Fontana",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "git+https://github.com/ginoftn/noesis-gen-light.git"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://github.com/ginoftn/noesis-gen-light",
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/ginoftn/noesis-gen/issues"
|
|
31
|
+
},
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=18.0.0"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bonjour
|
|
3
|
+
description: First session of the day. Checks time, loads adapted context, presents the daily brief.
|
|
4
|
+
user-invocable: true
|
|
5
|
+
disable-model-invocation: false
|
|
6
|
+
argument-hint: ""
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Bonjour -- First interactive session of the day
|
|
10
|
+
|
|
11
|
+
This skill is for the FIRST session only. For subsequent sessions, use `/sync`.
|
|
12
|
+
|
|
13
|
+
## Step 1: Check current time
|
|
14
|
+
|
|
15
|
+
Run `date "+%Y-%m-%d %H:%M %A"` — MANDATORY, before anything else.
|
|
16
|
+
|
|
17
|
+
Determine the moment:
|
|
18
|
+
- 05h-11h59: `morning` — energetic greeting
|
|
19
|
+
- 12h-17h59: `afternoon` — casual greeting
|
|
20
|
+
- 18h-22h59: `evening` — focused, lighter context load
|
|
21
|
+
- 23h-04h59: `night` — minimal, complicit
|
|
22
|
+
|
|
23
|
+
## Step 2: Load context (adapted to time)
|
|
24
|
+
|
|
25
|
+
### Always (any time of day)
|
|
26
|
+
|
|
27
|
+
1. Today's daily note: `vault/SHARED.ENV/daily-notes/YYYY-MM-DD.md`
|
|
28
|
+
2. Today's digest: `vault/AI.ENV/outputs/digest-latest.md` (if available)
|
|
29
|
+
3. Active objectives: `vault/SHARED.ENV/registres/projets-actifs.md`
|
|
30
|
+
|
|
31
|
+
### Morning or afternoon (before 18h) — full load
|
|
32
|
+
|
|
33
|
+
4. Momentum: `vault/SHARED.ENV/registres/momentum.md`
|
|
34
|
+
5. Annual + quarterly objectives: `vault/USER.ENV/objectifs/annuel.md` + `trimestriel.md`
|
|
35
|
+
6. Today's agent outputs: `vault/AI.ENV/outputs/` (files from today)
|
|
36
|
+
|
|
37
|
+
### Evening or night (18h+) — light load
|
|
38
|
+
|
|
39
|
+
4. Momentum: "Current focus" section only
|
|
40
|
+
5. Agent outputs only if new since last session
|
|
41
|
+
6. DO NOT reload projets-actifs or annual objectives — too heavy for evening
|
|
42
|
+
|
|
43
|
+
## Step 3: Check autonomous sessions
|
|
44
|
+
|
|
45
|
+
If autonomous sessions (digest, auto session) have already run today:
|
|
46
|
+
- Mention in 1 line what they produced
|
|
47
|
+
- If no output visible, note it (not an anomaly if before scheduled time)
|
|
48
|
+
|
|
49
|
+
## Step 4: Display the brief
|
|
50
|
+
|
|
51
|
+
Format adapted to the moment, in the user's primary language:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
## [Greeting] -- [day] [date], [time]
|
|
55
|
+
|
|
56
|
+
### Today
|
|
57
|
+
- [remaining schedule, key events]
|
|
58
|
+
- [autonomous sessions if already run]
|
|
59
|
+
|
|
60
|
+
### Active projects [EVENING: replace with "Tonight"]
|
|
61
|
+
- [hot projects, 1 line each]
|
|
62
|
+
- [XP streak if relevant]
|
|
63
|
+
|
|
64
|
+
### What brings you here?
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Evening/night:** reduce "Active projects" to the strict minimum. No full panorama.
|
|
68
|
+
|
|
69
|
+
## Step 5: Ask for invisible context
|
|
70
|
+
|
|
71
|
+
Always end by asking what happened in spaces the system can't see (other tools, reflections, conversations, reading). Integrated in "What brings you here?" — no need for a separate question unless the day has been long.
|
|
72
|
+
|
|
73
|
+
## Rules
|
|
74
|
+
|
|
75
|
+
- **NEVER invoke this skill if an interactive session already happened today.** Use `/sync` instead.
|
|
76
|
+
- USER.ENV files (profil, portrait, voice-dna) are loaded by CLAUDE.md at boot — don't re-read here.
|
|
77
|
+
- Compact. Every line carries information. No filler.
|
|
78
|
+
- Tone adapts to the moment: energetic morning, focused evening, complicit night.
|
|
79
|
+
- Communicate in the user's primary language.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: deepwork
|
|
3
|
+
description: Deep work mode. Loads full project context, structures in pomodoros, auto-recap at the end.
|
|
4
|
+
user-invocable: true
|
|
5
|
+
disable-model-invocation: false
|
|
6
|
+
argument-hint: "<PROJECT> [DURATION in minutes, default 60]"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Deep Work -- Immersive session
|
|
10
|
+
|
|
11
|
+
Start an immersive creative work session. Everything loaded, everything ready, minimize interruptions.
|
|
12
|
+
|
|
13
|
+
## Prerequisites
|
|
14
|
+
|
|
15
|
+
$ARGUMENTS must contain at least a project name. If absent, ask.
|
|
16
|
+
Duration is optional (default 60 minutes).
|
|
17
|
+
|
|
18
|
+
## Phase 1: Context loading (silent)
|
|
19
|
+
|
|
20
|
+
Read everything without displaying details, just a loading message:
|
|
21
|
+
|
|
22
|
+
1. Project file: `vault/SHARED.ENV/registres/projets/<PROJECT>.md`
|
|
23
|
+
2. Latest daily note: `vault/SHARED.ENV/daily-notes/`
|
|
24
|
+
3. Momentum: `vault/SHARED.ENV/registres/momentum.md`
|
|
25
|
+
4. Voice-dna (project-relevant parts): `vault/USER.ENV/voice-dna.md`
|
|
26
|
+
5. XP tracker: `vault/SHARED.ENV/gamification/xp-tracker.md`
|
|
27
|
+
|
|
28
|
+
## Phase 2: Briefing (compact)
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
+======================================================+
|
|
32
|
+
| DEEP WORK -- PROJECT (Xmin) |
|
|
33
|
+
+======================================================+
|
|
34
|
+
| CONTEXT |
|
|
35
|
+
| Last activity: [date + what] |
|
|
36
|
+
| State: [completion + next step] |
|
|
37
|
+
| Estimated energy: [based on time + momentum] |
|
|
38
|
+
| |
|
|
39
|
+
| SESSION PLAN |
|
|
40
|
+
| P1 [00:00-00:25] [micro-objective 1] |
|
|
41
|
+
| -- [5min break] |
|
|
42
|
+
| P2 [00:30-00:55] [micro-objective 2] |
|
|
43
|
+
| [+ more if duration > 60min] |
|
|
44
|
+
| |
|
|
45
|
+
| Ready? (or adjust the plan) |
|
|
46
|
+
+======================================================+
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Pomodoro structure:
|
|
50
|
+
- 30min → 1x25 + 5min break
|
|
51
|
+
- 60min → 2x25 + 10min breaks
|
|
52
|
+
- 90min → 3x25 + 15min breaks
|
|
53
|
+
- 120min → 4x25 + breaks + long break
|
|
54
|
+
|
|
55
|
+
## Phase 3: Work (focus)
|
|
56
|
+
|
|
57
|
+
- Stay on the project. Don't suggest digressions.
|
|
58
|
+
- If the user drifts, gently refocus: "Save that for after? Pomodoro is running."
|
|
59
|
+
- No /status, no /sync during deep work.
|
|
60
|
+
- Note off-topic ideas in an internal buffer for the recap.
|
|
61
|
+
|
|
62
|
+
## Phase 4: Auto-recap (at the end)
|
|
63
|
+
|
|
64
|
+
When the session ends (user says "stop" or time is up):
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
+======================================================+
|
|
68
|
+
| END DEEP WORK -- PROJECT |
|
|
69
|
+
+======================================================+
|
|
70
|
+
| Actual duration: Xmin |
|
|
71
|
+
| Pomodoros completed: X/Y |
|
|
72
|
+
| XP earned: +XX |
|
|
73
|
+
| |
|
|
74
|
+
| WHAT WAS DONE |
|
|
75
|
+
| [factual list] |
|
|
76
|
+
| |
|
|
77
|
+
| BUFFERED IDEAS (off-topic) |
|
|
78
|
+
| - [idea 1 -- save to captures?] |
|
|
79
|
+
| - [idea 2] |
|
|
80
|
+
| |
|
|
81
|
+
| NEXT DEEP WORK SUGGESTED |
|
|
82
|
+
| -> [next logical step + suggested duration] |
|
|
83
|
+
+======================================================+
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
1. Update `vault/SHARED.ENV/gamification/xp-tracker.md` with earned XP
|
|
87
|
+
2. Write the recap to today's daily note (same format as `/recap write`)
|
|
88
|
+
3. Offer to save buffered ideas to `vault/SHARED.ENV/captures/`
|
|
89
|
+
|
|
90
|
+
## Style
|
|
91
|
+
|
|
92
|
+
- Compact briefing, no filler
|
|
93
|
+
- During work: maximum focus, creation-oriented responses
|
|
94
|
+
- Recap: factual, celebratory if productive, neutral otherwise
|
|
95
|
+
- Never guilt-trip if deep work is shorter than planned
|
|
96
|
+
- Communicate in the user's primary language
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: profile-deep
|
|
3
|
+
description: Enrich profile, portrait, and voice-dna by analyzing the user's writing and work patterns.
|
|
4
|
+
user-invocable: true
|
|
5
|
+
disable-model-invocation: false
|
|
6
|
+
argument-hint: "[focus] -- no argument = full analysis, 'voice' = voice-dna only, 'patterns' = patterns only"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Profile Deep -- Enrich your cognitive profile
|
|
10
|
+
|
|
11
|
+
Analyze the user's files and writing to deepen the profile, portrait, and voice-dna. Can be run as many times as wanted — each pass adds depth.
|
|
12
|
+
|
|
13
|
+
## What you do
|
|
14
|
+
|
|
15
|
+
### Step 1: Scan for material
|
|
16
|
+
|
|
17
|
+
Scan the user's project directories for text content:
|
|
18
|
+
- Look for .md, .txt files modified in the last 90 days
|
|
19
|
+
- Prioritize: long files (>500 words), creative writing, personal notes
|
|
20
|
+
- Identify 5-10 candidate files across different projects
|
|
21
|
+
- Show the list to the user: "I found these files. OK to analyze the style? I'll read how you write, not what you write."
|
|
22
|
+
|
|
23
|
+
### Step 2: Voice analysis (via subagent)
|
|
24
|
+
|
|
25
|
+
Launch the voice-analyzer subagent (`subagents/voice-analyzer-CLAUDE.md`) with the approved file list.
|
|
26
|
+
|
|
27
|
+
The subagent analyzes:
|
|
28
|
+
- Sentence length, register, recurring tics, rhythm, narrative voice
|
|
29
|
+
- Patterns across files (not just within one)
|
|
30
|
+
- What's absent from the writing
|
|
31
|
+
|
|
32
|
+
Update `vault/USER.ENV/voice-dna.md` Part 2 with the results. If Part 2 already exists, enrich it (don't overwrite — add new observations, confirm or revise existing ones).
|
|
33
|
+
|
|
34
|
+
### Step 3: Pattern analysis
|
|
35
|
+
|
|
36
|
+
From the file scan + conversation history + daily notes, identify:
|
|
37
|
+
- **Work patterns:** When does the user work? In bursts or steadily? Morning or night?
|
|
38
|
+
- **Project patterns:** How many projects started vs finished? Common themes?
|
|
39
|
+
- **Behavioral patterns:** Does the user start more than finish? Organize instead of do? Theorize instead of act?
|
|
40
|
+
|
|
41
|
+
Update `vault/USER.ENV/portrait.md` with new observations. Show changes to the user before writing.
|
|
42
|
+
|
|
43
|
+
### Step 4: Red threads
|
|
44
|
+
|
|
45
|
+
Look across all detected projects for recurring themes — the deep connections:
|
|
46
|
+
- Shared motifs, characters, ideas
|
|
47
|
+
- Complementary projects (one explores what another avoids)
|
|
48
|
+
- Evolution over time (what the user returns to)
|
|
49
|
+
|
|
50
|
+
Update `vault/USER.ENV/voice-dna.md` Part 3 (Red threads). Show to user before writing.
|
|
51
|
+
|
|
52
|
+
### Step 5: Profile summary
|
|
53
|
+
|
|
54
|
+
If `vault/USER.ENV/profil.md` has empty sections or thin content, propose enrichments based on everything analyzed. Show diff to user before writing.
|
|
55
|
+
|
|
56
|
+
## Modes
|
|
57
|
+
|
|
58
|
+
### `/profile-deep` (full analysis)
|
|
59
|
+
Runs all 5 steps.
|
|
60
|
+
|
|
61
|
+
### `/profile-deep voice` (voice only)
|
|
62
|
+
Runs steps 1-2 only. Quick voice-dna enrichment.
|
|
63
|
+
|
|
64
|
+
### `/profile-deep patterns` (patterns only)
|
|
65
|
+
Runs steps 3-4 only. No file reading, just analysis from existing data.
|
|
66
|
+
|
|
67
|
+
## Rules
|
|
68
|
+
|
|
69
|
+
- **Always ask before reading files.** Show the list, get approval.
|
|
70
|
+
- **Analyze style, not content.** "Uses em dashes heavily" not "writes about loss."
|
|
71
|
+
- **Show changes before writing.** The user validates every edit to USER.ENV.
|
|
72
|
+
- **Additive, not destructive.** Each pass enriches, never overwrites previous analysis.
|
|
73
|
+
- **Write in the user's primary language.**
|
|
74
|
+
- This is the ONLY skill that writes to USER.ENV (besides the initial setup).
|