primocode 7.0.0 → 7.0.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/bin/primocode.js CHANGED
@@ -20,6 +20,7 @@ const { c, welcomeBox, Spinner, ProgressBar, askYesNo } = require('../lib/ui');
20
20
  const api = require('../lib/api');
21
21
  const tools = require('../lib/tools');
22
22
  const cfg = require('../lib/config');
23
+ const { createProjectDir, getProjectDir, listProjects } = require('../lib/config');
23
24
  const { runAct } = require('../lib/act');
24
25
 
25
26
  const VERSION = pkg.version;
@@ -30,10 +31,12 @@ const state = {
30
31
  mode: 'primocode',
31
32
  attachedFiles: [],
32
33
  lastResponse: '',
34
+ currentProject: null,
33
35
  };
34
36
 
35
37
  const HELP = `
36
38
  ${c.bold('Comandos')}
39
+ ${c.brand('/project')} lista projetos ou muda: /project <nome>
37
40
  ${c.brand('/mode')} Primo Code / Chat
38
41
  ${c.brand('/attach')} (Caminho do arquivo ou pasta) anexa arquivo
39
42
  ${c.brand('/clear')} limpa conversa
package/lib/act.js CHANGED
@@ -29,7 +29,7 @@ function makeLogger() {
29
29
  }
30
30
 
31
31
  async function runAct(userPrompt, opts) {
32
- const { server, model, history } = opts || {};
32
+ const { server, model, history, projectDir, projectName } = opts || {};
33
33
  const logger = makeLogger();
34
34
  const messages = [
35
35
  ...(Array.isArray(history) ? history.filter(m => m && m.role && m.content).slice(-20) : []),
package/lib/api.js CHANGED
@@ -30,7 +30,9 @@ function requestStream(serverUrl, endpoint, payload, onEvent) {
30
30
  });
31
31
  }
32
32
 
33
- function requestAct(serverUrl, messages, model) { return request(serverUrl, '/api/act', { messages, model }); }
33
+ function requestAct(serverUrl, messages, model, extras) {
34
+ return request(serverUrl, '/api/act', { messages, model, ...(extras || {}) });
35
+ }
34
36
 
35
37
  function getHealth(serverUrl) {
36
38
  return new Promise((resolve, reject) => { const url=new URL('/health',serverUrl); const client=url.protocol==='https:'?https:http; const req=client.get(url, (res)=>{ let body=''; res.on('data',c=>body+=c); res.on('end',()=>{ try { resolve(JSON.parse(body)); } catch { reject(new Error('Resposta inválida do health check')); } }); }); req.on('error',reject); });
package/lib/config.js CHANGED
@@ -1,4 +1,9 @@
1
1
  // Carrega config de ~/.primocode/config.json + env vars.
2
+ // Estrutura de pastas:
3
+ // ~/primocode/ <- raiz (projetos + you.md)
4
+ // ~/primocode/primocode/ <- codigo interno do CLI
5
+ // ~/primocode/<projeto>/ <- projetos gerados
6
+ // ~/primocode/<projeto>/memory.md <- memorias do projeto
2
7
 
3
8
  'use strict';
4
9
 
@@ -7,31 +12,112 @@ const path = require('path');
7
12
  const os = require('os');
8
13
 
9
14
  const HOME = os.homedir();
15
+ const ROOT_DIR = path.join(HOME, 'primocode');
16
+ const INTERNAL_DIR = path.join(ROOT_DIR, 'primocode');
10
17
  const CONFIG_DIR = path.join(HOME, '.primocode');
11
18
  const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
12
19
  const HISTORY_FILE = path.join(CONFIG_DIR, 'history.jsonl');
13
20
 
14
- function ensureDir() {
15
- try { fs.mkdirSync(CONFIG_DIR, { recursive: true }); } catch {}
21
+ const YOU_MD_TEMPLATE = `# You - PrimoCode AI
22
+
23
+ ## Sobre mim
24
+ Sou o Kimi Chat, um assistente de IA desenvolvido pela Moonshot AI.
25
+
26
+ ## Capacidades
27
+ - Ajudo na criacao de sistemas complexos
28
+ - Geracao de codigo de alto nivel
29
+ - Automacao de desktop e navegador
30
+ - Controle via CDP (Chrome DevTools Protocol)
31
+
32
+ ## Projetos
33
+ Este arquivo contem informacoes sobre mim e projetos em geral.
34
+ Cada pasta de projeto tem suas memorias em memory.md.
35
+ `;
36
+
37
+ const MEMORY_MD_TEMPLATE = `# Memorias do Projeto
38
+
39
+ ## Descricao
40
+ {nome_do_projeto}
41
+
42
+ ## Tecnologias
43
+ - Tecnologia: {tecnologia}
44
+
45
+ ## Estrutura de Pastas
46
+ - {estrutura}
47
+
48
+ ## Notas
49
+ - Criado em: {data}
50
+
51
+ ## Historico
52
+ - Primeira interacao: {data}
53
+ `;
54
+
55
+ function ensureDir(dir) {
56
+ try { fs.mkdirSync(dir, { recursive: true }); } catch {}
57
+ }
58
+
59
+ function ensureStructure() {
60
+ ensureDir(ROOT_DIR);
61
+ ensureDir(INTERNAL_DIR);
62
+ ensureDir(CONFIG_DIR);
63
+ const youMdPath = path.join(ROOT_DIR, 'you.md');
64
+ if (!fs.existsSync(youMdPath)) {
65
+ fs.writeFileSync(youMdPath, YOU_MD_TEMPLATE, 'utf-8');
66
+ }
67
+ return { rootDir: ROOT_DIR, internalDir: INTERNAL_DIR };
68
+ }
69
+
70
+ function createProjectDir(projectName) {
71
+ ensureStructure();
72
+ const projectDir = path.join(ROOT_DIR, projectName);
73
+ ensureDir(projectDir);
74
+ const memoryPath = path.join(projectDir, 'memory.md');
75
+ if (!fs.existsSync(memoryPath)) {
76
+ const content = MEMORY_MD_TEMPLATE
77
+ .replace(/{nome_do_projeto}/g, projectName)
78
+ .replace(/{tecnologia}/g, 'a definir')
79
+ .replace(/{estrutura}/g, 'a definir')
80
+ .replace(/{data}/g, new Date().toISOString().split('T')[0]);
81
+ fs.writeFileSync(memoryPath, content, 'utf-8');
82
+ }
83
+ return projectDir;
84
+ }
85
+
86
+ function getProjectDir(projectName) {
87
+ if (!projectName) return ROOT_DIR;
88
+ return path.join(ROOT_DIR, projectName);
89
+ }
90
+
91
+ function listProjects() {
92
+ ensureStructure();
93
+ try {
94
+ return fs.readdirSync(ROOT_DIR)
95
+ .filter(name => {
96
+ const fullPath = path.join(ROOT_DIR, name);
97
+ return fs.statSync(fullPath).isDirectory() && name !== 'primocode';
98
+ });
99
+ } catch { return []; }
16
100
  }
17
101
 
18
102
  function loadConfig() {
19
- ensureDir();
103
+ ensureDir(CONFIG_DIR);
104
+ ensureStructure();
20
105
  let file = {};
21
106
  try {
22
107
  if (fs.existsSync(CONFIG_FILE)) file = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'));
23
108
  } catch { file = {}; }
24
-
25
109
  return {
26
110
  server: process.env.PRIMOCODE_SERVER || file.server || 'https://primocode-server.onrender.com',
27
111
  model: process.env.PRIMOCODE_MODEL || file.model || 'main',
28
112
  autoApply: file.autoApply === true,
113
+ currentProject: file.currentProject || null,
114
+ rootDir: ROOT_DIR,
29
115
  _file: file,
30
116
  };
31
117
  }
32
118
 
33
119
  function saveConfig(partial) {
34
- ensureDir();
120
+ ensureDir(CONFIG_DIR);
35
121
  const cur = (() => { try { return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8')); } catch { return {}; } })();
36
122
  const next = { ...cur, ...partial };
37
123
  fs.writeFileSync(CONFIG_FILE, JSON.stringify(next, null, 2), 'utf8');
@@ -39,10 +125,16 @@ function saveConfig(partial) {
39
125
  }
40
126
 
41
127
  function appendHistory(entry) {
42
- ensureDir();
128
+ ensureDir(CONFIG_DIR);
43
129
  try {
44
130
  fs.appendFileSync(HISTORY_FILE, JSON.stringify({ ts: Date.now(), ...entry }) + '\n', 'utf8');
45
131
  } catch {}
46
132
  }
47
133
 
48
- module.exports = { loadConfig, saveConfig, appendHistory, CONFIG_DIR, CONFIG_FILE, HISTORY_FILE };
134
+ module.exports = {
135
+ loadConfig, saveConfig, appendHistory,
136
+ CONFIG_DIR, CONFIG_FILE, HISTORY_FILE,
137
+ ROOT_DIR, INTERNAL_DIR,
138
+ ensureStructure, createProjectDir, getProjectDir, listProjects,
139
+ YOU_MD_TEMPLATE, MEMORY_MD_TEMPLATE,
140
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "primocode",
3
- "version": "7.0.0",
3
+ "version": "7.0.1",
4
4
  "description": "PrimoCode \u2014 agente de engenharia com IA e cursor pr\u00f3prio. Modo primocode cria arquivos, controla o desktop e navegador. Modo chat \u00e9 conversa pura.",
5
5
  "main": "bin/primocode.js",
6
6
  "bin": "./bin/primocode.js",