Skip to content
Merged
47 changes: 47 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Repository Guidelines

## Project Structure & Module Organization
- Root packages live under `code/*` (e.g., `code/core`, `code/lib/create-storybook`, `code/frameworks`). Each package uses `src/` for code with colocated tests.
- Scripts and dev tooling: `scripts/` (sandbox generation, tasks, CI helpers).
- Example sandboxes: `sandbox/`; documentation: `docs/`.

## Build, Test, and Development Commands
- `yarn i` — bootstrap the repo (installs and builds scripts, then packages).
- `yarn task --task dev --template react-vite/default-ts` — run a local sandbox dev workflow.
- `yarn --cwd code build` — build all packages.
- `yarn test` (root) or `yarn --cwd code test` — run Vitest across packages.
- Important: after changes that affect sandboxes or compiled outputs, run `yarn task --task "compile"` before validating with Vitest.

## Coding Style & Naming Conventions
- TypeScript-first. Use top‑level `import` statements; avoid `require`.
- Formatting via Prettier; lint with ESLint: `yarn --cwd code lint`.
- Naming: descriptive; files use kebab-case; types/classes use PascalCase.

## Testing Guidelines
- Framework: Vitest (repository-wide). Aim to maintain or improve coverage where you touch code. Use snapshots intentionally.

### Use Wallaby.js first
- Use Wallaby.js for test results, errors, and debugging
- Leverage runtime values and coverage data when debugging tests
- Fall back to terminal only if Wallaby isn't available

1. Analyze failing tests with Wallaby and identify the cause of the failure.
2. Use Wallaby's covered files to find relevant implementation files or narrow your search.
3. Use Wallaby's runtime values tool and coverage tool to support your reasoning.
4. Suggest and explain a code fix that will resolve the failure.
5. After the fix, use Wallaby's reported test state to confirm that the test now passes.
6. If the test still fails, continue iterating with updated Wallaby data until it passes.
7. If a snapshot update is needed, use Wallaby's snapshot tools for it.

When responding:
- Explain your reasoning step by step.
- Use runtime and coverage data directly to justify your conclusions.

## Commit & Pull Request Guidelines
- Commits: concise, imperative subject lines; reference issues when applicable.
- PRs: include a clear description, rationale, and testing notes (what you ran, e.g., `yarn --cwd code test`). Add screenshots/logs when relevant and link related issues/PRs.

## Security & Configuration Tips
- Do not commit secrets. Use environment variables and local `.env` files.
- Keep local tool versions aligned (see `.nvmrc` and `packageManager`). Update docs when changing commands or flags.

