@cloudcli-ai/cloudcli 1.28.0 → 1.29.0
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/README.de.md +11 -0
- package/README.ja.md +11 -0
- package/README.ko.md +13 -1
- package/README.md +31 -21
- package/README.ru.md +12 -1
- package/README.zh-CN.md +13 -1
- package/dist/api-docs.html +2 -2
- package/dist/assets/index-ByHZ8-LL.css +32 -0
- package/dist/assets/index-Cdn2Scm1.js +1262 -0
- package/dist/assets/{vendor-codemirror-C8f1vU1x.js → vendor-codemirror-NA4v81it.js} +1 -1
- package/dist/assets/{vendor-react-CdSTmIF1.js → vendor-react-D7WwDXvu.js} +1 -1
- package/dist/index.html +4 -4
- package/dist/sw.js +3 -3
- package/package.json +3 -2
- package/server/cli.js +367 -8
- package/server/index.js +19 -157
- package/server/routes/agent.js +1 -1
- package/server/services/notification-orchestrator.js +1 -1
- package/dist/assets/index-B1XAhG_4.css +0 -32
- package/dist/assets/index-BWQPmiP5.js +0 -1275
package/server/index.js
CHANGED
|
@@ -435,13 +435,20 @@ app.post('/api/system/update', authenticateToken, async (req, res) => {
|
|
|
435
435
|
|
|
436
436
|
console.log('Starting system update from directory:', projectRoot);
|
|
437
437
|
|
|
438
|
-
//
|
|
439
|
-
const updateCommand =
|
|
440
|
-
|
|
441
|
-
|
|
438
|
+
// Platform deployments use their own update workflow from the project root.
|
|
439
|
+
const updateCommand = IS_PLATFORM
|
|
440
|
+
// In platform, husky and dev dependencies are not needed
|
|
441
|
+
? 'npm run update:platform'
|
|
442
|
+
: installMode === 'git'
|
|
443
|
+
? 'git checkout main && git pull && npm install'
|
|
444
|
+
: 'npm install -g @cloudcli-ai/cloudcli@latest';
|
|
445
|
+
|
|
446
|
+
const updateCwd = IS_PLATFORM || installMode === 'git'
|
|
447
|
+
? projectRoot
|
|
448
|
+
: os.homedir();
|
|
442
449
|
|
|
443
450
|
const child = spawn('sh', ['-c', updateCommand], {
|
|
444
|
-
cwd:
|
|
451
|
+
cwd: updateCwd,
|
|
445
452
|
env: process.env
|
|
446
453
|
});
|
|
447
454
|
|
|
@@ -812,7 +819,7 @@ app.get('/api/projects/:projectName/file', authenticateToken, async (req, res) =
|
|
|
812
819
|
}
|
|
813
820
|
});
|
|
814
821
|
|
|
815
|
-
// Serve
|
|
822
|
+
// Serve raw file bytes for previews and downloads.
|
|
816
823
|
app.get('/api/projects/:projectName/files/content', authenticateToken, async (req, res) => {
|
|
817
824
|
try {
|
|
818
825
|
const { projectName } = req.params;
|
|
@@ -829,7 +836,11 @@ app.get('/api/projects/:projectName/files/content', authenticateToken, async (re
|
|
|
829
836
|
return res.status(404).json({ error: 'Project not found' });
|
|
830
837
|
}
|
|
831
838
|
|
|
832
|
-
|
|
839
|
+
// Match the text reader endpoint so callers can pass either project-relative
|
|
840
|
+
// or absolute paths without changing how the bytes are served.
|
|
841
|
+
const resolved = path.isAbsolute(filePath)
|
|
842
|
+
? path.resolve(filePath)
|
|
843
|
+
: path.resolve(projectRoot, filePath);
|
|
833
844
|
const normalizedRoot = path.resolve(projectRoot) + path.sep;
|
|
834
845
|
if (!resolved.startsWith(normalizedRoot)) {
|
|
835
846
|
return res.status(403).json({ error: 'Path must be under project root' });
|
|
@@ -1980,155 +1991,6 @@ function handleShellConnection(ws) {
|
|
|
1980
1991
|
console.error('[ERROR] Shell WebSocket error:', error);
|
|
1981
1992
|
});
|
|
1982
1993
|
}
|
|
1983
|
-
// Audio transcription endpoint
|
|
1984
|
-
app.post('/api/transcribe', authenticateToken, async (req, res) => {
|
|
1985
|
-
try {
|
|
1986
|
-
const multer = (await import('multer')).default;
|
|
1987
|
-
const upload = multer({ storage: multer.memoryStorage() });
|
|
1988
|
-
|
|
1989
|
-
// Handle multipart form data
|
|
1990
|
-
upload.single('audio')(req, res, async (err) => {
|
|
1991
|
-
if (err) {
|
|
1992
|
-
return res.status(400).json({ error: 'Failed to process audio file' });
|
|
1993
|
-
}
|
|
1994
|
-
|
|
1995
|
-
if (!req.file) {
|
|
1996
|
-
return res.status(400).json({ error: 'No audio file provided' });
|
|
1997
|
-
}
|
|
1998
|
-
|
|
1999
|
-
const apiKey = process.env.OPENAI_API_KEY;
|
|
2000
|
-
if (!apiKey) {
|
|
2001
|
-
return res.status(500).json({ error: 'OpenAI API key not configured. Please set OPENAI_API_KEY in server environment.' });
|
|
2002
|
-
}
|
|
2003
|
-
|
|
2004
|
-
try {
|
|
2005
|
-
// Create form data for OpenAI
|
|
2006
|
-
const FormData = (await import('form-data')).default;
|
|
2007
|
-
const formData = new FormData();
|
|
2008
|
-
formData.append('file', req.file.buffer, {
|
|
2009
|
-
filename: req.file.originalname,
|
|
2010
|
-
contentType: req.file.mimetype
|
|
2011
|
-
});
|
|
2012
|
-
formData.append('model', 'whisper-1');
|
|
2013
|
-
formData.append('response_format', 'json');
|
|
2014
|
-
formData.append('language', 'en');
|
|
2015
|
-
|
|
2016
|
-
// Make request to OpenAI
|
|
2017
|
-
const response = await fetch('https://api.openai.com/v1/audio/transcriptions', {
|
|
2018
|
-
method: 'POST',
|
|
2019
|
-
headers: {
|
|
2020
|
-
'Authorization': `Bearer ${apiKey}`,
|
|
2021
|
-
...formData.getHeaders()
|
|
2022
|
-
},
|
|
2023
|
-
body: formData
|
|
2024
|
-
});
|
|
2025
|
-
|
|
2026
|
-
if (!response.ok) {
|
|
2027
|
-
const errorData = await response.json().catch(() => ({}));
|
|
2028
|
-
throw new Error(errorData.error?.message || `Whisper API error: ${response.status}`);
|
|
2029
|
-
}
|
|
2030
|
-
|
|
2031
|
-
const data = await response.json();
|
|
2032
|
-
let transcribedText = data.text || '';
|
|
2033
|
-
|
|
2034
|
-
// Check if enhancement mode is enabled
|
|
2035
|
-
const mode = req.body.mode || 'default';
|
|
2036
|
-
|
|
2037
|
-
// If no transcribed text, return empty
|
|
2038
|
-
if (!transcribedText) {
|
|
2039
|
-
return res.json({ text: '' });
|
|
2040
|
-
}
|
|
2041
|
-
|
|
2042
|
-
// If default mode, return transcribed text without enhancement
|
|
2043
|
-
if (mode === 'default') {
|
|
2044
|
-
return res.json({ text: transcribedText });
|
|
2045
|
-
}
|
|
2046
|
-
|
|
2047
|
-
// Handle different enhancement modes
|
|
2048
|
-
try {
|
|
2049
|
-
const OpenAI = (await import('openai')).default;
|
|
2050
|
-
const openai = new OpenAI({ apiKey });
|
|
2051
|
-
|
|
2052
|
-
let prompt, systemMessage, temperature = 0.7, maxTokens = 800;
|
|
2053
|
-
|
|
2054
|
-
switch (mode) {
|
|
2055
|
-
case 'prompt':
|
|
2056
|
-
systemMessage = 'You are an expert prompt engineer who creates clear, detailed, and effective prompts.';
|
|
2057
|
-
prompt = `You are an expert prompt engineer. Transform the following rough instruction into a clear, detailed, and context-aware AI prompt.
|
|
2058
|
-
|
|
2059
|
-
Your enhanced prompt should:
|
|
2060
|
-
1. Be specific and unambiguous
|
|
2061
|
-
2. Include relevant context and constraints
|
|
2062
|
-
3. Specify the desired output format
|
|
2063
|
-
4. Use clear, actionable language
|
|
2064
|
-
5. Include examples where helpful
|
|
2065
|
-
6. Consider edge cases and potential ambiguities
|
|
2066
|
-
|
|
2067
|
-
Transform this rough instruction into a well-crafted prompt:
|
|
2068
|
-
"${transcribedText}"
|
|
2069
|
-
|
|
2070
|
-
Enhanced prompt:`;
|
|
2071
|
-
break;
|
|
2072
|
-
|
|
2073
|
-
case 'vibe':
|
|
2074
|
-
case 'instructions':
|
|
2075
|
-
case 'architect':
|
|
2076
|
-
systemMessage = 'You are a helpful assistant that formats ideas into clear, actionable instructions for AI agents.';
|
|
2077
|
-
temperature = 0.5; // Lower temperature for more controlled output
|
|
2078
|
-
prompt = `Transform the following idea into clear, well-structured instructions that an AI agent can easily understand and execute.
|
|
2079
|
-
|
|
2080
|
-
IMPORTANT RULES:
|
|
2081
|
-
- Format as clear, step-by-step instructions
|
|
2082
|
-
- Add reasonable implementation details based on common patterns
|
|
2083
|
-
- Only include details directly related to what was asked
|
|
2084
|
-
- Do NOT add features or functionality not mentioned
|
|
2085
|
-
- Keep the original intent and scope intact
|
|
2086
|
-
- Use clear, actionable language an agent can follow
|
|
2087
|
-
|
|
2088
|
-
Transform this idea into agent-friendly instructions:
|
|
2089
|
-
"${transcribedText}"
|
|
2090
|
-
|
|
2091
|
-
Agent instructions:`;
|
|
2092
|
-
break;
|
|
2093
|
-
|
|
2094
|
-
default:
|
|
2095
|
-
// No enhancement needed
|
|
2096
|
-
break;
|
|
2097
|
-
}
|
|
2098
|
-
|
|
2099
|
-
// Only make GPT call if we have a prompt
|
|
2100
|
-
if (prompt) {
|
|
2101
|
-
const completion = await openai.chat.completions.create({
|
|
2102
|
-
model: 'gpt-4o-mini',
|
|
2103
|
-
messages: [
|
|
2104
|
-
{ role: 'system', content: systemMessage },
|
|
2105
|
-
{ role: 'user', content: prompt }
|
|
2106
|
-
],
|
|
2107
|
-
temperature: temperature,
|
|
2108
|
-
max_tokens: maxTokens
|
|
2109
|
-
});
|
|
2110
|
-
|
|
2111
|
-
transcribedText = completion.choices[0].message.content || transcribedText;
|
|
2112
|
-
}
|
|
2113
|
-
|
|
2114
|
-
} catch (gptError) {
|
|
2115
|
-
console.error('GPT processing error:', gptError);
|
|
2116
|
-
// Fall back to original transcription if GPT fails
|
|
2117
|
-
}
|
|
2118
|
-
|
|
2119
|
-
res.json({ text: transcribedText });
|
|
2120
|
-
|
|
2121
|
-
} catch (error) {
|
|
2122
|
-
console.error('Transcription error:', error);
|
|
2123
|
-
res.status(500).json({ error: error.message });
|
|
2124
|
-
}
|
|
2125
|
-
});
|
|
2126
|
-
} catch (error) {
|
|
2127
|
-
console.error('Endpoint error:', error);
|
|
2128
|
-
res.status(500).json({ error: 'Internal server error' });
|
|
2129
|
-
}
|
|
2130
|
-
});
|
|
2131
|
-
|
|
2132
1994
|
// Image upload endpoint
|
|
2133
1995
|
app.post('/api/projects/:projectName/upload-images', authenticateToken, async (req, res) => {
|
|
2134
1996
|
try {
|
|
@@ -2544,7 +2406,7 @@ async function startServer() {
|
|
|
2544
2406
|
|
|
2545
2407
|
console.log('');
|
|
2546
2408
|
console.log(c.dim('═'.repeat(63)));
|
|
2547
|
-
console.log(` ${c.bright('
|
|
2409
|
+
console.log(` ${c.bright('CloudCLI Server - Ready')}`);
|
|
2548
2410
|
console.log(c.dim('═'.repeat(63)));
|
|
2549
2411
|
console.log('');
|
|
2550
2412
|
console.log(`${c.info('[INFO]')} Server URL: ${c.bright('http://' + DISPLAY_HOST + ':' + SERVER_PORT)}`);
|
package/server/routes/agent.js
CHANGED
|
@@ -1125,7 +1125,7 @@ router.post('/', validateExternalApiKey, async (req, res) => {
|
|
|
1125
1125
|
} else {
|
|
1126
1126
|
prBody += `Agent task: ${message}`;
|
|
1127
1127
|
}
|
|
1128
|
-
prBody += '\n\n---\n*This pull request was automatically created by
|
|
1128
|
+
prBody += '\n\n---\n*This pull request was automatically created by CloudCLI.ai Agent.*';
|
|
1129
1129
|
|
|
1130
1130
|
console.log(`📝 PR Title: ${prTitle}`);
|
|
1131
1131
|
|
|
@@ -125,7 +125,7 @@ function buildPushBody(event) {
|
|
|
125
125
|
const message = CODE_MAP[event.code] || 'You have a new notification';
|
|
126
126
|
|
|
127
127
|
return {
|
|
128
|
-
title: sessionName || '
|
|
128
|
+
title: sessionName || 'CloudCLI',
|
|
129
129
|
body: `${providerLabel}: ${message}`,
|
|
130
130
|
data: {
|
|
131
131
|
sessionId: event.sessionId || null,
|