validation.ts
commands/add-dir/validation.ts
111
Lines
3207
Bytes
3
Exports
7
Imports
10
Keywords
What this is
This page documents one file from the repository and includes its full source so you can read it without leaving the docs site.
Beginner explanation
This file lives in the command layer. It likely turns a user action into concrete program behavior.
How it is used
Start from the exports list and related files. Those are the easiest clues for where this file fits into the system.
Expert explanation
Architecturally, this file intersects with commands. It contains 111 lines, 7 detected imports, and 3 detected exports.
Important relationships
Detected exports
AddDirectoryResultvalidateDirectoryForWorkspaceaddDirHelpMessage
Keywords
absolutepathresulttypedirectorypathchalkdirectoryresultboldpathworkingdircode
Detected imports
chalkfs/promisespath../../Tool.js../../utils/errors.js../../utils/path.js../../utils/permissions/filesystem.js
Source notes
This page embeds the full file contents. Small or leaf files are still indexed honestly instead of being over-explained.
Full source
import chalk from 'chalk'
import { stat } from 'fs/promises'
import { dirname, resolve } from 'path'
import type { ToolPermissionContext } from '../../Tool.js'
import { getErrnoCode } from '../../utils/errors.js'
import { expandPath } from '../../utils/path.js'
import {
allWorkingDirectories,
pathInWorkingPath,
} from '../../utils/permissions/filesystem.js'
export type AddDirectoryResult =
| {
resultType: 'success'
absolutePath: string
}
| {
resultType: 'emptyPath'
}
| {
resultType: 'pathNotFound' | 'notADirectory'
directoryPath: string
absolutePath: string
}
| {
resultType: 'alreadyInWorkingDirectory'
directoryPath: string
workingDir: string
}
export async function validateDirectoryForWorkspace(
directoryPath: string,
permissionContext: ToolPermissionContext,
): Promise<AddDirectoryResult> {
if (!directoryPath) {
return {
resultType: 'emptyPath',
}
}
// resolve() strips the trailing slash expandPath can leave on absolute
// inputs, so /foo and /foo/ map to the same storage key (CC-33).
const absolutePath = resolve(expandPath(directoryPath))
// Check if path exists and is a directory (single syscall)
try {
const stats = await stat(absolutePath)
if (!stats.isDirectory()) {
return {
resultType: 'notADirectory',
directoryPath,
absolutePath,
}
}
} catch (e: unknown) {
const code = getErrnoCode(e)
// Match prior existsSync() semantics: treat any of these as "not found"
// rather than re-throwing. EACCES/EPERM in particular must not crash
// startup when a settings-configured additional directory is inaccessible.
if (
code === 'ENOENT' ||
code === 'ENOTDIR' ||
code === 'EACCES' ||
code === 'EPERM'
) {
return {
resultType: 'pathNotFound',
directoryPath,
absolutePath,
}
}
throw e
}
// Get current permission context
const currentWorkingDirs = allWorkingDirectories(permissionContext)
// Check if already within an existing working directory
for (const workingDir of currentWorkingDirs) {
if (pathInWorkingPath(absolutePath, workingDir)) {
return {
resultType: 'alreadyInWorkingDirectory',
directoryPath,
workingDir,
}
}
}
return {
resultType: 'success',
absolutePath,
}
}
export function addDirHelpMessage(result: AddDirectoryResult): string {
switch (result.resultType) {
case 'emptyPath':
return 'Please provide a directory path.'
case 'pathNotFound':
return `Path ${chalk.bold(result.absolutePath)} was not found.`
case 'notADirectory': {
const parentDir = dirname(result.absolutePath)
return `${chalk.bold(result.directoryPath)} is not a directory. Did you mean to add the parent directory ${chalk.bold(parentDir)}?`
}
case 'alreadyInWorkingDirectory':
return `${chalk.bold(result.directoryPath)} is already accessible within the existing working directory ${chalk.bold(result.workingDir)}.`
case 'success':
return `Added ${chalk.bold(result.absolutePath)} as a working directory.`
}
}