@lovelybunch/api 1.0.69-alpha.17 → 1.0.69-alpha.19
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/git.d.ts +1 -0
- package/dist/lib/git.js +14 -1
- package/dist/lib/jobs/job-runner.js +3 -2
- package/dist/routes/api/v1/events/purge/route.d.ts +0 -2
- package/dist/routes/api/v1/events/purge/route.js +2 -14
- package/dist/routes/api/v1/events/route.d.ts +0 -2
- package/dist/routes/api/v1/events/route.js +2 -14
- 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/events/stream/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/server-with-static.js +38 -23
- package/dist/server.js +38 -23
- package/package.json +4 -4
- package/static/assets/{index-BwPO_Kh8.js → index-BGfUbDUx.js} +238 -238
- package/static/assets/index-CfRmV6nM.css +33 -0
- package/static/index.html +2 -2
- package/static/assets/index-B9teXSU8.css +0 -33
|
@@ -2,7 +2,11 @@ import { AuthConfig, LocalAuthUser, AuthSession, ApiKey, UserRole } from '@lovel
|
|
|
2
2
|
export declare class AuthManager {
|
|
3
3
|
private authConfigPath;
|
|
4
4
|
private authConfig;
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Create an AuthManager instance.
|
|
7
|
+
* @param configPath - Optional custom path to auth.json. If not provided, uses OS app data directory.
|
|
8
|
+
*/
|
|
9
|
+
constructor(configPath?: string);
|
|
6
10
|
/**
|
|
7
11
|
* Check if auth is enabled
|
|
8
12
|
*/
|
|
@@ -119,4 +123,8 @@ export declare class AuthManager {
|
|
|
119
123
|
*/
|
|
120
124
|
clearCache(): void;
|
|
121
125
|
}
|
|
122
|
-
|
|
126
|
+
/**
|
|
127
|
+
* Get the singleton AuthManager instance.
|
|
128
|
+
* @param configPath - Optional custom path to auth.json. If not provided, uses OS app data directory.
|
|
129
|
+
*/
|
|
130
|
+
export declare function getAuthManager(configPath?: string): AuthManager;
|
|
@@ -3,14 +3,19 @@ import path from 'path';
|
|
|
3
3
|
import bcrypt from 'bcrypt';
|
|
4
4
|
import jwt from 'jsonwebtoken';
|
|
5
5
|
import crypto from 'crypto';
|
|
6
|
+
import { getAuthConfigPath } from '@lovelybunch/core';
|
|
6
7
|
const SALT_ROUNDS = 10;
|
|
7
8
|
const DEFAULT_SESSION_EXPIRY = '7d';
|
|
8
9
|
const DEFAULT_COOKIE_NAME = 'nut-session';
|
|
9
10
|
export class AuthManager {
|
|
10
11
|
authConfigPath;
|
|
11
12
|
authConfig = null;
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Create an AuthManager instance.
|
|
15
|
+
* @param configPath - Optional custom path to auth.json. If not provided, uses OS app data directory.
|
|
16
|
+
*/
|
|
17
|
+
constructor(configPath) {
|
|
18
|
+
this.authConfigPath = configPath ?? getAuthConfigPath();
|
|
14
19
|
}
|
|
15
20
|
/**
|
|
16
21
|
* Check if auth is enabled
|
|
@@ -45,6 +50,9 @@ export class AuthManager {
|
|
|
45
50
|
* Save auth config to file
|
|
46
51
|
*/
|
|
47
52
|
async saveAuthConfig(config) {
|
|
53
|
+
// Ensure the directory exists
|
|
54
|
+
const dir = path.dirname(this.authConfigPath);
|
|
55
|
+
await fs.mkdir(dir, { recursive: true });
|
|
48
56
|
await fs.writeFile(this.authConfigPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
49
57
|
this.authConfig = config;
|
|
50
58
|
}
|
|
@@ -402,10 +410,13 @@ export class AuthManager {
|
|
|
402
410
|
}
|
|
403
411
|
// Singleton instance
|
|
404
412
|
let authManagerInstance = null;
|
|
405
|
-
|
|
413
|
+
/**
|
|
414
|
+
* Get the singleton AuthManager instance.
|
|
415
|
+
* @param configPath - Optional custom path to auth.json. If not provided, uses OS app data directory.
|
|
416
|
+
*/
|
|
417
|
+
export function getAuthManager(configPath) {
|
|
406
418
|
if (!authManagerInstance) {
|
|
407
|
-
|
|
408
|
-
authManagerInstance = new AuthManager(path);
|
|
419
|
+
authManagerInstance = new AuthManager(configPath);
|
|
409
420
|
}
|
|
410
421
|
return authManagerInstance;
|
|
411
422
|
}
|
package/dist/lib/git.d.ts
CHANGED
|
@@ -44,6 +44,7 @@ export declare function getCredentialConfig(): Promise<{
|
|
|
44
44
|
origin?: string;
|
|
45
45
|
}>;
|
|
46
46
|
export declare function setRemoteUrl(remoteUrl: string): Promise<void>;
|
|
47
|
+
export declare function removeRemote(): Promise<void>;
|
|
47
48
|
export declare function storeCredentials(username: string, password: string, remoteUrl?: string): Promise<void>;
|
|
48
49
|
export interface WorktreeInfo {
|
|
49
50
|
name: string;
|
package/dist/lib/git.js
CHANGED
|
@@ -158,7 +158,8 @@ export async function pushCurrent() {
|
|
|
158
158
|
console.error('[git] Error reading GitHub token:', tokenError);
|
|
159
159
|
}
|
|
160
160
|
console.log('[git] Executing git push...');
|
|
161
|
-
|
|
161
|
+
// Use -u to set upstream tracking if not already set (harmless if already configured)
|
|
162
|
+
const { stdout } = await runGit(['push', '-u', 'origin', 'HEAD'], { timeout: 30000 }); // 30 second timeout for push
|
|
162
163
|
console.log('[git] Push completed successfully');
|
|
163
164
|
return stdout;
|
|
164
165
|
}
|
|
@@ -257,6 +258,18 @@ export async function setRemoteUrl(remoteUrl) {
|
|
|
257
258
|
await runGit(['remote', 'add', 'origin', trimmed]);
|
|
258
259
|
}
|
|
259
260
|
}
|
|
261
|
+
export async function removeRemote() {
|
|
262
|
+
// Check if origin exists
|
|
263
|
+
try {
|
|
264
|
+
await runGit(['config', '--get', 'remote.origin.url']);
|
|
265
|
+
// If we get here, origin exists, so remove it
|
|
266
|
+
await runGit(['remote', 'remove', 'origin']);
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
// Origin doesn't exist, nothing to do
|
|
270
|
+
throw new Error('No remote configured');
|
|
271
|
+
}
|
|
272
|
+
}
|
|
260
273
|
export async function storeCredentials(username, password, remoteUrl) {
|
|
261
274
|
// If a remote URL is provided, set it first
|
|
262
275
|
if (remoteUrl && remoteUrl.trim()) {
|
|
@@ -46,11 +46,12 @@ function buildCommand(agent, instruction, config) {
|
|
|
46
46
|
break;
|
|
47
47
|
}
|
|
48
48
|
case 'droid': {
|
|
49
|
-
// For Factory Droid, use
|
|
49
|
+
// For Factory Droid, use exec mode with --auto high for non-interactive scheduled jobs
|
|
50
|
+
// See: https://docs.factory.ai/reference/cli-reference#autonomy-levels
|
|
50
51
|
const mcpFlags = config.mcpServers && config.mcpServers.length > 0
|
|
51
52
|
? config.mcpServers.map(server => `--mcp ${shellQuote(server)}`).join(' ')
|
|
52
53
|
: '';
|
|
53
|
-
mainCommand = `droid
|
|
54
|
+
mainCommand = `droid exec --auto high ${mcpFlags} ${quotedInstruction}`.trim();
|
|
54
55
|
break;
|
|
55
56
|
}
|
|
56
57
|
case 'claude':
|
|
@@ -9,8 +9,6 @@ import { Context } from "hono";
|
|
|
9
9
|
*/
|
|
10
10
|
export declare function POST(c: Context): Promise<(Response & import("hono").TypedResponse<{
|
|
11
11
|
error: string;
|
|
12
|
-
}, 404, "json">) | (Response & import("hono").TypedResponse<{
|
|
13
|
-
error: string;
|
|
14
12
|
}, 400, "json">) | (Response & import("hono").TypedResponse<{
|
|
15
13
|
deleted: number;
|
|
16
14
|
}, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
|
|
@@ -1,18 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Events purge endpoint
|
|
3
3
|
*/
|
|
4
|
+
import { getLogsDir } from "@lovelybunch/core";
|
|
4
5
|
import { promises as fs } from "fs";
|
|
5
6
|
import path from "path";
|
|
6
|
-
import { findGaitDirectory } from "../../../../../lib/gait-path.js";
|
|
7
|
-
/**
|
|
8
|
-
* Get the events directory path
|
|
9
|
-
*/
|
|
10
|
-
async function getEventsDir() {
|
|
11
|
-
const gaitDir = await findGaitDirectory();
|
|
12
|
-
if (!gaitDir)
|
|
13
|
-
return null;
|
|
14
|
-
return path.join(gaitDir, "logs");
|
|
15
|
-
}
|
|
16
7
|
/**
|
|
17
8
|
* POST /api/v1/events/purge
|
|
18
9
|
* Delete rotated files older than a timestamp
|
|
@@ -20,10 +11,7 @@ async function getEventsDir() {
|
|
|
20
11
|
*/
|
|
21
12
|
export async function POST(c) {
|
|
22
13
|
try {
|
|
23
|
-
const eventsDir =
|
|
24
|
-
if (!eventsDir) {
|
|
25
|
-
return c.json({ error: "Events directory not found" }, 404);
|
|
26
|
-
}
|
|
14
|
+
const eventsDir = getLogsDir();
|
|
27
15
|
const body = await c.req.json();
|
|
28
16
|
const beforeIso = body.beforeIso;
|
|
29
17
|
if (!beforeIso) {
|
|
@@ -19,8 +19,6 @@ export declare function POST(c: Context): Promise<(Response & import("hono").Typ
|
|
|
19
19
|
* Fetch a page of events from the current file
|
|
20
20
|
*/
|
|
21
21
|
export declare function GET(c: Context): Promise<(Response & import("hono").TypedResponse<{
|
|
22
|
-
error: string;
|
|
23
|
-
}, 404, "json">) | (Response & import("hono").TypedResponse<{
|
|
24
22
|
items: any[];
|
|
25
23
|
next_since_seq: number;
|
|
26
24
|
eof: boolean;
|
|
@@ -3,20 +3,11 @@
|
|
|
3
3
|
* Provides endpoints for logging, querying, and streaming events
|
|
4
4
|
*/
|
|
5
5
|
import { getLogger } from "@lovelybunch/core/logging";
|
|
6
|
+
import { getLogsDir } from "@lovelybunch/core";
|
|
6
7
|
import { promises as fs } from "fs";
|
|
7
8
|
import * as fsSync from "fs";
|
|
8
9
|
import path from "path";
|
|
9
|
-
import { findGaitDirectory } from "../../../../lib/gait-path.js";
|
|
10
10
|
import readline from "readline";
|
|
11
|
-
/**
|
|
12
|
-
* Get the events directory path
|
|
13
|
-
*/
|
|
14
|
-
async function getEventsDir() {
|
|
15
|
-
const gaitDir = await findGaitDirectory();
|
|
16
|
-
if (!gaitDir)
|
|
17
|
-
return null;
|
|
18
|
-
return path.join(gaitDir, "logs");
|
|
19
|
-
}
|
|
20
11
|
/**
|
|
21
12
|
* POST /api/v1/events
|
|
22
13
|
* Enqueue one or many events
|
|
@@ -50,10 +41,7 @@ export async function POST(c) {
|
|
|
50
41
|
*/
|
|
51
42
|
export async function GET(c) {
|
|
52
43
|
try {
|
|
53
|
-
const eventsDir =
|
|
54
|
-
if (!eventsDir) {
|
|
55
|
-
return c.json({ error: "Events directory not found" }, 404);
|
|
56
|
-
}
|
|
44
|
+
const eventsDir = getLogsDir();
|
|
57
45
|
const url = new URL(c.req.url);
|
|
58
46
|
const sinceSeq = parseInt(url.searchParams.get("since_seq") || "0", 10);
|
|
59
47
|
const limit = Math.min(parseInt(url.searchParams.get("limit") || "1000", 10), 5000);
|
|
@@ -7,8 +7,6 @@ import { Context } from "hono";
|
|
|
7
7
|
* Get logging system status and configuration
|
|
8
8
|
*/
|
|
9
9
|
export declare function GET(c: Context): Promise<(Response & import("hono").TypedResponse<{
|
|
10
|
-
error: string;
|
|
11
|
-
}, 404, "json">) | (Response & import("hono").TypedResponse<{
|
|
12
10
|
currentFile: string;
|
|
13
11
|
sizeBytes: number;
|
|
14
12
|
lastSeq: number;
|
|
@@ -2,28 +2,16 @@
|
|
|
2
2
|
* Events status endpoint
|
|
3
3
|
*/
|
|
4
4
|
import { getLogger } from "@lovelybunch/core/logging";
|
|
5
|
+
import { getLogsDir } from "@lovelybunch/core";
|
|
5
6
|
import { promises as fs } from "fs";
|
|
6
7
|
import path from "path";
|
|
7
|
-
import { findGaitDirectory } from "../../../../../lib/gait-path.js";
|
|
8
|
-
/**
|
|
9
|
-
* Get the events directory path
|
|
10
|
-
*/
|
|
11
|
-
async function getEventsDir() {
|
|
12
|
-
const gaitDir = await findGaitDirectory();
|
|
13
|
-
if (!gaitDir)
|
|
14
|
-
return null;
|
|
15
|
-
return path.join(gaitDir, "logs");
|
|
16
|
-
}
|
|
17
8
|
/**
|
|
18
9
|
* GET /api/v1/events/status
|
|
19
10
|
* Get logging system status and configuration
|
|
20
11
|
*/
|
|
21
12
|
export async function GET(c) {
|
|
22
13
|
try {
|
|
23
|
-
const eventsDir =
|
|
24
|
-
if (!eventsDir) {
|
|
25
|
-
return c.json({ error: "Events directory not found" }, 404);
|
|
26
|
-
}
|
|
14
|
+
const eventsDir = getLogsDir();
|
|
27
15
|
const logger = getLogger();
|
|
28
16
|
const currentFile = path.join(eventsDir, "events-current.jsonl");
|
|
29
17
|
let sizeBytes = 0;
|
|
@@ -2,29 +2,17 @@
|
|
|
2
2
|
* Events streaming endpoint for real-time tailing
|
|
3
3
|
*/
|
|
4
4
|
import { streamSSE } from "hono/streaming";
|
|
5
|
+
import { getLogsDir } from "@lovelybunch/core";
|
|
5
6
|
import { promises as fs } from "fs";
|
|
6
7
|
import * as fsSync from "fs";
|
|
7
8
|
import path from "path";
|
|
8
|
-
import { findGaitDirectory } from "../../../../../lib/gait-path.js";
|
|
9
9
|
import readline from "readline";
|
|
10
|
-
/**
|
|
11
|
-
* Get the events directory path
|
|
12
|
-
*/
|
|
13
|
-
async function getEventsDir() {
|
|
14
|
-
const gaitDir = await findGaitDirectory();
|
|
15
|
-
if (!gaitDir)
|
|
16
|
-
return null;
|
|
17
|
-
return path.join(gaitDir, "logs");
|
|
18
|
-
}
|
|
19
10
|
/**
|
|
20
11
|
* GET /api/v1/events/stream?since_seq=
|
|
21
12
|
* Server-Sent Events stream for near real-time tails
|
|
22
13
|
*/
|
|
23
14
|
export async function GET(c) {
|
|
24
|
-
const eventsDir =
|
|
25
|
-
if (!eventsDir) {
|
|
26
|
-
return c.json({ error: "Events directory not found" }, 404);
|
|
27
|
-
}
|
|
15
|
+
const eventsDir = getLogsDir();
|
|
28
16
|
const url = new URL(c.req.url);
|
|
29
17
|
const sinceSeq = parseInt(url.searchParams.get("since_seq") || "0", 10);
|
|
30
18
|
const currentFile = path.join(eventsDir, "events-current.jsonl");
|
|
@@ -111,6 +111,17 @@ app.put('/remote', async (c) => {
|
|
|
111
111
|
return c.json({ success: false, error: { message: e.message } }, 500);
|
|
112
112
|
}
|
|
113
113
|
});
|
|
114
|
+
// Delete Remote URL
|
|
115
|
+
app.delete('/remote', async (c) => {
|
|
116
|
+
try {
|
|
117
|
+
const { removeRemote } = await import('../../../../lib/git.js');
|
|
118
|
+
await removeRemote();
|
|
119
|
+
return c.json({ success: true, data: { message: 'Remote URL removed successfully' } });
|
|
120
|
+
}
|
|
121
|
+
catch (e) {
|
|
122
|
+
return c.json({ success: false, error: { message: e.message } }, 500);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
114
125
|
// Store Credentials
|
|
115
126
|
app.post('/credentials', async (c) => {
|
|
116
127
|
try {
|
|
@@ -402,13 +413,19 @@ app.post('/discard', async (c) => {
|
|
|
402
413
|
const statusCode = fileChange.status.trim();
|
|
403
414
|
// Handle different file statuses
|
|
404
415
|
if (statusCode === '??' || statusCode.includes('U')) {
|
|
405
|
-
// Untracked file - remove it
|
|
406
|
-
const {
|
|
416
|
+
// Untracked file or directory - remove it
|
|
417
|
+
const { rm, stat } = await import('fs/promises');
|
|
407
418
|
const { getRepoRoot } = await import('../../../../lib/git.js');
|
|
408
419
|
const repoRoot = await getRepoRoot();
|
|
409
420
|
const { join } = await import('path');
|
|
410
421
|
const fullPath = join(repoRoot, filePath);
|
|
411
|
-
await
|
|
422
|
+
const stats = await stat(fullPath);
|
|
423
|
+
if (stats.isDirectory()) {
|
|
424
|
+
await rm(fullPath, { recursive: true });
|
|
425
|
+
}
|
|
426
|
+
else {
|
|
427
|
+
await rm(fullPath);
|
|
428
|
+
}
|
|
412
429
|
}
|
|
413
430
|
else if (statusCode.includes('D')) {
|
|
414
431
|
// Deleted file - restore it
|
|
@@ -12,8 +12,8 @@ export declare function POST(c: Context): Promise<(Response & import("hono").Typ
|
|
|
12
12
|
run: {
|
|
13
13
|
id: string;
|
|
14
14
|
jobId: string;
|
|
15
|
-
trigger: import("@lovelybunch/
|
|
16
|
-
status: import("@lovelybunch/
|
|
15
|
+
trigger: import("@lovelybunch/core").ScheduledJobTrigger;
|
|
16
|
+
status: import("@lovelybunch/core").ScheduledJobRunStatus;
|
|
17
17
|
startedAt: string;
|
|
18
18
|
finishedAt?: string;
|
|
19
19
|
outputPath?: string;
|
|
@@ -7,7 +7,7 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
|
|
|
7
7
|
runningCount: number;
|
|
8
8
|
jobs: {
|
|
9
9
|
id: string;
|
|
10
|
-
status: import("@lovelybunch/
|
|
10
|
+
status: import("@lovelybunch/core").ScheduledJobStatus;
|
|
11
11
|
nextRunAt?: string;
|
|
12
12
|
lastRunAt?: string;
|
|
13
13
|
timerActive: boolean;
|
|
@@ -12,7 +12,7 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
|
|
|
12
12
|
intent: string;
|
|
13
13
|
content?: string;
|
|
14
14
|
author: {
|
|
15
|
-
type: import("@lovelybunch/
|
|
15
|
+
type: import("@lovelybunch/core").AuthorType;
|
|
16
16
|
id: string;
|
|
17
17
|
name: string;
|
|
18
18
|
email?: string;
|
|
@@ -47,7 +47,7 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
|
|
|
47
47
|
version: string;
|
|
48
48
|
name: string;
|
|
49
49
|
description: string;
|
|
50
|
-
type: import("@lovelybunch/
|
|
50
|
+
type: import("@lovelybunch/core").FeatureFlagType;
|
|
51
51
|
defaultValue: any;
|
|
52
52
|
scopes: string[];
|
|
53
53
|
targets: {
|
|
@@ -95,7 +95,7 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
|
|
|
95
95
|
minimumSampleSize: number;
|
|
96
96
|
testType: "two-tailed" | "one-tailed";
|
|
97
97
|
};
|
|
98
|
-
status: import("@lovelybunch/
|
|
98
|
+
status: import("@lovelybunch/core").ExperimentStatus;
|
|
99
99
|
startedAt?: string;
|
|
100
100
|
endedAt?: string;
|
|
101
101
|
}[];
|
|
@@ -133,7 +133,7 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
|
|
|
133
133
|
schedule?: string;
|
|
134
134
|
rollbackPlan?: string;
|
|
135
135
|
};
|
|
136
|
-
status: import("@lovelybunch/
|
|
136
|
+
status: import("@lovelybunch/core").CPStatus;
|
|
137
137
|
metadata: {
|
|
138
138
|
createdAt: string;
|
|
139
139
|
updatedAt: string;
|
|
@@ -169,7 +169,7 @@ export declare function PATCH(c: Context): Promise<(Response & import("hono").Ty
|
|
|
169
169
|
intent: string;
|
|
170
170
|
content?: string;
|
|
171
171
|
author: {
|
|
172
|
-
type: import("@lovelybunch/
|
|
172
|
+
type: import("@lovelybunch/core").AuthorType;
|
|
173
173
|
id: string;
|
|
174
174
|
name: string;
|
|
175
175
|
email?: string;
|
|
@@ -204,7 +204,7 @@ export declare function PATCH(c: Context): Promise<(Response & import("hono").Ty
|
|
|
204
204
|
version: string;
|
|
205
205
|
name: string;
|
|
206
206
|
description: string;
|
|
207
|
-
type: import("@lovelybunch/
|
|
207
|
+
type: import("@lovelybunch/core").FeatureFlagType;
|
|
208
208
|
defaultValue: any;
|
|
209
209
|
scopes: string[];
|
|
210
210
|
targets: {
|
|
@@ -252,7 +252,7 @@ export declare function PATCH(c: Context): Promise<(Response & import("hono").Ty
|
|
|
252
252
|
minimumSampleSize: number;
|
|
253
253
|
testType: "two-tailed" | "one-tailed";
|
|
254
254
|
};
|
|
255
|
-
status: import("@lovelybunch/
|
|
255
|
+
status: import("@lovelybunch/core").ExperimentStatus;
|
|
256
256
|
startedAt?: string;
|
|
257
257
|
endedAt?: string;
|
|
258
258
|
}[];
|
|
@@ -290,7 +290,7 @@ export declare function PATCH(c: Context): Promise<(Response & import("hono").Ty
|
|
|
290
290
|
schedule?: string;
|
|
291
291
|
rollbackPlan?: string;
|
|
292
292
|
};
|
|
293
|
-
status: import("@lovelybunch/
|
|
293
|
+
status: import("@lovelybunch/core").CPStatus;
|
|
294
294
|
metadata: {
|
|
295
295
|
createdAt: string;
|
|
296
296
|
updatedAt: string;
|
|
@@ -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.19",
|
|
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.19",
|
|
40
|
+
"@lovelybunch/mcp": "^1.0.69-alpha.19",
|
|
41
|
+
"@lovelybunch/types": "^1.0.69-alpha.19",
|
|
42
42
|
"arctic": "^1.9.2",
|
|
43
43
|
"bcrypt": "^5.1.1",
|
|
44
44
|
"cookie": "^0.6.0",
|