fidelizare-integrate 0.6.1 → 0.6.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fidelizare-integrate",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "description": "Asistent de integrare Fidelizare pentru softuri de gestiune si case de marcat. Scaneaza codul, gaseste locul potrivit si propune integrarea API-ului, in siguranta.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -109,8 +109,14 @@ async function main() {
109
109
 
110
110
  // No fallback. Clear error + support ticket.
111
111
  rule();
112
- out(' ' + paint('✗ Integrarea nu a putut rula.', C.redBright) + ' ' + paint('(' + r.reason + ')', C.dim) + '\n');
113
- if (r.reason === 'no_key') note('Lipseste cheia. Lipeste cheia ta API Fidelizare cand ti-o cere CLI-ul.', C.amber);
112
+ if (r.reason === 'no_integration') {
113
+ out(' ' + paint(' Nu am gasit un loc sigur de integrare.', C.redBright) + '\n');
114
+ if (r.summary && r.summary !== 'oprit') note(r.summary.split('\n')[0].slice(0, 120), C.dim);
115
+ note('Nimic nu a fost scris. Cheia NU a fost salvata.', C.amber);
116
+ } else {
117
+ out(' ' + paint('✗ Integrarea nu a putut rula.', C.redBright) + ' ' + paint('(' + r.reason + ')', C.dim) + '\n');
118
+ if (r.reason === 'no_key') note('Lipseste cheia. Lipeste cheia ta API Fidelizare cand ti-o cere CLI-ul.', C.amber);
119
+ }
114
120
  supportNote();
115
121
  rl.close();
116
122
  }
@@ -46,8 +46,16 @@ Pasi:
46
46
  run_test pana trece.
47
47
  6. Verifica sintaxa (check_syntax) si apeleaza finish cu un rezumat scurt.
48
48
 
49
+ Vorbeste cu utilizatorul cand ai nevoie (tool ask_user): cand nu gasesti fisierul
50
+ sau ramura de integrare, cand exista mai multe locuri posibile, sau cand ai o
51
+ nelamurire (o decizie da/nu, ce fisier, ce optiune). Inainte de prima editare a unui
52
+ fisier existent, confirma scurt cu ask_user: "Integrez in <fisier> la <ramura>, e
53
+ corect?". NU ghici cai si NU te opri in tacere: daca nu stii, intreaba.
54
+
49
55
  Nu apela finish inainte de a fi inserat apelul helper-ului in fisierul existent de
50
- vanzare cu insert_code. Daca ai folosit doar create_file, NU ai terminat.
56
+ vanzare cu insert_code. Daca ai folosit doar create_file, NU ai terminat. Daca,
57
+ dupa ce ai intrebat, chiar nu exista un loc de integrare, apeleaza finish si explica
58
+ clar ca nu s-a putut integra (nu inventa modificari).
51
59
 
52
60
  Reguli: modificari minime, fara refactor; pastreaza stilul si limbajul proiectului;
