tandem-mode 0.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.
Files changed (76) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +191 -0
  3. package/README.sr.md +194 -0
  4. package/dist/agent/clipboard.js +26 -0
  5. package/dist/agent/clipboard.js.map +1 -0
  6. package/dist/agent/loop.js +157 -0
  7. package/dist/agent/loop.js.map +1 -0
  8. package/dist/agent/pricing.js +21 -0
  9. package/dist/agent/pricing.js.map +1 -0
  10. package/dist/agent/session.js +78 -0
  11. package/dist/agent/session.js.map +1 -0
  12. package/dist/agent/tools/edit.js +78 -0
  13. package/dist/agent/tools/edit.js.map +1 -0
  14. package/dist/agent/tools/gitDiff.js +42 -0
  15. package/dist/agent/tools/gitDiff.js.map +1 -0
  16. package/dist/agent/tools/index.js +24 -0
  17. package/dist/agent/tools/index.js.map +1 -0
  18. package/dist/agent/tools/listDir.js +29 -0
  19. package/dist/agent/tools/listDir.js.map +1 -0
  20. package/dist/agent/tools/readFile.js +40 -0
  21. package/dist/agent/tools/readFile.js.map +1 -0
  22. package/dist/agent/tools/search.js +51 -0
  23. package/dist/agent/tools/search.js.map +1 -0
  24. package/dist/agent/tools/shell.js +95 -0
  25. package/dist/agent/tools/shell.js.map +1 -0
  26. package/dist/agent/tools/types.js +11 -0
  27. package/dist/agent/tools/types.js.map +1 -0
  28. package/dist/agent/tools/viewImage.js +34 -0
  29. package/dist/agent/tools/viewImage.js.map +1 -0
  30. package/dist/agent/tools/webSearch.js +27 -0
  31. package/dist/agent/tools/webSearch.js.map +1 -0
  32. package/dist/agent/usage.js +36 -0
  33. package/dist/agent/usage.js.map +1 -0
  34. package/dist/benchmark/runner.js +176 -0
  35. package/dist/benchmark/runner.js.map +1 -0
  36. package/dist/benchmark/tasks/bitwiseBulkPriceWizard.js +50 -0
  37. package/dist/benchmark/tasks/bitwiseBulkPriceWizard.js.map +1 -0
  38. package/dist/benchmark/types.js +2 -0
  39. package/dist/benchmark/types.js.map +1 -0
  40. package/dist/cli.js +442 -0
  41. package/dist/cli.js.map +1 -0
  42. package/dist/config/credentials.js +80 -0
  43. package/dist/config/credentials.js.map +1 -0
  44. package/dist/config/env.js +12 -0
  45. package/dist/config/env.js.map +1 -0
  46. package/dist/config/schema.js +6 -0
  47. package/dist/config/schema.js.map +1 -0
  48. package/dist/config/store.js +35 -0
  49. package/dist/config/store.js.map +1 -0
  50. package/dist/deepseek/client.js +145 -0
  51. package/dist/deepseek/client.js.map +1 -0
  52. package/dist/deepseek/types.js +2 -0
  53. package/dist/deepseek/types.js.map +1 -0
  54. package/dist/deepseek/vision.js +59 -0
  55. package/dist/deepseek/vision.js.map +1 -0
  56. package/dist/deepseek/webSearch.js +43 -0
  57. package/dist/deepseek/webSearch.js.map +1 -0
  58. package/dist/orchestrator/orchestrate.js +63 -0
  59. package/dist/orchestrator/orchestrate.js.map +1 -0
  60. package/dist/orchestrator/planner.js +48 -0
  61. package/dist/orchestrator/planner.js.map +1 -0
  62. package/dist/orchestrator/repoMap.js +52 -0
  63. package/dist/orchestrator/repoMap.js.map +1 -0
  64. package/dist/orchestrator/reviewer.js +53 -0
  65. package/dist/orchestrator/reviewer.js.map +1 -0
  66. package/dist/orchestrator/types.js +18 -0
  67. package/dist/orchestrator/types.js.map +1 -0
  68. package/dist/repl/commands.js +139 -0
  69. package/dist/repl/commands.js.map +1 -0
  70. package/dist/repl/state.js +2 -0
  71. package/dist/repl/state.js.map +1 -0
  72. package/dist/repl/system-prompt.js +5 -0
  73. package/dist/repl/system-prompt.js.map +1 -0
  74. package/dist/repl/wizard.js +34 -0
  75. package/dist/repl/wizard.js.map +1 -0
  76. package/package.json +49 -0
