Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 17 additions & 25 deletions src/cli/commands/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,17 +241,14 @@ export async function executeInit(
// 6b. Initialize Nexus if grove-managed — but skip if one is already running
if (nexusManaged) {
try {
const {
checkNexusCli,
nexusInit: runNexusInit,
inferNexusPreset,
discoverRunningNexus,
} = await import("../nexus-lifecycle.js");
const { generateNexusYaml, inferNexusPreset, discoverRunningNexus } = await import(
"../nexus-lifecycle.js"
);

// Reuse existing Nexus if any stack is running (avoid creating duplicate stacks).
// API key is read from .state.json (authoritative) via readNexusApiKey.
// Respect explicit GROVE_NEXUS_URL if already set (e.g., by user or parent process).
const existingUrl = process.env.GROVE_NEXUS_URL ?? (await discoverRunningNexus());
const existingUrl = process.env.GROVE_NEXUS_URL ?? (await discoverRunningNexus(options.cwd));
if (existingUrl) {
if (!process.env.GROVE_NEXUS_URL) {
process.env.GROVE_NEXUS_URL = existingUrl;
Expand All @@ -261,24 +258,19 @@ export async function executeInit(
if (key && !process.env.NEXUS_API_KEY) process.env.NEXUS_API_KEY = key;
console.log(`Reusing existing Nexus at ${existingUrl}`);
} else {
const hasNexus = await checkNexusCli();
if (hasNexus) {
const nexusPreset = inferNexusPreset({
name: options.name,
mode: resolvedMode,
preset: options.preset,
});
await runNexusInit(options.cwd, {
preset: nexusPreset,
channel: options.nexusChannel,
});
const channel = options.nexusChannel ?? "edge";
console.log(`Initialized Nexus backend (preset: ${nexusPreset}, channel: ${channel}).`);
} else {
console.log(
"Nexus CLI not found. 'grove up' will install and initialize it automatically.",
);
}
// Generate nexus.yaml directly — no nexus CLI required for initialization.
// `grove up` will shell out to `nexus up` to start the Docker stack.
const nexusPreset = inferNexusPreset({
name: options.name,
mode: resolvedMode,
preset: options.preset,
});
generateNexusYaml(options.cwd, {
preset: nexusPreset,
channel: options.nexusChannel,
});
const channel = options.nexusChannel ?? "edge";
console.log(`Initialized Nexus config (preset: ${nexusPreset}, channel: ${channel}).`);
}
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
Expand Down
7 changes: 6 additions & 1 deletion src/cli/commands/up.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,17 @@ export async function handleUp(args: readonly string[], groveOverride?: string):
);
}

const { startServices, stopServices } = await import("../../shared/service-lifecycle.js");
const { startServices, stopServices, persistNexusUrlToConfig } = await import(
"../../shared/service-lifecycle.js"
);
const services = await startServices({
groveDir,
build: opts.build,
nexusSource: opts.nexusSource,
});
if (services.resolvedNexusUrl) {
persistNexusUrlToConfig(groveDir, services.resolvedNexusUrl);
}

// Initialize local runtime for periodic cleanup (claim expiry + artifact GC).
// Uses frontierCacheTtlMs=0 since cleanup doesn't need frontier caching.
Expand Down
Loading
Loading