53
61
  nu scrie chei in cod; nu inventa cai de fisier.`;
@@ -61,6 +69,7 @@ const TOOLS = [
61
69
  { type: 'function', function: { name: 'web_fetch', description: 'Descarca un document de pe web (https), ex. documentatia API.', parameters: { type: 'object', properties: { url: { type: 'string' } }, required: ['url'] } } },
62
70
  { type: 'function', function: { name: 'run_test', description: 'Ruleaza o comanda de test/compilare in proiect (gated, doar runnere cunoscute).', parameters: { type: 'object', properties: { command: { type: 'string' } }, required: ['command'] } } },
63
71
  { type: 'function', function: { name: 'check_syntax', description: 'Verifica sintaxa unui fisier (doar Node).', parameters: { type: 'object', properties: { path: { type: 'string' } }, required: ['path'] } } },
72
+ { type: 'function', function: { name: 'ask_user', description: 'Intreaba utilizatorul cand nu esti sigur: ce fisier/ramura de integrare, o decizie da/nu, sau o alegere dintr-o lista de optiuni. Foloseste in loc sa ghicesti sau sa te opresti.', parameters: { type: 'object', properties: { question: { type: 'string' }, options: { type: 'array', items: { type: 'string' } } }, required: ['question'] } } },
64
73
  { type: 'function', function: { name: 'finish', description: 'Termina integrarea.', parameters: { type: 'object', properties: { summary: { type: 'string' } }, required: ['summary'] } } },
65
74
  ];
66
75
 
@@ -147,6 +156,23 @@ export async function runAgentLoop({ stack, rootDir, files, askRaw, auto, model,
147
156
  try { execFileSync('node', ['--check', a], { stdio: 'pipe' }); return 'OK sintaxa valida'; }
148
157
  catch (e) { return 'EROARE sintaxa: ' + (e.stderr?.toString() || e.message).slice(0, 300); }
149
158
  },
159
+ ask_user: async ({ question, options }) => {
160
+ const q = String(question || '').trim();
161
+ const opts = Array.isArray(options) ? options.filter(Boolean).map(String) : [];
162
+ out('\n ' + paint('? ', C.amber) + paint(q, C.white) + '\n');
163
+ opts.forEach((o, i) => out(' ' + paint(i + 1 + ')', C.dim) + ' ' + paint(o, C.ink) + '\n'));
164
+ if (auto) {
165
+ const def = opts.length ? opts[0] : 'da';
166
+ out(' ' + paint('› ' + def + ' (auto)', C.green) + '\n');
167
+ return def;
168
+ }
169
+ const a = (await askRaw(opts.length ? ' Alege (numar sau text):' : ' Raspuns (da / nu / text):')).trim();
170
+ if (opts.length && /^\d+$/.test(a)) {
171
+ const n = parseInt(a, 10);
172
+ if (n >= 1 && n <= opts.length) return opts[n - 1];
173
+ }
174
+ return a || (opts.length ? opts[0] : 'nu');
175
+ },
150
176
  finish: ({ summary }) => { finished = summary || 'gata'; return 'gata'; },
151
177
  };
152
178
 
@@ -155,8 +181,9 @@ export async function runAgentLoop({ stack, rootDir, files, askRaw, auto, model,
155
181
  { role: 'user', content: `Stack: ${stack}. Documentatie API: ${guide}. Proiect cu ${files.length} fisiere sursa. Incepe cu web_fetch pe documentatie, apoi orienteaza-te in cod, integreaza si scrie + ruleaza un test cu mock.` },
156
182
  ];
157
183
 
158
- const NAMES = { list_files: 'List', read_file: 'Read', grep: 'Grep', create_file: 'Write', insert_code: 'Edit', web_fetch: 'Fetch', run_test: 'Test', check_syntax: 'Check', finish: 'Done' };
184
+ const NAMES = { list_files: 'List', read_file: 'Read', grep: 'Grep', create_file: 'Write', insert_code: 'Edit', web_fetch: 'Fetch', run_test: 'Test', check_syntax: 'Check', ask_user: 'Ask', finish: 'Done' };
159
185
  const brief = (name, a) => {
186
+ if (name === 'ask_user') return '';
160
187
  if (name === 'grep') return a.pattern ? '"' + a.pattern + '"' : '';
161
188
  if (name === 'web_fetch') return a.url || '';
162
189
  if (name === 'run_test') return a.command ? '`' + a.command + '`' : '';
@@ -199,5 +226,12 @@ export async function runAgentLoop({ stack, rootDir, files, askRaw, auto, model,
199
226
  }
200
227
  }
201
228
 
202
- return { ok: true, changes: [...new Set(changes)], summary: finished || 'oprit', model: usedModel };
229
+ // Honest outcome: a finish (or a stall) with zero applied edits is NOT a
230
+ // success. Report it as no_integration so the CLI shows an error + support
231
+ // link instead of a green "done" + writing the key to .env.
232
+ const applied = [...new Set(changes)];
233
+ if (applied.length === 0) {
234
+ return { ok: false, reason: 'no_integration', summary: finished || 'oprit', model: usedModel };
235
+ }
236
+ return { ok: true, changes: applied, summary: finished || 'gata', model: usedModel };
203
237
  }