package/dist/cli.js ADDED
@@ -0,0 +1,442 @@
1
+ #!/usr/bin/env node
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useState } from "react";
4
+ import { render, Text, Box, useApp } from "ink";
5
+ import readline from "node:readline";
6
+ import path from "node:path";
7
+ import { mkdir } from "node:fs/promises";
8
+ import { resolveApiKey, resolveBaseUrl } from "./config/env.js";
9
+ import { loadConfig } from "./config/store.js";
10
+ import { DEFAULT_CONFIG } from "./config/schema.js";
11
+ import { runFirstRunWizard } from "./repl/wizard.js";
12
+ import { handleCommand } from "./repl/commands.js";
13
+ import { SYSTEM_PROMPT } from "./repl/system-prompt.js";
14
+ import { runAgentLoop } from "./agent/loop.js";
15
+ import { UsageAccumulator } from "./agent/usage.js";
16
+ import { isPeakHour } from "./agent/pricing.js";
17
+ import { saveClipboardImage } from "./agent/clipboard.js";
18
+ import { runOrchestration } from "./orchestrator/orchestrate.js";
19
+ import { appendSessionMessage, createSession, findLatestSession, loadSessionMessages } from "./agent/session.js";
20
+ function TurnView({ state, turn, askApproval, onDone, }) {
21
+ const { exit } = useApp();
22
+ const [reasoning, setReasoning] = useState("");
23
+ const [content, setContent] = useState("");
24
+ const [toolLog, setToolLog] = useState([]);
25
+ const [pending, setPending] = useState(null);
26
+ const [usageLine, setUsageLine] = useState(null);
27
+ const [error, setError] = useState(null);
28
+ const [notice, setNotice] = useState(null);
29
+ useEffect(() => {
30
+ async function run() {
31
+ const approve = async (toolName, args) => {
32
+ if (state.autoApprove) {
33
+ console.error(`[--yes] auto-odobreno: ${toolName}(${JSON.stringify(args)})`);
34
+ return true;
35
+ }
36
+ if (state.alwaysApprovedTools.has(toolName))
37
+ return true;
38
+ setPending({ toolName, args });
39
+ const response = await askApproval(toolName, args);
40
+ setPending(null);
41
+ if (response.always)
42
+ state.alwaysApprovedTools.add(toolName);
43
+ return response.approved;
44
+ };
45
+ for await (const event of runAgentLoop(turn.messages, {
46
+ env: state.env,
47
+ model: turn.model,
48
+ cwd: state.cwd,
49
+ session: state.session,
50
+ usage: state.usage,
51
+ approve,
52
+ ...(turn.thinking !== undefined ? { thinking: turn.thinking } : {}),
53
+ ...(turn.budgetUsd !== undefined ? { budgetUsd: turn.budgetUsd } : {}),
54
+ ...(turn.signal !== undefined ? { signal: turn.signal } : {}),
55
+ })) {
56
+ handleEvent(event);
57
+ }
58
+ function handleEvent(event) {
59
+ switch (event.type) {
60
+ case "reasoning_delta":
61
+ setReasoning((prev) => prev + event.delta);
62
+ break;
63
+ case "content_delta":
64
+ setContent((prev) => prev + event.delta);
65
+ break;
66
+ case "tool_call_start":
67
+ setToolLog((prev) => [...prev, { id: event.id, name: event.name, args: event.args, status: "running" }]);
68
+ break;
69
+ case "tool_call_result":
70
+ setToolLog((prev) => prev.map((t) => t.id === event.id ? { ...t, status: "done", output: event.result.output, isError: event.result.isError } : t));
71
+ break;
72
+ case "tool_call_denied":
73
+ setToolLog((prev) => prev.map((t) => (t.id === event.id ? { ...t, status: "denied" } : t)));
74
+ break;
75
+ case "usage": {
76
+ const total = state.usage.totals();
77
+ setUsageLine(`tokens: ${total.promptTokens} in (${total.promptCacheHitTokens} cached) / ${total.completionTokens} out · ~$${state.usage.estimatedCostUsd().toFixed(4)} · ${state.usage.callCount} poziva`);
78
+ break;
79
+ }
80
+ case "final":
81
+ setContent(event.content);
82
+ break;
83
+ case "max_iterations_reached":
84
+ setNotice("Dostignut je maksimalan broj iteracija bez finalnog odgovora.");
85
+ break;
86
+ case "budget_exceeded":
87
+ setNotice(`Budžet od $${event.budgetUsd.toFixed(2)} je dostignut (potrošeno ~$${event.spentUsd.toFixed(4)}). Petlja je zaustavljena pre sledećeg poziva — sesija je sačuvana, poveci budžet sa /budget i nastavi.`);
88
+ break;
89
+ case "interrupted":
90
+ setNotice("⏹ Prekinuto (ESC). Sesija je sačuvana do ove tačke.");
91
+ break;
92
+ }
93
+ }
94
+ }
95
+ run()
96
+ .catch((err) => {
97
+ setError(err instanceof Error ? err.message : String(err));
98
+ })
99
+ .finally(() => {
100
+ exit();
101
+ onDone();
102
+ });
103
+ // eslint-disable-next-line react-hooks/exhaustive-deps
104
+ }, []);
105
+ return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [reasoning.length > 0 && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { dimColor: true, children: "\u273B Razmi\u0161ljam\u2026" }), _jsx(Text, { dimColor: true, children: reasoning })] })), toolLog.map((t) => {
106
+ const lines = t.output?.split("\n") ?? [];
107
+ const preview = lines.slice(0, 3).join("\n");
108
+ const more = lines.length > 3;
109
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: t.status === "denied" ? "yellow" : t.isError ? "red" : "cyan", children: ["\u23FA ", t.name, "(", JSON.stringify(t.args), ")", t.status === "running" ? "…" : t.status === "denied" ? " (odbijeno)" : ""] }), preview && (_jsxs(Text, { dimColor: true, children: [" ⎿ ", preview.slice(0, 400), more || preview.length > 400 ? ` … (${lines.length} linija)` : ""] }))] }, t.id));
110
+ }), pending && (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [_jsxs(Text, { color: "yellow", bold: true, children: ["Destruktivna akcija: ", pending.toolName, "(", JSON.stringify(pending.args), ")"] }), _jsx(Text, { dimColor: true, children: "y = dozvoli, n = odbij, a = uvek dozvoli ovaj alat ovoj sesiji (odgovor ispod)" })] })), content.length > 0 && _jsx(Text, { children: content }), usageLine && _jsx(Text, { color: "gray", children: usageLine }), notice && _jsx(Text, { color: "yellow", children: notice }), error && _jsxs(Text, { color: "red", children: ["Gre\u0161ka: ", error] })] }));
111
+ }
112
+ function truncatePath(p, max = 50) {
113
+ return p.length > max ? `…${p.slice(-(max - 1))}` : p;
114
+ }
115
+ function Banner({ state }) {
116
+ const { exit } = useApp();
117
+ useEffect(() => {
118
+ exit();
119
+ // eslint-disable-next-line react-hooks/exhaustive-deps
120
+ }, []);
121
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: "\u273B Tandem Mode" }), _jsx(Text, { dimColor: true, children: truncatePath(state.cwd) })] }));
122
+ }
123
+ async function showBanner(state) {
124
+ await render(_jsx(Banner, { state: state })).waitUntilExit();
125
+ }
126
+ async function runTurnConfig(state, turn, askApproval) {
127
+ await new Promise((resolve) => {
128
+ render(_jsx(TurnView, { state: state, turn: turn, askApproval: askApproval, onDone: resolve }));
129
+ });
130
+ }
131
+ async function runTurn(state, userText, askApproval, signal) {
132
+ const userMsg = { role: "user", content: userText };
133
+ state.messages.push(userMsg);
134
+ await appendSessionMessage(state.session, userMsg);
135
+ const thinking = state.thinkingEnabled ? { reasoningEffort: state.reasoningEffort } : undefined;
136
+ const turn = { messages: state.messages, model: state.model };
137
+ if (thinking !== undefined)
138
+ turn.thinking = thinking;
139
+ if (state.budgetUsd !== undefined)
140
+ turn.budgetUsd = state.budgetUsd;
141
+ if (signal !== undefined)
142
+ turn.signal = signal;
143
+ await runTurnConfig(state, turn, askApproval);
144
+ }
145
+ function isAbortError(err) {
146
+ return err instanceof Error && err.name === "AbortError";
147
+ }
148
+ async function runPlanTask(state, task, askApproval, signal) {
149
+ try {
150
+ await runOrchestration(task, {
151
+ cwd: state.cwd,
152
+ env: state.env,
153
+ maxReviewLoops: state.maxReviewLoops,
154
+ usage: state.usage,
155
+ ...(signal !== undefined ? { signal } : {}),
156
+ runWorkerTurn: (turn) => runTurnConfig(state, turn, askApproval),
157
+ });
158
+ }
159
+ catch (err) {
160
+ if (isAbortError(err)) {
161
+ console.log("⏹ Orkestracija prekinuta (ESC).");
162
+ }
163
+ else {
164
+ console.error(`Greška u orkestraciji: ${err instanceof Error ? err.message : String(err)}`);
165
+ }
166
+ }
167
+ }
168
+ function parseApprovalAnswer(raw) {
169
+ const lower = raw.trim().toLowerCase();
170
+ if (lower === "a" || lower === "always")
171
+ return { approved: true, always: true };
172
+ return { approved: lower === "y", always: false };
173
+ }
174
+ /** Za single-shot poteze: sopstveni for-await čitač linija samo za y/n/a odobrenja. */
175
+ function createLineApprover() {
176
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
177
+ const resolveRef = { current: null };
178
+ const consumeLines = async () => {
179
+ for await (const rawLine of rl) {
180
+ if (resolveRef.current) {
181
+ resolveRef.current(parseApprovalAnswer(rawLine));
182
+ resolveRef.current = null;
183
+ }
184
+ }
185
+ };
186
+ void consumeLines();
187
+ const approve = (toolName, args) => {
188
+ console.log(`\nDozvoli izvršavanje ${toolName}(${JSON.stringify(args)})? (y/n/a — a = uvek dozvoli ovaj alat)`);
189
+ return new Promise((resolve) => {
190
+ resolveRef.current = resolve;
191
+ });
192
+ };
193
+ return { approve, close: () => rl.close() };
194
+ }
195
+ /**
196
+ * `.question()` je nepouzdan na piped/non-TTY stdin-u posle prvog poziva
197
+ * (poznata Node quirka — drugi poziv nikad ne razrešava). Zato se čitanje
198
+ * linija radi isključivo preko `for await...of rl`, koje pouzdano isporučuje
199
+ * svaku liniju, uz ručni state-machine za odobrenje umesto ugnježdenog
200
+ * `.question()`.
201
+ */
202
+ async function runRepl(state) {
203
+ await showBanner(state);
204
+ console.log("/help za komande, /exit za izlaz.\n");
205
+ if (isPeakHour(new Date())) {
206
+ console.log("⚠ Trenutno je peak sat (01–04h ili 06–10h UTC) — cene su duplo veće nego off-peak.\n");
207
+ }
208
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout, prompt: "> " });
209
+ let closed = false;
210
+ rl.on("close", () => {
211
+ closed = true;
212
+ });
213
+ const showPrompt = () => {
214
+ if (!closed)
215
+ rl.prompt();
216
+ };
217
+ const approvalRef = { current: null };
218
+ let turnActive = false;
219
+ let lastTurn = Promise.resolve();
220
+ const askApproval = (toolName, args) => {
221
+ console.log(`\nDozvoli izvršavanje ${toolName}(${JSON.stringify(args)})? (y/n/a — a = uvek dozvoli ovaj alat)`);
222
+ return new Promise((resolve) => {
223
+ approvalRef.current = resolve;
224
+ });
225
+ };
226
+ // ESC prekida trenutni potez. Radi samo na pravom TTY-ju — piped/scriptovani
227
+ // unos ne generiše keypress evente, pa je interrupt tiho no-op tamo.
228
+ const abortRef = { current: null };
229
+ readline.emitKeypressEvents(process.stdin);
230
+ process.stdin.on("keypress", (_str, key) => {
231
+ if (key?.name === "escape" && abortRef.current) {
232
+ abortRef.current.abort();
233
+ }
234
+ });
235
+ showPrompt();
236
+ for await (const rawLine of rl) {
237
+ const line = rawLine.trim();
238
+ if (approvalRef.current) {
239
+ approvalRef.current(parseApprovalAnswer(line));
240
+ approvalRef.current = null;
241
+ continue;
242
+ }
243
+ if (!line) {
244
+ showPrompt();
245
+ continue;
246
+ }
247
+ if (turnActive) {
248
+ console.log("Sačekaj da se trenutni potez završi.");
249
+ continue;
250
+ }
251
+ const beginTurn = (run) => {
252
+ turnActive = true;
253
+ const controller = new AbortController();
254
+ abortRef.current = controller;
255
+ lastTurn = run(controller.signal).finally(() => {
256
+ abortRef.current = null;
257
+ turnActive = false;
258
+ showPrompt();
259
+ });
260
+ };
261
+ if (line.startsWith("/plan ")) {
262
+ const task = line.slice("/plan ".length).trim();
263
+ if (!task) {
264
+ console.log("Upotreba: /plan <opis zadatka>");
265
+ showPrompt();
266
+ continue;
267
+ }
268
+ beginTurn((signal) => runPlanTask(state, task, askApproval, signal));
269
+ continue;
270
+ }
271
+ if (line === "/paste" || line.startsWith("/paste ")) {
272
+ const extra = line.slice("/paste".length).trim();
273
+ try {
274
+ const destDir = path.join(state.cwd, ".tandem", "tmp");
275
+ await mkdir(destDir, { recursive: true });
276
+ const destPath = path.join(destDir, `paste-${Date.now()}.png`);
277
+ const ok = await saveClipboardImage(destPath);
278
+ if (!ok) {
279
+ console.log("Nema slike u clipboard-u.");
280
+ showPrompt();
281
+ continue;
282
+ }
283
+ const relPath = path.relative(state.cwd, destPath);
284
+ const text = `[slika zalepljena iz clipboard-a: ${relPath}] ${extra || "Pogledaj sliku i opiši šta vidiš."}`;
285
+ beginTurn((signal) => runTurn(state, text, askApproval, signal));
286
+ }
287
+ catch (err) {
288
+ console.log(`Greška: ${err instanceof Error ? err.message : String(err)}`);
289
+ showPrompt();
290
+ }
291
+ continue;
292
+ }
293
+ if (line.startsWith("/")) {
294
+ const outcome = await handleCommand(line, state);
295
+ if (outcome === "exit")
296
+ break;
297
+ showPrompt();
298
+ continue;
299
+ }
300
+ beginTurn((signal) => runTurn(state, line, askApproval, signal));
301
+ }
302
+ await lastTurn;
303
+ if (!closed)
304
+ rl.close();
305
+ }
306
+ function parseArgv(argv) {
307
+ const rest = [];
308
+ let resume = false;
309
+ let autoApprove = false;
310
+ let plan = false;
311
+ let model;
312
+ let effort;
313
+ let budgetUsd;
314
+ let maxReviewLoops;
315
+ for (let i = 0; i < argv.length; i++) {
316
+ const arg = argv[i];
317
+ if (arg === "--resume" || arg === "-r") {
318
+ resume = true;
319
+ }
320
+ else if (arg === "--yes" || arg === "-y") {
321
+ autoApprove = true;
322
+ }
323
+ else if (arg === "--plan") {
324
+ plan = true;
325
+ }
326
+ else if (arg === "--model") {
327
+ const value = argv[++i];
328
+ if (value === "deepseek-v4-pro" || value === "deepseek-v4-flash")
329
+ model = value;
330
+ }
331
+ else if (arg === "--effort") {
332
+ const value = argv[++i];
333
+ if (value === "low" || value === "high" || value === "max")
334
+ effort = value;
335
+ }
336
+ else if (arg === "--budget") {
337
+ const value = Number(argv[++i]);
338
+ if (Number.isFinite(value) && value > 0)
339
+ budgetUsd = value;
340
+ }
341
+ else if (arg === "--max-review-loops") {
342
+ const value = Number(argv[++i]);
343
+ if (Number.isFinite(value) && value > 0)
344
+ maxReviewLoops = value;
345
+ }
346
+ else if (arg !== undefined) {
347
+ rest.push(arg);
348
+ }
349
+ }
350
+ const parsed = { prompt: rest.join(" ").trim(), resume, autoApprove, plan };
351
+ if (model !== undefined)
352
+ parsed.model = model;
353
+ if (effort !== undefined)
354
+ parsed.effort = effort;
355
+ if (budgetUsd !== undefined)
356
+ parsed.budgetUsd = budgetUsd;
357
+ if (maxReviewLoops !== undefined)
358
+ parsed.maxReviewLoops = maxReviewLoops;
359
+ return parsed;
360
+ }
361
+ async function main() {
362
+ const cwd = process.cwd();
363
+ const parsed = parseArgv(process.argv.slice(2));
364
+ const config = await loadConfig(cwd);
365
+ let apiKey = await resolveApiKey();
366
+ if (!apiKey) {
367
+ if (!process.stdin.isTTY) {
368
+ console.error("Nema DeepSeek API ključa. Postavi DEEPSEEK_API_KEY env promenljivu ili pokreni tandem interaktivno da odradiš first-run wizard.");
369
+ process.exitCode = 1;
370
+ return;
371
+ }
372
+ const wizardConfig = await runFirstRunWizard();
373
+ Object.assign(config, wizardConfig);
374
+ apiKey = await resolveApiKey();
375
+ if (!apiKey) {
376
+ console.error("Ključ nije sačuvan ispravno — pokušaj ponovo.");
377
+ process.exitCode = 1;
378
+ return;
379
+ }
380
+ }
381
+ const env = { apiKey, baseUrl: resolveBaseUrl(config) };
382
+ let session;
383
+ let messages;
384
+ if (parsed.resume) {
385
+ const existing = await findLatestSession(cwd);
386
+ if (!existing) {
387
+ console.error("Nema prethodne sesije za nastavak u ovom direktorijumu.");
388
+ process.exitCode = 1;
389
+ return;
390
+ }
391
+ session = existing;
392
+ messages = await loadSessionMessages(existing.filePath);
393
+ }
394
+ else {
395
+ session = await createSession(cwd);
396
+ const systemMsg = { role: "system", content: SYSTEM_PROMPT };
397
+ messages = [systemMsg];
398
+ await appendSessionMessage(session, systemMsg);
399
+ }
400
+ const state = {
401
+ env,
402
+ cwd,
403
+ model: parsed.model ?? config.defaultModel ?? DEFAULT_CONFIG.defaultModel,
404
+ thinkingEnabled: true,
405
+ reasoningEffort: parsed.effort ?? config.defaultReasoningEffort ?? DEFAULT_CONFIG.defaultReasoningEffort,
406
+ maxReviewLoops: parsed.maxReviewLoops ?? config.maxReviewLoops ?? DEFAULT_CONFIG.maxReviewLoops,
407
+ autoApprove: parsed.autoApprove,
408
+ alwaysApprovedTools: new Set(),
409
+ session,
410
+ messages,
411
+ usage: new UsageAccumulator(),
412
+ };
413
+ const budgetUsd = parsed.budgetUsd ?? config.budgetUsd;
414
+ if (budgetUsd !== undefined)
415
+ state.budgetUsd = budgetUsd;
416
+ if (parsed.prompt) {
417
+ const approver = createLineApprover();
418
+ const controller = new AbortController();
419
+ if (process.stdin.isTTY) {
420
+ readline.emitKeypressEvents(process.stdin);
421
+ process.stdin.on("keypress", (_str, key) => {
422
+ if (key?.name === "escape")
423
+ controller.abort();
424
+ });
425
+ }
426
+ if (parsed.plan) {
427
+ await runPlanTask(state, parsed.prompt, approver.approve, controller.signal);
428
+ }
429
+ else {
430
+ await runTurn(state, parsed.prompt, approver.approve, controller.signal);
431
+ }
432
+ approver.close();
433
+ }
434
+ else {
435
+ await runRepl(state);
436
+ }
437
+ }
438
+ main().catch((err) => {
439
+ console.error(err instanceof Error ? err.message : String(err));
440
+ process.exitCode = 1;
441
+ });
442
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ import { spawn } from "node:child_process";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ const CRED_PATH = path.join(os.homedir(), "AppData", "Local", "TandemMode", "credentials.dat");
5
+ // Nije tajna — samo dodatni ulaz pomešan sa DPAPI ključem vezanim za OS nalog,
6
+ // koji je stvarna zaštita.
7
+ const ENTROPY = "tandem-mode-v1";
8
+ /**
9
+ * DPAPI-šifrovan fajl umesto punog Windows Credential Manager-a — isti
10
+ * mehanizam (samo ovaj OS nalog može dešifrovati), ali direktan .NET poziv
11
+ * bez multi-platform auto-detekcije. `cross-keychain` je probana prva
12
+ * (M2) i odbačena: 15-18s po pozivu na ovoj mašini čak i sa native
13
+ * bindingom, jer njena detekcija backend-a proba sve platforme redom.
14
+ * Linux/macOS ide u good-first-issues, isto obrazloženje kao clipboard.ts.
15
+ *
16
+ * Ključ se ISKLJUČIVO prosleđuje kroz stdin, nikad kroz argumente komande —
17
+ * argumenti su vidljivi u listi procesa (Task Manager i sl.) dok proces traje.
18
+ */
19
+ function assertWindows() {
20
+ if (process.platform !== "win32") {
21
+ throw new Error("Čuvanje API ključa je trenutno podržano samo na Windows-u.");
22
+ }
23
+ }
24
+ function runPs(script, stdin) {
25
+ return new Promise((resolve, reject) => {
26
+ const child = spawn("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", script]);
27
+ let stdout = "";
28
+ let stderr = "";
29
+ child.stdout.on("data", (d) => (stdout += d.toString("utf8")));
30
+ child.stderr.on("data", (d) => (stderr += d.toString("utf8")));
31
+ child.on("error", reject);
32
+ child.on("close", (code) => {
33
+ if (code === 0)
34
+ resolve(stdout.trim());
35
+ else
36
+ reject(new Error(`powershell exited with code ${code}: ${stderr.trim()}`));
37
+ });
38
+ if (stdin !== undefined)
39
+ child.stdin.write(stdin, "utf8");
40
+ child.stdin.end();
41
+ });
42
+ }
43
+ export async function getStoredApiKey() {
44
+ assertWindows();
45
+ const script = `
46
+ Add-Type -AssemblyName System.Security
47
+ $path = '${CRED_PATH.replace(/'/g, "''")}'
48
+ if (-not (Test-Path $path)) { Write-Output '__NULL__'; exit }
49
+ try {
50
+ $protected = [System.IO.File]::ReadAllBytes($path)
51
+ $entropy = [System.Text.Encoding]::UTF8.GetBytes('${ENTROPY}')
52
+ $bytes = [System.Security.Cryptography.ProtectedData]::Unprotect($protected, $entropy, [System.Security.Cryptography.DataProtectionScope]::CurrentUser)
53
+ [System.Text.Encoding]::UTF8.GetString($bytes)
54
+ } catch {
55
+ Write-Output '__NULL__'
56
+ }`;
57
+ const result = await runPs(script);
58
+ return result === "__NULL__" || result === "" ? null : result;
59
+ }
60
+ export async function setStoredApiKey(key) {
61
+ assertWindows();
62
+ const dir = path.dirname(CRED_PATH);
63
+ const script = `
64
+ Add-Type -AssemblyName System.Security
65
+ New-Item -ItemType Directory -Force -Path '${dir.replace(/'/g, "''")}' | Out-Null
66
+ $key = [Console]::In.ReadToEnd()
67
+ $bytes = [System.Text.Encoding]::UTF8.GetBytes($key)
68
+ $entropy = [System.Text.Encoding]::UTF8.GetBytes('${ENTROPY}')
69
+ $protected = [System.Security.Cryptography.ProtectedData]::Protect($bytes, $entropy, [System.Security.Cryptography.DataProtectionScope]::CurrentUser)
70
+ [System.IO.File]::WriteAllBytes('${CRED_PATH.replace(/'/g, "''")}', $protected)`;
71
+ await runPs(script, key);
72
+ }
73
+ export async function deleteStoredApiKey() {
74
+ assertWindows();
75
+ const script = `
76
+ $path = '${CRED_PATH.replace(/'/g, "''")}'
77
+ if (Test-Path $path) { Remove-Item $path -Force }`;
78
+ await runPs(script);
79
+ }
80
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/config/credentials.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { getStoredApiKey } from "./credentials.js";
2
+ /** DEEPSEEK_API_KEY (env) ima prednost nad OS credential store-om — za CI/automatizaciju. */
3
+ export async function resolveApiKey() {
4
+ const envKey = process.env["DEEPSEEK_API_KEY"];
5
+ if (envKey)
6
+ return envKey;
7
+ return getStoredApiKey();
8
+ }
9
+ export function resolveBaseUrl(config) {
10
+ return process.env["DEEPSEEK_BASE_URL"] ?? config.baseUrl ?? "https://api.deepseek.com";
11
+ }
12
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/config/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAQnD,6FAA6F;AAC7F,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAC/C,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,OAAO,eAAe,EAAE,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAoB;IACjD,OAAO,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,MAAM,CAAC,OAAO,IAAI,0BAA0B,CAAC;AAC1F,CAAC"}
@@ -0,0 +1,6 @@
1
+ export const DEFAULT_CONFIG = {
2
+ defaultModel: "deepseek-v4-pro",
3
+ defaultReasoningEffort: "high",
4
+ maxReviewLoops: 3,
5
+ };
6
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAQA,MAAM,CAAC,MAAM,cAAc,GAA+F;IACxH,YAAY,EAAE,iBAAiB;IAC/B,sBAAsB,EAAE,MAAM;IAC9B,cAAc,EAAE,CAAC;CAClB,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ function globalConfigPath() {
5
+ return path.join(os.homedir(), ".tandem", "config.json");
6
+ }
7
+ function projectConfigPath(cwd) {
8
+ return path.join(cwd, ".tandem", "config.json");
9
+ }
10
+ async function readConfigFile(filePath) {
11
+ try {
12
+ const raw = await readFile(filePath, "utf8");
13
+ return JSON.parse(raw);
14
+ }
15
+ catch (err) {
16
+ if (err.code === "ENOENT")
17
+ return {};
18
+ throw err;
19
+ }
20
+ }
21
+ /** Global < project. Session-level overrides (slash komande) žive u runtime stanju, ne ovde. */
22
+ export async function loadConfig(cwd) {
23
+ const [global, project] = await Promise.all([
24
+ readConfigFile(globalConfigPath()),
25
+ readConfigFile(projectConfigPath(cwd)),
26
+ ]);
27
+ return { ...global, ...project };
28
+ }
29
+ export async function saveGlobalConfig(partial) {
30
+ const filePath = globalConfigPath();
31
+ const existing = await readConfigFile(filePath);
32
+ await mkdir(path.dirname(filePath), { recursive: true });
33
+ await writeFile(filePath, JSON.stringify({ ...existing, ...partial }, null, 2) + "\n", "utf8");
34
+ }
35
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/config/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,SAAS,gBAAgB;IACvB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAW;IACpC,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;AAClD,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,QAAgB;IAC5C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAiB,CAAC;IACzC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QAChE,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,gGAAgG;AAChG,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW;IAC1C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC1C,cAAc,CAAC,gBAAgB,EAAE,CAAC;QAClC,cAAc,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;KACvC,CAAC,CAAC;IACH,OAAO,EAAE,GAAG,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC;AACnC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAAqB;IAC1D,MAAM,QAAQ,GAAG,gBAAgB,EAAE,CAAC;IACpC,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,MAAM,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,QAAQ,EAAE,GAAG,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;AACjG,CAAC"}