gadget/packages/api/src/lib/workspace-detector.ts
Rob Colbert e7857016e3 feat(workspace): intelligent startup - detect workspace by walking up directory hierarchy
- Add detectWorkspace() utility in packages/api/src/lib/workspace-detector.ts
  that walks up from process.cwd() looking for .gadget/workspace.json
- Update gadget-drone to detect workspace at startup, change to workspace
  directory, and restore original startup directory on shutdown
- Update gadget-tasks with same workspace detection pattern
- Both tools now fail fast if started outside a managed workspace
- Prevents creating invalid workspaces when started from subdirectories
2026-05-17 17:09:16 -04:00

58 lines
1.5 KiB
TypeScript

// src/lib/workspace-detector.ts
// Copyright (C) 2026 Rob Colbert <rob.colbert@openplatform.us>
// Licensed under the Apache License, Version 2.0
import fs from "node:fs/promises";
import path from "node:path";
export interface WorkspaceDetectionResult {
found: boolean;
workspaceDir?: string;
startupDir: string;
}
/**
* Walks up the directory tree from startDir looking for .gadget/workspace.json.
* Returns the workspace directory if found, or { found: false } if not.
*
* @param startDir - The directory to start searching from (defaults to process.cwd())
* @returns Promise resolving to workspace detection result
*/
export async function detectWorkspace(
startDir: string = process.cwd(),
): Promise<WorkspaceDetectionResult> {
const startupDir = path.resolve(startDir);
let currentDir = startupDir;
// Walk up the directory tree until we hit root
while (true) {
const workspaceFile = path.join(currentDir, ".gadget", "workspace.json");
try {
await fs.access(workspaceFile);
// Found the workspace
return {
found: true,
workspaceDir: currentDir,
startupDir,
};
} catch {
// workspace.json not found in this directory, go up one level
}
const parentDir = path.dirname(currentDir);
// Check if we've reached the root (parent equals current)
if (parentDir === currentDir) {
break;
}
currentDir = parentDir;
}
// No workspace.json found in any parent directory
return {
found: false,
startupDir,
};
}