@lovelybunch/api 1.0.69-alpha.16 → 1.0.69-alpha.18
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/lib/auth/auth-manager.d.ts +10 -2
- package/dist/lib/auth/auth-manager.js +16 -5
- package/dist/lib/env-injection.d.ts +6 -0
- package/dist/lib/env-injection.js +64 -0
- package/dist/lib/git.d.ts +1 -0
- package/dist/lib/git.js +14 -1
- package/dist/lib/jobs/job-runner.js +22 -3
- package/dist/lib/terminal/terminal-manager.js +3 -2
- package/dist/routes/api/v1/config/index.js +1 -2
- package/dist/routes/api/v1/config/route.d.ts +0 -11
- package/dist/routes/api/v1/config/route.js +20 -104
- package/dist/routes/api/v1/events/status/route.d.ts +0 -2
- package/dist/routes/api/v1/events/status/route.js +2 -14
- package/dist/routes/api/v1/git/index.js +20 -3
- package/dist/routes/api/v1/jobs/[id]/run/route.d.ts +2 -2
- package/dist/routes/api/v1/jobs/status/route.d.ts +1 -1
- package/dist/routes/api/v1/proposals/[id]/route.d.ts +8 -8
- package/dist/routes/api/v1/resources/generate/route.js +58 -6
- package/dist/server-with-static.js +38 -23
- package/dist/server.js +38 -23
- package/package.json +4 -4
- package/static/assets/{index-8zDqsxO-.js → index-B8R7MEZ5.js} +231 -228
- package/static/assets/index-CfRmV6nM.css +33 -0
- package/static/index.html +2 -2
- package/static/assets/index-uyccX96d.css +0 -33
|
@@ -1,10 +1,49 @@
|
|
|
1
1
|
import Replicate from 'replicate';
|
|
2
2
|
import { promises as fs } from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
import { homedir } from 'os';
|
|
5
|
+
import { existsSync, readFileSync } from 'fs';
|
|
6
|
+
/**
|
|
7
|
+
* Get Replicate API token from global config or environment variable
|
|
8
|
+
*/
|
|
9
|
+
function getReplicateApiToken() {
|
|
10
|
+
// First try global config
|
|
11
|
+
try {
|
|
12
|
+
const platform = process.platform;
|
|
13
|
+
let configDir;
|
|
14
|
+
if (platform === 'win32') {
|
|
15
|
+
configDir = path.join(process.env.APPDATA || homedir(), 'coconuts');
|
|
16
|
+
}
|
|
17
|
+
else if (platform === 'darwin') {
|
|
18
|
+
configDir = path.join(homedir(), 'Library', 'Application Support', 'coconuts');
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
configDir = path.join(process.env.XDG_CONFIG_HOME || path.join(homedir(), '.config'), 'coconuts');
|
|
22
|
+
}
|
|
23
|
+
const configPath = path.join(configDir, 'config.json');
|
|
24
|
+
if (existsSync(configPath)) {
|
|
25
|
+
const config = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
26
|
+
if (config.apiKeys?.replicate) {
|
|
27
|
+
return config.apiKeys.replicate;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
console.warn('Failed to load Replicate token from config:', error);
|
|
33
|
+
}
|
|
34
|
+
// Fallback to environment variable
|
|
35
|
+
return process.env.REPLICATE_API_TOKEN || null;
|
|
36
|
+
}
|
|
37
|
+
// Initialize Replicate client lazily to ensure token is loaded at request time
|
|
38
|
+
function getReplicateClient() {
|
|
39
|
+
const token = getReplicateApiToken();
|
|
40
|
+
if (!token) {
|
|
41
|
+
throw new Error('Replicate API token not configured');
|
|
42
|
+
}
|
|
43
|
+
return new Replicate({
|
|
44
|
+
auth: token,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
8
47
|
function getResourcesPath() {
|
|
9
48
|
let basePath;
|
|
10
49
|
if (process.env.NODE_ENV === 'development' && process.env.GAIT_DEV_ROOT) {
|
|
@@ -69,6 +108,17 @@ function getAspectRatio(dimensions) {
|
|
|
69
108
|
}
|
|
70
109
|
export async function POST(c) {
|
|
71
110
|
try {
|
|
111
|
+
// Check if Replicate API token is configured
|
|
112
|
+
const replicateToken = getReplicateApiToken();
|
|
113
|
+
if (!replicateToken) {
|
|
114
|
+
return c.json({
|
|
115
|
+
success: false,
|
|
116
|
+
error: {
|
|
117
|
+
code: 'MISSING_API_TOKEN',
|
|
118
|
+
message: 'Replicate API token not configured. Please add it in Settings → Integrations.'
|
|
119
|
+
}
|
|
120
|
+
}, 400);
|
|
121
|
+
}
|
|
72
122
|
const body = await c.req.json();
|
|
73
123
|
const { prompt, inspiration, dimensions, resolution, model, image_input } = body;
|
|
74
124
|
if (!prompt) {
|
|
@@ -130,7 +180,8 @@ export async function POST(c) {
|
|
|
130
180
|
continue;
|
|
131
181
|
}
|
|
132
182
|
const fileBuffer = await fs.readFile(filePath);
|
|
133
|
-
const
|
|
183
|
+
const replicateClient = getReplicateClient();
|
|
184
|
+
const uploadedFile = await replicateClient.files.create(fileBuffer, {
|
|
134
185
|
resourceId,
|
|
135
186
|
originalName: resource.name,
|
|
136
187
|
});
|
|
@@ -160,7 +211,8 @@ export async function POST(c) {
|
|
|
160
211
|
}
|
|
161
212
|
// Run the model (defaulting to nano-banana-pro)
|
|
162
213
|
const modelId = model === 'Nano Banana Pro' ? 'google/nano-banana-pro' : 'google/nano-banana-pro';
|
|
163
|
-
const
|
|
214
|
+
const replicateClient = getReplicateClient();
|
|
215
|
+
const output = await replicateClient.run(modelId, { input });
|
|
164
216
|
// Extract URL from output
|
|
165
217
|
// Replicate output can be: string URL, array of URLs, or FileOutput object with url() method
|
|
166
218
|
let imageUrl;
|
|
@@ -11,6 +11,7 @@ import { getGlobalTerminalManager } from './lib/terminal/global-manager.js';
|
|
|
11
11
|
import { getGlobalJobScheduler } from './lib/jobs/global-job-scheduler.js';
|
|
12
12
|
import { fileURLToPath } from 'url';
|
|
13
13
|
import { getLogger } from '@lovelybunch/core/logging';
|
|
14
|
+
import { getLogsDir } from '@lovelybunch/core';
|
|
14
15
|
const __filename = fileURLToPath(import.meta.url);
|
|
15
16
|
const __dirname = path.dirname(__filename);
|
|
16
17
|
// Load environment variables from .env file in project root
|
|
@@ -30,11 +31,15 @@ function findNutDirectorySync() {
|
|
|
30
31
|
}
|
|
31
32
|
return null;
|
|
32
33
|
}
|
|
33
|
-
// Initialize logger with config from .nut/config.json
|
|
34
|
+
// Initialize logger with config from .nut/config.json or use OS app data directory
|
|
34
35
|
// This must happen BEFORE importing route handlers (they call getLogger at module level)
|
|
35
36
|
console.log('🔍 Initializing activity logging...');
|
|
36
37
|
try {
|
|
37
38
|
const nutDir = findNutDirectorySync();
|
|
39
|
+
let logsDir = getLogsDir(); // Default to OS app data directory
|
|
40
|
+
let coconutId = 'unknown.coconut';
|
|
41
|
+
let rotateBytes = 128 * 1024 * 1024;
|
|
42
|
+
let loggingEnabled = true; // Default to enabled
|
|
38
43
|
if (nutDir) {
|
|
39
44
|
const projectRoot = path.dirname(nutDir);
|
|
40
45
|
const configPath = path.join(nutDir, 'config.json');
|
|
@@ -42,32 +47,42 @@ try {
|
|
|
42
47
|
console.log(' Config path:', configPath);
|
|
43
48
|
const configData = fs.readFileSync(configPath, 'utf-8');
|
|
44
49
|
const config = JSON.parse(configData);
|
|
45
|
-
if
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
coconutId: config.coconut?.id || 'unknown.coconut',
|
|
49
|
-
logsDir: logsDir,
|
|
50
|
-
rotateBytes: config.logging?.rotateBytes || 128 * 1024 * 1024
|
|
51
|
-
});
|
|
52
|
-
console.log('📝 Activity logging ENABLED');
|
|
53
|
-
console.log(' Logs directory:', logsDir);
|
|
54
|
-
console.log(' Coconut ID:', config.coconut?.id || 'unknown.coconut');
|
|
55
|
-
// Test log immediately
|
|
56
|
-
logger.log({
|
|
57
|
-
kind: 'system.startup',
|
|
58
|
-
actor: 'system',
|
|
59
|
-
subject: 'server',
|
|
60
|
-
tags: ['system', 'startup'],
|
|
61
|
-
payload: { message: 'Server starting with logging enabled' }
|
|
62
|
-
});
|
|
63
|
-
console.log(' ✓ Test event logged');
|
|
50
|
+
// Check if logging is explicitly disabled in config
|
|
51
|
+
if (config.logging?.enabled === false) {
|
|
52
|
+
loggingEnabled = false;
|
|
64
53
|
}
|
|
65
|
-
|
|
66
|
-
|
|
54
|
+
// Allow config to override logs location (relative paths resolve from project root)
|
|
55
|
+
if (config.logging?.location) {
|
|
56
|
+
logsDir = path.resolve(projectRoot, config.logging.location);
|
|
67
57
|
}
|
|
58
|
+
if (config.coconut?.id) {
|
|
59
|
+
coconutId = config.coconut.id;
|
|
60
|
+
}
|
|
61
|
+
if (config.logging?.rotateBytes) {
|
|
62
|
+
rotateBytes = config.logging.rotateBytes;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (loggingEnabled) {
|
|
66
|
+
const logger = getLogger({
|
|
67
|
+
coconutId,
|
|
68
|
+
logsDir,
|
|
69
|
+
rotateBytes
|
|
70
|
+
});
|
|
71
|
+
console.log('📝 Activity logging ENABLED');
|
|
72
|
+
console.log(' Logs directory:', logsDir);
|
|
73
|
+
console.log(' Coconut ID:', coconutId);
|
|
74
|
+
// Test log immediately
|
|
75
|
+
logger.log({
|
|
76
|
+
kind: 'system.startup',
|
|
77
|
+
actor: 'system',
|
|
78
|
+
subject: 'server',
|
|
79
|
+
tags: ['system', 'startup'],
|
|
80
|
+
payload: { message: 'Server starting with logging enabled' }
|
|
81
|
+
});
|
|
82
|
+
console.log(' ✓ Test event logged');
|
|
68
83
|
}
|
|
69
84
|
else {
|
|
70
|
-
console.log('
|
|
85
|
+
console.log('📝 Activity logging disabled in config');
|
|
71
86
|
}
|
|
72
87
|
}
|
|
73
88
|
catch (error) {
|
package/dist/server.js
CHANGED
|
@@ -10,6 +10,7 @@ import path from 'path';
|
|
|
10
10
|
import { fileURLToPath } from 'url';
|
|
11
11
|
import fs from 'fs';
|
|
12
12
|
import { getLogger } from '@lovelybunch/core/logging';
|
|
13
|
+
import { getLogsDir } from '@lovelybunch/core';
|
|
13
14
|
const __filename = fileURLToPath(import.meta.url);
|
|
14
15
|
const __dirname = path.dirname(__filename);
|
|
15
16
|
// Load environment variables from .env file in project root
|
|
@@ -29,11 +30,15 @@ function findNutDirectorySync() {
|
|
|
29
30
|
}
|
|
30
31
|
return null;
|
|
31
32
|
}
|
|
32
|
-
// Initialize logger with config from .nut/config.json
|
|
33
|
+
// Initialize logger with config from .nut/config.json or use OS app data directory
|
|
33
34
|
// This must happen BEFORE importing route handlers (they call getLogger at module level)
|
|
34
35
|
console.log('🔍 Initializing activity logging...');
|
|
35
36
|
try {
|
|
36
37
|
const nutDir = findNutDirectorySync();
|
|
38
|
+
let logsDir = getLogsDir(); // Default to OS app data directory
|
|
39
|
+
let coconutId = 'unknown.coconut';
|
|
40
|
+
let rotateBytes = 128 * 1024 * 1024;
|
|
41
|
+
let loggingEnabled = true; // Default to enabled
|
|
37
42
|
if (nutDir) {
|
|
38
43
|
const projectRoot = path.dirname(nutDir);
|
|
39
44
|
const configPath = path.join(nutDir, 'config.json');
|
|
@@ -41,32 +46,42 @@ try {
|
|
|
41
46
|
console.log(' Config path:', configPath);
|
|
42
47
|
const configData = fs.readFileSync(configPath, 'utf-8');
|
|
43
48
|
const config = JSON.parse(configData);
|
|
44
|
-
if
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
coconutId: config.coconut?.id || 'unknown.coconut',
|
|
48
|
-
logsDir: logsDir,
|
|
49
|
-
rotateBytes: config.logging?.rotateBytes || 128 * 1024 * 1024
|
|
50
|
-
});
|
|
51
|
-
console.log('📝 Activity logging ENABLED');
|
|
52
|
-
console.log(' Logs directory:', logsDir);
|
|
53
|
-
console.log(' Coconut ID:', config.coconut?.id || 'unknown.coconut');
|
|
54
|
-
// Test log immediately
|
|
55
|
-
logger.log({
|
|
56
|
-
kind: 'system.startup',
|
|
57
|
-
actor: 'system',
|
|
58
|
-
subject: 'server',
|
|
59
|
-
tags: ['system', 'startup'],
|
|
60
|
-
payload: { message: 'Server starting with logging enabled' }
|
|
61
|
-
});
|
|
62
|
-
console.log(' ✓ Test event logged');
|
|
49
|
+
// Check if logging is explicitly disabled in config
|
|
50
|
+
if (config.logging?.enabled === false) {
|
|
51
|
+
loggingEnabled = false;
|
|
63
52
|
}
|
|
64
|
-
|
|
65
|
-
|
|
53
|
+
// Allow config to override logs location (relative paths resolve from project root)
|
|
54
|
+
if (config.logging?.location) {
|
|
55
|
+
logsDir = path.resolve(projectRoot, config.logging.location);
|
|
66
56
|
}
|
|
57
|
+
if (config.coconut?.id) {
|
|
58
|
+
coconutId = config.coconut.id;
|
|
59
|
+
}
|
|
60
|
+
if (config.logging?.rotateBytes) {
|
|
61
|
+
rotateBytes = config.logging.rotateBytes;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (loggingEnabled) {
|
|
65
|
+
const logger = getLogger({
|
|
66
|
+
coconutId,
|
|
67
|
+
logsDir,
|
|
68
|
+
rotateBytes
|
|
69
|
+
});
|
|
70
|
+
console.log('📝 Activity logging ENABLED');
|
|
71
|
+
console.log(' Logs directory:', logsDir);
|
|
72
|
+
console.log(' Coconut ID:', coconutId);
|
|
73
|
+
// Test log immediately
|
|
74
|
+
logger.log({
|
|
75
|
+
kind: 'system.startup',
|
|
76
|
+
actor: 'system',
|
|
77
|
+
subject: 'server',
|
|
78
|
+
tags: ['system', 'startup'],
|
|
79
|
+
payload: { message: 'Server starting with logging enabled' }
|
|
80
|
+
});
|
|
81
|
+
console.log(' ✓ Test event logged');
|
|
67
82
|
}
|
|
68
83
|
else {
|
|
69
|
-
console.log('
|
|
84
|
+
console.log('📝 Activity logging disabled in config');
|
|
70
85
|
}
|
|
71
86
|
}
|
|
72
87
|
catch (error) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lovelybunch/api",
|
|
3
|
-
"version": "1.0.69-alpha.
|
|
3
|
+
"version": "1.0.69-alpha.18",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/server-with-static.js",
|
|
6
6
|
"exports": {
|
|
@@ -36,9 +36,9 @@
|
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@hono/node-server": "^1.13.7",
|
|
38
38
|
"@hono/node-ws": "^1.0.6",
|
|
39
|
-
"@lovelybunch/core": "^1.0.69-alpha.
|
|
40
|
-
"@lovelybunch/mcp": "^1.0.69-alpha.
|
|
41
|
-
"@lovelybunch/types": "^1.0.69-alpha.
|
|
39
|
+
"@lovelybunch/core": "^1.0.69-alpha.18",
|
|
40
|
+
"@lovelybunch/mcp": "^1.0.69-alpha.18",
|
|
41
|
+
"@lovelybunch/types": "^1.0.69-alpha.18",
|
|
42
42
|
"arctic": "^1.9.2",
|
|
43
43
|
"bcrypt": "^5.1.1",
|
|
44
44
|
"cookie": "^0.6.0",
|