@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.
@@ -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
- constructor(dataPath: string);
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
- export declare function getAuthManager(dataPath?: string): AuthManager;
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
- constructor(dataPath) {
13
- this.authConfigPath = path.join(dataPath, '.nut', 'auth.json');
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
- export function getAuthManager(dataPath) {
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
- const path = dataPath || process.env.GAIT_DATA_PATH || process.cwd();
408
- authManagerInstance = new AuthManager(path);
419
+ authManagerInstance = new AuthManager(configPath);
409
420
  }
410
421
  return authManagerInstance;
411
422
  }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Get environment variables to inject into spawned child processes
3
+ * These are the API keys that coding agents (Claude Code, Codex, Gemini CLI) will use
4
+ * Returns a full environment object with process.env merged with API keys
5
+ */
6
+ export declare function getInjectedEnv(): Record<string, string>;
@@ -0,0 +1,64 @@
1
+ import { homedir } from 'os';
2
+ import { join } from 'path';
3
+ import { existsSync, readFileSync } from 'fs';
4
+ /**
5
+ * Get the path to the global config file
6
+ */
7
+ function getGlobalConfigPath() {
8
+ const platform = process.platform;
9
+ let configDir;
10
+ if (platform === 'win32') {
11
+ configDir = join(process.env.APPDATA || homedir(), 'coconuts');
12
+ }
13
+ else if (platform === 'darwin') {
14
+ configDir = join(homedir(), 'Library', 'Application Support', 'coconuts');
15
+ }
16
+ else {
17
+ // Linux/Unix
18
+ configDir = join(process.env.XDG_CONFIG_HOME || join(homedir(), '.config'), 'coconuts');
19
+ }
20
+ return join(configDir, 'config.json');
21
+ }
22
+ /**
23
+ * Load global config from OS-specific location
24
+ */
25
+ function loadGlobalConfig() {
26
+ const configPath = getGlobalConfigPath();
27
+ if (!existsSync(configPath)) {
28
+ return { apiKeys: {}, defaults: {} };
29
+ }
30
+ try {
31
+ const content = readFileSync(configPath, 'utf-8');
32
+ return JSON.parse(content);
33
+ }
34
+ catch (error) {
35
+ console.warn('Warning: Could not parse global config file, using defaults');
36
+ return { apiKeys: {}, defaults: {} };
37
+ }
38
+ }
39
+ /**
40
+ * Get environment variables to inject into spawned child processes
41
+ * These are the API keys that coding agents (Claude Code, Codex, Gemini CLI) will use
42
+ * Returns a full environment object with process.env merged with API keys
43
+ */
44
+ export function getInjectedEnv() {
45
+ const config = loadGlobalConfig();
46
+ const env = { ...process.env };
47
+ // Only inject keys that are actually configured
48
+ if (config.apiKeys?.anthropic) {
49
+ env.ANTHROPIC_API_KEY = config.apiKeys.anthropic;
50
+ }
51
+ if (config.apiKeys?.openai) {
52
+ env.OPENAI_API_KEY = config.apiKeys.openai;
53
+ }
54
+ if (config.apiKeys?.gemini) {
55
+ env.GEMINI_API_KEY = config.apiKeys.gemini;
56
+ }
57
+ if (config.apiKeys?.replicate) {
58
+ env.REPLICATE_API_TOKEN = config.apiKeys.replicate;
59
+ }
60
+ if (config.apiKeys?.factorydroid) {
61
+ env.FACTORY_API_KEY = config.apiKeys.factorydroid;
62
+ }
63
+ return env;
64
+ }
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
- const { stdout } = await runGit(['push'], { timeout: 30000 }); // 30 second timeout for push
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()) {
@@ -3,6 +3,7 @@ import { createWriteStream } from 'fs';
3
3
  import { promises as fs } from 'fs';
4
4
  import path from 'path';
5
5
  import { getProjectRoot } from '../project-paths.js';
6
+ import { getInjectedEnv } from '../env-injection.js';
6
7
  function shellQuote(value) {
7
8
  if (value === '')
8
9
  return "''";
@@ -16,6 +17,8 @@ function resolveAgent(model) {
16
17
  return 'gemini';
17
18
  if (lower.includes('codex') || lower.includes('gpt') || lower.includes('openai'))
18
19
  return 'codex';
20
+ if (lower.includes('droid') || lower.includes('factory'))
21
+ return 'droid';
19
22
  return 'claude';
20
23
  }
21
24
  function buildCommand(agent, instruction, config) {
@@ -42,6 +45,15 @@ function buildCommand(agent, instruction, config) {
42
45
  : baseCmd;
43
46
  break;
44
47
  }
48
+ case 'droid': {
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
51
+ const mcpFlags = config.mcpServers && config.mcpServers.length > 0
52
+ ? config.mcpServers.map(server => `--mcp ${shellQuote(server)}`).join(' ')
53
+ : '';
54
+ mainCommand = `droid exec --auto high ${mcpFlags} ${quotedInstruction}`.trim();
55
+ break;
56
+ }
45
57
  case 'claude':
46
58
  default: {
47
59
  // Claude uses .mcp.json for MCP server configuration (no --mcp flag)
@@ -55,12 +67,14 @@ function buildCommand(agent, instruction, config) {
55
67
  const CLI_AGENT_LABEL = {
56
68
  claude: 'Claude',
57
69
  gemini: 'Gemini',
58
- codex: 'Code'
70
+ codex: 'Codex',
71
+ droid: 'Factory Droid'
59
72
  };
60
73
  const CLI_AGENT_BINARY = {
61
74
  claude: 'claude',
62
75
  gemini: 'gemini',
63
- codex: 'codex'
76
+ codex: 'codex',
77
+ droid: 'droid'
64
78
  };
65
79
  const DEFAULT_MAX_RUNTIME_MS = 30 * 60 * 1000; // 30 minutes
66
80
  function getMaxRuntime() {
@@ -223,9 +237,14 @@ export class JobRunner {
223
237
  });
224
238
  return;
225
239
  }
240
+ // Inject API keys from global config into child process environment
241
+ const injectedEnv = getInjectedEnv();
226
242
  const child = spawn('bash', ['-lc', shellCommand], {
227
243
  cwd: projectRoot,
228
- env: process.env,
244
+ env: {
245
+ ...process.env,
246
+ ...injectedEnv
247
+ },
229
248
  stdio: ['ignore', 'pipe', 'pipe'],
230
249
  });
231
250
  const maxRuntime = getMaxRuntime();
@@ -5,6 +5,7 @@ import fs from 'fs';
5
5
  import { createInitScript } from './context-helper.js';
6
6
  import { getShellPath, getShellArgs, prepareShellInit } from './shell-utils.js';
7
7
  import { getLogger, AgentKinds } from '@lovelybunch/core/logging';
8
+ import { getInjectedEnv } from '../env-injection.js';
8
9
  export class TerminalManager {
9
10
  sessions = new Map();
10
11
  cleanupInterval;
@@ -82,9 +83,9 @@ export class TerminalManager {
82
83
  }
83
84
  // Get shell arguments
84
85
  const shellArgs = getShellArgs(shellPath, initScriptPath);
85
- // Prepare environment variables
86
+ // Prepare environment variables with API keys injected
86
87
  const env = {
87
- ...process.env,
88
+ ...getInjectedEnv(),
88
89
  COCONUT_PROPOSAL_ID: proposalId,
89
90
  COCONUT_CONTEXT_PATH: path.join(projectRoot, '.nut', 'context'),
90
91
  COCONUT_PROPOSAL_PATH: path.join(projectRoot, '.nut', 'proposals', `${proposalId}.md`),
@@ -1,8 +1,7 @@
1
1
  import { Hono } from 'hono';
2
- import { GET, PUT, TEST, EXPORT } from './route.js';
2
+ import { GET, PUT, TEST } from './route.js';
3
3
  const config = new Hono();
4
4
  config.get('/', GET);
5
5
  config.put('/', PUT);
6
6
  config.post('/test', TEST);
7
- config.post('/export-to-env', EXPORT);
8
7
  export default config;
@@ -30,14 +30,3 @@ export declare function TEST(c: Context): Promise<(Response & import("hono").Typ
30
30
  success: false;
31
31
  message: string;
32
32
  }, 501, "json">)>;
33
- export declare function EXPORT(c: Context): Promise<(Response & import("hono").TypedResponse<{
34
- success: false;
35
- message: string;
36
- }, 400, "json">) | (Response & import("hono").TypedResponse<{
37
- success: false;
38
- message: string;
39
- }, 500, "json">) | (Response & import("hono").TypedResponse<{
40
- success: true;
41
- message: string;
42
- envPath: string;
43
- }, import("hono/utils/http-status").ContentfulStatusCode, "json">)>;
@@ -233,114 +233,30 @@ export async function TEST(c) {
233
233
  return c.json({ success: false, message: err instanceof Error ? err.message : 'Network error' }, 200);
234
234
  }
235
235
  }
236
- // Other providers not wired up yet
237
- return c.json({ success: false, message: `Provider '${provider}' test not implemented yet` }, 501);
238
- }
239
- catch (error) {
240
- return c.json({ success: false, message: 'Invalid request body' }, 400);
241
- }
242
- }
243
- // Provider to environment variable mapping
244
- const PROVIDER_ENV_VARS = {
245
- openrouter: 'OPENROUTER_API_KEY',
246
- anthropic: 'ANTHROPIC_API_KEY',
247
- openai: 'OPENAI_API_KEY',
248
- gemini: 'GEMINI_API_KEY',
249
- factorydroid: 'FACTORY_DROID_API_KEY',
250
- bedrock: 'AWS_BEDROCK_API_KEY',
251
- baseten: 'BASETEN_API_KEY',
252
- fireworks: 'FIREWORKS_API_KEY',
253
- deepinfra: 'DEEPINFRA_API_KEY'
254
- };
255
- // Helper to find workspace root (where .env should be written)
256
- async function findWorkspaceRoot() {
257
- // Try to find .nut directory first
258
- let currentDir = process.cwd();
259
- while (currentDir !== path.parse(currentDir).root) {
260
- const nutPath = path.join(currentDir, '.nut');
261
- try {
262
- await fs.access(nutPath);
263
- // Found .nut directory, return parent as workspace root
264
- return currentDir;
265
- }
266
- catch {
267
- currentDir = path.dirname(currentDir);
268
- }
269
- }
270
- // Fallback to cwd if no .nut found
271
- return process.cwd();
272
- }
273
- // POST /api/v1/config/export-to-env
274
- // Body: { provider: string }
275
- // Exports the saved API key for a provider to a .env file in workspace root
276
- export async function EXPORT(c) {
277
- try {
278
- const body = await c.req.json();
279
- const provider = (body?.provider || '').toString();
280
- if (!provider) {
281
- return c.json({ success: false, message: 'Missing provider' }, 400);
282
- }
283
- const envVarName = PROVIDER_ENV_VARS[provider];
284
- if (!envVarName) {
285
- return c.json({ success: false, message: `Unknown provider: ${provider}` }, 400);
286
- }
287
- // Load the API key from global config
288
- const configPath = await getGlobalConfigPath();
289
- let config = { apiKeys: {}, defaults: {} };
290
- try {
291
- const content = await fs.readFile(configPath, 'utf-8');
292
- config = JSON.parse(content);
293
- }
294
- catch {
295
- // Config doesn't exist yet
296
- }
297
- const apiKey = config.apiKeys?.[provider];
298
- if (!apiKey) {
299
- return c.json({ success: false, message: `No API key configured for ${provider}` }, 400);
300
- }
301
- // Find workspace root
302
- const workspaceRoot = await findWorkspaceRoot();
303
- if (!workspaceRoot) {
304
- return c.json({ success: false, message: 'Could not find workspace root' }, 500);
305
- }
306
- const envPath = path.join(workspaceRoot, '.env');
307
- // Read existing .env file if it exists
308
- let envContent = '';
309
- try {
310
- envContent = await fs.readFile(envPath, 'utf-8');
311
- }
312
- catch {
313
- // File doesn't exist, will create new
314
- }
315
- // Parse existing env vars
316
- const envLines = envContent.split('\n');
317
- let found = false;
318
- const updatedLines = envLines.map(line => {
319
- const trimmed = line.trim();
320
- if (trimmed.startsWith(envVarName + '=') || trimmed.startsWith(envVarName + ' =')) {
321
- found = true;
322
- return `${envVarName}=${apiKey}`;
236
+ if (provider === 'replicate') {
237
+ try {
238
+ // Test Replicate API by listing models (lightweight endpoint)
239
+ const resp = await fetch('https://api.replicate.com/v1/models', {
240
+ method: 'GET',
241
+ headers: {
242
+ 'Authorization': `Bearer ${effectiveKey}`,
243
+ 'Content-Type': 'application/json',
244
+ },
245
+ });
246
+ if (!resp.ok) {
247
+ const text = await resp.text();
248
+ return c.json({ success: false, message: `Replicate rejected token: ${text.slice(0, 200)}` }, 200);
249
+ }
250
+ return c.json({ success: true, message: 'Replicate token is valid' });
323
251
  }
324
- return line;
325
- });
326
- // If not found, append to the end
327
- if (!found) {
328
- // Add a newline if the file doesn't end with one
329
- if (updatedLines.length > 0 && updatedLines[updatedLines.length - 1] !== '') {
330
- updatedLines.push('');
252
+ catch (err) {
253
+ return c.json({ success: false, message: err instanceof Error ? err.message : 'Network error' }, 200);
331
254
  }
332
- updatedLines.push(`${envVarName}=${apiKey}`);
333
255
  }
334
- // Write back to .env file
335
- await fs.writeFile(envPath, updatedLines.join('\n'), 'utf-8');
336
- return c.json({
337
- success: true,
338
- message: `${envVarName} saved to .env file`,
339
- envPath
340
- });
256
+ // Other providers not wired up yet
257
+ return c.json({ success: false, message: `Provider '${provider}' test not implemented yet` }, 501);
341
258
  }
342
259
  catch (error) {
343
- console.error('Error exporting to env:', error);
344
- return c.json({ success: false, message: error instanceof Error ? error.message : 'Failed to export to env' }, 500);
260
+ return c.json({ success: false, message: 'Invalid request body' }, 400);
345
261
  }
346
262
  }
@@ -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 = await getEventsDir();
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;
@@ -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 { unlink } = await import('fs/promises');
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 unlink(fullPath);
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/types").ScheduledJobTrigger;
16
- status: import("@lovelybunch/types").ScheduledJobRunStatus;
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/types").ScheduledJobStatus;
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/types").AuthorType;
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/types").FeatureFlagType;
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/types").ExperimentStatus;
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/types").CPStatus;
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/types").AuthorType;
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/types").FeatureFlagType;
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/types").ExperimentStatus;
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/types").CPStatus;
293
+ status: import("@lovelybunch/core").CPStatus;
294
294
  metadata: {
295
295
  createdAt: string;
296
296
  updatedAt: string;