draftify-cli 1.0.78 → 1.0.80
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/dist/commands/refactor.js +1 -3
- package/dist/repl.js +31 -77
- package/dist/utils/api.js +24 -2
- package/dist/utils/config.js +0 -9
- package/dist/utils/ui.js +2 -2
- package/package.json +1 -1
|
@@ -47,9 +47,7 @@ async function refactorCommand(file, options) {
|
|
|
47
47
|
}
|
|
48
48
|
const spinner = (0, ui_1.createSpinner)("Analyzing and refactoring...").start();
|
|
49
49
|
try {
|
|
50
|
-
const result = await (0, api_1.refactorCodeApi)(path_1.default.basename(file), code, instruction, [], (0, config_1.getModel)(), []
|
|
51
|
-
"Medium" // default thinking level
|
|
52
|
-
);
|
|
50
|
+
const result = await (0, api_1.refactorCodeApi)(path_1.default.basename(file), code, instruction, [], (0, config_1.getModel)(), []);
|
|
53
51
|
spinner.stop();
|
|
54
52
|
ui_1.ui.success("Refactoring complete");
|
|
55
53
|
ui_1.ui.divider();
|
package/dist/repl.js
CHANGED
|
@@ -46,51 +46,13 @@ function getContextForPrompt(dir, prompt) {
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
walk(dir, 0);
|
|
49
|
-
const lowercasePrompt = prompt.toLowerCase();
|
|
50
|
-
// Check if any specific workspace files are mentioned in the prompt
|
|
51
|
-
const matchedFiles = allPaths.filter(filePath => {
|
|
52
|
-
const baseName = path_1.default.basename(filePath).toLowerCase();
|
|
53
|
-
const nameWithoutExt = path_1.default.parse(baseName).name.toLowerCase();
|
|
54
|
-
const ext = path_1.default.extname(filePath).toLowerCase();
|
|
55
|
-
const validExts = [
|
|
56
|
-
'.ts', '.tsx', '.js', '.jsx', '.css', '.json', '.html',
|
|
57
|
-
'.py', '.md', '.txt', '.c', '.cpp', '.h', '.java', '.go', '.rs', '.php', '.rb', '.sh'
|
|
58
|
-
];
|
|
59
|
-
if (!validExts.includes(ext))
|
|
60
|
-
return false;
|
|
61
|
-
// Check if the prompt contains the full filename (e.g. 'snake.py') or name without ext (e.g. 'snake')
|
|
62
|
-
return lowercasePrompt.includes(baseName) || (nameWithoutExt.length > 2 && lowercasePrompt.includes(nameWithoutExt));
|
|
63
|
-
});
|
|
64
|
-
let filesToRead = [];
|
|
65
|
-
if (matchedFiles.length > 0) {
|
|
66
|
-
// If specific files are mentioned, only load those files
|
|
67
|
-
filesToRead = matchedFiles.slice(0, 5);
|
|
68
|
-
}
|
|
69
|
-
// Load the contents of selected files
|
|
70
|
-
for (const filePath of filesToRead) {
|
|
71
|
-
const fullPath = path_1.default.resolve(dir, filePath);
|
|
72
|
-
try {
|
|
73
|
-
ui_1.ui.fileRead(filePath);
|
|
74
|
-
const content = fs_1.default.readFileSync(fullPath, 'utf-8');
|
|
75
|
-
if (content.length < 50000) { // Limit to 50KB per file
|
|
76
|
-
codeFiles.push({ path: filePath, content });
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
catch {
|
|
80
|
-
// Ignore unreadable files
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
49
|
let structureStr = allPaths.join('\n');
|
|
84
50
|
if (allPaths.length >= maxPaths) {
|
|
85
51
|
structureStr += '\n... (and more files omitted)';
|
|
86
52
|
}
|
|
87
53
|
let combinedCode = `--- PROJECT DIRECTORY STRUCTURE ---\n${structureStr}\n\n`;
|
|
88
|
-
if (codeFiles.length > 0) {
|
|
89
|
-
combinedCode += `--- ATTACHED FILE CONTENTS ---\n`;
|
|
90
|
-
combinedCode += codeFiles.map(f => `--- File: ${f.path} ---\n${f.content}\n`).join('\n');
|
|
91
|
-
}
|
|
92
54
|
return {
|
|
93
|
-
fileName:
|
|
55
|
+
fileName: "workspace_context",
|
|
94
56
|
code: combinedCode
|
|
95
57
|
};
|
|
96
58
|
}
|
|
@@ -313,7 +275,7 @@ async function startRepl(initialUsername) {
|
|
|
313
275
|
}
|
|
314
276
|
const renderWelcome = () => {
|
|
315
277
|
console.clear();
|
|
316
|
-
ui_1.ui.welcomeScreen(repoName, currentModel, username, plan
|
|
278
|
+
ui_1.ui.welcomeScreen(repoName, currentModel, username, plan);
|
|
317
279
|
};
|
|
318
280
|
renderWelcome();
|
|
319
281
|
let conversationHistory = [];
|
|
@@ -329,7 +291,7 @@ async function startRepl(initialUsername) {
|
|
|
329
291
|
ui_1.ui.info(`Answers automatically sent to the AI.`);
|
|
330
292
|
}
|
|
331
293
|
else {
|
|
332
|
-
const commandsList = ['/new-chat', '/chats', '/skills', '/model', '/
|
|
294
|
+
const commandsList = ['/new-chat', '/chats', '/skills', '/model', '/usage', '/login', '/logout', '/help', '/exit', '/quit'];
|
|
333
295
|
ui_1.ui.divider();
|
|
334
296
|
let answer = await getInteractiveInput((0, kleur_1.dim)("> "), commandsList);
|
|
335
297
|
ui_1.ui.divider();
|
|
@@ -415,7 +377,6 @@ async function startRepl(initialUsername) {
|
|
|
415
377
|
console.log(` ${(0, kleur_1.cyan)("/chats")} - List and load previous chats`);
|
|
416
378
|
console.log(` ${(0, kleur_1.cyan)("/skills")} - Manage and configure skills`);
|
|
417
379
|
console.log(` ${(0, kleur_1.cyan)("/model")} - Switch model (e.g., /model Opus 4.8-level)`);
|
|
418
|
-
console.log(` ${(0, kleur_1.cyan)("/thinking-level")} - Adjust the AI's thinking process depth`);
|
|
419
380
|
console.log(` ${(0, kleur_1.cyan)("/login")} - Log in to your Draftify account`);
|
|
420
381
|
console.log(` ${(0, kleur_1.cyan)("/logout")} - Log out of your account`);
|
|
421
382
|
console.log(` ${(0, kleur_1.cyan)("/usage")} - Show your token usage and quota`);
|
|
@@ -429,8 +390,30 @@ async function startRepl(initialUsername) {
|
|
|
429
390
|
}
|
|
430
391
|
else if (cmd === "usage") {
|
|
431
392
|
ui_1.ui.header("Usage & Quota");
|
|
432
|
-
|
|
433
|
-
|
|
393
|
+
const spinner = (0, ui_1.createSpinner)("Fetching usage...");
|
|
394
|
+
spinner.start();
|
|
395
|
+
try {
|
|
396
|
+
const usage = await (0, api_1.getUserUsage)();
|
|
397
|
+
spinner.stop();
|
|
398
|
+
if (usage) {
|
|
399
|
+
const quotaStr = usage.r1Limit === -1 ? "Infinite" : usage.r1Limit.toLocaleString();
|
|
400
|
+
console.log(` Plan: ${(0, kleur_1.cyan)(usage.plan)}`);
|
|
401
|
+
console.log(` Opus 4.8-level Quota: ${(0, kleur_1.cyan)(quotaStr)} tokens`);
|
|
402
|
+
console.log(` Opus 4.8-level Used: ${(0, kleur_1.cyan)(usage.r1TokensUsed.toLocaleString())} tokens\n`);
|
|
403
|
+
}
|
|
404
|
+
else {
|
|
405
|
+
ui_1.ui.error("Could not fetch usage. Are you logged in?");
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
catch (e) {
|
|
409
|
+
spinner.stop();
|
|
410
|
+
if (e.message === "UNAUTHORIZED") {
|
|
411
|
+
ui_1.ui.error("You are not logged in. Please run '/login' first.");
|
|
412
|
+
}
|
|
413
|
+
else {
|
|
414
|
+
ui_1.ui.error("Failed to fetch usage: " + e.message);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
434
417
|
}
|
|
435
418
|
else if (cmd === "chats") {
|
|
436
419
|
const chats = (0, chats_1.loadChats)();
|
|
@@ -507,34 +490,6 @@ async function startRepl(initialUsername) {
|
|
|
507
490
|
}
|
|
508
491
|
}
|
|
509
492
|
}
|
|
510
|
-
else if (cmd === "thinking-level") {
|
|
511
|
-
const { Select } = require('enquirer');
|
|
512
|
-
try {
|
|
513
|
-
const prompt = new Select({
|
|
514
|
-
name: 'level',
|
|
515
|
-
message: 'Select Thinking Level:',
|
|
516
|
-
choices: [
|
|
517
|
-
{ name: 'Adaptive', message: 'Adaptive - Auto-detect (best)' },
|
|
518
|
-
{ name: 'Low', message: 'Low - Ultra-fast' },
|
|
519
|
-
{ name: 'Medium', message: 'Medium - Balanced' },
|
|
520
|
-
{ name: 'High', message: 'High - Deep logic' },
|
|
521
|
-
{ name: 'Cancel', message: 'Cancel' }
|
|
522
|
-
]
|
|
523
|
-
});
|
|
524
|
-
const answer = await prompt.run();
|
|
525
|
-
if (answer !== 'Cancel') {
|
|
526
|
-
(0, config_1.setThinkingLevel)(answer);
|
|
527
|
-
renderWelcome();
|
|
528
|
-
ui_1.ui.success(`Thinking level updated to: ${answer}`);
|
|
529
|
-
}
|
|
530
|
-
else {
|
|
531
|
-
ui_1.ui.info("Thinking level selection aborted.");
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
catch (e) {
|
|
535
|
-
ui_1.ui.info("Thinking level selection aborted.");
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
493
|
else {
|
|
539
494
|
ui_1.ui.error(`Unknown command: /${cmd}`);
|
|
540
495
|
}
|
|
@@ -873,12 +828,12 @@ async function startRepl(initialUsername) {
|
|
|
873
828
|
retryHistory.push({ role: "assistant", content: partialText });
|
|
874
829
|
retryPrompt = "Continue exactly from where you left off. Do not repeat what you already said, just continue the exact code or sentence you were writing.";
|
|
875
830
|
}
|
|
876
|
-
spinner = (0, ui_1.createSpinner)("
|
|
831
|
+
spinner = (0, ui_1.createSpinner)("Working...").start();
|
|
877
832
|
if (retryCount > 0) {
|
|
878
833
|
spinner.setPrefix(`Retrying... (${retryCount}/3)`);
|
|
879
834
|
}
|
|
880
835
|
let thisAttemptText = "";
|
|
881
|
-
const attemptResult = await (0, api_1.refactorCodeApi)(requestPayloadFileName, requestPayloadCode, retryPrompt, retryHistory, currentModel, activeSkillsData, (
|
|
836
|
+
const attemptResult = await (0, api_1.refactorCodeApi)(requestPayloadFileName, requestPayloadCode, retryPrompt, retryHistory, currentModel, activeSkillsData, (chunk) => {
|
|
882
837
|
thisAttemptText += chunk;
|
|
883
838
|
currentStreamedText = partialText + thisAttemptText;
|
|
884
839
|
// Find the last opened tag that hasn't been closed yet
|
|
@@ -978,9 +933,8 @@ async function startRepl(initialUsername) {
|
|
|
978
933
|
.replace(/<RUN_COMMAND([\s\S]*?)>([\s\S]*?)<\/RUN_COMMAND>/g, '<RUN_COMMAND$1>[Command execution parsed]</RUN_COMMAND>');
|
|
979
934
|
conversationHistory.push({ role: "user", content: tokenOptimizedInput });
|
|
980
935
|
conversationHistory.push({ role: "assistant", content: tokenOptimizedResult });
|
|
981
|
-
// Keep
|
|
982
|
-
const
|
|
983
|
-
const maxHistory = currentThinking === "High" ? 18 : (currentThinking === "Medium" ? 10 : 6);
|
|
936
|
+
// Keep a reasonable history length to prevent infinite token growth
|
|
937
|
+
const maxHistory = 10;
|
|
984
938
|
if (conversationHistory.length > maxHistory) {
|
|
985
939
|
conversationHistory = conversationHistory.slice(conversationHistory.length - maxHistory);
|
|
986
940
|
}
|
package/dist/utils/api.js
CHANGED
|
@@ -5,10 +5,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.refactorCodeApi = refactorCodeApi;
|
|
7
7
|
exports.getUserProfile = getUserProfile;
|
|
8
|
+
exports.getUserUsage = getUserUsage;
|
|
8
9
|
const config_1 = require("./config");
|
|
9
10
|
const dotenv_1 = __importDefault(require("dotenv"));
|
|
10
11
|
dotenv_1.default.config();
|
|
11
|
-
async function refactorCodeApi(fileName, code, instruction, history, modelName, skillsData,
|
|
12
|
+
async function refactorCodeApi(fileName, code, instruction, history, modelName, skillsData, onChunk, abortSignal) {
|
|
12
13
|
const token = (0, config_1.getToken)();
|
|
13
14
|
if (!token) {
|
|
14
15
|
throw new Error("No token found. Please run 'draftify login' first.");
|
|
@@ -20,7 +21,7 @@ async function refactorCodeApi(fileName, code, instruction, history, modelName,
|
|
|
20
21
|
"Content-Type": "application/json",
|
|
21
22
|
Authorization: `Bearer ${token}`
|
|
22
23
|
},
|
|
23
|
-
body: JSON.stringify({ fileName, code, instruction: `[SYSTEM NOTE: You are the ${modelName} model. If asked about your identity, you MUST state exactly: "Én a ${modelName} modell vagyok a Draftify platformon."]\n\n` + instruction, history, modelName, skillsData
|
|
24
|
+
body: JSON.stringify({ fileName, code, instruction: `[SYSTEM NOTE: You are the ${modelName} model. If asked about your identity, you MUST state exactly: "Én a ${modelName} modell vagyok a Draftify platformon."]\n\n` + instruction, history, modelName, skillsData }),
|
|
24
25
|
signal: abortSignal
|
|
25
26
|
});
|
|
26
27
|
if (!response.ok) {
|
|
@@ -106,3 +107,24 @@ async function getUserProfile() {
|
|
|
106
107
|
}
|
|
107
108
|
return null;
|
|
108
109
|
}
|
|
110
|
+
async function getUserUsage() {
|
|
111
|
+
const token = (0, config_1.getToken)();
|
|
112
|
+
if (!token)
|
|
113
|
+
throw new Error("UNAUTHORIZED");
|
|
114
|
+
// Replace the trailing /api/cli or /api/user/profile with /api/user/usage
|
|
115
|
+
let apiUrl = (0, config_1.getApiUrl)();
|
|
116
|
+
apiUrl = apiUrl.replace(/\/api\/.*$/, "/api/user/usage");
|
|
117
|
+
try {
|
|
118
|
+
const response = await fetch(apiUrl, {
|
|
119
|
+
method: "GET",
|
|
120
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
121
|
+
});
|
|
122
|
+
if (response.ok) {
|
|
123
|
+
return await response.json();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
catch (e) {
|
|
127
|
+
// Ignore errors
|
|
128
|
+
}
|
|
129
|
+
return null;
|
|
130
|
+
}
|
package/dist/utils/config.js
CHANGED
|
@@ -11,8 +11,6 @@ exports.getModel = getModel;
|
|
|
11
11
|
exports.setModel = setModel;
|
|
12
12
|
exports.getSkills = getSkills;
|
|
13
13
|
exports.setSkills = setSkills;
|
|
14
|
-
exports.getThinkingLevel = getThinkingLevel;
|
|
15
|
-
exports.setThinkingLevel = setThinkingLevel;
|
|
16
14
|
exports.getGeminiApiKey = getGeminiApiKey;
|
|
17
15
|
exports.getTokensUsed = getTokensUsed;
|
|
18
16
|
exports.addTokensUsed = addTokensUsed;
|
|
@@ -67,13 +65,6 @@ function getSkills() {
|
|
|
67
65
|
function setSkills(skills) {
|
|
68
66
|
saveConfig({ skills });
|
|
69
67
|
}
|
|
70
|
-
function getThinkingLevel() {
|
|
71
|
-
const config = getConfig();
|
|
72
|
-
return config.thinkingLevel || 'Medium';
|
|
73
|
-
}
|
|
74
|
-
function setThinkingLevel(level) {
|
|
75
|
-
saveConfig({ thinkingLevel: level });
|
|
76
|
-
}
|
|
77
68
|
function getGeminiApiKey() {
|
|
78
69
|
const config = getConfig();
|
|
79
70
|
return config.geminiApiKey || null;
|
package/dist/utils/ui.js
CHANGED
|
@@ -106,7 +106,7 @@ exports.ui = {
|
|
|
106
106
|
const text = `Draftify Scale | Engine: ${model} | Repo: ${repoName}`;
|
|
107
107
|
console.log(`\n ${(0, kleur_1.dim)(`[${text}]`)}`);
|
|
108
108
|
},
|
|
109
|
-
welcomeScreen: (repoName, model, username, plan = "Draftify Scale"
|
|
109
|
+
welcomeScreen: (repoName, model, username, plan = "Draftify Scale") => {
|
|
110
110
|
resetInline();
|
|
111
111
|
// Borderless Claude Code style with strong orange logo
|
|
112
112
|
const orange = (s) => `\x1b[38;5;208m${s}\x1b[0m`;
|
|
@@ -116,7 +116,7 @@ exports.ui = {
|
|
|
116
116
|
const greeting = username ? `Welcome ${username} to Draftify Code!` : "Welcome to Draftify Code!";
|
|
117
117
|
console.log(` ${orange("█ █ █ █")} ${white(greeting)}`);
|
|
118
118
|
console.log(` ${orange("█████████")} ${white("Draftify Code ")}${gray("v1.0.0")}`);
|
|
119
|
-
console.log(` ${orange("█ █████ █")} ${gray(`${model}
|
|
119
|
+
console.log(` ${orange("█ █████ █")} ${gray(`${model} [${plan}]`)}`);
|
|
120
120
|
console.log(` ${orange("█████████")} ${gray(process.cwd())}`);
|
|
121
121
|
console.log(` ${orange(" █ █ ")}`);
|
|
122
122
|
console.log("");
|