2 changes: 1 addition & 1 deletion code/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@
"@babel/parser": "^7.26.9",
"@babel/traverse": "^7.26.9",
"@babel/types": "^7.26.8",
"@clack/prompts": "1.0.0-alpha.6",
"@clack/prompts": "1.0.0-alpha.7",
"@devtools-ds/object-inspector": "^1.1.2",
"@discoveryjs/json-ext": "^0.5.3",
"@emotion/cache": "^11.14.0",
Expand Down
20 changes: 17 additions & 3 deletions code/core/src/node-logger/prompts/prompt-functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,18 @@ export const spinner = (options: SpinnerOptions): SpinnerInstance => {
spinnerInstance.start(message);
}
},
stop: (message?: string) => {
cancel: (message?: string) => {
activeSpinner = null;
restoreConsoleLog();
if (shouldLog('info')) {
spinnerInstance.stop(message);
spinnerInstance.cancel(message);
}
},
error: (message?: string) => {
activeSpinner = null;
restoreConsoleLog();
if (shouldLog('error')) {
spinnerInstance.error(message);
}
},
message: (text: string) => {
Expand All @@ -146,11 +153,18 @@ export const spinner = (options: SpinnerOptions): SpinnerInstance => {
maybeLog(message);
}
},
stop: (message) => {
cancel: (message) => {
if (message) {
maybeLog(message);
}
},
error: (message) => {
if (message) {
if (shouldLog('error')) {
logger.error(message);
}
}
},
message: (message) => {
maybeLog(message);
},
Expand Down
3 changes: 2 additions & 1 deletion code/core/src/node-logger/prompts/prompt-provider-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ export interface PromptOptions {

export interface SpinnerInstance {
start: (message?: string) => void;
stop: (message?: string) => void;
cancel: (message?: string) => void;
error: (message?: string) => void;
message: (text: string) => void;
}

Expand Down
8 changes: 6 additions & 2 deletions code/core/src/node-logger/prompts/prompt-provider-clack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,13 @@ export class ClackPromptProvider extends PromptProvider {
logTracker.addLog('info', `${spinnerId}: ${message}`);
task.message(message);
},
stop: (message) => {
cancel: (message) => {
logTracker.addLog('info', `${spinnerId}-stop: ${message}`);
task.stop(message);
task.cancel(message);
},
error: (message) => {
logTracker.addLog('error', `${spinnerId}-stop: ${message}`);
task.error(message);
},
};
}
Expand Down
6 changes: 3 additions & 3 deletions code/core/src/node-logger/tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export const executeTaskWithSpinner = async (
await childProcess;
}
logTracker.addLog('info', success);
task.stop(success);
task.cancel(success);
} catch (err: any) {
const isAborted =
abortController?.signal.aborted ||
Expand All @@ -158,12 +158,12 @@ export const executeTaskWithSpinner = async (

if (isAborted) {
logTracker.addLog('info', `${intro} aborted`);
task.stop(CLI_COLORS.warning(`${intro} aborted`));
task.cancel(CLI_COLORS.warning(`${intro} aborted`));
return;
}
const errorMessage = err instanceof Error ? (err.stack ?? err.message) : String(err);
logTracker.addLog('error', error, { error: errorMessage });
task.stop(CLI_COLORS.error(error));
task.error(CLI_COLORS.error(error));
throw err;
} finally {
cleanup?.();
Expand Down
2 changes: 1 addition & 1 deletion code/lib/cli-storybook/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ export const getProjects = async (
const projects = await collectProjects(options, detectedConfigDirs, () =>
task.message(`Detecting projects: ${++count} projects`)
);
task.stop(`${projects.length} ${projects.length > 1 ? 'projects' : 'project'} detected`);
task.cancel(`${projects.length} ${projects.length > 1 ? 'projects' : 'project'} detected`);

// Separate valid and error projects
const validProjects = projects.filter(isSuccessResult);
Expand Down
3 changes: 2 additions & 1 deletion code/lib/create-storybook/src/scaffold-new-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ export const scaffoldNewProject = async (
cwd: targetDir,
});
} catch (e) {
spinner.stop(
spinner.error(
`Failed to create a new "${projectDisplayName}" project with ${packageManagerName}`
);
throw new GenerateNewProjectOnInitError({
Expand All @@ -189,6 +189,7 @@ export const scaffoldNewProject = async (
});
}

// Use stop for successful completion; cancel is reserved for aborted flows
spinner.stop(`${projectDisplayName} project with ${packageManagerName} created successfully!`);

if (!disableTelemetry) {
Expand Down
20 changes: 10 additions & 10 deletions code/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2104,24 +2104,24 @@ __metadata:
languageName: node
linkType: hard

"@clack/core@npm:1.0.0-alpha.6":
version: 1.0.0-alpha.6
resolution: "@clack/core@npm:1.0.0-alpha.6"
"@clack/core@npm:1.0.0-alpha.7":
version: 1.0.0-alpha.7
resolution: "@clack/core@npm:1.0.0-alpha.7"
dependencies:
picocolors: "npm:^1.0.0"
sisteransi: "npm:^1.0.5"
checksum: 10c0/5d8949d74bccda55d31510f481a93828f8341e2ecfde1c5809cdd3e5b4d9f2c8fd74e34a3a38062b73fcf8897178edceaa3f884b48943b6473991e878e69eda2
checksum: 10c0/e3d706101c57252d41c77abfb16d1f163bc9e4b81cacbc70c022a859c500ceb7024049d8ff907c8869dcaa9e141e4ef6bb57b83c46027fcdc188072f7b0cc728
languageName: node
linkType: hard

"@clack/prompts@npm:1.0.0-alpha.6":
version: 1.0.0-alpha.6
resolution: "@clack/prompts@npm:1.0.0-alpha.6"
"@clack/prompts@npm:1.0.0-alpha.7":
version: 1.0.0-alpha.7
resolution: "@clack/prompts@npm:1.0.0-alpha.7"
dependencies:
"@clack/core": "npm:1.0.0-alpha.6"
"@clack/core": "npm:1.0.0-alpha.7"
picocolors: "npm:^1.0.0"
sisteransi: "npm:^1.0.5"
checksum: 10c0/c6a18a805aba72ffc879d7870dda28596f5081ccba30808e0e1d7f7cd9c3fad93101ff252de3e0001de564fbe8d162ebd637de2c7c06c39c12301d2d876c9544
checksum: 10c0/21f657868fe538e260f0c79026cca909b51013ad8017a6951869c976dded786383b604db616fed2a799b40c300f7df672fa3e7f4c2e1484819c7fc482b2bd9bb
languageName: node
linkType: hard

Expand Down Expand Up @@ -25878,7 +25878,7 @@ __metadata:
"@babel/parser": "npm:^7.26.9"
"@babel/traverse": "npm:^7.26.9"
"@babel/types": "npm:^7.26.8"
"@clack/prompts": "npm:1.0.0-alpha.6"
"@clack/prompts": "npm:1.0.0-alpha.7"
"@devtools-ds/object-inspector": "npm:^1.1.2"
"@discoveryjs/json-ext": "npm:^0.5.3"
"@emotion/cache": "npm:^11.14.0"
Expand Down
2 changes: 1 addition & 1 deletion scripts/tasks/sandbox-parts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ export const init: Task['run'] = async (
await executeCLIStep(steps.init, {
cwd,
optionValues: {
loglevel: debug ? 'debug' : 'info',
loglevel: 'debug',
yes: true,
...extra,
...(template.initOptions || {}),
Expand Down